diff --git a/.gitignore b/.gitignore index 88295e7..fa4d28d 100644 --- a/.gitignore +++ b/.gitignore @@ -87,6 +87,7 @@ keystore.properties # IDE .vscode/launch.json .vscode/settings.json +.contextstream/ # Cloudflare Wrangler .wrangler diff --git a/CLAUDE.md b/CLAUDE.md index 55af890..d3b0cad 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,6 +1,6 @@ # MeshCore Open - Flutter Client -Open-source Flutter client for MeshCore LoRa mesh networking devices. +Open-source Flutter client for MeshCore LoRa mesh networking devices. Connects to MeshCore-compatible radios over **BLE, TCP, or USB serial** and provides direct/channel chat, contact and channel management, on-map node tracking, repeater administration, and on-device message translation. ## Build Commands @@ -17,6 +17,9 @@ Open-source Flutter client for MeshCore LoRa mesh networking devices. # Build iOS ~/flutter/bin/flutter build ios +# Build versioned web release (uses build_pipe) +~/flutter/bin/dart run build_pipe + # Run static analysis ~/flutter/bin/flutter analyze @@ -28,43 +31,132 @@ Open-source Flutter client for MeshCore LoRa mesh networking devices. ``` lib/ -├── main.dart # App entry point, MaterialApp setup with Provider -├── connector/ -│ └── meshcore_connector.dart # BLE communication layer (MeshCoreConnector) -├── screens/ -│ ├── scanner_screen.dart # BLE device scanning (home screen) -│ ├── device_screen.dart # Connected device hub with navigation -│ ├── chat_screen.dart # Chat interface (placeholder) -│ ├── contacts_screen.dart # Contacts list (placeholder) -│ └── settings_screen.dart # Device info and app settings -└── widgets/ - └── device_tile.dart # Device list item with signal strength +├── main.dart # Entry point: MultiProvider wiring, locale + theme, initial route +├── connector/ # Unified BLE/TCP/USB transport layer +│ ├── meshcore_connector.dart # Central state holder + ChangeNotifier (all transports) +│ ├── meshcore_connector_tcp.dart # TCP transport helper +│ ├── meshcore_connector_usb.dart # USB serial transport helper +│ ├── meshcore_protocol.dart # Frame size + version constants +│ └── meshcore_uuids.dart # Nordic UART UUIDs + scan name prefixes +├── models/ # Plain data classes (Contact, Channel, Message, Community, …) +├── services/ # ChangeNotifier services + IO services (retry, translation, ML, …) +├── storage/ # SharedPreferences-backed stores, scoped per device key +├── helpers/ # Pure utilities (Smaz compression, GIF parsing, scroll helpers) +├── utils/ # Platform / IO / UX utilities (logger, GPX export, dialogs) +├── theme/ # MeshPalette (defined, not yet wired in main.dart) +├── l10n/ # ARB localization for 18 locales +├── icons/ # Custom icon widgets +├── widgets/ # Reusable widgets (AppBar, BatteryUi, QR, jump-to-bottom, …) +└── screens/ # ~26 screens — see Screens section below ``` +## Screens + +All screens are fully implemented (no remaining placeholders). + +### Connection / Scanning +| Screen | Purpose | +|---|---| +| `scanner_screen.dart` | BLE device scan and connect — main entry point | +| `tcp_screen.dart` | Connect to a MeshCore device over TCP/IP | +| `usb_screen.dart` | Connect to a MeshCore device over USB serial | +| `discovery_screen.dart` | Browse all discovered (non-contact) mesh nodes | +| `chrome_required_screen.dart` | Web gate for non-Chrome browsers (BLE unavailable) | + +### Chat / Messaging +| Screen | Purpose | +|---|---| +| `chat_screen.dart` | Direct (private) messaging with a contact | +| `channel_chat_screen.dart` | Group messaging inside a named channel | +| `channels_screen.dart` | List and manage channels (add/edit/delete) | +| `channel_message_path_screen.dart` | Hop-by-hop route a channel message took, with map overlay | + +### Contacts / Neighbors +| Screen | Purpose | +|---|---| +| `contacts_screen.dart` | Full contacts list with previews and management | +| `neighbors_screen.dart` | Nodes directly heard by the connected radio (one-hop) | + +### Repeater Management +| Screen | Purpose | +|---|---| +| `repeater_hub_screen.dart` | Top-level repeater hub; navigates to sub-screens | +| `repeater_status_screen.dart` | Live status of a managed repeater node | +| `repeater_cli_screen.dart` | Raw command-line interface to a repeater | +| `repeater_settings_screen.dart` | Full radio/node settings editor for a repeater | + +### Map / Location +| Screen | Purpose | +|---|---| +| `map_screen.dart` | Main map view of contacts/nodes with live GPS positions | +| `line_of_sight_map_screen.dart` | Terrain LOS analysis between configurable endpoints | +| `path_trace_map.dart` | Animates the hop path a direct message traveled | +| `map_cache_screen.dart` | Download/clear offline map tile cache | +| `community_qr_scanner_screen.dart` | Scan QR to join a mesh community/channel | + +### Settings / Debug / Diagnostics +| Screen | Purpose | +|---|---| +| `settings_screen.dart` | Connected device settings: radio params, identity, GPS | +| `app_settings_screen.dart` | App preferences: theme, units, map source, notifications | +| `app_debug_log_screen.dart` | In-app log viewer (app-layer messages) | +| `ble_debug_log_screen.dart` | In-app log viewer (raw BLE frame traffic) | +| `companion_radio_stats_screen.dart` | RF stats (RSSI, SNR, packet counts) for paired radio | +| `telemetry_screen.dart` | Battery / sensor / environmental telemetry for a contact | + ## Architecture ### State Management -- **Provider** with `ChangeNotifier` pattern -- `MeshCoreConnector` is the central state holder for BLE connection -- Screens use `Consumer` for reactive UI updates + +`Provider` with `ChangeNotifier`. `main.dart` wires a `MultiProvider` with the following: + +| Provider | Role | +|---|---| +| `MeshCoreConnector` | Active transport (BLE/TCP/USB), connection state, frame I/O | +| `MessageRetryService` | ACK tracking and retry scheduling with backoff | +| `PathHistoryService` | Per-contact routing history (LRU cache, 50 contacts) | +| `AppSettingsService` | App preferences (theme, units, locale, notifications) | +| `BleDebugLogService` | Raw BLE frame log buffer | +| `AppDebugLogService` | Structured app log buffer | +| `ChatTextScaleService` | Pinch-to-zoom text scale for chat screens | +| `TranslationService` | On-device LLM translation (llamadart) | +| `UiViewStateService` | Contacts/channels sort/filter/search state | +| `TimeoutPredictionService` | ML linear regression for ACK timeout prediction | +| `StorageService` | Path history + delivery observation persistence | +| `MapTileCacheService` | OSM tile pre-cache | + +Screens consume these via `Consumer` (or `context.watch()` / `context.read()`) for reactive UI. + +### Storage / Persistence + +All stores in `lib/storage/` use `PrefsManager` (a `SharedPreferences` singleton initialized in `main()`). Most stores **scope keys by the first 10 hex chars of the connected device's public key**, so per-radio data is isolated. + +| Store | Persists | +|---|---| +| `message_store`, `channel_message_store` | Direct + channel messages | +| `contact_store`, `contact_discovery_store` | Known + discovered contacts | +| `channel_store`, `channel_order_store`, `channel_settings_store` | Channels, display order, per-channel Smaz toggle | +| `community_store` | Communities (32-byte shared secrets) | +| `contact_group_store`, `contact_settings_store` | Groups, per-contact Smaz toggle | +| `unread_store` | Per-contact unread counts (debounced writes) | + +GGUF translation models are stored as files (not SharedPreferences) via `translation_file_store`. ### Theming - Material 3 design (`useMaterial3: true`) - System-based dark/light mode (`ThemeMode.system`) - Blue color scheme seed +- `lib/theme/mesh_theme.dart` defines a warm-dark `MeshPalette` (phosphor-green accents) but is **not currently wired** in `main.dart` — available for a future redesign -## BLE Protocol +### Localization -### Nordic UART Service (NUS) -- **Service UUID**: `6e400001-b5a3-f393-e0a9-e50e24dcca9e` -- **RX Characteristic**: `6e400002-b5a3-f393-e0a9-e50e24dcca9e` (Write to device) -- **TX Characteristic**: `6e400003-b5a3-f393-e0a9-e50e24dcca9e` (Notify from device) +18 locales supported via Flutter's standard ARB pipeline (`lib/l10n/`): en, de, es, fr, it, pt, ru, uk, bg, hu, ja, ko, nl, pl, sk, sl, sv, zh. Language override comes from `AppSettingsService.settings.languageOverride`. Use the `context.l10n` extension (`lib/l10n/l10n.dart`) for translated strings; contact-type names live in `contact_localization.dart`. -### Device Discovery -- Scans for devices with known name prefixes -- Filters by `platformName` or `advertisementData.advName` +## Transports -### Connection States +`MeshCoreConnector` unifies all three transports under one `ChangeNotifier`. There is **no shared base class** — selection is via the `MeshCoreTransportType { bluetooth, usb, tcp }` enum, and BLE/TCP/USB share the same connection-state enum, send/receive API, and frame protocol. + +### Connection State ```dart enum MeshCoreConnectionState { disconnected, @@ -75,28 +167,136 @@ enum MeshCoreConnectionState { } ``` -### Frame I/O -- **Send**: `MeshCoreConnector.sendFrame(Uint8List data)` -- **Receive**: `MeshCoreConnector.receivedFrames` stream of `Uint8List` +### Frame I/O (all transports) +- **Send**: `MeshCoreConnector.sendFrame(Uint8List data, {String? channelSendQueueId, bool expectsGenericAck})` +- **Receive**: `Stream get receivedFrames` +- **Protocol constants** (`meshcore_protocol.dart`): `maxFrameSize = 172`, `maxTextPayloadBytes = 160`, `appProtocolVersion = 4` + +### BLE — Nordic UART Service (NUS) +- **Service UUID**: `6e400001-b5a3-f393-e0a9-e50e24dcca9e` +- **RX Characteristic** (write to device): `6e400002-b5a3-f393-e0a9-e50e24dcca9e` +- **TX Characteristic** (notify from device): `6e400003-b5a3-f393-e0a9-e50e24dcca9e` +- **Discovery**: scans for devices whose name starts with `MeshCore-`, `Whisper-`, `WisCore-`, `Seeed`, `Lilygo`, `HT-`, or `LowMesh_MC_` (filters on both `platformName` and `advertisementData.advName`) +- **Linux**: `linux_ble_pairing_service.dart` falls back to `bluetoothctl` when BlueZ agent prompts fail + +### TCP +- Manual host/port entry, persisted via `AppSettingsService` (`tcpServerAddress`, `tcpServerPort`) +- UI hint: `192.168.40.10` / port `5000` +- Disabled on web (`PlatformInfo.isWeb`) +- API: `MeshCoreConnector.connectTcp(host: ..., port: ...)` + +### USB Serial (flserial) +- Default baud rate: `115200` +- Port enumeration: `MeshCoreConnector.listUsbPorts()` +- COBS-framed packets via `usb_serial_frame_codec.dart` +- macOS device-name resolution via `ioreg` (`utils/macos_usb_device_names.dart`) +- API: `MeshCoreConnector.connectUsb(portName: ..., baudRate: 115200)` ## Dependencies +App version: `8.0.0+11` — Dart SDK constraint: `^3.9.2` + +**Connectivity** + +| Package | Version | Purpose | +|---------|---------|---------| +| flutter_blue_plus | ^2.1.0 | BLE scanning, connecting, and UART data transfer | +| flutter_blue_plus_platform_interface | ^8.2.1 | Platform-interface layer required by flutter_blue_plus | +| flserial | git (MeshEnvy fork) | USB serial transport for wired device connections (TODO: upstream pending) | + +**State / Storage** + +| Package | Version | Purpose | +|---------|---------|---------| +| provider | ^6.1.5+1 | ChangeNotifier-based state management across screens | +| shared_preferences | ^2.2.2 | Persistent key-value storage for user settings | +| path_provider | ^2.1.5 | Locates platform-appropriate directories for file I/O | + +**Crypto** + +| Package | Version | Purpose | +|---------|---------|---------| +| crypto | ^3.0.3 | SHA/HMAC hashing used in message authentication | +| pointycastle | ^4.0.0 | AES encryption/decryption for channel and direct messages | +| uuid | ^4.3.3 | Generates UUIDs for message and contact identity | + +**Maps & Location** + +| Package | Version | Purpose | +|---------|---------|---------| +| flutter_map | ^8.2.2 | Interactive tile map for node positions and path traces | +| latlong2 | ^0.9.1 | LatLng coordinate type used throughout map and GPS code | +| gpx | ^2.3.0 | Export node paths as GPX track files | + +**UI** + +| Package | Version | Purpose | +|---------|---------|---------| +| material_symbols_icons | ^4.2906.0 | Extended Material Symbols icon set (line-of-sight, etc.) | +| flutter_svg | ^2.0.10+1 | Renders SVG assets (custom icons such as LoS indicator) | +| cached_network_image | ^3.4.1 | Caches map tile images downloaded over the network | +| flutter_cache_manager | ^3.4.1 | Underlying cache manager used by cached_network_image | +| flutter_linkify | ^6.0.0 | Auto-detects and makes URLs tappable in chat messages | +| mobile_scanner | ^7.1.4 | QR/barcode scanning for contact and channel import | +| qr_flutter | ^4.1.0 | Generates QR codes for sharing contacts and channels | +| cupertino_icons | ^1.0.8 | iOS-style icon font (bundled for completeness) | +| characters | ^1.4.0 | Unicode-aware string operations for message text handling | + +**Notifications / Background** + | Package | Version | Purpose | |---------|---------|---------| -| flutter_blue_plus | ^2.1.0 | BLE communication | -| provider | ^6.1.5+1 | State management | -| cupertino_icons | ^1.0.8 | iOS-style icons | +| flutter_local_notifications | ^20.1.0 | Shows local push notifications for incoming messages | +| flutter_foreground_task | ^9.2.0 | Keeps the app alive in background to maintain BLE/USB connection | + +**ML / AI** + +| Package | Version | Purpose | +|---------|---------|---------| +| ml_algo | ^16.0.0 | OLS regression used in `timeout_prediction_service.dart` to predict message ACK timeouts | +| ml_dataframe | ^1.0.0 | DataFrame input format required by ml_algo | +| llamadart | >=0.6.8 <0.7.0 | On-device LLM inference used in `translation_service.dart` for message translation | + +**Misc** + +| Package | Version | Purpose | +|---------|---------|---------| +| http | ^1.2.0 | Fetches tile URLs and any remote API calls | +| url_launcher | ^6.3.0 | Opens URLs in the system browser from linkified chat text | +| share_plus | ^12.0.1 | Shares files (e.g. exported GPX tracks) via the system share sheet | +| package_info_plus | ^9.0.0 | Reads app version/build number displayed in settings | +| web | ^1.1.1 | Web-platform APIs for USB serial and browser detection on Flutter Web | +| intl | any | Internationalization and locale formatting (required by flutter_localizations) | +| build_pipe | ^0.3.1 | CI/CD build pipeline configuration (web release builds with versioned assets) | ## Platform Configuration ### Android (`android/app/src/main/AndroidManifest.xml`) -- `BLUETOOTH`, `BLUETOOTH_ADMIN` (API 30 and below) -- `BLUETOOTH_SCAN`, `BLUETOOTH_CONNECT`, `BLUETOOTH_ADVERTISE` (API 31+) -- `ACCESS_FINE_LOCATION`, `ACCESS_COARSE_LOCATION` (for BLE scanning) +- `INTERNET` (map tiles, translation model downloads) +- `BLUETOOTH`, `BLUETOOTH_ADMIN` (API ≤ 30) +- `BLUETOOTH_SCAN` (with `neverForLocation`), `BLUETOOTH_CONNECT`, `BLUETOOTH_ADVERTISE` (API 31+) +- `ACCESS_FINE_LOCATION`, `ACCESS_COARSE_LOCATION` (BLE scanning on API ≤ 30) +- `POST_NOTIFICATIONS` (API 33+) +- `FOREGROUND_SERVICE`, `FOREGROUND_SERVICE_CONNECTED_DEVICE` (background BLE/USB connection) +- `WAKE_LOCK` +- `CAMERA` (QR scanning, declared as optional feature) +- USB host hardware feature (optional) + +`flutter_foreground_task` registers a `ForegroundService` with `foregroundServiceType="connectedDevice"` and `stopWithTask="false"`. + +**Build config (`android/app/build.gradle.kts`)**: `applicationId = com.meshcore.meshcore_open`, NDK `29.0.14206865`, Java 8 core-library desugaring (`desugar_jdk_libs:2.1.4`), release signing via `key.properties` (debug fallback). ### iOS (`ios/Runner/Info.plist`) -- `NSBluetoothAlwaysUsageDescription` -- `NSBluetoothPeripheralUsageDescription` +- `NSBluetoothAlwaysUsageDescription`, `NSBluetoothPeripheralUsageDescription` +- `NSCameraUsageDescription` (QR scanning to join communities) +- Background modes: `bluetooth-central` +- `LSApplicationQueriesSchemes`: `http`, `https` + +### Web (`web/`) +PWA scaffold present but boilerplate (`manifest.json` and `index.html` are unmodified Flutter defaults). BLE is unsupported in browsers; TCP and Web Serial USB may work in Chrome only. `ChromeRequiredScreen` gates non-Chrome web users. Versioned releases are produced via `build_pipe` (`?v=` cache busting, no service worker). + +### Desktop +`linux/`, `windows/`, and `macos/` directories are present as Flutter scaffolds. No app-specific native config has been added; BLE on desktop has not been validated. ## Coding Conventions @@ -123,14 +323,14 @@ enum MeshCoreConnectionState { | File | Purpose | |------|---------| -| `lib/connector/meshcore_connector.dart` | All BLE logic - scanning, connecting, data transfer | -| `lib/screens/scanner_screen.dart` | Entry point UI, device list | -| `lib/main.dart` | App configuration, theme, Provider setup | -| `pubspec.yaml` | Dependencies and project metadata | - -## Placeholder Screens - -The following screens are implemented as placeholders and need full implementation: -- `chat_screen.dart` - Mesh chat functionality -- `contacts_screen.dart` - Contact management -- `settings_screen.dart` - Radio settings, node identity, location (partially implemented) +| `lib/main.dart` | App configuration, MultiProvider setup, theme, locale, initial route | +| `lib/connector/meshcore_connector.dart` | Unified BLE/TCP/USB transport state holder | +| `lib/connector/meshcore_protocol.dart` | Frame size limits and protocol version | +| `lib/connector/meshcore_uuids.dart` | NUS UUIDs and BLE scan name prefixes | +| `lib/services/app_settings_service.dart` | App-wide settings (`AppSettings` JSON in SharedPreferences) | +| `lib/services/storage_service.dart` | Path history + delivery observation persistence | +| `lib/services/message_retry_service.dart` | ACK tracking + retry scheduling | +| `lib/services/translation_service.dart` | On-device LLM translation (llamadart) | +| `lib/storage/prefs_manager.dart` | SharedPreferences singleton initialized in `main()` | +| `lib/screens/scanner_screen.dart` | Home screen — BLE scan and connect | +| `pubspec.yaml` | Dependencies and project metadata (current version `8.0.0+11`) | diff --git a/README.md b/README.md index ac188f6..94d54ba 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ Open-source Flutter client for MeshCore LoRa mesh networking devices. MeshCore Open is a cross-platform mobile application for communicating with MeshCore LoRa mesh network devices via Bluetooth Low Energy (BLE). The app enables long-range, off-grid communication through peer-to-peer messaging, public channels, and mesh networking capabilities. +**Website:** [meshcoreopen.org](https://meshcoreopen.org/) + Get it on Obtainium diff --git a/documentation/additional-features.md b/documentation/additional-features.md index f7b8319..5dfd268 100644 --- a/documentation/additional-features.md +++ b/documentation/additional-features.md @@ -25,8 +25,8 @@ A bottom sheet with a search field and a grid of GIF thumbnails. ### How to Access App Settings → Appearance → Language -### Supported Languages (15) -English, French, Spanish, German, Polish, Slovenian, Portuguese, Italian, Chinese, Swedish, Dutch, Slovak, Bulgarian, Russian, Ukrainian +### Supported Languages (18) +English, French, Spanish, German, Polish, Slovenian, Portuguese, Italian, Chinese, Swedish, Dutch, Slovak, Bulgarian, Russian, Ukrainian, Hungarian, Japanese, Korean ### How It Works - All UI strings go through Flutter's ARB localization system @@ -185,3 +185,77 @@ An ML-based service that predicts expected delivery timeouts: - Blends per-contact statistics with ML predictions - Falls back to `3000 + 3000 × pathLength` ms when insufficient data - Observations are persisted to storage via a 2-second debounced timer (observations within 2s of app termination may be lost) + +--- + +## On-Device Message Translation + +### What It Is +An optional on-device translation service powered by an embedded LLM (llamadart, running GGUF models). Translation runs entirely on-device — no data leaves the app. + +### How to Access +Tap the translate button on any received message. On first use, the GGUF model file is downloaded and cached locally. + +### How It Works +- Model files are managed by `TranslationFileStore`; download progress is shown in-place +- Translation runs via `TranslationService` using the llamadart CPU backend (arm64 and x64 on Android) +- Translated text is shown in `TranslatedMessageContent` as an inline overlay on the original message bubble +- Each translation is cached; re-tapping shows the cached result without re-running inference + +--- + +## Emoji Reactions + +### How to Access +Long-press a message bubble in any direct or channel chat, then select a reaction emoji. + +### What the User Sees +An emoji picker inline with common reactions. Selected reactions appear below the message bubble with a count. + +### How It Works +- Implemented via `emoji_picker.dart` and `reaction_helper.dart` +- Reactions are transmitted as a special message type visible to all participants with MeshCore Open + +--- + +## Linkification + +### What It Does +URLs and `meshcore://` URIs in received messages are automatically detected and rendered as tappable links. + +### How It Works +- Powered by the `flutter_linkify` package via `link_handler.dart` +- Tapping a URL opens the system browser; tapping a `meshcore://` URI imports the contact + +--- + +## GPX Export + +### How to Access +Settings → Export section (three options: Export Repeaters, Export Contacts, Export All). + +### What It Does +Exports contacts with GPS coordinates to a `.gpx` file via the OS share sheet. Not available on web. + +--- + +## Pinch-to-Zoom Chat Text + +### What It Does +Users can pinch to scale all chat text up or down within a session. + +### How It Works +- Implemented via `ChatTextScaleService` and `ChatZoomWrapper` +- Scale range: 0.8× to 1.8× +- The chosen scale persists across the session via the service + +--- + +## Background Service (Android) + +### What It Does +On Android, a foreground service (`background_service.dart`) keeps the BLE connection and message handling alive when the app is in the background. On other platforms this is a no-op. + +### User Impact +- A persistent notification appears while the service is running +- Messages are received and retry logic continues even when the app is not in the foreground diff --git a/documentation/ble-protocol.md b/documentation/ble-protocol.md index ec24094..f9d2acb 100644 --- a/documentation/ble-protocol.md +++ b/documentation/ble-protocol.md @@ -33,7 +33,6 @@ RX (device → host): [0x3E][len_lo][len_hi][payload...] - Length: 2-byte little-endian, payload only - Max payload: 172 bytes - TCP: `tcpNoDelay: true` (Nagle disabled), writes serialized to prevent interleaving -- USB: 10ms post-write delay between frames ## Connection State Machine @@ -53,9 +52,11 @@ enum MeshCoreConnectionState { - `MeshCore-` - `Whisper-` - `WisCore-` + - `Seeed` + - `Lilygo` - `HT-` - `LowMesh_MC_` -2. **Connect** with 15-second timeout +2. **Connect** with 15-second timeout (6 seconds on Linux) 3. **Request MTU** 185 bytes (non-web only) 4. **Discover services** and locate NUS 5. **Enable TX notifications** (up to 3 attempts on native) @@ -79,7 +80,7 @@ On unexpected disconnection, auto-reconnect with exponential backoff: | Max path size | 64 bytes | Maximum path data | | Max name size | 32 bytes | Maximum node name | | Max text payload | 160 bytes | Firmware `MAX_TEXT_LEN` | -| App protocol version | 3 | Sent in device query | +| App protocol version | 4 | Sent in device query | | Contact frame size | 148 bytes | Fixed-size contact record | ## Command Codes (App → Device) diff --git a/documentation/channels.md b/documentation/channels.md index 21fb52e..49db176 100644 --- a/documentation/channels.md +++ b/documentation/channels.md @@ -28,7 +28,6 @@ QuickSwitchBar tab 1 (middle) from any main screen. - **Scrollable list of channel cards**, each showing: - Type icon with color coding (purple badge overlay for community channels) - Channel name (or "Channel N" if unnamed) - - Subtitle: "Public channel", "Hashtag channel", "Private channel", or "Community channel - {name}" - Unread badge (if messages are unread) - Drag handle (when manual sort is active) - **"+" FAB** to add a new channel @@ -70,9 +69,9 @@ Tap a channel card to open the channel chat screen. ### App Bar -- Type icon (public/private/hashtag) +- Type icon: globe for public channels, tag (#) for all other channel types - Channel name -- Subtitle: "{type} - {N} unread" +- Subtitle: "{Public|Private} • {N} unread" (e.g., "Public • 3 unread") ### Message Display @@ -113,17 +112,9 @@ Tap a channel card to open the channel chat screen. | Path | Desktop only | Opens message path view | | Add Reaction | Incoming messages only | Opens emoji picker (cannot react to your own messages) | | Copy | All messages | Copies text to clipboard | +| Mark as Unread | Incoming messages only | Marks this message and all subsequent incoming messages as unread | | Delete | All messages | Removes locally (not from mesh) | -### Message Path Viewing - -Tap a message bubble to open the Channel Message Path Screen, which shows: -- Each hop in the path as a visual chain -- Known contacts identified by name at each hop -- Observed vs. declared hop counts -- Alternative path variants (if received via multiple paths) -- Map view buttons for geographic path visualization - ## Communities Communities are a layer above channels that provide a private namespace. diff --git a/documentation/chat-and-messaging.md b/documentation/chat-and-messaging.md index 22030d5..baf2ab8 100644 --- a/documentation/chat-and-messaging.md +++ b/documentation/chat-and-messaging.md @@ -37,6 +37,7 @@ From the Contacts screen, tap any Chat-type contact to open the ChatScreen. ### Input Bar - **GIF button** (left): Opens GIF picker bottom sheet +- **Translation button** (optional, between GIF and text field): Shown only when translation is enabled in App Settings. Tap to configure outgoing-message translation language and on/off toggle. - **Text field** (center): Auto-capitalization, enforces UTF-8 byte limit in real-time - **Send button** (right): Submits the message - On desktop: Enter/Numpad Enter also submits @@ -66,8 +67,8 @@ Outgoing messages display a status indicator: When enabled in App Settings, additional metadata appears inside each bubble: - Timestamp (HH:MM) -- Retry count (e.g., "Retry 2 of 4") -- Status icon +- Retry count (e.g., "Retry 2 of 4") — only shown for outgoing messages where at least one retry has occurred +- Status icon (outgoing only) - Round-trip time in seconds (if delivered) ## Message Length Limits @@ -86,7 +87,7 @@ When a direct message is sent: 1. The app computes an expected ACK hash: `SHA256([timestamp][attempt][text][selfPubKey])[0:4]` — matching the firmware's hash calculation. If SMAZ compression is enabled, the compressed text (not the original) is hashed 2. On device acknowledgment (`RESP_CODE_SENT`), the message transitions to "sent" and a timeout timer starts -3. **Timeout duration**: Preferably from the ML timeout prediction service; otherwise `3000 + 3000 × path_length` milliseconds (15000ms for flood) +3. **Timeout duration**: Preferably from the ML timeout prediction service; otherwise calculated from LoRa airtime physics: `500 + (airtime × 6 + 250) × (pathLength + 1)` ms for direct paths, `500 + 16 × airtime` ms for flood (airtime is estimated from the radio's current spreading factor, bandwidth, and coding rate) 4. On timeout, the message is retried with **exponential backoff**: `1000 × 2^retryCount` ms (1s, 2s, 4s, 8s, 16s...) 5. **Max retries**: Configurable (default 5, range 2–10) 6. After max retries, the message is marked "failed" — but a **30-second grace window** remains during which a late ACK can still resolve the message to "delivered" @@ -115,6 +116,7 @@ Add emoji reactions to incoming messages (not your own): | Add reaction | Incoming messages only | Opens emoji picker | | View path | Mobile: tap bubble directly; Desktop: long-press/right-click menu | Shows message routing path | | Copy | All messages | Copies text to clipboard | +| Mark as Unread | Incoming messages only | Marks this message and all subsequent incoming messages as unread | | Delete | All messages | Removes locally (not from mesh) | | Retry | Failed outgoing messages | Re-sends the message | | Open chat with sender | Room server chats | Opens 1:1 chat with the message sender | diff --git a/documentation/contacts.md b/documentation/contacts.md index 1a94ba2..7ff5ad7 100644 --- a/documentation/contacts.md +++ b/documentation/contacts.md @@ -73,7 +73,8 @@ Groups are stored per radio identity (scoped by public key). | Action | Availability | Description | |---|---|---| -| Path Trace / Ping | Repeaters, Rooms (always); Chat if `pathLength > 0` | Opens PathTraceMapScreen. Label shows "Ping" when no path bytes are known, "Path Trace" otherwise | +| Ping | Repeaters (always) | Opens PathTraceMapScreen targeting the repeater | +| Path Trace | Rooms (always); Chat/Sensor if `pathLength > 0` | Opens PathTraceMapScreen. For rooms, label shows "Ping" when no path bytes are known, "Path Trace" when path bytes are available | | Manage Repeater | Repeaters only | Login dialog → RepeaterHubScreen | | Room Login | Rooms only | Login dialog → ChatScreen | | Room Management | Rooms only | Login dialog → RepeaterHubScreen (management mode) | diff --git a/documentation/map-and-location.md b/documentation/map-and-location.md index f293abe..93ba634 100644 --- a/documentation/map-and-location.md +++ b/documentation/map-and-location.md @@ -25,7 +25,7 @@ All contacts with known GPS coordinates are plotted: | Room | Purple | Meeting room | | Sensor | Orange | Sensors | -Node name labels appear automatically at zoom level 12 and above. +Node name labels appear automatically at zoom level 14 and above. ### Shared Map Pins (Flag Icons) Location pins shared in chat messages are displayed as flags: @@ -88,10 +88,10 @@ Shows a bottom sheet with: - **Set as my location**: Updates your device's advertised location ### Filter Dialog (FAB) -Toggle visibility of: chat nodes, repeaters, other nodes, guessed locations, discovery contacts. +Toggle visibility of: chat nodes, repeaters, other nodes, guessed locations, discovery contacts, overlapping markers (stacked markers at similar coordinates), and shared map pins (flag markers). Additional filters: - **Key prefix filter**: Show only contacts whose public key starts with a given prefix -- **Last-seen time slider**: From 1 hour to "all time" +- **Last-seen time slider**: Exponential scale from near-zero to 6 months, with "all time" at the top end ### Legend Card (Top-Right) Shows node count and pin count. Tappable to expand a legend of all marker types. diff --git a/documentation/navigation.md b/documentation/navigation.md index 9003122..b0994fd 100644 --- a/documentation/navigation.md +++ b/documentation/navigation.md @@ -22,31 +22,16 @@ The QuickSwitchBar is a Material 3 `NavigationBar` with a frosted-glass visual t Tapping a tab replaces the current screen with a subtle fade + slight horizontal nudge transition (220ms forward, 200ms reverse). The back button is suppressed on all three main screens — navigation between them is flat, not stacked. All icons use outline variants (`people_outline`, `tag`, `map_outlined`) following Material 3 conventions. -## Device Screen +## Disconnection -The Device Screen is a transitional hub that shows after connection. In practice, the app navigates directly to Contacts after connecting, but the Device Screen is reachable via the QuickSwitchBar. - -### What the User Sees - -**App Bar**: -- Left: Battery indicator chip (tappable — toggles between percentage and voltage display). Icon changes based on level: `battery_unknown` when data unavailable, `battery_alert` (orange) at 15% or below, `battery_full` otherwise -- Left-aligned title (`centerTitle: false`): Two-line layout — small grey "MeshCore" label above the device name in bold -- Right: Disconnect button (`bluetooth_disabled` crossed-out icon) and Settings button (tune icon) - -**Body**: -- **Connection Card**: Device avatar, device name, device ID, "Connected" chip, and battery chip -- **Quick Switch** section: The QuickSwitchBar widget for navigating to Contacts/Channels/Map - -### Disconnection - -- The disconnect button shows a confirmation dialog before disconnecting +- The disconnect button (available in the Settings screen and other main screens) shows a confirmation dialog before disconnecting - If the device disconnects unexpectedly, the app automatically navigates back to the Scanner screen (fires after the current frame completes via a post-frame callback) - This auto-navigation behavior (`DisconnectNavigationMixin`) is shared across all main screens ## Theme and Locale - **Theme mode** is user-configurable in App Settings (System / Light / Dark) — not locked to system -- **Language** can be overridden to one of 15 supported languages, or follow the system locale +- **Language** can be overridden to one of 18 supported languages, or follow the system locale - On web, if a non-Chromium browser is detected, the app shows a `ChromeRequiredScreen` instead of the Scanner (Web Bluetooth requires Chromium) ## Full Navigation Graph diff --git a/documentation/notifications.md b/documentation/notifications.md index 0eb2574..7db9f0f 100644 --- a/documentation/notifications.md +++ b/documentation/notifications.md @@ -73,7 +73,7 @@ There is no per-contact muting. The notification system prevents notification storms: - **Minimum interval**: 3 seconds between individual notifications -- **Batch window**: If multiple notifications arrive within 5 seconds, they are combined into a single summary notification on a fourth Android channel (`batch_summary`): "MeshCore Activity — 2 messages, 1 channel message, 3 new nodes". Note: batch summaries are Android-only; on Apple platforms individual notifications are shown +- **Batch window**: If multiple notifications arrive within 5 seconds, they are combined into a single summary notification on a fourth Android channel (`batch_summary`). The title is "MeshCore Activity" and the body lists the grouped counts (e.g., "2 messages, 1 channel message, 3 new nodes"). Batch summaries are Android-only; queued notifications that overflow the batch window are silently dropped on other platforms ## Notification Clearing diff --git a/documentation/repeater-management.md b/documentation/repeater-management.md index be5015f..754d4e2 100644 --- a/documentation/repeater-management.md +++ b/documentation/repeater-management.md @@ -17,8 +17,8 @@ From the Contacts screen: - Password field with show/hide toggle - "Save password" checkbox (persists for future logins). If a saved password exists, it is pre-filled and the checkbox is pre-checked, making login one-tap - Routing mode selector and "Manage Paths" link are available directly in the dialog (configure routing before login) -- Auto-retries up to 5 times on timeout, showing progress ("Attempt 2 of 5"). A wrong password stops immediately after the first attempt — only timeouts trigger retries -- After 5 failed attempts, further login attempts are blocked +- Auto-retries up to 5 times on timeout, showing progress ("Attempt 2 of 5"). A wrong password (explicit failure response) stops immediately — only timeouts trigger retries +- If auto-clock-sync is enabled for this repeater (configured in Repeater Settings), a `clock sync` command is sent automatically on successful login --- @@ -28,15 +28,17 @@ The central management screen showing: - **Header card**: Repeater name, short public key, path label, GPS coordinates (if known) - **Battery chemistry selector**: NMC / LiFePO4 / LiPo (saved per repeater) -- **Management tool cards** (full-width cards with chevron arrows, not a grid). Title dynamically shows "Repeater Management" or "Room Management" based on contact type: +- **Management tool cards** (full-width cards with chevron arrows, not a grid). Title dynamically shows "Repeater Management" or "Room Management" (admin) or "Repeater Guest" / "Room Guest" (guest) based on contact type and login result: -| Card | Destination | -|---|---| -| Status | Repeater Status Screen | -| Telemetry | Telemetry Screen | -| CLI | Repeater CLI Screen | -| Neighbors | Neighbors Screen | -| Settings | Repeater Settings Screen | +| Card | Destination | Visibility | +|---|---|---| +| Status | Repeater Status Screen | All users | +| Telemetry | Telemetry Screen | All users | +| CLI | Repeater CLI Screen | Admin only | +| Neighbors | Neighbors Screen | All users | +| Settings | Repeater Settings Screen | Admin only | + +The battery chemistry selector and CLI/Settings cards are hidden from guest users. --- @@ -47,26 +49,28 @@ The central management screen showing: Three information cards: **System Information**: -- Battery percentage -- Uptime -- Queue length -- Error flags +- Battery percentage and voltage (e.g. "85% / 3.95V"), using the battery chemistry set in the hub screen - Clock at login time +- Uptime (days/hours/minutes/seconds) +- Queue length +- Debug flags (error event count) **Radio Statistics**: - Last RSSI and SNR - Noise floor -- TX and RX airtime +- TX airtime and RX airtime **Packet Statistics**: -- Packets sent, received, and duplicates -- Broken down by flood vs. direct +- Packets sent and received, each broken down by flood vs. direct +- Duplicates, broken down by flood vs. direct +- Channel utilization (% of uptime used by TX + RX) ### Key Interactions - Auto-queries the repeater on open; shows a loading spinner until data arrives -- On timeout: red snackbar error. On success: data appears with a green snackbar confirmation -- Pull-to-refresh or refresh button to re-query +- On timeout: red snackbar error. On success: data appears in-place (no extra snackbar) +- Pull-to-refresh or refresh button in the app bar to re-query - Routing mode popup and path management dialog in app bar (these controls appear on **all** management sub-screens, not just Status) +- Accepts both binary `RESP_CODE_STATUS_RESPONSE` frames and legacy JSON text responses --- @@ -76,7 +80,7 @@ A terminal-style interface for sending commands directly to the repeater. ### What the User Sees -- **Quick-command bar** (horizontal scroll): Shortcut buttons for common commands (get name, get radio, get tx, neighbors, ver, advert, clock) +- **Quick-command bar** (horizontal scroll): Shortcut buttons for 9 common commands (advert, get name, get radio, get tx, discover.neighbors, neighbors, ver, clock, clock sync) - **Command history list**: Sent commands in primary color, responses in secondary color - **Input bar**: Up/down history arrows, monospace text field with `> ` prefix, send button @@ -92,9 +96,13 @@ A terminal-style interface for sending commands directly to the repeater. ### Available CLI Commands -**General**: `advert`, `reboot`, `clock`, `password`, `ver`, `clear stats` +The in-app help reference (help icon) documents all known commands. Categories: + +**General**: `advert`, `advert.zerohop`, `reboot`, `clock`, `clock sync`, `password`, `ver`, `clear stats`, `erase`, `poweroff`, `shutdown`, `clkreboot`, `start ota`, `time`, `board`, `discover.neighbors`, `powersaving`, `stats-packets`, `stats-radio`, `stats-core` + +**Get**: `get name`, `get role`, `get public.key`, `get prv.key`, `get repeat`, `get tx`, `get freq`, `get radio`, `get radio.rxgain`, `get af`, `get dutycycle`, `get int.thresh`, `get agc.reset.interval`, `get multi.acks`, `get allow.read.only`, `get advert.interval`, `get flood.advert.interval`, `get guest.password`, `get lat`, `get lon`, `get rxdelay`, `get txdelay`, `get direct.txdelay`, `get flood.max`, `get owner.info`, `get path.hash.mode`, `get loop.detect`, `get acl`, `get bridge.*`, `get adc.multiplier`, `get bootloader.ver` -**Settings**: `set name`, `set af`, `set tx`, `set repeat`, `set allow.read.only`, `set flood.max`, `set int.thresh`, `set agc.reset.interval`, `set multi.acks`, `set advert.interval`, `set flood.advert.interval`, `set guest.password`, `set lat`, `set lon`, `set radio`, `set rxdelay`, `set txdelay`, `set direct.txdelay`, `set bridge.*`, `set adc.multiplier`, `tempradio`, `setperm` +**Set**: `set name`, `set af`, `set tx`, `set repeat`, `set allow.read.only`, `set flood.max`, `set int.thresh`, `set agc.reset.interval`, `set multi.acks`, `set advert.interval`, `set flood.advert.interval`, `set guest.password`, `set lat`, `set lon`, `set freq`, `set radio`, `set rxdelay`, `set txdelay`, `set direct.txdelay`, `set radio.rxgain`, `set dutycycle`, `set loop.detect`, `set path.hash.mode`, `set owner.info`, `set prv.key`, `set bridge.*`, `set adc.multiplier`, `tempradio`, `setperm` **Bridge**: `get bridge.type` @@ -102,9 +110,11 @@ A terminal-style interface for sending commands directly to the repeater. **Neighbors**: `neighbors`, `neighbor.remove` -**Region Management**: `region`, `region load/get/put/remove/allowf/denyf/home/save` +**Power Management**: `get pwrmgt.support`, `get pwrmgt.source`, `get pwrmgt.bootreason`, `get pwrmgt.bootmv` -**GPS**: `gps`, `gps on/off/sync/setloc/advert` +**Sensors**: `sensor get {key}` + +**Region Management**: `region`, `region load`, `region get`, `region put`, `region remove`, `region allowf`, `region denyf`, `region home`, `region save`, `region default`, `region list allowed`, `region list denied` --- @@ -147,40 +157,63 @@ A card titled "Repeater's Neighbors - N" listing each neighbor as: ### What the User Sees -Five configuration cards: +Nine configuration cards, each with its own per-field refresh button(s): **1. Basic Settings** - Name field -- Admin password field -- Guest password field +- Admin password field (write-only; always sent when non-empty) +- Guest password field (write-only; always sent when non-empty) **2. Radio Settings** - Frequency (MHz) -- TX Power (dBm) +- TX Power (dBm) — has its own independent refresh button - Bandwidth dropdown (kHz) - Spreading Factor (SF5–SF12) - Coding Rate (4/5–4/8) +- RX Gain boost toggle **3. Location Settings** -- Latitude and longitude fields +- Latitude and longitude fields, each with an independent refresh button **4. Features** -- Packet forwarding toggle -- Guest access toggle +- Packet forwarding toggle (`set repeat`) +- Guest access toggle (`set allow.read.only`) +- Multi-ACKs toggle (`set multi.acks`) +- Auto clock sync after login toggle (local app setting only, not sent to repeater) + +**5. Network Health** +- Loop detection dropdown (off / minimal / moderate / strict; `set loop.detect`) +- Duty cycle slider (1–100%; `set dutycycle`) -**5. Advertisement Settings** +**6. Advertisement Settings** - Local advert interval slider (60–240 minutes) with enable/disable toggle - Flood advert interval slider (3–168 hours) with enable/disable toggle +- Flood max hops slider (0–64; `set flood.max`) + +**7. Owner Info** +- Multi-line text field for operator contact info (`set owner.info`); newlines sent as `|` + +**8. Actions** (one-tap, no save needed) +- Send Advertisement (`advert`) +- Send Zero-Hop Advertisement (`advert.zerohop`) +- Clock Sync (`clock sync`) + +**9. Advanced** (collapsed by default) +- Path hash mode dropdown (0–2; `set path.hash.mode`) +- TX delay field (`set txdelay`) +- Direct TX delay field (`set direct.txdelay`) +- Interference threshold field (`set int.thresh`) +- AGC reset interval slider (0–240s in multiples of 4; `set agc.reset.interval`) -**6. Danger Zone** (red-styled card) -- Reboot repeater -- Erase filesystem (serial-only warning) +**Danger Zone** (red-styled card) +- Reboot repeater (sends `reboot` with confirmation dialog) +- Erase filesystem (serial-only; shows informational snackbar only — no command is sent over the air) ### Key Interactions -- **Settings are NOT auto-fetched on open**. Only name and location are pre-filled from locally cached contact data. You must tap each section's refresh button to fetch live values from the repeater -- TX Power has its own separate refresh button, independent from the main Radio Settings refresh -- Save button appears when changes are detected -- Settings are sent sequentially with 200ms delays between commands (fire-and-forget, no per-command acknowledgment wait) -- Validation prevents invalid values (e.g., frequency range, LoRa parameter compatibility) +- **Settings are NOT auto-fetched on open**. Name is pre-filled from cached contact data. Each section has its own refresh button to fetch live values from the repeater +- TX Power, RX Gain, latitude, longitude, and advanced fields each have independent inline refresh buttons +- Save button in app bar appears when any change is detected; failed commands keep those fields dirty for retry +- Settings are sent sequentially with 200ms delays between commands; firmware responses are checked and partial failures are reported in a snackbar +- Some changes (e.g. radio frequency) require a reboot; the firmware response triggers an orange "reboot needed" snackbar - Advertisement interval sliders reset to defaults when re-enabled (local: 60 min, flood: 3 hours) -- **Erase Filesystem** does NOT send any command over the air — tapping it only shows a snackbar explaining the operation requires physical serial access. It is effectively non-functional when connected wirelessly +- **Erase Filesystem** does NOT send any command over the air — tapping it only shows a snackbar explaining the operation requires physical serial access diff --git a/documentation/scanner-and-connection.md b/documentation/scanner-and-connection.md index 2c5dbae..080e448 100644 --- a/documentation/scanner-and-connection.md +++ b/documentation/scanner-and-connection.md @@ -51,7 +51,7 @@ Note: The weak (-80 to -90 dBm) and poor (< -90 dBm) tiers share the same icon s ### How Scanning Works -- Filters for devices with names starting with `MeshCore-` or `Whisper-` +- Filters for devices with names starting with one of the known prefixes: `MeshCore-`, `Whisper-`, `WisCore-`, `Seeed`, `Lilygo`, `HT-`, `LowMesh_MC_` - Uses low-latency scan mode on Android - Scans for 10 seconds then auto-stops - On iOS/macOS, waits for BLE adapter initialization before starting @@ -61,7 +61,7 @@ Note: The weak (-80 to -90 dBm) and poor (< -90 dBm) tiers share the same icon s Tap a device tile or its Connect button: 1. The connector stops scanning and transitions to "connecting" -2. Connects to the device with a 15-second timeout +2. Connects to the device with a 15-second timeout (6 seconds on Linux) 3. Requests MTU 185 bytes for optimal throughput 4. Discovers BLE services and locates the Nordic UART Service 5. Subscribes to TX notifications for receiving data diff --git a/documentation/settings.md b/documentation/settings.md index 70e39e2..74e8c93 100644 --- a/documentation/settings.md +++ b/documentation/settings.md @@ -46,7 +46,7 @@ A dedicated sub-screen for app-level preferences (nothing here is sent to the de ### Appearance - **Theme**: System / Light / Dark -- **Language**: System default or one of 15 languages (English, French, Spanish, German, Polish, Slovenian, Portuguese, Italian, Chinese, Swedish, Dutch, Slovak, Bulgarian, Russian, Ukrainian) +- **Language**: System default or one of 18 languages (English, French, Spanish, German, Polish, Slovenian, Portuguese, Italian, Chinese, Swedish, Dutch, Slovak, Bulgarian, Russian, Ukrainian, Hungarian, Japanese, Korean) - **Enable Message Tracing**: Shows path trace overlays and extra metadata on messages ### Notifications @@ -57,6 +57,7 @@ A dedicated sub-screen for app-level preferences (nothing here is sent to the de ### Messaging - **Clear Path on Max Retry**: Erases the stored routing path after all retries fail +- **Jump to Oldest Unread**: When opening a chat, scrolls to the oldest unread message instead of the newest - **Auto Route Rotation**: Enables weighted routing algorithm. When enabled, expands to show five slider sub-settings (hidden when off): - Max Route Weight (1–10, default 5, integer steps) - Initial Route Weight (0.5–5.0, default 3.0) @@ -67,6 +68,15 @@ A dedicated sub-screen for app-level preferences (nothing here is sent to the de ### Battery - **Battery Chemistry**: NMC / LiFePO4 / LiPo (per device, used to calibrate percentage from voltage) +### Translation +Not shown on web. Controls on-device message translation powered by a locally-downloaded ML model: +- **Enable Translation**: Translates incoming messages into the selected target language +- **Translate Composer**: Translates outgoing messages from the target language back before sending +- **Target Language**: Language to translate into (searchable list; defaults to the app language) +- **Downloaded Model**: Dropdown to select among already-downloaded translation models +- **Preset Model**: Download a curated preset model with one tap +- **Custom Model URL**: Enter a URL to download a custom GGUF-format model; shows download progress and a cancel button + ### Map Display - **Show Repeaters**: Toggle repeater markers on map - **Show Chat Nodes**: Toggle chat node markers @@ -91,7 +101,7 @@ These settings are sent directly to the connected device firmware. ### Radio Settings Opens a dialog pre-populated with the device's current radio settings. Contains: -- **Preset dropdown**: 19 regional presets — selecting a preset immediately fills all fields below. Full list: Australia, Australia (Narrow), Australia SA/WA/QLD, Czech Republic, EU 433MHz, EU/UK (Long Range), EU/UK (Medium Range), EU/UK (Narrow), New Zealand, New Zealand (Narrow), Portugal 433, Portugal 869, Switzerland, USA Arizona, USA/Canada, Vietnam, Off-Grid 433, Off-Grid 869, Off-Grid 918 +- **Preset dropdown**: 19 regional presets — selecting a preset immediately fills all fields below. Full list: Australia, Australia (Narrow), Australia SA, WA, QLD, Czech Republic, EU 433MHz, EU/UK (Long Range), EU/UK (Medium Range), EU/UK (Narrow), New Zealand, New Zealand (Narrow), Portugal 433, Portugal 869, Switzerland, USA Arizona, USA/Canada, Vietnam, Off-Grid 433, Off-Grid 869, Off-Grid 918 - **Frequency** (MHz): Free text, validated 300–2500 MHz - **Bandwidth**: Dropdown (7.8 / 10.4 / 15.6 / 20.8 / 31.25 / 41.7 / 62.5 / 125 / 250 / 500 kHz) - **Spreading Factor**: SF5–SF12 diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index b432277..538ee38 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -16,6 +16,7 @@ import '../models/message.dart'; import '../models/path_selection.dart'; import '../models/translation_support.dart'; import '../helpers/reaction_helper.dart'; +import '../helpers/cyr2lat.dart'; import '../helpers/smaz.dart'; import '../services/app_debug_log_service.dart'; import '../services/ble_debug_log_service.dart'; @@ -165,6 +166,8 @@ class MeshCoreConnector extends ChangeNotifier { Timer? _selfInfoRetryTimer; Timer? _reconnectTimer; Timer? _batteryPollTimer; + Timer? _gpsLocationPollTimer; + static const _gpsLocationPollInterval = Duration(minutes: 1); Timer? _radioStatsPollTimer; int _radioStatsPollRefCount = 0; final ValueNotifier radioStatsNotifier = @@ -252,6 +255,11 @@ class MeshCoreConnector extends ChangeNotifier { Future _pathOpLock = Future.value(); Map? _currentCustomVars; + /// Maps repeater pubkey-prefix hex (12 hex chars = first 6 bytes) → the + /// repeater's RTC clock at the moment of the most recent successful login. + /// Reported by firmware in the login-success push frame at byte offset 8. + final Map _repeaterLoginClocks = {}; + // Channel syncing state (sequential pattern) bool _isSyncingChannels = false; bool _channelSyncInFlight = false; @@ -283,9 +291,13 @@ class MeshCoreConnector extends ChangeNotifier { final UnreadStore _unreadStore = UnreadStore(); List _cachedChannels = []; final Map _channelSmazEnabled = {}; + final Map _channelCyr2LatEnabled = {}; + final Map _channelCyr2LatProfileId = {}; bool _lastSentWasCliCommand = false; // Track if last sent message was a CLI command final Map _contactSmazEnabled = {}; + final Map _contactCyr2LatEnabled = {}; + final Map _contactCyr2LatProfileId = {}; final Set _knownContactKeys = {}; final Map _contactUnreadCount = {}; final Map _repeaterBatterySnapshots = {}; @@ -399,6 +411,17 @@ class MeshCoreConnector extends ChangeNotifier { int get advertLocationPolicy => _advertLocPolicy; int get multiAcks => _multiAcks; bool? get clientRepeat => _clientRepeat; + + /// Returns the repeater's RTC clock at the time of the most recent + /// successful login, looked up by the contact's full public key. + /// Returns null if no login response has been observed for this repeater + /// since connection. + DateTime? repeaterClockAtLogin(Uint8List publicKey) { + if (publicKey.length < 6) return null; + final prefix = pubKeyToHex(publicKey.sublist(0, 6)); + return _repeaterLoginClocks[prefix]; + } + void rememberNonRepeatRadioState(MeshCoreRadioStateSnapshot snapshot) { _rememberedNonRepeatRadioState = snapshot; } @@ -607,6 +630,20 @@ class MeshCoreConnector extends ChangeNotifier { _ensureContactSmazSettingLoaded(contactKeyHex); } + bool isChannelCyr2LatEnabled(int channelIndex) { + _ensureChannelCyr2LatSettingLoaded(channelIndex); + return _channelCyr2LatEnabled[channelIndex] ?? false; + } + + bool isContactCyr2LatEnabled(String contactKeyHex) { + _ensureContactCyr2LatSettingLoaded(contactKeyHex); + return _contactCyr2LatEnabled[contactKeyHex] ?? false; + } + + void ensureContactCyr2LatSettingLoaded(String contactKeyHex) { + _ensureContactCyr2LatSettingLoaded(contactKeyHex); + } + Future loadUnreadState() async { _contactUnreadCount ..clear() @@ -658,6 +695,27 @@ class MeshCoreConnector extends ChangeNotifier { } } + void setContactUnreadCount(String contactKeyHex, int count) { + _contactUnreadCount[contactKeyHex] = count; + _unreadStore.saveContactUnreadCount( + Map.from(_contactUnreadCount), + ); + notifyListeners(); + } + + void setChannelUnreadCount(int channelIndex, int count) { + final channel = _findChannelByIndex(channelIndex); + if (channel != null) { + channel.unreadCount = count; + unawaited( + _channelStore.saveChannels( + _channels.isNotEmpty ? _channels : _cachedChannels, + ), + ); + notifyListeners(); + } + } + void markChannelRead(int channelIndex) { final channel = _findChannelByIndex(channelIndex); if (channel != null && channel.unreadCount > 0) { @@ -682,6 +740,10 @@ class MeshCoreConnector extends ChangeNotifier { Future setChannelSmazEnabled(int channelIndex, bool enabled) async { _channelSmazEnabled[channelIndex] = enabled; + if (enabled) { + _channelCyr2LatEnabled[channelIndex] = false; + await _channelSettingsStore.saveCyr2LatEnabled(channelIndex, false); + } await _channelSettingsStore.saveSmazEnabled(channelIndex, enabled); notifyListeners(); } @@ -692,6 +754,25 @@ class MeshCoreConnector extends ChangeNotifier { notifyListeners(); } + Future setChannelCyr2LatEnabled(int channelIndex, bool enabled) async { + _channelCyr2LatEnabled[channelIndex] = enabled; + if (enabled) { + _channelSmazEnabled[channelIndex] = false; + await _channelSettingsStore.saveSmazEnabled(channelIndex, false); + } + await _channelSettingsStore.saveCyr2LatEnabled(channelIndex, enabled); + notifyListeners(); + } + + Future setContactCyr2LatEnabled( + String contactKeyHex, + bool enabled, + ) async { + _contactCyr2LatEnabled[contactKeyHex] = enabled; + await _contactSettingsStore.saveCyr2LatEnabled(contactKeyHex, enabled); + notifyListeners(); + } + Future _loadChannelOrder() async { _channelOrder = await _channelOrderStore.loadChannelOrder(); _applyChannelOrder(); @@ -828,6 +909,7 @@ class MeshCoreConnector extends ChangeNotifier { ..addAll(cached); for (final contact in cached) { _ensureContactSmazSettingLoaded(contact.publicKeyHex); + _ensureContactCyr2LatSettingLoaded(contact.publicKeyHex); } } @@ -840,9 +922,12 @@ class MeshCoreConnector extends ChangeNotifier { Future loadChannelSettings({int? maxChannels}) async { _channelSmazEnabled.clear(); + _channelCyr2LatEnabled.clear(); final channelCount = maxChannels ?? _maxChannels; for (int i = 0; i < channelCount; i++) { _channelSmazEnabled[i] = await _channelSettingsStore.loadSmazEnabled(i); + _channelCyr2LatEnabled[i] = await _channelSettingsStore + .loadCyr2LatEnabled(i); } } @@ -2140,6 +2225,7 @@ class MeshCoreConnector extends ChangeNotifier { return; } _bleInitialSyncStarted = true; + _pendingInitialContactsSync = true; await _requestDeviceInfo(); _startBatteryPolling(); @@ -2399,6 +2485,25 @@ class MeshCoreConnector extends ChangeNotifier { _batteryPollTimer = null; } + /// Start polling the radio's GPS-backed self-info every minute. + /// No-op if already running. Triggered when the radio reports `gps=1`. + void _startGpsLocationPolling() { + if (_gpsLocationPollTimer != null) return; + _gpsLocationPollTimer = Timer.periodic(_gpsLocationPollInterval, (timer) { + if (!isConnected) { + timer.cancel(); + _gpsLocationPollTimer = null; + return; + } + unawaited(sendFrame(buildAppStartFrame())); + }); + } + + void _stopGpsLocationPolling() { + _gpsLocationPollTimer?.cancel(); + _gpsLocationPollTimer = null; + } + void setPollingInterval(int i) { _pollingInterval = i.clamp(1, 60); if (isConnected) { @@ -2994,13 +3099,7 @@ class MeshCoreConnector extends ChangeNotifier { _pendingChannelSentQueue.add(message.messageId); notifyListeners(); - final trimmed = text.trim(); - final isStructuredPayload = - trimmed.startsWith('g:') || trimmed.startsWith('m:'); - final outboundText = - (isChannelSmazEnabled(channel.index) && !isStructuredPayload) - ? Smaz.encodeIfSmaller(text) - : text; + final outboundText = prepareChannelOutboundText(channel.index, text); await _waitForRadioQuiet(lastInboundRxTime: _lastChannelMsgRxTime); await sendFrame( buildSendChannelTextMsgFrame(channel.index, outboundText), @@ -3242,6 +3341,18 @@ class MeshCoreConnector extends ChangeNotifier { Future setCustomVar(String value) async { if (!isConnected) return; await sendFrame(buildSetCustomVarFrame(value)); + final sep = value.indexOf(':'); + if (sep > 0) { + final key = value.substring(0, sep); + final val = value.substring(sep + 1); + (_currentCustomVars ??= {})[key] = val; + notifyListeners(); + } + if (value == 'gps:1') { + _startGpsLocationPolling(); + } else if (value == 'gps:0') { + _stopGpsLocationPolling(); + } } Future sendSelfAdvert({bool flood = true}) async { @@ -3549,6 +3660,8 @@ class MeshCoreConnector extends ChangeNotifier { _handlePathUpdated(frame); break; case pushCodeLoginSuccess: + _handleLoginSuccess(frame); + break; case pushCodeLoginFail: case pushCodeStatusResponse: break; @@ -3675,6 +3788,14 @@ class MeshCoreConnector extends ChangeNotifier { _usbManager.updateConnectedLabel(selfName); } + // GPS poll responses arrive as RESP_CODE_SELF_INFO but are not the real + // handshake — only update location and notify, skip store reloads and + // contact sync which would clear and re-fetch contacts every minute. + if (!wasAwaitingSelfInfo) { + notifyListeners(); + return; + } + //set all the stores' public key so they can load the correct data _channelMessageStore.setPublicKeyHex = selfPublicKeyHex; _messageStore.setPublicKeyHex = selfPublicKeyHex; @@ -3701,12 +3822,6 @@ class MeshCoreConnector extends ChangeNotifier { _selfInfoRetryTimer = null; notifyListeners(); - if (PlatformInfo.isWeb && - _activeTransport == MeshCoreTransportType.bluetooth && - !wasAwaitingSelfInfo) { - return; - } - // Auto-fetch contacts after getting self info. On web BLE, defer this // until after channel 0 so startup writes stay serialized. if (PlatformInfo.isWeb && @@ -4003,7 +4118,7 @@ class MeshCoreConnector extends ChangeNotifier { ); } else { appLogger.info( - "Discovered contact ${contact.name} (type ${contact.typeLabel}) not added due to auto-add settings", + "Discovered contact ${contact.name} (type ${contact.typeLabelRaw}) not added due to auto-add settings", tag: 'Connector', ); return; @@ -4025,7 +4140,7 @@ class MeshCoreConnector extends ChangeNotifier { if (settings.notificationsEnabled && settings.notifyOnNewAdvert) { _notificationService.showAdvertNotification( contactName: contact.name, - contactType: contact.typeLabel, + contactType: contact.typeLabelRaw, contactId: contact.publicKeyHex, ); } @@ -4100,7 +4215,7 @@ class MeshCoreConnector extends ChangeNotifier { if (settings.notificationsEnabled && settings.notifyOnNewAdvert) { _notificationService.showAdvertNotification( contactName: contact.name, - contactType: contact.typeLabel, + contactType: contact.typeLabelRaw, contactId: contact.publicKeyHex, ); } @@ -4123,7 +4238,9 @@ class MeshCoreConnector extends ChangeNotifier { if (_contacts.isEmpty) return 0; var latest = 0; for (final contact in _contacts) { - final seconds = contact.lastSeen.millisecondsSinceEpoch ~/ 1000; + // prefer lastmod per spec, fallback to lastseen + final source = contact.lastModified ?? contact.lastSeen; + final seconds = source.millisecondsSinceEpoch ~/ 1000; if (seconds > latest) { latest = seconds; } @@ -4438,6 +4555,72 @@ class MeshCoreConnector extends ChangeNotifier { }); } + void _ensureContactCyr2LatSettingLoaded(String contactKeyHex) { + if (_contactCyr2LatEnabled.containsKey(contactKeyHex)) return; + _contactSettingsStore.loadCyr2LatEnabled(contactKeyHex).then((enabled) { + if (_contactCyr2LatEnabled[contactKeyHex] == enabled) return; + _contactCyr2LatEnabled[contactKeyHex] = enabled; + notifyListeners(); + }); + } + + void _ensureContactCyr2LatProfileLoaded(String contactKeyHex) { + if (_contactCyr2LatProfileId.containsKey(contactKeyHex)) return; + _contactSettingsStore.loadCyr2LatProfileId(contactKeyHex).then((profileId) { + if (_contactCyr2LatProfileId[contactKeyHex] == profileId) return; + _contactCyr2LatProfileId[contactKeyHex] = profileId; + notifyListeners(); + }); + } + + void _ensureChannelCyr2LatSettingLoaded(int channelIndex) { + if (_channelCyr2LatEnabled.containsKey(channelIndex)) return; + _channelSettingsStore.loadCyr2LatEnabled(channelIndex).then((enabled) { + if (_channelCyr2LatEnabled[channelIndex] == enabled) return; + _channelCyr2LatEnabled[channelIndex] = enabled; + notifyListeners(); + }); + } + + void _ensureChannelCyr2LatProfileLoaded(int channelIndex) { + if (_channelCyr2LatProfileId.containsKey(channelIndex)) return; + _channelSettingsStore.loadCyr2LatProfileId(channelIndex).then((profileId) { + if (_channelCyr2LatProfileId[channelIndex] == profileId) return; + _channelCyr2LatProfileId[channelIndex] = profileId; + notifyListeners(); + }); + } + + String? getChannelCyr2LatProfileId(int channelIndex) { + _ensureChannelCyr2LatProfileLoaded(channelIndex); + return _channelCyr2LatProfileId[channelIndex]; + } + + Future setChannelCyr2LatProfileId( + int channelIndex, + String? profileId, + ) async { + if (_channelCyr2LatProfileId[channelIndex] == profileId) return; + _channelCyr2LatProfileId[channelIndex] = profileId; + await _channelSettingsStore.saveCyr2LatProfileId(channelIndex, profileId); + notifyListeners(); + } + + String? getContactCyr2LatProfileId(String contactKeyHex) { + _ensureContactCyr2LatProfileLoaded(contactKeyHex); + return _contactCyr2LatProfileId[contactKeyHex]; + } + + Future setContactCyr2LatProfileId( + String contactKeyHex, + String? profileId, + ) async { + if (_contactCyr2LatProfileId[contactKeyHex] == profileId) return; + _contactCyr2LatProfileId[contactKeyHex] = profileId; + await _contactSettingsStore.saveCyr2LatProfileId(contactKeyHex, profileId); + notifyListeners(); + } + /// Prepares contact outbound text by applying SMAZ encoding if enabled. /// This should be used to transform text before computing ACK hashes. String prepareContactOutboundText(Contact contact, String text) { @@ -4446,8 +4629,54 @@ class MeshCoreConnector extends ChangeNotifier { trimmed.startsWith('g:') || trimmed.startsWith('m:') || trimmed.startsWith('V1|'); - if (!isStructuredPayload && isContactSmazEnabled(contact.publicKeyHex)) { - return Smaz.encodeIfSmaller(text); + if (!isStructuredPayload) { + if (isContactSmazEnabled(contact.publicKeyHex)) { + return Smaz.encodeIfSmaller(text); + } else if (isContactCyr2LatEnabled(contact.publicKeyHex)) { + final profileId = getContactCyr2LatProfileId(contact.publicKeyHex); + final profile = profileId != null && _appSettingsService != null + ? _appSettingsService!.getCyr2LatProfileById(profileId) + : null; + if (profile != null) { + Cyr2Lat.setCharMap(profile.charMap); + } else { + // Use global profile + final globalProfile = _appSettingsService + ?.getSelectedCyr2LatProfile(); + if (globalProfile != null) { + Cyr2Lat.setCharMap(globalProfile.charMap); + } + } + return Cyr2Lat.encode(text); + } + } + return text; + } + + String prepareChannelOutboundText(int channelIndex, String text) { + final trimmed = text.trim(); + final isStructuredPayload = + trimmed.startsWith('g:') || trimmed.startsWith('m:'); + if (!isStructuredPayload) { + if (isChannelSmazEnabled(channelIndex)) { + return Smaz.encodeIfSmaller(text); + } else if (isChannelCyr2LatEnabled(channelIndex)) { + final profileId = getChannelCyr2LatProfileId(channelIndex); + final profile = profileId != null && _appSettingsService != null + ? _appSettingsService!.getCyr2LatProfileById(profileId) + : null; + if (profile != null) { + Cyr2Lat.setCharMap(profile.charMap); + } else { + // Use global profile + final globalProfile = _appSettingsService + ?.getSelectedCyr2LatProfile(); + if (globalProfile != null) { + Cyr2Lat.setCharMap(globalProfile.charMap); + } + } + return Cyr2Lat.encode(text); + } } return text; } @@ -5496,6 +5725,7 @@ class MeshCoreConnector extends ChangeNotifier { void _handleDisconnection() { _stopBatteryPolling(); + _stopGpsLocationPolling(); _stopRadioStatsPolling(); _latestRadioStats = null; radioStatsNotifier.value = null; @@ -5581,10 +5811,35 @@ class MeshCoreConnector extends ChangeNotifier { return result; } + /// Parse PUSH_CODE_LOGIN_SUCCESS (0x85) frame and stash the repeater's + /// reported clock. Frame layout (firmware companion_radio/MyMesh.cpp:678+): + /// [0]=0x85, [1]=permissions, [2..7]=pubkey prefix (6 bytes), + /// [8..11]=repeater RTC unix seconds (LE), [12]=ACL perms, [13]=fw level + /// The timestamp is only present in the v7+ "new login response" — older + /// firmware emits a shorter frame that we silently skip. + void _handleLoginSuccess(Uint8List frame) { + if (frame.length < 12) return; + final prefix = pubKeyToHex(frame.sublist(2, 8)); + final ts = ByteData.sublistView(frame, 8, 12).getUint32(0, Endian.little); + if (ts == 0) return; + _repeaterLoginClocks[prefix] = DateTime.fromMillisecondsSinceEpoch( + ts * 1000, + isUtc: true, + ); + notifyListeners(); + } + void _handleCustomVars(Uint8List frame) { final buf = BufferReader(frame.sublist(1)); try { _currentCustomVars = _parseKeyValueString(buf.readCString()); + // Reflect current GPS state in the polling timer (handles initial + // device state on connect as well as external CLI/USB toggles). + if (_currentCustomVars?['gps'] == '1') { + _startGpsLocationPolling(); + } else { + _stopGpsLocationPolling(); + } } catch (e) { appLogger.warn('Malformed custom vars frame: $e', tag: 'Connector'); } @@ -5640,6 +5895,7 @@ class MeshCoreConnector extends ChangeNotifier { _notifyListenersTimer?.cancel(); _reconnectTimer?.cancel(); _batteryPollTimer?.cancel(); + _gpsLocationPollTimer?.cancel(); _radioStatsPollTimer?.cancel(); radioStatsNotifier.dispose(); _receivedFramesController.close(); @@ -6021,7 +6277,7 @@ class MeshCoreConnector extends ChangeNotifier { if (settings.notificationsEnabled && settings.notifyOnNewAdvert) { _notificationService.showAdvertNotification( contactName: contact.name, - contactType: contact.typeLabel, + contactType: contact.typeLabelRaw, contactId: contact.publicKeyHex, ); } diff --git a/lib/connector/meshcore_protocol.dart b/lib/connector/meshcore_protocol.dart index 396d78b..f55e968 100644 --- a/lib/connector/meshcore_protocol.dart +++ b/lib/connector/meshcore_protocol.dart @@ -320,7 +320,7 @@ const int maxPathSize = 64; const int pathHashSize = 1; const int maxNameSize = 32; const int maxFrameSize = 172; -const int appProtocolVersion = 3; +const int appProtocolVersion = 4; // Matches firmware MAX_TEXT_LEN (10 * CIPHER_BLOCK_SIZE). const int maxTextPayloadBytes = 160; const int _sendTextMsgOverheadBytes = @@ -720,25 +720,19 @@ Uint8List buildUpdateContactPathFrame( final timestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000; writer.writeUInt32LE(timestamp); - if ((lat == null || lon == null) && lastModified != null) { - // If lat/lon not provided, write zeros - writer.writeInt32LE(0); - writer.writeInt32LE(0); - } else { - // Latitude and Longitude are expected in degrees, convert to int by multiplying by 1e6 - // Latitude - final latitude = lat ?? 0.0; - writer.writeInt32LE((latitude * 1e6).round()); - - // Longitude - final longitude = lon ?? 0.0; - writer.writeInt32LE((longitude * 1e6).round()); - } - - if (lastModified != null) { - // Last modified - final lastModifiedTimestamp = lastModified.millisecondsSinceEpoch ~/ 1000; - writer.writeUInt32LE(lastModifiedTimestamp); + // Optional [Lat x4, Lon x4][timestamp x4] tail per the doc comment above. + // Emit 8 bytes of position (zero-filled when only lastModified is provided) + // followed by an optional 4-byte timestamp. Earlier code emitted the + // position block twice, which corrupted the tail and caused the firmware + // to parse the second lat as the timestamp. See #427. + final hasLocation = lat != null && lon != null; + if (hasLocation || lastModified != null) { + writer.writeInt32LE(hasLocation ? (lat * 1e6).round() : 0); + writer.writeInt32LE(hasLocation ? (lon * 1e6).round() : 0); + if (lastModified != null) { + final lastModifiedTimestamp = lastModified.millisecondsSinceEpoch ~/ 1000; + writer.writeUInt32LE(lastModifiedTimestamp); + } } return writer.toBytes(); diff --git a/lib/helpers/chat_scroll_controller.dart b/lib/helpers/chat_scroll_controller.dart index d2c73fb..c0d1974 100644 --- a/lib/helpers/chat_scroll_controller.dart +++ b/lib/helpers/chat_scroll_controller.dart @@ -49,6 +49,25 @@ class ChatScrollController extends ScrollController { } } + /// Jumps toward an off-screen message so that lazy ListView.builder builds + /// items near it. Only visible + cacheExtent items have real heights, so we + /// use proportion of maxScrollExtent (itself an estimate from built items' + /// avg height). Call [onJumped] on the next frame to ensureVisible/scroll + /// to the exact target. + void jumpToEstimatedOffset({ + required int unreadCount, + required int totalMessages, + required VoidCallback onJumped, + }) { + if (!hasClients || totalMessages == 0) return; + final maxExtent = position.maxScrollExtent; + final jumpOffset = maxExtent * (unreadCount / totalMessages); + if (jumpOffset > 100) { + jumpTo(jumpOffset); + } + WidgetsBinding.instance.addPostFrameCallback((_) => onJumped()); + } + void scrollToBottomIfAtBottom() { // Only scroll if jump button is NOT showing (i.e., already at bottom) if (!showJumpToBottom.value && hasClients && position.maxScrollExtent > 0) { diff --git a/lib/helpers/cyr2lat.dart b/lib/helpers/cyr2lat.dart new file mode 100644 index 0000000..a7ec5dd --- /dev/null +++ b/lib/helpers/cyr2lat.dart @@ -0,0 +1,63 @@ +class Cyr2Lat { + static Map _charMap = { + 'А': 'A', + 'В': 'B', + 'Е': 'E', + 'Ё': 'E', + 'З': '3', + 'К': 'K', + 'М': 'M', + 'Н': 'H', + 'О': 'O', + 'Р': 'P', + 'С': 'C', + 'Т': 'T', + 'Х': 'X', + 'Ь': 'b', + 'а': 'a', + 'е': 'e', + 'ё': 'e', + 'о': 'o', + 'р': 'p', + 'с': 'c', + 'у': 'y', + 'х': 'x', + }; + + static final RegExp _prefixRegExp = RegExp(r'\@\[[\S\s]+\] '); + + static void setCharMap(Map charMap) { + _charMap = Map.from(charMap); + } + + static String encode(String text) { + if (text.isEmpty) return text; + final buffer = StringBuffer(); + + final senderName = extractSenderName(text); + final msgText = removeSenderName(text); + + for (final rune in msgText.runes) { + final char = String.fromCharCode(rune); + buffer.write(_charMap[char] ?? char); + } + + return senderName + buffer.toString(); + } + + static String removeSenderName(String text) { + final match = _prefixRegExp.matchAsPrefix(text); + if (match != null) { + return text.substring(match.end); + } + return text; + } + + static String extractSenderName(String text) { + final match = _prefixRegExp.matchAsPrefix(text); + if (match != null) { + return match.group(0) ?? ''; + } + return ''; + } +} diff --git a/lib/helpers/utf8_length_limiter.dart b/lib/helpers/utf8_length_limiter.dart index c6acdd2..4188ec6 100644 --- a/lib/helpers/utf8_length_limiter.dart +++ b/lib/helpers/utf8_length_limiter.dart @@ -4,8 +4,14 @@ import 'package:flutter/services.dart'; class Utf8LengthLimitingTextInputFormatter extends TextInputFormatter { final int maxBytes; + final String Function(String)? encoder; - const Utf8LengthLimitingTextInputFormatter(this.maxBytes); + const Utf8LengthLimitingTextInputFormatter(this.maxBytes, {this.encoder}); + + int _effectiveByteLength(String text) { + final effective = encoder != null ? encoder!(text) : text; + return utf8.encode(effective).length; + } @override TextEditingValue formatEditUpdate( @@ -13,8 +19,7 @@ class Utf8LengthLimitingTextInputFormatter extends TextInputFormatter { TextEditingValue newValue, ) { if (maxBytes <= 0) return oldValue; - final bytes = utf8.encode(newValue.text); - if (bytes.length <= maxBytes) return newValue; + if (_effectiveByteLength(newValue.text) <= maxBytes) return newValue; final truncated = _truncateToMaxBytes(newValue.text, maxBytes); return TextEditingValue( @@ -25,6 +30,14 @@ class Utf8LengthLimitingTextInputFormatter extends TextInputFormatter { } String _truncateToMaxBytes(String text, int limit) { + if (encoder != null) { + final runes = text.runes.toList(); + while (runes.isNotEmpty && + _effectiveByteLength(String.fromCharCodes(runes)) > maxBytes) { + runes.removeLast(); + } + return String.fromCharCodes(runes); + } final buffer = StringBuffer(); var used = 0; for (final rune in text.runes) { diff --git a/lib/l10n/app_bg.arb b/lib/l10n/app_bg.arb index 7ac5417..45536cf 100644 --- a/lib/l10n/app_bg.arb +++ b/lib/l10n/app_bg.arb @@ -52,7 +52,7 @@ } } }, - "scanner_title": "MeshCore Open", + "scanner_title": "MeshCore – Отворена версия", "scanner_scanning": "Сканиране за устройства...", "scanner_connecting": "Свързвам се...", "scanner_disconnecting": "Изключване...", @@ -104,6 +104,8 @@ "settings_privacyModeEnabled": "Режим на поверителност е активиран", "settings_privacyModeDisabled": "Режим на поверителност е деактивиран", "settings_actions": "Действия", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Изпрати Реклама", "settings_sendAdvertisementSubtitle": "Сега присъствие в ефир", "settings_advertisementSent": "Реклама изпратена", @@ -121,7 +123,7 @@ "settings_appDebugLog": "Лог на отстраняване на грешки на приложението", "settings_appDebugLogSubtitle": "Съобщения за отстраняване на грешки на приложението", "settings_about": "За нас", - "settings_aboutVersion": "MeshCore Open v{version}", + "settings_aboutVersion": "MeshCore Open, версия {version}", "@settings_aboutVersion": { "placeholders": { "version": { @@ -140,7 +142,7 @@ "settings_infoChannelCount": "Брой канали", "settings_presets": "Предварителни настройки", "settings_frequency": "Честота (MHz)", - "settings_frequencyHelper": "300.0 - 2500.0", + "settings_frequencyHelper": "300,0 – 2500,0", "settings_frequencyInvalid": "Невалидна честота (300-2500 MHz)", "settings_bandwidth": "Ширина на честотния спектър", "settings_spreadingFactor": "Фактор на разпространение", @@ -164,18 +166,18 @@ "appSettings_themeDark": "Тъмно", "appSettings_language": "Език", "appSettings_languageSystem": "Система по подразбиране", - "appSettings_languageEn": "English", - "appSettings_languageFr": "Français", - "appSettings_languageEs": "Español", - "appSettings_languageDe": "Deutsch", - "appSettings_languagePl": "Polski", - "appSettings_languageSl": "Slovenščina", - "appSettings_languagePt": "Português", - "appSettings_languageIt": "Italiano", - "appSettings_languageZh": "中文", - "appSettings_languageSv": "Svenska", - "appSettings_languageNl": "Nederlands", - "appSettings_languageSk": "Slovenčina", + "appSettings_languageEn": "Английски", + "appSettings_languageFr": "Френски", + "appSettings_languageEs": "Испански", + "appSettings_languageDe": "Немски", + "appSettings_languagePl": "Полски", + "appSettings_languageSl": "Словенски език", + "appSettings_languagePt": "Португалски", + "appSettings_languageIt": "Италиански", + "appSettings_languageZh": "Китайски", + "appSettings_languageSv": "Шведски", + "appSettings_languageNl": "Хололандски", + "appSettings_languageSk": "Словенски", "appSettings_languageBg": "Български", "appSettings_notifications": "Уведомления", "appSettings_enableNotifications": "Активирай Известия", @@ -337,11 +339,8 @@ } } }, - "channels_hashtagChannel": "Канал с хаштаг", "channels_public": "Публично", "channels_private": "Личен", - "channels_publicChannel": "Публичен канал", - "channels_privateChannel": "Частен канал", "channels_editChannel": "Редактирай канал", "channels_muteChannel": "Заглуши канала", "channels_unmuteChannel": "Включи известията на канала", @@ -367,7 +366,7 @@ "channels_channelName": "Име на канала", "channels_usePublicChannel": "Използвайте публичен канал", "channels_standardPublicPsk": "Стандартен публичен PSK", - "channels_pskHex": "PSK (Hex)", + "channels_pskHex": "PSK (шестнадесетичен код)", "channels_generateRandomPsk": "Генерирай случайна PSK", "channels_enterChannelName": "Моля, въведете име на канал.", "channels_pskMustBe32Hex": "PSK трябва да бъде 32 шестнаредни знака.", @@ -388,6 +387,22 @@ } }, "channels_smazCompression": "Компресия SMAZ", + "channels_cyr2latCompression": "Компресия Cyr2Lat", + "channels_cyr2latCompressionDscr": "Заменя някои кирилични символи с латиница при изпращане.", + "channels_cyr2latSettingsHeading": "Настройки на Cyr2Lat", + "channels_cyr2latSettingsSubheading": "Списък със замествания", + "channels_cyr2latSettingsDscr": "Редактиране на JSON конфигурацията за заместване на символи", + "channels_cyr2latSettingsDialogHint": "JSON карта за замествания", + "channels_cyr2latSettingsDialogWrongJSON": "Неправилен JSON: {error}", + "settings_cyr2latProfileAdd": "Добавяне на профил Cyr2Lat", + "settings_cyr2latProfileName": "Име на профила", + "settings_cyr2latProfileNameEmpty": "Името на профила не може да бъде празно", + "settings_cyr2latProfileAdded": "Профилът е добавен успешно", + "settings_cyr2latProfileUpdated": "Профилът е актуализиран успешно", + "settings_cyr2latProfileEdit": "Редактиране на Cyr2Lat профил", + "settings_cyr2latProfileDelete": "Изтриване на профил Cyr2Lat", + "settings_cyr2latProfileDeleted": "Профилът беше изтрит успешно", + "settings_cyr2latProfileDeleteDscr": "Сигурен ли сте, че искате да изтриете профила \"{name}\"?", "channels_channelUpdated": "Каналът \"{name}\" е актуализиран", "@channels_channelUpdated": { "placeholders": { @@ -399,7 +414,7 @@ "channels_publicChannelAdded": "Публичен канал добавен", "channels_sortBy": "Сортирай по", "channels_sortManual": "Ръчно", - "channels_sortAZ": "A-Z", + "channels_sortAZ": "От A до Я", "channels_sortLatestMessages": "Последни съобщения", "channels_sortUnread": "Непрочетено", "chat_noMessages": "Няма съобщения.", @@ -477,7 +492,7 @@ "debugLog_noEntries": "Все още няма дебъг логове.", "debugLog_enableInSettings": "Активирайте отстраняване на грешки в настройките на приложението", "debugLog_frames": "Рамки", - "debugLog_rawLogRx": "Raw Log-RX", + "debugLog_rawLogRx": "Необработен лог-RX", "debugLog_noBleActivity": "Няма BLE активност към момента.", "debugFrame_length": "Дължина на кадъра: {count} байта", "@debugFrame_length": { @@ -531,7 +546,7 @@ } } }, - "debugFrame_textTypeCli": "CLI", + "debugFrame_textTypeCli": "Команден ред (CLI)", "debugFrame_textTypePlain": "Просто", "debugFrame_text": "- Текст: \"{text}\"", "@debugFrame_text": { @@ -550,7 +565,7 @@ "chat_pathHistoryFull": "Историята на пътя е пълна. Премахнете записи, за да добавите нови.", "chat_hopSingular": "скочи", "chat_hopPlural": "скоци", - "chat_hopsCount": "{count} {count, plural, =1{hop} other{hops}}", + "chat_hopsCount": "{count} {count, plural, =1{скача} other{скача}}", "@chat_hopsCount": { "placeholders": { "count": { @@ -883,7 +898,7 @@ "repeater_statusSubtitle": "Прегледайте статуса, статистиката и съседните устройства.", "repeater_telemetry": "Телеметрия", "repeater_telemetrySubtitle": "Прегледайте телеметрията на сензорите и системните статистики", - "repeater_cli": "CLI", + "repeater_cli": "Команден ред (CLI)", "repeater_cliSubtitle": "Изпрати команди към ретранслатора", "repeater_settings": "Настройки", "repeater_settingsSubtitle": "Конфигурирайте параметрите на репитера", @@ -1059,6 +1074,81 @@ }, "repeater_confirm": "БеПотвърди", "repeater_settingsSaved": "Настройките са запазени успешно.", + "repeater_rxGain": "Увеличен коефициент на възвръщаемост (RX)", + "repeater_rxGainHelper": "По-висока чувствителност, по-голям ток (само за SX1262/SX1268)", + "repeater_refreshRxGain": "Възстановете повишената ефективност на RX", + "repeater_multiAcks": "Множество потвърждения", + "repeater_multiAcksSubtitle": "Признавайте съобщения по множество канали за по-добро доставяне.", + "repeater_refreshMultiAcks": "Обновете множество потвърждения", + "repeater_networkHealth": "Състояние на мрежата", + "repeater_loopDetect": "Откриване на цикли", + "repeater_loopDetectHelper": "Изпратете пакети, които изглеждат като цикли в маршрутизацията.", + "repeater_loopDetectOff": "Изключено", + "repeater_loopDetectMinimal": "Минимален", + "repeater_loopDetectModerate": "Умерен", + "repeater_loopDetectStrict": "Строг", + "repeater_dutyCycle": "Цикъл на работа/почивка", + "repeater_dutyCycleHelper": "Максимален процент на използване на времето на въздуха", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Информация за оператора", + "repeater_ownerInfoHelper": "Публични метаданни за този репитер", + "repeater_refreshOwnerInfo": "Обновете информацията за оператора", + "repeater_floodMax": "Максимален брой скачания при наводнение", + "repeater_floodMaxHelper": "Максималният брой пакети, които един поток може да пренесе (0-64)", + "repeater_advancedSettings": "Напреднал", + "repeater_advancedSettingsSubtitle": "Регулаторни копчета за опитни оператори", + "repeater_pathHashMode": "Режим за хеширане на пътища", + "repeater_pathHashModeHelper": "Байтовете, използвани за кодиране на идентификатора на този репитер в таговете за откриване на потоци/цикли, са: 0=1 байт (256 идентификатора, до 64 скача), 1=2 байта (65 000 идентификатора, до 32 скача), 2=3 байта (16 милиона идентификатора, до 21 скача). Версии 1.13 и по-стари версии на фърмуера използват многобайтови пътища – само след като мрежата е актуализирана до версия 1.14 или по-нова.", + "repeater_txDelay": "Забавяне на проекта \"Flood TX\"", + "repeater_txDelayHelper": "Предавайте разстоянието между пакетите за трафик при наводнения, като множител на времето за пренос на пакета (0-2, по подразбиране 0.5). По-висока стойност означава по-малко сблъсъци, но по-бавно предаване.", + "repeater_directTxDelay": "Директно забавяне на сигнала", + "repeater_directTxDelayHelper": "Предаване на интервали за директен (не-масивен) трафик, като множител на времето за пренос на пакета (0-2, по подразбиране 0.3).", + "repeater_intThresh": "Праг на интерференция", + "repeater_intThreshHelper": "Прагът е зададен на нивото на шума на радиото, така че да отхвърля смущения, които са над този праг. 0 – изключва; активирайте само, ако забележите грешки в шумна честотна лента.", + "repeater_agcResetInterval": "Интервал за рестартиране на AGC", + "repeater_agcResetIntervalHelper": "Колко често да се рестартира автоматичната настройка на усилването, за да се възстанови от състояние, в което усилването е блокирано. Времето за рестартиране е няколко секунди, като се определя като кратна на 4. 0 деактивира периодичното рестартиране.", + "repeater_actionsTitle": "Действия", + "repeater_sendAdvert": "Изпратете реклама за навод", + "repeater_sendAdvertSubtitle": "Публикувайте реклама за навод в мрежата.", + "repeater_sendAdvertZeroHop": "Изпратете реклама без преминаване през други системи", + "repeater_sendAdvertZeroHopSubtitle": "Публикувайте реклама, която достига до целевата аудитория само чрез директно разпространение (без използване на посредници).", + "repeater_clockSync": "Синхронизиране на часовника сега", + "repeater_clockSyncSubtitle": "Настройте времето на телефона си да съвпада с времето на репитера.", + "repeater_actionSucceeded": "{action} succeeded", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} failed: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Настройки запаметени – рестартирайте ретранслатора, за да ги приложите.", + "repeater_settingsPartialFailure": "Някои настройки не успяха: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Грешка при запазване на настройките: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1070,11 +1160,9 @@ "repeater_refreshBasicSettings": "Обнови Основни Настройки", "repeater_refreshRadioSettings": "Обнови настройките на радиопредавателите", "repeater_refreshTxPower": "Обнови TX захранване", - "repeater_refreshLocationSettings": "Обнови настройките на местоположението", "repeater_refreshPacketForwarding": "Обнови пакетно пренасочване", "repeater_refreshGuestAccess": "Обнови достъп за гости", "repeater_refreshPrivacyMode": "Обнови Режим на поверителност", - "repeater_refreshAdvertisementSettings": "Обнови Настройки на Рекламата", "repeater_refreshed": "{label} е обновено", "@repeater_refreshed": { "placeholders": { @@ -1347,7 +1435,7 @@ "listFilter_sortBy": "Сортирай по", "listFilter_latestMessages": "Последни съобщения", "listFilter_heardRecently": "Слушано е наскоро", - "listFilter_az": "A-Z", + "listFilter_az": "А-Я", "listFilter_filters": "Филтри", "listFilter_all": "Всички", "listFilter_users": "Потребители", @@ -1922,13 +2010,6 @@ "contact_teleLocSubtitle": "Позволи споделяне на данни за местоположение", "contact_teleLoc": "Местоположение на телеметрията", "contact_teleEnvSubtitle": "Позволи споделяне на данни от средносферните датчици", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_initialRouteWeight": "Първоначална тежест на маршрута", "appSettings_maxRouteWeight": "Максимално допустимо тегло на маршрута", "appSettings_initialRouteWeightSubtitle": "Начално тегло за новооткрити маршрути", @@ -1940,7 +2021,6 @@ "appSettings_maxMessageRetries": "Максимален брой опити за изпращане на съобщение", "appSettings_maxMessageRetriesSubtitle": "Брой опити за повторно изпращане, преди съобщението да бъде маркирано като неуспешно.", "path_routeWeight": "{weight}/{max}", - "settings_multiAck": "Мулти-потвърди: {value}", "settings_telemetryModeUpdated": "Режим на телеметрията е обновен", "map_showOverlaps": "Покриване на ключа на повтаряча", "map_runTraceWithReturnPath": "Върни се по същия път.", @@ -2073,5 +2153,163 @@ "chat_sendMessage": "Изпратете съобщение", "room_guest": "Информация за сървъра на стаята", "repeater_guest": "Информация за ретранслаторите", - "repeater_guestTools": "Инструменти за гости" + "repeater_guestTools": "Инструменти за гости", + "repeater_getCategory": "Получете стойности", + "repeater_powerMgmt": "Управление на енергията", + "repeater_sensors": "Датчици", + "repeater_cliHelpPowerOff": "Изключва устройството. (не се очаква отговор)", + "repeater_cliHelpClkReboot": "Възстановява часовника до известна историческа дата и рестартира устройството.", + "repeater_cliHelpAdvertZeroHop": "Изпраща реклама, която достига само до съседни устройства (само до съседни мрежи).", + "repeater_cliHelpStartOta": "Стартира актуализация на фърмуера чрез въздушното, на всички поддържани платки.", + "repeater_cliHelpTime": "Задава времето на устройството към зададените секунди от началото на Unix ерата. Времето не може да се върне назад.", + "repeater_cliHelpBoard": "Показва производителя на платката / идентификатора на хардуера.", + "repeater_cliHelpDiscoverNeighbors": "Изпраща заявка за откриване на съседни възли. (Само за устройства тип репитер)", + "repeater_cliHelpPowersaving": "Показва дали режимът за пестене на енергия е активиран или деактивиран.", + "repeater_cliHelpPowersavingOnOff": "Активира или деактивира режима за пестене на енергия (ако е поддържан).", + "repeater_cliHelpErase": "(Само за серийни устройства) Форматира файловата система на устройството. Изтрива всички настройки и контакти.", + "repeater_cliHelpSetDutyCycle": "Задава максимално допустимия процент на използване на времето за предаване (от 1 до 100 процента). Вътрешно коригира фактора за времето на предаване.", + "repeater_cliHelpSetPrvKey": "(Само за серийни номера) Заменя личната част от ключа за идентификация на устройството. Необходимо е да се рестартира устройството, за да се приложи. Генерира нов публичен ключ.", + "repeater_cliHelpSetRadioRxGain": "(Само за SX126x) Превключва усиления на приемния сигнал (RX gain) за подобрена чувствителност при по-високо потребление на ток.", + "repeater_cliHelpSetOwnerInfo": "Задава низовете с информация за контакт на собственика, които са включени в рекламите. Използвайте '|' за нови редове.", + "repeater_cliHelpSetPathHashMode": "Задава режима за хеширане на пътищата. 0 = за стари системи, 1 = за стандартни системи, 2 = за строги системи. Влияе върху начина, по който се съпоставят маршрутите.", + "repeater_cliHelpSetLoopDetect": "Задава чувствителността за откриване на цикли в маршрутизацията: изключена, минимална, умерена или строга.", + "repeater_cliHelpSetFreq": "(Само за серийно управление) Бързо задава само честотата. Необходимо е рестартиране. Препоръчително е да се използват настройките за \"радио\", за да се зададат всички параметри.", + "repeater_cliHelpSetBridgeChannel": "(Само за моста ESPNow) Определя WiFi канала (от 1 до 14), използван от моста.", + "repeater_cliHelpGetName": "Показва зададеното име на възела.", + "repeater_cliHelpGetRole": "Показва ролята на фърмуера (например, репитер, сървър за стая и т.н.).", + "repeater_cliHelpGetPublicKey": "Показва публичния ключ на устройството.", + "repeater_cliHelpGetPrvKey": "(Само за серийния номер) Показва личната ключа на устройството. Трябва да се третира като тайна.", + "repeater_cliHelpGetRepeat": "Показва дали функцията за пренасочване на пакети (ролята на репитер) е активирана или деактивирана.", + "repeater_cliHelpGetTx": "Показва текущата мощност на TX в dBm.", + "repeater_cliHelpGetFreq": "Показва зададената честота в MHz.", + "repeater_cliHelpGetRadio": "Показва пълните радио параметри: честота, ширина на честотния обхват, фактор на разпространение, скорост на кодиране.", + "repeater_cliHelpGetRadioRxGain": "(Само за SX126x) Показва състоянието на усиления сигнал на RX.", + "repeater_cliHelpGetAf": "Показва текущия коефициент на въздействие върху въздуха.", + "repeater_cliHelpGetDutyCycle": "Показва текущия допустим цикъл на работа като процент.", + "repeater_cliHelpGetIntThresh": "Показва прага на интерференцията на канала в децибели (dB).", + "repeater_cliHelpGetAgcResetInterval": "Показва интервала за рестартиране на AGC в секунди.", + "repeater_cliHelpGetMultiAcks": "Показва дали режимът \"двоен ACK\" е активиран (1) или деактивиран (0).", + "repeater_cliHelpGetAllowReadOnly": "Показва дали е разрешено само четене за гостите.", + "repeater_cliHelpGetAdvertInterval": "Показва времето на рекламата в минути.", + "repeater_cliHelpGetFloodAdvertInterval": "Показва интервала на рекламата за навод в часове.", + "repeater_cliHelpGetGuestPassword": "Показва зададения парол за гост.", + "repeater_cliHelpGetLat": "Показва зададената географска ширина.", + "repeater_cliHelpGetLon": "Показва зададената дължина.", + "repeater_cliHelpGetRxDelay": "Показва основната стойност на забавянето на сигнала.", + "repeater_cliHelpGetTxDelay": "Показва коефициента за забавяне при режим на наводняване.", + "repeater_cliHelpGetDirectTxDelay": "Показва коефициента за забавяне при директен режим.", + "repeater_cliHelpGetFloodMax": "Показва максималния брой на повторни наводнения.", + "repeater_cliHelpGetOwnerInfo": "Показва информацията за контакт на собственика.", + "repeater_cliHelpGetPathHashMode": "Показва режима на хеширане на пътя (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Показва чувствителността към откриване на цикли.", + "repeater_cliHelpGetAcl": "(Само за серийни номера) Изброява настройките за контрол на достъпа в репитера.", + "repeater_cliHelpGetBridgeEnabled": "Показва дали мостът е активиран.", + "repeater_cliHelpGetBridgeDelay": "Показва забавянето на моста в милисекунди.", + "repeater_cliHelpGetBridgeSource": "Показва дали мостът изпраща или получава пакети RX или TX.", + "repeater_cliHelpGetBridgeBaud": "(Само за мост RS232) Показва скоростта на предаване на данните на моста.", + "repeater_cliHelpGetBridgeChannel": "(Само за моста ESPNow) Показва канала на WiFi на моста.", + "repeater_cliHelpGetBridgeSecret": "(Само за моста ESPNow) Показва споделения секрет на моста.", + "repeater_cliHelpGetBootloaderVer": "(Само за NRF52) Показва версията на зареждащия софтуер.", + "repeater_cliHelpGetAdcMultiplier": "Показва множителя на аналоговия-цифров преобразувател (мащабиране на напрежението от батерията).", + "repeater_cliHelpGetPwrMgtSupport": "Описва дали борда на директорите има поддръжка за управление на захранването.", + "repeater_cliHelpGetPwrMgtSource": "Показва текущия източник на захранване: външен или батерия.", + "repeater_cliHelpGetPwrMgtBootReason": "Показва най-скорошните причини за рестартиране и изключване.", + "repeater_cliHelpGetPwrMgtBootMv": "Показва напрежението на батерията при стартиране, измерено в миливолта (mV).", + "repeater_cliHelpSensorGet": "Чете персонализирана настройка на сензор чрез клавиш.", + "repeater_cliHelpSensorSet": "Създава персонализирана настройка за сензор.", + "repeater_cliHelpSensorList": "Показва всички настройки на потребителските сензори, разделени на страници, започвайки от опционален индекс.", + "repeater_cliHelpRegionDefault": "Показва текущия обхват на региона по подразбиране.", + "repeater_cliHelpRegionDefaultSet": "Задава обхвата на региона по подразбиране. Използвайте \"\", за да го изчистите.", + "repeater_cliHelpRegionListAllowed": "Списва регионите, които позволяват преминаване на превозни средства при наводнение.", + "repeater_cliHelpRegionListDenied": "Списва региони, които забраняват движението по пътищата при наводнения.", + "repeater_cliHelpStatsPackets": "(Само за серия) Показва статистически данни на ниво пакет.", + "repeater_cliHelpStatsRadio": "(Само за конкретен сериал) Показва радиостатистика.", + "repeater_cliHelpStatsCore": "(Само за серийния номер) Показва основните статистически данни за фърмуера.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "settings_multiAck": "Множество потвърждения", + "map_sharedAt": "Споделено", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losSelectedObstructionTitle": "Избрано препятствие", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losBlockedSpotsHint": "Кликнете върху блокираната точка, за да я отбележите на картата.", + "losBlockedSpotsTitle": "Ограничени места", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "chat_markAsUnread": "Отбелязване като непрочетено", + "settings_companionDebugLogSubtitle": "Команди, отговори и сурови данни за протоколите BLE/TCP/USB", + "chat_newMessages": "Нови съобщения", + "settings_companionDebugLog": "Лог за отстраняване на грешки (за съпътстваща програма)", + "repeater_chanUtil": "Използване на канала" } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 4695505..7f491d4 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -52,7 +52,7 @@ } } }, - "scanner_title": "MeshCore Open", + "scanner_title": "MeshCore – Open-Version", "scanner_scanning": "Scannen nach Geräten...", "scanner_connecting": "Verbunden...", "scanner_disconnecting": "Trenne...", @@ -104,6 +104,8 @@ "settings_privacyModeEnabled": "Datenschutzmodus aktiviert", "settings_privacyModeDisabled": "Datenschutzmodus deaktiviert", "settings_actions": "Aktionen", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Sende Ankündigung", "settings_sendAdvertisementSubtitle": "Sende eine Ankündigung", "settings_advertisementSent": "Ankündigung gesendet", @@ -121,7 +123,7 @@ "settings_appDebugLog": "App-Debug-Protokoll", "settings_appDebugLogSubtitle": "Anwendung Debug-Nachrichten", "settings_about": "Über", - "settings_aboutVersion": "MeshCore Open v{version}", + "settings_aboutVersion": "MeshCore Open, Version {version}", "@settings_aboutVersion": { "placeholders": { "version": { @@ -146,7 +148,7 @@ "settings_spreadingFactor": "Verteilungsfaktor", "settings_codingRate": "Kodierungsrate", "settings_txPower": "TX-Leistung (dBm)", - "settings_txPowerHelper": "0 - 22", + "settings_txPowerHelper": "0 – 22", "settings_txPowerInvalid": "Ungültige TX-Leistung (0-22 dBm)", "settings_error": "Fehler: {message}", "@settings_error": { @@ -158,25 +160,25 @@ }, "appSettings_title": "App-Einstellungen", "appSettings_appearance": "Aussehen", - "appSettings_theme": "Theme", + "appSettings_theme": "Thema", "appSettings_themeSystem": "Systemstandard", "appSettings_themeLight": "Hell", "appSettings_themeDark": "Dunkel", "appSettings_language": "Sprache", "appSettings_languageSystem": "Systemstandard", - "appSettings_languageEn": "English", - "appSettings_languageFr": "Français", - "appSettings_languageEs": "Español", + "appSettings_languageEn": "Englisch", + "appSettings_languageFr": "Französisch", + "appSettings_languageEs": "Spanisch", "appSettings_languageDe": "Deutsch", - "appSettings_languagePl": "Polski", - "appSettings_languageSl": "Slovenščina", - "appSettings_languagePt": "Português", - "appSettings_languageIt": "Italiano", - "appSettings_languageZh": "中文", - "appSettings_languageSv": "Svenska", - "appSettings_languageNl": "Nederlands", - "appSettings_languageSk": "Slovenčina", - "appSettings_languageBg": "Български", + "appSettings_languagePl": "Polnisch", + "appSettings_languageSl": "Slowenisch", + "appSettings_languagePt": "Portugiesisch", + "appSettings_languageIt": "Italienisch", + "appSettings_languageZh": "Chinesisch", + "appSettings_languageSv": "Schwedisch", + "appSettings_languageNl": "Niederländisch", + "appSettings_languageSk": "Slowenisch", + "appSettings_languageBg": "Bulgarisch", "appSettings_notifications": "Benachrichtigungen", "appSettings_enableNotifications": "Benachrichtigungen aktivieren", "appSettings_enableNotificationsSubtitle": "Erhalte Benachrichtigungen für Nachrichten und Ankündigungen", @@ -337,11 +339,8 @@ } } }, - "channels_hashtagChannel": "Hashtag-Kanal", "channels_public": "Öffentlich", "channels_private": "Privat", - "channels_publicChannel": "Öffentlicher Kanal", - "channels_privateChannel": "Privater Kanal", "channels_editChannel": "Kanal bearbeiten", "channels_muteChannel": "Kanal stummschalten", "channels_unmuteChannel": "Kanal Stummschaltung aufheben", @@ -367,7 +366,7 @@ "channels_channelName": "Kanalname", "channels_usePublicChannel": "Verwende öffentlichen Kanal", "channels_standardPublicPsk": "Öffentliche Standard PSK", - "channels_pskHex": "PSK (Hex)", + "channels_pskHex": "PSK (Hexadezimal)", "channels_generateRandomPsk": "Zufällige PSK generieren", "channels_enterChannelName": "Bitte geben Sie einen Kanalnamen ein.", "channels_pskMustBe32Hex": "Die PSK muss 32 hexadezimale Zeichen haben.", @@ -388,6 +387,22 @@ } }, "channels_smazCompression": "SMAZ-Komprimierung", + "channels_cyr2latCompression": "Cyr2Lat-Komprimierung", + "channels_cyr2latCompressionDscr": "Ersetzt einige kyrillische Zeichen durch lateinische Zeichen, wenn sie gesendet werden.", + "channels_cyr2latSettingsHeading": "Cyr2Lat-Einstellungen", + "channels_cyr2latSettingsSubheading": "Ersetzungsliste", + "channels_cyr2latSettingsDscr": "JSON-Konfiguration für die Zeichenersetzung bearbeiten", + "channels_cyr2latSettingsDialogHint": "JSON-Ersetzungstabelle", + "channels_cyr2latSettingsDialogWrongJSON": "Ungültiges JSON: {error}", + "settings_cyr2latProfileAdd": "Cyr2Lat-Profil hinzufügen", + "settings_cyr2latProfileName": "Profilname", + "settings_cyr2latProfileNameEmpty": "Der Profilname darf nicht leer sein", + "settings_cyr2latProfileAdded": "Profil erfolgreich hinzugefügt", + "settings_cyr2latProfileUpdated": "Profil erfolgreich aktualisiert", + "settings_cyr2latProfileEdit": "Cyr2Lat-Profil bearbeiten", + "settings_cyr2latProfileDelete": "Cyr2Lat-Profil löschen", + "settings_cyr2latProfileDeleted": "Profil erfolgreich gelöscht", + "settings_cyr2latProfileDeleteDscr": "Möchten Sie das Profil \"{name}\" wirklich löschen?", "channels_channelUpdated": "Kanal \"{name}\" aktualisiert", "@channels_channelUpdated": { "placeholders": { @@ -512,7 +527,7 @@ } } }, - "debugFrame_flags": "- Flags: 0x{value}", + "debugFrame_flags": "- Flaggen: 0x{value}", "@debugFrame_flags": { "placeholders": { "value": { @@ -531,7 +546,7 @@ } } }, - "debugFrame_textTypeCli": "CLI", + "debugFrame_textTypeCli": "Befehlszeilen-Schnittstelle", "debugFrame_textTypePlain": "Einfach", "debugFrame_text": "- Text: \"{text}\"", "@debugFrame_text": { @@ -633,7 +648,7 @@ } } }, - "map_pinsCount": "Pins: {count}", + "map_pinsCount": "Nadeln: {count}", "@map_pinsCount": { "placeholders": { "count": { @@ -642,20 +657,20 @@ } }, "map_chat": "Benutzer", - "map_repeater": "Repeater", + "map_repeater": "Wiederholungseinheit", "map_room": "Raum", "map_sensor": "Sensor", "map_pinDm": "Pin (Kontakt)", "map_pinPrivate": "Pin (Channel)", - "map_pinPublic": "Pin (Public)", + "map_pinPublic": "Kennzeichnung (Öffentlich)", "map_lastSeen": "Letzte Sichtung", "map_disconnectConfirm": "Sind Sie sicher, dass Sie sich von diesem Gerät trennen möchten?", "map_from": "Von", "map_source": "Quelle", - "map_flags": "Flags", + "map_flags": "Flaggen", "map_shareMarkerHere": "Teilen Sie den Marker hier.", "map_pinLabel": "Pin Name", - "map_label": "Label", + "map_label": "Etikett", "map_pointOfInterest": "Punkt von Interesse", "map_sendToContact": "Senden an Kontakt", "map_sendToChannel": "Senden an Kanal", @@ -883,7 +898,7 @@ "repeater_statusSubtitle": "Status, Statistiken und Nachbarn anzeigen", "repeater_telemetry": "Telemetrie", "repeater_telemetrySubtitle": "Sensordaten und Systemwerte anzeigen", - "repeater_cli": "CLI", + "repeater_cli": "Befehlszeilen-Schnittstelle", "repeater_cliSubtitle": "Sende Befehle an den Repeater", "repeater_settings": "Einstellungen", "repeater_settingsSubtitle": "Repeater-parameter konfigurieren", @@ -984,7 +999,7 @@ }, "repeater_settingsTitle": "Repeater Einstellungen", "repeater_basicSettings": "Grundlegende Einstellungen", - "repeater_repeaterName": "Repeater Name", + "repeater_repeaterName": "Name des Repeater", "repeater_repeaterNameHelper": "Anzeigename für diesen Repeater", "repeater_adminPassword": "Admin-Passwort", "repeater_adminPasswordHelper": "Vollzugriffspasswort", @@ -992,7 +1007,7 @@ "repeater_guestPasswordHelper": "Schreibgeschütztes Zugriffspasswort", "repeater_radioSettings": "Funk Einstellungen", "repeater_frequencyMhz": "Frequenz (MHz)", - "repeater_frequencyHelper": "300-2500 MHz", + "repeater_frequencyHelper": "300–2500 MHz", "repeater_txPower": "TX Power", "repeater_txPowerHelper": "1-30 dBm", "repeater_bandwidth": "Bandbreite", @@ -1059,6 +1074,81 @@ }, "repeater_confirm": "Bestätigen", "repeater_settingsSaved": "Einstellungen erfolgreich gespeichert", + "repeater_rxGain": "Erhöhter RX-Gewinn", + "repeater_rxGainHelper": "Höhere Empfindlichkeit, höherer Stromverbrauch (nur für SX1262/SX1268)", + "repeater_refreshRxGain": "Erneuerung des verstärkten RX-Effekts", + "repeater_multiAcks": "Mehrere Bestätigungen", + "repeater_multiAcksSubtitle": "Nachrichten über verschiedene Pfade senden, um die Zustellbarkeit zu verbessern.", + "repeater_refreshMultiAcks": "Mehrere Bestätigungen neu senden/aktualisieren", + "repeater_networkHealth": "Netzwerkgesundheit", + "repeater_loopDetect": "Erkennung von Schleifen", + "repeater_loopDetectHelper": "Erstellen Sie \"Flood\"-Pakete, die so aussehen, als ob sie Schleifen erzeugen.", + "repeater_loopDetectOff": "Aus", + "repeater_loopDetectMinimal": "Minimal", + "repeater_loopDetectModerate": "mäßig", + "repeater_loopDetectStrict": "streng", + "repeater_dutyCycle": "Betriebsdauer", + "repeater_dutyCycleHelper": "Höchster zulässiger Prozentsatz der Sendefläche", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Information zum Betreiber", + "repeater_ownerInfoHelper": "Öffentliche Metadaten für dieses Gerät", + "repeater_refreshOwnerInfo": "Aktualisieren Sie die Informationen zum Betreiber", + "repeater_floodMax": "Max-Hops-Flut", + "repeater_floodMaxHelper": "Maximale Anzahl an Hop-Paketen, die ein einzelnes Paket durchlaufen kann (0-64)", + "repeater_advancedSettings": "Fortgeschritten", + "repeater_advancedSettingsSubtitle": "Regler für erfahrene Bediener", + "repeater_pathHashMode": "Hash-Modus für Pfade", + "repeater_pathHashModeHelper": "Bytes, die zur Kodierung der ID dieses Repeaters in Flood-Pfad-/Schleifen-Erkennung-Tags verwendet werden. 0 = 1 Byte (256 IDs, bis zu 64 Hops), 1 = 2 Bytes (65.000 IDs, bis zu 32 Hops), 2 = 3 Bytes (16 Millionen IDs, bis zu 21 Hops). Firmware-Versionen 1.13 und älter verwenden mehrstellige Pfade – ab Version 1.14+ wird nur ein Pfad erstellt, sobald das Netzwerk aktiv ist.", + "repeater_txDelay": "Verzögerung bei Flood TX", + "repeater_txDelayHelper": "Wiederholung des Abstands für Hochwasser-Verkehr, als Multiplikator der Übertragungszeit des Pakets (0-2, Standardwert 0,5). Höherer Wert = weniger Kollisionen, aber langsamere Übertragung.", + "repeater_directTxDelay": "Direkter TX-Verzögerung", + "repeater_directTxDelayHelper": "Die Übertragungsrate für direkten (nicht-fluten) Datenverkehr wird als Vielfaches der Übertragungszeit des Pakets festgelegt (0-2, Standardwert 0,3).", + "repeater_intThresh": "Grenzwert für Störungen", + "repeater_intThreshHelper": "Der Schwellenwert wird an die Rauschpegel-Kalibrierung des Radios angepasst, sodass Störungen über diesem Wert abgefangen werden. 0 deaktiviert – erhöhen Sie diesen Wert nur, wenn Sie in einem verrauschten Frequenzbereich RX-Fehler feststellen.", + "repeater_agcResetInterval": "Intervall für die Rücksetzung von AGC", + "repeater_agcResetIntervalHelper": "Wie oft sollte die automatische Verstärkungskontrolle des Radios zurückgesetzt werden, um von einem Zustand mit zu hoher Verstärkung wieder in einen normalen Zustand zu gelangen? Die Einstellung „Sekunden“ ermöglicht eine Rücksetzung alle 4 Sekunden. Die Einstellung „0“ deaktiviert die periodische Rücksetzung.", + "repeater_actionsTitle": "Aktionen", + "repeater_sendAdvert": "Flood-Werbung versenden", + "repeater_sendAdvertSubtitle": "Eine Werbekampagne für Überschwemmungen über das Netzwerk verbreiten.", + "repeater_sendAdvertZeroHop": "Versenden Sie eine Anzeige ohne Zwischenvermittler.", + "repeater_sendAdvertZeroHopSubtitle": "Eine Werbekampagne mit einem einzigen Sender (ohne Weiterleitung) senden.", + "repeater_clockSync": "Uhr jetzt synchronisieren", + "repeater_clockSyncSubtitle": "Übertragen Sie die Uhrzeit Ihres Telefons an den Repeater.", + "repeater_actionSucceeded": "{action} war erfolgreich", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} fehlgeschlagen: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Einstellungen gespeichert – Repeater neu starten, um die Änderungen anzuwenden.", + "repeater_settingsPartialFailure": "Einige Einstellungen sind fehlgeschlagen: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Fehler beim Speichern der Einstellungen: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1070,11 +1160,9 @@ "repeater_refreshBasicSettings": "Grundlegende Einstellungen aktualisieren", "repeater_refreshRadioSettings": "Radio-Einstellungen aktualisieren", "repeater_refreshTxPower": "Sendeleistung aktualisieren", - "repeater_refreshLocationSettings": "Aktualisieren Sie die Standort Einstellungen", "repeater_refreshPacketForwarding": "Aktualisieren Paketweiterleitung", "repeater_refreshGuestAccess": "Aktualisieren Sie den Gastzugriff", "repeater_refreshPrivacyMode": "Wiederherstellen des Datenschutzzustands", - "repeater_refreshAdvertisementSettings": "Aktualisieren Sie die Ankündigungseinstellungen", "repeater_refreshed": "{label} wurde aktualisiert", "@repeater_refreshed": { "placeholders": { @@ -1091,7 +1179,7 @@ } } }, - "repeater_cliTitle": "Repeater CLI", + "repeater_cliTitle": "Befehlszeilen-Schnittstelle (CLI) für Repeater", "repeater_debugNextCommand": "Fehlersuche des nächsten Befehls", "repeater_commandHelp": "Hilfe", "repeater_clearHistory": "Löschen der Historie", @@ -1347,7 +1435,7 @@ "listFilter_sortBy": "Sortiere nach", "listFilter_latestMessages": "Letzte Nachrichten", "listFilter_heardRecently": "Kürzlich gehört", - "listFilter_az": "A-Z", + "listFilter_az": "Von A bis Z", "listFilter_filters": "Filtere", "listFilter_all": "Alle", "listFilter_favorites": "Favoriten", @@ -1462,7 +1550,7 @@ } } }, - "common_ok": "OK", + "common_ok": "Alles klar", "community_create": "Erstelle Community", "community_createDesc": "Erstelle eine neue Community und teile sie über den QR-Code.", "community_join": "Beitreten", @@ -1473,14 +1561,14 @@ "community_showQr": "Zeige QR-Code", "community_publicChannel": "Community Öffentlich", "community_enterName": "Bitte Community-Name eingeben", - "community_title": "Community", + "community_title": "Gemeinschaft", "community_created": "Community \"{name}\" wurde erstellt", "community_joined": "Community \"{name}\" beigetreten", "community_qrTitle": "Teile Community", "community_qrInstructions": "Scannen Sie diesen QR-Code, um sich \"{name}\" anzuschließen.", "community_hashtagPrivacyHint": "Community-Hashtag-Kanäle können nur von Mitgliedern der Community betreten werden", - "community_hashtagChannel": "Community Hashtag", - "community_name": "Community Name", + "community_hashtagChannel": "Gemeinschaftlicher Hashtag", + "community_name": "Name der Gemeinde", "community_invalidQrCode": "Ungültiger Community-QR-Code", "community_alreadyMember": "Bereits registriert", "community_alreadyMemberMessage": "Sie sind bereits Mitglied von \"{name}\".", @@ -1507,7 +1595,7 @@ "community_regularHashtagDesc": "Öffentlicher Hashtag (jeder kann teilnehmen)", "community_communityHashtagDesc": "Nur für Mitglieder der Community", "community_forCommunity": "Für {name}", - "community_communityHashtag": "Community Hashtag", + "community_communityHashtag": "Gemeinschaftlicher Hashtag", "@community_regenerateSecretConfirm": { "placeholders": { "name": { @@ -1907,7 +1995,7 @@ "connectionChoiceTcpLabel": "TCP", "tcpHostHint": "192.168.40.10", "tcpScreenTitle": "Verbinden über TCP", - "tcpPortLabel": "Port", + "tcpPortLabel": "Hafen", "tcpPortHint": "5000", "tcpStatus_notConnected": "Geben Sie den Endpunkt ein und verbinden Sie sich.", "tcpStatus_connectingTo": "Verbindung zu {endpoint}...", @@ -1950,13 +2038,6 @@ "contact_lastSeen": "Zuletzt gesehen", "contact_clearChat": "Chat löschen", "contact_teleEnvSubtitle": "Teilen von Umgebungsensordaten zulassen", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_initialRouteWeightSubtitle": "Ausgangsgewicht für neu entdeckte Pfade", "appSettings_maxRouteWeightSubtitle": "Maximales Gewicht, das ein Weg durch erfolgreiche Lieferungen erreichen kann.", "appSettings_maxRouteWeight": "Maximale Gesamtstreckenlänge", @@ -1969,7 +2050,6 @@ "appSettings_maxMessageRetriesSubtitle": "Anzahl der Versuche, eine Nachricht erneut zu senden, bevor sie als fehlgeschlagen markiert wird.", "path_routeWeight": "{weight}/{max}", "settings_telemetryModeUpdated": "Telemetriemodus aktualisiert", - "settings_multiAck": "Mehrfach-Bestätigungen: {value}", "map_showOverlaps": "Überlappungen der Repeater-Taste", "map_runTraceWithReturnPath": "Auf dem gleichen Pfad zurückkehren.", "@radioStats_noiseFloor": { @@ -2101,5 +2181,163 @@ "repeater_guest": "Informationen zu Repeatern", "repeater_guestTools": "Gastwerkzeuge", "chat_sendMessage": "Nachricht senden", - "room_guest": "Informationen zum Room Server" + "room_guest": "Informationen zum Room Server", + "repeater_getCategory": "Werte erhalten", + "repeater_powerMgmt": "Energieverwaltung", + "repeater_sensors": "Sensoren", + "repeater_cliHelpPowerOff": "Schaltet das Gerät aus. (keine Antwort erwartet)", + "repeater_cliHelpClkReboot": "Setzt die Uhr auf einen bekannten Zeitpunkt zurück und startet das Gerät neu.", + "repeater_cliHelpAdvertZeroHop": "Sendet eine Werbeanzeige, die nur an unmittelbare Nachbarn gesendet wird (ohne Zwischenstation).", + "repeater_cliHelpStartOta": "Startet ein Firmware-Update über Funk, das auf unterstützten Boards durchgeführt wird.", + "repeater_cliHelpTime": "Stellt die Gerätuhr auf die angegebene Unix-Epoche in Sekunden ein. Die Uhr kann nicht rückwärts laufen.", + "repeater_cliHelpBoard": "Zeigt den Hersteller/die Hardware-Kennung an.", + "repeater_cliHelpDiscoverNeighbors": "Sendet eine Anfrage zur Entdeckung von Nachbarn in der Nähe. (Nur bei Repeatern)", + "repeater_cliHelpPowersaving": "Zeigt an, ob der Energiesparmodus aktiviert oder deaktiviert ist.", + "repeater_cliHelpPowersavingOnOff": "Aktiviert oder deaktiviert den Energiesparmodus (falls unterstützt).", + "repeater_cliHelpErase": "(Nur für serielle Schnittstellen) Formatiert das Dateisystem des Geräts. Löscht alle Einstellungen und Kontakte.", + "repeater_cliHelpSetDutyCycle": "Legt den maximal zulässigen Übertragungszyklus als Prozentsatz fest (1-100). Passt den Zeitfaktor intern an.", + "repeater_cliHelpSetPrvKey": "(Nur für serielle Anwendungen) Ersetzt den privaten Schlüssel zur Geräteidentifizierung. Nach der Anwendung ist ein Neustart erforderlich. Generiert einen neuen öffentlichen Schlüssel.", + "repeater_cliHelpSetRadioRxGain": "(Nur für SX126x) Schaltet die verstärkte RX-Verstärkung ein, um die Empfindlichkeit bei höherem Stromverbrauch zu verbessern.", + "repeater_cliHelpSetOwnerInfo": "Definiert den String mit den Kontaktinformationen des Eigentümers, der in den Anzeigen enthalten ist. Verwenden Sie '|' für Zeilenumbrüche.", + "repeater_cliHelpSetPathHashMode": "Legt den Modus für die Pfad-Hashes fest. 0 = ältere Version, 1 = Standard, 2 = streng. Beeinflusst, wie Routing-Pfade abgeglichen werden.", + "repeater_cliHelpSetLoopDetect": "Legt die Empfindlichkeit der Schleifenerkennung fest: aus, minimal, moderat oder streng.", + "repeater_cliHelpSetFreq": "(Nur für die serielle Schnittstelle) Ermöglicht die schnelle Einstellung der Frequenz. Nach der Einstellung ist ein Neustart erforderlich. Für die vollständige Einstellung aller Radio-Parameter wird die Option \"Radio einstellen\" empfohlen.", + "repeater_cliHelpSetBridgeChannel": "(Nur für ESPNow-Brücke) Legt den verwendeten WLAN-Kanal (1-14) für die Brücke fest.", + "repeater_cliHelpGetName": "Zeigt den konfigurierten Knotenamen an.", + "repeater_cliHelpGetRole": "Zeigt die Funktion der Firmware an (Repeater, Raumserver usw.).", + "repeater_cliHelpGetPublicKey": "Zeigt den öffentlichen Schlüssel des Geräts an.", + "repeater_cliHelpGetPrvKey": "(Nur für serielle Kommunikation) Zeigt den privaten Schlüssel des Geräts an. Behandeln Sie diesen als ein Geheimnis.", + "repeater_cliHelpGetRepeat": "Zeigt an, ob die Weiterleitung von Paketen (als Repeater) aktiviert oder deaktiviert ist.", + "repeater_cliHelpGetTx": "Zeigt die aktuelle Sendeleistung in dBm an.", + "repeater_cliHelpGetFreq": "Zeigt die konfigurierte Funkfrequenz in MHz an.", + "repeater_cliHelpGetRadio": "Zeigt alle Funkparameter an: Frequenz, Bandbreite, Spreading-Faktor, Codierungsrate.", + "repeater_cliHelpGetRadioRxGain": "(Nur für SX126x) Zeigt den Zustand des verstärkten Empfangs (RX).", + "repeater_cliHelpGetAf": "Zeigt den aktuellen Zeitfaktor an.", + "repeater_cliHelpGetDutyCycle": "Zeigt den aktuellen zulässigen Schaltzyklus als Prozentsatz an.", + "repeater_cliHelpGetIntThresh": "Zeigt den Grenzwert für Kanalüberlagerung in dB an.", + "repeater_cliHelpGetAgcResetInterval": "Zeigt das Intervall für die Rücksetzung des AGC in Sekunden an.", + "repeater_cliHelpGetMultiAcks": "Zeigt an, ob der Modus \"doppelte ACK\"-Funktion aktiviert (1) oder deaktiviert (0) ist.", + "repeater_cliHelpGetAllowReadOnly": "Zeigt an, ob der Zugriff für Gäste nur in Lesemodus erlaubt ist.", + "repeater_cliHelpGetAdvertInterval": "Zeigt die Dauer des lokalen Werbeintervalls in Minuten an.", + "repeater_cliHelpGetFloodAdvertInterval": "Zeigt die Dauer der Werbeunterbrechung in Stunden an.", + "repeater_cliHelpGetGuestPassword": "Zeigt das konfigurierte Gast-Passwort an.", + "repeater_cliHelpGetLat": "Zeigt die konfigurierte Breitengrade.", + "repeater_cliHelpGetLon": "Zeigt die konfigurierte Länge an.", + "repeater_cliHelpGetRxDelay": "Zeigt den Basiswert für die Verzögerungszeit an.", + "repeater_cliHelpGetTxDelay": "Zeigt den Faktor für die Übertragungsverzögerung im Notfallmodus an.", + "repeater_cliHelpGetDirectTxDelay": "Zeigt den Faktor für die Verzögerung im Direktmodus an.", + "repeater_cliHelpGetFloodMax": "Zeigt die maximale Anzahl von Überschwemmungsphasen an.", + "repeater_cliHelpGetOwnerInfo": "Zeigt die Zeichenkette mit den Kontaktinformationen des Eigentümers an.", + "repeater_cliHelpGetPathHashMode": "Zeigt den Pfad-Hash-Modus (0/1/2) an.", + "repeater_cliHelpGetLoopDetect": "Zeigt die Empfindlichkeit der Schleifenerkennung an.", + "repeater_cliHelpGetAcl": "(Nur für serielle Kommunikation) Zeigt die Zugriffskontrolleinträge auf einem Repeater an.", + "repeater_cliHelpGetBridgeEnabled": "Zeigt an, ob die Brücke aktiviert ist.", + "repeater_cliHelpGetBridgeDelay": "Zeigt die Verzögerung der Brücke in Millisekunden an.", + "repeater_cliHelpGetBridgeSource": "Zeigt, ob die Brücke RX- oder TX-Pakete empfängt oder sendet.", + "repeater_cliHelpGetBridgeBaud": "(Nur für RS232-Verbindungen) Zeigt die Baudrate der Verbindung an.", + "repeater_cliHelpGetBridgeChannel": "(Nur für ESPNow-Brücke) Zeigt den WLAN-Kanal der Brücke an.", + "repeater_cliHelpGetBridgeSecret": "(Nur für ESPNow-Brücke) Zeigt das gemeinsam genutzte Geheimnis der Brücke.", + "repeater_cliHelpGetBootloaderVer": "(Nur für NRF52) Zeigt die Version des Bootloaders an.", + "repeater_cliHelpGetAdcMultiplier": "Zeigt den ADC-Verstärker (Spannungs-Skalierung) an.", + "repeater_cliHelpGetPwrMgtSupport": "Gibt an, ob der Verwaltungsrat die Funktion zur Energieverwaltung unterstützt.", + "repeater_cliHelpGetPwrMgtSource": "Zeigt die aktuelle Stromquelle an: extern oder Batterie.", + "repeater_cliHelpGetPwrMgtBootReason": "Zeigt die aktuellsten Gründe für einen Neustart und Herunterfahren an.", + "repeater_cliHelpGetPwrMgtBootMv": "Zeigt die Batteriespannung beim Start in Millivolt (mV) an.", + "repeater_cliHelpSensorGet": "Liest eine benutzerdefinierte Sensoreinstellung über eine Taste.", + "repeater_cliHelpSensorSet": "Erstellt eine benutzerdefinierte Sensoreinstellung.", + "repeater_cliHelpSensorList": "Zeigt alle benutzerdefinierten Sensoreinstellungen an, wobei die Seitennummerierung optional von einem Startindex abhängt.", + "repeater_cliHelpRegionDefault": "Zeigt den aktuellen Standard-Region-Bereich an.", + "repeater_cliHelpRegionDefaultSet": "Definiert den Standard-Regionenbereich. Verwenden Sie \"\", um diesen zu löschen.", + "repeater_cliHelpRegionListAllowed": "Nennt die Regionen, die Überschwemmungsverkehr zulassen.", + "repeater_cliHelpRegionListDenied": "Auflistung von Regionen, die den Verkehr aufgrund von Überschwemmungen verbieten.", + "repeater_cliHelpStatsPackets": "(Nur für serielle Verbindungen) Zeigt Statistiken auf Paketebene.", + "repeater_cliHelpStatsRadio": "(Nur für Serien) Zeigt Radiostatistiken an.", + "repeater_cliHelpStatsCore": "(Nur für serielle Schnittstellen) Zeigt grundlegende Firmware-Statistiken.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "settings_multiAck": "Mehrere Bestätigungen", + "map_sharedAt": "Geteilt", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losBlockedSpotsTitle": "Reservierte Plätze", + "losSelectedObstructionTitle": "Ausgewählte Behinderung", + "losBlockedSpotChip": "{distance} • {distanceUnit} • {obstruction} {heightUnit}", + "losBlockedSpotsHint": "Klicken Sie auf einen blockierten Bereich, um ihn auf der Karte hervorzuheben.", + "losSelectedObstructionDetails": "Blockiert durch {obstruction} in einer Höhe von {heightUnit}, {distanceFromA} von A und {distanceFromB} von B ({distanceUnit}).", + "chat_markAsUnread": "Als nicht gelesen markieren", + "chat_newMessages": "Neue Nachrichten", + "settings_companionDebugLog": "Debug-Protokoll für die Begleitsoftware", + "settings_companionDebugLogSubtitle": "BLE/TCP/USB-Befehle, Antworten und Rohdaten", + "repeater_chanUtil": "Nutzung des Kanals" } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 8ad6bf3..456fab5 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -12,6 +12,7 @@ "common_delete": "Delete", "common_deleteAll": "Delete All", "common_close": "Close", + "common_done": "Done", "common_edit": "Edit", "common_add": "Add", "common_settings": "Settings", @@ -51,8 +52,8 @@ "connectionChoiceBluetoothLabel": "Bluetooth", "connectionChoiceTcpLabel": "TCP", "tcpScreenTitle": "Connect over TCP", - "tcpHostLabel": "IP Address", - "tcpHostHint": "192.168.40.10", + "tcpHostLabel": "Endpoint", + "tcpHostHint": "192.168.40.10 / example.com", "tcpPortLabel": "Port", "tcpPortHint": "5000", "tcpStatus_notConnected": "Enter endpoint and connect", @@ -64,7 +65,7 @@ } } }, - "tcpErrorHostRequired": "IP address is required.", + "tcpErrorHostRequired": "Host is required.", "tcpErrorPortInvalid": "Port must be between 1 and 65535.", "tcpErrorUnsupported": "TCP transport is not supported on this platform.", "tcpErrorTimedOut": "TCP connection timed out.", @@ -127,7 +128,6 @@ } } }, - "scanner_stop": "Stop", "scanner_scan": "Scan", "scanner_bluetoothOff": "Bluetooth is off", @@ -178,16 +178,11 @@ "settings_telemetryEnvironmentMode": "Telemetry Environment Mode", "settings_advertLocation": "Advert Location", "settings_advertLocationSubtitle": "Include location in advert.", - "settings_multiAck": "Multi-ACKs: {value}", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, + "settings_multiAck": "Multi-ACKs", "settings_telemetryModeUpdated": "Telemetry mode updated", "settings_actions": "Actions", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Send Advertisement", "settings_sendAdvertisementSubtitle": "Broadcast presence now", "settings_advertisementSent": "Advertisement sent", @@ -200,8 +195,8 @@ "settings_rebootDeviceSubtitle": "Restart the MeshCore device", "settings_rebootDeviceConfirm": "Are you sure you want to reboot the device? You will be disconnected.", "settings_debug": "Debug", - "settings_bleDebugLog": "BLE Debug Log", - "settings_bleDebugLogSubtitle": "BLE commands, responses, and raw data", + "settings_companionDebugLog": "Companion Debug Log", + "settings_companionDebugLogSubtitle": "BLE/TCP/USB commands, responses, and raw data", "settings_appDebugLog": "App Debug Log", "settings_appDebugLogSubtitle": "Application debug messages", "settings_about": "About", @@ -521,11 +516,16 @@ } } }, - "channels_hashtagChannel": "Hashtag channel", "channels_public": "Public", + "channels_via": "via {path}", + "@channels_via": { + "placeholders": { + "path": { + "type": "String" + } + } + }, "channels_private": "Private", - "channels_publicChannel": "Public channel", - "channels_privateChannel": "Private channel", "channels_editChannel": "Edit channel", "channels_muteChannel": "Mute channel", "channels_unmuteChannel": "Unmute channel", @@ -580,6 +580,18 @@ } }, "channels_smazCompression": "SMAZ compression", + "channels_cyr2latCompression": "Cyr2Lat compression", + "channels_cyr2latCompressionDscr": "Replaces some Cyrillic characters with Latin characters when sending.", + "channels_cyr2latSettingsHeading": "Cyr2Lat Setup", + "channels_cyr2latSettingsSubheading": "List of replacements", + "channels_cyr2latSettingsDscr": "Edit the JSON configuration of character replacement", + "channels_cyr2latSettingsDialogHint": "JSON replacement map", + "channels_cyr2latSettingsDialogWrongJSON": "Invalid JSON: {error}", + "@channels_cyr2latSettingsDialogWrongJSON": { + "placeholders": { + "error": {} + } + }, "channels_channelUpdated": "Channel \"{name}\" updated", "@channels_channelUpdated": { "placeholders": { @@ -588,6 +600,22 @@ } } }, + "settings_cyr2latProfileAdd": "Add Cyr2Lat Profile", + "settings_cyr2latProfileName": "Profile Name", + "settings_cyr2latProfileNameEmpty": "Profile name cannot be empty", + "settings_cyr2latProfileAdded": "Profile added successfully", + "settings_cyr2latProfileUpdated": "Profile updated successfully", + "settings_cyr2latProfileEdit": "Edit Cyr2Lat Profile", + "settings_cyr2latProfileDelete": "Delete Cyr2Lat Profile", + "settings_cyr2latProfileDeleted": "Profile deleted successfully", + "settings_cyr2latProfileDeleteDscr": "Are you sure you want to delete the profile \"{name}\"?", + "@settings_cyr2latProfileDeleteDscr": { + "placeholders": { + "name": { + "type": "String" + } + } + }, "channels_publicChannelAdded": "Public channel added", "channels_sortBy": "Sort by", "channels_sortManual": "Manual", @@ -608,10 +636,10 @@ "channels_hashtagHint": "e.g. #team", "chat_noMessages": "No messages yet", "chat_sendMessage": "Send message", - "chat_sendMessageTo": "Send message to {name}", + "chat_sendMessageTo": "Send a message to {contactName}", "@chat_sendMessageTo": { "placeholders": { - "name": { + "contactName": { "type": "String" } } @@ -635,14 +663,6 @@ } }, "chat_location": "Location", - "chat_sendMessageTo": "Send a message to {contactName}", - "@chat_sendMessageTo": { - "placeholders": { - "contactName": { - "type": "String" - } - } - }, "chat_typeMessage": "Type a message...", "chat_messageTooLong": "Message too long (max {maxBytes} bytes).", "@chat_messageTooLong": { @@ -773,6 +793,7 @@ } }, "chat_successes": "successes", + "chat_score": "Score", "chat_removePath": "Remove path", "chat_noPathHistoryYet": "No path history yet.\nSend a message to discover paths.", "chat_pathActions": "Path Actions:", @@ -824,6 +845,8 @@ } } }, + "chat_markAsUnread": "Mark as Unread", + "chat_newMessages": "New messages", "chat_openLink": "Open Link?", "chat_openLinkConfirmation": "Do you want to open this link in your browser?", "chat_open": "Open", @@ -869,6 +892,12 @@ "map_from": "From", "map_source": "Source", "map_flags": "Flags", + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", "map_shareMarkerHere": "Share marker here", "map_setAsMyLocation": "Set as my location", "map_pinLabel": "Pin label", @@ -903,6 +932,7 @@ "map_guessedLocation": "Guessed location", "map_lastSeenTime": "Last Seen Time", "map_sharedPin": "Shared pin", + "map_sharedAt": "Shared", "map_joinRoom": "Join Room", "map_manageRepeater": "Manage Repeater", "map_tapToAdd": "Tap on nodes to add them to the path.", @@ -1154,6 +1184,7 @@ "repeater_noiseFloor": "Noise Floor", "repeater_txAirtime": "TX Airtime", "repeater_rxAirtime": "RX Airtime", + "repeater_chanUtil": "Channel Utilization", "repeater_packetStatistics": "Packet Statistics", "repeater_sent": "Sent", "repeater_received": "Received", @@ -1299,6 +1330,81 @@ }, "repeater_confirm": "Confirm", "repeater_settingsSaved": "Settings saved successfully", + "repeater_rxGain": "Boosted RX gain", + "repeater_rxGainHelper": "Higher sensitivity, more current draw (SX1262/SX1268 only)", + "repeater_refreshRxGain": "Refresh boosted RX gain", + "repeater_multiAcks": "Multi-ACKs", + "repeater_multiAcksSubtitle": "Acknowledge messages over multiple paths for better delivery", + "repeater_refreshMultiAcks": "Refresh multi-ACKs", + "repeater_networkHealth": "Network health", + "repeater_loopDetect": "Loop detection", + "repeater_loopDetectHelper": "Drop flood packets that look like routing loops", + "repeater_loopDetectOff": "Off", + "repeater_loopDetectMinimal": "Minimal", + "repeater_loopDetectModerate": "Moderate", + "repeater_loopDetectStrict": "Strict", + "repeater_dutyCycle": "Duty cycle", + "repeater_dutyCycleHelper": "Maximum percentage of airtime", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Operator info", + "repeater_ownerInfoHelper": "Public metadata for this repeater", + "repeater_refreshOwnerInfo": "Refresh operator info", + "repeater_floodMax": "Flood max hops", + "repeater_floodMaxHelper": "Maximum hops a flood packet may travel (0-64)", + "repeater_advancedSettings": "Advanced", + "repeater_advancedSettingsSubtitle": "Tuning knobs for experienced operators", + "repeater_pathHashMode": "Path hash mode", + "repeater_pathHashModeHelper": "Bytes used to encode this repeater's ID in flood path/loop-detect tags. 0=1 byte (256 IDs, up to 64 hops), 1=2 bytes (65K IDs, up to 32 hops), 2=3 bytes (16M IDs, up to 21 hops). v1.13 and older firmware drops multi-byte paths — only raise once your network is on v1.14+.", + "repeater_txDelay": "Flood TX delay", + "repeater_txDelayHelper": "Retransmit spacing for flood traffic, as a multiplier of the packet's airtime (0-2, default 0.5). Higher = fewer collisions but slower delivery.", + "repeater_directTxDelay": "Direct TX delay", + "repeater_directTxDelayHelper": "Retransmit spacing for direct (non-flood) traffic, as a multiplier of the packet's airtime (0-2, default 0.3).", + "repeater_intThresh": "Interference threshold", + "repeater_intThreshHelper": "Threshold passed to the radio's noise-floor calibration so it rejects interference above this level. 0 disables — only raise if you see RX errors in a noisy band.", + "repeater_agcResetInterval": "AGC reset interval", + "repeater_agcResetIntervalHelper": "How often to reset the radio's automatic gain control to recover from a stuck gain state. Seconds, snapped down to a multiple of 4. 0 disables periodic resets.", + "repeater_actionsTitle": "Actions", + "repeater_sendAdvert": "Send flood advert", + "repeater_sendAdvertSubtitle": "Broadcast a flood advert through the network", + "repeater_sendAdvertZeroHop": "Send zero-hop advert", + "repeater_sendAdvertZeroHopSubtitle": "Broadcast a one-hop advert (no relays)", + "repeater_clockSync": "Sync clock now", + "repeater_clockSyncSubtitle": "Push your phone's time to the repeater", + "repeater_actionSucceeded": "{action} succeeded", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} failed: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Settings saved — reboot the repeater to apply", + "repeater_settingsPartialFailure": "Some settings failed: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Error saving settings: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1310,11 +1416,9 @@ "repeater_refreshBasicSettings": "Refresh Basic Settings", "repeater_refreshRadioSettings": "Refresh Radio Settings", "repeater_refreshTxPower": "Refresh TX power", - "repeater_refreshLocationSettings": "Refresh Location Settings", "repeater_refreshPacketForwarding": "Refresh Packet Forwarding", "repeater_refreshGuestAccess": "Refresh Guest Access", "repeater_refreshPrivacyMode": "Refresh Privacy Mode", - "repeater_refreshAdvertisementSettings": "Refresh Advertisement Settings", "repeater_refreshed": "{label} refreshed", "@repeater_refreshed": { "placeholders": { @@ -1424,6 +1528,77 @@ "repeater_regionNote": "Region commands have been introduced to manage region definitions and permissions.", "repeater_gpsManagement": "GPS Management", "repeater_gpsNote": "gps command has been introduced to manage location related topics.", + "repeater_getCategory": "Get Values", + "repeater_powerMgmt": "Power Management", + "repeater_sensors": "Sensors", + "repeater_cliHelpPowerOff": "Powers the device off. (no response expected)", + "repeater_cliHelpClkReboot": "Resets the clock to a known epoch and reboots the device.", + "repeater_cliHelpAdvertZeroHop": "Sends a zero-hop advertisement (immediate neighbors only).", + "repeater_cliHelpStartOta": "Starts an over-the-air firmware update on supported boards.", + "repeater_cliHelpTime": "Sets the device clock to the given Unix epoch seconds. Clock cannot move backwards.", + "repeater_cliHelpBoard": "Shows the board manufacturer / hardware identifier.", + "repeater_cliHelpDiscoverNeighbors": "Sends a node-discovery request to nearby neighbors. (Repeater only)", + "repeater_cliHelpPowersaving": "Shows whether powersaving mode is on or off.", + "repeater_cliHelpPowersavingOnOff": "Enables or disables powersaving mode (where supported).", + "repeater_cliHelpErase": "(Serial only) Formats the device file system. Wipes all settings and contacts.", + "repeater_cliHelpSetDutyCycle": "Sets the maximum allowed transmit duty cycle as a percentage (1-100). Internally adjusts the airtime factor.", + "repeater_cliHelpSetPrvKey": "(Serial only) Replaces the device identity private key. Reboot required to apply. Generates a new public key.", + "repeater_cliHelpSetRadioRxGain": "(SX126x only) Toggles boosted RX gain for improved sensitivity at higher current draw.", + "repeater_cliHelpSetOwnerInfo": "Sets the owner contact info string included in adverts. Use '|' for newlines.", + "repeater_cliHelpSetPathHashMode": "Sets the path-hash mode. 0 = legacy, 1 = standard, 2 = strict. Affects how routing paths are matched.", + "repeater_cliHelpSetLoopDetect": "Sets the routing loop-detection sensitivity: off, minimal, moderate, or strict.", + "repeater_cliHelpSetFreq": "(Serial only) Quickly sets just the frequency. Reboot required. Prefer \"set radio\" for full radio params.", + "repeater_cliHelpSetBridgeChannel": "(ESPNow bridge only) Sets the WiFi channel (1-14) used by the bridge.", + "repeater_cliHelpGetName": "Shows the configured node name.", + "repeater_cliHelpGetRole": "Shows the firmware role (Repeater, Room Server, etc.).", + "repeater_cliHelpGetPublicKey": "Shows the device public key.", + "repeater_cliHelpGetPrvKey": "(Serial only) Shows the device private key. Treat as a secret.", + "repeater_cliHelpGetRepeat": "Shows whether packet forwarding (repeater role) is on or off.", + "repeater_cliHelpGetTx": "Shows the current TX power in dBm.", + "repeater_cliHelpGetFreq": "Shows the configured radio frequency in MHz.", + "repeater_cliHelpGetRadio": "Shows full radio params: freq, bandwidth, spreading factor, coding rate.", + "repeater_cliHelpGetRadioRxGain": "(SX126x only) Shows the RX boosted gain state.", + "repeater_cliHelpGetAf": "Shows the current airtime factor.", + "repeater_cliHelpGetDutyCycle": "Shows the current allowed duty cycle as a percentage.", + "repeater_cliHelpGetIntThresh": "Shows the channel interference threshold in dB.", + "repeater_cliHelpGetAgcResetInterval": "Shows the AGC reset interval in seconds.", + "repeater_cliHelpGetMultiAcks": "Shows whether double-ACK mode is on (1) or off (0).", + "repeater_cliHelpGetAllowReadOnly": "Shows whether guest read-only access is allowed.", + "repeater_cliHelpGetAdvertInterval": "Shows the local advertisement interval in minutes.", + "repeater_cliHelpGetFloodAdvertInterval": "Shows the flood advertisement interval in hours.", + "repeater_cliHelpGetGuestPassword": "Shows the configured guest password.", + "repeater_cliHelpGetLat": "Shows the configured latitude.", + "repeater_cliHelpGetLon": "Shows the configured longitude.", + "repeater_cliHelpGetRxDelay": "Shows the rxdelay base value.", + "repeater_cliHelpGetTxDelay": "Shows the flood-mode txdelay factor.", + "repeater_cliHelpGetDirectTxDelay": "Shows the direct-mode txdelay factor.", + "repeater_cliHelpGetFloodMax": "Shows the maximum flood hop count.", + "repeater_cliHelpGetOwnerInfo": "Shows the owner contact info string.", + "repeater_cliHelpGetPathHashMode": "Shows the path-hash mode (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Shows the loop-detection sensitivity.", + "repeater_cliHelpGetAcl": "(Serial only) Lists the access-control entries on a repeater.", + "repeater_cliHelpGetBridgeEnabled": "Shows whether the bridge is enabled.", + "repeater_cliHelpGetBridgeDelay": "Shows the bridge delay in ms.", + "repeater_cliHelpGetBridgeSource": "Shows whether the bridge logs RX or TX packets.", + "repeater_cliHelpGetBridgeBaud": "(RS232 bridge only) Shows the bridge baud rate.", + "repeater_cliHelpGetBridgeChannel": "(ESPNow bridge only) Shows the bridge WiFi channel.", + "repeater_cliHelpGetBridgeSecret": "(ESPNow bridge only) Shows the bridge shared secret.", + "repeater_cliHelpGetBootloaderVer": "(NRF52 only) Shows the bootloader version.", + "repeater_cliHelpGetAdcMultiplier": "Shows the ADC multiplier (battery-voltage scaling).", + "repeater_cliHelpGetPwrMgtSupport": "Reports whether the board has power-management support.", + "repeater_cliHelpGetPwrMgtSource": "Shows the current power source: external or battery.", + "repeater_cliHelpGetPwrMgtBootReason": "Shows the most recent reset and shutdown reasons.", + "repeater_cliHelpGetPwrMgtBootMv": "Shows the boot-time battery voltage in mV.", + "repeater_cliHelpSensorGet": "Reads a custom sensor setting by key.", + "repeater_cliHelpSensorSet": "Writes a custom sensor setting.", + "repeater_cliHelpSensorList": "Lists all custom sensor settings, paginated from optional start index.", + "repeater_cliHelpRegionDefault": "Shows the current default region scope.", + "repeater_cliHelpRegionDefaultSet": "Sets the default region scope. Use \"\" to clear.", + "repeater_cliHelpRegionListAllowed": "Lists regions that allow flood traffic.", + "repeater_cliHelpRegionListDenied": "Lists regions that deny flood traffic.", + "repeater_cliHelpStatsPackets": "(Serial only) Shows packet-level statistics.", + "repeater_cliHelpStatsRadio": "(Serial only) Shows radio statistics.", + "repeater_cliHelpStatsCore": "(Serial only) Shows core firmware statistics.", "telemetry_receivedData": "Received Telemetry Data", "telemetry_requestTimeout": "Telemetry request timed out.", "telemetry_errorLoading": "Error loading telemetry: {error}", @@ -1882,6 +2057,46 @@ "losLegendRadioHorizon": "Radio horizon", "losLegendLosBeam": "LOS beam", "losLegendTerrain": "Terrain", + "losBlockedSpotsTitle": "Blocked spots", + "losBlockedSpotsHint": "Tap a blocked spot to highlight it on the map.", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "losSelectedObstructionTitle": "Selected obstruction", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, "losFrequencyLabel": "Frequency", "losFrequencyInfoTooltip": "View calculation details", "losFrequencyDialogTitle": "Radio horizon calculation", @@ -2068,7 +2283,6 @@ "radioStats_stripWaiting": "Fetching radio stats…", "radioStats_settingsTile": "Radio stats", "radioStats_settingsSubtitle": "Noise floor, RSSI, SNR, and airtime", - "translation_title": "Translation", "translation_enableTitle": "Enable translation", "translation_enableSubtitle": "Translate incoming messages and allow pre-send translation.", @@ -2121,5 +2335,36 @@ } }, "translation_translationOptions": "Translation options", - "translation_systemLanguage": "System language" + "translation_systemLanguage": "System language", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown" } diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index ac9527b..d4cf27d 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -52,7 +52,7 @@ } } }, - "scanner_title": "MeshCore Open", + "scanner_title": "MeshCore: Versión abierta", "scanner_scanning": "Escaneando dispositivos...", "scanner_connecting": "Conectando...", "scanner_disconnecting": "Desconectando...", @@ -104,6 +104,8 @@ "settings_privacyModeEnabled": "Modo de privacidad activado", "settings_privacyModeDisabled": "Modo de privacidad desactivado", "settings_actions": "Acciones", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Enviar Anuncio", "settings_sendAdvertisementSubtitle": "Presencia de transmisión ahora", "settings_advertisementSent": "Anuncio enviado", @@ -121,7 +123,7 @@ "settings_appDebugLog": "Registro de Depuración de la App", "settings_appDebugLogSubtitle": "Mensajes de depuración de la aplicación", "settings_about": "Acerca de", - "settings_aboutVersion": "MeshCore Open v{version}", + "settings_aboutVersion": "MeshCore Open versión {version}", "@settings_aboutVersion": { "placeholders": { "version": { @@ -164,19 +166,19 @@ "appSettings_themeDark": "Oscuro", "appSettings_language": "Idioma", "appSettings_languageSystem": "Predeterminado del sistema", - "appSettings_languageEn": "English", - "appSettings_languageFr": "Français", + "appSettings_languageEn": "Inglés", + "appSettings_languageFr": "Francés", "appSettings_languageEs": "Español", - "appSettings_languageDe": "Deutsch", - "appSettings_languagePl": "Polski", - "appSettings_languageSl": "Slovenščina", - "appSettings_languagePt": "Português", + "appSettings_languageDe": "Alemán", + "appSettings_languagePl": "Polaco", + "appSettings_languageSl": "Esloveno", + "appSettings_languagePt": "Portugués", "appSettings_languageIt": "Italiano", - "appSettings_languageZh": "中文", - "appSettings_languageSv": "Svenska", - "appSettings_languageNl": "Nederlands", - "appSettings_languageSk": "Slovenčina", - "appSettings_languageBg": "Български", + "appSettings_languageZh": "Chino", + "appSettings_languageSv": "Sueco", + "appSettings_languageNl": "Neerlandés", + "appSettings_languageSk": "Esloveno", + "appSettings_languageBg": "Bulgaro", "appSettings_notifications": "Notificaciones", "appSettings_enableNotifications": "Habilitar Notificaciones", "appSettings_enableNotificationsSubtitle": "Recibir notificaciones para mensajes y anuncios", @@ -209,8 +211,8 @@ } }, "appSettings_batteryChemistryConnectFirst": "Conéctate a un dispositivo para elegir", - "appSettings_batteryNmc": "18650 NMC (3.0-4.2V)", - "appSettings_batteryLifepo4": "LiFePO4 (2.6-3.65V)", + "appSettings_batteryNmc": "18650 NMC (3,0-4,2 V)", + "appSettings_batteryLifepo4": "LiFePO4 (2.6-3.65 V)", "appSettings_batteryLipo": "LiPo (3.0-4.2V)", "appSettings_mapDisplay": "Visualización del Mapa", "appSettings_showRepeaters": "Mostrar Repetidores", @@ -298,7 +300,7 @@ "contacts_noContactsMatchFilter": "No hay contactos que coincidan con tu filtro", "contacts_noMembers": "No miembros", "contacts_lastSeenNow": "Última vez que se vio ahora", - "contacts_lastSeenMinsAgo": "~ {minutes} min.", + "contacts_lastSeenMinsAgo": "~ {minutes} minutos", "@contacts_lastSeenMinsAgo": { "placeholders": { "minutes": { @@ -337,11 +339,8 @@ } } }, - "channels_hashtagChannel": "Canal con hashtag", "channels_public": "Público", "channels_private": "Privado", - "channels_publicChannel": "Canal público", - "channels_privateChannel": "Canal privado", "channels_editChannel": "Editar canal", "channels_muteChannel": "Silenciar canal", "channels_unmuteChannel": "Activar canal", @@ -388,6 +387,22 @@ } }, "channels_smazCompression": "Compresión SMAZ", + "channels_cyr2latCompression": "Compresión Cyr2Lat", + "channels_cyr2latCompressionDscr": "Reemplaza algunos caracteres cirílicos con caracteres latinos al enviar.", + "channels_cyr2latSettingsHeading": "Configuración de Cyr2Lat", + "channels_cyr2latSettingsSubheading": "Lista de sustituciones", + "channels_cyr2latSettingsDscr": "Editar la configuración JSON de sustitución de caracteres", + "channels_cyr2latSettingsDialogHint": "Mapa JSON de sustituciones", + "channels_cyr2latSettingsDialogWrongJSON": "JSON incorrecto: {error}", + "settings_cyr2latProfileAdd": "Añadir perfil Cyr2Lat", + "settings_cyr2latProfileName": "Nombre del perfil", + "settings_cyr2latProfileNameEmpty": "El nombre del perfil no puede estar vacío", + "settings_cyr2latProfileAdded": "Perfil añadido correctamente", + "settings_cyr2latProfileUpdated": "Perfil actualizado correctamente", + "settings_cyr2latProfileEdit": "Editar perfil Cyr2Lat", + "settings_cyr2latProfileDelete": "Eliminar perfil Cyr2Lat", + "settings_cyr2latProfileDeleted": "Perfil eliminado correctamente", + "settings_cyr2latProfileDeleteDscr": "¿Está seguro de que desea eliminar el perfil \"{name}\"?", "channels_channelUpdated": "Canal \"{name}\" actualizado", "@channels_channelUpdated": { "placeholders": { @@ -399,7 +414,7 @@ "channels_publicChannelAdded": "Canal público añadido", "channels_sortBy": "Ordenar por", "channels_sortManual": "Manual", - "channels_sortAZ": "A-Z", + "channels_sortAZ": "De la A a la Z", "channels_sortLatestMessages": "Últimos mensajes", "channels_sortUnread": "Sin leer", "chat_noMessages": "Aún no hay mensajes", @@ -463,7 +478,7 @@ "emojiCategoryObjects": "Objetos", "gifPicker_title": "Elegir un GIF", "gifPicker_searchHint": "Buscar GIFs...", - "gifPicker_poweredBy": "Powered by GIPHY", + "gifPicker_poweredBy": "Con tecnología de GIPHY", "gifPicker_noGifsFound": "No se encontraron GIFs", "gifPicker_failedLoad": "No se pudo cargar los GIFs", "gifPicker_failedSearch": "No se encontraron GIFs", @@ -531,7 +546,7 @@ } } }, - "debugFrame_textTypeCli": "CLI", + "debugFrame_textTypeCli": "Interfaz de línea de comandos", "debugFrame_textTypePlain": "Sencillo", "debugFrame_text": "- Texto: \"{text}\"", "@debugFrame_text": { @@ -550,7 +565,7 @@ "chat_pathHistoryFull": "El historial de rutas está completo. Eliminar entradas para añadir nuevas.", "chat_hopSingular": "salta", "chat_hopPlural": "salta", - "chat_hopsCount": "{count} {count, plural, =1{hop} other{hops}}", + "chat_hopsCount": "{count} {count, plural, =1{salto} other{saltos}}", "@chat_hopsCount": { "placeholders": { "count": { @@ -645,7 +660,7 @@ "map_repeater": "Repetidor", "map_room": "Habitación", "map_sensor": "Sensor", - "map_pinDm": "Pin (DM)", + "map_pinDm": "Etiqueta (DM)", "map_pinPrivate": "Bloqueo (Privado)", "map_pinPublic": "Clave (Pública)", "map_lastSeen": "Última vez que se vio", @@ -881,9 +896,9 @@ "repeater_managementTools": "Herramientas de Gestión", "repeater_status": "Estado", "repeater_statusSubtitle": "Ver el estado, las estadísticas y los vecinos del repetidor", - "repeater_telemetry": "Telemetry", + "repeater_telemetry": "Telemetría", "repeater_telemetrySubtitle": "Ver la telemetría de los sensores y las estadísticas del sistema", - "repeater_cli": "CLI", + "repeater_cli": "Interfaz de línea de comandos", "repeater_cliSubtitle": "Enviar comandos al repetidor", "repeater_settings": "Configuración", "repeater_settingsSubtitle": "Configurar parámetros del repetidor", @@ -1059,6 +1074,81 @@ }, "repeater_confirm": "Confirmar", "repeater_settingsSaved": "Guardado de ajustes exitoso", + "repeater_rxGain": "Aumento en la ganancia de RX", + "repeater_rxGainHelper": "Mayor sensibilidad, mayor consumo de corriente (solo para SX1262/SX1268)", + "repeater_refreshRxGain": "Aumenta el rendimiento de RX con la nueva versión.", + "repeater_multiAcks": "Múltiples respuestas de confirmación", + "repeater_multiAcksSubtitle": "Reconocer mensajes a través de múltiples vías para una mejor entrega.", + "repeater_refreshMultiAcks": "Reenviar múltiples confirmaciones", + "repeater_networkHealth": "Salud de la red", + "repeater_loopDetect": "Detección de bucles", + "repeater_loopDetectHelper": "Crea paquetes de \"flujo\" que parezcan bucles de enrutamiento.", + "repeater_loopDetectOff": "Fuera", + "repeater_loopDetectMinimal": "Mínimo", + "repeater_loopDetectModerate": "Moderado", + "repeater_loopDetectStrict": "Estrictos", + "repeater_dutyCycle": "Ciclo de trabajo", + "repeater_dutyCycleHelper": "Porcentaje máximo de tiempo de antena", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Información del operador", + "repeater_ownerInfoHelper": "Metadatos públicos para este repetidor", + "repeater_refreshOwnerInfo": "Actualizar información del operador", + "repeater_floodMax": "Máximo número de saltos en caso de inundación", + "repeater_floodMaxHelper": "Número máximo de paquetes de flujo que un nodo puede enviar (0-64)", + "repeater_advancedSettings": "Avanzado", + "repeater_advancedSettingsSubtitle": "Perillas de ajuste para operadores experimentados", + "repeater_pathHashMode": "Modo de hash de ruta", + "repeater_pathHashModeHelper": "Bytes utilizados para codificar el ID de este repetidor en las etiquetas de ruta/detección de bucles. 0=1 byte (256 IDs, hasta 64 saltos), 1=2 bytes (65.000 IDs, hasta 32 saltos), 2=3 bytes (16 millones de IDs, hasta 21 saltos). Las versiones 1.13 y anteriores de firmware eliminan rutas de múltiples bytes; solo se detectan una vez que la red está activa en la versión 1.14 o posterior.", + "repeater_txDelay": "Retraso en Flood, TX", + "repeater_txDelayHelper": "Ajuste de retransmisión para el tráfico de inundación, como un multiplicador del tiempo de transmisión del paquete (0-2, valor predeterminado 0.5). Un valor más alto significa menos colisiones, pero una entrega más lenta.", + "repeater_directTxDelay": "Retraso directo en TX", + "repeater_directTxDelayHelper": "Reenvío de espacios para el tráfico directo (no masivo), como un multiplicador del tiempo de transmisión del paquete (0-2, valor predeterminado 0.3).", + "repeater_intThresh": "Límite de interferencia", + "repeater_intThreshHelper": "Se establece un umbral para la calibración del nivel de ruido de la radio, de modo que rechaza las interferencias que superen este nivel. 0 deshabilita — solo aumente este valor si observa errores en una banda de frecuencia con mucho ruido.", + "repeater_agcResetInterval": "Intervalo de reinicio de AGC", + "repeater_agcResetIntervalHelper": "¿Con qué frecuencia se debe restablecer el control automático de ganancia del radio para recuperarse de un estado de ganancia bloqueada? Se puede restablecer cada pocos segundos, o cada 4 segundos. Desactivar la función de restablecimiento periódico.", + "repeater_actionsTitle": "Acciones", + "repeater_sendAdvert": "Enviar anuncio sobre inundaciones", + "repeater_sendAdvertSubtitle": "Transmite un anuncio sobre inundaciones a través de la red.", + "repeater_sendAdvertZeroHop": "Enviar anuncio sin intermediarios", + "repeater_sendAdvertZeroHopSubtitle": "Transmite un anuncio de un solo salto (sin retransmisiones).", + "repeater_clockSync": "Sincronizar reloj ahora", + "repeater_clockSyncSubtitle": "Envía la hora de tu teléfono al repetidor.", + "repeater_actionSucceeded": "{action} succeeded", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} failed: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Configuración guardada — reinicie el repetidor para aplicar los cambios.", + "repeater_settingsPartialFailure": "Algunas configuraciones no se pudieron aplicar: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Error al guardar la configuración: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1070,11 +1160,9 @@ "repeater_refreshBasicSettings": "Actualizar Configuración Básica", "repeater_refreshRadioSettings": "Actualizar Ajustes de Radio", "repeater_refreshTxPower": "Actualizar TX de energía", - "repeater_refreshLocationSettings": "Actualizar Configuración de Ubicación", "repeater_refreshPacketForwarding": "Actualizar Enrutamiento de Paquetes", "repeater_refreshGuestAccess": "Actualizar Acceso Invitados", "repeater_refreshPrivacyMode": "Actualizar Modo Privacidad", - "repeater_refreshAdvertisementSettings": "Actualizar Configuración de Anuncios", "repeater_refreshed": "{label} actualizado", "@repeater_refreshed": { "placeholders": { @@ -1347,7 +1435,7 @@ "listFilter_sortBy": "Ordenar por", "listFilter_latestMessages": "Últimos mensajes", "listFilter_heardRecently": "Escuchado recientemente", - "listFilter_az": "A-Z", + "listFilter_az": "De la A a la Z", "listFilter_filters": "Filtros", "listFilter_all": "Todas", "listFilter_users": "Usuarios", @@ -1950,13 +2038,6 @@ "contact_teleBaseSubtitle": "Permitir el intercambio de nivel de batería y telemetría básica", "contact_teleEnv": "Entorno de Telemetría", "contact_teleEnvSubtitle": "Permitir el intercambio de datos de sensores de entorno", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_initialRouteWeight": "Peso inicial de la ruta", "appSettings_maxRouteWeight": "Peso máximo permitido para la ruta", "appSettings_initialRouteWeightSubtitle": "Peso inicial para rutas recién descubiertas", @@ -1969,7 +2050,7 @@ "appSettings_maxMessageRetriesSubtitle": "Número de intentos de reintento antes de marcar un mensaje como fallido.", "path_routeWeight": "{weight}/{max}", "settings_telemetryModeUpdated": "Modo de telemetría actualizado", - "settings_multiAck": "Multi-ACKs: {value}", + "settings_multiAck": "Múltiples respuestas de confirmación", "map_showOverlaps": "Superposiciones de tecla repetidora", "map_runTraceWithReturnPath": "Volver atrás por el mismo camino.", "@radioStats_noiseFloor": { @@ -2101,5 +2182,162 @@ "repeater_guest": "Información sobre repetidores", "chat_sendMessage": "Enviar mensaje", "repeater_guestTools": "Herramientas para invitados", - "room_guest": "Información del servidor" + "room_guest": "Información del servidor", + "repeater_getCategory": "Obtener valores", + "repeater_powerMgmt": "Gestión de la energía", + "repeater_sensors": "Sensores", + "repeater_cliHelpPowerOff": "Apaga el dispositivo. (no se espera respuesta)", + "repeater_cliHelpClkReboot": "Restablece el reloj a una fecha conocida y reinicia el dispositivo.", + "repeater_cliHelpAdvertZeroHop": "Envía un anuncio que no requiere saltos (solo para los vecinos inmediatos).", + "repeater_cliHelpStartOta": "Inicia una actualización de firmware por aire en las placas compatibles.", + "repeater_cliHelpTime": "Establece la hora del dispositivo en los segundos correspondientes a la época Unix. La hora no puede retroceder.", + "repeater_cliHelpBoard": "Muestra el fabricante de la placa base / identificador de hardware.", + "repeater_cliHelpDiscoverNeighbors": "Envía una solicitud de descubrimiento de nodos a los vecinos cercanos. (Solo para repetidores)", + "repeater_cliHelpPowersaving": "Indica si el modo de ahorro de energía está activado o desactivado.", + "repeater_cliHelpPowersavingOnOff": "Activa o desactiva el modo de ahorro de energía (si está disponible).", + "repeater_cliHelpErase": "(Solo para dispositivos) Formatea el sistema de archivos del dispositivo. Elimina todas las configuraciones y contactos.", + "repeater_cliHelpSetDutyCycle": "Establece el ciclo de transmisión máximo permitido como un porcentaje (1-100). Ajusta internamente el factor de tiempo de aire.", + "repeater_cliHelpSetPrvKey": "(Solo para series) Reemplaza la clave privada de identificación del dispositivo. Se requiere reiniciar para aplicar. Genera una nueva clave pública.", + "repeater_cliHelpSetRadioRxGain": "(Solo para SX126x) Activa/desactiva el amplificador de la RX para mejorar la sensibilidad a corrientes más altas.", + "repeater_cliHelpSetOwnerInfo": "Define la cadena de información de contacto del propietario que se incluye en los anuncios. Utilice '|' para indicar nuevas líneas.", + "repeater_cliHelpSetPathHashMode": "Establece el modo de hash de la ruta. 0 = antiguo, 1 = estándar, 2 = estricto. Afecta la forma en que se comparan las rutas.", + "repeater_cliHelpSetLoopDetect": "Establece la sensibilidad para la detección de bucles de enrutamiento: apagado, mínimo, moderado o estricto.", + "repeater_cliHelpSetFreq": "(Solo para la configuración de frecuencia) Establece rápidamente la frecuencia deseada. Se requiere reiniciar. Se recomienda utilizar la opción \"configurar radio\" para obtener todos los parámetros de la radio.", + "repeater_cliHelpSetBridgeChannel": "(Solo para el puente ESPNow) Establece el canal de WiFi (1-14) que utiliza el puente.", + "repeater_cliHelpGetName": "Muestra el nombre del nodo configurado.", + "repeater_cliHelpGetRole": "Muestra el rol del firmware (Repetidor, Servidor de habitación, etc.).", + "repeater_cliHelpGetPublicKey": "Muestra la clave pública del dispositivo.", + "repeater_cliHelpGetPrvKey": "(Solo para uso en serie) Muestra la clave privada del dispositivo. Trátala como una información confidencial.", + "repeater_cliHelpGetRepeat": "Indica si el enrutamiento de paquetes (función de repetidor) está activado o desactivado.", + "repeater_cliHelpGetTx": "Muestra la potencia actual en dBm.", + "repeater_cliHelpGetFreq": "Muestra la frecuencia de radio configurada en MHz.", + "repeater_cliHelpGetRadio": "Muestra todos los parámetros de radio: frecuencia, ancho de banda, factor de dispersión, tasa de codificación.", + "repeater_cliHelpGetRadioRxGain": "(Solo para SX126x) Muestra el estado de ganancia amplificada del receptor.", + "repeater_cliHelpGetAf": "Muestra el factor de tiempo actual.", + "repeater_cliHelpGetDutyCycle": "Muestra el ciclo de trabajo actual permitido como un porcentaje.", + "repeater_cliHelpGetIntThresh": "Muestra el umbral de interferencia del canal en dB.", + "repeater_cliHelpGetAgcResetInterval": "Muestra el intervalo de reinicio del AGC en segundos.", + "repeater_cliHelpGetMultiAcks": "Indica si el modo de confirmación doble está activado (1) o desactivado (0).", + "repeater_cliHelpGetAllowReadOnly": "Indica si se permite el acceso de solo lectura para los usuarios invitados.", + "repeater_cliHelpGetAdvertInterval": "Muestra el intervalo de publicidad local en minutos.", + "repeater_cliHelpGetFloodAdvertInterval": "Muestra el intervalo de publicidad para la emisión de la señal de inundación, expresado en horas.", + "repeater_cliHelpGetGuestPassword": "Muestra la contraseña de invitado configurada.", + "repeater_cliHelpGetLat": "Muestra la latitud configurada.", + "repeater_cliHelpGetLon": "Muestra la longitud configurada.", + "repeater_cliHelpGetRxDelay": "Muestra el valor base de rxdelay.", + "repeater_cliHelpGetTxDelay": "Muestra el factor de retardo en modo de inundación.", + "repeater_cliHelpGetDirectTxDelay": "Muestra el factor de retardo en modo directo.", + "repeater_cliHelpGetFloodMax": "Muestra el número máximo de saltos por inundación.", + "repeater_cliHelpGetOwnerInfo": "Muestra la cadena de información de contacto del propietario.", + "repeater_cliHelpGetPathHashMode": "Muestra el modo de hash de ruta (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Muestra la sensibilidad en la detección de bucles.", + "repeater_cliHelpGetAcl": "(Solo para series) Enumera las entradas de control de acceso en un repetidor.", + "repeater_cliHelpGetBridgeEnabled": "Indica si el puente está habilitado.", + "repeater_cliHelpGetBridgeDelay": "Muestra el retardo del puente en milisegundos.", + "repeater_cliHelpGetBridgeSource": "Indica si el puente está enviando o recibiendo paquetes RX o TX.", + "repeater_cliHelpGetBridgeBaud": "(Solo puente RS232) Muestra la velocidad de transmisión del puente.", + "repeater_cliHelpGetBridgeChannel": "(Solo para el puente ESPNow) Muestra el canal WiFi del puente.", + "repeater_cliHelpGetBridgeSecret": "(Solo para el puente ESPNow) Muestra el secreto compartido por el puente.", + "repeater_cliHelpGetBootloaderVer": "(Solo NRF52) Muestra la versión del cargador.", + "repeater_cliHelpGetAdcMultiplier": "Muestra el multiplicador del ADC (escalado de voltaje de la batería).", + "repeater_cliHelpGetPwrMgtSupport": "Indica si el sistema cuenta con funciones de gestión de energía.", + "repeater_cliHelpGetPwrMgtSource": "Indica la fuente de energía actual: externa o batería.", + "repeater_cliHelpGetPwrMgtBootReason": "Muestra las razones más recientes de reinicio y apagado.", + "repeater_cliHelpGetPwrMgtBootMv": "Muestra el voltaje de la batería al encender el sistema en milivoltios (mV).", + "repeater_cliHelpSensorGet": "Lee una configuración de sensor personalizada mediante una tecla.", + "repeater_cliHelpSensorSet": "Crea una configuración personalizada para un sensor.", + "repeater_cliHelpSensorList": "Muestra todas las configuraciones de sensores personalizadas, paginadas a partir de un índice de inicio opcional.", + "repeater_cliHelpRegionDefault": "Muestra el ámbito predeterminado actual.", + "repeater_cliHelpRegionDefaultSet": "Establece el ámbito regional predeterminado. Utilice \"\" para restablecer a la configuración predeterminada.", + "repeater_cliHelpRegionListAllowed": "Enumera las regiones que permiten el paso de vehículos debido a inundaciones.", + "repeater_cliHelpRegionListDenied": "Enumera las regiones que prohíben el tráfico debido a las inundaciones.", + "repeater_cliHelpStatsPackets": "(Solo para series) Muestra estadísticas a nivel de paquetes.", + "repeater_cliHelpStatsRadio": "(Solo para transmisiones en serie) Muestra estadísticas de radio.", + "repeater_cliHelpStatsCore": "(Solo para series) Muestra estadísticas clave del firmware.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "map_sharedAt": "Compartido", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losBlockedSpotsTitle": "Espacios ocupados", + "losBlockedSpotsHint": "Seleccione un punto bloqueado para resaltarlo en el mapa.", + "losSelectedObstructionTitle": "Obstrucción seleccionada", + "losSelectedObstructionDetails": "Bloqueado por {obstruction} a una altura de {heightUnit}, a {distanceFromA} metros de A y a {distanceFromB} metros de B ({distanceUnit}).", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "settings_companionDebugLog": "Registro de depuración asociado", + "chat_newMessages": "Nuevos mensajes", + "settings_companionDebugLogSubtitle": "Comandos, respuestas y datos brutos para protocolos BLE/TCP/USB", + "chat_markAsUnread": "Marcar como no leído", + "repeater_chanUtil": "Utilización del canal" } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index a942aa2..7817c20 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -9,7 +9,7 @@ }, "@@locale": "fr", "appTitle": "MeshCore Open", - "nav_contacts": "Contacts", + "nav_contacts": "Coordonnées", "nav_channels": "Canaux", "nav_map": "Carte", "common_cancel": "Annuler", @@ -104,6 +104,8 @@ "settings_privacyModeEnabled": "Mode de confidentialité activé", "settings_privacyModeDisabled": "Mode de confidentialité désactivé", "settings_actions": "Actions", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "S'annoncer", "settings_sendAdvertisementSubtitle": "Présence diffusée maintenant", "settings_advertisementSent": "Annonce envoyée", @@ -121,7 +123,7 @@ "settings_appDebugLog": "Journal de débogage de l'application", "settings_appDebugLogSubtitle": "Messages de débogage de l'application", "settings_about": "À propos", - "settings_aboutVersion": "MeshCore Open v{version}", + "settings_aboutVersion": "MeshCore Open {version}", "@settings_aboutVersion": { "placeholders": { "version": { @@ -132,7 +134,7 @@ "settings_aboutLegalese": "Projet MeshCore Open Source 2026", "settings_aboutDescription": "Un client Flutter open source pour les appareils de réseau mesh MeshCore LoRa.", "settings_infoName": "Nom", - "settings_infoId": "ID", + "settings_infoId": "Numéro d'identification", "settings_infoStatus": "État", "settings_infoBattery": "Batterie", "settings_infoPublicKey": "Clé Publique", @@ -164,19 +166,19 @@ "appSettings_themeDark": "Sombre", "appSettings_language": "Langue", "appSettings_languageSystem": "Par défaut du système", - "appSettings_languageEn": "English", + "appSettings_languageEn": "Anglais", "appSettings_languageFr": "Français", - "appSettings_languageEs": "Español", - "appSettings_languageDe": "Deutsch", - "appSettings_languagePl": "Polski", - "appSettings_languageSl": "Slovenščina", - "appSettings_languagePt": "Português", - "appSettings_languageIt": "Italiano", - "appSettings_languageZh": "中文", - "appSettings_languageSv": "Svenska", - "appSettings_languageNl": "Nederlands", - "appSettings_languageSk": "Slovenčina", - "appSettings_languageBg": "Български", + "appSettings_languageEs": "Espagnol", + "appSettings_languageDe": "Allemand", + "appSettings_languagePl": "Polonais", + "appSettings_languageSl": "Sloveno", + "appSettings_languagePt": "Portugais", + "appSettings_languageIt": "Italien", + "appSettings_languageZh": "Chinois", + "appSettings_languageSv": "Suédois", + "appSettings_languageNl": "Néerlandais", + "appSettings_languageSk": "Slovène", + "appSettings_languageBg": "Bulgare", "appSettings_notifications": "Notifications", "appSettings_enableNotifications": "Activer les Notifications", "appSettings_enableNotificationsSubtitle": "Recevoir des notifications pour les messages et les annonces", @@ -254,7 +256,7 @@ "appSettings_appDebugLoggingSubtitle": "Enregistrez les messages de débogage de l'application Log pour le dépannage.", "appSettings_appDebugLoggingEnabled": "Journalisation de débogage de l'application activée", "appSettings_appDebugLoggingDisabled": "Le débogage de l'application est désactivé.", - "contacts_title": "Contacts", + "contacts_title": "Coordonnées", "contacts_noContacts": "Aucun contact trouvé.", "contacts_contactsWillAppear": "Les contacts apparaîtront lorsque les appareils font leur annonce.", "contacts_searchContacts": "Rechercher des contacts...", @@ -298,7 +300,7 @@ "contacts_noContactsMatchFilter": "Aucun contact ne correspond à votre filtre.", "contacts_noMembers": "Aucun membre", "contacts_lastSeenNow": "Vu maintenant", - "contacts_lastSeenMinsAgo": "~ {minutes} min.", + "contacts_lastSeenMinsAgo": "~ {minutes} minutes.", "@contacts_lastSeenMinsAgo": { "placeholders": { "minutes": { @@ -337,11 +339,8 @@ } } }, - "channels_hashtagChannel": "Canal avec hashtag", "channels_public": "Public", "channels_private": "Privé", - "channels_publicChannel": "Canal public", - "channels_privateChannel": "Canal privé", "channels_editChannel": "Modifier le canal", "channels_muteChannel": "Désactiver les notifications du canal", "channels_unmuteChannel": "Réactiver les notifications du canal", @@ -367,7 +366,7 @@ "channels_channelName": "Nom du canal", "channels_usePublicChannel": "Utiliser le canal public", "channels_standardPublicPsk": "PSK public standard", - "channels_pskHex": "PSK (Hex)", + "channels_pskHex": "PSK (Hexadécimal)", "channels_generateRandomPsk": "Générer une clé de modulation PSK aléatoire", "channels_enterChannelName": "Veuillez entrer un nom de canal", "channels_pskMustBe32Hex": "Le PKS doit être composé de 32 caractères hexadécimaux.", @@ -388,6 +387,22 @@ } }, "channels_smazCompression": "Compression SMAZ", + "channels_cyr2latCompression": "Compression Cyr2Lat", + "channels_cyr2latCompressionDscr": "Remplace certains caractères cyrilliques par des caractères latins lors de l'envoi.", + "channels_cyr2latSettingsHeading": "Paramètres Cyr2Lat", + "channels_cyr2latSettingsSubheading": "Liste des remplacements", + "channels_cyr2latSettingsDscr": "Modifier la configuration JSON des remplacements de caractères", + "channels_cyr2latSettingsDialogHint": "Tableau de remplacement JSON", + "channels_cyr2latSettingsDialogWrongJSON": "JSON incorrect : {error}", + "settings_cyr2latProfileAdd": "Ajouter un profil Cyr2Lat", + "settings_cyr2latProfileName": "Nom du profil", + "settings_cyr2latProfileNameEmpty": "Le nom du profil ne peut pas être vide", + "settings_cyr2latProfileAdded": "Profil ajouté avec succès", + "settings_cyr2latProfileUpdated": "Profil mis à jour avec succès", + "settings_cyr2latProfileEdit": "Modifier le profil Cyr2Lat", + "settings_cyr2latProfileDelete": "Supprimer le profil Cyr2Lat", + "settings_cyr2latProfileDeleted": "Profil supprimé avec succès", + "settings_cyr2latProfileDeleteDscr": "Êtes-vous sûr de vouloir supprimer le profil \"{name}\"?", "channels_channelUpdated": "Le canal \"{name}\" a été mis à jour", "@channels_channelUpdated": { "placeholders": { @@ -496,7 +511,7 @@ } }, "debugFrame_textMessageHeader": "Message :", - "debugFrame_destinationPubKey": "- Destination PubKey: {pubKey}", + "debugFrame_destinationPubKey": "- Clé publique de destination : {pubKey}", "@debugFrame_destinationPubKey": { "placeholders": { "pubKey": { @@ -641,7 +656,7 @@ } } }, - "map_chat": "Chat", + "map_chat": "Conversation", "map_repeater": "Répéteur", "map_room": "Room Server", "map_sensor": "Capteur", @@ -994,7 +1009,7 @@ "repeater_frequencyMhz": "Fréquence (MHz)", "repeater_frequencyHelper": "300-2500 MHz", "repeater_txPower": "TX Puissance", - "repeater_txPowerHelper": "1-30 dBm", + "repeater_txPowerHelper": "1 à 30 dBm", "repeater_bandwidth": "Bande passante", "repeater_spreadingFactor": "Facteur de répartition (SF)", "repeater_codingRate": "Taux de codage (CR)", @@ -1059,6 +1074,81 @@ }, "repeater_confirm": "Confirmer", "repeater_settingsSaved": "Les paramètres ont été enregistrés avec succès.", + "repeater_rxGain": "Augmentation du rendement de RX", + "repeater_rxGainHelper": "Meilleure sensibilité, consommation de courant plus élevée (uniquement pour les modèles SX1262/SX1268)", + "repeater_refreshRxGain": "Renforcer les gains de RX grâce à la mise à jour", + "repeater_multiAcks": "Plusieurs accusés de réception", + "repeater_multiAcksSubtitle": "Valider les messages via plusieurs chemins pour une meilleure livraison.", + "repeater_refreshMultiAcks": "Renvoyer plusieurs accusés de réception", + "repeater_networkHealth": "Santé du réseau", + "repeater_loopDetect": "Détection de boucles", + "repeater_loopDetectHelper": "Envoyer des paquets de données qui semblent former des boucles de routage.", + "repeater_loopDetectOff": "Prix", + "repeater_loopDetectMinimal": "Minimal", + "repeater_loopDetectModerate": "Modéré", + "repeater_loopDetectStrict": "Strict", + "repeater_dutyCycle": "Cycle de fonctionnement", + "repeater_dutyCycleHelper": "Pourcentage maximal de temps d'antenne", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Informations sur l'opérateur", + "repeater_ownerInfoHelper": "Métadonnées publiques pour cet émetteur", + "repeater_refreshOwnerInfo": "Rafraîchir les informations sur l'opérateur", + "repeater_floodMax": "Nombre maximal de sauts lors des inondations", + "repeater_floodMaxHelper": "Nombre maximal de paquets de données qu'un flux peut transmettre (0-64)", + "repeater_advancedSettings": "Avancé", + "repeater_advancedSettingsSubtitle": "Molettes de réglage pour les opérateurs expérimentés", + "repeater_pathHashMode": "Mode de hachage de chemin", + "repeater_pathHashModeHelper": "Octets utilisés pour encoder l'ID de ce routeur dans les balises de détection de flux/boucles. 0 = 1 octet (256 ID, jusqu'à 64 sauts), 1 = 2 octets (65 000 ID, jusqu'à 32 sauts), 2 = 3 octets (16 millions d'ID, jusqu'à 21 sauts). Les versions 1.13 et antérieures utilisent des chemins multi-octets ; à partir de la version 1.14, cela n'est plus nécessaire.", + "repeater_txDelay": "Retard dû aux inondations à Texas", + "repeater_txDelayHelper": "Rétransmettre l'espacement pour le trafic de secours en cas de inondation, en multipliant le temps d'émission du paquet (0-2, valeur par défaut : 0,5). Une valeur plus élevée signifie moins de collisions, mais une vitesse de transmission plus lente.", + "repeater_directTxDelay": "Retard de transmission direct", + "repeater_directTxDelayHelper": "Rétransmettre l'espacement pour le trafic direct (non-inondation), en multipliant le temps de transmission des paquets (0-2, valeur par défaut : 0,3).", + "repeater_intThresh": "Seuil de perturbation", + "repeater_intThreshHelper": "Seuil dépassé pour la calibration du niveau de bruit de la radio, afin de rejeter les interférences supérieures à ce niveau. 0 désactive – ne mettez cette valeur que si vous constatez des erreurs RX dans une bande de fréquences bruyante.", + "repeater_agcResetInterval": "Interval de réinitialisation de l'AGC", + "repeater_agcResetIntervalHelper": "À quelle fréquence réinitialiser le contrôle automatique du gain de la radio pour revenir à un état normal ? Chaque seconde, ou à chaque multiple de 4. Désactiver la réinitialisation périodique avec 0.", + "repeater_actionsTitle": "Actions", + "repeater_sendAdvert": "Envoyer une publicité sur les inondations", + "repeater_sendAdvertSubtitle": "Diffuser une publicité sur les inondations via le réseau.", + "repeater_sendAdvertZeroHop": "Envoyer une publicité sans intermédiaire", + "repeater_sendAdvertZeroHopSubtitle": "Diffuser une publicité d'un seul saut (sans relais)", + "repeater_clockSync": "Synchroniser l'heure maintenant", + "repeater_clockSyncSubtitle": "Envoyez l'heure de votre téléphone au répéteur.", + "repeater_actionSucceeded": "{action} a réussi", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} a échoué : {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Paramètres sauvegardés — redémarrer le répéteur pour appliquer les modifications.", + "repeater_settingsPartialFailure": "Certaines configurations ont échoué : {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Erreur lors de la sauvegarde des paramètres : {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1070,11 +1160,9 @@ "repeater_refreshBasicSettings": "Rafraîchir les paramètres de base", "repeater_refreshRadioSettings": "Rafraîchir les paramètres Radio", "repeater_refreshTxPower": "Rafraîchir la tension TX", - "repeater_refreshLocationSettings": "Rafraîchir les paramètres de localisation", "repeater_refreshPacketForwarding": "Rafraîchir le routage des paquets", "repeater_refreshGuestAccess": "Rafraîchir l'accès invité", "repeater_refreshPrivacyMode": "Rafraîchir le Mode Confidentialité", - "repeater_refreshAdvertisementSettings": "Rafraîchir les Paramètres des annonces", "repeater_refreshed": "{label} rafraîchi", "@repeater_refreshed": { "placeholders": { @@ -1352,7 +1440,7 @@ "listFilter_all": "Tout", "listFilter_users": "Utilisateurs", "listFilter_repeaters": "Répéteurs", - "listFilter_roomServers": "Room servers", + "listFilter_roomServers": "Serveurs de salle", "listFilter_unreadOnly": "Messages non lus seulement", "listFilter_newGroup": "Nouveau groupe", "@neighbors_errorLoading": { @@ -1459,7 +1547,7 @@ } } }, - "common_ok": "OK", + "common_ok": "D'accord", "community_title": "Communauté", "community_create": "Créer une Communauté", "community_createDesc": "Créer une nouvelle communauté et la partager via QR code.", @@ -1922,13 +2010,6 @@ "contact_lastSeen": "Dernière fois vu", "contact_clearChat": "Effacer la conversation", "contact_teleBaseSubtitle": "Autoriser le partage du niveau de batterie et de la télémétrie de base", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_maxRouteWeightSubtitle": "Poids maximal qu'un itinéraire peut accumuler grâce à des livraisons réussies.", "appSettings_initialRouteWeight": "Poids initial de l'itinéraire", "appSettings_maxRouteWeight": "Poids maximal autorisé pour le trajet", @@ -1940,7 +2021,6 @@ "appSettings_maxMessageRetries": "Nombre maximal de tentatives de récupération de messages", "appSettings_maxMessageRetriesSubtitle": "Nombre de tentatives de relance avant de marquer un message comme ayant échoué.", "path_routeWeight": "{weight}/{max}", - "settings_multiAck": "Multi-ACKs : {value}", "settings_telemetryModeUpdated": "Le mode télémétrie a été mis à jour", "map_showOverlaps": "Chevauchement de la touche répétitive", "map_runTraceWithReturnPath": "Revenir sur le même chemin.", @@ -2073,5 +2153,170 @@ "repeater_guestTools": "Outils pour les invités", "chat_sendMessage": "Envoyer un message", "room_guest": "Informations sur le serveur", - "repeater_guest": "Informations sur les répéteurs" + "repeater_guest": "Informations sur les répéteurs", + "@notification_messagesCount": { + "placeholders": { + "count": { + "type": "int" + } + } + }, + "repeater_getCategory": "Obtenir des valeurs", + "repeater_powerMgmt": "Gestion de l'énergie", + "repeater_sensors": "Capteurs", + "repeater_cliHelpPowerOff": "Éteint l'appareil. (aucune réponse n'est attendue)", + "repeater_cliHelpClkReboot": "Réinitialise l'horloge à une époque connue et redémarre l'appareil.", + "repeater_cliHelpAdvertZeroHop": "Envoie une publicité sans intermédiaire (uniquement aux voisins immédiats).", + "repeater_cliHelpStartOta": "Démarre une mise à jour du firmware par voie radio sur les cartes prises en charge.", + "repeater_cliHelpTime": "Définit l'heure de l'appareil sur les secondes de l'époque Unix spécifiée. L'heure ne peut pas reculer.", + "repeater_cliHelpBoard": "Indique le fabricant du panneau / l'identifiant du matériel.", + "repeater_cliHelpDiscoverNeighbors": "Envoie une requête de découverte de nœuds aux voisins proches. (Uniquement pour les répéteurs)", + "repeater_cliHelpPowersaving": "Indique si le mode d'économie d'énergie est activé ou désactivé.", + "repeater_cliHelpPowersavingOnOff": "Active ou désactive le mode d'économie d'énergie (si pris en charge).", + "repeater_cliHelpErase": "(Uniquement pour les appareils) Formate le système de fichiers de l'appareil. Efface tous les paramètres et les contacts.", + "repeater_cliHelpSetDutyCycle": "Définit le cycle de transmission maximal autorisé en pourcentage (de 1 à 100). Ajuste automatiquement le facteur de temps d'émission.", + "repeater_cliHelpSetPrvKey": "(Uniquement pour les séries) Remplace la clé privée d'identification de l'appareil. Un redémarrage est nécessaire pour appliquer. Génère une nouvelle clé publique.", + "repeater_cliHelpSetRadioRxGain": "(Uniquement pour les SX126x) Active le gain RX amplifié pour une meilleure sensibilité à des courants plus élevés.", + "repeater_cliHelpSetOwnerInfo": "Définit la chaîne d'informations de contact du propriétaire, qui figure dans les annonces. Utilisez '|' pour les sauts de ligne.", + "repeater_cliHelpSetPathHashMode": "Définit le mode de hachage de chemin. 0 = mode ancien, 1 = mode standard, 2 = mode strict. Influence la façon dont les chemins de routage sont correspondus.", + "repeater_cliHelpSetLoopDetect": "Définit la sensibilité de la détection des boucles de routage : désactivée, minimale, modérée ou stricte.", + "repeater_cliHelpSetFreq": "(Uniquement pour les modèles série) Permet de régler rapidement la fréquence. Redémarrage nécessaire. Il est préférable d'utiliser l'option \"réglage radio\" pour configurer tous les paramètres radio.", + "repeater_cliHelpSetBridgeChannel": "(Uniquement pour le pont ESPNow) Définit le canal WiFi (de 1 à 14) utilisé par le pont.", + "repeater_cliHelpGetName": "Affiche le nom du nœud configuré.", + "repeater_cliHelpGetRole": "Indique le rôle du firmware (répéteur, serveur de pièce, etc.).", + "repeater_cliHelpGetPublicKey": "Affiche la clé publique du dispositif.", + "repeater_cliHelpGetPrvKey": "(Uniquement pour les séries) Affiche la clé privée de l'appareil. Traitez-la comme une information confidentielle.", + "repeater_cliHelpGetRepeat": "Indique si le transfert de paquets (en tant que routeur) est activé ou désactivé.", + "repeater_cliHelpGetTx": "Indique la puissance actuelle en dBm.", + "repeater_cliHelpGetFreq": "Affiche la fréquence radio configurée en MHz.", + "repeater_cliHelpGetRadio": "Affiche tous les paramètres radio : fréquence, largeur de bande, facteur de dispersion, taux de codage.", + "repeater_cliHelpGetRadioRxGain": "(Uniquement pour les SX126x) Affiche l'état du gain amplifié de la réception.", + "repeater_cliHelpGetAf": "Indique le facteur de temps d'antenne actuel.", + "repeater_cliHelpGetDutyCycle": "Affiche le cycle de fonctionnement actuel autorisé en pourcentage.", + "repeater_cliHelpGetIntThresh": "Indique le seuil d'interférence du canal en dB.", + "repeater_cliHelpGetAgcResetInterval": "Indique l'intervalle de réinitialisation de l'AGC en secondes.", + "repeater_cliHelpGetMultiAcks": "Indique si le mode \"double ACK\" est activé (1) ou désactivé (0).", + "repeater_cliHelpGetAllowReadOnly": "Indique si l'accès en lecture seule pour les invités est autorisé.", + "repeater_cliHelpGetAdvertInterval": "Indique l'intervalle publicitaire local en minutes.", + "repeater_cliHelpGetFloodAdvertInterval": "Indique l'intervalle publicitaire pour la diffusion de l'annonce en heures.", + "repeater_cliHelpGetGuestPassword": "Affiche le mot de passe invité configuré.", + "repeater_cliHelpGetLat": "Affiche la latitude configurée.", + "repeater_cliHelpGetLon": "Affiche la longitude configurée.", + "repeater_cliHelpGetRxDelay": "Affiche la valeur de base de rxdelay.", + "repeater_cliHelpGetTxDelay": "Indique le facteur de délai de transmission en mode inondation.", + "repeater_cliHelpGetDirectTxDelay": "Indique le facteur de délai direct.", + "repeater_cliHelpGetFloodMax": "Indique le nombre maximal de fois où le niveau de l'eau a atteint son point culminant.", + "repeater_cliHelpGetOwnerInfo": "Affiche la chaîne d'informations de contact du propriétaire.", + "repeater_cliHelpGetPathHashMode": "Affiche le mode \"hash de chemin\" (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Illustre la sensibilité à la détection des boucles.", + "repeater_cliHelpGetAcl": "(Uniquement pour les séries) Liste les entrées de contrôle d'accès sur un répéteur.", + "repeater_cliHelpGetBridgeEnabled": "Indique si le pont est activé.", + "repeater_cliHelpGetBridgeDelay": "Indique le délai du pont en millisecondes.", + "repeater_cliHelpGetBridgeSource": "Indique si le pont transmet des paquets RX ou TX.", + "repeater_cliHelpGetBridgeBaud": "(Uniquement pour le pont RS232) Affiche la vitesse de communication du pont.", + "repeater_cliHelpGetBridgeChannel": "(Uniquement pour le pont ESPNow) Affiche le canal WiFi du pont.", + "repeater_cliHelpGetBridgeSecret": "(Uniquement pour le pont ESPNow) Affiche la clé partagée du pont.", + "repeater_cliHelpGetBootloaderVer": "(Uniquement pour le NRF52) Affiche la version du chargeur initial.", + "repeater_cliHelpGetAdcMultiplier": "Affiche le multiplicateur de l'ADC (mise à l'échelle de la tension de la batterie).", + "repeater_cliHelpGetPwrMgtSupport": "Indique si le système dispose de fonctionnalités de gestion de l'alimentation.", + "repeater_cliHelpGetPwrMgtSource": "Indique la source d'alimentation actuelle : externe ou batterie.", + "repeater_cliHelpGetPwrMgtBootReason": "Indique les raisons les plus récentes de réinitialisation et d'arrêt.", + "repeater_cliHelpGetPwrMgtBootMv": "Affiche la tension de la batterie au démarrage, en millivolts (mV).", + "repeater_cliHelpSensorGet": "Lit une valeur de configuration personnalisée pour un capteur en utilisant une touche.", + "repeater_cliHelpSensorSet": "Crée une configuration personnalisée pour un capteur.", + "repeater_cliHelpSensorList": "Affiche toutes les configurations de capteurs personnalisées, avec une pagination à partir d'un index de départ optionnel.", + "repeater_cliHelpRegionDefault": "Affiche la portée régionale par défaut actuelle.", + "repeater_cliHelpRegionDefaultSet": "Définit la portée régionale par défaut. Utilisez \"\" pour la réinitialiser.", + "repeater_cliHelpRegionListAllowed": "Énumère les régions autorisant la circulation des véhicules en cas de inondation.", + "repeater_cliHelpRegionListDenied": "Liste des régions qui interdisent la circulation en cas de inondation.", + "repeater_cliHelpStatsPackets": "(Uniquement pour les séries) Affiche des statistiques au niveau des paquets.", + "repeater_cliHelpStatsRadio": "(Uniquement pour les séries) Affiche les statistiques de la radio.", + "repeater_cliHelpStatsCore": "(Uniquement pour les séries) Affiche les statistiques du micrologicem intégré.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "settings_multiAck": "Plusieurs accusés de réception", + "map_sharedAt": "Partagé", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losSelectedObstructionTitle": "Obstruction sélectionnée", + "losBlockedSpotsTitle": "Places occupés", + "losBlockedSpotsHint": "Sélectionnez un emplacement bloqué pour le mettre en évidence sur la carte.", + "losSelectedObstructionDetails": "Bloqué par {obstruction}, à une hauteur de {heightUnit}, à une distance de {distanceFromA} par rapport à A et à une distance de {distanceFromB} par rapport à B ({distanceUnit}).", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "settings_companionDebugLog": "Journal de débogage associé", + "chat_markAsUnread": "Signaler comme non lu", + "chat_newMessages": "Nouveaux messages", + "settings_companionDebugLogSubtitle": "Commandes, réponses et données brutes pour les protocoles BLE/TCP/USB", + "repeater_chanUtil": "Utilisation du canal" } diff --git a/lib/l10n/app_hu.arb b/lib/l10n/app_hu.arb index 6f43463..9742618 100644 --- a/lib/l10n/app_hu.arb +++ b/lib/l10n/app_hu.arb @@ -167,6 +167,8 @@ "settings_privacyModeEnabled": "Adatvédelem mód beállítva", "settings_privacyModeDisabled": "Adatvédelem mód kikapcsolva", "settings_actions": "Tevékenységek", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Hirdetés küldése", "settings_sendAdvertisementSubtitle": "A nyilvános megjelenés", "settings_advertisementSent": "Hirdetés elküldve", @@ -489,11 +491,8 @@ } } }, - "channels_hashtagChannel": "Hashtag-ok közössége", "channels_public": "A nyilvánosság számára", "channels_private": "Személyes", - "channels_publicChannel": "Össztávos csatorna", - "channels_privateChannel": "Személyes csatorna", "channels_editChannel": "Csatorna szerkesztése", "channels_muteChannel": "Csendes csatorna", "channels_unmuteChannel": "Engedje be a hangot", @@ -548,6 +547,22 @@ } }, "channels_smazCompression": "SMAZ kompresszió", + "channels_cyr2latCompression": "Cyr2Lat kompresszió", + "channels_cyr2latCompressionDscr": "Néhány Cirill betűt Latin betűkkel helyettesít küldéskor.", + "channels_cyr2latSettingsHeading": "Cyr2Lat beállítások", + "channels_cyr2latSettingsSubheading": "Helyettesítési lista", + "channels_cyr2latSettingsDscr": "A karakterhelyettesítési JSON-konfiguráció szerkesztése", + "channels_cyr2latSettingsDialogHint": "JSON-csere táblázat", + "channels_cyr2latSettingsDialogWrongJSON": "Hibás JSON: {error}", + "settings_cyr2latProfileAdd": "Cyr2Lat-profil hozzáadása", + "settings_cyr2latProfileName": "Profil neve", + "settings_cyr2latProfileNameEmpty": "A profil neve nem lehet üres", + "settings_cyr2latProfileAdded": "A profil hozzáadása sikeres", + "settings_cyr2latProfileUpdated": "A profil frissítése sikeres", + "settings_cyr2latProfileEdit": "Cyr2Lat profil szerkesztése", + "settings_cyr2latProfileDelete": "Cyr2Lat profil törlése", + "settings_cyr2latProfileDeleted": "A profil törlése sikeresen megtörtént", + "settings_cyr2latProfileDeleteDscr": "Biztosan törölni szeretné a \"{name}\" profilt?", "channels_channelUpdated": "A {name} csatorna frissítve", "@channels_channelUpdated": { "placeholders": { @@ -1245,6 +1260,81 @@ }, "repeater_confirm": "Beküldve", "repeater_settingsSaved": "Beállítások sikeresen mentve", + "repeater_rxGain": "Nagyobb RX-jel erősítés", + "repeater_rxGainHelper": "Magasabb érzékenység, nagyobb áramfelvétel (csak SX1262/SX1268 esetén)", + "repeater_refreshRxGain": "Újraindított, fokozott RX hatás", + "repeater_multiAcks": "Többszörös visszaigazolások", + "repeater_multiAcksSubtitle": "Ismerje el üzeneteket több úton is, hogy biztosítsa a jobb átadást.", + "repeater_refreshMultiAcks": "Frissítse a többször is kapott visszaigazolásokat.", + "repeater_networkHealth": "Hálózati állapot", + "repeater_loopDetect": "Ciklusok azonosítása", + "repeater_loopDetectHelper": "Készíts olyan \"vízfolyást\" megjelenítő csomagokat, amelyek úgy néznek ki, mint egy hibaút.", + "repeater_loopDetectOff": "Le, kikap", + "repeater_loopDetectMinimal": "Minimális", + "repeater_loopDetectModerate": "Közepes", + "repeater_loopDetectStrict": "Szigorú", + "repeater_dutyCycle": "Munka- és pihenőidő aránya", + "repeater_dutyCycleHelper": "A maximális időszámítás százalékos aránya", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Üzemeltető információ", + "repeater_ownerInfoHelper": "A nyilvánosan elérhető metadatak a repeaterhez", + "repeater_refreshOwnerInfo": "Frissítse az üzemeltető adatokat", + "repeater_floodMax": "A vízmaximumos ugrások", + "repeater_floodMaxHelper": "A legmagasabb szám, amely egy vízszint-csomagban szerepelhet (0-64)", + "repeater_advancedSettings": "Haladó", + "repeater_advancedSettingsSubtitle": "Erkélő kapcsolók tapasztalt kezelők számára", + "repeater_pathHashMode": "Út-hash mód", + "repeater_pathHashModeHelper": "A byte-ok, amelyek az alábbi repeater-ek azonosítójának kódolására szolgálnak a flood-útvonal/ciklus-észlelő címkékben. 0=1 byte (256 azonosító, akár 64 útvonal), 1=2 byte (65 000 azonosító, akár 32 útvonal), 2=3 byte (16 millió azonosító, akár 21 útvonal). A v1.13-as verziótól kezdődően és az azt követő verziókban a több byte-os útvonalak megszűntek – csak egyetlen útvonal létesül, miután a hálózat a v1.14-es verzióra vagy az azt követő verzióra frissült.", + "repeater_txDelay": "Flood TX késés", + "repeater_txDelayHelper": "Újraküldési intervallum árvíz esetén, amely a csomag átviteli idejének (0-2, alapérték 0,5) szorzata. Minél nagyobb az érték, annál kevesebb ütközés, de lassabb a továbbítás.", + "repeater_directTxDelay": "Közvetlen TX késés", + "repeater_directTxDelayHelper": "A közvetlen (nem tömeges) forgalomhoz tartozó adatcsomagok újrádiózására szolgáló intervallum, amely a csomag átviteli idejének (0-2, alapértelmezett érték 0,3) szorzata.", + "repeater_intThresh": "Interferencia határ", + "repeater_intThreshHelper": "A határt a rádió zajszintjének kalibrálására állították, így elutasítja a fenti szint feletti interferenciákat. 0 kikapcsol – csak akkor állítsa be, ha zajos frekvencián RX hibákat észlel.", + "repeater_agcResetInterval": "AGC visszazárási intervallum", + "repeater_agcResetIntervalHelper": "Mennyi időnként kell a rádió automatikus hangerőszabályozását visszaállítani, hogy kijavítsa a problémát? A visszaállítás időtartama: másoderek, amely 4-szeresével osztható. A 0 érték a periodikus visszaállítás kikapcsolását jelzi.", + "repeater_actionsTitle": "Tevékenységek", + "repeater_sendAdvert": "Eljuttass flood hirdetést", + "repeater_sendAdvertSubtitle": "Terjesztse egy árvíz elleni reklámot a hálózaton keresztül.", + "repeater_sendAdvertZeroHop": "Küldj egy közvetlen hirdetést", + "repeater_sendAdvertZeroHopSubtitle": "Adja közzé egyetlen átjáró hirdetést (nincs átjátszás).", + "repeater_clockSync": "Synchronizálja az órát", + "repeater_clockSyncSubtitle": "Állítsa be a telefon időzítését a repeaterhez.", + "repeater_actionSucceeded": "{action} sikert aratott", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} sikertelen: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Beállítások mentve – újraindítsa a repeatert, hogy alkalmazza", + "repeater_settingsPartialFailure": "Bizonyos beállítások nem sikerültek: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Hibás beállítások mentése: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1256,11 +1346,9 @@ "repeater_refreshBasicSettings": "Visszaállítás az alapértékekre", "repeater_refreshRadioSettings": "Frissítse a rádió beállításait", "repeater_refreshTxPower": "Újraindítás TX-támogatással", - "repeater_refreshLocationSettings": "Újraindítás helyszín beállításokkal", "repeater_refreshPacketForwarding": "Csomagok továbbításának frissítése", "repeater_refreshGuestAccess": "Újraindítás vendégHozzáférés", "repeater_refreshPrivacyMode": "Visszaállítás a magánéletvédő módra", - "repeater_refreshAdvertisementSettings": "Újraindítás hirdetés beállítások", "repeater_refreshed": "{label} frissítve", "@repeater_refreshed": { "placeholders": { @@ -2012,13 +2100,6 @@ "radioStats_stripWaiting": "Rádió adatok begyűjtése…", "radioStats_settingsTile": "Rádió statisztikák", "radioStats_settingsSubtitle": "Háttérzaj, RSSI, zaj-sűrűség, és a használat időtartama", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "settings_denyAll": "Elutasítom", "settings_privacySettingsDescription": "Válassza ki, hogy az eszközének melyik információkat oszt meg másokkal.", "settings_privacySubtitle": "Ellenőrizd, hogy milyen információkat osztanak meg.", @@ -2030,7 +2111,6 @@ "settings_telemetryEnvironmentMode": "Adatkapcsolati környezeti mód", "settings_advertLocation": "Reklám megjelenési hely", "settings_advertLocationSubtitle": "A hirdetés tartalmazza a helyszínt.", - "settings_multiAck": "Többszöri visszaigazolások: {value}", "settings_telemetryModeUpdated": "A telemetriamód frissítve", "contact_info": "Kapcsolattartási információk", "contact_settings": "Kapcsolat beállítások", @@ -2111,5 +2191,163 @@ "repeater_guestTools": "Vendégek számára elérhető eszközök", "room_guest": "Szoba szerver információk", "chat_sendMessage": "Üzenet küldése", - "repeater_guest": "Adatok a repeaterről" + "repeater_guest": "Adatok a repeaterről", + "repeater_getCategory": "Szereplő értékek", + "repeater_powerMgmt": "Energiahatékonyság, energiafelhasználás optimalizálása", + "repeater_sensors": "Érzékelők", + "repeater_cliHelpPowerOff": "Át kapcsolja a készüléket. (nincs válasz elvárás)", + "repeater_cliHelpClkReboot": "Visszaállítja az órát egy ismert időpontra, majd újraindítja a készüléket.", + "repeater_cliHelpAdvertZeroHop": "Küld egy közvetlen szomszédoknak szóló hirdetést, amely közvetlen kapcsolatot igényel.", + "repeater_cliHelpStartOta": "Elindítja a vezeték nélküli útvonalon történő firmware frissítést a támogatott kártyákon.", + "repeater_cliHelpTime": "Beállítja a eszköz óráját a megadott Unix-időpont (Unix epoch) időpontra. Az óra nem tud visszanyúlni.", + "repeater_cliHelpBoard": "Megjeleníti a gyártó nevét/a hardver azonosítóját.", + "repeater_cliHelpDiscoverNeighbors": "Kérést küld a közeli eszközöknek, hogy azok is megtalálják egymást. (Csak egy repeater eszköz számára)", + "repeater_cliHelpPowersaving": "Megmutatja, hogy a takarékos üzemmód engedélyezve van-e vagy nem.", + "repeater_cliHelpPowersavingOnOff": "Engedélyezi vagy kikapcsolja a takarékos üzemmódot (ha támogatott).", + "repeater_cliHelpErase": "(Csak sorozatban) Formázza a eszköz fájlrendszerét. Eltávolítja az összes beállítást és a kapcsolatokat.", + "repeater_cliHelpSetDutyCycle": "Beállítja a maximális engedélyezett átviteli időtartamot százalékban (1-100). Belsőleg módosítja az időtartam-szabályozást.", + "repeater_cliHelpSetPrvKey": "(Csak sorozatban) Cseréli a eszköz egyedi kulcsát. Az alkalmazáshoz újraindítás szükséges. Új nyilvános kulcsot generál.", + "repeater_cliHelpSetRadioRxGain": "(Csak SX126x család) A növelt RX erősítést be- és kikapcsolható, így a nagyobb áramfelvétel esetén is javítható a érzékenység.", + "repeater_cliHelpSetOwnerInfo": "Megadja az üvegezésben megjelenő tulajdonos elérhetőségeinek szövegét. Használja a '|' karaktert új sorok elválasztására.", + "repeater_cliHelpSetPathHashMode": "Beállítja a hálózati útvonal-hash módot. 0 = régebbi, 1 = szabványos, 2 = szigorú. Hatással van a hálózati útvonalak megadatalására.", + "repeater_cliHelpSetLoopDetect": "Beállítja a hibaforrás-keresés érzékenységét: kikapcsolva, minimális, közepes vagy szigorú.", + "repeater_cliHelpSetFreq": "(Csak soros mód) Gyorsan beállítja a frekvenciát. A rendszer újraindítás szükséges. A teljes rádióparaméterek beállításához a \"rádió beállítás\" funkciót javaslom.", + "repeater_cliHelpSetBridgeChannel": "(Csak ESPNow híd esetén) Beállítja a híd által használt WiFi-csatornát (1-14).", + "repeater_cliHelpGetName": "Megjeleníti a konfigurált csomópont nevét.", + "repeater_cliHelpGetRole": "Megmutatja a firmware funkcióját (repeater, szobai szerver stb.).", + "repeater_cliHelpGetPublicKey": "Megjeleníti a eszköz nyilvános kulcsát.", + "repeater_cliHelpGetPrvKey": "(Csak soros mód) Megjeleníti a eszköz privát kulcsát. Kezelje titkos információként.", + "repeater_cliHelpGetRepeat": "Megmutatja, hogy a csomagok továbbításának (repeater funkció) engedélyezve van-e vagy nem.", + "repeater_cliHelpGetTx": "Megmutatja a jelenlegi TX (átvitel) teljesítményt dBm-ben.", + "repeater_cliHelpGetFreq": "Megjeleníti a konfigurált rádiófrekvenciát MHz-ben.", + "repeater_cliHelpGetRadio": "Megjeleníti az összes rádióparamétert: frekvencia, sávszélesség, széttétező tényező, kódolási ráta.", + "repeater_cliHelpGetRadioRxGain": "(Csak SX126x családra) Megjeleníti az RX erősítés állapotát.", + "repeater_cliHelpGetAf": "Megmutatja az aktuális időadó tényezőt.", + "repeater_cliHelpGetDutyCycle": "Megmutatja az aktuális engedélyezett működési ciklust százalékban.", + "repeater_cliHelpGetIntThresh": "Megmutatja a csatornák közötti interferencia szintjét dB-ben.", + "repeater_cliHelpGetAgcResetInterval": "Megmutatja az AGC (automatikus gain-kontroll) visszaállítási időt másodpercekben.", + "repeater_cliHelpGetMultiAcks": "Megmutatja, hogy a kettős visszaigazolás (double-ACK) mód engedélyezve van-e (1), vagy kikapcsolva (0).", + "repeater_cliHelpGetAllowReadOnly": "Megmutatja, hogy a vendég csak olvasási jogosítást engedélyez-e.", + "repeater_cliHelpGetAdvertInterval": "Megmutatja a helyi hirdetés időtartamát percenként.", + "repeater_cliHelpGetFloodAdvertInterval": "Megmutatja az aktuális időzítést, amikor megjelenik a vízparti reklám, órákonként.", + "repeater_cliHelpGetGuestPassword": "Megjeleníti a konfigurált vendégjelszót.", + "repeater_cliHelpGetLat": "Megjeleníti a beállított szélességet.", + "repeater_cliHelpGetLon": "Megjeleníti a beállított hosszúságot.", + "repeater_cliHelpGetRxDelay": "Megmutatja az alapértéket a késéshez.", + "repeater_cliHelpGetTxDelay": "Megmutatja a vízszint-érzékelő jelátviteli késésének tényezőjét.", + "repeater_cliHelpGetDirectTxDelay": "Megmutatja a közvetlen módban használt késés tényezőt.", + "repeater_cliHelpGetFloodMax": "Megmutatja a maximális vízszint-emelkedés mértékét.", + "repeater_cliHelpGetOwnerInfo": "Megjeleníti az tulajdonos elérhetőségének szövegét.", + "repeater_cliHelpGetPathHashMode": "Megjeleníti a hash-alapú mód (0/1/2) beállításokat.", + "repeater_cliHelpGetLoopDetect": "Mutatja a cikkszám-azonosító érzékenységet.", + "repeater_cliHelpGetAcl": "(Csak sorozat) A repeateren található hozzáférési szabályok listája.", + "repeater_cliHelpGetBridgeEnabled": "Megmutatja, hogy a híd engedélyezve van-e.", + "repeater_cliHelpGetBridgeDelay": "Megmutatja a hídon bekövetkező késést másodpercben.", + "repeater_cliHelpGetBridgeSource": "Megmutatja, hogy a híd RX vagy TX csomagokat fogad-e.", + "repeater_cliHelpGetBridgeBaud": "(Csak RS232 híd) Megjeleníti a híd sebességét.", + "repeater_cliHelpGetBridgeChannel": "(Csak ESPNow híd) Megjeleníti a híd által használt WiFi csatornát.", + "repeater_cliHelpGetBridgeSecret": "(Csak ESPNow híd esetén) Megjeleníti a híd által megosztott titkos kulcsot.", + "repeater_cliHelpGetBootloaderVer": "(Csak NRF52 esetén) Megjeleníti a bootloader verzióját.", + "repeater_cliHelpGetAdcMultiplier": "A bemeneti feszültség-átalakító (akkumulátor-feszültség-szabályozó) működését mutatja.", + "repeater_cliHelpGetPwrMgtSupport": "Megállapítja, hogy a felügyelet rendelkezik-e energiahatékonysági támogatással.", + "repeater_cliHelpGetPwrMgtSource": "Megmutatja az aktuális energiaforrást: külső vagy akkumulátor.", + "repeater_cliHelpGetPwrMgtBootReason": "Megjeleníti az utolsó újraindítás és leállítás okait.", + "repeater_cliHelpGetPwrMgtBootMv": "Megjeleníti a rendszerindításkor mért akkumulátor feszültséget millivoltban (mV).", + "repeater_cliHelpSensorGet": "Beolvas egy felhasználó által definiált szenzor beállítást kulcs segítségével.", + "repeater_cliHelpSensorSet": "Egyedi szenzorbeállítások létrehozása.", + "repeater_cliHelpSensorList": "Összesíti az összes egyedi szenzor beállításot, oldalanként, opcionális kezdő index alapján.", + "repeater_cliHelpRegionDefault": "Megmutatja a jelenlegi alapértelmezett régió határait.", + "repeater_cliHelpRegionDefaultSet": "Beállítja az alapértelmezett régió hatókörét. Használja a \"\" értéket a törléshez.", + "repeater_cliHelpRegionListAllowed": "Felhasználható területek, ahol árvíz esetén forgalmat engedélyeznek.", + "repeater_cliHelpRegionListDenied": "Felhasznál, amelyek elutasítják a árvíz okozta forgalmat.", + "repeater_cliHelpStatsPackets": "(Csak sorozat) A csomagok szintjén történő statisztikát mutat.", + "repeater_cliHelpStatsRadio": "(Csak sorozat) Mutat rádióstatisztikákat.", + "repeater_cliHelpStatsCore": "(Csak soros mód) A főfirmware-adatokat mutatja.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "settings_multiAck": "Többszörös visszaigazolások", + "map_sharedAt": "Megosztva", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losSelectedObstructionTitle": "Kiválasztott akadály", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losBlockedSpotsHint": "A blokkolt területet megjelölve, hogy a térképen kiemeljük.", + "losBlockedSpotsTitle": "Foglalhatatlan területek", + "losSelectedObstructionDetails": "Elakadt a {obstruction} miatt, {heightUnit} magasságban, {distanceFromA} méterrel A-tól és {distanceFromB} méterrel B-től ({distanceUnit}).", + "chat_markAsUnread": "Merekje olvashatóként", + "chat_newMessages": "Új üzenetek", + "settings_companionDebugLog": "Párhuzamos hibakeresési napló", + "settings_companionDebugLogSubtitle": "BLE/TCP/USB parancsok, válaszok és alapvető adatok", + "repeater_chanUtil": "Csatorna-használat" } diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index 387c8cf..664bcee 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -104,6 +104,8 @@ "settings_privacyModeEnabled": "Modalità privacy abilitata", "settings_privacyModeDisabled": "Modalità privacy disabilitata", "settings_actions": "Azioni", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Invia Annuncio", "settings_sendAdvertisementSubtitle": "Presenza trasmessa ora", "settings_advertisementSent": "Annuncio inviato", @@ -121,7 +123,7 @@ "settings_appDebugLog": "Log di Debug dell'App", "settings_appDebugLogSubtitle": "Messaggi di debug dell'applicazione", "settings_about": "Informazioni", - "settings_aboutVersion": "MeshCore Open v{version}", + "settings_aboutVersion": "MeshCore Open versione {version}", "@settings_aboutVersion": { "placeholders": { "version": { @@ -164,19 +166,19 @@ "appSettings_themeDark": "Scuro", "appSettings_language": "Lingua", "appSettings_languageSystem": "Predefinito di sistema", - "appSettings_languageEn": "English", - "appSettings_languageFr": "Français", - "appSettings_languageEs": "Español", - "appSettings_languageDe": "Deutsch", - "appSettings_languagePl": "Polski", - "appSettings_languageSl": "Slovenščina", - "appSettings_languagePt": "Português", + "appSettings_languageEn": "Inglese", + "appSettings_languageFr": "Francese", + "appSettings_languageEs": "Spagnolo", + "appSettings_languageDe": "Tedesco", + "appSettings_languagePl": "Polacco", + "appSettings_languageSl": "Sloveno", + "appSettings_languagePt": "Portoghese", "appSettings_languageIt": "Italiano", - "appSettings_languageZh": "中文", - "appSettings_languageSv": "Svenska", - "appSettings_languageNl": "Nederlands", - "appSettings_languageSk": "Slovenčina", - "appSettings_languageBg": "Български", + "appSettings_languageZh": "Cinese", + "appSettings_languageSv": "Svedese", + "appSettings_languageNl": "Olandese", + "appSettings_languageSk": "Sloveno", + "appSettings_languageBg": "Bulgaro", "appSettings_notifications": "Notifiche", "appSettings_enableNotifications": "Abilita Notifiche", "appSettings_enableNotificationsSubtitle": "Ricevi notifiche per messaggi e annunci", @@ -337,11 +339,8 @@ } } }, - "channels_hashtagChannel": "Canale hashtag", "channels_public": "Pubblico", "channels_private": "Privato", - "channels_publicChannel": "Canale pubblico", - "channels_privateChannel": "Canale privato", "channels_editChannel": "Modifica canale", "channels_muteChannel": "Silenzia canale", "channels_unmuteChannel": "Attiva notifiche canale", @@ -367,7 +366,7 @@ "channels_channelName": "Nome canale", "channels_usePublicChannel": "Utilizza il canale pubblico", "channels_standardPublicPsk": "PSK pubblico standard", - "channels_pskHex": "PSK (Hex)", + "channels_pskHex": "PSK (esadecimale)", "channels_generateRandomPsk": "Genera una chiave di permutazione casuale", "channels_enterChannelName": "Inserisci un nome per il canale", "channels_pskMustBe32Hex": "PSK deve essere composto da 32 caratteri esadecimali.", @@ -388,6 +387,22 @@ } }, "channels_smazCompression": "Compressione SMAZ", + "channels_cyr2latCompression": "Compressione Cyr2Lat", + "channels_cyr2latCompressionDscr": "Sostituisce alcuni caratteri cirillici con caratteri latini durante l'invio.", + "channels_cyr2latSettingsHeading": "Impostazioni Cyr2Lat", + "channels_cyr2latSettingsSubheading": "Elenco delle sostituzioni", + "channels_cyr2latSettingsDscr": "Modifica la configurazione JSON delle sostituzioni dei caratteri", + "channels_cyr2latSettingsDialogHint": "Mappa JSON delle sostituzioni", + "channels_cyr2latSettingsDialogWrongJSON": "JSON non corretto: {error}", + "settings_cyr2latProfileAdd": "Aggiungi profilo Cyr2Lat", + "settings_cyr2latProfileName": "Nome profilo", + "settings_cyr2latProfileNameEmpty": "Il nome del profilo non può essere vuoto", + "settings_cyr2latProfileAdded": "Profilo aggiunto con successo", + "settings_cyr2latProfileUpdated": "Profilo aggiornato con successo", + "settings_cyr2latProfileEdit": "Modifica profilo Cyr2Lat", + "settings_cyr2latProfileDelete": "Elimina profilo Cyr2Lat", + "settings_cyr2latProfileDeleted": "Profilo eliminato con successo", + "settings_cyr2latProfileDeleteDscr": "Sei sicuro di voler eliminare il profilo \"{name}\"?", "channels_channelUpdated": "Canale \"{name}\" aggiornato", "@channels_channelUpdated": { "placeholders": { @@ -399,7 +414,7 @@ "channels_publicChannelAdded": "Canale pubblico aggiunto", "channels_sortBy": "Ordina per", "channels_sortManual": "Manuale", - "channels_sortAZ": "A-Z", + "channels_sortAZ": "D-Z", "channels_sortLatestMessages": "Ultimi messaggi", "channels_sortUnread": "Non letto", "chat_noMessages": "Nessun messaggio ancora", @@ -456,7 +471,7 @@ "chat_sendGif": "Invia GIF", "chat_reply": "Rispondi", "chat_addReaction": "Aggiungi Reazione", - "chat_me": "Me", + "chat_me": "Io", "emojiCategorySmileys": "Emoji", "emojiCategoryGestures": "Gesti", "emojiCategoryHearts": "Cuori", @@ -504,7 +519,7 @@ } } }, - "debugFrame_timestamp": "- Timestamp: {timestamp}", + "debugFrame_timestamp": "- Marca temporale: {timestamp}", "@debugFrame_timestamp": { "placeholders": { "timestamp": { @@ -881,7 +896,7 @@ "repeater_managementTools": "Strumenti di Gestione", "repeater_status": "Stato", "repeater_statusSubtitle": "Visualizza lo stato, le statistiche e i vicini del ripetitore", - "repeater_telemetry": "Telemetry", + "repeater_telemetry": "Telemetria", "repeater_telemetrySubtitle": "Visualizza i dati di telemetria dei sensori e le statistiche di sistema", "repeater_cli": "CLI", "repeater_cliSubtitle": "Invia comandi al ripetitore", @@ -996,7 +1011,7 @@ "repeater_txPower": "TX Potenza", "repeater_txPowerHelper": "1-30 dBm", "repeater_bandwidth": "Larghezza di banda", - "repeater_spreadingFactor": "Spreading Factor", + "repeater_spreadingFactor": "Fattore di propagazione", "repeater_codingRate": "Tasso di Codifica", "repeater_locationSettings": "Impostazioni Luogo", "repeater_latitude": "Latitudine", @@ -1059,6 +1074,81 @@ }, "repeater_confirm": "Conferma", "repeater_settingsSaved": "Impostazioni salvate con successo", + "repeater_rxGain": "Aumento del guadagno RX", + "repeater_rxGainHelper": "Maggiore sensibilità, maggiore assorbimento di corrente (solo per SX1262/SX1268)", + "repeater_refreshRxGain": "Rafforza l'effetto di RX", + "repeater_multiAcks": "ACK multipli", + "repeater_multiAcksSubtitle": "Riconoscere i messaggi attraverso percorsi multipli per una migliore consegna.", + "repeater_refreshMultiAcks": "Riaffermare più ACK", + "repeater_networkHealth": "Salute della rete", + "repeater_loopDetect": "Rilevamento di cicli", + "repeater_loopDetectHelper": "Crea pacchetti di dati che simulano loop di routing.", + "repeater_loopDetectOff": "Offerte", + "repeater_loopDetectMinimal": "Essenziale", + "repeater_loopDetectModerate": "Moderato", + "repeater_loopDetectStrict": "Rigido", + "repeater_dutyCycle": "Ciclo di lavoro", + "repeater_dutyCycleHelper": "Percentuale massima di utilizzo dello spazio pubblicitario", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Informazioni sull'operatore", + "repeater_ownerInfoHelper": "Metadati pubblici per questo ripetitore", + "repeater_refreshOwnerInfo": "Aggiorna le informazioni sull'operatore", + "repeater_floodMax": "Massimo numero di salti in caso di inondazione", + "repeater_floodMaxHelper": "Numero massimo di pacchetti che un flusso può attraversare (0-64)", + "repeater_advancedSettings": "Avanzato", + "repeater_advancedSettingsSubtitle": "Manopole di regolazione per operatori esperti", + "repeater_pathHashMode": "Modalità di hashing del percorso", + "repeater_pathHashModeHelper": "Byte utilizzati per codificare l'ID di questo ripetitore nei tag per il rilevamento del percorso/loop. 0=1 byte (256 ID, fino a 64 salti), 1=2 byte (65.000 ID, fino a 32 salti), 2=3 byte (16 milioni di ID, fino a 21 salti). Le versioni 1.13 e precedenti utilizzano percorsi multi-byte: è necessario attivare la rete prima di utilizzare questa funzionalità (a partire dalla versione 1.14).", + "repeater_txDelay": "Ritardo a Flood, TX", + "repeater_txDelayHelper": "Riassegnare lo spazio tra i pacchetti per gestire il traffico intenso, come un moltiplicatore del tempo di trasmissione (da 0 a 2, valore predefinito 0,5). Un valore più alto significa meno collisioni, ma una trasmissione più lenta.", + "repeater_directTxDelay": "Ritardo diretto TX", + "repeater_directTxDelayHelper": "Riassegnare lo spazio per il traffico diretto (non di massa), come un moltiplicatore del tempo di trasmissione del pacchetto (da 0 a 2, valore predefinito 0,3).", + "repeater_intThresh": "Soglia di interferenza", + "repeater_intThreshHelper": "Il limite è stato impostato per la calibrazione del livello di rumore del ricevitore, in modo che esso rifiuti i segnali di interferenza superiori a questo livello. 0 disabilita – aumentalo solo se si verificano errori nel ricevitore in una banda di frequenza rumorosa.", + "repeater_agcResetInterval": "Intervallo di ripristino di AGC", + "repeater_agcResetIntervalHelper": "Con quale frequenza è necessario resettare il controllo automatico del guadagno per ripristinare il funzionamento dopo un'interruzione. Impostare su secondi, ridotti a multipli di 4. Disattivare la reimpostazione periodica.", + "repeater_actionsTitle": "Azioni", + "repeater_sendAdvert": "Inviare annuncio relativo alle inondazioni", + "repeater_sendAdvertSubtitle": "Trasmettere un annuncio pubblicitario relativo alle inondazioni attraverso la rete.", + "repeater_sendAdvertZeroHop": "Inviare un annuncio senza intermediari", + "repeater_sendAdvertZeroHopSubtitle": "Trasmettere un annuncio a un solo hop (senza ripetitori)", + "repeater_clockSync": "Sincronizza l'orologio ora", + "repeater_clockSyncSubtitle": "Imposta l'ora del tuo telefono sul ripetitore.", + "repeater_actionSucceeded": "{action} ha avuto successo", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} failed: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Impostazioni salvate — riavviare il ripetitore per applicare le modifiche", + "repeater_settingsPartialFailure": "Alcune impostazioni non sono state salvate: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Errore durante il salvataggio delle impostazioni: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1070,11 +1160,9 @@ "repeater_refreshBasicSettings": "Aggiorna Impostazioni Base", "repeater_refreshRadioSettings": "Aggiorna le Impostazioni Radio", "repeater_refreshTxPower": "Aggiorna TX potenza", - "repeater_refreshLocationSettings": "Aggiorna le Impostazioni della Posizione", "repeater_refreshPacketForwarding": "Aggiorna il inoltro pacchetti", "repeater_refreshGuestAccess": "Aggiorna Accesso Ospite", "repeater_refreshPrivacyMode": "Aggiorna Modalità Privacy", - "repeater_refreshAdvertisementSettings": "Aggiorna le Impostazioni dell'Annuncio", "repeater_refreshed": "{label} aggiornato", "@repeater_refreshed": { "placeholders": { @@ -1347,7 +1435,7 @@ "listFilter_sortBy": "Ordina per", "listFilter_latestMessages": "Ultimi messaggi", "listFilter_heardRecently": "Sentito di recente", - "listFilter_az": "A-Z", + "listFilter_az": "D-Z", "listFilter_filters": "Filtri", "listFilter_all": "Tutti", "listFilter_users": "Utenti", @@ -1459,7 +1547,7 @@ } } }, - "common_ok": "OK", + "common_ok": "Va bene", "community_title": "Comunità", "community_create": "Crea Comunità", "community_createDesc": "Crea una nuova comunità e condividila tramite codice QR.", @@ -1922,13 +2010,6 @@ "contact_teleBaseSubtitle": "Consenti la condivisione del livello della batteria e della telemetria di base", "contact_teleEnvSubtitle": "Consenti la condivisione dei dati del sensore ambientale", "contact_teleEnv": "Ambiente di telemetria", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_initialRouteWeight": "Peso iniziale del percorso", "appSettings_initialRouteWeightSubtitle": "Peso di partenza per nuovi percorsi", "appSettings_maxRouteWeightSubtitle": "Il peso massimo che un percorso può accumulare grazie a consegne di successo.", @@ -1941,7 +2022,7 @@ "appSettings_maxMessageRetriesSubtitle": "Numero di tentativi di riprova prima di considerare un messaggio come fallito.", "path_routeWeight": "{weight}/{max}", "settings_telemetryModeUpdated": "Modalità telemetria aggiornata", - "settings_multiAck": "Multi-ACKs: {value}", + "settings_multiAck": "ACK multipli", "map_showOverlaps": "Sovrapposizioni della chiave ripetitore", "map_runTraceWithReturnPath": "Tornare indietro sullo stesso percorso", "@radioStats_noiseFloor": { @@ -2073,5 +2154,162 @@ "repeater_guest": "Informazioni sul ripetitore", "repeater_guestTools": "Strumenti per gli ospiti", "chat_sendMessage": "Invia messaggio", - "room_guest": "Informazioni sul server" + "room_guest": "Informazioni sul server", + "repeater_getCategory": "Ottenere valori", + "repeater_powerMgmt": "Gestione dell'energia", + "repeater_sensors": "Sensori", + "repeater_cliHelpPowerOff": "Disattiva il dispositivo. (non ci si aspetta alcuna risposta)", + "repeater_cliHelpClkReboot": "Riporta l'orologio a un'epoca nota e riavvia il dispositivo.", + "repeater_cliHelpAdvertZeroHop": "Invia un annuncio che raggiunge solo i vicini immediati (senza passaggi intermedi).", + "repeater_cliHelpStartOta": "Avvia un aggiornamento del firmware tramite la trasmissione radio su schede supportate.", + "repeater_cliHelpTime": "Imposta l'orario del dispositivo sui secondi dell'epoca Unix specificati. L'orario non può andare indietro.", + "repeater_cliHelpBoard": "Indica il produttore della scheda e l'identificatore hardware.", + "repeater_cliHelpDiscoverNeighbors": "Invia una richiesta di scoperta di nodi ai vicini. (Solo per ripetitori)", + "repeater_cliHelpPowersaving": "Indica se la modalità di risparmio energetico è attiva o disattivata.", + "repeater_cliHelpPowersavingOnOff": "Abilita o disabilita la modalità di risparmio energetico (se supportata).", + "repeater_cliHelpErase": "(Solo per sistemi di serializzazione) Formatta il file system del dispositivo. Elimina tutte le impostazioni e i contatti.", + "repeater_cliHelpSetDutyCycle": "Imposta il ciclo di trasmissione massimo consentito in percentuale (da 1 a 100). Regola internamente il fattore di tempo di trasmissione.", + "repeater_cliHelpSetPrvKey": "(Solo per serie) Sostituisce la chiave privata di identificazione del dispositivo. È necessario riavviare il dispositivo per applicare la modifica. Genera una nuova chiave pubblica.", + "repeater_cliHelpSetRadioRxGain": "(Solo per SX126x) Permette di attivare un guadagno RX potenziato per una maggiore sensibilità a correnti più elevate.", + "repeater_cliHelpSetOwnerInfo": "Definisce la stringa contenente le informazioni di contatto del proprietario, presente negli annunci. Utilizzare '|' per i newline.", + "repeater_cliHelpSetPathHashMode": "Imposta la modalità di hashing del percorso. 0 = modalità legacy, 1 = modalità standard, 2 = modalità rigorosa. Influisce su come vengono abbinati i percorsi di routing.", + "repeater_cliHelpSetLoopDetect": "Imposta il livello di sensibilità per il rilevamento dei loop di routing: disattivato, minimo, moderato o rigoroso.", + "repeater_cliHelpSetFreq": "(Solo per la funzione di regolazione della frequenza) Imposta rapidamente la frequenza desiderata. È necessario riavviare il dispositivo. Si consiglia di utilizzare la funzione \"imposta radio\" per impostare tutti i parametri radio.", + "repeater_cliHelpSetBridgeChannel": "(Solo per il bridge ESPNow) Imposta il canale Wi-Fi (da 1 a 14) utilizzato dal bridge.", + "repeater_cliHelpGetName": "Mostra il nome del nodo configurato.", + "repeater_cliHelpGetRole": "Indica il ruolo del firmware (ripetitore, server per stanza, ecc.).", + "repeater_cliHelpGetPublicKey": "Mostra la chiave pubblica del dispositivo.", + "repeater_cliHelpGetPrvKey": "(Solo per serie) Visualizza la chiave privata del dispositivo. Trattala come una informazione riservata.", + "repeater_cliHelpGetRepeat": "Indica se la funzione di inoltro dei pacchetti (funzione di ripetitore) è attiva o disattivata.", + "repeater_cliHelpGetTx": "Mostra la potenza attuale in dBm.", + "repeater_cliHelpGetFreq": "Mostra la frequenza radio configurata in MHz.", + "repeater_cliHelpGetRadio": "Visualizza tutti i parametri radio: frequenza, larghezza di banda, fattore di spreading, tasso di codifica.", + "repeater_cliHelpGetRadioRxGain": "(Solo per i moduli SX126x) Mostra lo stato del guadagno potenziato del RX.", + "repeater_cliHelpGetAf": "Mostra il fattore di trasmissione attuale.", + "repeater_cliHelpGetDutyCycle": "Mostra il ciclo di lavoro attuale consentito in percentuale.", + "repeater_cliHelpGetIntThresh": "Mostra il limite di interferenza del canale in dB.", + "repeater_cliHelpGetAgcResetInterval": "Indica l'intervallo di reset dell'AGC in secondi.", + "repeater_cliHelpGetMultiAcks": "Indica se la modalità \"ACK doppio\" è attiva (1) o disattivata (0).", + "repeater_cliHelpGetAllowReadOnly": "Indica se è consentito l'accesso in sola lettura per gli ospiti.", + "repeater_cliHelpGetAdvertInterval": "Indica l'intervallo pubblicitario locale in minuti.", + "repeater_cliHelpGetFloodAdvertInterval": "Indica l'intervallo pubblicitario per la trasmissione del servizio di allerta alluvioni, espresso in ore.", + "repeater_cliHelpGetGuestPassword": "Visualizza la password del guest configurata.", + "repeater_cliHelpGetLat": "Mostra la latitudine configurata.", + "repeater_cliHelpGetLon": "Mostra la longitudine impostata.", + "repeater_cliHelpGetRxDelay": "Mostra il valore base di rxdelay.", + "repeater_cliHelpGetTxDelay": "Mostra il fattore di ritardo in modalità di allarme.", + "repeater_cliHelpGetDirectTxDelay": "Mostra il fattore di ritardo in modalità diretta.", + "repeater_cliHelpGetFloodMax": "Mostra il numero massimo di salti dovuto all'inondazione.", + "repeater_cliHelpGetOwnerInfo": "Visualizza la stringa contenente le informazioni di contatto del proprietario.", + "repeater_cliHelpGetPathHashMode": "Mostra la modalità \"hash del percorso\" (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Indica la sensibilità alla rilevazione di loop.", + "repeater_cliHelpGetAcl": "(Solo per serie) Elenca le voci di controllo degli accessi su un ripetitore.", + "repeater_cliHelpGetBridgeEnabled": "Indica se il ponte è attivo.", + "repeater_cliHelpGetBridgeDelay": "Mostra il ritardo del ponte in millisecondi.", + "repeater_cliHelpGetBridgeSource": "Indica se il bridge sta inviando pacchetti RX o TX.", + "repeater_cliHelpGetBridgeBaud": "(Solo per l'adattatore RS232) Visualizza la velocità di trasmissione del bridge.", + "repeater_cliHelpGetBridgeChannel": "(Solo per il bridge ESPNow) Visualizza il canale WiFi del bridge.", + "repeater_cliHelpGetBridgeSecret": "(Solo per il bridge ESPNow) Visualizza la chiave segreta condivisa.", + "repeater_cliHelpGetBootloaderVer": "(Solo per NRF52) Visualizza la versione del bootloader.", + "repeater_cliHelpGetAdcMultiplier": "Mostra il moltiplicatore ADC (adattamento della tensione della batteria).", + "repeater_cliHelpGetPwrMgtSupport": "Indica se il sistema dispone di funzionalità di gestione dell'energia.", + "repeater_cliHelpGetPwrMgtSource": "Indica la fonte di alimentazione attuale: esterna o batteria.", + "repeater_cliHelpGetPwrMgtBootReason": "Mostra le ragioni più recenti per il ripristino e lo spegnimento.", + "repeater_cliHelpGetPwrMgtBootMv": "Mostra la tensione della batteria al momento dell'accensione, misurata in millivolt (mV).", + "repeater_cliHelpSensorGet": "Legge un valore di configurazione personalizzato per un sensore tramite un tasto.", + "repeater_cliHelpSensorSet": "Definisce una configurazione personalizzata per un sensore.", + "repeater_cliHelpSensorList": "Elenca tutte le impostazioni personalizzate dei sensori, organizzate in pagine a partire da un indice di inizio opzionale.", + "repeater_cliHelpRegionDefault": "Mostra l'ambito predefinito corrente.", + "repeater_cliHelpRegionDefaultSet": "Definisce l'ambito regionale predefinito. Utilizzare \"\" per cancellare.", + "repeater_cliHelpRegionListAllowed": "Elenca le regioni che consentono il transito di veicoli in caso di allagamenti.", + "repeater_cliHelpRegionListDenied": "Elenca le regioni che vietano il transito in caso di alluvioni.", + "repeater_cliHelpStatsPackets": "(Solo per la visualizzazione dei dati seriali) Mostra statistiche a livello di pacchetto.", + "repeater_cliHelpStatsRadio": "(Solo per serie TV) Visualizza statistiche relative alla trasmissione radiofonica.", + "repeater_cliHelpStatsCore": "(Solo per serie) Visualizza le statistiche del firmware di base.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "map_sharedAt": "Condiviso", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losSelectedObstructionTitle": "Ostacolo selezionato", + "losBlockedSpotsHint": "Tocca un punto bloccato sulla mappa per evidenziarlo.", + "losBlockedSpotsTitle": "Posti occupati", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "settings_companionDebugLogSubtitle": "Comandi, risposte e dati grezzi per protocolli BLE/TCP/USB", + "settings_companionDebugLog": "Registro di debug per il supporto", + "chat_newMessages": "Nuovi messaggi", + "chat_markAsUnread": "Segna come non letto", + "repeater_chanUtil": "Utilizzo del canale" } diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index b63f146..9d2cef2 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -49,7 +49,7 @@ "scanner_title": "MeshCore オープン", "connectionChoiceUsbLabel": "USB", "connectionChoiceBluetoothLabel": "ブルートゥース", - "connectionChoiceTcpLabel": "TCP", + "connectionChoiceTcpLabel": "TCP (Transmission Control Protocol)", "tcpScreenTitle": "TCP を使用して接続", "tcpHostLabel": "IPアドレス", "tcpHostHint": "192.168.40.10", @@ -167,6 +167,8 @@ "settings_privacyModeEnabled": "プライバシーモードが有効になっています", "settings_privacyModeDisabled": "プライバシーモードは無効化されています", "settings_actions": "行動", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "広告を送信する", "settings_sendAdvertisementSubtitle": "現在、放送での活動", "settings_advertisementSent": "広告が送信されました", @@ -489,11 +491,8 @@ } } }, - "channels_hashtagChannel": "ハッシュタグチャンネル", "channels_public": "一般の人々", "channels_private": "個人の", - "channels_publicChannel": "一般チャンネル", - "channels_privateChannel": "プライベートチャンネル", "channels_editChannel": "チャンネルを編集する", "channels_muteChannel": "ミュート機能", "channels_unmuteChannel": "ミュートを解除する", @@ -548,6 +547,22 @@ } }, "channels_smazCompression": "SMAZ 圧縮", + "channels_cyr2latCompression": "Cyr2Lat 圧縮", + "channels_cyr2latCompressionDscr": "送信時に一部のキリル文字をラテン文字に置き換えます。", + "channels_cyr2latSettingsHeading": "cyr2latの設定", + "channels_cyr2latSettingsSubheading": "置換リスト", + "channels_cyr2latSettingsDscr": "文字置換のJSON設定を編集する", + "channels_cyr2latSettingsDialogHint": "JSON置換マップ", + "channels_cyr2latSettingsDialogWrongJSON": "不正なJSON: {error}", + "settings_cyr2latProfileAdd": "Cyr2Latプロファイルの追加", + "settings_cyr2latProfileName": "プロファイル名", + "settings_cyr2latProfileNameEmpty": "プロファイル名は空にできません", + "settings_cyr2latProfileAdded": "プロファイルが正常に追加されました", + "settings_cyr2latProfileUpdated": "プロファイルの更新に成功しました", + "settings_cyr2latProfileEdit": "Cyr2Latプロファイルを編集", + "settings_cyr2latProfileDelete": "Cyr2Latプロファイルを削除", + "settings_cyr2latProfileDeleted": "プロファイルの削除に成功しました", + "settings_cyr2latProfileDeleteDscr": "プロファイル \"{name}\" を削除してもよろしいですか?", "channels_channelUpdated": "チャンネル「{name}」が更新されました", "@channels_channelUpdated": { "placeholders": { @@ -1245,6 +1260,81 @@ }, "repeater_confirm": "確認", "repeater_settingsSaved": "設定が正常に保存されました", + "repeater_rxGain": "RX ゲインの向上", + "repeater_rxGainHelper": "より高い感度、より大きな電流(SX1262/SX1268のみ)", + "repeater_refreshRxGain": "強化されたRX効果を再確認", + "repeater_multiAcks": "複数のACK(応答)", + "repeater_multiAcksSubtitle": "複数の経路でメッセージを送信することで、より確実な配信を実現する。", + "repeater_refreshMultiAcks": "複数のACKをリフレッシュする", + "repeater_networkHealth": "ネットワークの状態", + "repeater_loopDetect": "ループ検出", + "repeater_loopDetectHelper": "ルーティングループに見えるような、洪水パケットを送信する", + "repeater_loopDetectOff": "オフ", + "repeater_loopDetectMinimal": "最小限の", + "repeater_loopDetectModerate": "適度な", + "repeater_loopDetectStrict": "厳格な", + "repeater_dutyCycle": "動作サイクル", + "repeater_dutyCycleHelper": "最大の使用時間割合", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "事業者の情報", + "repeater_ownerInfoHelper": "このリピーターに関する公開メタデータ", + "repeater_refreshOwnerInfo": "オペレーター情報の更新", + "repeater_floodMax": "最大ホップ数", + "repeater_floodMaxHelper": "洪水パケットが移動できる最大ホップ数 (0-64)", + "repeater_advancedSettings": "高度な", + "repeater_advancedSettingsSubtitle": "経験豊富なオペレーター向けの調整ノブ", + "repeater_pathHashMode": "パスハッシュモード", + "repeater_pathHashModeHelper": "このリピーターのIDをフローパス/ループ検出タグにエンコードするために使用されるバイト数。 0=1バイト (256個のID、最大64ホップ)、1=2バイト (65,000個のID、最大32ホップ)、2=3バイト (160万個のID、最大21ホップ)。 v1.13およびそれ以前のファームウェアでは、マルチバイトパスがサポートされていません。 v1.14以降のバージョンでは、一度ネットワークが起動されると、パスが一度だけ検出されます。", + "repeater_txDelay": "フロイド・TXでの遅延", + "repeater_txDelayHelper": "洪水時の交通量に対応するための再送信間隔を、パケットの通信時間を掛けた値(0~2、デフォルト0.5)で設定します。値を大きくすると衝突が減りますが、通信速度が遅くなります。", + "repeater_directTxDelay": "直接的なTX遅延", + "repeater_directTxDelayHelper": "直接(フラッドではない)トラフィックに対する再送信間隔を、パケットの空中時間(0~2、デフォルト0.3)の倍数として設定する。", + "repeater_intThresh": "干渉閾値", + "repeater_intThreshHelper": "ラジオのノイズレベルを基準とする閾値を設定し、このレベルを超えるノイズを抑制します。 0 を設定すると、ノイズの多い帯域で RX エラーが発生した場合のみ、この値を上げることができます。", + "repeater_agcResetInterval": "AGCのリセット間隔", + "repeater_agcResetIntervalHelper": "ラジオの自動ゲイン制御をリセットする頻度について:ゲインが固定状態になった場合に、回復するために、何度リセットするかを設定します。4の倍数でリセットする場合、0を設定すると、定期的なリセットは停止します。", + "repeater_actionsTitle": "行動", + "repeater_sendAdvert": "洪水に関する広告を送信", + "repeater_sendAdvertSubtitle": "ネットワークを通じて、洪水に関する広告を放送する", + "repeater_sendAdvertZeroHop": "ゼロホップ形式の広告を送信する", + "repeater_sendAdvertZeroHopSubtitle": "ワンホップでの広告放送(中継なし)", + "repeater_clockSync": "現在、時刻を同期する", + "repeater_clockSyncSubtitle": "スマートフォンの時刻をルーターに設定する", + "repeater_actionSucceeded": "{action} が成功しました", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} の実行に失敗しました: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "設定を保存しました — リピーターを再起動して適用してください", + "repeater_settingsPartialFailure": "設定の一部でエラーが発生しました:{failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "設定の保存に失敗しました:{error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1256,11 +1346,9 @@ "repeater_refreshBasicSettings": "基本設定をリセットする", "repeater_refreshRadioSettings": "ラジオ設定をリセットする", "repeater_refreshTxPower": "TX の電力レベルをリセットする", - "repeater_refreshLocationSettings": "場所設定をリセットする", "repeater_refreshPacketForwarding": "パケット転送の刷新", "repeater_refreshGuestAccess": "ゲストへのアクセスをリフレッシュする", "repeater_refreshPrivacyMode": "プライバシーモードをリセットする", - "repeater_refreshAdvertisementSettings": "広告設定のリセット", "repeater_refreshed": "{label} が更新されました", "@repeater_refreshed": { "placeholders": { @@ -2012,13 +2100,6 @@ "radioStats_stripWaiting": "ラジオの統計情報を取得中…", "radioStats_settingsTile": "ラジオの統計", "radioStats_settingsSubtitle": "ノイズレベル、RSSI、SNR、および通信時間", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "settings_privacy": "プライバシー設定", "settings_privacySubtitle": "共有する情報の内容を管理する。", "settings_denyAll": "すべてを否定", @@ -2030,7 +2111,6 @@ "settings_telemetryEnvironmentMode": "テレメトリ環境モード", "settings_advertLocation": "広告掲載場所", "settings_advertLocationSubtitle": "広告に場所を記載してください。", - "settings_multiAck": "複数のACK:{value}", "settings_telemetryModeUpdated": "テレメトリモードが更新されました", "contact_info": "連絡先", "contact_settings": "連絡設定", @@ -2111,5 +2191,163 @@ "room_guest": "ルームサーバーに関する情報", "chat_sendMessage": "メッセージを送信する", "repeater_guest": "繰り返し送信に関する情報", - "repeater_guestTools": "ゲスト向けツール" + "repeater_guestTools": "ゲスト向けツール", + "repeater_getCategory": "価値を取得する", + "repeater_powerMgmt": "電力管理", + "repeater_sensors": "センサー", + "repeater_cliHelpPowerOff": "デバイスをシャットダウンします。(応答は期待されていません)", + "repeater_cliHelpClkReboot": "時計を既知の基準時点にリセットし、デバイスを再起動します。", + "repeater_cliHelpAdvertZeroHop": "近隣のデバイスのみに、ゼロホップの広告を送信します。", + "repeater_cliHelpStartOta": "サポートされているボードに対して、無線でファームウェアのアップデートを開始します。", + "repeater_cliHelpTime": "デバイスのクロックを、指定されたUnixエポックの秒数に設定します。クロックは逆方向に進むことはできません。", + "repeater_cliHelpBoard": "製造元の名前/ハードウェア識別子を表示します。", + "repeater_cliHelpDiscoverNeighbors": "近隣のノードに対して、ノードの探索リクエストを送信します。(中継機能のみ)", + "repeater_cliHelpPowersaving": "省電力モードがオンになっているかどうかを表示します。", + "repeater_cliHelpPowersavingOnOff": "省電力モード(対応している場合)を有効または無効にします。", + "repeater_cliHelpErase": "(シリアルモードのみ)デバイスのファイルシステムをフォーマットします。すべての設定と連絡先を消去します。", + "repeater_cliHelpSetDutyCycle": "送信可能な最大デューティサイクルをパーセントで設定します(1〜100)。内部で、空き時間の要素を調整します。", + "repeater_cliHelpSetPrvKey": "(シリアル番号のみ)デバイスのプライベートキーを置き換えます。適用には再起動が必要です。新しいパブリックキーを生成します。", + "repeater_cliHelpSetRadioRxGain": "(SX126xのみ)高電流での使用時に、感度を向上させるために、増幅されたRXのゲインを切り替えることができます。", + "repeater_cliHelpSetOwnerInfo": "広告に記載されている所有者連絡先情報を設定します。改行には'|'を使用してください。", + "repeater_cliHelpSetPathHashMode": "パスハッシュモードを設定します。 0 = 従来のモード、1 = 標準モード、2 = 厳格モード。ルーティングパスのマッチング方法に影響します。", + "repeater_cliHelpSetLoopDetect": "ルーティングループ検出の感度を設定します:オフ、最小、中程度、または厳格。", + "repeater_cliHelpSetFreq": "(シリアル設定のみ)特定の周波数のみを素早く設定できます。再起動が必要です。「ラジオ設定」を使用すると、ラジオのすべてのパラメータを設定できます。", + "repeater_cliHelpSetBridgeChannel": "(ESPNowブリッジのみ)ブリッジで使用するWi-Fiチャンネル(1~14)を設定します。", + "repeater_cliHelpGetName": "設定されたノードの名前を表示します。", + "repeater_cliHelpGetRole": "ファームウェアの役割(リピーター、ルームサーバーなど)を表示します。", + "repeater_cliHelpGetPublicKey": "デバイスの公開鍵を表示します。", + "repeater_cliHelpGetPrvKey": "(シリアル番号のみ)デバイスのプライベートキーを表示します。機密情報として扱ってください。", + "repeater_cliHelpGetRepeat": "パケット転送(リピーター機能)が有効になっているかどうかを表示します。", + "repeater_cliHelpGetTx": "現在のTX(送信)電力のdBm値を表示します。", + "repeater_cliHelpGetFreq": "設定された無線周波数をMHzで表示します。", + "repeater_cliHelpGetRadio": "以下のすべての無線パラメータを表示: 周波数、帯域幅、スプレッドファクター、符号化レート。", + "repeater_cliHelpGetRadioRxGain": "(SX126xのみ) RX の増幅ゲインの状態を表示します。", + "repeater_cliHelpGetAf": "現在の空き時間係数を表示します。", + "repeater_cliHelpGetDutyCycle": "現在の許可されたデューティサイクルをパーセントで表示します。", + "repeater_cliHelpGetIntThresh": "チャンネル干渉の閾値をdBで表示します。", + "repeater_cliHelpGetAgcResetInterval": "AGCのリセット間隔を秒単位で表示します。", + "repeater_cliHelpGetMultiAcks": "ダブルACKモードが有効 (1) か無効 (0) かを示す。", + "repeater_cliHelpGetAllowReadOnly": "ゲストによる読み取り専用アクセスが許可されているかどうかを示す。", + "repeater_cliHelpGetAdvertInterval": "ローカル広告の時間を分単位で表示します。", + "repeater_cliHelpGetFloodAdvertInterval": "洪水に関する広告の放送時間を時間単位で表示します。", + "repeater_cliHelpGetGuestPassword": "設定されたゲストパスワードを表示します。", + "repeater_cliHelpGetLat": "設定された緯度を表示します。", + "repeater_cliHelpGetLon": "設定された経度を表示します。", + "repeater_cliHelpGetRxDelay": "rxdelay の基本値を表示します。", + "repeater_cliHelpGetTxDelay": "洪水モードにおける送信遅延の要因を示します。", + "repeater_cliHelpGetDirectTxDelay": "ダイレクトモードの遅延要素を示します。", + "repeater_cliHelpGetFloodMax": "最大浸水範囲の回数を表示します。", + "repeater_cliHelpGetOwnerInfo": "所有者の連絡先情報を表示します。", + "repeater_cliHelpGetPathHashMode": "パスハッシュモード(0/1/2)を表示します。", + "repeater_cliHelpGetLoopDetect": "ループ検出の感度を示す。", + "repeater_cliHelpGetAcl": "(シリアルのみ)リピーター上のアクセス制御設定を一覧表示します。", + "repeater_cliHelpGetBridgeEnabled": "橋が有効になっているかどうかを表示します。", + "repeater_cliHelpGetBridgeDelay": "橋の遅延時間をミリ秒(ms)で表示します。", + "repeater_cliHelpGetBridgeSource": "RX または TX パケットを橋渡ししているかどうかを示す。", + "repeater_cliHelpGetBridgeBaud": "(RS232 橋渡し機能のみ)橋渡しのボーレートを表示します。", + "repeater_cliHelpGetBridgeChannel": "(ESPNowブリッジのみ)ブリッジで使用しているWi-Fiチャンネルを表示します。", + "repeater_cliHelpGetBridgeSecret": "(ESPNowブリッジのみ)ブリッジで共有されている秘密鍵を表示します。", + "repeater_cliHelpGetBootloaderVer": "(NRF52のみ)ブートローダーのバージョンを表示します。", + "repeater_cliHelpGetAdcMultiplier": "ADC(アナログ-デジタル変換)のマルチプライヤー(バッテリー電圧のスケーリング)を表示します。", + "repeater_cliHelpGetPwrMgtSupport": "取締役会が電力管理機能をサポートしているかどうかを報告します。", + "repeater_cliHelpGetPwrMgtSource": "現在の電源(外部電源またはバッテリー)を表示します。", + "repeater_cliHelpGetPwrMgtBootReason": "最新のリセットおよびシャットダウンの理由を表示します。", + "repeater_cliHelpGetPwrMgtBootMv": "起動時のバッテリー電圧をmVで表示します。", + "repeater_cliHelpSensorGet": "キーを使用して、カスタムセンサーの設定を読み取る。", + "repeater_cliHelpSensorSet": "カスタムセンサーの設定を作成する。", + "repeater_cliHelpSensorList": "カスタムセンサーの設定をすべてリスト表示し、オプションで指定できる開始インデックスからページ分割して表示します。", + "repeater_cliHelpRegionDefault": "現在のデフォルトの地域範囲を表示します。", + "repeater_cliHelpRegionDefaultSet": "デフォルトの地域範囲を設定します。「」を使用すると、設定をリセットできます。", + "repeater_cliHelpRegionListAllowed": "洪水時の通行が許可されている地域の一覧", + "repeater_cliHelpRegionListDenied": "洪水による交通を遮断している地域の一覧", + "repeater_cliHelpStatsPackets": "(シリアルのみ)パケットレベルの統計情報を表示します。", + "repeater_cliHelpStatsRadio": "(シリーズのみ)ラジオの統計情報を表示します。", + "repeater_cliHelpStatsCore": "(シリアルのみ)主要なファームウェアの統計情報を表示します。", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "settings_multiAck": "複数のACK(応答)", + "map_sharedAt": "共有済み", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losBlockedSpotsHint": "地図上で、特定された場所を強調するために、該当する場所をタップしてください。", + "losSelectedObstructionTitle": "選択された障害", + "losBlockedSpotsTitle": "利用できない場所", + "losSelectedObstructionDetails": "{obstruction} によって {heightUnit} の高さで、A地点から {distanceFromA}、B地点から {distanceFromB} ({distanceUnit}) の距離で塞がれています。", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "settings_companionDebugLogSubtitle": "BLE/TCP/USB 関連のコマンド、応答、および生のデータ", + "settings_companionDebugLog": "同伴デバッグログ", + "chat_newMessages": "新しいメッセージ", + "chat_markAsUnread": "未読としてマークする", + "repeater_chanUtil": "チャンネルの利用状況" } diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb index 40721fe..d778429 100644 --- a/lib/l10n/app_ko.arb +++ b/lib/l10n/app_ko.arb @@ -167,6 +167,8 @@ "settings_privacyModeEnabled": "개인 정보 보호 모드 활성화", "settings_privacyModeDisabled": "개인 정보 보호 모드 비활성화", "settings_actions": "행동", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "광고 전송", "settings_sendAdvertisementSubtitle": "방송 활동", "settings_advertisementSent": "광고 전송", @@ -489,11 +491,8 @@ } } }, - "channels_hashtagChannel": "해시태그 채널", "channels_public": "대중의", "channels_private": "사립", - "channels_publicChannel": "공개 채널", - "channels_privateChannel": "개인 채널", "channels_editChannel": "채널 편집", "channels_muteChannel": "음소거 채널", "channels_unmuteChannel": "채널 음소거 해제", @@ -548,6 +547,22 @@ } }, "channels_smazCompression": "SMAZ 압축", + "channels_cyr2latCompression": "Cyr2Lat 압축", + "channels_cyr2latCompressionDscr": "보낼 때 일부 키릴 문자를 라틴 문자로 바꿉니다.", + "channels_cyr2latSettingsHeading": "Cyr2Lat 설정", + "channels_cyr2latSettingsSubheading": "변환 목록", + "channels_cyr2latSettingsDscr": "문자 변환 JSON 구성 편집", + "channels_cyr2latSettingsDialogHint": "JSON 변환 맵", + "channels_cyr2latSettingsDialogWrongJSON": "잘못된 JSON: {error}", + "settings_cyr2latProfileAdd": "Cyr2Lat 프로필 추가", + "settings_cyr2latProfileName": "프로필 이름", + "settings_cyr2latProfileNameEmpty": "프로필 이름은 비워둘 수 없습니다", + "settings_cyr2latProfileAdded": "프로필이 성공적으로 추가되었습니다", + "settings_cyr2latProfileUpdated": "프로필이 성공적으로 업데이트되었습니다", + "settings_cyr2latProfileEdit": "Cyr2Lat 프로필 편집", + "settings_cyr2latProfileDelete": "Cyr2Lat 프로필 삭제", + "settings_cyr2latProfileDeleted": "프로필이 성공적으로 삭제되었습니다", + "settings_cyr2latProfileDeleteDscr": "\"{name}\" 프로필을 삭제하시겠습니까?", "channels_channelUpdated": "채널 \"{name}\"이 업데이트되었습니다.", "@channels_channelUpdated": { "placeholders": { @@ -1245,6 +1260,81 @@ }, "repeater_confirm": "확인", "repeater_settingsSaved": "설정이 성공적으로 저장되었습니다.", + "repeater_rxGain": "향상된 RX 성능", + "repeater_rxGainHelper": "더 높은 감도, 더 많은 전류 소모 (SX1262/SX1268에만 해당)", + "repeater_refreshRxGain": "RX 성능 향상 효과 재확인", + "repeater_multiAcks": "다중 ACK", + "repeater_multiAcksSubtitle": "다양한 경로를 통해 메시지를 확인하여 전달 효율성을 높입니다.", + "repeater_refreshMultiAcks": "다중 ACK 재확인", + "repeater_networkHealth": "네트워크 상태", + "repeater_loopDetect": "루프 감지", + "repeater_loopDetectHelper": "라우팅 루프처럼 보이는 과도한 데이터 패킷을 전송", + "repeater_loopDetectOff": "거기", + "repeater_loopDetectMinimal": "최소", + "repeater_loopDetectModerate": "적당한", + "repeater_loopDetectStrict": "엄격한", + "repeater_dutyCycle": "작동 주기", + "repeater_dutyCycleHelper": "허용되는 최대 방송 시간 비율", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "운영자 정보", + "repeater_ownerInfoHelper": "이 리피터에 대한 공개 메타데이터", + "repeater_refreshOwnerInfo": "운영자 정보 업데이트", + "repeater_floodMax": "최대 홉 수", + "repeater_floodMaxHelper": "최대 패킷이 이동할 수 있는 홉 수 (0-64)", + "repeater_advancedSettings": "고급", + "repeater_advancedSettingsSubtitle": "숙련된 운영자를 위한 조절 노브", + "repeater_pathHashMode": "패스 해시 모드", + "repeater_pathHashModeHelper": "이 리피터의 ID를 플러드 경로/루프 감지 태그에 인코딩하는 데 사용되는 바이트 수: 0=1 바이트 (256개의 ID, 최대 64개의 홉), 1=2 바이트 (65,000개의 ID, 최대 32개의 홉), 2=3 바이트 (16백만 개의 ID, 최대 21개의 홉). v1.13 및 이전 버전의 펌웨어는 다중 바이트 경로를 지원하지 않으며, 네트워크가 v1.14 이상으로 업그레이드되면 한 번만 감지합니다.", + "repeater_txDelay": "플러드 TX 지연", + "repeater_txDelayHelper": "홍수 시 교통량에 맞춰 재전송 간격을 설정합니다. 이는 패킷의 전송 시간을 곱한 값 (0-2, 기본값 0.5)으로 설정합니다. 값이 클수록 충돌이 줄어들지만 전송 속도가 느려집니다.", + "repeater_directTxDelay": "직접적인 TX 지연", + "repeater_directTxDelayHelper": "직접 (대량 전송이 아닌) 트래픽에 대한 재전송 간격을, 패킷의 전송 시간을 곱하여 설정 (0-2, 기본값 0.3).", + "repeater_intThresh": "간섭 허용치", + "repeater_intThreshHelper": "신호의 잡음 수준을 기준으로 작동하며, 이 수준 이상의 간섭은 차단합니다. 0은 비활성화 상태를 의미하며, 잡음이 심한 대역에서 RX 오류가 발생할 경우에만 활성화해야 합니다.", + "repeater_agcResetInterval": "AGC 재설정 간격", + "repeater_agcResetIntervalHelper": "자동 게인 제어를 재설정하여 신호가 불안정해졌을 때 원래 상태로 복구하는 빈도를 설정하는 방법은 다음과 같습니다. 4의 배수 단위로 설정하면 주기적인 재설정이 수행됩니다. 0을 설정하면 주기적인 재설정이 수행되지 않습니다.", + "repeater_actionsTitle": "행동", + "repeater_sendAdvert": "홍수 관련 광고 전송", + "repeater_sendAdvertSubtitle": "네트워크를 통해 홍수 광고를 방송", + "repeater_sendAdvertZeroHop": "제로 홉 광고 전송", + "repeater_sendAdvertZeroHopSubtitle": "단일 중계 (중계 없이) 광고를 송출", + "repeater_clockSync": "현재 시계 동기화", + "repeater_clockSyncSubtitle": "스마트폰의 시간을 리피터로 설정", + "repeater_actionSucceeded": "{action}이 성공적으로 완료되었습니다.", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} 실패: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "설정이 저장되었습니다. 다시 시작하여 설정을 적용하세요.", + "repeater_settingsPartialFailure": "다음 설정에 실패했습니다: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "설정 저장 오류: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1256,11 +1346,9 @@ "repeater_refreshBasicSettings": "기본 설정 초기화", "repeater_refreshRadioSettings": "라디오 설정 초기화", "repeater_refreshTxPower": "TX 전원 재설정", - "repeater_refreshLocationSettings": "위치 설정 초기화", "repeater_refreshPacketForwarding": "패킷 전송 재시작", "repeater_refreshGuestAccess": "게스트 접근 권한 갱신", "repeater_refreshPrivacyMode": "개인 정보 보호 모드 재설정", - "repeater_refreshAdvertisementSettings": "광고 설정 재설정", "repeater_refreshed": "{label}가 갱신됨", "@repeater_refreshed": { "placeholders": { @@ -2012,13 +2100,6 @@ "radioStats_stripWaiting": "라디오 통계 가져오기…", "radioStats_settingsTile": "라디오 통계", "radioStats_settingsSubtitle": "잡음 수준, RSSI, 신호 대 잡음비, 통신 시간", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "settings_privacy": "개인 정보 설정", "settings_privacySubtitle": "어떤 정보를 공유할지 통제하세요.", "settings_privacySettingsDescription": "어떤 정보를 기기가 다른 사람들과 공유할지 선택하세요.", @@ -2030,7 +2111,6 @@ "settings_telemetryEnvironmentMode": "텔레메트리 환경 모드", "settings_advertLocation": "광고 위치", "settings_advertLocationSubtitle": "광고에 위치 정보를 포함하세요.", - "settings_multiAck": "다중 ACK: {value}", "settings_telemetryModeUpdated": "텔레메트리 모드 업데이트 완료", "contact_info": "연락처", "contact_settings": "연락처 설정", @@ -2111,5 +2191,163 @@ "repeater_guestTools": "손님용 도구", "chat_sendMessage": "메시지를 보내기", "repeater_guest": "반복 장비 정보", - "room_guest": "서버 정보" + "room_guest": "서버 정보", + "repeater_getCategory": "가치 얻기", + "repeater_powerMgmt": "전력 관리", + "repeater_sensors": "센서", + "repeater_cliHelpPowerOff": "장치를 끄는 기능 (응답이 없을 것으로 예상)", + "repeater_cliHelpClkReboot": "시계를 알려진 시점으로 재설정하고 장치를 재부팅합니다.", + "repeater_cliHelpAdvertZeroHop": "직접적인 연결 없이 이웃에게만 광고를 전송합니다.", + "repeater_cliHelpStartOta": "지원되는 보드에서 무선으로 펌웨어 업데이트를 시작합니다.", + "repeater_cliHelpTime": "장치를 주어진 유닉스 에포크 초부터 시간으로 설정합니다. 시간은 이전으로 이동할 수 없습니다.", + "repeater_cliHelpBoard": "제조사/하드웨어 식별 정보를 표시합니다.", + "repeater_cliHelpDiscoverNeighbors": "인접한 노드에 대한 탐색 요청을 보냅니다. (리피터만 해당)", + "repeater_cliHelpPowersaving": "절전 모드가 켜져 있는지 확인하는 표시", + "repeater_cliHelpPowersavingOnOff": "절전 모드를 활성화하거나 비활성화할 수 있습니다 (지원되는 경우).", + "repeater_cliHelpErase": "(단일 사용) 장치 파일 시스템을 포맷합니다. 모든 설정 및 연락처를 삭제합니다.", + "repeater_cliHelpSetDutyCycle": "최대 허용 전송 주기(백분율)를 설정합니다(1~100%). 내부적으로 통신 시간을 조정합니다.", + "repeater_cliHelpSetPrvKey": "(시리얼 키만 해당) 장치 식별용 개인 키를 대체합니다. 적용하려면 재부팅이 필요합니다. 새로운 공개 키를 생성합니다.", + "repeater_cliHelpSetRadioRxGain": "(SX126x 전용) 더 높은 전류를 사용할 때 더 나은 감도를 위해 증폭된 RX 감쇠 기능을 전환합니다.", + "repeater_cliHelpSetOwnerInfo": "광고에 포함된 소유자 연락처 정보를 지정합니다. 줄 바꿈을 위해 '|' 문자를 사용합니다.", + "repeater_cliHelpSetPathHashMode": "경로 해시 모드를 설정합니다. 0 = 고전 방식, 1 = 표준 방식, 2 = 엄격한 방식. 경로 매칭 방식에 영향을 미칩니다.", + "repeater_cliHelpSetLoopDetect": "라우팅 루프 감지 감도 설정: 끄기, 최소, 중간, 또는 엄격", + "repeater_cliHelpSetFreq": "(단일 기능) 특정 주파수만 빠르게 설정합니다. 재부팅이 필요합니다. 전체 라디오 파라미터 설정에는 \"라디오 설정\" 기능을 사용하는 것이 좋습니다.", + "repeater_cliHelpSetBridgeChannel": "(ESPNow 브리지만 해당) 브리지에서 사용되는 WiFi 채널(1~14)을 설정합니다.", + "repeater_cliHelpGetName": "구성된 노드의 이름을 표시합니다.", + "repeater_cliHelpGetRole": "펌웨어 역할(리피터, 룸 서버 등)을 보여줍니다.", + "repeater_cliHelpGetPublicKey": "장치의 공개 키를 표시합니다.", + "repeater_cliHelpGetPrvKey": "(전용) 장치의 개인 키를 표시합니다. 비밀 정보로 취급합니다.", + "repeater_cliHelpGetRepeat": "패킷 전달(리피터 기능)이 활성화되어 있는지 여부를 표시합니다.", + "repeater_cliHelpGetTx": "현재 TX 전력(dBm)을 표시합니다.", + "repeater_cliHelpGetFreq": "구성된 무선 주파수를 MHz 단위로 표시합니다.", + "repeater_cliHelpGetRadio": "전체 무선 파라미터 표시: 주파수, 대역폭, 스프레딩 계수, 인코딩 속도", + "repeater_cliHelpGetRadioRxGain": "(SX126x 전용) RX의 증폭 이득 상태를 표시합니다.", + "repeater_cliHelpGetAf": "현재 공기 시간 요소를 보여줍니다.", + "repeater_cliHelpGetDutyCycle": "현재 허용되는 작업 주기를 백분율로 표시합니다.", + "repeater_cliHelpGetIntThresh": "채널 간섭 임계값을 dB 단위로 표시합니다.", + "repeater_cliHelpGetAgcResetInterval": "AGC 재설정 간격을 초 단위로 표시합니다.", + "repeater_cliHelpGetMultiAcks": "더블 ACK 모드가 활성화되어 있는지 (1) 또는 비활성화되어 있는지 (0)를 표시합니다.", + "repeater_cliHelpGetAllowReadOnly": "게스트의 읽기 전용 액세스가 허용되는지 여부를 표시합니다.", + "repeater_cliHelpGetAdvertInterval": "지역 광고 시간 간격을 분 단위로 표시합니다.", + "repeater_cliHelpGetFloodAdvertInterval": "홍수 광고 시간 간격을 시간 단위로 표시합니다.", + "repeater_cliHelpGetGuestPassword": "구성된 게스트 비밀번호를 표시합니다.", + "repeater_cliHelpGetLat": "설정된 위도를 보여줍니다.", + "repeater_cliHelpGetLon": "설정된 경도를 보여줍니다.", + "repeater_cliHelpGetRxDelay": "Rxdelay 기본 값을 표시합니다.", + "repeater_cliHelpGetTxDelay": "홍수 모드에서의 전송 지연 계수를 보여줍니다.", + "repeater_cliHelpGetDirectTxDelay": "직렬 모드에서의 딜레이 계수를 보여줍니다.", + "repeater_cliHelpGetFloodMax": "최대 홍수 발생 횟수를 보여줍니다.", + "repeater_cliHelpGetOwnerInfo": "소유주 연락처 정보를 표시합니다.", + "repeater_cliHelpGetPathHashMode": "경로 해시 모드 (0/1/2)를 표시합니다.", + "repeater_cliHelpGetLoopDetect": "루프 탐지 감도를 보여줍니다.", + "repeater_cliHelpGetAcl": "(단순히 목록만 표시) 리피터에 설정된 접근 제어 항목 목록을 보여줍니다.", + "repeater_cliHelpGetBridgeEnabled": "다리 기능이 활성화되어 있는지 여부를 표시합니다.", + "repeater_cliHelpGetBridgeDelay": "다리 통과 시간(밀리초)을 표시합니다.", + "repeater_cliHelpGetBridgeSource": "브리지 로그가 RX 또는 TX 패킷을 기록하는지 여부를 보여줍니다.", + "repeater_cliHelpGetBridgeBaud": "(RS232 브리지 기능만) 브리지의 보드 속도를 표시합니다.", + "repeater_cliHelpGetBridgeChannel": "(ESPNow 브리지만 해당) 브리지의 Wi-Fi 채널을 표시합니다.", + "repeater_cliHelpGetBridgeSecret": "(ESPNow 브리지만 해당) 브리지에서 공유된 비밀을 표시합니다.", + "repeater_cliHelpGetBootloaderVer": "(NRF52만 해당) 부팅 로더 버전을 표시합니다.", + "repeater_cliHelpGetAdcMultiplier": "배터리 전압을 스케일링하는 ADC 멀티플라이어를 보여줍니다.", + "repeater_cliHelpGetPwrMgtSupport": "이 보드가 전력 관리 기능을 지원하는지 여부를 나타냅니다.", + "repeater_cliHelpGetPwrMgtSource": "현재 전원 공급 장치 (외부 전원 또는 배터리)를 표시합니다.", + "repeater_cliHelpGetPwrMgtBootReason": "가장 최근 재설정 및 종료 이유를 보여줍니다.", + "repeater_cliHelpGetPwrMgtBootMv": "부팅 시 배터리 전압을 mV 단위로 표시합니다.", + "repeater_cliHelpSensorGet": "키를 사용하여 사용자 정의 센서 설정을 읽습니다.", + "repeater_cliHelpSensorSet": "사용자 정의 센서 설정을 작성합니다.", + "repeater_cliHelpSensorList": "사용자 정의 센서 설정 목록을, 선택적으로 지정된 시작 인덱스부터 페이지 나누어 표시합니다.", + "repeater_cliHelpRegionDefault": "현재 기본 지역 범위를 보여줍니다.", + "repeater_cliHelpRegionDefaultSet": "기본 지역 범위를 설정합니다. \"\"을 사용하여 초기화합니다.", + "repeater_cliHelpRegionListAllowed": "홍수 피해 차량 통행이 가능한 지역 목록", + "repeater_cliHelpRegionListDenied": "홍수 발생 시 통행 금지 지역 목록", + "repeater_cliHelpStatsPackets": "(전송 속도만 표시) 패킷 수준의 통계 정보를 보여줍니다.", + "repeater_cliHelpStatsRadio": "(특정 시리즈만 해당) 라디오 통계 정보를 표시합니다.", + "repeater_cliHelpStatsCore": "(시리얼 번호만 표시) 핵심 펌웨어 통계 정보를 보여줍니다.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "settings_multiAck": "다중 ACK", + "map_sharedAt": "공유됨", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losBlockedSpotsHint": "지도에서 특정 위치를 강조하려면 해당 위치를 클릭하세요.", + "losBlockedSpotsTitle": "차단된 공간", + "losSelectedObstructionTitle": "선택된 장애물", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "settings_companionDebugLog": "동반 디버깅 로그", + "chat_newMessages": "새로운 메시지", + "settings_companionDebugLogSubtitle": "BLE/TCP/USB 명령어, 응답 및 원시 데이터", + "chat_markAsUnread": "미리 읽지 않음으로 표시", + "repeater_chanUtil": "채널 활용도" } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 2c1342d..159d755 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -202,6 +202,12 @@ abstract class AppLocalizations { /// **'Close'** String get common_close; + /// No description provided for @common_done. + /// + /// In en, this message translates to: + /// **'Done'** + String get common_done; + /// No description provided for @common_edit. /// /// In en, this message translates to: @@ -355,13 +361,13 @@ abstract class AppLocalizations { /// No description provided for @tcpHostLabel. /// /// In en, this message translates to: - /// **'IP Address'** + /// **'Endpoint'** String get tcpHostLabel; /// No description provided for @tcpHostHint. /// /// In en, this message translates to: - /// **'192.168.40.10'** + /// **'192.168.40.10 / example.com'** String get tcpHostHint; /// No description provided for @tcpPortLabel. @@ -391,7 +397,7 @@ abstract class AppLocalizations { /// No description provided for @tcpErrorHostRequired. /// /// In en, this message translates to: - /// **'IP address is required.'** + /// **'Host is required.'** String get tcpErrorHostRequired; /// No description provided for @tcpErrorPortInvalid. @@ -901,8 +907,8 @@ abstract class AppLocalizations { /// No description provided for @settings_multiAck. /// /// In en, this message translates to: - /// **'Multi-ACKs: {value}'** - String settings_multiAck(String value); + /// **'Multi-ACKs'** + String get settings_multiAck; /// No description provided for @settings_telemetryModeUpdated. /// @@ -916,6 +922,18 @@ abstract class AppLocalizations { /// **'Actions'** String get settings_actions; + /// No description provided for @settings_deleteAllPaths. + /// + /// In en, this message translates to: + /// **'Delete All Paths'** + String get settings_deleteAllPaths; + + /// No description provided for @settings_deleteAllPathsSubtitle. + /// + /// In en, this message translates to: + /// **'Clear all path data from contacts.'** + String get settings_deleteAllPathsSubtitle; + /// No description provided for @settings_sendAdvertisement. /// /// In en, this message translates to: @@ -988,17 +1006,17 @@ abstract class AppLocalizations { /// **'Debug'** String get settings_debug; - /// No description provided for @settings_bleDebugLog. + /// No description provided for @settings_companionDebugLog. /// /// In en, this message translates to: - /// **'BLE Debug Log'** - String get settings_bleDebugLog; + /// **'Companion Debug Log'** + String get settings_companionDebugLog; - /// No description provided for @settings_bleDebugLogSubtitle. + /// No description provided for @settings_companionDebugLogSubtitle. /// /// In en, this message translates to: - /// **'BLE commands, responses, and raw data'** - String get settings_bleDebugLogSubtitle; + /// **'BLE/TCP/USB commands, responses, and raw data'** + String get settings_companionDebugLogSubtitle; /// No description provided for @settings_appDebugLog. /// @@ -2032,35 +2050,23 @@ abstract class AppLocalizations { /// **'Channel {index}'** String channels_channelIndex(int index); - /// No description provided for @channels_hashtagChannel. - /// - /// In en, this message translates to: - /// **'Hashtag channel'** - String get channels_hashtagChannel; - /// No description provided for @channels_public. /// /// In en, this message translates to: /// **'Public'** String get channels_public; - /// No description provided for @channels_private. - /// - /// In en, this message translates to: - /// **'Private'** - String get channels_private; - - /// No description provided for @channels_publicChannel. + /// No description provided for @channels_via. /// /// In en, this message translates to: - /// **'Public channel'** - String get channels_publicChannel; + /// **'via {path}'** + String channels_via(String path); - /// No description provided for @channels_privateChannel. + /// No description provided for @channels_private. /// /// In en, this message translates to: - /// **'Private channel'** - String get channels_privateChannel; + /// **'Private'** + String get channels_private; /// No description provided for @channels_editChannel. /// @@ -2176,12 +2182,108 @@ abstract class AppLocalizations { /// **'SMAZ compression'** String get channels_smazCompression; + /// No description provided for @channels_cyr2latCompression. + /// + /// In en, this message translates to: + /// **'Cyr2Lat compression'** + String get channels_cyr2latCompression; + + /// No description provided for @channels_cyr2latCompressionDscr. + /// + /// In en, this message translates to: + /// **'Replaces some Cyrillic characters with Latin characters when sending.'** + String get channels_cyr2latCompressionDscr; + + /// No description provided for @channels_cyr2latSettingsHeading. + /// + /// In en, this message translates to: + /// **'Cyr2Lat Setup'** + String get channels_cyr2latSettingsHeading; + + /// No description provided for @channels_cyr2latSettingsSubheading. + /// + /// In en, this message translates to: + /// **'List of replacements'** + String get channels_cyr2latSettingsSubheading; + + /// No description provided for @channels_cyr2latSettingsDscr. + /// + /// In en, this message translates to: + /// **'Edit the JSON configuration of character replacement'** + String get channels_cyr2latSettingsDscr; + + /// No description provided for @channels_cyr2latSettingsDialogHint. + /// + /// In en, this message translates to: + /// **'JSON replacement map'** + String get channels_cyr2latSettingsDialogHint; + + /// No description provided for @channels_cyr2latSettingsDialogWrongJSON. + /// + /// In en, this message translates to: + /// **'Invalid JSON: {error}'** + String channels_cyr2latSettingsDialogWrongJSON(Object error); + /// No description provided for @channels_channelUpdated. /// /// In en, this message translates to: /// **'Channel \"{name}\" updated'** String channels_channelUpdated(String name); + /// No description provided for @settings_cyr2latProfileAdd. + /// + /// In en, this message translates to: + /// **'Add Cyr2Lat Profile'** + String get settings_cyr2latProfileAdd; + + /// No description provided for @settings_cyr2latProfileName. + /// + /// In en, this message translates to: + /// **'Profile Name'** + String get settings_cyr2latProfileName; + + /// No description provided for @settings_cyr2latProfileNameEmpty. + /// + /// In en, this message translates to: + /// **'Profile name cannot be empty'** + String get settings_cyr2latProfileNameEmpty; + + /// No description provided for @settings_cyr2latProfileAdded. + /// + /// In en, this message translates to: + /// **'Profile added successfully'** + String get settings_cyr2latProfileAdded; + + /// No description provided for @settings_cyr2latProfileUpdated. + /// + /// In en, this message translates to: + /// **'Profile updated successfully'** + String get settings_cyr2latProfileUpdated; + + /// No description provided for @settings_cyr2latProfileEdit. + /// + /// In en, this message translates to: + /// **'Edit Cyr2Lat Profile'** + String get settings_cyr2latProfileEdit; + + /// No description provided for @settings_cyr2latProfileDelete. + /// + /// In en, this message translates to: + /// **'Delete Cyr2Lat Profile'** + String get settings_cyr2latProfileDelete; + + /// No description provided for @settings_cyr2latProfileDeleted. + /// + /// In en, this message translates to: + /// **'Profile deleted successfully'** + String get settings_cyr2latProfileDeleted; + + /// No description provided for @settings_cyr2latProfileDeleteDscr. + /// + /// In en, this message translates to: + /// **'Are you sure you want to delete the profile \"{name}\"?'** + String settings_cyr2latProfileDeleteDscr(String name); + /// No description provided for @channels_publicChannelAdded. /// /// In en, this message translates to: @@ -2662,6 +2764,12 @@ abstract class AppLocalizations { /// **'successes'** String get chat_successes; + /// No description provided for @chat_score. + /// + /// In en, this message translates to: + /// **'Score'** + String get chat_score; + /// No description provided for @chat_removePath. /// /// In en, this message translates to: @@ -2824,6 +2932,18 @@ abstract class AppLocalizations { /// **'Unread: {count}'** String chat_unread(int count); + /// No description provided for @chat_markAsUnread. + /// + /// In en, this message translates to: + /// **'Mark as Unread'** + String get chat_markAsUnread; + + /// No description provided for @chat_newMessages. + /// + /// In en, this message translates to: + /// **'New messages'** + String get chat_newMessages; + /// No description provided for @chat_openLink. /// /// In en, this message translates to: @@ -2968,6 +3088,42 @@ abstract class AppLocalizations { /// **'Flags'** String get map_flags; + /// No description provided for @map_type. + /// + /// In en, this message translates to: + /// **'Type'** + String get map_type; + + /// No description provided for @map_path. + /// + /// In en, this message translates to: + /// **'Path'** + String get map_path; + + /// No description provided for @map_location. + /// + /// In en, this message translates to: + /// **'Location'** + String get map_location; + + /// No description provided for @map_estLocation. + /// + /// In en, this message translates to: + /// **'Est. Location'** + String get map_estLocation; + + /// No description provided for @map_publicKey. + /// + /// In en, this message translates to: + /// **'Public Key'** + String get map_publicKey; + + /// No description provided for @map_publicKeyPrefixHint. + /// + /// In en, this message translates to: + /// **'e.g. ab12'** + String get map_publicKeyPrefixHint; + /// No description provided for @map_shareMarkerHere. /// /// In en, this message translates to: @@ -3130,6 +3286,12 @@ abstract class AppLocalizations { /// **'Shared pin'** String get map_sharedPin; + /// No description provided for @map_sharedAt. + /// + /// In en, this message translates to: + /// **'Shared'** + String get map_sharedAt; + /// No description provided for @map_joinRoom. /// /// In en, this message translates to: @@ -3825,6 +3987,12 @@ abstract class AppLocalizations { /// **'RX Airtime'** String get repeater_rxAirtime; + /// No description provided for @repeater_chanUtil. + /// + /// In en, this message translates to: + /// **'Channel Utilization'** + String get repeater_chanUtil; + /// No description provided for @repeater_packetStatistics. /// /// In en, this message translates to: @@ -4178,6 +4346,270 @@ abstract class AppLocalizations { /// **'Settings saved successfully'** String get repeater_settingsSaved; + /// No description provided for @repeater_rxGain. + /// + /// In en, this message translates to: + /// **'Boosted RX gain'** + String get repeater_rxGain; + + /// No description provided for @repeater_rxGainHelper. + /// + /// In en, this message translates to: + /// **'Higher sensitivity, more current draw (SX1262/SX1268 only)'** + String get repeater_rxGainHelper; + + /// No description provided for @repeater_refreshRxGain. + /// + /// In en, this message translates to: + /// **'Refresh boosted RX gain'** + String get repeater_refreshRxGain; + + /// No description provided for @repeater_multiAcks. + /// + /// In en, this message translates to: + /// **'Multi-ACKs'** + String get repeater_multiAcks; + + /// No description provided for @repeater_multiAcksSubtitle. + /// + /// In en, this message translates to: + /// **'Acknowledge messages over multiple paths for better delivery'** + String get repeater_multiAcksSubtitle; + + /// No description provided for @repeater_refreshMultiAcks. + /// + /// In en, this message translates to: + /// **'Refresh multi-ACKs'** + String get repeater_refreshMultiAcks; + + /// No description provided for @repeater_networkHealth. + /// + /// In en, this message translates to: + /// **'Network health'** + String get repeater_networkHealth; + + /// No description provided for @repeater_loopDetect. + /// + /// In en, this message translates to: + /// **'Loop detection'** + String get repeater_loopDetect; + + /// No description provided for @repeater_loopDetectHelper. + /// + /// In en, this message translates to: + /// **'Drop flood packets that look like routing loops'** + String get repeater_loopDetectHelper; + + /// No description provided for @repeater_loopDetectOff. + /// + /// In en, this message translates to: + /// **'Off'** + String get repeater_loopDetectOff; + + /// No description provided for @repeater_loopDetectMinimal. + /// + /// In en, this message translates to: + /// **'Minimal'** + String get repeater_loopDetectMinimal; + + /// No description provided for @repeater_loopDetectModerate. + /// + /// In en, this message translates to: + /// **'Moderate'** + String get repeater_loopDetectModerate; + + /// No description provided for @repeater_loopDetectStrict. + /// + /// In en, this message translates to: + /// **'Strict'** + String get repeater_loopDetectStrict; + + /// No description provided for @repeater_dutyCycle. + /// + /// In en, this message translates to: + /// **'Duty cycle'** + String get repeater_dutyCycle; + + /// No description provided for @repeater_dutyCycleHelper. + /// + /// In en, this message translates to: + /// **'Maximum percentage of airtime'** + String get repeater_dutyCycleHelper; + + /// No description provided for @repeater_dutyCyclePercent. + /// + /// In en, this message translates to: + /// **'{percent}%'** + String repeater_dutyCyclePercent(int percent); + + /// No description provided for @repeater_ownerInfo. + /// + /// In en, this message translates to: + /// **'Operator info'** + String get repeater_ownerInfo; + + /// No description provided for @repeater_ownerInfoHelper. + /// + /// In en, this message translates to: + /// **'Public metadata for this repeater'** + String get repeater_ownerInfoHelper; + + /// No description provided for @repeater_refreshOwnerInfo. + /// + /// In en, this message translates to: + /// **'Refresh operator info'** + String get repeater_refreshOwnerInfo; + + /// No description provided for @repeater_floodMax. + /// + /// In en, this message translates to: + /// **'Flood max hops'** + String get repeater_floodMax; + + /// No description provided for @repeater_floodMaxHelper. + /// + /// In en, this message translates to: + /// **'Maximum hops a flood packet may travel (0-64)'** + String get repeater_floodMaxHelper; + + /// No description provided for @repeater_advancedSettings. + /// + /// In en, this message translates to: + /// **'Advanced'** + String get repeater_advancedSettings; + + /// No description provided for @repeater_advancedSettingsSubtitle. + /// + /// In en, this message translates to: + /// **'Tuning knobs for experienced operators'** + String get repeater_advancedSettingsSubtitle; + + /// No description provided for @repeater_pathHashMode. + /// + /// In en, this message translates to: + /// **'Path hash mode'** + String get repeater_pathHashMode; + + /// No description provided for @repeater_pathHashModeHelper. + /// + /// In en, this message translates to: + /// **'Bytes used to encode this repeater\'s ID in flood path/loop-detect tags. 0=1 byte (256 IDs, up to 64 hops), 1=2 bytes (65K IDs, up to 32 hops), 2=3 bytes (16M IDs, up to 21 hops). v1.13 and older firmware drops multi-byte paths — only raise once your network is on v1.14+.'** + String get repeater_pathHashModeHelper; + + /// No description provided for @repeater_txDelay. + /// + /// In en, this message translates to: + /// **'Flood TX delay'** + String get repeater_txDelay; + + /// No description provided for @repeater_txDelayHelper. + /// + /// In en, this message translates to: + /// **'Retransmit spacing for flood traffic, as a multiplier of the packet\'s airtime (0-2, default 0.5). Higher = fewer collisions but slower delivery.'** + String get repeater_txDelayHelper; + + /// No description provided for @repeater_directTxDelay. + /// + /// In en, this message translates to: + /// **'Direct TX delay'** + String get repeater_directTxDelay; + + /// No description provided for @repeater_directTxDelayHelper. + /// + /// In en, this message translates to: + /// **'Retransmit spacing for direct (non-flood) traffic, as a multiplier of the packet\'s airtime (0-2, default 0.3).'** + String get repeater_directTxDelayHelper; + + /// No description provided for @repeater_intThresh. + /// + /// In en, this message translates to: + /// **'Interference threshold'** + String get repeater_intThresh; + + /// No description provided for @repeater_intThreshHelper. + /// + /// In en, this message translates to: + /// **'Threshold passed to the radio\'s noise-floor calibration so it rejects interference above this level. 0 disables — only raise if you see RX errors in a noisy band.'** + String get repeater_intThreshHelper; + + /// No description provided for @repeater_agcResetInterval. + /// + /// In en, this message translates to: + /// **'AGC reset interval'** + String get repeater_agcResetInterval; + + /// No description provided for @repeater_agcResetIntervalHelper. + /// + /// In en, this message translates to: + /// **'How often to reset the radio\'s automatic gain control to recover from a stuck gain state. Seconds, snapped down to a multiple of 4. 0 disables periodic resets.'** + String get repeater_agcResetIntervalHelper; + + /// No description provided for @repeater_actionsTitle. + /// + /// In en, this message translates to: + /// **'Actions'** + String get repeater_actionsTitle; + + /// No description provided for @repeater_sendAdvert. + /// + /// In en, this message translates to: + /// **'Send flood advert'** + String get repeater_sendAdvert; + + /// No description provided for @repeater_sendAdvertSubtitle. + /// + /// In en, this message translates to: + /// **'Broadcast a flood advert through the network'** + String get repeater_sendAdvertSubtitle; + + /// No description provided for @repeater_sendAdvertZeroHop. + /// + /// In en, this message translates to: + /// **'Send zero-hop advert'** + String get repeater_sendAdvertZeroHop; + + /// No description provided for @repeater_sendAdvertZeroHopSubtitle. + /// + /// In en, this message translates to: + /// **'Broadcast a one-hop advert (no relays)'** + String get repeater_sendAdvertZeroHopSubtitle; + + /// No description provided for @repeater_clockSync. + /// + /// In en, this message translates to: + /// **'Sync clock now'** + String get repeater_clockSync; + + /// No description provided for @repeater_clockSyncSubtitle. + /// + /// In en, this message translates to: + /// **'Push your phone\'s time to the repeater'** + String get repeater_clockSyncSubtitle; + + /// No description provided for @repeater_actionSucceeded. + /// + /// In en, this message translates to: + /// **'{action} succeeded'** + String repeater_actionSucceeded(String action); + + /// No description provided for @repeater_actionFailed. + /// + /// In en, this message translates to: + /// **'{action} failed: {error}'** + String repeater_actionFailed(String action, String error); + + /// No description provided for @repeater_settingsSavedRebootNeeded. + /// + /// In en, this message translates to: + /// **'Settings saved — reboot the repeater to apply'** + String get repeater_settingsSavedRebootNeeded; + + /// No description provided for @repeater_settingsPartialFailure. + /// + /// In en, this message translates to: + /// **'Some settings failed: {failures}'** + String repeater_settingsPartialFailure(String failures); + /// No description provided for @repeater_errorSavingSettings. /// /// In en, this message translates to: @@ -4202,12 +4634,6 @@ abstract class AppLocalizations { /// **'Refresh TX power'** String get repeater_refreshTxPower; - /// No description provided for @repeater_refreshLocationSettings. - /// - /// In en, this message translates to: - /// **'Refresh Location Settings'** - String get repeater_refreshLocationSettings; - /// No description provided for @repeater_refreshPacketForwarding. /// /// In en, this message translates to: @@ -4226,12 +4652,6 @@ abstract class AppLocalizations { /// **'Refresh Privacy Mode'** String get repeater_refreshPrivacyMode; - /// No description provided for @repeater_refreshAdvertisementSettings. - /// - /// In en, this message translates to: - /// **'Refresh Advertisement Settings'** - String get repeater_refreshAdvertisementSettings; - /// No description provided for @repeater_refreshed. /// /// In en, this message translates to: @@ -4760,23 +5180,449 @@ abstract class AppLocalizations { /// **'gps command has been introduced to manage location related topics.'** String get repeater_gpsNote; - /// No description provided for @telemetry_receivedData. + /// No description provided for @repeater_getCategory. /// /// In en, this message translates to: - /// **'Received Telemetry Data'** - String get telemetry_receivedData; + /// **'Get Values'** + String get repeater_getCategory; - /// No description provided for @telemetry_requestTimeout. + /// No description provided for @repeater_powerMgmt. /// /// In en, this message translates to: - /// **'Telemetry request timed out.'** - String get telemetry_requestTimeout; + /// **'Power Management'** + String get repeater_powerMgmt; - /// No description provided for @telemetry_errorLoading. + /// No description provided for @repeater_sensors. /// /// In en, this message translates to: - /// **'Error loading telemetry: {error}'** - String telemetry_errorLoading(String error); + /// **'Sensors'** + String get repeater_sensors; + + /// No description provided for @repeater_cliHelpPowerOff. + /// + /// In en, this message translates to: + /// **'Powers the device off. (no response expected)'** + String get repeater_cliHelpPowerOff; + + /// No description provided for @repeater_cliHelpClkReboot. + /// + /// In en, this message translates to: + /// **'Resets the clock to a known epoch and reboots the device.'** + String get repeater_cliHelpClkReboot; + + /// No description provided for @repeater_cliHelpAdvertZeroHop. + /// + /// In en, this message translates to: + /// **'Sends a zero-hop advertisement (immediate neighbors only).'** + String get repeater_cliHelpAdvertZeroHop; + + /// No description provided for @repeater_cliHelpStartOta. + /// + /// In en, this message translates to: + /// **'Starts an over-the-air firmware update on supported boards.'** + String get repeater_cliHelpStartOta; + + /// No description provided for @repeater_cliHelpTime. + /// + /// In en, this message translates to: + /// **'Sets the device clock to the given Unix epoch seconds. Clock cannot move backwards.'** + String get repeater_cliHelpTime; + + /// No description provided for @repeater_cliHelpBoard. + /// + /// In en, this message translates to: + /// **'Shows the board manufacturer / hardware identifier.'** + String get repeater_cliHelpBoard; + + /// No description provided for @repeater_cliHelpDiscoverNeighbors. + /// + /// In en, this message translates to: + /// **'Sends a node-discovery request to nearby neighbors. (Repeater only)'** + String get repeater_cliHelpDiscoverNeighbors; + + /// No description provided for @repeater_cliHelpPowersaving. + /// + /// In en, this message translates to: + /// **'Shows whether powersaving mode is on or off.'** + String get repeater_cliHelpPowersaving; + + /// No description provided for @repeater_cliHelpPowersavingOnOff. + /// + /// In en, this message translates to: + /// **'Enables or disables powersaving mode (where supported).'** + String get repeater_cliHelpPowersavingOnOff; + + /// No description provided for @repeater_cliHelpErase. + /// + /// In en, this message translates to: + /// **'(Serial only) Formats the device file system. Wipes all settings and contacts.'** + String get repeater_cliHelpErase; + + /// No description provided for @repeater_cliHelpSetDutyCycle. + /// + /// In en, this message translates to: + /// **'Sets the maximum allowed transmit duty cycle as a percentage (1-100). Internally adjusts the airtime factor.'** + String get repeater_cliHelpSetDutyCycle; + + /// No description provided for @repeater_cliHelpSetPrvKey. + /// + /// In en, this message translates to: + /// **'(Serial only) Replaces the device identity private key. Reboot required to apply. Generates a new public key.'** + String get repeater_cliHelpSetPrvKey; + + /// No description provided for @repeater_cliHelpSetRadioRxGain. + /// + /// In en, this message translates to: + /// **'(SX126x only) Toggles boosted RX gain for improved sensitivity at higher current draw.'** + String get repeater_cliHelpSetRadioRxGain; + + /// No description provided for @repeater_cliHelpSetOwnerInfo. + /// + /// In en, this message translates to: + /// **'Sets the owner contact info string included in adverts. Use \'|\' for newlines.'** + String get repeater_cliHelpSetOwnerInfo; + + /// No description provided for @repeater_cliHelpSetPathHashMode. + /// + /// In en, this message translates to: + /// **'Sets the path-hash mode. 0 = legacy, 1 = standard, 2 = strict. Affects how routing paths are matched.'** + String get repeater_cliHelpSetPathHashMode; + + /// No description provided for @repeater_cliHelpSetLoopDetect. + /// + /// In en, this message translates to: + /// **'Sets the routing loop-detection sensitivity: off, minimal, moderate, or strict.'** + String get repeater_cliHelpSetLoopDetect; + + /// No description provided for @repeater_cliHelpSetFreq. + /// + /// In en, this message translates to: + /// **'(Serial only) Quickly sets just the frequency. Reboot required. Prefer \"set radio\" for full radio params.'** + String get repeater_cliHelpSetFreq; + + /// No description provided for @repeater_cliHelpSetBridgeChannel. + /// + /// In en, this message translates to: + /// **'(ESPNow bridge only) Sets the WiFi channel (1-14) used by the bridge.'** + String get repeater_cliHelpSetBridgeChannel; + + /// No description provided for @repeater_cliHelpGetName. + /// + /// In en, this message translates to: + /// **'Shows the configured node name.'** + String get repeater_cliHelpGetName; + + /// No description provided for @repeater_cliHelpGetRole. + /// + /// In en, this message translates to: + /// **'Shows the firmware role (Repeater, Room Server, etc.).'** + String get repeater_cliHelpGetRole; + + /// No description provided for @repeater_cliHelpGetPublicKey. + /// + /// In en, this message translates to: + /// **'Shows the device public key.'** + String get repeater_cliHelpGetPublicKey; + + /// No description provided for @repeater_cliHelpGetPrvKey. + /// + /// In en, this message translates to: + /// **'(Serial only) Shows the device private key. Treat as a secret.'** + String get repeater_cliHelpGetPrvKey; + + /// No description provided for @repeater_cliHelpGetRepeat. + /// + /// In en, this message translates to: + /// **'Shows whether packet forwarding (repeater role) is on or off.'** + String get repeater_cliHelpGetRepeat; + + /// No description provided for @repeater_cliHelpGetTx. + /// + /// In en, this message translates to: + /// **'Shows the current TX power in dBm.'** + String get repeater_cliHelpGetTx; + + /// No description provided for @repeater_cliHelpGetFreq. + /// + /// In en, this message translates to: + /// **'Shows the configured radio frequency in MHz.'** + String get repeater_cliHelpGetFreq; + + /// No description provided for @repeater_cliHelpGetRadio. + /// + /// In en, this message translates to: + /// **'Shows full radio params: freq, bandwidth, spreading factor, coding rate.'** + String get repeater_cliHelpGetRadio; + + /// No description provided for @repeater_cliHelpGetRadioRxGain. + /// + /// In en, this message translates to: + /// **'(SX126x only) Shows the RX boosted gain state.'** + String get repeater_cliHelpGetRadioRxGain; + + /// No description provided for @repeater_cliHelpGetAf. + /// + /// In en, this message translates to: + /// **'Shows the current airtime factor.'** + String get repeater_cliHelpGetAf; + + /// No description provided for @repeater_cliHelpGetDutyCycle. + /// + /// In en, this message translates to: + /// **'Shows the current allowed duty cycle as a percentage.'** + String get repeater_cliHelpGetDutyCycle; + + /// No description provided for @repeater_cliHelpGetIntThresh. + /// + /// In en, this message translates to: + /// **'Shows the channel interference threshold in dB.'** + String get repeater_cliHelpGetIntThresh; + + /// No description provided for @repeater_cliHelpGetAgcResetInterval. + /// + /// In en, this message translates to: + /// **'Shows the AGC reset interval in seconds.'** + String get repeater_cliHelpGetAgcResetInterval; + + /// No description provided for @repeater_cliHelpGetMultiAcks. + /// + /// In en, this message translates to: + /// **'Shows whether double-ACK mode is on (1) or off (0).'** + String get repeater_cliHelpGetMultiAcks; + + /// No description provided for @repeater_cliHelpGetAllowReadOnly. + /// + /// In en, this message translates to: + /// **'Shows whether guest read-only access is allowed.'** + String get repeater_cliHelpGetAllowReadOnly; + + /// No description provided for @repeater_cliHelpGetAdvertInterval. + /// + /// In en, this message translates to: + /// **'Shows the local advertisement interval in minutes.'** + String get repeater_cliHelpGetAdvertInterval; + + /// No description provided for @repeater_cliHelpGetFloodAdvertInterval. + /// + /// In en, this message translates to: + /// **'Shows the flood advertisement interval in hours.'** + String get repeater_cliHelpGetFloodAdvertInterval; + + /// No description provided for @repeater_cliHelpGetGuestPassword. + /// + /// In en, this message translates to: + /// **'Shows the configured guest password.'** + String get repeater_cliHelpGetGuestPassword; + + /// No description provided for @repeater_cliHelpGetLat. + /// + /// In en, this message translates to: + /// **'Shows the configured latitude.'** + String get repeater_cliHelpGetLat; + + /// No description provided for @repeater_cliHelpGetLon. + /// + /// In en, this message translates to: + /// **'Shows the configured longitude.'** + String get repeater_cliHelpGetLon; + + /// No description provided for @repeater_cliHelpGetRxDelay. + /// + /// In en, this message translates to: + /// **'Shows the rxdelay base value.'** + String get repeater_cliHelpGetRxDelay; + + /// No description provided for @repeater_cliHelpGetTxDelay. + /// + /// In en, this message translates to: + /// **'Shows the flood-mode txdelay factor.'** + String get repeater_cliHelpGetTxDelay; + + /// No description provided for @repeater_cliHelpGetDirectTxDelay. + /// + /// In en, this message translates to: + /// **'Shows the direct-mode txdelay factor.'** + String get repeater_cliHelpGetDirectTxDelay; + + /// No description provided for @repeater_cliHelpGetFloodMax. + /// + /// In en, this message translates to: + /// **'Shows the maximum flood hop count.'** + String get repeater_cliHelpGetFloodMax; + + /// No description provided for @repeater_cliHelpGetOwnerInfo. + /// + /// In en, this message translates to: + /// **'Shows the owner contact info string.'** + String get repeater_cliHelpGetOwnerInfo; + + /// No description provided for @repeater_cliHelpGetPathHashMode. + /// + /// In en, this message translates to: + /// **'Shows the path-hash mode (0/1/2).'** + String get repeater_cliHelpGetPathHashMode; + + /// No description provided for @repeater_cliHelpGetLoopDetect. + /// + /// In en, this message translates to: + /// **'Shows the loop-detection sensitivity.'** + String get repeater_cliHelpGetLoopDetect; + + /// No description provided for @repeater_cliHelpGetAcl. + /// + /// In en, this message translates to: + /// **'(Serial only) Lists the access-control entries on a repeater.'** + String get repeater_cliHelpGetAcl; + + /// No description provided for @repeater_cliHelpGetBridgeEnabled. + /// + /// In en, this message translates to: + /// **'Shows whether the bridge is enabled.'** + String get repeater_cliHelpGetBridgeEnabled; + + /// No description provided for @repeater_cliHelpGetBridgeDelay. + /// + /// In en, this message translates to: + /// **'Shows the bridge delay in ms.'** + String get repeater_cliHelpGetBridgeDelay; + + /// No description provided for @repeater_cliHelpGetBridgeSource. + /// + /// In en, this message translates to: + /// **'Shows whether the bridge logs RX or TX packets.'** + String get repeater_cliHelpGetBridgeSource; + + /// No description provided for @repeater_cliHelpGetBridgeBaud. + /// + /// In en, this message translates to: + /// **'(RS232 bridge only) Shows the bridge baud rate.'** + String get repeater_cliHelpGetBridgeBaud; + + /// No description provided for @repeater_cliHelpGetBridgeChannel. + /// + /// In en, this message translates to: + /// **'(ESPNow bridge only) Shows the bridge WiFi channel.'** + String get repeater_cliHelpGetBridgeChannel; + + /// No description provided for @repeater_cliHelpGetBridgeSecret. + /// + /// In en, this message translates to: + /// **'(ESPNow bridge only) Shows the bridge shared secret.'** + String get repeater_cliHelpGetBridgeSecret; + + /// No description provided for @repeater_cliHelpGetBootloaderVer. + /// + /// In en, this message translates to: + /// **'(NRF52 only) Shows the bootloader version.'** + String get repeater_cliHelpGetBootloaderVer; + + /// No description provided for @repeater_cliHelpGetAdcMultiplier. + /// + /// In en, this message translates to: + /// **'Shows the ADC multiplier (battery-voltage scaling).'** + String get repeater_cliHelpGetAdcMultiplier; + + /// No description provided for @repeater_cliHelpGetPwrMgtSupport. + /// + /// In en, this message translates to: + /// **'Reports whether the board has power-management support.'** + String get repeater_cliHelpGetPwrMgtSupport; + + /// No description provided for @repeater_cliHelpGetPwrMgtSource. + /// + /// In en, this message translates to: + /// **'Shows the current power source: external or battery.'** + String get repeater_cliHelpGetPwrMgtSource; + + /// No description provided for @repeater_cliHelpGetPwrMgtBootReason. + /// + /// In en, this message translates to: + /// **'Shows the most recent reset and shutdown reasons.'** + String get repeater_cliHelpGetPwrMgtBootReason; + + /// No description provided for @repeater_cliHelpGetPwrMgtBootMv. + /// + /// In en, this message translates to: + /// **'Shows the boot-time battery voltage in mV.'** + String get repeater_cliHelpGetPwrMgtBootMv; + + /// No description provided for @repeater_cliHelpSensorGet. + /// + /// In en, this message translates to: + /// **'Reads a custom sensor setting by key.'** + String get repeater_cliHelpSensorGet; + + /// No description provided for @repeater_cliHelpSensorSet. + /// + /// In en, this message translates to: + /// **'Writes a custom sensor setting.'** + String get repeater_cliHelpSensorSet; + + /// No description provided for @repeater_cliHelpSensorList. + /// + /// In en, this message translates to: + /// **'Lists all custom sensor settings, paginated from optional start index.'** + String get repeater_cliHelpSensorList; + + /// No description provided for @repeater_cliHelpRegionDefault. + /// + /// In en, this message translates to: + /// **'Shows the current default region scope.'** + String get repeater_cliHelpRegionDefault; + + /// No description provided for @repeater_cliHelpRegionDefaultSet. + /// + /// In en, this message translates to: + /// **'Sets the default region scope. Use \"\" to clear.'** + String get repeater_cliHelpRegionDefaultSet; + + /// No description provided for @repeater_cliHelpRegionListAllowed. + /// + /// In en, this message translates to: + /// **'Lists regions that allow flood traffic.'** + String get repeater_cliHelpRegionListAllowed; + + /// No description provided for @repeater_cliHelpRegionListDenied. + /// + /// In en, this message translates to: + /// **'Lists regions that deny flood traffic.'** + String get repeater_cliHelpRegionListDenied; + + /// No description provided for @repeater_cliHelpStatsPackets. + /// + /// In en, this message translates to: + /// **'(Serial only) Shows packet-level statistics.'** + String get repeater_cliHelpStatsPackets; + + /// No description provided for @repeater_cliHelpStatsRadio. + /// + /// In en, this message translates to: + /// **'(Serial only) Shows radio statistics.'** + String get repeater_cliHelpStatsRadio; + + /// No description provided for @repeater_cliHelpStatsCore. + /// + /// In en, this message translates to: + /// **'(Serial only) Shows core firmware statistics.'** + String get repeater_cliHelpStatsCore; + + /// No description provided for @telemetry_receivedData. + /// + /// In en, this message translates to: + /// **'Received Telemetry Data'** + String get telemetry_receivedData; + + /// No description provided for @telemetry_requestTimeout. + /// + /// In en, this message translates to: + /// **'Telemetry request timed out.'** + String get telemetry_requestTimeout; + + /// No description provided for @telemetry_errorLoading. + /// + /// In en, this message translates to: + /// **'Error loading telemetry: {error}'** + String telemetry_errorLoading(String error); /// No description provided for @telemetry_noData. /// @@ -5640,6 +6486,47 @@ abstract class AppLocalizations { /// **'Terrain'** String get losLegendTerrain; + /// No description provided for @losBlockedSpotsTitle. + /// + /// In en, this message translates to: + /// **'Blocked spots'** + String get losBlockedSpotsTitle; + + /// No description provided for @losBlockedSpotsHint. + /// + /// In en, this message translates to: + /// **'Tap a blocked spot to highlight it on the map.'** + String get losBlockedSpotsHint; + + /// No description provided for @losBlockedSpotChip. + /// + /// In en, this message translates to: + /// **'{distance} {distanceUnit} • {obstruction} {heightUnit}'** + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ); + + /// No description provided for @losSelectedObstructionTitle. + /// + /// In en, this message translates to: + /// **'Selected obstruction'** + String get losSelectedObstructionTitle; + + /// No description provided for @losSelectedObstructionDetails. + /// + /// In en, this message translates to: + /// **'Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).'** + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ); + /// No description provided for @losFrequencyLabel. /// /// In en, this message translates to: @@ -6388,6 +7275,66 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'System language'** String get translation_systemLanguage; + + /// No description provided for @background_serviceTitle. + /// + /// In en, this message translates to: + /// **'MeshCore running'** + String get background_serviceTitle; + + /// No description provided for @background_serviceText. + /// + /// In en, this message translates to: + /// **'Keeping BLE connected'** + String get background_serviceText; + + /// No description provided for @appSettings_translationModelDeleted. + /// + /// In en, this message translates to: + /// **'Deleted {name}'** + String appSettings_translationModelDeleted(String name); + + /// No description provided for @appSettings_translationModelDeleteFailed. + /// + /// In en, this message translates to: + /// **'Failed to delete: {error}'** + String appSettings_translationModelDeleteFailed(String error); + + /// No description provided for @channels_channelUpdateFailed. + /// + /// In en, this message translates to: + /// **'Failed to update channel: {error}'** + String channels_channelUpdateFailed(String error); + + /// No description provided for @contact_typeChat. + /// + /// In en, this message translates to: + /// **'Chat'** + String get contact_typeChat; + + /// No description provided for @contact_typeRepeater. + /// + /// In en, this message translates to: + /// **'Repeater'** + String get contact_typeRepeater; + + /// No description provided for @contact_typeRoom. + /// + /// In en, this message translates to: + /// **'Room'** + String get contact_typeRoom; + + /// No description provided for @contact_typeSensor. + /// + /// In en, this message translates to: + /// **'Sensor'** + String get contact_typeSensor; + + /// No description provided for @contact_typeUnknown. + /// + /// In en, this message translates to: + /// **'Unknown'** + String get contact_typeUnknown; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_bg.dart b/lib/l10n/app_localizations_bg.dart index b3e1279..409803b 100644 --- a/lib/l10n/app_localizations_bg.dart +++ b/lib/l10n/app_localizations_bg.dart @@ -44,6 +44,9 @@ class AppLocalizationsBg extends AppLocalizations { @override String get common_close => 'Затвори'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Редактирай'; @@ -109,7 +112,7 @@ class AppLocalizationsBg extends AppLocalizations { } @override - String get scanner_title => 'MeshCore Open'; + String get scanner_title => 'MeshCore – Отворена версия'; @override String get connectionChoiceUsbLabel => 'USB'; @@ -437,9 +440,7 @@ class AppLocalizationsBg extends AppLocalizations { 'Включи местоположение в обявата'; @override - String settings_multiAck(String value) { - return 'Мулти-потвърди: $value'; - } + String get settings_multiAck => 'Множество потвърждения'; @override String get settings_telemetryModeUpdated => 'Режим на телеметрията е обновен'; @@ -447,6 +448,13 @@ class AppLocalizationsBg extends AppLocalizations { @override String get settings_actions => 'Действия'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Изпрати Реклама'; @@ -488,11 +496,12 @@ class AppLocalizationsBg extends AppLocalizations { String get settings_debug => 'Отстрани'; @override - String get settings_bleDebugLog => 'Лог за отстраняване на грешки на BLE'; + String get settings_companionDebugLog => + 'Лог за отстраняване на грешки (за съпътстваща програма)'; @override - String get settings_bleDebugLogSubtitle => - 'Команди, отговори и сурови данни BLE'; + String get settings_companionDebugLogSubtitle => + 'Команди, отговори и сурови данни за протоколите BLE/TCP/USB'; @override String get settings_appDebugLog => @@ -507,7 +516,7 @@ class AppLocalizationsBg extends AppLocalizations { @override String settings_aboutVersion(String version) { - return 'MeshCore Open v$version'; + return 'MeshCore Open, версия $version'; } @override @@ -549,7 +558,7 @@ class AppLocalizationsBg extends AppLocalizations { String get settings_frequency => 'Честота (MHz)'; @override - String get settings_frequencyHelper => '300.0 - 2500.0'; + String get settings_frequencyHelper => '300,0 – 2500,0'; @override String get settings_frequencyInvalid => 'Невалидна честота (300-2500 MHz)'; @@ -613,40 +622,40 @@ class AppLocalizationsBg extends AppLocalizations { String get appSettings_languageSystem => 'Система по подразбиране'; @override - String get appSettings_languageEn => 'English'; + String get appSettings_languageEn => 'Английски'; @override - String get appSettings_languageFr => 'Français'; + String get appSettings_languageFr => 'Френски'; @override - String get appSettings_languageEs => 'Español'; + String get appSettings_languageEs => 'Испански'; @override - String get appSettings_languageDe => 'Deutsch'; + String get appSettings_languageDe => 'Немски'; @override - String get appSettings_languagePl => 'Polski'; + String get appSettings_languagePl => 'Полски'; @override - String get appSettings_languageSl => 'Slovenščina'; + String get appSettings_languageSl => 'Словенски език'; @override - String get appSettings_languagePt => 'Português'; + String get appSettings_languagePt => 'Португалски'; @override - String get appSettings_languageIt => 'Italiano'; + String get appSettings_languageIt => 'Италиански'; @override - String get appSettings_languageZh => '中文'; + String get appSettings_languageZh => 'Китайски'; @override - String get appSettings_languageSv => 'Svenska'; + String get appSettings_languageSv => 'Шведски'; @override - String get appSettings_languageNl => 'Nederlands'; + String get appSettings_languageNl => 'Хололандски'; @override - String get appSettings_languageSk => 'Slovenčina'; + String get appSettings_languageSk => 'Словенски'; @override String get appSettings_languageBg => 'Български'; @@ -1091,20 +1100,16 @@ class AppLocalizationsBg extends AppLocalizations { return 'Канал $index'; } - @override - String get channels_hashtagChannel => 'Канал с хаштаг'; - @override String get channels_public => 'Публично'; @override - String get channels_private => 'Личен'; - - @override - String get channels_publicChannel => 'Публичен канал'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Частен канал'; + String get channels_private => 'Личен'; @override String get channels_editChannel => 'Редактирай канал'; @@ -1149,7 +1154,7 @@ class AppLocalizationsBg extends AppLocalizations { String get channels_standardPublicPsk => 'Стандартен публичен PSK'; @override - String get channels_pskHex => 'PSK (Hex)'; + String get channels_pskHex => 'PSK (шестнадесетичен код)'; @override String get channels_generateRandomPsk => 'Генерирай случайна PSK'; @@ -1174,11 +1179,67 @@ class AppLocalizationsBg extends AppLocalizations { @override String get channels_smazCompression => 'Компресия SMAZ'; + @override + String get channels_cyr2latCompression => 'Компресия Cyr2Lat'; + + @override + String get channels_cyr2latCompressionDscr => + 'Заменя някои кирилични символи с латиница при изпращане.'; + + @override + String get channels_cyr2latSettingsHeading => 'Настройки на Cyr2Lat'; + + @override + String get channels_cyr2latSettingsSubheading => 'Списък със замествания'; + + @override + String get channels_cyr2latSettingsDscr => + 'Редактиране на JSON конфигурацията за заместване на символи'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON карта за замествания'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'Неправилен JSON: $error'; + } + @override String channels_channelUpdated(String name) { return 'Каналът \"$name\" е актуализиран'; } + @override + String get settings_cyr2latProfileAdd => 'Добавяне на профил Cyr2Lat'; + + @override + String get settings_cyr2latProfileName => 'Име на профила'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'Името на профила не може да бъде празно'; + + @override + String get settings_cyr2latProfileAdded => 'Профилът е добавен успешно'; + + @override + String get settings_cyr2latProfileUpdated => + 'Профилът е актуализиран успешно'; + + @override + String get settings_cyr2latProfileEdit => 'Редактиране на Cyr2Lat профил'; + + @override + String get settings_cyr2latProfileDelete => 'Изтриване на профил Cyr2Lat'; + + @override + String get settings_cyr2latProfileDeleted => 'Профилът беше изтрит успешно'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Сигурен ли сте, че искате да изтриете профила \"$name\"?'; + } + @override String get channels_publicChannelAdded => 'Публичен канал добавен'; @@ -1189,7 +1250,7 @@ class AppLocalizationsBg extends AppLocalizations { String get channels_sortManual => 'Ръчно'; @override - String get channels_sortAZ => 'A-Z'; + String get channels_sortAZ => 'От A до Я'; @override String get channels_sortLatestMessages => 'Последни съобщения'; @@ -1363,7 +1424,7 @@ class AppLocalizationsBg extends AppLocalizations { String get debugLog_frames => 'Рамки'; @override - String get debugLog_rawLogRx => 'Raw Log-RX'; + String get debugLog_rawLogRx => 'Необработен лог-RX'; @override String get debugLog_noBleActivity => 'Няма BLE активност към момента.'; @@ -1402,7 +1463,7 @@ class AppLocalizationsBg extends AppLocalizations { } @override - String get debugFrame_textTypeCli => 'CLI'; + String get debugFrame_textTypeCli => 'Команден ред (CLI)'; @override String get debugFrame_textTypePlain => 'Просто'; @@ -1449,8 +1510,8 @@ class AppLocalizationsBg extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'hops', - one: 'hop', + other: 'скача', + one: 'скача', ); return '$count $_temp0'; } @@ -1458,6 +1519,9 @@ class AppLocalizationsBg extends AppLocalizations { @override String get chat_successes => 'Успехи'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Премахни пътя'; @@ -1560,6 +1624,12 @@ class AppLocalizationsBg extends AppLocalizations { return 'Непрочетени: $count'; } + @override + String get chat_markAsUnread => 'Отбелязване като непрочетено'; + + @override + String get chat_newMessages => 'Нови съобщения'; + @override String get chat_openLink => 'Отваряне на връзката?'; @@ -1641,6 +1711,24 @@ class AppLocalizationsBg extends AppLocalizations { @override String get map_flags => 'Флаг'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'Споделете маркер тук'; @@ -1726,6 +1814,9 @@ class AppLocalizationsBg extends AppLocalizations { @override String get map_sharedPin => 'Споделено копие'; + @override + String get map_sharedAt => 'Споделено'; + @override String get map_joinRoom => 'Присъедини се към стаята'; @@ -2046,7 +2137,7 @@ class AppLocalizationsBg extends AppLocalizations { 'Прегледайте телеметрията на сензорите и системните статистики'; @override - String get repeater_cli => 'CLI'; + String get repeater_cli => 'Команден ред (CLI)'; @override String get repeater_cliSubtitle => 'Изпрати команди към ретранслатора'; @@ -2137,6 +2228,9 @@ class AppLocalizationsBg extends AppLocalizations { @override String get repeater_rxAirtime => 'RX Airtime'; + @override + String get repeater_chanUtil => 'Използване на канала'; + @override String get repeater_packetStatistics => 'Статистика на пакетите'; @@ -2347,6 +2441,163 @@ class AppLocalizationsBg extends AppLocalizations { @override String get repeater_settingsSaved => 'Настройките са запазени успешно.'; + @override + String get repeater_rxGain => 'Увеличен коефициент на възвръщаемост (RX)'; + + @override + String get repeater_rxGainHelper => + 'По-висока чувствителност, по-голям ток (само за SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => + 'Възстановете повишената ефективност на RX'; + + @override + String get repeater_multiAcks => 'Множество потвърждения'; + + @override + String get repeater_multiAcksSubtitle => + 'Признавайте съобщения по множество канали за по-добро доставяне.'; + + @override + String get repeater_refreshMultiAcks => 'Обновете множество потвърждения'; + + @override + String get repeater_networkHealth => 'Състояние на мрежата'; + + @override + String get repeater_loopDetect => 'Откриване на цикли'; + + @override + String get repeater_loopDetectHelper => + 'Изпратете пакети, които изглеждат като цикли в маршрутизацията.'; + + @override + String get repeater_loopDetectOff => 'Изключено'; + + @override + String get repeater_loopDetectMinimal => 'Минимален'; + + @override + String get repeater_loopDetectModerate => 'Умерен'; + + @override + String get repeater_loopDetectStrict => 'Строг'; + + @override + String get repeater_dutyCycle => 'Цикъл на работа/почивка'; + + @override + String get repeater_dutyCycleHelper => + 'Максимален процент на използване на времето на въздуха'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Информация за оператора'; + + @override + String get repeater_ownerInfoHelper => 'Публични метаданни за този репитер'; + + @override + String get repeater_refreshOwnerInfo => 'Обновете информацията за оператора'; + + @override + String get repeater_floodMax => 'Максимален брой скачания при наводнение'; + + @override + String get repeater_floodMaxHelper => + 'Максималният брой пакети, които един поток може да пренесе (0-64)'; + + @override + String get repeater_advancedSettings => 'Напреднал'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Регулаторни копчета за опитни оператори'; + + @override + String get repeater_pathHashMode => 'Режим за хеширане на пътища'; + + @override + String get repeater_pathHashModeHelper => + 'Байтовете, използвани за кодиране на идентификатора на този репитер в таговете за откриване на потоци/цикли, са: 0=1 байт (256 идентификатора, до 64 скача), 1=2 байта (65 000 идентификатора, до 32 скача), 2=3 байта (16 милиона идентификатора, до 21 скача). Версии 1.13 и по-стари версии на фърмуера използват многобайтови пътища – само след като мрежата е актуализирана до версия 1.14 или по-нова.'; + + @override + String get repeater_txDelay => 'Забавяне на проекта \"Flood TX\"'; + + @override + String get repeater_txDelayHelper => + 'Предавайте разстоянието между пакетите за трафик при наводнения, като множител на времето за пренос на пакета (0-2, по подразбиране 0.5). По-висока стойност означава по-малко сблъсъци, но по-бавно предаване.'; + + @override + String get repeater_directTxDelay => 'Директно забавяне на сигнала'; + + @override + String get repeater_directTxDelayHelper => + 'Предаване на интервали за директен (не-масивен) трафик, като множител на времето за пренос на пакета (0-2, по подразбиране 0.3).'; + + @override + String get repeater_intThresh => 'Праг на интерференция'; + + @override + String get repeater_intThreshHelper => + 'Прагът е зададен на нивото на шума на радиото, така че да отхвърля смущения, които са над този праг. 0 – изключва; активирайте само, ако забележите грешки в шумна честотна лента.'; + + @override + String get repeater_agcResetInterval => 'Интервал за рестартиране на AGC'; + + @override + String get repeater_agcResetIntervalHelper => + 'Колко често да се рестартира автоматичната настройка на усилването, за да се възстанови от състояние, в което усилването е блокирано. Времето за рестартиране е няколко секунди, като се определя като кратна на 4. 0 деактивира периодичното рестартиране.'; + + @override + String get repeater_actionsTitle => 'Действия'; + + @override + String get repeater_sendAdvert => 'Изпратете реклама за навод'; + + @override + String get repeater_sendAdvertSubtitle => + 'Публикувайте реклама за навод в мрежата.'; + + @override + String get repeater_sendAdvertZeroHop => + 'Изпратете реклама без преминаване през други системи'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Публикувайте реклама, която достига до целевата аудитория само чрез директно разпространение (без използване на посредници).'; + + @override + String get repeater_clockSync => 'Синхронизиране на часовника сега'; + + @override + String get repeater_clockSyncSubtitle => + 'Настройте времето на телефона си да съвпада с времето на репитера.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action succeeded'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action failed: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Настройки запаметени – рестартирайте ретранслатора, за да ги приложите.'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Някои настройки не успяха: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Грешка при запазване на настройките: $error'; @@ -2362,10 +2613,6 @@ class AppLocalizationsBg extends AppLocalizations { @override String get repeater_refreshTxPower => 'Обнови TX захранване'; - @override - String get repeater_refreshLocationSettings => - 'Обнови настройките на местоположението'; - @override String get repeater_refreshPacketForwarding => 'Обнови пакетно пренасочване'; @@ -2375,10 +2622,6 @@ class AppLocalizationsBg extends AppLocalizations { @override String get repeater_refreshPrivacyMode => 'Обнови Режим на поверителност'; - @override - String get repeater_refreshAdvertisementSettings => - 'Обнови Настройки на Рекламата'; - @override String repeater_refreshed(String label) { return '$label е обновено'; @@ -2703,6 +2946,282 @@ class AppLocalizationsBg extends AppLocalizations { String get repeater_gpsNote => 'GPS командата е въведена, за да управлява теми, свързани с местоположението.'; + @override + String get repeater_getCategory => 'Получете стойности'; + + @override + String get repeater_powerMgmt => 'Управление на енергията'; + + @override + String get repeater_sensors => 'Датчици'; + + @override + String get repeater_cliHelpPowerOff => + 'Изключва устройството. (не се очаква отговор)'; + + @override + String get repeater_cliHelpClkReboot => + 'Възстановява часовника до известна историческа дата и рестартира устройството.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Изпраща реклама, която достига само до съседни устройства (само до съседни мрежи).'; + + @override + String get repeater_cliHelpStartOta => + 'Стартира актуализация на фърмуера чрез въздушното, на всички поддържани платки.'; + + @override + String get repeater_cliHelpTime => + 'Задава времето на устройството към зададените секунди от началото на Unix ерата. Времето не може да се върне назад.'; + + @override + String get repeater_cliHelpBoard => + 'Показва производителя на платката / идентификатора на хардуера.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Изпраща заявка за откриване на съседни възли. (Само за устройства тип репитер)'; + + @override + String get repeater_cliHelpPowersaving => + 'Показва дали режимът за пестене на енергия е активиран или деактивиран.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Активира или деактивира режима за пестене на енергия (ако е поддържан).'; + + @override + String get repeater_cliHelpErase => + '(Само за серийни устройства) Форматира файловата система на устройството. Изтрива всички настройки и контакти.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Задава максимално допустимия процент на използване на времето за предаване (от 1 до 100 процента). Вътрешно коригира фактора за времето на предаване.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Само за серийни номера) Заменя личната част от ключа за идентификация на устройството. Необходимо е да се рестартира устройството, за да се приложи. Генерира нов публичен ключ.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(Само за SX126x) Превключва усиления на приемния сигнал (RX gain) за подобрена чувствителност при по-високо потребление на ток.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Задава низовете с информация за контакт на собственика, които са включени в рекламите. Използвайте \'|\' за нови редове.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Задава режима за хеширане на пътищата. 0 = за стари системи, 1 = за стандартни системи, 2 = за строги системи. Влияе върху начина, по който се съпоставят маршрутите.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Задава чувствителността за откриване на цикли в маршрутизацията: изключена, минимална, умерена или строга.'; + + @override + String get repeater_cliHelpSetFreq => + '(Само за серийно управление) Бързо задава само честотата. Необходимо е рестартиране. Препоръчително е да се използват настройките за \"радио\", за да се зададат всички параметри.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Само за моста ESPNow) Определя WiFi канала (от 1 до 14), използван от моста.'; + + @override + String get repeater_cliHelpGetName => 'Показва зададеното име на възела.'; + + @override + String get repeater_cliHelpGetRole => + 'Показва ролята на фърмуера (например, репитер, сървър за стая и т.н.).'; + + @override + String get repeater_cliHelpGetPublicKey => + 'Показва публичния ключ на устройството.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Само за серийния номер) Показва личната ключа на устройството. Трябва да се третира като тайна.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Показва дали функцията за пренасочване на пакети (ролята на репитер) е активирана или деактивирана.'; + + @override + String get repeater_cliHelpGetTx => 'Показва текущата мощност на TX в dBm.'; + + @override + String get repeater_cliHelpGetFreq => 'Показва зададената честота в MHz.'; + + @override + String get repeater_cliHelpGetRadio => + 'Показва пълните радио параметри: честота, ширина на честотния обхват, фактор на разпространение, скорост на кодиране.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(Само за SX126x) Показва състоянието на усиления сигнал на RX.'; + + @override + String get repeater_cliHelpGetAf => + 'Показва текущия коефициент на въздействие върху въздуха.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Показва текущия допустим цикъл на работа като процент.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Показва прага на интерференцията на канала в децибели (dB).'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Показва интервала за рестартиране на AGC в секунди.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Показва дали режимът \"двоен ACK\" е активиран (1) или деактивиран (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Показва дали е разрешено само четене за гостите.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Показва времето на рекламата в минути.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Показва интервала на рекламата за навод в часове.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Показва зададения парол за гост.'; + + @override + String get repeater_cliHelpGetLat => 'Показва зададената географска ширина.'; + + @override + String get repeater_cliHelpGetLon => 'Показва зададената дължина.'; + + @override + String get repeater_cliHelpGetRxDelay => + 'Показва основната стойност на забавянето на сигнала.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Показва коефициента за забавяне при режим на наводняване.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Показва коефициента за забавяне при директен режим.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Показва максималния брой на повторни наводнения.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Показва информацията за контакт на собственика.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Показва режима на хеширане на пътя (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Показва чувствителността към откриване на цикли.'; + + @override + String get repeater_cliHelpGetAcl => + '(Само за серийни номера) Изброява настройките за контрол на достъпа в репитера.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Показва дали мостът е активиран.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Показва забавянето на моста в милисекунди.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Показва дали мостът изпраща или получава пакети RX или TX.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Само за мост RS232) Показва скоростта на предаване на данните на моста.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Само за моста ESPNow) Показва канала на WiFi на моста.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Само за моста ESPNow) Показва споделения секрет на моста.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(Само за NRF52) Показва версията на зареждащия софтуер.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Показва множителя на аналоговия-цифров преобразувател (мащабиране на напрежението от батерията).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Описва дали борда на директорите има поддръжка за управление на захранването.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Показва текущия източник на захранване: външен или батерия.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Показва най-скорошните причини за рестартиране и изключване.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Показва напрежението на батерията при стартиране, измерено в миливолта (mV).'; + + @override + String get repeater_cliHelpSensorGet => + 'Чете персонализирана настройка на сензор чрез клавиш.'; + + @override + String get repeater_cliHelpSensorSet => + 'Създава персонализирана настройка за сензор.'; + + @override + String get repeater_cliHelpSensorList => + 'Показва всички настройки на потребителските сензори, разделени на страници, започвайки от опционален индекс.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Показва текущия обхват на региона по подразбиране.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Задава обхвата на региона по подразбиране. Използвайте \"\", за да го изчистите.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Списва регионите, които позволяват преминаване на превозни средства при наводнение.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Списва региони, които забраняват движението по пътищата при наводнения.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Само за серия) Показва статистически данни на ниво пакет.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Само за конкретен сериал) Показва радиостатистика.'; + + @override + String get repeater_cliHelpStatsCore => + '(Само за серийния номер) Показва основните статистически данни за фърмуера.'; + @override String get telemetry_receivedData => 'Получени телеметрични данни'; @@ -3068,7 +3587,7 @@ class AppLocalizationsBg extends AppLocalizations { String get listFilter_heardRecently => 'Слушано е наскоро'; @override - String get listFilter_az => 'A-Z'; + String get listFilter_az => 'А-Я'; @override String get listFilter_filters => 'Филтри'; @@ -3238,6 +3757,37 @@ class AppLocalizationsBg extends AppLocalizations { @override String get losLegendTerrain => 'Терен'; + @override + String get losBlockedSpotsTitle => 'Ограничени места'; + + @override + String get losBlockedSpotsHint => + 'Кликнете върху блокираната точка, за да я отбележите на картата.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Избрано препятствие'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Честота'; @@ -3702,4 +4252,40 @@ class AppLocalizationsBg extends AppLocalizations { @override String get translation_systemLanguage => 'Език на системата'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index d7c1691..9f06906 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -24,7 +24,7 @@ class AppLocalizationsDe extends AppLocalizations { String get common_cancel => 'Abbrechen'; @override - String get common_ok => 'OK'; + String get common_ok => 'Alles klar'; @override String get common_connect => 'Verbinden'; @@ -44,6 +44,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get common_close => 'Schließen'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Bearbeiten'; @@ -109,7 +112,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get scanner_title => 'MeshCore Open'; + String get scanner_title => 'MeshCore – Open-Version'; @override String get connectionChoiceUsbLabel => 'USB'; @@ -130,7 +133,7 @@ class AppLocalizationsDe extends AppLocalizations { String get tcpHostHint => '192.168.40.10'; @override - String get tcpPortLabel => 'Port'; + String get tcpPortLabel => 'Hafen'; @override String get tcpPortHint => '5000'; @@ -435,9 +438,7 @@ class AppLocalizationsDe extends AppLocalizations { 'Ort in der Anzeige einbeziehen'; @override - String settings_multiAck(String value) { - return 'Mehrfach-Bestätigungen: $value'; - } + String get settings_multiAck => 'Mehrere Bestätigungen'; @override String get settings_telemetryModeUpdated => 'Telemetriemodus aktualisiert'; @@ -445,6 +446,13 @@ class AppLocalizationsDe extends AppLocalizations { @override String get settings_actions => 'Aktionen'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Sende Ankündigung'; @@ -485,11 +493,12 @@ class AppLocalizationsDe extends AppLocalizations { String get settings_debug => 'Fehlerbehebung'; @override - String get settings_bleDebugLog => 'BLE-Debug-Protokoll'; + String get settings_companionDebugLog => + 'Debug-Protokoll für die Begleitsoftware'; @override - String get settings_bleDebugLogSubtitle => - 'BLE-Befehle, Antworten und Rohdaten'; + String get settings_companionDebugLogSubtitle => + 'BLE/TCP/USB-Befehle, Antworten und Rohdaten'; @override String get settings_appDebugLog => 'App-Debug-Protokoll'; @@ -502,7 +511,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String settings_aboutVersion(String version) { - return 'MeshCore Open v$version'; + return 'MeshCore Open, Version $version'; } @override @@ -562,7 +571,7 @@ class AppLocalizationsDe extends AppLocalizations { String get settings_txPower => 'TX-Leistung (dBm)'; @override - String get settings_txPowerHelper => '0 - 22'; + String get settings_txPowerHelper => '0 – 22'; @override String get settings_txPowerInvalid => 'Ungültige TX-Leistung (0-22 dBm)'; @@ -590,7 +599,7 @@ class AppLocalizationsDe extends AppLocalizations { String get appSettings_appearance => 'Aussehen'; @override - String get appSettings_theme => 'Theme'; + String get appSettings_theme => 'Thema'; @override String get appSettings_themeSystem => 'Systemstandard'; @@ -608,43 +617,43 @@ class AppLocalizationsDe extends AppLocalizations { String get appSettings_languageSystem => 'Systemstandard'; @override - String get appSettings_languageEn => 'English'; + String get appSettings_languageEn => 'Englisch'; @override - String get appSettings_languageFr => 'Français'; + String get appSettings_languageFr => 'Französisch'; @override - String get appSettings_languageEs => 'Español'; + String get appSettings_languageEs => 'Spanisch'; @override String get appSettings_languageDe => 'Deutsch'; @override - String get appSettings_languagePl => 'Polski'; + String get appSettings_languagePl => 'Polnisch'; @override - String get appSettings_languageSl => 'Slovenščina'; + String get appSettings_languageSl => 'Slowenisch'; @override - String get appSettings_languagePt => 'Português'; + String get appSettings_languagePt => 'Portugiesisch'; @override - String get appSettings_languageIt => 'Italiano'; + String get appSettings_languageIt => 'Italienisch'; @override - String get appSettings_languageZh => '中文'; + String get appSettings_languageZh => 'Chinesisch'; @override - String get appSettings_languageSv => 'Svenska'; + String get appSettings_languageSv => 'Schwedisch'; @override - String get appSettings_languageNl => 'Nederlands'; + String get appSettings_languageNl => 'Niederländisch'; @override - String get appSettings_languageSk => 'Slovenčina'; + String get appSettings_languageSk => 'Slowenisch'; @override - String get appSettings_languageBg => 'Български'; + String get appSettings_languageBg => 'Bulgarisch'; @override String get appSettings_languageRu => 'Russisch'; @@ -1086,20 +1095,16 @@ class AppLocalizationsDe extends AppLocalizations { return 'Kanal $index'; } - @override - String get channels_hashtagChannel => 'Hashtag-Kanal'; - @override String get channels_public => 'Öffentlich'; @override - String get channels_private => 'Privat'; - - @override - String get channels_publicChannel => 'Öffentlicher Kanal'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Privater Kanal'; + String get channels_private => 'Privat'; @override String get channels_editChannel => 'Kanal bearbeiten'; @@ -1144,7 +1149,7 @@ class AppLocalizationsDe extends AppLocalizations { String get channels_standardPublicPsk => 'Öffentliche Standard PSK'; @override - String get channels_pskHex => 'PSK (Hex)'; + String get channels_pskHex => 'PSK (Hexadezimal)'; @override String get channels_generateRandomPsk => 'Zufällige PSK generieren'; @@ -1170,11 +1175,67 @@ class AppLocalizationsDe extends AppLocalizations { @override String get channels_smazCompression => 'SMAZ-Komprimierung'; + @override + String get channels_cyr2latCompression => 'Cyr2Lat-Komprimierung'; + + @override + String get channels_cyr2latCompressionDscr => + 'Ersetzt einige kyrillische Zeichen durch lateinische Zeichen, wenn sie gesendet werden.'; + + @override + String get channels_cyr2latSettingsHeading => 'Cyr2Lat-Einstellungen'; + + @override + String get channels_cyr2latSettingsSubheading => 'Ersetzungsliste'; + + @override + String get channels_cyr2latSettingsDscr => + 'JSON-Konfiguration für die Zeichenersetzung bearbeiten'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON-Ersetzungstabelle'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'Ungültiges JSON: $error'; + } + @override String channels_channelUpdated(String name) { return 'Kanal \"$name\" aktualisiert'; } + @override + String get settings_cyr2latProfileAdd => 'Cyr2Lat-Profil hinzufügen'; + + @override + String get settings_cyr2latProfileName => 'Profilname'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'Der Profilname darf nicht leer sein'; + + @override + String get settings_cyr2latProfileAdded => 'Profil erfolgreich hinzugefügt'; + + @override + String get settings_cyr2latProfileUpdated => + 'Profil erfolgreich aktualisiert'; + + @override + String get settings_cyr2latProfileEdit => 'Cyr2Lat-Profil bearbeiten'; + + @override + String get settings_cyr2latProfileDelete => 'Cyr2Lat-Profil löschen'; + + @override + String get settings_cyr2latProfileDeleted => 'Profil erfolgreich gelöscht'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Möchten Sie das Profil \"$name\" wirklich löschen?'; + } + @override String get channels_publicChannelAdded => 'Öffentlicher Kanal hinzugefügt'; @@ -1391,7 +1452,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String debugFrame_flags(String value) { - return '- Flags: 0x$value'; + return '- Flaggen: 0x$value'; } @override @@ -1400,7 +1461,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get debugFrame_textTypeCli => 'CLI'; + String get debugFrame_textTypeCli => 'Befehlszeilen-Schnittstelle'; @override String get debugFrame_textTypePlain => 'Einfach'; @@ -1457,6 +1518,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get chat_successes => 'Erfolgreich'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Pfad entfernen'; @@ -1557,6 +1621,12 @@ class AppLocalizationsDe extends AppLocalizations { return 'Ungelesen: $count'; } + @override + String get chat_markAsUnread => 'Als nicht gelesen markieren'; + + @override + String get chat_newMessages => 'Neue Nachrichten'; + @override String get chat_openLink => 'Link öffnen?'; @@ -1598,14 +1668,14 @@ class AppLocalizationsDe extends AppLocalizations { @override String map_pinsCount(int count) { - return 'Pins: $count'; + return 'Nadeln: $count'; } @override String get map_chat => 'Benutzer'; @override - String get map_repeater => 'Repeater'; + String get map_repeater => 'Wiederholungseinheit'; @override String get map_room => 'Raum'; @@ -1620,7 +1690,7 @@ class AppLocalizationsDe extends AppLocalizations { String get map_pinPrivate => 'Pin (Channel)'; @override - String get map_pinPublic => 'Pin (Public)'; + String get map_pinPublic => 'Kennzeichnung (Öffentlich)'; @override String get map_lastSeen => 'Letzte Sichtung'; @@ -1636,7 +1706,25 @@ class AppLocalizationsDe extends AppLocalizations { String get map_source => 'Quelle'; @override - String get map_flags => 'Flags'; + String get map_flags => 'Flaggen'; + + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; @override String get map_shareMarkerHere => 'Teilen Sie den Marker hier.'; @@ -1648,7 +1736,7 @@ class AppLocalizationsDe extends AppLocalizations { String get map_pinLabel => 'Pin Name'; @override - String get map_label => 'Label'; + String get map_label => 'Etikett'; @override String get map_pointOfInterest => 'Punkt von Interesse'; @@ -1723,6 +1811,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get map_sharedPin => 'Gemeinsames Passwort'; + @override + String get map_sharedAt => 'Geteilt'; + @override String get map_joinRoom => 'Beitreten Sie dem Raum'; @@ -2044,7 +2135,7 @@ class AppLocalizationsDe extends AppLocalizations { 'Sensordaten und Systemwerte anzeigen'; @override - String get repeater_cli => 'CLI'; + String get repeater_cli => 'Befehlszeilen-Schnittstelle'; @override String get repeater_cliSubtitle => 'Sende Befehle an den Repeater'; @@ -2133,6 +2224,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get repeater_rxAirtime => 'RX Airtime'; + @override + String get repeater_chanUtil => 'Nutzung des Kanals'; + @override String get repeater_packetStatistics => 'Paketstatistiken'; @@ -2182,7 +2276,7 @@ class AppLocalizationsDe extends AppLocalizations { String get repeater_basicSettings => 'Grundlegende Einstellungen'; @override - String get repeater_repeaterName => 'Repeater Name'; + String get repeater_repeaterName => 'Name des Repeater'; @override String get repeater_repeaterNameHelper => 'Anzeigename für diesen Repeater'; @@ -2207,7 +2301,7 @@ class AppLocalizationsDe extends AppLocalizations { String get repeater_frequencyMhz => 'Frequenz (MHz)'; @override - String get repeater_frequencyHelper => '300-2500 MHz'; + String get repeater_frequencyHelper => '300–2500 MHz'; @override String get repeater_txPower => 'TX Power'; @@ -2344,6 +2438,166 @@ class AppLocalizationsDe extends AppLocalizations { @override String get repeater_settingsSaved => 'Einstellungen erfolgreich gespeichert'; + @override + String get repeater_rxGain => 'Erhöhter RX-Gewinn'; + + @override + String get repeater_rxGainHelper => + 'Höhere Empfindlichkeit, höherer Stromverbrauch (nur für SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => 'Erneuerung des verstärkten RX-Effekts'; + + @override + String get repeater_multiAcks => 'Mehrere Bestätigungen'; + + @override + String get repeater_multiAcksSubtitle => + 'Nachrichten über verschiedene Pfade senden, um die Zustellbarkeit zu verbessern.'; + + @override + String get repeater_refreshMultiAcks => + 'Mehrere Bestätigungen neu senden/aktualisieren'; + + @override + String get repeater_networkHealth => 'Netzwerkgesundheit'; + + @override + String get repeater_loopDetect => 'Erkennung von Schleifen'; + + @override + String get repeater_loopDetectHelper => + 'Erstellen Sie \"Flood\"-Pakete, die so aussehen, als ob sie Schleifen erzeugen.'; + + @override + String get repeater_loopDetectOff => 'Aus'; + + @override + String get repeater_loopDetectMinimal => 'Minimal'; + + @override + String get repeater_loopDetectModerate => 'mäßig'; + + @override + String get repeater_loopDetectStrict => 'streng'; + + @override + String get repeater_dutyCycle => 'Betriebsdauer'; + + @override + String get repeater_dutyCycleHelper => + 'Höchster zulässiger Prozentsatz der Sendefläche'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Information zum Betreiber'; + + @override + String get repeater_ownerInfoHelper => + 'Öffentliche Metadaten für dieses Gerät'; + + @override + String get repeater_refreshOwnerInfo => + 'Aktualisieren Sie die Informationen zum Betreiber'; + + @override + String get repeater_floodMax => 'Max-Hops-Flut'; + + @override + String get repeater_floodMaxHelper => + 'Maximale Anzahl an Hop-Paketen, die ein einzelnes Paket durchlaufen kann (0-64)'; + + @override + String get repeater_advancedSettings => 'Fortgeschritten'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Regler für erfahrene Bediener'; + + @override + String get repeater_pathHashMode => 'Hash-Modus für Pfade'; + + @override + String get repeater_pathHashModeHelper => + 'Bytes, die zur Kodierung der ID dieses Repeaters in Flood-Pfad-/Schleifen-Erkennung-Tags verwendet werden. 0 = 1 Byte (256 IDs, bis zu 64 Hops), 1 = 2 Bytes (65.000 IDs, bis zu 32 Hops), 2 = 3 Bytes (16 Millionen IDs, bis zu 21 Hops). Firmware-Versionen 1.13 und älter verwenden mehrstellige Pfade – ab Version 1.14+ wird nur ein Pfad erstellt, sobald das Netzwerk aktiv ist.'; + + @override + String get repeater_txDelay => 'Verzögerung bei Flood TX'; + + @override + String get repeater_txDelayHelper => + 'Wiederholung des Abstands für Hochwasser-Verkehr, als Multiplikator der Übertragungszeit des Pakets (0-2, Standardwert 0,5). Höherer Wert = weniger Kollisionen, aber langsamere Übertragung.'; + + @override + String get repeater_directTxDelay => 'Direkter TX-Verzögerung'; + + @override + String get repeater_directTxDelayHelper => + 'Die Übertragungsrate für direkten (nicht-fluten) Datenverkehr wird als Vielfaches der Übertragungszeit des Pakets festgelegt (0-2, Standardwert 0,3).'; + + @override + String get repeater_intThresh => 'Grenzwert für Störungen'; + + @override + String get repeater_intThreshHelper => + 'Der Schwellenwert wird an die Rauschpegel-Kalibrierung des Radios angepasst, sodass Störungen über diesem Wert abgefangen werden. 0 deaktiviert – erhöhen Sie diesen Wert nur, wenn Sie in einem verrauschten Frequenzbereich RX-Fehler feststellen.'; + + @override + String get repeater_agcResetInterval => + 'Intervall für die Rücksetzung von AGC'; + + @override + String get repeater_agcResetIntervalHelper => + 'Wie oft sollte die automatische Verstärkungskontrolle des Radios zurückgesetzt werden, um von einem Zustand mit zu hoher Verstärkung wieder in einen normalen Zustand zu gelangen? Die Einstellung „Sekunden“ ermöglicht eine Rücksetzung alle 4 Sekunden. Die Einstellung „0“ deaktiviert die periodische Rücksetzung.'; + + @override + String get repeater_actionsTitle => 'Aktionen'; + + @override + String get repeater_sendAdvert => 'Flood-Werbung versenden'; + + @override + String get repeater_sendAdvertSubtitle => + 'Eine Werbekampagne für Überschwemmungen über das Netzwerk verbreiten.'; + + @override + String get repeater_sendAdvertZeroHop => + 'Versenden Sie eine Anzeige ohne Zwischenvermittler.'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Eine Werbekampagne mit einem einzigen Sender (ohne Weiterleitung) senden.'; + + @override + String get repeater_clockSync => 'Uhr jetzt synchronisieren'; + + @override + String get repeater_clockSyncSubtitle => + 'Übertragen Sie die Uhrzeit Ihres Telefons an den Repeater.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action war erfolgreich'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action fehlgeschlagen: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Einstellungen gespeichert – Repeater neu starten, um die Änderungen anzuwenden.'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Einige Einstellungen sind fehlgeschlagen: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Fehler beim Speichern der Einstellungen: $error'; @@ -2360,10 +2614,6 @@ class AppLocalizationsDe extends AppLocalizations { @override String get repeater_refreshTxPower => 'Sendeleistung aktualisieren'; - @override - String get repeater_refreshLocationSettings => - 'Aktualisieren Sie die Standort Einstellungen'; - @override String get repeater_refreshPacketForwarding => 'Aktualisieren Paketweiterleitung'; @@ -2375,10 +2625,6 @@ class AppLocalizationsDe extends AppLocalizations { String get repeater_refreshPrivacyMode => 'Wiederherstellen des Datenschutzzustands'; - @override - String get repeater_refreshAdvertisementSettings => - 'Aktualisieren Sie die Ankündigungseinstellungen'; - @override String repeater_refreshed(String label) { return '$label wurde aktualisiert'; @@ -2390,7 +2636,8 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get repeater_cliTitle => 'Repeater CLI'; + String get repeater_cliTitle => + 'Befehlszeilen-Schnittstelle (CLI) für Repeater'; @override String get repeater_debugNextCommand => 'Fehlersuche des nächsten Befehls'; @@ -2702,6 +2949,284 @@ class AppLocalizationsDe extends AppLocalizations { String get repeater_gpsNote => 'Der GPS-Befehl wurde eingeführt, um Standortbezogene Themen zu verwalten.'; + @override + String get repeater_getCategory => 'Werte erhalten'; + + @override + String get repeater_powerMgmt => 'Energieverwaltung'; + + @override + String get repeater_sensors => 'Sensoren'; + + @override + String get repeater_cliHelpPowerOff => + 'Schaltet das Gerät aus. (keine Antwort erwartet)'; + + @override + String get repeater_cliHelpClkReboot => + 'Setzt die Uhr auf einen bekannten Zeitpunkt zurück und startet das Gerät neu.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Sendet eine Werbeanzeige, die nur an unmittelbare Nachbarn gesendet wird (ohne Zwischenstation).'; + + @override + String get repeater_cliHelpStartOta => + 'Startet ein Firmware-Update über Funk, das auf unterstützten Boards durchgeführt wird.'; + + @override + String get repeater_cliHelpTime => + 'Stellt die Gerätuhr auf die angegebene Unix-Epoche in Sekunden ein. Die Uhr kann nicht rückwärts laufen.'; + + @override + String get repeater_cliHelpBoard => + 'Zeigt den Hersteller/die Hardware-Kennung an.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Sendet eine Anfrage zur Entdeckung von Nachbarn in der Nähe. (Nur bei Repeatern)'; + + @override + String get repeater_cliHelpPowersaving => + 'Zeigt an, ob der Energiesparmodus aktiviert oder deaktiviert ist.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Aktiviert oder deaktiviert den Energiesparmodus (falls unterstützt).'; + + @override + String get repeater_cliHelpErase => + '(Nur für serielle Schnittstellen) Formatiert das Dateisystem des Geräts. Löscht alle Einstellungen und Kontakte.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Legt den maximal zulässigen Übertragungszyklus als Prozentsatz fest (1-100). Passt den Zeitfaktor intern an.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Nur für serielle Anwendungen) Ersetzt den privaten Schlüssel zur Geräteidentifizierung. Nach der Anwendung ist ein Neustart erforderlich. Generiert einen neuen öffentlichen Schlüssel.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(Nur für SX126x) Schaltet die verstärkte RX-Verstärkung ein, um die Empfindlichkeit bei höherem Stromverbrauch zu verbessern.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Definiert den String mit den Kontaktinformationen des Eigentümers, der in den Anzeigen enthalten ist. Verwenden Sie \'|\' für Zeilenumbrüche.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Legt den Modus für die Pfad-Hashes fest. 0 = ältere Version, 1 = Standard, 2 = streng. Beeinflusst, wie Routing-Pfade abgeglichen werden.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Legt die Empfindlichkeit der Schleifenerkennung fest: aus, minimal, moderat oder streng.'; + + @override + String get repeater_cliHelpSetFreq => + '(Nur für die serielle Schnittstelle) Ermöglicht die schnelle Einstellung der Frequenz. Nach der Einstellung ist ein Neustart erforderlich. Für die vollständige Einstellung aller Radio-Parameter wird die Option \"Radio einstellen\" empfohlen.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Nur für ESPNow-Brücke) Legt den verwendeten WLAN-Kanal (1-14) für die Brücke fest.'; + + @override + String get repeater_cliHelpGetName => + 'Zeigt den konfigurierten Knotenamen an.'; + + @override + String get repeater_cliHelpGetRole => + 'Zeigt die Funktion der Firmware an (Repeater, Raumserver usw.).'; + + @override + String get repeater_cliHelpGetPublicKey => + 'Zeigt den öffentlichen Schlüssel des Geräts an.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Nur für serielle Kommunikation) Zeigt den privaten Schlüssel des Geräts an. Behandeln Sie diesen als ein Geheimnis.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Zeigt an, ob die Weiterleitung von Paketen (als Repeater) aktiviert oder deaktiviert ist.'; + + @override + String get repeater_cliHelpGetTx => + 'Zeigt die aktuelle Sendeleistung in dBm an.'; + + @override + String get repeater_cliHelpGetFreq => + 'Zeigt die konfigurierte Funkfrequenz in MHz an.'; + + @override + String get repeater_cliHelpGetRadio => + 'Zeigt alle Funkparameter an: Frequenz, Bandbreite, Spreading-Faktor, Codierungsrate.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(Nur für SX126x) Zeigt den Zustand des verstärkten Empfangs (RX).'; + + @override + String get repeater_cliHelpGetAf => 'Zeigt den aktuellen Zeitfaktor an.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Zeigt den aktuellen zulässigen Schaltzyklus als Prozentsatz an.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Zeigt den Grenzwert für Kanalüberlagerung in dB an.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Zeigt das Intervall für die Rücksetzung des AGC in Sekunden an.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Zeigt an, ob der Modus \"doppelte ACK\"-Funktion aktiviert (1) oder deaktiviert (0) ist.'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Zeigt an, ob der Zugriff für Gäste nur in Lesemodus erlaubt ist.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Zeigt die Dauer des lokalen Werbeintervalls in Minuten an.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Zeigt die Dauer der Werbeunterbrechung in Stunden an.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Zeigt das konfigurierte Gast-Passwort an.'; + + @override + String get repeater_cliHelpGetLat => 'Zeigt die konfigurierte Breitengrade.'; + + @override + String get repeater_cliHelpGetLon => 'Zeigt die konfigurierte Länge an.'; + + @override + String get repeater_cliHelpGetRxDelay => + 'Zeigt den Basiswert für die Verzögerungszeit an.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Zeigt den Faktor für die Übertragungsverzögerung im Notfallmodus an.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Zeigt den Faktor für die Verzögerung im Direktmodus an.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Zeigt die maximale Anzahl von Überschwemmungsphasen an.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Zeigt die Zeichenkette mit den Kontaktinformationen des Eigentümers an.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Zeigt den Pfad-Hash-Modus (0/1/2) an.'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Zeigt die Empfindlichkeit der Schleifenerkennung an.'; + + @override + String get repeater_cliHelpGetAcl => + '(Nur für serielle Kommunikation) Zeigt die Zugriffskontrolleinträge auf einem Repeater an.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Zeigt an, ob die Brücke aktiviert ist.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Zeigt die Verzögerung der Brücke in Millisekunden an.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Zeigt, ob die Brücke RX- oder TX-Pakete empfängt oder sendet.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Nur für RS232-Verbindungen) Zeigt die Baudrate der Verbindung an.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Nur für ESPNow-Brücke) Zeigt den WLAN-Kanal der Brücke an.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Nur für ESPNow-Brücke) Zeigt das gemeinsam genutzte Geheimnis der Brücke.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(Nur für NRF52) Zeigt die Version des Bootloaders an.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Zeigt den ADC-Verstärker (Spannungs-Skalierung) an.'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Gibt an, ob der Verwaltungsrat die Funktion zur Energieverwaltung unterstützt.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Zeigt die aktuelle Stromquelle an: extern oder Batterie.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Zeigt die aktuellsten Gründe für einen Neustart und Herunterfahren an.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Zeigt die Batteriespannung beim Start in Millivolt (mV) an.'; + + @override + String get repeater_cliHelpSensorGet => + 'Liest eine benutzerdefinierte Sensoreinstellung über eine Taste.'; + + @override + String get repeater_cliHelpSensorSet => + 'Erstellt eine benutzerdefinierte Sensoreinstellung.'; + + @override + String get repeater_cliHelpSensorList => + 'Zeigt alle benutzerdefinierten Sensoreinstellungen an, wobei die Seitennummerierung optional von einem Startindex abhängt.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Zeigt den aktuellen Standard-Region-Bereich an.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Definiert den Standard-Regionenbereich. Verwenden Sie \"\", um diesen zu löschen.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Nennt die Regionen, die Überschwemmungsverkehr zulassen.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Auflistung von Regionen, die den Verkehr aufgrund von Überschwemmungen verbieten.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Nur für serielle Verbindungen) Zeigt Statistiken auf Paketebene.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Nur für Serien) Zeigt Radiostatistiken an.'; + + @override + String get repeater_cliHelpStatsCore => + '(Nur für serielle Schnittstellen) Zeigt grundlegende Firmware-Statistiken.'; + @override String get telemetry_receivedData => 'Empfangene Telemetriedaten'; @@ -2889,7 +3414,7 @@ class AppLocalizationsDe extends AppLocalizations { String get channelPath_unknownRepeater => 'Unbekannter Repeater'; @override - String get community_title => 'Community'; + String get community_title => 'Gemeinschaft'; @override String get community_create => 'Erstelle Community'; @@ -2923,10 +3448,10 @@ class AppLocalizationsDe extends AppLocalizations { String get community_publicChannel => 'Community Öffentlich'; @override - String get community_hashtagChannel => 'Community Hashtag'; + String get community_hashtagChannel => 'Gemeinschaftlicher Hashtag'; @override - String get community_name => 'Community Name'; + String get community_name => 'Name der Gemeinde'; @override String get community_enterName => 'Bitte Community-Name eingeben'; @@ -3048,7 +3573,7 @@ class AppLocalizationsDe extends AppLocalizations { 'Öffentlicher Hashtag (jeder kann teilnehmen)'; @override - String get community_communityHashtag => 'Community Hashtag'; + String get community_communityHashtag => 'Gemeinschaftlicher Hashtag'; @override String get community_communityHashtagDesc => @@ -3072,7 +3597,7 @@ class AppLocalizationsDe extends AppLocalizations { String get listFilter_heardRecently => 'Kürzlich gehört'; @override - String get listFilter_az => 'A-Z'; + String get listFilter_az => 'Von A bis Z'; @override String get listFilter_filters => 'Filtere'; @@ -3243,6 +3768,37 @@ class AppLocalizationsDe extends AppLocalizations { @override String get losLegendTerrain => 'Gelände'; + @override + String get losBlockedSpotsTitle => 'Reservierte Plätze'; + + @override + String get losBlockedSpotsHint => + 'Klicken Sie auf einen blockierten Bereich, um ihn auf der Karte hervorzuheben.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance • $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Ausgewählte Behinderung'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blockiert durch $obstruction in einer Höhe von $heightUnit, $distanceFromA von A und $distanceFromB von B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Frequenz'; @@ -3713,4 +4269,40 @@ class AppLocalizationsDe extends AppLocalizations { @override String get translation_systemLanguage => 'Sprache des Systems'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index a2a88b0..6def06b 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -44,6 +44,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get common_close => 'Close'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Edit'; @@ -124,10 +127,10 @@ class AppLocalizationsEn extends AppLocalizations { String get tcpScreenTitle => 'Connect over TCP'; @override - String get tcpHostLabel => 'IP Address'; + String get tcpHostLabel => 'Endpoint'; @override - String get tcpHostHint => '192.168.40.10'; + String get tcpHostHint => '192.168.40.10 / example.com'; @override String get tcpPortLabel => 'Port'; @@ -144,7 +147,7 @@ class AppLocalizationsEn extends AppLocalizations { } @override - String get tcpErrorHostRequired => 'IP address is required.'; + String get tcpErrorHostRequired => 'Host is required.'; @override String get tcpErrorPortInvalid => 'Port must be between 1 and 65535.'; @@ -427,9 +430,7 @@ class AppLocalizationsEn extends AppLocalizations { String get settings_advertLocationSubtitle => 'Include location in advert.'; @override - String settings_multiAck(String value) { - return 'Multi-ACKs: $value'; - } + String get settings_multiAck => 'Multi-ACKs'; @override String get settings_telemetryModeUpdated => 'Telemetry mode updated'; @@ -437,6 +438,13 @@ class AppLocalizationsEn extends AppLocalizations { @override String get settings_actions => 'Actions'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Send Advertisement'; @@ -476,11 +484,11 @@ class AppLocalizationsEn extends AppLocalizations { String get settings_debug => 'Debug'; @override - String get settings_bleDebugLog => 'BLE Debug Log'; + String get settings_companionDebugLog => 'Companion Debug Log'; @override - String get settings_bleDebugLogSubtitle => - 'BLE commands, responses, and raw data'; + String get settings_companionDebugLogSubtitle => + 'BLE/TCP/USB commands, responses, and raw data'; @override String get settings_appDebugLog => 'App Debug Log'; @@ -1068,20 +1076,16 @@ class AppLocalizationsEn extends AppLocalizations { return 'Channel $index'; } - @override - String get channels_hashtagChannel => 'Hashtag channel'; - @override String get channels_public => 'Public'; @override - String get channels_private => 'Private'; - - @override - String get channels_publicChannel => 'Public channel'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Private channel'; + String get channels_private => 'Private'; @override String get channels_editChannel => 'Edit channel'; @@ -1150,11 +1154,65 @@ class AppLocalizationsEn extends AppLocalizations { @override String get channels_smazCompression => 'SMAZ compression'; + @override + String get channels_cyr2latCompression => 'Cyr2Lat compression'; + + @override + String get channels_cyr2latCompressionDscr => + 'Replaces some Cyrillic characters with Latin characters when sending.'; + + @override + String get channels_cyr2latSettingsHeading => 'Cyr2Lat Setup'; + + @override + String get channels_cyr2latSettingsSubheading => 'List of replacements'; + + @override + String get channels_cyr2latSettingsDscr => + 'Edit the JSON configuration of character replacement'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON replacement map'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'Invalid JSON: $error'; + } + @override String channels_channelUpdated(String name) { return 'Channel \"$name\" updated'; } + @override + String get settings_cyr2latProfileAdd => 'Add Cyr2Lat Profile'; + + @override + String get settings_cyr2latProfileName => 'Profile Name'; + + @override + String get settings_cyr2latProfileNameEmpty => 'Profile name cannot be empty'; + + @override + String get settings_cyr2latProfileAdded => 'Profile added successfully'; + + @override + String get settings_cyr2latProfileUpdated => 'Profile updated successfully'; + + @override + String get settings_cyr2latProfileEdit => 'Edit Cyr2Lat Profile'; + + @override + String get settings_cyr2latProfileDelete => 'Delete Cyr2Lat Profile'; + + @override + String get settings_cyr2latProfileDeleted => 'Profile deleted successfully'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Are you sure you want to delete the profile \"$name\"?'; + } + @override String get channels_publicChannelAdded => 'Public channel added'; @@ -1430,6 +1488,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get chat_successes => 'successes'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Remove path'; @@ -1527,6 +1588,12 @@ class AppLocalizationsEn extends AppLocalizations { return 'Unread: $count'; } + @override + String get chat_markAsUnread => 'Mark as Unread'; + + @override + String get chat_newMessages => 'New messages'; + @override String get chat_openLink => 'Open Link?'; @@ -1608,6 +1675,24 @@ class AppLocalizationsEn extends AppLocalizations { @override String get map_flags => 'Flags'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'Share marker here'; @@ -1692,6 +1777,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get map_sharedPin => 'Shared pin'; + @override + String get map_sharedAt => 'Shared'; + @override String get map_joinRoom => 'Join Room'; @@ -2092,6 +2180,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get repeater_rxAirtime => 'RX Airtime'; + @override + String get repeater_chanUtil => 'Channel Utilization'; + @override String get repeater_packetStatistics => 'Packet Statistics'; @@ -2298,6 +2389,160 @@ class AppLocalizationsEn extends AppLocalizations { @override String get repeater_settingsSaved => 'Settings saved successfully'; + @override + String get repeater_rxGain => 'Boosted RX gain'; + + @override + String get repeater_rxGainHelper => + 'Higher sensitivity, more current draw (SX1262/SX1268 only)'; + + @override + String get repeater_refreshRxGain => 'Refresh boosted RX gain'; + + @override + String get repeater_multiAcks => 'Multi-ACKs'; + + @override + String get repeater_multiAcksSubtitle => + 'Acknowledge messages over multiple paths for better delivery'; + + @override + String get repeater_refreshMultiAcks => 'Refresh multi-ACKs'; + + @override + String get repeater_networkHealth => 'Network health'; + + @override + String get repeater_loopDetect => 'Loop detection'; + + @override + String get repeater_loopDetectHelper => + 'Drop flood packets that look like routing loops'; + + @override + String get repeater_loopDetectOff => 'Off'; + + @override + String get repeater_loopDetectMinimal => 'Minimal'; + + @override + String get repeater_loopDetectModerate => 'Moderate'; + + @override + String get repeater_loopDetectStrict => 'Strict'; + + @override + String get repeater_dutyCycle => 'Duty cycle'; + + @override + String get repeater_dutyCycleHelper => 'Maximum percentage of airtime'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Operator info'; + + @override + String get repeater_ownerInfoHelper => 'Public metadata for this repeater'; + + @override + String get repeater_refreshOwnerInfo => 'Refresh operator info'; + + @override + String get repeater_floodMax => 'Flood max hops'; + + @override + String get repeater_floodMaxHelper => + 'Maximum hops a flood packet may travel (0-64)'; + + @override + String get repeater_advancedSettings => 'Advanced'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Tuning knobs for experienced operators'; + + @override + String get repeater_pathHashMode => 'Path hash mode'; + + @override + String get repeater_pathHashModeHelper => + 'Bytes used to encode this repeater\'s ID in flood path/loop-detect tags. 0=1 byte (256 IDs, up to 64 hops), 1=2 bytes (65K IDs, up to 32 hops), 2=3 bytes (16M IDs, up to 21 hops). v1.13 and older firmware drops multi-byte paths — only raise once your network is on v1.14+.'; + + @override + String get repeater_txDelay => 'Flood TX delay'; + + @override + String get repeater_txDelayHelper => + 'Retransmit spacing for flood traffic, as a multiplier of the packet\'s airtime (0-2, default 0.5). Higher = fewer collisions but slower delivery.'; + + @override + String get repeater_directTxDelay => 'Direct TX delay'; + + @override + String get repeater_directTxDelayHelper => + 'Retransmit spacing for direct (non-flood) traffic, as a multiplier of the packet\'s airtime (0-2, default 0.3).'; + + @override + String get repeater_intThresh => 'Interference threshold'; + + @override + String get repeater_intThreshHelper => + 'Threshold passed to the radio\'s noise-floor calibration so it rejects interference above this level. 0 disables — only raise if you see RX errors in a noisy band.'; + + @override + String get repeater_agcResetInterval => 'AGC reset interval'; + + @override + String get repeater_agcResetIntervalHelper => + 'How often to reset the radio\'s automatic gain control to recover from a stuck gain state. Seconds, snapped down to a multiple of 4. 0 disables periodic resets.'; + + @override + String get repeater_actionsTitle => 'Actions'; + + @override + String get repeater_sendAdvert => 'Send flood advert'; + + @override + String get repeater_sendAdvertSubtitle => + 'Broadcast a flood advert through the network'; + + @override + String get repeater_sendAdvertZeroHop => 'Send zero-hop advert'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Broadcast a one-hop advert (no relays)'; + + @override + String get repeater_clockSync => 'Sync clock now'; + + @override + String get repeater_clockSyncSubtitle => + 'Push your phone\'s time to the repeater'; + + @override + String repeater_actionSucceeded(String action) { + return '$action succeeded'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action failed: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Settings saved — reboot the repeater to apply'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Some settings failed: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Error saving settings: $error'; @@ -2312,9 +2557,6 @@ class AppLocalizationsEn extends AppLocalizations { @override String get repeater_refreshTxPower => 'Refresh TX power'; - @override - String get repeater_refreshLocationSettings => 'Refresh Location Settings'; - @override String get repeater_refreshPacketForwarding => 'Refresh Packet Forwarding'; @@ -2324,10 +2566,6 @@ class AppLocalizationsEn extends AppLocalizations { @override String get repeater_refreshPrivacyMode => 'Refresh Privacy Mode'; - @override - String get repeater_refreshAdvertisementSettings => - 'Refresh Advertisement Settings'; - @override String repeater_refreshed(String label) { return '$label refreshed'; @@ -2649,6 +2887,278 @@ class AppLocalizationsEn extends AppLocalizations { String get repeater_gpsNote => 'gps command has been introduced to manage location related topics.'; + @override + String get repeater_getCategory => 'Get Values'; + + @override + String get repeater_powerMgmt => 'Power Management'; + + @override + String get repeater_sensors => 'Sensors'; + + @override + String get repeater_cliHelpPowerOff => + 'Powers the device off. (no response expected)'; + + @override + String get repeater_cliHelpClkReboot => + 'Resets the clock to a known epoch and reboots the device.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Sends a zero-hop advertisement (immediate neighbors only).'; + + @override + String get repeater_cliHelpStartOta => + 'Starts an over-the-air firmware update on supported boards.'; + + @override + String get repeater_cliHelpTime => + 'Sets the device clock to the given Unix epoch seconds. Clock cannot move backwards.'; + + @override + String get repeater_cliHelpBoard => + 'Shows the board manufacturer / hardware identifier.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Sends a node-discovery request to nearby neighbors. (Repeater only)'; + + @override + String get repeater_cliHelpPowersaving => + 'Shows whether powersaving mode is on or off.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Enables or disables powersaving mode (where supported).'; + + @override + String get repeater_cliHelpErase => + '(Serial only) Formats the device file system. Wipes all settings and contacts.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Sets the maximum allowed transmit duty cycle as a percentage (1-100). Internally adjusts the airtime factor.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Serial only) Replaces the device identity private key. Reboot required to apply. Generates a new public key.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(SX126x only) Toggles boosted RX gain for improved sensitivity at higher current draw.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Sets the owner contact info string included in adverts. Use \'|\' for newlines.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Sets the path-hash mode. 0 = legacy, 1 = standard, 2 = strict. Affects how routing paths are matched.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Sets the routing loop-detection sensitivity: off, minimal, moderate, or strict.'; + + @override + String get repeater_cliHelpSetFreq => + '(Serial only) Quickly sets just the frequency. Reboot required. Prefer \"set radio\" for full radio params.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(ESPNow bridge only) Sets the WiFi channel (1-14) used by the bridge.'; + + @override + String get repeater_cliHelpGetName => 'Shows the configured node name.'; + + @override + String get repeater_cliHelpGetRole => + 'Shows the firmware role (Repeater, Room Server, etc.).'; + + @override + String get repeater_cliHelpGetPublicKey => 'Shows the device public key.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Serial only) Shows the device private key. Treat as a secret.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Shows whether packet forwarding (repeater role) is on or off.'; + + @override + String get repeater_cliHelpGetTx => 'Shows the current TX power in dBm.'; + + @override + String get repeater_cliHelpGetFreq => + 'Shows the configured radio frequency in MHz.'; + + @override + String get repeater_cliHelpGetRadio => + 'Shows full radio params: freq, bandwidth, spreading factor, coding rate.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(SX126x only) Shows the RX boosted gain state.'; + + @override + String get repeater_cliHelpGetAf => 'Shows the current airtime factor.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Shows the current allowed duty cycle as a percentage.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Shows the channel interference threshold in dB.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Shows the AGC reset interval in seconds.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Shows whether double-ACK mode is on (1) or off (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Shows whether guest read-only access is allowed.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Shows the local advertisement interval in minutes.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Shows the flood advertisement interval in hours.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Shows the configured guest password.'; + + @override + String get repeater_cliHelpGetLat => 'Shows the configured latitude.'; + + @override + String get repeater_cliHelpGetLon => 'Shows the configured longitude.'; + + @override + String get repeater_cliHelpGetRxDelay => 'Shows the rxdelay base value.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Shows the flood-mode txdelay factor.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Shows the direct-mode txdelay factor.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Shows the maximum flood hop count.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Shows the owner contact info string.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Shows the path-hash mode (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Shows the loop-detection sensitivity.'; + + @override + String get repeater_cliHelpGetAcl => + '(Serial only) Lists the access-control entries on a repeater.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Shows whether the bridge is enabled.'; + + @override + String get repeater_cliHelpGetBridgeDelay => 'Shows the bridge delay in ms.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Shows whether the bridge logs RX or TX packets.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(RS232 bridge only) Shows the bridge baud rate.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(ESPNow bridge only) Shows the bridge WiFi channel.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(ESPNow bridge only) Shows the bridge shared secret.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(NRF52 only) Shows the bootloader version.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Shows the ADC multiplier (battery-voltage scaling).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Reports whether the board has power-management support.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Shows the current power source: external or battery.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Shows the most recent reset and shutdown reasons.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Shows the boot-time battery voltage in mV.'; + + @override + String get repeater_cliHelpSensorGet => + 'Reads a custom sensor setting by key.'; + + @override + String get repeater_cliHelpSensorSet => 'Writes a custom sensor setting.'; + + @override + String get repeater_cliHelpSensorList => + 'Lists all custom sensor settings, paginated from optional start index.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Shows the current default region scope.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Sets the default region scope. Use \"\" to clear.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Lists regions that allow flood traffic.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Lists regions that deny flood traffic.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Serial only) Shows packet-level statistics.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Serial only) Shows radio statistics.'; + + @override + String get repeater_cliHelpStatsCore => + '(Serial only) Shows core firmware statistics.'; + @override String get telemetry_receivedData => 'Received Telemetry Data'; @@ -3182,6 +3692,37 @@ class AppLocalizationsEn extends AppLocalizations { @override String get losLegendTerrain => 'Terrain'; + @override + String get losBlockedSpotsTitle => 'Blocked spots'; + + @override + String get losBlockedSpotsHint => + 'Tap a blocked spot to highlight it on the map.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Selected obstruction'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Frequency'; @@ -3633,4 +4174,40 @@ class AppLocalizationsEn extends AppLocalizations { @override String get translation_systemLanguage => 'System language'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index a127012..bb4f40e 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -44,6 +44,9 @@ class AppLocalizationsEs extends AppLocalizations { @override String get common_close => 'Cerrar'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Editar'; @@ -109,7 +112,7 @@ class AppLocalizationsEs extends AppLocalizations { } @override - String get scanner_title => 'MeshCore Open'; + String get scanner_title => 'MeshCore: Versión abierta'; @override String get connectionChoiceUsbLabel => 'USB'; @@ -434,9 +437,7 @@ class AppLocalizationsEs extends AppLocalizations { String get settings_advertLocationSubtitle => 'Incluir ubicación en anuncio'; @override - String settings_multiAck(String value) { - return 'Multi-ACKs: $value'; - } + String get settings_multiAck => 'Múltiples respuestas de confirmación'; @override String get settings_telemetryModeUpdated => 'Modo de telemetría actualizado'; @@ -444,6 +445,13 @@ class AppLocalizationsEs extends AppLocalizations { @override String get settings_actions => 'Acciones'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Enviar Anuncio'; @@ -486,11 +494,11 @@ class AppLocalizationsEs extends AppLocalizations { String get settings_debug => 'Depurar'; @override - String get settings_bleDebugLog => 'Registro de Depuración BLE'; + String get settings_companionDebugLog => 'Registro de depuración asociado'; @override - String get settings_bleDebugLogSubtitle => - 'Comandos, respuestas y datos brutos de BLE'; + String get settings_companionDebugLogSubtitle => + 'Comandos, respuestas y datos brutos para protocolos BLE/TCP/USB'; @override String get settings_appDebugLog => 'Registro de Depuración de la App'; @@ -504,7 +512,7 @@ class AppLocalizationsEs extends AppLocalizations { @override String settings_aboutVersion(String version) { - return 'MeshCore Open v$version'; + return 'MeshCore Open versión $version'; } @override @@ -610,43 +618,43 @@ class AppLocalizationsEs extends AppLocalizations { String get appSettings_languageSystem => 'Predeterminado del sistema'; @override - String get appSettings_languageEn => 'English'; + String get appSettings_languageEn => 'Inglés'; @override - String get appSettings_languageFr => 'Français'; + String get appSettings_languageFr => 'Francés'; @override String get appSettings_languageEs => 'Español'; @override - String get appSettings_languageDe => 'Deutsch'; + String get appSettings_languageDe => 'Alemán'; @override - String get appSettings_languagePl => 'Polski'; + String get appSettings_languagePl => 'Polaco'; @override - String get appSettings_languageSl => 'Slovenščina'; + String get appSettings_languageSl => 'Esloveno'; @override - String get appSettings_languagePt => 'Português'; + String get appSettings_languagePt => 'Portugués'; @override String get appSettings_languageIt => 'Italiano'; @override - String get appSettings_languageZh => '中文'; + String get appSettings_languageZh => 'Chino'; @override - String get appSettings_languageSv => 'Svenska'; + String get appSettings_languageSv => 'Sueco'; @override - String get appSettings_languageNl => 'Nederlands'; + String get appSettings_languageNl => 'Neerlandés'; @override - String get appSettings_languageSk => 'Slovenčina'; + String get appSettings_languageSk => 'Esloveno'; @override - String get appSettings_languageBg => 'Български'; + String get appSettings_languageBg => 'Bulgaro'; @override String get appSettings_languageRu => 'Ruso'; @@ -798,10 +806,10 @@ class AppLocalizationsEs extends AppLocalizations { 'Conéctate a un dispositivo para elegir'; @override - String get appSettings_batteryNmc => '18650 NMC (3.0-4.2V)'; + String get appSettings_batteryNmc => '18650 NMC (3,0-4,2 V)'; @override - String get appSettings_batteryLifepo4 => 'LiFePO4 (2.6-3.65V)'; + String get appSettings_batteryLifepo4 => 'LiFePO4 (2.6-3.65 V)'; @override String get appSettings_batteryLipo => 'LiPo (3.0-4.2V)'; @@ -1013,7 +1021,7 @@ class AppLocalizationsEs extends AppLocalizations { @override String contacts_lastSeenMinsAgo(int minutes) { - return '~ $minutes min.'; + return '~ $minutes minutos'; } @override @@ -1088,20 +1096,16 @@ class AppLocalizationsEs extends AppLocalizations { return 'Canal $index'; } - @override - String get channels_hashtagChannel => 'Canal con hashtag'; - @override String get channels_public => 'Público'; @override - String get channels_private => 'Privado'; - - @override - String get channels_publicChannel => 'Canal público'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Canal privado'; + String get channels_private => 'Privado'; @override String get channels_editChannel => 'Editar canal'; @@ -1172,11 +1176,67 @@ class AppLocalizationsEs extends AppLocalizations { @override String get channels_smazCompression => 'Compresión SMAZ'; + @override + String get channels_cyr2latCompression => 'Compresión Cyr2Lat'; + + @override + String get channels_cyr2latCompressionDscr => + 'Reemplaza algunos caracteres cirílicos con caracteres latinos al enviar.'; + + @override + String get channels_cyr2latSettingsHeading => 'Configuración de Cyr2Lat'; + + @override + String get channels_cyr2latSettingsSubheading => 'Lista de sustituciones'; + + @override + String get channels_cyr2latSettingsDscr => + 'Editar la configuración JSON de sustitución de caracteres'; + + @override + String get channels_cyr2latSettingsDialogHint => 'Mapa JSON de sustituciones'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'JSON incorrecto: $error'; + } + @override String channels_channelUpdated(String name) { return 'Canal \"$name\" actualizado'; } + @override + String get settings_cyr2latProfileAdd => 'Añadir perfil Cyr2Lat'; + + @override + String get settings_cyr2latProfileName => 'Nombre del perfil'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'El nombre del perfil no puede estar vacío'; + + @override + String get settings_cyr2latProfileAdded => 'Perfil añadido correctamente'; + + @override + String get settings_cyr2latProfileUpdated => + 'Perfil actualizado correctamente'; + + @override + String get settings_cyr2latProfileEdit => 'Editar perfil Cyr2Lat'; + + @override + String get settings_cyr2latProfileDelete => 'Eliminar perfil Cyr2Lat'; + + @override + String get settings_cyr2latProfileDeleted => 'Perfil eliminado correctamente'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return '¿Está seguro de que desea eliminar el perfil \"$name\"?'; + } + @override String get channels_publicChannelAdded => 'Canal público añadido'; @@ -1187,7 +1247,7 @@ class AppLocalizationsEs extends AppLocalizations { String get channels_sortManual => 'Manual'; @override - String get channels_sortAZ => 'A-Z'; + String get channels_sortAZ => 'De la A a la Z'; @override String get channels_sortLatestMessages => 'Últimos mensajes'; @@ -1318,7 +1378,7 @@ class AppLocalizationsEs extends AppLocalizations { String get gifPicker_searchHint => 'Buscar GIFs...'; @override - String get gifPicker_poweredBy => 'Powered by GIPHY'; + String get gifPicker_poweredBy => 'Con tecnología de GIPHY'; @override String get gifPicker_noGifsFound => 'No se encontraron GIFs'; @@ -1400,7 +1460,7 @@ class AppLocalizationsEs extends AppLocalizations { } @override - String get debugFrame_textTypeCli => 'CLI'; + String get debugFrame_textTypeCli => 'Interfaz de línea de comandos'; @override String get debugFrame_textTypePlain => 'Sencillo'; @@ -1446,8 +1506,8 @@ class AppLocalizationsEs extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'hops', - one: 'hop', + other: 'saltos', + one: 'salto', ); return '$count $_temp0'; } @@ -1455,6 +1515,9 @@ class AppLocalizationsEs extends AppLocalizations { @override String get chat_successes => 'Éxitos'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Eliminar ruta'; @@ -1556,6 +1619,12 @@ class AppLocalizationsEs extends AppLocalizations { return 'Sin leer: $count'; } + @override + String get chat_markAsUnread => 'Marcar como no leído'; + + @override + String get chat_newMessages => 'Nuevos mensajes'; + @override String get chat_openLink => '¿Abrir enlace?'; @@ -1613,7 +1682,7 @@ class AppLocalizationsEs extends AppLocalizations { String get map_sensor => 'Sensor'; @override - String get map_pinDm => 'Pin (DM)'; + String get map_pinDm => 'Etiqueta (DM)'; @override String get map_pinPrivate => 'Bloqueo (Privado)'; @@ -1637,6 +1706,24 @@ class AppLocalizationsEs extends AppLocalizations { @override String get map_flags => 'Banderas'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'Compartir marcador aquí'; @@ -1722,6 +1809,9 @@ class AppLocalizationsEs extends AppLocalizations { @override String get map_sharedPin => 'Pin compartido'; + @override + String get map_sharedAt => 'Compartido'; + @override String get map_joinRoom => 'Únete a la sala'; @@ -2035,14 +2125,14 @@ class AppLocalizationsEs extends AppLocalizations { 'Ver el estado, las estadísticas y los vecinos del repetidor'; @override - String get repeater_telemetry => 'Telemetry'; + String get repeater_telemetry => 'Telemetría'; @override String get repeater_telemetrySubtitle => 'Ver la telemetría de los sensores y las estadísticas del sistema'; @override - String get repeater_cli => 'CLI'; + String get repeater_cli => 'Interfaz de línea de comandos'; @override String get repeater_cliSubtitle => 'Enviar comandos al repetidor'; @@ -2129,6 +2219,9 @@ class AppLocalizationsEs extends AppLocalizations { @override String get repeater_rxAirtime => 'RX Airtime'; + @override + String get repeater_chanUtil => 'Utilización del canal'; + @override String get repeater_packetStatistics => 'Estadísticas del Paquete'; @@ -2341,6 +2434,164 @@ class AppLocalizationsEs extends AppLocalizations { @override String get repeater_settingsSaved => 'Guardado de ajustes exitoso'; + @override + String get repeater_rxGain => 'Aumento en la ganancia de RX'; + + @override + String get repeater_rxGainHelper => + 'Mayor sensibilidad, mayor consumo de corriente (solo para SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => + 'Aumenta el rendimiento de RX con la nueva versión.'; + + @override + String get repeater_multiAcks => 'Múltiples respuestas de confirmación'; + + @override + String get repeater_multiAcksSubtitle => + 'Reconocer mensajes a través de múltiples vías para una mejor entrega.'; + + @override + String get repeater_refreshMultiAcks => 'Reenviar múltiples confirmaciones'; + + @override + String get repeater_networkHealth => 'Salud de la red'; + + @override + String get repeater_loopDetect => 'Detección de bucles'; + + @override + String get repeater_loopDetectHelper => + 'Crea paquetes de \"flujo\" que parezcan bucles de enrutamiento.'; + + @override + String get repeater_loopDetectOff => 'Fuera'; + + @override + String get repeater_loopDetectMinimal => 'Mínimo'; + + @override + String get repeater_loopDetectModerate => 'Moderado'; + + @override + String get repeater_loopDetectStrict => 'Estrictos'; + + @override + String get repeater_dutyCycle => 'Ciclo de trabajo'; + + @override + String get repeater_dutyCycleHelper => + 'Porcentaje máximo de tiempo de antena'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Información del operador'; + + @override + String get repeater_ownerInfoHelper => + 'Metadatos públicos para este repetidor'; + + @override + String get repeater_refreshOwnerInfo => 'Actualizar información del operador'; + + @override + String get repeater_floodMax => + 'Máximo número de saltos en caso de inundación'; + + @override + String get repeater_floodMaxHelper => + 'Número máximo de paquetes de flujo que un nodo puede enviar (0-64)'; + + @override + String get repeater_advancedSettings => 'Avanzado'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Perillas de ajuste para operadores experimentados'; + + @override + String get repeater_pathHashMode => 'Modo de hash de ruta'; + + @override + String get repeater_pathHashModeHelper => + 'Bytes utilizados para codificar el ID de este repetidor en las etiquetas de ruta/detección de bucles. 0=1 byte (256 IDs, hasta 64 saltos), 1=2 bytes (65.000 IDs, hasta 32 saltos), 2=3 bytes (16 millones de IDs, hasta 21 saltos). Las versiones 1.13 y anteriores de firmware eliminan rutas de múltiples bytes; solo se detectan una vez que la red está activa en la versión 1.14 o posterior.'; + + @override + String get repeater_txDelay => 'Retraso en Flood, TX'; + + @override + String get repeater_txDelayHelper => + 'Ajuste de retransmisión para el tráfico de inundación, como un multiplicador del tiempo de transmisión del paquete (0-2, valor predeterminado 0.5). Un valor más alto significa menos colisiones, pero una entrega más lenta.'; + + @override + String get repeater_directTxDelay => 'Retraso directo en TX'; + + @override + String get repeater_directTxDelayHelper => + 'Reenvío de espacios para el tráfico directo (no masivo), como un multiplicador del tiempo de transmisión del paquete (0-2, valor predeterminado 0.3).'; + + @override + String get repeater_intThresh => 'Límite de interferencia'; + + @override + String get repeater_intThreshHelper => + 'Se establece un umbral para la calibración del nivel de ruido de la radio, de modo que rechaza las interferencias que superen este nivel. 0 deshabilita — solo aumente este valor si observa errores en una banda de frecuencia con mucho ruido.'; + + @override + String get repeater_agcResetInterval => 'Intervalo de reinicio de AGC'; + + @override + String get repeater_agcResetIntervalHelper => + '¿Con qué frecuencia se debe restablecer el control automático de ganancia del radio para recuperarse de un estado de ganancia bloqueada? Se puede restablecer cada pocos segundos, o cada 4 segundos. Desactivar la función de restablecimiento periódico.'; + + @override + String get repeater_actionsTitle => 'Acciones'; + + @override + String get repeater_sendAdvert => 'Enviar anuncio sobre inundaciones'; + + @override + String get repeater_sendAdvertSubtitle => + 'Transmite un anuncio sobre inundaciones a través de la red.'; + + @override + String get repeater_sendAdvertZeroHop => 'Enviar anuncio sin intermediarios'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Transmite un anuncio de un solo salto (sin retransmisiones).'; + + @override + String get repeater_clockSync => 'Sincronizar reloj ahora'; + + @override + String get repeater_clockSyncSubtitle => + 'Envía la hora de tu teléfono al repetidor.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action succeeded'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action failed: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Configuración guardada — reinicie el repetidor para aplicar los cambios.'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Algunas configuraciones no se pudieron aplicar: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Error al guardar la configuración: $error'; @@ -2355,10 +2606,6 @@ class AppLocalizationsEs extends AppLocalizations { @override String get repeater_refreshTxPower => 'Actualizar TX de energía'; - @override - String get repeater_refreshLocationSettings => - 'Actualizar Configuración de Ubicación'; - @override String get repeater_refreshPacketForwarding => 'Actualizar Enrutamiento de Paquetes'; @@ -2369,10 +2616,6 @@ class AppLocalizationsEs extends AppLocalizations { @override String get repeater_refreshPrivacyMode => 'Actualizar Modo Privacidad'; - @override - String get repeater_refreshAdvertisementSettings => - 'Actualizar Configuración de Anuncios'; - @override String repeater_refreshed(String label) { return '$label actualizado'; @@ -2697,6 +2940,282 @@ class AppLocalizationsEs extends AppLocalizations { String get repeater_gpsNote => 'Se ha introducido un comando GPS para gestionar temas relacionados con la ubicación.'; + @override + String get repeater_getCategory => 'Obtener valores'; + + @override + String get repeater_powerMgmt => 'Gestión de la energía'; + + @override + String get repeater_sensors => 'Sensores'; + + @override + String get repeater_cliHelpPowerOff => + 'Apaga el dispositivo. (no se espera respuesta)'; + + @override + String get repeater_cliHelpClkReboot => + 'Restablece el reloj a una fecha conocida y reinicia el dispositivo.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Envía un anuncio que no requiere saltos (solo para los vecinos inmediatos).'; + + @override + String get repeater_cliHelpStartOta => + 'Inicia una actualización de firmware por aire en las placas compatibles.'; + + @override + String get repeater_cliHelpTime => + 'Establece la hora del dispositivo en los segundos correspondientes a la época Unix. La hora no puede retroceder.'; + + @override + String get repeater_cliHelpBoard => + 'Muestra el fabricante de la placa base / identificador de hardware.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Envía una solicitud de descubrimiento de nodos a los vecinos cercanos. (Solo para repetidores)'; + + @override + String get repeater_cliHelpPowersaving => + 'Indica si el modo de ahorro de energía está activado o desactivado.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Activa o desactiva el modo de ahorro de energía (si está disponible).'; + + @override + String get repeater_cliHelpErase => + '(Solo para dispositivos) Formatea el sistema de archivos del dispositivo. Elimina todas las configuraciones y contactos.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Establece el ciclo de transmisión máximo permitido como un porcentaje (1-100). Ajusta internamente el factor de tiempo de aire.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Solo para series) Reemplaza la clave privada de identificación del dispositivo. Se requiere reiniciar para aplicar. Genera una nueva clave pública.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(Solo para SX126x) Activa/desactiva el amplificador de la RX para mejorar la sensibilidad a corrientes más altas.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Define la cadena de información de contacto del propietario que se incluye en los anuncios. Utilice \'|\' para indicar nuevas líneas.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Establece el modo de hash de la ruta. 0 = antiguo, 1 = estándar, 2 = estricto. Afecta la forma en que se comparan las rutas.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Establece la sensibilidad para la detección de bucles de enrutamiento: apagado, mínimo, moderado o estricto.'; + + @override + String get repeater_cliHelpSetFreq => + '(Solo para la configuración de frecuencia) Establece rápidamente la frecuencia deseada. Se requiere reiniciar. Se recomienda utilizar la opción \"configurar radio\" para obtener todos los parámetros de la radio.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Solo para el puente ESPNow) Establece el canal de WiFi (1-14) que utiliza el puente.'; + + @override + String get repeater_cliHelpGetName => + 'Muestra el nombre del nodo configurado.'; + + @override + String get repeater_cliHelpGetRole => + 'Muestra el rol del firmware (Repetidor, Servidor de habitación, etc.).'; + + @override + String get repeater_cliHelpGetPublicKey => + 'Muestra la clave pública del dispositivo.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Solo para uso en serie) Muestra la clave privada del dispositivo. Trátala como una información confidencial.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Indica si el enrutamiento de paquetes (función de repetidor) está activado o desactivado.'; + + @override + String get repeater_cliHelpGetTx => 'Muestra la potencia actual en dBm.'; + + @override + String get repeater_cliHelpGetFreq => + 'Muestra la frecuencia de radio configurada en MHz.'; + + @override + String get repeater_cliHelpGetRadio => + 'Muestra todos los parámetros de radio: frecuencia, ancho de banda, factor de dispersión, tasa de codificación.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(Solo para SX126x) Muestra el estado de ganancia amplificada del receptor.'; + + @override + String get repeater_cliHelpGetAf => 'Muestra el factor de tiempo actual.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Muestra el ciclo de trabajo actual permitido como un porcentaje.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Muestra el umbral de interferencia del canal en dB.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Muestra el intervalo de reinicio del AGC en segundos.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Indica si el modo de confirmación doble está activado (1) o desactivado (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Indica si se permite el acceso de solo lectura para los usuarios invitados.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Muestra el intervalo de publicidad local en minutos.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Muestra el intervalo de publicidad para la emisión de la señal de inundación, expresado en horas.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Muestra la contraseña de invitado configurada.'; + + @override + String get repeater_cliHelpGetLat => 'Muestra la latitud configurada.'; + + @override + String get repeater_cliHelpGetLon => 'Muestra la longitud configurada.'; + + @override + String get repeater_cliHelpGetRxDelay => 'Muestra el valor base de rxdelay.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Muestra el factor de retardo en modo de inundación.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Muestra el factor de retardo en modo directo.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Muestra el número máximo de saltos por inundación.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Muestra la cadena de información de contacto del propietario.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Muestra el modo de hash de ruta (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Muestra la sensibilidad en la detección de bucles.'; + + @override + String get repeater_cliHelpGetAcl => + '(Solo para series) Enumera las entradas de control de acceso en un repetidor.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Indica si el puente está habilitado.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Muestra el retardo del puente en milisegundos.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Indica si el puente está enviando o recibiendo paquetes RX o TX.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Solo puente RS232) Muestra la velocidad de transmisión del puente.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Solo para el puente ESPNow) Muestra el canal WiFi del puente.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Solo para el puente ESPNow) Muestra el secreto compartido por el puente.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(Solo NRF52) Muestra la versión del cargador.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Muestra el multiplicador del ADC (escalado de voltaje de la batería).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Indica si el sistema cuenta con funciones de gestión de energía.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Indica la fuente de energía actual: externa o batería.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Muestra las razones más recientes de reinicio y apagado.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Muestra el voltaje de la batería al encender el sistema en milivoltios (mV).'; + + @override + String get repeater_cliHelpSensorGet => + 'Lee una configuración de sensor personalizada mediante una tecla.'; + + @override + String get repeater_cliHelpSensorSet => + 'Crea una configuración personalizada para un sensor.'; + + @override + String get repeater_cliHelpSensorList => + 'Muestra todas las configuraciones de sensores personalizadas, paginadas a partir de un índice de inicio opcional.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Muestra el ámbito predeterminado actual.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Establece el ámbito regional predeterminado. Utilice \"\" para restablecer a la configuración predeterminada.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Enumera las regiones que permiten el paso de vehículos debido a inundaciones.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Enumera las regiones que prohíben el tráfico debido a las inundaciones.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Solo para series) Muestra estadísticas a nivel de paquetes.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Solo para transmisiones en serie) Muestra estadísticas de radio.'; + + @override + String get repeater_cliHelpStatsCore => + '(Solo para series) Muestra estadísticas clave del firmware.'; + @override String get telemetry_receivedData => 'Datos de Telemetría Recibidos'; @@ -3065,7 +3584,7 @@ class AppLocalizationsEs extends AppLocalizations { String get listFilter_heardRecently => 'Escuchado recientemente'; @override - String get listFilter_az => 'A-Z'; + String get listFilter_az => 'De la A a la Z'; @override String get listFilter_filters => 'Filtros'; @@ -3237,6 +3756,37 @@ class AppLocalizationsEs extends AppLocalizations { @override String get losLegendTerrain => 'Terreno'; + @override + String get losBlockedSpotsTitle => 'Espacios ocupados'; + + @override + String get losBlockedSpotsHint => + 'Seleccione un punto bloqueado para resaltarlo en el mapa.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Obstrucción seleccionada'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Bloqueado por $obstruction a una altura de $heightUnit, a $distanceFromA metros de A y a $distanceFromB metros de B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Frecuencia'; @@ -3706,4 +4256,40 @@ class AppLocalizationsEs extends AppLocalizations { @override String get translation_systemLanguage => 'Idioma del sistema'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index a006391..44e4065 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -12,7 +12,7 @@ class AppLocalizationsFr extends AppLocalizations { String get appTitle => 'MeshCore Open'; @override - String get nav_contacts => 'Contacts'; + String get nav_contacts => 'Coordonnées'; @override String get nav_channels => 'Canaux'; @@ -24,7 +24,7 @@ class AppLocalizationsFr extends AppLocalizations { String get common_cancel => 'Annuler'; @override - String get common_ok => 'OK'; + String get common_ok => 'D\'accord'; @override String get common_connect => 'Connecter'; @@ -44,6 +44,9 @@ class AppLocalizationsFr extends AppLocalizations { @override String get common_close => 'Fermer'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Modifier'; @@ -438,9 +441,7 @@ class AppLocalizationsFr extends AppLocalizations { 'Inclure l\'emplacement dans l\'annonce'; @override - String settings_multiAck(String value) { - return 'Multi-ACKs : $value'; - } + String get settings_multiAck => 'Plusieurs accusés de réception'; @override String get settings_telemetryModeUpdated => @@ -449,6 +450,13 @@ class AppLocalizationsFr extends AppLocalizations { @override String get settings_actions => 'Actions'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'S\'annoncer'; @@ -490,11 +498,11 @@ class AppLocalizationsFr extends AppLocalizations { String get settings_debug => 'Déboguer'; @override - String get settings_bleDebugLog => 'Journal de débogage BLE'; + String get settings_companionDebugLog => 'Journal de débogage associé'; @override - String get settings_bleDebugLogSubtitle => - 'Commandes BLE, réponses et données brutes'; + String get settings_companionDebugLogSubtitle => + 'Commandes, réponses et données brutes pour les protocoles BLE/TCP/USB'; @override String get settings_appDebugLog => 'Journal de débogage de l\'application'; @@ -508,7 +516,7 @@ class AppLocalizationsFr extends AppLocalizations { @override String settings_aboutVersion(String version) { - return 'MeshCore Open v$version'; + return 'MeshCore Open $version'; } @override @@ -526,7 +534,7 @@ class AppLocalizationsFr extends AppLocalizations { String get settings_infoName => 'Nom'; @override - String get settings_infoId => 'ID'; + String get settings_infoId => 'Numéro d\'identification'; @override String get settings_infoStatus => 'État'; @@ -614,43 +622,43 @@ class AppLocalizationsFr extends AppLocalizations { String get appSettings_languageSystem => 'Par défaut du système'; @override - String get appSettings_languageEn => 'English'; + String get appSettings_languageEn => 'Anglais'; @override String get appSettings_languageFr => 'Français'; @override - String get appSettings_languageEs => 'Español'; + String get appSettings_languageEs => 'Espagnol'; @override - String get appSettings_languageDe => 'Deutsch'; + String get appSettings_languageDe => 'Allemand'; @override - String get appSettings_languagePl => 'Polski'; + String get appSettings_languagePl => 'Polonais'; @override - String get appSettings_languageSl => 'Slovenščina'; + String get appSettings_languageSl => 'Sloveno'; @override - String get appSettings_languagePt => 'Português'; + String get appSettings_languagePt => 'Portugais'; @override - String get appSettings_languageIt => 'Italiano'; + String get appSettings_languageIt => 'Italien'; @override - String get appSettings_languageZh => '中文'; + String get appSettings_languageZh => 'Chinois'; @override - String get appSettings_languageSv => 'Svenska'; + String get appSettings_languageSv => 'Suédois'; @override - String get appSettings_languageNl => 'Nederlands'; + String get appSettings_languageNl => 'Néerlandais'; @override - String get appSettings_languageSk => 'Slovenčina'; + String get appSettings_languageSk => 'Slovène'; @override - String get appSettings_languageBg => 'Български'; + String get appSettings_languageBg => 'Bulgare'; @override String get appSettings_languageRu => 'Russe'; @@ -909,7 +917,7 @@ class AppLocalizationsFr extends AppLocalizations { 'Le débogage de l\'application est désactivé.'; @override - String get contacts_title => 'Contacts'; + String get contacts_title => 'Coordonnées'; @override String get contacts_noContacts => 'Aucun contact trouvé.'; @@ -1018,7 +1026,7 @@ class AppLocalizationsFr extends AppLocalizations { @override String contacts_lastSeenMinsAgo(int minutes) { - return '~ $minutes min.'; + return '~ $minutes minutes.'; } @override @@ -1093,20 +1101,16 @@ class AppLocalizationsFr extends AppLocalizations { return 'Canal $index'; } - @override - String get channels_hashtagChannel => 'Canal avec hashtag'; - @override String get channels_public => 'Public'; @override - String get channels_private => 'Privé'; - - @override - String get channels_publicChannel => 'Canal public'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Canal privé'; + String get channels_private => 'Privé'; @override String get channels_editChannel => 'Modifier le canal'; @@ -1151,7 +1155,7 @@ class AppLocalizationsFr extends AppLocalizations { String get channels_standardPublicPsk => 'PSK public standard'; @override - String get channels_pskHex => 'PSK (Hex)'; + String get channels_pskHex => 'PSK (Hexadécimal)'; @override String get channels_generateRandomPsk => @@ -1177,11 +1181,67 @@ class AppLocalizationsFr extends AppLocalizations { @override String get channels_smazCompression => 'Compression SMAZ'; + @override + String get channels_cyr2latCompression => 'Compression Cyr2Lat'; + + @override + String get channels_cyr2latCompressionDscr => + 'Remplace certains caractères cyrilliques par des caractères latins lors de l\'envoi.'; + + @override + String get channels_cyr2latSettingsHeading => 'Paramètres Cyr2Lat'; + + @override + String get channels_cyr2latSettingsSubheading => 'Liste des remplacements'; + + @override + String get channels_cyr2latSettingsDscr => + 'Modifier la configuration JSON des remplacements de caractères'; + + @override + String get channels_cyr2latSettingsDialogHint => + 'Tableau de remplacement JSON'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'JSON incorrect : $error'; + } + @override String channels_channelUpdated(String name) { return 'Le canal \"$name\" a été mis à jour'; } + @override + String get settings_cyr2latProfileAdd => 'Ajouter un profil Cyr2Lat'; + + @override + String get settings_cyr2latProfileName => 'Nom du profil'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'Le nom du profil ne peut pas être vide'; + + @override + String get settings_cyr2latProfileAdded => 'Profil ajouté avec succès'; + + @override + String get settings_cyr2latProfileUpdated => 'Profil mis à jour avec succès'; + + @override + String get settings_cyr2latProfileEdit => 'Modifier le profil Cyr2Lat'; + + @override + String get settings_cyr2latProfileDelete => 'Supprimer le profil Cyr2Lat'; + + @override + String get settings_cyr2latProfileDeleted => 'Profil supprimé avec succès'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Êtes-vous sûr de vouloir supprimer le profil \"$name\"?'; + } + @override String get channels_publicChannelAdded => 'Le canal public a été ajouté'; @@ -1387,7 +1447,7 @@ class AppLocalizationsFr extends AppLocalizations { @override String debugFrame_destinationPubKey(String pubKey) { - return '- Destination PubKey: $pubKey'; + return '- Clé publique de destination : $pubKey'; } @override @@ -1462,6 +1522,9 @@ class AppLocalizationsFr extends AppLocalizations { @override String get chat_successes => 'Succès'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Supprimer le chemin'; @@ -1565,6 +1628,12 @@ class AppLocalizationsFr extends AppLocalizations { return 'Non lu : $count'; } + @override + String get chat_markAsUnread => 'Signaler comme non lu'; + + @override + String get chat_newMessages => 'Nouveaux messages'; + @override String get chat_openLink => 'Ouvrir le lien ?'; @@ -1611,7 +1680,7 @@ class AppLocalizationsFr extends AppLocalizations { } @override - String get map_chat => 'Chat'; + String get map_chat => 'Conversation'; @override String get map_repeater => 'Répéteur'; @@ -1647,6 +1716,24 @@ class AppLocalizationsFr extends AppLocalizations { @override String get map_flags => 'Drapeaux'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'Partager le marqueur ici'; @@ -1732,6 +1819,9 @@ class AppLocalizationsFr extends AppLocalizations { @override String get map_sharedPin => 'Clé partagée'; + @override + String get map_sharedAt => 'Partagé'; + @override String get map_joinRoom => 'Rejoindre le room server'; @@ -2143,6 +2233,9 @@ class AppLocalizationsFr extends AppLocalizations { @override String get repeater_rxAirtime => 'RX Airtime'; + @override + String get repeater_chanUtil => 'Utilisation du canal'; + @override String get repeater_packetStatistics => 'Statistiques des paquets'; @@ -2223,7 +2316,7 @@ class AppLocalizationsFr extends AppLocalizations { String get repeater_txPower => 'TX Puissance'; @override - String get repeater_txPowerHelper => '1-30 dBm'; + String get repeater_txPowerHelper => '1 à 30 dBm'; @override String get repeater_bandwidth => 'Bande passante'; @@ -2357,6 +2450,168 @@ class AppLocalizationsFr extends AppLocalizations { String get repeater_settingsSaved => 'Les paramètres ont été enregistrés avec succès.'; + @override + String get repeater_rxGain => 'Augmentation du rendement de RX'; + + @override + String get repeater_rxGainHelper => + 'Meilleure sensibilité, consommation de courant plus élevée (uniquement pour les modèles SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => + 'Renforcer les gains de RX grâce à la mise à jour'; + + @override + String get repeater_multiAcks => 'Plusieurs accusés de réception'; + + @override + String get repeater_multiAcksSubtitle => + 'Valider les messages via plusieurs chemins pour une meilleure livraison.'; + + @override + String get repeater_refreshMultiAcks => + 'Renvoyer plusieurs accusés de réception'; + + @override + String get repeater_networkHealth => 'Santé du réseau'; + + @override + String get repeater_loopDetect => 'Détection de boucles'; + + @override + String get repeater_loopDetectHelper => + 'Envoyer des paquets de données qui semblent former des boucles de routage.'; + + @override + String get repeater_loopDetectOff => 'Prix'; + + @override + String get repeater_loopDetectMinimal => 'Minimal'; + + @override + String get repeater_loopDetectModerate => 'Modéré'; + + @override + String get repeater_loopDetectStrict => 'Strict'; + + @override + String get repeater_dutyCycle => 'Cycle de fonctionnement'; + + @override + String get repeater_dutyCycleHelper => + 'Pourcentage maximal de temps d\'antenne'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Informations sur l\'opérateur'; + + @override + String get repeater_ownerInfoHelper => + 'Métadonnées publiques pour cet émetteur'; + + @override + String get repeater_refreshOwnerInfo => + 'Rafraîchir les informations sur l\'opérateur'; + + @override + String get repeater_floodMax => + 'Nombre maximal de sauts lors des inondations'; + + @override + String get repeater_floodMaxHelper => + 'Nombre maximal de paquets de données qu\'un flux peut transmettre (0-64)'; + + @override + String get repeater_advancedSettings => 'Avancé'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Molettes de réglage pour les opérateurs expérimentés'; + + @override + String get repeater_pathHashMode => 'Mode de hachage de chemin'; + + @override + String get repeater_pathHashModeHelper => + 'Octets utilisés pour encoder l\'ID de ce routeur dans les balises de détection de flux/boucles. 0 = 1 octet (256 ID, jusqu\'à 64 sauts), 1 = 2 octets (65 000 ID, jusqu\'à 32 sauts), 2 = 3 octets (16 millions d\'ID, jusqu\'à 21 sauts). Les versions 1.13 et antérieures utilisent des chemins multi-octets ; à partir de la version 1.14, cela n\'est plus nécessaire.'; + + @override + String get repeater_txDelay => 'Retard dû aux inondations à Texas'; + + @override + String get repeater_txDelayHelper => + 'Rétransmettre l\'espacement pour le trafic de secours en cas de inondation, en multipliant le temps d\'émission du paquet (0-2, valeur par défaut : 0,5). Une valeur plus élevée signifie moins de collisions, mais une vitesse de transmission plus lente.'; + + @override + String get repeater_directTxDelay => 'Retard de transmission direct'; + + @override + String get repeater_directTxDelayHelper => + 'Rétransmettre l\'espacement pour le trafic direct (non-inondation), en multipliant le temps de transmission des paquets (0-2, valeur par défaut : 0,3).'; + + @override + String get repeater_intThresh => 'Seuil de perturbation'; + + @override + String get repeater_intThreshHelper => + 'Seuil dépassé pour la calibration du niveau de bruit de la radio, afin de rejeter les interférences supérieures à ce niveau. 0 désactive – ne mettez cette valeur que si vous constatez des erreurs RX dans une bande de fréquences bruyante.'; + + @override + String get repeater_agcResetInterval => + 'Interval de réinitialisation de l\'AGC'; + + @override + String get repeater_agcResetIntervalHelper => + 'À quelle fréquence réinitialiser le contrôle automatique du gain de la radio pour revenir à un état normal ? Chaque seconde, ou à chaque multiple de 4. Désactiver la réinitialisation périodique avec 0.'; + + @override + String get repeater_actionsTitle => 'Actions'; + + @override + String get repeater_sendAdvert => 'Envoyer une publicité sur les inondations'; + + @override + String get repeater_sendAdvertSubtitle => + 'Diffuser une publicité sur les inondations via le réseau.'; + + @override + String get repeater_sendAdvertZeroHop => + 'Envoyer une publicité sans intermédiaire'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Diffuser une publicité d\'un seul saut (sans relais)'; + + @override + String get repeater_clockSync => 'Synchroniser l\'heure maintenant'; + + @override + String get repeater_clockSyncSubtitle => + 'Envoyez l\'heure de votre téléphone au répéteur.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action a réussi'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action a échoué : $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Paramètres sauvegardés — redémarrer le répéteur pour appliquer les modifications.'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Certaines configurations ont échoué : $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Erreur lors de la sauvegarde des paramètres : $error'; @@ -2372,10 +2627,6 @@ class AppLocalizationsFr extends AppLocalizations { @override String get repeater_refreshTxPower => 'Rafraîchir la tension TX'; - @override - String get repeater_refreshLocationSettings => - 'Rafraîchir les paramètres de localisation'; - @override String get repeater_refreshPacketForwarding => 'Rafraîchir le routage des paquets'; @@ -2387,10 +2638,6 @@ class AppLocalizationsFr extends AppLocalizations { String get repeater_refreshPrivacyMode => 'Rafraîchir le Mode Confidentialité'; - @override - String get repeater_refreshAdvertisementSettings => - 'Rafraîchir les Paramètres des annonces'; - @override String repeater_refreshed(String label) { return '$label rafraîchi'; @@ -2715,6 +2962,283 @@ class AppLocalizationsFr extends AppLocalizations { String get repeater_gpsNote => 'La commande GPS a été introduite pour gérer les sujets liés à la localisation.'; + @override + String get repeater_getCategory => 'Obtenir des valeurs'; + + @override + String get repeater_powerMgmt => 'Gestion de l\'énergie'; + + @override + String get repeater_sensors => 'Capteurs'; + + @override + String get repeater_cliHelpPowerOff => + 'Éteint l\'appareil. (aucune réponse n\'est attendue)'; + + @override + String get repeater_cliHelpClkReboot => + 'Réinitialise l\'horloge à une époque connue et redémarre l\'appareil.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Envoie une publicité sans intermédiaire (uniquement aux voisins immédiats).'; + + @override + String get repeater_cliHelpStartOta => + 'Démarre une mise à jour du firmware par voie radio sur les cartes prises en charge.'; + + @override + String get repeater_cliHelpTime => + 'Définit l\'heure de l\'appareil sur les secondes de l\'époque Unix spécifiée. L\'heure ne peut pas reculer.'; + + @override + String get repeater_cliHelpBoard => + 'Indique le fabricant du panneau / l\'identifiant du matériel.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Envoie une requête de découverte de nœuds aux voisins proches. (Uniquement pour les répéteurs)'; + + @override + String get repeater_cliHelpPowersaving => + 'Indique si le mode d\'économie d\'énergie est activé ou désactivé.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Active ou désactive le mode d\'économie d\'énergie (si pris en charge).'; + + @override + String get repeater_cliHelpErase => + '(Uniquement pour les appareils) Formate le système de fichiers de l\'appareil. Efface tous les paramètres et les contacts.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Définit le cycle de transmission maximal autorisé en pourcentage (de 1 à 100). Ajuste automatiquement le facteur de temps d\'émission.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Uniquement pour les séries) Remplace la clé privée d\'identification de l\'appareil. Un redémarrage est nécessaire pour appliquer. Génère une nouvelle clé publique.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(Uniquement pour les SX126x) Active le gain RX amplifié pour une meilleure sensibilité à des courants plus élevés.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Définit la chaîne d\'informations de contact du propriétaire, qui figure dans les annonces. Utilisez \'|\' pour les sauts de ligne.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Définit le mode de hachage de chemin. 0 = mode ancien, 1 = mode standard, 2 = mode strict. Influence la façon dont les chemins de routage sont correspondus.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Définit la sensibilité de la détection des boucles de routage : désactivée, minimale, modérée ou stricte.'; + + @override + String get repeater_cliHelpSetFreq => + '(Uniquement pour les modèles série) Permet de régler rapidement la fréquence. Redémarrage nécessaire. Il est préférable d\'utiliser l\'option \"réglage radio\" pour configurer tous les paramètres radio.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Uniquement pour le pont ESPNow) Définit le canal WiFi (de 1 à 14) utilisé par le pont.'; + + @override + String get repeater_cliHelpGetName => 'Affiche le nom du nœud configuré.'; + + @override + String get repeater_cliHelpGetRole => + 'Indique le rôle du firmware (répéteur, serveur de pièce, etc.).'; + + @override + String get repeater_cliHelpGetPublicKey => + 'Affiche la clé publique du dispositif.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Uniquement pour les séries) Affiche la clé privée de l\'appareil. Traitez-la comme une information confidentielle.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Indique si le transfert de paquets (en tant que routeur) est activé ou désactivé.'; + + @override + String get repeater_cliHelpGetTx => 'Indique la puissance actuelle en dBm.'; + + @override + String get repeater_cliHelpGetFreq => + 'Affiche la fréquence radio configurée en MHz.'; + + @override + String get repeater_cliHelpGetRadio => + 'Affiche tous les paramètres radio : fréquence, largeur de bande, facteur de dispersion, taux de codage.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(Uniquement pour les SX126x) Affiche l\'état du gain amplifié de la réception.'; + + @override + String get repeater_cliHelpGetAf => + 'Indique le facteur de temps d\'antenne actuel.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Affiche le cycle de fonctionnement actuel autorisé en pourcentage.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Indique le seuil d\'interférence du canal en dB.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Indique l\'intervalle de réinitialisation de l\'AGC en secondes.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Indique si le mode \"double ACK\" est activé (1) ou désactivé (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Indique si l\'accès en lecture seule pour les invités est autorisé.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Indique l\'intervalle publicitaire local en minutes.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Indique l\'intervalle publicitaire pour la diffusion de l\'annonce en heures.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Affiche le mot de passe invité configuré.'; + + @override + String get repeater_cliHelpGetLat => 'Affiche la latitude configurée.'; + + @override + String get repeater_cliHelpGetLon => 'Affiche la longitude configurée.'; + + @override + String get repeater_cliHelpGetRxDelay => + 'Affiche la valeur de base de rxdelay.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Indique le facteur de délai de transmission en mode inondation.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Indique le facteur de délai direct.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Indique le nombre maximal de fois où le niveau de l\'eau a atteint son point culminant.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Affiche la chaîne d\'informations de contact du propriétaire.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Affiche le mode \"hash de chemin\" (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Illustre la sensibilité à la détection des boucles.'; + + @override + String get repeater_cliHelpGetAcl => + '(Uniquement pour les séries) Liste les entrées de contrôle d\'accès sur un répéteur.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Indique si le pont est activé.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Indique le délai du pont en millisecondes.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Indique si le pont transmet des paquets RX ou TX.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Uniquement pour le pont RS232) Affiche la vitesse de communication du pont.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Uniquement pour le pont ESPNow) Affiche le canal WiFi du pont.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Uniquement pour le pont ESPNow) Affiche la clé partagée du pont.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(Uniquement pour le NRF52) Affiche la version du chargeur initial.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Affiche le multiplicateur de l\'ADC (mise à l\'échelle de la tension de la batterie).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Indique si le système dispose de fonctionnalités de gestion de l\'alimentation.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Indique la source d\'alimentation actuelle : externe ou batterie.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Indique les raisons les plus récentes de réinitialisation et d\'arrêt.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Affiche la tension de la batterie au démarrage, en millivolts (mV).'; + + @override + String get repeater_cliHelpSensorGet => + 'Lit une valeur de configuration personnalisée pour un capteur en utilisant une touche.'; + + @override + String get repeater_cliHelpSensorSet => + 'Crée une configuration personnalisée pour un capteur.'; + + @override + String get repeater_cliHelpSensorList => + 'Affiche toutes les configurations de capteurs personnalisées, avec une pagination à partir d\'un index de départ optionnel.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Affiche la portée régionale par défaut actuelle.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Définit la portée régionale par défaut. Utilisez \"\" pour la réinitialiser.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Énumère les régions autorisant la circulation des véhicules en cas de inondation.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Liste des régions qui interdisent la circulation en cas de inondation.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Uniquement pour les séries) Affiche des statistiques au niveau des paquets.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Uniquement pour les séries) Affiche les statistiques de la radio.'; + + @override + String get repeater_cliHelpStatsCore => + '(Uniquement pour les séries) Affiche les statistiques du micrologicem intégré.'; + @override String get telemetry_receivedData => 'Données de télémétrie reçues'; @@ -3108,7 +3632,7 @@ class AppLocalizationsFr extends AppLocalizations { String get listFilter_repeaters => 'Répéteurs'; @override - String get listFilter_roomServers => 'Room servers'; + String get listFilter_roomServers => 'Serveurs de salle'; @override String get listFilter_unreadOnly => 'Messages non lus seulement'; @@ -3255,6 +3779,37 @@ class AppLocalizationsFr extends AppLocalizations { @override String get losLegendTerrain => 'Terrain'; + @override + String get losBlockedSpotsTitle => 'Places occupés'; + + @override + String get losBlockedSpotsHint => + 'Sélectionnez un emplacement bloqué pour le mettre en évidence sur la carte.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Obstruction sélectionnée'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Bloqué par $obstruction, à une hauteur de $heightUnit, à une distance de $distanceFromA par rapport à A et à une distance de $distanceFromB par rapport à B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Fréquence'; @@ -3730,4 +4285,40 @@ class AppLocalizationsFr extends AppLocalizations { @override String get translation_systemLanguage => 'Langue du système'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_hu.dart b/lib/l10n/app_localizations_hu.dart index 1ad8558..298a6fd 100644 --- a/lib/l10n/app_localizations_hu.dart +++ b/lib/l10n/app_localizations_hu.dart @@ -44,6 +44,9 @@ class AppLocalizationsHu extends AppLocalizations { @override String get common_close => 'Bezárás'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Szerkesztés'; @@ -437,9 +440,7 @@ class AppLocalizationsHu extends AppLocalizations { 'A hirdetés tartalmazza a helyszínt.'; @override - String settings_multiAck(String value) { - return 'Többszöri visszaigazolások: $value'; - } + String get settings_multiAck => 'Többszörös visszaigazolások'; @override String get settings_telemetryModeUpdated => 'A telemetriamód frissítve'; @@ -447,6 +448,13 @@ class AppLocalizationsHu extends AppLocalizations { @override String get settings_actions => 'Tevékenységek'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Hirdetés küldése'; @@ -488,11 +496,11 @@ class AppLocalizationsHu extends AppLocalizations { String get settings_debug => 'Hibakeresés'; @override - String get settings_bleDebugLog => 'BLE hibaelhárítási napló'; + String get settings_companionDebugLog => 'Párhuzamos hibakeresési napló'; @override - String get settings_bleDebugLogSubtitle => - 'BLE parancsok, válaszok és alapvető adatok'; + String get settings_companionDebugLogSubtitle => + 'BLE/TCP/USB parancsok, válaszok és alapvető adatok'; @override String get settings_appDebugLog => 'App-debug log'; @@ -1093,20 +1101,16 @@ class AppLocalizationsHu extends AppLocalizations { return '$index-os csatorna'; } - @override - String get channels_hashtagChannel => 'Hashtag-ok közössége'; - @override String get channels_public => 'A nyilvánosság számára'; @override - String get channels_private => 'Személyes'; - - @override - String get channels_publicChannel => 'Össztávos csatorna'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Személyes csatorna'; + String get channels_private => 'Személyes'; @override String get channels_editChannel => 'Csatorna szerkesztése'; @@ -1177,11 +1181,66 @@ class AppLocalizationsHu extends AppLocalizations { @override String get channels_smazCompression => 'SMAZ kompresszió'; + @override + String get channels_cyr2latCompression => 'Cyr2Lat kompresszió'; + + @override + String get channels_cyr2latCompressionDscr => + 'Néhány Cirill betűt Latin betűkkel helyettesít küldéskor.'; + + @override + String get channels_cyr2latSettingsHeading => 'Cyr2Lat beállítások'; + + @override + String get channels_cyr2latSettingsSubheading => 'Helyettesítési lista'; + + @override + String get channels_cyr2latSettingsDscr => + 'A karakterhelyettesítési JSON-konfiguráció szerkesztése'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON-csere táblázat'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'Hibás JSON: $error'; + } + @override String channels_channelUpdated(String name) { return 'A $name csatorna frissítve'; } + @override + String get settings_cyr2latProfileAdd => 'Cyr2Lat-profil hozzáadása'; + + @override + String get settings_cyr2latProfileName => 'Profil neve'; + + @override + String get settings_cyr2latProfileNameEmpty => 'A profil neve nem lehet üres'; + + @override + String get settings_cyr2latProfileAdded => 'A profil hozzáadása sikeres'; + + @override + String get settings_cyr2latProfileUpdated => 'A profil frissítése sikeres'; + + @override + String get settings_cyr2latProfileEdit => 'Cyr2Lat profil szerkesztése'; + + @override + String get settings_cyr2latProfileDelete => 'Cyr2Lat profil törlése'; + + @override + String get settings_cyr2latProfileDeleted => + 'A profil törlése sikeresen megtörtént'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Biztosan törölni szeretné a \"$name\" profilt?'; + } + @override String get channels_publicChannelAdded => 'A nyilvános csatorna hozzáadva'; @@ -1467,6 +1526,9 @@ class AppLocalizationsHu extends AppLocalizations { @override String get chat_successes => 'sikerek'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Törölje a elérési útvonalat'; @@ -1567,6 +1629,12 @@ class AppLocalizationsHu extends AppLocalizations { return 'Olvasatlan: $count'; } + @override + String get chat_markAsUnread => 'Merekje olvashatóként'; + + @override + String get chat_newMessages => 'Új üzenetek'; + @override String get chat_openLink => 'Nyisd meg a linket?'; @@ -1649,6 +1717,24 @@ class AppLocalizationsHu extends AppLocalizations { @override String get map_flags => 'Zászló'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'Osztja ezt a tartalmat itt'; @@ -1735,6 +1821,9 @@ class AppLocalizationsHu extends AppLocalizations { @override String get map_sharedPin => 'Gemeinsames PIN-kód'; + @override + String get map_sharedAt => 'Megosztva'; + @override String get map_joinRoom => 'Csatlakozás a szobához'; @@ -2146,6 +2235,9 @@ class AppLocalizationsHu extends AppLocalizations { @override String get repeater_rxAirtime => 'RX Airtime'; + @override + String get repeater_chanUtil => 'Csatorna-használat'; + @override String get repeater_packetStatistics => 'Csomagok statisztikája'; @@ -2354,6 +2446,163 @@ class AppLocalizationsHu extends AppLocalizations { @override String get repeater_settingsSaved => 'Beállítások sikeresen mentve'; + @override + String get repeater_rxGain => 'Nagyobb RX-jel erősítés'; + + @override + String get repeater_rxGainHelper => + 'Magasabb érzékenység, nagyobb áramfelvétel (csak SX1262/SX1268 esetén)'; + + @override + String get repeater_refreshRxGain => 'Újraindított, fokozott RX hatás'; + + @override + String get repeater_multiAcks => 'Többszörös visszaigazolások'; + + @override + String get repeater_multiAcksSubtitle => + 'Ismerje el üzeneteket több úton is, hogy biztosítsa a jobb átadást.'; + + @override + String get repeater_refreshMultiAcks => + 'Frissítse a többször is kapott visszaigazolásokat.'; + + @override + String get repeater_networkHealth => 'Hálózati állapot'; + + @override + String get repeater_loopDetect => 'Ciklusok azonosítása'; + + @override + String get repeater_loopDetectHelper => + 'Készíts olyan \"vízfolyást\" megjelenítő csomagokat, amelyek úgy néznek ki, mint egy hibaút.'; + + @override + String get repeater_loopDetectOff => 'Le, kikap'; + + @override + String get repeater_loopDetectMinimal => 'Minimális'; + + @override + String get repeater_loopDetectModerate => 'Közepes'; + + @override + String get repeater_loopDetectStrict => 'Szigorú'; + + @override + String get repeater_dutyCycle => 'Munka- és pihenőidő aránya'; + + @override + String get repeater_dutyCycleHelper => + 'A maximális időszámítás százalékos aránya'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Üzemeltető információ'; + + @override + String get repeater_ownerInfoHelper => + 'A nyilvánosan elérhető metadatak a repeaterhez'; + + @override + String get repeater_refreshOwnerInfo => 'Frissítse az üzemeltető adatokat'; + + @override + String get repeater_floodMax => 'A vízmaximumos ugrások'; + + @override + String get repeater_floodMaxHelper => + 'A legmagasabb szám, amely egy vízszint-csomagban szerepelhet (0-64)'; + + @override + String get repeater_advancedSettings => 'Haladó'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Erkélő kapcsolók tapasztalt kezelők számára'; + + @override + String get repeater_pathHashMode => 'Út-hash mód'; + + @override + String get repeater_pathHashModeHelper => + 'A byte-ok, amelyek az alábbi repeater-ek azonosítójának kódolására szolgálnak a flood-útvonal/ciklus-észlelő címkékben. 0=1 byte (256 azonosító, akár 64 útvonal), 1=2 byte (65 000 azonosító, akár 32 útvonal), 2=3 byte (16 millió azonosító, akár 21 útvonal). A v1.13-as verziótól kezdődően és az azt követő verziókban a több byte-os útvonalak megszűntek – csak egyetlen útvonal létesül, miután a hálózat a v1.14-es verzióra vagy az azt követő verzióra frissült.'; + + @override + String get repeater_txDelay => 'Flood TX késés'; + + @override + String get repeater_txDelayHelper => + 'Újraküldési intervallum árvíz esetén, amely a csomag átviteli idejének (0-2, alapérték 0,5) szorzata. Minél nagyobb az érték, annál kevesebb ütközés, de lassabb a továbbítás.'; + + @override + String get repeater_directTxDelay => 'Közvetlen TX késés'; + + @override + String get repeater_directTxDelayHelper => + 'A közvetlen (nem tömeges) forgalomhoz tartozó adatcsomagok újrádiózására szolgáló intervallum, amely a csomag átviteli idejének (0-2, alapértelmezett érték 0,3) szorzata.'; + + @override + String get repeater_intThresh => 'Interferencia határ'; + + @override + String get repeater_intThreshHelper => + 'A határt a rádió zajszintjének kalibrálására állították, így elutasítja a fenti szint feletti interferenciákat. 0 kikapcsol – csak akkor állítsa be, ha zajos frekvencián RX hibákat észlel.'; + + @override + String get repeater_agcResetInterval => 'AGC visszazárási intervallum'; + + @override + String get repeater_agcResetIntervalHelper => + 'Mennyi időnként kell a rádió automatikus hangerőszabályozását visszaállítani, hogy kijavítsa a problémát? A visszaállítás időtartama: másoderek, amely 4-szeresével osztható. A 0 érték a periodikus visszaállítás kikapcsolását jelzi.'; + + @override + String get repeater_actionsTitle => 'Tevékenységek'; + + @override + String get repeater_sendAdvert => 'Eljuttass flood hirdetést'; + + @override + String get repeater_sendAdvertSubtitle => + 'Terjesztse egy árvíz elleni reklámot a hálózaton keresztül.'; + + @override + String get repeater_sendAdvertZeroHop => 'Küldj egy közvetlen hirdetést'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Adja közzé egyetlen átjáró hirdetést (nincs átjátszás).'; + + @override + String get repeater_clockSync => 'Synchronizálja az órát'; + + @override + String get repeater_clockSyncSubtitle => + 'Állítsa be a telefon időzítését a repeaterhez.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action sikert aratott'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action sikertelen: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Beállítások mentve – újraindítsa a repeatert, hogy alkalmazza'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Bizonyos beállítások nem sikerültek: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Hibás beállítások mentése: $error'; @@ -2368,10 +2617,6 @@ class AppLocalizationsHu extends AppLocalizations { @override String get repeater_refreshTxPower => 'Újraindítás TX-támogatással'; - @override - String get repeater_refreshLocationSettings => - 'Újraindítás helyszín beállításokkal'; - @override String get repeater_refreshPacketForwarding => 'Csomagok továbbításának frissítése'; @@ -2383,10 +2628,6 @@ class AppLocalizationsHu extends AppLocalizations { String get repeater_refreshPrivacyMode => 'Visszaállítás a magánéletvédő módra'; - @override - String get repeater_refreshAdvertisementSettings => - 'Újraindítás hirdetés beállítások'; - @override String repeater_refreshed(String label) { return '$label frissítve'; @@ -2712,6 +2953,285 @@ class AppLocalizationsHu extends AppLocalizations { String get repeater_gpsNote => 'Az GPS-al kapcsolatos funkciók lehetővé teszik a helyszín-személyesítéssel kapcsolatos feladatok kezelését.'; + @override + String get repeater_getCategory => 'Szereplő értékek'; + + @override + String get repeater_powerMgmt => + 'Energiahatékonyság, energiafelhasználás optimalizálása'; + + @override + String get repeater_sensors => 'Érzékelők'; + + @override + String get repeater_cliHelpPowerOff => + 'Át kapcsolja a készüléket. (nincs válasz elvárás)'; + + @override + String get repeater_cliHelpClkReboot => + 'Visszaállítja az órát egy ismert időpontra, majd újraindítja a készüléket.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Küld egy közvetlen szomszédoknak szóló hirdetést, amely közvetlen kapcsolatot igényel.'; + + @override + String get repeater_cliHelpStartOta => + 'Elindítja a vezeték nélküli útvonalon történő firmware frissítést a támogatott kártyákon.'; + + @override + String get repeater_cliHelpTime => + 'Beállítja a eszköz óráját a megadott Unix-időpont (Unix epoch) időpontra. Az óra nem tud visszanyúlni.'; + + @override + String get repeater_cliHelpBoard => + 'Megjeleníti a gyártó nevét/a hardver azonosítóját.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Kérést küld a közeli eszközöknek, hogy azok is megtalálják egymást. (Csak egy repeater eszköz számára)'; + + @override + String get repeater_cliHelpPowersaving => + 'Megmutatja, hogy a takarékos üzemmód engedélyezve van-e vagy nem.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Engedélyezi vagy kikapcsolja a takarékos üzemmódot (ha támogatott).'; + + @override + String get repeater_cliHelpErase => + '(Csak sorozatban) Formázza a eszköz fájlrendszerét. Eltávolítja az összes beállítást és a kapcsolatokat.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Beállítja a maximális engedélyezett átviteli időtartamot százalékban (1-100). Belsőleg módosítja az időtartam-szabályozást.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Csak sorozatban) Cseréli a eszköz egyedi kulcsát. Az alkalmazáshoz újraindítás szükséges. Új nyilvános kulcsot generál.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(Csak SX126x család) A növelt RX erősítést be- és kikapcsolható, így a nagyobb áramfelvétel esetén is javítható a érzékenység.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Megadja az üvegezésben megjelenő tulajdonos elérhetőségeinek szövegét. Használja a \'|\' karaktert új sorok elválasztására.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Beállítja a hálózati útvonal-hash módot. 0 = régebbi, 1 = szabványos, 2 = szigorú. Hatással van a hálózati útvonalak megadatalására.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Beállítja a hibaforrás-keresés érzékenységét: kikapcsolva, minimális, közepes vagy szigorú.'; + + @override + String get repeater_cliHelpSetFreq => + '(Csak soros mód) Gyorsan beállítja a frekvenciát. A rendszer újraindítás szükséges. A teljes rádióparaméterek beállításához a \"rádió beállítás\" funkciót javaslom.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Csak ESPNow híd esetén) Beállítja a híd által használt WiFi-csatornát (1-14).'; + + @override + String get repeater_cliHelpGetName => + 'Megjeleníti a konfigurált csomópont nevét.'; + + @override + String get repeater_cliHelpGetRole => + 'Megmutatja a firmware funkcióját (repeater, szobai szerver stb.).'; + + @override + String get repeater_cliHelpGetPublicKey => + 'Megjeleníti a eszköz nyilvános kulcsát.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Csak soros mód) Megjeleníti a eszköz privát kulcsát. Kezelje titkos információként.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Megmutatja, hogy a csomagok továbbításának (repeater funkció) engedélyezve van-e vagy nem.'; + + @override + String get repeater_cliHelpGetTx => + 'Megmutatja a jelenlegi TX (átvitel) teljesítményt dBm-ben.'; + + @override + String get repeater_cliHelpGetFreq => + 'Megjeleníti a konfigurált rádiófrekvenciát MHz-ben.'; + + @override + String get repeater_cliHelpGetRadio => + 'Megjeleníti az összes rádióparamétert: frekvencia, sávszélesség, széttétező tényező, kódolási ráta.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(Csak SX126x családra) Megjeleníti az RX erősítés állapotát.'; + + @override + String get repeater_cliHelpGetAf => 'Megmutatja az aktuális időadó tényezőt.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Megmutatja az aktuális engedélyezett működési ciklust százalékban.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Megmutatja a csatornák közötti interferencia szintjét dB-ben.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Megmutatja az AGC (automatikus gain-kontroll) visszaállítási időt másodpercekben.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Megmutatja, hogy a kettős visszaigazolás (double-ACK) mód engedélyezve van-e (1), vagy kikapcsolva (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Megmutatja, hogy a vendég csak olvasási jogosítást engedélyez-e.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Megmutatja a helyi hirdetés időtartamát percenként.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Megmutatja az aktuális időzítést, amikor megjelenik a vízparti reklám, órákonként.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Megjeleníti a konfigurált vendégjelszót.'; + + @override + String get repeater_cliHelpGetLat => 'Megjeleníti a beállított szélességet.'; + + @override + String get repeater_cliHelpGetLon => 'Megjeleníti a beállított hosszúságot.'; + + @override + String get repeater_cliHelpGetRxDelay => + 'Megmutatja az alapértéket a késéshez.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Megmutatja a vízszint-érzékelő jelátviteli késésének tényezőjét.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Megmutatja a közvetlen módban használt késés tényezőt.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Megmutatja a maximális vízszint-emelkedés mértékét.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Megjeleníti az tulajdonos elérhetőségének szövegét.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Megjeleníti a hash-alapú mód (0/1/2) beállításokat.'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Mutatja a cikkszám-azonosító érzékenységet.'; + + @override + String get repeater_cliHelpGetAcl => + '(Csak sorozat) A repeateren található hozzáférési szabályok listája.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Megmutatja, hogy a híd engedélyezve van-e.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Megmutatja a hídon bekövetkező késést másodpercben.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Megmutatja, hogy a híd RX vagy TX csomagokat fogad-e.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Csak RS232 híd) Megjeleníti a híd sebességét.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Csak ESPNow híd) Megjeleníti a híd által használt WiFi csatornát.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Csak ESPNow híd esetén) Megjeleníti a híd által megosztott titkos kulcsot.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(Csak NRF52 esetén) Megjeleníti a bootloader verzióját.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'A bemeneti feszültség-átalakító (akkumulátor-feszültség-szabályozó) működését mutatja.'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Megállapítja, hogy a felügyelet rendelkezik-e energiahatékonysági támogatással.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Megmutatja az aktuális energiaforrást: külső vagy akkumulátor.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Megjeleníti az utolsó újraindítás és leállítás okait.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Megjeleníti a rendszerindításkor mért akkumulátor feszültséget millivoltban (mV).'; + + @override + String get repeater_cliHelpSensorGet => + 'Beolvas egy felhasználó által definiált szenzor beállítást kulcs segítségével.'; + + @override + String get repeater_cliHelpSensorSet => + 'Egyedi szenzorbeállítások létrehozása.'; + + @override + String get repeater_cliHelpSensorList => + 'Összesíti az összes egyedi szenzor beállításot, oldalanként, opcionális kezdő index alapján.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Megmutatja a jelenlegi alapértelmezett régió határait.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Beállítja az alapértelmezett régió hatókörét. Használja a \"\" értéket a törléshez.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Felhasználható területek, ahol árvíz esetén forgalmat engedélyeznek.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Felhasznál, amelyek elutasítják a árvíz okozta forgalmat.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Csak sorozat) A csomagok szintjén történő statisztikát mutat.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Csak sorozat) Mutat rádióstatisztikákat.'; + + @override + String get repeater_cliHelpStatsCore => + '(Csak soros mód) A főfirmware-adatokat mutatja.'; + @override String get telemetry_receivedData => 'Kapott adatokat a szenzorokról'; @@ -3251,6 +3771,37 @@ class AppLocalizationsHu extends AppLocalizations { @override String get losLegendTerrain => 'Terület'; + @override + String get losBlockedSpotsTitle => 'Foglalhatatlan területek'; + + @override + String get losBlockedSpotsHint => + 'A blokkolt területet megjelölve, hogy a térképen kiemeljük.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Kiválasztott akadály'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Elakadt a $obstruction miatt, $heightUnit magasságban, $distanceFromA méterrel A-tól és $distanceFromB méterrel B-től ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Hatósság'; @@ -3722,4 +4273,40 @@ class AppLocalizationsHu extends AppLocalizations { @override String get translation_systemLanguage => 'Rendszer nyelvé'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart index 3a55559..e3f7ee5 100644 --- a/lib/l10n/app_localizations_it.dart +++ b/lib/l10n/app_localizations_it.dart @@ -24,7 +24,7 @@ class AppLocalizationsIt extends AppLocalizations { String get common_cancel => 'Annulla'; @override - String get common_ok => 'OK'; + String get common_ok => 'Va bene'; @override String get common_connect => 'Connetti'; @@ -44,6 +44,9 @@ class AppLocalizationsIt extends AppLocalizations { @override String get common_close => 'Chiudi'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Modifica'; @@ -437,9 +440,7 @@ class AppLocalizationsIt extends AppLocalizations { 'Includi la posizione nell\'annuncio'; @override - String settings_multiAck(String value) { - return 'Multi-ACKs: $value'; - } + String get settings_multiAck => 'ACK multipli'; @override String get settings_telemetryModeUpdated => 'Modalità telemetria aggiornata'; @@ -447,6 +448,13 @@ class AppLocalizationsIt extends AppLocalizations { @override String get settings_actions => 'Azioni'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Invia Annuncio'; @@ -488,11 +496,11 @@ class AppLocalizationsIt extends AppLocalizations { String get settings_debug => 'Risoluzione dei problemi'; @override - String get settings_bleDebugLog => 'Log di Debug BLE'; + String get settings_companionDebugLog => 'Registro di debug per il supporto'; @override - String get settings_bleDebugLogSubtitle => - 'Comandi, risposte e dati grezzi BLE'; + String get settings_companionDebugLogSubtitle => + 'Comandi, risposte e dati grezzi per protocolli BLE/TCP/USB'; @override String get settings_appDebugLog => 'Log di Debug dell\'App'; @@ -506,7 +514,7 @@ class AppLocalizationsIt extends AppLocalizations { @override String settings_aboutVersion(String version) { - return 'MeshCore Open v$version'; + return 'MeshCore Open versione $version'; } @override @@ -612,43 +620,43 @@ class AppLocalizationsIt extends AppLocalizations { String get appSettings_languageSystem => 'Predefinito di sistema'; @override - String get appSettings_languageEn => 'English'; + String get appSettings_languageEn => 'Inglese'; @override - String get appSettings_languageFr => 'Français'; + String get appSettings_languageFr => 'Francese'; @override - String get appSettings_languageEs => 'Español'; + String get appSettings_languageEs => 'Spagnolo'; @override - String get appSettings_languageDe => 'Deutsch'; + String get appSettings_languageDe => 'Tedesco'; @override - String get appSettings_languagePl => 'Polski'; + String get appSettings_languagePl => 'Polacco'; @override - String get appSettings_languageSl => 'Slovenščina'; + String get appSettings_languageSl => 'Sloveno'; @override - String get appSettings_languagePt => 'Português'; + String get appSettings_languagePt => 'Portoghese'; @override String get appSettings_languageIt => 'Italiano'; @override - String get appSettings_languageZh => '中文'; + String get appSettings_languageZh => 'Cinese'; @override - String get appSettings_languageSv => 'Svenska'; + String get appSettings_languageSv => 'Svedese'; @override - String get appSettings_languageNl => 'Nederlands'; + String get appSettings_languageNl => 'Olandese'; @override - String get appSettings_languageSk => 'Slovenčina'; + String get appSettings_languageSk => 'Sloveno'; @override - String get appSettings_languageBg => 'Български'; + String get appSettings_languageBg => 'Bulgaro'; @override String get appSettings_languageRu => 'Russo'; @@ -1089,20 +1097,16 @@ class AppLocalizationsIt extends AppLocalizations { return 'Canale $index'; } - @override - String get channels_hashtagChannel => 'Canale hashtag'; - @override String get channels_public => 'Pubblico'; @override - String get channels_private => 'Privato'; - - @override - String get channels_publicChannel => 'Canale pubblico'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Canale privato'; + String get channels_private => 'Privato'; @override String get channels_editChannel => 'Modifica canale'; @@ -1147,7 +1151,7 @@ class AppLocalizationsIt extends AppLocalizations { String get channels_standardPublicPsk => 'PSK pubblico standard'; @override - String get channels_pskHex => 'PSK (Hex)'; + String get channels_pskHex => 'PSK (esadecimale)'; @override String get channels_generateRandomPsk => @@ -1173,11 +1177,68 @@ class AppLocalizationsIt extends AppLocalizations { @override String get channels_smazCompression => 'Compressione SMAZ'; + @override + String get channels_cyr2latCompression => 'Compressione Cyr2Lat'; + + @override + String get channels_cyr2latCompressionDscr => + 'Sostituisce alcuni caratteri cirillici con caratteri latini durante l\'invio.'; + + @override + String get channels_cyr2latSettingsHeading => 'Impostazioni Cyr2Lat'; + + @override + String get channels_cyr2latSettingsSubheading => 'Elenco delle sostituzioni'; + + @override + String get channels_cyr2latSettingsDscr => + 'Modifica la configurazione JSON delle sostituzioni dei caratteri'; + + @override + String get channels_cyr2latSettingsDialogHint => + 'Mappa JSON delle sostituzioni'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'JSON non corretto: $error'; + } + @override String channels_channelUpdated(String name) { return 'Canale \"$name\" aggiornato'; } + @override + String get settings_cyr2latProfileAdd => 'Aggiungi profilo Cyr2Lat'; + + @override + String get settings_cyr2latProfileName => 'Nome profilo'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'Il nome del profilo non può essere vuoto'; + + @override + String get settings_cyr2latProfileAdded => 'Profilo aggiunto con successo'; + + @override + String get settings_cyr2latProfileUpdated => + 'Profilo aggiornato con successo'; + + @override + String get settings_cyr2latProfileEdit => 'Modifica profilo Cyr2Lat'; + + @override + String get settings_cyr2latProfileDelete => 'Elimina profilo Cyr2Lat'; + + @override + String get settings_cyr2latProfileDeleted => 'Profilo eliminato con successo'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Sei sicuro di voler eliminare il profilo \"$name\"?'; + } + @override String get channels_publicChannelAdded => 'Canale pubblico aggiunto'; @@ -1188,7 +1249,7 @@ class AppLocalizationsIt extends AppLocalizations { String get channels_sortManual => 'Manuale'; @override - String get channels_sortAZ => 'A-Z'; + String get channels_sortAZ => 'D-Z'; @override String get channels_sortLatestMessages => 'Ultimi messaggi'; @@ -1298,7 +1359,7 @@ class AppLocalizationsIt extends AppLocalizations { String get chat_addReaction => 'Aggiungi Reazione'; @override - String get chat_me => 'Me'; + String get chat_me => 'Io'; @override String get emojiCategorySmileys => 'Emoji'; @@ -1387,7 +1448,7 @@ class AppLocalizationsIt extends AppLocalizations { @override String debugFrame_timestamp(int timestamp) { - return '- Timestamp: $timestamp'; + return '- Marca temporale: $timestamp'; } @override @@ -1456,6 +1517,9 @@ class AppLocalizationsIt extends AppLocalizations { @override String get chat_successes => 'successi'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Rimuovi percorso'; @@ -1558,6 +1622,12 @@ class AppLocalizationsIt extends AppLocalizations { return 'Non letti: $count'; } + @override + String get chat_markAsUnread => 'Segna come non letto'; + + @override + String get chat_newMessages => 'Nuovi messaggi'; + @override String get chat_openLink => 'Aprire il link?'; @@ -1639,6 +1709,24 @@ class AppLocalizationsIt extends AppLocalizations { @override String get map_flags => 'Bandiere'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'Condividi marcatore qui'; @@ -1723,6 +1811,9 @@ class AppLocalizationsIt extends AppLocalizations { @override String get map_sharedPin => 'Condividi PIN'; + @override + String get map_sharedAt => 'Condiviso'; + @override String get map_joinRoom => 'Unisciti alla stanza'; @@ -2036,7 +2127,7 @@ class AppLocalizationsIt extends AppLocalizations { 'Visualizza lo stato, le statistiche e i vicini del ripetitore'; @override - String get repeater_telemetry => 'Telemetry'; + String get repeater_telemetry => 'Telemetria'; @override String get repeater_telemetrySubtitle => @@ -2132,6 +2223,9 @@ class AppLocalizationsIt extends AppLocalizations { @override String get repeater_rxAirtime => 'RX Airtime'; + @override + String get repeater_chanUtil => 'Utilizzo del canale'; + @override String get repeater_packetStatistics => 'Statistiche del Pacchetto'; @@ -2219,7 +2313,7 @@ class AppLocalizationsIt extends AppLocalizations { String get repeater_bandwidth => 'Larghezza di banda'; @override - String get repeater_spreadingFactor => 'Spreading Factor'; + String get repeater_spreadingFactor => 'Fattore di propagazione'; @override String get repeater_codingRate => 'Tasso di Codifica'; @@ -2344,6 +2438,166 @@ class AppLocalizationsIt extends AppLocalizations { @override String get repeater_settingsSaved => 'Impostazioni salvate con successo'; + @override + String get repeater_rxGain => 'Aumento del guadagno RX'; + + @override + String get repeater_rxGainHelper => + 'Maggiore sensibilità, maggiore assorbimento di corrente (solo per SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => 'Rafforza l\'effetto di RX'; + + @override + String get repeater_multiAcks => 'ACK multipli'; + + @override + String get repeater_multiAcksSubtitle => + 'Riconoscere i messaggi attraverso percorsi multipli per una migliore consegna.'; + + @override + String get repeater_refreshMultiAcks => 'Riaffermare più ACK'; + + @override + String get repeater_networkHealth => 'Salute della rete'; + + @override + String get repeater_loopDetect => 'Rilevamento di cicli'; + + @override + String get repeater_loopDetectHelper => + 'Crea pacchetti di dati che simulano loop di routing.'; + + @override + String get repeater_loopDetectOff => 'Offerte'; + + @override + String get repeater_loopDetectMinimal => 'Essenziale'; + + @override + String get repeater_loopDetectModerate => 'Moderato'; + + @override + String get repeater_loopDetectStrict => 'Rigido'; + + @override + String get repeater_dutyCycle => 'Ciclo di lavoro'; + + @override + String get repeater_dutyCycleHelper => + 'Percentuale massima di utilizzo dello spazio pubblicitario'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Informazioni sull\'operatore'; + + @override + String get repeater_ownerInfoHelper => + 'Metadati pubblici per questo ripetitore'; + + @override + String get repeater_refreshOwnerInfo => + 'Aggiorna le informazioni sull\'operatore'; + + @override + String get repeater_floodMax => + 'Massimo numero di salti in caso di inondazione'; + + @override + String get repeater_floodMaxHelper => + 'Numero massimo di pacchetti che un flusso può attraversare (0-64)'; + + @override + String get repeater_advancedSettings => 'Avanzato'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Manopole di regolazione per operatori esperti'; + + @override + String get repeater_pathHashMode => 'Modalità di hashing del percorso'; + + @override + String get repeater_pathHashModeHelper => + 'Byte utilizzati per codificare l\'ID di questo ripetitore nei tag per il rilevamento del percorso/loop. 0=1 byte (256 ID, fino a 64 salti), 1=2 byte (65.000 ID, fino a 32 salti), 2=3 byte (16 milioni di ID, fino a 21 salti). Le versioni 1.13 e precedenti utilizzano percorsi multi-byte: è necessario attivare la rete prima di utilizzare questa funzionalità (a partire dalla versione 1.14).'; + + @override + String get repeater_txDelay => 'Ritardo a Flood, TX'; + + @override + String get repeater_txDelayHelper => + 'Riassegnare lo spazio tra i pacchetti per gestire il traffico intenso, come un moltiplicatore del tempo di trasmissione (da 0 a 2, valore predefinito 0,5). Un valore più alto significa meno collisioni, ma una trasmissione più lenta.'; + + @override + String get repeater_directTxDelay => 'Ritardo diretto TX'; + + @override + String get repeater_directTxDelayHelper => + 'Riassegnare lo spazio per il traffico diretto (non di massa), come un moltiplicatore del tempo di trasmissione del pacchetto (da 0 a 2, valore predefinito 0,3).'; + + @override + String get repeater_intThresh => 'Soglia di interferenza'; + + @override + String get repeater_intThreshHelper => + 'Il limite è stato impostato per la calibrazione del livello di rumore del ricevitore, in modo che esso rifiuti i segnali di interferenza superiori a questo livello. 0 disabilita – aumentalo solo se si verificano errori nel ricevitore in una banda di frequenza rumorosa.'; + + @override + String get repeater_agcResetInterval => 'Intervallo di ripristino di AGC'; + + @override + String get repeater_agcResetIntervalHelper => + 'Con quale frequenza è necessario resettare il controllo automatico del guadagno per ripristinare il funzionamento dopo un\'interruzione. Impostare su secondi, ridotti a multipli di 4. Disattivare la reimpostazione periodica.'; + + @override + String get repeater_actionsTitle => 'Azioni'; + + @override + String get repeater_sendAdvert => + 'Inviare annuncio relativo alle inondazioni'; + + @override + String get repeater_sendAdvertSubtitle => + 'Trasmettere un annuncio pubblicitario relativo alle inondazioni attraverso la rete.'; + + @override + String get repeater_sendAdvertZeroHop => + 'Inviare un annuncio senza intermediari'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Trasmettere un annuncio a un solo hop (senza ripetitori)'; + + @override + String get repeater_clockSync => 'Sincronizza l\'orologio ora'; + + @override + String get repeater_clockSyncSubtitle => + 'Imposta l\'ora del tuo telefono sul ripetitore.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action ha avuto successo'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action failed: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Impostazioni salvate — riavviare il ripetitore per applicare le modifiche'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Alcune impostazioni non sono state salvate: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Errore durante il salvataggio delle impostazioni: $error'; @@ -2358,10 +2612,6 @@ class AppLocalizationsIt extends AppLocalizations { @override String get repeater_refreshTxPower => 'Aggiorna TX potenza'; - @override - String get repeater_refreshLocationSettings => - 'Aggiorna le Impostazioni della Posizione'; - @override String get repeater_refreshPacketForwarding => 'Aggiorna il inoltro pacchetti'; @@ -2372,10 +2622,6 @@ class AppLocalizationsIt extends AppLocalizations { @override String get repeater_refreshPrivacyMode => 'Aggiorna Modalità Privacy'; - @override - String get repeater_refreshAdvertisementSettings => - 'Aggiorna le Impostazioni dell\'Annuncio'; - @override String repeater_refreshed(String label) { return '$label aggiornato'; @@ -2701,6 +2947,281 @@ class AppLocalizationsIt extends AppLocalizations { String get repeater_gpsNote => 'è stata introdotta una funzione gps per gestire le tematiche relative alla posizione.'; + @override + String get repeater_getCategory => 'Ottenere valori'; + + @override + String get repeater_powerMgmt => 'Gestione dell\'energia'; + + @override + String get repeater_sensors => 'Sensori'; + + @override + String get repeater_cliHelpPowerOff => + 'Disattiva il dispositivo. (non ci si aspetta alcuna risposta)'; + + @override + String get repeater_cliHelpClkReboot => + 'Riporta l\'orologio a un\'epoca nota e riavvia il dispositivo.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Invia un annuncio che raggiunge solo i vicini immediati (senza passaggi intermedi).'; + + @override + String get repeater_cliHelpStartOta => + 'Avvia un aggiornamento del firmware tramite la trasmissione radio su schede supportate.'; + + @override + String get repeater_cliHelpTime => + 'Imposta l\'orario del dispositivo sui secondi dell\'epoca Unix specificati. L\'orario non può andare indietro.'; + + @override + String get repeater_cliHelpBoard => + 'Indica il produttore della scheda e l\'identificatore hardware.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Invia una richiesta di scoperta di nodi ai vicini. (Solo per ripetitori)'; + + @override + String get repeater_cliHelpPowersaving => + 'Indica se la modalità di risparmio energetico è attiva o disattivata.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Abilita o disabilita la modalità di risparmio energetico (se supportata).'; + + @override + String get repeater_cliHelpErase => + '(Solo per sistemi di serializzazione) Formatta il file system del dispositivo. Elimina tutte le impostazioni e i contatti.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Imposta il ciclo di trasmissione massimo consentito in percentuale (da 1 a 100). Regola internamente il fattore di tempo di trasmissione.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Solo per serie) Sostituisce la chiave privata di identificazione del dispositivo. È necessario riavviare il dispositivo per applicare la modifica. Genera una nuova chiave pubblica.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(Solo per SX126x) Permette di attivare un guadagno RX potenziato per una maggiore sensibilità a correnti più elevate.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Definisce la stringa contenente le informazioni di contatto del proprietario, presente negli annunci. Utilizzare \'|\' per i newline.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Imposta la modalità di hashing del percorso. 0 = modalità legacy, 1 = modalità standard, 2 = modalità rigorosa. Influisce su come vengono abbinati i percorsi di routing.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Imposta il livello di sensibilità per il rilevamento dei loop di routing: disattivato, minimo, moderato o rigoroso.'; + + @override + String get repeater_cliHelpSetFreq => + '(Solo per la funzione di regolazione della frequenza) Imposta rapidamente la frequenza desiderata. È necessario riavviare il dispositivo. Si consiglia di utilizzare la funzione \"imposta radio\" per impostare tutti i parametri radio.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Solo per il bridge ESPNow) Imposta il canale Wi-Fi (da 1 a 14) utilizzato dal bridge.'; + + @override + String get repeater_cliHelpGetName => 'Mostra il nome del nodo configurato.'; + + @override + String get repeater_cliHelpGetRole => + 'Indica il ruolo del firmware (ripetitore, server per stanza, ecc.).'; + + @override + String get repeater_cliHelpGetPublicKey => + 'Mostra la chiave pubblica del dispositivo.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Solo per serie) Visualizza la chiave privata del dispositivo. Trattala come una informazione riservata.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Indica se la funzione di inoltro dei pacchetti (funzione di ripetitore) è attiva o disattivata.'; + + @override + String get repeater_cliHelpGetTx => 'Mostra la potenza attuale in dBm.'; + + @override + String get repeater_cliHelpGetFreq => + 'Mostra la frequenza radio configurata in MHz.'; + + @override + String get repeater_cliHelpGetRadio => + 'Visualizza tutti i parametri radio: frequenza, larghezza di banda, fattore di spreading, tasso di codifica.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(Solo per i moduli SX126x) Mostra lo stato del guadagno potenziato del RX.'; + + @override + String get repeater_cliHelpGetAf => + 'Mostra il fattore di trasmissione attuale.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Mostra il ciclo di lavoro attuale consentito in percentuale.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Mostra il limite di interferenza del canale in dB.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Indica l\'intervallo di reset dell\'AGC in secondi.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Indica se la modalità \"ACK doppio\" è attiva (1) o disattivata (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Indica se è consentito l\'accesso in sola lettura per gli ospiti.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Indica l\'intervallo pubblicitario locale in minuti.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Indica l\'intervallo pubblicitario per la trasmissione del servizio di allerta alluvioni, espresso in ore.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Visualizza la password del guest configurata.'; + + @override + String get repeater_cliHelpGetLat => 'Mostra la latitudine configurata.'; + + @override + String get repeater_cliHelpGetLon => 'Mostra la longitudine impostata.'; + + @override + String get repeater_cliHelpGetRxDelay => 'Mostra il valore base di rxdelay.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Mostra il fattore di ritardo in modalità di allarme.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Mostra il fattore di ritardo in modalità diretta.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Mostra il numero massimo di salti dovuto all\'inondazione.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Visualizza la stringa contenente le informazioni di contatto del proprietario.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Mostra la modalità \"hash del percorso\" (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Indica la sensibilità alla rilevazione di loop.'; + + @override + String get repeater_cliHelpGetAcl => + '(Solo per serie) Elenca le voci di controllo degli accessi su un ripetitore.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => 'Indica se il ponte è attivo.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Mostra il ritardo del ponte in millisecondi.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Indica se il bridge sta inviando pacchetti RX o TX.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Solo per l\'adattatore RS232) Visualizza la velocità di trasmissione del bridge.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Solo per il bridge ESPNow) Visualizza il canale WiFi del bridge.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Solo per il bridge ESPNow) Visualizza la chiave segreta condivisa.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(Solo per NRF52) Visualizza la versione del bootloader.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Mostra il moltiplicatore ADC (adattamento della tensione della batteria).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Indica se il sistema dispone di funzionalità di gestione dell\'energia.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Indica la fonte di alimentazione attuale: esterna o batteria.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Mostra le ragioni più recenti per il ripristino e lo spegnimento.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Mostra la tensione della batteria al momento dell\'accensione, misurata in millivolt (mV).'; + + @override + String get repeater_cliHelpSensorGet => + 'Legge un valore di configurazione personalizzato per un sensore tramite un tasto.'; + + @override + String get repeater_cliHelpSensorSet => + 'Definisce una configurazione personalizzata per un sensore.'; + + @override + String get repeater_cliHelpSensorList => + 'Elenca tutte le impostazioni personalizzate dei sensori, organizzate in pagine a partire da un indice di inizio opzionale.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Mostra l\'ambito predefinito corrente.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Definisce l\'ambito regionale predefinito. Utilizzare \"\" per cancellare.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Elenca le regioni che consentono il transito di veicoli in caso di allagamenti.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Elenca le regioni che vietano il transito in caso di alluvioni.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Solo per la visualizzazione dei dati seriali) Mostra statistiche a livello di pacchetto.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Solo per serie TV) Visualizza statistiche relative alla trasmissione radiofonica.'; + + @override + String get repeater_cliHelpStatsCore => + '(Solo per serie) Visualizza le statistiche del firmware di base.'; + @override String get telemetry_receivedData => 'Dati Telemetria Ricevuti'; @@ -3068,7 +3589,7 @@ class AppLocalizationsIt extends AppLocalizations { String get listFilter_heardRecently => 'Sentito di recente'; @override - String get listFilter_az => 'A-Z'; + String get listFilter_az => 'D-Z'; @override String get listFilter_filters => 'Filtri'; @@ -3240,6 +3761,37 @@ class AppLocalizationsIt extends AppLocalizations { @override String get losLegendTerrain => 'Terreno'; + @override + String get losBlockedSpotsTitle => 'Posti occupati'; + + @override + String get losBlockedSpotsHint => + 'Tocca un punto bloccato sulla mappa per evidenziarlo.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Ostacolo selezionato'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Frequenza'; @@ -3709,4 +4261,40 @@ class AppLocalizationsIt extends AppLocalizations { @override String get translation_systemLanguage => 'Lingua del sistema'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_ja.dart b/lib/l10n/app_localizations_ja.dart index afb8c29..263a906 100644 --- a/lib/l10n/app_localizations_ja.dart +++ b/lib/l10n/app_localizations_ja.dart @@ -44,6 +44,9 @@ class AppLocalizationsJa extends AppLocalizations { @override String get common_close => '閉じる'; + @override + String get common_done => 'Done'; + @override String get common_edit => '編集'; @@ -118,7 +121,7 @@ class AppLocalizationsJa extends AppLocalizations { String get connectionChoiceBluetoothLabel => 'ブルートゥース'; @override - String get connectionChoiceTcpLabel => 'TCP'; + String get connectionChoiceTcpLabel => 'TCP (Transmission Control Protocol)'; @override String get tcpScreenTitle => 'TCP を使用して接続'; @@ -414,9 +417,7 @@ class AppLocalizationsJa extends AppLocalizations { String get settings_advertLocationSubtitle => '広告に場所を記載してください。'; @override - String settings_multiAck(String value) { - return '複数のACK:$value'; - } + String get settings_multiAck => '複数のACK(応答)'; @override String get settings_telemetryModeUpdated => 'テレメトリモードが更新されました'; @@ -424,6 +425,13 @@ class AppLocalizationsJa extends AppLocalizations { @override String get settings_actions => '行動'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => '広告を送信する'; @@ -462,10 +470,11 @@ class AppLocalizationsJa extends AppLocalizations { String get settings_debug => 'デバッグ'; @override - String get settings_bleDebugLog => 'BLE デバッグログ'; + String get settings_companionDebugLog => '同伴デバッグログ'; @override - String get settings_bleDebugLogSubtitle => 'BLEコマンド、応答、および生のデータ'; + String get settings_companionDebugLogSubtitle => + 'BLE/TCP/USB 関連のコマンド、応答、および生のデータ'; @override String get settings_appDebugLog => 'アプリケーションのデバッグログ'; @@ -1035,20 +1044,16 @@ class AppLocalizationsJa extends AppLocalizations { return 'チャンネル $index'; } - @override - String get channels_hashtagChannel => 'ハッシュタグチャンネル'; - @override String get channels_public => '一般の人々'; @override - String get channels_private => '個人の'; - - @override - String get channels_publicChannel => '一般チャンネル'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'プライベートチャンネル'; + String get channels_private => '個人の'; @override String get channels_editChannel => 'チャンネルを編集する'; @@ -1117,11 +1122,63 @@ class AppLocalizationsJa extends AppLocalizations { @override String get channels_smazCompression => 'SMAZ 圧縮'; + @override + String get channels_cyr2latCompression => 'Cyr2Lat 圧縮'; + + @override + String get channels_cyr2latCompressionDscr => '送信時に一部のキリル文字をラテン文字に置き換えます。'; + + @override + String get channels_cyr2latSettingsHeading => 'cyr2latの設定'; + + @override + String get channels_cyr2latSettingsSubheading => '置換リスト'; + + @override + String get channels_cyr2latSettingsDscr => '文字置換のJSON設定を編集する'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON置換マップ'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return '不正なJSON: $error'; + } + @override String channels_channelUpdated(String name) { return 'チャンネル「$name」が更新されました'; } + @override + String get settings_cyr2latProfileAdd => 'Cyr2Latプロファイルの追加'; + + @override + String get settings_cyr2latProfileName => 'プロファイル名'; + + @override + String get settings_cyr2latProfileNameEmpty => 'プロファイル名は空にできません'; + + @override + String get settings_cyr2latProfileAdded => 'プロファイルが正常に追加されました'; + + @override + String get settings_cyr2latProfileUpdated => 'プロファイルの更新に成功しました'; + + @override + String get settings_cyr2latProfileEdit => 'Cyr2Latプロファイルを編集'; + + @override + String get settings_cyr2latProfileDelete => 'Cyr2Latプロファイルを削除'; + + @override + String get settings_cyr2latProfileDeleted => 'プロファイルの削除に成功しました'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'プロファイル \"$name\" を削除してもよろしいですか?'; + } + @override String get channels_publicChannelAdded => 'パブリックチャンネルが追加されました'; @@ -1394,6 +1451,9 @@ class AppLocalizationsJa extends AppLocalizations { @override String get chat_successes => '成功事例'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'パスを削除する'; @@ -1489,6 +1549,12 @@ class AppLocalizationsJa extends AppLocalizations { return '未読: $count'; } + @override + String get chat_markAsUnread => '未読としてマークする'; + + @override + String get chat_newMessages => '新しいメッセージ'; + @override String get chat_openLink => 'リンクを開く?'; @@ -1567,6 +1633,24 @@ class AppLocalizationsJa extends AppLocalizations { @override String get map_flags => '旗'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'この場所でシェア'; @@ -1650,6 +1734,9 @@ class AppLocalizationsJa extends AppLocalizations { @override String get map_sharedPin => '共有パスワード'; + @override + String get map_sharedAt => '共有済み'; + @override String get map_joinRoom => '部屋に参加する'; @@ -2043,6 +2130,9 @@ class AppLocalizationsJa extends AppLocalizations { @override String get repeater_rxAirtime => 'RX 空き時間'; + @override + String get repeater_chanUtil => 'チャンネルの利用状況'; + @override String get repeater_packetStatistics => 'パケット統計'; @@ -2242,6 +2332,152 @@ class AppLocalizationsJa extends AppLocalizations { @override String get repeater_settingsSaved => '設定が正常に保存されました'; + @override + String get repeater_rxGain => 'RX ゲインの向上'; + + @override + String get repeater_rxGainHelper => 'より高い感度、より大きな電流(SX1262/SX1268のみ)'; + + @override + String get repeater_refreshRxGain => '強化されたRX効果を再確認'; + + @override + String get repeater_multiAcks => '複数のACK(応答)'; + + @override + String get repeater_multiAcksSubtitle => '複数の経路でメッセージを送信することで、より確実な配信を実現する。'; + + @override + String get repeater_refreshMultiAcks => '複数のACKをリフレッシュする'; + + @override + String get repeater_networkHealth => 'ネットワークの状態'; + + @override + String get repeater_loopDetect => 'ループ検出'; + + @override + String get repeater_loopDetectHelper => 'ルーティングループに見えるような、洪水パケットを送信する'; + + @override + String get repeater_loopDetectOff => 'オフ'; + + @override + String get repeater_loopDetectMinimal => '最小限の'; + + @override + String get repeater_loopDetectModerate => '適度な'; + + @override + String get repeater_loopDetectStrict => '厳格な'; + + @override + String get repeater_dutyCycle => '動作サイクル'; + + @override + String get repeater_dutyCycleHelper => '最大の使用時間割合'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => '事業者の情報'; + + @override + String get repeater_ownerInfoHelper => 'このリピーターに関する公開メタデータ'; + + @override + String get repeater_refreshOwnerInfo => 'オペレーター情報の更新'; + + @override + String get repeater_floodMax => '最大ホップ数'; + + @override + String get repeater_floodMaxHelper => '洪水パケットが移動できる最大ホップ数 (0-64)'; + + @override + String get repeater_advancedSettings => '高度な'; + + @override + String get repeater_advancedSettingsSubtitle => '経験豊富なオペレーター向けの調整ノブ'; + + @override + String get repeater_pathHashMode => 'パスハッシュモード'; + + @override + String get repeater_pathHashModeHelper => + 'このリピーターのIDをフローパス/ループ検出タグにエンコードするために使用されるバイト数。 0=1バイト (256個のID、最大64ホップ)、1=2バイト (65,000個のID、最大32ホップ)、2=3バイト (160万個のID、最大21ホップ)。 v1.13およびそれ以前のファームウェアでは、マルチバイトパスがサポートされていません。 v1.14以降のバージョンでは、一度ネットワークが起動されると、パスが一度だけ検出されます。'; + + @override + String get repeater_txDelay => 'フロイド・TXでの遅延'; + + @override + String get repeater_txDelayHelper => + '洪水時の交通量に対応するための再送信間隔を、パケットの通信時間を掛けた値(0~2、デフォルト0.5)で設定します。値を大きくすると衝突が減りますが、通信速度が遅くなります。'; + + @override + String get repeater_directTxDelay => '直接的なTX遅延'; + + @override + String get repeater_directTxDelayHelper => + '直接(フラッドではない)トラフィックに対する再送信間隔を、パケットの空中時間(0~2、デフォルト0.3)の倍数として設定する。'; + + @override + String get repeater_intThresh => '干渉閾値'; + + @override + String get repeater_intThreshHelper => + 'ラジオのノイズレベルを基準とする閾値を設定し、このレベルを超えるノイズを抑制します。 0 を設定すると、ノイズの多い帯域で RX エラーが発生した場合のみ、この値を上げることができます。'; + + @override + String get repeater_agcResetInterval => 'AGCのリセット間隔'; + + @override + String get repeater_agcResetIntervalHelper => + 'ラジオの自動ゲイン制御をリセットする頻度について:ゲインが固定状態になった場合に、回復するために、何度リセットするかを設定します。4の倍数でリセットする場合、0を設定すると、定期的なリセットは停止します。'; + + @override + String get repeater_actionsTitle => '行動'; + + @override + String get repeater_sendAdvert => '洪水に関する広告を送信'; + + @override + String get repeater_sendAdvertSubtitle => 'ネットワークを通じて、洪水に関する広告を放送する'; + + @override + String get repeater_sendAdvertZeroHop => 'ゼロホップ形式の広告を送信する'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => 'ワンホップでの広告放送(中継なし)'; + + @override + String get repeater_clockSync => '現在、時刻を同期する'; + + @override + String get repeater_clockSyncSubtitle => 'スマートフォンの時刻をルーターに設定する'; + + @override + String repeater_actionSucceeded(String action) { + return '$action が成功しました'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action の実行に失敗しました: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + '設定を保存しました — リピーターを再起動して適用してください'; + + @override + String repeater_settingsPartialFailure(String failures) { + return '設定の一部でエラーが発生しました:$failures'; + } + @override String repeater_errorSavingSettings(String error) { return '設定の保存に失敗しました:$error'; @@ -2256,9 +2492,6 @@ class AppLocalizationsJa extends AppLocalizations { @override String get repeater_refreshTxPower => 'TX の電力レベルをリセットする'; - @override - String get repeater_refreshLocationSettings => '場所設定をリセットする'; - @override String get repeater_refreshPacketForwarding => 'パケット転送の刷新'; @@ -2268,9 +2501,6 @@ class AppLocalizationsJa extends AppLocalizations { @override String get repeater_refreshPrivacyMode => 'プライバシーモードをリセットする'; - @override - String get repeater_refreshAdvertisementSettings => '広告設定のリセット'; - @override String repeater_refreshed(String label) { return '$label が更新されました'; @@ -2571,6 +2801,245 @@ class AppLocalizationsJa extends AppLocalizations { @override String get repeater_gpsNote => 'GPSコマンドは、位置情報に関連するタスクを管理するために導入されました。'; + @override + String get repeater_getCategory => '価値を取得する'; + + @override + String get repeater_powerMgmt => '電力管理'; + + @override + String get repeater_sensors => 'センサー'; + + @override + String get repeater_cliHelpPowerOff => 'デバイスをシャットダウンします。(応答は期待されていません)'; + + @override + String get repeater_cliHelpClkReboot => '時計を既知の基準時点にリセットし、デバイスを再起動します。'; + + @override + String get repeater_cliHelpAdvertZeroHop => '近隣のデバイスのみに、ゼロホップの広告を送信します。'; + + @override + String get repeater_cliHelpStartOta => + 'サポートされているボードに対して、無線でファームウェアのアップデートを開始します。'; + + @override + String get repeater_cliHelpTime => + 'デバイスのクロックを、指定されたUnixエポックの秒数に設定します。クロックは逆方向に進むことはできません。'; + + @override + String get repeater_cliHelpBoard => '製造元の名前/ハードウェア識別子を表示します。'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + '近隣のノードに対して、ノードの探索リクエストを送信します。(中継機能のみ)'; + + @override + String get repeater_cliHelpPowersaving => '省電力モードがオンになっているかどうかを表示します。'; + + @override + String get repeater_cliHelpPowersavingOnOff => + '省電力モード(対応している場合)を有効または無効にします。'; + + @override + String get repeater_cliHelpErase => + '(シリアルモードのみ)デバイスのファイルシステムをフォーマットします。すべての設定と連絡先を消去します。'; + + @override + String get repeater_cliHelpSetDutyCycle => + '送信可能な最大デューティサイクルをパーセントで設定します(1〜100)。内部で、空き時間の要素を調整します。'; + + @override + String get repeater_cliHelpSetPrvKey => + '(シリアル番号のみ)デバイスのプライベートキーを置き換えます。適用には再起動が必要です。新しいパブリックキーを生成します。'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(SX126xのみ)高電流での使用時に、感度を向上させるために、増幅されたRXのゲインを切り替えることができます。'; + + @override + String get repeater_cliHelpSetOwnerInfo => + '広告に記載されている所有者連絡先情報を設定します。改行には\'|\'を使用してください。'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'パスハッシュモードを設定します。 0 = 従来のモード、1 = 標準モード、2 = 厳格モード。ルーティングパスのマッチング方法に影響します。'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'ルーティングループ検出の感度を設定します:オフ、最小、中程度、または厳格。'; + + @override + String get repeater_cliHelpSetFreq => + '(シリアル設定のみ)特定の周波数のみを素早く設定できます。再起動が必要です。「ラジオ設定」を使用すると、ラジオのすべてのパラメータを設定できます。'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(ESPNowブリッジのみ)ブリッジで使用するWi-Fiチャンネル(1~14)を設定します。'; + + @override + String get repeater_cliHelpGetName => '設定されたノードの名前を表示します。'; + + @override + String get repeater_cliHelpGetRole => 'ファームウェアの役割(リピーター、ルームサーバーなど)を表示します。'; + + @override + String get repeater_cliHelpGetPublicKey => 'デバイスの公開鍵を表示します。'; + + @override + String get repeater_cliHelpGetPrvKey => + '(シリアル番号のみ)デバイスのプライベートキーを表示します。機密情報として扱ってください。'; + + @override + String get repeater_cliHelpGetRepeat => 'パケット転送(リピーター機能)が有効になっているかどうかを表示します。'; + + @override + String get repeater_cliHelpGetTx => '現在のTX(送信)電力のdBm値を表示します。'; + + @override + String get repeater_cliHelpGetFreq => '設定された無線周波数をMHzで表示します。'; + + @override + String get repeater_cliHelpGetRadio => + '以下のすべての無線パラメータを表示: 周波数、帯域幅、スプレッドファクター、符号化レート。'; + + @override + String get repeater_cliHelpGetRadioRxGain => '(SX126xのみ) RX の増幅ゲインの状態を表示します。'; + + @override + String get repeater_cliHelpGetAf => '現在の空き時間係数を表示します。'; + + @override + String get repeater_cliHelpGetDutyCycle => '現在の許可されたデューティサイクルをパーセントで表示します。'; + + @override + String get repeater_cliHelpGetIntThresh => 'チャンネル干渉の閾値をdBで表示します。'; + + @override + String get repeater_cliHelpGetAgcResetInterval => 'AGCのリセット間隔を秒単位で表示します。'; + + @override + String get repeater_cliHelpGetMultiAcks => 'ダブルACKモードが有効 (1) か無効 (0) かを示す。'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'ゲストによる読み取り専用アクセスが許可されているかどうかを示す。'; + + @override + String get repeater_cliHelpGetAdvertInterval => 'ローカル広告の時間を分単位で表示します。'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + '洪水に関する広告の放送時間を時間単位で表示します。'; + + @override + String get repeater_cliHelpGetGuestPassword => '設定されたゲストパスワードを表示します。'; + + @override + String get repeater_cliHelpGetLat => '設定された緯度を表示します。'; + + @override + String get repeater_cliHelpGetLon => '設定された経度を表示します。'; + + @override + String get repeater_cliHelpGetRxDelay => 'rxdelay の基本値を表示します。'; + + @override + String get repeater_cliHelpGetTxDelay => '洪水モードにおける送信遅延の要因を示します。'; + + @override + String get repeater_cliHelpGetDirectTxDelay => 'ダイレクトモードの遅延要素を示します。'; + + @override + String get repeater_cliHelpGetFloodMax => '最大浸水範囲の回数を表示します。'; + + @override + String get repeater_cliHelpGetOwnerInfo => '所有者の連絡先情報を表示します。'; + + @override + String get repeater_cliHelpGetPathHashMode => 'パスハッシュモード(0/1/2)を表示します。'; + + @override + String get repeater_cliHelpGetLoopDetect => 'ループ検出の感度を示す。'; + + @override + String get repeater_cliHelpGetAcl => '(シリアルのみ)リピーター上のアクセス制御設定を一覧表示します。'; + + @override + String get repeater_cliHelpGetBridgeEnabled => '橋が有効になっているかどうかを表示します。'; + + @override + String get repeater_cliHelpGetBridgeDelay => '橋の遅延時間をミリ秒(ms)で表示します。'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'RX または TX パケットを橋渡ししているかどうかを示す。'; + + @override + String get repeater_cliHelpGetBridgeBaud => '(RS232 橋渡し機能のみ)橋渡しのボーレートを表示します。'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(ESPNowブリッジのみ)ブリッジで使用しているWi-Fiチャンネルを表示します。'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(ESPNowブリッジのみ)ブリッジで共有されている秘密鍵を表示します。'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(NRF52のみ)ブートローダーのバージョンを表示します。'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'ADC(アナログ-デジタル変換)のマルチプライヤー(バッテリー電圧のスケーリング)を表示します。'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + '取締役会が電力管理機能をサポートしているかどうかを報告します。'; + + @override + String get repeater_cliHelpGetPwrMgtSource => '現在の電源(外部電源またはバッテリー)を表示します。'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + '最新のリセットおよびシャットダウンの理由を表示します。'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => '起動時のバッテリー電圧をmVで表示します。'; + + @override + String get repeater_cliHelpSensorGet => 'キーを使用して、カスタムセンサーの設定を読み取る。'; + + @override + String get repeater_cliHelpSensorSet => 'カスタムセンサーの設定を作成する。'; + + @override + String get repeater_cliHelpSensorList => + 'カスタムセンサーの設定をすべてリスト表示し、オプションで指定できる開始インデックスからページ分割して表示します。'; + + @override + String get repeater_cliHelpRegionDefault => '現在のデフォルトの地域範囲を表示します。'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'デフォルトの地域範囲を設定します。「」を使用すると、設定をリセットできます。'; + + @override + String get repeater_cliHelpRegionListAllowed => '洪水時の通行が許可されている地域の一覧'; + + @override + String get repeater_cliHelpRegionListDenied => '洪水による交通を遮断している地域の一覧'; + + @override + String get repeater_cliHelpStatsPackets => '(シリアルのみ)パケットレベルの統計情報を表示します。'; + + @override + String get repeater_cliHelpStatsRadio => '(シリーズのみ)ラジオの統計情報を表示します。'; + + @override + String get repeater_cliHelpStatsCore => '(シリアルのみ)主要なファームウェアの統計情報を表示します。'; + @override String get telemetry_receivedData => '受信したテレメトリーデータ'; @@ -3092,6 +3561,36 @@ class AppLocalizationsJa extends AppLocalizations { @override String get losLegendTerrain => '地形'; + @override + String get losBlockedSpotsTitle => '利用できない場所'; + + @override + String get losBlockedSpotsHint => '地図上で、特定された場所を強調するために、該当する場所をタップしてください。'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => '選択された障害'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return '$obstruction によって $heightUnit の高さで、A地点から $distanceFromA、B地点から $distanceFromB ($distanceUnit) の距離で塞がれています。'; + } + @override String get losFrequencyLabel => '周波数'; @@ -3528,4 +4027,40 @@ class AppLocalizationsJa extends AppLocalizations { @override String get translation_systemLanguage => 'システム言語'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index ff4bd26..f9c0d76 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -44,6 +44,9 @@ class AppLocalizationsKo extends AppLocalizations { @override String get common_close => '닫기'; + @override + String get common_done => 'Done'; + @override String get common_edit => '수정'; @@ -414,9 +417,7 @@ class AppLocalizationsKo extends AppLocalizations { String get settings_advertLocationSubtitle => '광고에 위치 정보를 포함하세요.'; @override - String settings_multiAck(String value) { - return '다중 ACK: $value'; - } + String get settings_multiAck => '다중 ACK'; @override String get settings_telemetryModeUpdated => '텔레메트리 모드 업데이트 완료'; @@ -424,6 +425,13 @@ class AppLocalizationsKo extends AppLocalizations { @override String get settings_actions => '행동'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => '광고 전송'; @@ -462,10 +470,11 @@ class AppLocalizationsKo extends AppLocalizations { String get settings_debug => '디버깅'; @override - String get settings_bleDebugLog => 'BLE 디버그 로그'; + String get settings_companionDebugLog => '동반 디버깅 로그'; @override - String get settings_bleDebugLogSubtitle => 'BLE 명령어, 응답 및 원시 데이터'; + String get settings_companionDebugLogSubtitle => + 'BLE/TCP/USB 명령어, 응답 및 원시 데이터'; @override String get settings_appDebugLog => '앱 디버깅 로그'; @@ -1030,20 +1039,16 @@ class AppLocalizationsKo extends AppLocalizations { return '채널 $index'; } - @override - String get channels_hashtagChannel => '해시태그 채널'; - @override String get channels_public => '대중의'; @override - String get channels_private => '사립'; - - @override - String get channels_publicChannel => '공개 채널'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => '개인 채널'; + String get channels_private => '사립'; @override String get channels_editChannel => '채널 편집'; @@ -1112,11 +1117,63 @@ class AppLocalizationsKo extends AppLocalizations { @override String get channels_smazCompression => 'SMAZ 압축'; + @override + String get channels_cyr2latCompression => 'Cyr2Lat 압축'; + + @override + String get channels_cyr2latCompressionDscr => '보낼 때 일부 키릴 문자를 라틴 문자로 바꿉니다.'; + + @override + String get channels_cyr2latSettingsHeading => 'Cyr2Lat 설정'; + + @override + String get channels_cyr2latSettingsSubheading => '변환 목록'; + + @override + String get channels_cyr2latSettingsDscr => '문자 변환 JSON 구성 편집'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON 변환 맵'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return '잘못된 JSON: $error'; + } + @override String channels_channelUpdated(String name) { return '채널 \"$name\"이 업데이트되었습니다.'; } + @override + String get settings_cyr2latProfileAdd => 'Cyr2Lat 프로필 추가'; + + @override + String get settings_cyr2latProfileName => '프로필 이름'; + + @override + String get settings_cyr2latProfileNameEmpty => '프로필 이름은 비워둘 수 없습니다'; + + @override + String get settings_cyr2latProfileAdded => '프로필이 성공적으로 추가되었습니다'; + + @override + String get settings_cyr2latProfileUpdated => '프로필이 성공적으로 업데이트되었습니다'; + + @override + String get settings_cyr2latProfileEdit => 'Cyr2Lat 프로필 편집'; + + @override + String get settings_cyr2latProfileDelete => 'Cyr2Lat 프로필 삭제'; + + @override + String get settings_cyr2latProfileDeleted => '프로필이 성공적으로 삭제되었습니다'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return '\"$name\" 프로필을 삭제하시겠습니까?'; + } + @override String get channels_publicChannelAdded => '공개 채널 추가'; @@ -1390,6 +1447,9 @@ class AppLocalizationsKo extends AppLocalizations { @override String get chat_successes => '성공 사례'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => '경로 제거'; @@ -1485,6 +1545,12 @@ class AppLocalizationsKo extends AppLocalizations { return '읽지 않음: $count'; } + @override + String get chat_markAsUnread => '미리 읽지 않음으로 표시'; + + @override + String get chat_newMessages => '새로운 메시지'; + @override String get chat_openLink => '링크를 열기?'; @@ -1563,6 +1629,24 @@ class AppLocalizationsKo extends AppLocalizations { @override String get map_flags => '깃발'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => '여기에서 마커 공유'; @@ -1646,6 +1730,9 @@ class AppLocalizationsKo extends AppLocalizations { @override String get map_sharedPin => '공유 비밀번호'; + @override + String get map_sharedAt => '공유됨'; + @override String get map_joinRoom => '방에 참여'; @@ -2040,6 +2127,9 @@ class AppLocalizationsKo extends AppLocalizations { @override String get repeater_rxAirtime => 'RX 에어타임'; + @override + String get repeater_chanUtil => '채널 활용도'; + @override String get repeater_packetStatistics => '패킷 통계'; @@ -2240,6 +2330,153 @@ class AppLocalizationsKo extends AppLocalizations { @override String get repeater_settingsSaved => '설정이 성공적으로 저장되었습니다.'; + @override + String get repeater_rxGain => '향상된 RX 성능'; + + @override + String get repeater_rxGainHelper => + '더 높은 감도, 더 많은 전류 소모 (SX1262/SX1268에만 해당)'; + + @override + String get repeater_refreshRxGain => 'RX 성능 향상 효과 재확인'; + + @override + String get repeater_multiAcks => '다중 ACK'; + + @override + String get repeater_multiAcksSubtitle => '다양한 경로를 통해 메시지를 확인하여 전달 효율성을 높입니다.'; + + @override + String get repeater_refreshMultiAcks => '다중 ACK 재확인'; + + @override + String get repeater_networkHealth => '네트워크 상태'; + + @override + String get repeater_loopDetect => '루프 감지'; + + @override + String get repeater_loopDetectHelper => '라우팅 루프처럼 보이는 과도한 데이터 패킷을 전송'; + + @override + String get repeater_loopDetectOff => '거기'; + + @override + String get repeater_loopDetectMinimal => '최소'; + + @override + String get repeater_loopDetectModerate => '적당한'; + + @override + String get repeater_loopDetectStrict => '엄격한'; + + @override + String get repeater_dutyCycle => '작동 주기'; + + @override + String get repeater_dutyCycleHelper => '허용되는 최대 방송 시간 비율'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => '운영자 정보'; + + @override + String get repeater_ownerInfoHelper => '이 리피터에 대한 공개 메타데이터'; + + @override + String get repeater_refreshOwnerInfo => '운영자 정보 업데이트'; + + @override + String get repeater_floodMax => '최대 홉 수'; + + @override + String get repeater_floodMaxHelper => '최대 패킷이 이동할 수 있는 홉 수 (0-64)'; + + @override + String get repeater_advancedSettings => '고급'; + + @override + String get repeater_advancedSettingsSubtitle => '숙련된 운영자를 위한 조절 노브'; + + @override + String get repeater_pathHashMode => '패스 해시 모드'; + + @override + String get repeater_pathHashModeHelper => + '이 리피터의 ID를 플러드 경로/루프 감지 태그에 인코딩하는 데 사용되는 바이트 수: 0=1 바이트 (256개의 ID, 최대 64개의 홉), 1=2 바이트 (65,000개의 ID, 최대 32개의 홉), 2=3 바이트 (16백만 개의 ID, 최대 21개의 홉). v1.13 및 이전 버전의 펌웨어는 다중 바이트 경로를 지원하지 않으며, 네트워크가 v1.14 이상으로 업그레이드되면 한 번만 감지합니다.'; + + @override + String get repeater_txDelay => '플러드 TX 지연'; + + @override + String get repeater_txDelayHelper => + '홍수 시 교통량에 맞춰 재전송 간격을 설정합니다. 이는 패킷의 전송 시간을 곱한 값 (0-2, 기본값 0.5)으로 설정합니다. 값이 클수록 충돌이 줄어들지만 전송 속도가 느려집니다.'; + + @override + String get repeater_directTxDelay => '직접적인 TX 지연'; + + @override + String get repeater_directTxDelayHelper => + '직접 (대량 전송이 아닌) 트래픽에 대한 재전송 간격을, 패킷의 전송 시간을 곱하여 설정 (0-2, 기본값 0.3).'; + + @override + String get repeater_intThresh => '간섭 허용치'; + + @override + String get repeater_intThreshHelper => + '신호의 잡음 수준을 기준으로 작동하며, 이 수준 이상의 간섭은 차단합니다. 0은 비활성화 상태를 의미하며, 잡음이 심한 대역에서 RX 오류가 발생할 경우에만 활성화해야 합니다.'; + + @override + String get repeater_agcResetInterval => 'AGC 재설정 간격'; + + @override + String get repeater_agcResetIntervalHelper => + '자동 게인 제어를 재설정하여 신호가 불안정해졌을 때 원래 상태로 복구하는 빈도를 설정하는 방법은 다음과 같습니다. 4의 배수 단위로 설정하면 주기적인 재설정이 수행됩니다. 0을 설정하면 주기적인 재설정이 수행되지 않습니다.'; + + @override + String get repeater_actionsTitle => '행동'; + + @override + String get repeater_sendAdvert => '홍수 관련 광고 전송'; + + @override + String get repeater_sendAdvertSubtitle => '네트워크를 통해 홍수 광고를 방송'; + + @override + String get repeater_sendAdvertZeroHop => '제로 홉 광고 전송'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => '단일 중계 (중계 없이) 광고를 송출'; + + @override + String get repeater_clockSync => '현재 시계 동기화'; + + @override + String get repeater_clockSyncSubtitle => '스마트폰의 시간을 리피터로 설정'; + + @override + String repeater_actionSucceeded(String action) { + return '$action이 성공적으로 완료되었습니다.'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action 실패: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + '설정이 저장되었습니다. 다시 시작하여 설정을 적용하세요.'; + + @override + String repeater_settingsPartialFailure(String failures) { + return '다음 설정에 실패했습니다: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return '설정 저장 오류: $error'; @@ -2254,9 +2491,6 @@ class AppLocalizationsKo extends AppLocalizations { @override String get repeater_refreshTxPower => 'TX 전원 재설정'; - @override - String get repeater_refreshLocationSettings => '위치 설정 초기화'; - @override String get repeater_refreshPacketForwarding => '패킷 전송 재시작'; @@ -2266,9 +2500,6 @@ class AppLocalizationsKo extends AppLocalizations { @override String get repeater_refreshPrivacyMode => '개인 정보 보호 모드 재설정'; - @override - String get repeater_refreshAdvertisementSettings => '광고 설정 재설정'; - @override String repeater_refreshed(String label) { return '$label가 갱신됨'; @@ -2571,6 +2802,246 @@ class AppLocalizationsKo extends AppLocalizations { @override String get repeater_gpsNote => 'GPS 명령이 위치 관련 주제를 관리하기 위해 도입되었습니다.'; + @override + String get repeater_getCategory => '가치 얻기'; + + @override + String get repeater_powerMgmt => '전력 관리'; + + @override + String get repeater_sensors => '센서'; + + @override + String get repeater_cliHelpPowerOff => '장치를 끄는 기능 (응답이 없을 것으로 예상)'; + + @override + String get repeater_cliHelpClkReboot => '시계를 알려진 시점으로 재설정하고 장치를 재부팅합니다.'; + + @override + String get repeater_cliHelpAdvertZeroHop => '직접적인 연결 없이 이웃에게만 광고를 전송합니다.'; + + @override + String get repeater_cliHelpStartOta => '지원되는 보드에서 무선으로 펌웨어 업데이트를 시작합니다.'; + + @override + String get repeater_cliHelpTime => + '장치를 주어진 유닉스 에포크 초부터 시간으로 설정합니다. 시간은 이전으로 이동할 수 없습니다.'; + + @override + String get repeater_cliHelpBoard => '제조사/하드웨어 식별 정보를 표시합니다.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + '인접한 노드에 대한 탐색 요청을 보냅니다. (리피터만 해당)'; + + @override + String get repeater_cliHelpPowersaving => '절전 모드가 켜져 있는지 확인하는 표시'; + + @override + String get repeater_cliHelpPowersavingOnOff => + '절전 모드를 활성화하거나 비활성화할 수 있습니다 (지원되는 경우).'; + + @override + String get repeater_cliHelpErase => + '(단일 사용) 장치 파일 시스템을 포맷합니다. 모든 설정 및 연락처를 삭제합니다.'; + + @override + String get repeater_cliHelpSetDutyCycle => + '최대 허용 전송 주기(백분율)를 설정합니다(1~100%). 내부적으로 통신 시간을 조정합니다.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(시리얼 키만 해당) 장치 식별용 개인 키를 대체합니다. 적용하려면 재부팅이 필요합니다. 새로운 공개 키를 생성합니다.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(SX126x 전용) 더 높은 전류를 사용할 때 더 나은 감도를 위해 증폭된 RX 감쇠 기능을 전환합니다.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + '광고에 포함된 소유자 연락처 정보를 지정합니다. 줄 바꿈을 위해 \'|\' 문자를 사용합니다.'; + + @override + String get repeater_cliHelpSetPathHashMode => + '경로 해시 모드를 설정합니다. 0 = 고전 방식, 1 = 표준 방식, 2 = 엄격한 방식. 경로 매칭 방식에 영향을 미칩니다.'; + + @override + String get repeater_cliHelpSetLoopDetect => + '라우팅 루프 감지 감도 설정: 끄기, 최소, 중간, 또는 엄격'; + + @override + String get repeater_cliHelpSetFreq => + '(단일 기능) 특정 주파수만 빠르게 설정합니다. 재부팅이 필요합니다. 전체 라디오 파라미터 설정에는 \"라디오 설정\" 기능을 사용하는 것이 좋습니다.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(ESPNow 브리지만 해당) 브리지에서 사용되는 WiFi 채널(1~14)을 설정합니다.'; + + @override + String get repeater_cliHelpGetName => '구성된 노드의 이름을 표시합니다.'; + + @override + String get repeater_cliHelpGetRole => '펌웨어 역할(리피터, 룸 서버 등)을 보여줍니다.'; + + @override + String get repeater_cliHelpGetPublicKey => '장치의 공개 키를 표시합니다.'; + + @override + String get repeater_cliHelpGetPrvKey => '(전용) 장치의 개인 키를 표시합니다. 비밀 정보로 취급합니다.'; + + @override + String get repeater_cliHelpGetRepeat => '패킷 전달(리피터 기능)이 활성화되어 있는지 여부를 표시합니다.'; + + @override + String get repeater_cliHelpGetTx => '현재 TX 전력(dBm)을 표시합니다.'; + + @override + String get repeater_cliHelpGetFreq => '구성된 무선 주파수를 MHz 단위로 표시합니다.'; + + @override + String get repeater_cliHelpGetRadio => + '전체 무선 파라미터 표시: 주파수, 대역폭, 스프레딩 계수, 인코딩 속도'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(SX126x 전용) RX의 증폭 이득 상태를 표시합니다.'; + + @override + String get repeater_cliHelpGetAf => '현재 공기 시간 요소를 보여줍니다.'; + + @override + String get repeater_cliHelpGetDutyCycle => '현재 허용되는 작업 주기를 백분율로 표시합니다.'; + + @override + String get repeater_cliHelpGetIntThresh => '채널 간섭 임계값을 dB 단위로 표시합니다.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => 'AGC 재설정 간격을 초 단위로 표시합니다.'; + + @override + String get repeater_cliHelpGetMultiAcks => + '더블 ACK 모드가 활성화되어 있는지 (1) 또는 비활성화되어 있는지 (0)를 표시합니다.'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + '게스트의 읽기 전용 액세스가 허용되는지 여부를 표시합니다.'; + + @override + String get repeater_cliHelpGetAdvertInterval => '지역 광고 시간 간격을 분 단위로 표시합니다.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + '홍수 광고 시간 간격을 시간 단위로 표시합니다.'; + + @override + String get repeater_cliHelpGetGuestPassword => '구성된 게스트 비밀번호를 표시합니다.'; + + @override + String get repeater_cliHelpGetLat => '설정된 위도를 보여줍니다.'; + + @override + String get repeater_cliHelpGetLon => '설정된 경도를 보여줍니다.'; + + @override + String get repeater_cliHelpGetRxDelay => 'Rxdelay 기본 값을 표시합니다.'; + + @override + String get repeater_cliHelpGetTxDelay => '홍수 모드에서의 전송 지연 계수를 보여줍니다.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => '직렬 모드에서의 딜레이 계수를 보여줍니다.'; + + @override + String get repeater_cliHelpGetFloodMax => '최대 홍수 발생 횟수를 보여줍니다.'; + + @override + String get repeater_cliHelpGetOwnerInfo => '소유주 연락처 정보를 표시합니다.'; + + @override + String get repeater_cliHelpGetPathHashMode => '경로 해시 모드 (0/1/2)를 표시합니다.'; + + @override + String get repeater_cliHelpGetLoopDetect => '루프 탐지 감도를 보여줍니다.'; + + @override + String get repeater_cliHelpGetAcl => + '(단순히 목록만 표시) 리피터에 설정된 접근 제어 항목 목록을 보여줍니다.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => '다리 기능이 활성화되어 있는지 여부를 표시합니다.'; + + @override + String get repeater_cliHelpGetBridgeDelay => '다리 통과 시간(밀리초)을 표시합니다.'; + + @override + String get repeater_cliHelpGetBridgeSource => + '브리지 로그가 RX 또는 TX 패킷을 기록하는지 여부를 보여줍니다.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(RS232 브리지 기능만) 브리지의 보드 속도를 표시합니다.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(ESPNow 브리지만 해당) 브리지의 Wi-Fi 채널을 표시합니다.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(ESPNow 브리지만 해당) 브리지에서 공유된 비밀을 표시합니다.'; + + @override + String get repeater_cliHelpGetBootloaderVer => '(NRF52만 해당) 부팅 로더 버전을 표시합니다.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + '배터리 전압을 스케일링하는 ADC 멀티플라이어를 보여줍니다.'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + '이 보드가 전력 관리 기능을 지원하는지 여부를 나타냅니다.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + '현재 전원 공급 장치 (외부 전원 또는 배터리)를 표시합니다.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => '가장 최근 재설정 및 종료 이유를 보여줍니다.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => '부팅 시 배터리 전압을 mV 단위로 표시합니다.'; + + @override + String get repeater_cliHelpSensorGet => '키를 사용하여 사용자 정의 센서 설정을 읽습니다.'; + + @override + String get repeater_cliHelpSensorSet => '사용자 정의 센서 설정을 작성합니다.'; + + @override + String get repeater_cliHelpSensorList => + '사용자 정의 센서 설정 목록을, 선택적으로 지정된 시작 인덱스부터 페이지 나누어 표시합니다.'; + + @override + String get repeater_cliHelpRegionDefault => '현재 기본 지역 범위를 보여줍니다.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + '기본 지역 범위를 설정합니다. \"\"을 사용하여 초기화합니다.'; + + @override + String get repeater_cliHelpRegionListAllowed => '홍수 피해 차량 통행이 가능한 지역 목록'; + + @override + String get repeater_cliHelpRegionListDenied => '홍수 발생 시 통행 금지 지역 목록'; + + @override + String get repeater_cliHelpStatsPackets => '(전송 속도만 표시) 패킷 수준의 통계 정보를 보여줍니다.'; + + @override + String get repeater_cliHelpStatsRadio => '(특정 시리즈만 해당) 라디오 통계 정보를 표시합니다.'; + + @override + String get repeater_cliHelpStatsCore => '(시리얼 번호만 표시) 핵심 펌웨어 통계 정보를 보여줍니다.'; + @override String get telemetry_receivedData => '수신된 통신 데이터'; @@ -3092,6 +3563,36 @@ class AppLocalizationsKo extends AppLocalizations { @override String get losLegendTerrain => '지형'; + @override + String get losBlockedSpotsTitle => '차단된 공간'; + + @override + String get losBlockedSpotsHint => '지도에서 특정 위치를 강조하려면 해당 위치를 클릭하세요.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => '선택된 장애물'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => '빈도'; @@ -3527,4 +4028,40 @@ class AppLocalizationsKo extends AppLocalizations { @override String get translation_systemLanguage => '시스템 언어'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index dd770e1..ad140bf 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -24,7 +24,7 @@ class AppLocalizationsNl extends AppLocalizations { String get common_cancel => 'Annuleren'; @override - String get common_ok => 'OK'; + String get common_ok => 'Prima'; @override String get common_connect => 'Verbinden'; @@ -44,6 +44,9 @@ class AppLocalizationsNl extends AppLocalizations { @override String get common_close => 'Sluiten'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Bewerken'; @@ -271,7 +274,7 @@ class AppLocalizationsNl extends AppLocalizations { String get scanner_stop => 'Stoppen'; @override - String get scanner_scan => 'Scan'; + String get scanner_scan => 'Scannen'; @override String get scanner_bluetoothOff => 'Bluetooth is uitgeschakeld'; @@ -379,7 +382,7 @@ class AppLocalizationsNl extends AppLocalizations { 'Instellingen voor het toevoegen van contacten'; @override - String get settings_privacyMode => 'Privacy Mode'; + String get settings_privacyMode => 'Privacy-modus'; @override String get settings_privacyModeSubtitle => @@ -432,9 +435,7 @@ class AppLocalizationsNl extends AppLocalizations { 'Locatie opnemen in advertentie'; @override - String settings_multiAck(String value) { - return 'Multi-ACKs: $value'; - } + String get settings_multiAck => 'Meerdere bevestigingen'; @override String get settings_telemetryModeUpdated => 'Telemetrie-modus bijgewerkt'; @@ -442,6 +443,13 @@ class AppLocalizationsNl extends AppLocalizations { @override String get settings_actions => 'Acties'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Verzend Advertentie'; @@ -479,17 +487,18 @@ class AppLocalizationsNl extends AppLocalizations { 'Ben je er zeker van dat je het apparaat opnieuw wilt opstarten? Je wordt losgekoppeld.'; @override - String get settings_debug => 'Debug'; + String get settings_debug => 'Foutopsporing'; @override - String get settings_bleDebugLog => 'BLE Debug Log'; + String get settings_companionDebugLog => + 'Debuglog voor aanvullende informatie'; @override - String get settings_bleDebugLogSubtitle => - 'BLE commando\'s, antwoorden en ruwe data'; + String get settings_companionDebugLogSubtitle => + 'BLE/TCP/USB commando\'s, antwoorden en ruwe data'; @override - String get settings_appDebugLog => 'App Debug Log'; + String get settings_appDebugLog => 'Debuglog van de app'; @override String get settings_appDebugLogSubtitle => 'Toepassingsdebugberichten'; @@ -499,7 +508,7 @@ class AppLocalizationsNl extends AppLocalizations { @override String settings_aboutVersion(String version) { - return 'MeshCore Open v$version'; + return 'MeshCore Open versie $version'; } @override @@ -535,7 +544,7 @@ class AppLocalizationsNl extends AppLocalizations { String get settings_infoChannelCount => 'Aantal Kanalen'; @override - String get settings_presets => 'Presets'; + String get settings_presets => 'Voorgeprogrammeerde instellingen'; @override String get settings_frequency => 'Frequentie (MHz)'; @@ -605,43 +614,43 @@ class AppLocalizationsNl extends AppLocalizations { String get appSettings_languageSystem => 'Standaardinstelling'; @override - String get appSettings_languageEn => 'English'; + String get appSettings_languageEn => 'Engels'; @override - String get appSettings_languageFr => 'Français'; + String get appSettings_languageFr => 'Frans'; @override - String get appSettings_languageEs => 'Español'; + String get appSettings_languageEs => 'Spaans'; @override - String get appSettings_languageDe => 'Deutsch'; + String get appSettings_languageDe => 'Duits'; @override - String get appSettings_languagePl => 'Polski'; + String get appSettings_languagePl => 'Pools'; @override - String get appSettings_languageSl => 'Slovenščina'; + String get appSettings_languageSl => 'Sloveens'; @override - String get appSettings_languagePt => 'Português'; + String get appSettings_languagePt => 'Portugees'; @override - String get appSettings_languageIt => 'Italiano'; + String get appSettings_languageIt => 'Italiaans'; @override - String get appSettings_languageZh => '中文'; + String get appSettings_languageZh => 'Chinees'; @override - String get appSettings_languageSv => 'Svenska'; + String get appSettings_languageSv => 'Zweeds'; @override String get appSettings_languageNl => 'Nederlands'; @override - String get appSettings_languageSk => 'Slovenčina'; + String get appSettings_languageSk => 'Sloveens'; @override - String get appSettings_languageBg => 'Български'; + String get appSettings_languageBg => 'Bulgaars'; @override String get appSettings_languageRu => 'Russisch'; @@ -878,7 +887,7 @@ class AppLocalizationsNl extends AppLocalizations { } @override - String get appSettings_debugCard => 'Debug'; + String get appSettings_debugCard => 'Foutopsporing'; @override String get appSettings_appDebugLogging => 'App Debuggen Loggen'; @@ -960,7 +969,7 @@ class AppLocalizationsNl extends AppLocalizations { String get contacts_roomLogin => 'Ruimte Inloggen'; @override - String get contacts_openChat => 'Open Chat'; + String get contacts_openChat => 'Open gesprek'; @override String get contacts_editGroup => 'Groep bewerken'; @@ -1078,20 +1087,16 @@ class AppLocalizationsNl extends AppLocalizations { return 'Kanaal $index'; } - @override - String get channels_hashtagChannel => 'Hashtag kanaal'; - @override String get channels_public => 'Openbaar'; @override - String get channels_private => 'Privé'; - - @override - String get channels_publicChannel => 'Open kanaal'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Private kanaal'; + String get channels_private => 'Privé'; @override String get channels_editChannel => 'Kanaal bewerken'; @@ -1161,11 +1166,66 @@ class AppLocalizationsNl extends AppLocalizations { @override String get channels_smazCompression => 'SMAZ compressie'; + @override + String get channels_cyr2latCompression => 'Cyr2Lat compressie'; + + @override + String get channels_cyr2latCompressionDscr => + 'Vervangt sommige Cyrillische tekens door Latijnse tekens bij het verzenden.'; + + @override + String get channels_cyr2latSettingsHeading => 'Instellingen Cyr2Lat'; + + @override + String get channels_cyr2latSettingsSubheading => 'Lijst met vervangingen'; + + @override + String get channels_cyr2latSettingsDscr => + 'Bewerk de JSON-configuratie voor tekenvervanging'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON-vervangingskaart'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'Onjuiste JSON: $error'; + } + @override String channels_channelUpdated(String name) { return 'Kanaal \"$name\" is bijgewerkt'; } + @override + String get settings_cyr2latProfileAdd => 'Cyr2Lat-profiel toevoegen'; + + @override + String get settings_cyr2latProfileName => 'Profielnaam'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'Profielnaam mag niet leeg zijn'; + + @override + String get settings_cyr2latProfileAdded => 'Profiel succesvol toegevoegd'; + + @override + String get settings_cyr2latProfileUpdated => 'Profiel succesvol bijgewerkt'; + + @override + String get settings_cyr2latProfileEdit => 'Cyr2Lat-profiel bewerken'; + + @override + String get settings_cyr2latProfileDelete => 'Cyr2Lat-profiel verwijderen'; + + @override + String get settings_cyr2latProfileDeleted => 'Profiel succesvol verwijderd'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Weet u zeker dat u het profiel \"$name\" wilt verwijderen?'; + } + @override String get channels_publicChannelAdded => 'Open kanaal toegevoegd'; @@ -1176,7 +1236,7 @@ class AppLocalizationsNl extends AppLocalizations { String get channels_sortManual => 'Handmatig'; @override - String get channels_sortAZ => 'A-Z'; + String get channels_sortAZ => 'Alfabetisch'; @override String get channels_sortLatestMessages => 'Recent berichten'; @@ -1322,7 +1382,7 @@ class AppLocalizationsNl extends AppLocalizations { String get gifPicker_noInternet => 'Geen internetverbinding'; @override - String get debugLog_appTitle => 'App Debug Log'; + String get debugLog_appTitle => 'Debuglog van de app'; @override String get debugLog_bleTitle => 'BLE Debug Log'; @@ -1350,7 +1410,7 @@ class AppLocalizationsNl extends AppLocalizations { String get debugLog_frames => 'Ramen'; @override - String get debugLog_rawLogRx => 'Raw Log-RX'; + String get debugLog_rawLogRx => 'Niet-verwerkt Log-RX'; @override String get debugLog_noBleActivity => 'Geen BLE-activiteit nog.'; @@ -1400,7 +1460,7 @@ class AppLocalizationsNl extends AppLocalizations { } @override - String get debugFrame_hexDump => 'Hex Dump:'; + String get debugFrame_hexDump => 'Hex-dump:'; @override String get chat_pathManagement => 'Beheer van Paden'; @@ -1444,6 +1504,9 @@ class AppLocalizationsNl extends AppLocalizations { @override String get chat_successes => 'Succesvol'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Pad verwijderen'; @@ -1532,7 +1595,7 @@ class AppLocalizationsNl extends AppLocalizations { } @override - String get chat_floodAuto => 'Flood (auto)'; + String get chat_floodAuto => 'Overstroming (van een auto)'; @override String get chat_direct => 'Direct'; @@ -1545,6 +1608,12 @@ class AppLocalizationsNl extends AppLocalizations { return 'Nieuw: $count'; } + @override + String get chat_markAsUnread => 'Markeer als ongelezen'; + + @override + String get chat_newMessages => 'Nieuwe berichten'; + @override String get chat_openLink => 'Link openen?'; @@ -1564,7 +1633,7 @@ class AppLocalizationsNl extends AppLocalizations { String get chat_invalidLink => 'Ongeldig linkformaat'; @override - String get map_title => 'Node Map'; + String get map_title => 'Kaart van de knopen'; @override String get map_lineOfSight => 'Zichtlijn'; @@ -1581,7 +1650,7 @@ class AppLocalizationsNl extends AppLocalizations { @override String map_nodesCount(int count) { - return 'Nodes: $count'; + return 'Knooppunten: $count'; } @override @@ -1593,7 +1662,7 @@ class AppLocalizationsNl extends AppLocalizations { String get map_chat => 'Chat'; @override - String get map_repeater => 'Repeater'; + String get map_repeater => 'Herhaald'; @override String get map_room => 'Ruimte'; @@ -1626,6 +1695,24 @@ class AppLocalizationsNl extends AppLocalizations { @override String get map_flags => 'Vlaggen'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'Deel marker hier'; @@ -1636,7 +1723,7 @@ class AppLocalizationsNl extends AppLocalizations { String get map_pinLabel => 'Label vastzetten'; @override - String get map_label => 'Label'; + String get map_label => 'Etiket'; @override String get map_pointOfInterest => 'Interessepunt'; @@ -1663,7 +1750,7 @@ class AppLocalizationsNl extends AppLocalizations { 'Verbind met een apparaat om markers te delen'; @override - String get map_filterNodes => 'Filter Nodes'; + String get map_filterNodes => 'Filternodes'; @override String get map_nodeTypes => 'Nodetypes'; @@ -1672,7 +1759,7 @@ class AppLocalizationsNl extends AppLocalizations { String get map_chatNodes => 'Chatnodes'; @override - String get map_repeaters => 'Repeaters'; + String get map_repeaters => 'Herhaalders'; @override String get map_otherNodes => 'Andere Nodes'; @@ -1711,6 +1798,9 @@ class AppLocalizationsNl extends AppLocalizations { @override String get map_sharedPin => 'Gedeelde pin'; + @override + String get map_sharedAt => 'Gedeeld'; + @override String get map_joinRoom => 'Kamer Toetreden'; @@ -1753,7 +1843,7 @@ class AppLocalizationsNl extends AppLocalizations { } @override - String get mapCache_downloadAction => 'Download'; + String get mapCache_downloadAction => 'Downloaden'; @override String mapCache_cachedTiles(int count) { @@ -1901,7 +1991,7 @@ class AppLocalizationsNl extends AppLocalizations { 'Voer het wachtwoord van de kamer in om toegang te krijgen tot instellingen en status.'; @override - String get login_routing => 'Routing'; + String get login_routing => 'Routeplanning'; @override String get login_routingMode => 'Routeerwijze'; @@ -2023,7 +2113,7 @@ class AppLocalizationsNl extends AppLocalizations { 'Status, statistieken en buren bekijken'; @override - String get repeater_telemetry => 'Telemetry'; + String get repeater_telemetry => 'Telemetrie'; @override String get repeater_telemetrySubtitle => @@ -2118,6 +2208,9 @@ class AppLocalizationsNl extends AppLocalizations { @override String get repeater_rxAirtime => 'RX-zendtijd'; + @override + String get repeater_chanUtil => 'Gebruik van het kanaal'; + @override String get repeater_packetStatistics => 'Pakketstatistieken'; @@ -2152,7 +2245,7 @@ class AppLocalizationsNl extends AppLocalizations { @override String repeater_duplicatesFloodDirect(String flood, String direct) { - return 'Flood: $flood, Direct: $direct'; + return 'Overstroming: $flood, Direct: $direct'; } @override @@ -2326,6 +2419,164 @@ class AppLocalizationsNl extends AppLocalizations { @override String get repeater_settingsSaved => 'Instellingen succesvol opgeslagen'; + @override + String get repeater_rxGain => 'Verhoogde RX-uitgang'; + + @override + String get repeater_rxGainHelper => + 'Hogere gevoeligheid, grotere stroomverbruik (alleen voor SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => + 'Versterk de reeds bestaande RX-verbetering.'; + + @override + String get repeater_multiAcks => 'Meerdere bevestigingen'; + + @override + String get repeater_multiAcksSubtitle => + 'Bevestig berichten via verschillende routes voor een betere levering.'; + + @override + String get repeater_refreshMultiAcks => 'Herhaal meerdere bevestigingen'; + + @override + String get repeater_networkHealth => 'Netwerkgezondheid'; + + @override + String get repeater_loopDetect => 'Detectie van beweging'; + + @override + String get repeater_loopDetectHelper => + 'Verzend pakketten die eruitzien als routing-lusjes'; + + @override + String get repeater_loopDetectOff => 'Af'; + + @override + String get repeater_loopDetectMinimal => 'Minimaal'; + + @override + String get repeater_loopDetectModerate => 'Matig'; + + @override + String get repeater_loopDetectStrict => 'Strikte'; + + @override + String get repeater_dutyCycle => 'Werkcyclus'; + + @override + String get repeater_dutyCycleHelper => + 'Maximale percentage van de beschikbare uitzendtijd'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Informatie over de operator'; + + @override + String get repeater_ownerInfoHelper => 'Openbare metadata voor deze repeater'; + + @override + String get repeater_refreshOwnerInfo => 'Herstel informatie over de operator'; + + @override + String get repeater_floodMax => 'Maximale hoeveelheid hop'; + + @override + String get repeater_floodMaxHelper => + 'Maximale hoeveelheid hop die een pakket kan bevatten (0-64)'; + + @override + String get repeater_advancedSettings => 'Geavanceerd'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Regelhendels voor ervaren gebruikers'; + + @override + String get repeater_pathHashMode => 'Hash-modus voor paden'; + + @override + String get repeater_pathHashModeHelper => + 'Bytes die gebruikt worden om de ID van deze repeater te coderen in flood-pad/lusdetectietags. 0=1 byte (256 ID\'s, tot 64 hops), 1=2 bytes (65.000 ID\'s, tot 32 hops), 2=3 bytes (16 miljoen ID\'s, tot 21 hops). Versies 1.13 en ouder gebruiken multi-byte paden – alleen na het activeren van het netwerk.'; + + @override + String get repeater_txDelay => 'Vertraging bij Flood TX'; + + @override + String get repeater_txDelayHelper => + 'Herzendinterval voor verkeer tijdens overstromingen, als een veelvoud van de tijd die het pakket nodig heeft (0-2, standaard 0.5). Een hoger getal betekent minder botsingen, maar ook een langere leveringstijd.'; + + @override + String get repeater_directTxDelay => 'Directe vertraging'; + + @override + String get repeater_directTxDelayHelper => + 'De overzending van tijdslots voor directe (niet-massaal) verkeer, als een vermenigvuldigingsfactor van de tijd die een pakket nodig heeft (0-2, standaard 0,3).'; + + @override + String get repeater_intThresh => 'Grenswaarde voor interferentie'; + + @override + String get repeater_intThreshHelper => + 'De drempelwaarde is ingesteld zodat de radio storingen boven deze waarde kan detecteren en blokkeren. 0 staat voor \"uitgezet\" – alleen verhoog deze waarde als u fouten in een storingrijke band ziet.'; + + @override + String get repeater_agcResetInterval => + 'Interval voor het opnieuw instellen van AGC'; + + @override + String get repeater_agcResetIntervalHelper => + 'Hoe vaak moet u de automatische gainregeling van de radio opnieuw instellen om terug te keren van een situatie waarin de gain vastzit? Elke seconde, of elke 4e seconde. Het uitschakelen van de periodieke reset (0) zorgt ervoor dat de gain niet automatisch wordt aangepast.'; + + @override + String get repeater_actionsTitle => 'Acties'; + + @override + String get repeater_sendAdvert => 'Verzend advertentie over overstromingen'; + + @override + String get repeater_sendAdvertSubtitle => + 'Zend een advertentie over overstromingen uit via het netwerk.'; + + @override + String get repeater_sendAdvertZeroHop => + 'Verzend een advertentie zonder tussenliggende stap'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Zend een advertentie met één enkele verbinding (zonder tussenliggende zenders).'; + + @override + String get repeater_clockSync => 'Synchroniseer klok nu'; + + @override + String get repeater_clockSyncSubtitle => + 'Stel de tijd van je telefoon in op de repeater.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action is gelukt'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action failed: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Instellingen opgeslagen – start de zender opnieuw om de wijzigingen toe te passen.'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Sommige instellingen zijn niet correct uitgevoerd: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Fout bij het opslaan van de instellingen: $error'; @@ -2341,10 +2592,6 @@ class AppLocalizationsNl extends AppLocalizations { @override String get repeater_refreshTxPower => 'Nieuw laden TX-vermogen'; - @override - String get repeater_refreshLocationSettings => - 'Instellingen Locatie Vernieuwen'; - @override String get repeater_refreshPacketForwarding => 'Vernieuwen Pakket Doorversturing'; @@ -2355,10 +2602,6 @@ class AppLocalizationsNl extends AppLocalizations { @override String get repeater_refreshPrivacyMode => 'Privacymode vernieuwen'; - @override - String get repeater_refreshAdvertisementSettings => - 'Instellingen Advertentie Bijwerken'; - @override String repeater_refreshed(String label) { return '$label is vernieuwd'; @@ -2370,7 +2613,7 @@ class AppLocalizationsNl extends AppLocalizations { } @override - String get repeater_cliTitle => 'Repeater CLI'; + String get repeater_cliTitle => 'CLI-interface voor de repeater'; @override String get repeater_debugNextCommand => 'Debug Volgende Commando'; @@ -2662,7 +2905,7 @@ class AppLocalizationsNl extends AppLocalizations { String get repeater_bridge => 'Bruggen'; @override - String get repeater_logging => 'Logging'; + String get repeater_logging => 'Loggen'; @override String get repeater_neighborsRepeaterOnly => 'Buren (Alleen repeaters)'; @@ -2682,6 +2925,283 @@ class AppLocalizationsNl extends AppLocalizations { String get repeater_gpsNote => 'De GPS-commando is geïntroduceerd om locatiegerelateerde onderwerpen te beheren.'; + @override + String get repeater_getCategory => 'Waarden verkrijgen'; + + @override + String get repeater_powerMgmt => 'Energiebeheer'; + + @override + String get repeater_sensors => 'Sensoren'; + + @override + String get repeater_cliHelpPowerOff => + 'Zorgt ervoor dat het apparaat wordt uitgeschakeld. (geen reactie verwacht)'; + + @override + String get repeater_cliHelpClkReboot => + 'Stelt de klok terug naar een bekende tijd en start het apparaat opnieuw op.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Verstuurt een advertentie die alleen naar directe buren wordt gericht (geen tussenliggende stops).'; + + @override + String get repeater_cliHelpStartOta => + 'Start een firmware-update via de lucht op ondersteunde boards.'; + + @override + String get repeater_cliHelpTime => + 'Stelt de klok van het apparaat in op de gegeven Unix-tijd (aantal seconden vanaf de Unix-epoch). De klok kan niet teruggedraaid worden.'; + + @override + String get repeater_cliHelpBoard => + 'Geeft de fabrikant van het bord en/of de hardware-identificatie weer.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Stuurt een verzoek om buren in de buurt te ontdekken. (Alleen van toepassing op een repeater)'; + + @override + String get repeater_cliHelpPowersaving => + 'Geeft aan of de energiebesparingsmodus is ingeschakeld of uitgeschakeld.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Activeert of deactiveert de energiebesparingsmodus (indien ondersteund).'; + + @override + String get repeater_cliHelpErase => + '(Alleen voor seriële verbindingen) Formateert het bestandssysteem van het apparaat. Verwijdert alle instellingen en contacten.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Stelt het maximale toegestane transmissiepercentage in (in procenten, 1-100). Past intern de tijdsschaal aan.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Alleen voor seriële toepassingen) Vervangt de private sleutel van het apparaat. Een herstart is vereist om deze wijziging toe te passen. Genereert een nieuwe publieke sleutel.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(Alleen voor SX126x-chips) Schakelt de versterkte RX-gain in om de gevoeligheid te verbeteren bij een hoger stroomverbruik.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Definieert de string met contactgegevens van de eigenaar, die in de advertenties wordt opgenomen. Gebruik \'|\' voor nieuwe regels.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Stelt de modus voor het berekenen van de hash van de route in. 0 = voorheen, 1 = standaard, 2 = strikt. Beïnvloedt hoe de routes worden gematched.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Stelt de gevoeligheid voor het detecteren van een lus in de routing in: uit, minimaal, matig of strikt.'; + + @override + String get repeater_cliHelpSetFreq => + '(Alleen voor seriële communicatie) Stelt snel alleen de frequentie in. Herstart is vereist. Het is aan te raden om \"radio instellingen\" te gebruiken voor alle radioparameters.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Alleen voor ESPNow-brug) Stelt het WiFi-kanaal (1-14) in dat door de brug wordt gebruikt.'; + + @override + String get repeater_cliHelpGetName => + 'Toont de naam van de geconfigureerde knoop.'; + + @override + String get repeater_cliHelpGetRole => + 'Geeft de rol van de firmware aan (herhaald, server voor een kamer, enz.).'; + + @override + String get repeater_cliHelpGetPublicKey => + 'Toont het openbare sleutel van het apparaat.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Alleen voor seriële communicatie) Toont de private sleutel van het apparaat. Behandel dit als een geheim.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Geeft aan of het doorsturen van pakketten (als repeater) is ingeschakeld of uitgeschakeld.'; + + @override + String get repeater_cliHelpGetTx => 'Toont de huidige zendvermogen in dBm.'; + + @override + String get repeater_cliHelpGetFreq => + 'Toont de geconfigureerde frequentie in MHz.'; + + @override + String get repeater_cliHelpGetRadio => + 'Geeft alle radioparameters weer: frequentie, bandbreedte, spreidfactor, codegraad.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(Alleen voor SX126x-chips) Toont de status van de versterking van de RX-ontvangst.'; + + @override + String get repeater_cliHelpGetAf => 'Geeft de huidige tijdsfactor weer.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Toont de huidige toegestane duty cycle als een percentage.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Toont het drempelwaarde voor signaalinterferentie in dB.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Geeft het interval in seconden aan voor het resetten van de AGC (Automatic Gain Control).'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Geeft aan of de modus \"dubbele bevestiging\" is ingeschakeld (1) of uitgeschakeld (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Geeft aan of er toegang is voor gastgebruikers zonder rechten.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Geeft de duur van de lokale reclame in minuten aan.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Geeft de duur van de reclame-interval in uren aan.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Toont het ingestelde gastwachtwoord.'; + + @override + String get repeater_cliHelpGetLat => 'Toont de ingestelde breedtegraad.'; + + @override + String get repeater_cliHelpGetLon => 'Toont de ingestelde lengtegraad.'; + + @override + String get repeater_cliHelpGetRxDelay => + 'Toont de basiswaarde van de rx-vertraging.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Geeft de factor weer die de vertraging in de flood-modus bepaalt.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Geeft de factor voor de vertraging in de directe modus weer.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Toont het maximale aantal keer dat een overstroming heeft plaatsgevonden.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Toont de string met contactgegevens van de eigenaar.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Toont de modus voor het berekenen van de hash (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Geeft de gevoeligheid voor het detecteren van lusvorming weer.'; + + @override + String get repeater_cliHelpGetAcl => + '(Alleen voor seriële communicatie) Geeft de toegangscontroles weer op een repeater.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Geeft aan of de brug is ingeschakeld.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Geeft de vertraging van de brug in milliseconden weer.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Geeft aan of de brug RX- of TX-pakketten verwerkt.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Alleen RS232-brug) Toont de baud-snelheid van de brug.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Alleen voor ESPNow-brug) Toont het WiFi-kanaal van de brug.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Alleen voor ESPNow-brug) Toont het gedeelde geheime sleutel.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(Alleen voor NRF52) Toont de versie van de bootloader.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Toont de ADC-vermenigvuldiging (schalen van de batterijspanning).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Geeft aan of het bestuur ondersteuning heeft voor het beheer van energieverbruik.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Geeft de huidige stroombron aan: extern of batterij.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Geeft de meest recente redenen voor het opnieuw opstarten en afsluiten weer.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Geeft de batterijspanning in mV weer, direct na het opstarten.'; + + @override + String get repeater_cliHelpSensorGet => + 'Leest een aangepaste sensorgegevens op basis van een sleutel.'; + + @override + String get repeater_cliHelpSensorSet => + 'Maakt een aangepaste instelling voor een sensor.'; + + @override + String get repeater_cliHelpSensorList => + 'Toont alle aangepaste instellingen voor sensoren, gegroepeerd op basis van een optionele startindex.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Toont het huidige standaard regio-bereik.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Stelt de standaard regio-omvang in. Gebruik \"\" om deze te resetten.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Lijst van gebieden waar doorstromen tijdens overstromingen is toegestaan.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Geeft een lijst van regio\'s die het verkeer tijdens overstromingen verbieden.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Alleen voor seriële verbindingen) Toont statistieken op pakketniveau.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Alleen voor serienummers) Toont radio-statistieken.'; + + @override + String get repeater_cliHelpStatsCore => + '(Alleen voor seriële communicatie) Toont de belangrijkste firmware-statistieken.'; + @override String get telemetry_receivedData => 'Ontvangen Telemetriedata'; @@ -2774,7 +3294,7 @@ class AppLocalizationsNl extends AppLocalizations { String get channelPath_otherObservedPaths => 'Overige Waargenomen Paden'; @override - String get channelPath_repeaterHops => 'Repeater Hops'; + String get channelPath_repeaterHops => 'Herhaalde sprongen'; @override String get channelPath_noHopDetails => @@ -2790,7 +3310,7 @@ class AppLocalizationsNl extends AppLocalizations { String get channelPath_timeLabel => 'Tijd'; @override - String get channelPath_repeatsLabel => 'Repeats'; + String get channelPath_repeatsLabel => 'Herhaalt'; @override String channelPath_pathLabel(int index) { @@ -2822,7 +3342,7 @@ class AppLocalizationsNl extends AppLocalizations { String get channelPath_unknownPath => 'Onbekend'; @override - String get channelPath_floodPath => 'Flood'; + String get channelPath_floodPath => 'Overstroming'; @override String get channelPath_directPath => 'Direct'; @@ -3051,7 +3571,7 @@ class AppLocalizationsNl extends AppLocalizations { String get listFilter_heardRecently => 'Recent gezien'; @override - String get listFilter_az => 'A-Z'; + String get listFilter_az => 'Alfabetisch'; @override String get listFilter_filters => 'Filters'; @@ -3072,7 +3592,7 @@ class AppLocalizationsNl extends AppLocalizations { String get listFilter_users => 'Gebruikers'; @override - String get listFilter_repeaters => 'Repeaters'; + String get listFilter_repeaters => 'Herhalers'; @override String get listFilter_roomServers => 'Roomservers'; @@ -3222,6 +3742,37 @@ class AppLocalizationsNl extends AppLocalizations { @override String get losLegendTerrain => 'Terrein'; + @override + String get losBlockedSpotsTitle => 'Geplande plaatsen'; + + @override + String get losBlockedSpotsHint => + 'Tik op een geblokkeerd gebied om het op de kaart te markeren.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Geselecteerde obstakel'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Frequentie'; @@ -3251,7 +3802,7 @@ class AppLocalizationsNl extends AppLocalizations { String get contacts_repeaterPathTrace => 'Pad traceren naar repeater'; @override - String get contacts_repeaterPing => 'Ping repeater'; + String get contacts_repeaterPing => 'Ping-repeater'; @override String get contacts_roomPathTrace => 'Padtrace naar room server'; @@ -3264,7 +3815,7 @@ class AppLocalizationsNl extends AppLocalizations { @override String contacts_pathTraceTo(String name) { - return 'Trace route to $name'; + return 'Volg de route naar $name'; } @override @@ -3686,4 +4237,40 @@ class AppLocalizationsNl extends AppLocalizations { @override String get translation_systemLanguage => 'Taal van het systeem'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_pl.dart b/lib/l10n/app_localizations_pl.dart index 357dd7e..6c7c369 100644 --- a/lib/l10n/app_localizations_pl.dart +++ b/lib/l10n/app_localizations_pl.dart @@ -24,7 +24,7 @@ class AppLocalizationsPl extends AppLocalizations { String get common_cancel => 'Anuluj'; @override - String get common_ok => 'OK'; + String get common_ok => 'Dobrze'; @override String get common_connect => 'Połącz'; @@ -44,6 +44,9 @@ class AppLocalizationsPl extends AppLocalizations { @override String get common_close => 'Zamknij'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Edytuj'; @@ -109,7 +112,7 @@ class AppLocalizationsPl extends AppLocalizations { } @override - String get scanner_title => 'MeshCore Open'; + String get scanner_title => 'MeshCore – wersja open source'; @override String get connectionChoiceUsbLabel => 'USB'; @@ -439,9 +442,7 @@ class AppLocalizationsPl extends AppLocalizations { 'Uwzględnij lokalizację w ogłoszeniu'; @override - String settings_multiAck(String value) { - return 'Wielokrotne ACK: $value'; - } + String get settings_multiAck => 'Wielokrotne potwierdzenia odbioru'; @override String get settings_telemetryModeUpdated => @@ -450,6 +451,13 @@ class AppLocalizationsPl extends AppLocalizations { @override String get settings_actions => 'Działania'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Wyślij rozgłoszenie'; @@ -487,14 +495,15 @@ class AppLocalizationsPl extends AppLocalizations { 'Czy na pewno chcesz zrestartować urządzenie? Będziesz odłączony.'; @override - String get settings_debug => 'Debug'; + String get settings_debug => 'Naprawianie błędów'; @override - String get settings_bleDebugLog => 'Dziennik debugowania BLE'; + String get settings_companionDebugLog => + 'Log debugowania (dla pomocy w rozwiązywaniu problemów)'; @override - String get settings_bleDebugLogSubtitle => - 'Polecenia BLE, odpowiedzi i surowe dane'; + String get settings_companionDebugLogSubtitle => + 'Polecenia, odpowiedzi i surowe dane związane z protokołami BLE/TCP/USB'; @override String get settings_appDebugLog => 'Dziennik debugowania aplikacji'; @@ -507,7 +516,7 @@ class AppLocalizationsPl extends AppLocalizations { @override String settings_aboutVersion(String version) { - return 'MeshCore Open v$version'; + return 'MeshCore Open w wersji $version'; } @override @@ -528,7 +537,7 @@ class AppLocalizationsPl extends AppLocalizations { String get settings_infoId => 'ID'; @override - String get settings_infoStatus => 'Status'; + String get settings_infoStatus => 'Stan'; @override String get settings_infoBattery => 'Bateria'; @@ -568,7 +577,7 @@ class AppLocalizationsPl extends AppLocalizations { String get settings_txPower => 'Moc TX (dBm)'; @override - String get settings_txPowerHelper => '0 - 22'; + String get settings_txPowerHelper => '0 – 22'; @override String get settings_txPowerInvalid => 'Nieprawidłowa moc TX (0-22 dBm)'; @@ -614,43 +623,43 @@ class AppLocalizationsPl extends AppLocalizations { String get appSettings_languageSystem => 'Domyślny systemowy'; @override - String get appSettings_languageEn => 'English'; + String get appSettings_languageEn => 'Angielski'; @override - String get appSettings_languageFr => 'Français'; + String get appSettings_languageFr => 'Francuski'; @override - String get appSettings_languageEs => 'Español'; + String get appSettings_languageEs => 'Hiszpański'; @override - String get appSettings_languageDe => 'Deutsch'; + String get appSettings_languageDe => 'Niemiecki'; @override String get appSettings_languagePl => 'Polski'; @override - String get appSettings_languageSl => 'Slovenščina'; + String get appSettings_languageSl => 'Słoweński'; @override - String get appSettings_languagePt => 'Português'; + String get appSettings_languagePt => 'Portugalski'; @override - String get appSettings_languageIt => 'Italiano'; + String get appSettings_languageIt => 'Włoski'; @override - String get appSettings_languageZh => '中文'; + String get appSettings_languageZh => 'Chiński'; @override - String get appSettings_languageSv => 'Svenska'; + String get appSettings_languageSv => 'Szwedzki'; @override - String get appSettings_languageNl => 'Nederlands'; + String get appSettings_languageNl => 'Niderlandzki'; @override - String get appSettings_languageSk => 'Slovenčina'; + String get appSettings_languageSk => 'Słoweniština'; @override - String get appSettings_languageBg => 'Български'; + String get appSettings_languageBg => 'Българский'; @override String get appSettings_languageRu => 'Rosyjski'; @@ -887,7 +896,7 @@ class AppLocalizationsPl extends AppLocalizations { } @override - String get appSettings_debugCard => 'Debug'; + String get appSettings_debugCard => 'Naprawianie błędów'; @override String get appSettings_appDebugLogging => 'Logowanie Debugowania Aplikacji'; @@ -1098,20 +1107,16 @@ class AppLocalizationsPl extends AppLocalizations { return 'Kanał $index'; } - @override - String get channels_hashtagChannel => 'Kanał hashtagów'; - @override String get channels_public => 'Publiczny'; @override - String get channels_private => 'Prywatny'; - - @override - String get channels_publicChannel => 'Kanał publiczny'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Prywatny kanał'; + String get channels_private => 'Prywatny'; @override String get channels_editChannel => 'Edytuj kanał'; @@ -1156,7 +1161,7 @@ class AppLocalizationsPl extends AppLocalizations { String get channels_standardPublicPsk => 'Standardowy publiczny PSK'; @override - String get channels_pskHex => 'PSK (Hex)'; + String get channels_pskHex => 'PSK (heksadecymalne)'; @override String get channels_generateRandomPsk => 'Wygeneruj losowy klucz PSK'; @@ -1181,11 +1186,68 @@ class AppLocalizationsPl extends AppLocalizations { @override String get channels_smazCompression => 'Kompresja SMAZ'; + @override + String get channels_cyr2latCompression => 'Kompresja Cyr2Lat'; + + @override + String get channels_cyr2latCompressionDscr => + 'Zastępuje niektóre znaki cyrylicy alfabetem łacińskim podczas wysyłania.'; + + @override + String get channels_cyr2latSettingsHeading => 'Ustawienia Cyr2Lat'; + + @override + String get channels_cyr2latSettingsSubheading => 'Lista zamian'; + + @override + String get channels_cyr2latSettingsDscr => + 'Edytuj konfigurację JSON zamiany znaków'; + + @override + String get channels_cyr2latSettingsDialogHint => 'Mapa zamian JSON'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'Nieprawidłowy JSON: $error'; + } + @override String channels_channelUpdated(String name) { return 'Kanał \"$name\" został zaktualizowany'; } + @override + String get settings_cyr2latProfileAdd => 'Dodaj profil Cyr2Lat'; + + @override + String get settings_cyr2latProfileName => 'Nazwa profilu'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'Nazwa profilu nie może być pusta'; + + @override + String get settings_cyr2latProfileAdded => 'Profil dodano pomyślnie'; + + @override + String get settings_cyr2latProfileUpdated => + 'Profil został pomyślnie zaktualizowany'; + + @override + String get settings_cyr2latProfileEdit => 'Edytuj profil Cyr2Lat'; + + @override + String get settings_cyr2latProfileDelete => 'Usuń profil Cyr2Lat'; + + @override + String get settings_cyr2latProfileDeleted => + 'Profil został pomyślnie usunięty'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Czy na pewno chcesz usunąć profil \"$name\"?'; + } + @override String get channels_publicChannelAdded => 'Kanał publiczny dodany'; @@ -1196,7 +1258,7 @@ class AppLocalizationsPl extends AppLocalizations { String get channels_sortManual => 'Ręczna'; @override - String get channels_sortAZ => 'A-Z'; + String get channels_sortAZ => 'Od A do Z'; @override String get channels_sortLatestMessages => 'Najnowsze wiadomości'; @@ -1410,7 +1472,7 @@ class AppLocalizationsPl extends AppLocalizations { } @override - String get debugFrame_textTypeCli => 'CLI'; + String get debugFrame_textTypeCli => 'Interfejs wiersza poleceń'; @override String get debugFrame_textTypePlain => 'Zwykły'; @@ -1468,6 +1530,9 @@ class AppLocalizationsPl extends AppLocalizations { @override String get chat_successes => 'Sukcesy'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Usuń ścieżkę'; @@ -1569,6 +1634,12 @@ class AppLocalizationsPl extends AppLocalizations { return 'Nieprzeczytane: $count'; } + @override + String get chat_markAsUnread => 'Oznacz jako nieprzeczytane'; + + @override + String get chat_newMessages => 'Nowe wiadomości'; + @override String get chat_openLink => 'Otworzyć link?'; @@ -1650,6 +1721,24 @@ class AppLocalizationsPl extends AppLocalizations { @override String get map_flags => 'Flagi'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'Udostępnij znacznik tutaj'; @@ -1735,6 +1824,9 @@ class AppLocalizationsPl extends AppLocalizations { @override String get map_sharedPin => 'Udostępniona pinezka'; + @override + String get map_sharedAt => 'Udostępnione'; + @override String get map_joinRoom => 'Dołącz do pokoju'; @@ -2044,7 +2136,7 @@ class AppLocalizationsPl extends AppLocalizations { String get repeater_guestTools => 'Narzędzia dla gości'; @override - String get repeater_status => 'Status'; + String get repeater_status => 'Stan'; @override String get repeater_statusSubtitle => @@ -2058,7 +2150,7 @@ class AppLocalizationsPl extends AppLocalizations { 'Wyświetl dane telemetryczne z czujników i statystyki systemu'; @override - String get repeater_cli => 'CLI'; + String get repeater_cli => 'Interfejs wiersza poleceń'; @override String get repeater_cliSubtitle => 'Wyślij polecenia do przekaźnika'; @@ -2147,6 +2239,9 @@ class AppLocalizationsPl extends AppLocalizations { @override String get repeater_rxAirtime => 'Czas odbioru RX'; + @override + String get repeater_chanUtil => 'Wykorzystanie kanału'; + @override String get repeater_packetStatistics => 'Statystyki pakietów'; @@ -2220,7 +2315,7 @@ class AppLocalizationsPl extends AppLocalizations { String get repeater_frequencyMhz => 'Częstotliwość (MHz)'; @override - String get repeater_frequencyHelper => '300-2500 MHz'; + String get repeater_frequencyHelper => '300–2500 MHz'; @override String get repeater_txPower => 'Moc TX'; @@ -2354,6 +2449,164 @@ class AppLocalizationsPl extends AppLocalizations { @override String get repeater_settingsSaved => 'Ustawienia zostały pomyślnie zapisane.'; + @override + String get repeater_rxGain => 'Zwiększony zysk RX'; + + @override + String get repeater_rxGainHelper => + 'Większa czułość, większe pobieranie prądu (dotyczy tylko SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => 'Zaktualizuj zwiększone zyski RX'; + + @override + String get repeater_multiAcks => 'Wielokrotne potwierdzenia odbioru'; + + @override + String get repeater_multiAcksSubtitle => + 'Potwierdź odbiór wiadomości za pomocą różnych ścieżek, aby zapewnić lepszą dostawę.'; + + @override + String get repeater_refreshMultiAcks => + 'Odświeżanie wielokrotnych potwierdzeń'; + + @override + String get repeater_networkHealth => 'Stan sieci'; + + @override + String get repeater_loopDetect => 'Wykrywanie pętli'; + + @override + String get repeater_loopDetectHelper => + 'Wysyłaj pakiety, które wyglądają jak pętle routingu.'; + + @override + String get repeater_loopDetectOff => 'Z domu'; + + @override + String get repeater_loopDetectMinimal => 'Minimalny'; + + @override + String get repeater_loopDetectModerate => 'Umiarkowany'; + + @override + String get repeater_loopDetectStrict => 'Surowe'; + + @override + String get repeater_dutyCycle => 'Cykl pracy'; + + @override + String get repeater_dutyCycleHelper => + 'Maksymalny procent czasu, który stacja może wykorzystać.'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Informacje o operatorze'; + + @override + String get repeater_ownerInfoHelper => + 'Publiczne metadane dla tego urządzenia powielającego'; + + @override + String get repeater_refreshOwnerInfo => + 'Aktualizacja danych dotyczących operatora'; + + @override + String get repeater_floodMax => 'Maksymalna liczba skoków podczas powodzi'; + + @override + String get repeater_floodMaxHelper => + 'Maksymalna liczba pakietów, które mogą przemieszczać się w jednym strumieniu (0-64)'; + + @override + String get repeater_advancedSettings => 'Zaawansowany'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Regulowane pokrętła dla doświadczonych operatorów'; + + @override + String get repeater_pathHashMode => 'Tryb haszujący ścieżkę'; + + @override + String get repeater_pathHashModeHelper => + 'Bity wykorzystywane do kodowania identyfikatora tego urządzenia w tagach ścieżek/detekcji pętli. 0=1 bity (256 identyfikatorów, do 64 skoków), 1=2 bity (65 000 identyfikatorów, do 32 skoków), 2=3 bity (1 600 000 identyfikatorów, do 21 skoków). Wersje 1.13 i wcześniejsze nie obsługują ścieżek wielobitowych – wykrywają tylko jedną, gdy sieć jest w wersji 1.14 lub nowszej.'; + + @override + String get repeater_txDelay => 'Opóźnienie w Flood, TX'; + + @override + String get repeater_txDelayHelper => + 'Ustawienie odstępu dla ruchu związanego z powodzią, jako mnożnik czasu przesyłania pakietu (0-2, domyślnie 0,5). Wyższe wartości oznaczają mniejszą liczbę kolizji, ale wolniejszą prędkość przesyłania.'; + + @override + String get repeater_directTxDelay => 'Bezpośrednie opóźnienie sygnału TX'; + + @override + String get repeater_directTxDelayHelper => + 'Ustawienie odstępu dla ruchu bezpośredniego (bez rozgłaszania), jako mnożnika czasu przesyłania pakietu (0-2, domyślnie 0,3).'; + + @override + String get repeater_intThresh => 'Próg zakłóceń'; + + @override + String get repeater_intThreshHelper => + 'Próg został ustawiony na poziom szumów w radiu, dzięki czemu odrzuca sygnały zakłócające powyżej tego poziomu. 0 oznacza wyłączenie – ustaw tylko wtedy, gdy występują błędy odbierania w szumie.'; + + @override + String get repeater_agcResetInterval => 'Interwał resetowania AGC'; + + @override + String get repeater_agcResetIntervalHelper => + 'Jak często należy resetować automatyczną regulację głośności radia, aby odzyskać z sytuacji, w której głośność jest ustawiona na stałe. Ustawienie \"0\" dezaktywuje okresowe resetowanie.'; + + @override + String get repeater_actionsTitle => 'Działania'; + + @override + String get repeater_sendAdvert => 'Wysłać reklamę dotyczącą powodzi'; + + @override + String get repeater_sendAdvertSubtitle => + 'Wyemituj reklamę dotyczącą powodzi w sieci.'; + + @override + String get repeater_sendAdvertZeroHop => 'Wysłać reklamę bez pośrednictwa'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Napisz reklamę, która będzie transmitowana bezpośrednio (bez powtarzania).'; + + @override + String get repeater_clockSync => 'Synchronizuj zegar'; + + @override + String get repeater_clockSyncSubtitle => + 'Przekaż czas z telefonu do urządzenia powielającego'; + + @override + String repeater_actionSucceeded(String action) { + return '$action zakończyło się pomyślnie'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action failed: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Ustawienia zapisane – uruchom ponownie repeater, aby zastosować zmiany.'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Niektóre ustawienia nie zostały zaimplementowane: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Błąd zapisu ustawień: $error'; @@ -2368,10 +2621,6 @@ class AppLocalizationsPl extends AppLocalizations { @override String get repeater_refreshTxPower => 'Odśwież moc TX'; - @override - String get repeater_refreshLocationSettings => - 'Odśwież Ustawienia Lokalizacji'; - @override String get repeater_refreshPacketForwarding => 'Odśwież trasowanie pakietów'; @@ -2381,10 +2630,6 @@ class AppLocalizationsPl extends AppLocalizations { @override String get repeater_refreshPrivacyMode => 'Odśwież Tryb Prywatności'; - @override - String get repeater_refreshAdvertisementSettings => - 'Odśwież ustawienia rozgłoszeń'; - @override String repeater_refreshed(String label) { return '$label odświeżone'; @@ -2708,6 +2953,286 @@ class AppLocalizationsPl extends AppLocalizations { String get repeater_gpsNote => 'Polecenie GPS zostało wprowadzone w celu zarządzania tematami związanymi z lokalizacją.'; + @override + String get repeater_getCategory => 'Uzyskaj wartości'; + + @override + String get repeater_powerMgmt => 'Zarządzanie energią'; + + @override + String get repeater_sensors => 'Czujniki'; + + @override + String get repeater_cliHelpPowerOff => + 'Wyłącza urządzenie. (oczekiwanie na brak reakcji)'; + + @override + String get repeater_cliHelpClkReboot => + 'Przywraca zegar do znanego punktu odniesienia i resetuje urządzenie.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Wysyła reklamę, która dociera bezpośrednio do sąsiadów (bez pośrednictwa).'; + + @override + String get repeater_cliHelpStartOta => + 'Rozpoczyna aktualizację oprogramowania przez sieć (bezpośrednio z urządzenia).'; + + @override + String get repeater_cliHelpTime => + 'Ustawia zegar urządzenia na określone sekundy od epoki Unix. Zegar nie może się cofać.'; + + @override + String get repeater_cliHelpBoard => + 'Wyświetla informacje o producencie płyty głównej / identyfikator sprzętu.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Wysyła żądanie wykrywania sąsiednich węzłów. (Działa tylko w urządzeniu powielającym sygnał)'; + + @override + String get repeater_cliHelpPowersaving => + 'Pokazuje, czy tryb oszczędzania energii jest włączony, czy wyłączony.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Umożliwia lub wyłącza tryb oszczędzania energii (jeśli jest obsługiwany).'; + + @override + String get repeater_cliHelpErase => + '(Dla urządzeń) Formatuje system plików urządzenia. Usuwa wszystkie ustawienia i kontakty.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Ustawia maksymalny dopuszczalny cykl przesyłania w procentach (1-100). Automatycznie dostosowuje współczynnik czasu przesyłania.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Dla urządzeń) Zastępuje klucz prywatny identyfikujący urządzenie. Wymagana jest ponowna uruchomienie urządzenia, aby zastosować zmianę. Generuje nowy klucz publiczny.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(tylko SX126x) Włącza wzmocniony sygnał RX, co poprawia czułość przy wyższym poborze prądu.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Określa ciąg znaków zawierający dane kontaktowe właściciela, który znajduje się w ogłoszeniach. Użyj \'|\' jako separatora wierszy.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Ustawia tryb haszowania ścieżki. 0 = stary, 1 = standardowy, 2 = restrykcyjny. Wpływa na sposób dopasowywania ścieżek routingu.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Ustawia czułość detekcji pętli routingu: wyłączona, minimalna, umiarkowana lub rygorystyczna.'; + + @override + String get repeater_cliHelpSetFreq => + '(Dla urządzeń szeregowych) Szybko ustawia tylko częstotliwość. Wymagana ponowna uruchomienie. Zaleca się użycie opcji \"ustawienie radia\" w celu ustawienia wszystkich parametrów radia.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Tylko most ESPNow) Ustawia kanał WiFi (od 1 do 14), który jest wykorzystywany przez most.'; + + @override + String get repeater_cliHelpGetName => + 'Wyświetla nazwę skonfigurowanego węzła.'; + + @override + String get repeater_cliHelpGetRole => + 'Pokazuje rolę oprogramowania (np. repeater, serwer dla pokoju).'; + + @override + String get repeater_cliHelpGetPublicKey => + 'Wyświetla publiczny klucz urządzenia.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Tylko dla serialu) Wyświetla prywatny klucz urządzenia. Traktuj go jako poufny.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Pokazuje, czy funkcja przekierowywania pakietów (funkcja repeatera) jest włączona lub wyłączona.'; + + @override + String get repeater_cliHelpGetTx => 'Pokazuje aktualną moc transmisji w dBm.'; + + @override + String get repeater_cliHelpGetFreq => + 'Pokazuje skonfigurowaną częstotliwość radiową w MHz.'; + + @override + String get repeater_cliHelpGetRadio => + 'Wyświetla pełne parametry radia: częstotliwość, szerokość pasma, współczynnik modulacji, stopień kodowania.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(tylko SX126x) Wyświetla stan wzmocnienia sygnału RX.'; + + @override + String get repeater_cliHelpGetAf => + 'Pokazuje aktualny współczynnik czasu emisji.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Pokazuje aktualny dopuszczalny cykl pracy w procentach.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Pokazuje próg zakłóceń kanału w dB.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Pokazuje interwał resetowania AGC w sekundach.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Pokazuje, czy tryb podwójnego potwierdzania jest włączony (1) czy wyłączony (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Pokazuje, czy dostęp dla gości jest ograniczony do odczytu tylko.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Pokazuje czas trwania lokalnej reklamy w minutach.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Pokazuje interwał reklamowy dotyczący powodzi w godzinach.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Wyświetla ustawione hasło dla gościa.'; + + @override + String get repeater_cliHelpGetLat => + 'Pokazuje ustawioną szerokość geograficzną.'; + + @override + String get repeater_cliHelpGetLon => + 'Pokazuje ustawioną długość geograficzną.'; + + @override + String get repeater_cliHelpGetRxDelay => + 'Pokazuje bazową wartość opóźnienia RX.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Pokazuje współczynnik opóźnienia transmisji w trybie zalewowym.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Pokazuje współczynnik opóźnienia w trybie bezpośrednim.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Pokazuje maksymalną liczbę skoków spowodowanych powodzią.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Wyświetla ciąg znaków zawierający dane kontaktowe właściciela.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Pokazuje tryb haszujący ścieżkę (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Pokazuje czułość detekcji pętli.'; + + @override + String get repeater_cliHelpGetAcl => + '(Tylko dla seriali) Wyświetla wpisy kontroli dostępu w repeaterze.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Pokazuje, czy most jest włączony.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Pokazuje opóźnienie mostu w milisekundach.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Pokazuje, czy most odbiera pakiety RX lub TX.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Tylko interfejs RS232) Wyświetla prędkość transmisji na interfejsie RS232.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Tylko moduł ESPNow) Wyświetla kanał WiFi modułu.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Tylko most ESPNow) Wyświetla sekret udostępniony przez most.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(tylko dla NRF52) Wyświetla wersję bootloadera.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Pokazuje wzmacniacz ADC (skalowanie napięcia baterii).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Informuje, czy rada nadzorcza posiada wsparcie w zakresie zarządzania energią.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Pokazuje aktualne źródło zasilania: zewnętrzne lub bateryjne.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Pokazuje najnowsze przyczyny resetowania i wyłączania.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Pokazuje napięcie baterii podczas uruchamiania systemu w milivoltach (mV).'; + + @override + String get repeater_cliHelpSensorGet => + 'Odczytuje ustawienie czujnika zdefiniowane za pomocą klawisza.'; + + @override + String get repeater_cliHelpSensorSet => + 'Tworzy niestandardowe ustawienia dla czujnika.'; + + @override + String get repeater_cliHelpSensorList => + 'Wyświetla wszystkie ustawienia dla niestandardowych czujników, podzielone na strony, z opcjonalnym indeksem początkowym.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Pokazuje aktualny domyślny zakres regionu.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Ustawia domyślny zakres regionu. Użyj wartości \"\", aby go zresetować.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Wymienia regiony, w których dopuszczony jest ruch związany z powodzami.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Wymienia regiony, w których ruch związany z powodziami jest ograniczony.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Tylko dla serialu) Prezentuje statystyki na poziomie pakietów.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Tylko serial) Prezentuje statystyki dotyczące nadawania radiowego.'; + + @override + String get repeater_cliHelpStatsCore => + '(Tylko wersja serialowa) Wyświetla podstawowe statystyki o oprogramowaniu.'; + @override String get telemetry_receivedData => 'Odebrane dane telemetrii'; @@ -2745,7 +3270,7 @@ class AppLocalizationsPl extends AppLocalizations { @override String telemetry_batteryValue(int percent, String volts) { - return '$percent% / ${volts}V'; + return '$percent% / $volts W'; } @override @@ -3077,7 +3602,7 @@ class AppLocalizationsPl extends AppLocalizations { String get listFilter_heardRecently => 'Słyszano niedawno'; @override - String get listFilter_az => 'A-Z'; + String get listFilter_az => 'Od A do Z'; @override String get listFilter_filters => 'Filtry'; @@ -3247,6 +3772,37 @@ class AppLocalizationsPl extends AppLocalizations { @override String get losLegendTerrain => 'Teren'; + @override + String get losBlockedSpotsTitle => 'Zablokowane miejsca'; + + @override + String get losBlockedSpotsHint => + 'Kliknij zablokowane miejsce, aby je zaznaczyć na mapie.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Wybór przeszkody'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Częstotliwość'; @@ -3717,4 +4273,40 @@ class AppLocalizationsPl extends AppLocalizations { @override String get translation_systemLanguage => 'Język systemu'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index 2dfcd8b..e6fd49e 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -24,7 +24,7 @@ class AppLocalizationsPt extends AppLocalizations { String get common_cancel => 'Cancelar'; @override - String get common_ok => 'OK'; + String get common_ok => 'Tudo bem'; @override String get common_connect => 'Conectar'; @@ -44,6 +44,9 @@ class AppLocalizationsPt extends AppLocalizations { @override String get common_close => 'Fechar'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Editar'; @@ -109,7 +112,7 @@ class AppLocalizationsPt extends AppLocalizations { } @override - String get scanner_title => 'MeshCore Open'; + String get scanner_title => 'MeshCore: Versão aberta'; @override String get connectionChoiceUsbLabel => 'USB'; @@ -436,9 +439,7 @@ class AppLocalizationsPt extends AppLocalizations { 'Incluir localização no anúncio'; @override - String settings_multiAck(String value) { - return 'Multi-ACKs: $value'; - } + String get settings_multiAck => 'Multi-ACKs'; @override String get settings_telemetryModeUpdated => 'Modo de telemetria atualizado'; @@ -446,6 +447,13 @@ class AppLocalizationsPt extends AppLocalizations { @override String get settings_actions => 'Ações'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Enviar Publicidade'; @@ -488,11 +496,11 @@ class AppLocalizationsPt extends AppLocalizations { String get settings_debug => 'Depurar'; @override - String get settings_bleDebugLog => 'Log de Depuração BLE'; + String get settings_companionDebugLog => 'Registro de depuração auxiliar'; @override - String get settings_bleDebugLogSubtitle => - 'Comandos, respostas e dados brutos do BLE'; + String get settings_companionDebugLogSubtitle => + 'Comandos, respostas e dados brutos para protocolos BLE/TCP/USB'; @override String get settings_appDebugLog => 'Log de Depuração do Aplicativo'; @@ -527,7 +535,7 @@ class AppLocalizationsPt extends AppLocalizations { String get settings_infoId => 'ID'; @override - String get settings_infoStatus => 'Status'; + String get settings_infoStatus => 'Estado'; @override String get settings_infoBattery => 'Bateria'; @@ -542,7 +550,7 @@ class AppLocalizationsPt extends AppLocalizations { String get settings_infoChannelCount => 'Número do Canal'; @override - String get settings_presets => 'Presets'; + String get settings_presets => 'Configurações pré-definidas'; @override String get settings_frequency => 'Frequência (MHz)'; @@ -612,22 +620,22 @@ class AppLocalizationsPt extends AppLocalizations { String get appSettings_languageSystem => 'Padrão do sistema'; @override - String get appSettings_languageEn => 'English'; + String get appSettings_languageEn => 'Inglês'; @override - String get appSettings_languageFr => 'Français'; + String get appSettings_languageFr => 'Francês'; @override - String get appSettings_languageEs => 'Español'; + String get appSettings_languageEs => 'Espanhol'; @override - String get appSettings_languageDe => 'Deutsch'; + String get appSettings_languageDe => 'Alemão'; @override - String get appSettings_languagePl => 'Polski'; + String get appSettings_languagePl => 'Polonês'; @override - String get appSettings_languageSl => 'Slovenščina'; + String get appSettings_languageSl => 'Esloveno'; @override String get appSettings_languagePt => 'Português'; @@ -636,19 +644,19 @@ class AppLocalizationsPt extends AppLocalizations { String get appSettings_languageIt => 'Italiano'; @override - String get appSettings_languageZh => '中文'; + String get appSettings_languageZh => 'Chinês'; @override - String get appSettings_languageSv => 'Svenska'; + String get appSettings_languageSv => 'Sueco'; @override - String get appSettings_languageNl => 'Nederlands'; + String get appSettings_languageNl => 'Holandês'; @override - String get appSettings_languageSk => 'Slovenčina'; + String get appSettings_languageSk => 'Esloveno'; @override - String get appSettings_languageBg => 'Български'; + String get appSettings_languageBg => 'Búlgaro'; @override String get appSettings_languageRu => 'Russo'; @@ -1089,20 +1097,16 @@ class AppLocalizationsPt extends AppLocalizations { return 'Canal $index'; } - @override - String get channels_hashtagChannel => 'Canal com hashtag'; - @override String get channels_public => 'Público'; @override - String get channels_private => 'Privado'; - - @override - String get channels_publicChannel => 'Canal público'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Canal privado'; + String get channels_private => 'Privado'; @override String get channels_editChannel => 'Editar canal'; @@ -1172,11 +1176,66 @@ class AppLocalizationsPt extends AppLocalizations { @override String get channels_smazCompression => 'Compressão SMAZ'; + @override + String get channels_cyr2latCompression => 'Compressão Cyr2Lat'; + + @override + String get channels_cyr2latCompressionDscr => + 'Substitui alguns caracteres cirílicos por caracteres latinos ao enviar.'; + + @override + String get channels_cyr2latSettingsHeading => 'Configuração do Cyr2Lat'; + + @override + String get channels_cyr2latSettingsSubheading => 'Lista de substituições'; + + @override + String get channels_cyr2latSettingsDscr => + 'Editar a configuração JSON de substituição de caracteres'; + + @override + String get channels_cyr2latSettingsDialogHint => 'Mapa de substituições JSON'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'JSON incorreto: $error'; + } + @override String channels_channelUpdated(String name) { return 'Canal \"$name\" atualizado'; } + @override + String get settings_cyr2latProfileAdd => 'Adicionar perfil Cyr2Lat'; + + @override + String get settings_cyr2latProfileName => 'Nome do perfil'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'O nome do perfil não pode estar vazio'; + + @override + String get settings_cyr2latProfileAdded => 'Perfil adicionado com sucesso'; + + @override + String get settings_cyr2latProfileUpdated => 'Perfil atualizado com sucesso'; + + @override + String get settings_cyr2latProfileEdit => 'Editar perfil Cyr2Lat'; + + @override + String get settings_cyr2latProfileDelete => 'Eliminar perfil Cyr2Lat'; + + @override + String get settings_cyr2latProfileDeleted => 'Perfil eliminado com sucesso'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Tem a certeza de que deseja eliminar o perfil \"$name\"?'; + } + @override String get channels_publicChannelAdded => 'Canal público adicionado'; @@ -1187,7 +1246,7 @@ class AppLocalizationsPt extends AppLocalizations { String get channels_sortManual => 'Manual'; @override - String get channels_sortAZ => 'A-Z'; + String get channels_sortAZ => 'De A a Z'; @override String get channels_sortLatestMessages => 'Últimas mensagens'; @@ -1386,7 +1445,7 @@ class AppLocalizationsPt extends AppLocalizations { @override String debugFrame_timestamp(int timestamp) { - return '- Timestamp: $timestamp'; + return '- Carimbo: $timestamp'; } @override @@ -1400,7 +1459,7 @@ class AppLocalizationsPt extends AppLocalizations { } @override - String get debugFrame_textTypeCli => 'CLI'; + String get debugFrame_textTypeCli => 'Interface de Linha de Comando'; @override String get debugFrame_textTypePlain => 'Simples'; @@ -1446,8 +1505,8 @@ class AppLocalizationsPt extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'hops', - one: 'hop', + other: 'saltos', + one: 'salto', ); return '$count $_temp0'; } @@ -1455,6 +1514,9 @@ class AppLocalizationsPt extends AppLocalizations { @override String get chat_successes => 'Sucessos'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Remover caminho'; @@ -1556,6 +1618,12 @@ class AppLocalizationsPt extends AppLocalizations { return 'Não lido: $count'; } + @override + String get chat_markAsUnread => 'Marcar como não lido'; + + @override + String get chat_newMessages => 'Novas mensagens'; + @override String get chat_openLink => 'Abrir link?'; @@ -1638,6 +1706,24 @@ class AppLocalizationsPt extends AppLocalizations { @override String get map_flags => 'Bandeiras'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'Compartilhar marcador aqui'; @@ -1723,6 +1809,9 @@ class AppLocalizationsPt extends AppLocalizations { @override String get map_sharedPin => 'Pin compartilhado'; + @override + String get map_sharedAt => 'Compartilhado'; + @override String get map_joinRoom => 'Junte-se à Sala'; @@ -1927,7 +2016,7 @@ class AppLocalizationsPt extends AppLocalizations { String get login_managePaths => 'Gerenciar Caminhos'; @override - String get login_login => 'Login'; + String get login_login => 'Entrar'; @override String login_attempt(int current, int max) { @@ -2028,7 +2117,7 @@ class AppLocalizationsPt extends AppLocalizations { String get repeater_guestTools => 'Ferramentas para hóspedes'; @override - String get repeater_status => 'Status'; + String get repeater_status => 'Estado'; @override String get repeater_statusSubtitle => @@ -2042,7 +2131,7 @@ class AppLocalizationsPt extends AppLocalizations { 'Visualizar telemetria de sensores e estatísticas do sistema'; @override - String get repeater_cli => 'CLI'; + String get repeater_cli => 'Interface de Linha de Comando'; @override String get repeater_cliSubtitle => 'Enviar comandos ao repetidor'; @@ -2129,6 +2218,9 @@ class AppLocalizationsPt extends AppLocalizations { @override String get repeater_rxAirtime => 'RX Airtime'; + @override + String get repeater_chanUtil => 'Utilização do canal'; + @override String get repeater_packetStatistics => 'Estatísticas de Pacote'; @@ -2206,7 +2298,7 @@ class AppLocalizationsPt extends AppLocalizations { String get repeater_frequencyHelper => '300-2500 MHz'; @override - String get repeater_txPower => 'TX Power'; + String get repeater_txPower => 'Energia da TX'; @override String get repeater_txPowerHelper => '1-30 dBm'; @@ -2340,6 +2432,163 @@ class AppLocalizationsPt extends AppLocalizations { @override String get repeater_settingsSaved => 'Configurações salvas com sucesso'; + @override + String get repeater_rxGain => 'Aumento do ganho do RX'; + + @override + String get repeater_rxGainHelper => + 'Maior sensibilidade, maior consumo de corrente (apenas para SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => 'Reforçar o ganho do RX'; + + @override + String get repeater_multiAcks => 'Múltiplas respostas de confirmação'; + + @override + String get repeater_multiAcksSubtitle => + 'Reconheça mensagens através de múltiplos caminhos para uma melhor entrega.'; + + @override + String get repeater_refreshMultiAcks => 'Reiniciar múltiplas confirmações'; + + @override + String get repeater_networkHealth => 'Saúde da rede'; + + @override + String get repeater_loopDetect => 'Detecção de loops'; + + @override + String get repeater_loopDetectHelper => + 'Envie pacotes que pareçam ser loops de roteamento.'; + + @override + String get repeater_loopDetectOff => 'Desligado'; + + @override + String get repeater_loopDetectMinimal => 'Mínimo'; + + @override + String get repeater_loopDetectModerate => 'Moderado'; + + @override + String get repeater_loopDetectStrict => 'Rígido'; + + @override + String get repeater_dutyCycle => 'Ciclo de operação'; + + @override + String get repeater_dutyCycleHelper => + 'Porcentagem máxima de tempo de transmissão'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Informações sobre o operador'; + + @override + String get repeater_ownerInfoHelper => + 'Metadados públicos para este repetidor'; + + @override + String get repeater_refreshOwnerInfo => 'Atualizar informações do operador'; + + @override + String get repeater_floodMax => + 'Número máximo de saltos em caso de inundação'; + + @override + String get repeater_floodMaxHelper => + 'Número máximo de saltos que um pacote de inundação pode percorrer (0-64)'; + + @override + String get repeater_advancedSettings => 'Avançado'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Controles de ajuste para operadores experientes'; + + @override + String get repeater_pathHashMode => 'Modo de hash de caminho'; + + @override + String get repeater_pathHashModeHelper => + 'Bytes utilizados para codificar o ID deste repetidor nas tags de caminho/detecção de loop. 0=1 byte (256 IDs, até 64 saltos), 1=2 bytes (65.000 IDs, até 32 saltos), 2=3 bytes (16 milhões de IDs, até 21 saltos). As versões 1.13 e anteriores do firmware não suportam caminhos multi-byte — apenas funcionam uma vez após a ativação da rede (a partir da versão 1.14+).'; + + @override + String get repeater_txDelay => 'Atraso na entrega em Flood, TX'; + + @override + String get repeater_txDelayHelper => + 'Ajuste de espaçamento para tráfego de inundações, como um multiplicador do tempo de transmissão (0-2, padrão 0,5). Quanto maior, menos colisões, mas uma entrega mais lenta.'; + + @override + String get repeater_directTxDelay => 'Atraso direto no sinal TX'; + + @override + String get repeater_directTxDelayHelper => + 'Intervalo de retransmissão para tráfego direto (não em enxame), como um multiplicador do tempo de transmissão do pacote (0-2, padrão 0,3).'; + + @override + String get repeater_intThresh => 'Limite de interferência'; + + @override + String get repeater_intThreshHelper => + 'O limite é definido para o nível de ruído do rádio, de modo que ele rejeite interferências acima desse nível. 0 desativa – aumente apenas se você observar erros de RX em uma faixa de frequência com ruído.'; + + @override + String get repeater_agcResetInterval => 'Intervalo de reinicialização do AGC'; + + @override + String get repeater_agcResetIntervalHelper => + 'Com que frequência redefinir o controle automático de ganho do rádio para recuperar de um estado em que o ganho está travado. Segundos, reduzidos a um múltiplo de 4. 0 desativa as redefinições periódicas.'; + + @override + String get repeater_actionsTitle => 'Ações'; + + @override + String get repeater_sendAdvert => 'Envie anúncio sobre inundações'; + + @override + String get repeater_sendAdvertSubtitle => + 'Transmita um anúncio sobre inundações pela rede.'; + + @override + String get repeater_sendAdvertZeroHop => 'Enviar anúncio sem intermediários'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Transmita um anúncio de um único salto (sem repetição).'; + + @override + String get repeater_clockSync => 'Sincronize o relógio agora'; + + @override + String get repeater_clockSyncSubtitle => + 'Envie a hora do seu telefone para o repetidor.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action succeeded'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action failed: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Configurações salvas — reinicie o repetidor para aplicar as alterações.'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Algumas configurações falharam: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Erro ao salvar as configurações: $error'; @@ -2355,10 +2604,6 @@ class AppLocalizationsPt extends AppLocalizations { @override String get repeater_refreshTxPower => 'Atualizar TX de energia'; - @override - String get repeater_refreshLocationSettings => - 'Atualizar Configurações de Localização'; - @override String get repeater_refreshPacketForwarding => 'Atualizar Roteamento de Pacotes'; @@ -2369,10 +2614,6 @@ class AppLocalizationsPt extends AppLocalizations { @override String get repeater_refreshPrivacyMode => 'Atualizar Modo Privacidade'; - @override - String get repeater_refreshAdvertisementSettings => - 'Atualizar Configurações do Anúncio'; - @override String repeater_refreshed(String label) { return '$label atualizado'; @@ -2696,6 +2937,283 @@ class AppLocalizationsPt extends AppLocalizations { String get repeater_gpsNote => 'O comando GPS foi introduzido para gerenciar tópicos relacionados à localização.'; + @override + String get repeater_getCategory => 'Obter valores'; + + @override + String get repeater_powerMgmt => 'Gerenciamento de energia'; + + @override + String get repeater_sensors => 'Sensores'; + + @override + String get repeater_cliHelpPowerOff => + 'Desliga o dispositivo. (não se espera resposta)'; + + @override + String get repeater_cliHelpClkReboot => + 'Redefine o relógio para uma data conhecida e reinicia o dispositivo.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Envia um anúncio sem \"salto\" (apenas para vizinhos próximos).'; + + @override + String get repeater_cliHelpStartOta => + 'Inicia uma atualização de firmware via rádio em placas compatíveis.'; + + @override + String get repeater_cliHelpTime => + 'Define o relógio do dispositivo para os segundos da época Unix especificados. O relógio não pode retroceder.'; + + @override + String get repeater_cliHelpBoard => + 'Indica o fabricante da placa / identificador de hardware.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Envia uma solicitação de descoberta de nós para os vizinhos próximos. (Apenas para repetidores)'; + + @override + String get repeater_cliHelpPowersaving => + 'Indica se o modo de economia de energia está ativado ou desativado.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Habilita ou desabilita o modo de economia de energia (quando disponível).'; + + @override + String get repeater_cliHelpErase => + '(Apenas para dispositivos) Formata o sistema de arquivos do dispositivo. Apaga todas as configurações e contatos.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Define o ciclo de transmissão máximo permitido como uma porcentagem (1-100). Ajusta internamente o fator de tempo de transmissão.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Apenas para uso em série) Substitui a chave privada de identificação do dispositivo. É necessário reiniciar o dispositivo para aplicar a alteração. Gera uma nova chave pública.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(Apenas para SX126x) Alterna o ganho amplificado do receptor (RX) para melhorar a sensibilidade em condições de corrente mais elevada.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Define a string com as informações de contato do proprietário, que será incluída nos anúncios. Utilize \'|\' para indicar novas linhas.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Define o modo de hash de caminho. 0 = modo legado, 1 = modo padrão, 2 = modo rigoroso. Afeta a forma como os caminhos de roteamento são correspondidos.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Define o nível de sensibilidade para a detecção de loops de roteamento: desligado, mínimo, moderado ou estrito.'; + + @override + String get repeater_cliHelpSetFreq => + '(Apenas para rádio) Define rapidamente a frequência. É necessário reiniciar o dispositivo. Recomenda-se usar a opção \"configurar rádio\" para definir todos os parâmetros do rádio.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Apenas para a ponte ESPNow) Define o canal Wi-Fi (1-14) utilizado pela ponte.'; + + @override + String get repeater_cliHelpGetName => 'Mostra o nome do nó configurado.'; + + @override + String get repeater_cliHelpGetRole => + 'Mostra o papel do firmware (Repetidor, Servidor de Sala, etc.).'; + + @override + String get repeater_cliHelpGetPublicKey => + 'Exibe a chave pública do dispositivo.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Apenas para uso em série) Exibe a chave privada do dispositivo. Trate-a como uma informação confidencial.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Indica se a função de encaminhamento de pacotes (função de repetidor) está ativada ou desativada.'; + + @override + String get repeater_cliHelpGetTx => 'Mostra a potência atual em dBm.'; + + @override + String get repeater_cliHelpGetFreq => + 'Mostra a frequência de rádio configurada em MHz.'; + + @override + String get repeater_cliHelpGetRadio => + 'Exibe todos os parâmetros de rádio: frequência, largura de banda, fator de espalhamento, taxa de codificação.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(Apenas para SX126x) Mostra o estado do ganho amplificado do RX.'; + + @override + String get repeater_cliHelpGetAf => + 'Mostra o fator de tempo de transmissão atual.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Mostra o ciclo de trabalho atual permitido em porcentagem.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Mostra o limite de interferência do canal em dB.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Mostra o intervalo de reinicialização do AGC em segundos.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Indica se o modo de confirmação dupla está ativado (1) ou desativado (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Indica se o acesso somente de leitura para os convidados está habilitado.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Indica o intervalo de publicidade local em minutos.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Mostra o intervalo de tempo da publicidade relacionada às inundações, em horas.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Mostra a senha de convidado configurada.'; + + @override + String get repeater_cliHelpGetLat => 'Mostra a latitude configurada.'; + + @override + String get repeater_cliHelpGetLon => 'Mostra a longitude configurada.'; + + @override + String get repeater_cliHelpGetRxDelay => + 'Mostra o valor base do atraso de resposta.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Mostra o fator de atraso em modo de inundação.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Mostra o fator de atraso direto.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Mostra o número máximo de saltos devido às inundações.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Exibe a string de informações de contato do proprietário.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Mostra o modo de hash de caminho (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Demonstra a sensibilidade na detecção de loops.'; + + @override + String get repeater_cliHelpGetAcl => + '(Apenas para séries) Lista as entradas de controle de acesso em um repetidor.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Indica se a ponte está habilitada.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Mostra o atraso da ponte em milissegundos.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Indica se a ponte está enviando ou recebendo pacotes RX ou TX.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Apenas para ponte RS232) Exibe a taxa de baud da ponte.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Apenas para a ponte ESPNow) Exibe o canal WiFi da ponte.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Apenas para a ponte ESPNow) Exibe o segredo compartilhado pela ponte.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(Apenas para NRF52) Exibe a versão do bootloader.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Mostra o multiplicador do ADC (escalonamento da tensão da bateria).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Indica se o sistema possui suporte para gerenciamento de energia.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Indica a fonte de energia atual: externa ou bateria.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Mostra as razões mais recentes para a reinicialização e desligamento.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Mostra a tensão da bateria no momento da inicialização, em milivolts (mV).'; + + @override + String get repeater_cliHelpSensorGet => + 'Lê uma configuração de sensor personalizada através de uma chave.'; + + @override + String get repeater_cliHelpSensorSet => + 'Cria uma configuração personalizada para um sensor.'; + + @override + String get repeater_cliHelpSensorList => + 'Lista todas as configurações de sensores personalizadas, organizadas em páginas a partir de um índice de início opcional.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Mostra o escopo de região padrão atual.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Define o escopo regional padrão. Use \"\" para limpar.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Lista as regiões que permitem o tráfego em áreas de risco de inundações.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Lista as regiões que restringem o tráfego em áreas de risco de inundações.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Apenas para séries) Apresenta estatísticas em nível de pacotes.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Apenas para transmissões em série) Exibe estatísticas de rádio.'; + + @override + String get repeater_cliHelpStatsCore => + '(Apenas para dispositivos em série) Exibe estatísticas básicas do firmware.'; + @override String get telemetry_receivedData => 'Dados de Telemetria Recebidos'; @@ -3066,7 +3584,7 @@ class AppLocalizationsPt extends AppLocalizations { String get listFilter_heardRecently => 'Ouvido recentemente'; @override - String get listFilter_az => 'A-Z'; + String get listFilter_az => 'De A a Z'; @override String get listFilter_filters => 'Filtros'; @@ -3236,6 +3754,37 @@ class AppLocalizationsPt extends AppLocalizations { @override String get losLegendTerrain => 'Terreno'; + @override + String get losBlockedSpotsTitle => 'Locais ocupados'; + + @override + String get losBlockedSpotsHint => + 'Toque em um ponto bloqueado para destacá-lo no mapa.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Obstrução selecionada'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Frequência'; @@ -3700,4 +4249,40 @@ class AppLocalizationsPt extends AppLocalizations { @override String get translation_systemLanguage => 'Idioma do sistema'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 4fac42c..2545200 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -44,6 +44,9 @@ class AppLocalizationsRu extends AppLocalizations { @override String get common_close => 'Закрыть'; + @override + String get common_done => 'Готово'; + @override String get common_edit => 'Изменить'; @@ -436,9 +439,7 @@ class AppLocalizationsRu extends AppLocalizations { 'Включить местоположение в объявление'; @override - String settings_multiAck(String value) { - return 'Мульти-ACK: $value'; - } + String get settings_multiAck => 'Несколько подтверждений'; @override String get settings_telemetryModeUpdated => 'Режим телеметрии обновлен'; @@ -446,6 +447,13 @@ class AppLocalizationsRu extends AppLocalizations { @override String get settings_actions => 'Действия'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Отправить анонсирование'; @@ -487,11 +495,12 @@ class AppLocalizationsRu extends AppLocalizations { String get settings_debug => 'Отладка'; @override - String get settings_bleDebugLog => 'Журнал отладки BLE'; + String get settings_companionDebugLog => + 'Журнал отладки (для сопутствующего приложения)'; @override - String get settings_bleDebugLogSubtitle => - 'Команды BLE, ответы и сырые данные'; + String get settings_companionDebugLogSubtitle => + 'Команды, ответы и необработанные данные, используемые для протоколов BLE, TCP и USB.'; @override String get settings_appDebugLog => 'Журнал отладки приложения'; @@ -1089,20 +1098,16 @@ class AppLocalizationsRu extends AppLocalizations { return 'Канал $index'; } - @override - String get channels_hashtagChannel => 'Хэштег-канал'; - @override String get channels_public => 'Публичный'; @override - String get channels_private => 'Приватный'; - - @override - String get channels_publicChannel => 'Публичный канал'; + String channels_via(String path) { + return 'через $path'; + } @override - String get channels_privateChannel => 'Приватный канал'; + String get channels_private => 'Приватный'; @override String get channels_editChannel => 'Изменить канал'; @@ -1172,11 +1177,66 @@ class AppLocalizationsRu extends AppLocalizations { @override String get channels_smazCompression => 'Сжатие SMAZ'; + @override + String get channels_cyr2latCompression => 'Сжатие Cyr2Lat'; + + @override + String get channels_cyr2latCompressionDscr => + 'Заменяет некоторые кириллические символы на латиницу при отправке.'; + + @override + String get channels_cyr2latSettingsHeading => 'Настройка Cyr2Lat'; + + @override + String get channels_cyr2latSettingsSubheading => 'Список замен'; + + @override + String get channels_cyr2latSettingsDscr => + 'Редактировать JSON-конфигурацию замены символов'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON-карта замен'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'Некорректный JSON: $error'; + } + @override String channels_channelUpdated(String name) { return 'Канал \"$name\" обновлён'; } + @override + String get settings_cyr2latProfileAdd => 'Добавить профиль Cyr2Lat'; + + @override + String get settings_cyr2latProfileName => 'Название профиля'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'Название профиля не может быть пустым'; + + @override + String get settings_cyr2latProfileAdded => 'Профиль добавлен'; + + @override + String get settings_cyr2latProfileUpdated => 'Профиль успешно обновлен'; + + @override + String get settings_cyr2latProfileEdit => 'Редактировать профиль Cyr2Lat'; + + @override + String get settings_cyr2latProfileDelete => 'Удалить профиль Cyr2Lat'; + + @override + String get settings_cyr2latProfileDeleted => 'Профиль успешно удален'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Вы действительно хотите удалить профиль \"$name\"?'; + } + @override String get channels_publicChannelAdded => 'Публичный канал добавлен'; @@ -1458,6 +1518,9 @@ class AppLocalizationsRu extends AppLocalizations { @override String get chat_successes => 'успешно'; + @override + String get chat_score => 'Оценка'; + @override String get chat_removePath => 'Удалить маршрут'; @@ -1560,6 +1623,12 @@ class AppLocalizationsRu extends AppLocalizations { return 'Непрочитанных: $count'; } + @override + String get chat_markAsUnread => 'Пометить как непрочитанные'; + + @override + String get chat_newMessages => 'Новые сообщения'; + @override String get chat_openLink => 'Открыть ссылку?'; @@ -1641,6 +1710,24 @@ class AppLocalizationsRu extends AppLocalizations { @override String get map_flags => 'Флаги'; + @override + String get map_type => 'Тип'; + + @override + String get map_path => 'Путь'; + + @override + String get map_location => 'Местоположение'; + + @override + String get map_estLocation => 'Прибл. местоположение'; + + @override + String get map_publicKey => 'Публичный ключ'; + + @override + String get map_publicKeyPrefixHint => 'напр. ab12'; + @override String get map_shareMarkerHere => 'Поделиться меткой здесь'; @@ -1726,6 +1813,9 @@ class AppLocalizationsRu extends AppLocalizations { @override String get map_sharedPin => 'Общая метка'; + @override + String get map_sharedAt => 'Поделено'; + @override String get map_joinRoom => 'Присоединиться к комнате'; @@ -2134,6 +2224,9 @@ class AppLocalizationsRu extends AppLocalizations { @override String get repeater_rxAirtime => 'Время эфира (приём)'; + @override + String get repeater_chanUtil => 'Использование канала'; + @override String get repeater_packetStatistics => 'Статистика пакетов'; @@ -2346,6 +2439,164 @@ class AppLocalizationsRu extends AppLocalizations { @override String get repeater_settingsSaved => 'Настройки успешно сохранены'; + @override + String get repeater_rxGain => 'Увеличенная эффективность RX'; + + @override + String get repeater_rxGainHelper => + 'Более высокая чувствительность, больший ток потребления (только для SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => 'Обновите усиление RX'; + + @override + String get repeater_multiAcks => 'Несколько подтверждений'; + + @override + String get repeater_multiAcksSubtitle => + 'Обеспечьте доставку сообщений по нескольким каналам для повышения эффективности.'; + + @override + String get repeater_refreshMultiAcks => 'Обновление нескольких подтверждений'; + + @override + String get repeater_networkHealth => 'Состояние сети'; + + @override + String get repeater_loopDetect => 'Обнаружение циклов'; + + @override + String get repeater_loopDetectHelper => + 'Создайте пакеты данных, которые выглядят как циклы маршрутизации.'; + + @override + String get repeater_loopDetectOff => 'Отключено'; + + @override + String get repeater_loopDetectMinimal => 'Минимальный'; + + @override + String get repeater_loopDetectModerate => 'Умеренный'; + + @override + String get repeater_loopDetectStrict => 'Строгий'; + + @override + String get repeater_dutyCycle => 'Цикл работы'; + + @override + String get repeater_dutyCycleHelper => + 'Максимальный процент времени, выделенного на трансляцию.'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Информация о операторе'; + + @override + String get repeater_ownerInfoHelper => + 'Общая метаинформация для этого ретранслятора'; + + @override + String get repeater_refreshOwnerInfo => 'Обновить информацию о операторе'; + + @override + String get repeater_floodMax => + 'Максимальное количество прыжков при наводнении'; + + @override + String get repeater_floodMaxHelper => + 'Максимальное количество пакетов, которые могут быть отправлены в одном потоке (0-64)'; + + @override + String get repeater_advancedSettings => 'Продвинутый'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Регуляторы для опытных операторов'; + + @override + String get repeater_pathHashMode => 'Режим хеширования пути'; + + @override + String get repeater_pathHashModeHelper => + 'Байты, используемые для кодирования идентификатора этого ретранслятора в тегах для обнаружения потоков/циклов. 0 = 1 байт (256 идентификаторов, до 64 переходов), 1 = 2 байта (65 000 идентификаторов, до 32 переходов), 2 = 3 байта (1 600 000 идентификаторов, до 21 перехода). Версии прошивки v1.13 и более ранние версии не поддерживают многобайтовые пути — они поднимаются только после того, как ваша сеть будет обновлена до версии v1.14 и выше.'; + + @override + String get repeater_txDelay => 'Задержка в работе системы Flood TX'; + + @override + String get repeater_txDelayHelper => + 'Передача с увеличенным интервалом для трафика во время наводнения, в качестве коэффициента, умножающего время передачи пакета (от 0 до 2, по умолчанию 0,5). Более высокое значение означает меньшее количество столкновений, но более медленную передачу.'; + + @override + String get repeater_directTxDelay => 'Прямая задержка сигнала TX'; + + @override + String get repeater_directTxDelayHelper => + 'Передача промежуточных данных для прямого (немассового) трафика, в качестве коэффициента, равного времени передачи пакета (от 0 до 2, по умолчанию 0,3).'; + + @override + String get repeater_intThresh => 'Пороговое значение помех'; + + @override + String get repeater_intThreshHelper => + 'Порог устанавливается для калибровки уровня шума радио, чтобы оно отсеивало помехи, превышающие этот уровень. Значение \"0\" означает отключение – используйте только в случае, если вы наблюдаете ошибки при приеме сигнала в шумном диапазоне.'; + + @override + String get repeater_agcResetInterval => 'Интервал сброса AGC'; + + @override + String get repeater_agcResetIntervalHelper => + 'Как часто следует сбрасывать автоматическую регулировку усиления радио, чтобы вернуться к нормальному состоянию после заклинивания? Интервал сброса составляет несколько секунд, кратный 4. Отключение периодического сброса осуществляется с помощью параметра 0.'; + + @override + String get repeater_actionsTitle => 'Действия'; + + @override + String get repeater_sendAdvert => 'Отправить объявление о наводнении'; + + @override + String get repeater_sendAdvertSubtitle => + 'Разместите рекламу о наводнении в эфире по всей сети.'; + + @override + String get repeater_sendAdvertZeroHop => + 'Опубликуйте рекламу, не требующую промежуточного распространения.'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Разместите рекламу, распространяемую одним способом (без использования ретрансляторов).'; + + @override + String get repeater_clockSync => 'Синхронизировать время сейчас'; + + @override + String get repeater_clockSyncSubtitle => + 'Установите время на вашем телефоне, чтобы оно совпадало со временем ретранслятора.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action succeeded'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action failed: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Настройки сохранены — перезагрузите ретранслятор, чтобы применить их.'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Некоторые настройки не удалось применить: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Ошибка сохранения настроек: $error'; @@ -2360,10 +2611,6 @@ class AppLocalizationsRu extends AppLocalizations { @override String get repeater_refreshTxPower => 'Обновить мощность передачи'; - @override - String get repeater_refreshLocationSettings => - 'Обновить настройки местоположения'; - @override String get repeater_refreshPacketForwarding => 'Обновить пересылку пакетов'; @@ -2373,10 +2620,6 @@ class AppLocalizationsRu extends AppLocalizations { @override String get repeater_refreshPrivacyMode => 'Обновить режим конфиденциальности'; - @override - String get repeater_refreshAdvertisementSettings => - 'Обновить настройки анонсирований'; - @override String repeater_refreshed(String label) { return '$label обновлён'; @@ -2702,6 +2945,284 @@ class AppLocalizationsRu extends AppLocalizations { String get repeater_gpsNote => 'Команда gps введена для управления параметрами, связанными с местоположением.'; + @override + String get repeater_getCategory => 'Получить значения'; + + @override + String get repeater_powerMgmt => 'Управление энергопотреблением'; + + @override + String get repeater_sensors => 'Датчики'; + + @override + String get repeater_cliHelpPowerOff => + 'Отключает устройство. (ожидается отсутствие ответа).'; + + @override + String get repeater_cliHelpClkReboot => + 'Сбрасывает часы до известной эпохи и перезапускает устройство.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Отправляет рекламу, распространяемую только среди ближайших соседей (без промежуточных узлов).'; + + @override + String get repeater_cliHelpStartOta => + 'Запускает обновление прошивки по воздуху на поддерживаемых устройствах.'; + + @override + String get repeater_cliHelpTime => + 'Устанавливает время устройства в соответствии с заданными секундами от начала эпохи Unix. Время не может сброситься назад.'; + + @override + String get repeater_cliHelpBoard => + 'Отображает информацию о производителе платы / идентификатор аппаратного обеспечения.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Отправляет запрос на обнаружение соседних узлов. (Только для ретранслятора)'; + + @override + String get repeater_cliHelpPowersaving => + 'Показывает, включен ли режим экономии энергии.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Включает или выключает режим экономии энергии (если он поддерживается).'; + + @override + String get repeater_cliHelpErase => + '(Только для серийного использования) Форматирует файловую систему устройства. Удаляет все настройки и контакты.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Устанавливает максимальный допустимый цикл передачи данных в процентах (от 1 до 100). Внутренне корректирует коэффициент времени передачи.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Только для серийного использования) Заменяет приватный ключ, идентифицирующий устройство. Требуется перезагрузка для применения. Генерирует новый публичный ключ.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(Только для SX126x) Переключает усиление RX для повышения чувствительности при больших токах потребления.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Указывает строку с контактной информацией владельца, которая должна быть включена в объявления. Используйте \'|\' для переносов строк.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Устанавливает режим хеширования пути. 0 = устаревший, 1 = стандартный, 2 = строгий. Влияет на то, как определяются маршруты.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Устанавливает чувствительность обнаружения циклов маршрутизации: \"выключено\", \"минимальная\", \"умеренная\" или \"строгая\".'; + + @override + String get repeater_cliHelpSetFreq => + '(Только для настройки) Быстро устанавливает только частоту. Требуется перезагрузка. Рекомендуется использовать функцию \"настройка радио\" для полного набора параметров.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Только для моста ESPNow) Устанавливает канал Wi-Fi (от 1 до 14), используемый мостом.'; + + @override + String get repeater_cliHelpGetName => 'Отображает имя настроенного узла.'; + + @override + String get repeater_cliHelpGetRole => + 'Отображает роль прошивки (ретранслятор, сервер для комнаты и т.д.).'; + + @override + String get repeater_cliHelpGetPublicKey => + 'Отображает открытый ключ устройства.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Только для серийного использования) Отображает приватный ключ устройства. Рассматривайте его как секретную информацию.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Отображает, включена ли функция перенаправления пакетов (функция ретранслятора) или нет.'; + + @override + String get repeater_cliHelpGetTx => + 'Отображает текущую мощность передатчика в дБм.'; + + @override + String get repeater_cliHelpGetFreq => + 'Отображает настроенную частоту радиосигнала в мегагерцах.'; + + @override + String get repeater_cliHelpGetRadio => + 'Отображает все параметры радиосигнала: частоту, полосу пропускания, коэффициент модуляции, скорость кодирования.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(Только для SX126x) Отображает состояние усиления сигнала на входе RX.'; + + @override + String get repeater_cliHelpGetAf => + 'Отображает текущий коэффициент времени эфира.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Отображает текущий допустимый цикл работы в процентах.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Отображает порог помех в децибелах.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Отображает интервал сброса автоматической регулировки усиления в секундах.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Показывает, включен ли режим двойной подтверждения (1) или выключен (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Отображает, разрешен ли доступ для чтения только для гостей.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Отображает продолжительность рекламного блока в минутах.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Отображает интервал времени показа рекламного ролика в часах.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Отображает установленный пароль для гостя.'; + + @override + String get repeater_cliHelpGetLat => 'Отображает заданную широту.'; + + @override + String get repeater_cliHelpGetLon => 'Отображает заданную долготу.'; + + @override + String get repeater_cliHelpGetRxDelay => + 'Отображает базовое значение задержки.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Отображает коэффициент задержки при работе в режиме затопления.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Отображает коэффициент задержки в режиме прямого подключения.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Отображает максимальное количество переходов при затоплении.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Отображает строку с контактной информацией владельца.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Отображает режим работы с хэшем пути (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Отображает чувствительность к обнаружению циклов.'; + + @override + String get repeater_cliHelpGetAcl => + '(Только для серий) Перечисляет записи управления доступом на ретрансляторе.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Показывает, включена ли функция моста.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Отображает задержку в миллисекундах.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Отображает, какие пакеты RX или TX передаются через мост.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Только для интерфейса RS232) Отображает скорость передачи данных на интерфейсе RS232.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Только для моста ESPNow) Отображает канал WiFi, используемый мостом.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Только для моста ESPNow) Отображает общий секрет, используемый мостом.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(Только для NRF52) Отображает версию загрузчика.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Отображает коэффициент умножения аналого-цифрового преобразователя (масштабирование напряжения от батареи).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Сообщает, есть ли у совета поддержки функций управления питанием.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Отображает текущий источник питания: внешний или аккумулятор.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Отображает последние причины сброса и выключения.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Отображает напряжение батареи при запуске системы в милливольтах (мВ).'; + + @override + String get repeater_cliHelpSensorGet => + 'Считывает пользовательское значение для датчика по указанному ключу.'; + + @override + String get repeater_cliHelpSensorSet => + 'Создает пользовательские настройки для датчика.'; + + @override + String get repeater_cliHelpSensorList => + 'Перечисляет все пользовательские настройки датчиков, разбитые на страницы с возможностью указания начального индекса.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Отображает текущий область действия по умолчанию.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Устанавливает значение региона по умолчанию. Используйте \"\", чтобы сбросить значение.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Перечисляет регионы, где разрешено движение транспорта во время наводнений.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Перечисляет регионы, где запрещено движение транспорта во время наводнений.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Только для серийной версии) Отображает статистику на уровне пакетов.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Только для серий) Отображает статистику радио.'; + + @override + String get repeater_cliHelpStatsCore => + '(Только для серийного оборудования) Отображает основные статистические данные прошивки.'; + @override String get telemetry_receivedData => 'Полученные телеметрические данные'; @@ -3241,6 +3762,38 @@ class AppLocalizationsRu extends AppLocalizations { @override String get losLegendTerrain => 'Рельеф'; + @override + String get losBlockedSpotsTitle => 'Зарезервированные места'; + + @override + String get losBlockedSpotsHint => + 'Щелкните по заблокированной области, чтобы выделить ее на карте.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => + 'Выбранный объект, препятствующий движению'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Частота'; @@ -3714,4 +4267,40 @@ class AppLocalizationsRu extends AppLocalizations { @override String get translation_systemLanguage => 'Язык системы'; + + @override + String get background_serviceTitle => 'MeshCore работает'; + + @override + String get background_serviceText => 'Поддерживает BLE-соединение'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Удалено $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Не удалось удалить: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Не удалось обновить канал: $error'; + } + + @override + String get contact_typeChat => 'Чат'; + + @override + String get contact_typeRepeater => 'Ретранслятор'; + + @override + String get contact_typeRoom => 'Комната'; + + @override + String get contact_typeSensor => 'Датчик'; + + @override + String get contact_typeUnknown => 'Неизвестно'; } diff --git a/lib/l10n/app_localizations_sk.dart b/lib/l10n/app_localizations_sk.dart index c42e024..9146138 100644 --- a/lib/l10n/app_localizations_sk.dart +++ b/lib/l10n/app_localizations_sk.dart @@ -44,6 +44,9 @@ class AppLocalizationsSk extends AppLocalizations { @override String get common_close => 'Zavrieť'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Upraviť'; @@ -109,7 +112,7 @@ class AppLocalizationsSk extends AppLocalizations { } @override - String get scanner_title => 'MeshCore Open'; + String get scanner_title => 'MeshCore – Verzia pre verejnosť'; @override String get connectionChoiceUsbLabel => 'USB'; @@ -130,10 +133,10 @@ class AppLocalizationsSk extends AppLocalizations { String get tcpHostHint => '192.168.40.10'; @override - String get tcpPortLabel => 'Port'; + String get tcpPortLabel => 'Prístav'; @override - String get tcpPortHint => '5000'; + String get tcpPortHint => '5 000'; @override String get tcpStatus_notConnected => 'Zadajte cieľovú adresu a pripojte sa.'; @@ -430,9 +433,7 @@ class AppLocalizationsSk extends AppLocalizations { String get settings_advertLocationSubtitle => 'Zahrnúť polohu do inzerátu'; @override - String settings_multiAck(String value) { - return 'Viaceré ACK: $value'; - } + String get settings_multiAck => 'Viaceré ACK'; @override String get settings_telemetryModeUpdated => @@ -441,6 +442,13 @@ class AppLocalizationsSk extends AppLocalizations { @override String get settings_actions => 'Možné akcie'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Odoslať reklamu'; @@ -482,11 +490,12 @@ class AppLocalizationsSk extends AppLocalizations { String get settings_debug => 'Ladenie'; @override - String get settings_bleDebugLog => 'Log BLE Debug'; + String get settings_companionDebugLog => + 'Logovanie pre ladenie (sprievodný log)'; @override - String get settings_bleDebugLogSubtitle => - 'Príkazy BLE, odpovede a surové dáta'; + String get settings_companionDebugLogSubtitle => + 'Príkazy, odpovede a surové dáta pre protokoly BLE/TCP/USB'; @override String get settings_appDebugLog => 'Záznam ladenia aplikácie'; @@ -499,7 +508,7 @@ class AppLocalizationsSk extends AppLocalizations { @override String settings_aboutVersion(String version) { - return 'MeshCore Open v$version'; + return 'MeshCore, verzia $version'; } @override @@ -517,10 +526,10 @@ class AppLocalizationsSk extends AppLocalizations { String get settings_infoName => 'Meno'; @override - String get settings_infoId => 'ID'; + String get settings_infoId => 'Identifikátor'; @override - String get settings_infoStatus => 'Status'; + String get settings_infoStatus => 'Stav'; @override String get settings_infoBattery => 'Batéria'; @@ -559,7 +568,7 @@ class AppLocalizationsSk extends AppLocalizations { String get settings_txPower => 'TX Výkon (dBm)'; @override - String get settings_txPowerHelper => '0 - 22'; + String get settings_txPowerHelper => '0 – 22'; @override String get settings_txPowerInvalid => 'Neplatná hodnota výkonu TX (0-22 dBm)'; @@ -605,43 +614,43 @@ class AppLocalizationsSk extends AppLocalizations { String get appSettings_languageSystem => 'Predvolený systém'; @override - String get appSettings_languageEn => 'English'; + String get appSettings_languageEn => 'Anglicky'; @override - String get appSettings_languageFr => 'Français'; + String get appSettings_languageFr => 'Francúzština'; @override - String get appSettings_languageEs => 'Español'; + String get appSettings_languageEs => 'Španielsky'; @override - String get appSettings_languageDe => 'Deutsch'; + String get appSettings_languageDe => 'Nemecky'; @override - String get appSettings_languagePl => 'Polski'; + String get appSettings_languagePl => 'Poľský'; @override - String get appSettings_languageSl => 'Slovenščina'; + String get appSettings_languageSl => 'Slovenčina'; @override - String get appSettings_languagePt => 'Português'; + String get appSettings_languagePt => 'Portugalčina'; @override - String get appSettings_languageIt => 'Italiano'; + String get appSettings_languageIt => 'Taliančina'; @override - String get appSettings_languageZh => '中文'; + String get appSettings_languageZh => 'Čínština'; @override - String get appSettings_languageSv => 'Svenska'; + String get appSettings_languageSv => 'Švédska'; @override - String get appSettings_languageNl => 'Nederlands'; + String get appSettings_languageNl => 'Niderlandsky'; @override String get appSettings_languageSk => 'Slovenčina'; @override - String get appSettings_languageBg => 'Български'; + String get appSettings_languageBg => 'Българština'; @override String get appSettings_languageRu => 'Ruština'; @@ -1078,20 +1087,16 @@ class AppLocalizationsSk extends AppLocalizations { return 'Kanál $index'; } - @override - String get channels_hashtagChannel => 'Kanál s hashtagom'; - @override String get channels_public => 'Veľké verejné'; @override - String get channels_private => 'Osobné'; - - @override - String get channels_publicChannel => 'Veľké verejne kanály'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Osobné kanál'; + String get channels_private => 'Osobné'; @override String get channels_editChannel => 'Upraviť kanál'; @@ -1161,11 +1166,67 @@ class AppLocalizationsSk extends AppLocalizations { @override String get channels_smazCompression => 'Odstránenie kompresie SMAZ'; + @override + String get channels_cyr2latCompression => 'Odstránenie kompresie Cyr2Lat'; + + @override + String get channels_cyr2latCompressionDscr => + 'Pri odosielaní nahradí niektoré znaky cyriliky latinskými znakmi.'; + + @override + String get channels_cyr2latSettingsHeading => 'Nastavenia Cyr2Lat'; + + @override + String get channels_cyr2latSettingsSubheading => 'Zoznam nahradení'; + + @override + String get channels_cyr2latSettingsDscr => + 'Upravte konfiguráciu JSON pre nahradenie znakov'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON mapa nahradení'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'Nesprávny JSON: $error'; + } + @override String channels_channelUpdated(String name) { return 'Kanál \"$name\" bol aktualizovaný'; } + @override + String get settings_cyr2latProfileAdd => 'Pridať profil Cyr2Lat'; + + @override + String get settings_cyr2latProfileName => 'Názov profilu'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'Názov profilu nesmie byť prázdny'; + + @override + String get settings_cyr2latProfileAdded => 'Profil bol úspešne pridaný'; + + @override + String get settings_cyr2latProfileUpdated => + 'Profil bol úspešne aktualizovaný'; + + @override + String get settings_cyr2latProfileEdit => 'Upraviť profil Cyr2Lat'; + + @override + String get settings_cyr2latProfileDelete => 'Odstrániť profil Cyr2Lat'; + + @override + String get settings_cyr2latProfileDeleted => 'Profil bol úspešne odstránený'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Naozaj chcete odstrániť profil \"$name\"?'; + } + @override String get channels_publicChannelAdded => 'Veľký kanál pridaný'; @@ -1176,7 +1237,7 @@ class AppLocalizationsSk extends AppLocalizations { String get channels_sortManual => 'Ručne'; @override - String get channels_sortAZ => 'A-Z'; + String get channels_sortAZ => 'Od A po Z'; @override String get channels_sortLatestMessages => 'Posledné správy'; @@ -1350,7 +1411,7 @@ class AppLocalizationsSk extends AppLocalizations { String get debugLog_frames => 'Rámce'; @override - String get debugLog_rawLogRx => 'Raw Log-RX'; + String get debugLog_rawLogRx => 'Čistý log – RX'; @override String get debugLog_noBleActivity => 'Zatiaľ žiadna aktivita BLE.'; @@ -1389,7 +1450,7 @@ class AppLocalizationsSk extends AppLocalizations { } @override - String get debugFrame_textTypeCli => 'CLI'; + String get debugFrame_textTypeCli => 'CLI (Command Line Interface)'; @override String get debugFrame_textTypePlain => 'Jednoduché'; @@ -1400,7 +1461,7 @@ class AppLocalizationsSk extends AppLocalizations { } @override - String get debugFrame_hexDump => 'Hex Dump:'; + String get debugFrame_hexDump => 'Hexová analýza:'; @override String get chat_pathManagement => 'Správa ciest'; @@ -1436,8 +1497,8 @@ class AppLocalizationsSk extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'hops', - one: 'hop', + other: 'skoky', + one: 'skok', ); return '$count $_temp0'; } @@ -1445,6 +1506,9 @@ class AppLocalizationsSk extends AppLocalizations { @override String get chat_successes => 'Úspechy'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Odstrániť cestu'; @@ -1546,6 +1610,12 @@ class AppLocalizationsSk extends AppLocalizations { return 'Nezriadené: $count'; } + @override + String get chat_markAsUnread => 'Označenie ako neprečítané'; + + @override + String get chat_newMessages => 'Nové správy'; + @override String get chat_openLink => 'Otvoriť odkaz?'; @@ -1568,10 +1638,10 @@ class AppLocalizationsSk extends AppLocalizations { String get map_title => 'Mapa uzlov'; @override - String get map_lineOfSight => 'Line of Sight'; + String get map_lineOfSight => 'Úroveň výhľadu'; @override - String get map_losScreenTitle => 'Line of Sight'; + String get map_losScreenTitle => 'Úroveň výhľadu'; @override String get map_noNodesWithLocation => 'Žiadne uzly s údajmi o polohe'; @@ -1627,6 +1697,24 @@ class AppLocalizationsSk extends AppLocalizations { @override String get map_flags => 'Zástavy'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'Zdieľte značku tu'; @@ -1712,6 +1800,9 @@ class AppLocalizationsSk extends AppLocalizations { @override String get map_sharedPin => 'Zdieľaný PIN'; + @override + String get map_sharedAt => 'Zdieľané'; + @override String get map_joinRoom => 'Pripojiť miestnosť'; @@ -2017,7 +2108,7 @@ class AppLocalizationsSk extends AppLocalizations { String get repeater_guestTools => 'Nástroje pre hostí'; @override - String get repeater_status => 'Status'; + String get repeater_status => 'Stav'; @override String get repeater_statusSubtitle => @@ -2031,7 +2122,7 @@ class AppLocalizationsSk extends AppLocalizations { 'Zobraziť telemetriu senzorov a systémových štatistík'; @override - String get repeater_cli => 'CLI'; + String get repeater_cli => 'CLI (Command Line Interface)'; @override String get repeater_cliSubtitle => 'Pošlite príkazy opakovaču'; @@ -2119,6 +2210,9 @@ class AppLocalizationsSk extends AppLocalizations { @override String get repeater_rxAirtime => 'RX Airtime'; + @override + String get repeater_chanUtil => 'Využitie kanálu'; + @override String get repeater_packetStatistics => 'Statistiky balíka'; @@ -2192,7 +2286,7 @@ class AppLocalizationsSk extends AppLocalizations { String get repeater_frequencyMhz => 'Frekvencia (MHz)'; @override - String get repeater_frequencyHelper => '300-2500 MHz'; + String get repeater_frequencyHelper => '300–2500 MHz'; @override String get repeater_txPower => 'TX Power'; @@ -2325,6 +2419,163 @@ class AppLocalizationsSk extends AppLocalizations { @override String get repeater_settingsSaved => 'Nastavenia boli uložené úspešne.'; + @override + String get repeater_rxGain => 'Zvýšený zisk RX'; + + @override + String get repeater_rxGainHelper => + 'Vyššia citlivosť, vyšší príkon (platí len pre modely SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => 'Obnovte zvýšený zisk z RX'; + + @override + String get repeater_multiAcks => 'Víťazné potvrdenia (víťazné ACK)'; + + @override + String get repeater_multiAcksSubtitle => + 'Potvrďte správy prostredníctvom viacerých trás pre lepšiu doručenie.'; + + @override + String get repeater_refreshMultiAcks => + 'Opätovne potvrďte viacero ACK signálov'; + + @override + String get repeater_networkHealth => 'Zdravie siete'; + + @override + String get repeater_loopDetect => 'Detekcia slučiek'; + + @override + String get repeater_loopDetectHelper => + 'Vytvorte balíčky, ktoré vizuálne pripomínajú slučky v síti.'; + + @override + String get repeater_loopDetectOff => 'Vypnuté'; + + @override + String get repeater_loopDetectMinimal => 'Minimálny'; + + @override + String get repeater_loopDetectModerate => 'Stredný, mierny'; + + @override + String get repeater_loopDetectStrict => 'Prísne'; + + @override + String get repeater_dutyCycle => 'Cyklus činnosti'; + + @override + String get repeater_dutyCycleHelper => + 'Maximálna percentáľ dostupného času vysielania'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Informácie o poskytovateľovi'; + + @override + String get repeater_ownerInfoHelper => + 'Veľké dátové informácie pre tento vysielací zdroj'; + + @override + String get repeater_refreshOwnerInfo => 'Zísť informácie o operátore'; + + @override + String get repeater_floodMax => 'Maximálny počet skokov pri povodni'; + + @override + String get repeater_floodMaxHelper => + 'Maximálny počet paketov, ktoré môžu preletieť cez jeden hop (0-64)'; + + @override + String get repeater_advancedSettings => 'Pokročilé'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Ovládacie knopy pre skúsených operátorov'; + + @override + String get repeater_pathHashMode => 'Režim hashovania cesty'; + + @override + String get repeater_pathHashModeHelper => + 'Byty použité na zakódovanie ID tohto opakovača v tagoch pre trasu/detekciu slučky. 0 = 1 bytu (256 ID, až 64 skokov), 1 = 2 byty (65 000 ID, až 32 skokov), 2 = 3 byty (16 miliónov ID, až 21 skokov). Verzie 1.13 a staršie nepodporujú viacbytové trasy – fungujú len, keď je sieť aktivovaná.'; + + @override + String get repeater_txDelay => 'Zpoždanie v Flood, TX'; + + @override + String get repeater_txDelayHelper => + 'Nastavenie pre opakované vysielanie pre dopravu počas povodní, ako násobok času, ktorý paket využije (0-2, výchoce hodnota 0,5). Vyššia hodnota znamená menej kolízii, ale pomalšie doručovanie.'; + + @override + String get repeater_directTxDelay => 'Priame oneskorenie TX'; + + @override + String get repeater_directTxDelayHelper => + 'Nastavenie pre retransmisiu pre priame (nie pre plnú sieť), ako násobok času prenosu paketov (0-2, výchoce 0,3).'; + + @override + String get repeater_intThresh => 'Hranica, pri ktorej dochádza k rušeniu'; + + @override + String get repeater_intThreshHelper => + 'Hranica je nastavená tak, aby odfiltrovala šum nad touto úrovňou. Hodnota 0 znamená, že sa nebude nič odfiltrovať – nastavte ju len v prípade, že zaznamenáte chyby pri prijímaní signálu v šumnej frekvencii.'; + + @override + String get repeater_agcResetInterval => 'Interval reštartu AGC'; + + @override + String get repeater_agcResetIntervalHelper => + 'Ako často by ste mali reštartovať automatické ovládanie zosilnenia, aby ste sa vrátili do normálneho stavu, ak je zosilnenie zablokované? Nastavenie „4.0“ vypne pravidelné reštarty.'; + + @override + String get repeater_actionsTitle => 'Opatrenia'; + + @override + String get repeater_sendAdvert => 'Odoslať inzerát o povodňovej situácii'; + + @override + String get repeater_sendAdvertSubtitle => + 'Zverejnite reklamu na povodňu prostredníctvom siete.'; + + @override + String get repeater_sendAdvertZeroHop => 'Odoslať reklamu bez prenosu'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Zverejnite reklamnú správu, ktorá sa prenáša len raz (bez prenosov).'; + + @override + String get repeater_clockSync => 'Synchronizujte hodiny teraz'; + + @override + String get repeater_clockSyncSubtitle => + 'Nastavte čas na vašom telefóne, aby odpovedal na volania z vysielacieho zariadenia.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action succeeded'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action failed: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Nastavenia uložené – reštartujte vysielací prístroj, aby sa nastavenia aplikovali.'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Niektoré nastavenia neúspešné: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Chyba pri ukladaní nastavení: $error'; @@ -2339,9 +2590,6 @@ class AppLocalizationsSk extends AppLocalizations { @override String get repeater_refreshTxPower => 'Obnoviť TX napájanie'; - @override - String get repeater_refreshLocationSettings => 'Obnoviť Nastavenia Miesta'; - @override String get repeater_refreshPacketForwarding => 'Obnoviť smerovanie paketov'; @@ -2351,10 +2599,6 @@ class AppLocalizationsSk extends AppLocalizations { @override String get repeater_refreshPrivacyMode => 'Obnoviť Ochranný režim'; - @override - String get repeater_refreshAdvertisementSettings => - 'Obnoviť nastavenia reklamy'; - @override String repeater_refreshed(String label) { return '$label sa znova načítalo'; @@ -2679,6 +2923,284 @@ class AppLocalizationsSk extends AppLocalizations { String get repeater_gpsNote => 'GPS príkaz bol zavádzaný na riadenie lokalitných tém.'; + @override + String get repeater_getCategory => 'Zísť hodnoty'; + + @override + String get repeater_powerMgmt => 'Správa energie'; + + @override + String get repeater_sensors => 'Senzory'; + + @override + String get repeater_cliHelpPowerOff => + 'Vypína zariadenie. (neočakáva sa žiadna odpoveď)'; + + @override + String get repeater_cliHelpClkReboot => + 'Resetuje hodiny na známu epochu a reštartuje zariadenie.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Rozosiela reklamu, ktorá sa prenáša len medzi susednými zariadeniami (bez prenosu cez iné siete).'; + + @override + String get repeater_cliHelpStartOta => + 'Spustí aktualizáciu firmvéru prostredníctvom diaľkového prenosu na podporovaných doskách.'; + + @override + String get repeater_cliHelpTime => + 'Nastavuje časovník zariadenia na zadané sekundy od Unix epochy. Časovník sa nedá otáčať dozadu.'; + + @override + String get repeater_cliHelpBoard => + 'Zobrazuje informácie o výrobcom dosky / identifikátor hardvéru.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Odosiela požiadavku na nájdenie susedných uzlov. (Len pre opakovače)'; + + @override + String get repeater_cliHelpPowersaving => + 'Ukazuje, či je režim úspory energie zapnutý alebo vypnutý.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Umožňuje alebo vypína režim úspory energie (ak je podporovaný).'; + + @override + String get repeater_cliHelpErase => + '(Používa sa len pre sériové zariadenia) Formátuje systém súborov zariadenia. Vymaže všetky nastavenia a kontakty.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Nastavuje maximálnu povolenú frekvenciu prenosu ako percento (1-100). Internálne upravuje faktor času prenosu.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Používa sa len v sériovej verzii) Nahradí privátny kľúč, ktorý identifikuje zariadenie. Po aplikácii je potrebné zariadenie reštartovať. Generuje nový verejný kľúč.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(iba pre SX126x) Zapína zvýšený zisk prijímania pre zlepšenie citlivosti pri vyššom príkonu.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Definuje reťazec s informáciami o kontaktnom osobě, ktorý je zahrnutý v reklamách. Používajte \'|\' pre nové riadky.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Nastavuje režim hashovania cesty. 0 = starý režim, 1 = štandardný režim, 2 = striktný režim. Ovplyvňuje, ako sa prekladajú trasy.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Nastavuje citlivosť detekcie slučky routovania: vypnutá, minimálna, stredná alebo prísna.'; + + @override + String get repeater_cliHelpSetFreq => + '(Používa sa len v sériovej verzii) Rýchlo nastavuje len frekvenciu. Je potrebné reštartovať. Pre úplné nastavenie rádia preferujte funkciu \"nastavenie rádia\".'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Používa sa len pre ESPNow most) Nastavuje WiFi kanál (1-14), ktorý používa most.'; + + @override + String get repeater_cliHelpGetName => 'Zobrazuje zadané meno uzla.'; + + @override + String get repeater_cliHelpGetRole => + 'Ukazuje funkciu firmvéru (opakovač, server pre miestnosť atď.).'; + + @override + String get repeater_cliHelpGetPublicKey => + 'Zobrazuje verejný kľúč zariadenia.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Používa sa len v sériových aplikáciách) Zobrazuje súkromný kľúč zariadenia. Zotriďte ho ako tajný údaj.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Ukazuje, či je funkcia preposielania paketov (funkcia opakéra) zapnutá alebo vypnutá.'; + + @override + String get repeater_cliHelpGetTx => + 'Zobrazuje aktuálnu výkonovú hodnotu TX v dBm.'; + + @override + String get repeater_cliHelpGetFreq => + 'Zobrazuje nakonfigurovanú frekvenciu v MHz.'; + + @override + String get repeater_cliHelpGetRadio => + 'Zobrazuje všetky parametre rádiového signálu: frekvencia, šírka pásma, faktor rozširovania, rýchlosť kódovania.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(iba pre SX126x) Zobrazuje stav zosilnenia prijímača RX.'; + + @override + String get repeater_cliHelpGetAf => + 'Zobrazuje aktuálny koeficient času vysielania.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Zobrazuje aktuálnu povolenú frekvenciu ako percentáž.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Zobrazuje hranicu pre prechodové signály v dB.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Zobrazuje interval reštartovania AGC v sekundách.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Ukazuje, či je režim dvojité potvrdenie zapnutý (1) alebo vypnutý (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Ukazuje, či je povolená len čítacia funkcia pre hostí.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Zobrazuje čas trvania miestnej reklamnej pauzy v minútach.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Zobrazuje časový interval reklamy počas záplavy v hodinách.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Zobrazuje nastavené heslo pre hosta.'; + + @override + String get repeater_cliHelpGetLat => 'Zobrazuje nastavenú šírku.'; + + @override + String get repeater_cliHelpGetLon => 'Zobrazuje nastavenú dĺžku.'; + + @override + String get repeater_cliHelpGetRxDelay => + 'Zobrazuje základnú hodnotu rxdelay.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Ukazuje faktor zpoždenia pre režim povodňovej komunikácie.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Zobrazuje faktor zloženia pri priamej modulácii.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Zobrazuje maximálny počet opakovaní povodňového stavu.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Zobrazuje reťazec s kontaktnými údajmi vlastníka.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Zobrazuje režim hashovania cesty (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Ukazuje citlivosť na detekciu slučiek.'; + + @override + String get repeater_cliHelpGetAcl => + '(Používa sa len v sériovej konfigurácii) Zobrazuje prístupové pravidlá na opakovači.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Ukazuje, či je most povolený.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Zobrazuje čas strávený prechodom mosta v milisekundách.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Ukazuje, či most prijíma alebo vysiela RX alebo TX balíky.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(iba pre rozhranie RS232) Zobrazuje rýchlosť prenosu dát na rozhraní RS232.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Používa sa len pre ESPNow) Zobrazuje WiFi kanál mosta.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Používa sa len pre ESPNow most) Zobrazuje spoločný tajný kľúč mosta.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(iba pre NRF52) Zobrazuje verziu bootloaderu.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Zobrazuje násobič ADC (škálovanie napätia batérie).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Označuje, či riadiace orgány majú podporu pre správu energie.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Ukazuje aktuálny zdroj napájania: externý alebo batéria.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Zobrazuje najaktuálnejšie dôvody pre reštart a vypnutie.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Zobrazuje napätie batérie pri spustení systému v milivoltov (mV).'; + + @override + String get repeater_cliHelpSensorGet => + 'Číta hodnotu nastavenia pre špecifický senzor pomocou klávesového vstupu.'; + + @override + String get repeater_cliHelpSensorSet => + 'Vytvára vlastné nastavenie pre senzor.'; + + @override + String get repeater_cliHelpSensorList => + 'Zobrazuje všetky nastavenia pre špecifické senzory, zoradené podľa voliteľného indexu začiatku.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Zobrazuje aktuálnu rozsiahku, ktorá je nastavená ako výchozí.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Nastavuje výchoce rozsiahku regiónu. Použite \"\", aby ju vymazal.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Zoznam oblastí, ktoré umožňujú premávku počas povodní.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Zoznam oblastí, ktoré zakazujú premávku v dôsledku povodní.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Len pre sériové záznamy) Zobrazuje štatistiky na úrovni paketov.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Len pre sériu) Zobrazuje údaje o rádiových staniciach.'; + + @override + String get repeater_cliHelpStatsCore => + '(Len pre sériové modely) Zobrazuje základné štatistiky firmvéru.'; + @override String get telemetry_receivedData => 'Obdolené Telemetrické dáta'; @@ -3046,7 +3568,7 @@ class AppLocalizationsSk extends AppLocalizations { String get listFilter_heardRecently => 'Nedávno počuli.'; @override - String get listFilter_az => 'A-Z'; + String get listFilter_az => 'Od A po Z'; @override String get listFilter_filters => 'Filtre'; @@ -3216,6 +3738,37 @@ class AppLocalizationsSk extends AppLocalizations { @override String get losLegendTerrain => 'Terén'; + @override + String get losBlockedSpotsTitle => 'Zablokované miesta'; + + @override + String get losBlockedSpotsHint => + 'Kliknite na zablokované miesto, aby ste ho zvýraznili na mape.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Vybraná prekážka'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Frekvencia'; @@ -3680,4 +4233,40 @@ class AppLocalizationsSk extends AppLocalizations { @override String get translation_systemLanguage => 'Jazyk systému'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_sl.dart b/lib/l10n/app_localizations_sl.dart index 2d89aa4..4810364 100644 --- a/lib/l10n/app_localizations_sl.dart +++ b/lib/l10n/app_localizations_sl.dart @@ -44,6 +44,9 @@ class AppLocalizationsSl extends AppLocalizations { @override String get common_close => 'Zapri'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Uredi'; @@ -105,11 +108,11 @@ class AppLocalizationsSl extends AppLocalizations { @override String common_percentValue(int percent) { - return '$percent%'; + return '$percent %'; } @override - String get scanner_title => 'MeshCore Open'; + String get scanner_title => 'MeshCore – Odprto'; @override String get connectionChoiceUsbLabel => 'USB'; @@ -430,9 +433,7 @@ class AppLocalizationsSl extends AppLocalizations { String get settings_advertLocationSubtitle => 'Vključi lokacijo v oglas.'; @override - String settings_multiAck(String value) { - return 'Večkratni potrditvi: $value'; - } + String get settings_multiAck => 'Več potrdil'; @override String get settings_telemetryModeUpdated => 'Način telemetrije posodobljen'; @@ -440,6 +441,13 @@ class AppLocalizationsSl extends AppLocalizations { @override String get settings_actions => 'Akcije'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Pošlji Oglas'; @@ -477,14 +485,14 @@ class AppLocalizationsSl extends AppLocalizations { 'Ste prepričani, da želite ponovno zagnati napravo? Povezava bo prekinjena.'; @override - String get settings_debug => 'Debug'; + String get settings_debug => 'Odpravljanje napak'; @override - String get settings_bleDebugLog => 'BLE debug log (razhroščevanje)'; + String get settings_companionDebugLog => 'Log zapis za odpravljanje napak'; @override - String get settings_bleDebugLogSubtitle => - 'BLE ukazi, odgovori in surovi podatki'; + String get settings_companionDebugLogSubtitle => + 'Navodila, odgovori in surova podatka za BLE/TCP/USB.'; @override String get settings_appDebugLog => 'Logi aplikacije'; @@ -497,7 +505,7 @@ class AppLocalizationsSl extends AppLocalizations { @override String settings_aboutVersion(String version) { - return 'MeshCore Open v$version'; + return 'MeshCore, različ $version'; } @override @@ -518,7 +526,7 @@ class AppLocalizationsSl extends AppLocalizations { String get settings_infoId => 'ID'; @override - String get settings_infoStatus => 'Status'; + String get settings_infoStatus => 'Stanje'; @override String get settings_infoBattery => 'Baterija'; @@ -557,7 +565,7 @@ class AppLocalizationsSl extends AppLocalizations { String get settings_txPower => 'TX Moč (dBm)'; @override - String get settings_txPowerHelper => '0 - 22'; + String get settings_txPowerHelper => '0 – 22'; @override String get settings_txPowerInvalid => 'Neveljavna TX moč (0-22 dBm)'; @@ -603,40 +611,40 @@ class AppLocalizationsSl extends AppLocalizations { String get appSettings_languageSystem => 'Sistemska privzeta vrednost'; @override - String get appSettings_languageEn => 'English'; + String get appSettings_languageEn => 'Angleščina'; @override - String get appSettings_languageFr => 'Français'; + String get appSettings_languageFr => 'Francija'; @override - String get appSettings_languageEs => 'Español'; + String get appSettings_languageEs => 'Španščina'; @override - String get appSettings_languageDe => 'Deutsch'; + String get appSettings_languageDe => 'Nemščina'; @override - String get appSettings_languagePl => 'Polski'; + String get appSettings_languagePl => 'Poljski'; @override String get appSettings_languageSl => 'Slovenščina'; @override - String get appSettings_languagePt => 'Português'; + String get appSettings_languagePt => 'Portugalski'; @override - String get appSettings_languageIt => 'Italiano'; + String get appSettings_languageIt => 'Italijanščina'; @override String get appSettings_languageZh => '中文'; @override - String get appSettings_languageSv => 'Svenska'; + String get appSettings_languageSv => 'Švedska'; @override - String get appSettings_languageNl => 'Nederlands'; + String get appSettings_languageNl => 'Nizozemsko'; @override - String get appSettings_languageSk => 'Slovenčina'; + String get appSettings_languageSk => 'Slovenščina'; @override String get appSettings_languageBg => 'Български'; @@ -1076,20 +1084,16 @@ class AppLocalizationsSl extends AppLocalizations { return 'Kanal $index'; } - @override - String get channels_hashtagChannel => 'Hashtag kanal'; - @override String get channels_public => 'Javni'; @override - String get channels_private => 'Zasebni'; - - @override - String get channels_publicChannel => 'Javni kanal'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Zasebni kanal'; + String get channels_private => 'Zasebni'; @override String get channels_editChannel => 'Uredi kanal'; @@ -1159,11 +1163,67 @@ class AppLocalizationsSl extends AppLocalizations { @override String get channels_smazCompression => 'Kompresija SMAZ'; + @override + String get channels_cyr2latCompression => 'Kompresija Cyr2Lat'; + + @override + String get channels_cyr2latCompressionDscr => + 'Pri pošiljanju nekatere cirilice nadomesti z latiničnimi.'; + + @override + String get channels_cyr2latSettingsHeading => 'Nastavitve Cyr2Lat'; + + @override + String get channels_cyr2latSettingsSubheading => 'Seznam zamenjav'; + + @override + String get channels_cyr2latSettingsDscr => + 'Uredi JSON-konfiguracijo zamenjav znakov'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON-tabela zamenjav'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'Nepravilen JSON: $error'; + } + @override String channels_channelUpdated(String name) { return 'Kanal $name je bil posodobljen'; } + @override + String get settings_cyr2latProfileAdd => 'Dodaj profil Cyr2Lat'; + + @override + String get settings_cyr2latProfileName => 'Ime profila'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'Ime profila ne sme biti prazno'; + + @override + String get settings_cyr2latProfileAdded => 'Profil je bil uspešno dodan'; + + @override + String get settings_cyr2latProfileUpdated => + 'Profil je bil uspešno posodobljen'; + + @override + String get settings_cyr2latProfileEdit => 'Uredi profil Cyr2Lat'; + + @override + String get settings_cyr2latProfileDelete => 'Izbriši profil Cyr2Lat'; + + @override + String get settings_cyr2latProfileDeleted => 'Profil je bil uspešno izbrisan'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Ali res želite izbrisati profil \"$name\"?'; + } + @override String get channels_publicChannelAdded => 'javna skupnost dodana'; @@ -1174,7 +1234,7 @@ class AppLocalizationsSl extends AppLocalizations { String get channels_sortManual => 'Ročno'; @override - String get channels_sortAZ => 'A-Z'; + String get channels_sortAZ => 'A do Z'; @override String get channels_sortLatestMessages => 'Najnovejše sporočilo'; @@ -1387,7 +1447,7 @@ class AppLocalizationsSl extends AppLocalizations { } @override - String get debugFrame_textTypeCli => 'CLI'; + String get debugFrame_textTypeCli => 'CLI (Command Line Interface)'; @override String get debugFrame_textTypePlain => 'Preprosto'; @@ -1398,7 +1458,7 @@ class AppLocalizationsSl extends AppLocalizations { } @override - String get debugFrame_hexDump => 'Hex Dump:'; + String get debugFrame_hexDump => 'Izpis heksadecimalnih vrednosti:'; @override String get chat_pathManagement => 'Upravljanje poti'; @@ -1433,8 +1493,8 @@ class AppLocalizationsSl extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'hops', - one: 'hop', + other: 'skoki', + one: 'skok', ); return '$count $_temp0'; } @@ -1442,6 +1502,9 @@ class AppLocalizationsSl extends AppLocalizations { @override String get chat_successes => 'Uspešni'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Izbriši pot'; @@ -1541,6 +1604,12 @@ class AppLocalizationsSl extends AppLocalizations { return 'Nerešeno: $count'; } + @override + String get chat_markAsUnread => 'Označiti kot neneobdelano'; + + @override + String get chat_newMessages => 'Nove novice'; + @override String get chat_openLink => 'Odpreti povezavo?'; @@ -1623,6 +1692,24 @@ class AppLocalizationsSl extends AppLocalizations { @override String get map_flags => 'Zapestnice'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'Delite točke tukaj.'; @@ -1707,6 +1794,9 @@ class AppLocalizationsSl extends AppLocalizations { @override String get map_sharedPin => 'Deljeno naslovno geslo'; + @override + String get map_sharedAt => 'Deljeno'; + @override String get map_joinRoom => 'Pridružiti sobo'; @@ -2014,7 +2104,7 @@ class AppLocalizationsSl extends AppLocalizations { String get repeater_guestTools => 'Naložila za goste'; @override - String get repeater_status => 'Status'; + String get repeater_status => 'Stanje'; @override String get repeater_statusSubtitle => @@ -2028,7 +2118,7 @@ class AppLocalizationsSl extends AppLocalizations { 'Pogledate telemetrijo senzorjev in sistemske statistike'; @override - String get repeater_cli => 'CLI'; + String get repeater_cli => 'CLI (Command Line Interface)'; @override String get repeater_cliSubtitle => @@ -2116,6 +2206,9 @@ class AppLocalizationsSl extends AppLocalizations { @override String get repeater_rxAirtime => 'RX Airtime'; + @override + String get repeater_chanUtil => 'Uporaba kanala'; + @override String get repeater_packetStatistics => 'Statistika paketa'; @@ -2189,7 +2282,7 @@ class AppLocalizationsSl extends AppLocalizations { String get repeater_frequencyMhz => 'Frekvenca (MHz)'; @override - String get repeater_frequencyHelper => '300-2500 MHz'; + String get repeater_frequencyHelper => '300–2500 MHz'; @override String get repeater_txPower => 'TX Moč'; @@ -2323,6 +2416,162 @@ class AppLocalizationsSl extends AppLocalizations { @override String get repeater_settingsSaved => 'Nastavitve so shranjene uspešno.'; + @override + String get repeater_rxGain => 'Povečana dobitka RX'; + + @override + String get repeater_rxGainHelper => + 'Veća občutljivost, večji porabljeni tok (velja samo za SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => 'Povečana dobitka RX, posodobit'; + + @override + String get repeater_multiAcks => 'Več potrdil'; + + @override + String get repeater_multiAcksSubtitle => + 'Potrdite sporočila po več poti za boljši dostop'; + + @override + String get repeater_refreshMultiAcks => 'Ponovite več potrdil'; + + @override + String get repeater_networkHealth => 'Zdravilo omrežja'; + + @override + String get repeater_loopDetect => 'Detekcija ciklov'; + + @override + String get repeater_loopDetectHelper => + 'Izpišite pakete, ki izgledajo kot pete v omrežju.'; + + @override + String get repeater_loopDetectOff => 'Izklopljeno'; + + @override + String get repeater_loopDetectMinimal => 'Minimalen'; + + @override + String get repeater_loopDetectModerate => 'Umiren'; + + @override + String get repeater_loopDetectStrict => 'Strogi'; + + @override + String get repeater_dutyCycle => 'Ciklus delovanja'; + + @override + String get repeater_dutyCycleHelper => + 'Najvišji odstotek časa, ki ga lahko posreduje.'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent %'; + } + + @override + String get repeater_ownerInfo => 'Informacije o operaterju'; + + @override + String get repeater_ownerInfoHelper => 'javni podatki o tej napravi'; + + @override + String get repeater_refreshOwnerInfo => 'Prejmi informacije o operaterju'; + + @override + String get repeater_floodMax => 'Največji možni odmerek'; + + @override + String get repeater_floodMaxHelper => + 'Največje število paketov, ki lahko potujejo v enem plovilnem paketu (0-64)'; + + @override + String get repeater_advancedSettings => 'Napredno'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Gumbi za nastavljanje za izkušene uporabnike'; + + @override + String get repeater_pathHashMode => 'Način ustvarjanja hash-a poti'; + + @override + String get repeater_pathHashModeHelper => + 'Biti, ki so bila uporabljena za kodiranje ID-ja tega releja v oznakah za zaznavanje pot/kroga, imajo naslednje velikosti: 0=1 bit (256 ID-jev, do 64 skokov), 1=2 biti (65.000 ID-jev, do 32 skokov), 2=3 biti (16 milijonov ID-jev, do 21 skokov). V različicah 1.13 in starejših se ustvarjajo večbitne poti – vendar se to zgodi šele, ko je omrežje vklopljeno v različicah 1.14 in kasnejših.'; + + @override + String get repeater_txDelay => 'Zatemnitevanje zaradi poplav v Texasu'; + + @override + String get repeater_txDelayHelper => + 'Uporaba intervalov za ponovno pošiljanje v primeru prometa zaradi poplav, kot pomnožnik časovne trajanje paketa (0-2, privzeto 0,5). Veje vrednost = manjše kolizije, vendar počasnejše dostavo.'; + + @override + String get repeater_directTxDelay => 'Neposredni časovno odlašanje'; + + @override + String get repeater_directTxDelayHelper => + 'Razdalja za ponovno pošiljanje za neposredno (neobvezen) promet, kot pomnožnik časovne trajanja paketa (0-2, privzeto 0,3).'; + + @override + String get repeater_intThresh => 'Meja, pri kateri nastane motnja'; + + @override + String get repeater_intThreshHelper => + 'Tretja stopnja se uporablja za kalibracijo šumnega nivoja radija, kar omogoča, da se izklaplja pri šumu, ki presega to raven. 0 izklopi – uporabite le, če zaznate napake v šumnem pasu.'; + + @override + String get repeater_agcResetInterval => 'Interval ponovne kalibracije AGC'; + + @override + String get repeater_agcResetIntervalHelper => + 'Kako pogosto je treba ponovno nastaviti samodejno regulacijo občutljivosti, da se vrnete v normalno stanje? Interval je nastavljen na nekaj sekund, natančno na 4. 0 izklopi periodično ponovno nastavljanje.'; + + @override + String get repeater_actionsTitle => 'Dejanja'; + + @override + String get repeater_sendAdvert => 'Pošlji oglas o poplavah'; + + @override + String get repeater_sendAdvertSubtitle => + 'Razpustite oglas o poplavah preko omrežja.'; + + @override + String get repeater_sendAdvertZeroHop => + 'Pošlji oglas, ki ne potrebuje posrednika.'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Premejte oglas, ki uporablja eno povezavo (brez posrednikov).'; + + @override + String get repeater_clockSync => 'Sinerizirajte uro zdaj'; + + @override + String get repeater_clockSyncSubtitle => + 'Nastavite čas na telefonu, da se sinhronizira s repeatrom.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action je uspel'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action ni bilo uspešno: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Nastavitve shranjene – ponovni zagon repetitorja za uporabo'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Nekatna nastavitva niso uspešna: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Napaka pri shranjevanju nastavitev: $error'; @@ -2338,10 +2587,6 @@ class AppLocalizationsSl extends AppLocalizations { @override String get repeater_refreshTxPower => 'Ponovno nastavi TX moč'; - @override - String get repeater_refreshLocationSettings => - 'Ponovno Nastavi Nastavitve Lokacije'; - @override String get repeater_refreshPacketForwarding => 'Ponovno nastavitve usmerjevanja paketa'; @@ -2353,10 +2598,6 @@ class AppLocalizationsSl extends AppLocalizations { String get repeater_refreshPrivacyMode => 'Ponovno aktiviraj način zasebnosti'; - @override - String get repeater_refreshAdvertisementSettings => - 'Ponovno nastavi Oglede Oglasi'; - @override String repeater_refreshed(String label) { return '$label je bil/a posodobljen/a'; @@ -2680,6 +2921,281 @@ class AppLocalizationsSl extends AppLocalizations { String get repeater_gpsNote => 'GPS ukaz je bil uveden za upravljanje z vprašanji, povezanimi z lokacijo.'; + @override + String get repeater_getCategory => 'Dobite vrednosti'; + + @override + String get repeater_powerMgmt => 'Upravljanje z energijo'; + + @override + String get repeater_sensors => 'Senzori'; + + @override + String get repeater_cliHelpPowerOff => + 'Izklopi naprave. (ne pričakujemo odziva)'; + + @override + String get repeater_cliHelpClkReboot => + 'Ponovno nastavi uro na znano točko in ponovno vklopi naprave.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Pošlje oglas, ki doseže samo neposredne sosede (brez posredovanja).'; + + @override + String get repeater_cliHelpStartOta => + 'Začne nadstrekovno ažuriranje programne opreme na podprtih ploščah.'; + + @override + String get repeater_cliHelpTime => + 'Nastavi časovni ukaz naprave na podano število sekund od Unixovega začetka. Časovni ukaz ne more iti nazaj.'; + + @override + String get repeater_cliHelpBoard => + 'Prikaže proizvajalca plošče / identifikator strojne opreme.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Pošlje zahtevo za odkrivanje sosednjih naprav. (Samo za repeatere)'; + + @override + String get repeater_cliHelpPowersaving => + 'Prikaže, ali je vklopljen način varčevanja z energijo.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Omogoča ali onemogoča način varčevanja z energijo (če je podprt).'; + + @override + String get repeater_cliHelpErase => + '(Samo za serijske naprave) Formira datotapno sistemsko okolje. Izbriše vse nastavitve in kontakte.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Določi maksimalni dovoljeni čas, ki ga naprave lahko posredujejo, v odstotkih (1-100). Samodejno prilagodi faktor, ki odvisen je od časa, ki ga naprave lahko posredujejo.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Samo za serijske naprave) Nadomesti zasebni ključ za identifikacijo naprave. Za uporabo je potrebna ponovna aktivacija. Ustvari nov javni ključ.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(Samo za SX126x) Vklopi povečano občutljivost RX za izboljšano delovanje pri večjih navorih.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Določi niz z informacijami o kontaktni osebi, ki je v oglasih. Za uporabo novih vrstic uporabite \'|\'.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Nastavlja način \"hash poti\". 0 = za stare sisteme, 1 = za standard, 2 = za stroge. Vpliva na to, kako so poti uskladene.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Nastavlja občutljivost detekcije ponavljajočih se povezav: izklopljeno, minimalno, umeren, ali strogo.'; + + @override + String get repeater_cliHelpSetFreq => + '(Samo za serijske naprave) Hitro nastavi samo frekvenco. Potrebna je ponovna aktivacija. Za popolno nastavitev radio parametrov je priporočljivo uporabiti možnost \"nastavitev radia\".'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Samo za most ESPNow) Nastavlja kanal WiFi-ja (1-14), ki ga uporablja most.'; + + @override + String get repeater_cliHelpGetName => 'Prikaže ime konfigurirane notranje.'; + + @override + String get repeater_cliHelpGetRole => + 'Prikaže vlogo programskega oprema (repeater, strežnik za sobo itd.).'; + + @override + String get repeater_cliHelpGetPublicKey => 'Prikazuje javni ključ naprave.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Samo za serijske naprave) Prikazuje zasebni ključ naprave. Sprejemajte ga kot skrivno informacijo.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Pokaže, ali je omogočeno posredovanje paketov (delovanje kot repetitor).'; + + @override + String get repeater_cliHelpGetTx => 'Prikazuje trenutno moč TX v dBm.'; + + @override + String get repeater_cliHelpGetFreq => 'Prikaže nastavljeno frekvenco v MHz.'; + + @override + String get repeater_cliHelpGetRadio => + 'Prikaže vse parametre radija: frekvenco, širino pasu, faktor razširjanja, raven kodiranja.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(Samo za SX126x) Prikazuje stanje povečanega dobiča na RX.'; + + @override + String get repeater_cliHelpGetAf => + 'Prikazuje trenutni faktor, ki določa časovno obdobje.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Prikazuje trenutno dovoljeno stopnjo delovanja kot odstotek.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Prikazuje prag medsebojnega vpliva kanala v dB.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Prikazuje interval ponovne kalibracije AGC v sekundah.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Pokaže, ali je vklopljen način dvojnega potrdila (1) ali je izklopljen (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Pokaže, ali je omogočen le brani dostop za goste.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Prikazuje časovno obdobje lokalne reklame v minutah.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Prikaže časovno obdobje, ko se prikazuje oglas o poplavah, v urah.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Prikaže nastavljeno geslo za gostitelja.'; + + @override + String get repeater_cliHelpGetLat => 'Prikaže določeno zemljepisno širino.'; + + @override + String get repeater_cliHelpGetLon => 'Prikaže določeno merilo dolžine.'; + + @override + String get repeater_cliHelpGetRxDelay => + 'Prikazuje osnovno vrednost RX odlašanja.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Prikazuje faktor zamude v načinu delovanja pri plavlju.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Prikazuje faktor odlašanja signala v režimu neposredne komunikacije.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Prikazuje največjo število, kolikokrat lahko voda doseže najvišjo višino.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Prikazuje niz z informacijami o lastniku.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Prikaže način delovanja z hashjem poti (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Prikazuje občutljivost na zaznavanje ciklov.'; + + @override + String get repeater_cliHelpGetAcl => + '(Samo za serije) Navaja vnos za nadzor dostopa na ponovljalniku.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Pokaže, ali je most omogočen.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Prikazuje zamik mosta v milisekundah.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Pokaže, ali most prenaša pakete RX ali TX.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Samo za most RS232) Prikazuje hitrost prenosa podatkov na mostu.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Samo za most ESPNow) Prikazuje kanal WiFi mosta.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Samo za most ESPNow) Prikazuje tajno, ki jo deli most.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(Samo za NRF52) Prikazuje različico programskega orodja.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Prikazuje pomnoževalnik ADC (skaliranje napetosti baterije).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Navaja, ali ima uprava področje za upravljanje z energijo.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Prikaže trenutni vir napajanja: zunanji ali baterija.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Prikazuje najnovejšo razlog za ponovno nastavitve in izklop.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Prikazuje napetost baterije v mV ob zagonu.'; + + @override + String get repeater_cliHelpSensorGet => + 'Prebere določeno vrednost senzorja preko tipke.'; + + @override + String get repeater_cliHelpSensorSet => + 'Ustvari prilagojeno nastavitev za senzor.'; + + @override + String get repeater_cliHelpSensorList => + 'Navaja vse nastavitve za uporabniške senzorje, razvrščene po želeni začetni indeksu.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Prikaže trenutno privzeto območje.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Določi privzeto območje. Za izbris uporabite \"\".'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Navaja regije, ki dovoljujejo promet v času poplav.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Navaja regije, ki preprečujejo promet zaradi poplav.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Samo za serijske povezave) Prikazuje statistiko na nivoju paketov.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Samo za serije) Prikazuje statistične podatke o radiju.'; + + @override + String get repeater_cliHelpStatsCore => + '(Samo za serijske naprave) Prikazuje osnovne statistične podatke.'; + @override String get telemetry_receivedData => 'Prejeto Telemetrično podatke'; @@ -3047,7 +3563,7 @@ class AppLocalizationsSl extends AppLocalizations { String get listFilter_heardRecently => 'Nedavno slišan'; @override - String get listFilter_az => 'A-Z'; + String get listFilter_az => 'A do Z'; @override String get listFilter_filters => 'Filtri'; @@ -3217,6 +3733,37 @@ class AppLocalizationsSl extends AppLocalizations { @override String get losLegendTerrain => 'Teren'; + @override + String get losBlockedSpotsTitle => 'Zasedena parkirišča'; + + @override + String get losBlockedSpotsHint => + 'Dotaknite blokirano točko, da jo označite na zemljeplati.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Izbrano ovire'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Frekvenca'; @@ -3684,4 +4231,40 @@ class AppLocalizationsSl extends AppLocalizations { @override String get translation_systemLanguage => 'Jezik sistema'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_sv.dart b/lib/l10n/app_localizations_sv.dart index 38e0893..7453c18 100644 --- a/lib/l10n/app_localizations_sv.dart +++ b/lib/l10n/app_localizations_sv.dart @@ -44,6 +44,9 @@ class AppLocalizationsSv extends AppLocalizations { @override String get common_close => 'Stänga'; + @override + String get common_done => 'Done'; + @override String get common_edit => 'Redigera'; @@ -109,7 +112,7 @@ class AppLocalizationsSv extends AppLocalizations { } @override - String get scanner_title => 'MeshCore Open'; + String get scanner_title => 'MeshCore – Öppen version'; @override String get connectionChoiceUsbLabel => 'USB'; @@ -130,7 +133,7 @@ class AppLocalizationsSv extends AppLocalizations { String get tcpHostHint => '192.168.40.10'; @override - String get tcpPortLabel => 'Port'; + String get tcpPortLabel => 'Hamn'; @override String get tcpPortHint => '5000'; @@ -428,9 +431,7 @@ class AppLocalizationsSv extends AppLocalizations { String get settings_advertLocationSubtitle => 'Inkludera plats i annonsen'; @override - String settings_multiAck(String value) { - return 'Multi-ACKs: $value'; - } + String get settings_multiAck => 'Flera bekräftelser'; @override String get settings_telemetryModeUpdated => 'Telemetri-läge uppdaterat'; @@ -438,6 +439,13 @@ class AppLocalizationsSv extends AppLocalizations { @override String get settings_actions => 'Åtgärder'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => 'Skicka Annons'; @@ -477,10 +485,11 @@ class AppLocalizationsSv extends AppLocalizations { String get settings_debug => 'Felsök'; @override - String get settings_bleDebugLog => 'BLE-felsökning'; + String get settings_companionDebugLog => 'Följande felsökningslogg'; @override - String get settings_bleDebugLogSubtitle => 'BLE-kommandon, svar och rådata'; + String get settings_companionDebugLogSubtitle => + 'BLE/TCP/USB-kommandon, svar och rådata'; @override String get settings_appDebugLog => 'Appfelsökning'; @@ -494,7 +503,7 @@ class AppLocalizationsSv extends AppLocalizations { @override String settings_aboutVersion(String version) { - return 'MeshCore Open v$version'; + return 'MeshCore Open version $version'; } @override @@ -554,7 +563,7 @@ class AppLocalizationsSv extends AppLocalizations { String get settings_txPower => 'TX-effekt (dBm)'; @override - String get settings_txPowerHelper => '0 - 22'; + String get settings_txPowerHelper => '0 – 22'; @override String get settings_txPowerInvalid => 'Ogiltig TX-effekt (0-22 dBm)'; @@ -600,43 +609,43 @@ class AppLocalizationsSv extends AppLocalizations { String get appSettings_languageSystem => 'Systemstandard'; @override - String get appSettings_languageEn => 'English'; + String get appSettings_languageEn => 'Engelska'; @override - String get appSettings_languageFr => 'Français'; + String get appSettings_languageFr => 'Franska'; @override - String get appSettings_languageEs => 'Español'; + String get appSettings_languageEs => 'Spanska'; @override - String get appSettings_languageDe => 'Deutsch'; + String get appSettings_languageDe => 'Tyskt'; @override - String get appSettings_languagePl => 'Polski'; + String get appSettings_languagePl => 'Polsk'; @override - String get appSettings_languageSl => 'Slovenščina'; + String get appSettings_languageSl => 'Sloveniska'; @override - String get appSettings_languagePt => 'Português'; + String get appSettings_languagePt => 'Portugisiska'; @override - String get appSettings_languageIt => 'Italiano'; + String get appSettings_languageIt => 'Italienska'; @override - String get appSettings_languageZh => '中文'; + String get appSettings_languageZh => 'Kinesiska'; @override String get appSettings_languageSv => 'Svenska'; @override - String get appSettings_languageNl => 'Nederlands'; + String get appSettings_languageNl => 'Nederländska'; @override - String get appSettings_languageSk => 'Slovenčina'; + String get appSettings_languageSk => 'Sloveniska'; @override - String get appSettings_languageBg => 'Български'; + String get appSettings_languageBg => 'Bulgariska'; @override String get appSettings_languageRu => 'Ryska'; @@ -783,13 +792,13 @@ class AppLocalizationsSv extends AppLocalizations { 'Anslut till en enhet för att välja'; @override - String get appSettings_batteryNmc => '18650 NMC (3.0-4.2V)'; + String get appSettings_batteryNmc => '18650 NMC (3,0-4,2V)'; @override String get appSettings_batteryLifepo4 => 'LiFePO4 (2,6–3,65V)'; @override - String get appSettings_batteryLipo => 'LiPo (3.0-4.2V)'; + String get appSettings_batteryLipo => 'LiPo (3,0-4,2V)'; @override String get appSettings_mapDisplay => 'Kartvisning'; @@ -1069,20 +1078,16 @@ class AppLocalizationsSv extends AppLocalizations { return 'Kanal $index'; } - @override - String get channels_hashtagChannel => 'Hashtagkanal'; - @override String get channels_public => 'Offentligt'; @override - String get channels_private => 'Privat'; - - @override - String get channels_publicChannel => 'Allmänt kanal'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => 'Privat kanal'; + String get channels_private => 'Privat'; @override String get channels_editChannel => 'Redigera kanal'; @@ -1127,7 +1132,7 @@ class AppLocalizationsSv extends AppLocalizations { String get channels_standardPublicPsk => 'Standard allmän PSK'; @override - String get channels_pskHex => 'PSK (Hex)'; + String get channels_pskHex => 'PSK (heks)'; @override String get channels_generateRandomPsk => 'Generera slumpmässig PSK'; @@ -1151,11 +1156,66 @@ class AppLocalizationsSv extends AppLocalizations { @override String get channels_smazCompression => 'SMAZ-komprimering'; + @override + String get channels_cyr2latCompression => 'Cyr2Lat-komprimering'; + + @override + String get channels_cyr2latCompressionDscr => + 'Ersätter vissa kyrilliska tecken med latinska tecken när du skickar.'; + + @override + String get channels_cyr2latSettingsHeading => 'Inställningar för Cyr2Lat'; + + @override + String get channels_cyr2latSettingsSubheading => 'Ersättningslista'; + + @override + String get channels_cyr2latSettingsDscr => + 'Redigera JSON-konfigurationen för teckenersättning'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON-ersättningskarta'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'Felaktig JSON: $error'; + } + @override String channels_channelUpdated(String name) { return 'Kanalen \"$name\" har uppdaterats'; } + @override + String get settings_cyr2latProfileAdd => 'Lägg till Cyr2Lat-profil'; + + @override + String get settings_cyr2latProfileName => 'Profilnamn'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'Profilnamnet får inte vara tomt'; + + @override + String get settings_cyr2latProfileAdded => 'Profilen har lagts till'; + + @override + String get settings_cyr2latProfileUpdated => 'Profilen har uppdaterats'; + + @override + String get settings_cyr2latProfileEdit => 'Redigera Cyr2Lat-profil'; + + @override + String get settings_cyr2latProfileDelete => 'Ta bort Cyr2Lat-profil'; + + @override + String get settings_cyr2latProfileDeleted => 'Profilen har tagits bort'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Är du säker på att du vill ta bort profilen \"$name\"?'; + } + @override String get channels_publicChannelAdded => 'Allmänt kanal tillagd'; @@ -1381,7 +1441,7 @@ class AppLocalizationsSv extends AppLocalizations { } @override - String get debugFrame_textTypeCli => 'CLI'; + String get debugFrame_textTypeCli => 'Kommandorad'; @override String get debugFrame_textTypePlain => 'Enkel'; @@ -1428,8 +1488,8 @@ class AppLocalizationsSv extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'hops', - one: 'hop', + other: 'hopp', + one: 'hopp', ); return '$count $_temp0'; } @@ -1437,6 +1497,9 @@ class AppLocalizationsSv extends AppLocalizations { @override String get chat_successes => 'framgångar'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => 'Ta bort sökväg'; @@ -1535,6 +1598,12 @@ class AppLocalizationsSv extends AppLocalizations { return 'Olästa: $count'; } + @override + String get chat_markAsUnread => 'Markera som oläst'; + + @override + String get chat_newMessages => 'Nya meddelanden'; + @override String get chat_openLink => 'Öppna länk?'; @@ -1616,6 +1685,24 @@ class AppLocalizationsSv extends AppLocalizations { @override String get map_flags => 'Flaggor'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => 'Dela markeringen här'; @@ -1701,6 +1788,9 @@ class AppLocalizationsSv extends AppLocalizations { @override String get map_sharedPin => 'Delad PIN'; + @override + String get map_sharedAt => 'Delad'; + @override String get map_joinRoom => 'Gå med i rum'; @@ -2010,14 +2100,14 @@ class AppLocalizationsSv extends AppLocalizations { 'Visa återspolningsstatus, statistik och grannar'; @override - String get repeater_telemetry => 'Telemetry'; + String get repeater_telemetry => 'Telemetri'; @override String get repeater_telemetrySubtitle => 'Visa telemetri för sensorer och systemstatistik'; @override - String get repeater_cli => 'CLI'; + String get repeater_cli => 'Kommandoradgränssnitt'; @override String get repeater_cliSubtitle => 'Skicka kommandon till repetitorn'; @@ -2105,6 +2195,9 @@ class AppLocalizationsSv extends AppLocalizations { @override String get repeater_rxAirtime => 'RX Airtime'; + @override + String get repeater_chanUtil => 'Användning av kanal'; + @override String get repeater_packetStatistics => 'Paketstatistik'; @@ -2178,7 +2271,7 @@ class AppLocalizationsSv extends AppLocalizations { String get repeater_frequencyMhz => 'Frekvens (MHz)'; @override - String get repeater_frequencyHelper => '300-2500 MHz'; + String get repeater_frequencyHelper => '300–2500 MHz'; @override String get repeater_txPower => 'TX Effekt'; @@ -2312,6 +2405,162 @@ class AppLocalizationsSv extends AppLocalizations { String get repeater_settingsSaved => 'Inställningarna sparades framgångsrikt.'; + @override + String get repeater_rxGain => 'Ökad RX-vinst'; + + @override + String get repeater_rxGainHelper => + 'Ökad känslighet, högre strömförbrukning (endast för SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => 'Återställ förbättrad RX-signalstyrka'; + + @override + String get repeater_multiAcks => 'Flera bekräftelser'; + + @override + String get repeater_multiAcksSubtitle => + 'Bekräfta meddelanden via flera olika kanaler för bättre leverans.'; + + @override + String get repeater_refreshMultiAcks => 'Återställ flera ACK-meddelanden'; + + @override + String get repeater_networkHealth => 'Nätverkets hälsa'; + + @override + String get repeater_loopDetect => 'Identifiering av loopar'; + + @override + String get repeater_loopDetectHelper => + 'Skapa \"flödespaket\" som ser ut som att de bildar en loop (en återkommande krets).'; + + @override + String get repeater_loopDetectOff => 'Av'; + + @override + String get repeater_loopDetectMinimal => 'Minimal'; + + @override + String get repeater_loopDetectModerate => 'Måttlig'; + + @override + String get repeater_loopDetectStrict => 'Strikt'; + + @override + String get repeater_dutyCycle => 'Arbetscykel'; + + @override + String get repeater_dutyCycleHelper => 'Maximal procentandel av sändningstid'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Information om operatören'; + + @override + String get repeater_ownerInfoHelper => + 'Offentliga metadata för denna sändare'; + + @override + String get repeater_refreshOwnerInfo => 'Uppdatera information om personal'; + + @override + String get repeater_floodMax => 'Maximala mängden humle'; + + @override + String get repeater_floodMaxHelper => + 'Maximalt antal hopp en paket kan färdas (0-64)'; + + @override + String get repeater_advancedSettings => 'Avancerad'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Ställjusteringsknappar för erfarna användare'; + + @override + String get repeater_pathHashMode => 'Hash-läge för sökväg'; + + @override + String get repeater_pathHashModeHelper => + 'Byte används för att koda denna repeaters ID i taggar för att upptäcka loopar/flödesvägar. 0=1 byte (256 ID:n, upp till 64 hopp), 1=2 byte (65 000 ID:n, upp till 32 hopp), 2=3 byte (16 miljoner ID:n, upp till 21 hopp). Versioner 1.13 och äldre har stöd för multi-byte-vägar – endast en gång när nätverket är aktiverat (från och med version 1.14).'; + + @override + String get repeater_txDelay => 'Försening i Flood TX'; + + @override + String get repeater_txDelayHelper => + 'Återöverföringsintervall för trafik under perioder med hög belastning, som en multiplikator av paketets överföringstid (0-2, standard 0,5). Högre värde = färre kollisioner, men långsammare leverans.'; + + @override + String get repeater_directTxDelay => 'Direkt TX-fördröjning'; + + @override + String get repeater_directTxDelayHelper => + 'Återöverföringsintervall för direkt (icke-översvämmande) trafik, som en multiplikator av paketets överföringstid (0-2, standard 0,3).'; + + @override + String get repeater_intThresh => 'Tröskelvärde för störning'; + + @override + String get repeater_intThreshHelper => + 'Tröskelvärdet har ställts in så att den filtrerar bort störningar som överstiger detta värde. 0 stänger av – aktivera endast om du ser RX-fel i ett störningsfyllt frekvensområde.'; + + @override + String get repeater_agcResetInterval => 'Återställningsintervall för AGC'; + + @override + String get repeater_agcResetIntervalHelper => + 'Hur ofta ska man återställa radioens automatiska förstärkning för att återhämta sig från ett tillstånd där förstärkningen är fast? Sekunder, inställda till en multipel av 4. 0 stänger av periodiska återställningar.'; + + @override + String get repeater_actionsTitle => 'Åtgärder'; + + @override + String get repeater_sendAdvert => 'Skicka annons om översvämning'; + + @override + String get repeater_sendAdvertSubtitle => + 'Sänd en reklamfilm om översvämningar via nätverket.'; + + @override + String get repeater_sendAdvertZeroHop => + 'Skicka en annons som inte kräver någon mellanstopp'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Sänd en reklamkampanj med en enda sändare (utan mellanliggande sändare).'; + + @override + String get repeater_clockSync => 'Synkronisera klockan nu'; + + @override + String get repeater_clockSyncSubtitle => + 'Ställ din telefons tid till repeatern.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action lyckades'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action misslyckades: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Inställningar sparade – starta om repetern för att tillämpa dem'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Vissa inställningar misslyckades: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Fel vid sparande av inställningar: $error'; @@ -2327,10 +2576,6 @@ class AppLocalizationsSv extends AppLocalizations { @override String get repeater_refreshTxPower => 'Återställ TX-effekt'; - @override - String get repeater_refreshLocationSettings => - 'Uppdatera Lokationsinställningar'; - @override String get repeater_refreshPacketForwarding => 'Återställ Paketväxling'; @@ -2340,10 +2585,6 @@ class AppLocalizationsSv extends AppLocalizations { @override String get repeater_refreshPrivacyMode => 'Återställ Sekretessläge'; - @override - String get repeater_refreshAdvertisementSettings => - 'Återställ Annonsinställningar'; - @override String repeater_refreshed(String label) { return '$label har uppdaterats'; @@ -2665,6 +2906,277 @@ class AppLocalizationsSv extends AppLocalizations { String get repeater_gpsNote => 'GPS-kommando har introducerats för att hantera platsrelaterade ämnen.'; + @override + String get repeater_getCategory => 'Hämta värden'; + + @override + String get repeater_powerMgmt => 'Effektstyrning'; + + @override + String get repeater_sensors => 'Sensorer'; + + @override + String get repeater_cliHelpPowerOff => + 'Stänger av enheten. (ingen respons förväntas)'; + + @override + String get repeater_cliHelpClkReboot => + 'Återställer klockan till en känd tidpunkt och startar om enheten.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Skickar en annons som når endast direkt grannar (endast närmaste grannar).'; + + @override + String get repeater_cliHelpStartOta => + 'Startar en firmware-uppdatering via luft, på kompatibla enheter.'; + + @override + String get repeater_cliHelpTime => + 'Ställer enheten till den angivna Unix-epokens tid. Klockan kan inte gå bakåt.'; + + @override + String get repeater_cliHelpBoard => + 'Visar tillverkaren av moderkortet / hårdvaru-identifieraren.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Skickar en förfrågan om att upptäcka närliggande noder. (Endast för repetrar)'; + + @override + String get repeater_cliHelpPowersaving => + 'Visar om energisparläget är aktiverat eller avstängt.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Aktiverar eller inaktiverar energisparläget (om det stöds).'; + + @override + String get repeater_cliHelpErase => + '(Endast för seriell kommunikation) Formaterar enhetens filsystem. Raderar alla inställningar och kontakter.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Anger den maximala tillåtna överföringsfrekvensen som en procent (1-100). Justerar automatiskt tidsfaktorn.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Endast för seriell användning) Ersätter enhetsens privata nyckel. Återstart krävs för att tillämpa. Genererar en ny publik nyckel.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(Endast SX126x) Aktiverar förstärkt mottagargain för förbättrad känslighet vid högre strömförbrukning.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Anger kontaktinformationen som ska inkluderas i annonserna. Använd \'|\' för att separera olika fält.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Definierar läget för hash-baserad ruttning. 0 = äldre läge, 1 = standard, 2 = strikt. Påverkar hur ruttvägar matchas.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Ställer in känsligheten för att detektera loopar i routningen: av, minimal, måttlig eller strikt.'; + + @override + String get repeater_cliHelpSetFreq => + '(Endast för seriell kommunikation) Ställer snabbt bara frekvensen. Kräver omstart. Föredrar \"ställ radio\" för att få full kontroll över radioinställningarna.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Endast ESPNow-brygga) Anger WiFi-kanalen (1-14) som används av bryggan.'; + + @override + String get repeater_cliHelpGetName => 'Visar det konfigurerade nodnamnet.'; + + @override + String get repeater_cliHelpGetRole => + 'Visar firmware-funktionen (Repeater, Room Server, etc.).'; + + @override + String get repeater_cliHelpGetPublicKey => 'Visar enhetens publika nyckel.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Endast för seriell användning) Visar enheters privata nyckel. Behandla detta som en hemlighet.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Visar om funktionen för att vidarebefordra paket (som en repeater) är aktiverad eller inaktiverad.'; + + @override + String get repeater_cliHelpGetTx => 'Visar aktuell TX-effekt i dBm.'; + + @override + String get repeater_cliHelpGetFreq => + 'Visar den konfigurerade radiovågen i MHz.'; + + @override + String get repeater_cliHelpGetRadio => + 'Visar alla radioparametrar: frekvens, bandbredd, spridningsfaktor, kodningshastighet.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(Endast för SX126x) Visar RX:s förstärkningstillstånd.'; + + @override + String get repeater_cliHelpGetAf => 'Visar aktuell tidssats.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Visar den aktuella tillåtna arbetscykeln i procent.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Visar gränsen för kanalinterferens i dB.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Visar återställningsintervallet för AGC i sekunder.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Visar om dubbelbekräftelseläget är aktiverat (1) eller avstängt (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Visar om gäst har tillåtelse att endast läsa.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Visar den lokala reklampausens längd i minuter.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Visar tidsintervallet för reklamsegmentet under översvämningen, i timmar.'; + + @override + String get repeater_cliHelpGetGuestPassword => 'Visar det angivna gästlösen.'; + + @override + String get repeater_cliHelpGetLat => 'Visar den angivna latituden.'; + + @override + String get repeater_cliHelpGetLon => 'Visar den angivna longituden.'; + + @override + String get repeater_cliHelpGetRxDelay => 'Visar grundvärdet för rxdelay.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Visar faktor för fördröjning i flödesläge.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Visar faktorn för fördröjning i direktläge.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Visar det maximala antalet gånger en översvämning har inträffat.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Visar strängen med kontaktinformation för ägaren.'; + + @override + String get repeater_cliHelpGetPathHashMode => 'Visar hash-läge (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Visar känsligheten för att detektera loopar.'; + + @override + String get repeater_cliHelpGetAcl => + '(Endast för serier) Visar åtkomstkontrollinställningarna för en repeater.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => 'Visar om bron är aktiverad.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Visar fördröjningen i bron i millisekunder.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Visar om bron skickar RX- eller TX-paket.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Enbart RS232-brygga) Visar bryggans baud-hastighet.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Endast ESPNow-brygga) Visar WiFi-kanal för bryggan.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Endast ESPNow-brygga) Visar bryggans delade hemlighet.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(Endast för NRF52) Visar versionen av bootloadern.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Visar ADC-multiplikatorn (skalning av batterispänning).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Anger om styrelsen har stöd för energihantering.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Visar aktuell strömkälla: extern eller batteri.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Visar de senaste orsakerna till återställning och avstängning.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Visar batterispänningen vid start i millivolt (mV).'; + + @override + String get repeater_cliHelpSensorGet => + 'Läser en anpassad sensorinställning via tangentbordet.'; + + @override + String get repeater_cliHelpSensorSet => + 'Skapar en anpassad inställning för en sensor.'; + + @override + String get repeater_cliHelpSensorList => + 'Visar alla anpassade sensorinställningar, sorterade från ett valfritt startindex.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Visar det aktuella standardområde.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Definierar standardområde. Använd \"\" för att återställa till standard.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Lista områden där det är tillåtet med trafik under översvämningsförhållanden.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Listar områden där trafik på grund av översvämningar är förbjuden.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Endast för seriell kommunikation) Visar statistik på paketnivå.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Enbart för serier) Visar radiostatistik.'; + + @override + String get repeater_cliHelpStatsCore => + '(Enbart för seriell kommunikation) Visar grundläggande firmware-statistik.'; + @override String get telemetry_receivedData => 'Mottagen Telemetridata'; @@ -2884,7 +3396,7 @@ class AppLocalizationsSv extends AppLocalizations { String get community_publicChannel => 'Föreningens Offentliga'; @override - String get community_hashtagChannel => 'Community Hashtag'; + String get community_hashtagChannel => 'Hashtag för gemenskapen'; @override String get community_name => 'Gemenskapens namn'; @@ -3008,7 +3520,7 @@ class AppLocalizationsSv extends AppLocalizations { 'Offentlig hashtag (alla kan gå med)'; @override - String get community_communityHashtag => 'Community Hashtag'; + String get community_communityHashtag => 'Gemenskaps-hashtag'; @override String get community_communityHashtagDesc => 'Endast för medlemmar'; @@ -3199,6 +3711,37 @@ class AppLocalizationsSv extends AppLocalizations { @override String get losLegendTerrain => 'Terräng'; + @override + String get losBlockedSpotsTitle => 'Reserverade platser'; + + @override + String get losBlockedSpotsHint => + 'Klicka på en markerad plats för att framhäva den på kartan.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Vald hinder'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Frekvens'; @@ -3219,7 +3762,7 @@ class AppLocalizationsSv extends AppLocalizations { } @override - String get contacts_pathTrace => 'Path Trace'; + String get contacts_pathTrace => 'Spårning'; @override String get contacts_ping => 'Ping'; @@ -3662,4 +4205,40 @@ class AppLocalizationsSv extends AppLocalizations { @override String get translation_systemLanguage => 'Språk för systemet'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index 8ed4b9f..9c30fd8 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -44,6 +44,9 @@ class AppLocalizationsUk extends AppLocalizations { @override String get common_close => 'Закрити'; + @override + String get common_done => 'Готово'; + @override String get common_edit => 'Редагувати'; @@ -69,7 +72,7 @@ class AppLocalizationsUk extends AppLocalizations { String get common_continue => 'Продовжити'; @override - String get common_share => 'Поділитися'; + String get common_share => 'Поділитись'; @override String get common_copy => 'Копіювати'; @@ -109,7 +112,7 @@ class AppLocalizationsUk extends AppLocalizations { } @override - String get scanner_title => 'MeshCore Open'; + String get scanner_title => 'MeshCore: Відкритий доступ'; @override String get connectionChoiceUsbLabel => 'USB'; @@ -121,7 +124,7 @@ class AppLocalizationsUk extends AppLocalizations { String get connectionChoiceTcpLabel => 'TCP'; @override - String get tcpScreenTitle => 'З\'єднатися через протокол TCP'; + String get tcpScreenTitle => 'Підключитись через TCP'; @override String get tcpHostLabel => 'IP-адреса'; @@ -147,7 +150,7 @@ class AppLocalizationsUk extends AppLocalizations { String get tcpErrorHostRequired => 'Необхідно вказати IP-адресу.'; @override - String get tcpErrorPortInvalid => 'Порт повинен бути в межах від 1 до 65535.'; + String get tcpErrorPortInvalid => 'Порт має бути в межах від 1 до 65535.'; @override String get tcpErrorUnsupported => @@ -155,11 +158,11 @@ class AppLocalizationsUk extends AppLocalizations { @override String get tcpErrorTimedOut => - 'З\'єднання TCP завершилося через закінчення часу очікування.'; + 'З\'єднання TCP завершилось через закінчення часу очікування.'; @override String tcpConnectionFailed(String error) { - return 'Не вдалося встановити з\'єднання TCP: $error'; + return 'Не вдалось встановити з\'єднання TCP: $error'; } @override @@ -167,7 +170,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get usbScreenSubtitle => - 'Виберіть виявлене серійне пристрій і підключіть його безпосередньо до вашого вузла MeshCore.'; + 'Виберіть виявлений USB-пристрій і підключіть його безпосередньо до вашого вузла MeshCore.'; @override String get usbScreenStatus => 'Виберіть пристрій USB'; @@ -198,11 +201,11 @@ class AppLocalizationsUk extends AppLocalizations { String get usbErrorNotConnected => 'Немає підключених пристроїв USB.'; @override - String get usbErrorOpenFailed => 'Не вдалося відкрити вибране USB-пристрій.'; + String get usbErrorOpenFailed => 'Не вдалось відкрити вибране USB-пристрій.'; @override String get usbErrorConnectFailed => - 'Не вдалося підключитися до вибраного USB-пристрою.'; + 'Не вдалось підключитись до вибраного USB-пристрою.'; @override String get usbErrorUnsupported => @@ -220,7 +223,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get usbErrorConnectTimedOut => - 'З\'єднання не вдалося встановити. Переконайтеся, що пристрій має встановлене програмне забезпечення USB Companion.'; + 'З\'єднання не вдалось встановити. Переконайтесь, що пристрій має встановлене програмне забезпечення USB Companion.'; @override String get usbFallbackDeviceName => @@ -237,7 +240,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String usbConnectionFailed(String error) { - return 'Не вдалося встановити з\'єднання через USB: $error'; + return 'Не вдалось встановити з\'єднання через USB: $error'; } @override @@ -287,7 +290,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get scanner_chromeRequiredMessage => - 'Для підтримки Bluetooth у цьому веб-додатку потрібен Google Chrome або браузер на базі Chromium.'; + 'Для підтримки Bluetooth у цьому вебзастосунку потрібен Google Chrome або браузер на базі Chromium.'; @override String get scanner_enableBluetooth => 'Увімкніть Bluetooth'; @@ -305,7 +308,7 @@ class AppLocalizationsUk extends AppLocalizations { String get settings_deviceInfo => 'Інформація про пристрій'; @override - String get settings_appSettings => 'Налаштування програми'; + String get settings_appSettings => 'Налаштування застосунку'; @override String get settings_appSettingsSubtitle => @@ -337,13 +340,13 @@ class AppLocalizationsUk extends AppLocalizations { String get settings_radioSettingsUpdated => 'Налаштування радіо оновлено'; @override - String get settings_location => 'Розташування'; + String get settings_location => 'Геопозиція'; @override - String get settings_locationSubtitle => 'GPS координати'; + String get settings_locationSubtitle => 'GPS-координати'; @override - String get settings_locationUpdated => 'Розташування оновлено'; + String get settings_locationUpdated => 'Геопозицію оновлено'; @override String get settings_locationBothRequired => 'Введіть широту та довготу.'; @@ -356,7 +359,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get settings_locationGPSEnableSubtitle => - 'Вмикає автоматичне оновлення місцезнаходження через GPS.'; + 'Вмикає автоматичне оновлення геопозиції через GPS.'; @override String get settings_locationIntervalSec => 'Інтервал для GPS (Секунди)'; @@ -383,11 +386,11 @@ class AppLocalizationsUk extends AppLocalizations { @override String get settings_privacyModeSubtitle => - 'Приховати ім\'я/розташування в оголошеннях'; + 'Приховати ім\'я/геопозицію в оголошеннях'; @override String get settings_privacyModeToggle => - 'Увімкніть режим приватності, щоб приховати своє ім\'я та місцезнаходження в оголошеннях.'; + 'Увімкніть режим приватності, щоб приховати своє ім\'я та геопозицію в оголошеннях.'; @override String get settings_privacyModeEnabled => 'Режим приватності увімкнено'; @@ -400,7 +403,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get settings_privacySubtitle => - 'Керуйте інформацією, яку буде спільно використовуватися'; + 'Керуйте інформацією, яка буде спільно використовуватись'; @override String get settings_privacySettingsDescription => @@ -425,16 +428,14 @@ class AppLocalizationsUk extends AppLocalizations { String get settings_telemetryEnvironmentMode => 'Режим середовища телеметрії'; @override - String get settings_advertLocation => 'Розміщення реклами'; + String get settings_advertLocation => 'Геопозиція в оголошенні'; @override String get settings_advertLocationSubtitle => - 'Включити місце розташування в оголошення'; + 'Включити геопозицію в оголошення'; @override - String settings_multiAck(String value) { - return 'Багатократне підтвердження: $value'; - } + String get settings_multiAck => 'Багато підтверджень'; @override String get settings_telemetryModeUpdated => 'Режим телеметрії оновлено'; @@ -442,6 +443,13 @@ class AppLocalizationsUk extends AppLocalizations { @override String get settings_actions => 'Дії'; + @override + String get settings_deleteAllPaths => 'Видалити всі шляхи'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Очистити всі дані шляхів у контактах.'; + @override String get settings_sendAdvertisement => 'Оголосити себе'; @@ -484,21 +492,22 @@ class AppLocalizationsUk extends AppLocalizations { String get settings_debug => 'Налагодження'; @override - String get settings_bleDebugLog => 'Журнал налагодження BLE'; + String get settings_companionDebugLog => + 'Журнал відлачування (для супутника)'; @override - String get settings_bleDebugLogSubtitle => - 'Команди BLE, відповіді та необроблені дані'; + String get settings_companionDebugLogSubtitle => + 'Команди, відповіді та необроблена інформація для протоколів BLE/TCP/USB'; @override - String get settings_appDebugLog => 'Журнал налагодження програми'; + String get settings_appDebugLog => 'Журнал налагодження застосунку'; @override String get settings_appDebugLogSubtitle => - 'Повідомлення налагодження програми'; + 'Повідомлення налагодження застосунку'; @override - String get settings_about => 'Про програму'; + String get settings_about => 'Про застосунок'; @override String settings_aboutVersion(String version) { @@ -520,7 +529,7 @@ class AppLocalizationsUk extends AppLocalizations { String get settings_infoName => 'Ім\'я'; @override - String get settings_infoId => 'ID'; + String get settings_infoId => 'Ідентифікатор'; @override String get settings_infoStatus => 'Статус'; @@ -544,7 +553,7 @@ class AppLocalizationsUk extends AppLocalizations { String get settings_frequency => 'Частота (МГц)'; @override - String get settings_frequencyHelper => '300.0 - 2500.0'; + String get settings_frequencyHelper => '300,0 – 2500,0'; @override String get settings_frequencyInvalid => 'Некоректна частота (300-2500 МГц)'; @@ -584,7 +593,7 @@ class AppLocalizationsUk extends AppLocalizations { } @override - String get appSettings_title => 'Налаштування програми'; + String get appSettings_title => 'Налаштування застосунку'; @override String get appSettings_appearance => 'Вигляд'; @@ -608,43 +617,43 @@ class AppLocalizationsUk extends AppLocalizations { String get appSettings_languageSystem => 'Як у системі'; @override - String get appSettings_languageEn => 'English'; + String get appSettings_languageEn => 'Англійська'; @override - String get appSettings_languageFr => 'Français'; + String get appSettings_languageFr => 'Французька'; @override - String get appSettings_languageEs => 'Español'; + String get appSettings_languageEs => 'Іспанська'; @override - String get appSettings_languageDe => 'Deutsch'; + String get appSettings_languageDe => 'Німецькою'; @override - String get appSettings_languagePl => 'Polski'; + String get appSettings_languagePl => 'Польська'; @override - String get appSettings_languageSl => 'Slovenščina'; + String get appSettings_languageSl => 'Словенська мова'; @override - String get appSettings_languagePt => 'Português'; + String get appSettings_languagePt => 'Португальська'; @override - String get appSettings_languageIt => 'Italiano'; + String get appSettings_languageIt => 'Італійська'; @override - String get appSettings_languageZh => '中文'; + String get appSettings_languageZh => 'Китайська'; @override - String get appSettings_languageSv => 'Svenska'; + String get appSettings_languageSv => 'Шведська'; @override - String get appSettings_languageNl => 'Nederlands'; + String get appSettings_languageNl => 'Нідерландська'; @override - String get appSettings_languageSk => 'Slovenčina'; + String get appSettings_languageSk => 'Словенська'; @override - String get appSettings_languageBg => 'Български'; + String get appSettings_languageBg => 'Болгарська'; @override String get appSettings_languageRu => 'Російська'; @@ -719,14 +728,14 @@ class AppLocalizationsUk extends AppLocalizations { @override String get appSettings_pathsWillNotBeCleared => - 'Шляхи не будуть очищатися автоматично.'; + 'Шляхи не будуть очищатись автоматично.'; @override String get appSettings_autoRouteRotation => 'Авторотація маршруту'; @override String get appSettings_autoRouteRotationSubtitle => - 'Чергувати найкращі шляхи та режим «на всю мережу» (flood)'; + 'Чергувати найкращі шляхи та режим «через всю мережу» (flood)'; @override String get appSettings_autoRouteRotationEnabled => @@ -864,13 +873,13 @@ class AppLocalizationsUk extends AppLocalizations { String get appSettings_offlineMapCache => 'Офлайн-кеш карти'; @override - String get appSettings_unitsTitle => 'одиниці'; + String get appSettings_unitsTitle => 'Одиниці'; @override - String get appSettings_unitsMetric => 'Метричний (м / км)'; + String get appSettings_unitsMetric => 'Метричні (м / км)'; @override - String get appSettings_unitsImperial => 'Імперська (ft / mi)'; + String get appSettings_unitsImperial => 'Імперські (ft / mi)'; @override String get appSettings_noAreaSelected => 'Область не вибрано'; @@ -884,19 +893,20 @@ class AppLocalizationsUk extends AppLocalizations { String get appSettings_debugCard => 'Налагодження'; @override - String get appSettings_appDebugLogging => 'Логування налагодження програми'; + String get appSettings_appDebugLogging => + 'Журналювання налагодження застосунку'; @override String get appSettings_appDebugLoggingSubtitle => - 'Записувати повідомлення налагодження програми в лог для усунення несправностей.'; + 'Записувати повідомлення налагодження застосунку в журнал для усунення несправностей.'; @override String get appSettings_appDebugLoggingEnabled => - 'Логування налагодження програми увімкнено'; + 'Журналювання налагодження застосунку увімкнено'; @override String get appSettings_appDebugLoggingDisabled => - 'Налагодження програми вимкнено.'; + 'Журналювання налагодження застосунку вимкнено.'; @override String get contacts_title => 'Контакти'; @@ -1043,14 +1053,14 @@ class AppLocalizationsUk extends AppLocalizations { String get contact_clearChat => 'Очистити чат'; @override - String get contact_teleBase => 'Базовий телебачення'; + String get contact_teleBase => 'Базова телеметрія'; @override String get contact_teleBaseSubtitle => 'Дозволити спільний доступ до рівня заряду батареї та базової телеметрії'; @override - String get contact_teleLoc => 'Розташування телеметрії'; + String get contact_teleLoc => 'Геопозиція телеметрії'; @override String get contact_teleLocSubtitle => @@ -1083,20 +1093,16 @@ class AppLocalizationsUk extends AppLocalizations { return 'Канал $index'; } - @override - String get channels_hashtagChannel => 'Канал з хештегом'; - @override String get channels_public => 'Публічний'; @override - String get channels_private => 'Приватний'; - - @override - String get channels_publicChannel => 'Публічний канал'; + String channels_via(String path) { + return 'через $path'; + } @override - String get channels_privateChannel => 'Приватний канал'; + String get channels_private => 'Приватний'; @override String get channels_editChannel => 'Редагувати канал'; @@ -1117,7 +1123,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String channels_channelDeleteFailed(String name) { - return 'Не вдалося видалити канал \"$name\"'; + return 'Не вдалось видалити канал \"$name\"'; } @override @@ -1141,7 +1147,7 @@ class AppLocalizationsUk extends AppLocalizations { String get channels_standardPublicPsk => 'Стандартний публічний PSK'; @override - String get channels_pskHex => 'PSK (Hex)'; + String get channels_pskHex => 'PSK (шестнадцяткова система)'; @override String get channels_generateRandomPsk => 'Згенерувати випадковий ключ PSK'; @@ -1151,7 +1157,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get channels_pskMustBe32Hex => - 'PSK має складатися з 32 шістнадцяткових символів.'; + 'PSK має складатись з 32 шістнадцяткових символів.'; @override String channels_channelAdded(String name) { @@ -1166,11 +1172,66 @@ class AppLocalizationsUk extends AppLocalizations { @override String get channels_smazCompression => 'Стиснення SMAZ'; + @override + String get channels_cyr2latCompression => 'Стиснення Cyr2Lat'; + + @override + String get channels_cyr2latCompressionDscr => + 'Замінює деякі кириличні символи на латиницю при відправці.'; + + @override + String get channels_cyr2latSettingsHeading => 'Налаштування Cyr2Lat'; + + @override + String get channels_cyr2latSettingsSubheading => 'Список замін'; + + @override + String get channels_cyr2latSettingsDscr => + 'Редагувати JSON-конфігурацію заміни символів'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON-карта замін'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'Некоректний JSON: $error'; + } + @override String channels_channelUpdated(String name) { return 'Канал «$name» оновлено'; } + @override + String get settings_cyr2latProfileAdd => 'Додати профіль Cyr2Lat'; + + @override + String get settings_cyr2latProfileName => 'Назва профілю'; + + @override + String get settings_cyr2latProfileNameEmpty => + 'Назва профілю не може бути порожньою'; + + @override + String get settings_cyr2latProfileAdded => 'Профіль успішно додано'; + + @override + String get settings_cyr2latProfileUpdated => 'Профіль успішно оновлено'; + + @override + String get settings_cyr2latProfileEdit => 'Редагувати профіль Cyr2Lat'; + + @override + String get settings_cyr2latProfileDelete => 'Видалити профіль Cyr2Lat'; + + @override + String get settings_cyr2latProfileDeleted => 'Профіль успішно видалено'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return 'Ви впевнені, що хочете видалити профіль \"$name\"?'; + } + @override String get channels_publicChannelAdded => 'Публічний канал додано'; @@ -1196,24 +1257,24 @@ class AppLocalizationsUk extends AppLocalizations { String get channels_createPrivateChannelDesc => 'Захищено секретним ключем.'; @override - String get channels_joinPrivateChannel => 'Приєднатися до приватного каналу'; + String get channels_joinPrivateChannel => 'Приєднатись до приватного каналу'; @override String get channels_joinPrivateChannelDesc => 'Ввести секретний ключ вручну.'; @override - String get channels_joinPublicChannel => 'Приєднатися до публічного каналу'; + String get channels_joinPublicChannel => 'Приєднатись до публічного каналу'; @override String get channels_joinPublicChannelDesc => - 'Будь-хто може приєднатися до цього каналу.'; + 'Будь-хто може приєднатись до цього каналу.'; @override - String get channels_joinHashtagChannel => 'Приєднатися до каналу з хештегом'; + String get channels_joinHashtagChannel => 'Приєднатись до хештег-каналу'; @override String get channels_joinHashtagChannelDesc => - 'Будь-хто може приєднатися до каналів #hashtag.'; + 'Будь-хто може приєднатись до хештег-каналів.'; @override String get channels_scanQrCode => 'Сканувати QR-код'; @@ -1256,7 +1317,7 @@ class AppLocalizationsUk extends AppLocalizations { } @override - String get chat_location => 'Розташування'; + String get chat_location => 'Геопозиція'; @override String get chat_typeMessage => 'Введіть повідомлення...'; @@ -1317,7 +1378,7 @@ class AppLocalizationsUk extends AppLocalizations { String get gifPicker_noGifsFound => 'GIF не знайдено'; @override - String get gifPicker_failedLoad => 'Не вдалося завантажити GIF-файли'; + String get gifPicker_failedLoad => 'Не вдалось завантажити GIF-файли'; @override String get gifPicker_failedSearch => 'Пошук GIF не вдався'; @@ -1326,7 +1387,7 @@ class AppLocalizationsUk extends AppLocalizations { String get gifPicker_noInternet => 'Немає інтернет-з\'єднання'; @override - String get debugLog_appTitle => 'Журнал налагодження програми'; + String get debugLog_appTitle => 'Журнал налагодження застосунку'; @override String get debugLog_bleTitle => 'Журнал налагодження BLE'; @@ -1349,7 +1410,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get debugLog_enableInSettings => - 'Увімкніть налагодження програми в налаштуваннях'; + 'Увімкніть налагодження застосунку в налаштуваннях'; @override String get debugLog_frames => 'Кадри'; @@ -1394,7 +1455,7 @@ class AppLocalizationsUk extends AppLocalizations { } @override - String get debugFrame_textTypeCli => 'CLI'; + String get debugFrame_textTypeCli => 'CLI (Command Line Interface)'; @override String get debugFrame_textTypePlain => 'Звичайний'; @@ -1420,31 +1481,31 @@ class AppLocalizationsUk extends AppLocalizations { String get chat_autoUseSavedPath => 'Авто (використовувати збережений шлях)'; @override - String get chat_forceFloodMode => 'Примусово на всю мережу'; + String get chat_forceFloodMode => 'Примусово через всю мережу'; @override String get chat_recentAckPaths => - 'Недавні шляхи ACK (натисніть, щоб використати):'; + 'Підтверджені шляхи (натисніть, щоб використати):'; @override String get chat_pathHistoryFull => 'Історія шляхів заповнена. Видаліть записи, щоб додати нові.'; @override - String get chat_hopSingular => 'Стрибок'; + String get chat_hopSingular => 'Перехід'; @override - String get chat_hopPlural => 'стрибків'; + String get chat_hopPlural => 'переходів'; @override String chat_hopsCount(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'стрибків', - many: 'стрибків', - few: 'стрибки', - one: 'стрибок', + other: 'переходів', + many: 'переходів', + few: 'переходи', + one: 'перехід', ); return '$count $_temp0'; } @@ -1452,6 +1513,9 @@ class AppLocalizationsUk extends AppLocalizations { @override String get chat_successes => 'Успішно'; + @override + String get chat_score => 'Оцінка'; + @override String get chat_removePath => 'Видалити шлях'; @@ -1481,11 +1545,11 @@ class AppLocalizationsUk extends AppLocalizations { @override String get chat_floodModeSubtitle => - 'Використовувати перемикач маршрутизації в панелі програми'; + 'Використовувати перемикач маршрутизації в панелі застосунку'; @override String get chat_floodModeEnabled => - 'Увімкнено режим «на всю мережу». Перемикайте через іконку маршрутизації на панелі інструментів.'; + 'Увімкнено режим «через всю мережу». Перемикайте через іконку маршрутизації на панелі інструментів.'; @override String get chat_fullPath => 'Повний шлях'; @@ -1499,10 +1563,10 @@ class AppLocalizationsUk extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( hopCount, locale: localeName, - other: 'стрибків', - many: 'стрибків', - few: 'стрибки', - one: 'стрибок', + other: 'переходів', + many: 'переходів', + few: 'переходи', + one: 'перехід', ); return 'Шлях встановлено: $hopCount $_temp0 - $status'; } @@ -1530,30 +1594,36 @@ class AppLocalizationsUk extends AppLocalizations { String get chat_compressOutgoingMessages => 'Стискати вихідні повідомлення'; @override - String get chat_floodForced => 'На всю мережу (примусово)'; + String get chat_floodForced => 'Через всю мережу (примусово)'; @override - String get chat_directForced => 'Прямий (примусово)'; + String get chat_directForced => 'Напряму (примусово)'; @override String chat_hopsForced(int count) { - return '$count стрибків (примусово)'; + return '$count переходів (примусово)'; } @override - String get chat_floodAuto => 'На всю мережу (авто)'; + String get chat_floodAuto => 'Через всю мережу (авто)'; @override - String get chat_direct => 'Прямий'; + String get chat_direct => 'Напряму'; @override - String get chat_poiShared => 'Точкою інтересу поділилися'; + String get chat_poiShared => 'Поділилися точкою інтересу'; @override String chat_unread(int count) { return 'Непрочитано: $count'; } + @override + String get chat_markAsUnread => 'Позначити як непрочитане'; + + @override + String get chat_newMessages => 'Нові повідомлення'; + @override String get chat_openLink => 'Відкрити посилання?'; @@ -1566,7 +1636,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String chat_couldNotOpenLink(String url) { - return 'Не вдалося відкрити посилання: $url'; + return 'Не вдалось відкрити посилання: $url'; } @override @@ -1582,12 +1652,11 @@ class AppLocalizationsUk extends AppLocalizations { String get map_losScreenTitle => 'Пряма видимість'; @override - String get map_noNodesWithLocation => - 'Немає вузлів з даними про розташування'; + String get map_noNodesWithLocation => 'Немає вузлів з даними про геопозицію'; @override String get map_nodesNeedGps => - 'Вузли повинні надавати свої GPS координати,\nщоб з\'явитися на карті.'; + 'Вузли мають надавати свої GPS координати,\nщоб з\'явитись на карті.'; @override String map_nodesCount(int count) { @@ -1625,7 +1694,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get map_disconnectConfirm => - 'Ви впевнені, що хочете відключитися від цього пристрою?'; + 'Ви впевнені, що хочете відключитись від цього пристрою?'; @override String get map_from => 'Від'; @@ -1637,10 +1706,28 @@ class AppLocalizationsUk extends AppLocalizations { String get map_flags => 'Прапорці'; @override - String get map_shareMarkerHere => 'Поділитися маркером тут'; + String get map_type => 'Тип'; + + @override + String get map_path => 'Шлях'; @override - String get map_setAsMyLocation => 'Встановити моє місцезнаходження'; + String get map_location => 'Геопозиція'; + + @override + String get map_estLocation => 'Орієнтовна геопозиція'; + + @override + String get map_publicKey => 'Публічний ключ'; + + @override + String get map_publicKeyPrefixHint => 'напр. ab12'; + + @override + String get map_shareMarkerHere => 'Поділитись маркером тут'; + + @override + String get map_setAsMyLocation => 'Встановити мою геопозицію'; @override String get map_pinLabel => 'Мітка піна'; @@ -1661,16 +1748,16 @@ class AppLocalizationsUk extends AppLocalizations { String get map_noChannelsAvailable => 'Немає доступних каналів'; @override - String get map_publicLocationShare => 'Поділитися в публічному місці'; + String get map_publicLocationShare => 'Поділитись в публічному місці'; @override String map_publicLocationShareConfirm(String channelLabel) { - return 'Ви збираєтеся поділитися розташуванням у $channelLabel. Цей канал публічний, і кожен, хто має ключ PSK, може це побачити.'; + return 'Ви збираєтесь поділитись геопозицією у $channelLabel. Цей канал публічний, і кожен, хто має ключ PSK, може це побачити.'; } @override String get map_connectToShareMarkers => - 'Підключіться до пристрою, щоб поділитися маркерами'; + 'Підключіться до пристрою, щоб поділитись маркерами'; @override String get map_filterNodes => 'Фільтрувати вузли'; @@ -1688,7 +1775,7 @@ class AppLocalizationsUk extends AppLocalizations { String get map_otherNodes => 'Інші вузли'; @override - String get map_showOverlaps => 'Перекриття ключа повторювача'; + String get map_showOverlaps => 'Перекриття ключів ретрансляторів'; @override String get map_keyPrefix => 'Префікс ключа'; @@ -1707,13 +1794,13 @@ class AppLocalizationsUk extends AppLocalizations { @override String get map_showGuessedLocations => - 'Показати місцезнаходження передбачених вузлів'; + 'Показати геопозиції передбачених вузлів'; @override - String get map_showDiscoveryContacts => 'Показати контакти Відкриття'; + String get map_showDiscoveryContacts => 'Показати виявлені контакти'; @override - String get map_guessedLocation => 'Визначено місцезнаходження'; + String get map_guessedLocation => 'Передбачена геопозиція'; @override String get map_lastSeenTime => 'Час останньої активності'; @@ -1722,7 +1809,10 @@ class AppLocalizationsUk extends AppLocalizations { String get map_sharedPin => 'Спільний пін'; @override - String get map_joinRoom => 'Приєднатися до кімнати'; + String get map_sharedAt => 'Поділено'; + + @override + String get map_joinRoom => 'Приєднатись до кімнати'; @override String get map_manageRepeater => 'Керувати ретранслятором'; @@ -1734,13 +1824,13 @@ class AppLocalizationsUk extends AppLocalizations { String get map_runTrace => 'Виконати трасування шляху'; @override - String get map_runTraceWithReturnPath => 'Повернутися назад тим же шляхом'; + String get map_runTraceWithReturnPath => 'Повернутись назад тим же шляхом'; @override String get map_removeLast => 'Видалити останній'; @override - String get map_pathTraceCancelled => 'Відмінується трасування шляху'; + String get map_pathTraceCancelled => 'Трасування шляху скасовано.'; @override String get mapCache_title => 'Офлайн-кеш карти'; @@ -1880,7 +1970,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get dialog_disconnectConfirm => - 'Ви впевнені, що хочете відключитися від цього пристрою?'; + 'Ви впевнені, що хочете відключитись від цього пристрою?'; @override String get login_repeaterLogin => 'Вхід у ретранслятор'; @@ -1916,10 +2006,10 @@ class AppLocalizationsUk extends AppLocalizations { String get login_routingMode => 'Режим маршрутизації'; @override - String get login_autoUseSavedPath => 'Авто (використовувати збережений шлях)'; + String get login_autoUseSavedPath => 'Авто (збережений шлях)'; @override - String get login_forceFloodMode => 'Примусово на всю мережу'; + String get login_forceFloodMode => 'Примусово через всю мережу'; @override String get login_managePaths => 'Керувати шляхами'; @@ -1957,10 +2047,10 @@ class AppLocalizationsUk extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'стрибками', - many: 'стрибками', - few: 'стрибками', - one: 'стрибком', + other: 'переходами', + many: 'переходами', + few: 'переходами', + one: 'переходом', ); return 'Використання шляху з $count $_temp0'; } @@ -1973,7 +2063,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get path_hexPrefixInstructions => - 'Введіть 2-символьні hex-префікси для кожного стрибка, розділені комами.'; + 'Введіть 2-символьні hex-префікси для кожного переходу, розділені комами.'; @override String get path_hexPrefixExample => @@ -1984,7 +2074,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get path_helperMaxHops => - 'Макс. 64 стрибки. Кожен префікс - 2 шістнадцяткові символи (1 байт)'; + 'Макс. 64 переходи. Кожен префікс — 2 шістнадцяткові символи (1 байт)'; @override String get path_selectFromContacts => 'Вибрати з контактів:'; @@ -2003,7 +2093,7 @@ class AppLocalizationsUk extends AppLocalizations { } @override - String get path_tooLong => 'Шлях занадто довгий. Максимум 64 стрибки.'; + String get path_tooLong => 'Шлях занадто довгий. Максимум 64 переходи.'; @override String get path_setPath => 'Встановити шлях'; @@ -2024,7 +2114,7 @@ class AppLocalizationsUk extends AppLocalizations { String get repeater_managementTools => 'Інструменти керування'; @override - String get repeater_guestTools => 'Інструменти для гостей'; + String get repeater_guestTools => 'Гостьові інструменти'; @override String get repeater_status => 'Статус'; @@ -2041,7 +2131,7 @@ class AppLocalizationsUk extends AppLocalizations { 'Показати телеметрію сенсорів та статистику системи'; @override - String get repeater_cli => 'CLI'; + String get repeater_cli => 'CLI (Command Line Interface)'; @override String get repeater_cliSubtitle => 'Надіслати команди ретранслятору'; @@ -2051,7 +2141,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_neighborsSubtitle => - 'Показати сусідів нульового стрибка.'; + 'Показати сусідів, доступних без ретрансляції.'; @override String get repeater_settings => 'Налаштування'; @@ -2077,7 +2167,7 @@ class AppLocalizationsUk extends AppLocalizations { 'Авто (використовувати збережений шлях)'; @override - String get repeater_forceFloodMode => 'Примусово на всю мережу'; + String get repeater_forceFloodMode => 'Примусово через всю мережу'; @override String get repeater_pathManagement => 'Керування шляхами'; @@ -2130,6 +2220,9 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_rxAirtime => 'Ефірний час RX'; + @override + String get repeater_chanUtil => 'Використання каналу'; + @override String get repeater_packetStatistics => 'Статистика пакетів'; @@ -2154,17 +2247,17 @@ class AppLocalizationsUk extends AppLocalizations { @override String repeater_packetTxTotal(int total, String flood, String direct) { - return 'Всього: $total, На всю мережу: $flood, Прямі: $direct'; + return 'Всього: $total, Через всю мережу: $flood, Прямі: $direct'; } @override String repeater_packetRxTotal(int total, String flood, String direct) { - return 'Всього: $total, На всю мережу: $flood, Прямі: $direct'; + return 'Всього: $total, Через всю мережу: $flood, Прямі: $direct'; } @override String repeater_duplicatesFloodDirect(String flood, String direct) { - return 'На всю мережу: $flood, Прямі: $direct'; + return 'Через всю мережу: $flood, Прямі: $direct'; } @override @@ -2223,7 +2316,7 @@ class AppLocalizationsUk extends AppLocalizations { String get repeater_codingRate => 'Швидкість кодування'; @override - String get repeater_locationSettings => 'Налаштування розташування'; + String get repeater_locationSettings => 'Налаштування геопозиції'; @override String get repeater_latitude => 'Широта'; @@ -2261,14 +2354,14 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_privacyModeSubtitle => - 'Приховати ім\'я/розташування в оголошеннях'; + 'Приховати ім\'я/геопозицію в оголошеннях'; @override String get repeater_advertisementSettings => 'Налаштування оголошень'; @override String get repeater_localAdvertInterval => - 'Інтервал локальних оголошень (0 стрибків)'; + 'Інтервал локальних оголошень (без ретрансляції)'; @override String repeater_localAdvertIntervalMinutes(int minutes) { @@ -2277,7 +2370,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_floodAdvertInterval => - 'Інтервал оголошень на всю мережу (flood)'; + 'Інтервал оголошень через всю мережу (flood)'; @override String repeater_floodAdvertIntervalHours(int hours) { @@ -2304,7 +2397,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_regenerateIdentityKey => - 'Перегенерувати ключ ідентичності'; + 'Перегенерувати ключ ідентифікації'; @override String get repeater_regenerateIdentityKeySubtitle => @@ -2312,7 +2405,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_regenerateIdentityKeyConfirm => - 'Це створить нову ідентичність для ретранслятора. Продовжити?'; + 'Це створить нову ідентифікацію для ретранслятора. Продовжити?'; @override String get repeater_eraseFileSystem => 'Очистити файлову систему'; @@ -2345,6 +2438,163 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_settingsSaved => 'Налаштування успішно збережено.'; + @override + String get repeater_rxGain => 'Підвищена ефективність RX'; + + @override + String get repeater_rxGainHelper => + 'Вища чутливість, більший струм споживання (тільки для SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => 'Оновіть підвищений прибуток від RX'; + + @override + String get repeater_multiAcks => 'Багато підтверджень'; + + @override + String get repeater_multiAcksSubtitle => + 'Розпізнавайте повідомлення через різні канали для кращої доставки.'; + + @override + String get repeater_refreshMultiAcks => 'Оновити кілька підтверджень'; + + @override + String get repeater_networkHealth => 'Стан мережі'; + + @override + String get repeater_loopDetect => 'Виявлення циклів'; + + @override + String get repeater_loopDetectHelper => + 'Створіть пакети, які імітують цикли маршрутизації.'; + + @override + String get repeater_loopDetectOff => 'Відключення'; + + @override + String get repeater_loopDetectMinimal => 'Мінімальний'; + + @override + String get repeater_loopDetectModerate => 'Помірний'; + + @override + String get repeater_loopDetectStrict => 'Суворий'; + + @override + String get repeater_dutyCycle => 'Цикл роботи'; + + @override + String get repeater_dutyCycleHelper => + 'Максимальний відсоток часу, який може бути виділено для трансляції.'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => 'Інформація про оператора'; + + @override + String get repeater_ownerInfoHelper => + 'Публічні метадані для цього ретранслятора'; + + @override + String get repeater_refreshOwnerInfo => 'Оновити інформацію про оператора'; + + @override + String get repeater_floodMax => + 'Максимальна кількість стрибків під час повені'; + + @override + String get repeater_floodMaxHelper => + 'Максимальна кількість хмелю, яку може містити один пакет (0-64)'; + + @override + String get repeater_advancedSettings => 'Просунутий'; + + @override + String get repeater_advancedSettingsSubtitle => + 'Регулювальні ручки для досвідчених операторів'; + + @override + String get repeater_pathHashMode => 'Режим хешування шляху'; + + @override + String get repeater_pathHashModeHelper => + 'Байти, що використовуються для кодування ідентифікатора цього ретранслятора в тегах для виявлення потоків/петлі. 0=1 байт (256 ідентифікаторів, до 64 перехідів), 1=2 байти (65 000 ідентифікаторів, до 32 перехідів), 2=3 байти (16 мільйонів ідентифікаторів, до 21 переходу). Версії 1.13 та старіші не підтримують багатобайтні шляхи — вони активуються лише після того, як мережа буде оновлена до версії 1.14+.'; + + @override + String get repeater_txDelay => 'Затримка у Flood, штат Техас'; + + @override + String get repeater_txDelayHelper => + 'Повторне надсилання з урахуванням навантаження від потоків транспорту, як множник від часу передачі пакета (0-2, за замовчуванням 0,5). Чим вище значення, тим менше конфліктів, але повільніше передавання.'; + + @override + String get repeater_directTxDelay => 'Пряме затримка TX'; + + @override + String get repeater_directTxDelayHelper => + 'Відновлення інтервалів для прямого (немасового) трафіку, як множник часу передачі пакета (від 0 до 2, за замовчуванням 0,3).'; + + @override + String get repeater_intThresh => 'Порогове значення перешкод'; + + @override + String get repeater_intThreshHelper => + 'Порогове значення встановлено для калібрування шумового рівня радіо, щоб відхиляти сигнали, що перевищують цей рівень. 0 – вимкнено; активуйте лише у разі виявлення помилок RX у шумному діапазоні.'; + + @override + String get repeater_agcResetInterval => 'Інтервал перезавантаження AGC'; + + @override + String get repeater_agcResetIntervalHelper => + 'Як часто потрібно скидати автоматичне регулювання гучності радіо, щоб відновити нормальну роботу після ситуації, коли гучність була заблокована. Кожні кілька секунд, зменшуючи значення до кратного 4. Вимкнення періодичного скидання.'; + + @override + String get repeater_actionsTitle => 'Дії'; + + @override + String get repeater_sendAdvert => 'Надіслати рекламу щодо повені'; + + @override + String get repeater_sendAdvertSubtitle => + 'Розповсюдити рекламу про надзвичайну ситуацію (повен) через мережу.'; + + @override + String get repeater_sendAdvertZeroHop => 'Надіслати рекламу без посередників'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => + 'Розповсюдити рекламу з однією переадресацією (без повторного розповсюдження)'; + + @override + String get repeater_clockSync => 'Синхронізувати годинник зараз'; + + @override + String get repeater_clockSyncSubtitle => + 'Передайте час вашого телефону на ретранслятор.'; + + @override + String repeater_actionSucceeded(String action) { + return '$action succeeded'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action failed: $error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => + 'Налаштування збережено — перезавантажте ретранслятор для застосування.'; + + @override + String repeater_settingsPartialFailure(String failures) { + return 'Деякі налаштування не вдалося застосувати: $failures'; + } + @override String repeater_errorSavingSettings(String error) { return 'Помилка збереження налаштувань: $error'; @@ -2359,10 +2609,6 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_refreshTxPower => 'Оновити потужність TX'; - @override - String get repeater_refreshLocationSettings => - 'Оновити налаштування розташування'; - @override String get repeater_refreshPacketForwarding => 'Оновити пересилання пакетів'; @@ -2372,10 +2618,6 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_refreshPrivacyMode => 'Оновити режим приватності'; - @override - String get repeater_refreshAdvertisementSettings => - 'Оновити налаштування оголошень'; - @override String repeater_refreshed(String label) { return '$label оновлено'; @@ -2450,7 +2692,7 @@ class AppLocalizationsUk extends AppLocalizations { String get repeater_cliQuickClockSync => 'Синхронізація годинника'; @override - String get repeater_cliQuickDiscovery => 'Відкрити сусідів'; + String get repeater_cliQuickDiscovery => 'Виявити сусідів'; @override String get repeater_cliHelpAdvert => 'Надсилає пакет оголошення'; @@ -2492,7 +2734,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_cliHelpSetFloodMax => - 'Встановлює максимальну кількість стрибків для вхідних пакетів flood (якщо >= max, пакет не пересилається).'; + 'Встановлює максимальну кількість переходів для вхідних пакетів flood (якщо >= max, пакет не пересилається).'; @override String get repeater_cliHelpSetIntThresh => @@ -2512,7 +2754,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_cliHelpSetFloodAdvertInterval => - 'Встановлює інтервал таймера в годинах для надсилання пакету оголошення на всю мережу. Встановіть 0 для вимкнення.'; + 'Встановлює інтервал таймера в годинах для надсилання пакету оголошення через всю мережу. Встановіть 0 для вимкнення.'; @override String get repeater_cliHelpSetGuestPassword => @@ -2539,7 +2781,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_cliHelpSetTxDelay => - 'Встановлює множник для часу роботи в режимі «на всю мережу» (flood) для пакету та системи випадкових слотів, щоб затримати його відправку (для зменшення ймовірності колізій).'; + 'Встановлює множник для часу роботи в режимі «через всю мережу» (flood) для пакету та системи випадкових слотів, щоб затримати його відправку (для зменшення ймовірності колізій).'; @override String get repeater_cliHelpSetDirectTxDelay => @@ -2602,7 +2844,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_cliHelpRegion => - '(тільки серійний) Перелічує всі визначені регіони та поточні дозволи на оголошення «на всю мережу» (flood).'; + '(тільки серійний) Перелічує всі визначені регіони та поточні дозволи на оголошення «через всю мережу» (flood).'; @override String get repeater_cliHelpRegionLoad => @@ -2656,11 +2898,11 @@ class AppLocalizationsUk extends AppLocalizations { @override String get repeater_cliHelpGpsAdvert => - 'Надає конфігурацію оголошення розташування вузла:\n- none : не включати розташування в оголошення\n- share : ділитися розташуванням GPS (з SensorManager)\n- prefs : оголошувати розташування, збережене в налаштуваннях'; + 'Надає конфігурацію оголошення геопозиції вузла:\n- none : не включати геопозицію в оголошення\n- share : ділитись геопозицією GPS (з SensorManager)\n- prefs : оголошувати геопозицію, збережену в налаштуваннях'; @override String get repeater_cliHelpGpsAdvertSet => - 'Встановлює конфігурацію оголошення розташування.'; + 'Встановлює конфігурацію оголошення геопозиції.'; @override String get repeater_commandsListTitle => 'Список команд'; @@ -2679,7 +2921,7 @@ class AppLocalizationsUk extends AppLocalizations { String get repeater_bridge => 'Міст'; @override - String get repeater_logging => 'Логування'; + String get repeater_logging => 'Журналювання'; @override String get repeater_neighborsRepeaterOnly => 'Сусіди (Тільки ретранслятор)'; @@ -2699,6 +2941,285 @@ class AppLocalizationsUk extends AppLocalizations { String get repeater_gpsNote => 'Команда GPS була введена для керування питаннями, пов\'язаними з локацією.'; + @override + String get repeater_getCategory => 'Отримати цінності'; + + @override + String get repeater_powerMgmt => 'Управління енергоспоживанням'; + + @override + String get repeater_sensors => 'Датчики'; + + @override + String get repeater_cliHelpPowerOff => + 'Вмикає живлення пристрою. (очікується відсутність відповіді)'; + + @override + String get repeater_cliHelpClkReboot => + 'Скидає годинник до відомої епохи та перезавантажує пристрій.'; + + @override + String get repeater_cliHelpAdvertZeroHop => + 'Надсилає рекламу, яка не проходить через інші мережі (лише до безпосередніх сусідів).'; + + @override + String get repeater_cliHelpStartOta => + 'Запускає оновлення прошивки безпосередньо через повітря на сумісних платах.'; + + @override + String get repeater_cliHelpTime => + 'Встановлює час пристрою відповідно до заданих секунд від початку епохи Unix. Час не може відкачуватися назад.'; + + @override + String get repeater_cliHelpBoard => + 'Показує виробника/ідентифікатор обладнання.'; + + @override + String get repeater_cliHelpDiscoverNeighbors => + 'Відправляє запит на виявлення сусідніх вузлів. (Тільки для повторювачів)'; + + @override + String get repeater_cliHelpPowersaving => + 'Показує, чи увімкнено режим енергозбереження, чи ні.'; + + @override + String get repeater_cliHelpPowersavingOnOff => + 'Увімкне або вимкне режим енергозбереження (якщо підтримується).'; + + @override + String get repeater_cliHelpErase => + '(Тільки для серійного використання) Форматує файлову систему пристрою. Видаляє всі налаштування та контакти.'; + + @override + String get repeater_cliHelpSetDutyCycle => + 'Встановлює максимальний допустимий цикл передавання як відсоток (від 1 до 100). Автоматично коригує коефіцієнт використання часу.'; + + @override + String get repeater_cliHelpSetPrvKey => + '(Тільки для серійного використання) Замінює приватний ключ ідентифікації пристрою. Необхідне перезавантаження для застосування. Генерує новий публічний ключ.'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(Тільки для SX126x) Увімкнення посиленого рівня RX для покращення чутливості при високому споживанні струму.'; + + @override + String get repeater_cliHelpSetOwnerInfo => + 'Вказує рядок з контактною інформацією власника, який вказано в оголошеннях. Використовуйте \'|\' для переходу на новий рядок.'; + + @override + String get repeater_cliHelpSetPathHashMode => + 'Встановлює режим хешування шляху. 0 = для старих систем, 1 = для стандартних, 2 = для суворих. Впливає на те, як маршрути порівнюються.'; + + @override + String get repeater_cliHelpSetLoopDetect => + 'Встановлює чутливість виявлення циклів маршрутизації: вимкнено, мінімальну, помірну або жорстку.'; + + @override + String get repeater_cliHelpSetFreq => + '(Тільки для серійного пристрою) Швидко встановлює лише частоту. Потрібно перезавантажити. Рекомендується використовувати функцію \"налаштування радіо\", щоб задати всі параметри радіо.'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(Тільки для мосту ESPNow) Встановлює канал Wi-Fi (від 1 до 14), який використовується мостом.'; + + @override + String get repeater_cliHelpGetName => + 'Показує назву узла, яка була налаштована.'; + + @override + String get repeater_cliHelpGetRole => + 'Показує роль прошивки (ретранслятор, сервер кімнати тощо).'; + + @override + String get repeater_cliHelpGetPublicKey => + 'Відображає публічний ключ пристрою.'; + + @override + String get repeater_cliHelpGetPrvKey => + '(Тільки для серійного використання) Показує приватний ключ пристрою. Розглядайте його як секретну інформацію.'; + + @override + String get repeater_cliHelpGetRepeat => + 'Показує, чи активна функція перенаправлення пакетів (роль повторювача).'; + + @override + String get repeater_cliHelpGetTx => + 'Показує потожну потужність передавача в децибелах (dBm).'; + + @override + String get repeater_cliHelpGetFreq => + 'Показує налаштовану радіочастоту в мегагерцах (MHz).'; + + @override + String get repeater_cliHelpGetRadio => + 'Показує повні параметри радіосигналу: частоту, смугу пропускання, коефіцієнт модуляції, швидкість кодування.'; + + @override + String get repeater_cliHelpGetRadioRxGain => + '(Тільки для SX126x) Показує стан посилення сигналу RX.'; + + @override + String get repeater_cliHelpGetAf => + 'Показує поточний коефіцієнт часу трансляції.'; + + @override + String get repeater_cliHelpGetDutyCycle => + 'Показує поточний допустимий цикл роботи як відсоток.'; + + @override + String get repeater_cliHelpGetIntThresh => + 'Показує поріг перешкод каналу в децибелах.'; + + @override + String get repeater_cliHelpGetAgcResetInterval => + 'Показує інтервал перезавантаження AGC у секундах.'; + + @override + String get repeater_cliHelpGetMultiAcks => + 'Показує, чи увімкнено режим подвійного підтвердження (1) або вимкнено (0).'; + + @override + String get repeater_cliHelpGetAllowReadOnly => + 'Показує, чи дозволено лише читання для гостей.'; + + @override + String get repeater_cliHelpGetAdvertInterval => + 'Показує тривалість місцевої рекламної паузи в хвилинах.'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => + 'Показує інтервал часу між рекламними роликами про повені, виражений у годинах.'; + + @override + String get repeater_cliHelpGetGuestPassword => + 'Відображає налаштований пароль для гостей.'; + + @override + String get repeater_cliHelpGetLat => 'Відображає задану широту.'; + + @override + String get repeater_cliHelpGetLon => 'Відображає задану довготу.'; + + @override + String get repeater_cliHelpGetRxDelay => + 'Відображає базове значення rxdelay.'; + + @override + String get repeater_cliHelpGetTxDelay => + 'Показує коефіцієнт затримки сигналу у режимі затоплення.'; + + @override + String get repeater_cliHelpGetDirectTxDelay => + 'Показує коефіцієнт затримки сигналу в режимі прямого зв\'язку.'; + + @override + String get repeater_cliHelpGetFloodMax => + 'Показує максимальну кількість підйомів, спричинених повенем.'; + + @override + String get repeater_cliHelpGetOwnerInfo => + 'Відображає рядок з контактною інформацією власника.'; + + @override + String get repeater_cliHelpGetPathHashMode => + 'Відображає режим хешування шляху (0/1/2).'; + + @override + String get repeater_cliHelpGetLoopDetect => + 'Демонструє чутливість до виявлення циклів.'; + + @override + String get repeater_cliHelpGetAcl => + '(Тільки для серій) Перераховує записи контролю доступу на репітері.'; + + @override + String get repeater_cliHelpGetBridgeEnabled => + 'Показує, чи увімкнено цей міст.'; + + @override + String get repeater_cliHelpGetBridgeDelay => + 'Показує затримку мосту в мілісекундах.'; + + @override + String get repeater_cliHelpGetBridgeSource => + 'Показує, чи маршрутизує міст пакети RX або TX.'; + + @override + String get repeater_cliHelpGetBridgeBaud => + '(Тільки для мосту RS232) Показує швидкість передачі даних на мосту.'; + + @override + String get repeater_cliHelpGetBridgeChannel => + '(Тільки для мосту ESPNow) Показує канал WiFi мосту.'; + + @override + String get repeater_cliHelpGetBridgeSecret => + '(Тільки для мосту ESPNow) Показує секрет, який використовується для зв\'язку.'; + + @override + String get repeater_cliHelpGetBootloaderVer => + '(Тільки для NRF52) Показує версію завантажувача.'; + + @override + String get repeater_cliHelpGetAdcMultiplier => + 'Відображає коефіцієнт множення аналого-цифрового перетворювача (масштабування напруги від батареї).'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => + 'Показує, чи має рада директорів підтримку в управлінні енергоспоживанням.'; + + @override + String get repeater_cliHelpGetPwrMgtSource => + 'Показує поточне джерело живлення: зовнішнє або акумуляторне.'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => + 'Показує останні причини перезавантаження та вимкнення.'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => + 'Показує напругу акумулятора під час запуску системи в мілівольтах (мВ).'; + + @override + String get repeater_cliHelpSensorGet => + 'Читає налаштування датчика, вказане за допомогою ключа.'; + + @override + String get repeater_cliHelpSensorSet => + 'Створює налаштування для спеціального датчика.'; + + @override + String get repeater_cliHelpSensorList => + 'Перераховує всі налаштування користувацьких датчиків, розділені на сторінки, починаючи з опціонального індексу початку.'; + + @override + String get repeater_cliHelpRegionDefault => + 'Показує поточний область дії за замовчуванням.'; + + @override + String get repeater_cliHelpRegionDefaultSet => + 'Встановлює значення регіону за замовчуванням. Використовуйте \"\", щоб очистити.'; + + @override + String get repeater_cliHelpRegionListAllowed => + 'Перелік регіонів, де дозволено рух транспорту під час повені.'; + + @override + String get repeater_cliHelpRegionListDenied => + 'Перелік регіонів, які забороняють рух транспорту під час повені.'; + + @override + String get repeater_cliHelpStatsPackets => + '(Тільки для серійного використання) Відображає статистику на рівні пакетів.'; + + @override + String get repeater_cliHelpStatsRadio => + '(Тільки для серій) Відображає радіостатистику.'; + + @override + String get repeater_cliHelpStatsCore => + '(Тільки для серійного використання) Відображає основні статистичні дані про програмне забезпечення.'; + @override String get telemetry_receivedData => 'Дані телеметрії отримано'; @@ -2790,7 +3311,7 @@ class AppLocalizationsUk extends AppLocalizations { String get channelPath_otherObservedPaths => 'Інші спостережувані шляхи'; @override - String get channelPath_repeaterHops => 'Стрибки ретранслятора'; + String get channelPath_repeaterHops => 'Переходи через ретранслятори'; @override String get channelPath_noHopDetails => @@ -2822,7 +3343,7 @@ class AppLocalizationsUk extends AppLocalizations { } @override - String get channelPath_noLocationData => 'Немає даних про розташування'; + String get channelPath_noLocationData => 'Немає даних про геопозицію'; @override String channelPath_timeWithDate(int day, int month, String time) { @@ -2838,19 +3359,19 @@ class AppLocalizationsUk extends AppLocalizations { String get channelPath_unknownPath => 'Невідомий'; @override - String get channelPath_floodPath => 'На всю мережу'; + String get channelPath_floodPath => 'Через всю мережу'; @override - String get channelPath_directPath => 'Прямий'; + String get channelPath_directPath => 'Напряму'; @override String channelPath_observedZeroOf(int total) { - return '0 з $total стрибків'; + return '0 з $total переходів'; } @override String channelPath_observedSomeOf(int observed, int total) { - return '$observed з $total стрибків'; + return '$observed з $total переходів'; } @override @@ -2878,7 +3399,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get channelPath_noHopDetailsAvailable => - 'Деталі стрибків недоступні для цього пакету.'; + 'Деталі переходів недоступні для цього пакету.'; @override String get channelPath_unknownRepeater => 'Невідомий ретранслятор'; @@ -2891,17 +3412,17 @@ class AppLocalizationsUk extends AppLocalizations { @override String get community_createDesc => - 'Створити нову спільноту та поділитися через QR-код.'; + 'Створити нову спільноту та поділитись через QR-код.'; @override - String get community_join => 'Приєднатися'; + String get community_join => 'Приєднатись'; @override - String get community_joinTitle => 'Приєднатися до спільноти'; + String get community_joinTitle => 'Приєднатись до спільноти'; @override String community_joinConfirmation(String name) { - return 'Ви бажаєте приєднатися до спільноти «$name»?'; + return 'Ви бажаєте приєднатись до спільноти «$name»?'; } @override @@ -2937,16 +3458,16 @@ class AppLocalizationsUk extends AppLocalizations { } @override - String get community_qrTitle => 'Поділитися спільнотою'; + String get community_qrTitle => 'Поділитись спільнотою'; @override String community_qrInstructions(String name) { - return 'Відскануйте цей QR-код, щоб приєднатися до $name'; + return 'Відскануйте цей QR-код, щоб приєднатись до $name'; } @override String get community_hashtagPrivacyHint => - 'Канали хештегів спільноти доступні лише членам спільноти'; + 'Хештег-канали спільноти доступні лише членам спільноти'; @override String get community_invalidQrCode => 'Недійсний QR-код спільноти'; @@ -3003,11 +3524,11 @@ class AppLocalizationsUk extends AppLocalizations { } @override - String get community_regenerateSecret => 'Перегенерувати секрет'; + String get community_regenerateSecret => 'Перегенерувати секретний ключ'; @override String community_regenerateSecretConfirm(String name) { - return 'Перегенерувати секретний ключ для «$name»? Всі учасники повинні будуть відсканувати новий QR-код, щоб продовжити спілкування.'; + return 'Перегенерувати секретний ключ для «$name»? Усі учасники матимуть відсканувати новий QR-код, щоб продовжити спілкування.'; } @override @@ -3015,20 +3536,20 @@ class AppLocalizationsUk extends AppLocalizations { @override String community_secretRegenerated(String name) { - return 'Секретний пароль для «$name» перегенеровано'; + return 'Секретний ключ для «$name» перегенеровано'; } @override - String get community_updateSecret => 'Оновити секрет'; + String get community_updateSecret => 'Оновити секретний ключ'; @override String community_secretUpdated(String name) { - return 'Зміну секрету для «$name» оновлено'; + return 'Секретний ключ для «$name» оновлено'; } @override String community_scanToUpdateSecret(String name) { - return 'Відскануйте новий QR-код, щоб оновити пароль для «$name»'; + return 'Відскануйте новий QR-код, щоб оновити секретний ключ для «$name»'; } @override @@ -3036,7 +3557,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get community_addHashtagChannelDesc => - 'Додати канал хештегу для цієї спільноти'; + 'Додати хештег-канал для цієї спільноти'; @override String get community_selectCommunity => 'Вибрати спільноту'; @@ -3046,7 +3567,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get community_regularHashtagDesc => - 'Публічний хештег (будь-хто може приєднатися)'; + 'Публічний хештег (будь-хто може приєднатись)'; @override String get community_communityHashtag => 'Хештег спільноти'; @@ -3070,7 +3591,7 @@ class AppLocalizationsUk extends AppLocalizations { String get listFilter_latestMessages => 'Останні повідомлення'; @override - String get listFilter_heardRecently => 'Нещодавно чули'; + String get listFilter_heardRecently => 'Нещодавно почуті'; @override String get listFilter_az => 'А-Я'; @@ -3109,17 +3630,17 @@ class AppLocalizationsUk extends AppLocalizations { String get pathTrace_you => 'Ви'; @override - String get pathTrace_failed => 'Відстеження шляху не вдалося.'; + String get pathTrace_failed => 'Відстеження шляху не вдалось.'; @override String get pathTrace_notAvailable => 'Трасування шляху недоступне.'; @override - String get pathTrace_refreshTooltip => 'Оновити Path Trace'; + String get pathTrace_refreshTooltip => 'Оновити трасування шляху'; @override String get pathTrace_someHopsNoLocation => - 'Одне або більше хмелів відсутнє місце розташування!'; + 'Один або декілька переходів не мають даних про геопозицію!'; @override String get pathTrace_clearTooltip => 'Очистити шлях'; @@ -3155,7 +3676,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String losCustomPointLabel(int index) { - return 'Спеціальний $index'; + return 'Власна точка $index'; } @override @@ -3220,7 +3741,7 @@ class AppLocalizationsUk extends AppLocalizations { 'Недійсні дані про точки/висоту для розрахунку LOS.'; @override - String get losRenameCustomPoint => 'Перейменуйте спеціальну точку'; + String get losRenameCustomPoint => 'Перейменувати власну точку'; @override String get losPointName => 'Назва точки'; @@ -3244,6 +3765,37 @@ class AppLocalizationsUk extends AppLocalizations { @override String get losLegendTerrain => 'Рельєф'; + @override + String get losBlockedSpotsTitle => 'Заблоковані місця'; + + @override + String get losBlockedSpotsHint => + 'Натисніть на заблоковане місце, щоб виділити його на карті.'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => 'Вибраний об\'єкт перешкоди'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => 'Частота'; @@ -3270,10 +3822,10 @@ class AppLocalizationsUk extends AppLocalizations { String get contacts_ping => 'Пінгувати'; @override - String get contacts_repeaterPathTrace => 'Трасування шляху до повторювача'; + String get contacts_repeaterPathTrace => 'Трасування шляху до ретранслятора'; @override - String get contacts_repeaterPing => 'Пінгувати повторювач'; + String get contacts_repeaterPing => 'Пінгувати ретранслятор'; @override String get contacts_roomPathTrace => 'Трасування шляху до серверу кімнати'; @@ -3299,28 +3851,26 @@ class AppLocalizationsUk extends AppLocalizations { String get contacts_contactImported => 'Контакт було імпортовано.'; @override - String get contacts_contactImportFailed => 'Контакт не вдалося імпортувати'; + String get contacts_contactImportFailed => 'Контакт не вдалось імпортувати'; @override - String get contacts_zeroHopAdvert => 'Реклама без перехоплення'; + String get contacts_zeroHopAdvert => 'Оголошення без ретрансляції'; @override - String get contacts_floodAdvert => 'Залив реклами'; + String get contacts_floodAdvert => 'Оголошення з ретрансляцією'; @override - String get contacts_copyAdvertToClipboard => - 'Копіювати оголошення в буфер обміну'; + String get contacts_copyAdvertToClipboard => 'Копіювати оголошення'; @override - String get contacts_addContactFromClipboard => - 'Додати контакт з буфера обміну'; + String get contacts_addContactFromClipboard => 'Додати контакт з буфера'; @override String get contacts_ShareContact => 'Копіювати контакт у буфер обміну'; @override String get contacts_ShareContactZeroHop => - 'Поділитися контактом за оголошенням'; + 'Поділитись контактом за оголошенням'; @override String get contacts_zeroHopContactAdvertSent => @@ -3328,15 +3878,15 @@ class AppLocalizationsUk extends AppLocalizations { @override String get contacts_zeroHopContactAdvertFailed => - 'Не вдалося надіслати контакт.'; + 'Не вдалось надіслати контакт.'; @override String get contacts_contactAdvertCopied => - 'Рекламу скопійовано до буфера обміну.'; + 'Оголошення скопійовано до буфера обміну.'; @override String get contacts_contactAdvertCopyFailed => - 'Копіювання оголошення в буфер обміну завершилося невдало'; + 'Копіювання оголошення в буфер обміну завершилось невдало'; @override String get notification_activityTitle => 'Активність MeshCore'; @@ -3374,7 +3924,7 @@ class AppLocalizationsUk extends AppLocalizations { locale: localeName, other: 'нових вузлів', many: 'нових вузлів', - few: 'нових вузли', + few: 'нові вузли', one: 'новий вузол', ); return '$count $_temp0'; @@ -3390,25 +3940,25 @@ class AppLocalizationsUk extends AppLocalizations { @override String get settings_gpxExportRepeaters => - 'Експортувати ретранслятори / сервер кімнати до GPX'; + 'Експорт ретрансляторів і серверів кімнат у GPX'; @override String get settings_gpxExportRepeatersSubtitle => - 'Експортує ретранслятори / сервер кімнати з місцезнаходженням у файл GPX.'; + 'Експортує ретранслятори та сервери кімнат з геопозицією у файл GPX.'; @override - String get settings_gpxExportContacts => 'Експортувати супутників до GPX'; + String get settings_gpxExportContacts => 'Експорт контактів у GPX'; @override String get settings_gpxExportContactsSubtitle => - 'Експортує супутників з місцезнаходженням у файл GPX.'; + 'Експортує контакти з геопозицією у файл GPX.'; @override - String get settings_gpxExportAll => 'Експортувати всі контакти до GPX'; + String get settings_gpxExportAll => 'Експорт усіх контактів у GPX'; @override String get settings_gpxExportAllSubtitle => - 'Експортує всі контакти з місцем розташування у файл GPX.'; + 'Експортує всі контакти з геопозицією у файл GPX.'; @override String get settings_gpxExportSuccess => 'Успішно експортовано файл GPX.'; @@ -3421,14 +3971,14 @@ class AppLocalizationsUk extends AppLocalizations { 'Не підтримується на вашому пристрої/операційній системі'; @override - String get settings_gpxExportError => 'Сталася помилка під час експорту.'; + String get settings_gpxExportError => 'Сталась помилка під час експорту.'; @override String get settings_gpxExportRepeatersRoom => - 'Місцезнаходження повторювача та сервера кімнати'; + 'Геопозиції ретрансляторів та серверів кімнат'; @override - String get settings_gpxExportChat => 'Місця супутників'; + String get settings_gpxExportChat => 'Геопозиції контактів'; @override String get settings_gpxExportAllContacts => 'Усі місця контактів'; @@ -3442,7 +3992,7 @@ class AppLocalizationsUk extends AppLocalizations { 'експорт даних карти meshcore-open у форматі GPX'; @override - String get snrIndicator_nearByRepeaters => 'Ближні ретранслятори'; + String get snrIndicator_nearByRepeaters => 'Найближчі ретранслятори'; @override String get snrIndicator_lastSeen => 'Останній раз бачили'; @@ -3463,15 +4013,15 @@ class AppLocalizationsUk extends AppLocalizations { @override String get contactsSettings_autoAddUsersSubtitle => - 'Дозволити супутникові автоматично додавати виявлених користувачів'; + 'Дозволити пристрою-компаньйону автоматично додавати виявлених користувачів'; @override String get contactsSettings_autoAddRepeatersTitle => - 'Автоматично додавати повторювачі'; + 'Автоматично додавати ретранслятори'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Дозволити супутнику автоматично додавати виявлені ретранслятори'; + 'Дозволити пристрою-компаньйону автоматично додавати виявлені ретранслятори'; @override String get contactsSettings_autoAddRoomServersTitle => @@ -3479,15 +4029,15 @@ class AppLocalizationsUk extends AppLocalizations { @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Дозволити супровіднику автоматично додавати виявлені сервери кімнат.'; + 'Дозволити пристрою-компаньйону автоматично додавати виявлені сервери кімнат.'; @override String get contactsSettings_autoAddSensorsTitle => - 'Автоматично додавати датчики'; + 'Автоматично додавати сенсори'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Дозволити супровіднику автоматично додавати виявлені сенсори'; + 'Дозволити пристрою-компаньйону автоматично додавати виявлені сенсори'; @override String get contactsSettings_overwriteOldestTitle => 'Перезаписати найстаріше'; @@ -3537,33 +4087,33 @@ class AppLocalizationsUk extends AppLocalizations { @override String get appSettings_jumpToOldestUnreadSubtitle => - 'При відкритті чату з не прочитаними повідомленнями, прокрутіть до першого не прочитаного повідомлення, а не до останнього.'; + 'При відкритті чату з непрочитаними повідомленнями, прокрутіть до першого непрочитаного повідомлення, а не до останнього.'; @override - String get appSettings_languageHu => 'Угорський'; + String get appSettings_languageHu => 'Угорська'; @override String get appSettings_languageJa => 'Японська'; @override - String get appSettings_languageKo => 'Кореєська'; + String get appSettings_languageKo => 'Корейська'; @override String get radioStats_tooltip => 'Статистика радіо та мережі'; @override - String get radioStats_screenTitle => 'Дані про радіостанції'; + String get radioStats_screenTitle => 'Статистика радіо'; @override String get radioStats_notConnected => - 'Підключіться до пристрою, щоб переглядати статистику радіопередач.'; + 'Підключіться до пристрою, щоб переглядати статистику радіо.'; @override String get radioStats_firmwareTooOld => - 'Статистика радіо приймача вимагає супутнього програмного забезпечення версії 8 або новішої.'; + 'Статистика радіо вимагає прошивки пристрою-компаньйона версії 8 або новішої.'; @override - String get radioStats_waiting => 'Очікую на отримання даних…'; + String get radioStats_waiting => 'Очікування даних…'; @override String radioStats_noiseFloor(int noiseDbm) { @@ -3582,12 +4132,12 @@ class AppLocalizationsUk extends AppLocalizations { @override String radioStats_txAir(int seconds) { - return 'Час трансляції на телеканалі TX (загальний): $seconds секунд'; + return 'Час в ефірі TX (загальний): $seconds секунд'; } @override String radioStats_rxAir(int seconds) { - return 'Загальний час використання RX: $seconds секунд'; + return 'Час в ефірі RX (загальний): $seconds секунд'; } @override @@ -3603,11 +4153,11 @@ class AppLocalizationsUk extends AppLocalizations { String get radioStats_stripWaiting => 'Отримано статистику радіо…'; @override - String get radioStats_settingsTile => 'Дані про радіостанції'; + String get radioStats_settingsTile => 'Статистика радіо'; @override String get radioStats_settingsSubtitle => - 'Рівень шуму, RSSI, SNR та час, протягом якого пристрій використовує радіоканал.'; + 'Рівень шуму, RSSI, SNR та час в ефірі.'; @override String get translation_title => 'Переклад'; @@ -3630,14 +4180,14 @@ class AppLocalizationsUk extends AppLocalizations { String get translation_targetLanguage => 'Цільова мова'; @override - String get translation_useAppLanguage => 'Використовуйте мову додатку'; + String get translation_useAppLanguage => 'Використовувати мову застосунку'; @override String get translation_downloadedModelLabel => 'Завантажений шаблон'; @override String get translation_presetModelLabel => - 'Заздалегідь налаштований модель від Hugging Face'; + 'Попередньо налаштована модель з Hugging Face'; @override String get translation_manualUrlLabel => @@ -3673,7 +4223,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String translation_downloadFailed(String error) { - return 'Не вдалося завантажити: $error'; + return 'Не вдалось завантажити: $error'; } @override @@ -3718,4 +4268,40 @@ class AppLocalizationsUk extends AppLocalizations { @override String get translation_systemLanguage => 'Мова системи'; + + @override + String get background_serviceTitle => 'MeshCore працює'; + + @override + String get background_serviceText => 'Підтримує з\'єднання BLE'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Видалено $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Не вдалось видалити: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Не вдалось оновити канал: $error'; + } + + @override + String get contact_typeChat => 'Чат'; + + @override + String get contact_typeRepeater => 'Ретранслятор'; + + @override + String get contact_typeRoom => 'Кімната'; + + @override + String get contact_typeSensor => 'Сенсор'; + + @override + String get contact_typeUnknown => 'Невідомо'; } diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index 4f38c64..d2304a6 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -44,6 +44,9 @@ class AppLocalizationsZh extends AppLocalizations { @override String get common_close => '关闭'; + @override + String get common_done => 'Done'; + @override String get common_edit => '编辑'; @@ -282,7 +285,7 @@ class AppLocalizationsZh extends AppLocalizations { String get device_quickSwitch => '快速切换'; @override - String get device_meshcore => 'MeshCore'; + String get device_meshcore => '网格核心'; @override String get settings_title => '设置'; @@ -408,9 +411,7 @@ class AppLocalizationsZh extends AppLocalizations { String get settings_advertLocationSubtitle => '在广告中包含位置'; @override - String settings_multiAck(String value) { - return '多重ACK:$value'; - } + String get settings_multiAck => '多重ACK'; @override String get settings_telemetryModeUpdated => '遥测模式已更新'; @@ -418,6 +419,13 @@ class AppLocalizationsZh extends AppLocalizations { @override String get settings_actions => '操作'; + @override + String get settings_deleteAllPaths => 'Delete All Paths'; + + @override + String get settings_deleteAllPathsSubtitle => + 'Clear all path data from contacts.'; + @override String get settings_sendAdvertisement => '发送广播'; @@ -455,10 +463,10 @@ class AppLocalizationsZh extends AppLocalizations { String get settings_debug => '调试'; @override - String get settings_bleDebugLog => 'BLE 调试日志'; + String get settings_companionDebugLog => '调试日志'; @override - String get settings_bleDebugLogSubtitle => 'BLE 命令、响应和原始数据'; + String get settings_companionDebugLogSubtitle => 'BLE/TCP/USB 协议、响应和原始数据'; @override String get settings_appDebugLog => '应用调试日志'; @@ -1017,20 +1025,16 @@ class AppLocalizationsZh extends AppLocalizations { return '频道 $index'; } - @override - String get channels_hashtagChannel => '标签频道'; - @override String get channels_public => '公共'; @override - String get channels_private => '私有'; - - @override - String get channels_publicChannel => '公共频道'; + String channels_via(String path) { + return 'via $path'; + } @override - String get channels_privateChannel => '私有频道'; + String get channels_private => '私有'; @override String get channels_editChannel => '编辑频道'; @@ -1099,11 +1103,63 @@ class AppLocalizationsZh extends AppLocalizations { @override String get channels_smazCompression => 'SMAZ 压缩'; + @override + String get channels_cyr2latCompression => 'Cyr2Lat 压缩'; + + @override + String get channels_cyr2latCompressionDscr => '发送时将一些西里尔字符替换为拉丁字符。'; + + @override + String get channels_cyr2latSettingsHeading => 'Cyr2Lat 設定'; + + @override + String get channels_cyr2latSettingsSubheading => '替換清單'; + + @override + String get channels_cyr2latSettingsDscr => '編輯 JSON 字元替換設定檔'; + + @override + String get channels_cyr2latSettingsDialogHint => 'JSON 替換映射表'; + + @override + String channels_cyr2latSettingsDialogWrongJSON(Object error) { + return 'JSON 格式錯誤:$error'; + } + @override String channels_channelUpdated(String name) { return '频道 \"$name\" 已更新'; } + @override + String get settings_cyr2latProfileAdd => '新增 Cyr2Lat 設定檔'; + + @override + String get settings_cyr2latProfileName => '設定檔名稱'; + + @override + String get settings_cyr2latProfileNameEmpty => '設定檔名稱不能為空'; + + @override + String get settings_cyr2latProfileAdded => '設定檔已成功新增'; + + @override + String get settings_cyr2latProfileUpdated => '設定檔已成功更新'; + + @override + String get settings_cyr2latProfileEdit => '編輯 Cyr2Lat 設定檔'; + + @override + String get settings_cyr2latProfileDelete => '刪除 Cyr2Lat 設定檔'; + + @override + String get settings_cyr2latProfileDeleted => '設定檔已成功刪除'; + + @override + String settings_cyr2latProfileDeleteDscr(String name) { + return '您確定要刪除設定檔 \"$name\" 嗎?'; + } + @override String get channels_publicChannelAdded => '已添加公共频道'; @@ -1114,7 +1170,7 @@ class AppLocalizationsZh extends AppLocalizations { String get channels_sortManual => '手动'; @override - String get channels_sortAZ => 'A-Z'; + String get channels_sortAZ => 'A到Z'; @override String get channels_sortLatestMessages => '最新消息'; @@ -1370,6 +1426,9 @@ class AppLocalizationsZh extends AppLocalizations { @override String get chat_successes => '成功'; + @override + String get chat_score => 'Score'; + @override String get chat_removePath => '移除路径'; @@ -1457,6 +1516,12 @@ class AppLocalizationsZh extends AppLocalizations { return '未读:$count'; } + @override + String get chat_markAsUnread => '标记为未读'; + + @override + String get chat_newMessages => '新的消息'; + @override String get chat_openLink => '打开链接?'; @@ -1535,6 +1600,24 @@ class AppLocalizationsZh extends AppLocalizations { @override String get map_flags => '标志'; + @override + String get map_type => 'Type'; + + @override + String get map_path => 'Path'; + + @override + String get map_location => 'Location'; + + @override + String get map_estLocation => 'Est. Location'; + + @override + String get map_publicKey => 'Public Key'; + + @override + String get map_publicKeyPrefixHint => 'e.g. ab12'; + @override String get map_shareMarkerHere => '在此分享标记'; @@ -1618,6 +1701,9 @@ class AppLocalizationsZh extends AppLocalizations { @override String get map_sharedPin => '共享标记'; + @override + String get map_sharedAt => '已分享'; + @override String get map_joinRoom => '加入房间'; @@ -2000,6 +2086,9 @@ class AppLocalizationsZh extends AppLocalizations { @override String get repeater_rxAirtime => '接收空中时间'; + @override + String get repeater_chanUtil => '频道利用率'; + @override String get repeater_packetStatistics => '数据包统计'; @@ -2073,7 +2162,7 @@ class AppLocalizationsZh extends AppLocalizations { String get repeater_frequencyMhz => '频率 (MHz)'; @override - String get repeater_frequencyHelper => '300-2500 MHz'; + String get repeater_frequencyHelper => '300-2500 兆赫'; @override String get repeater_txPower => 'TX 功率'; @@ -2197,6 +2286,151 @@ class AppLocalizationsZh extends AppLocalizations { @override String get repeater_settingsSaved => '设置保存成功'; + @override + String get repeater_rxGain => '增强的 RX 增益'; + + @override + String get repeater_rxGainHelper => '更高的灵敏度,更大的电流消耗(仅适用于 SX1262/SX1268)'; + + @override + String get repeater_refreshRxGain => '重新启动增强型 RX 功能'; + + @override + String get repeater_multiAcks => '多重确认'; + + @override + String get repeater_multiAcksSubtitle => '通过多个路径确认消息,以提高传递效率。'; + + @override + String get repeater_refreshMultiAcks => '刷新多个确认'; + + @override + String get repeater_networkHealth => '网络健康'; + + @override + String get repeater_loopDetect => '循环检测'; + + @override + String get repeater_loopDetectHelper => '创建看起来像路由环的“洪水包”'; + + @override + String get repeater_loopDetectOff => '离开'; + + @override + String get repeater_loopDetectMinimal => '最少'; + + @override + String get repeater_loopDetectModerate => '适度的'; + + @override + String get repeater_loopDetectStrict => '严格'; + + @override + String get repeater_dutyCycle => '工作周期'; + + @override + String get repeater_dutyCycleHelper => '最大可使用的空闲时间百分比'; + + @override + String repeater_dutyCyclePercent(int percent) { + return '$percent%'; + } + + @override + String get repeater_ownerInfo => '运营商信息'; + + @override + String get repeater_ownerInfoHelper => '此复播器的公共元数据'; + + @override + String get repeater_refreshOwnerInfo => '刷新操作员信息'; + + @override + String get repeater_floodMax => '最大跳跃次数'; + + @override + String get repeater_floodMaxHelper => '一个洪水包中,最大可以传输的跳数 (0-64)'; + + @override + String get repeater_advancedSettings => '高级'; + + @override + String get repeater_advancedSettingsSubtitle => '高级操作员使用的调节旋钮'; + + @override + String get repeater_pathHashMode => '路径哈希模式'; + + @override + String get repeater_pathHashModeHelper => + '用于编码此复用器的 ID 的字节数,在“洪流路径/环检测”标签中使用。 0=1 字节(256 个 ID,最多 64 个跳跃),1=2 字节(65K 个 ID,最多 32 个跳跃),2=3 字节(16M 个 ID,最多 21 个跳跃)。 v1.13 及更早版本的固件会使用多字节路径——只有在您的网络升级到 v1.14 或更高版本后才会生效。'; + + @override + String get repeater_txDelay => '洪水(德克萨斯州)延误'; + + @override + String get repeater_txDelayHelper => + '对于洪水流量,重新传输间隔应设置为包的传输时间(0-2,默认值为0.5)的倍数。 较高的值意味着更少的冲突,但传输速度会变慢。'; + + @override + String get repeater_directTxDelay => '直接的 TX 延迟'; + + @override + String get repeater_directTxDelayHelper => + '对于直接(非广播)流量,重新传输间隔应设置为包的传输时间(0-2,默认值为0.3)的倍数。'; + + @override + String get repeater_intThresh => '干扰阈值'; + + @override + String get repeater_intThreshHelper => + '将阈值传递给射频信号的噪声水平校准,使其能够拒绝高于该水平的干扰。 0 表示禁用——只有在您在嘈杂频段中看到 RX 错误时才启用。'; + + @override + String get repeater_agcResetInterval => 'AGC 恢复间隔'; + + @override + String get repeater_agcResetIntervalHelper => + '为了从失控的增益状态中恢复,应该多久重置收音机的自动增益控制?设置为“秒”,每次重置间隔为4秒。将此选项设置为“0”将禁用周期性重置。'; + + @override + String get repeater_actionsTitle => '行动'; + + @override + String get repeater_sendAdvert => '发布防洪广告'; + + @override + String get repeater_sendAdvertSubtitle => '通过网络播放防洪广告'; + + @override + String get repeater_sendAdvertZeroHop => '发送零跳广告'; + + @override + String get repeater_sendAdvertZeroHopSubtitle => '进行单跳广告广播(不使用中继)'; + + @override + String get repeater_clockSync => '现在同步时钟'; + + @override + String get repeater_clockSyncSubtitle => '将手机的时间设置为与中继器同步'; + + @override + String repeater_actionSucceeded(String action) { + return '$action 成功'; + } + + @override + String repeater_actionFailed(String action, String error) { + return '$action 失败:$error'; + } + + @override + String get repeater_settingsSavedRebootNeeded => '设置已保存 — 重启发射器以应用'; + + @override + String repeater_settingsPartialFailure(String failures) { + return '部分设置失败:$failures'; + } + @override String repeater_errorSavingSettings(String error) { return '保存设置时出错:$error'; @@ -2211,9 +2445,6 @@ class AppLocalizationsZh extends AppLocalizations { @override String get repeater_refreshTxPower => '刷新 TX 功率'; - @override - String get repeater_refreshLocationSettings => '刷新位置设置'; - @override String get repeater_refreshPacketForwarding => '刷新包转发'; @@ -2223,9 +2454,6 @@ class AppLocalizationsZh extends AppLocalizations { @override String get repeater_refreshPrivacyMode => '刷新隐私模式'; - @override - String get repeater_refreshAdvertisementSettings => '刷新广播设置'; - @override String repeater_refreshed(String label) { return '$label 已刷新'; @@ -2497,6 +2725,226 @@ class AppLocalizationsZh extends AppLocalizations { @override String get repeater_gpsNote => 'GPS 命令用于位置相关任务'; + @override + String get repeater_getCategory => '获取值'; + + @override + String get repeater_powerMgmt => '电源管理'; + + @override + String get repeater_sensors => '传感器'; + + @override + String get repeater_cliHelpPowerOff => '关闭设备。(不应有任何响应)'; + + @override + String get repeater_cliHelpClkReboot => '将时钟重置为已知的时间点,并重启设备。'; + + @override + String get repeater_cliHelpAdvertZeroHop => '发送无中继广告(仅限于邻居)。'; + + @override + String get repeater_cliHelpStartOta => '在支持的板上启动通过空中进行固件更新。'; + + @override + String get repeater_cliHelpTime => '将设备时钟设置为给定的 Unix 纪元秒。时钟不能倒退。'; + + @override + String get repeater_cliHelpBoard => '显示制造商/硬件标识。'; + + @override + String get repeater_cliHelpDiscoverNeighbors => '向附近的邻居发送节点发现请求。(仅限中继器)'; + + @override + String get repeater_cliHelpPowersaving => '显示节能模式是否已开启或已关闭。'; + + @override + String get repeater_cliHelpPowersavingOnOff => '启用或禁用节能模式(如果支持)。'; + + @override + String get repeater_cliHelpErase => '(仅适用于序列模式)格式化设备的文件系统。清除所有设置和联系人。'; + + @override + String get repeater_cliHelpSetDutyCycle => + '设定允许的最大传输时段百分比(1-100)。内部调整空闲时间因子。'; + + @override + String get repeater_cliHelpSetPrvKey => + '(仅适用于序列号)替换设备身份私钥。需要重启才能应用。生成一个新的公钥。'; + + @override + String get repeater_cliHelpSetRadioRxGain => + '(仅适用于 SX126x 芯片) 启用增强型 RX 增益,以在较高电流下提高灵敏度。'; + + @override + String get repeater_cliHelpSetOwnerInfo => '设置广告中包含的联系人信息字符串。使用 \'|\' 作为换行符。'; + + @override + String get repeater_cliHelpSetPathHashMode => + '设置路径哈希模式。 0 = 传统模式,1 = 标准模式,2 = 严格模式。 影响路由路径的匹配方式。'; + + @override + String get repeater_cliHelpSetLoopDetect => '设置路由环检测的灵敏度:关闭、低、中、或高。'; + + @override + String get repeater_cliHelpSetFreq => + '(仅限串行模式)快速设置频率。需要重启。 建议使用“设置收音机参数”功能,以便设置完整的收音机参数。'; + + @override + String get repeater_cliHelpSetBridgeChannel => + '(仅适用于 ESPNow 桥)设置桥使用的 WiFi 频道(1-14)。'; + + @override + String get repeater_cliHelpGetName => '显示配置的节点名称。'; + + @override + String get repeater_cliHelpGetRole => '显示固件的功能(如:中继器、房间服务器等)。'; + + @override + String get repeater_cliHelpGetPublicKey => '显示设备的公钥。'; + + @override + String get repeater_cliHelpGetPrvKey => '(仅适用于序列号)显示设备的私钥。请将其视为机密信息。'; + + @override + String get repeater_cliHelpGetRepeat => '显示数据包转发(作为中继器)是否已启用或已禁用。'; + + @override + String get repeater_cliHelpGetTx => '显示当前的发射功率(以dBm为单位)。'; + + @override + String get repeater_cliHelpGetFreq => '显示配置的射频频率(以兆赫兹为单位)。'; + + @override + String get repeater_cliHelpGetRadio => '显示完整的无线电参数:频率、带宽、扩频因子、编码速率。'; + + @override + String get repeater_cliHelpGetRadioRxGain => '(仅适用于 SX126x 模块)显示 RX 放大器的状态。'; + + @override + String get repeater_cliHelpGetAf => '显示当前的空闲时间系数。'; + + @override + String get repeater_cliHelpGetDutyCycle => '显示当前允许的占空比(以百分比表示)。'; + + @override + String get repeater_cliHelpGetIntThresh => '显示信道干扰阈值(以dB为单位)。'; + + @override + String get repeater_cliHelpGetAgcResetInterval => '显示 AGC 重置的间隔时间(以秒为单位)。'; + + @override + String get repeater_cliHelpGetMultiAcks => '显示双重确认模式是否已启用(1)或已禁用(0)。'; + + @override + String get repeater_cliHelpGetAllowReadOnly => '显示是否允许访客仅限查看权限。'; + + @override + String get repeater_cliHelpGetAdvertInterval => '显示本地广告的时间间隔,单位为分钟。'; + + @override + String get repeater_cliHelpGetFloodAdvertInterval => '显示洪水广告的播放时间间隔,以小时为单位。'; + + @override + String get repeater_cliHelpGetGuestPassword => '显示已配置的访客密码。'; + + @override + String get repeater_cliHelpGetLat => '显示已配置的纬度。'; + + @override + String get repeater_cliHelpGetLon => '显示已配置的经度。'; + + @override + String get repeater_cliHelpGetRxDelay => '显示 rxdelay 的基本值。'; + + @override + String get repeater_cliHelpGetTxDelay => '显示洪水模式下的传输延迟系数。'; + + @override + String get repeater_cliHelpGetDirectTxDelay => '显示直接模式下的时延系数。'; + + @override + String get repeater_cliHelpGetFloodMax => '显示最大洪水传播次数。'; + + @override + String get repeater_cliHelpGetOwnerInfo => '显示所有者的联系信息。'; + + @override + String get repeater_cliHelpGetPathHashMode => '显示哈希模式(0/1/2)。'; + + @override + String get repeater_cliHelpGetLoopDetect => '显示循环检测的灵敏度。'; + + @override + String get repeater_cliHelpGetAcl => '(仅适用于序列号)列出复用器上的访问控制条目。'; + + @override + String get repeater_cliHelpGetBridgeEnabled => '显示桥是否已启用。'; + + @override + String get repeater_cliHelpGetBridgeDelay => '显示桥梁延迟的时间,单位为毫秒。'; + + @override + String get repeater_cliHelpGetBridgeSource => '显示桥接设备是否接收或发送 RX 或 TX 类型的数据包。'; + + @override + String get repeater_cliHelpGetBridgeBaud => '(仅限 RS232 桥)显示桥的波特率。'; + + @override + String get repeater_cliHelpGetBridgeChannel => '(仅适用于 ESPNow 桥)显示桥的 WiFi 通道。'; + + @override + String get repeater_cliHelpGetBridgeSecret => '(仅适用于 ESPNow 桥)显示桥的共享密钥。'; + + @override + String get repeater_cliHelpGetBootloaderVer => '(仅适用于NRF52)显示引导程序版本。'; + + @override + String get repeater_cliHelpGetAdcMultiplier => '显示 ADC 乘数(电池电压缩放)。'; + + @override + String get repeater_cliHelpGetPwrMgtSupport => '报告董事会是否支持电源管理功能。'; + + @override + String get repeater_cliHelpGetPwrMgtSource => '显示当前的电源:外部电源或电池。'; + + @override + String get repeater_cliHelpGetPwrMgtBootReason => '显示最近的重置和关闭原因。'; + + @override + String get repeater_cliHelpGetPwrMgtBootMv => '显示启动时的电池电压,单位为毫伏 (mV)。'; + + @override + String get repeater_cliHelpSensorGet => '通过按键读取自定义传感器设置。'; + + @override + String get repeater_cliHelpSensorSet => '编写自定义传感器设置。'; + + @override + String get repeater_cliHelpSensorList => '列出所有自定义传感器设置,并按可选的起始索引进行分页显示。'; + + @override + String get repeater_cliHelpRegionDefault => '显示当前默认的区域范围。'; + + @override + String get repeater_cliHelpRegionDefaultSet => + '设置默认的区域范围。使用 \"\" 可以清除。'; + + @override + String get repeater_cliHelpRegionListAllowed => '列出允许洪水交通的区域。'; + + @override + String get repeater_cliHelpRegionListDenied => '列出禁止洪水交通的区域。'; + + @override + String get repeater_cliHelpStatsPackets => '(仅显示序列信息)显示数据包级别的统计信息。'; + + @override + String get repeater_cliHelpStatsRadio => '(仅显示序列信息)显示收音机相关统计数据。'; + + @override + String get repeater_cliHelpStatsCore => '(仅显示序列号)显示核心固件统计信息。'; + @override String get telemetry_receivedData => '接收到的遥测数据'; @@ -2538,7 +2986,7 @@ class AppLocalizationsZh extends AppLocalizations { @override String telemetry_voltageValue(String volts) { - return '${volts}V'; + return '$volts伏'; } @override @@ -2852,7 +3300,7 @@ class AppLocalizationsZh extends AppLocalizations { String get listFilter_heardRecently => '最近听到'; @override - String get listFilter_az => 'A-Z'; + String get listFilter_az => 'A到Z'; @override String get listFilter_filters => '筛选'; @@ -3016,6 +3464,36 @@ class AppLocalizationsZh extends AppLocalizations { @override String get losLegendTerrain => '地形'; + @override + String get losBlockedSpotsTitle => '被占用区域'; + + @override + String get losBlockedSpotsHint => '点击地图上的某个被遮盖的区域,以突出显示该区域。'; + + @override + String losBlockedSpotChip( + String distance, + String distanceUnit, + String obstruction, + String heightUnit, + ) { + return '$distance $distanceUnit • $obstruction $heightUnit'; + } + + @override + String get losSelectedObstructionTitle => '选择性阻碍'; + + @override + String losSelectedObstructionDetails( + String obstruction, + String heightUnit, + String distanceFromA, + String distanceUnit, + String distanceFromB, + ) { + return 'Blocked by $obstruction $heightUnit, $distanceFromA from A and $distanceFromB from B ($distanceUnit).'; + } + @override String get losFrequencyLabel => '频率'; @@ -3039,7 +3517,7 @@ class AppLocalizationsZh extends AppLocalizations { String get contacts_pathTrace => '路径追踪'; @override - String get contacts_ping => 'Ping'; + String get contacts_ping => '乒'; @override String get contacts_repeaterPathTrace => 'Trace 转发节点'; @@ -3424,4 +3902,40 @@ class AppLocalizationsZh extends AppLocalizations { @override String get translation_systemLanguage => '系统语言'; + + @override + String get background_serviceTitle => 'MeshCore running'; + + @override + String get background_serviceText => 'Keeping BLE connected'; + + @override + String appSettings_translationModelDeleted(String name) { + return 'Deleted $name'; + } + + @override + String appSettings_translationModelDeleteFailed(String error) { + return 'Failed to delete: $error'; + } + + @override + String channels_channelUpdateFailed(String error) { + return 'Failed to update channel: $error'; + } + + @override + String get contact_typeChat => 'Chat'; + + @override + String get contact_typeRepeater => 'Repeater'; + + @override + String get contact_typeRoom => 'Room'; + + @override + String get contact_typeSensor => 'Sensor'; + + @override + String get contact_typeUnknown => 'Unknown'; } diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index 96bdb84..7e83215 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -76,7 +76,7 @@ } }, "scanner_stop": "Stoppen", - "scanner_scan": "Scan", + "scanner_scan": "Scannen", "device_quickSwitch": "Snelle overschakeling", "device_meshcore": "MeshCore", "settings_title": "Instellingen", @@ -98,12 +98,14 @@ "settings_locationInvalid": "Ongeldige breedtegraad of lengtegraad.", "settings_latitude": "Breedtegraad", "settings_longitude": "Lengtegraad", - "settings_privacyMode": "Privacy Mode", + "settings_privacyMode": "Privacy-modus", "settings_privacyModeSubtitle": "Naam/locatie verbergen in advertenties", "settings_privacyModeToggle": "Schakel privacy modus in om je naam en locatie in advertenties te verbergen.", "settings_privacyModeEnabled": "Privacy modus is ingeschakeld", "settings_privacyModeDisabled": "Privacy modus is uitgeschakeld", "settings_actions": "Acties", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Verzend Advertentie", "settings_sendAdvertisementSubtitle": "Nu aanwezigheid uitzenden", "settings_advertisementSent": "Advertentie verzonden", @@ -115,13 +117,13 @@ "settings_rebootDevice": "Apparaat opnieuw opstarten", "settings_rebootDeviceSubtitle": "Herstart het MeshCore-apparaat", "settings_rebootDeviceConfirm": "Ben je er zeker van dat je het apparaat opnieuw wilt opstarten? Je wordt losgekoppeld.", - "settings_debug": "Debug", + "settings_debug": "Foutopsporing", "settings_bleDebugLog": "BLE Debug Log", "settings_bleDebugLogSubtitle": "BLE commando's, antwoorden en ruwe data", - "settings_appDebugLog": "App Debug Log", + "settings_appDebugLog": "Debuglog van de app", "settings_appDebugLogSubtitle": "Toepassingsdebugberichten", "settings_about": "Over", - "settings_aboutVersion": "MeshCore Open v{version}", + "settings_aboutVersion": "MeshCore Open versie {version}", "@settings_aboutVersion": { "placeholders": { "version": { @@ -138,7 +140,7 @@ "settings_infoPublicKey": "Openbare Sleutel", "settings_infoContactsCount": "Aantal Contacten", "settings_infoChannelCount": "Aantal Kanalen", - "settings_presets": "Presets", + "settings_presets": "Voorgeprogrammeerde instellingen", "settings_frequency": "Frequentie (MHz)", "settings_frequencyHelper": "300,0 - 2500,0", "settings_frequencyInvalid": "Ongeldige frequentie (300-2500 MHz)", @@ -164,19 +166,19 @@ "appSettings_themeDark": "Donker", "appSettings_language": "Taal", "appSettings_languageSystem": "Standaardinstelling", - "appSettings_languageEn": "English", - "appSettings_languageFr": "Français", - "appSettings_languageEs": "Español", - "appSettings_languageDe": "Deutsch", - "appSettings_languagePl": "Polski", - "appSettings_languageSl": "Slovenščina", - "appSettings_languagePt": "Português", - "appSettings_languageIt": "Italiano", - "appSettings_languageZh": "中文", - "appSettings_languageSv": "Svenska", + "appSettings_languageEn": "Engels", + "appSettings_languageFr": "Frans", + "appSettings_languageEs": "Spaans", + "appSettings_languageDe": "Duits", + "appSettings_languagePl": "Pools", + "appSettings_languageSl": "Sloveens", + "appSettings_languagePt": "Portugees", + "appSettings_languageIt": "Italiaans", + "appSettings_languageZh": "Chinees", + "appSettings_languageSv": "Zweeds", "appSettings_languageNl": "Nederlands", - "appSettings_languageSk": "Slovenčina", - "appSettings_languageBg": "Български", + "appSettings_languageSk": "Sloveens", + "appSettings_languageBg": "Bulgaars", "appSettings_notifications": "Notificaties", "appSettings_enableNotifications": "Notificaties inschakelen", "appSettings_enableNotificationsSubtitle": "Ontvang meldingen voor berichten en advertenties", @@ -249,7 +251,7 @@ } } }, - "appSettings_debugCard": "Debug", + "appSettings_debugCard": "Foutopsporing", "appSettings_appDebugLogging": "App Debuggen Loggen", "appSettings_appDebugLoggingSubtitle": "Log app debugberichten voor probleemoplossing", "appSettings_appDebugLoggingEnabled": "App debug logging is ingeschakeld", @@ -271,7 +273,7 @@ }, "contacts_manageRepeater": "Beheer Repeater", "contacts_roomLogin": "Ruimte Inloggen", - "contacts_openChat": "Open Chat", + "contacts_openChat": "Open gesprek", "contacts_editGroup": "Groep bewerken", "contacts_deleteGroup": "Groep verwijderen", "contacts_deleteGroupConfirm": "Verwijder {groupName}?", @@ -337,11 +339,8 @@ } } }, - "channels_hashtagChannel": "Hashtag kanaal", "channels_public": "Openbaar", "channels_private": "Privé", - "channels_publicChannel": "Open kanaal", - "channels_privateChannel": "Private kanaal", "channels_editChannel": "Kanaal bewerken", "channels_muteChannel": "Kanaal dempen", "channels_unmuteChannel": "Kanaal dempen opheffen", @@ -388,6 +387,22 @@ } }, "channels_smazCompression": "SMAZ compressie", + "channels_cyr2latCompression": "Cyr2Lat compressie", + "channels_cyr2latCompressionDscr": "Vervangt sommige Cyrillische tekens door Latijnse tekens bij het verzenden.", + "channels_cyr2latSettingsHeading": "Instellingen Cyr2Lat", + "channels_cyr2latSettingsSubheading": "Lijst met vervangingen", + "channels_cyr2latSettingsDscr": "Bewerk de JSON-configuratie voor tekenvervanging", + "channels_cyr2latSettingsDialogHint": "JSON-vervangingskaart", + "channels_cyr2latSettingsDialogWrongJSON": "Onjuiste JSON: {error}", + "settings_cyr2latProfileAdd": "Cyr2Lat-profiel toevoegen", + "settings_cyr2latProfileName": "Profielnaam", + "settings_cyr2latProfileNameEmpty": "Profielnaam mag niet leeg zijn", + "settings_cyr2latProfileAdded": "Profiel succesvol toegevoegd", + "settings_cyr2latProfileUpdated": "Profiel succesvol bijgewerkt", + "settings_cyr2latProfileEdit": "Cyr2Lat-profiel bewerken", + "settings_cyr2latProfileDelete": "Cyr2Lat-profiel verwijderen", + "settings_cyr2latProfileDeleted": "Profiel succesvol verwijderd", + "settings_cyr2latProfileDeleteDscr": "Weet u zeker dat u het profiel \"{name}\" wilt verwijderen?", "channels_channelUpdated": "Kanaal \"{name}\" is bijgewerkt", "@channels_channelUpdated": { "placeholders": { @@ -399,7 +414,7 @@ "channels_publicChannelAdded": "Open kanaal toegevoegd", "channels_sortBy": "Sorteren door", "channels_sortManual": "Handmatig", - "channels_sortAZ": "A-Z", + "channels_sortAZ": "Alfabetisch", "channels_sortLatestMessages": "Recent berichten", "channels_sortUnread": "Ongelezen", "chat_noMessages": "Nog geen berichten.", @@ -468,7 +483,7 @@ "gifPicker_failedLoad": "GIF's konden niet worden geladen", "gifPicker_failedSearch": "Zoeken mislukt", "gifPicker_noInternet": "Geen internetverbinding", - "debugLog_appTitle": "App Debug Log", + "debugLog_appTitle": "Debuglog van de app", "debugLog_bleTitle": "BLE Debug Log", "debugLog_copyLog": "Kopieer log", "debugLog_clearLog": "Log wissen", @@ -477,7 +492,7 @@ "debugLog_noEntries": "Nog geen debug logs beschikbaar.", "debugLog_enableInSettings": "Schakel app debug logging in de instellingen", "debugLog_frames": "Ramen", - "debugLog_rawLogRx": "Raw Log-RX", + "debugLog_rawLogRx": "Niet-verwerkt Log-RX", "debugLog_noBleActivity": "Geen BLE-activiteit nog.", "debugFrame_length": "Frame Lengte: {count} bytes", "@debugFrame_length": { @@ -541,7 +556,7 @@ } } }, - "debugFrame_hexDump": "Hex Dump:", + "debugFrame_hexDump": "Hex-dump:", "chat_pathManagement": "Beheer van Paden", "chat_routingMode": "Routeerwijze", "chat_autoUseSavedPath": "Automatisch (gebruik opgeslagen pad)", @@ -599,7 +614,7 @@ } } }, - "chat_floodAuto": "Flood (auto)", + "chat_floodAuto": "Overstroming (van een auto)", "chat_direct": "Direct", "chat_poiShared": "Gedeelde POI", "chat_unread": "Nieuw: {count}", @@ -622,10 +637,10 @@ } }, "chat_invalidLink": "Ongeldig linkformaat", - "map_title": "Node Map", + "map_title": "Kaart van de knopen", "map_noNodesWithLocation": "Geen nodes met locatiegegevens", "map_nodesNeedGps": "Nodes moeten hun GPS-coördinaten delen\nom op de kaart te verschijnen", - "map_nodesCount": "Nodes: {count}", + "map_nodesCount": "Knooppunten: {count}", "@map_nodesCount": { "placeholders": { "count": { @@ -642,7 +657,7 @@ } }, "map_chat": "Chat", - "map_repeater": "Repeater", + "map_repeater": "Herhaald", "map_room": "Ruimte", "map_sensor": "Sensor", "map_pinDm": "Verzenden als bericht (DM)", @@ -655,7 +670,7 @@ "map_flags": "Vlaggen", "map_shareMarkerHere": "Deel marker hier", "map_pinLabel": "Label vastzetten", - "map_label": "Label", + "map_label": "Etiket", "map_pointOfInterest": "Interessepunt", "map_sendToContact": "Verzenden naar contact", "map_sendToChannel": "Verzenden naar kanaal", @@ -670,10 +685,10 @@ } }, "map_connectToShareMarkers": "Verbind met een apparaat om markers te delen", - "map_filterNodes": "Filter Nodes", + "map_filterNodes": "Filternodes", "map_nodeTypes": "Nodetypes", "map_chatNodes": "Chatnodes", - "map_repeaters": "Repeaters", + "map_repeaters": "Herhaalders", "map_otherNodes": "Andere Nodes", "map_keyPrefix": "Prefix sleutel", "map_filterByKeyPrefix": "Filteren op sleutelvoorgemeld", @@ -696,7 +711,7 @@ } } }, - "mapCache_downloadAction": "Download", + "mapCache_downloadAction": "Downloaden", "mapCache_cachedTiles": "Opgeslagen {count} tegels", "@mapCache_cachedTiles": { "placeholders": { @@ -814,7 +829,7 @@ "login_savePasswordSubtitle": "Het wachtwoord wordt veilig op dit apparaat opgeslagen.", "login_repeaterDescription": "Voer het wachtwoord van de repeater in om instellingen en status te openen.", "login_roomDescription": "Voer het wachtwoord van de kamer in om toegang te krijgen tot instellingen en status.", - "login_routing": "Routing", + "login_routing": "Routeplanning", "login_routingMode": "Routeerwijze", "login_autoUseSavedPath": "Automatisch (gebruik opgeslagen pad)", "login_forceFloodMode": "Dwing Floodmodus Af", @@ -881,7 +896,7 @@ "repeater_managementTools": "Beheerfuncties", "repeater_status": "Status", "repeater_statusSubtitle": "Status, statistieken en buren bekijken", - "repeater_telemetry": "Telemetry", + "repeater_telemetry": "Telemetrie", "repeater_telemetrySubtitle": "Bekijk telemetrie van sensoren en systeemgegevens", "repeater_cli": "CLI", "repeater_cliSubtitle": "Verzend commando's naar de repeater", @@ -963,7 +978,7 @@ } } }, - "repeater_duplicatesFloodDirect": "Flood: {flood}, Direct: {direct}", + "repeater_duplicatesFloodDirect": "Overstroming: {flood}, Direct: {direct}", "@repeater_duplicatesFloodDirect": { "placeholders": { "flood": { @@ -1059,6 +1074,81 @@ }, "repeater_confirm": "Bevestigen", "repeater_settingsSaved": "Instellingen succesvol opgeslagen", + "repeater_rxGain": "Verhoogde RX-uitgang", + "repeater_rxGainHelper": "Hogere gevoeligheid, grotere stroomverbruik (alleen voor SX1262/SX1268)", + "repeater_refreshRxGain": "Versterk de reeds bestaande RX-verbetering.", + "repeater_multiAcks": "Meerdere bevestigingen", + "repeater_multiAcksSubtitle": "Bevestig berichten via verschillende routes voor een betere levering.", + "repeater_refreshMultiAcks": "Herhaal meerdere bevestigingen", + "repeater_networkHealth": "Netwerkgezondheid", + "repeater_loopDetect": "Detectie van beweging", + "repeater_loopDetectHelper": "Verzend pakketten die eruitzien als routing-lusjes", + "repeater_loopDetectOff": "Af", + "repeater_loopDetectMinimal": "Minimaal", + "repeater_loopDetectModerate": "Matig", + "repeater_loopDetectStrict": "Strikte", + "repeater_dutyCycle": "Werkcyclus", + "repeater_dutyCycleHelper": "Maximale percentage van de beschikbare uitzendtijd", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Informatie over de operator", + "repeater_ownerInfoHelper": "Openbare metadata voor deze repeater", + "repeater_refreshOwnerInfo": "Herstel informatie over de operator", + "repeater_floodMax": "Maximale hoeveelheid hop", + "repeater_floodMaxHelper": "Maximale hoeveelheid hop die een pakket kan bevatten (0-64)", + "repeater_advancedSettings": "Geavanceerd", + "repeater_advancedSettingsSubtitle": "Regelhendels voor ervaren gebruikers", + "repeater_pathHashMode": "Hash-modus voor paden", + "repeater_pathHashModeHelper": "Bytes die gebruikt worden om de ID van deze repeater te coderen in flood-pad/lusdetectietags. 0=1 byte (256 ID's, tot 64 hops), 1=2 bytes (65.000 ID's, tot 32 hops), 2=3 bytes (16 miljoen ID's, tot 21 hops). Versies 1.13 en ouder gebruiken multi-byte paden – alleen na het activeren van het netwerk.", + "repeater_txDelay": "Vertraging bij Flood TX", + "repeater_txDelayHelper": "Herzendinterval voor verkeer tijdens overstromingen, als een veelvoud van de tijd die het pakket nodig heeft (0-2, standaard 0.5). Een hoger getal betekent minder botsingen, maar ook een langere leveringstijd.", + "repeater_directTxDelay": "Directe vertraging", + "repeater_directTxDelayHelper": "De overzending van tijdslots voor directe (niet-massaal) verkeer, als een vermenigvuldigingsfactor van de tijd die een pakket nodig heeft (0-2, standaard 0,3).", + "repeater_intThresh": "Grenswaarde voor interferentie", + "repeater_intThreshHelper": "De drempelwaarde is ingesteld zodat de radio storingen boven deze waarde kan detecteren en blokkeren. 0 staat voor \"uitgezet\" – alleen verhoog deze waarde als u fouten in een storingrijke band ziet.", + "repeater_agcResetInterval": "Interval voor het opnieuw instellen van AGC", + "repeater_agcResetIntervalHelper": "Hoe vaak moet u de automatische gainregeling van de radio opnieuw instellen om terug te keren van een situatie waarin de gain vastzit? Elke seconde, of elke 4e seconde. Het uitschakelen van de periodieke reset (0) zorgt ervoor dat de gain niet automatisch wordt aangepast.", + "repeater_actionsTitle": "Acties", + "repeater_sendAdvert": "Verzend advertentie over overstromingen", + "repeater_sendAdvertSubtitle": "Zend een advertentie over overstromingen uit via het netwerk.", + "repeater_sendAdvertZeroHop": "Verzend een advertentie zonder tussenliggende stap", + "repeater_sendAdvertZeroHopSubtitle": "Zend een advertentie met één enkele verbinding (zonder tussenliggende zenders).", + "repeater_clockSync": "Synchroniseer klok nu", + "repeater_clockSyncSubtitle": "Stel de tijd van je telefoon in op de repeater.", + "repeater_actionSucceeded": "{action} is gelukt", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} failed: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Instellingen opgeslagen – start de zender opnieuw om de wijzigingen toe te passen.", + "repeater_settingsPartialFailure": "Sommige instellingen zijn niet correct uitgevoerd: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Fout bij het opslaan van de instellingen: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1070,11 +1160,9 @@ "repeater_refreshBasicSettings": "Basisinstellingen vernieuwen", "repeater_refreshRadioSettings": "Radiozender Instellingen Verversen", "repeater_refreshTxPower": "Nieuw laden TX-vermogen", - "repeater_refreshLocationSettings": "Instellingen Locatie Vernieuwen", "repeater_refreshPacketForwarding": "Vernieuwen Pakket Doorversturing", "repeater_refreshGuestAccess": "Toegang Gast Vernieuwen", "repeater_refreshPrivacyMode": "Privacymode vernieuwen", - "repeater_refreshAdvertisementSettings": "Instellingen Advertentie Bijwerken", "repeater_refreshed": "{label} is vernieuwd", "@repeater_refreshed": { "placeholders": { @@ -1091,7 +1179,7 @@ } } }, - "repeater_cliTitle": "Repeater CLI", + "repeater_cliTitle": "CLI-interface voor de repeater", "repeater_debugNextCommand": "Debug Volgende Commando", "repeater_commandHelp": "Help", "repeater_clearHistory": "Geschiedenis Verwijderen", @@ -1176,7 +1264,7 @@ "repeater_general": "Algemeen", "repeater_settingsCategory": "Instellingen", "repeater_bridge": "Bruggen", - "repeater_logging": "Logging", + "repeater_logging": "Loggen", "repeater_neighborsRepeaterOnly": "Buren (Alleen repeaters)", "repeater_regionManagementRepeaterOnly": "Regiobeheer (Alleen Repeater)", "repeater_regionNote": "Regio-commando's zijn geïntroduceerd om regio-definities en permissies te beheren.", @@ -1247,12 +1335,12 @@ "channelPath_title": "Pakketpad", "channelPath_viewMap": "Kaart bekijken", "channelPath_otherObservedPaths": "Overige Waargenomen Paden", - "channelPath_repeaterHops": "Repeater Hops", + "channelPath_repeaterHops": "Herhaalde sprongen", "channelPath_noHopDetails": "De details van de pakket zijn niet verstrekt.", "channelPath_messageDetails": "Details Bericht", "channelPath_senderLabel": "Afzender", "channelPath_timeLabel": "Tijd", - "channelPath_repeatsLabel": "Repeats", + "channelPath_repeatsLabel": "Herhaalt", "channelPath_pathLabel": "Pad {index}", "channelPath_observedLabel": "Waargenomen", "channelPath_observedPathTitle": "Waargenomen pad {index} • {hops}", @@ -1290,7 +1378,7 @@ } }, "channelPath_unknownPath": "Onbekend", - "channelPath_floodPath": "Flood", + "channelPath_floodPath": "Overstroming", "channelPath_directPath": "Direct", "channelPath_observedZeroOf": "0 van {total} sprongen", "@channelPath_observedZeroOf": { @@ -1347,11 +1435,11 @@ "listFilter_sortBy": "Sorteren door", "listFilter_latestMessages": "Recente berichten", "listFilter_heardRecently": "Recent gezien", - "listFilter_az": "A-Z", + "listFilter_az": "Alfabetisch", "listFilter_filters": "Filters", "listFilter_all": "Alles", "listFilter_users": "Gebruikers", - "listFilter_repeaters": "Repeaters", + "listFilter_repeaters": "Herhalers", "listFilter_roomServers": "Roomservers", "listFilter_unreadOnly": "Alleen ongelezen", "listFilter_newGroup": "Nieuwe groep", @@ -1460,7 +1548,7 @@ } }, "community_title": "Gemeenschap", - "common_ok": "OK", + "common_ok": "Prima", "community_createDesc": "Maak een nieuwe community en deel deze via QR-code.", "community_create": "Maak Gemeenschap", "community_join": "Sluit aan", @@ -1554,11 +1642,11 @@ "contacts_pathTrace": "Pad Traceren", "contacts_ping": "Pingen", "contacts_repeaterPathTrace": "Pad traceren naar repeater", - "contacts_repeaterPing": "Ping repeater", + "contacts_repeaterPing": "Ping-repeater", "contacts_roomPathTrace": "Padtrace naar room server", "contacts_roomPing": "Ping kamer server", "contacts_chatTraceRoute": "Route traceren", - "contacts_pathTraceTo": "Trace route to {name}", + "contacts_pathTraceTo": "Volg de route naar {name}", "appSettings_languageUk": "Oekraïens", "contacts_invalidAdvertFormat": "Ongeldige contactgegevens", "contacts_contactImportFailed": "Contact kon niet geïmporteerd worden.", @@ -1922,13 +2010,6 @@ "contact_lastSeen": "Laatst gezien", "contact_clearChat": "Chat leegmaken", "contact_teleBaseSubtitle": "Sta delen van batterij niveau en basis telemetrie toe", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_maxRouteWeightSubtitle": "Het maximale gewicht dat een route kan bereiken door succesvolle leveringen.", "appSettings_initialRouteWeight": "เริ่มต้น gewicht van de route", "appSettings_maxRouteWeight": "Maximale gewicht voor de route", @@ -1941,7 +2022,7 @@ "appSettings_maxMessageRetriesSubtitle": "Aantal pogingen om een bericht opnieuw te versturen voordat het als mislukt wordt gemarkeerd", "path_routeWeight": "{weight}/{max}", "settings_telemetryModeUpdated": "Telemetrie-modus bijgewerkt", - "settings_multiAck": "Multi-ACKs: {value}", + "settings_multiAck": "Meerdere bevestigingen", "map_showOverlaps": "Herhalingssleutel overlapt", "map_runTraceWithReturnPath": "Terugkeren op hetzelfde pad.", "@radioStats_noiseFloor": { @@ -2073,5 +2154,162 @@ "repeater_guestTools": "Gastenfuncties", "room_guest": "Informatie over de server", "chat_sendMessage": "Verzend bericht", - "repeater_guest": "Informatie over herhalingsapparatuur" + "repeater_guest": "Informatie over herhalingsapparatuur", + "repeater_getCategory": "Waarden verkrijgen", + "repeater_powerMgmt": "Energiebeheer", + "repeater_sensors": "Sensoren", + "repeater_cliHelpPowerOff": "Zorgt ervoor dat het apparaat wordt uitgeschakeld. (geen reactie verwacht)", + "repeater_cliHelpClkReboot": "Stelt de klok terug naar een bekende tijd en start het apparaat opnieuw op.", + "repeater_cliHelpAdvertZeroHop": "Verstuurt een advertentie die alleen naar directe buren wordt gericht (geen tussenliggende stops).", + "repeater_cliHelpStartOta": "Start een firmware-update via de lucht op ondersteunde boards.", + "repeater_cliHelpTime": "Stelt de klok van het apparaat in op de gegeven Unix-tijd (aantal seconden vanaf de Unix-epoch). De klok kan niet teruggedraaid worden.", + "repeater_cliHelpBoard": "Geeft de fabrikant van het bord en/of de hardware-identificatie weer.", + "repeater_cliHelpDiscoverNeighbors": "Stuurt een verzoek om buren in de buurt te ontdekken. (Alleen van toepassing op een repeater)", + "repeater_cliHelpPowersaving": "Geeft aan of de energiebesparingsmodus is ingeschakeld of uitgeschakeld.", + "repeater_cliHelpPowersavingOnOff": "Activeert of deactiveert de energiebesparingsmodus (indien ondersteund).", + "repeater_cliHelpErase": "(Alleen voor seriële verbindingen) Formateert het bestandssysteem van het apparaat. Verwijdert alle instellingen en contacten.", + "repeater_cliHelpSetDutyCycle": "Stelt het maximale toegestane transmissiepercentage in (in procenten, 1-100). Past intern de tijdsschaal aan.", + "repeater_cliHelpSetPrvKey": "(Alleen voor seriële toepassingen) Vervangt de private sleutel van het apparaat. Een herstart is vereist om deze wijziging toe te passen. Genereert een nieuwe publieke sleutel.", + "repeater_cliHelpSetRadioRxGain": "(Alleen voor SX126x-chips) Schakelt de versterkte RX-gain in om de gevoeligheid te verbeteren bij een hoger stroomverbruik.", + "repeater_cliHelpSetOwnerInfo": "Definieert de string met contactgegevens van de eigenaar, die in de advertenties wordt opgenomen. Gebruik '|' voor nieuwe regels.", + "repeater_cliHelpSetPathHashMode": "Stelt de modus voor het berekenen van de hash van de route in. 0 = voorheen, 1 = standaard, 2 = strikt. Beïnvloedt hoe de routes worden gematched.", + "repeater_cliHelpSetLoopDetect": "Stelt de gevoeligheid voor het detecteren van een lus in de routing in: uit, minimaal, matig of strikt.", + "repeater_cliHelpSetFreq": "(Alleen voor seriële communicatie) Stelt snel alleen de frequentie in. Herstart is vereist. Het is aan te raden om \"radio instellingen\" te gebruiken voor alle radioparameters.", + "repeater_cliHelpSetBridgeChannel": "(Alleen voor ESPNow-brug) Stelt het WiFi-kanaal (1-14) in dat door de brug wordt gebruikt.", + "repeater_cliHelpGetName": "Toont de naam van de geconfigureerde knoop.", + "repeater_cliHelpGetRole": "Geeft de rol van de firmware aan (herhaald, server voor een kamer, enz.).", + "repeater_cliHelpGetPublicKey": "Toont het openbare sleutel van het apparaat.", + "repeater_cliHelpGetPrvKey": "(Alleen voor seriële communicatie) Toont de private sleutel van het apparaat. Behandel dit als een geheim.", + "repeater_cliHelpGetRepeat": "Geeft aan of het doorsturen van pakketten (als repeater) is ingeschakeld of uitgeschakeld.", + "repeater_cliHelpGetTx": "Toont de huidige zendvermogen in dBm.", + "repeater_cliHelpGetFreq": "Toont de geconfigureerde frequentie in MHz.", + "repeater_cliHelpGetRadio": "Geeft alle radioparameters weer: frequentie, bandbreedte, spreidfactor, codegraad.", + "repeater_cliHelpGetRadioRxGain": "(Alleen voor SX126x-chips) Toont de status van de versterking van de RX-ontvangst.", + "repeater_cliHelpGetAf": "Geeft de huidige tijdsfactor weer.", + "repeater_cliHelpGetDutyCycle": "Toont de huidige toegestane duty cycle als een percentage.", + "repeater_cliHelpGetIntThresh": "Toont het drempelwaarde voor signaalinterferentie in dB.", + "repeater_cliHelpGetAgcResetInterval": "Geeft het interval in seconden aan voor het resetten van de AGC (Automatic Gain Control).", + "repeater_cliHelpGetMultiAcks": "Geeft aan of de modus \"dubbele bevestiging\" is ingeschakeld (1) of uitgeschakeld (0).", + "repeater_cliHelpGetAllowReadOnly": "Geeft aan of er toegang is voor gastgebruikers zonder rechten.", + "repeater_cliHelpGetAdvertInterval": "Geeft de duur van de lokale reclame in minuten aan.", + "repeater_cliHelpGetFloodAdvertInterval": "Geeft de duur van de reclame-interval in uren aan.", + "repeater_cliHelpGetGuestPassword": "Toont het ingestelde gastwachtwoord.", + "repeater_cliHelpGetLat": "Toont de ingestelde breedtegraad.", + "repeater_cliHelpGetLon": "Toont de ingestelde lengtegraad.", + "repeater_cliHelpGetRxDelay": "Toont de basiswaarde van de rx-vertraging.", + "repeater_cliHelpGetTxDelay": "Geeft de factor weer die de vertraging in de flood-modus bepaalt.", + "repeater_cliHelpGetDirectTxDelay": "Geeft de factor voor de vertraging in de directe modus weer.", + "repeater_cliHelpGetFloodMax": "Toont het maximale aantal keer dat een overstroming heeft plaatsgevonden.", + "repeater_cliHelpGetOwnerInfo": "Toont de string met contactgegevens van de eigenaar.", + "repeater_cliHelpGetPathHashMode": "Toont de modus voor het berekenen van de hash (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Geeft de gevoeligheid voor het detecteren van lusvorming weer.", + "repeater_cliHelpGetAcl": "(Alleen voor seriële communicatie) Geeft de toegangscontroles weer op een repeater.", + "repeater_cliHelpGetBridgeEnabled": "Geeft aan of de brug is ingeschakeld.", + "repeater_cliHelpGetBridgeDelay": "Geeft de vertraging van de brug in milliseconden weer.", + "repeater_cliHelpGetBridgeSource": "Geeft aan of de brug RX- of TX-pakketten verwerkt.", + "repeater_cliHelpGetBridgeBaud": "(Alleen RS232-brug) Toont de baud-snelheid van de brug.", + "repeater_cliHelpGetBridgeChannel": "(Alleen voor ESPNow-brug) Toont het WiFi-kanaal van de brug.", + "repeater_cliHelpGetBridgeSecret": "(Alleen voor ESPNow-brug) Toont het gedeelde geheime sleutel.", + "repeater_cliHelpGetBootloaderVer": "(Alleen voor NRF52) Toont de versie van de bootloader.", + "repeater_cliHelpGetAdcMultiplier": "Toont de ADC-vermenigvuldiging (schalen van de batterijspanning).", + "repeater_cliHelpGetPwrMgtSupport": "Geeft aan of het bestuur ondersteuning heeft voor het beheer van energieverbruik.", + "repeater_cliHelpGetPwrMgtSource": "Geeft de huidige stroombron aan: extern of batterij.", + "repeater_cliHelpGetPwrMgtBootReason": "Geeft de meest recente redenen voor het opnieuw opstarten en afsluiten weer.", + "repeater_cliHelpGetPwrMgtBootMv": "Geeft de batterijspanning in mV weer, direct na het opstarten.", + "repeater_cliHelpSensorGet": "Leest een aangepaste sensorgegevens op basis van een sleutel.", + "repeater_cliHelpSensorSet": "Maakt een aangepaste instelling voor een sensor.", + "repeater_cliHelpSensorList": "Toont alle aangepaste instellingen voor sensoren, gegroepeerd op basis van een optionele startindex.", + "repeater_cliHelpRegionDefault": "Toont het huidige standaard regio-bereik.", + "repeater_cliHelpRegionDefaultSet": "Stelt de standaard regio-omvang in. Gebruik \"\" om deze te resetten.", + "repeater_cliHelpRegionListAllowed": "Lijst van gebieden waar doorstromen tijdens overstromingen is toegestaan.", + "repeater_cliHelpRegionListDenied": "Geeft een lijst van regio's die het verkeer tijdens overstromingen verbieden.", + "repeater_cliHelpStatsPackets": "(Alleen voor seriële verbindingen) Toont statistieken op pakketniveau.", + "repeater_cliHelpStatsRadio": "(Alleen voor serienummers) Toont radio-statistieken.", + "repeater_cliHelpStatsCore": "(Alleen voor seriële communicatie) Toont de belangrijkste firmware-statistieken.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "map_sharedAt": "Gedeeld", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losSelectedObstructionTitle": "Geselecteerde obstakel", + "losBlockedSpotsHint": "Tik op een geblokkeerd gebied om het op de kaart te markeren.", + "losBlockedSpotsTitle": "Geplande plaatsen", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "settings_companionDebugLog": "Debuglog voor aanvullende informatie", + "chat_newMessages": "Nieuwe berichten", + "chat_markAsUnread": "Markeer als ongelezen", + "settings_companionDebugLogSubtitle": "BLE/TCP/USB commando's, antwoorden en ruwe data", + "repeater_chanUtil": "Gebruik van het kanaal" } diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index b62a78a..4366e27 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -52,7 +52,7 @@ } } }, - "scanner_title": "MeshCore Open", + "scanner_title": "MeshCore – wersja open source", "scanner_scanning": "Skanowanie urządzeń...", "scanner_connecting": "Łączenie...", "scanner_disconnecting": "Odłączanie...", @@ -104,6 +104,8 @@ "settings_privacyModeEnabled": "Tryb prywatności włączony", "settings_privacyModeDisabled": "Tryb prywatności wyłączony", "settings_actions": "Działania", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Wyślij rozgłoszenie", "settings_sendAdvertisementSubtitle": "Nadaj obecność teraz", "settings_advertisementSent": "Rozgłoszenie wysłane", @@ -115,13 +117,13 @@ "settings_rebootDevice": "Zrestartuj Urządzenie", "settings_rebootDeviceSubtitle": "Zrestartuj urządzenie MeshCore", "settings_rebootDeviceConfirm": "Czy na pewno chcesz zrestartować urządzenie? Będziesz odłączony.", - "settings_debug": "Debug", + "settings_debug": "Naprawianie błędów", "settings_bleDebugLog": "Dziennik debugowania BLE", "settings_bleDebugLogSubtitle": "Polecenia BLE, odpowiedzi i surowe dane", "settings_appDebugLog": "Dziennik debugowania aplikacji", "settings_appDebugLogSubtitle": "Komunikaty debugowania aplikacji", "settings_about": "O aplikacji", - "settings_aboutVersion": "MeshCore Open v{version}", + "settings_aboutVersion": "MeshCore Open w wersji {version}", "@settings_aboutVersion": { "placeholders": { "version": { @@ -133,7 +135,7 @@ "settings_aboutDescription": "Otwartoźródłowy klient Flutter dla urządzeń MeshCore LoRa do sieci mesh.", "settings_infoName": "Nazwa", "settings_infoId": "ID", - "settings_infoStatus": "Status", + "settings_infoStatus": "Stan", "settings_infoBattery": "Bateria", "settings_infoPublicKey": "Klucz Publiczny", "settings_infoContactsCount": "Liczba kontaktów", @@ -146,7 +148,7 @@ "settings_spreadingFactor": "Współczynnik rozpraszania", "settings_codingRate": "Współczynnik kodowania", "settings_txPower": "Moc TX (dBm)", - "settings_txPowerHelper": "0 - 22", + "settings_txPowerHelper": "0 – 22", "settings_txPowerInvalid": "Nieprawidłowa moc TX (0-22 dBm)", "settings_error": "Błąd: {message}", "@settings_error": { @@ -164,19 +166,19 @@ "appSettings_themeDark": "Ciemny", "appSettings_language": "Język", "appSettings_languageSystem": "Domyślny systemowy", - "appSettings_languageEn": "English", - "appSettings_languageFr": "Français", - "appSettings_languageEs": "Español", - "appSettings_languageDe": "Deutsch", + "appSettings_languageEn": "Angielski", + "appSettings_languageFr": "Francuski", + "appSettings_languageEs": "Hiszpański", + "appSettings_languageDe": "Niemiecki", "appSettings_languagePl": "Polski", - "appSettings_languageSl": "Slovenščina", - "appSettings_languagePt": "Português", - "appSettings_languageIt": "Italiano", - "appSettings_languageZh": "中文", - "appSettings_languageSv": "Svenska", - "appSettings_languageNl": "Nederlands", - "appSettings_languageSk": "Slovenčina", - "appSettings_languageBg": "Български", + "appSettings_languageSl": "Słoweński", + "appSettings_languagePt": "Portugalski", + "appSettings_languageIt": "Włoski", + "appSettings_languageZh": "Chiński", + "appSettings_languageSv": "Szwedzki", + "appSettings_languageNl": "Niderlandzki", + "appSettings_languageSk": "Słoweniština", + "appSettings_languageBg": "Българский", "appSettings_notifications": "Powiadomienia", "appSettings_enableNotifications": "Włącz Powiadomienia", "appSettings_enableNotificationsSubtitle": "Otrzymuj powiadomienia o wiadomościach i rozgłoszeniach.", @@ -249,7 +251,7 @@ } } }, - "appSettings_debugCard": "Debug", + "appSettings_debugCard": "Naprawianie błędów", "appSettings_appDebugLogging": "Logowanie Debugowania Aplikacji", "appSettings_appDebugLoggingSubtitle": "Rejestruj komunikaty debugowania aplikacji w celu diagnozowania problemów.", "appSettings_appDebugLoggingEnabled": "Logowanie debugowania aplikacji włączone", @@ -347,11 +349,8 @@ } } }, - "channels_hashtagChannel": "Kanał hashtagów", "channels_public": "Publiczny", "channels_private": "Prywatny", - "channels_publicChannel": "Kanał publiczny", - "channels_privateChannel": "Prywatny kanał", "channels_editChannel": "Edytuj kanał", "channels_muteChannel": "Wycisz kanał", "channels_unmuteChannel": "Wyłącz wyciszenie kanału", @@ -377,7 +376,7 @@ "channels_channelName": "Nazwa kanału", "channels_usePublicChannel": "Użyj kanału publicznego", "channels_standardPublicPsk": "Standardowy publiczny PSK", - "channels_pskHex": "PSK (Hex)", + "channels_pskHex": "PSK (heksadecymalne)", "channels_generateRandomPsk": "Wygeneruj losowy klucz PSK", "channels_enterChannelName": "Proszę podać nazwę kanału.", "channels_pskMustBe32Hex": "PSK musi składać się z 32 znaków szesnastkowych.", @@ -398,6 +397,22 @@ } }, "channels_smazCompression": "Kompresja SMAZ", + "channels_cyr2latCompression": "Kompresja Cyr2Lat", + "channels_cyr2latCompressionDscr": "Zastępuje niektóre znaki cyrylicy alfabetem łacińskim podczas wysyłania.", + "channels_cyr2latSettingsHeading": "Ustawienia Cyr2Lat", + "channels_cyr2latSettingsSubheading": "Lista zamian", + "channels_cyr2latSettingsDscr": "Edytuj konfigurację JSON zamiany znaków", + "channels_cyr2latSettingsDialogHint": "Mapa zamian JSON", + "channels_cyr2latSettingsDialogWrongJSON": "Nieprawidłowy JSON: {error}", + "settings_cyr2latProfileAdd": "Dodaj profil Cyr2Lat", + "settings_cyr2latProfileName": "Nazwa profilu", + "settings_cyr2latProfileNameEmpty": "Nazwa profilu nie może być pusta", + "settings_cyr2latProfileAdded": "Profil dodano pomyślnie", + "settings_cyr2latProfileUpdated": "Profil został pomyślnie zaktualizowany", + "settings_cyr2latProfileEdit": "Edytuj profil Cyr2Lat", + "settings_cyr2latProfileDelete": "Usuń profil Cyr2Lat", + "settings_cyr2latProfileDeleted": "Profil został pomyślnie usunięty", + "settings_cyr2latProfileDeleteDscr": "Czy na pewno chcesz usunąć profil \"{name}\"?", "channels_channelUpdated": "Kanał \"{name}\" został zaktualizowany", "@channels_channelUpdated": { "placeholders": { @@ -409,7 +424,7 @@ "channels_publicChannelAdded": "Kanał publiczny dodany", "channels_sortBy": "Sortuj po", "channels_sortManual": "Ręczna", - "channels_sortAZ": "A-Z", + "channels_sortAZ": "Od A do Z", "channels_sortLatestMessages": "Najnowsze wiadomości", "channels_sortUnread": "Nieprzeczytane", "chat_noMessages": "Brak jeszcze wiadomości", @@ -541,7 +556,7 @@ } } }, - "debugFrame_textTypeCli": "CLI", + "debugFrame_textTypeCli": "Interfejs wiersza poleceń", "debugFrame_textTypePlain": "Zwykły", "debugFrame_text": "- Tekst: \"{text}\"", "@debugFrame_text": { @@ -889,11 +904,11 @@ "path_setPath": "Ustaw Ścieżkę", "repeater_management": "Zarządzanie przekaźnikami", "repeater_managementTools": "Narzędzia Zarządzania", - "repeater_status": "Status", + "repeater_status": "Stan", "repeater_statusSubtitle": "Wyświetl status przekaźnika, statystyki i sąsiadów.", "repeater_telemetry": "Telemetria", "repeater_telemetrySubtitle": "Wyświetl dane telemetryczne z czujników i statystyki systemu", - "repeater_cli": "CLI", + "repeater_cli": "Interfejs wiersza poleceń", "repeater_cliSubtitle": "Wyślij polecenia do przekaźnika", "repeater_settings": "Ustawienia", "repeater_settingsSubtitle": "Skonfiguruj parametry przekaźnika", @@ -1002,7 +1017,7 @@ "repeater_guestPasswordHelper": "Hasło tylko do odczytu", "repeater_radioSettings": "Ustawienia radia", "repeater_frequencyMhz": "Częstotliwość (MHz)", - "repeater_frequencyHelper": "300-2500 MHz", + "repeater_frequencyHelper": "300–2500 MHz", "repeater_txPower": "Moc TX", "repeater_txPowerHelper": "1-30 dBm", "repeater_bandwidth": "Przepustowość", @@ -1069,6 +1084,81 @@ }, "repeater_confirm": "Potwierdź", "repeater_settingsSaved": "Ustawienia zostały pomyślnie zapisane.", + "repeater_rxGain": "Zwiększony zysk RX", + "repeater_rxGainHelper": "Większa czułość, większe pobieranie prądu (dotyczy tylko SX1262/SX1268)", + "repeater_refreshRxGain": "Zaktualizuj zwiększone zyski RX", + "repeater_multiAcks": "Wielokrotne potwierdzenia odbioru", + "repeater_multiAcksSubtitle": "Potwierdź odbiór wiadomości za pomocą różnych ścieżek, aby zapewnić lepszą dostawę.", + "repeater_refreshMultiAcks": "Odświeżanie wielokrotnych potwierdzeń", + "repeater_networkHealth": "Stan sieci", + "repeater_loopDetect": "Wykrywanie pętli", + "repeater_loopDetectHelper": "Wysyłaj pakiety, które wyglądają jak pętle routingu.", + "repeater_loopDetectOff": "Z domu", + "repeater_loopDetectMinimal": "Minimalny", + "repeater_loopDetectModerate": "Umiarkowany", + "repeater_loopDetectStrict": "Surowe", + "repeater_dutyCycle": "Cykl pracy", + "repeater_dutyCycleHelper": "Maksymalny procent czasu, który stacja może wykorzystać.", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Informacje o operatorze", + "repeater_ownerInfoHelper": "Publiczne metadane dla tego urządzenia powielającego", + "repeater_refreshOwnerInfo": "Aktualizacja danych dotyczących operatora", + "repeater_floodMax": "Maksymalna liczba skoków podczas powodzi", + "repeater_floodMaxHelper": "Maksymalna liczba pakietów, które mogą przemieszczać się w jednym strumieniu (0-64)", + "repeater_advancedSettings": "Zaawansowany", + "repeater_advancedSettingsSubtitle": "Regulowane pokrętła dla doświadczonych operatorów", + "repeater_pathHashMode": "Tryb haszujący ścieżkę", + "repeater_pathHashModeHelper": "Bity wykorzystywane do kodowania identyfikatora tego urządzenia w tagach ścieżek/detekcji pętli. 0=1 bity (256 identyfikatorów, do 64 skoków), 1=2 bity (65 000 identyfikatorów, do 32 skoków), 2=3 bity (1 600 000 identyfikatorów, do 21 skoków). Wersje 1.13 i wcześniejsze nie obsługują ścieżek wielobitowych – wykrywają tylko jedną, gdy sieć jest w wersji 1.14 lub nowszej.", + "repeater_txDelay": "Opóźnienie w Flood, TX", + "repeater_txDelayHelper": "Ustawienie odstępu dla ruchu związanego z powodzią, jako mnożnik czasu przesyłania pakietu (0-2, domyślnie 0,5). Wyższe wartości oznaczają mniejszą liczbę kolizji, ale wolniejszą prędkość przesyłania.", + "repeater_directTxDelay": "Bezpośrednie opóźnienie sygnału TX", + "repeater_directTxDelayHelper": "Ustawienie odstępu dla ruchu bezpośredniego (bez rozgłaszania), jako mnożnika czasu przesyłania pakietu (0-2, domyślnie 0,3).", + "repeater_intThresh": "Próg zakłóceń", + "repeater_intThreshHelper": "Próg został ustawiony na poziom szumów w radiu, dzięki czemu odrzuca sygnały zakłócające powyżej tego poziomu. 0 oznacza wyłączenie – ustaw tylko wtedy, gdy występują błędy odbierania w szumie.", + "repeater_agcResetInterval": "Interwał resetowania AGC", + "repeater_agcResetIntervalHelper": "Jak często należy resetować automatyczną regulację głośności radia, aby odzyskać z sytuacji, w której głośność jest ustawiona na stałe. Ustawienie \"0\" dezaktywuje okresowe resetowanie.", + "repeater_actionsTitle": "Działania", + "repeater_sendAdvert": "Wysłać reklamę dotyczącą powodzi", + "repeater_sendAdvertSubtitle": "Wyemituj reklamę dotyczącą powodzi w sieci.", + "repeater_sendAdvertZeroHop": "Wysłać reklamę bez pośrednictwa", + "repeater_sendAdvertZeroHopSubtitle": "Napisz reklamę, która będzie transmitowana bezpośrednio (bez powtarzania).", + "repeater_clockSync": "Synchronizuj zegar", + "repeater_clockSyncSubtitle": "Przekaż czas z telefonu do urządzenia powielającego", + "repeater_actionSucceeded": "{action} zakończyło się pomyślnie", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} failed: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Ustawienia zapisane – uruchom ponownie repeater, aby zastosować zmiany.", + "repeater_settingsPartialFailure": "Niektóre ustawienia nie zostały zaimplementowane: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Błąd zapisu ustawień: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1080,11 +1170,9 @@ "repeater_refreshBasicSettings": "Odśwież Podstawowe Ustawienia", "repeater_refreshRadioSettings": "Odśwież ustawienia radia", "repeater_refreshTxPower": "Odśwież moc TX", - "repeater_refreshLocationSettings": "Odśwież Ustawienia Lokalizacji", "repeater_refreshPacketForwarding": "Odśwież trasowanie pakietów", "repeater_refreshGuestAccess": "Odśwież dostęp gościa", "repeater_refreshPrivacyMode": "Odśwież Tryb Prywatności", - "repeater_refreshAdvertisementSettings": "Odśwież ustawienia rozgłoszeń", "repeater_refreshed": "{label} odświeżone", "@repeater_refreshed": { "placeholders": { @@ -1216,7 +1304,7 @@ "telemetry_mcuTemperatureLabel": "Temperatura MCU", "telemetry_temperatureLabel": "Temperatura", "telemetry_currentLabel": "Prąd", - "telemetry_batteryValue": "{percent}% / {volts}V", + "telemetry_batteryValue": "{percent}% / {volts} W", "@telemetry_batteryValue": { "placeholders": { "percent": { @@ -1357,7 +1445,7 @@ "listFilter_sortBy": "Sortuj po", "listFilter_latestMessages": "Najnowsze wiadomości", "listFilter_heardRecently": "Słyszano niedawno", - "listFilter_az": "A-Z", + "listFilter_az": "Od A do Z", "listFilter_filters": "Filtry", "listFilter_all": "Wszystko", "listFilter_users": "Użytkownicy", @@ -1472,7 +1560,7 @@ "community_createDesc": "Utwórz nową społeczność i udostępnij za pomocą kodu QR.", "community_title": "Społeczność", "community_create": "Utwórz Społeczność", - "common_ok": "OK", + "common_ok": "Dobrze", "community_join": "Dołącz", "community_joinTitle": "Dołącz do społeczności", "community_joinConfirmation": "Czy chcesz dołączyć do społeczności \"{name}\"?", @@ -1960,13 +2048,6 @@ "contact_settings": "Ustawienia kontaktowe", "contact_lastSeen": "Ostatnio widziany", "contact_teleBaseSubtitle": "Pozwól na udostępnianie poziomu naładowania baterii i podstawowych danych telemetrycznych", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_initialRouteWeight": "Początkowa waga trasy", "appSettings_maxRouteWeight": "Maksymalny dopuszczalny ciężar pojazdu", "appSettings_initialRouteWeightSubtitle": "Początkowa waga dla nowych, odkrytych ścieżek", @@ -1979,7 +2060,6 @@ "appSettings_maxMessageRetriesSubtitle": "Liczba prób ponownego wysłania wiadomości przed oznaczaniem jej jako nieudanej", "path_routeWeight": "{weight}/{max}", "settings_telemetryModeUpdated": "Tryb telemetryczny zaktualizowany", - "settings_multiAck": "Wielokrotne ACK: {value}", "map_showOverlaps": "Nakładające się klucze przekaźników", "map_runTraceWithReturnPath": "Wróć tą samą ścieżką", "@radioStats_noiseFloor": { @@ -2111,5 +2191,163 @@ "chat_sendMessage": "Wyślij wiadomość", "repeater_guestTools": "Narzędzia dla gości", "repeater_guest": "Informacje dotyczące urządzenia powtarzającego", - "room_guest": "Informacje o serwerze" + "room_guest": "Informacje o serwerze", + "repeater_getCategory": "Uzyskaj wartości", + "repeater_powerMgmt": "Zarządzanie energią", + "repeater_sensors": "Czujniki", + "repeater_cliHelpPowerOff": "Wyłącza urządzenie. (oczekiwanie na brak reakcji)", + "repeater_cliHelpClkReboot": "Przywraca zegar do znanego punktu odniesienia i resetuje urządzenie.", + "repeater_cliHelpAdvertZeroHop": "Wysyła reklamę, która dociera bezpośrednio do sąsiadów (bez pośrednictwa).", + "repeater_cliHelpStartOta": "Rozpoczyna aktualizację oprogramowania przez sieć (bezpośrednio z urządzenia).", + "repeater_cliHelpTime": "Ustawia zegar urządzenia na określone sekundy od epoki Unix. Zegar nie może się cofać.", + "repeater_cliHelpBoard": "Wyświetla informacje o producencie płyty głównej / identyfikator sprzętu.", + "repeater_cliHelpDiscoverNeighbors": "Wysyła żądanie wykrywania sąsiednich węzłów. (Działa tylko w urządzeniu powielającym sygnał)", + "repeater_cliHelpPowersaving": "Pokazuje, czy tryb oszczędzania energii jest włączony, czy wyłączony.", + "repeater_cliHelpPowersavingOnOff": "Umożliwia lub wyłącza tryb oszczędzania energii (jeśli jest obsługiwany).", + "repeater_cliHelpErase": "(Dla urządzeń) Formatuje system plików urządzenia. Usuwa wszystkie ustawienia i kontakty.", + "repeater_cliHelpSetDutyCycle": "Ustawia maksymalny dopuszczalny cykl przesyłania w procentach (1-100). Automatycznie dostosowuje współczynnik czasu przesyłania.", + "repeater_cliHelpSetPrvKey": "(Dla urządzeń) Zastępuje klucz prywatny identyfikujący urządzenie. Wymagana jest ponowna uruchomienie urządzenia, aby zastosować zmianę. Generuje nowy klucz publiczny.", + "repeater_cliHelpSetRadioRxGain": "(tylko SX126x) Włącza wzmocniony sygnał RX, co poprawia czułość przy wyższym poborze prądu.", + "repeater_cliHelpSetOwnerInfo": "Określa ciąg znaków zawierający dane kontaktowe właściciela, który znajduje się w ogłoszeniach. Użyj '|' jako separatora wierszy.", + "repeater_cliHelpSetPathHashMode": "Ustawia tryb haszowania ścieżki. 0 = stary, 1 = standardowy, 2 = restrykcyjny. Wpływa na sposób dopasowywania ścieżek routingu.", + "repeater_cliHelpSetLoopDetect": "Ustawia czułość detekcji pętli routingu: wyłączona, minimalna, umiarkowana lub rygorystyczna.", + "repeater_cliHelpSetFreq": "(Dla urządzeń szeregowych) Szybko ustawia tylko częstotliwość. Wymagana ponowna uruchomienie. Zaleca się użycie opcji \"ustawienie radia\" w celu ustawienia wszystkich parametrów radia.", + "repeater_cliHelpSetBridgeChannel": "(Tylko most ESPNow) Ustawia kanał WiFi (od 1 do 14), który jest wykorzystywany przez most.", + "repeater_cliHelpGetName": "Wyświetla nazwę skonfigurowanego węzła.", + "repeater_cliHelpGetRole": "Pokazuje rolę oprogramowania (np. repeater, serwer dla pokoju).", + "repeater_cliHelpGetPublicKey": "Wyświetla publiczny klucz urządzenia.", + "repeater_cliHelpGetPrvKey": "(Tylko dla serialu) Wyświetla prywatny klucz urządzenia. Traktuj go jako poufny.", + "repeater_cliHelpGetRepeat": "Pokazuje, czy funkcja przekierowywania pakietów (funkcja repeatera) jest włączona lub wyłączona.", + "repeater_cliHelpGetTx": "Pokazuje aktualną moc transmisji w dBm.", + "repeater_cliHelpGetFreq": "Pokazuje skonfigurowaną częstotliwość radiową w MHz.", + "repeater_cliHelpGetRadio": "Wyświetla pełne parametry radia: częstotliwość, szerokość pasma, współczynnik modulacji, stopień kodowania.", + "repeater_cliHelpGetRadioRxGain": "(tylko SX126x) Wyświetla stan wzmocnienia sygnału RX.", + "repeater_cliHelpGetAf": "Pokazuje aktualny współczynnik czasu emisji.", + "repeater_cliHelpGetDutyCycle": "Pokazuje aktualny dopuszczalny cykl pracy w procentach.", + "repeater_cliHelpGetIntThresh": "Pokazuje próg zakłóceń kanału w dB.", + "repeater_cliHelpGetAgcResetInterval": "Pokazuje interwał resetowania AGC w sekundach.", + "repeater_cliHelpGetMultiAcks": "Pokazuje, czy tryb podwójnego potwierdzania jest włączony (1) czy wyłączony (0).", + "repeater_cliHelpGetAllowReadOnly": "Pokazuje, czy dostęp dla gości jest ograniczony do odczytu tylko.", + "repeater_cliHelpGetAdvertInterval": "Pokazuje czas trwania lokalnej reklamy w minutach.", + "repeater_cliHelpGetFloodAdvertInterval": "Pokazuje interwał reklamowy dotyczący powodzi w godzinach.", + "repeater_cliHelpGetGuestPassword": "Wyświetla ustawione hasło dla gościa.", + "repeater_cliHelpGetLat": "Pokazuje ustawioną szerokość geograficzną.", + "repeater_cliHelpGetLon": "Pokazuje ustawioną długość geograficzną.", + "repeater_cliHelpGetRxDelay": "Pokazuje bazową wartość opóźnienia RX.", + "repeater_cliHelpGetTxDelay": "Pokazuje współczynnik opóźnienia transmisji w trybie zalewowym.", + "repeater_cliHelpGetDirectTxDelay": "Pokazuje współczynnik opóźnienia w trybie bezpośrednim.", + "repeater_cliHelpGetFloodMax": "Pokazuje maksymalną liczbę skoków spowodowanych powodzią.", + "repeater_cliHelpGetOwnerInfo": "Wyświetla ciąg znaków zawierający dane kontaktowe właściciela.", + "repeater_cliHelpGetPathHashMode": "Pokazuje tryb haszujący ścieżkę (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Pokazuje czułość detekcji pętli.", + "repeater_cliHelpGetAcl": "(Tylko dla seriali) Wyświetla wpisy kontroli dostępu w repeaterze.", + "repeater_cliHelpGetBridgeEnabled": "Pokazuje, czy most jest włączony.", + "repeater_cliHelpGetBridgeDelay": "Pokazuje opóźnienie mostu w milisekundach.", + "repeater_cliHelpGetBridgeSource": "Pokazuje, czy most odbiera pakiety RX lub TX.", + "repeater_cliHelpGetBridgeBaud": "(Tylko interfejs RS232) Wyświetla prędkość transmisji na interfejsie RS232.", + "repeater_cliHelpGetBridgeChannel": "(Tylko moduł ESPNow) Wyświetla kanał WiFi modułu.", + "repeater_cliHelpGetBridgeSecret": "(Tylko most ESPNow) Wyświetla sekret udostępniony przez most.", + "repeater_cliHelpGetBootloaderVer": "(tylko dla NRF52) Wyświetla wersję bootloadera.", + "repeater_cliHelpGetAdcMultiplier": "Pokazuje wzmacniacz ADC (skalowanie napięcia baterii).", + "repeater_cliHelpGetPwrMgtSupport": "Informuje, czy rada nadzorcza posiada wsparcie w zakresie zarządzania energią.", + "repeater_cliHelpGetPwrMgtSource": "Pokazuje aktualne źródło zasilania: zewnętrzne lub bateryjne.", + "repeater_cliHelpGetPwrMgtBootReason": "Pokazuje najnowsze przyczyny resetowania i wyłączania.", + "repeater_cliHelpGetPwrMgtBootMv": "Pokazuje napięcie baterii podczas uruchamiania systemu w milivoltach (mV).", + "repeater_cliHelpSensorGet": "Odczytuje ustawienie czujnika zdefiniowane za pomocą klawisza.", + "repeater_cliHelpSensorSet": "Tworzy niestandardowe ustawienia dla czujnika.", + "repeater_cliHelpSensorList": "Wyświetla wszystkie ustawienia dla niestandardowych czujników, podzielone na strony, z opcjonalnym indeksem początkowym.", + "repeater_cliHelpRegionDefault": "Pokazuje aktualny domyślny zakres regionu.", + "repeater_cliHelpRegionDefaultSet": "Ustawia domyślny zakres regionu. Użyj wartości \"\", aby go zresetować.", + "repeater_cliHelpRegionListAllowed": "Wymienia regiony, w których dopuszczony jest ruch związany z powodzami.", + "repeater_cliHelpRegionListDenied": "Wymienia regiony, w których ruch związany z powodziami jest ograniczony.", + "repeater_cliHelpStatsPackets": "(Tylko dla serialu) Prezentuje statystyki na poziomie pakietów.", + "repeater_cliHelpStatsRadio": "(Tylko serial) Prezentuje statystyki dotyczące nadawania radiowego.", + "repeater_cliHelpStatsCore": "(Tylko wersja serialowa) Wyświetla podstawowe statystyki o oprogramowaniu.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "settings_multiAck": "Wielokrotne potwierdzenia odbioru", + "map_sharedAt": "Udostępnione", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losSelectedObstructionTitle": "Wybór przeszkody", + "losBlockedSpotsTitle": "Zablokowane miejsca", + "losBlockedSpotsHint": "Kliknij zablokowane miejsce, aby je zaznaczyć na mapie.", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "chat_newMessages": "Nowe wiadomości", + "settings_companionDebugLogSubtitle": "Polecenia, odpowiedzi i surowe dane związane z protokołami BLE/TCP/USB", + "chat_markAsUnread": "Oznacz jako nieprzeczytane", + "settings_companionDebugLog": "Log debugowania (dla pomocy w rozwiązywaniu problemów)", + "repeater_chanUtil": "Wykorzystanie kanału" } diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index bf3e893..6b8abbb 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -52,7 +52,7 @@ } } }, - "scanner_title": "MeshCore Open", + "scanner_title": "MeshCore: Versão aberta", "scanner_scanning": "Procurando por dispositivos...", "scanner_connecting": "Conectando...", "scanner_disconnecting": "Desconectando...", @@ -104,6 +104,8 @@ "settings_privacyModeEnabled": "Modo de privacidade ativado", "settings_privacyModeDisabled": "Modo de privacidade desativado", "settings_actions": "Ações", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Enviar Publicidade", "settings_sendAdvertisementSubtitle": "Presença de transmissão agora", "settings_advertisementSent": "Anúncio enviado", @@ -133,12 +135,12 @@ "settings_aboutDescription": "Um cliente Flutter de código aberto para dispositivos de rede mesh LoRa Core da MeshCore.", "settings_infoName": "Nome", "settings_infoId": "ID", - "settings_infoStatus": "Status", + "settings_infoStatus": "Estado", "settings_infoBattery": "Bateria", "settings_infoPublicKey": "Chave Pública", "settings_infoContactsCount": "Número de Contatos", "settings_infoChannelCount": "Número do Canal", - "settings_presets": "Presets", + "settings_presets": "Configurações pré-definidas", "settings_frequency": "Frequência (MHz)", "settings_frequencyHelper": "300,0 - 2500,0", "settings_frequencyInvalid": "Frequência inválida (300-2500 MHz)", @@ -164,19 +166,19 @@ "appSettings_themeDark": "Escuro", "appSettings_language": "Idioma", "appSettings_languageSystem": "Padrão do sistema", - "appSettings_languageEn": "English", - "appSettings_languageFr": "Français", - "appSettings_languageEs": "Español", - "appSettings_languageDe": "Deutsch", - "appSettings_languagePl": "Polski", - "appSettings_languageSl": "Slovenščina", + "appSettings_languageEn": "Inglês", + "appSettings_languageFr": "Francês", + "appSettings_languageEs": "Espanhol", + "appSettings_languageDe": "Alemão", + "appSettings_languagePl": "Polonês", + "appSettings_languageSl": "Esloveno", "appSettings_languagePt": "Português", "appSettings_languageIt": "Italiano", - "appSettings_languageZh": "中文", - "appSettings_languageSv": "Svenska", - "appSettings_languageNl": "Nederlands", - "appSettings_languageSk": "Slovenčina", - "appSettings_languageBg": "Български", + "appSettings_languageZh": "Chinês", + "appSettings_languageSv": "Sueco", + "appSettings_languageNl": "Holandês", + "appSettings_languageSk": "Esloveno", + "appSettings_languageBg": "Búlgaro", "appSettings_notifications": "Notificações", "appSettings_enableNotifications": "Ativar Notificações", "appSettings_enableNotificationsSubtitle": "Receber notificações para mensagens e anúncios", @@ -337,11 +339,8 @@ } } }, - "channels_hashtagChannel": "Canal com hashtag", "channels_public": "Público", "channels_private": "Privado", - "channels_publicChannel": "Canal público", - "channels_privateChannel": "Canal privado", "channels_editChannel": "Editar canal", "channels_muteChannel": "Silenciar canal", "channels_unmuteChannel": "Ativar canal", @@ -388,6 +387,22 @@ } }, "channels_smazCompression": "Compressão SMAZ", + "channels_cyr2latCompression": "Compressão Cyr2Lat", + "channels_cyr2latCompressionDscr": "Substitui alguns caracteres cirílicos por caracteres latinos ao enviar.", + "channels_cyr2latSettingsHeading": "Configuração do Cyr2Lat", + "channels_cyr2latSettingsSubheading": "Lista de substituições", + "channels_cyr2latSettingsDscr": "Editar a configuração JSON de substituição de caracteres", + "channels_cyr2latSettingsDialogHint": "Mapa de substituições JSON", + "channels_cyr2latSettingsDialogWrongJSON": "JSON incorreto: {error}", + "settings_cyr2latProfileAdd": "Adicionar perfil Cyr2Lat", + "settings_cyr2latProfileName": "Nome do perfil", + "settings_cyr2latProfileNameEmpty": "O nome do perfil não pode estar vazio", + "settings_cyr2latProfileAdded": "Perfil adicionado com sucesso", + "settings_cyr2latProfileUpdated": "Perfil atualizado com sucesso", + "settings_cyr2latProfileEdit": "Editar perfil Cyr2Lat", + "settings_cyr2latProfileDelete": "Eliminar perfil Cyr2Lat", + "settings_cyr2latProfileDeleted": "Perfil eliminado com sucesso", + "settings_cyr2latProfileDeleteDscr": "Tem a certeza de que deseja eliminar o perfil \"{name}\"?", "channels_channelUpdated": "Canal \"{name}\" atualizado", "@channels_channelUpdated": { "placeholders": { @@ -399,7 +414,7 @@ "channels_publicChannelAdded": "Canal público adicionado", "channels_sortBy": "Ordenar por", "channels_sortManual": "Manual", - "channels_sortAZ": "A-Z", + "channels_sortAZ": "De A a Z", "channels_sortLatestMessages": "Últimas mensagens", "channels_sortUnread": "Não lido", "chat_noMessages": "Ainda não existem mensagens.", @@ -504,7 +519,7 @@ } } }, - "debugFrame_timestamp": "- Timestamp: {timestamp}", + "debugFrame_timestamp": "- Carimbo: {timestamp}", "@debugFrame_timestamp": { "placeholders": { "timestamp": { @@ -531,7 +546,7 @@ } } }, - "debugFrame_textTypeCli": "CLI", + "debugFrame_textTypeCli": "Interface de Linha de Comando", "debugFrame_textTypePlain": "Simples", "debugFrame_text": "- Texto: \"{text}\"", "@debugFrame_text": { @@ -550,7 +565,7 @@ "chat_pathHistoryFull": "O histórico está cheio. Remova entradas para adicionar novas.", "chat_hopSingular": "pule", "chat_hopPlural": "salta", - "chat_hopsCount": "{count} {count, plural, =1{hop} other{hops}}", + "chat_hopsCount": "{count} {count, plural, =1{salto} other{saltos}}", "@chat_hopsCount": { "placeholders": { "count": { @@ -819,7 +834,7 @@ "login_autoUseSavedPath": "Auto (usar caminho salvo)", "login_forceFloodMode": "Modo de Inundação Forçado", "login_managePaths": "Gerenciar Caminhos", - "login_login": "Login", + "login_login": "Entrar", "login_attempt": "Tentar {current}/{max}", "@login_attempt": { "placeholders": { @@ -879,11 +894,11 @@ "path_setPath": "Definir Caminho", "repeater_management": "Gerenciamento de Repetidor", "repeater_managementTools": "Ferramentas de Gerenciamento", - "repeater_status": "Status", + "repeater_status": "Estado", "repeater_statusSubtitle": "Visualizar status do repetidor, estatísticas e vizinhos.", "repeater_telemetry": "Telemetria", "repeater_telemetrySubtitle": "Visualizar telemetria de sensores e estatísticas do sistema", - "repeater_cli": "CLI", + "repeater_cli": "Interface de Linha de Comando", "repeater_cliSubtitle": "Enviar comandos ao repetidor", "repeater_settings": "Configurações", "repeater_settingsSubtitle": "Configurar parâmetros do repetidor", @@ -993,7 +1008,7 @@ "repeater_radioSettings": "Configurações de Rádio", "repeater_frequencyMhz": "Frequência (MHz)", "repeater_frequencyHelper": "300-2500 MHz", - "repeater_txPower": "TX Power", + "repeater_txPower": "Energia da TX", "repeater_txPowerHelper": "1-30 dBm", "repeater_bandwidth": "Largura de banda", "repeater_spreadingFactor": "Fator de Dispersão", @@ -1059,6 +1074,81 @@ }, "repeater_confirm": "Confirmar", "repeater_settingsSaved": "Configurações salvas com sucesso", + "repeater_rxGain": "Aumento do ganho do RX", + "repeater_rxGainHelper": "Maior sensibilidade, maior consumo de corrente (apenas para SX1262/SX1268)", + "repeater_refreshRxGain": "Reforçar o ganho do RX", + "repeater_multiAcks": "Múltiplas respostas de confirmação", + "repeater_multiAcksSubtitle": "Reconheça mensagens através de múltiplos caminhos para uma melhor entrega.", + "repeater_refreshMultiAcks": "Reiniciar múltiplas confirmações", + "repeater_networkHealth": "Saúde da rede", + "repeater_loopDetect": "Detecção de loops", + "repeater_loopDetectHelper": "Envie pacotes que pareçam ser loops de roteamento.", + "repeater_loopDetectOff": "Desligado", + "repeater_loopDetectMinimal": "Mínimo", + "repeater_loopDetectModerate": "Moderado", + "repeater_loopDetectStrict": "Rígido", + "repeater_dutyCycle": "Ciclo de operação", + "repeater_dutyCycleHelper": "Porcentagem máxima de tempo de transmissão", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Informações sobre o operador", + "repeater_ownerInfoHelper": "Metadados públicos para este repetidor", + "repeater_refreshOwnerInfo": "Atualizar informações do operador", + "repeater_floodMax": "Número máximo de saltos em caso de inundação", + "repeater_floodMaxHelper": "Número máximo de saltos que um pacote de inundação pode percorrer (0-64)", + "repeater_advancedSettings": "Avançado", + "repeater_advancedSettingsSubtitle": "Controles de ajuste para operadores experientes", + "repeater_pathHashMode": "Modo de hash de caminho", + "repeater_pathHashModeHelper": "Bytes utilizados para codificar o ID deste repetidor nas tags de caminho/detecção de loop. 0=1 byte (256 IDs, até 64 saltos), 1=2 bytes (65.000 IDs, até 32 saltos), 2=3 bytes (16 milhões de IDs, até 21 saltos). As versões 1.13 e anteriores do firmware não suportam caminhos multi-byte — apenas funcionam uma vez após a ativação da rede (a partir da versão 1.14+).", + "repeater_txDelay": "Atraso na entrega em Flood, TX", + "repeater_txDelayHelper": "Ajuste de espaçamento para tráfego de inundações, como um multiplicador do tempo de transmissão (0-2, padrão 0,5). Quanto maior, menos colisões, mas uma entrega mais lenta.", + "repeater_directTxDelay": "Atraso direto no sinal TX", + "repeater_directTxDelayHelper": "Intervalo de retransmissão para tráfego direto (não em enxame), como um multiplicador do tempo de transmissão do pacote (0-2, padrão 0,3).", + "repeater_intThresh": "Limite de interferência", + "repeater_intThreshHelper": "O limite é definido para o nível de ruído do rádio, de modo que ele rejeite interferências acima desse nível. 0 desativa – aumente apenas se você observar erros de RX em uma faixa de frequência com ruído.", + "repeater_agcResetInterval": "Intervalo de reinicialização do AGC", + "repeater_agcResetIntervalHelper": "Com que frequência redefinir o controle automático de ganho do rádio para recuperar de um estado em que o ganho está travado. Segundos, reduzidos a um múltiplo de 4. 0 desativa as redefinições periódicas.", + "repeater_actionsTitle": "Ações", + "repeater_sendAdvert": "Envie anúncio sobre inundações", + "repeater_sendAdvertSubtitle": "Transmita um anúncio sobre inundações pela rede.", + "repeater_sendAdvertZeroHop": "Enviar anúncio sem intermediários", + "repeater_sendAdvertZeroHopSubtitle": "Transmita um anúncio de um único salto (sem repetição).", + "repeater_clockSync": "Sincronize o relógio agora", + "repeater_clockSyncSubtitle": "Envie a hora do seu telefone para o repetidor.", + "repeater_actionSucceeded": "{action} succeeded", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} failed: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Configurações salvas — reinicie o repetidor para aplicar as alterações.", + "repeater_settingsPartialFailure": "Algumas configurações falharam: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Erro ao salvar as configurações: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1070,11 +1160,9 @@ "repeater_refreshBasicSettings": "Atualizar Configurações Básicas", "repeater_refreshRadioSettings": "Atualizar Configurações de Rádio", "repeater_refreshTxPower": "Atualizar TX de energia", - "repeater_refreshLocationSettings": "Atualizar Configurações de Localização", "repeater_refreshPacketForwarding": "Atualizar Roteamento de Pacotes", "repeater_refreshGuestAccess": "Atualizar Acesso de Convidados", "repeater_refreshPrivacyMode": "Atualizar Modo Privacidade", - "repeater_refreshAdvertisementSettings": "Atualizar Configurações do Anúncio", "repeater_refreshed": "{label} atualizado", "@repeater_refreshed": { "placeholders": { @@ -1347,7 +1435,7 @@ "listFilter_sortBy": "Ordenar por", "listFilter_latestMessages": "Últimas mensagens", "listFilter_heardRecently": "Ouvido recentemente", - "listFilter_az": "A-Z", + "listFilter_az": "De A a Z", "listFilter_filters": "Filtros", "listFilter_all": "Tudo", "listFilter_users": "Usuários", @@ -1461,7 +1549,7 @@ }, "community_title": "Comunidade", "community_createDesc": "Crie uma nova comunidade e compartilhe via código QR.", - "common_ok": "OK", + "common_ok": "Tudo bem", "community_create": "Criar Comunidade", "community_join": "Junte-se", "community_joinTitle": "Junte-se à Comunidade", @@ -1922,13 +2010,6 @@ "contact_telemetry": "Telemetria", "contact_settings": "Configurações de Contato", "contact_teleBaseSubtitle": "Permitir compartilhamento do nível da bateria e telemetria básica", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_initialRouteWeight": "Peso Inicial da Rota", "appSettings_maxRouteWeight": "Peso Máximo da Rota", "appSettings_maxRouteWeightSubtitle": "Peso máximo que um determinado percurso pode acumular com entregas bem-sucedidas.", @@ -1941,7 +2022,7 @@ "appSettings_maxMessageRetriesSubtitle": "Número de tentativas de reenvio antes de classificar uma mensagem como falha.", "path_routeWeight": "{weight}/{max}", "settings_telemetryModeUpdated": "Modo de telemetria atualizado", - "settings_multiAck": "Multi-ACKs: {value}", + "settings_multiAck": "Multi-ACKs", "map_showOverlaps": "Sobreposições da Chave Repeater", "map_runTraceWithReturnPath": "Retornar ao mesmo caminho.", "@radioStats_noiseFloor": { @@ -2073,5 +2154,162 @@ "room_guest": "Informações do Servidor", "chat_sendMessage": "Enviar mensagem", "repeater_guest": "Informações sobre repetidores", - "repeater_guestTools": "Ferramentas para hóspedes" + "repeater_guestTools": "Ferramentas para hóspedes", + "repeater_getCategory": "Obter valores", + "repeater_powerMgmt": "Gerenciamento de energia", + "repeater_sensors": "Sensores", + "repeater_cliHelpPowerOff": "Desliga o dispositivo. (não se espera resposta)", + "repeater_cliHelpClkReboot": "Redefine o relógio para uma data conhecida e reinicia o dispositivo.", + "repeater_cliHelpAdvertZeroHop": "Envia um anúncio sem \"salto\" (apenas para vizinhos próximos).", + "repeater_cliHelpStartOta": "Inicia uma atualização de firmware via rádio em placas compatíveis.", + "repeater_cliHelpTime": "Define o relógio do dispositivo para os segundos da época Unix especificados. O relógio não pode retroceder.", + "repeater_cliHelpBoard": "Indica o fabricante da placa / identificador de hardware.", + "repeater_cliHelpDiscoverNeighbors": "Envia uma solicitação de descoberta de nós para os vizinhos próximos. (Apenas para repetidores)", + "repeater_cliHelpPowersaving": "Indica se o modo de economia de energia está ativado ou desativado.", + "repeater_cliHelpPowersavingOnOff": "Habilita ou desabilita o modo de economia de energia (quando disponível).", + "repeater_cliHelpErase": "(Apenas para dispositivos) Formata o sistema de arquivos do dispositivo. Apaga todas as configurações e contatos.", + "repeater_cliHelpSetDutyCycle": "Define o ciclo de transmissão máximo permitido como uma porcentagem (1-100). Ajusta internamente o fator de tempo de transmissão.", + "repeater_cliHelpSetPrvKey": "(Apenas para uso em série) Substitui a chave privada de identificação do dispositivo. É necessário reiniciar o dispositivo para aplicar a alteração. Gera uma nova chave pública.", + "repeater_cliHelpSetRadioRxGain": "(Apenas para SX126x) Alterna o ganho amplificado do receptor (RX) para melhorar a sensibilidade em condições de corrente mais elevada.", + "repeater_cliHelpSetOwnerInfo": "Define a string com as informações de contato do proprietário, que será incluída nos anúncios. Utilize '|' para indicar novas linhas.", + "repeater_cliHelpSetPathHashMode": "Define o modo de hash de caminho. 0 = modo legado, 1 = modo padrão, 2 = modo rigoroso. Afeta a forma como os caminhos de roteamento são correspondidos.", + "repeater_cliHelpSetLoopDetect": "Define o nível de sensibilidade para a detecção de loops de roteamento: desligado, mínimo, moderado ou estrito.", + "repeater_cliHelpSetFreq": "(Apenas para rádio) Define rapidamente a frequência. É necessário reiniciar o dispositivo. Recomenda-se usar a opção \"configurar rádio\" para definir todos os parâmetros do rádio.", + "repeater_cliHelpSetBridgeChannel": "(Apenas para a ponte ESPNow) Define o canal Wi-Fi (1-14) utilizado pela ponte.", + "repeater_cliHelpGetName": "Mostra o nome do nó configurado.", + "repeater_cliHelpGetRole": "Mostra o papel do firmware (Repetidor, Servidor de Sala, etc.).", + "repeater_cliHelpGetPublicKey": "Exibe a chave pública do dispositivo.", + "repeater_cliHelpGetPrvKey": "(Apenas para uso em série) Exibe a chave privada do dispositivo. Trate-a como uma informação confidencial.", + "repeater_cliHelpGetRepeat": "Indica se a função de encaminhamento de pacotes (função de repetidor) está ativada ou desativada.", + "repeater_cliHelpGetTx": "Mostra a potência atual em dBm.", + "repeater_cliHelpGetFreq": "Mostra a frequência de rádio configurada em MHz.", + "repeater_cliHelpGetRadio": "Exibe todos os parâmetros de rádio: frequência, largura de banda, fator de espalhamento, taxa de codificação.", + "repeater_cliHelpGetRadioRxGain": "(Apenas para SX126x) Mostra o estado do ganho amplificado do RX.", + "repeater_cliHelpGetAf": "Mostra o fator de tempo de transmissão atual.", + "repeater_cliHelpGetDutyCycle": "Mostra o ciclo de trabalho atual permitido em porcentagem.", + "repeater_cliHelpGetIntThresh": "Mostra o limite de interferência do canal em dB.", + "repeater_cliHelpGetAgcResetInterval": "Mostra o intervalo de reinicialização do AGC em segundos.", + "repeater_cliHelpGetMultiAcks": "Indica se o modo de confirmação dupla está ativado (1) ou desativado (0).", + "repeater_cliHelpGetAllowReadOnly": "Indica se o acesso somente de leitura para os convidados está habilitado.", + "repeater_cliHelpGetAdvertInterval": "Indica o intervalo de publicidade local em minutos.", + "repeater_cliHelpGetFloodAdvertInterval": "Mostra o intervalo de tempo da publicidade relacionada às inundações, em horas.", + "repeater_cliHelpGetGuestPassword": "Mostra a senha de convidado configurada.", + "repeater_cliHelpGetLat": "Mostra a latitude configurada.", + "repeater_cliHelpGetLon": "Mostra a longitude configurada.", + "repeater_cliHelpGetRxDelay": "Mostra o valor base do atraso de resposta.", + "repeater_cliHelpGetTxDelay": "Mostra o fator de atraso em modo de inundação.", + "repeater_cliHelpGetDirectTxDelay": "Mostra o fator de atraso direto.", + "repeater_cliHelpGetFloodMax": "Mostra o número máximo de saltos devido às inundações.", + "repeater_cliHelpGetOwnerInfo": "Exibe a string de informações de contato do proprietário.", + "repeater_cliHelpGetPathHashMode": "Mostra o modo de hash de caminho (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Demonstra a sensibilidade na detecção de loops.", + "repeater_cliHelpGetAcl": "(Apenas para séries) Lista as entradas de controle de acesso em um repetidor.", + "repeater_cliHelpGetBridgeEnabled": "Indica se a ponte está habilitada.", + "repeater_cliHelpGetBridgeDelay": "Mostra o atraso da ponte em milissegundos.", + "repeater_cliHelpGetBridgeSource": "Indica se a ponte está enviando ou recebendo pacotes RX ou TX.", + "repeater_cliHelpGetBridgeBaud": "(Apenas para ponte RS232) Exibe a taxa de baud da ponte.", + "repeater_cliHelpGetBridgeChannel": "(Apenas para a ponte ESPNow) Exibe o canal WiFi da ponte.", + "repeater_cliHelpGetBridgeSecret": "(Apenas para a ponte ESPNow) Exibe o segredo compartilhado pela ponte.", + "repeater_cliHelpGetBootloaderVer": "(Apenas para NRF52) Exibe a versão do bootloader.", + "repeater_cliHelpGetAdcMultiplier": "Mostra o multiplicador do ADC (escalonamento da tensão da bateria).", + "repeater_cliHelpGetPwrMgtSupport": "Indica se o sistema possui suporte para gerenciamento de energia.", + "repeater_cliHelpGetPwrMgtSource": "Indica a fonte de energia atual: externa ou bateria.", + "repeater_cliHelpGetPwrMgtBootReason": "Mostra as razões mais recentes para a reinicialização e desligamento.", + "repeater_cliHelpGetPwrMgtBootMv": "Mostra a tensão da bateria no momento da inicialização, em milivolts (mV).", + "repeater_cliHelpSensorGet": "Lê uma configuração de sensor personalizada através de uma chave.", + "repeater_cliHelpSensorSet": "Cria uma configuração personalizada para um sensor.", + "repeater_cliHelpSensorList": "Lista todas as configurações de sensores personalizadas, organizadas em páginas a partir de um índice de início opcional.", + "repeater_cliHelpRegionDefault": "Mostra o escopo de região padrão atual.", + "repeater_cliHelpRegionDefaultSet": "Define o escopo regional padrão. Use \"\" para limpar.", + "repeater_cliHelpRegionListAllowed": "Lista as regiões que permitem o tráfego em áreas de risco de inundações.", + "repeater_cliHelpRegionListDenied": "Lista as regiões que restringem o tráfego em áreas de risco de inundações.", + "repeater_cliHelpStatsPackets": "(Apenas para séries) Apresenta estatísticas em nível de pacotes.", + "repeater_cliHelpStatsRadio": "(Apenas para transmissões em série) Exibe estatísticas de rádio.", + "repeater_cliHelpStatsCore": "(Apenas para dispositivos em série) Exibe estatísticas básicas do firmware.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "map_sharedAt": "Compartilhado", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losBlockedSpotsTitle": "Locais ocupados", + "losBlockedSpotsHint": "Toque em um ponto bloqueado para destacá-lo no mapa.", + "losSelectedObstructionTitle": "Obstrução selecionada", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "settings_companionDebugLog": "Registro de depuração auxiliar", + "settings_companionDebugLogSubtitle": "Comandos, respostas e dados brutos para protocolos BLE/TCP/USB", + "chat_markAsUnread": "Marcar como não lido", + "chat_newMessages": "Novas mensagens", + "repeater_chanUtil": "Utilização do canal" } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index a83d139..5d5bcfc 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -81,6 +81,8 @@ "settings_privacyModeEnabled": "Режим конфиденциальности включен", "settings_privacyModeDisabled": "Режим конфиденциальности выключен", "settings_actions": "Действия", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Отправить анонсирование", "settings_sendAdvertisementSubtitle": "Отправить анонсирование о присутствии сейчас", "settings_advertisementSent": "Анонсирование отправлено", @@ -229,11 +231,8 @@ "channels_searchChannels": "Поиск каналов...", "channels_noChannelsFound": "Каналы не найдены", "channels_channelIndex": "Канал {index}", - "channels_hashtagChannel": "Хэштег-канал", "channels_public": "Публичный", "channels_private": "Приватный", - "channels_publicChannel": "Публичный канал", - "channels_privateChannel": "Приватный канал", "channels_editChannel": "Изменить канал", "channels_muteChannel": "Отключить уведомления канала", "channels_unmuteChannel": "Включить уведомления канала", @@ -252,6 +251,22 @@ "channels_channelAdded": "Канал \"{name}\" добавлен", "channels_editChannelTitle": "Изменить канал {index}", "channels_smazCompression": "Сжатие SMAZ", + "channels_cyr2latCompression": "Сжатие Cyr2Lat", + "channels_cyr2latCompressionDscr": "Заменяет некоторые кириллические символы на латиницу при отправке.", + "channels_cyr2latSettingsHeading": "Настройка Cyr2Lat", + "channels_cyr2latSettingsSubheading": "Список замен", + "channels_cyr2latSettingsDscr": "Редактировать JSON-конфигурацию замены символов", + "channels_cyr2latSettingsDialogHint": "JSON-карта замен", + "channels_cyr2latSettingsDialogWrongJSON": "Некорректный JSON: {error}", + "settings_cyr2latProfileAdd": "Добавить профиль Cyr2Lat", + "settings_cyr2latProfileName": "Название профиля", + "settings_cyr2latProfileNameEmpty": "Название профиля не может быть пустым", + "settings_cyr2latProfileAdded": "Профиль добавлен", + "settings_cyr2latProfileUpdated": "Профиль успешно обновлен", + "settings_cyr2latProfileEdit": "Редактировать профиль Cyr2Lat", + "settings_cyr2latProfileDelete": "Удалить профиль Cyr2Lat", + "settings_cyr2latProfileDeleted": "Профиль успешно удален", + "settings_cyr2latProfileDeleteDscr": "Вы действительно хотите удалить профиль \"{name}\"?", "channels_channelUpdated": "Канал \"{name}\" обновлён", "channels_publicChannelAdded": "Публичный канал добавлен", "channels_sortBy": "Сортировка", @@ -358,6 +373,8 @@ "chat_direct": "Прямой", "chat_poiShared": "Точка интереса отправлена", "chat_unread": "Непрочитанных: {count}", + "chat_markAsUnread": "Пометить как непрочитанные", + "chat_newMessages": "Новые сообщения", "map_title": "Карта нод", "map_noNodesWithLocation": "Нет нод с данными о местоположении", "map_nodesNeedGps": "Ноды должны передавать свои GPS-координаты, чтобы отображаться на карте", @@ -1162,13 +1179,6 @@ "contact_clearChat": "Очистить чат", "contact_lastSeen": "Последний раз видели", "contact_teleBaseSubtitle": "Разрешить обмен уровнем заряда батареи и базовой телеметрией", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_maxRouteWeight": "Максимальный допустимый вес маршрута", "appSettings_maxRouteWeightSubtitle": "Максимальный вес, который может быть перевезён по определённому маршруту при успешных доставках.", "appSettings_initialRouteWeightSubtitle": "Начальный вес для новых, только что открытых маршрутов", @@ -1181,7 +1191,6 @@ "appSettings_maxMessageRetriesSubtitle": "Количество попыток повторной отправки сообщения перед тем, как пометить его как неудачное.", "path_routeWeight": "{weight}/{max}", "settings_telemetryModeUpdated": "Режим телеметрии обновлен", - "settings_multiAck": "Мульти-ACK: {value}", "map_showOverlaps": "Перекрытия ключа повтора", "map_runTraceWithReturnPath": "Вернуться обратно по тому же пути", "@radioStats_noiseFloor": { @@ -1313,5 +1322,297 @@ "chat_sendMessage": "Отправить сообщение", "repeater_guest": "Информация о ретрансляторе", "room_guest": "Информация о сервере", - "repeater_guestTools": "Инструменты для гостей" + "repeater_guestTools": "Инструменты для гостей", + "common_done": "Готово", + "background_serviceTitle": "MeshCore работает", + "background_serviceText": "Поддерживает BLE-соединение", + "appSettings_translationModelDeleted": "Удалено {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Не удалось удалить: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Не удалось обновить канал: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Тип", + "map_path": "Путь", + "map_location": "Местоположение", + "map_estLocation": "Прибл. местоположение", + "map_publicKey": "Публичный ключ", + "map_publicKeyPrefixHint": "напр. ab12", + "contact_typeChat": "Чат", + "contact_typeRepeater": "Ретранслятор", + "contact_typeRoom": "Комната", + "contact_typeSensor": "Датчик", + "contact_typeUnknown": "Неизвестно", + "channels_via": "через {path}", + "chat_score": "Оценка", + "settings_multiAck": "Несколько подтверждений", + "map_sharedAt": "Поделено", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losBlockedSpotsHint": "Щелкните по заблокированной области, чтобы выделить ее на карте.", + "losBlockedSpotsTitle": "Зарезервированные места", + "losSelectedObstructionTitle": "Выбранный объект, препятствующий движению", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "repeater_rxGain": "Увеличенная эффективность RX", + "repeater_rxGainHelper": "Более высокая чувствительность, больший ток потребления (только для SX1262/SX1268)", + "repeater_refreshRxGain": "Обновите усиление RX", + "repeater_multiAcks": "Несколько подтверждений", + "repeater_multiAcksSubtitle": "Обеспечьте доставку сообщений по нескольким каналам для повышения эффективности.", + "repeater_refreshMultiAcks": "Обновление нескольких подтверждений", + "repeater_networkHealth": "Состояние сети", + "repeater_loopDetect": "Обнаружение циклов", + "repeater_loopDetectHelper": "Создайте пакеты данных, которые выглядят как циклы маршрутизации.", + "repeater_loopDetectOff": "Отключено", + "repeater_loopDetectMinimal": "Минимальный", + "repeater_loopDetectModerate": "Умеренный", + "repeater_loopDetectStrict": "Строгий", + "repeater_dutyCycle": "Цикл работы", + "repeater_dutyCycleHelper": "Максимальный процент времени, выделенного на трансляцию.", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Информация о операторе", + "repeater_ownerInfoHelper": "Общая метаинформация для этого ретранслятора", + "repeater_refreshOwnerInfo": "Обновить информацию о операторе", + "repeater_floodMax": "Максимальное количество прыжков при наводнении", + "repeater_floodMaxHelper": "Максимальное количество пакетов, которые могут быть отправлены в одном потоке (0-64)", + "repeater_advancedSettings": "Продвинутый", + "repeater_advancedSettingsSubtitle": "Регуляторы для опытных операторов", + "repeater_pathHashMode": "Режим хеширования пути", + "repeater_pathHashModeHelper": "Байты, используемые для кодирования идентификатора этого ретранслятора в тегах для обнаружения потоков/циклов. 0 = 1 байт (256 идентификаторов, до 64 переходов), 1 = 2 байта (65 000 идентификаторов, до 32 переходов), 2 = 3 байта (1 600 000 идентификаторов, до 21 перехода). Версии прошивки v1.13 и более ранние версии не поддерживают многобайтовые пути — они поднимаются только после того, как ваша сеть будет обновлена до версии v1.14 и выше.", + "repeater_txDelay": "Задержка в работе системы Flood TX", + "repeater_txDelayHelper": "Передача с увеличенным интервалом для трафика во время наводнения, в качестве коэффициента, умножающего время передачи пакета (от 0 до 2, по умолчанию 0,5). Более высокое значение означает меньшее количество столкновений, но более медленную передачу.", + "repeater_directTxDelay": "Прямая задержка сигнала TX", + "repeater_directTxDelayHelper": "Передача промежуточных данных для прямого (немассового) трафика, в качестве коэффициента, равного времени передачи пакета (от 0 до 2, по умолчанию 0,3).", + "repeater_intThresh": "Пороговое значение помех", + "repeater_intThreshHelper": "Порог устанавливается для калибровки уровня шума радио, чтобы оно отсеивало помехи, превышающие этот уровень. Значение \"0\" означает отключение – используйте только в случае, если вы наблюдаете ошибки при приеме сигнала в шумном диапазоне.", + "repeater_agcResetInterval": "Интервал сброса AGC", + "repeater_agcResetIntervalHelper": "Как часто следует сбрасывать автоматическую регулировку усиления радио, чтобы вернуться к нормальному состоянию после заклинивания? Интервал сброса составляет несколько секунд, кратный 4. Отключение периодического сброса осуществляется с помощью параметра 0.", + "repeater_actionsTitle": "Действия", + "repeater_sendAdvert": "Отправить объявление о наводнении", + "repeater_sendAdvertSubtitle": "Разместите рекламу о наводнении в эфире по всей сети.", + "repeater_sendAdvertZeroHop": "Опубликуйте рекламу, не требующую промежуточного распространения.", + "repeater_sendAdvertZeroHopSubtitle": "Разместите рекламу, распространяемую одним способом (без использования ретрансляторов).", + "repeater_clockSync": "Синхронизировать время сейчас", + "repeater_clockSyncSubtitle": "Установите время на вашем телефоне, чтобы оно совпадало со временем ретранслятора.", + "repeater_actionSucceeded": "{action} succeeded", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} failed: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Настройки сохранены — перезагрузите ретранслятор, чтобы применить их.", + "repeater_settingsPartialFailure": "Некоторые настройки не удалось применить: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, + "@settings_multiAck": { + "placeholders": { + "value": { + "type": "String" + } + } + }, + "@common_percentValue": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "@settings_aboutVersion": { + "placeholders": { + "version": { + "type": "String" + } + } + }, + "@telemetry_temperatureValue": { + "placeholders": { + "celsius": { + "type": "String" + }, + "fahrenheit": { + "type": "String" + } + } + }, + "@channelPath_timeWithDate": { + "placeholders": { + "day": { + "type": "int" + }, + "month": { + "type": "int" + }, + "time": { + "type": "String" + } + } + }, + "@channelPath_timeOnly": { + "placeholders": { + "time": { + "type": "String" + } + } + }, + "@channelPath_selectedPathLabel": { + "placeholders": { + "label": { + "type": "String" + }, + "prefixes": { + "type": "String" + } + } + }, + "repeater_getCategory": "Получить значения", + "repeater_powerMgmt": "Управление энергопотреблением", + "repeater_sensors": "Датчики", + "repeater_cliHelpPowerOff": "Отключает устройство. (ожидается отсутствие ответа).", + "repeater_cliHelpClkReboot": "Сбрасывает часы до известной эпохи и перезапускает устройство.", + "repeater_cliHelpAdvertZeroHop": "Отправляет рекламу, распространяемую только среди ближайших соседей (без промежуточных узлов).", + "repeater_cliHelpStartOta": "Запускает обновление прошивки по воздуху на поддерживаемых устройствах.", + "repeater_cliHelpTime": "Устанавливает время устройства в соответствии с заданными секундами от начала эпохи Unix. Время не может сброситься назад.", + "repeater_cliHelpBoard": "Отображает информацию о производителе платы / идентификатор аппаратного обеспечения.", + "repeater_cliHelpDiscoverNeighbors": "Отправляет запрос на обнаружение соседних узлов. (Только для ретранслятора)", + "repeater_cliHelpPowersavingOnOff": "Включает или выключает режим экономии энергии (если он поддерживается).", + "repeater_cliHelpPowersaving": "Показывает, включен ли режим экономии энергии.", + "repeater_cliHelpErase": "(Только для серийного использования) Форматирует файловую систему устройства. Удаляет все настройки и контакты.", + "repeater_cliHelpSetDutyCycle": "Устанавливает максимальный допустимый цикл передачи данных в процентах (от 1 до 100). Внутренне корректирует коэффициент времени передачи.", + "repeater_cliHelpSetPrvKey": "(Только для серийного использования) Заменяет приватный ключ, идентифицирующий устройство. Требуется перезагрузка для применения. Генерирует новый публичный ключ.", + "repeater_cliHelpSetRadioRxGain": "(Только для SX126x) Переключает усиление RX для повышения чувствительности при больших токах потребления.", + "repeater_cliHelpSetOwnerInfo": "Указывает строку с контактной информацией владельца, которая должна быть включена в объявления. Используйте '|' для переносов строк.", + "repeater_cliHelpSetPathHashMode": "Устанавливает режим хеширования пути. 0 = устаревший, 1 = стандартный, 2 = строгий. Влияет на то, как определяются маршруты.", + "repeater_cliHelpSetLoopDetect": "Устанавливает чувствительность обнаружения циклов маршрутизации: \"выключено\", \"минимальная\", \"умеренная\" или \"строгая\".", + "repeater_cliHelpSetFreq": "(Только для настройки) Быстро устанавливает только частоту. Требуется перезагрузка. Рекомендуется использовать функцию \"настройка радио\" для полного набора параметров.", + "repeater_cliHelpSetBridgeChannel": "(Только для моста ESPNow) Устанавливает канал Wi-Fi (от 1 до 14), используемый мостом.", + "repeater_cliHelpGetName": "Отображает имя настроенного узла.", + "repeater_cliHelpGetRole": "Отображает роль прошивки (ретранслятор, сервер для комнаты и т.д.).", + "repeater_cliHelpGetPublicKey": "Отображает открытый ключ устройства.", + "repeater_cliHelpGetPrvKey": "(Только для серийного использования) Отображает приватный ключ устройства. Рассматривайте его как секретную информацию.", + "repeater_cliHelpGetRepeat": "Отображает, включена ли функция перенаправления пакетов (функция ретранслятора) или нет.", + "repeater_cliHelpGetTx": "Отображает текущую мощность передатчика в дБм.", + "repeater_cliHelpGetFreq": "Отображает настроенную частоту радиосигнала в мегагерцах.", + "repeater_cliHelpGetRadio": "Отображает все параметры радиосигнала: частоту, полосу пропускания, коэффициент модуляции, скорость кодирования.", + "repeater_cliHelpGetRadioRxGain": "(Только для SX126x) Отображает состояние усиления сигнала на входе RX.", + "repeater_cliHelpGetAf": "Отображает текущий коэффициент времени эфира.", + "repeater_cliHelpGetDutyCycle": "Отображает текущий допустимый цикл работы в процентах.", + "repeater_cliHelpGetIntThresh": "Отображает порог помех в децибелах.", + "repeater_cliHelpGetAgcResetInterval": "Отображает интервал сброса автоматической регулировки усиления в секундах.", + "repeater_cliHelpGetMultiAcks": "Показывает, включен ли режим двойной подтверждения (1) или выключен (0).", + "repeater_cliHelpGetAllowReadOnly": "Отображает, разрешен ли доступ для чтения только для гостей.", + "repeater_cliHelpGetAdvertInterval": "Отображает продолжительность рекламного блока в минутах.", + "repeater_cliHelpGetFloodAdvertInterval": "Отображает интервал времени показа рекламного ролика в часах.", + "repeater_cliHelpGetGuestPassword": "Отображает установленный пароль для гостя.", + "repeater_cliHelpGetLat": "Отображает заданную широту.", + "repeater_cliHelpGetLon": "Отображает заданную долготу.", + "repeater_cliHelpGetRxDelay": "Отображает базовое значение задержки.", + "repeater_cliHelpGetTxDelay": "Отображает коэффициент задержки при работе в режиме затопления.", + "repeater_cliHelpGetDirectTxDelay": "Отображает коэффициент задержки в режиме прямого подключения.", + "repeater_cliHelpGetFloodMax": "Отображает максимальное количество переходов при затоплении.", + "repeater_cliHelpGetOwnerInfo": "Отображает строку с контактной информацией владельца.", + "repeater_cliHelpGetPathHashMode": "Отображает режим работы с хэшем пути (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Отображает чувствительность к обнаружению циклов.", + "repeater_cliHelpGetAcl": "(Только для серий) Перечисляет записи управления доступом на ретрансляторе.", + "repeater_cliHelpGetBridgeEnabled": "Показывает, включена ли функция моста.", + "repeater_cliHelpGetBridgeDelay": "Отображает задержку в миллисекундах.", + "repeater_cliHelpGetBridgeSource": "Отображает, какие пакеты RX или TX передаются через мост.", + "repeater_cliHelpGetBridgeBaud": "(Только для интерфейса RS232) Отображает скорость передачи данных на интерфейсе RS232.", + "repeater_cliHelpGetBridgeChannel": "(Только для моста ESPNow) Отображает канал WiFi, используемый мостом.", + "repeater_cliHelpGetBridgeSecret": "(Только для моста ESPNow) Отображает общий секрет, используемый мостом.", + "repeater_cliHelpGetBootloaderVer": "(Только для NRF52) Отображает версию загрузчика.", + "repeater_cliHelpGetAdcMultiplier": "Отображает коэффициент умножения аналого-цифрового преобразователя (масштабирование напряжения от батареи).", + "repeater_cliHelpGetPwrMgtSupport": "Сообщает, есть ли у совета поддержки функций управления питанием.", + "repeater_cliHelpGetPwrMgtSource": "Отображает текущий источник питания: внешний или аккумулятор.", + "repeater_cliHelpGetPwrMgtBootReason": "Отображает последние причины сброса и выключения.", + "repeater_cliHelpGetPwrMgtBootMv": "Отображает напряжение батареи при запуске системы в милливольтах (мВ).", + "repeater_cliHelpSensorGet": "Считывает пользовательское значение для датчика по указанному ключу.", + "repeater_cliHelpSensorSet": "Создает пользовательские настройки для датчика.", + "repeater_cliHelpSensorList": "Перечисляет все пользовательские настройки датчиков, разбитые на страницы с возможностью указания начального индекса.", + "repeater_cliHelpRegionDefault": "Отображает текущий область действия по умолчанию.", + "repeater_cliHelpRegionDefaultSet": "Устанавливает значение региона по умолчанию. Используйте \"\", чтобы сбросить значение.", + "repeater_cliHelpRegionListAllowed": "Перечисляет регионы, где разрешено движение транспорта во время наводнений.", + "repeater_cliHelpRegionListDenied": "Перечисляет регионы, где запрещено движение транспорта во время наводнений.", + "repeater_cliHelpStatsPackets": "(Только для серийной версии) Отображает статистику на уровне пакетов.", + "repeater_cliHelpStatsRadio": "(Только для серий) Отображает статистику радио.", + "repeater_cliHelpStatsCore": "(Только для серийного оборудования) Отображает основные статистические данные прошивки.", + "settings_companionDebugLogSubtitle": "Команды, ответы и необработанные данные, используемые для протоколов BLE, TCP и USB.", + "repeater_chanUtil": "Использование канала", + "settings_companionDebugLog": "Журнал отладки (для сопутствующего приложения)" } diff --git a/lib/l10n/app_sk.arb b/lib/l10n/app_sk.arb index e4466c3..713c397 100644 --- a/lib/l10n/app_sk.arb +++ b/lib/l10n/app_sk.arb @@ -52,7 +52,7 @@ } } }, - "scanner_title": "MeshCore Open", + "scanner_title": "MeshCore – Verzia pre verejnosť", "scanner_scanning": "Skrívania zariadení...", "scanner_connecting": "Pripojujem sa...", "scanner_disconnecting": "Odpojuje sa...", @@ -104,6 +104,8 @@ "settings_privacyModeEnabled": "Ochranný režim je povolený.", "settings_privacyModeDisabled": "Ochranný režim je vypnutý", "settings_actions": "Možné akcie", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Odoslať reklamu", "settings_sendAdvertisementSubtitle": "Momentálne priezornejšie.", "settings_advertisementSent": "Reklama odeslaná", @@ -121,7 +123,7 @@ "settings_appDebugLog": "Záznam ladenia aplikácie", "settings_appDebugLogSubtitle": "Správy z ladenia aplikácie", "settings_about": "O nás", - "settings_aboutVersion": "MeshCore Open v{version}", + "settings_aboutVersion": "MeshCore, verzia {version}", "@settings_aboutVersion": { "placeholders": { "version": { @@ -132,8 +134,8 @@ "settings_aboutLegalese": "MeshCore Open Source Projekt 2024", "settings_aboutDescription": "Otvorený zdrojový Flutter klient pre MeshCore LoRa sieťové zariadenia.", "settings_infoName": "Meno", - "settings_infoId": "ID", - "settings_infoStatus": "Status", + "settings_infoId": "Identifikátor", + "settings_infoStatus": "Stav", "settings_infoBattery": "Batéria", "settings_infoPublicKey": "Verejný kľúč", "settings_infoContactsCount": "Počet kontaktov", @@ -146,7 +148,7 @@ "settings_spreadingFactor": "Rozptýľovací faktor", "settings_codingRate": "Cenový kurz pre programovanie", "settings_txPower": "TX Výkon (dBm)", - "settings_txPowerHelper": "0 - 22", + "settings_txPowerHelper": "0 – 22", "settings_txPowerInvalid": "Neplatná hodnota výkonu TX (0-22 dBm)", "settings_error": "Chyba: {message}", "@settings_error": { @@ -164,19 +166,19 @@ "appSettings_themeDark": "Tmavé", "appSettings_language": "Jazyk", "appSettings_languageSystem": "Predvolený systém", - "appSettings_languageEn": "English", - "appSettings_languageFr": "Français", - "appSettings_languageEs": "Español", - "appSettings_languageDe": "Deutsch", - "appSettings_languagePl": "Polski", - "appSettings_languageSl": "Slovenščina", - "appSettings_languagePt": "Português", - "appSettings_languageIt": "Italiano", - "appSettings_languageZh": "中文", - "appSettings_languageSv": "Svenska", - "appSettings_languageNl": "Nederlands", + "appSettings_languageEn": "Anglicky", + "appSettings_languageFr": "Francúzština", + "appSettings_languageEs": "Španielsky", + "appSettings_languageDe": "Nemecky", + "appSettings_languagePl": "Poľský", + "appSettings_languageSl": "Slovenčina", + "appSettings_languagePt": "Portugalčina", + "appSettings_languageIt": "Taliančina", + "appSettings_languageZh": "Čínština", + "appSettings_languageSv": "Švédska", + "appSettings_languageNl": "Niderlandsky", "appSettings_languageSk": "Slovenčina", - "appSettings_languageBg": "Български", + "appSettings_languageBg": "Българština", "appSettings_notifications": "Upozornenia", "appSettings_enableNotifications": "Povolte Notifikácie", "appSettings_enableNotificationsSubtitle": "Zísť o upozornenia na správy a inzeráty", @@ -337,11 +339,8 @@ } } }, - "channels_hashtagChannel": "Kanál s hashtagom", "channels_public": "Veľké verejné", "channels_private": "Osobné", - "channels_publicChannel": "Veľké verejne kanály", - "channels_privateChannel": "Osobné kanál", "channels_editChannel": "Upraviť kanál", "channels_muteChannel": "Stlmiť kanál", "channels_unmuteChannel": "Zrušiť stlmenie kanála", @@ -388,6 +387,22 @@ } }, "channels_smazCompression": "Odstránenie kompresie SMAZ", + "channels_cyr2latCompression": "Odstránenie kompresie Cyr2Lat", + "channels_cyr2latCompressionDscr": "Pri odosielaní nahradí niektoré znaky cyriliky latinskými znakmi.", + "channels_cyr2latSettingsHeading": "Nastavenia Cyr2Lat", + "channels_cyr2latSettingsSubheading": "Zoznam nahradení", + "channels_cyr2latSettingsDscr": "Upravte konfiguráciu JSON pre nahradenie znakov", + "channels_cyr2latSettingsDialogHint": "JSON mapa nahradení", + "channels_cyr2latSettingsDialogWrongJSON": "Nesprávny JSON: {error}", + "settings_cyr2latProfileAdd": "Pridať profil Cyr2Lat", + "settings_cyr2latProfileName": "Názov profilu", + "settings_cyr2latProfileNameEmpty": "Názov profilu nesmie byť prázdny", + "settings_cyr2latProfileAdded": "Profil bol úspešne pridaný", + "settings_cyr2latProfileUpdated": "Profil bol úspešne aktualizovaný", + "settings_cyr2latProfileEdit": "Upraviť profil Cyr2Lat", + "settings_cyr2latProfileDelete": "Odstrániť profil Cyr2Lat", + "settings_cyr2latProfileDeleted": "Profil bol úspešne odstránený", + "settings_cyr2latProfileDeleteDscr": "Naozaj chcete odstrániť profil \"{name}\"?", "channels_channelUpdated": "Kanál \"{name}\" bol aktualizovaný", "@channels_channelUpdated": { "placeholders": { @@ -399,7 +414,7 @@ "channels_publicChannelAdded": "Veľký kanál pridaný", "channels_sortBy": "Triediť podľa", "channels_sortManual": "Ručne", - "channels_sortAZ": "A-Z", + "channels_sortAZ": "Od A po Z", "channels_sortLatestMessages": "Posledné správy", "channels_sortUnread": "Nezriadené", "chat_noMessages": "Zatiaľ žiadne správy.", @@ -477,7 +492,7 @@ "debugLog_noEntries": "Zatiaľ neboli zaznamenané žiadne debug logy.", "debugLog_enableInSettings": "Povolte ladicové logy v nastaveniach", "debugLog_frames": "Rámce", - "debugLog_rawLogRx": "Raw Log-RX", + "debugLog_rawLogRx": "Čistý log – RX", "debugLog_noBleActivity": "Zatiaľ žiadna aktivita BLE.", "debugFrame_length": "Dĺžka rámca: {count} bajtov", "@debugFrame_length": { @@ -531,7 +546,7 @@ } } }, - "debugFrame_textTypeCli": "CLI", + "debugFrame_textTypeCli": "CLI (Command Line Interface)", "debugFrame_textTypePlain": "Jednoduché", "debugFrame_text": "- Text: \"{text}\"", "@debugFrame_text": { @@ -541,7 +556,7 @@ } } }, - "debugFrame_hexDump": "Hex Dump:", + "debugFrame_hexDump": "Hexová analýza:", "chat_pathManagement": "Správa ciest", "chat_routingMode": "Režim trasy", "chat_autoUseSavedPath": "Použiť uloženú cestu", @@ -550,7 +565,7 @@ "chat_pathHistoryFull": "História ciest je plná. Odstráňte záznamy, aby ste mohli pridať nové.", "chat_hopSingular": "Skok", "chat_hopPlural": "Skákať", - "chat_hopsCount": "{count} {count, plural, =1{hop} other{hops}}", + "chat_hopsCount": "{count} {count, plural, =1{skok} other{skoky}}", "@chat_hopsCount": { "placeholders": { "count": { @@ -879,11 +894,11 @@ "path_setPath": "Nastaviť cestu", "repeater_management": "Správa opakérov", "repeater_managementTools": "Nástroje na správu", - "repeater_status": "Status", + "repeater_status": "Stav", "repeater_statusSubtitle": "Zobraziť stav, štatistiky a susedov repeatera", "repeater_telemetry": "Telemetria", "repeater_telemetrySubtitle": "Zobraziť telemetriu senzorov a systémových štatistík", - "repeater_cli": "CLI", + "repeater_cli": "CLI (Command Line Interface)", "repeater_cliSubtitle": "Pošlite príkazy opakovaču", "repeater_settings": "Nastavenia", "repeater_settingsSubtitle": "Konfigurujte parametre opakovača", @@ -992,7 +1007,7 @@ "repeater_guestPasswordHelper": "Prístupový heslo iba na čítanie", "repeater_radioSettings": "Nastavenia rádia", "repeater_frequencyMhz": "Frekvencia (MHz)", - "repeater_frequencyHelper": "300-2500 MHz", + "repeater_frequencyHelper": "300–2500 MHz", "repeater_txPower": "TX Power", "repeater_txPowerHelper": "1-30 dBm", "repeater_bandwidth": "Šírka pásma", @@ -1059,6 +1074,81 @@ }, "repeater_confirm": "Potvrdiť", "repeater_settingsSaved": "Nastavenia boli uložené úspešne.", + "repeater_rxGain": "Zvýšený zisk RX", + "repeater_rxGainHelper": "Vyššia citlivosť, vyšší príkon (platí len pre modely SX1262/SX1268)", + "repeater_refreshRxGain": "Obnovte zvýšený zisk z RX", + "repeater_multiAcks": "Víťazné potvrdenia (víťazné ACK)", + "repeater_multiAcksSubtitle": "Potvrďte správy prostredníctvom viacerých trás pre lepšiu doručenie.", + "repeater_refreshMultiAcks": "Opätovne potvrďte viacero ACK signálov", + "repeater_networkHealth": "Zdravie siete", + "repeater_loopDetect": "Detekcia slučiek", + "repeater_loopDetectHelper": "Vytvorte balíčky, ktoré vizuálne pripomínajú slučky v síti.", + "repeater_loopDetectOff": "Vypnuté", + "repeater_loopDetectMinimal": "Minimálny", + "repeater_loopDetectModerate": "Stredný, mierny", + "repeater_loopDetectStrict": "Prísne", + "repeater_dutyCycle": "Cyklus činnosti", + "repeater_dutyCycleHelper": "Maximálna percentáľ dostupného času vysielania", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Informácie o poskytovateľovi", + "repeater_ownerInfoHelper": "Veľké dátové informácie pre tento vysielací zdroj", + "repeater_refreshOwnerInfo": "Zísť informácie o operátore", + "repeater_floodMax": "Maximálny počet skokov pri povodni", + "repeater_floodMaxHelper": "Maximálny počet paketov, ktoré môžu preletieť cez jeden hop (0-64)", + "repeater_advancedSettings": "Pokročilé", + "repeater_advancedSettingsSubtitle": "Ovládacie knopy pre skúsených operátorov", + "repeater_pathHashMode": "Režim hashovania cesty", + "repeater_pathHashModeHelper": "Byty použité na zakódovanie ID tohto opakovača v tagoch pre trasu/detekciu slučky. 0 = 1 bytu (256 ID, až 64 skokov), 1 = 2 byty (65 000 ID, až 32 skokov), 2 = 3 byty (16 miliónov ID, až 21 skokov). Verzie 1.13 a staršie nepodporujú viacbytové trasy – fungujú len, keď je sieť aktivovaná.", + "repeater_txDelay": "Zpoždanie v Flood, TX", + "repeater_txDelayHelper": "Nastavenie pre opakované vysielanie pre dopravu počas povodní, ako násobok času, ktorý paket využije (0-2, výchoce hodnota 0,5). Vyššia hodnota znamená menej kolízii, ale pomalšie doručovanie.", + "repeater_directTxDelay": "Priame oneskorenie TX", + "repeater_directTxDelayHelper": "Nastavenie pre retransmisiu pre priame (nie pre plnú sieť), ako násobok času prenosu paketov (0-2, výchoce 0,3).", + "repeater_intThresh": "Hranica, pri ktorej dochádza k rušeniu", + "repeater_intThreshHelper": "Hranica je nastavená tak, aby odfiltrovala šum nad touto úrovňou. Hodnota 0 znamená, že sa nebude nič odfiltrovať – nastavte ju len v prípade, že zaznamenáte chyby pri prijímaní signálu v šumnej frekvencii.", + "repeater_agcResetInterval": "Interval reštartu AGC", + "repeater_agcResetIntervalHelper": "Ako často by ste mali reštartovať automatické ovládanie zosilnenia, aby ste sa vrátili do normálneho stavu, ak je zosilnenie zablokované? Nastavenie „4.0“ vypne pravidelné reštarty.", + "repeater_actionsTitle": "Opatrenia", + "repeater_sendAdvert": "Odoslať inzerát o povodňovej situácii", + "repeater_sendAdvertSubtitle": "Zverejnite reklamu na povodňu prostredníctvom siete.", + "repeater_sendAdvertZeroHop": "Odoslať reklamu bez prenosu", + "repeater_sendAdvertZeroHopSubtitle": "Zverejnite reklamnú správu, ktorá sa prenáša len raz (bez prenosov).", + "repeater_clockSync": "Synchronizujte hodiny teraz", + "repeater_clockSyncSubtitle": "Nastavte čas na vašom telefóne, aby odpovedal na volania z vysielacieho zariadenia.", + "repeater_actionSucceeded": "{action} succeeded", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} failed: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Nastavenia uložené – reštartujte vysielací prístroj, aby sa nastavenia aplikovali.", + "repeater_settingsPartialFailure": "Niektoré nastavenia neúspešné: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Chyba pri ukladaní nastavení: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1070,11 +1160,9 @@ "repeater_refreshBasicSettings": "Obnoviť základné nastavenia", "repeater_refreshRadioSettings": "Obnoviť Nastavenia Rádií", "repeater_refreshTxPower": "Obnoviť TX napájanie", - "repeater_refreshLocationSettings": "Obnoviť Nastavenia Miesta", "repeater_refreshPacketForwarding": "Obnoviť smerovanie paketov", "repeater_refreshGuestAccess": "Obnoviť prístup hosťa", "repeater_refreshPrivacyMode": "Obnoviť Ochranný režim", - "repeater_refreshAdvertisementSettings": "Obnoviť nastavenia reklamy", "repeater_refreshed": "{label} sa znova načítalo", "@repeater_refreshed": { "placeholders": { @@ -1347,7 +1435,7 @@ "listFilter_sortBy": "Triediť podľa", "listFilter_latestMessages": "Posledné správy", "listFilter_heardRecently": "Nedávno počuli.", - "listFilter_az": "A-Z", + "listFilter_az": "Od A po Z", "listFilter_filters": "Filtre", "listFilter_all": "Všetko", "listFilter_users": "Používatelia", @@ -1619,8 +1707,8 @@ "appSettings_unitsTitle": "Jednotky", "appSettings_unitsMetric": "Metrické (m / km)", "appSettings_unitsImperial": "Imperiálne (ft / mi)", - "map_lineOfSight": "Line of Sight", - "map_losScreenTitle": "Line of Sight", + "map_lineOfSight": "Úroveň výhľadu", + "map_losScreenTitle": "Úroveň výhľadu", "losSelectStartEnd": "Vyberte počiatočný a koncový uzol pre LOS.", "losRunFailed": "Kontrola priamej viditeľnosti zlyhala: {error}", "@losRunFailed": { @@ -1879,8 +1967,8 @@ "tcpHostLabel": "IP adresa", "tcpScreenTitle": "Spojte sa pomocou protokolu TCP", "connectionChoiceTcpLabel": "TCP", - "tcpPortLabel": "Port", - "tcpPortHint": "5000", + "tcpPortLabel": "Prístav", + "tcpPortHint": "5 000", "tcpStatus_notConnected": "Zadajte cieľovú adresu a pripojte sa.", "tcpStatus_connectingTo": "Pripojenie k {endpoint}...", "tcpErrorHostRequired": "Je potrebné zadať IP adresu.", @@ -1922,13 +2010,6 @@ "contact_lastSeen": "Naposledy videný", "contact_teleBase": "Báza telemetrie", "contact_teleEnvSubtitle": "Povoliť zdieľanie údajov senzorov prostredia", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_maxRouteWeightSubtitle": "Maximálna hmotnosť, ktorú môže trás prenášať vďaka úspešným zásielkam.", "appSettings_initialRouteWeightSubtitle": "Počiatočná váha pre nové, objavené cesty", "appSettings_initialRouteWeight": "Počiatočná váha trasy", @@ -1941,7 +2022,7 @@ "appSettings_maxMessageRetriesSubtitle": "Počet pokusov o odošleť pred označením správy ako neúspešnej", "path_routeWeight": "{weight}/{max}", "settings_telemetryModeUpdated": "Režim telemetrie bol aktualizovaný", - "settings_multiAck": "Viaceré ACK: {value}", + "settings_multiAck": "Viaceré ACK", "map_showOverlaps": "Prekrývanie opakovača kľúča", "map_runTraceWithReturnPath": "Vráťte sa späť po tej istej ceste.", "@radioStats_noiseFloor": { @@ -2073,5 +2154,162 @@ "chat_sendMessage": "Odoslať správu", "repeater_guest": "Informácie o opakovači", "room_guest": "Informácie o serveri", - "repeater_guestTools": "Nástroje pre hostí" + "repeater_guestTools": "Nástroje pre hostí", + "repeater_getCategory": "Zísť hodnoty", + "repeater_powerMgmt": "Správa energie", + "repeater_sensors": "Senzory", + "repeater_cliHelpPowerOff": "Vypína zariadenie. (neočakáva sa žiadna odpoveď)", + "repeater_cliHelpClkReboot": "Resetuje hodiny na známu epochu a reštartuje zariadenie.", + "repeater_cliHelpAdvertZeroHop": "Rozosiela reklamu, ktorá sa prenáša len medzi susednými zariadeniami (bez prenosu cez iné siete).", + "repeater_cliHelpStartOta": "Spustí aktualizáciu firmvéru prostredníctvom diaľkového prenosu na podporovaných doskách.", + "repeater_cliHelpTime": "Nastavuje časovník zariadenia na zadané sekundy od Unix epochy. Časovník sa nedá otáčať dozadu.", + "repeater_cliHelpBoard": "Zobrazuje informácie o výrobcom dosky / identifikátor hardvéru.", + "repeater_cliHelpDiscoverNeighbors": "Odosiela požiadavku na nájdenie susedných uzlov. (Len pre opakovače)", + "repeater_cliHelpPowersaving": "Ukazuje, či je režim úspory energie zapnutý alebo vypnutý.", + "repeater_cliHelpPowersavingOnOff": "Umožňuje alebo vypína režim úspory energie (ak je podporovaný).", + "repeater_cliHelpErase": "(Používa sa len pre sériové zariadenia) Formátuje systém súborov zariadenia. Vymaže všetky nastavenia a kontakty.", + "repeater_cliHelpSetDutyCycle": "Nastavuje maximálnu povolenú frekvenciu prenosu ako percento (1-100). Internálne upravuje faktor času prenosu.", + "repeater_cliHelpSetPrvKey": "(Používa sa len v sériovej verzii) Nahradí privátny kľúč, ktorý identifikuje zariadenie. Po aplikácii je potrebné zariadenie reštartovať. Generuje nový verejný kľúč.", + "repeater_cliHelpSetRadioRxGain": "(iba pre SX126x) Zapína zvýšený zisk prijímania pre zlepšenie citlivosti pri vyššom príkonu.", + "repeater_cliHelpSetOwnerInfo": "Definuje reťazec s informáciami o kontaktnom osobě, ktorý je zahrnutý v reklamách. Používajte '|' pre nové riadky.", + "repeater_cliHelpSetPathHashMode": "Nastavuje režim hashovania cesty. 0 = starý režim, 1 = štandardný režim, 2 = striktný režim. Ovplyvňuje, ako sa prekladajú trasy.", + "repeater_cliHelpSetLoopDetect": "Nastavuje citlivosť detekcie slučky routovania: vypnutá, minimálna, stredná alebo prísna.", + "repeater_cliHelpSetFreq": "(Používa sa len v sériovej verzii) Rýchlo nastavuje len frekvenciu. Je potrebné reštartovať. Pre úplné nastavenie rádia preferujte funkciu \"nastavenie rádia\".", + "repeater_cliHelpSetBridgeChannel": "(Používa sa len pre ESPNow most) Nastavuje WiFi kanál (1-14), ktorý používa most.", + "repeater_cliHelpGetName": "Zobrazuje zadané meno uzla.", + "repeater_cliHelpGetRole": "Ukazuje funkciu firmvéru (opakovač, server pre miestnosť atď.).", + "repeater_cliHelpGetPublicKey": "Zobrazuje verejný kľúč zariadenia.", + "repeater_cliHelpGetPrvKey": "(Používa sa len v sériových aplikáciách) Zobrazuje súkromný kľúč zariadenia. Zotriďte ho ako tajný údaj.", + "repeater_cliHelpGetRepeat": "Ukazuje, či je funkcia preposielania paketov (funkcia opakéra) zapnutá alebo vypnutá.", + "repeater_cliHelpGetTx": "Zobrazuje aktuálnu výkonovú hodnotu TX v dBm.", + "repeater_cliHelpGetFreq": "Zobrazuje nakonfigurovanú frekvenciu v MHz.", + "repeater_cliHelpGetRadio": "Zobrazuje všetky parametre rádiového signálu: frekvencia, šírka pásma, faktor rozširovania, rýchlosť kódovania.", + "repeater_cliHelpGetRadioRxGain": "(iba pre SX126x) Zobrazuje stav zosilnenia prijímača RX.", + "repeater_cliHelpGetAf": "Zobrazuje aktuálny koeficient času vysielania.", + "repeater_cliHelpGetDutyCycle": "Zobrazuje aktuálnu povolenú frekvenciu ako percentáž.", + "repeater_cliHelpGetIntThresh": "Zobrazuje hranicu pre prechodové signály v dB.", + "repeater_cliHelpGetAgcResetInterval": "Zobrazuje interval reštartovania AGC v sekundách.", + "repeater_cliHelpGetMultiAcks": "Ukazuje, či je režim dvojité potvrdenie zapnutý (1) alebo vypnutý (0).", + "repeater_cliHelpGetAllowReadOnly": "Ukazuje, či je povolená len čítacia funkcia pre hostí.", + "repeater_cliHelpGetAdvertInterval": "Zobrazuje čas trvania miestnej reklamnej pauzy v minútach.", + "repeater_cliHelpGetFloodAdvertInterval": "Zobrazuje časový interval reklamy počas záplavy v hodinách.", + "repeater_cliHelpGetGuestPassword": "Zobrazuje nastavené heslo pre hosta.", + "repeater_cliHelpGetLat": "Zobrazuje nastavenú šírku.", + "repeater_cliHelpGetLon": "Zobrazuje nastavenú dĺžku.", + "repeater_cliHelpGetRxDelay": "Zobrazuje základnú hodnotu rxdelay.", + "repeater_cliHelpGetTxDelay": "Ukazuje faktor zpoždenia pre režim povodňovej komunikácie.", + "repeater_cliHelpGetDirectTxDelay": "Zobrazuje faktor zloženia pri priamej modulácii.", + "repeater_cliHelpGetFloodMax": "Zobrazuje maximálny počet opakovaní povodňového stavu.", + "repeater_cliHelpGetOwnerInfo": "Zobrazuje reťazec s kontaktnými údajmi vlastníka.", + "repeater_cliHelpGetPathHashMode": "Zobrazuje režim hashovania cesty (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Ukazuje citlivosť na detekciu slučiek.", + "repeater_cliHelpGetAcl": "(Používa sa len v sériovej konfigurácii) Zobrazuje prístupové pravidlá na opakovači.", + "repeater_cliHelpGetBridgeEnabled": "Ukazuje, či je most povolený.", + "repeater_cliHelpGetBridgeDelay": "Zobrazuje čas strávený prechodom mosta v milisekundách.", + "repeater_cliHelpGetBridgeSource": "Ukazuje, či most prijíma alebo vysiela RX alebo TX balíky.", + "repeater_cliHelpGetBridgeBaud": "(iba pre rozhranie RS232) Zobrazuje rýchlosť prenosu dát na rozhraní RS232.", + "repeater_cliHelpGetBridgeChannel": "(Používa sa len pre ESPNow) Zobrazuje WiFi kanál mosta.", + "repeater_cliHelpGetBridgeSecret": "(Používa sa len pre ESPNow most) Zobrazuje spoločný tajný kľúč mosta.", + "repeater_cliHelpGetBootloaderVer": "(iba pre NRF52) Zobrazuje verziu bootloaderu.", + "repeater_cliHelpGetAdcMultiplier": "Zobrazuje násobič ADC (škálovanie napätia batérie).", + "repeater_cliHelpGetPwrMgtSupport": "Označuje, či riadiace orgány majú podporu pre správu energie.", + "repeater_cliHelpGetPwrMgtSource": "Ukazuje aktuálny zdroj napájania: externý alebo batéria.", + "repeater_cliHelpGetPwrMgtBootReason": "Zobrazuje najaktuálnejšie dôvody pre reštart a vypnutie.", + "repeater_cliHelpGetPwrMgtBootMv": "Zobrazuje napätie batérie pri spustení systému v milivoltov (mV).", + "repeater_cliHelpSensorGet": "Číta hodnotu nastavenia pre špecifický senzor pomocou klávesového vstupu.", + "repeater_cliHelpSensorSet": "Vytvára vlastné nastavenie pre senzor.", + "repeater_cliHelpSensorList": "Zobrazuje všetky nastavenia pre špecifické senzory, zoradené podľa voliteľného indexu začiatku.", + "repeater_cliHelpRegionDefault": "Zobrazuje aktuálnu rozsiahku, ktorá je nastavená ako výchozí.", + "repeater_cliHelpRegionDefaultSet": "Nastavuje výchoce rozsiahku regiónu. Použite \"\", aby ju vymazal.", + "repeater_cliHelpRegionListAllowed": "Zoznam oblastí, ktoré umožňujú premávku počas povodní.", + "repeater_cliHelpRegionListDenied": "Zoznam oblastí, ktoré zakazujú premávku v dôsledku povodní.", + "repeater_cliHelpStatsPackets": "(Len pre sériové záznamy) Zobrazuje štatistiky na úrovni paketov.", + "repeater_cliHelpStatsRadio": "(Len pre sériu) Zobrazuje údaje o rádiových staniciach.", + "repeater_cliHelpStatsCore": "(Len pre sériové modely) Zobrazuje základné štatistiky firmvéru.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "map_sharedAt": "Zdieľané", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losBlockedSpotsTitle": "Zablokované miesta", + "losBlockedSpotsHint": "Kliknite na zablokované miesto, aby ste ho zvýraznili na mape.", + "losSelectedObstructionTitle": "Vybraná prekážka", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "chat_markAsUnread": "Označenie ako neprečítané", + "settings_companionDebugLogSubtitle": "Príkazy, odpovede a surové dáta pre protokoly BLE/TCP/USB", + "settings_companionDebugLog": "Logovanie pre ladenie (sprievodný log)", + "chat_newMessages": "Nové správy", + "repeater_chanUtil": "Využitie kanálu" } diff --git a/lib/l10n/app_sl.arb b/lib/l10n/app_sl.arb index f6a317e..00930c8 100644 --- a/lib/l10n/app_sl.arb +++ b/lib/l10n/app_sl.arb @@ -44,7 +44,7 @@ } } }, - "common_percentValue": "{percent}%", + "common_percentValue": "{percent} %", "@common_percentValue": { "placeholders": { "percent": { @@ -52,7 +52,7 @@ } } }, - "scanner_title": "MeshCore Open", + "scanner_title": "MeshCore – Odprto", "scanner_scanning": "Skeniram za naprave...", "scanner_connecting": "Povezujem se...", "scanner_disconnecting": "Odklapljam se...", @@ -104,6 +104,8 @@ "settings_privacyModeEnabled": "Privatni način je omogočen.", "settings_privacyModeDisabled": "Privatni način je onemogočen.", "settings_actions": "Akcije", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Pošlji Oglas", "settings_sendAdvertisementSubtitle": "Trenutna prisotnost v oddajah", "settings_advertisementSent": "Oglas poslan", @@ -115,13 +117,13 @@ "settings_rebootDevice": "Ponovni zagon naprave", "settings_rebootDeviceSubtitle": "Ponovno zaženi MeshCore napravo", "settings_rebootDeviceConfirm": "Ste prepričani, da želite ponovno zagnati napravo? Povezava bo prekinjena.", - "settings_debug": "Debug", + "settings_debug": "Odpravljanje napak", "settings_bleDebugLog": "BLE debug log (razhroščevanje)", "settings_bleDebugLogSubtitle": "BLE ukazi, odgovori in surovi podatki", "settings_appDebugLog": "Logi aplikacije", "settings_appDebugLogSubtitle": "Debug sporočila aplikacije", "settings_about": "Oglejte si", - "settings_aboutVersion": "MeshCore Open v{version}", + "settings_aboutVersion": "MeshCore, različ {version}", "@settings_aboutVersion": { "placeholders": { "version": { @@ -133,7 +135,7 @@ "settings_aboutDescription": "Odprtokodni Flutter klient za naprave za LoRa omrežje MeshCore.", "settings_infoName": "Ime", "settings_infoId": "ID", - "settings_infoStatus": "Status", + "settings_infoStatus": "Stanje", "settings_infoBattery": "Baterija", "settings_infoPublicKey": "Javni ključ", "settings_infoContactsCount": "Število stikov", @@ -146,7 +148,7 @@ "settings_spreadingFactor": "Razširitveni faktor", "settings_codingRate": "Programska hitrost", "settings_txPower": "TX Moč (dBm)", - "settings_txPowerHelper": "0 - 22", + "settings_txPowerHelper": "0 – 22", "settings_txPowerInvalid": "Neveljavna TX moč (0-22 dBm)", "settings_error": "Napaka: {message}", "@settings_error": { @@ -164,18 +166,18 @@ "appSettings_themeDark": "Temno", "appSettings_language": "Jezik", "appSettings_languageSystem": "Sistemska privzeta vrednost", - "appSettings_languageEn": "English", - "appSettings_languageFr": "Français", - "appSettings_languageEs": "Español", - "appSettings_languageDe": "Deutsch", - "appSettings_languagePl": "Polski", + "appSettings_languageEn": "Angleščina", + "appSettings_languageFr": "Francija", + "appSettings_languageEs": "Španščina", + "appSettings_languageDe": "Nemščina", + "appSettings_languagePl": "Poljski", "appSettings_languageSl": "Slovenščina", - "appSettings_languagePt": "Português", - "appSettings_languageIt": "Italiano", + "appSettings_languagePt": "Portugalski", + "appSettings_languageIt": "Italijanščina", "appSettings_languageZh": "中文", - "appSettings_languageSv": "Svenska", - "appSettings_languageNl": "Nederlands", - "appSettings_languageSk": "Slovenčina", + "appSettings_languageSv": "Švedska", + "appSettings_languageNl": "Nizozemsko", + "appSettings_languageSk": "Slovenščina", "appSettings_languageBg": "Български", "appSettings_notifications": "Obvestila", "appSettings_enableNotifications": "Omogoči obvestila", @@ -337,11 +339,8 @@ } } }, - "channels_hashtagChannel": "Hashtag kanal", "channels_public": "Javni", "channels_private": "Zasebni", - "channels_publicChannel": "Javni kanal", - "channels_privateChannel": "Zasebni kanal", "channels_editChannel": "Uredi kanal", "channels_muteChannel": "Utišaj kanal", "channels_unmuteChannel": "Vklopi obvestila kanala", @@ -388,6 +387,22 @@ } }, "channels_smazCompression": "Kompresija SMAZ", + "channels_cyr2latCompression": "Kompresija Cyr2Lat", + "channels_cyr2latCompressionDscr": "Pri pošiljanju nekatere cirilice nadomesti z latiničnimi.", + "channels_cyr2latSettingsHeading": "Nastavitve Cyr2Lat", + "channels_cyr2latSettingsSubheading": "Seznam zamenjav", + "channels_cyr2latSettingsDscr": "Uredi JSON-konfiguracijo zamenjav znakov", + "channels_cyr2latSettingsDialogHint": "JSON-tabela zamenjav", + "channels_cyr2latSettingsDialogWrongJSON": "Nepravilen JSON: {error}", + "settings_cyr2latProfileAdd": "Dodaj profil Cyr2Lat", + "settings_cyr2latProfileName": "Ime profila", + "settings_cyr2latProfileNameEmpty": "Ime profila ne sme biti prazno", + "settings_cyr2latProfileAdded": "Profil je bil uspešno dodan", + "settings_cyr2latProfileUpdated": "Profil je bil uspešno posodobljen", + "settings_cyr2latProfileEdit": "Uredi profil Cyr2Lat", + "settings_cyr2latProfileDelete": "Izbriši profil Cyr2Lat", + "settings_cyr2latProfileDeleted": "Profil je bil uspešno izbrisan", + "settings_cyr2latProfileDeleteDscr": "Ali res želite izbrisati profil \"{name}\"?", "channels_channelUpdated": "Kanal {name} je bil posodobljen", "@channels_channelUpdated": { "placeholders": { @@ -399,7 +414,7 @@ "channels_publicChannelAdded": "javna skupnost dodana", "channels_sortBy": "Sortiraj po", "channels_sortManual": "Ročno", - "channels_sortAZ": "A-Z", + "channels_sortAZ": "A do Z", "channels_sortLatestMessages": "Najnovejše sporočilo", "channels_sortUnread": "Nerešeno", "chat_noMessages": "Še ni sporočil.", @@ -531,7 +546,7 @@ } } }, - "debugFrame_textTypeCli": "CLI", + "debugFrame_textTypeCli": "CLI (Command Line Interface)", "debugFrame_textTypePlain": "Preprosto", "debugFrame_text": "- Tekst: \"{text}\"", "@debugFrame_text": { @@ -541,7 +556,7 @@ } } }, - "debugFrame_hexDump": "Hex Dump:", + "debugFrame_hexDump": "Izpis heksadecimalnih vrednosti:", "chat_pathManagement": "Upravljanje poti", "chat_routingMode": "Navodilo za usmerjevalni način", "chat_autoUseSavedPath": "Avto (uporabi shranjeno pot)", @@ -550,7 +565,7 @@ "chat_pathHistoryFull": "Zapiske o poti so popolni. Izbriši vnose, da dodaš nove.", "chat_hopSingular": "skok", "chat_hopPlural": "skokov", - "chat_hopsCount": "{count} {count, plural, =1{hop} other{hops}}", + "chat_hopsCount": "{count} {count, plural, =1{skok} other{skoki}}", "@chat_hopsCount": { "placeholders": { "count": { @@ -879,11 +894,11 @@ "path_setPath": "Nastavi Pot", "repeater_management": "Upravljanje ponovitve", "repeater_managementTools": "Upravne orodje", - "repeater_status": "Status", + "repeater_status": "Stanje", "repeater_statusSubtitle": "Pogledati stanje, statistike in sosede repeatera", "repeater_telemetry": "Telemetrija", "repeater_telemetrySubtitle": "Pogledate telemetrijo senzorjev in sistemske statistike", - "repeater_cli": "CLI", + "repeater_cli": "CLI (Command Line Interface)", "repeater_cliSubtitle": "Pošlji ukazne povelje na ponovitveno enoto.", "repeater_settings": "Nastavitve", "repeater_settingsSubtitle": "Konfigurirajte parametre ponovitelja", @@ -992,7 +1007,7 @@ "repeater_guestPasswordHelper": "Odpovedni dostopni geslo", "repeater_radioSettings": "Nastavitve Radija", "repeater_frequencyMhz": "Frekvenca (MHz)", - "repeater_frequencyHelper": "300-2500 MHz", + "repeater_frequencyHelper": "300–2500 MHz", "repeater_txPower": "TX Moč", "repeater_txPowerHelper": "1-30 dBm", "repeater_bandwidth": "Pasovna širina", @@ -1059,6 +1074,81 @@ }, "repeater_confirm": "Potrdit", "repeater_settingsSaved": "Nastavitve so shranjene uspešno.", + "repeater_rxGain": "Povečana dobitka RX", + "repeater_rxGainHelper": "Veća občutljivost, večji porabljeni tok (velja samo za SX1262/SX1268)", + "repeater_refreshRxGain": "Povečana dobitka RX, posodobit", + "repeater_multiAcks": "Več potrdil", + "repeater_multiAcksSubtitle": "Potrdite sporočila po več poti za boljši dostop", + "repeater_refreshMultiAcks": "Ponovite več potrdil", + "repeater_networkHealth": "Zdravilo omrežja", + "repeater_loopDetect": "Detekcija ciklov", + "repeater_loopDetectHelper": "Izpišite pakete, ki izgledajo kot pete v omrežju.", + "repeater_loopDetectOff": "Izklopljeno", + "repeater_loopDetectMinimal": "Minimalen", + "repeater_loopDetectModerate": "Umiren", + "repeater_loopDetectStrict": "Strogi", + "repeater_dutyCycle": "Ciklus delovanja", + "repeater_dutyCycleHelper": "Najvišji odstotek časa, ki ga lahko posreduje.", + "repeater_dutyCyclePercent": "{percent} %", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Informacije o operaterju", + "repeater_ownerInfoHelper": "javni podatki o tej napravi", + "repeater_refreshOwnerInfo": "Prejmi informacije o operaterju", + "repeater_floodMax": "Največji možni odmerek", + "repeater_floodMaxHelper": "Največje število paketov, ki lahko potujejo v enem plovilnem paketu (0-64)", + "repeater_advancedSettings": "Napredno", + "repeater_advancedSettingsSubtitle": "Gumbi za nastavljanje za izkušene uporabnike", + "repeater_pathHashMode": "Način ustvarjanja hash-a poti", + "repeater_pathHashModeHelper": "Biti, ki so bila uporabljena za kodiranje ID-ja tega releja v oznakah za zaznavanje pot/kroga, imajo naslednje velikosti: 0=1 bit (256 ID-jev, do 64 skokov), 1=2 biti (65.000 ID-jev, do 32 skokov), 2=3 biti (16 milijonov ID-jev, do 21 skokov). V različicah 1.13 in starejših se ustvarjajo večbitne poti – vendar se to zgodi šele, ko je omrežje vklopljeno v različicah 1.14 in kasnejših.", + "repeater_txDelay": "Zatemnitevanje zaradi poplav v Texasu", + "repeater_txDelayHelper": "Uporaba intervalov za ponovno pošiljanje v primeru prometa zaradi poplav, kot pomnožnik časovne trajanje paketa (0-2, privzeto 0,5). Veje vrednost = manjše kolizije, vendar počasnejše dostavo.", + "repeater_directTxDelay": "Neposredni časovno odlašanje", + "repeater_directTxDelayHelper": "Razdalja za ponovno pošiljanje za neposredno (neobvezen) promet, kot pomnožnik časovne trajanja paketa (0-2, privzeto 0,3).", + "repeater_intThresh": "Meja, pri kateri nastane motnja", + "repeater_intThreshHelper": "Tretja stopnja se uporablja za kalibracijo šumnega nivoja radija, kar omogoča, da se izklaplja pri šumu, ki presega to raven. 0 izklopi – uporabite le, če zaznate napake v šumnem pasu.", + "repeater_agcResetInterval": "Interval ponovne kalibracije AGC", + "repeater_agcResetIntervalHelper": "Kako pogosto je treba ponovno nastaviti samodejno regulacijo občutljivosti, da se vrnete v normalno stanje? Interval je nastavljen na nekaj sekund, natančno na 4. 0 izklopi periodično ponovno nastavljanje.", + "repeater_actionsTitle": "Dejanja", + "repeater_sendAdvert": "Pošlji oglas o poplavah", + "repeater_sendAdvertSubtitle": "Razpustite oglas o poplavah preko omrežja.", + "repeater_sendAdvertZeroHop": "Pošlji oglas, ki ne potrebuje posrednika.", + "repeater_sendAdvertZeroHopSubtitle": "Premejte oglas, ki uporablja eno povezavo (brez posrednikov).", + "repeater_clockSync": "Sinerizirajte uro zdaj", + "repeater_clockSyncSubtitle": "Nastavite čas na telefonu, da se sinhronizira s repeatrom.", + "repeater_actionSucceeded": "{action} je uspel", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} ni bilo uspešno: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Nastavitve shranjene – ponovni zagon repetitorja za uporabo", + "repeater_settingsPartialFailure": "Nekatna nastavitva niso uspešna: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Napaka pri shranjevanju nastavitev: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1070,11 +1160,9 @@ "repeater_refreshBasicSettings": "Ponovno nastavi osnovne nastavitve", "repeater_refreshRadioSettings": "Ponovno Nastavitve Radija", "repeater_refreshTxPower": "Ponovno nastavi TX moč", - "repeater_refreshLocationSettings": "Ponovno Nastavi Nastavitve Lokacije", "repeater_refreshPacketForwarding": "Ponovno nastavitve usmerjevanja paketa", "repeater_refreshGuestAccess": "Ponovno nastavitve dostopa gostov", "repeater_refreshPrivacyMode": "Ponovno aktiviraj način zasebnosti", - "repeater_refreshAdvertisementSettings": "Ponovno nastavi Oglede Oglasi", "repeater_refreshed": "{label} je bil/a posodobljen/a", "@repeater_refreshed": { "placeholders": { @@ -1347,7 +1435,7 @@ "listFilter_sortBy": "Sortiraj po", "listFilter_latestMessages": "Najnovejše sporočilo", "listFilter_heardRecently": "Nedavno slišan", - "listFilter_az": "A-Z", + "listFilter_az": "A do Z", "listFilter_filters": "Filtri", "listFilter_all": "Vse", "listFilter_users": "Uporabniki", @@ -1922,13 +2010,6 @@ "contact_teleEnv": "Okolje telemetrije", "contact_teleEnvSubtitle": "Dovoli deljenje podatkov okoljskih senzorjev", "contact_teleLocSubtitle": "Dovoli deljenje podatkov o lokaciji", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_maxRouteWeightSubtitle": "Največja teža, ki jo lahko pot doseže s uspešnimi dostavnami.", "appSettings_initialRouteWeight": "Izvirna teža poti", "appSettings_initialRouteWeightSubtitle": "Izguba teže za nove, odkriti poti", @@ -1940,7 +2021,6 @@ "appSettings_maxMessageRetries": "Najve število poskusov pošiljanja sporočil", "appSettings_maxMessageRetriesSubtitle": "Število poskusov ponovnega poslanja, preden se sporočilo označuje kot neuspešno", "path_routeWeight": "{weight}/{max}", - "settings_multiAck": "Večkratni potrditvi: {value}", "settings_telemetryModeUpdated": "Način telemetrije posodobljen", "map_showOverlaps": "Prekrivanje ključa ponovnega predvajanja", "map_runTraceWithReturnPath": "Vrni se nazaj po isti poti.", @@ -2073,5 +2153,163 @@ "repeater_guest": "Informacije o ponovljalniku", "chat_sendMessage": "Pošlji sporočilo", "room_guest": "Informacije o strežniku", - "repeater_guestTools": "Naložila za goste" + "repeater_guestTools": "Naložila za goste", + "repeater_getCategory": "Dobite vrednosti", + "repeater_powerMgmt": "Upravljanje z energijo", + "repeater_sensors": "Senzori", + "repeater_cliHelpPowerOff": "Izklopi naprave. (ne pričakujemo odziva)", + "repeater_cliHelpClkReboot": "Ponovno nastavi uro na znano točko in ponovno vklopi naprave.", + "repeater_cliHelpAdvertZeroHop": "Pošlje oglas, ki doseže samo neposredne sosede (brez posredovanja).", + "repeater_cliHelpStartOta": "Začne nadstrekovno ažuriranje programne opreme na podprtih ploščah.", + "repeater_cliHelpTime": "Nastavi časovni ukaz naprave na podano število sekund od Unixovega začetka. Časovni ukaz ne more iti nazaj.", + "repeater_cliHelpBoard": "Prikaže proizvajalca plošče / identifikator strojne opreme.", + "repeater_cliHelpDiscoverNeighbors": "Pošlje zahtevo za odkrivanje sosednjih naprav. (Samo za repeatere)", + "repeater_cliHelpPowersaving": "Prikaže, ali je vklopljen način varčevanja z energijo.", + "repeater_cliHelpPowersavingOnOff": "Omogoča ali onemogoča način varčevanja z energijo (če je podprt).", + "repeater_cliHelpErase": "(Samo za serijske naprave) Formira datotapno sistemsko okolje. Izbriše vse nastavitve in kontakte.", + "repeater_cliHelpSetDutyCycle": "Določi maksimalni dovoljeni čas, ki ga naprave lahko posredujejo, v odstotkih (1-100). Samodejno prilagodi faktor, ki odvisen je od časa, ki ga naprave lahko posredujejo.", + "repeater_cliHelpSetPrvKey": "(Samo za serijske naprave) Nadomesti zasebni ključ za identifikacijo naprave. Za uporabo je potrebna ponovna aktivacija. Ustvari nov javni ključ.", + "repeater_cliHelpSetRadioRxGain": "(Samo za SX126x) Vklopi povečano občutljivost RX za izboljšano delovanje pri večjih navorih.", + "repeater_cliHelpSetOwnerInfo": "Določi niz z informacijami o kontaktni osebi, ki je v oglasih. Za uporabo novih vrstic uporabite '|'.", + "repeater_cliHelpSetPathHashMode": "Nastavlja način \"hash poti\". 0 = za stare sisteme, 1 = za standard, 2 = za stroge. Vpliva na to, kako so poti uskladene.", + "repeater_cliHelpSetLoopDetect": "Nastavlja občutljivost detekcije ponavljajočih se povezav: izklopljeno, minimalno, umeren, ali strogo.", + "repeater_cliHelpSetFreq": "(Samo za serijske naprave) Hitro nastavi samo frekvenco. Potrebna je ponovna aktivacija. Za popolno nastavitev radio parametrov je priporočljivo uporabiti možnost \"nastavitev radia\".", + "repeater_cliHelpSetBridgeChannel": "(Samo za most ESPNow) Nastavlja kanal WiFi-ja (1-14), ki ga uporablja most.", + "repeater_cliHelpGetName": "Prikaže ime konfigurirane notranje.", + "repeater_cliHelpGetRole": "Prikaže vlogo programskega oprema (repeater, strežnik za sobo itd.).", + "repeater_cliHelpGetPublicKey": "Prikazuje javni ključ naprave.", + "repeater_cliHelpGetPrvKey": "(Samo za serijske naprave) Prikazuje zasebni ključ naprave. Sprejemajte ga kot skrivno informacijo.", + "repeater_cliHelpGetRepeat": "Pokaže, ali je omogočeno posredovanje paketov (delovanje kot repetitor).", + "repeater_cliHelpGetTx": "Prikazuje trenutno moč TX v dBm.", + "repeater_cliHelpGetFreq": "Prikaže nastavljeno frekvenco v MHz.", + "repeater_cliHelpGetRadio": "Prikaže vse parametre radija: frekvenco, širino pasu, faktor razširjanja, raven kodiranja.", + "repeater_cliHelpGetRadioRxGain": "(Samo za SX126x) Prikazuje stanje povečanega dobiča na RX.", + "repeater_cliHelpGetAf": "Prikazuje trenutni faktor, ki določa časovno obdobje.", + "repeater_cliHelpGetDutyCycle": "Prikazuje trenutno dovoljeno stopnjo delovanja kot odstotek.", + "repeater_cliHelpGetIntThresh": "Prikazuje prag medsebojnega vpliva kanala v dB.", + "repeater_cliHelpGetAgcResetInterval": "Prikazuje interval ponovne kalibracije AGC v sekundah.", + "repeater_cliHelpGetMultiAcks": "Pokaže, ali je vklopljen način dvojnega potrdila (1) ali je izklopljen (0).", + "repeater_cliHelpGetAllowReadOnly": "Pokaže, ali je omogočen le brani dostop za goste.", + "repeater_cliHelpGetAdvertInterval": "Prikazuje časovno obdobje lokalne reklame v minutah.", + "repeater_cliHelpGetFloodAdvertInterval": "Prikaže časovno obdobje, ko se prikazuje oglas o poplavah, v urah.", + "repeater_cliHelpGetGuestPassword": "Prikaže nastavljeno geslo za gostitelja.", + "repeater_cliHelpGetLat": "Prikaže določeno zemljepisno širino.", + "repeater_cliHelpGetLon": "Prikaže določeno merilo dolžine.", + "repeater_cliHelpGetRxDelay": "Prikazuje osnovno vrednost RX odlašanja.", + "repeater_cliHelpGetTxDelay": "Prikazuje faktor zamude v načinu delovanja pri plavlju.", + "repeater_cliHelpGetDirectTxDelay": "Prikazuje faktor odlašanja signala v režimu neposredne komunikacije.", + "repeater_cliHelpGetFloodMax": "Prikazuje največjo število, kolikokrat lahko voda doseže najvišjo višino.", + "repeater_cliHelpGetOwnerInfo": "Prikazuje niz z informacijami o lastniku.", + "repeater_cliHelpGetPathHashMode": "Prikaže način delovanja z hashjem poti (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Prikazuje občutljivost na zaznavanje ciklov.", + "repeater_cliHelpGetAcl": "(Samo za serije) Navaja vnos za nadzor dostopa na ponovljalniku.", + "repeater_cliHelpGetBridgeEnabled": "Pokaže, ali je most omogočen.", + "repeater_cliHelpGetBridgeDelay": "Prikazuje zamik mosta v milisekundah.", + "repeater_cliHelpGetBridgeSource": "Pokaže, ali most prenaša pakete RX ali TX.", + "repeater_cliHelpGetBridgeBaud": "(Samo za most RS232) Prikazuje hitrost prenosa podatkov na mostu.", + "repeater_cliHelpGetBridgeChannel": "(Samo za most ESPNow) Prikazuje kanal WiFi mosta.", + "repeater_cliHelpGetBridgeSecret": "(Samo za most ESPNow) Prikazuje tajno, ki jo deli most.", + "repeater_cliHelpGetBootloaderVer": "(Samo za NRF52) Prikazuje različico programskega orodja.", + "repeater_cliHelpGetAdcMultiplier": "Prikazuje pomnoževalnik ADC (skaliranje napetosti baterije).", + "repeater_cliHelpGetPwrMgtSupport": "Navaja, ali ima uprava področje za upravljanje z energijo.", + "repeater_cliHelpGetPwrMgtSource": "Prikaže trenutni vir napajanja: zunanji ali baterija.", + "repeater_cliHelpGetPwrMgtBootReason": "Prikazuje najnovejšo razlog za ponovno nastavitve in izklop.", + "repeater_cliHelpGetPwrMgtBootMv": "Prikazuje napetost baterije v mV ob zagonu.", + "repeater_cliHelpSensorGet": "Prebere določeno vrednost senzorja preko tipke.", + "repeater_cliHelpSensorSet": "Ustvari prilagojeno nastavitev za senzor.", + "repeater_cliHelpSensorList": "Navaja vse nastavitve za uporabniške senzorje, razvrščene po želeni začetni indeksu.", + "repeater_cliHelpRegionDefault": "Prikaže trenutno privzeto območje.", + "repeater_cliHelpRegionDefaultSet": "Določi privzeto območje. Za izbris uporabite \"\".", + "repeater_cliHelpRegionListAllowed": "Navaja regije, ki dovoljujejo promet v času poplav.", + "repeater_cliHelpRegionListDenied": "Navaja regije, ki preprečujejo promet zaradi poplav.", + "repeater_cliHelpStatsPackets": "(Samo za serijske povezave) Prikazuje statistiko na nivoju paketov.", + "repeater_cliHelpStatsRadio": "(Samo za serije) Prikazuje statistične podatke o radiju.", + "repeater_cliHelpStatsCore": "(Samo za serijske naprave) Prikazuje osnovne statistične podatke.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "settings_multiAck": "Več potrdil", + "map_sharedAt": "Deljeno", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losBlockedSpotsHint": "Dotaknite blokirano točko, da jo označite na zemljeplati.", + "losSelectedObstructionTitle": "Izbrano ovire", + "losBlockedSpotsTitle": "Zasedena parkirišča", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "settings_companionDebugLog": "Log zapis za odpravljanje napak", + "chat_markAsUnread": "Označiti kot neneobdelano", + "chat_newMessages": "Nove novice", + "settings_companionDebugLogSubtitle": "Navodila, odgovori in surova podatka za BLE/TCP/USB.", + "repeater_chanUtil": "Uporaba kanala" } diff --git a/lib/l10n/app_sv.arb b/lib/l10n/app_sv.arb index eab348c..00fd3b0 100644 --- a/lib/l10n/app_sv.arb +++ b/lib/l10n/app_sv.arb @@ -52,7 +52,7 @@ } } }, - "scanner_title": "MeshCore Open", + "scanner_title": "MeshCore – Öppen version", "scanner_scanning": "Söker efter enheter...", "scanner_connecting": "Anslutning...", "scanner_disconnecting": "Anslutning bryts...", @@ -104,6 +104,8 @@ "settings_privacyModeEnabled": "Privatläget är aktiverat", "settings_privacyModeDisabled": "Privatläge är avstängt", "settings_actions": "Åtgärder", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "Skicka Annons", "settings_sendAdvertisementSubtitle": "Sändning finns nu", "settings_advertisementSent": "Annons skickad", @@ -121,7 +123,7 @@ "settings_appDebugLog": "Appfelsökning", "settings_appDebugLogSubtitle": "Applikations felsökningsmeddelanden", "settings_about": "Om", - "settings_aboutVersion": "MeshCore Open v{version}", + "settings_aboutVersion": "MeshCore Open version {version}", "@settings_aboutVersion": { "placeholders": { "version": { @@ -146,7 +148,7 @@ "settings_spreadingFactor": "Spreadingfaktor", "settings_codingRate": "Kodningsgrad", "settings_txPower": "TX-effekt (dBm)", - "settings_txPowerHelper": "0 - 22", + "settings_txPowerHelper": "0 – 22", "settings_txPowerInvalid": "Ogiltig TX-effekt (0-22 dBm)", "settings_error": "Fel: {message}", "@settings_error": { @@ -164,19 +166,19 @@ "appSettings_themeDark": "Mörk", "appSettings_language": "Språk", "appSettings_languageSystem": "Systemstandard", - "appSettings_languageEn": "English", - "appSettings_languageFr": "Français", - "appSettings_languageEs": "Español", - "appSettings_languageDe": "Deutsch", - "appSettings_languagePl": "Polski", - "appSettings_languageSl": "Slovenščina", - "appSettings_languagePt": "Português", - "appSettings_languageIt": "Italiano", - "appSettings_languageZh": "中文", + "appSettings_languageEn": "Engelska", + "appSettings_languageFr": "Franska", + "appSettings_languageEs": "Spanska", + "appSettings_languageDe": "Tyskt", + "appSettings_languagePl": "Polsk", + "appSettings_languageSl": "Sloveniska", + "appSettings_languagePt": "Portugisiska", + "appSettings_languageIt": "Italienska", + "appSettings_languageZh": "Kinesiska", "appSettings_languageSv": "Svenska", - "appSettings_languageNl": "Nederlands", - "appSettings_languageSk": "Slovenčina", - "appSettings_languageBg": "Български", + "appSettings_languageNl": "Nederländska", + "appSettings_languageSk": "Sloveniska", + "appSettings_languageBg": "Bulgariska", "appSettings_notifications": "Meddelanden", "appSettings_enableNotifications": "Aktivera Notifikationer", "appSettings_enableNotificationsSubtitle": "Ta emot notiser för meddelanden och reklam", @@ -209,9 +211,9 @@ } }, "appSettings_batteryChemistryConnectFirst": "Anslut till en enhet för att välja", - "appSettings_batteryNmc": "18650 NMC (3.0-4.2V)", + "appSettings_batteryNmc": "18650 NMC (3,0-4,2V)", "appSettings_batteryLifepo4": "LiFePO4 (2,6–3,65V)", - "appSettings_batteryLipo": "LiPo (3.0-4.2V)", + "appSettings_batteryLipo": "LiPo (3,0-4,2V)", "appSettings_mapDisplay": "Kartvisning", "appSettings_showRepeaters": "Visa återuppslag", "appSettings_showRepeatersSubtitle": "Visa återspelsnoder på kartan", @@ -337,11 +339,8 @@ } } }, - "channels_hashtagChannel": "Hashtagkanal", "channels_public": "Offentligt", "channels_private": "Privat", - "channels_publicChannel": "Allmänt kanal", - "channels_privateChannel": "Privat kanal", "channels_editChannel": "Redigera kanal", "channels_muteChannel": "Tysta kanal", "channels_unmuteChannel": "Slå på ljud för kanal", @@ -367,7 +366,7 @@ "channels_channelName": "Kanalnamn", "channels_usePublicChannel": "Använd Publikkanal", "channels_standardPublicPsk": "Standard allmän PSK", - "channels_pskHex": "PSK (Hex)", + "channels_pskHex": "PSK (heks)", "channels_generateRandomPsk": "Generera slumpmässig PSK", "channels_enterChannelName": "Ange en kanalnamn", "channels_pskMustBe32Hex": "PSK måste vara 32 hexadecimala tecken", @@ -388,6 +387,22 @@ } }, "channels_smazCompression": "SMAZ-komprimering", + "channels_cyr2latCompression": "Cyr2Lat-komprimering", + "channels_cyr2latCompressionDscr": "Ersätter vissa kyrilliska tecken med latinska tecken när du skickar.", + "channels_cyr2latSettingsHeading": "Inställningar för Cyr2Lat", + "channels_cyr2latSettingsSubheading": "Ersättningslista", + "channels_cyr2latSettingsDscr": "Redigera JSON-konfigurationen för teckenersättning", + "channels_cyr2latSettingsDialogHint": "JSON-ersättningskarta", + "channels_cyr2latSettingsDialogWrongJSON": "Felaktig JSON: {error}", + "settings_cyr2latProfileAdd": "Lägg till Cyr2Lat-profil", + "settings_cyr2latProfileName": "Profilnamn", + "settings_cyr2latProfileNameEmpty": "Profilnamnet får inte vara tomt", + "settings_cyr2latProfileAdded": "Profilen har lagts till", + "settings_cyr2latProfileUpdated": "Profilen har uppdaterats", + "settings_cyr2latProfileEdit": "Redigera Cyr2Lat-profil", + "settings_cyr2latProfileDelete": "Ta bort Cyr2Lat-profil", + "settings_cyr2latProfileDeleted": "Profilen har tagits bort", + "settings_cyr2latProfileDeleteDscr": "Är du säker på att du vill ta bort profilen \"{name}\"?", "channels_channelUpdated": "Kanalen \"{name}\" har uppdaterats", "@channels_channelUpdated": { "placeholders": { @@ -531,7 +546,7 @@ } } }, - "debugFrame_textTypeCli": "CLI", + "debugFrame_textTypeCli": "Kommandorad", "debugFrame_textTypePlain": "Enkel", "debugFrame_text": "- Text: \"{text}\"", "@debugFrame_text": { @@ -550,7 +565,7 @@ "chat_pathHistoryFull": "Historisk sökväg är full. Ta bort poster för att lägga till nya.", "chat_hopSingular": "hoppa", "chat_hopPlural": "hoppar", - "chat_hopsCount": "{count} {count, plural, =1{hop} other{hops}}", + "chat_hopsCount": "{count} {count, plural, =1{hopp} other{hopp} }", "@chat_hopsCount": { "placeholders": { "count": { @@ -881,9 +896,9 @@ "repeater_managementTools": "Administrationsverktyg", "repeater_status": "Status", "repeater_statusSubtitle": "Visa återspolningsstatus, statistik och grannar", - "repeater_telemetry": "Telemetry", + "repeater_telemetry": "Telemetri", "repeater_telemetrySubtitle": "Visa telemetri för sensorer och systemstatistik", - "repeater_cli": "CLI", + "repeater_cli": "Kommandoradgränssnitt", "repeater_cliSubtitle": "Skicka kommandon till repetitorn", "repeater_settings": "Inställningar", "repeater_settingsSubtitle": "Konfigurera återspolarparametrar", @@ -992,7 +1007,7 @@ "repeater_guestPasswordHelper": "Läs-skyddspassord", "repeater_radioSettings": "Radioinställningar", "repeater_frequencyMhz": "Frekvens (MHz)", - "repeater_frequencyHelper": "300-2500 MHz", + "repeater_frequencyHelper": "300–2500 MHz", "repeater_txPower": "TX Effekt", "repeater_txPowerHelper": "1-30 dBm", "repeater_bandwidth": "Bandbredd", @@ -1059,6 +1074,81 @@ }, "repeater_confirm": "Bekräfta", "repeater_settingsSaved": "Inställningarna sparades framgångsrikt.", + "repeater_rxGain": "Ökad RX-vinst", + "repeater_rxGainHelper": "Ökad känslighet, högre strömförbrukning (endast för SX1262/SX1268)", + "repeater_refreshRxGain": "Återställ förbättrad RX-signalstyrka", + "repeater_multiAcks": "Flera bekräftelser", + "repeater_multiAcksSubtitle": "Bekräfta meddelanden via flera olika kanaler för bättre leverans.", + "repeater_refreshMultiAcks": "Återställ flera ACK-meddelanden", + "repeater_networkHealth": "Nätverkets hälsa", + "repeater_loopDetect": "Identifiering av loopar", + "repeater_loopDetectHelper": "Skapa \"flödespaket\" som ser ut som att de bildar en loop (en återkommande krets).", + "repeater_loopDetectOff": "Av", + "repeater_loopDetectMinimal": "Minimal", + "repeater_loopDetectModerate": "Måttlig", + "repeater_loopDetectStrict": "Strikt", + "repeater_dutyCycle": "Arbetscykel", + "repeater_dutyCycleHelper": "Maximal procentandel av sändningstid", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Information om operatören", + "repeater_ownerInfoHelper": "Offentliga metadata för denna sändare", + "repeater_refreshOwnerInfo": "Uppdatera information om personal", + "repeater_floodMax": "Maximala mängden humle", + "repeater_floodMaxHelper": "Maximalt antal hopp en paket kan färdas (0-64)", + "repeater_advancedSettings": "Avancerad", + "repeater_advancedSettingsSubtitle": "Ställjusteringsknappar för erfarna användare", + "repeater_pathHashMode": "Hash-läge för sökväg", + "repeater_pathHashModeHelper": "Byte används för att koda denna repeaters ID i taggar för att upptäcka loopar/flödesvägar. 0=1 byte (256 ID:n, upp till 64 hopp), 1=2 byte (65 000 ID:n, upp till 32 hopp), 2=3 byte (16 miljoner ID:n, upp till 21 hopp). Versioner 1.13 och äldre har stöd för multi-byte-vägar – endast en gång när nätverket är aktiverat (från och med version 1.14).", + "repeater_txDelay": "Försening i Flood TX", + "repeater_txDelayHelper": "Återöverföringsintervall för trafik under perioder med hög belastning, som en multiplikator av paketets överföringstid (0-2, standard 0,5). Högre värde = färre kollisioner, men långsammare leverans.", + "repeater_directTxDelay": "Direkt TX-fördröjning", + "repeater_directTxDelayHelper": "Återöverföringsintervall för direkt (icke-översvämmande) trafik, som en multiplikator av paketets överföringstid (0-2, standard 0,3).", + "repeater_intThresh": "Tröskelvärde för störning", + "repeater_intThreshHelper": "Tröskelvärdet har ställts in så att den filtrerar bort störningar som överstiger detta värde. 0 stänger av – aktivera endast om du ser RX-fel i ett störningsfyllt frekvensområde.", + "repeater_agcResetInterval": "Återställningsintervall för AGC", + "repeater_agcResetIntervalHelper": "Hur ofta ska man återställa radioens automatiska förstärkning för att återhämta sig från ett tillstånd där förstärkningen är fast? Sekunder, inställda till en multipel av 4. 0 stänger av periodiska återställningar.", + "repeater_actionsTitle": "Åtgärder", + "repeater_sendAdvert": "Skicka annons om översvämning", + "repeater_sendAdvertSubtitle": "Sänd en reklamfilm om översvämningar via nätverket.", + "repeater_sendAdvertZeroHop": "Skicka en annons som inte kräver någon mellanstopp", + "repeater_sendAdvertZeroHopSubtitle": "Sänd en reklamkampanj med en enda sändare (utan mellanliggande sändare).", + "repeater_clockSync": "Synkronisera klockan nu", + "repeater_clockSyncSubtitle": "Ställ din telefons tid till repeatern.", + "repeater_actionSucceeded": "{action} lyckades", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} misslyckades: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Inställningar sparade – starta om repetern för att tillämpa dem", + "repeater_settingsPartialFailure": "Vissa inställningar misslyckades: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Fel vid sparande av inställningar: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1070,11 +1160,9 @@ "repeater_refreshBasicSettings": "Återställ Grundläggande Inställningar", "repeater_refreshRadioSettings": "Återställ Radiosinställningar", "repeater_refreshTxPower": "Återställ TX-effekt", - "repeater_refreshLocationSettings": "Uppdatera Lokationsinställningar", "repeater_refreshPacketForwarding": "Återställ Paketväxling", "repeater_refreshGuestAccess": "Återställ Gäståtkomst", "repeater_refreshPrivacyMode": "Återställ Sekretessläge", - "repeater_refreshAdvertisementSettings": "Återställ Annonsinställningar", "repeater_refreshed": "{label} har uppdaterats", "@repeater_refreshed": { "placeholders": { @@ -1477,7 +1565,7 @@ "community_qrTitle": "Dela Gemenskap", "community_qrInstructions": "Skanna denna QR-kod för att gå med i \"{name}\"", "community_hashtagPrivacyHint": "Community-hashtagkanaler kan endast nås av medlemmar i communityn", - "community_hashtagChannel": "Community Hashtag", + "community_hashtagChannel": "Hashtag för gemenskapen", "community_invalidQrCode": "Ogiltig community QR-kod", "community_alreadyMember": "Är redan medlem", "community_alreadyMemberMessage": "Du är redan medlem av \"{name}\".", @@ -1504,7 +1592,7 @@ "community_regularHashtagDesc": "Offentlig hashtag (alla kan gå med)", "community_communityHashtagDesc": "Endast för medlemmar", "community_forCommunity": "För {name}", - "community_communityHashtag": "Community Hashtag", + "community_communityHashtag": "Gemenskaps-hashtag", "@community_regenerateSecretConfirm": { "placeholders": { "name": { @@ -1551,7 +1639,7 @@ "pathTrace_failed": "Sökvägsföljning misslyckades.", "pathTrace_notAvailable": "Path trace ej tillgänglig.", "pathTrace_refreshTooltip": "Uppdatera Path Trace", - "contacts_pathTrace": "Path Trace", + "contacts_pathTrace": "Spårning", "contacts_ping": "Ping", "contacts_repeaterPathTrace": "Vägspårning till repeater", "contacts_repeaterPing": "Ping-repeater", @@ -1879,7 +1967,7 @@ "tcpHostLabel": "IP-adress", "tcpScreenTitle": "Anslut via TCP", "connectionChoiceTcpLabel": "TCP", - "tcpPortLabel": "Port", + "tcpPortLabel": "Hamn", "tcpPortHint": "5000", "tcpStatus_notConnected": "Ange slutpunkt och anslut", "tcpStatus_connectingTo": "Anslutning till {endpoint}...", @@ -1922,13 +2010,6 @@ "contact_teleBaseSubtitle": "Tillåt delning av batterinivå och grundläggande telemetri", "contact_teleLoc": "Telemetridata plats", "contact_teleLocSubtitle": "Tillåt delning av platsdata", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_initialRouteWeightSubtitle": "Initial vikt för nyligen upptäckta vägar", "appSettings_maxRouteWeight": "Maximalt tillåtet vikt för rutten", "appSettings_maxRouteWeightSubtitle": "Maximal vikt som en leveransväg kan ackumulera från framgångsrika leveranser.", @@ -1941,7 +2022,7 @@ "appSettings_maxMessageRetriesSubtitle": "Antal försök att skicka om ett meddelande innan det markeras som misslyckat.", "path_routeWeight": "{weight}/{max}", "settings_telemetryModeUpdated": "Telemetri-läge uppdaterat", - "settings_multiAck": "Multi-ACKs: {value}", + "settings_multiAck": "Flera bekräftelser", "map_showOverlaps": "Repeater-nyckelöverlappningar", "map_runTraceWithReturnPath": "Gå tillbaka på samma väg", "@radioStats_noiseFloor": { @@ -2073,5 +2154,162 @@ "repeater_guest": "Information om repetorer", "chat_sendMessage": "Skicka meddelande", "repeater_guestTools": "Gästverktyg", - "room_guest": "Information om servern" + "room_guest": "Information om servern", + "repeater_getCategory": "Hämta värden", + "repeater_powerMgmt": "Effektstyrning", + "repeater_sensors": "Sensorer", + "repeater_cliHelpPowerOff": "Stänger av enheten. (ingen respons förväntas)", + "repeater_cliHelpClkReboot": "Återställer klockan till en känd tidpunkt och startar om enheten.", + "repeater_cliHelpAdvertZeroHop": "Skickar en annons som når endast direkt grannar (endast närmaste grannar).", + "repeater_cliHelpStartOta": "Startar en firmware-uppdatering via luft, på kompatibla enheter.", + "repeater_cliHelpTime": "Ställer enheten till den angivna Unix-epokens tid. Klockan kan inte gå bakåt.", + "repeater_cliHelpBoard": "Visar tillverkaren av moderkortet / hårdvaru-identifieraren.", + "repeater_cliHelpDiscoverNeighbors": "Skickar en förfrågan om att upptäcka närliggande noder. (Endast för repetrar)", + "repeater_cliHelpPowersaving": "Visar om energisparläget är aktiverat eller avstängt.", + "repeater_cliHelpPowersavingOnOff": "Aktiverar eller inaktiverar energisparläget (om det stöds).", + "repeater_cliHelpErase": "(Endast för seriell kommunikation) Formaterar enhetens filsystem. Raderar alla inställningar och kontakter.", + "repeater_cliHelpSetDutyCycle": "Anger den maximala tillåtna överföringsfrekvensen som en procent (1-100). Justerar automatiskt tidsfaktorn.", + "repeater_cliHelpSetPrvKey": "(Endast för seriell användning) Ersätter enhetsens privata nyckel. Återstart krävs för att tillämpa. Genererar en ny publik nyckel.", + "repeater_cliHelpSetRadioRxGain": "(Endast SX126x) Aktiverar förstärkt mottagargain för förbättrad känslighet vid högre strömförbrukning.", + "repeater_cliHelpSetOwnerInfo": "Anger kontaktinformationen som ska inkluderas i annonserna. Använd '|' för att separera olika fält.", + "repeater_cliHelpSetPathHashMode": "Definierar läget för hash-baserad ruttning. 0 = äldre läge, 1 = standard, 2 = strikt. Påverkar hur ruttvägar matchas.", + "repeater_cliHelpSetLoopDetect": "Ställer in känsligheten för att detektera loopar i routningen: av, minimal, måttlig eller strikt.", + "repeater_cliHelpSetFreq": "(Endast för seriell kommunikation) Ställer snabbt bara frekvensen. Kräver omstart. Föredrar \"ställ radio\" för att få full kontroll över radioinställningarna.", + "repeater_cliHelpSetBridgeChannel": "(Endast ESPNow-brygga) Anger WiFi-kanalen (1-14) som används av bryggan.", + "repeater_cliHelpGetName": "Visar det konfigurerade nodnamnet.", + "repeater_cliHelpGetRole": "Visar firmware-funktionen (Repeater, Room Server, etc.).", + "repeater_cliHelpGetPublicKey": "Visar enhetens publika nyckel.", + "repeater_cliHelpGetPrvKey": "(Endast för seriell användning) Visar enheters privata nyckel. Behandla detta som en hemlighet.", + "repeater_cliHelpGetRepeat": "Visar om funktionen för att vidarebefordra paket (som en repeater) är aktiverad eller inaktiverad.", + "repeater_cliHelpGetTx": "Visar aktuell TX-effekt i dBm.", + "repeater_cliHelpGetFreq": "Visar den konfigurerade radiovågen i MHz.", + "repeater_cliHelpGetRadio": "Visar alla radioparametrar: frekvens, bandbredd, spridningsfaktor, kodningshastighet.", + "repeater_cliHelpGetRadioRxGain": "(Endast för SX126x) Visar RX:s förstärkningstillstånd.", + "repeater_cliHelpGetAf": "Visar aktuell tidssats.", + "repeater_cliHelpGetDutyCycle": "Visar den aktuella tillåtna arbetscykeln i procent.", + "repeater_cliHelpGetIntThresh": "Visar gränsen för kanalinterferens i dB.", + "repeater_cliHelpGetAgcResetInterval": "Visar återställningsintervallet för AGC i sekunder.", + "repeater_cliHelpGetMultiAcks": "Visar om dubbelbekräftelseläget är aktiverat (1) eller avstängt (0).", + "repeater_cliHelpGetAllowReadOnly": "Visar om gäst har tillåtelse att endast läsa.", + "repeater_cliHelpGetAdvertInterval": "Visar den lokala reklampausens längd i minuter.", + "repeater_cliHelpGetFloodAdvertInterval": "Visar tidsintervallet för reklamsegmentet under översvämningen, i timmar.", + "repeater_cliHelpGetGuestPassword": "Visar det angivna gästlösen.", + "repeater_cliHelpGetLat": "Visar den angivna latituden.", + "repeater_cliHelpGetLon": "Visar den angivna longituden.", + "repeater_cliHelpGetRxDelay": "Visar grundvärdet för rxdelay.", + "repeater_cliHelpGetTxDelay": "Visar faktor för fördröjning i flödesläge.", + "repeater_cliHelpGetDirectTxDelay": "Visar faktorn för fördröjning i direktläge.", + "repeater_cliHelpGetFloodMax": "Visar det maximala antalet gånger en översvämning har inträffat.", + "repeater_cliHelpGetOwnerInfo": "Visar strängen med kontaktinformation för ägaren.", + "repeater_cliHelpGetPathHashMode": "Visar hash-läge (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Visar känsligheten för att detektera loopar.", + "repeater_cliHelpGetAcl": "(Endast för serier) Visar åtkomstkontrollinställningarna för en repeater.", + "repeater_cliHelpGetBridgeEnabled": "Visar om bron är aktiverad.", + "repeater_cliHelpGetBridgeDelay": "Visar fördröjningen i bron i millisekunder.", + "repeater_cliHelpGetBridgeSource": "Visar om bron skickar RX- eller TX-paket.", + "repeater_cliHelpGetBridgeBaud": "(Enbart RS232-brygga) Visar bryggans baud-hastighet.", + "repeater_cliHelpGetBridgeChannel": "(Endast ESPNow-brygga) Visar WiFi-kanal för bryggan.", + "repeater_cliHelpGetBridgeSecret": "(Endast ESPNow-brygga) Visar bryggans delade hemlighet.", + "repeater_cliHelpGetBootloaderVer": "(Endast för NRF52) Visar versionen av bootloadern.", + "repeater_cliHelpGetAdcMultiplier": "Visar ADC-multiplikatorn (skalning av batterispänning).", + "repeater_cliHelpGetPwrMgtSupport": "Anger om styrelsen har stöd för energihantering.", + "repeater_cliHelpGetPwrMgtSource": "Visar aktuell strömkälla: extern eller batteri.", + "repeater_cliHelpGetPwrMgtBootReason": "Visar de senaste orsakerna till återställning och avstängning.", + "repeater_cliHelpGetPwrMgtBootMv": "Visar batterispänningen vid start i millivolt (mV).", + "repeater_cliHelpSensorGet": "Läser en anpassad sensorinställning via tangentbordet.", + "repeater_cliHelpSensorSet": "Skapar en anpassad inställning för en sensor.", + "repeater_cliHelpSensorList": "Visar alla anpassade sensorinställningar, sorterade från ett valfritt startindex.", + "repeater_cliHelpRegionDefault": "Visar det aktuella standardområde.", + "repeater_cliHelpRegionDefaultSet": "Definierar standardområde. Använd \"\" för att återställa till standard.", + "repeater_cliHelpRegionListAllowed": "Lista områden där det är tillåtet med trafik under översvämningsförhållanden.", + "repeater_cliHelpRegionListDenied": "Listar områden där trafik på grund av översvämningar är förbjuden.", + "repeater_cliHelpStatsPackets": "(Endast för seriell kommunikation) Visar statistik på paketnivå.", + "repeater_cliHelpStatsRadio": "(Enbart för serier) Visar radiostatistik.", + "repeater_cliHelpStatsCore": "(Enbart för seriell kommunikation) Visar grundläggande firmware-statistik.", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "map_sharedAt": "Delad", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losBlockedSpotsTitle": "Reserverade platser", + "losSelectedObstructionTitle": "Vald hinder", + "losBlockedSpotsHint": "Klicka på en markerad plats för att framhäva den på kartan.", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "chat_markAsUnread": "Markera som oläst", + "settings_companionDebugLog": "Följande felsökningslogg", + "chat_newMessages": "Nya meddelanden", + "settings_companionDebugLogSubtitle": "BLE/TCP/USB-kommandon, svar och rådata", + "repeater_chanUtil": "Användning av kanal" } diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb index a005b36..8330d36 100644 --- a/lib/l10n/app_uk.arb +++ b/lib/l10n/app_uk.arb @@ -1,5 +1,5 @@ { - "channels_channelDeleteFailed": "Не вдалося видалити канал \"{name}\"", + "channels_channelDeleteFailed": "Не вдалось видалити канал \"{name}\"", "@channels_channelDeleteFailed": { "placeholders": { "name": { @@ -18,6 +18,7 @@ "common_save": "Зберегти", "common_delete": "Видалити", "common_close": "Закрити", + "common_done": "Готово", "common_edit": "Редагувати", "common_add": "Додати", "common_settings": "Налаштування", @@ -26,7 +27,7 @@ "common_disconnected": "Відключено", "common_create": "Створити", "common_continue": "Продовжити", - "common_share": "Поділитися", + "common_share": "Поділитись", "common_copy": "Копіювати", "common_retry": "Повторити", "common_hide": "Приховати", @@ -52,7 +53,7 @@ } } }, - "scanner_title": "MeshCore Open", + "scanner_title": "MeshCore: Відкритий доступ", "scanner_scanning": "Пошук пристроїв...", "scanner_connecting": "Підключення...", "scanner_disconnecting": "Відключення...", @@ -81,7 +82,7 @@ "device_meshcore": "MeshCore", "settings_title": "Налаштування", "settings_deviceInfo": "Інформація про пристрій", - "settings_appSettings": "Налаштування програми", + "settings_appSettings": "Налаштування застосунку", "settings_appSettingsSubtitle": "Сповіщення, повідомлення та налаштування карти", "settings_nodeSettings": "Налаштування вузла", "settings_nodeName": "Ім'я вузла", @@ -91,19 +92,21 @@ "settings_radioSettings": "Налаштування радіо", "settings_radioSettingsSubtitle": "Частота, потужність, коефіцієнт розширення", "settings_radioSettingsUpdated": "Налаштування радіо оновлено", - "settings_location": "Розташування", - "settings_locationSubtitle": "GPS координати", - "settings_locationUpdated": "Розташування оновлено", + "settings_location": "Геопозиція", + "settings_locationSubtitle": "GPS-координати", + "settings_locationUpdated": "Геопозицію оновлено", "settings_locationBothRequired": "Введіть широту та довготу.", "settings_locationInvalid": "Некоректна широта або довгота.", "settings_latitude": "Широта", "settings_longitude": "Довгота", "settings_privacyMode": "Режим приватності", - "settings_privacyModeSubtitle": "Приховати ім'я/розташування в оголошеннях", - "settings_privacyModeToggle": "Увімкніть режим приватності, щоб приховати своє ім'я та місцезнаходження в оголошеннях.", + "settings_privacyModeSubtitle": "Приховати ім'я/геопозицію в оголошеннях", + "settings_privacyModeToggle": "Увімкніть режим приватності, щоб приховати своє ім'я та геопозицію в оголошеннях.", "settings_privacyModeEnabled": "Режим приватності увімкнено", "settings_privacyModeDisabled": "Режим приватності вимкнено", "settings_actions": "Дії", + "settings_deleteAllPaths": "Видалити всі шляхи", + "settings_deleteAllPathsSubtitle": "Очистити всі дані шляхів у контактах.", "settings_sendAdvertisement": "Оголосити себе", "settings_sendAdvertisementSubtitle": "Транслювати присутність зараз", "settings_advertisementSent": "Оголошення надіслано", @@ -118,9 +121,9 @@ "settings_debug": "Налагодження", "settings_bleDebugLog": "Журнал налагодження BLE", "settings_bleDebugLogSubtitle": "Команди BLE, відповіді та необроблені дані", - "settings_appDebugLog": "Журнал налагодження програми", - "settings_appDebugLogSubtitle": "Повідомлення налагодження програми", - "settings_about": "Про програму", + "settings_appDebugLog": "Журнал налагодження застосунку", + "settings_appDebugLogSubtitle": "Повідомлення налагодження застосунку", + "settings_about": "Про застосунок", "settings_aboutVersion": "MeshCore Open v{version}", "@settings_aboutVersion": { "placeholders": { @@ -132,7 +135,7 @@ "settings_aboutLegalese": "Проєкт MeshCore Open Source 2026", "settings_aboutDescription": "Клієнт Flutter з відкритим вихідним кодом для пристроїв мережі MeshCore LoRa.", "settings_infoName": "Ім'я", - "settings_infoId": "ID", + "settings_infoId": "Ідентифікатор", "settings_infoStatus": "Статус", "settings_infoBattery": "Батарея", "settings_infoPublicKey": "Відкритий ключ", @@ -140,7 +143,7 @@ "settings_infoChannelCount": "Кількість каналів", "settings_presets": "Попередні налаштування", "settings_frequency": "Частота (МГц)", - "settings_frequencyHelper": "300.0 - 2500.0", + "settings_frequencyHelper": "300,0 – 2500,0", "settings_frequencyInvalid": "Некоректна частота (300-2500 МГц)", "settings_bandwidth": "Смуга пропускання", "settings_spreadingFactor": "Коефіцієнт розширення", @@ -156,7 +159,7 @@ } } }, - "appSettings_title": "Налаштування програми", + "appSettings_title": "Налаштування застосунку", "appSettings_appearance": "Вигляд", "appSettings_theme": "Тема", "appSettings_themeSystem": "Системна", @@ -164,19 +167,19 @@ "appSettings_themeDark": "Темна", "appSettings_language": "Мова", "appSettings_languageSystem": "Як у системі", - "appSettings_languageEn": "English", - "appSettings_languageFr": "Français", - "appSettings_languageEs": "Español", - "appSettings_languageDe": "Deutsch", - "appSettings_languagePl": "Polski", - "appSettings_languageSl": "Slovenščina", - "appSettings_languagePt": "Português", - "appSettings_languageIt": "Italiano", - "appSettings_languageZh": "中文", - "appSettings_languageSv": "Svenska", - "appSettings_languageNl": "Nederlands", - "appSettings_languageSk": "Slovenčina", - "appSettings_languageBg": "Български", + "appSettings_languageEn": "Англійська", + "appSettings_languageFr": "Французька", + "appSettings_languageEs": "Іспанська", + "appSettings_languageDe": "Німецькою", + "appSettings_languagePl": "Польська", + "appSettings_languageSl": "Словенська мова", + "appSettings_languagePt": "Португальська", + "appSettings_languageIt": "Італійська", + "appSettings_languageZh": "Китайська", + "appSettings_languageSv": "Шведська", + "appSettings_languageNl": "Нідерландська", + "appSettings_languageSk": "Словенська", + "appSettings_languageBg": "Болгарська", "appSettings_languageUk": "Українська", "appSettings_notifications": "Сповіщення", "appSettings_enableNotifications": "Увімкнути сповіщення", @@ -194,9 +197,9 @@ "appSettings_clearPathOnMaxRetry": "Очищати шлях після макс. спроб", "appSettings_clearPathOnMaxRetrySubtitle": "Скидати шлях до контакту після 5 невдалих спроб надсилання", "appSettings_pathsWillBeCleared": "Шляхи будуть очищені після 5 невдалих спроб.", - "appSettings_pathsWillNotBeCleared": "Шляхи не будуть очищатися автоматично.", + "appSettings_pathsWillNotBeCleared": "Шляхи не будуть очищатись автоматично.", "appSettings_autoRouteRotation": "Авторотація маршруту", - "appSettings_autoRouteRotationSubtitle": "Чергувати найкращі шляхи та режим «на всю мережу» (flood)", + "appSettings_autoRouteRotationSubtitle": "Чергувати найкращі шляхи та режим «через всю мережу» (flood)", "appSettings_autoRouteRotationEnabled": "Авторотація маршрутизації увімкнена", "appSettings_autoRouteRotationDisabled": "Авторотація маршрутизації вимкнена", "appSettings_battery": "Батарея", @@ -251,10 +254,10 @@ } }, "appSettings_debugCard": "Налагодження", - "appSettings_appDebugLogging": "Логування налагодження програми", - "appSettings_appDebugLoggingSubtitle": "Записувати повідомлення налагодження програми в лог для усунення несправностей.", - "appSettings_appDebugLoggingEnabled": "Логування налагодження програми увімкнено", - "appSettings_appDebugLoggingDisabled": "Налагодження програми вимкнено.", + "appSettings_appDebugLogging": "Журналювання налагодження застосунку", + "appSettings_appDebugLoggingSubtitle": "Записувати повідомлення налагодження застосунку в журнал для усунення несправностей.", + "appSettings_appDebugLoggingEnabled": "Журналювання налагодження застосунку увімкнено", + "appSettings_appDebugLoggingDisabled": "Журналювання налагодження застосунку вимкнено.", "contacts_title": "Контакти", "contacts_noContacts": "Контактів не знайдено.", "contacts_contactsWillAppear": "Контакти з'являться, коли пристрої надішлють оголошення.", @@ -338,11 +341,9 @@ } } }, - "channels_hashtagChannel": "Канал з хештегом", "channels_public": "Публічний", + "channels_via": "через {path}", "channels_private": "Приватний", - "channels_publicChannel": "Публічний канал", - "channels_privateChannel": "Приватний канал", "channels_editChannel": "Редагувати канал", "channels_muteChannel": "Вимкнути сповіщення каналу", "channels_unmuteChannel": "Увімкнути сповіщення каналу", @@ -368,10 +369,10 @@ "channels_channelName": "Назва каналу", "channels_usePublicChannel": "Використовувати публічний канал", "channels_standardPublicPsk": "Стандартний публічний PSK", - "channels_pskHex": "PSK (Hex)", + "channels_pskHex": "PSK (шестнадцяткова система)", "channels_generateRandomPsk": "Згенерувати випадковий ключ PSK", "channels_enterChannelName": "Будь ласка, введіть назву каналу", - "channels_pskMustBe32Hex": "PSK має складатися з 32 шістнадцяткових символів.", + "channels_pskMustBe32Hex": "PSK має складатись з 32 шістнадцяткових символів.", "channels_channelAdded": "Канал «{name}» додано", "@channels_channelAdded": { "placeholders": { @@ -389,6 +390,22 @@ } }, "channels_smazCompression": "Стиснення SMAZ", + "channels_cyr2latCompression": "Стиснення Cyr2Lat", + "channels_cyr2latCompressionDscr": "Замінює деякі кириличні символи на латиницю при відправці.", + "channels_cyr2latSettingsHeading": "Налаштування Cyr2Lat", + "channels_cyr2latSettingsSubheading": "Список замін", + "channels_cyr2latSettingsDscr": "Редагувати JSON-конфігурацію заміни символів", + "channels_cyr2latSettingsDialogHint": "JSON-карта замін", + "channels_cyr2latSettingsDialogWrongJSON": "Некоректний JSON: {error}", + "settings_cyr2latProfileAdd": "Додати профіль Cyr2Lat", + "settings_cyr2latProfileName": "Назва профілю", + "settings_cyr2latProfileNameEmpty": "Назва профілю не може бути порожньою", + "settings_cyr2latProfileAdded": "Профіль успішно додано", + "settings_cyr2latProfileUpdated": "Профіль успішно оновлено", + "settings_cyr2latProfileEdit": "Редагувати профіль Cyr2Lat", + "settings_cyr2latProfileDelete": "Видалити профіль Cyr2Lat", + "settings_cyr2latProfileDeleted": "Профіль успішно видалено", + "settings_cyr2latProfileDeleteDscr": "Ви впевнені, що хочете видалити профіль \"{name}\"?", "channels_channelUpdated": "Канал «{name}» оновлено", "@channels_channelUpdated": { "placeholders": { @@ -422,7 +439,7 @@ } } }, - "chat_location": "Розташування", + "chat_location": "Геопозиція", "chat_sendMessageTo": "Надіслати повідомлення {contactName}", "@chat_sendMessageTo": { "placeholders": { @@ -466,17 +483,17 @@ "gifPicker_searchHint": "Пошук GIF...", "gifPicker_poweredBy": "На базі GIPHY", "gifPicker_noGifsFound": "GIF не знайдено", - "gifPicker_failedLoad": "Не вдалося завантажити GIF-файли", + "gifPicker_failedLoad": "Не вдалось завантажити GIF-файли", "gifPicker_failedSearch": "Пошук GIF не вдався", "gifPicker_noInternet": "Немає інтернет-з'єднання", - "debugLog_appTitle": "Журнал налагодження програми", + "debugLog_appTitle": "Журнал налагодження застосунку", "debugLog_bleTitle": "Журнал налагодження BLE", "debugLog_copyLog": "Копіювати журнал", "debugLog_clearLog": "Очистити журнал", "debugLog_copied": "Журнал налагодження скопійовано", "debugLog_bleCopied": "Журнал BLE скопійовано", "debugLog_noEntries": "Поки що немає записів журналу налагодження.", - "debugLog_enableInSettings": "Увімкніть налагодження програми в налаштуваннях", + "debugLog_enableInSettings": "Увімкніть налагодження застосунку в налаштуваннях", "debugLog_frames": "Кадри", "debugLog_rawLogRx": "Необроблений лог - RX", "debugLog_noBleActivity": "Поки що немає активності BLE.", @@ -532,7 +549,7 @@ } } }, - "debugFrame_textTypeCli": "CLI", + "debugFrame_textTypeCli": "CLI (Command Line Interface)", "debugFrame_textTypePlain": "Звичайний", "debugFrame_text": "- Текст: \"{text}\"", "@debugFrame_text": { @@ -546,12 +563,12 @@ "chat_pathManagement": "Керування шляхами", "chat_routingMode": "Режим маршрутизації", "chat_autoUseSavedPath": "Авто (використовувати збережений шлях)", - "chat_forceFloodMode": "Примусово на всю мережу", - "chat_recentAckPaths": "Недавні шляхи ACK (натисніть, щоб використати):", + "chat_forceFloodMode": "Примусово через всю мережу", + "chat_recentAckPaths": "Підтверджені шляхи (натисніть, щоб використати):", "chat_pathHistoryFull": "Історія шляхів заповнена. Видаліть записи, щоб додати нові.", - "chat_hopSingular": "Стрибок", - "chat_hopPlural": "стрибків", - "chat_hopsCount": "{count} {count, plural, =1{стрибок} few{стрибки} many{стрибків} other{стрибків}}", + "chat_hopSingular": "Перехід", + "chat_hopPlural": "переходів", + "chat_hopsCount": "{count} {count, plural, =1{перехід} few{переходи} many{переходів} other{переходів}}", "@chat_hopsCount": { "placeholders": { "count": { @@ -560,6 +577,7 @@ } }, "chat_successes": "Успішно", + "chat_score": "Оцінка", "chat_removePath": "Видалити шлях", "chat_noPathHistoryYet": "Історія шляхів недоступна.\nНадішліть повідомлення, щоб виявити шляхи.", "chat_pathActions": "Дії зі шляхом:", @@ -568,11 +586,11 @@ "chat_clearPath": "Очистити шлях", "chat_clearPathSubtitle": "Примусово повторити пошук при наступному надсиланні", "chat_pathCleared": "Шлях очищено. Наступне повідомлення оновить маршрут.", - "chat_floodModeSubtitle": "Використовувати перемикач маршрутизації в панелі програми", - "chat_floodModeEnabled": "Увімкнено режим «на всю мережу». Перемикайте через іконку маршрутизації на панелі інструментів.", + "chat_floodModeSubtitle": "Використовувати перемикач маршрутизації в панелі застосунку", + "chat_floodModeEnabled": "Увімкнено режим «через всю мережу». Перемикайте через іконку маршрутизації на панелі інструментів.", "chat_fullPath": "Повний шлях", "chat_pathDetailsNotAvailable": "Деталі шляху ще недоступні. Спробуйте надіслати повідомлення для оновлення.", - "chat_pathSetHops": "Шлях встановлено: {hopCount} {hopCount, plural, =1{стрибок} few{стрибки} many{стрибків} other{стрибків}} - {status}", + "chat_pathSetHops": "Шлях встановлено: {hopCount} {hopCount, plural, =1{перехід} few{переходи} many{переходів} other{переходів}} - {status}", "@chat_pathSetHops": { "placeholders": { "hopCount": { @@ -590,9 +608,9 @@ "chat_path": "Шлях", "chat_publicKey": "Відкритий ключ", "chat_compressOutgoingMessages": "Стискати вихідні повідомлення", - "chat_floodForced": "На всю мережу (примусово)", - "chat_directForced": "Прямий (примусово)", - "chat_hopsForced": "{count} стрибків (примусово)", + "chat_floodForced": "Через всю мережу (примусово)", + "chat_directForced": "Напряму (примусово)", + "chat_hopsForced": "{count} переходів (примусово)", "@chat_hopsForced": { "placeholders": { "count": { @@ -600,9 +618,9 @@ } } }, - "chat_floodAuto": "На всю мережу (авто)", - "chat_direct": "Прямий", - "chat_poiShared": "Точкою інтересу поділилися", + "chat_floodAuto": "Через всю мережу (авто)", + "chat_direct": "Напряму", + "chat_poiShared": "Поділилися точкою інтересу", "chat_unread": "Непрочитано: {count}", "@chat_unread": { "placeholders": { @@ -614,7 +632,7 @@ "chat_openLink": "Відкрити посилання?", "chat_openLinkConfirmation": "Ви хочете відкрити це посилання у браузері?", "chat_open": "Відкрити", - "chat_couldNotOpenLink": "Не вдалося відкрити посилання: {url}", + "chat_couldNotOpenLink": "Не вдалось відкрити посилання: {url}", "@chat_couldNotOpenLink": { "placeholders": { "url": { @@ -624,8 +642,8 @@ }, "chat_invalidLink": "Невірний формат посилання", "map_title": "Карта вузлів", - "map_noNodesWithLocation": "Немає вузлів з даними про розташування", - "map_nodesNeedGps": "Вузли повинні надавати свої GPS координати,\nщоб з'явитися на карті.", + "map_noNodesWithLocation": "Немає вузлів з даними про геопозицію", + "map_nodesNeedGps": "Вузли мають надавати свої GPS координати,\nщоб з'явитись на карті.", "map_nodesCount": "Вузли: {count}", "@map_nodesCount": { "placeholders": { @@ -650,19 +668,25 @@ "map_pinPrivate": "Замок (Приватний)", "map_pinPublic": "Ключ (Публічний)", "map_lastSeen": "Останній раз бачили", - "map_disconnectConfirm": "Ви впевнені, що хочете відключитися від цього пристрою?", + "map_disconnectConfirm": "Ви впевнені, що хочете відключитись від цього пристрою?", "map_from": "Від", "map_source": "Джерело", "map_flags": "Прапорці", - "map_shareMarkerHere": "Поділитися маркером тут", + "map_type": "Тип", + "map_path": "Шлях", + "map_location": "Геопозиція", + "map_estLocation": "Орієнтовна геопозиція", + "map_publicKey": "Публічний ключ", + "map_publicKeyPrefixHint": "напр. ab12", + "map_shareMarkerHere": "Поділитись маркером тут", "map_pinLabel": "Мітка піна", "map_label": "Мітка", "map_pointOfInterest": "Точка інтересу", "map_sendToContact": "Надіслати контакту", "map_sendToChannel": "Надіслати в канал", "map_noChannelsAvailable": "Немає доступних каналів", - "map_publicLocationShare": "Поділитися в публічному місці", - "map_publicLocationShareConfirm": "Ви збираєтеся поділитися розташуванням у {channelLabel}. Цей канал публічний, і кожен, хто має ключ PSK, може це побачити.", + "map_publicLocationShare": "Поділитись в публічному місці", + "map_publicLocationShareConfirm": "Ви збираєтесь поділитись геопозицією у {channelLabel}. Цей канал публічний, і кожен, хто має ключ PSK, може це побачити.", "@map_publicLocationShareConfirm": { "placeholders": { "channelLabel": { @@ -670,7 +694,7 @@ } } }, - "map_connectToShareMarkers": "Підключіться до пристрою, щоб поділитися маркерами", + "map_connectToShareMarkers": "Підключіться до пристрою, щоб поділитись маркерами", "map_filterNodes": "Фільтрувати вузли", "map_nodeTypes": "Типи вузлів", "map_chatNodes": "Вузли чату", @@ -683,7 +707,7 @@ "map_showSharedMarkers": "Показувати спільні маркери", "map_lastSeenTime": "Час останньої активності", "map_sharedPin": "Спільний пін", - "map_joinRoom": "Приєднатися до кімнати", + "map_joinRoom": "Приєднатись до кімнати", "map_manageRepeater": "Керувати ретранслятором", "mapCache_title": "Офлайн-кеш карти", "mapCache_selectAreaFirst": "Спершу виберіть область для кешування", @@ -806,7 +830,7 @@ "time_minutes": "хвилин", "time_allTime": "Весь час", "dialog_disconnect": "Відключити", - "dialog_disconnectConfirm": "Ви впевнені, що хочете відключитися від цього пристрою?", + "dialog_disconnectConfirm": "Ви впевнені, що хочете відключитись від цього пристрою?", "login_repeaterLogin": "Вхід у ретранслятор", "login_roomLogin": "Вхід у кімнату", "login_password": "Пароль", @@ -817,8 +841,8 @@ "login_roomDescription": "Введіть пароль кімнати для доступу до налаштувань та статусу.", "login_routing": "Маршрутизація", "login_routingMode": "Режим маршрутизації", - "login_autoUseSavedPath": "Авто (використовувати збережений шлях)", - "login_forceFloodMode": "Примусово на всю мережу", + "login_autoUseSavedPath": "Авто (збережений шлях)", + "login_forceFloodMode": "Примусово через всю мережу", "login_managePaths": "Керувати шляхами", "login_login": "Вхід", "login_attempt": "Спроба {current}/{max}", @@ -851,7 +875,7 @@ } } }, - "path_usingHopsPath": "Використання шляху з {count} {count, plural, =1{стрибком} few{стрибками} many{стрибками} other{стрибками}}", + "path_usingHopsPath": "Використання шляху з {count} {count, plural, =1{переходом} few{переходами} many{переходами} other{переходами}}", "@path_usingHopsPath": { "placeholders": { "count": { @@ -861,10 +885,10 @@ }, "path_enterCustomPath": "Ввести власний шлях", "path_currentPathLabel": "Поточний шлях", - "path_hexPrefixInstructions": "Введіть 2-символьні hex-префікси для кожного стрибка, розділені комами.", + "path_hexPrefixInstructions": "Введіть 2-символьні hex-префікси для кожного переходу, розділені комами.", "path_hexPrefixExample": "Приклад: A1,F2,3C (кожен вузол використовує перший байт свого відкритого ключа).", "path_labelHexPrefixes": "Hex-префікси", - "path_helperMaxHops": "Макс. 64 стрибки. Кожен префікс - 2 шістнадцяткові символи (1 байт)", + "path_helperMaxHops": "Макс. 64 переходи. Кожен префікс — 2 шістнадцяткові символи (1 байт)", "path_selectFromContacts": "Вибрати з контактів:", "path_noRepeatersFound": "Ретрансляторів або серверів кімнат не знайдено.", "path_customPathsRequire": "Власні шляхи вимагають проміжних вузлів, які можуть передавати повідомлення.", @@ -876,7 +900,7 @@ } } }, - "path_tooLong": "Шлях занадто довгий. Максимум 64 стрибки.", + "path_tooLong": "Шлях занадто довгий. Максимум 64 переходи.", "path_setPath": "Встановити шлях", "repeater_management": "Керування ретранслятором", "repeater_managementTools": "Інструменти керування", @@ -884,14 +908,14 @@ "repeater_statusSubtitle": "Показати статус, статистику та сусідів ретранслятора", "repeater_telemetry": "Телеметрія", "repeater_telemetrySubtitle": "Показати телеметрію сенсорів та статистику системи", - "repeater_cli": "CLI", + "repeater_cli": "CLI (Command Line Interface)", "repeater_cliSubtitle": "Надіслати команди ретранслятору", "repeater_settings": "Налаштування", "repeater_settingsSubtitle": "Налаштувати параметри ретранслятора", "repeater_statusTitle": "Статус ретранслятора", "repeater_routingMode": "Режим маршрутизації", "repeater_autoUseSavedPath": "Авто (використовувати збережений шлях)", - "repeater_forceFloodMode": "Примусово на всю мережу", + "repeater_forceFloodMode": "Примусово через всю мережу", "repeater_pathManagement": "Керування шляхами", "repeater_refresh": "Оновити", "repeater_statusRequestTimeout": "Час очікування запиту статусу вичерпано.", @@ -936,7 +960,7 @@ } } }, - "repeater_packetTxTotal": "Всього: {total}, На всю мережу: {flood}, Прямі: {direct}", + "repeater_packetTxTotal": "Всього: {total}, Через всю мережу: {flood}, Прямі: {direct}", "@repeater_packetTxTotal": { "placeholders": { "total": { @@ -950,7 +974,7 @@ } } }, - "repeater_packetRxTotal": "Всього: {total}, На всю мережу: {flood}, Прямі: {direct}", + "repeater_packetRxTotal": "Всього: {total}, Через всю мережу: {flood}, Прямі: {direct}", "@repeater_packetRxTotal": { "placeholders": { "total": { @@ -964,7 +988,7 @@ } } }, - "repeater_duplicatesFloodDirect": "На всю мережу: {flood}, Прямі: {direct}", + "repeater_duplicatesFloodDirect": "Через всю мережу: {flood}, Прямі: {direct}", "@repeater_duplicatesFloodDirect": { "placeholders": { "flood": { @@ -999,7 +1023,7 @@ "repeater_bandwidth": "Смуга пропускання", "repeater_spreadingFactor": "Коефіцієнт розширення", "repeater_codingRate": "Швидкість кодування", - "repeater_locationSettings": "Налаштування розташування", + "repeater_locationSettings": "Налаштування геопозиції", "repeater_latitude": "Широта", "repeater_latitudeHelper": "Десяткові градуси (наприклад, 37.7749)", "repeater_longitude": "Довгота", @@ -1010,9 +1034,9 @@ "repeater_guestAccess": "Гостьовий доступ", "repeater_guestAccessSubtitle": "Дозволити гостьовий доступ лише для читання", "repeater_privacyMode": "Режим приватності", - "repeater_privacyModeSubtitle": "Приховати ім'я/розташування в оголошеннях", + "repeater_privacyModeSubtitle": "Приховати ім'я/геопозицію в оголошеннях", "repeater_advertisementSettings": "Налаштування оголошень", - "repeater_localAdvertInterval": "Інтервал локальних оголошень (0 стрибків)", + "repeater_localAdvertInterval": "Інтервал локальних оголошень (без ретрансляції)", "repeater_localAdvertIntervalMinutes": "{minutes} хвилин", "@repeater_localAdvertIntervalMinutes": { "placeholders": { @@ -1021,7 +1045,7 @@ } } }, - "repeater_floodAdvertInterval": "Інтервал оголошень на всю мережу (flood)", + "repeater_floodAdvertInterval": "Інтервал оголошень через всю мережу (flood)", "repeater_floodAdvertIntervalHours": "{hours} годин", "@repeater_floodAdvertIntervalHours": { "placeholders": { @@ -1035,9 +1059,9 @@ "repeater_rebootRepeater": "Перезавантажити ретранслятор", "repeater_rebootRepeaterSubtitle": "Скинути пристрій ретранслятора", "repeater_rebootRepeaterConfirm": "Ви впевнені, що хочете перезавантажити цей ретранслятор?", - "repeater_regenerateIdentityKey": "Перегенерувати ключ ідентичності", + "repeater_regenerateIdentityKey": "Перегенерувати ключ ідентифікації", "repeater_regenerateIdentityKeySubtitle": "Згенерувати нову пару ключів (публічний/приватний)", - "repeater_regenerateIdentityKeyConfirm": "Це створить нову ідентичність для ретранслятора. Продовжити?", + "repeater_regenerateIdentityKeyConfirm": "Це створить нову ідентифікацію для ретранслятора. Продовжити?", "repeater_eraseFileSystem": "Очистити файлову систему", "repeater_eraseFileSystemSubtitle": "Відформатувати файлову систему ретранслятора", "repeater_eraseFileSystemConfirm": "УВАГА: Це видалить всі дані з ретранслятора. Це не можна скасувати!", @@ -1060,6 +1084,81 @@ }, "repeater_confirm": "Підтвердити", "repeater_settingsSaved": "Налаштування успішно збережено.", + "repeater_rxGain": "Підвищена ефективність RX", + "repeater_rxGainHelper": "Вища чутливість, більший струм споживання (тільки для SX1262/SX1268)", + "repeater_refreshRxGain": "Оновіть підвищений прибуток від RX", + "repeater_multiAcks": "Багато підтверджень", + "repeater_multiAcksSubtitle": "Розпізнавайте повідомлення через різні канали для кращої доставки.", + "repeater_refreshMultiAcks": "Оновити кілька підтверджень", + "repeater_networkHealth": "Стан мережі", + "repeater_loopDetect": "Виявлення циклів", + "repeater_loopDetectHelper": "Створіть пакети, які імітують цикли маршрутизації.", + "repeater_loopDetectOff": "Відключення", + "repeater_loopDetectMinimal": "Мінімальний", + "repeater_loopDetectModerate": "Помірний", + "repeater_loopDetectStrict": "Суворий", + "repeater_dutyCycle": "Цикл роботи", + "repeater_dutyCycleHelper": "Максимальний відсоток часу, який може бути виділено для трансляції.", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "Інформація про оператора", + "repeater_ownerInfoHelper": "Публічні метадані для цього ретранслятора", + "repeater_refreshOwnerInfo": "Оновити інформацію про оператора", + "repeater_floodMax": "Максимальна кількість стрибків під час повені", + "repeater_floodMaxHelper": "Максимальна кількість хмелю, яку може містити один пакет (0-64)", + "repeater_advancedSettings": "Просунутий", + "repeater_advancedSettingsSubtitle": "Регулювальні ручки для досвідчених операторів", + "repeater_pathHashMode": "Режим хешування шляху", + "repeater_pathHashModeHelper": "Байти, що використовуються для кодування ідентифікатора цього ретранслятора в тегах для виявлення потоків/петлі. 0=1 байт (256 ідентифікаторів, до 64 перехідів), 1=2 байти (65 000 ідентифікаторів, до 32 перехідів), 2=3 байти (16 мільйонів ідентифікаторів, до 21 переходу). Версії 1.13 та старіші не підтримують багатобайтні шляхи — вони активуються лише після того, як мережа буде оновлена до версії 1.14+.", + "repeater_txDelay": "Затримка у Flood, штат Техас", + "repeater_txDelayHelper": "Повторне надсилання з урахуванням навантаження від потоків транспорту, як множник від часу передачі пакета (0-2, за замовчуванням 0,5). Чим вище значення, тим менше конфліктів, але повільніше передавання.", + "repeater_directTxDelay": "Пряме затримка TX", + "repeater_directTxDelayHelper": "Відновлення інтервалів для прямого (немасового) трафіку, як множник часу передачі пакета (від 0 до 2, за замовчуванням 0,3).", + "repeater_intThresh": "Порогове значення перешкод", + "repeater_intThreshHelper": "Порогове значення встановлено для калібрування шумового рівня радіо, щоб відхиляти сигнали, що перевищують цей рівень. 0 – вимкнено; активуйте лише у разі виявлення помилок RX у шумному діапазоні.", + "repeater_agcResetInterval": "Інтервал перезавантаження AGC", + "repeater_agcResetIntervalHelper": "Як часто потрібно скидати автоматичне регулювання гучності радіо, щоб відновити нормальну роботу після ситуації, коли гучність була заблокована. Кожні кілька секунд, зменшуючи значення до кратного 4. Вимкнення періодичного скидання.", + "repeater_actionsTitle": "Дії", + "repeater_sendAdvert": "Надіслати рекламу щодо повені", + "repeater_sendAdvertSubtitle": "Розповсюдити рекламу про надзвичайну ситуацію (повен) через мережу.", + "repeater_sendAdvertZeroHop": "Надіслати рекламу без посередників", + "repeater_sendAdvertZeroHopSubtitle": "Розповсюдити рекламу з однією переадресацією (без повторного розповсюдження)", + "repeater_clockSync": "Синхронізувати годинник зараз", + "repeater_clockSyncSubtitle": "Передайте час вашого телефону на ретранслятор.", + "repeater_actionSucceeded": "{action} succeeded", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} failed: {error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "Налаштування збережено — перезавантажте ретранслятор для застосування.", + "repeater_settingsPartialFailure": "Деякі налаштування не вдалося застосувати: {failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "Помилка збереження налаштувань: {error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1071,11 +1170,10 @@ "repeater_refreshBasicSettings": "Оновити основні налаштування", "repeater_refreshRadioSettings": "Оновити налаштування радіо", "repeater_refreshTxPower": "Оновити потужність TX", - "repeater_refreshLocationSettings": "Оновити налаштування розташування", + "repeater_refreshLocationSettings": "Оновити налаштування геопозиції", "repeater_refreshPacketForwarding": "Оновити пересилання пакетів", "repeater_refreshGuestAccess": "Оновити гостьовий доступ", "repeater_refreshPrivacyMode": "Оновити режим приватності", - "repeater_refreshAdvertisementSettings": "Оновити налаштування оголошень", "repeater_refreshed": "{label} оновлено", "@repeater_refreshed": { "placeholders": { @@ -1128,19 +1226,19 @@ "repeater_cliHelpSetTx": "Встановлює потужність передачі LoRa в дБм (для застосування потрібне перезавантаження).", "repeater_cliHelpSetRepeat": "Вмикає або вимикає роль ретранслятора для цього вузла.", "repeater_cliHelpSetAllowReadOnly": "(Сервер кімнати) Якщо «увімкнено», порожній пароль дозволить вхід, але не дозволить публікувати в кімнаті. (тільки читання)", - "repeater_cliHelpSetFloodMax": "Встановлює максимальну кількість стрибків для вхідних пакетів flood (якщо >= max, пакет не пересилається).", + "repeater_cliHelpSetFloodMax": "Встановлює максимальну кількість переходів для вхідних пакетів flood (якщо >= max, пакет не пересилається).", "repeater_cliHelpSetIntThresh": "Встановлює поріг інтерференції (в дБ). Значення за замовчуванням — 14. Встановлення на 0 вимикає виявлення інтерференції каналу.", "repeater_cliHelpSetAgcResetInterval": "Встановлює інтервал скидання автоматичного контролера посилення (AGC). Встановіть 0 для вимкнення.", "repeater_cliHelpSetMultiAcks": "Вмикає або вимикає функціональність подвійних ACK.", "repeater_cliHelpSetAdvertInterval": "Встановлює інтервал таймера для надсилання локального пакету оголошення (без ретрансляції). Встановіть 0 для вимкнення.", - "repeater_cliHelpSetFloodAdvertInterval": "Встановлює інтервал таймера в годинах для надсилання пакету оголошення на всю мережу. Встановіть 0 для вимкнення.", + "repeater_cliHelpSetFloodAdvertInterval": "Встановлює інтервал таймера в годинах для надсилання пакету оголошення через всю мережу. Встановіть 0 для вимкнення.", "repeater_cliHelpSetGuestPassword": "Встановлює/оновлює гостьовий пароль. (для ретрансляторів гостьові підключення можуть надсилати запит «Get Stats»)", "repeater_cliHelpSetName": "Встановлює ім'я для оголошення.", "repeater_cliHelpSetLat": "Встановлює широту для карти оголошень. (десяткові градуси)", "repeater_cliHelpSetLon": "Встановлює довготу для карти оголошень. (десяткові градуси)", "repeater_cliHelpSetRadio": "Повністю встановлює нові параметри радіо та зберігає їх у налаштуваннях. Потребує команди «перезавантаження» для застосування.", "repeater_cliHelpSetRxDelay": "Базові (експериментальні) параметри для застосування невеликої затримки до отриманих пакетів залежно від сили сигналу/оцінки. Встановіть 0 для вимкнення.", - "repeater_cliHelpSetTxDelay": "Встановлює множник для часу роботи в режимі «на всю мережу» (flood) для пакету та системи випадкових слотів, щоб затримати його відправку (для зменшення ймовірності колізій).", + "repeater_cliHelpSetTxDelay": "Встановлює множник для часу роботи в режимі «через всю мережу» (flood) для пакету та системи випадкових слотів, щоб затримати його відправку (для зменшення ймовірності колізій).", "repeater_cliHelpSetDirectTxDelay": "Те саме, що й txdelay, але для застосування випадкової затримки при пересиланні пакетів у прямому режимі.", "repeater_cliHelpSetBridgeEnabled": "Увімкнути/Вимкнути міст.", "repeater_cliHelpSetBridgeDelay": "Встановити затримку перед пересиланням пакетів.", @@ -1156,7 +1254,7 @@ "repeater_cliHelpLogErase": "Видаляє журнали пакетів з файлової системи.", "repeater_cliHelpNeighbors": "Показує список інших вузлів-ретрансляторів, почутих через оголошення без ретрансляції. Кожен рядок — id-hex-префікс:timestamp:snr-помножено-на-4", "repeater_cliHelpNeighborRemove": "Видаляє перший відповідний запис (за префіксом публічного ключа (hex)) зі списку сусідів.", - "repeater_cliHelpRegion": "(тільки серійний) Перелічує всі визначені регіони та поточні дозволи на оголошення «на всю мережу» (flood).", + "repeater_cliHelpRegion": "(тільки серійний) Перелічує всі визначені регіони та поточні дозволи на оголошення «через всю мережу» (flood).", "repeater_cliHelpRegionLoad": "ПРИМІТКА: це спеціальний виклик кількох команд. Кожна наступна команда — це назва регіону (з відступом пробілами для позначення ієрархії батьків, мінімум один пробіл). Завершується надсиланням порожнього рядка/команди.", "repeater_cliHelpRegionGet": "Шукає регіон із заданим префіксом назви (або «» для глобальної області). Відповідає: «-> ім'я-регіону (ім'я-батька) 'F'»", "repeater_cliHelpRegionPut": "Додає або оновлює визначення регіону з заданою назвою.", @@ -1170,14 +1268,14 @@ "repeater_cliHelpGpsOnOff": "Увімкнути/вимкнути GPS.", "repeater_cliHelpGpsSync": "Синхронізує час вузла з годинником GPS.", "repeater_cliHelpGpsSetLoc": "Встановлює позицію вузла за координатами GPS і зберігає в налаштуваннях.", - "repeater_cliHelpGpsAdvert": "Надає конфігурацію оголошення розташування вузла:\n- none : не включати розташування в оголошення\n- share : ділитися розташуванням GPS (з SensorManager)\n- prefs : оголошувати розташування, збережене в налаштуваннях", - "repeater_cliHelpGpsAdvertSet": "Встановлює конфігурацію оголошення розташування.", + "repeater_cliHelpGpsAdvert": "Надає конфігурацію оголошення геопозиції вузла:\n- none : не включати геопозицію в оголошення\n- share : ділитись геопозицією GPS (з SensorManager)\n- prefs : оголошувати геопозицію, збережену в налаштуваннях", + "repeater_cliHelpGpsAdvertSet": "Встановлює конфігурацію оголошення геопозиції.", "repeater_commandsListTitle": "Список команд", "repeater_commandsListNote": "ПРИМІТКА: для різних команд «set»... також існує команда «get»...", "repeater_general": "Загальні", "repeater_settingsCategory": "Налаштування", "repeater_bridge": "Міст", - "repeater_logging": "Логування", + "repeater_logging": "Журналювання", "repeater_neighborsRepeaterOnly": "Сусіди (Тільки ретранслятор)", "repeater_regionManagementRepeaterOnly": "Керування регіонами (Тільки ретранслятор)", "repeater_regionNote": "Команди регіонів були введені для керування визначеннями та дозволами регіонів.", @@ -1248,7 +1346,7 @@ "channelPath_title": "Шлях пакету", "channelPath_viewMap": "Показати карту", "channelPath_otherObservedPaths": "Інші спостережувані шляхи", - "channelPath_repeaterHops": "Стрибки ретранслятора", + "channelPath_repeaterHops": "Переходи через ретранслятори", "channelPath_noHopDetails": "Деталі відправки не надані для цього пакету.", "channelPath_messageDetails": "Деталі повідомлення", "channelPath_senderLabel": "Відправник", @@ -1267,7 +1365,7 @@ } } }, - "channelPath_noLocationData": "Немає даних про розташування", + "channelPath_noLocationData": "Немає даних про геопозицію", "channelPath_timeWithDate": "{day}/{month} {time}", "@channelPath_timeWithDate": { "placeholders": { @@ -1291,9 +1389,9 @@ } }, "channelPath_unknownPath": "Невідомий", - "channelPath_floodPath": "На всю мережу", - "channelPath_directPath": "Прямий", - "channelPath_observedZeroOf": "0 з {total} стрибків", + "channelPath_floodPath": "Через всю мережу", + "channelPath_directPath": "Напряму", + "channelPath_observedZeroOf": "0 з {total} переходів", "@channelPath_observedZeroOf": { "placeholders": { "total": { @@ -1301,7 +1399,7 @@ } } }, - "channelPath_observedSomeOf": "{observed} з {total} стрибків", + "channelPath_observedSomeOf": "{observed} з {total} переходів", "@channelPath_observedSomeOf": { "placeholders": { "observed": { @@ -1342,12 +1440,12 @@ } } }, - "channelPath_noHopDetailsAvailable": "Деталі стрибків недоступні для цього пакету.", + "channelPath_noHopDetailsAvailable": "Деталі переходів недоступні для цього пакету.", "channelPath_unknownRepeater": "Невідомий ретранслятор", "listFilter_tooltip": "Фільтр та сортування", "listFilter_sortBy": "Сортувати за", "listFilter_latestMessages": "Останні повідомлення", - "listFilter_heardRecently": "Нещодавно чули", + "listFilter_heardRecently": "Нещодавно почуті", "listFilter_az": "А-Я", "listFilter_filters": "Фільтри", "listFilter_all": "Все", @@ -1364,20 +1462,20 @@ } }, "repeater_neighbors": "Сусіди", - "repeater_neighborsSubtitle": "Показати сусідів нульового стрибка.", + "repeater_neighborsSubtitle": "Показати сусідів, доступних без ретрансляції.", "neighbors_receivedData": "Дані сусідів отримано", "neighbors_requestTimedOut": "Час запиту сусідів вичерпано.", "neighbors_errorLoading": "Помилка завантаження сусідів: {error}", "neighbors_repeatersNeighbors": "Ретранслятори-сусіди", "neighbors_noData": "Дані про сусідів недоступні.", "channels_createPrivateChannelDesc": "Захищено секретним ключем.", - "channels_joinPrivateChannel": "Приєднатися до приватного каналу", + "channels_joinPrivateChannel": "Приєднатись до приватного каналу", "channels_createPrivateChannel": "Створити приватний канал", "channels_joinPrivateChannelDesc": "Ввести секретний ключ вручну.", - "channels_joinPublicChannel": "Приєднатися до публічного каналу", - "channels_joinPublicChannelDesc": "Будь-хто може приєднатися до цього каналу.", - "channels_joinHashtagChannel": "Приєднатися до каналу з хештегом", - "channels_joinHashtagChannelDesc": "Будь-хто може приєднатися до каналів #hashtag.", + "channels_joinPublicChannel": "Приєднатись до публічного каналу", + "channels_joinPublicChannelDesc": "Будь-хто може приєднатись до цього каналу.", + "channels_joinHashtagChannel": "Приєднатись до хештег-каналу", + "channels_joinHashtagChannelDesc": "Будь-хто може приєднатись до хештег-каналів.", "channels_scanQrCode": "Сканувати QR-код", "channels_scanQrCodeComingSoon": "Скоро буде", "channels_enterHashtag": "Введіть хештег", @@ -1399,7 +1497,7 @@ "neighbors_unknownContact": "Невідомий відкритий ключ {pubkey}", "neighbors_heardAgo": "Почуто: {time} тому", "settings_locationGPSEnable": "Увімкнути GPS", - "settings_locationGPSEnableSubtitle": "Вмикає автоматичне оновлення місцезнаходження через GPS.", + "settings_locationGPSEnableSubtitle": "Вмикає автоматичне оновлення геопозиції через GPS.", "settings_locationIntervalSec": "Інтервал для GPS (Секунди)", "settings_locationIntervalInvalid": "Інтервал має бути не менше 60 секунд і менше 86400 секунд.", "contacts_manageRoom": "Керувати сервером кімнати", @@ -1463,10 +1561,10 @@ "common_ok": "ОК", "community_title": "Спільнота", "community_create": "Створити спільноту", - "community_createDesc": "Створити нову спільноту та поділитися через QR-код.", - "community_join": "Приєднатися", - "community_joinTitle": "Приєднатися до спільноти", - "community_joinConfirmation": "Ви бажаєте приєднатися до спільноти «{name}»?", + "community_createDesc": "Створити нову спільноту та поділитись через QR-код.", + "community_join": "Приєднатись", + "community_joinTitle": "Приєднатись до спільноти", + "community_joinConfirmation": "Ви бажаєте приєднатись до спільноти «{name}»?", "community_scanQr": "Сканувати QR спільноти", "community_scanInstructions": "Наведіть камеру на QR-код спільноти.", "community_showQr": "Показати QR-код", @@ -1476,9 +1574,9 @@ "community_enterName": "Введіть назву спільноти", "community_created": "Спільноту «{name}» створено", "community_joined": "Приєднався до спільноти «{name}»", - "community_qrTitle": "Поділитися спільнотою", - "community_qrInstructions": "Відскануйте цей QR-код, щоб приєднатися до {name}", - "community_hashtagPrivacyHint": "Канали хештегів спільноти доступні лише членам спільноти", + "community_qrTitle": "Поділитись спільнотою", + "community_qrInstructions": "Відскануйте цей QR-код, щоб приєднатись до {name}", + "community_hashtagPrivacyHint": "Хештег-канали спільноти доступні лише членам спільноти", "community_invalidQrCode": "Недійсний QR-код спільноти", "community_alreadyMember": "Вже учасник", "community_alreadyMemberMessage": "Ви вже є учасником «{name}».", @@ -1499,10 +1597,10 @@ }, "community_deleted": "Спільноту «{name}» покинуто", "community_addHashtagChannel": "Додати хештег спільноти", - "community_addHashtagChannelDesc": "Додати канал хештегу для цієї спільноти", + "community_addHashtagChannelDesc": "Додати хештег-канал для цієї спільноти", "community_selectCommunity": "Вибрати спільноту", "community_regularHashtag": "Звичайний хештег", - "community_regularHashtagDesc": "Публічний хештег (будь-хто може приєднатися)", + "community_regularHashtagDesc": "Публічний хештег (будь-хто може приєднатись)", "community_communityHashtag": "Хештег спільноти", "community_communityHashtagDesc": "Ексклюзивно для членів спільноти", "community_forCommunity": "Для {name}", @@ -1534,13 +1632,13 @@ } } }, - "community_regenerateSecret": "Перегенерувати секрет", - "community_regenerateSecretConfirm": "Перегенерувати секретний ключ для «{name}»? Всі учасники повинні будуть відсканувати новий QR-код, щоб продовжити спілкування.", + "community_regenerateSecret": "Перегенерувати секретний ключ", + "community_regenerateSecretConfirm": "Перегенерувати секретний ключ для «{name}»? Усі учасники матимуть відсканувати новий QR-код, щоб продовжити спілкування.", "community_regenerate": "Перегенерувати", - "community_secretRegenerated": "Секретний пароль для «{name}» перегенеровано", - "community_scanToUpdateSecret": "Відскануйте новий QR-код, щоб оновити пароль для «{name}»", - "community_updateSecret": "Оновити секрет", - "community_secretUpdated": "Зміну секрету для «{name}» оновлено", + "community_secretRegenerated": "Секретний ключ для «{name}» перегенеровано", + "community_scanToUpdateSecret": "Відскануйте новий QR-код, щоб оновити секретний ключ для «{name}»", + "community_updateSecret": "Оновити секретний ключ", + "community_secretUpdated": "Секретний ключ для «{name}» оновлено", "@contacts_pathTraceTo": { "placeholders": { "name": { @@ -1549,76 +1647,76 @@ } }, "pathTrace_you": "Ви", - "pathTrace_failed": "Відстеження шляху не вдалося.", + "pathTrace_failed": "Відстеження шляху не вдалось.", "pathTrace_notAvailable": "Трасування шляху недоступне.", - "pathTrace_refreshTooltip": "Оновити Path Trace", + "pathTrace_refreshTooltip": "Оновити трасування шляху", "contacts_pathTrace": "Трасування шляхів", "contacts_ping": "Пінгувати", - "contacts_repeaterPathTrace": "Трасування шляху до повторювача", - "contacts_repeaterPing": "Пінгувати повторювач", + "contacts_repeaterPathTrace": "Трасування шляху до ретранслятора", + "contacts_repeaterPing": "Пінгувати ретранслятор", "contacts_roomPathTrace": "Трасування шляху до серверу кімнати", "contacts_roomPing": "Пінг сервера кімнати", "contacts_chatTraceRoute": "Трасування шляху", "contacts_pathTraceTo": "Відстежити маршрут до {name}", "contacts_invalidAdvertFormat": "Недійсні контактні дані", "contacts_contactImported": "Контакт було імпортовано.", - "contacts_contactImportFailed": "Контакт не вдалося імпортувати", - "contacts_zeroHopAdvert": "Реклама без перехоплення", - "contacts_floodAdvert": "Залив реклами", - "contacts_copyAdvertToClipboard": "Копіювати оголошення в буфер обміну", + "contacts_contactImportFailed": "Контакт не вдалось імпортувати", + "contacts_zeroHopAdvert": "Оголошення без ретрансляції", + "contacts_floodAdvert": "Оголошення з ретрансляцією", + "contacts_copyAdvertToClipboard": "Копіювати оголошення", "contacts_clipboardEmpty": "Буфер обміну порожній", "appSettings_languageRu": "Російська", "appSettings_enableMessageTracing": "Увімкнути відстеження повідомлень", "appSettings_enableMessageTracingSubtitle": "Показувати детальні метадані про маршрутизацію та час для повідомлень", "contacts_ShareContact": "Копіювати контакт у буфер обміну", - "contacts_zeroHopContactAdvertFailed": "Не вдалося надіслати контакт.", - "contacts_contactAdvertCopied": "Рекламу скопійовано до буфера обміну.", - "contacts_contactAdvertCopyFailed": "Копіювання оголошення в буфер обміну завершилося невдало", + "contacts_zeroHopContactAdvertFailed": "Не вдалось надіслати контакт.", + "contacts_contactAdvertCopied": "Оголошення скопійовано до буфера обміну.", + "contacts_contactAdvertCopyFailed": "Копіювання оголошення в буфер обміну завершилось невдало", "contacts_zeroHopContactAdvertSent": "Відправлено контакт за оголошенням", - "contacts_addContactFromClipboard": "Додати контакт з буфера обміну", - "contacts_ShareContactZeroHop": "Поділитися контактом за оголошенням", + "contacts_addContactFromClipboard": "Додати контакт з буфера", + "contacts_ShareContactZeroHop": "Поділитись контактом за оголошенням", "notification_activityTitle": "Активність MeshCore", "notification_messagesCount": "{count} {count, plural, =1{повідомлення} few{повідомлення} many{повідомлень} other{повідомлень}}", "notification_channelMessagesCount": "{count} {count, plural, =1{повідомлення каналу} few{повідомлення каналу} many{повідомлень каналу} other{повідомлень каналу}}", - "notification_newNodesCount": "{count} {count, plural, =1{новий вузол} few{нових вузли} many{нових вузлів} other{нових вузлів}}", + "notification_newNodesCount": "{count} {count, plural, =1{новий вузол} few{нові вузли} many{нових вузлів} other{нових вузлів}}", "notification_newTypeDiscovered": "Виявлено новий {contactType}", "notification_receivedNewMessage": "Отримано нове повідомлення", - "settings_gpxExportRepeaters": "Експортувати ретранслятори / сервер кімнати до GPX", - "settings_gpxExportRepeatersSubtitle": "Експортує ретранслятори / сервер кімнати з місцезнаходженням у файл GPX.", + "settings_gpxExportRepeaters": "Експорт ретрансляторів і серверів кімнат у GPX", + "settings_gpxExportRepeatersSubtitle": "Експортує ретранслятори та сервери кімнат з геопозицією у файл GPX.", "settings_gpxExportSuccess": "Успішно експортовано файл GPX.", "settings_gpxExportNoContacts": "Немає контактів для експорту.", "settings_gpxExportNotAvailable": "Не підтримується на вашому пристрої/операційній системі", - "settings_gpxExportError": "Сталася помилка під час експорту.", - "settings_gpxExportAllSubtitle": "Експортує всі контакти з місцем розташування у файл GPX.", - "settings_gpxExportAll": "Експортувати всі контакти до GPX", - "settings_gpxExportContactsSubtitle": "Експортує супутників з місцезнаходженням у файл GPX.", - "settings_gpxExportContacts": "Експортувати супутників до GPX", - "settings_gpxExportRepeatersRoom": "Місцезнаходження повторювача та сервера кімнати", - "settings_gpxExportChat": "Місця супутників", + "settings_gpxExportError": "Сталась помилка під час експорту.", + "settings_gpxExportAllSubtitle": "Експортує всі контакти з геопозицією у файл GPX.", + "settings_gpxExportAll": "Експорт усіх контактів у GPX", + "settings_gpxExportContactsSubtitle": "Експортує контакти з геопозицією у файл GPX.", + "settings_gpxExportContacts": "Експорт контактів у GPX", + "settings_gpxExportRepeatersRoom": "Геопозиції ретрансляторів та серверів кімнат", + "settings_gpxExportChat": "Геопозиції контактів", "settings_gpxExportShareText": "Дані карти експортовані з meshcore-open", "settings_gpxExportAllContacts": "Усі місця контактів", "settings_gpxExportShareSubject": "експорт даних карти meshcore-open у форматі GPX", - "pathTrace_someHopsNoLocation": "Одне або більше хмелів відсутнє місце розташування!", + "pathTrace_someHopsNoLocation": "Один або декілька переходів не мають даних про геопозицію!", "map_tapToAdd": "Натисніть на вузли, щоб додати їх до шляху", "map_runTrace": "Виконати трасування шляху", "pathTrace_clearTooltip": "Очистити шлях", "map_removeLast": "Видалити останній", - "map_pathTraceCancelled": "Відмінується трасування шляху", + "map_pathTraceCancelled": "Трасування шляху скасовано.", "scanner_enableBluetooth": "Увімкніть Bluetooth", "scanner_bluetoothOffMessage": "Будь ласка, увімкніть Bluetooth, щоб сканувати пристрої.", "scanner_chromeRequired": "Потрібен браузер Chrome", - "scanner_chromeRequiredMessage": "Для підтримки Bluetooth у цьому веб-додатку потрібен Google Chrome або браузер на базі Chromium.", + "scanner_chromeRequiredMessage": "Для підтримки Bluetooth у цьому вебзастосунку потрібен Google Chrome або браузер на базі Chromium.", "scanner_bluetoothOff": "Bluetooth вимкнено", "snrIndicator_lastSeen": "Останній раз бачили", - "snrIndicator_nearByRepeaters": "Ближні ретранслятори", + "snrIndicator_nearByRepeaters": "Найближчі ретранслятори", "chat_ShowAllPaths": "Показати всі шляхи", "settings_clientRepeatFreqWarning": "Повтор без підключення до мережі вимагає частоти 433, 869 або 918 МГц.", "settings_clientRepeatSubtitle": "Дозвольте цьому пристрою повторювати пакети даних для інших пристроїв.", "settings_clientRepeat": "Автономна система", "settings_aboutOpenMeteoAttribution": "Дані про висоту LOS: Open-Meteo (CC BY 4.0)", - "appSettings_unitsTitle": "одиниці", - "appSettings_unitsMetric": "Метричний (м / км)", - "appSettings_unitsImperial": "Імперська (ft / mi)", + "appSettings_unitsTitle": "Одиниці", + "appSettings_unitsMetric": "Метричні (м / км)", + "appSettings_unitsImperial": "Імперські (ft / mi)", "map_lineOfSight": "Пряма видимість", "map_losScreenTitle": "Пряма видимість", "losSelectStartEnd": "Виберіть початковий і кінцевий вузли для LOS.", @@ -1636,7 +1734,7 @@ "losMenuSubtitle": "Торкніться вузлів або утримуйте карту, щоб отримати власні точки", "losShowDisplayNodes": "Показати вузли відображення", "losCustomPoints": "Користувальницькі точки", - "losCustomPointLabel": "Спеціальний {index}", + "losCustomPointLabel": "Власна точка {index}", "@losCustomPointLabel": { "placeholders": { "index": { @@ -1725,7 +1823,7 @@ }, "losErrorElevationUnavailable": "Дані про висоту недоступні для одного чи кількох зразків.", "losErrorInvalidInput": "Недійсні дані про точки/висоту для розрахунку LOS.", - "losRenameCustomPoint": "Перейменуйте спеціальну точку", + "losRenameCustomPoint": "Перейменувати власну точку", "losPointName": "Назва точки", "losShowPanelTooltip": "Показати панель LOS", "losHidePanelTooltip": "Приховати панель LOS", @@ -1805,19 +1903,19 @@ "contacts_unread": "Непрочитане", "settings_contactSettingsSubtitle": "Налаштування для додавання контактів", "settings_contactSettings": "Налаштування контактів", - "contactsSettings_autoAddUsersSubtitle": "Дозволити супутникові автоматично додавати виявлених користувачів", - "contactsSettings_autoAddRepeatersTitle": "Автоматично додавати повторювачі", - "contactsSettings_autoAddRepeatersSubtitle": "Дозволити супутнику автоматично додавати виявлені ретранслятори", + "contactsSettings_autoAddUsersSubtitle": "Дозволити пристрою-компаньйону автоматично додавати виявлених користувачів", + "contactsSettings_autoAddRepeatersTitle": "Автоматично додавати ретранслятори", + "contactsSettings_autoAddRepeatersSubtitle": "Дозволити пристрою-компаньйону автоматично додавати виявлені ретранслятори", "contactsSettings_autoAddRoomServersTitle": "Автоматично додавати сервери кімнат", "contactsSettings_otherTitle": "Інші налаштування, пов'язані з контактами", "contactsSettings_autoAddTitle": "Автоматичне виявлення", "contactsSettings_autoAddUsersTitle": "Автоматично додавати користувачів", "contactsSettings_title": "Налаштування контактів", - "contactsSettings_autoAddRoomServersSubtitle": "Дозволити супровіднику автоматично додавати виявлені сервери кімнат.", - "contactsSettings_autoAddSensorsTitle": "Автоматично додавати датчики", + "contactsSettings_autoAddRoomServersSubtitle": "Дозволити пристрою-компаньйону автоматично додавати виявлені сервери кімнат.", + "contactsSettings_autoAddSensorsTitle": "Автоматично додавати сенсори", "discoveredContacts_searchHint": "Знайти виявлені контакти", "discoveredContacts_contactAdded": "Контакт додано", - "contactsSettings_autoAddSensorsSubtitle": "Дозволити супровіднику автоматично додавати виявлені сенсори", + "contactsSettings_autoAddSensorsSubtitle": "Дозволити пристрою-компаньйону автоматично додавати виявлені сенсори", "contactsSettings_overwriteOldestTitle": "Перезаписати найстаріше", "discoveredContacts_Title": "Виявлені контакти", "discoveredContacts_noMatching": "Відповідних контактів не знайдено", @@ -1828,9 +1926,9 @@ "common_deleteAll": "Видалити все", "discoveredContacts_deleteContactAll": "Видалити всі виявлені контакти", "discoveredContacts_deleteContactAllContent": "Ви впевнені, що хочете видалити всі виявлені контакти?", - "map_showGuessedLocations": "Показати місцезнаходження передбачених вузлів", - "map_guessedLocation": "Визначено місцезнаходження", - "usbScreenSubtitle": "Виберіть виявлене серійне пристрій і підключіть його безпосередньо до вашого вузла MeshCore.", + "map_showGuessedLocations": "Показати геопозиції передбачених вузлів", + "map_guessedLocation": "Передбачена геопозиція", + "usbScreenSubtitle": "Виберіть виявлений USB-пристрій і підключіть його безпосередньо до вашого вузла MeshCore.", "usbScreenTitle": "Підключити через USB", "connectionChoiceBluetoothLabel": "Bluetooth", "connectionChoiceUsbLabel": "USB", @@ -1842,8 +1940,8 @@ "usbErrorInvalidPort": "Виберіть дійсний USB-пристрій.", "usbErrorBusy": "Ще один запит на підключення через USB вже обробляється.", "usbErrorNotConnected": "Немає підключених пристроїв USB.", - "usbErrorOpenFailed": "Не вдалося відкрити вибране USB-пристрій.", - "usbErrorConnectFailed": "Не вдалося підключитися до вибраного USB-пристрою.", + "usbErrorOpenFailed": "Не вдалось відкрити вибране USB-пристрій.", + "usbErrorConnectFailed": "Не вдалось підключитись до вибраного USB-пристрою.", "usbErrorUnsupported": "Підтримка USB-серіального інтерфейсу не реалізована на цій платформі.", "usbErrorAlreadyActive": "USB-з'єднання вже встановлено.", "usbErrorNoDeviceSelected": "Не було вибрано жодного пристрою USB.", @@ -1858,9 +1956,9 @@ }, "usbStatus_searching": "Пошук пристроїв USB...", "usbStatus_notConnected": "Виберіть пристрій USB", - "usbConnectionFailed": "Не вдалося встановити з'єднання через USB: {error}", + "usbConnectionFailed": "Не вдалось встановити з'єднання через USB: {error}", "usbStatus_connecting": "Підключення до USB-пристрою...", - "usbErrorConnectTimedOut": "З'єднання не вдалося встановити. Переконайтеся, що пристрій має встановлене програмне забезпечення USB Companion.", + "usbErrorConnectTimedOut": "З'єднання не вдалось встановити. Переконайтесь, що пристрій має встановлене програмне забезпечення USB Companion.", "@tcpStatus_connectingTo": { "placeholders": { "endpoint": { @@ -1878,18 +1976,18 @@ "connectionChoiceTcpLabel": "TCP", "tcpHostHint": "192.168.40.10", "tcpHostLabel": "IP-адреса", - "tcpScreenTitle": "З'єднатися через протокол TCP", + "tcpScreenTitle": "Підключитись через TCP", "tcpPortLabel": "Порт", "tcpPortHint": "5000", "tcpStatus_notConnected": "Введіть кінцеву точку та підключіться", "tcpStatus_connectingTo": "Підключення до {endpoint}...", "tcpErrorHostRequired": "Необхідно вказати IP-адресу.", - "tcpErrorPortInvalid": "Порт повинен бути в межах від 1 до 65535.", + "tcpErrorPortInvalid": "Порт має бути в межах від 1 до 65535.", "tcpErrorUnsupported": "Транспорт TCP не підтримується на цій платформі.", - "tcpErrorTimedOut": "З'єднання TCP завершилося через закінчення часу очікування.", - "tcpConnectionFailed": "Не вдалося встановити з'єднання TCP: {error}", - "map_showDiscoveryContacts": "Показати контакти Відкриття", - "map_setAsMyLocation": "Встановити моє місцезнаходження", + "tcpErrorTimedOut": "З'єднання TCP завершилось через закінчення часу очікування.", + "tcpConnectionFailed": "Не вдалось встановити з'єднання TCP: {error}", + "map_showDiscoveryContacts": "Показати виявлені контакти", + "map_setAsMyLocation": "Встановити мою геопозицію", "@path_routeWeight": { "placeholders": { "weight": { @@ -1900,12 +1998,12 @@ } } }, - "settings_privacySubtitle": "Керуйте інформацією, яку буде спільно використовуватися", + "settings_privacySubtitle": "Керуйте інформацією, яка буде спільно використовуватись", "settings_privacy": "Налаштування приватності", "settings_telemetryBaseMode": "Режим базової телеметрії", "settings_telemetryLocationMode": "Режим місця телеметрії", - "settings_advertLocation": "Розміщення реклами", - "settings_advertLocationSubtitle": "Включити місце розташування в оголошення", + "settings_advertLocation": "Геопозиція в оголошенні", + "settings_advertLocationSubtitle": "Включити геопозицію в оголошення", "settings_privacySettingsDescription": "Виберіть, яку інформацію ваш пристрій буде передавати іншим.", "settings_allowAll": "Дозволити все", "settings_denyAll": "Відхилити все", @@ -1913,8 +2011,8 @@ "settings_telemetryEnvironmentMode": "Режим середовища телеметрії", "contact_info": "Контактна інформація", "contact_teleBaseSubtitle": "Дозволити спільний доступ до рівня заряду батареї та базової телеметрії", - "contact_teleLoc": "Розташування телеметрії", - "contact_teleBase": "Базовий телебачення", + "contact_teleLoc": "Геопозиція телеметрії", + "contact_teleBase": "Базова телеметрія", "contact_teleLocSubtitle": "Дозволити спільне використання даних про місцеположення", "contact_settings": "Налаштування контактів", "contact_telemetry": "Телеметрія", @@ -1922,13 +2020,6 @@ "contact_lastSeen": "Останній раз бачили", "contact_teleEnv": "Середовище телеметрії", "contact_teleEnvSubtitle": "Дозволити спільний доступ до даних датчиків середовища", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_initialRouteWeight": "Початкова вартість маршруту", "appSettings_initialRouteWeightSubtitle": "Початкова вага для нових відкритих шляхів", "appSettings_maxRouteWeight": "Максимальна вага маршруту", @@ -1941,9 +2032,8 @@ "appSettings_maxMessageRetriesSubtitle": "Кількість спроб повторного відправлення повідомлення перед тим, як позначити його як невдале", "path_routeWeight": "{weight}/{max}", "settings_telemetryModeUpdated": "Режим телеметрії оновлено", - "settings_multiAck": "Багатократне підтвердження: {value}", - "map_showOverlaps": "Перекриття ключа повторювача", - "map_runTraceWithReturnPath": "Повернутися назад тим же шляхом", + "map_showOverlaps": "Перекриття ключів ретрансляторів", + "map_runTraceWithReturnPath": "Повернутись назад тим же шляхом", "@radioStats_noiseFloor": { "placeholders": { "noiseDbm": { @@ -1987,26 +2077,26 @@ } }, "chat_sendCooldown": "Будь ласка, зачекайте трохи, перш ніж відправляти знову.", - "appSettings_languageHu": "Угорський", - "appSettings_jumpToOldestUnreadSubtitle": "При відкритті чату з не прочитаними повідомленнями, прокрутіть до першого не прочитаного повідомлення, а не до останнього.", + "appSettings_languageHu": "Угорська", + "appSettings_jumpToOldestUnreadSubtitle": "При відкритті чату з непрочитаними повідомленнями, прокрутіть до першого непрочитаного повідомлення, а не до останнього.", "appSettings_jumpToOldestUnread": "Перейти до найстарішого непрочитаного повідомлення", "appSettings_languageJa": "Японська", - "appSettings_languageKo": "Кореєська", + "appSettings_languageKo": "Корейська", "radioStats_tooltip": "Статистика радіо та мережі", - "radioStats_screenTitle": "Дані про радіостанції", - "radioStats_notConnected": "Підключіться до пристрою, щоб переглядати статистику радіопередач.", - "radioStats_firmwareTooOld": "Статистика радіо приймача вимагає супутнього програмного забезпечення версії 8 або новішої.", - "radioStats_waiting": "Очікую на отримання даних…", + "radioStats_screenTitle": "Статистика радіо", + "radioStats_notConnected": "Підключіться до пристрою, щоб переглядати статистику радіо.", + "radioStats_firmwareTooOld": "Статистика радіо вимагає прошивки пристрою-компаньйона версії 8 або новішої.", + "radioStats_waiting": "Очікування даних…", "radioStats_noiseFloor": "Рівень шуму: {noiseDbm} дБм", "radioStats_lastRssi": "Останній показник RSSI: {rssiDbm} дБм", "radioStats_lastSnr": "Останній показник SNR: {snr} дБ", - "radioStats_txAir": "Час трансляції на телеканалі TX (загальний): {seconds} секунд", - "radioStats_rxAir": "Загальний час використання RX: {seconds} секунд", + "radioStats_txAir": "Час в ефірі TX (загальний): {seconds} секунд", + "radioStats_rxAir": "Час в ефірі RX (загальний): {seconds} секунд", "radioStats_chartCaption": "Рівень шуму (дБм) на основі останніх вимірювань.", "radioStats_stripNoise": "Рівень шуму: {noiseDbm} дБм", "radioStats_stripWaiting": "Отримано статистику радіо…", - "radioStats_settingsTile": "Дані про радіостанції", - "radioStats_settingsSubtitle": "Рівень шуму, RSSI, SNR та час, протягом якого пристрій використовує радіоканал.", + "radioStats_settingsTile": "Статистика радіо", + "radioStats_settingsSubtitle": "Рівень шуму, RSSI, SNR та час в ефірі.", "@translation_downloadFailed": { "placeholders": { "error": { @@ -2020,9 +2110,9 @@ "translation_enableSubtitle": "Перекладати отримані повідомлення та дозволяти попередній переклад перед відправкою.", "translation_composerSubtitle": "Контролює стан ікон перекладу, який використовується за замовчуванням.", "translation_targetLanguage": "Цільова мова", - "translation_useAppLanguage": "Використовуйте мову додатку", + "translation_useAppLanguage": "Використовувати мову застосунку", "translation_downloadedModelLabel": "Завантажений шаблон", - "translation_presetModelLabel": "Заздалегідь налаштований модель від Hugging Face", + "translation_presetModelLabel": "Попередньо налаштована модель з Hugging Face", "translation_manualUrlLabel": "Посилання на веб-сторінку з інструкцією", "translation_downloadModel": "Завантажити модель", "translation_downloading": "Завантаження...", @@ -2033,7 +2123,7 @@ "translation_deleteModel": "Видалити модель", "translation_modelDownloaded": "Модель перекладу завантажена.", "translation_downloadStopped": "Завантаження призупинено.", - "translation_downloadFailed": "Не вдалося завантажити: {error}", + "translation_downloadFailed": "Не вдалось завантажити: {error}", "translation_enterUrlFirst": "Спочатку введіть URL моделі.", "@scanner_linuxPairingPinPrompt": { "placeholders": { @@ -2061,7 +2151,7 @@ "scanner_linuxPairingPinPrompt": "Введіть PIN для {deviceName} (залиште порожнім, якщо його немає).", "scanner_linuxPairingHidePin": "Приховати PIN", "repeater_cliQuickClockSync": "Синхронізація годинника", - "repeater_cliQuickDiscovery": "Відкрити сусідів", + "repeater_cliQuickDiscovery": "Виявити сусідів", "@repeater_clockSyncAfterLogin": { "description": "Repeater setting: auto sync device clock after successful login" }, @@ -2070,8 +2160,136 @@ }, "repeater_clockSyncAfterLoginSubtitle": "Автоматично надсилати повідомлення \"синхронізація годин\" після успішного входу.", "repeater_clockSyncAfterLogin": "Синхронізація годин після входу", - "repeater_guestTools": "Інструменти для гостей", + "repeater_guestTools": "Гостьові інструменти", "repeater_guest": "Інформація про ретранслятор", "room_guest": "Інформація про сервер кімнати", - "chat_sendMessage": "Надіслати повідомлення" + "chat_sendMessage": "Надіслати повідомлення", + "repeater_getCategory": "Отримати цінності", + "repeater_powerMgmt": "Управління енергоспоживанням", + "repeater_sensors": "Датчики", + "repeater_cliHelpPowerOff": "Вмикає живлення пристрою. (очікується відсутність відповіді)", + "repeater_cliHelpClkReboot": "Скидає годинник до відомої епохи та перезавантажує пристрій.", + "repeater_cliHelpAdvertZeroHop": "Надсилає рекламу, яка не проходить через інші мережі (лише до безпосередніх сусідів).", + "repeater_cliHelpStartOta": "Запускає оновлення прошивки безпосередньо через повітря на сумісних платах.", + "repeater_cliHelpTime": "Встановлює час пристрою відповідно до заданих секунд від початку епохи Unix. Час не може відкачуватися назад.", + "repeater_cliHelpBoard": "Показує виробника/ідентифікатор обладнання.", + "repeater_cliHelpDiscoverNeighbors": "Відправляє запит на виявлення сусідніх вузлів. (Тільки для повторювачів)", + "repeater_cliHelpPowersaving": "Показує, чи увімкнено режим енергозбереження, чи ні.", + "repeater_cliHelpPowersavingOnOff": "Увімкне або вимкне режим енергозбереження (якщо підтримується).", + "repeater_cliHelpErase": "(Тільки для серійного використання) Форматує файлову систему пристрою. Видаляє всі налаштування та контакти.", + "repeater_cliHelpSetDutyCycle": "Встановлює максимальний допустимий цикл передавання як відсоток (від 1 до 100). Автоматично коригує коефіцієнт використання часу.", + "repeater_cliHelpSetPrvKey": "(Тільки для серійного використання) Замінює приватний ключ ідентифікації пристрою. Необхідне перезавантаження для застосування. Генерує новий публічний ключ.", + "repeater_cliHelpSetRadioRxGain": "(Тільки для SX126x) Увімкнення посиленого рівня RX для покращення чутливості при високому споживанні струму.", + "repeater_cliHelpSetOwnerInfo": "Вказує рядок з контактною інформацією власника, який вказано в оголошеннях. Використовуйте '|' для переходу на новий рядок.", + "repeater_cliHelpSetPathHashMode": "Встановлює режим хешування шляху. 0 = для старих систем, 1 = для стандартних, 2 = для суворих. Впливає на те, як маршрути порівнюються.", + "repeater_cliHelpSetLoopDetect": "Встановлює чутливість виявлення циклів маршрутизації: вимкнено, мінімальну, помірну або жорстку.", + "repeater_cliHelpSetFreq": "(Тільки для серійного пристрою) Швидко встановлює лише частоту. Потрібно перезавантажити. Рекомендується використовувати функцію \"налаштування радіо\", щоб задати всі параметри радіо.", + "repeater_cliHelpSetBridgeChannel": "(Тільки для мосту ESPNow) Встановлює канал Wi-Fi (від 1 до 14), який використовується мостом.", + "repeater_cliHelpGetName": "Показує назву узла, яка була налаштована.", + "repeater_cliHelpGetRole": "Показує роль прошивки (ретранслятор, сервер кімнати тощо).", + "repeater_cliHelpGetPublicKey": "Відображає публічний ключ пристрою.", + "repeater_cliHelpGetPrvKey": "(Тільки для серійного використання) Показує приватний ключ пристрою. Розглядайте його як секретну інформацію.", + "repeater_cliHelpGetRepeat": "Показує, чи активна функція перенаправлення пакетів (роль повторювача).", + "repeater_cliHelpGetTx": "Показує потожну потужність передавача в децибелах (dBm).", + "repeater_cliHelpGetFreq": "Показує налаштовану радіочастоту в мегагерцах (MHz).", + "repeater_cliHelpGetRadio": "Показує повні параметри радіосигналу: частоту, смугу пропускання, коефіцієнт модуляції, швидкість кодування.", + "repeater_cliHelpGetRadioRxGain": "(Тільки для SX126x) Показує стан посилення сигналу RX.", + "repeater_cliHelpGetAf": "Показує поточний коефіцієнт часу трансляції.", + "repeater_cliHelpGetDutyCycle": "Показує поточний допустимий цикл роботи як відсоток.", + "repeater_cliHelpGetIntThresh": "Показує поріг перешкод каналу в децибелах.", + "repeater_cliHelpGetAgcResetInterval": "Показує інтервал перезавантаження AGC у секундах.", + "repeater_cliHelpGetMultiAcks": "Показує, чи увімкнено режим подвійного підтвердження (1) або вимкнено (0).", + "repeater_cliHelpGetAllowReadOnly": "Показує, чи дозволено лише читання для гостей.", + "repeater_cliHelpGetAdvertInterval": "Показує тривалість місцевої рекламної паузи в хвилинах.", + "repeater_cliHelpGetFloodAdvertInterval": "Показує інтервал часу між рекламними роликами про повені, виражений у годинах.", + "repeater_cliHelpGetGuestPassword": "Відображає налаштований пароль для гостей.", + "repeater_cliHelpGetLat": "Відображає задану широту.", + "repeater_cliHelpGetLon": "Відображає задану довготу.", + "repeater_cliHelpGetRxDelay": "Відображає базове значення rxdelay.", + "repeater_cliHelpGetTxDelay": "Показує коефіцієнт затримки сигналу у режимі затоплення.", + "repeater_cliHelpGetDirectTxDelay": "Показує коефіцієнт затримки сигналу в режимі прямого зв'язку.", + "repeater_cliHelpGetFloodMax": "Показує максимальну кількість підйомів, спричинених повенем.", + "repeater_cliHelpGetOwnerInfo": "Відображає рядок з контактною інформацією власника.", + "repeater_cliHelpGetPathHashMode": "Відображає режим хешування шляху (0/1/2).", + "repeater_cliHelpGetLoopDetect": "Демонструє чутливість до виявлення циклів.", + "repeater_cliHelpGetAcl": "(Тільки для серій) Перераховує записи контролю доступу на репітері.", + "repeater_cliHelpGetBridgeEnabled": "Показує, чи увімкнено цей міст.", + "repeater_cliHelpGetBridgeDelay": "Показує затримку мосту в мілісекундах.", + "repeater_cliHelpGetBridgeSource": "Показує, чи маршрутизує міст пакети RX або TX.", + "repeater_cliHelpGetBridgeBaud": "(Тільки для мосту RS232) Показує швидкість передачі даних на мосту.", + "repeater_cliHelpGetBridgeChannel": "(Тільки для мосту ESPNow) Показує канал WiFi мосту.", + "repeater_cliHelpGetBridgeSecret": "(Тільки для мосту ESPNow) Показує секрет, який використовується для зв'язку.", + "repeater_cliHelpGetBootloaderVer": "(Тільки для NRF52) Показує версію завантажувача.", + "repeater_cliHelpGetAdcMultiplier": "Відображає коефіцієнт множення аналого-цифрового перетворювача (масштабування напруги від батареї).", + "repeater_cliHelpGetPwrMgtSupport": "Показує, чи має рада директорів підтримку в управлінні енергоспоживанням.", + "repeater_cliHelpGetPwrMgtSource": "Показує поточне джерело живлення: зовнішнє або акумуляторне.", + "repeater_cliHelpGetPwrMgtBootReason": "Показує останні причини перезавантаження та вимкнення.", + "repeater_cliHelpGetPwrMgtBootMv": "Показує напругу акумулятора під час запуску системи в мілівольтах (мВ).", + "repeater_cliHelpSensorGet": "Читає налаштування датчика, вказане за допомогою ключа.", + "repeater_cliHelpSensorSet": "Створює налаштування для спеціального датчика.", + "repeater_cliHelpSensorList": "Перераховує всі налаштування користувацьких датчиків, розділені на сторінки, починаючи з опціонального індексу початку.", + "repeater_cliHelpRegionDefault": "Показує поточний область дії за замовчуванням.", + "repeater_cliHelpRegionDefaultSet": "Встановлює значення регіону за замовчуванням. Використовуйте \"\", щоб очистити.", + "repeater_cliHelpRegionListAllowed": "Перелік регіонів, де дозволено рух транспорту під час повені.", + "repeater_cliHelpRegionListDenied": "Перелік регіонів, які забороняють рух транспорту під час повені.", + "repeater_cliHelpStatsPackets": "(Тільки для серійного використання) Відображає статистику на рівні пакетів.", + "repeater_cliHelpStatsRadio": "(Тільки для серій) Відображає радіостатистику.", + "repeater_cliHelpStatsCore": "(Тільки для серійного використання) Відображає основні статистичні дані про програмне забезпечення.", + "background_serviceTitle": "MeshCore працює", + "background_serviceText": "Підтримує з'єднання BLE", + "appSettings_translationModelDeleted": "Видалено {name}", + "appSettings_translationModelDeleteFailed": "Не вдалось видалити: {error}", + "channels_channelUpdateFailed": "Не вдалось оновити канал: {error}", + "contact_typeChat": "Чат", + "contact_typeRepeater": "Ретранслятор", + "contact_typeRoom": "Кімната", + "contact_typeSensor": "Сенсор", + "contact_typeUnknown": "Невідомо", + "settings_multiAck": "Багато підтверджень", + "map_sharedAt": "Поділено", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losBlockedSpotsHint": "Натисніть на заблоковане місце, щоб виділити його на карті.", + "losBlockedSpotsTitle": "Заблоковані місця", + "losSelectedObstructionTitle": "Вибраний об'єкт перешкоди", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "settings_companionDebugLog": "Журнал відлачування (для супутника)", + "settings_companionDebugLogSubtitle": "Команди, відповіді та необроблена інформація для протоколів BLE/TCP/USB", + "chat_newMessages": "Нові повідомлення", + "chat_markAsUnread": "Позначити як непрочитане", + "repeater_chanUtil": "Використання каналу" } diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 9dc2325..1e28931 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -79,7 +79,7 @@ "scanner_stop": "停止", "scanner_scan": "扫描", "device_quickSwitch": "快速切换", - "device_meshcore": "MeshCore", + "device_meshcore": "网格核心", "settings_title": "设置", "settings_deviceInfo": "设备信息", "settings_appSettings": "应用设置", @@ -109,6 +109,8 @@ "settings_privacyModeEnabled": "隐私模式已启用", "settings_privacyModeDisabled": "隐私模式已关闭", "settings_actions": "操作", + "settings_deleteAllPaths": "Delete All Paths", + "settings_deleteAllPathsSubtitle": "Clear all path data from contacts.", "settings_sendAdvertisement": "发送广播", "settings_sendAdvertisementSubtitle": "立即发送广播", "settings_advertisementSent": "已发送广播", @@ -352,11 +354,8 @@ } } }, - "channels_hashtagChannel": "标签频道", "channels_public": "公共", "channels_private": "私有", - "channels_publicChannel": "公共频道", - "channels_privateChannel": "私有频道", "channels_editChannel": "编辑频道", "channels_muteChannel": "静音频道", "channels_unmuteChannel": "取消静音频道", @@ -403,6 +402,22 @@ } }, "channels_smazCompression": "SMAZ 压缩", + "channels_cyr2latCompression": "Cyr2Lat 压缩", + "channels_cyr2latCompressionDscr": "发送时将一些西里尔字符替换为拉丁字符。", + "channels_cyr2latSettingsHeading": "Cyr2Lat 設定", + "channels_cyr2latSettingsSubheading": "替換清單", + "channels_cyr2latSettingsDscr": "編輯 JSON 字元替換設定檔", + "channels_cyr2latSettingsDialogHint": "JSON 替換映射表", + "channels_cyr2latSettingsDialogWrongJSON": "JSON 格式錯誤:{error}", + "settings_cyr2latProfileAdd": "新增 Cyr2Lat 設定檔", + "settings_cyr2latProfileName": "設定檔名稱", + "settings_cyr2latProfileNameEmpty": "設定檔名稱不能為空", + "settings_cyr2latProfileAdded": "設定檔已成功新增", + "settings_cyr2latProfileUpdated": "設定檔已成功更新", + "settings_cyr2latProfileEdit": "編輯 Cyr2Lat 設定檔", + "settings_cyr2latProfileDelete": "刪除 Cyr2Lat 設定檔", + "settings_cyr2latProfileDeleted": "設定檔已成功刪除", + "settings_cyr2latProfileDeleteDscr": "您確定要刪除設定檔 \"{name}\" 嗎?", "channels_channelUpdated": "频道 \"{name}\" 已更新", "@channels_channelUpdated": { "placeholders": { @@ -414,7 +429,7 @@ "channels_publicChannelAdded": "已添加公共频道", "channels_sortBy": "排序方式", "channels_sortManual": "手动", - "channels_sortAZ": "A-Z", + "channels_sortAZ": "A到Z", "channels_sortLatestMessages": "最新消息", "channels_sortUnread": "未读", "channels_createPrivateChannel": "创建私有频道", @@ -1022,7 +1037,7 @@ "repeater_guestPasswordHelper": "只读访问密码", "repeater_radioSettings": "无线电设置", "repeater_frequencyMhz": "频率 (MHz)", - "repeater_frequencyHelper": "300-2500 MHz", + "repeater_frequencyHelper": "300-2500 兆赫", "repeater_txPower": "TX 功率", "repeater_txPowerHelper": "1-30 dBm", "repeater_bandwidth": "带宽", @@ -1089,6 +1104,81 @@ }, "repeater_confirm": "确认", "repeater_settingsSaved": "设置保存成功", + "repeater_rxGain": "增强的 RX 增益", + "repeater_rxGainHelper": "更高的灵敏度,更大的电流消耗(仅适用于 SX1262/SX1268)", + "repeater_refreshRxGain": "重新启动增强型 RX 功能", + "repeater_multiAcks": "多重确认", + "repeater_multiAcksSubtitle": "通过多个路径确认消息,以提高传递效率。", + "repeater_refreshMultiAcks": "刷新多个确认", + "repeater_networkHealth": "网络健康", + "repeater_loopDetect": "循环检测", + "repeater_loopDetectHelper": "创建看起来像路由环的“洪水包”", + "repeater_loopDetectOff": "离开", + "repeater_loopDetectMinimal": "最少", + "repeater_loopDetectModerate": "适度的", + "repeater_loopDetectStrict": "严格", + "repeater_dutyCycle": "工作周期", + "repeater_dutyCycleHelper": "最大可使用的空闲时间百分比", + "repeater_dutyCyclePercent": "{percent}%", + "@repeater_dutyCyclePercent": { + "placeholders": { + "percent": { + "type": "int" + } + } + }, + "repeater_ownerInfo": "运营商信息", + "repeater_ownerInfoHelper": "此复播器的公共元数据", + "repeater_refreshOwnerInfo": "刷新操作员信息", + "repeater_floodMax": "最大跳跃次数", + "repeater_floodMaxHelper": "一个洪水包中,最大可以传输的跳数 (0-64)", + "repeater_advancedSettings": "高级", + "repeater_advancedSettingsSubtitle": "高级操作员使用的调节旋钮", + "repeater_pathHashMode": "路径哈希模式", + "repeater_pathHashModeHelper": "用于编码此复用器的 ID 的字节数,在“洪流路径/环检测”标签中使用。 0=1 字节(256 个 ID,最多 64 个跳跃),1=2 字节(65K 个 ID,最多 32 个跳跃),2=3 字节(16M 个 ID,最多 21 个跳跃)。 v1.13 及更早版本的固件会使用多字节路径——只有在您的网络升级到 v1.14 或更高版本后才会生效。", + "repeater_txDelay": "洪水(德克萨斯州)延误", + "repeater_txDelayHelper": "对于洪水流量,重新传输间隔应设置为包的传输时间(0-2,默认值为0.5)的倍数。 较高的值意味着更少的冲突,但传输速度会变慢。", + "repeater_directTxDelay": "直接的 TX 延迟", + "repeater_directTxDelayHelper": "对于直接(非广播)流量,重新传输间隔应设置为包的传输时间(0-2,默认值为0.3)的倍数。", + "repeater_intThresh": "干扰阈值", + "repeater_intThreshHelper": "将阈值传递给射频信号的噪声水平校准,使其能够拒绝高于该水平的干扰。 0 表示禁用——只有在您在嘈杂频段中看到 RX 错误时才启用。", + "repeater_agcResetInterval": "AGC 恢复间隔", + "repeater_agcResetIntervalHelper": "为了从失控的增益状态中恢复,应该多久重置收音机的自动增益控制?设置为“秒”,每次重置间隔为4秒。将此选项设置为“0”将禁用周期性重置。", + "repeater_actionsTitle": "行动", + "repeater_sendAdvert": "发布防洪广告", + "repeater_sendAdvertSubtitle": "通过网络播放防洪广告", + "repeater_sendAdvertZeroHop": "发送零跳广告", + "repeater_sendAdvertZeroHopSubtitle": "进行单跳广告广播(不使用中继)", + "repeater_clockSync": "现在同步时钟", + "repeater_clockSyncSubtitle": "将手机的时间设置为与中继器同步", + "repeater_actionSucceeded": "{action} 成功", + "@repeater_actionSucceeded": { + "placeholders": { + "action": { + "type": "String" + } + } + }, + "repeater_actionFailed": "{action} 失败:{error}", + "@repeater_actionFailed": { + "placeholders": { + "action": { + "type": "String" + }, + "error": { + "type": "String" + } + } + }, + "repeater_settingsSavedRebootNeeded": "设置已保存 — 重启发射器以应用", + "repeater_settingsPartialFailure": "部分设置失败:{failures}", + "@repeater_settingsPartialFailure": { + "placeholders": { + "failures": { + "type": "String" + } + } + }, "repeater_errorSavingSettings": "保存设置时出错:{error}", "@repeater_errorSavingSettings": { "placeholders": { @@ -1100,11 +1190,9 @@ "repeater_refreshBasicSettings": "刷新基本设置", "repeater_refreshRadioSettings": "刷新无线电设置", "repeater_refreshTxPower": "刷新 TX 功率", - "repeater_refreshLocationSettings": "刷新位置设置", "repeater_refreshPacketForwarding": "刷新包转发", "repeater_refreshGuestAccess": "刷新访客权限", "repeater_refreshPrivacyMode": "刷新隐私模式", - "repeater_refreshAdvertisementSettings": "刷新广播设置", "repeater_refreshed": "{label} 已刷新", "@repeater_refreshed": { "placeholders": { @@ -1247,7 +1335,7 @@ } } }, - "telemetry_voltageValue": "{volts}V", + "telemetry_voltageValue": "{volts}伏", "@telemetry_voltageValue": { "placeholders": { "volts": { @@ -1541,7 +1629,7 @@ "listFilter_sortBy": "排序方式", "listFilter_latestMessages": "最新消息", "listFilter_heardRecently": "最近听到", - "listFilter_az": "A-Z", + "listFilter_az": "A到Z", "listFilter_filters": "筛选", "listFilter_all": "全部", "listFilter_users": "用户", @@ -1554,7 +1642,7 @@ "pathTrace_notAvailable": "无法获取路径信息。", "pathTrace_refreshTooltip": "刷新路径追踪", "contacts_pathTrace": "路径追踪", - "contacts_ping": "Ping", + "contacts_ping": "乒", "contacts_repeaterPathTrace": "Trace 转发节点", "contacts_repeaterPing": "Ping 转发节点", "contacts_roomPathTrace": "Trace 房间服务器", @@ -1927,13 +2015,6 @@ "contact_settings": "联系人设置", "contact_teleLocSubtitle": "允许共享位置数据", "contact_telemetry": "遥测数据", - "@settings_multiAck": { - "placeholders": { - "value": { - "type": "String" - } - } - }, "appSettings_maxRouteWeight": "最大路径重量", "appSettings_initialRouteWeightSubtitle": "新发现路径的初始重量", "appSettings_initialRouteWeight": "初始路线权重", @@ -1945,7 +2026,7 @@ "appSettings_maxMessageRetries": "最大消息重试次数", "appSettings_maxMessageRetriesSubtitle": "在将消息标记为失败之前,允许尝试的次数", "path_routeWeight": "{weight}/{max}", - "settings_multiAck": "多重ACK:{value}", + "settings_multiAck": "多重ACK", "settings_telemetryModeUpdated": "遥测模式已更新", "map_showOverlaps": "重复键重叠", "map_runTraceWithReturnPath": "沿着相同的路径返回", @@ -2078,5 +2159,162 @@ "repeater_guestTools": "访客工具", "repeater_guest": "重复器信息", "chat_sendMessage": "发送消息", - "room_guest": "服务器信息" + "room_guest": "服务器信息", + "repeater_getCategory": "获取值", + "repeater_powerMgmt": "电源管理", + "repeater_sensors": "传感器", + "repeater_cliHelpPowerOff": "关闭设备。(不应有任何响应)", + "repeater_cliHelpClkReboot": "将时钟重置为已知的时间点,并重启设备。", + "repeater_cliHelpAdvertZeroHop": "发送无中继广告(仅限于邻居)。", + "repeater_cliHelpStartOta": "在支持的板上启动通过空中进行固件更新。", + "repeater_cliHelpTime": "将设备时钟设置为给定的 Unix 纪元秒。时钟不能倒退。", + "repeater_cliHelpBoard": "显示制造商/硬件标识。", + "repeater_cliHelpDiscoverNeighbors": "向附近的邻居发送节点发现请求。(仅限中继器)", + "repeater_cliHelpPowersaving": "显示节能模式是否已开启或已关闭。", + "repeater_cliHelpPowersavingOnOff": "启用或禁用节能模式(如果支持)。", + "repeater_cliHelpErase": "(仅适用于序列模式)格式化设备的文件系统。清除所有设置和联系人。", + "repeater_cliHelpSetDutyCycle": "设定允许的最大传输时段百分比(1-100)。内部调整空闲时间因子。", + "repeater_cliHelpSetPrvKey": "(仅适用于序列号)替换设备身份私钥。需要重启才能应用。生成一个新的公钥。", + "repeater_cliHelpSetRadioRxGain": "(仅适用于 SX126x 芯片) 启用增强型 RX 增益,以在较高电流下提高灵敏度。", + "repeater_cliHelpSetOwnerInfo": "设置广告中包含的联系人信息字符串。使用 '|' 作为换行符。", + "repeater_cliHelpSetPathHashMode": "设置路径哈希模式。 0 = 传统模式,1 = 标准模式,2 = 严格模式。 影响路由路径的匹配方式。", + "repeater_cliHelpSetLoopDetect": "设置路由环检测的灵敏度:关闭、低、中、或高。", + "repeater_cliHelpSetFreq": "(仅限串行模式)快速设置频率。需要重启。 建议使用“设置收音机参数”功能,以便设置完整的收音机参数。", + "repeater_cliHelpSetBridgeChannel": "(仅适用于 ESPNow 桥)设置桥使用的 WiFi 频道(1-14)。", + "repeater_cliHelpGetName": "显示配置的节点名称。", + "repeater_cliHelpGetRole": "显示固件的功能(如:中继器、房间服务器等)。", + "repeater_cliHelpGetPublicKey": "显示设备的公钥。", + "repeater_cliHelpGetPrvKey": "(仅适用于序列号)显示设备的私钥。请将其视为机密信息。", + "repeater_cliHelpGetRepeat": "显示数据包转发(作为中继器)是否已启用或已禁用。", + "repeater_cliHelpGetTx": "显示当前的发射功率(以dBm为单位)。", + "repeater_cliHelpGetFreq": "显示配置的射频频率(以兆赫兹为单位)。", + "repeater_cliHelpGetRadio": "显示完整的无线电参数:频率、带宽、扩频因子、编码速率。", + "repeater_cliHelpGetRadioRxGain": "(仅适用于 SX126x 模块)显示 RX 放大器的状态。", + "repeater_cliHelpGetAf": "显示当前的空闲时间系数。", + "repeater_cliHelpGetDutyCycle": "显示当前允许的占空比(以百分比表示)。", + "repeater_cliHelpGetIntThresh": "显示信道干扰阈值(以dB为单位)。", + "repeater_cliHelpGetAgcResetInterval": "显示 AGC 重置的间隔时间(以秒为单位)。", + "repeater_cliHelpGetMultiAcks": "显示双重确认模式是否已启用(1)或已禁用(0)。", + "repeater_cliHelpGetAllowReadOnly": "显示是否允许访客仅限查看权限。", + "repeater_cliHelpGetAdvertInterval": "显示本地广告的时间间隔,单位为分钟。", + "repeater_cliHelpGetFloodAdvertInterval": "显示洪水广告的播放时间间隔,以小时为单位。", + "repeater_cliHelpGetGuestPassword": "显示已配置的访客密码。", + "repeater_cliHelpGetLat": "显示已配置的纬度。", + "repeater_cliHelpGetLon": "显示已配置的经度。", + "repeater_cliHelpGetRxDelay": "显示 rxdelay 的基本值。", + "repeater_cliHelpGetTxDelay": "显示洪水模式下的传输延迟系数。", + "repeater_cliHelpGetDirectTxDelay": "显示直接模式下的时延系数。", + "repeater_cliHelpGetFloodMax": "显示最大洪水传播次数。", + "repeater_cliHelpGetOwnerInfo": "显示所有者的联系信息。", + "repeater_cliHelpGetPathHashMode": "显示哈希模式(0/1/2)。", + "repeater_cliHelpGetLoopDetect": "显示循环检测的灵敏度。", + "repeater_cliHelpGetAcl": "(仅适用于序列号)列出复用器上的访问控制条目。", + "repeater_cliHelpGetBridgeEnabled": "显示桥是否已启用。", + "repeater_cliHelpGetBridgeDelay": "显示桥梁延迟的时间,单位为毫秒。", + "repeater_cliHelpGetBridgeSource": "显示桥接设备是否接收或发送 RX 或 TX 类型的数据包。", + "repeater_cliHelpGetBridgeBaud": "(仅限 RS232 桥)显示桥的波特率。", + "repeater_cliHelpGetBridgeChannel": "(仅适用于 ESPNow 桥)显示桥的 WiFi 通道。", + "repeater_cliHelpGetBridgeSecret": "(仅适用于 ESPNow 桥)显示桥的共享密钥。", + "repeater_cliHelpGetBootloaderVer": "(仅适用于NRF52)显示引导程序版本。", + "repeater_cliHelpGetAdcMultiplier": "显示 ADC 乘数(电池电压缩放)。", + "repeater_cliHelpGetPwrMgtSupport": "报告董事会是否支持电源管理功能。", + "repeater_cliHelpGetPwrMgtSource": "显示当前的电源:外部电源或电池。", + "repeater_cliHelpGetPwrMgtBootReason": "显示最近的重置和关闭原因。", + "repeater_cliHelpGetPwrMgtBootMv": "显示启动时的电池电压,单位为毫伏 (mV)。", + "repeater_cliHelpSensorGet": "通过按键读取自定义传感器设置。", + "repeater_cliHelpSensorSet": "编写自定义传感器设置。", + "repeater_cliHelpSensorList": "列出所有自定义传感器设置,并按可选的起始索引进行分页显示。", + "repeater_cliHelpRegionDefault": "显示当前默认的区域范围。", + "repeater_cliHelpRegionDefaultSet": "设置默认的区域范围。使用 \"\" 可以清除。", + "repeater_cliHelpRegionListAllowed": "列出允许洪水交通的区域。", + "repeater_cliHelpRegionListDenied": "列出禁止洪水交通的区域。", + "repeater_cliHelpStatsPackets": "(仅显示序列信息)显示数据包级别的统计信息。", + "repeater_cliHelpStatsRadio": "(仅显示序列信息)显示收音机相关统计数据。", + "repeater_cliHelpStatsCore": "(仅显示序列号)显示核心固件统计信息。", + "common_done": "Done", + "background_serviceTitle": "MeshCore running", + "background_serviceText": "Keeping BLE connected", + "appSettings_translationModelDeleted": "Deleted {name}", + "@appSettings_translationModelDeleted": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "appSettings_translationModelDeleteFailed": "Failed to delete: {error}", + "@appSettings_translationModelDeleteFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "channels_channelUpdateFailed": "Failed to update channel: {error}", + "@channels_channelUpdateFailed": { + "placeholders": { + "error": { + "type": "String" + } + } + }, + "map_type": "Type", + "map_path": "Path", + "map_location": "Location", + "map_estLocation": "Est. Location", + "map_publicKey": "Public Key", + "map_publicKeyPrefixHint": "e.g. ab12", + "contact_typeChat": "Chat", + "contact_typeRepeater": "Repeater", + "contact_typeRoom": "Room", + "contact_typeSensor": "Sensor", + "contact_typeUnknown": "Unknown", + "channels_via": "via {path}", + "chat_score": "Score", + "map_sharedAt": "已分享", + "@losBlockedSpotChip": { + "placeholders": { + "distance": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + } + } + }, + "@losSelectedObstructionDetails": { + "placeholders": { + "obstruction": { + "type": "String" + }, + "heightUnit": { + "type": "String" + }, + "distanceFromA": { + "type": "String" + }, + "distanceUnit": { + "type": "String" + }, + "distanceFromB": { + "type": "String" + } + } + }, + "losBlockedSpotsTitle": "被占用区域", + "losBlockedSpotsHint": "点击地图上的某个被遮盖的区域,以突出显示该区域。", + "losSelectedObstructionTitle": "选择性阻碍", + "losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}", + "losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).", + "chat_markAsUnread": "标记为未读", + "settings_companionDebugLog": "调试日志", + "chat_newMessages": "新的消息", + "settings_companionDebugLogSubtitle": "BLE/TCP/USB 协议、响应和原始数据", + "repeater_chanUtil": "频道利用率" } diff --git a/lib/l10n/contact_localization.dart b/lib/l10n/contact_localization.dart new file mode 100644 index 0000000..d8344a3 --- /dev/null +++ b/lib/l10n/contact_localization.dart @@ -0,0 +1,36 @@ +import '../connector/meshcore_protocol.dart'; +import '../models/contact.dart'; +import 'app_localizations.dart'; + +/// UI-level localization helpers for [Contact]. +/// +/// Kept out of the model layer so `Contact` does not depend on +/// `AppLocalizations`. Use these from widgets/screens; for logs and +/// non-UI export use `Contact.typeLabelRaw`. +extension ContactLocalization on Contact { + String typeLabel(AppLocalizations l10n) { + switch (type) { + case advTypeChat: + return l10n.contact_typeChat; + case advTypeRepeater: + return l10n.contact_typeRepeater; + case advTypeRoom: + return l10n.contact_typeRoom; + case advTypeSensor: + return l10n.contact_typeSensor; + default: + return l10n.contact_typeUnknown; + } + } + + String pathLabel(AppLocalizations l10n) { + if (pathOverride != null) { + if (pathOverride! < 0) return l10n.chat_floodForced; + if (pathOverride == 0) return l10n.chat_directForced; + return l10n.chat_hopsForced(pathOverride!); + } + if (pathLength < 0) return l10n.channelPath_floodPath; + if (pathLength == 0) return l10n.chat_direct; + return l10n.chat_hopsCount(pathLength); + } +} diff --git a/lib/main.dart b/lib/main.dart index 3e57eb1..cd62281 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -59,6 +59,9 @@ void main() async { final notificationService = NotificationService(); await notificationService.initialize(); await backgroundService.initialize(); + backgroundService.setLanguageOverrideProvider( + () => appSettingsService.settings.languageOverride, + ); _registerThirdPartyLicenses(); await chatTextScaleService.initialize(); diff --git a/lib/models/app_settings.dart b/lib/models/app_settings.dart index d3d3421..4e95311 100644 --- a/lib/models/app_settings.dart +++ b/lib/models/app_settings.dart @@ -13,6 +13,67 @@ extension UnitSystemValue on UnitSystem { } } +const Map defaultCyr2LatCharMap = { + 'А': 'A', + 'В': 'B', + 'Е': 'E', + 'Ё': 'E', + 'З': '3', + 'К': 'K', + 'М': 'M', + 'Н': 'H', + 'О': 'O', + 'Р': 'P', + 'С': 'C', + 'Т': 'T', + 'Х': 'X', + 'Ь': 'b', + 'а': 'a', + 'е': 'e', + 'ё': 'e', + 'о': 'o', + 'р': 'p', + 'с': 'c', + 'у': 'y', + 'х': 'x', +}; + +class Cyr2LatProfile { + final String id; + final String name; + final Map charMap; + + Cyr2LatProfile({required this.id, required this.name, required this.charMap}); + + Map toJson() { + return {'id': id, 'name': name, 'char_map': charMap}; + } + + factory Cyr2LatProfile.fromJson(Map json) { + return Cyr2LatProfile( + id: json['id'] as String, + name: json['name'] as String, + charMap: + (json['char_map'] as Map?)?.map( + (key, value) => MapEntry(key.toString(), value.toString()), + ) ?? + {}, + ); + } + + Cyr2LatProfile copyWith({ + String? id, + String? name, + Map? charMap, + }) { + return Cyr2LatProfile( + id: id ?? this.id, + name: name ?? this.name, + charMap: charMap ?? this.charMap, + ); + } +} + class AppSettings { static const Object _unset = Object(); @@ -57,6 +118,16 @@ class AppSettings { final String? translationModelSourceUrl; final String? translationSelectedModelId; final List translationDownloadedModels; + final List cyr2latProfiles; + final String selectedCyr2latProfileId; + + Map get cyr2latCharMap { + final profile = cyr2latProfiles.firstWhere( + (p) => p.id == selectedCyr2latProfileId, + orElse: () => cyr2latProfiles.first, + ); + return profile.charMap; + } AppSettings({ this.clearPathOnMaxRetry = false, @@ -100,10 +171,22 @@ class AppSettings { this.translationModelSourceUrl, this.translationSelectedModelId, List? translationDownloadedModels, + List? cyr2latProfiles, + String? selectedCyr2latProfileId, }) : batteryChemistryByDeviceId = batteryChemistryByDeviceId ?? {}, batteryChemistryByRepeaterId = batteryChemistryByRepeaterId ?? {}, mutedChannels = mutedChannels ?? {}, - translationDownloadedModels = translationDownloadedModels ?? const []; + translationDownloadedModels = translationDownloadedModels ?? const [], + cyr2latProfiles = + cyr2latProfiles ?? + [ + Cyr2LatProfile( + id: 'default', + name: 'Default', + charMap: defaultCyr2LatCharMap, + ), + ], + selectedCyr2latProfileId = selectedCyr2latProfileId ?? 'default'; Map toJson() { return { @@ -150,6 +233,10 @@ class AppSettings { 'translation_downloaded_models': translationDownloadedModels .map((model) => model.toJson()) .toList(), + 'cyr2lat_profiles': cyr2latProfiles + .map((profile) => profile.toJson()) + .toList(), + 'selected_cyr2lat_profile_id': selectedCyr2latProfileId, }; } @@ -237,6 +324,38 @@ class AppSettings { ) .toList() ?? const [], + cyr2latProfiles: + (json['cyr2lat_profiles'] as List?) + ?.map( + (entry) => Cyr2LatProfile.fromJson( + Map.from(entry as Map), + ), + ) + .toList() ?? + // Backward compatibility: if old cyr2lat_char_map exists, create a profile from it + (json['cyr2lat_char_map'] != null + ? [ + Cyr2LatProfile( + id: 'migrated', + name: 'Migrated Profile', + charMap: + (json['cyr2lat_char_map'] as Map?)?.map( + (key, value) => + MapEntry(key.toString(), value.toString()), + ) ?? + defaultCyr2LatCharMap, + ), + ] + : [ + Cyr2LatProfile( + id: 'default', + name: 'Default', + charMap: defaultCyr2LatCharMap, + ), + ]), + selectedCyr2latProfileId: + json['selected_cyr2lat_profile_id'] as String? ?? + (json['cyr2lat_char_map'] != null ? 'migrated' : 'default'), ); } @@ -282,6 +401,8 @@ class AppSettings { Object? translationModelSourceUrl = _unset, Object? translationSelectedModelId = _unset, List? translationDownloadedModels, + List? cyr2latProfiles, + String? selectedCyr2latProfileId, }) { return AppSettings( clearPathOnMaxRetry: clearPathOnMaxRetry ?? this.clearPathOnMaxRetry, @@ -345,6 +466,9 @@ class AppSettings { : translationSelectedModelId as String?, translationDownloadedModels: translationDownloadedModels ?? this.translationDownloadedModels, + cyr2latProfiles: cyr2latProfiles ?? this.cyr2latProfiles, + selectedCyr2latProfileId: + selectedCyr2latProfileId ?? this.selectedCyr2latProfileId, ); } } diff --git a/lib/models/contact.dart b/lib/models/contact.dart index 2699f93..01d10a9 100644 --- a/lib/models/contact.dart +++ b/lib/models/contact.dart @@ -17,6 +17,7 @@ class Contact { final double? longitude; final DateTime lastSeen; final DateTime lastMessageAt; + final DateTime? lastModified; final bool isActive; final bool wasPulled; final Uint8List? rawPacket; @@ -33,6 +34,7 @@ class Contact { this.latitude, this.longitude, required this.lastSeen, + this.lastModified, DateTime? lastMessageAt, this.isActive = true, this.wasPulled = false, @@ -41,7 +43,10 @@ class Contact { String get publicKeyHex => pubKeyToHex(publicKey); - String get typeLabel { + /// Non-localized type label, intended for logs and non-UI exports + /// (e.g. GPX). For UI use the `typeLabel(l10n)` extension in + /// `lib/l10n/contact_localization.dart`. + String get typeLabelRaw { switch (type) { case advTypeChat: return 'Chat'; @@ -56,17 +61,6 @@ class Contact { } } - String get pathLabel { - if (pathOverride != null) { - if (pathOverride! < 0) return 'Flood (forced)'; - if (pathOverride == 0) return 'Direct (forced)'; - return '$pathOverride hops (forced)'; - } - if (pathLength < 0) return 'Flood'; - if (pathLength == 0) return 'Direct'; - return '$pathLength hops'; - } - bool get hasLocation { const double epsilon = 1e-6; final lat = latitude ?? 0.0; @@ -94,6 +88,7 @@ class Contact { double? longitude, DateTime? lastSeen, DateTime? lastMessageAt, + DateTime? lastModified, bool? isActive, Uint8List? rawPacket, }) { @@ -114,6 +109,7 @@ class Contact { longitude: longitude ?? this.longitude, lastSeen: lastSeen ?? this.lastSeen, lastMessageAt: lastMessageAt ?? this.lastMessageAt, + lastModified: lastModified ?? this.lastModified, isActive: isActive ?? this.isActive, rawPacket: rawPacket ?? this.rawPacket, ); @@ -182,16 +178,34 @@ class Contact { return null; } - final lastMod = reader.readUInt32LE(); + // mandatory last_advert_timestamp + final lastAdvertTimestamp = reader.readUInt32LE(); double? lat, lon; - if (reader.remaining >= 8) { + DateTime? lastModified; + if (reader.remaining >= 12) { + final latRaw = reader.readInt32LE(); + final lonRaw = reader.readInt32LE(); + final lastModRaw = reader.readUInt32LE(); + // TODO: should this be &&? + if (latRaw != 0 || lonRaw != 0) { + lat = latRaw / 1e6; + lon = lonRaw / 1e6; + } + if (lastModRaw != 0) { + lastModified = DateTime.fromMillisecondsSinceEpoch(lastModRaw * 1000); + } + } else if (reader.remaining >= 8) { + // Old layout: gps without lastmod final latRaw = reader.readInt32LE(); final lonRaw = reader.readInt32LE(); if (latRaw != 0 || lonRaw != 0) { lat = latRaw / 1e6; lon = lonRaw / 1e6; } + appLogger.info( + 'Contact ${pubKeyToHex(pubKey).substring(0, 8)} has gps but no lastmod (legacy firmware layout)', + ); } return Contact( @@ -203,7 +217,10 @@ class Contact { path: pathBytes, latitude: lat, longitude: lon, - lastSeen: DateTime.fromMillisecondsSinceEpoch(lastMod * 1000), + lastSeen: DateTime.fromMillisecondsSinceEpoch( + lastAdvertTimestamp * 1000, + ), + lastModified: lastModified, isActive: true, rawPacket: null, ); diff --git a/lib/models/radio_settings.dart b/lib/models/radio_settings.dart index 37ef3cc..099d920 100644 --- a/lib/models/radio_settings.dart +++ b/lib/models/radio_settings.dart @@ -228,7 +228,7 @@ class RadioSettings { frequencyMHz: 433.0, bandwidth: LoRaBandwidth.bw250, spreadingFactor: LoRaSpreadingFactor.sf11, - codingRate: LoRaCodingRate.cr4_5, + codingRate: LoRaCodingRate.cr4_8, txPowerDbm: 20, ), ), @@ -238,7 +238,7 @@ class RadioSettings { frequencyMHz: 869.0, bandwidth: LoRaBandwidth.bw250, spreadingFactor: LoRaSpreadingFactor.sf11, - codingRate: LoRaCodingRate.cr4_5, + codingRate: LoRaCodingRate.cr4_8, txPowerDbm: 14, ), ), @@ -248,7 +248,7 @@ class RadioSettings { frequencyMHz: 918.0, bandwidth: LoRaBandwidth.bw250, spreadingFactor: LoRaSpreadingFactor.sf11, - codingRate: LoRaCodingRate.cr4_5, + codingRate: LoRaCodingRate.cr4_8, txPowerDbm: 20, ), ), diff --git a/lib/screens/app_settings_screen.dart b/lib/screens/app_settings_screen.dart index 80d8adb..94b3efe 100644 --- a/lib/screens/app_settings_screen.dart +++ b/lib/screens/app_settings_screen.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -60,6 +61,8 @@ class AppSettingsScreen extends StatelessWidget { const SizedBox(height: 16), _buildMapSettingsCard(context, settingsService), const SizedBox(height: 16), + _buildCyr2LatCard(context, settingsService), + const SizedBox(height: 16), _buildDebugCard(context, settingsService), ], ); @@ -1237,15 +1240,20 @@ class AppSettingsScreen extends StatelessWidget { if (!context.mounted) return; showDismissibleSnackBar( context, - // TODO: l10n - content: Text('Deleted ${translationModelFriendlyName(model)}.'), + content: Text( + context.l10n.appSettings_translationModelDeleted( + translationModelFriendlyName(model), + ), + ), ); } catch (error) { if (!context.mounted) return; showDismissibleSnackBar( context, - content: Text('Delete failed: $error'), - ); // TODO: l10n + content: Text( + context.l10n.appSettings_translationModelDeleteFailed('$error'), + ), + ); } } @@ -1255,6 +1263,298 @@ class AppSettingsScreen extends StatelessWidget { return '${sizeMb.toStringAsFixed(1)} MB • $source'; } + Widget _buildCyr2LatCard( + BuildContext context, + AppSettingsService settingsService, + ) { + final selectedProfile = settingsService.getSelectedCyr2LatProfile(); + return Card( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), + child: Text( + context.l10n.channels_cyr2latSettingsHeading, + style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), + child: DropdownButtonFormField( + initialValue: settingsService.settings.selectedCyr2latProfileId, + decoration: InputDecoration( + labelText: context.l10n.channels_cyr2latSettingsSubheading, + border: const OutlineInputBorder(), + ), + items: settingsService.settings.cyr2latProfiles.map((profile) { + return DropdownMenuItem( + value: profile.id, + child: Text(profile.name), + ); + }).toList(), + onChanged: (value) { + if (value != null) { + settingsService.setSelectedCyr2LatProfile(value); + } + }, + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), + child: Row( + children: [ + Expanded( + child: OutlinedButton.icon( + onPressed: () => + _showAddCyr2LatProfileDialog(context, settingsService), + icon: const Icon(Icons.add), + label: Text(context.l10n.common_add), + ), + ), + const SizedBox(width: 8), + Expanded( + child: OutlinedButton.icon( + onPressed: () => _showEditCyr2LatProfileDialog( + context, + settingsService, + selectedProfile, + ), + icon: const Icon(Icons.edit), + label: Text(context.l10n.common_edit), + ), + ), + const SizedBox(width: 8), + Expanded( + child: OutlinedButton.icon( + onPressed: + settingsService.settings.cyr2latProfiles.length > 1 + ? () => _showDeleteCyr2LatProfileDialog( + context, + settingsService, + selectedProfile, + ) + : null, + icon: const Icon(Icons.delete), + label: Text(context.l10n.common_delete), + ), + ), + ], + ), + ), + ], + ), + ); + } + + void _showAddCyr2LatProfileDialog( + BuildContext context, + AppSettingsService settingsService, + ) { + final nameController = TextEditingController(); + final jsonController = TextEditingController( + text: const JsonEncoder.withIndent(' ').convert(defaultCyr2LatCharMap), + ); + + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text(context.l10n.settings_cyr2latProfileAdd), + content: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + controller: nameController, + decoration: InputDecoration( + labelText: context.l10n.settings_cyr2latProfileName, + border: const OutlineInputBorder(), + ), + ), + const SizedBox(height: 16), + TextField( + controller: jsonController, + maxLines: 15, + decoration: InputDecoration( + labelText: context.l10n.channels_cyr2latSettingsDialogHint, + border: const OutlineInputBorder(), + hintText: context.l10n.channels_cyr2latSettingsDscr, + ), + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text(context.l10n.common_cancel), + ), + TextButton( + onPressed: () async { + if (nameController.text.isEmpty) { + showDismissibleSnackBar( + context, + content: Text(context.l10n.settings_cyr2latProfileNameEmpty), + ); + return; + } + try { + final json = + jsonDecode(jsonController.text) as Map; + final map = json.map( + (key, value) => MapEntry(key, value.toString()), + ); + final profile = Cyr2LatProfile( + id: DateTime.now().millisecondsSinceEpoch.toString(), + name: nameController.text, + charMap: map, + ); + await settingsService.addCyr2LatProfile(profile); + if (!context.mounted) return; + Navigator.pop(context); + showDismissibleSnackBar( + context, + content: Text(context.l10n.settings_cyr2latProfileAdded), + ); + } catch (e) { + showDismissibleSnackBar( + context, + content: Text( + context.l10n.channels_cyr2latSettingsDialogWrongJSON( + e.toString(), + ), + ), + ); + } + }, + child: Text(context.l10n.common_save), + ), + ], + ), + ); + } + + void _showEditCyr2LatProfileDialog( + BuildContext context, + AppSettingsService settingsService, + Cyr2LatProfile profile, + ) { + final nameController = TextEditingController(text: profile.name); + final jsonController = TextEditingController( + text: const JsonEncoder.withIndent(' ').convert(profile.charMap), + ); + + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text(context.l10n.settings_cyr2latProfileEdit), + content: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + controller: nameController, + decoration: InputDecoration( + labelText: context.l10n.settings_cyr2latProfileName, + border: const OutlineInputBorder(), + ), + ), + const SizedBox(height: 16), + TextField( + controller: jsonController, + maxLines: 15, + decoration: InputDecoration( + labelText: context.l10n.channels_cyr2latSettingsDialogHint, + border: const OutlineInputBorder(), + hintText: context.l10n.channels_cyr2latSettingsDscr, + ), + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text(context.l10n.common_cancel), + ), + TextButton( + onPressed: () async { + if (nameController.text.isEmpty) { + showDismissibleSnackBar( + context, + content: Text(context.l10n.settings_cyr2latProfileNameEmpty), + ); + return; + } + try { + final json = + jsonDecode(jsonController.text) as Map; + final map = json.map( + (key, value) => MapEntry(key, value.toString()), + ); + final updatedProfile = profile.copyWith( + name: nameController.text, + charMap: map, + ); + await settingsService.updateCyr2LatProfile(updatedProfile); + if (!context.mounted) return; + Navigator.pop(context); + showDismissibleSnackBar( + context, + content: Text(context.l10n.settings_cyr2latProfileUpdated), + ); + } catch (e) { + showDismissibleSnackBar( + context, + content: Text( + context.l10n.channels_cyr2latSettingsDialogWrongJSON( + e.toString(), + ), + ), + ); + } + }, + child: Text(context.l10n.common_save), + ), + ], + ), + ); + } + + void _showDeleteCyr2LatProfileDialog( + BuildContext context, + AppSettingsService settingsService, + Cyr2LatProfile profile, + ) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text(context.l10n.settings_cyr2latProfileDelete), + content: Text( + context.l10n.settings_cyr2latProfileDeleteDscr(profile.name), + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text(context.l10n.common_cancel), + ), + TextButton( + onPressed: () async { + await settingsService.removeCyr2LatProfile(profile.id); + if (!context.mounted) return; + Navigator.pop(context); + showDismissibleSnackBar( + context, + content: Text(context.l10n.settings_cyr2latProfileDeleted), + ); + }, + child: Text(context.l10n.common_delete), + ), + ], + ), + ); + } + Widget _buildDebugCard( BuildContext context, AppSettingsService settingsService, diff --git a/lib/screens/channel_chat_screen.dart b/lib/screens/channel_chat_screen.dart index e5b5f67..fcd5086 100644 --- a/lib/screens/channel_chat_screen.dart +++ b/lib/screens/channel_chat_screen.dart @@ -4,16 +4,16 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; -import 'package:latlong2/latlong.dart'; +import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import '../connector/meshcore_connector.dart'; import '../utils/platform_info.dart'; import '../helpers/chat_scroll_controller.dart'; import '../connector/meshcore_protocol.dart'; +import '../helpers/cyr2lat.dart'; import '../helpers/gif_helper.dart'; import '../helpers/reaction_helper.dart'; -import '../helpers/utf8_length_limiter.dart'; import '../helpers/snack_bar_builder.dart'; import '../l10n/l10n.dart'; import '../models/channel.dart'; @@ -23,6 +23,7 @@ import '../services/app_settings_service.dart'; import '../services/chat_text_scale_service.dart'; import '../services/translation_service.dart'; import '../utils/emoji_utils.dart'; +import '../widgets/byte_count_input.dart'; import '../widgets/chat_zoom_wrapper.dart'; import '../widgets/emoji_picker.dart'; import '../widgets/gif_message.dart'; @@ -32,13 +33,19 @@ import '../widgets/message_translation_button.dart'; import '../widgets/message_status_icon.dart'; import '../widgets/radio_stats_entry.dart'; import '../widgets/translated_message_content.dart'; +import '../widgets/unread_divider.dart'; import 'channel_message_path_screen.dart'; import 'map_screen.dart'; class ChannelChatScreen extends StatefulWidget { final Channel channel; + final int initialUnreadCount; - const ChannelChatScreen({super.key, required this.channel}); + const ChannelChatScreen({ + super.key, + required this.channel, + this.initialUnreadCount = 0, + }); @override State createState() => _ChannelChatScreenState(); @@ -55,32 +62,46 @@ class _ChannelChatScreenState extends State { MeshCoreConnector? _connector; DateTime? _lastChannelSendAt; bool _channelSkipNextBottomSnap = false; + String? _unreadDividerMessageId; + + String? _cachedFormatLocale; + late DateFormat _hmFormat; + late DateFormat _mdFormat; @override void initState() { super.initState(); _textFieldFocusNode.addListener(_onTextFieldFocusChange); _scrollController.onScrollNearTop = _loadOlderMessages; + _scrollController.showJumpToBottom.addListener(_clearDividerAtBottom); SchedulerBinding.instance.addPostFrameCallback((_) { if (!mounted) return; final connector = context.read(); final settings = context.read().settings; final idx = widget.channel.index; - final unread = connector.getUnreadCountForChannelIndex(idx); + final unread = widget.initialUnreadCount; + final messages = connector.getChannelMessages(widget.channel); ChannelMessage? anchor; - if (settings.jumpToOldestUnread && unread > 0) { - anchor = _findOldestUnreadChannelAnchor( - connector.getChannelMessages(widget.channel), - unread, - ); + if (unread > 0) { + anchor = _findOldestUnreadChannelAnchor(messages, unread); } + setState(() { + if (anchor != null) _unreadDividerMessageId = anchor.messageId; + }); connector.setActiveChannel(idx); _connector = connector; - if (anchor != null) { + if (anchor != null && settings.jumpToOldestUnread) { _channelSkipNextBottomSnap = true; WidgetsBinding.instance.addPostFrameCallback((_) { if (!mounted) return; - _scrollToMessage(anchor!.messageId); + _scrollController.jumpToEstimatedOffset( + unreadCount: unread, + totalMessages: messages.length, + onJumped: () { + if (!mounted) return; + _scrollToMessage(anchor!.messageId); + }, + ); }); } }); @@ -102,6 +123,13 @@ class _ChannelChatScreenState extends State { return oldest; } + void _clearDividerAtBottom() { + if (!_scrollController.showJumpToBottom.value && + _unreadDividerMessageId != null) { + setState(() => _unreadDividerMessageId = null); + } + } + void _onTextFieldFocusChange() { if (_textFieldFocusNode.hasFocus && mounted) { _scrollController.handleKeyboardOpen(); @@ -123,6 +151,7 @@ class _ChannelChatScreenState extends State { @override void dispose() { _connector?.setActiveChannel(null); + _scrollController.showJumpToBottom.removeListener(_clearDividerAtBottom); _textFieldFocusNode.removeListener(_onTextFieldFocusChange); _textFieldFocusNode.dispose(); _textController.dispose(); @@ -321,6 +350,9 @@ class _ChannelChatScreenState extends State { if (!_messageKeys.containsKey(message.messageId)) { _messageKeys[message.messageId] = GlobalKey(); } + final isUnreadAnchor = + _unreadDividerMessageId != null && + message.messageId == _unreadDividerMessageId; return Container( key: _messageKeys[message.messageId]!, child: Builder( @@ -329,10 +361,17 @@ class _ChannelChatScreenState extends State { .select( (service) => service.scale, ); - return _buildMessageBubble( + final bubble = _buildMessageBubble( message, textScale, ); + if (isUnreadAnchor) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [const UnreadDivider(), bubble], + ); + } + return bubble; }, ), ); @@ -352,12 +391,24 @@ class _ChannelChatScreenState extends State { ); } + void _markAsUnread(ChannelMessage message) { + final connector = context.read(); + final messages = connector.getChannelMessages(widget.channel); + var count = 0; + var found = false; + for (final m in messages) { + if (m.messageId == message.messageId) found = true; + if (found && !m.isOutgoing) count++; + } + connector.setChannelUnreadCount(widget.channel.index, count); + } + Widget _buildMessageBubble(ChannelMessage message, double textScale) { final settingsService = context.watch(); final enableTracing = settingsService.settings.enableMessageTracing; final isOutgoing = message.isOutgoing; final gifId = GifHelper.parseGif(message.text); - final poi = _parsePoiMessage(message.text); + final poi = parseMarkerText(message.text); final translatedDisplayText = message.translatedText != null && message.translatedText!.trim().isNotEmpty @@ -445,6 +496,7 @@ class _ChannelChatScreenState extends State { poi, isOutgoing, textScale, + message.senderName, trailing: (!enableTracing && isOutgoing) ? Padding( padding: const EdgeInsets.only(bottom: 2), @@ -555,7 +607,9 @@ class _ChannelChatScreenState extends State { ? const EdgeInsets.symmetric(horizontal: 8) : EdgeInsets.zero, child: Text( - 'via ${_formatPathPrefixes(displayPath)}', + context.l10n.channels_via( + _formatPathPrefixes(displayPath), + ), style: TextStyle( fontSize: 11, color: Colors.grey[600], @@ -576,7 +630,7 @@ class _ChannelChatScreenState extends State { mainAxisSize: MainAxisSize.min, children: [ Text( - _formatTime(message.timestamp), + _formatTime(context, message.timestamp), style: TextStyle( fontSize: 11, color: Colors.grey[600], @@ -701,7 +755,7 @@ class _ChannelChatScreenState extends State { final previewTextColor = colorScheme.onSurface.withValues(alpha: 0.7); final gifId = GifHelper.parseGif(replyText); - final poi = _parsePoiMessage(replyText); + final poi = parseMarkerText(replyText); Widget contentPreview; if (gifId != null) { @@ -812,24 +866,12 @@ class _ChannelChatScreenState extends State { ); } - _PoiInfo? _parsePoiMessage(String text) { - final trimmed = text.trim(); - final match = RegExp( - r'm:([\-0-9.]+),([\-0-9.]+)\|([^|]*)\|', - ).firstMatch(trimmed); - if (match == null) return null; - final lat = double.tryParse(match.group(1) ?? ''); - final lon = double.tryParse(match.group(2) ?? ''); - if (lat == null || lon == null) return null; - final label = match.group(3) ?? ''; - return _PoiInfo(lat: lat, lon: lon, label: label); - } - Widget _buildPoiMessage( BuildContext context, - _PoiInfo poi, + MarkerPayload poi, bool isOutgoing, - double textScale, { + double textScale, + String senderName, { Widget? trailing, }) { final colorScheme = Theme.of(context).colorScheme; @@ -849,12 +891,22 @@ class _ChannelChatScreenState extends State { padding: EdgeInsets.zero, constraints: const BoxConstraints(minWidth: 32, minHeight: 32), onPressed: () { + final selfName = context.read().selfName ?? 'Me'; + final fromName = isOutgoing ? selfName : senderName; + final key = buildSharedMarkerKey( + sourceId: 'channel:${widget.channel.index}', + label: poi.label, + fromName: fromName, + flags: poi.flags, + isChannel: true, + ); Navigator.push( context, MaterialPageRoute( builder: (context) => MapScreen( - highlightPosition: LatLng(poi.lat, poi.lon), + highlightPosition: poi.position, highlightLabel: poi.label, + highlightMarkerKey: key, ), ), ); @@ -1093,27 +1145,38 @@ class _ChannelChatScreenState extends State { ), ); } - - return TextField( + return ByteCountedTextField( + maxBytes: maxBytes, controller: _textController, focusNode: _textFieldFocusNode, - inputFormatters: [ - Utf8LengthLimitingTextInputFormatter(maxBytes), - ], - textCapitalization: TextCapitalization.sentences, + hintText: context.l10n.chat_typeMessage, + onSubmitted: (_) => _sendMessage(), + encoder: + (connector.isChannelSmazEnabled( + widget.channel.index, + ) || + connector.isChannelCyr2LatEnabled( + widget.channel.index, + )) + ? (text) => connector.prepareChannelOutboundText( + widget.channel.index, + text, + ) + : null, decoration: InputDecoration( hintText: context.l10n.chat_typeMessage, border: OutlineInputBorder( borderRadius: BorderRadius.circular(24), ), + filled: true, + fillColor: Theme.of( + context, + ).colorScheme.surfaceContainerLow, contentPadding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 8, + horizontal: 20, + vertical: 14, ), ), - maxLines: null, - textInputAction: TextInputAction.send, - onSubmitted: (_) => _sendMessage(), ); }, ), @@ -1195,7 +1258,11 @@ class _ChannelChatScreenState extends State { } final maxBytes = maxChannelMessageBytes(connector.selfName); - if (utf8.encode(messageText).length > maxBytes) { + final outboundText = connector.prepareChannelOutboundText( + widget.channel.index, + messageText, + ); + if (utf8.encode(outboundText).length > maxBytes) { showDismissibleSnackBar( context, content: Text(context.l10n.chat_messageTooLong(maxBytes)), @@ -1203,6 +1270,15 @@ class _ChannelChatScreenState extends State { return; } + // When messageText is transformed with cyr2lat, it (generally) hasn't visual differences, + // but we getting messages doubles in chat screen (source text and transformed). + // To prevent, we'll perform transform of source before pass to main sender logic. + // We can pass whole text, senderName will be kept intact + if (connector.isChannelCyr2LatEnabled(widget.channel.index)) { + messageText = Cyr2Lat.encode(messageText); + } + // end transform + _textController.clear(); _cancelReply(); _textFieldFocusNode.requestFocus(); @@ -1215,14 +1291,21 @@ class _ChannelChatScreenState extends State { ); } - String _formatTime(DateTime time) { + String _formatTime(BuildContext context, DateTime time) { final now = DateTime.now(); final diff = now.difference(time); + final locale = Localizations.localeOf(context).toString(); + if (locale != _cachedFormatLocale) { + _cachedFormatLocale = locale; + _hmFormat = DateFormat.Hm(locale); + _mdFormat = DateFormat.Md(locale); + } + final hm = _hmFormat.format(time); if (diff.inDays > 0) { - return '${time.day}/${time.month} ${time.hour}:${time.minute.toString().padLeft(2, '0')}'; + return '${_mdFormat.format(time)} $hm'; } else { - return '${time.hour}:${time.minute.toString().padLeft(2, '0')}'; + return hm; } } @@ -1278,6 +1361,15 @@ class _ChannelChatScreenState extends State { _copyMessageText(message.text); }, ), + if (!message.isOutgoing) + ListTile( + leading: const Icon(Icons.mark_chat_unread_outlined), + title: Text(context.l10n.chat_markAsUnread), + onTap: () { + Navigator.pop(sheetContext); + _markAsUnread(message); + }, + ), ListTile( leading: const Icon(Icons.delete_outline), title: Text(context.l10n.common_delete), @@ -1497,11 +1589,3 @@ class _SwipeReplyBubbleState extends State<_SwipeReplyBubble> { ); } } - -class _PoiInfo { - final double lat; - final double lon; - final String label; - - const _PoiInfo({required this.lat, required this.lon, required this.label}); -} diff --git a/lib/screens/channel_message_path_screen.dart b/lib/screens/channel_message_path_screen.dart index 53769d4..afb2b90 100644 --- a/lib/screens/channel_message_path_screen.dart +++ b/lib/screens/channel_message_path_screen.dart @@ -1,6 +1,6 @@ import 'dart:math'; -import 'dart:typed_data'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:latlong2/latlong.dart'; @@ -304,6 +304,8 @@ class ChannelMessagePathMapScreen extends StatefulWidget { class _ChannelMessagePathMapScreenState extends State { static const double _labelZoomThreshold = 8.5; + static const double _mapMinZoom = 2.0; + static const double _mapMaxZoom = 18.0; final MapController _mapController = MapController(); Uint8List? _selectedPath; @@ -330,6 +332,18 @@ class _ChannelMessagePathMapScreenState } } + @override + void dispose() { + _mapController.dispose(); + super.dispose(); + } + + bool _isDesktopPlatform(TargetPlatform platform) { + return platform == TargetPlatform.linux || + platform == TargetPlatform.windows || + platform == TargetPlatform.macOS; + } + double _getPathDistance(List points) { double totalDistance = 0.0; final distanceCalculator = Distance(); @@ -357,6 +371,70 @@ class _ChannelMessagePathMapScreenState }); } + void _zoomMapBy(double delta) { + final camera = _mapController.camera; + final nextZoom = (camera.zoom + delta) + .clamp(_mapMinZoom, _mapMaxZoom) + .toDouble(); + _mapController.move(camera.center, nextZoom); + } + + void _resetMapView({ + required LatLng initialCenter, + required double initialZoom, + required LatLngBounds? bounds, + }) { + if (bounds != null) { + _mapController.fitCamera( + CameraFit.bounds( + bounds: bounds, + padding: const EdgeInsets.all(64), + maxZoom: 16, + ), + ); + return; + } + _mapController.move(initialCenter, initialZoom); + } + + Widget _buildDesktopMapControls({ + required LatLng initialCenter, + required double initialZoom, + required LatLngBounds? bounds, + }) { + return Positioned( + left: 16, + top: 16, + child: Card( + elevation: 4, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + icon: const Icon(Icons.add), + tooltip: 'Zoom in', + onPressed: () => _zoomMapBy(1), + ), + IconButton( + icon: const Icon(Icons.remove), + tooltip: 'Zoom out', + onPressed: () => _zoomMapBy(-1), + ), + IconButton( + icon: const Icon(Icons.my_location), + tooltip: 'Center map', + onPressed: () => _resetMapView( + initialCenter: initialCenter, + initialZoom: initialZoom, + bounds: bounds, + ), + ), + ], + ), + ), + ); + } + @override Widget build(BuildContext context) { return Consumer( @@ -372,6 +450,7 @@ class _ChannelMessagePathMapScreenState primaryPath, widget.message.pathVariants, ); + final isDesktop = _isDesktopPlatform(defaultTargetPlatform); final selectedPathTmp = _resolveSelectedPath( _selectedPath, observedPaths, @@ -451,10 +530,20 @@ class _ChannelMessagePathMapScreenState padding: const EdgeInsets.all(64), maxZoom: 16, ), - minZoom: 2.0, - maxZoom: 18.0, + minZoom: _mapMinZoom, + maxZoom: _mapMaxZoom, interactionOptions: InteractionOptions( flags: ~InteractiveFlag.rotate, + scrollWheelVelocity: isDesktop ? 0.012 : 0.005, + cursorKeyboardRotationOptions: + CursorKeyboardRotationOptions.disabled(), + keyboardOptions: isDesktop + ? const KeyboardOptions( + enableArrowKeysPanning: true, + enableWASDPanning: true, + enableRFZooming: true, + ) + : const KeyboardOptions.disabled(), ), onPositionChanged: (camera, hasGesture) { final shouldShow = camera.zoom >= _labelZoomThreshold; @@ -486,6 +575,12 @@ class _ChannelMessagePathMapScreenState ), ], ), + if (isDesktop) + _buildDesktopMapControls( + initialCenter: initialCenter, + initialZoom: initialZoom, + bounds: bounds, + ), if (observedPaths.length > 1) _buildPathSelector(context, observedPaths, selectedIndex, ( index, diff --git a/lib/screens/channels_screen.dart b/lib/screens/channels_screen.dart index 44c7a69..4613a8e 100644 --- a/lib/screens/channels_screen.dart +++ b/lib/screens/channels_screen.dart @@ -384,7 +384,6 @@ class _ChannelsScreenState extends State IconData icon; Color iconColor; Color bgColor; - String subtitle; if (isCommunityChannel) { // Community channel styling @@ -392,28 +391,21 @@ class _ChannelsScreenState extends State bgColor = Colors.purple.withValues(alpha: 0.2); if (isCommunityPublic) { icon = Icons.groups; - subtitle = - '${context.l10n.community_publicChannel} • ${community.name}'; } else { icon = Icons.tag; - subtitle = - '${context.l10n.community_hashtagChannel} • ${community.name}'; } } else if (channel.isPublicChannel) { icon = Icons.public; iconColor = Colors.green; bgColor = Colors.green.withValues(alpha: 0.2); - subtitle = context.l10n.channels_publicChannel; } else if (channel.name.startsWith('#')) { icon = Icons.tag; iconColor = Colors.blue; bgColor = Colors.blue.withValues(alpha: 0.2); - subtitle = context.l10n.channels_hashtagChannel; } else { icon = Icons.lock; iconColor = Colors.blue; bgColor = Colors.blue.withValues(alpha: 0.2); - subtitle = context.l10n.channels_privateChannel; } return Card( @@ -430,14 +422,17 @@ class _ChannelsScreenState extends State : null, child: ListTile( dense: true, - minVerticalPadding: 0, + minVerticalPadding: 14, contentPadding: const EdgeInsets.symmetric(horizontal: 12), visualDensity: const VisualDensity(vertical: -2), leading: Stack( children: [ - CircleAvatar( - backgroundColor: bgColor, - child: Icon(icon, color: iconColor), + Padding( + padding: const EdgeInsets.symmetric(vertical: 3), + child: CircleAvatar( + backgroundColor: bgColor, + child: Icon(icon, color: iconColor), + ), ), if (isCommunityChannel) Positioned( @@ -469,11 +464,6 @@ class _ChannelsScreenState extends State : channel.name, style: const TextStyle(fontWeight: FontWeight.w500), ), - subtitle: Text( - subtitle, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ @@ -492,13 +482,19 @@ class _ChannelsScreenState extends State ], ), onTap: () async { + final unread = connector.getUnreadCountForChannelIndex( + channel.index, + ); connector.markChannelRead(channel.index); await Future.delayed(const Duration(milliseconds: 50)); if (context.mounted) { Navigator.push( context, MaterialPageRoute( - builder: (context) => ChannelChatScreen(channel: channel), + builder: (context) => ChannelChatScreen( + channel: channel, + initialUnreadCount: unread, + ), ), ); } @@ -1401,9 +1397,17 @@ class _ChannelsScreenState extends State MeshCoreConnector connector, Channel channel, ) { + final appSettingsService = Provider.of( + context, + listen: false, + ); final nameController = TextEditingController(text: channel.name); final pskController = TextEditingController(text: channel.pskHex); bool smazEnabled = connector.isChannelSmazEnabled(channel.index); + bool cyr2latEnabled = connector.isChannelCyr2LatEnabled(channel.index); + String? selectedCyr2LatProfileId = connector.getChannelCyr2LatProfileId( + channel.index, + ); showDialog( context: context, @@ -1449,8 +1453,52 @@ class _ChannelsScreenState extends State contentPadding: EdgeInsets.zero, title: Text(dialogContext.l10n.channels_smazCompression), value: smazEnabled, - onChanged: (value) => setState(() => smazEnabled = value), + onChanged: (value) => setState(() { + smazEnabled = value; + if (smazEnabled) { + cyr2latEnabled = false; + } + }), ), + SwitchListTile( + contentPadding: EdgeInsets.zero, + title: Text(dialogContext.l10n.channels_cyr2latCompression), + subtitle: Text( + dialogContext.l10n.channels_cyr2latCompressionDscr, + ), + value: cyr2latEnabled, + onChanged: (value) => setState(() { + cyr2latEnabled = value; + if (cyr2latEnabled) { + smazEnabled = false; + } + }), + ), + if (cyr2latEnabled) ...[ + Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 0, 8), + child: DropdownButtonFormField( + initialValue: selectedCyr2LatProfileId, + decoration: InputDecoration( + labelText: dialogContext + .l10n + .channels_cyr2latSettingsSubheading, + border: const OutlineInputBorder(), + ), + items: appSettingsService.settings.cyr2latProfiles.map(( + profile, + ) { + return DropdownMenuItem( + value: profile.id, + child: Text(profile.name), + ); + }).toList(), + onChanged: (value) => setState(() { + selectedCyr2LatProfileId = value; + }), + ), + ), + ], ], ), ), @@ -1482,6 +1530,14 @@ class _ChannelsScreenState extends State channel.index, smazEnabled, ); + await connector.setChannelCyr2LatEnabled( + channel.index, + cyr2latEnabled, + ); + await connector.setChannelCyr2LatProfileId( + channel.index, + selectedCyr2LatProfileId, + ); if (!context.mounted) return; showDismissibleSnackBar( context, @@ -1492,7 +1548,9 @@ class _ChannelsScreenState extends State if (!context.mounted) return; showDismissibleSnackBar( context, - content: Text('Failed to update channel: $e'), + content: Text( + context.l10n.channels_channelUpdateFailed('$e'), + ), ); } }, diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index 2aee61c..8d3bc66 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -9,18 +9,18 @@ import 'package:meshcore_open/screens/path_trace_map.dart'; import 'package:provider/provider.dart'; import '../utils/platform_info.dart'; -import 'package:latlong2/latlong.dart'; import '../connector/meshcore_connector.dart'; import '../connector/meshcore_protocol.dart'; +import '../helpers/cyr2lat.dart'; import '../helpers/reaction_helper.dart'; import '../widgets/message_status_icon.dart'; import '../helpers/chat_scroll_controller.dart'; import '../helpers/gif_helper.dart'; import '../helpers/path_helper.dart'; -import '../helpers/utf8_length_limiter.dart'; import '../models/channel_message.dart'; import '../models/contact.dart'; +import '../l10n/contact_localization.dart'; import '../models/message.dart'; import '../models/path_history.dart'; import '../models/translation_support.dart'; @@ -30,6 +30,7 @@ import '../services/path_history_service.dart'; import '../services/translation_service.dart'; import '../widgets/chat_zoom_wrapper.dart'; import '../widgets/elements_ui.dart'; +import '../widgets/byte_count_input.dart'; import 'channel_message_path_screen.dart'; import 'map_screen.dart'; import '../utils/emoji_utils.dart'; @@ -44,12 +45,18 @@ import '../widgets/translated_message_content.dart'; import '../utils/app_logger.dart'; import '../l10n/l10n.dart'; import '../helpers/snack_bar_builder.dart'; +import '../widgets/unread_divider.dart'; import 'telemetry_screen.dart'; class ChatScreen extends StatefulWidget { final Contact contact; + final int initialUnreadCount; - const ChatScreen({super.key, required this.contact}); + const ChatScreen({ + super.key, + required this.contact, + this.initialUnreadCount = 0, + }); @override State createState() => _ChatScreenState(); @@ -63,6 +70,7 @@ class _ChatScreenState extends State { bool _isLoadingOlder = false; MeshCoreConnector? _connector; Message? _pendingUnreadScrollTarget; + String? _unreadDividerMessageId; DateTime? _lastTextSendAt; @override @@ -70,34 +78,47 @@ class _ChatScreenState extends State { super.initState(); _textFieldFocusNode.addListener(_onTextFieldFocusChange); _scrollController.onScrollNearTop = _loadOlderMessages; + _scrollController.showJumpToBottom.addListener(_clearDividerAtBottom); SchedulerBinding.instance.addPostFrameCallback((_) { if (!mounted) return; final connector = context.read(); final settings = context.read().settings; final keyHex = widget.contact.publicKeyHex; - final unread = connector.getUnreadCountForContactKey(keyHex); + final unread = widget.initialUnreadCount; + final messages = connector.getMessages(widget.contact); Message? anchor; - if (settings.jumpToOldestUnread && unread > 0) { - anchor = _findOldestUnreadAnchor( - connector.getMessages(widget.contact), - unread, - ); + if (unread > 0) { + anchor = _findOldestUnreadAnchor(messages, unread); } + setState(() { + if (anchor != null) _unreadDividerMessageId = anchor.messageId; + if (anchor != null && settings.jumpToOldestUnread) { + _pendingUnreadScrollTarget = anchor; + } + }); connector.setActiveContact(keyHex); _connector = connector; - if (anchor != null) { - setState(() => _pendingUnreadScrollTarget = anchor); + if (anchor != null && settings.jumpToOldestUnread) { WidgetsBinding.instance.addPostFrameCallback((_) { if (!mounted) return; - final ctx = _unreadScrollKey.currentContext; - if (ctx != null) { - Scrollable.ensureVisible( - ctx, - duration: const Duration(milliseconds: 350), - alignment: 0.15, - ); - } - setState(() => _pendingUnreadScrollTarget = null); + _scrollController.jumpToEstimatedOffset( + unreadCount: unread, + totalMessages: messages.length, + onJumped: () async { + if (!mounted) return; + final ctx = _unreadScrollKey.currentContext; + if (ctx != null) { + await Scrollable.ensureVisible( + ctx, + duration: const Duration(milliseconds: 350), + alignment: 0.15, + ); + } + if (mounted) { + setState(() => _pendingUnreadScrollTarget = null); + } + }, + ); }); } }); @@ -116,6 +137,13 @@ class _ChatScreenState extends State { return oldest; } + void _clearDividerAtBottom() { + if (!_scrollController.showJumpToBottom.value && + _unreadDividerMessageId != null) { + setState(() => _unreadDividerMessageId = null); + } + } + void _onTextFieldFocusChange() { if (_textFieldFocusNode.hasFocus && mounted) { _scrollController.handleKeyboardOpen(); @@ -137,6 +165,7 @@ class _ChatScreenState extends State { @override void dispose() { _connector?.setActiveContact(null); + _scrollController.showJumpToBottom.removeListener(_clearDividerAtBottom); _textFieldFocusNode.removeListener(_onTextFieldFocusChange); _textFieldFocusNode.dispose(); _textController.dispose(); @@ -479,6 +508,7 @@ class _ChatScreenState extends State { senderName: resolvedContact.type == advTypeRoom ? "${contact.name} [$fourByteHex]" : contact.name, + sourceId: widget.contact.publicKeyHex, isRoomServer: resolvedContact.type == advTypeRoom, textScale: textScale, onTap: () => _openMessagePath(message, contact), @@ -486,10 +516,19 @@ class _ChatScreenState extends State { onRetryReaction: (msg, emoji) => _sendReaction(msg, contact, emoji), ); + final isUnreadAnchor = + _unreadDividerMessageId != null && + message.messageId == _unreadDividerMessageId; + final child = isUnreadAnchor + ? Column( + mainAxisSize: MainAxisSize.min, + children: [const UnreadDivider(), bubble], + ) + : bubble; if (identical(message, _pendingUnreadScrollTarget)) { - return KeyedSubtree(key: _unreadScrollKey, child: bubble); + return KeyedSubtree(key: _unreadScrollKey, child: child); } - return bubble; + return child; }, ); }, @@ -497,6 +536,18 @@ class _ChatScreenState extends State { ); } + void _markAsUnread(Message message) { + final connector = context.read(); + final messages = connector.getMessages(widget.contact); + var count = 0; + var found = false; + for (final m in messages) { + if (m.messageId == message.messageId) found = true; + if (found && !m.isOutgoing && !m.isCli) count++; + } + connector.setContactUnreadCount(widget.contact.publicKeyHex, count); + } + Widget _buildInputBar(MeshCoreConnector connector) { final maxBytes = maxContactMessageBytes(); final colorScheme = Theme.of(context).colorScheme; @@ -567,24 +618,38 @@ class _ChatScreenState extends State { ), ); } - - return TextField( + return ByteCountedTextField( + maxBytes: maxBytes, controller: _textController, focusNode: _textFieldFocusNode, - inputFormatters: [ - Utf8LengthLimitingTextInputFormatter(maxBytes), - ], - textCapitalization: TextCapitalization.sentences, + hintText: context.l10n.chat_typeMessage, + onSubmitted: (_) => _sendMessage(connector), + encoder: + (connector.isContactSmazEnabled( + widget.contact.publicKeyHex, + ) || + connector.isContactCyr2LatEnabled( + widget.contact.publicKeyHex, + )) + ? (text) => connector.prepareContactOutboundText( + widget.contact, + text, + ) + : null, decoration: InputDecoration( hintText: context.l10n.chat_typeMessage, - border: const OutlineInputBorder(), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(24), + ), + filled: true, + fillColor: Theme.of( + context, + ).colorScheme.surfaceContainerLow, contentPadding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 12, + horizontal: 20, + vertical: 14, ), ), - textInputAction: TextInputAction.send, - onSubmitted: (_) => _sendMessage(connector), ); }, ), @@ -672,7 +737,11 @@ class _ChatScreenState extends State { } } final maxBytes = maxContactMessageBytes(); - if (utf8.encode(outgoingText).length > maxBytes) { + final outboundText = connector.prepareContactOutboundText( + _resolveContact(connector), + outgoingText, + ); + if (utf8.encode(outboundText).length > maxBytes) { showDismissibleSnackBar( context, content: Text(context.l10n.chat_messageTooLong(maxBytes)), @@ -680,6 +749,18 @@ class _ChatScreenState extends State { return; } + // This is only for cyr2lat compression - to see the message being sent in the same format as the other person will receive + try { + if (connector.isContactCyr2LatEnabled( + _resolveContact(connector).publicKeyHex, + )) { + outgoingText = Cyr2Lat.encode(outgoingText); + } + } catch (_) { + // TODO maybe log + } + // end transform + _textController.clear(); _textFieldFocusNode.requestFocus(); connector.sendMessage( @@ -1153,8 +1234,14 @@ class _ChatScreenState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildInfoRow(context.l10n.chat_type, contact.typeLabel), - _buildInfoRow(context.l10n.chat_path, contact.pathLabel), + _buildInfoRow( + context.l10n.chat_type, + contact.typeLabel(context.l10n), + ), + _buildInfoRow( + context.l10n.chat_path, + contact.pathLabel(context.l10n), + ), _buildInfoRow( context.l10n.contact_lastSeen, _formatContactLastMessage(contact.lastMessageAt), @@ -1180,9 +1267,20 @@ class _ChatScreenState extends State { void _showContactSettings(BuildContext context) { final connector = Provider.of(context, listen: false); + final appSettingsService = Provider.of( + context, + listen: false, + ); connector.ensureContactSmazSettingLoaded(widget.contact.publicKeyHex); + connector.ensureContactCyr2LatSettingLoaded(widget.contact.publicKeyHex); final contact = widget.contact; bool smazEnabled = connector.isContactSmazEnabled(contact.publicKeyHex); + bool cyr2latEnabled = connector.isContactCyr2LatEnabled( + contact.publicKeyHex, + ); + String? selectedCyr2LatProfileId = connector.getContactCyr2LatProfileId( + contact.publicKeyHex, + ); bool teleBaseEnabled = contact.teleBaseEnabled; bool teleLocEnabled = contact.teleLocEnabled; bool teleEnvEnabled = contact.teleEnvEnabled; @@ -1213,10 +1311,72 @@ class _ChatScreenState extends State { contact.publicKeyHex, value, ); - setDialogState(() => smazEnabled = value); + connector.setContactCyr2LatEnabled( + contact.publicKeyHex, + false, + ); + setDialogState(() { + smazEnabled = value; + if (smazEnabled) { + cyr2latEnabled = false; + } + }); }, ), const Divider(height: 8), + SwitchListTile( + contentPadding: EdgeInsets.zero, + title: Text(context.l10n.channels_cyr2latCompression), + subtitle: Text(context.l10n.channels_cyr2latCompressionDscr), + value: cyr2latEnabled, + onChanged: (value) { + connector.setContactCyr2LatEnabled( + contact.publicKeyHex, + value, + ); + connector.setContactSmazEnabled( + contact.publicKeyHex, + false, + ); + setDialogState(() { + cyr2latEnabled = value; + if (cyr2latEnabled) { + smazEnabled = false; + } + }); + }, + ), + if (cyr2latEnabled) ...[ + Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 0, 8), + child: DropdownButtonFormField( + initialValue: selectedCyr2LatProfileId, + decoration: InputDecoration( + labelText: + context.l10n.channels_cyr2latSettingsSubheading, + border: const OutlineInputBorder(), + ), + items: appSettingsService.settings.cyr2latProfiles.map(( + profile, + ) { + return DropdownMenuItem( + value: profile.id, + child: Text(profile.name), + ); + }).toList(), + onChanged: (value) { + connector.setContactCyr2LatProfileId( + contact.publicKeyHex, + value, + ); + setDialogState(() { + selectedCyr2LatProfileId = value; + }); + }, + ), + ), + ], + const Divider(height: 8), SwitchListTile( contentPadding: EdgeInsets.zero, title: Text(context.l10n.contact_teleBase), @@ -1305,11 +1465,15 @@ class _ChatScreenState extends State { } void _openChat(BuildContext context, Contact contact) { - // Check if this is a repeater - context.read().markContactRead(contact.publicKeyHex); + final connector = context.read(); + final unread = connector.getUnreadCountForContactKey(contact.publicKeyHex); + connector.markContactRead(contact.publicKeyHex); Navigator.push( context, - MaterialPageRoute(builder: (context) => ChatScreen(contact: contact)), + MaterialPageRoute( + builder: (context) => + ChatScreen(contact: contact, initialUnreadCount: unread), + ), ); } @@ -1446,6 +1610,15 @@ class _ChatScreenState extends State { _copyMessageText(message.text); }, ), + if (!message.isOutgoing) + ListTile( + leading: const Icon(Icons.mark_chat_unread_outlined), + title: Text(context.l10n.chat_markAsUnread), + onTap: () { + Navigator.pop(sheetContext); + _markAsUnread(message); + }, + ), ListTile( leading: const Icon(Icons.delete_outline), title: Text(context.l10n.common_delete), @@ -1553,10 +1726,12 @@ class _MessageBubble extends StatelessWidget { final VoidCallback? onLongPress; final void Function(Message message, String emoji)? onRetryReaction; final double textScale; + final String sourceId; const _MessageBubble({ required this.message, required this.senderName, + required this.sourceId, required this.isRoomServer, required this.textScale, this.onTap, @@ -1571,7 +1746,7 @@ class _MessageBubble extends StatelessWidget { final isOutgoing = message.isOutgoing; final colorScheme = Theme.of(context).colorScheme; final gifId = GifHelper.parseGif(message.text); - final poi = _parsePoiMessage(message.text); + final poi = parseMarkerText(message.text); final isFailed = message.status == MessageStatus.failed; final bubbleColor = isFailed ? colorScheme.errorContainer @@ -1663,6 +1838,7 @@ class _MessageBubble extends StatelessWidget { textColor, metaColor, textScale, + senderName, trailing: (!enableTracing && isOutgoing) ? Padding( padding: const EdgeInsets.only(bottom: 2), @@ -1844,25 +2020,13 @@ class _MessageBubble extends StatelessWidget { ); } - _PoiInfo? _parsePoiMessage(String text) { - final trimmed = text.trim(); - final match = RegExp( - r'^m:([\-0-9.]+),([\-0-9.]+)\|([^|]*)\|.*$', - ).firstMatch(trimmed); - if (match == null) return null; - final lat = double.tryParse(match.group(1) ?? ''); - final lon = double.tryParse(match.group(2) ?? ''); - if (lat == null || lon == null) return null; - final label = match.group(3) ?? ''; - return _PoiInfo(lat: lat, lon: lon, label: label); - } - Widget _buildPoiMessage( BuildContext context, - _PoiInfo poi, + MarkerPayload poi, Color textColor, Color metaColor, - double textScale, { + double textScale, + String senderName, { Widget? trailing, }) { return Row( @@ -1872,13 +2036,23 @@ class _MessageBubble extends StatelessWidget { icon: Icon(Icons.location_on_outlined, color: textColor), padding: EdgeInsets.zero, constraints: const BoxConstraints(minWidth: 32, minHeight: 32), - onPressed: () { + onPressed: () async { + final selfName = context.read().selfName ?? 'Me'; + final fromName = message.isOutgoing ? selfName : senderName; + final key = buildSharedMarkerKey( + sourceId: sourceId, + label: poi.label, + fromName: fromName, + flags: poi.flags, + isChannel: false, + ); Navigator.push( context, MaterialPageRoute( builder: (context) => MapScreen( - highlightPosition: LatLng(poi.lat, poi.lon), + highlightPosition: poi.position, highlightLabel: poi.label, + highlightMarkerKey: key, ), ), ); @@ -2059,11 +2233,3 @@ class _MessageBubble extends StatelessWidget { return '$hour:$minute'; } } - -class _PoiInfo { - final double lat; - final double lon; - final String label; - - const _PoiInfo({required this.lat, required this.lon, required this.label}); -} diff --git a/lib/screens/contacts_screen.dart b/lib/screens/contacts_screen.dart index 54d3299..a4cc35c 100644 --- a/lib/screens/contacts_screen.dart +++ b/lib/screens/contacts_screen.dart @@ -13,6 +13,7 @@ import '../connector/meshcore_connector.dart'; import '../l10n/l10n.dart'; import '../connector/meshcore_protocol.dart'; import '../models/contact.dart'; +import '../l10n/contact_localization.dart'; import '../models/contact_group.dart'; import '../services/ui_view_state_service.dart'; import '../utils/contact_search.dart'; @@ -930,10 +931,17 @@ class _ContactsScreenState extends State } else if (contact.type == advTypeRoom) { _showRoomLogin(context, contact, RoomLoginDestination.chat); } else { - context.read().markContactRead(contact.publicKeyHex); + final connector = context.read(); + final unread = connector.getUnreadCountForContactKey( + contact.publicKeyHex, + ); + connector.markContactRead(contact.publicKeyHex); Navigator.push( context, - MaterialPageRoute(builder: (context) => ChatScreen(contact: contact)), + MaterialPageRoute( + builder: (context) => + ChatScreen(contact: contact, initialUnreadCount: unread), + ), ); } } @@ -988,7 +996,11 @@ class _ContactsScreenState extends State builder: (context) => RoomLoginDialog( room: room, onLogin: (password, isAdmin) { - context.read().markContactRead(room.publicKeyHex); + final connector = context.read(); + final unread = connector.getUnreadCountForContactKey( + room.publicKeyHex, + ); + connector.markContactRead(room.publicKeyHex); Navigator.push( context, MaterialPageRoute( @@ -999,7 +1011,7 @@ class _ContactsScreenState extends State password: password, isAdmin: isAdmin, ) - : ChatScreen(contact: room), + : ChatScreen(contact: room, initialUnreadCount: unread), ), ); }, @@ -1122,7 +1134,9 @@ class _ContactsScreenState extends State return CheckboxListTile( value: isSelected, title: Text(contact.name), - subtitle: Text(contact.typeLabel), + subtitle: Text( + contact.typeLabel(context.l10n), + ), onChanged: (value) { setDialogState(() { if (value == true) { @@ -1464,7 +1478,7 @@ class _ContactTile extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - contact.pathLabel, + contact.pathLabel(context.l10n), maxLines: 1, overflow: TextOverflow.ellipsis, ), diff --git a/lib/screens/line_of_sight_map_screen.dart b/lib/screens/line_of_sight_map_screen.dart index ec8a391..3ba79d5 100644 --- a/lib/screens/line_of_sight_map_screen.dart +++ b/lib/screens/line_of_sight_map_screen.dart @@ -1,6 +1,7 @@ import 'dart:math' as math; import 'dart:ui' as ui; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:latlong2/latlong.dart'; @@ -56,12 +57,16 @@ class _LineOfSightMapScreenState extends State { static const double _maxAntennaFeet = 400.0; static const double _maxAntennaMeters = _maxAntennaFeet / _metersToFeet; static const double _labelZoomThreshold = 8.5; + static const double _mapMinZoom = 2.0; + static const double _mapMaxZoom = 18.0; final LineOfSightService _lineOfSightService = LineOfSightService(); + final MapController _mapController = MapController(); bool _loading = false; String? _error; LineOfSightPathResult? _result; + LineOfSightObstruction? _selectedObstruction; LineOfSightEndpoint? _start; LineOfSightEndpoint? _end; final List _customEndpoints = []; @@ -98,10 +103,85 @@ class _LineOfSightMapScreenState extends State { @override void dispose() { + _mapController.dispose(); _lineOfSightService.dispose(); super.dispose(); } + bool _isDesktopPlatform(TargetPlatform platform) { + return platform == TargetPlatform.linux || + platform == TargetPlatform.windows || + platform == TargetPlatform.macOS; + } + + void _zoomMapBy(double delta) { + final camera = _mapController.camera; + final nextZoom = (camera.zoom + delta) + .clamp(_mapMinZoom, _mapMaxZoom) + .toDouble(); + _mapController.move(camera.center, nextZoom); + } + + void _resetMapView({ + required LatLng initialCenter, + required double initialZoom, + required LatLngBounds? bounds, + }) { + if (bounds != null) { + _mapController.fitCamera( + CameraFit.bounds( + bounds: bounds, + padding: const EdgeInsets.all(64), + maxZoom: 16, + ), + ); + return; + } + _mapController.move(initialCenter, initialZoom); + } + + Widget _buildDesktopMapControls({ + required LatLng initialCenter, + required double initialZoom, + required LatLngBounds? bounds, + }) { + final screenHeight = MediaQuery.of(context).size.height; + final topOffset = _showHud + ? math.min(screenHeight * 0.52 + 24, screenHeight - 220) + : 12.0; + return Positioned( + top: topOffset, + left: 12, + child: Card( + elevation: 4, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + icon: const Icon(Icons.add), + tooltip: 'Zoom in', + onPressed: () => _zoomMapBy(1), + ), + IconButton( + icon: const Icon(Icons.remove), + tooltip: 'Zoom out', + onPressed: () => _zoomMapBy(-1), + ), + IconButton( + icon: const Icon(Icons.my_location), + tooltip: 'Center map', + onPressed: () => _resetMapView( + initialCenter: initialCenter, + initialZoom: initialZoom, + bounds: bounds, + ), + ), + ], + ), + ), + ); + } + Future _runLos() async { final start = _start; final end = _end; @@ -111,6 +191,7 @@ class _LineOfSightMapScreenState extends State { if (start == null || end == null) { setState(() { _result = null; + _selectedObstruction = null; _error = _errorSelectStartEnd; }); return; @@ -142,6 +223,7 @@ class _LineOfSightMapScreenState extends State { } setState(() { _result = result; + _selectedObstruction = _defaultObstructionFor(result); }); } catch (e) { if (!mounted) return; @@ -156,6 +238,7 @@ class _LineOfSightMapScreenState extends State { } setState(() { _result = null; + _selectedObstruction = null; _error = context.l10n.losRunFailed(e.toString()); }); } finally { @@ -184,6 +267,7 @@ class _LineOfSightMapScreenState extends State { void _selectFromMap(LineOfSightEndpoint endpoint) { setState(() { _result = null; + _selectedObstruction = null; _error = null; if (_start == null || (_start != null && _end != null)) { _start = endpoint; @@ -241,6 +325,7 @@ class _LineOfSightMapScreenState extends State { _start = null; _end = null; _result = null; + _selectedObstruction = null; _error = _errorSelectStartEnd; }); } @@ -251,6 +336,7 @@ class _LineOfSightMapScreenState extends State { if (identical(_start, endpoint)) _start = null; if (identical(_end, endpoint)) _end = null; _result = null; + _selectedObstruction = null; }); } @@ -318,6 +404,7 @@ class _LineOfSightMapScreenState extends State { ? LatLngBounds.fromPoints(mapPoints) : null; final initialZoom = mapPoints.length > 1 ? 13.0 : 2.0; + final isDesktop = _isDesktopPlatform(defaultTargetPlatform); if (!_didReceivePositionUpdate) { _showMarkerLabels = initialZoom >= _labelZoomThreshold; } @@ -343,6 +430,7 @@ class _LineOfSightMapScreenState extends State { body: Stack( children: [ FlutterMap( + mapController: _mapController, options: MapOptions( initialCenter: initialCenter, initialZoom: initialZoom, @@ -355,7 +443,19 @@ class _LineOfSightMapScreenState extends State { ), interactionOptions: InteractionOptions( flags: ~InteractiveFlag.rotate, + scrollWheelVelocity: isDesktop ? 0.012 : 0.005, + cursorKeyboardRotationOptions: + CursorKeyboardRotationOptions.disabled(), + keyboardOptions: isDesktop + ? const KeyboardOptions( + enableArrowKeysPanning: true, + enableWASDPanning: true, + enableRFZooming: true, + ) + : const KeyboardOptions.disabled(), ), + minZoom: _mapMinZoom, + maxZoom: _mapMaxZoom, onLongPress: (_, point) => _addCustomPoint(point), onPositionChanged: (camera, hasGesture) { final shouldShow = camera.zoom >= _labelZoomThreshold; @@ -377,9 +477,17 @@ class _LineOfSightMapScreenState extends State { ), if (_result != null && _result!.segments.isNotEmpty) PolylineLayer(polylines: _buildSegmentPolylines(_result!)), - MarkerLayer(markers: _buildMarkers(endpoints)), + MarkerLayer( + markers: _buildMarkers(endpoints, _primaryObstructions()), + ), ], ), + if (isDesktop) + _buildDesktopMapControls( + initialCenter: initialCenter, + initialZoom: initialZoom, + bounds: bounds, + ), if (_showHud) Positioned( left: 12, @@ -445,6 +553,8 @@ class _LineOfSightMapScreenState extends State { ); final displayFrequencyMHz = segment?.frequencyMHz ?? reportedFrequencyMHz; final kFactorUsed = segment?.usedKFactor; + final obstructions = + segment?.obstructions ?? const []; final endpoints = _visibleEndpoints(); final distanceUnit = isImperial ? 'mi' : 'km'; final heightUnit = isImperial ? 'ft' : 'm'; @@ -463,31 +573,7 @@ class _LineOfSightMapScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ if (segment != null) - SizedBox( - height: 160, - width: double.infinity, - child: CustomPaint( - painter: _LosProfilePainter( - samples: segment.samples, - distanceUnit: distanceUnit, - heightUnit: heightUnit, - badgeTextStyle: - Theme.of(context).textTheme.labelSmall?.copyWith( - color: Colors.white70, - fontSize: 10, - fontWeight: FontWeight.w600, - ) ?? - const TextStyle( - color: Colors.white70, - fontSize: 10, - fontWeight: FontWeight.w600, - ), - terrainLabel: context.l10n.losLegendTerrain, - losBeamLabel: context.l10n.losLegendLosBeam, - radioHorizonLabel: context.l10n.losLegendRadioHorizon, - ), - ), - ) + _buildProfileView(segment, distanceUnit, heightUnit, isImperial) else SizedBox( height: 44, @@ -519,6 +605,96 @@ class _LineOfSightMapScreenState extends State { fontWeight: FontWeight.w600, ), ), + if (obstructions.isNotEmpty) ...[ + const SizedBox(height: 8), + Text( + context.l10n.losBlockedSpotsTitle, + style: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w700, + ), + ), + const SizedBox(height: 4), + Text( + context.l10n.losBlockedSpotsHint, + style: TextStyle(fontSize: 11, color: Colors.grey[700]), + ), + const SizedBox(height: 6), + Wrap( + spacing: 6, + runSpacing: 6, + children: [ + for (final obstruction in obstructions) + ChoiceChip( + label: Text( + _obstructionChipLabel(obstruction, isImperial), + style: const TextStyle(fontSize: 11), + ), + selected: + _selectedObstruction?.sampleIndex == + obstruction.sampleIndex, + onSelected: (_) => _selectObstruction(obstruction), + ), + ], + ), + if (_selectedObstruction != null) ...[ + const SizedBox(height: 8), + DecoratedBox( + decoration: BoxDecoration( + color: Colors.orange.withValues(alpha: 0.1), + borderRadius: BorderRadius.circular(10), + border: Border.all( + color: Colors.deepOrangeAccent.withValues(alpha: 0.45), + ), + ), + child: Padding( + padding: const EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + context.l10n.losSelectedObstructionTitle, + style: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w700, + ), + ), + const SizedBox(height: 4), + Text( + context.l10n.losSelectedObstructionDetails( + _formatHeightValue( + _selectedObstruction!.obstructionMeters, + isImperial, + ), + heightUnit, + _formatDistanceValue( + _selectedObstruction!.distanceMeters, + isImperial, + ), + distanceUnit, + _formatDistanceValue( + segment!.totalDistanceMeters - + _selectedObstruction!.distanceMeters, + isImperial, + ), + ), + style: const TextStyle(fontSize: 11), + ), + const SizedBox(height: 4), + Text( + '${_selectedObstruction!.point.latitude.toStringAsFixed(5)}, ' + '${_selectedObstruction!.point.longitude.toStringAsFixed(5)}', + style: TextStyle( + fontSize: 11, + color: Colors.grey[700], + ), + ), + ], + ), + ), + ), + ], + ], const SizedBox(height: 4), if (displayFrequencyMHz != null) Padding( @@ -605,6 +781,7 @@ class _LineOfSightMapScreenState extends State { _showDisplayNodes = value; _sanitizeSelection(); _result = null; + _selectedObstruction = null; }); }, ), @@ -655,6 +832,7 @@ class _LineOfSightMapScreenState extends State { setState(() { _start = value; _result = null; + _selectedObstruction = null; }); if (_start != null && _end != null) { _runLos(); @@ -670,6 +848,7 @@ class _LineOfSightMapScreenState extends State { setState(() { _end = value; _result = null; + _selectedObstruction = null; }); if (_start != null && _end != null) { _runLos(); @@ -769,6 +948,179 @@ class _LineOfSightMapScreenState extends State { return _result!.segments.first.result; } + List _primaryObstructions() { + return _primarySegmentResult()?.obstructions ?? const []; + } + + LineOfSightObstruction? _defaultObstructionFor( + LineOfSightPathResult? result, + ) { + if (result == null || result.segments.isEmpty) return null; + final obstructions = result.segments.first.result.obstructions; + if (obstructions.isEmpty) return null; + return obstructions.reduce( + (current, next) => + next.obstructionMeters > current.obstructionMeters ? next : current, + ); + } + + void _selectObstruction(LineOfSightObstruction obstruction) { + setState(() { + _selectedObstruction = obstruction; + }); + } + + String _formatDistanceValue(double meters, bool isImperial) { + final value = isImperial ? (meters / 1000.0) * _kmToMiles : meters / 1000.0; + return value.toStringAsFixed(2); + } + + String _formatHeightValue(double meters, bool isImperial) { + final value = isImperial ? meters * _metersToFeet : meters; + return value.toStringAsFixed(1); + } + + String _obstructionChipLabel( + LineOfSightObstruction obstruction, + bool isImperial, + ) { + final distanceUnit = isImperial ? 'mi' : 'km'; + final heightUnit = isImperial ? 'ft' : 'm'; + return context.l10n.losBlockedSpotChip( + _formatDistanceValue(obstruction.distanceMeters, isImperial), + distanceUnit, + _formatHeightValue(obstruction.obstructionMeters, isImperial), + heightUnit, + ); + } + + Widget _buildProfileView( + LineOfSightResult segment, + String distanceUnit, + String heightUnit, + bool isImperial, + ) { + if (segment.samples.length < 2) { + return SizedBox( + height: 160, + width: double.infinity, + child: CustomPaint( + painter: _LosProfilePainter( + samples: segment.samples, + distanceUnit: distanceUnit, + heightUnit: heightUnit, + badgeTextStyle: + Theme.of(context).textTheme.labelSmall?.copyWith( + color: Colors.white70, + fontSize: 10, + fontWeight: FontWeight.w600, + ) ?? + const TextStyle( + color: Colors.white70, + fontSize: 10, + fontWeight: FontWeight.w600, + ), + terrainLabel: context.l10n.losLegendTerrain, + losBeamLabel: context.l10n.losLegendLosBeam, + radioHorizonLabel: context.l10n.losLegendRadioHorizon, + selectedSampleIndex: _selectedObstruction?.sampleIndex, + ), + ), + ); + } + return SizedBox( + height: 160, + width: double.infinity, + child: LayoutBuilder( + builder: (context, constraints) { + final size = Size(constraints.maxWidth, 160); + final geometry = _LosProfileGeometry( + samples: segment.samples, + size: size, + ); + return Stack( + clipBehavior: Clip.none, + children: [ + Positioned.fill( + child: CustomPaint( + painter: _LosProfilePainter( + samples: segment.samples, + distanceUnit: distanceUnit, + heightUnit: heightUnit, + badgeTextStyle: + Theme.of(context).textTheme.labelSmall?.copyWith( + color: Colors.white70, + fontSize: 10, + fontWeight: FontWeight.w600, + ) ?? + const TextStyle( + color: Colors.white70, + fontSize: 10, + fontWeight: FontWeight.w600, + ), + terrainLabel: context.l10n.losLegendTerrain, + losBeamLabel: context.l10n.losLegendLosBeam, + radioHorizonLabel: context.l10n.losLegendRadioHorizon, + selectedSampleIndex: _selectedObstruction?.sampleIndex, + ), + ), + ), + for (final obstruction in segment.obstructions) + Builder( + builder: (context) { + final sample = segment.samples[obstruction.sampleIndex]; + final position = geometry.mapPoint( + sample.distanceMeters, + sample.terrainMeters, + ); + final isSelected = + _selectedObstruction?.sampleIndex == + obstruction.sampleIndex; + final markerSize = isSelected ? 18.0 : 14.0; + final left = (position.dx - markerSize / 2) + .clamp(0.0, math.max(0.0, size.width - markerSize)) + .toDouble(); + final top = (position.dy - markerSize / 2) + .clamp(0.0, math.max(0.0, size.height - markerSize)) + .toDouble(); + return Positioned( + left: left, + top: top, + child: Tooltip( + message: _obstructionChipLabel(obstruction, isImperial), + child: GestureDetector( + onTap: () => _selectObstruction(obstruction), + child: Container( + width: markerSize, + height: markerSize, + decoration: BoxDecoration( + color: isSelected + ? Colors.amberAccent + : Colors.deepOrangeAccent, + shape: BoxShape.circle, + border: Border.all( + color: isSelected + ? Colors.white + : Colors.black87, + width: isSelected ? 2 : 1.5, + ), + boxShadow: const [ + BoxShadow(color: Colors.black45, blurRadius: 4), + ], + ), + ), + ), + ), + ); + }, + ), + ], + ); + }, + ), + ); + } + String _profileStats(LineOfSightResult result, bool isImperial) { final distance = isImperial ? (result.totalDistanceMeters / 1000.0) * _kmToMiles @@ -820,8 +1172,51 @@ class _LineOfSightMapScreenState extends State { return polylines; } - List _buildMarkers(List endpoints) { + List _buildMarkers( + List endpoints, + List obstructions, + ) { return [ + for (final obstruction in obstructions) + Marker( + point: obstruction.point, + width: 52, + height: 52, + child: GestureDetector( + onTap: () => _selectObstruction(obstruction), + child: Center( + child: Container( + width: + _selectedObstruction?.sampleIndex == obstruction.sampleIndex + ? 36 + : 24, + height: + _selectedObstruction?.sampleIndex == obstruction.sampleIndex + ? 36 + : 24, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.transparent, + border: Border.all( + color: + _selectedObstruction?.sampleIndex == + obstruction.sampleIndex + ? Colors.amberAccent + : Colors.deepOrangeAccent, + width: + _selectedObstruction?.sampleIndex == + obstruction.sampleIndex + ? 4 + : 3, + ), + boxShadow: const [ + BoxShadow(color: Colors.black26, blurRadius: 6), + ], + ), + ), + ), + ), + ), for (final endpoint in endpoints) Marker( point: endpoint.point, @@ -1010,6 +1405,51 @@ class _LineOfSightMapScreenState extends State { } } +class _LosProfileGeometry { + static const horizontalPadding = 12.0; + static const verticalPadding = 12.0; + + final List samples; + final Size size; + late final double minY = samples + .map( + (s) => math.min( + math.min(s.terrainMeters, s.lineHeightMeters), + s.refractedHeightMeters, + ), + ) + .reduce(math.min); + late final double maxY = samples + .map( + (s) => math.max( + math.max(s.terrainMeters, s.lineHeightMeters), + s.refractedHeightMeters, + ), + ) + .reduce(math.max); + late final double ySpan = math.max(1.0, maxY - minY); + late final double maxDist = math.max(1.0, samples.last.distanceMeters); + late final double chartWidth = math.max( + 1.0, + size.width - horizontalPadding * 2, + ); + late final double chartHeight = math.max( + 1.0, + size.height - verticalPadding * 2, + ); + + _LosProfileGeometry({required this.samples, required this.size}); + + Offset mapPoint(double distanceMeters, double elevationMeters) { + final px = horizontalPadding + (distanceMeters / maxDist) * chartWidth; + final py = + size.height - + verticalPadding - + ((elevationMeters - minY) / ySpan) * chartHeight; + return Offset(px, py); + } +} + class _LosProfilePainter extends CustomPainter { final List samples; final String distanceUnit; @@ -1018,6 +1458,7 @@ class _LosProfilePainter extends CustomPainter { final String terrainLabel; final String losBeamLabel; final String radioHorizonLabel; + final int? selectedSampleIndex; const _LosProfilePainter({ required this.samples, @@ -1027,6 +1468,7 @@ class _LosProfilePainter extends CustomPainter { required this.terrainLabel, required this.losBeamLabel, required this.radioHorizonLabel, + this.selectedSampleIndex, }); @override @@ -1212,6 +1654,32 @@ class _LosProfilePainter extends CustomPainter { ..color = horizonFillColor ..style = PaintingStyle.fill, ); + + if (selectedSampleIndex != null && + selectedSampleIndex! >= 0 && + selectedSampleIndex! < samples.length) { + final selectedSample = samples[selectedSampleIndex!]; + final selectedPoint = mapPoint( + selectedSample.distanceMeters, + selectedSample.terrainMeters, + ); + canvas.drawLine( + Offset(selectedPoint.dx, verticalPadding), + Offset(selectedPoint.dx, size.height - verticalPadding), + Paint() + ..color = Colors.amberAccent.withValues(alpha: 0.7) + ..strokeWidth = 1.5, + ); + canvas.drawCircle(selectedPoint, 7, Paint()..color = Colors.amberAccent); + canvas.drawCircle( + selectedPoint, + 8.5, + Paint() + ..color = Colors.white + ..style = PaintingStyle.stroke + ..strokeWidth = 1.5, + ); + } } @override @@ -1222,7 +1690,8 @@ class _LosProfilePainter extends CustomPainter { oldDelegate.badgeTextStyle != badgeTextStyle || oldDelegate.terrainLabel != terrainLabel || oldDelegate.losBeamLabel != losBeamLabel || - oldDelegate.radioHorizonLabel != radioHorizonLabel; + oldDelegate.radioHorizonLabel != radioHorizonLabel || + oldDelegate.selectedSampleIndex != selectedSampleIndex; } void _drawUnitBadge(Canvas canvas, Size size) { diff --git a/lib/screens/map_cache_screen.dart b/lib/screens/map_cache_screen.dart index 1eb59a8..4057e0e 100644 --- a/lib/screens/map_cache_screen.dart +++ b/lib/screens/map_cache_screen.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:latlong2/latlong.dart'; @@ -18,6 +19,9 @@ class MapCacheScreen extends StatefulWidget { } class _MapCacheScreenState extends State { + static const double _mapMinZoom = 2.0; + static const double _mapMaxZoom = 18.0; + final MapController _mapController = MapController(); LatLngBounds? _selectedBounds; @@ -43,6 +47,61 @@ class _MapCacheScreenState extends State { super.dispose(); } + bool _isDesktopPlatform(TargetPlatform platform) { + return platform == TargetPlatform.linux || + platform == TargetPlatform.windows || + platform == TargetPlatform.macOS; + } + + void _zoomMapBy(double delta) { + final camera = _mapController.camera; + final nextZoom = (camera.zoom + delta) + .clamp(_mapMinZoom, _mapMaxZoom) + .toDouble(); + _mapController.move(camera.center, nextZoom); + } + + void _resetMapView() { + final bounds = _selectedBounds; + if (bounds != null) { + _mapController.fitCamera( + CameraFit.bounds(bounds: bounds, padding: const EdgeInsets.all(48)), + ); + return; + } + _mapController.move(const LatLng(0, 0), 2.0); + } + + Widget _buildDesktopMapControls() { + return Positioned( + top: 12, + left: 12, + child: Card( + elevation: 4, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + icon: const Icon(Icons.add), + tooltip: 'Zoom in', + onPressed: () => _zoomMapBy(1), + ), + IconButton( + icon: const Icon(Icons.remove), + tooltip: 'Zoom out', + onPressed: () => _zoomMapBy(-1), + ), + IconButton( + icon: const Icon(Icons.my_location), + tooltip: 'Center map', + onPressed: _resetMapView, + ), + ], + ), + ), + ); + } + void _loadSettings() { final settings = context.read().settings; final bounds = MapTileCacheService.boundsFromJson(settings.mapCacheBounds); @@ -222,6 +281,7 @@ class _MapCacheScreenState extends State { final tileCache = context.read(); final selectedBounds = _selectedBounds; final l10n = context.l10n; + final isDesktop = _isDesktopPlatform(defaultTargetPlatform); final progressValue = _estimatedTiles == 0 ? 0.0 : (_completedTiles / _estimatedTiles).clamp(0.0, 1.0).toDouble(); @@ -238,11 +298,24 @@ class _MapCacheScreenState extends State { children: [ FlutterMap( mapController: _mapController, - options: const MapOptions( - initialCenter: LatLng(0, 0), + options: MapOptions( + initialCenter: const LatLng(0, 0), initialZoom: 2.0, - minZoom: 2.0, - maxZoom: 18.0, + minZoom: _mapMinZoom, + maxZoom: _mapMaxZoom, + interactionOptions: InteractionOptions( + flags: ~InteractiveFlag.rotate, + scrollWheelVelocity: isDesktop ? 0.012 : 0.005, + cursorKeyboardRotationOptions: + CursorKeyboardRotationOptions.disabled(), + keyboardOptions: isDesktop + ? const KeyboardOptions( + enableArrowKeysPanning: true, + enableWASDPanning: true, + enableRFZooming: true, + ) + : const KeyboardOptions.disabled(), + ), ), children: [ TileLayer( @@ -265,6 +338,7 @@ class _MapCacheScreenState extends State { ), ], ), + if (isDesktop) _buildDesktopMapControls(), Positioned( top: 12, right: 12, diff --git a/lib/screens/map_screen.dart b/lib/screens/map_screen.dart index 6a8acda..4ae2fd4 100644 --- a/lib/screens/map_screen.dart +++ b/lib/screens/map_screen.dart @@ -1,6 +1,5 @@ import 'dart:collection'; import 'dart:math'; -import 'dart:typed_data'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -16,6 +15,7 @@ import '../connector/meshcore_protocol.dart'; import '../models/app_settings.dart'; import '../models/channel.dart'; import '../models/contact.dart'; +import '../l10n/contact_localization.dart'; import '../services/app_settings_service.dart'; import '../services/path_history_service.dart'; import '../services/map_marker_service.dart'; @@ -37,6 +37,7 @@ import 'line_of_sight_map_screen.dart'; class MapScreen extends StatefulWidget { final LatLng? highlightPosition; final String? highlightLabel; + final String? highlightMarkerKey; final double highlightZoom; final bool hideBackButton; @@ -44,6 +45,7 @@ class MapScreen extends StatefulWidget { super.key, this.highlightPosition, this.highlightLabel, + this.highlightMarkerKey, this.highlightZoom = 15.0, this.hideBackButton = false, }); @@ -55,6 +57,8 @@ class MapScreen extends StatefulWidget { class _MapScreenState extends State { // Zoom level at which node labels start to appear static const double _labelZoomThreshold = 14.0; + static const double _mapMinZoom = 2.0; + static const double _mapMaxZoom = 18.0; final MapController _mapController = MapController(); final MapMarkerService _markerService = MapMarkerService(); @@ -94,6 +98,19 @@ class _MapScreenState extends State { _removedMarkerIds = ids; _removedMarkersLoaded = true; }); + // If this screen was opened to highlight a marker, and that marker + // was previously removed, re-enable it now that we've loaded the saved + // removed IDs. + if (widget.highlightMarkerKey != null && + _removedMarkerIds.contains(widget.highlightMarkerKey)) { + final updated = Set.from(_removedMarkerIds); + updated.remove(widget.highlightMarkerKey); + if (!mounted) return; + setState(() { + _removedMarkerIds = updated; + }); + await _markerService.saveRemovedIds(updated); + } } bool _checkLocationPlausibility(double lat, double lon) { @@ -134,11 +151,62 @@ class _MapScreenState extends State { return zoom.clamp(4.0, 15.0); } + bool _isDesktopPlatform(TargetPlatform platform) { + return platform == TargetPlatform.linux || + platform == TargetPlatform.windows || + platform == TargetPlatform.macOS; + } + + void _zoomMapBy(double delta) { + final camera = _mapController.camera; + final nextZoom = (camera.zoom + delta) + .clamp(_mapMinZoom, _mapMaxZoom) + .toDouble(); + _mapController.move(camera.center, nextZoom); + } + + Widget _buildDesktopMapControls( + BuildContext context, { + required LatLng center, + required double zoom, + required bool hasPathSelector, + }) { + return Positioned( + left: 16, + top: hasPathSelector ? null : 16, + bottom: hasPathSelector ? 16 : null, + child: Card( + elevation: 4, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + icon: const Icon(Icons.add), + tooltip: 'Zoom in', + onPressed: () => _zoomMapBy(1), + ), + IconButton( + icon: const Icon(Icons.remove), + tooltip: 'Zoom out', + onPressed: () => _zoomMapBy(-1), + ), + IconButton( + icon: const Icon(Icons.my_location), + tooltip: 'Center map', + onPressed: () => _mapController.move(center, zoom), + ), + ], + ), + ), + ); + } + @override Widget build(BuildContext context) { return Consumer3( builder: (context, connector, settingsService, pathHistory, child) { final tileCache = context.read(); + final isDesktop = _isDesktopPlatform(defaultTargetPlatform); final settings = settingsService.settings; final allContacts = connector.allContacts; @@ -229,6 +297,24 @@ class _MapScreenState extends State { : [], ); + // Collect polylines for shared markers' history with dashed lines + final List sharedMarkerPolylines = []; + for (final marker in sharedMarkers) { + if (marker.history.isNotEmpty) { + final points = List.from(marker.history); + points.add(marker.position); + sharedMarkerPolylines.add( + Polyline( + points: points, + color: marker.isChannel + ? (marker.isPublicChannel ? Colors.orange : Colors.purple) + : Colors.blue, + strokeWidth: 3, + ), + ); + } + } + // Calculate center and zoom of all nodes, or default to (0, 0) LatLng center = const LatLng(0, 0); double initialZoom = 10.0; @@ -417,10 +503,20 @@ class _MapScreenState extends State { options: MapOptions( initialCenter: center, initialZoom: initialZoom, - minZoom: 2.0, - maxZoom: 18.0, + minZoom: _mapMinZoom, + maxZoom: _mapMaxZoom, interactionOptions: InteractionOptions( flags: ~InteractiveFlag.rotate, + scrollWheelVelocity: isDesktop ? 0.012 : 0.005, + cursorKeyboardRotationOptions: + CursorKeyboardRotationOptions.disabled(), + keyboardOptions: isDesktop + ? const KeyboardOptions( + enableArrowKeysPanning: true, + enableWASDPanning: true, + enableRFZooming: true, + ) + : const KeyboardOptions.disabled(), ), onTap: (_, latLng) { if (_isSelectingPoi) { @@ -475,6 +571,8 @@ class _MapScreenState extends State { ), if (_polylines.isNotEmpty && _isBuildingPathTrace) PolylineLayer(polylines: _polylines), + if (sharedMarkerPolylines.isNotEmpty) + PolylineLayer(polylines: sharedMarkerPolylines), MarkerLayer( markers: [ if (highlightPosition != null) @@ -562,6 +660,13 @@ class _MapScreenState extends State { sharedMarkers.length, guessedLocations.length, ), + if (isDesktop) + _buildDesktopMapControls( + context, + center: center, + zoom: initialZoom, + hasPathSelector: _isBuildingPathTrace, + ), if (_isBuildingPathTrace) _buildPathTraceOverlay(), ], ), @@ -1239,28 +1344,39 @@ class _MapScreenState extends State { } List<_SharedMarker> _collectSharedMarkers(MeshCoreConnector connector) { - final markers = <_SharedMarker>[]; + // Build a _SharedMarker per message (history empty), grouped by dedupe key. + // Afterwards pick the latest per key and fill its history from older ones. + final updatesByKey = >{}; final selfName = connector.selfName ?? 'Me'; + void addUpdate(_SharedMarker update) { + (updatesByKey[update.id] ??= <_SharedMarker>[]).add(update); + } + for (final contact in connector.contacts) { final messages = connector.getMessages(contact); for (final message in messages) { - final payload = _parseMarkerText(message.text); + final payload = parseMarkerText(message.text); if (payload == null) continue; final fromName = message.isOutgoing ? selfName : contact.name; - final id = _buildMarkerId( + final key = buildSharedMarkerKey( sourceId: contact.publicKeyHex, - timestamp: message.timestamp, - text: message.text, + label: payload.label, + fromName: fromName, + flags: payload.flags, + isChannel: false, ); - markers.add( + addUpdate( _SharedMarker( - id: id, + id: key, position: payload.position, - label: payload.label, + label: payload.label.isEmpty + ? context.l10n.map_sharedPin + : payload.label, flags: payload.flags, fromName: fromName, sourceLabel: contact.name, + timestamp: message.timestamp, isChannel: false, isPublicChannel: false, ), @@ -1272,23 +1388,28 @@ class _MapScreenState extends State { final isPublic = _isPublicChannel(channel); final messages = connector.getChannelMessages(channel); for (final message in messages) { - final payload = _parseMarkerText(message.text); + final payload = parseMarkerText(message.text); if (payload == null) continue; - final id = _buildMarkerId( + final key = buildSharedMarkerKey( sourceId: 'channel:${channel.index}', - timestamp: message.timestamp, - text: message.text, + label: payload.label, + fromName: message.senderName, + flags: payload.flags, + isChannel: true, ); - markers.add( + addUpdate( _SharedMarker( - id: id, + id: key, position: payload.position, - label: payload.label, + label: payload.label.isEmpty + ? context.l10n.map_sharedPin + : payload.label, flags: payload.flags, fromName: message.senderName, sourceLabel: channel.name.isEmpty ? 'Channel ${channel.index}' : channel.name, + timestamp: message.timestamp, isChannel: true, isPublicChannel: isPublic, ), @@ -1296,36 +1417,25 @@ class _MapScreenState extends State { } } - return markers; - } - - _MarkerPayload? _parseMarkerText(String text) { - final trimmed = text.trim(); - if (!trimmed.startsWith('m:')) return null; - - final parts = trimmed.substring(2).split('|'); - if (parts.isEmpty) return null; - final coords = parts[0].split(','); - if (coords.length != 2) return null; - final lat = double.tryParse(coords[0].trim()); - final lon = double.tryParse(coords[1].trim()); - if (lat == null || lon == null) return null; - - final label = parts.length > 1 ? parts[1].trim() : ''; - final flags = parts.length > 2 ? parts[2].trim() : ''; - return _MarkerPayload( - position: LatLng(lat, lon), - label: label.isEmpty ? context.l10n.map_sharedPin : label, - flags: flags, - ); - } + final markers = <_SharedMarker>[]; + updatesByKey.forEach((_, updates) { + updates.sort((a, b) => a.timestamp.compareTo(b.timestamp)); + final latest = updates.last; + // History: older positions, drop consecutive duplicates at same position. + final history = []; + for (var i = 0; i < updates.length - 1; i++) { + final p = updates[i].position; + if (history.isEmpty || + history.last.latitude != p.latitude || + history.last.longitude != p.longitude) { + history.add(p); + } + } + markers.add(latest.copyWithHistory(history)); + }); - String _buildMarkerId({ - required String sourceId, - required DateTime timestamp, - required String text, - }) { - return '$sourceId|${timestamp.millisecondsSinceEpoch}|$text'; + markers.sort((a, b) => b.timestamp.compareTo(a.timestamp)); + return markers; } Marker _buildSharedMarker(_SharedMarker marker) { @@ -1337,7 +1447,15 @@ class _MapScreenState extends State { width: 60, height: 60, child: GestureDetector( - onTap: () => _showMarkerInfo(marker), + onTap: () async { + if (_removedMarkerIds.contains(marker.id)) { + setState(() { + _removedMarkerIds.remove(marker.id); + }); + await _markerService.saveRemovedIds(_removedMarkerIds); + } + _showMarkerInfo(marker); + }, child: Column( children: [ Container( @@ -1391,11 +1509,17 @@ class _MapScreenState extends State { room: room, // onLogin(password, isAdmin) isAdmin not used for room caht screen onLogin: (password, _) { - // Navigate to chat screen after successful login - context.read().markContactRead(room.publicKeyHex); + final connector = context.read(); + final unread = connector.getUnreadCountForContactKey( + room.publicKeyHex, + ); + connector.markContactRead(room.publicKeyHex); Navigator.push( context, - MaterialPageRoute(builder: (context) => ChatScreen(contact: room)), + MaterialPageRoute( + builder: (context) => + ChatScreen(contact: room, initialUnreadCount: unread), + ), ); }, ), @@ -1425,23 +1549,29 @@ class _MapScreenState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildInfoRow('Type', contact.typeLabel), - _buildInfoRow('Path', contact.pathLabel), + _buildInfoRow( + context.l10n.map_type, + contact.typeLabel(context.l10n), + ), + _buildInfoRow( + context.l10n.map_path, + contact.pathLabel(context.l10n), + ), if (contact.hasLocation) _buildInfoRow( - 'Location', + context.l10n.map_location, '${contact.latitude!.toStringAsFixed(6)}, ${contact.longitude!.toStringAsFixed(6)}', ) else if (guessedPosition != null) _buildInfoRow( - 'Est. Location', + context.l10n.map_estLocation, '~${guessedPosition.latitude.toStringAsFixed(6)}, ${guessedPosition.longitude.toStringAsFixed(6)}', ), _buildInfoRow( context.l10n.map_lastSeen, _formatLastSeen(contact.lastSeen), ), - _buildInfoRow('Public Key', contact.publicKeyHex), + _buildInfoRow(context.l10n.map_publicKey, contact.publicKeyHex), ], ), actions: [ @@ -1456,11 +1586,17 @@ class _MapScreenState extends State { if (!contact.isActive) { connector.importDiscoveredContact(contact); } + final unread = connector.getUnreadCountForContactKey( + contact.publicKeyHex, + ); Navigator.pop(dialogContext); Navigator.push( context, MaterialPageRoute( - builder: (context) => ChatScreen(contact: contact), + builder: (context) => ChatScreen( + contact: contact, + initialUnreadCount: unread, + ), ), ); }, @@ -1542,7 +1678,9 @@ class _MapScreenState extends State { showDialog( context: context, builder: (dialogContext) => AlertDialog( - title: Text(marker.label), + title: Text( + marker.label.isEmpty ? context.l10n.map_sharedPin : marker.label, + ), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -1550,7 +1688,11 @@ class _MapScreenState extends State { _buildInfoRow(context.l10n.map_from, marker.fromName), _buildInfoRow(context.l10n.map_source, marker.sourceLabel), _buildInfoRow( - 'Location', + context.l10n.map_sharedAt, + _formatLastSeen(marker.timestamp), + ), + _buildInfoRow( + context.l10n.map_location, '${marker.position.latitude.toStringAsFixed(6)}, ${marker.position.longitude.toStringAsFixed(6)}', ), if (marker.flags.isNotEmpty) @@ -1715,6 +1857,10 @@ class _MapScreenState extends State { String defaultLabel, ) async { final controller = TextEditingController(text: defaultLabel); + controller.selection = TextSelection( + baseOffset: 0, + extentOffset: controller.text.length, + ); return showDialog( context: context, builder: (dialogContext) => AlertDialog( @@ -1865,9 +2011,6 @@ class _MapScreenState extends State { color: isPublic ? Colors.orange : Colors.blue, ), title: Text(label), - subtitle: isPublic - ? Text(context.l10n.channels_publicChannel) - : null, onTap: () async { Navigator.pop(sheetContext); final canSend = isPublic @@ -2019,7 +2162,7 @@ class _MapScreenState extends State { enabled: settings.mapKeyPrefixEnabled, decoration: InputDecoration( labelText: context.l10n.map_publicKeyPrefix, - hintText: 'e.g. ab12', + hintText: context.l10n.map_publicKeyPrefixHint, border: const OutlineInputBorder(), isDense: true, ), @@ -2310,18 +2453,50 @@ class _GuessedLocation { }); } -class _MarkerPayload { +class MarkerPayload { final LatLng position; final String label; final String flags; - _MarkerPayload({ + MarkerPayload({ required this.position, required this.label, required this.flags, }); } +/// Parse a shared marker text message of the form +/// `m:,|