mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-06-15 07:04:26 +10:00
Compare commits
6 Commits
ui
...
PRE-BETA-9.5
| Author | SHA1 | Date | |
|---|---|---|---|
| 9957e1fc1f | |||
| e38d03a32e | |||
| ea657a964a | |||
| 760d8e1db3 | |||
| 880df84828 | |||
| 815534d409 |
@@ -41,7 +41,7 @@ lib/
|
||||
├── 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)
|
||||
├── helpers/ # Pure utilities (Smaz compression, GIF parsing, scroll helpers, path hop resolution)
|
||||
├── utils/ # Platform / IO / UX utilities (logger, GPX export, dialogs)
|
||||
├── theme/ # MeshPalette (defined, not yet wired in main.dart)
|
||||
├── l10n/ # ARB localization for 18 locales
|
||||
@@ -194,14 +194,14 @@ enum MeshCoreConnectionState {
|
||||
|
||||
## Dependencies
|
||||
|
||||
App version: `8.0.0+11` — Dart SDK constraint: `^3.9.2`
|
||||
App version: `9.5.0+13` — 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 |
|
||||
| flutter_blue_plus_platform_interface | ^9.0.2 | Platform-interface layer required by flutter_blue_plus |
|
||||
| flserial | git (MeshEnvy fork) | USB serial transport for wired device connections (TODO: upstream pending) |
|
||||
|
||||
**State / Storage**
|
||||
@@ -232,7 +232,7 @@ App version: `8.0.0+11` — Dart SDK constraint: `^3.9.2`
|
||||
|
||||
| Package | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| material_symbols_icons | ^4.2906.0 | Extended Material Symbols icon set (line-of-sight, etc.) |
|
||||
| material_symbols_icons | ^4.2928.1 | 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 |
|
||||
@@ -246,7 +246,7 @@ App version: `8.0.0+11` — Dart SDK constraint: `^3.9.2`
|
||||
|
||||
| Package | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| flutter_local_notifications | ^20.1.0 | Shows local push notifications for incoming messages |
|
||||
| flutter_local_notifications | ^22.0.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**
|
||||
@@ -255,7 +255,8 @@ App version: `8.0.0+11` — Dart SDK constraint: `^3.9.2`
|
||||
|---------|---------|---------|
|
||||
| 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 |
|
||||
| llamadart | ^0.8.0 | On-device LLM inference used in `translation_service.dart` for message translation |
|
||||
| flutter_langdetect | ^0.0.1 | Detects a message's source language in `translation_service.dart` before translating |
|
||||
|
||||
**Misc**
|
||||
|
||||
@@ -263,8 +264,8 @@ App version: `8.0.0+11` — Dart SDK constraint: `^3.9.2`
|
||||
|---------|---------|---------|
|
||||
| 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 |
|
||||
| share_plus | ^13.1.0 | Shares files (e.g. exported GPX tracks) via the system share sheet |
|
||||
| package_info_plus | ^10.1.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) |
|
||||
@@ -333,4 +334,4 @@ PWA scaffold present but boilerplate (`manifest.json` and `index.html` are unmod
|
||||
| `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`) |
|
||||
| `pubspec.yaml` | Dependencies and project metadata (current version `9.5.0+13`) |
|
||||
|
||||
@@ -94,12 +94,12 @@ MeshCore Open is a cross-platform mobile application for communicating with Mesh
|
||||
|---------|---------|
|
||||
| flutter_blue_plus | Bluetooth Low Energy communication |
|
||||
| provider | State management |
|
||||
| sqflite | Local database storage |
|
||||
| shared_preferences | Local key-value storage (scoped per device) |
|
||||
| flutter_map | Interactive map display |
|
||||
| latlong2 | Geographic coordinate handling |
|
||||
| flutter_local_notifications | Background notification support |
|
||||
| smaz | Message compression |
|
||||
| pointycastle | Cryptographic operations |
|
||||
| llamadart | On-device LLM message translation |
|
||||
| intl | Internationalization and date formatting |
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
# This builtInKotlin flag was added automatically by Flutter migrator
|
||||
android.builtInKotlin=false
|
||||
# This newDsl flag was added automatically by Flutter migrator
|
||||
android.newDsl=false
|
||||
|
||||
@@ -198,6 +198,7 @@ Tap the translate button on any received message. On first use, the GGUF model f
|
||||
|
||||
### How It Works
|
||||
- Model files are managed by `TranslationFileStore`; download progress is shown in-place
|
||||
- Before translating, the source language is automatically detected using the `flutter_langdetect` package. If the detected language already matches the target language, translation is skipped
|
||||
- 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
|
||||
|
||||
@@ -56,6 +56,7 @@ enum MeshCoreConnectionState {
|
||||
- `Lilygo`
|
||||
- `HT-`
|
||||
- `LowMesh_MC_`
|
||||
- `NRF52`
|
||||
2. **Connect** with 15-second timeout (6 seconds on Linux)
|
||||
3. **Request MTU** 185 bytes (non-web only)
|
||||
4. **Discover services** and locate NUS
|
||||
@@ -115,13 +116,15 @@ On unexpected disconnection, auto-reconnect with exponential backoff:
|
||||
| 32 | CMD_SET_CHANNEL | Set channel name and PSK |
|
||||
| 36 | CMD_SEND_TRACE_PATH | Request path trace |
|
||||
| 38 | CMD_SET_OTHER_PARAMS | Set misc parameters |
|
||||
| 39 | CMD_GET_TELEMETRY_REQ | Request sensor telemetry |
|
||||
| 39 | CMD_SEND_TELEMETRY_REQ | Request sensor telemetry |
|
||||
| 40 | CMD_GET_CUSTOM_VAR | Get custom variables |
|
||||
| 41 | CMD_SET_CUSTOM_VAR | Set a custom variable |
|
||||
| 50 | CMD_SEND_BINARY_REQ | Send binary request |
|
||||
| 56 | CMD_GET_STATS | Request companion radio stats |
|
||||
| 57 | CMD_SEND_ANON_REQ | Send anonymous request |
|
||||
| 58 | CMD_SET_AUTO_ADD_CONFIG | Set auto-add configuration |
|
||||
| 59 | CMD_GET_AUTO_ADD_CONFIG | Get auto-add configuration |
|
||||
| 61 | CMD_SET_PATH_HASH_MODE | Set path hash width (bytes per hop) |
|
||||
|
||||
## Response / Push Codes (Device → App)
|
||||
|
||||
@@ -145,6 +148,7 @@ On unexpected disconnection, auto-reconnect with exponential backoff:
|
||||
| 17 | RESP_CODE_CHANNEL_MSG_RECV_V3 | Incoming channel message (v3) |
|
||||
| 18 | RESP_CODE_CHANNEL_INFO | Channel definition |
|
||||
| 21 | RESP_CODE_CUSTOM_VARS | Custom variables |
|
||||
| 24 | RESP_CODE_STATS | Companion radio stats |
|
||||
| 25 | RESP_CODE_AUTO_ADD_CONFIG | Auto-add flags |
|
||||
| 0x80 | PUSH_CODE_ADVERT | Known contact re-seen |
|
||||
| 0x81 | PUSH_CODE_PATH_UPDATED | Better path found; carries the 32-byte public key of the updated contact |
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Channels are broadcast group-chat spaces secured by a 16-byte pre-shared key (PSK). Any device with the same channel index and PSK will receive and decrypt channel messages. Unlike direct messages, channel messages are broadcast to the entire mesh.
|
||||
|
||||
Up to 8 channels (indices 0–7) can be active simultaneously on one device.
|
||||
The number of active channels is determined by the firmware (default 40); the device reports its actual limit at login.
|
||||
|
||||
## How to Access
|
||||
|
||||
@@ -17,7 +17,7 @@ QuickSwitchBar tab 1 (middle) from any main screen.
|
||||
| Public | Globe | Green | Fixed well-known PSK; any device can join |
|
||||
| Hashtag | Hash tag | Blue | PSK derived from the hashtag name via SHA-256; discoverable by convention |
|
||||
| Private | Lock | Blue | Random PSK; requires out-of-band sharing of the 32-hex key |
|
||||
| Community | Groups/Tag | Purple | PSK derived via HMAC-SHA256 from a community's shared secret |
|
||||
| Community | Groups/Tag | Magenta | PSK derived via HMAC-SHA256 from a community's shared secret |
|
||||
|
||||
## Channels List Screen
|
||||
|
||||
@@ -26,12 +26,12 @@ QuickSwitchBar tab 1 (middle) from any main screen.
|
||||
- **Search bar** with live text filtering (300ms debounce)
|
||||
- **Sort/filter button**
|
||||
- **Scrollable list of channel cards**, each showing:
|
||||
- Type icon with color coding (purple badge overlay for community channels)
|
||||
- Type icon with color coding (magenta badge overlay for community channels)
|
||||
- Channel name (or "Channel N" if unnamed)
|
||||
- Unread badge (if messages are unread)
|
||||
- Drag handle (when manual sort is active)
|
||||
- **"+" FAB** to add a new channel
|
||||
- **Overflow menu**: Disconnect, Manage Communities (only shown when at least one community exists), Settings
|
||||
- **Overflow menu**: Disconnect, Manage Communities, Settings
|
||||
|
||||
If no channels exist, an empty state with an "Add Public Channel" shortcut is shown. If a search produces no results, a separate "no results" empty state with a search-off icon is shown.
|
||||
|
||||
@@ -59,7 +59,7 @@ Tap the "+" FAB to open a dialog with six options:
|
||||
|
||||
| Action | Description |
|
||||
|---|---|
|
||||
| Edit | Change name, PSK (with a dice icon to generate a random PSK), or SMAZ compression toggle (compresses outgoing messages to allow longer text within the byte limit) |
|
||||
| Edit | Change name, PSK (with a dice icon to generate a random PSK), SMAZ compression toggle (compresses outgoing messages to allow longer text within the byte limit), or Cyr2Lat encoding toggle (transliterates Cyrillic to Latin for compatibility) |
|
||||
| Mute / Unmute | Toggle push notification suppression for this channel |
|
||||
| Delete | Remove the channel from the device (confirmation required) |
|
||||
|
||||
@@ -100,8 +100,7 @@ Tap a channel card to open the channel chat screen.
|
||||
|
||||
### Message Path Viewing
|
||||
|
||||
- **Mobile**: Tap a message bubble to view its routing path
|
||||
- **Desktop**: Long-press/right-click → "Path" (tapping the bubble does nothing on desktop)
|
||||
- **All platforms**: Long-press (or right-click on desktop) a message bubble → "Path"
|
||||
- Opens the Channel Message Path Screen (see [Additional Features](additional-features.md))
|
||||
|
||||
### Context Actions (Long-Press / Right-Click)
|
||||
@@ -109,7 +108,7 @@ Tap a channel card to open the channel chat screen.
|
||||
| Action | Availability | Description |
|
||||
|---|---|---|
|
||||
| Reply | All messages | Triggers reply mode |
|
||||
| Path | Desktop only | Opens message path view |
|
||||
| Path | All messages | 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 |
|
||||
@@ -142,7 +141,7 @@ From the channels screen overflow menu → "Manage Communities". Opens a draggab
|
||||
- **Tap a community** to directly show its QR code for sharing
|
||||
- **Popup menu** per community:
|
||||
- **Show QR** — displays the QR code for sharing with new members
|
||||
- **Delete** — removes the community locally and deletes all associated device channels (confirmation dialog warns how many channels will be removed)
|
||||
- **Leave Community** — removes the community locally and deletes all associated device channels (confirmation dialog warns how many channels will be removed)
|
||||
|
||||
## How Channels Differ from Direct Messages
|
||||
|
||||
|
||||
@@ -18,17 +18,15 @@ From the Contacts screen, tap any Chat-type contact to open the ChatScreen.
|
||||
|
||||
- **Title**: Contact name
|
||||
- **Subtitle**: Current routing path label (e.g., "2 hops", "flood (auto)", "direct (forced)") and unread count. Tapping the subtitle shows the full path details.
|
||||
- **Action buttons**:
|
||||
- **Routing mode** (waves icon): Switch between Auto, Direct, and Flood routing
|
||||
- **Path management** (timeline icon): View recent paths with hop count, round-trip time, age, and success count. Paths are color-coded by direct repeater (green/yellow/red/blue for ranked repeaters, grey for unknown). Tap a path to activate it (the device verifies and confirms via snackbar), long-press to view full path details, set custom paths, or force flood mode. A warning banner appears when history reaches 100 entries.
|
||||
- **Info** (info icon): Contact info dialog showing type, path, GPS coordinates, public key, and SMAZ compression toggle
|
||||
- **Action button**:
|
||||
- **Overflow menu** (⋮ icon): Contains Routing, Info, Telemetry, Settings, and Clear Chat. Routing opens the routing sheet where you can switch between Auto, Direct, and Flood routing and manage recent paths (hop count, round-trip time, age, success count, color-coded by repeater). Info shows a dialog with contact type, path, GPS coordinates, and public key.
|
||||
|
||||
### Message List
|
||||
|
||||
- Scrollable list with newest messages at the bottom
|
||||
- **Outgoing messages**: Right-aligned, primary color background. **Failed messages** change to a red-toned error container background
|
||||
- **Incoming messages**: Left-aligned, grey background with a colored avatar (initial letter or first emoji of sender name; color is deterministic from a hash of the sender name)
|
||||
- Bubble width capped at 65% of screen width
|
||||
- Bubble width capped at 72% of screen width
|
||||
- Hyperlinks rendered as tappable green underlined text
|
||||
- **Pinch-to-zoom**: Two-finger zoom (0.8x–1.8x) and double-tap to reset
|
||||
- **Jump to bottom**: Floating button appears when scrolled away from the bottom
|
||||
@@ -87,7 +85,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 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)
|
||||
3. **Timeout duration**: Preferably from the ML timeout prediction service; otherwise from the device's own `est_timeout` in `RESP_CODE_SENT` (clamped to the physics range); 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). The result is capped at 45 seconds.
|
||||
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"
|
||||
@@ -114,8 +112,9 @@ Add emoji reactions to incoming messages (not your own):
|
||||
| Action | Availability | Description |
|
||||
|---|---|---|
|
||||
| Add reaction | Incoming messages only | Opens emoji picker |
|
||||
| View path | Mobile: tap bubble directly; Desktop: long-press/right-click menu | Shows message routing path |
|
||||
| View path | All platforms: long-press/right-click menu | Shows message routing path |
|
||||
| Copy | All messages | Copies text to clipboard |
|
||||
| Translate | Incoming messages only (when translation is enabled and not yet translated) | Translates the message on-demand using the on-device model |
|
||||
| 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 |
|
||||
|
||||
+17
-18
@@ -6,18 +6,17 @@ The Contacts screen is the primary hub for managing mesh nodes your radio has a
|
||||
|
||||
## How to Access
|
||||
|
||||
- Automatically shown after connecting to a device
|
||||
- QuickSwitchBar tab 0 (leftmost) from Channels or Map screens
|
||||
- QuickSwitchBar tab 0 (leftmost) from Channels or Map screens (Channels is shown first after connecting)
|
||||
- Back navigation from Chat or Settings screens
|
||||
|
||||
## Contact Types
|
||||
|
||||
| Type | Avatar Color | Icon | Description |
|
||||
|---|---|---|---|
|
||||
| Chat | Blue | Chat bubble | Another user's mesh radio |
|
||||
| Repeater | Orange | Cell tower | A mesh repeater/relay node |
|
||||
| Room | Purple | Group | A room server for group chat |
|
||||
| Sensor | Green | Sensors | A sensor device |
|
||||
| Chat | Blue | Initials / emoji | Another user's mesh radio |
|
||||
| Repeater | Amber | Cell tower | A mesh repeater/relay node |
|
||||
| Room | Magenta | Meeting room | A room server for group chat |
|
||||
| Sensor | Teal | Sensors | A sensor device |
|
||||
|
||||
## Contact List
|
||||
|
||||
@@ -73,42 +72,42 @@ Groups are stored per radio identity (scoped by public key).
|
||||
|
||||
| Action | Availability | Description |
|
||||
|---|---|---|
|
||||
| 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 |
|
||||
| Ping | Repeaters only | Opens PathTraceMapScreen targeting the repeater |
|
||||
| Path Trace | Rooms (always); Chat/Sensor only 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) |
|
||||
| Open Chat | Chat/Sensor | Same as single tap |
|
||||
| Add/Remove Favorite | All types | Toggles the favorite flag |
|
||||
| Share Contact | All types | Copies `meshcore://<hex>` URI to clipboard |
|
||||
| Share Contact | All types | Requests advert from device → copies `meshcore://<hex>` URI to clipboard |
|
||||
| Share Contact Zero-Hop | All types | Broadcasts the contact's advertisement one hop |
|
||||
| Delete Contact | All types | Confirmation dialog → removes from device and clears messages |
|
||||
|
||||
## App Bar Menus
|
||||
|
||||
The Contacts screen has **two separate popup menus** in the app bar:
|
||||
The Contacts screen has a single **three-dot overflow menu** (`⋮`) in the app bar:
|
||||
|
||||
**Antenna icon menu** (contact sharing):
|
||||
- Discovered Contacts — opens the DiscoveryScreen
|
||||
- Add Contact from Clipboard — reads a `meshcore://<hex>` URI from clipboard and imports it
|
||||
- *(divider)*
|
||||
- Zero-Hop Advert — broadcasts your advertisement to immediately adjacent nodes
|
||||
- Flood Advert — broadcasts across the full mesh network
|
||||
- Copy Advert to Clipboard — copies your `meshcore://<hex>` URI for sharing externally
|
||||
- Add Contact from Clipboard — reads a `meshcore://<hex>` URI from clipboard and imports it
|
||||
|
||||
**Three-dot overflow menu**:
|
||||
- *(divider)*
|
||||
- Disconnect — disconnects from the device
|
||||
- Discovered Contacts — opens the DiscoveryScreen
|
||||
- Settings — opens the Settings screen
|
||||
|
||||
A **floating action button** (person-add icon) provides a shortcut sheet to "Add Contact from Clipboard" or "Discovered Contacts".
|
||||
|
||||
## Adding Contacts
|
||||
|
||||
### Automatic (Passive)
|
||||
When the radio hears an advertisement, the contact appears automatically if auto-add is enabled for that type (configurable in Settings → Contact Settings).
|
||||
|
||||
### Import from Clipboard
|
||||
Antenna menu → "Add Contact from Clipboard". Reads a `meshcore://<hex>` URI from clipboard and imports it to the device.
|
||||
Overflow menu (or the FAB shortcut) → "Add Contact from Clipboard". Reads a `meshcore://<hex>` URI from clipboard and imports it to the device.
|
||||
|
||||
### Import from Discovered Contacts
|
||||
Overflow menu → "Discovered Contacts". Shows nodes heard passively that haven't been added yet. Tap to immediately import (no confirmation dialog), or long-press for more options (Add, Copy URI, Delete). The Discovery screen has its own search bar, type filters (Users, Repeaters, Rooms, Favorites), and sort options (Last Seen, A-Z). An overflow "Delete All" option clears all discovered contacts.
|
||||
Overflow menu → "Discovered Contacts". Shows nodes heard passively that haven't been added yet. Tap to immediately import (no confirmation dialog), or long-press for more options (Copy URI, Delete). The Discovery screen has its own search bar, type filters (Users, Repeaters, Rooms), and sort options (Last Seen, A-Z). An overflow "Delete All" option clears all discovered contacts.
|
||||
|
||||
## Contact Sharing Format
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@ Location pins shared in chat messages are displayed as flags:
|
||||
|
||||
Tap a pin to see its info. Options to "Hide" (session only) or "Remove" (persistent).
|
||||
|
||||
### Predicted / Guessed Locations (Semi-Transparent)
|
||||
### Predicted / Guessed Locations
|
||||
|
||||
Many contacts on the mesh don't have GPS hardware, so the map has no explicit coordinates for them. Instead of leaving these contacts invisible, the app **infers an approximate position** by analyzing the repeater path the contact's messages travel through. These inferred positions are displayed as semi-transparent markers with a `not_listed_location` icon, visually distinct from confirmed-location markers.
|
||||
Many contacts on the mesh don't have GPS hardware, so the map has no explicit coordinates for them. Instead of leaving these contacts invisible, the app **infers an approximate position** by analyzing the repeater path the contact's messages travel through. These inferred positions are displayed as markers with a `not_listed_location` icon and a muted grey or colored border, visually distinct from confirmed-location markers.
|
||||
|
||||
#### Why guessed locations exist
|
||||
|
||||
@@ -55,19 +55,19 @@ In a mesh network, every message hops through one or more repeaters on its way t
|
||||
|
||||
5. **Compute the estimated position**:
|
||||
- **Single anchor**: The contact is placed on a small circle (330m radius) around the repeater. The angle on the circle is deterministic — derived from an FNV-1a hash of the contact's public key — so the same contact always appears at the same offset, preventing markers from stacking on top of each other.
|
||||
- **Two or more anchors**: The position is the average (centroid) of all anchor coordinates, with a smaller offset radius (80–120m) applied for visual separation.
|
||||
- **Two or more anchors**: The position is a weighted average of all anchor coordinates (each subsequent anchor weighted at half the previous one, biasing toward the first), with a smaller offset radius (120m for 2 anchors, 80m for 3+) applied for visual separation.
|
||||
|
||||
6. **Assign confidence level**:
|
||||
- **High confidence** (2+ anchors): Displayed at 55% opacity.
|
||||
- **Low confidence** (1 anchor): Displayed at 30% opacity.
|
||||
- **High confidence** (2+ anchors): The marker border uses the node's type color (brighter border).
|
||||
- **Low confidence** (1 anchor): The marker border is rendered in a muted grey.
|
||||
|
||||
7. **Cache the result**: The computation is cached using a key derived from the contact's paths, anchor positions, path-history version, and radio parameters. The cache is only invalidated when any of these inputs change, avoiding recomputation on every UI rebuild.
|
||||
|
||||
#### How to read guessed locations on the map
|
||||
|
||||
- **Semi-transparent marker** with a `not_listed_location` icon: This is a guessed position, not a confirmed GPS fix.
|
||||
- **More opaque** (55%): Higher confidence — the contact was seen through 2 or more repeaters with known positions.
|
||||
- **More transparent** (30%): Lower confidence — based on a single repeater anchor only.
|
||||
- **Marker with `not_listed_location` icon**: This is a guessed position, not a confirmed GPS fix.
|
||||
- **Colored border** (type color): Higher confidence — the contact was seen through 2 or more repeaters with known positions.
|
||||
- **Grey border**: Lower confidence — based on a single repeater anchor only.
|
||||
- Coordinates shown in the marker info dialog are prefixed with `~` to indicate they are estimated.
|
||||
- Guessed locations can be toggled on/off in the map filter dialog (FAB → "Guessed locations" toggle).
|
||||
|
||||
@@ -110,9 +110,16 @@ A map with a polyline showing the route from your node through repeater hops to
|
||||
- **Green circles**: Hops with known GPS coordinates
|
||||
- **Orange circles** (`~HH`): Inferred positions (no GPS but deducible from contacts)
|
||||
- **Red endpoint**: Target contact with known GPS
|
||||
- **Purple semi-transparent endpoint**: Target with guessed position
|
||||
- **Magenta endpoint**: Target with guessed position
|
||||
|
||||
A legend card at the bottom lists each hop pair with SNR quality icons and total path distance.
|
||||
A bottom panel shows each hop pair with SNR quality icons and total path distance. When multiple observed paths are available, a **Single / Combined** toggle appears at the top of the map. In Combined view, all paths are overlaid; shared segments are highlighted with a white halo and a path count badge appears on shared nodes.
|
||||
|
||||
The bottom panel also provides **packet animation controls**:
|
||||
- **Animation toggle** (on/off)
|
||||
- **Step back / Play / Step forward / Replay** buttons
|
||||
- **Follow packet lock** — keeps the map camera centered on the moving packet dot
|
||||
- **Speed selector** (0.5×, 1×, 2×, 4×)
|
||||
- A live **"Hop x of y · from → to"** label that tracks the active segment
|
||||
|
||||
### How It Works
|
||||
Sends a trace request frame over the mesh. The repeater network traces the path hop-by-hop and returns per-hop SNR data. For hops without GPS, positions are inferred by averaging GPS coordinates of contacts sharing that last-hop byte.
|
||||
@@ -125,17 +132,17 @@ Sends a trace request frame over the mesh. The repeater network traces the path
|
||||
From the main map, tap the terrain/antenna icon.
|
||||
|
||||
### What the User Sees
|
||||
A full-screen map with a collapsible control panel containing:
|
||||
- **Elevation profile chart**: Terrain fill (green), LOS beam line (white), radio horizon line (yellow)
|
||||
- **Status**: Clear (green) or blocked (red) with distance and minimum clearance
|
||||
- **Options panel**: Node toggles, endpoint dropdowns, antenna height sliders (0–400 ft), Run LOS button
|
||||
A full-screen map with a draggable bottom sheet containing:
|
||||
- **Elevation profile chart**: Terrain fill (green), LOS beam line (white), radio horizon line (yellow); obstruction points are marked as clickable dots on the chart
|
||||
- **Status summary**: Clear (green), Marginal (amber, within 5 m of obstruction), or Blocked (red) with distance and clearance/obstruction amount
|
||||
- **Options section** (collapsible): Node toggles, endpoint dropdowns, antenna height sliders (0–400 ft), Run LOS button
|
||||
|
||||
### Key Interactions
|
||||
- **Long-press the map** to add custom endpoints (orange pushpin markers, renameable/deleteable)
|
||||
- **Long-press the map** to add custom endpoints (pushpin markers, renameable/deleteable)
|
||||
- **Tap a marker** to select it as Point A or B; LOS runs automatically when both are set
|
||||
- **Antenna heights** are adjustable for both endpoints
|
||||
- **Map line** between endpoints is colored green (clear) or red (blocked)
|
||||
- Terrain elevation is fetched from the Open-Meteo API (21–81 sample points, cached 24 hours)
|
||||
- **Map line** between endpoints is colored green (clear), amber (marginal), or red (blocked)
|
||||
- Terrain elevation is fetched from the Open-Meteo API (21, 41, or 81 sample points depending on link distance, cached 24 hours)
|
||||
- K-factor is adjusted per radio frequency from a baseline of 4/3 at 915 MHz
|
||||
|
||||
---
|
||||
@@ -149,7 +156,7 @@ Settings → App Settings → Map Display → Offline Map Cache
|
||||
- Map with a blue polygon overlay showing previously selected cache bounds
|
||||
- Bounding box coordinates card
|
||||
- **Cache Area** controls: "Use Current View" and Clear buttons
|
||||
- **Zoom Range** slider (3–18) with estimated tile count
|
||||
- **Zoom Range** range slider (3–18, dual-handle for min and max) with estimated tile count
|
||||
- **Download progress** bar (when downloading)
|
||||
- **Download Tiles** and **Clear Cache** buttons
|
||||
|
||||
|
||||
+10
-10
@@ -5,7 +5,7 @@
|
||||
The app follows this general flow:
|
||||
|
||||
```
|
||||
Launch → Scanner Screen → [Connect via BLE/USB/TCP] → Contacts Screen
|
||||
Launch → Scanner Screen → [Connect via BLE/USB/TCP] → Channels Screen
|
||||
```
|
||||
|
||||
After connecting, the three main screens (Contacts, Channels, Map) are accessible via a persistent bottom navigation bar called the **QuickSwitchBar**.
|
||||
@@ -24,7 +24,7 @@ Tapping a tab replaces the current screen with a subtle fade + slight horizontal
|
||||
|
||||
## Disconnection
|
||||
|
||||
- The disconnect button (available in the Settings screen and other main screens) shows a confirmation dialog before disconnecting
|
||||
- The disconnect button (available in the overflow menu of each main screen) 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
|
||||
|
||||
@@ -38,11 +38,11 @@ Tapping a tab replaces the current screen with a subtle fade + slight horizontal
|
||||
|
||||
```
|
||||
ScannerScreen (root, always on stack)
|
||||
├─ [BLE connect] → push → ContactsScreen
|
||||
├─ [TCP FAB] → push → TcpScreen
|
||||
│ └─ [TCP connected] → pushReplacement → ContactsScreen
|
||||
└─ [USB FAB] → push → UsbScreen
|
||||
└─ [USB connected] → pushReplacement → ContactsScreen
|
||||
├─ [BLE connect] → push → ChannelsScreen
|
||||
├─ [TCP icon button] → push → TcpScreen
|
||||
│ └─ [TCP connected] → pushReplacement → ChannelsScreen
|
||||
└─ [USB icon button] → push → UsbScreen
|
||||
└─ [USB connected] → pushReplacement → ChannelsScreen
|
||||
|
||||
ContactsScreen (selected=0)
|
||||
├─ [quick-switch 1] → pushReplacement → ChannelsScreen
|
||||
@@ -60,9 +60,9 @@ ChannelsScreen (selected=1)
|
||||
MapScreen (selected=2)
|
||||
├─ [quick-switch 0] → pushReplacement → ContactsScreen
|
||||
├─ [quick-switch 1] → pushReplacement → ChannelsScreen
|
||||
├─ [radar button] → push → PathTraceMapScreen
|
||||
├─ [terrain button] → push → LineOfSightMapScreen
|
||||
└─ [long-press] → share marker / set location
|
||||
├─ [radar menu item] → enters in-map path trace mode (push → PathTraceMapScreen after path is built)
|
||||
├─ [terrain menu item] → push → LineOfSightMapScreen
|
||||
└─ [long-press] → share marker sheet
|
||||
|
||||
Settings (push from any main screen)
|
||||
└─ [App Settings] → push → AppSettingsScreen
|
||||
|
||||
@@ -22,7 +22,7 @@ MeshCore Open provides both **system notifications** (push-style OS alerts) and
|
||||
|
||||
### 3. Advertisement Notifications
|
||||
- **Triggered when**: A new node is discovered on the mesh for the first time
|
||||
- **Title**: "New [type] discovered" (e.g., "New chat node discovered")
|
||||
- **Title**: "New [type] discovered" (e.g., "New Chat discovered")
|
||||
- **Body**: Contact's name
|
||||
- **Priority**: Default
|
||||
- **Android channel**: `adverts`
|
||||
@@ -43,7 +43,7 @@ Red numeric badges appear throughout the UI:
|
||||
- **Contacts list**: Each contact row shows a red pill badge (e.g., "3") for unread messages
|
||||
- **Channels list**: Each channel row shows an unread badge
|
||||
- **Chat screen subtitle**: Shows unread count inline
|
||||
- Badges cap at "99+" for display
|
||||
- Badges cap at "9999+" for display
|
||||
|
||||
### How Unread Counts Work
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ The central management screen showing:
|
||||
|---|---|---|
|
||||
| Status | Repeater Status Screen | All users |
|
||||
| Telemetry | Telemetry Screen | All users |
|
||||
| CLI | Repeater CLI Screen | Admin only |
|
||||
| Neighbors | Neighbors Screen | All users |
|
||||
| CLI | Repeater CLI Screen | Admin only |
|
||||
| Settings | Repeater Settings Screen | Admin only |
|
||||
|
||||
The battery chemistry selector and CLI/Settings cards are hidden from guest users.
|
||||
@@ -89,7 +89,7 @@ A terminal-style interface for sending commands directly to the repeater.
|
||||
- Type a command and press send (or Enter on desktop)
|
||||
- Up/down arrows navigate through command history
|
||||
- Quick-command buttons populate and send common commands
|
||||
- Bug report icon: Shows raw frame debug info for the next typed command (shows error snackbar if input field is empty)
|
||||
- Overflow menu (three-dot icon): "Debug next command" option shows raw frame debug info for the next typed command (shows error snackbar if input field is empty)
|
||||
- Help icon: Opens a scrollable reference of all known CLI commands. Tapping any command populates the input field immediately
|
||||
- Clear icon: Wipes the command/response history
|
||||
- Failed/timed-out commands are automatically retried once
|
||||
@@ -112,7 +112,9 @@ The in-app help reference (help icon) documents all known commands. Categories:
|
||||
|
||||
**Power Management**: `get pwrmgt.support`, `get pwrmgt.source`, `get pwrmgt.bootreason`, `get pwrmgt.bootmv`
|
||||
|
||||
**Sensors**: `sensor get {key}`
|
||||
**Sensors**: `sensor get {key}`, `sensor set {key} {value}`, `sensor list [start]`
|
||||
|
||||
**GPS Management**: `gps`, `gps {on|off}`, `gps sync`, `gps setloc`, `gps advert`, `gps advert {none|share|prefs}`
|
||||
|
||||
**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`
|
||||
|
||||
@@ -207,7 +209,7 @@ Nine configuration cards, each with its own per-field refresh button(s):
|
||||
|
||||
**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)
|
||||
- Erase filesystem (serial-only; shows a confirmation dialog, then an informational snackbar — no command is sent over the air)
|
||||
|
||||
### Key Interactions
|
||||
- **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
|
||||
|
||||
@@ -28,9 +28,11 @@ The BLE Scanner is the app's home screen, displayed immediately on launch.
|
||||
|
||||
**Device List**: When no devices are found, shows a large Bluetooth icon with a prompt. The prompt text is dynamic: "Searching for devices..." while actively scanning, or "Tap Scan to search" when idle. When devices are found, shows a scrollable list of `DeviceTile` widgets.
|
||||
|
||||
**Bottom FAB Row**: Up to three floating action buttons:
|
||||
- **USB** button - Opens USB connection screen (Android, Windows, Linux, macOS, Chrome web only)
|
||||
- **TCP/IP** button - Opens TCP connection screen (all non-web platforms)
|
||||
**App Bar Actions**: Icon buttons in the top-right corner of the app bar:
|
||||
- **USB** icon button - Opens USB connection screen (Android, Windows, Linux, macOS, Chrome web only)
|
||||
- **TCP/IP** icon button - Opens TCP connection screen (all non-web platforms)
|
||||
|
||||
**Bottom FAB**: A single floating action button:
|
||||
- **BLE Scan** button - Toggles BLE scanning on/off; shows a spinner when scanning. **Disabled** (greyed out, not tappable) when Bluetooth is off
|
||||
|
||||
### Device Tile
|
||||
@@ -51,7 +53,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 one of the known prefixes: `MeshCore-`, `Whisper-`, `WisCore-`, `Seeed`, `Lilygo`, `HT-`, `LowMesh_MC_`
|
||||
- Filters for devices advertising the Nordic UART Service UUID (so community forks with non-standard names are still found). Known name prefixes used by stock firmware builds for reference: `MeshCore-`, `Whisper-`, `WisCore-`, `Seeed`, `Lilygo`, `HT-`, `LowMesh_MC_`, `NRF52`
|
||||
- Uses low-latency scan mode on Android
|
||||
- Scans for 10 seconds then auto-stops
|
||||
- On iOS/macOS, waits for BLE adapter initialization before starting
|
||||
@@ -65,7 +67,7 @@ Tap a device tile or its Connect button:
|
||||
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
|
||||
6. On success, automatically navigates to the Contacts screen
|
||||
6. On success, automatically navigates to the Channels screen
|
||||
7. On failure, shows a red error snackbar
|
||||
|
||||
---
|
||||
@@ -74,7 +76,7 @@ Tap a device tile or its Connect button:
|
||||
|
||||
### How to Access
|
||||
|
||||
From the Scanner screen, tap the **USB** FAB button.
|
||||
From the Scanner screen, tap the **USB** icon button in the app bar.
|
||||
|
||||
### What the User Sees
|
||||
|
||||
@@ -82,15 +84,15 @@ From the Scanner screen, tap the **USB** FAB button.
|
||||
- A list of detected USB serial ports, each showing:
|
||||
- Friendly display name
|
||||
- Raw port name (subtitle, only shown when it differs from the display name)
|
||||
- "Connect" button
|
||||
- FABs at the bottom to switch to BLE or TCP (these use `pushReplacement`, so back navigation returns to Scanner, not between USB/TCP)
|
||||
- Chevron trailing icon (the entire tile is tappable to connect)
|
||||
- Transport switcher buttons (outlined, not FABs) to switch to BLE or TCP (these use `pushReplacement`, so back navigation returns to Scanner, not between USB/TCP)
|
||||
|
||||
### Key Interactions
|
||||
|
||||
- On desktop (Windows, Linux, macOS): ports are polled every 2 seconds for hot-plug detection (polling pauses while connecting/connected)
|
||||
- On mobile: tap the "Scan" FAB to manually refresh
|
||||
- Tap a port or its Connect button to connect
|
||||
- On successful connection, navigates to Contacts screen
|
||||
- Tap a port tile to connect
|
||||
- On successful connection, navigates to Channels screen
|
||||
- On connection failure, the port list automatically refreshes
|
||||
- Platform-specific error messages for common USB failures (permission denied, device missing, device detached, device busy, driver missing, port invalid, timeout, and more)
|
||||
|
||||
@@ -100,7 +102,7 @@ From the Scanner screen, tap the **USB** FAB button.
|
||||
|
||||
### How to Access
|
||||
|
||||
From the Scanner screen, tap the **TCP/IP** FAB button.
|
||||
From the Scanner screen, tap the **TCP/IP** icon button in the app bar.
|
||||
|
||||
### What the User Sees
|
||||
|
||||
@@ -108,7 +110,7 @@ From the Scanner screen, tap the **TCP/IP** FAB button.
|
||||
- **Host address** text field
|
||||
- **Port number** text field
|
||||
- **Connect** button
|
||||
- FABs at the bottom to switch to USB or BLE
|
||||
- Transport switcher buttons (outlined, not FABs) to switch to USB or BLE
|
||||
|
||||
### Key Interactions
|
||||
|
||||
@@ -119,6 +121,6 @@ From the Scanner screen, tap the **TCP/IP** FAB button.
|
||||
- Validation errors are shown as red snackbars
|
||||
- The Connect button shows a spinner and "Connecting..." label while in progress
|
||||
- The status bar shows the specific host:port being connected to (e.g., "Connecting to 192.168.1.1:5000")
|
||||
- On success, navigates to Contacts screen and saves the host/port to settings
|
||||
- On success, navigates to Channels screen and saves the host/port to settings
|
||||
- On connection, the status bar shows the active TCP endpoint (e.g., "Connected to 192.168.1.1:5000")
|
||||
- Error messages for timeout, unsupported platform, and connection failures
|
||||
|
||||
+92
-74
@@ -12,12 +12,13 @@ Settings are only accessible while a device is connected.
|
||||
The settings screen is a scrollable list of cards:
|
||||
|
||||
1. [Device Info](#device-info)
|
||||
2. [App Settings](#app-settings) (link to sub-screen)
|
||||
3. [Node Settings](#node-settings)
|
||||
4. [Actions](#actions)
|
||||
5. [Debug](#debug)
|
||||
2. [Node Settings](#node-settings)
|
||||
3. [Location](#location)
|
||||
4. [App Settings](#app-settings) (link to sub-screen)
|
||||
5. [Actions](#actions)
|
||||
6. [Export](#export)
|
||||
7. [About](#about)
|
||||
7. [Debug](#debug)
|
||||
8. [About](#about)
|
||||
|
||||
---
|
||||
|
||||
@@ -40,56 +41,6 @@ Battery shows an alert icon and orange text when at 15% or below. The toggle onl
|
||||
|
||||
---
|
||||
|
||||
## App Settings
|
||||
|
||||
A dedicated sub-screen for app-level preferences (nothing here is sent to the device). All settings persist locally via SharedPreferences.
|
||||
|
||||
### Appearance
|
||||
- **Theme**: System / Light / Dark
|
||||
- **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
|
||||
- **Master enable/disable**: Requests OS permission when enabling
|
||||
- **Message notifications**: New direct message alerts
|
||||
- **Channel message notifications**: New channel message alerts
|
||||
- **Advertisement notifications**: New node discovery alerts
|
||||
|
||||
### 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)
|
||||
- Success Increment (0.1–2.0, default 0.5, 0.1 steps)
|
||||
- Failure Decrement (0.1–2.0, default 0.2, 0.1 steps)
|
||||
- Max Message Retries (2–10, default 5)
|
||||
|
||||
### 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
|
||||
- **Show Other Nodes**: Toggle room/sensor markers
|
||||
- **Time Filter**: All time / Last 1h / Last 6h / Last 24h / Last week
|
||||
- **Units**: Metric / Imperial
|
||||
- **Offline Map Cache**: Navigate to tile download screen
|
||||
|
||||
### Debug
|
||||
- **App Debug Logging**: Enable the in-app debug log
|
||||
|
||||
---
|
||||
|
||||
## Node Settings
|
||||
|
||||
These settings are sent directly to the connected device firmware.
|
||||
@@ -101,7 +52,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**: Regional presets — selecting a preset immediately fills all fields below. Includes presets for 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, numerous Russia city presets, Switzerland, USA Arizona, USA/Canada, and Vietnam
|
||||
- **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
|
||||
@@ -109,6 +60,13 @@ Opens a dialog pre-populated with the device's current radio settings. Contains:
|
||||
- **TX Power** (dBm): Validated 0 to device max (typically 22 dBm)
|
||||
- **Client Repeat** toggle: Only shown on firmware v9+; requires frequency to be exactly 433.000, 869.000, or 918.000 MHz (the Off-Grid presets). Save is blocked with a warning if enabled on other frequencies
|
||||
|
||||
### Companion Radio Stats
|
||||
Opens the RF statistics screen (RSSI, SNR, packet counts) for the paired radio. Only enabled when connected to a device that supports companion radio stats.
|
||||
|
||||
---
|
||||
|
||||
## Location
|
||||
|
||||
### Location
|
||||
Opens a dialog pre-populated with the device's current coordinates (if known):
|
||||
- Latitude and longitude fields (decimal, 6 decimal places). If only one field is provided, the other uses the device's current value
|
||||
@@ -125,8 +83,68 @@ Five toggles controlling which node types are auto-added when heard:
|
||||
- Auto-add Sensors
|
||||
- Overwrite Oldest (when contact list is full)
|
||||
|
||||
### Privacy Mode
|
||||
Opens a confirmation dialog with three buttons: Cancel, Enable, and Disable. Both states can be set from the same dialog regardless of current state. A snackbar confirms which state was applied. When on, the node stops broadcasting its location in advertisements.
|
||||
### Privacy
|
||||
Opens a dialog with controls for how the node shares telemetry and location data:
|
||||
- **Advert Location**: Toggle whether the node broadcasts its location in advertisements
|
||||
- **Multi-Ack**: Toggle multi-ack delivery confirmations
|
||||
- **Telemetry Base Mode**: Deny All / Allow by Contact / Allow All
|
||||
- **Telemetry Location Mode**: Deny All / Allow by Contact / Allow All
|
||||
- **Telemetry Environment Mode**: Deny All / Allow by Contact / Allow All
|
||||
|
||||
Settings take effect when saved. A snackbar confirms the update.
|
||||
|
||||
---
|
||||
|
||||
## App Settings
|
||||
|
||||
A dedicated sub-screen for app-level preferences (nothing here is sent to the device). All settings persist locally via SharedPreferences.
|
||||
|
||||
### Appearance
|
||||
- **Theme**: System / Light / Dark
|
||||
- **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)
|
||||
|
||||
### Notifications
|
||||
- **Master enable/disable**: Requests OS permission when enabling
|
||||
- **Message notifications**: New direct message alerts
|
||||
- **Channel message notifications**: New channel message alerts
|
||||
- **Advertisement notifications**: New node discovery alerts
|
||||
|
||||
### 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)
|
||||
- Success Increment (0.1–2.0, default 0.5, 0.1 steps)
|
||||
- Failure Decrement (0.1–2.0, default 0.2, 0.1 steps)
|
||||
- Max Message Retries (2–10, default 5)
|
||||
- **Enable Message Tracing**: Shows path trace overlays and extra metadata on messages
|
||||
|
||||
### Battery
|
||||
- **Battery Chemistry**: NMC / LiFePO4 / LiPo (per device, used to calibrate percentage from voltage)
|
||||
|
||||
### Map Display
|
||||
- **Show Repeaters**: Toggle repeater markers on map
|
||||
- **Show Chat Nodes**: Toggle chat node markers
|
||||
- **Show Other Nodes**: Toggle room/sensor markers
|
||||
- **Time Filter**: All time / Last 1h / Last 6h / Last 24h / Last week
|
||||
- **Units**: Metric / Imperial
|
||||
- **Offline Map Cache**: Navigate to tile download screen
|
||||
|
||||
### 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
|
||||
|
||||
### Cyrillic-to-Latin (Cyr2Lat)
|
||||
Controls character substitution profiles used to render Cyrillic text in Latin characters. A dropdown selects the active profile; Add, Edit, and Delete buttons manage the profile list (the last remaining profile cannot be deleted). Each profile stores a JSON character map.
|
||||
|
||||
### Debug
|
||||
- **App Debug Logging**: Enable the in-app debug log
|
||||
|
||||
---
|
||||
|
||||
@@ -136,10 +154,24 @@ One-tap device operations:
|
||||
|
||||
| Action | Description |
|
||||
|---|---|
|
||||
| Send Advertisement | Floods the mesh with your node's advertisement |
|
||||
| Sync Time | Sends current Unix timestamp to the device |
|
||||
| Refresh Contacts | Re-requests the full contact list |
|
||||
| Reboot Device | Confirmation dialog → reboots the device (shown in orange) |
|
||||
| Reboot Device | Confirmation dialog → reboots the device (shown in warning color) |
|
||||
| Delete All Paths | Confirmation dialog → clears all stored routing paths (shown in alert color) |
|
||||
|
||||
---
|
||||
|
||||
## Export
|
||||
|
||||
Three GPX export options (not available on web):
|
||||
|
||||
| Option | Exports |
|
||||
|---|---|
|
||||
| Export Repeaters | Repeaters and Rooms with GPS coordinates |
|
||||
| Export Contacts | Chat contacts with GPS coordinates |
|
||||
| Export All | All contacts with GPS coordinates |
|
||||
|
||||
Each creates a `.gpx` file and opens the OS share sheet. Feedback via snackbar for four outcomes: success, no contacts with coordinates, feature not available (web), or error.
|
||||
|
||||
---
|
||||
|
||||
@@ -160,20 +192,6 @@ Structured log entries (Info / Warning / Error), with tag, message, and timestam
|
||||
|
||||
---
|
||||
|
||||
## Export
|
||||
|
||||
Three GPX export options (not available on web):
|
||||
|
||||
| Option | Exports |
|
||||
|---|---|
|
||||
| Export Repeaters | Repeaters and Rooms with GPS coordinates |
|
||||
| Export Contacts | Chat contacts with GPS coordinates |
|
||||
| Export All | All contacts with GPS coordinates |
|
||||
|
||||
Each creates a `.gpx` file and opens the OS share sheet. Feedback via snackbar for four outcomes: success, no contacts with coordinates, feature not available (web), or error.
|
||||
|
||||
---
|
||||
|
||||
## About
|
||||
|
||||
Shows the standard Flutter about dialog with app name, version, and legal notice.
|
||||
|
||||
@@ -4459,24 +4459,27 @@ class MeshCoreConnector extends ChangeNotifier {
|
||||
secondsSinceLastRx: secSinceRx,
|
||||
);
|
||||
if (mlTimeout != null) {
|
||||
// Use device est_timeout as an additional ceiling when available —
|
||||
// the firmware computed it from real airtime, so it's better than
|
||||
// a physics guess built on a 50 ms fallback.
|
||||
final ceiling = deviceTimeoutMs != null && deviceTimeoutMs > physicsMin
|
||||
// Use device est_timeout as a baseline floor when available —
|
||||
// the firmware computed it from real airtime. Let the learned ML
|
||||
// estimate widen above it up to the hard cap, but never below it.
|
||||
final floor = deviceTimeoutMs != null && deviceTimeoutMs > physicsMin
|
||||
? deviceTimeoutMs.clamp(physicsMin, _hardMaxTimeoutMs)
|
||||
: physicsMax;
|
||||
: physicsMin.clamp(0, _hardMaxTimeoutMs);
|
||||
if (pathLength < 0) {
|
||||
// Flood: trust ML, only enforce firmware formula as floor
|
||||
if (mlTimeout < physicsMin) {
|
||||
return physicsMin.clamp(0, _hardMaxTimeoutMs);
|
||||
// Flood: trust ML, only enforce firmware estimate as floor
|
||||
if (mlTimeout < floor) {
|
||||
return floor.clamp(0, _hardMaxTimeoutMs);
|
||||
}
|
||||
}
|
||||
return mlTimeout.clamp(physicsMin, ceiling).clamp(0, _hardMaxTimeoutMs);
|
||||
return mlTimeout.clamp(floor, _hardMaxTimeoutMs);
|
||||
}
|
||||
|
||||
// No ML data — prefer device est_timeout (it used real airtime), then physics.
|
||||
// Cap the floor to the hard maximum so slow-flood physicsMin cannot exceed
|
||||
// the upper bound and make clamp() throw.
|
||||
if (deviceTimeoutMs != null && deviceTimeoutMs > 0) {
|
||||
return deviceTimeoutMs.clamp(physicsMin, _hardMaxTimeoutMs);
|
||||
final floor = physicsMin.clamp(0, _hardMaxTimeoutMs);
|
||||
return deviceTimeoutMs.clamp(floor, _hardMaxTimeoutMs);
|
||||
}
|
||||
return physicsMax.clamp(0, _hardMaxTimeoutMs);
|
||||
}
|
||||
|
||||
+337
-243
File diff suppressed because it is too large
Load Diff
+537
-337
File diff suppressed because it is too large
Load Diff
+471
-271
File diff suppressed because it is too large
Load Diff
+425
-204
File diff suppressed because it is too large
Load Diff
+1123
-1029
File diff suppressed because it is too large
Load Diff
+514
-239
File diff suppressed because it is too large
Load Diff
+562
-366
File diff suppressed because it is too large
Load Diff
+367
-174
@@ -5,8 +5,8 @@
|
||||
"nav_channels": "채널",
|
||||
"nav_map": "지도",
|
||||
"common_cancel": "취소",
|
||||
"common_ok": "알겠습니다",
|
||||
"common_connect": "연결",
|
||||
"common_ok": "확인",
|
||||
"common_connect": "연결하기",
|
||||
"common_unknownDevice": "알 수 없는 장치",
|
||||
"common_save": "저장",
|
||||
"common_delete": "삭제",
|
||||
@@ -16,21 +16,21 @@
|
||||
"common_add": "추가",
|
||||
"common_settings": "설정",
|
||||
"common_disconnect": "연결 해제",
|
||||
"common_connected": "연결된",
|
||||
"common_disconnected": "단절",
|
||||
"common_create": "만들다",
|
||||
"common_connected": "연결됨",
|
||||
"common_disconnected": "연결 해제됨",
|
||||
"common_create": "만들기",
|
||||
"common_continue": "계속",
|
||||
"common_share": "공유",
|
||||
"common_copy": "복사",
|
||||
"common_retry": "다시 시도",
|
||||
"common_hide": "숨기다",
|
||||
"common_hide": "숨기기",
|
||||
"common_remove": "제거",
|
||||
"common_enable": "활성화",
|
||||
"common_disable": "비활성화",
|
||||
"common_enable": "사용",
|
||||
"common_disable": "사용 안 함",
|
||||
"common_autoRefresh": "자동 새로고침",
|
||||
"common_interval": "간격",
|
||||
"common_reboot": "재부팅",
|
||||
"common_loading": "로딩 중...",
|
||||
"common_loading": "불러오는 중...",
|
||||
"common_notAvailable": "—",
|
||||
"common_voltageValue": "{volts} V",
|
||||
"@common_voltageValue": {
|
||||
@@ -48,16 +48,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"scanner_title": "MeshCore 공개",
|
||||
"scanner_title": "MeshCore Open",
|
||||
"connectionChoiceUsbLabel": "USB",
|
||||
"connectionChoiceBluetoothLabel": "블루투스",
|
||||
"connectionChoiceTcpLabel": "TCP",
|
||||
"tcpScreenTitle": "TCP를 통해 연결",
|
||||
"tcpHostLabel": "IP 주소",
|
||||
"tcpHostHint": "192.168.40.10",
|
||||
"tcpPortLabel": "항",
|
||||
"tcpHostHint": "192.168.40.10 / example.com",
|
||||
"tcpPortLabel": "포트",
|
||||
"tcpPortHint": "5000",
|
||||
"tcpStatus_notConnected": "목적지 주소 입력 후 연결",
|
||||
"tcpStatus_notConnected": "엔드포인트를 입력한 뒤 연결하세요.",
|
||||
"tcpStatus_connectingTo": "{endpoint}에 연결 중...",
|
||||
"@tcpStatus_connectingTo": {
|
||||
"placeholders": {
|
||||
@@ -80,21 +80,21 @@
|
||||
},
|
||||
"usbScreenTitle": "USB를 통해 연결",
|
||||
"usbScreenSubtitle": "감지된 시리얼 장치를 선택하고 MeshCore 노드에 직접 연결하십시오.",
|
||||
"usbScreenStatus": "USB 장치를 선택합니다.",
|
||||
"usbScreenNote": "USB 직렬 통신은 지원되는 안드로이드 장치 및 데스크톱 플랫폼에서 활성화됩니다.",
|
||||
"usbScreenEmptyState": "USB 장치가 탐지되지 않았습니다. USB 장치를 연결하고 다시 시도해 보세요.",
|
||||
"usbScreenStatus": "USB 장치를 선택하세요.",
|
||||
"usbScreenNote": "USB 직렬 통신은 지원되는 Android 기기 및 데스크톱 플랫폼에서 사용할 수 있습니다.",
|
||||
"usbScreenEmptyState": "USB 장치가 없습니다. 하나 연결한 뒤 새로고침하세요.",
|
||||
"usbErrorPermissionDenied": "USB 접근 권한이 거부되었습니다.",
|
||||
"usbErrorDeviceMissing": "선택한 USB 장치는 더 이상 사용 불가능합니다.",
|
||||
"usbErrorDeviceMissing": "선택한 USB 장치를 더 이상 사용할 수 없습니다.",
|
||||
"usbErrorInvalidPort": "유효한 USB 장치를 선택하세요.",
|
||||
"usbErrorBusy": "또 다른 USB 연결 요청이 이미 진행 중입니다.",
|
||||
"usbErrorBusy": "다른 USB 연결 요청이 이미 진행 중입니다.",
|
||||
"usbErrorNotConnected": "USB 장치가 연결되지 않았습니다.",
|
||||
"usbErrorOpenFailed": "선택한 USB 장치를 열 수 없습니다.",
|
||||
"usbErrorConnectFailed": "선택한 USB 장치에 연결에 실패했습니다.",
|
||||
"usbErrorConnectFailed": "선택한 USB 장치에 연결하지 못했습니다.",
|
||||
"usbErrorUnsupported": "이 플랫폼에서는 USB 직렬 통신을 지원하지 않습니다.",
|
||||
"usbErrorAlreadyActive": "USB 연결이 이미 활성화되어 있습니다.",
|
||||
"usbErrorAlreadyActive": "USB 연결이 이미 활성 상태입니다.",
|
||||
"usbErrorNoDeviceSelected": "USB 장치가 선택되지 않았습니다.",
|
||||
"usbErrorPortClosed": "USB 연결이 활성화되지 않았습니다.",
|
||||
"usbErrorConnectTimedOut": "연결이 시간 초과되었습니다. 장치가 USB Companion 펌웨어를 가지고 있는지 확인해 주세요.",
|
||||
"usbErrorPortClosed": "USB 연결이 열려 있지 않습니다.",
|
||||
"usbErrorConnectTimedOut": "연결 시간이 초과되었습니다. 장치에 USB Companion 펌웨어가 있는지 확인하세요.",
|
||||
"usbFallbackDeviceName": "웹 시리얼 장치",
|
||||
"usbStatus_notConnected": "USB 장치를 선택합니다.",
|
||||
"usbStatus_connecting": "USB 장치에 연결 중...",
|
||||
@@ -131,13 +131,13 @@
|
||||
},
|
||||
"scanner_stop": "멈춰",
|
||||
"scanner_scan": "스캔",
|
||||
"scanner_bluetoothOff": "블루투스는 꺼져 있습니다.",
|
||||
"scanner_bluetoothOffMessage": "블루투스를 켜서 장치를 검색해주세요.",
|
||||
"scanner_chromeRequired": "크롬 브라우저 필요",
|
||||
"scanner_chromeRequiredMessage": "이 웹 애플리케이션은 블루투드 지원을 위해 Google Chrome 또는 Chromium 기반 브라우저가 필요합니다.",
|
||||
"scanner_enableBluetooth": "블루투스 활성화",
|
||||
"scanner_bluetoothOff": "블루투스가 꺼져 있습니다.",
|
||||
"scanner_bluetoothOffMessage": "기기를 검색하려면 블루투스를 켜세요.",
|
||||
"scanner_chromeRequired": "Chrome 브라우저 필요",
|
||||
"scanner_chromeRequiredMessage": "이 웹 앱은 블루투스 지원을 위해 Google Chrome 또는 Chromium 기반 브라우저가 필요합니다.",
|
||||
"scanner_enableBluetooth": "블루투스 켜기",
|
||||
"device_quickSwitch": "빠른 전환",
|
||||
"device_meshcore": "메쉬코어",
|
||||
"device_meshcore": "MeshCore",
|
||||
"settings_title": "설정",
|
||||
"settings_deviceInfo": "장치 정보",
|
||||
"settings_appSettings": "앱 설정",
|
||||
@@ -148,7 +148,7 @@
|
||||
"settings_nodeNameHint": "노드 이름을 입력하세요",
|
||||
"settings_nodeNameUpdated": "이름 변경",
|
||||
"settings_radioSettings": "라디오 설정",
|
||||
"settings_radioSettingsSubtitle": "주파수, 전력, 스펙트럼",
|
||||
"settings_radioSettingsSubtitle": "주파수, 전력, 확산 계수",
|
||||
"settings_radioSettingsUpdated": "라디오 설정이 업데이트되었습니다.",
|
||||
"settings_location": "위치",
|
||||
"settings_locationSubtitle": "GPS 좌표",
|
||||
@@ -169,26 +169,26 @@
|
||||
"settings_privacyModeEnabled": "개인 정보 보호 모드 활성화",
|
||||
"settings_privacyModeDisabled": "개인 정보 보호 모드 비활성화",
|
||||
"settings_actions": "행동",
|
||||
"settings_deleteAllPaths": "Delete All Paths",
|
||||
"settings_deleteAllPathsSubtitle": "Clear all path data from contacts.",
|
||||
"settings_deleteAllPaths": "모든 경로 삭제",
|
||||
"settings_deleteAllPathsSubtitle": "연락처의 모든 경로 데이터를 지웁니다.",
|
||||
"settings_sendAdvertisement": "광고 전송",
|
||||
"settings_sendAdvertisementSubtitle": "방송 활동",
|
||||
"settings_advertisementSent": "광고 전송",
|
||||
"settings_syncTime": "동기화 시간",
|
||||
"settings_sendAdvertisementSubtitle": "현재 존재를 방송합니다.",
|
||||
"settings_advertisementSent": "광고가 전송되었습니다.",
|
||||
"settings_syncTime": "시간 동기화",
|
||||
"settings_syncTimeSubtitle": "장치 시계를 휴대폰 시간으로 설정",
|
||||
"settings_timeSynchronized": "시간 동기화",
|
||||
"settings_refreshContacts": "연락처 갱신",
|
||||
"settings_timeSynchronized": "시간이 동기화되었습니다.",
|
||||
"settings_refreshContacts": "연락처 새로고침",
|
||||
"settings_refreshContactsSubtitle": "장치에서 연락처 목록을 다시 불러오기",
|
||||
"settings_rebootDevice": "장치 재부팅",
|
||||
"settings_rebootDeviceSubtitle": "MeshCore 장치를 재부팅하세요.",
|
||||
"settings_rebootDeviceConfirm": "정말로 장치를 재부팅하시겠습니까? 이 경우 연결이 끊어집니다.",
|
||||
"settings_debug": "디버깅",
|
||||
"settings_rebootDeviceSubtitle": "MeshCore 장치를 재부팅합니다.",
|
||||
"settings_rebootDeviceConfirm": "정말 장치를 재부팅하시겠습니까? 연결이 끊어집니다.",
|
||||
"settings_debug": "디버그",
|
||||
"settings_bleDebugLog": "BLE 디버그 로그",
|
||||
"settings_bleDebugLogSubtitle": "BLE 명령어, 응답 및 원시 데이터",
|
||||
"settings_appDebugLog": "앱 디버깅 로그",
|
||||
"settings_appDebugLogSubtitle": "애플리케이션 디버깅 메시지",
|
||||
"settings_about": "소개",
|
||||
"settings_aboutVersion": "MeshCore Open {version} 버전",
|
||||
"settings_bleDebugLogSubtitle": "BLE 명령, 응답 및 원시 데이터",
|
||||
"settings_appDebugLog": "앱 디버그 로그",
|
||||
"settings_appDebugLogSubtitle": "애플리케이션 디버그 메시지",
|
||||
"settings_about": "정보",
|
||||
"settings_aboutVersion": "MeshCore Open v{version}",
|
||||
"@settings_aboutVersion": {
|
||||
"placeholders": {
|
||||
"version": {
|
||||
@@ -196,8 +196,8 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings_aboutLegalese": "2026년 MeshCore 오픈 소스 프로젝트",
|
||||
"settings_aboutDescription": "MeshCore LoRa 메시 네트워크 장치를 위한 오픈 소스 Flutter 클라이언트.",
|
||||
"settings_aboutLegalese": "2026 MeshCore 오픈 소스 프로젝트",
|
||||
"settings_aboutDescription": "MeshCore LoRa 메시 네트워크 장치를 위한 오픈소스 Flutter 클라이언트.",
|
||||
"settings_aboutOpenMeteoAttribution": "LOS 고도 데이터: Open-Meteo (CC BY 4.0)",
|
||||
"settings_infoName": "이름",
|
||||
"settings_infoId": "ID",
|
||||
@@ -206,19 +206,19 @@
|
||||
"settings_infoPublicKey": "공개 키",
|
||||
"settings_infoContactsCount": "연락처 수",
|
||||
"settings_infoChannelCount": "채널 수",
|
||||
"settings_presets": "기본 설정",
|
||||
"settings_presets": "프리셋",
|
||||
"settings_frequency": "주파수 (MHz)",
|
||||
"settings_frequencyHelper": "300.0 - 2500.0",
|
||||
"settings_frequencyInvalid": "유효하지 않은 주파수 (300-2500 MHz)",
|
||||
"settings_bandwidth": "대역폭",
|
||||
"settings_spreadingFactor": "분산 계수",
|
||||
"settings_codingRate": "코딩 속도",
|
||||
"settings_txPower": "TX 전력 (dBm)",
|
||||
"settings_txPower": "송신 전력 (dBm)",
|
||||
"settings_txPowerHelper": "0 - 22",
|
||||
"settings_txPowerInvalid": "유효하지 않은 TX 전력 (0-22 dBm)",
|
||||
"settings_txPowerInvalid": "유효하지 않은 송신 전력 (0-22 dBm)",
|
||||
"settings_clientRepeat": "오프그리드 반복",
|
||||
"settings_clientRepeatSubtitle": "이 장치가 다른 사람들을 위해 메시 패킷을 반복하도록 허용합니다.",
|
||||
"settings_clientRepeatFreqWarning": "오프그리드(무전력) 시스템 재연결에는 433MHz, 869MHz, 또는 918MHz 주파수가 필요합니다.",
|
||||
"settings_clientRepeatSubtitle": "이 장치가 다른 장치의 메시 패킷을 반복하도록 허용합니다.",
|
||||
"settings_clientRepeatFreqWarning": "오프그리드 반복에는 433MHz, 869MHz 또는 918MHz 주파수가 필요합니다.",
|
||||
"settings_error": "오류: {message}",
|
||||
"@settings_error": {
|
||||
"placeholders": {
|
||||
@@ -228,36 +228,36 @@
|
||||
}
|
||||
},
|
||||
"appSettings_title": "앱 설정",
|
||||
"appSettings_appearance": "외관",
|
||||
"appSettings_theme": "주제",
|
||||
"appSettings_themeSystem": "기본 설정",
|
||||
"appSettings_themeLight": "빛",
|
||||
"appSettings_themeDark": "어둡다",
|
||||
"appSettings_appearance": "모양",
|
||||
"appSettings_theme": "테마",
|
||||
"appSettings_themeSystem": "시스템 기본값",
|
||||
"appSettings_themeLight": "밝음",
|
||||
"appSettings_themeDark": "어두움",
|
||||
"appSettings_language": "언어",
|
||||
"appSettings_languageSystem": "기본 설정",
|
||||
"appSettings_languageEn": "영어",
|
||||
"appSettings_languageFr": "프랑스어",
|
||||
"appSettings_languageEs": "스페인어",
|
||||
"appSettings_languageDe": "독일어",
|
||||
"appSettings_languagePl": "폴란드",
|
||||
"appSettings_languagePl": "폴란드어",
|
||||
"appSettings_languageSl": "슬로베니아어",
|
||||
"appSettings_languagePt": "포르투갈어",
|
||||
"appSettings_languageIt": "이탈리아어",
|
||||
"appSettings_languageZh": "중국어",
|
||||
"appSettings_languageSv": "스웨덴어",
|
||||
"appSettings_languageNl": "네덜란드어",
|
||||
"appSettings_languageSk": "슬로베니아어",
|
||||
"appSettings_languageBg": "불가리",
|
||||
"appSettings_languageSk": "슬로바키아어",
|
||||
"appSettings_languageBg": "불가리아어",
|
||||
"appSettings_languageRu": "러시아어",
|
||||
"appSettings_languageUk": "우크라이나",
|
||||
"appSettings_languageUk": "우크라이나어",
|
||||
"appSettings_enableMessageTracing": "메시지 추적 기능 활성화",
|
||||
"appSettings_enableMessageTracingSubtitle": "메시지에 대한 상세한 경로 및 시간 정보를 표시",
|
||||
"appSettings_notifications": "알림",
|
||||
"appSettings_enableNotifications": "알림 활성화",
|
||||
"appSettings_enableNotificationsSubtitle": "메시지와 광고에 대한 알림을 받으세요.",
|
||||
"appSettings_notificationPermissionDenied": "알림 권한 거부",
|
||||
"appSettings_notificationsEnabled": "알림 기능 활성화",
|
||||
"appSettings_notificationsDisabled": "알림 기능 끄기",
|
||||
"appSettings_notificationsEnabled": "알림 사용",
|
||||
"appSettings_notificationsDisabled": "알림 사용 안 함",
|
||||
"appSettings_messageNotifications": "메시지 알림",
|
||||
"appSettings_messageNotificationsSubtitle": "새로운 메시지를 받을 때 알림 표시",
|
||||
"appSettings_channelMessageNotifications": "채널 메시지 알림",
|
||||
@@ -265,22 +265,22 @@
|
||||
"appSettings_advertisementNotifications": "광고 알림",
|
||||
"appSettings_advertisementNotificationsSubtitle": "새 노드가 발견되었을 때 알림 표시",
|
||||
"appSettings_messaging": "메시징",
|
||||
"appSettings_clearPathOnMaxRetry": "Max 재시도 시 경로 명확하게 설정",
|
||||
"appSettings_clearPathOnMaxRetrySubtitle": "5번의 전송 시도가 실패하면 연락 경로를 재설정",
|
||||
"appSettings_pathsWillBeCleared": "5번의 시도 실패 후, 해당 경로가 확보될 것입니다.",
|
||||
"appSettings_pathsWillNotBeCleared": "경로는 자동으로 정리되지 않습니다.",
|
||||
"appSettings_clearPathOnMaxRetry": "최대 재시도 시 경로 지우기",
|
||||
"appSettings_clearPathOnMaxRetrySubtitle": "전송 시도가 5번 실패하면 연락 경로를 재설정합니다.",
|
||||
"appSettings_pathsWillBeCleared": "5번 실패하면 해당 경로를 지웁니다.",
|
||||
"appSettings_pathsWillNotBeCleared": "경로를 자동으로 지우지 않습니다.",
|
||||
"appSettings_autoRouteRotation": "자동 경로 순환",
|
||||
"appSettings_autoRouteRotationSubtitle": "최적 경로와 방수 모드 사이를 전환",
|
||||
"appSettings_autoRouteRotationSubtitle": "최적 경로와 플러드 모드 사이를 전환합니다.",
|
||||
"appSettings_autoRouteRotationEnabled": "자동 경로 순환 기능 활성화",
|
||||
"appSettings_autoRouteRotationDisabled": "자동 경로 순환 기능 비활성화",
|
||||
"appSettings_maxRouteWeight": "최대 경로 무게",
|
||||
"appSettings_maxRouteWeightSubtitle": "한 경로가 성공적인 배송을 통해 누적할 수 있는 최대 무게",
|
||||
"appSettings_maxRouteWeight": "최대 경로 가중치",
|
||||
"appSettings_maxRouteWeightSubtitle": "한 경로가 성공적인 전송을 통해 누적할 수 있는 최대 가중치",
|
||||
"appSettings_initialRouteWeight": "초기 경로 가중치",
|
||||
"appSettings_initialRouteWeightSubtitle": "새롭게 발견된 경로의 초기 무게",
|
||||
"appSettings_routeWeightSuccessIncrement": "성공 횟수 증가",
|
||||
"appSettings_routeWeightSuccessIncrementSubtitle": "성공적으로 배송된 경로에 추가된 무게",
|
||||
"appSettings_routeWeightFailureDecrement": "오류 가중치 감소",
|
||||
"appSettings_routeWeightFailureDecrementSubtitle": "배송 실패 후 경로에서 제거된 무게",
|
||||
"appSettings_initialRouteWeightSubtitle": "새로 발견된 경로의 초기 가중치",
|
||||
"appSettings_routeWeightSuccessIncrement": "성공 시 증가",
|
||||
"appSettings_routeWeightSuccessIncrementSubtitle": "성공적으로 전송된 경로에 추가되는 가중치",
|
||||
"appSettings_routeWeightFailureDecrement": "실패 시 감소",
|
||||
"appSettings_routeWeightFailureDecrementSubtitle": "전송 실패 후 경로에서 제거되는 가중치",
|
||||
"appSettings_maxMessageRetries": "최대 메시지 재시도 횟수",
|
||||
"appSettings_maxMessageRetriesSubtitle": "메시지를 실패로 처리하기 전 시도 횟수",
|
||||
"path_routeWeight": "{weight}/{max}",
|
||||
@@ -295,8 +295,8 @@
|
||||
}
|
||||
},
|
||||
"appSettings_battery": "배터리",
|
||||
"appSettings_batteryChemistry": "배터리 화학",
|
||||
"appSettings_batteryChemistryPerDevice": "{deviceName} 당분간",
|
||||
"appSettings_batteryChemistry": "배터리 종류",
|
||||
"appSettings_batteryChemistryPerDevice": "{deviceName}별",
|
||||
"@appSettings_batteryChemistryPerDevice": {
|
||||
"placeholders": {
|
||||
"deviceName": {
|
||||
@@ -304,20 +304,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"appSettings_batteryChemistryConnectFirst": "장치를 선택하기 위해 연결",
|
||||
"appSettings_batteryChemistryConnectFirst": "배터리 종류를 선택하려면 먼저 장치를 연결하세요.",
|
||||
"appSettings_batteryNmc": "18650 NMC (3.0-4.2V)",
|
||||
"appSettings_batteryLifepo4": "LiFePO4 (2.6-3.65V)",
|
||||
"appSettings_batteryLipo": "리튬 폴리머 (3.0-4.2V)",
|
||||
"appSettings_mapDisplay": "지도 표시",
|
||||
"appSettings_showRepeaters": "반복 기능 표시",
|
||||
"appSettings_showRepeatersSubtitle": "지도에 반복자 노드를 표시",
|
||||
"appSettings_showRepeaters": "리피터 표시",
|
||||
"appSettings_showRepeatersSubtitle": "지도에 리피터 노드를 표시",
|
||||
"appSettings_showChatNodes": "채팅 노드 표시",
|
||||
"appSettings_showChatNodesSubtitle": "지도에 채팅 노드를 표시",
|
||||
"appSettings_showOtherNodes": "다른 노드 표시",
|
||||
"appSettings_showOtherNodesSubtitle": "지도에서 다른 노드 유형을 표시",
|
||||
"appSettings_showOtherNodesSubtitle": "지도에 다른 노드 유형을 표시",
|
||||
"appSettings_timeFilter": "시간 필터",
|
||||
"appSettings_timeFilterShowAll": "모든 노드 표시",
|
||||
"appSettings_timeFilterShowLast": "지난 {hours} 시간 동안의 노드 표시",
|
||||
"appSettings_timeFilterShowLast": "최근 {hours}시간 동안의 노드 표시",
|
||||
"@appSettings_timeFilterShowLast": {
|
||||
"placeholders": {
|
||||
"hours": {
|
||||
@@ -325,17 +325,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"appSettings_mapTimeFilter": "지도 필터",
|
||||
"appSettings_showNodesDiscoveredWithin": "다음 내역에서 발견된 노드 표시:",
|
||||
"appSettings_allTime": "모든 시간",
|
||||
"appSettings_lastHour": "지난 시간",
|
||||
"appSettings_mapTimeFilter": "지도 시간 필터",
|
||||
"appSettings_showNodesDiscoveredWithin": "다음 기간 내에 발견된 노드 표시:",
|
||||
"appSettings_allTime": "전체 기간",
|
||||
"appSettings_lastHour": "지난 1시간",
|
||||
"appSettings_last6Hours": "지난 6시간",
|
||||
"appSettings_last24Hours": "지난 24시간",
|
||||
"appSettings_lastWeek": "지난 주",
|
||||
"appSettings_offlineMapCache": "오프라인 지도 캐시",
|
||||
"appSettings_unitsTitle": "단위",
|
||||
"appSettings_unitsMetric": "단위 (m / km)",
|
||||
"appSettings_unitsImperial": "제국 (피트/마일)",
|
||||
"appSettings_unitsMetric": "미터법 (m / km)",
|
||||
"appSettings_unitsImperial": "영국식 (ft / mi)",
|
||||
"appSettings_noAreaSelected": "선택된 영역 없음",
|
||||
"appSettings_areaSelectedZoom": "선택된 영역 (줌 레벨: {minZoom} - {maxZoom})",
|
||||
"@appSettings_areaSelectedZoom": {
|
||||
@@ -348,9 +348,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"appSettings_debugCard": "디버깅",
|
||||
"appSettings_appDebugLogging": "앱 디버깅 로깅",
|
||||
"appSettings_appDebugLoggingSubtitle": "로그 앱 디버깅 메시지 (문제 해결을 위한)",
|
||||
"appSettings_debugCard": "디버그",
|
||||
"appSettings_appDebugLogging": "앱 디버그 로깅",
|
||||
"appSettings_appDebugLoggingSubtitle": "문제 해결을 위한 앱 디버그 메시지를 기록합니다.",
|
||||
"appSettings_appDebugLoggingEnabled": "앱 디버깅 로깅 활성화",
|
||||
"appSettings_appDebugLoggingDisabled": "앱 디버깅 로깅 비활성화",
|
||||
"contacts_title": "연락처",
|
||||
@@ -454,7 +454,7 @@
|
||||
"contacts_noContactsMatchFilter": "입력하신 검색 조건과 일치하는 연락처가 없습니다.",
|
||||
"contacts_noMembers": "회원 없음",
|
||||
"contacts_lastSeenNow": "최근",
|
||||
"contacts_lastSeenMinsAgo": "~ {minutes} min.",
|
||||
"contacts_lastSeenMinsAgo": "~ {minutes}분",
|
||||
"@contacts_lastSeenMinsAgo": {
|
||||
"placeholders": {
|
||||
"minutes": {
|
||||
@@ -463,7 +463,7 @@
|
||||
}
|
||||
},
|
||||
"contacts_lastSeenHourAgo": "약 1시간",
|
||||
"contacts_lastSeenHoursAgo": "~ {hours} hours",
|
||||
"contacts_lastSeenHoursAgo": "~ {hours}시간",
|
||||
"@contacts_lastSeenHoursAgo": {
|
||||
"placeholders": {
|
||||
"hours": {
|
||||
@@ -721,7 +721,7 @@
|
||||
}
|
||||
},
|
||||
"debugFrame_textTypeCli": "명령줄 인터페이스 (CLI)",
|
||||
"debugFrame_textTypePlain": "단순한",
|
||||
"debugFrame_textTypePlain": "일반 텍스트",
|
||||
"debugFrame_text": "- 텍스트: \"{text}\"",
|
||||
"@debugFrame_text": {
|
||||
"placeholders": {
|
||||
@@ -735,7 +735,7 @@
|
||||
"chat_ShowAllPaths": "모든 경로 표시",
|
||||
"chat_routingMode": "라우팅 방식",
|
||||
"chat_autoUseSavedPath": "자동 (저장된 경로 사용)",
|
||||
"chat_forceFloodMode": "강수 모드 활성화",
|
||||
"chat_forceFloodMode": "플러드 모드 활성화",
|
||||
"chat_recentAckPaths": "최근 사용한 ACK 경로 (사용하려면 탭):",
|
||||
"chat_pathHistoryFull": "이력 기록은 이미 가득 차 있습니다. 항목을 삭제하여 새로운 항목을 추가할 수 있습니다.",
|
||||
"chat_hopSingular": "점프",
|
||||
@@ -748,20 +748,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"chat_successes": "성공 사례",
|
||||
"chat_successes": "성공",
|
||||
"chat_removePath": "경로 제거",
|
||||
"chat_noPathHistoryYet": "아직 경로 기록이 없습니다.\n경로를 찾기 위해 메시지를 보내세요.",
|
||||
"chat_pathActions": "경로 작업:",
|
||||
"chat_setCustomPath": "사용자 지정 경로 설정",
|
||||
"chat_setCustomPathSubtitle": "수동으로 경로를 지정",
|
||||
"chat_clearPath": "명확한 길",
|
||||
"chat_clearPathSubtitle": "다음 전송 시, 강제 재전송 설정",
|
||||
"chat_clearPath": "경로 지우기",
|
||||
"chat_clearPathSubtitle": "다음 전송 시 강제로 새 경로를 찾습니다.",
|
||||
"chat_pathCleared": "경로가 확보되었습니다. 다음 메시지는 경로를 다시 찾을 것입니다.",
|
||||
"chat_floodModeSubtitle": "앱 바에서 라우팅 스위치를 사용",
|
||||
"chat_floodModeEnabled": "홍수 모드 활성화됨. 앱 바의 경로 아이콘을 사용하여 다시 전환할 수 있습니다.",
|
||||
"chat_floodModeSubtitle": "앱 바의 라우팅 스위치를 사용하세요.",
|
||||
"chat_floodModeEnabled": "플러드 모드가 활성화되었습니다. 앱 바의 경로 아이콘으로 다시 전환할 수 있습니다.",
|
||||
"chat_fullPath": "전체 경로",
|
||||
"chat_pathDetailsNotAvailable": "경로 정보는 아직 제공되지 않습니다. 메시지를 보내어 다시 시도해 보세요.",
|
||||
"chat_pathSetHops": "Path set: {hopCount} {hopCount, plural, =1{hop} other{hops}} - {status}",
|
||||
"chat_pathSetHops": "경로 설정: {hopCount} {hopCount, plural, =1{홉} other{홉}} - {status}",
|
||||
"@chat_pathSetHops": {
|
||||
"placeholders": {
|
||||
"hopCount": {
|
||||
@@ -772,16 +772,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"chat_pathSavedLocally": "로컬에 저장. 동기화 연결",
|
||||
"chat_pathDeviceConfirmed": "장치 확인 완료.",
|
||||
"chat_pathSavedLocally": "로컬에 저장되었습니다. 동기화할 장치에 연결하세요.",
|
||||
"chat_pathDeviceConfirmed": "장치가 확인되었습니다.",
|
||||
"chat_pathDeviceNotConfirmed": "기기가 아직 확인되지 않았습니다.",
|
||||
"chat_type": "종류",
|
||||
"chat_type": "유형",
|
||||
"chat_path": "경로",
|
||||
"chat_publicKey": "공개 키",
|
||||
"chat_compressOutgoingMessages": "전송되는 메시지 압축",
|
||||
"chat_floodForced": "홍수 (강제)",
|
||||
"chat_directForced": "직접적인 (강제적인)",
|
||||
"chat_hopsForced": "{count}번 띄우기 (강제)",
|
||||
"chat_floodForced": "플러드 (강제)",
|
||||
"chat_directForced": "직접 (강제)",
|
||||
"chat_hopsForced": "{count}홉 (강제)",
|
||||
"@chat_hopsForced": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
@@ -789,7 +789,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"chat_floodAuto": "홍수 (자동)",
|
||||
"chat_floodAuto": "플러드 (자동)",
|
||||
"chat_direct": "직접",
|
||||
"chat_poiShared": "공유된 POI",
|
||||
"chat_unread": "읽지 않음: {count}",
|
||||
@@ -905,7 +905,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"mapCache_cachedTilesWithFailed": "Cached {downloaded} tiles ({failed} failed)",
|
||||
"mapCache_cachedTilesWithFailed": "캐시된 타일 {downloaded}개 ({failed}개 실패)",
|
||||
"@mapCache_cachedTilesWithFailed": {
|
||||
"placeholders": {
|
||||
"downloaded": {
|
||||
@@ -931,7 +931,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"mapCache_downloadedTiles": "Downloaded {completed} / {total}",
|
||||
"mapCache_downloadedTiles": "다운로드됨 {completed} / {total}",
|
||||
"@mapCache_downloadedTiles": {
|
||||
"placeholders": {
|
||||
"completed": {
|
||||
@@ -978,7 +978,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"time_hoursAgo": "{hours}h ago",
|
||||
"time_hoursAgo": "{hours}시간 전",
|
||||
"@time_hoursAgo": {
|
||||
"placeholders": {
|
||||
"hours": {
|
||||
@@ -1040,8 +1040,8 @@
|
||||
}
|
||||
},
|
||||
"login_failedMessage": "로그인에 실패했습니다. 비밀번호가 잘못되었거나, 연결이 되지 않는 것 같습니다.",
|
||||
"common_reload": "다시 로드",
|
||||
"common_clear": "명확하게",
|
||||
"common_reload": "다시 불러오기",
|
||||
"common_clear": "지우기",
|
||||
"path_currentPath": "현재 경로: {path}",
|
||||
"@path_currentPath": {
|
||||
"placeholders": {
|
||||
@@ -1050,7 +1050,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"path_usingHopsPath": "Using {count} {count, plural, =1{hop} other{hops}} path",
|
||||
"path_usingHopsPath": "{count} {count, plural, =1{홉} other{홉}} 경로 사용 중",
|
||||
"@path_usingHopsPath": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
@@ -1577,7 +1577,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"neighbors_heardAgo": "Heard: {time} ago",
|
||||
"neighbors_heardAgo": "수신: {time} 전",
|
||||
"@neighbors_heardAgo": {
|
||||
"placeholders": {
|
||||
"time": {
|
||||
@@ -1641,7 +1641,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"channelPath_observedSomeOf": "{observed} of {total} hops",
|
||||
"channelPath_observedSomeOf": "{observed}/{total} 홉 관찰됨",
|
||||
"@channelPath_observedSomeOf": {
|
||||
"placeholders": {
|
||||
"observed": {
|
||||
@@ -1877,7 +1877,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"losAntennaB": "Antenna B: {value} {unit}",
|
||||
"losAntennaB": "안테나 B: {value} {unit}",
|
||||
"@losAntennaB": {
|
||||
"placeholders": {
|
||||
"value": {
|
||||
@@ -1890,7 +1890,7 @@
|
||||
},
|
||||
"losRun": "LOS (Loss of Signal) 상태로 전환",
|
||||
"losNoElevationData": "고도 정보 없음",
|
||||
"losProfileClear": "{distance} {distanceUnit}, clear LOS, min clearance {clearance} {heightUnit}",
|
||||
"losProfileClear": "{distance} {distanceUnit}, LOS 확보, 최소 여유 {clearance} {heightUnit}",
|
||||
"@losProfileClear": {
|
||||
"placeholders": {
|
||||
"distance": {
|
||||
@@ -1907,7 +1907,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"losProfileBlocked": "{distance} {distanceUnit}, blocked by {obstruction} {heightUnit}",
|
||||
"losProfileBlocked": "{distance} {distanceUnit}, {obstruction} {heightUnit}에 의해 차단됨",
|
||||
"@losProfileBlocked": {
|
||||
"placeholders": {
|
||||
"distance": {
|
||||
@@ -2305,10 +2305,10 @@
|
||||
"repeater_cliHelpStatsPackets": "(전송 속도만 표시) 패킷 수준의 통계 정보를 보여줍니다.",
|
||||
"repeater_cliHelpStatsRadio": "(특정 시리즈만 해당) 라디오 통계 정보를 표시합니다.",
|
||||
"repeater_cliHelpStatsCore": "(시리얼 번호만 표시) 핵심 펌웨어 통계 정보를 보여줍니다.",
|
||||
"common_done": "Done",
|
||||
"background_serviceTitle": "MeshCore running",
|
||||
"background_serviceText": "Keeping BLE connected",
|
||||
"appSettings_translationModelDeleted": "Deleted {name}",
|
||||
"common_done": "완료",
|
||||
"background_serviceTitle": "MeshCore 실행 중",
|
||||
"background_serviceText": "BLE 연결 유지 중",
|
||||
"appSettings_translationModelDeleted": "{name} 삭제됨",
|
||||
"@appSettings_translationModelDeleted": {
|
||||
"placeholders": {
|
||||
"name": {
|
||||
@@ -2316,7 +2316,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"appSettings_translationModelDeleteFailed": "Failed to delete: {error}",
|
||||
"appSettings_translationModelDeleteFailed": "삭제 실패: {error}",
|
||||
"@appSettings_translationModelDeleteFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
@@ -2324,7 +2324,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"channels_channelUpdateFailed": "Failed to update channel: {error}",
|
||||
"channels_channelUpdateFailed": "채널 업데이트 실패: {error}",
|
||||
"@channels_channelUpdateFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
@@ -2332,19 +2332,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"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_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": "다중 ACK",
|
||||
"map_sharedAt": "공유됨",
|
||||
"@losBlockedSpotChip": {
|
||||
@@ -2386,7 +2386,7 @@
|
||||
"losBlockedSpotsTitle": "차단된 공간",
|
||||
"losSelectedObstructionTitle": "선택된 장애물",
|
||||
"losBlockedSpotChip": "{distance} {distanceUnit} • {obstruction} {heightUnit}",
|
||||
"losSelectedObstructionDetails": "Blocked by {obstruction} {heightUnit}, {distanceFromA} from A and {distanceFromB} from B ({distanceUnit}).",
|
||||
"losSelectedObstructionDetails": "{obstruction} {heightUnit}에 의해 차단됨, A에서 {distanceFromA}, B에서 {distanceFromB} ({distanceUnit})",
|
||||
"settings_companionDebugLog": "동반 디버깅 로그",
|
||||
"chat_newMessages": "새로운 메시지",
|
||||
"settings_companionDebugLogSubtitle": "BLE/TCP/USB 명령어, 응답 및 원시 데이터",
|
||||
@@ -2433,56 +2433,249 @@
|
||||
"messageStatus_pending": "발송",
|
||||
"messageStatus_sent": "발송",
|
||||
"messageStatus_delivered": "배송 완료",
|
||||
"common_undo": "취소",
|
||||
"messageStatus_failed": "발송 실패",
|
||||
"messageStatus_repeated": "반복적으로 들었습니다",
|
||||
"common_undo": "되돌리기",
|
||||
"messageStatus_pending": "전송 중",
|
||||
"messageStatus_sent": "전송됨",
|
||||
"messageStatus_delivered": "전달됨",
|
||||
"messageStatus_failed": "전송 실패",
|
||||
"messageStatus_repeated": "반복 수신됨",
|
||||
"contacts_searchOpen": "연락처 검색",
|
||||
"contacts_moreOptions": "더 많은 옵션",
|
||||
"contacts_searchClose": "검색 닫기",
|
||||
"routing_title": "라우팅",
|
||||
"routing_modeAuto": "자동",
|
||||
"routing_modeFlood": "홍수",
|
||||
"routing_modeManual": "사용 설명서",
|
||||
"routing_modeAutoHint": "가장 잘 알려진 경로를 자동으로 선택하고, 경로가 없을 경우에는 무작위로 경로를 선택합니다.",
|
||||
"routing_modeFloodHint": "모든 증폭기를 통해 방송됩니다. 가장 안정적이지만, 더 많은 송출 시간을 사용합니다.",
|
||||
"routing_modeManualHint": "항상 설정하신 정확한 경로를 따라 이동합니다.",
|
||||
"routing_modeFlood": "플러드",
|
||||
"routing_modeManual": "수동",
|
||||
"routing_modeAutoHint": "가장 잘 알려진 경로를 자동으로 선택하고, 경로가 없으면 플러드로 전환합니다.",
|
||||
"routing_modeFloodHint": "모든 중계기를 통해 방송합니다. 가장 안정적이지만 송신 시간을 더 많이 사용합니다.",
|
||||
"routing_modeManualHint": "항상 지정한 정확한 경로를 따릅니다.",
|
||||
"routing_currentRoute": "현재 경로",
|
||||
"routing_directNoHops": "직접 연결 – 중계 장치 사용 없이",
|
||||
"routing_directNoHops": "직접 연결 - 중계 없음",
|
||||
"routing_noPathYet": "아직 경로가 없습니다. 다음 메시지가 도착할 때까지 계속 탐색합니다.",
|
||||
"routing_floodBroadcast": "모든 증폭기를 통해 방송",
|
||||
"routing_floodBroadcast": "모든 중계기를 통해 방송",
|
||||
"routing_editPath": "경로 편집",
|
||||
"routing_forgetPath": "길을 잊어라",
|
||||
"routing_forgetPath": "경로 지우기",
|
||||
"routing_knownPaths": "알려진 경로",
|
||||
"routing_knownPathsHint": "해당 항목으로 전환하기 위한 경로를 선택합니다.",
|
||||
"routing_knownPathsHint": "전환할 경로를 선택하세요.",
|
||||
"routing_inUse": "사용 중",
|
||||
"routing_qualityStrong": "강력한 첫 번째 단계",
|
||||
"routing_qualityGood": "좋은 첫 시작",
|
||||
"routing_qualityFair": "처음 시도",
|
||||
"routing_qualityWorked": "완료됨",
|
||||
"routing_qualityFlood": "홍수 피해 상황을 통해 들었습니다.",
|
||||
"routing_qualityUntested": "검증되지 않음",
|
||||
"routing_lastWorked": "{when}에 일했습니다",
|
||||
"routing_neverWorked": "확인되지 않음",
|
||||
"routing_floodDelivery": "홍수 피해 지역 배송",
|
||||
"routing_qualityStrong": "매우 좋음",
|
||||
"routing_qualityGood": "좋음",
|
||||
"routing_qualityFair": "보통",
|
||||
"routing_qualityWorked": "작동함",
|
||||
"routing_qualityFlood": "플러드로 수신됨",
|
||||
"routing_qualityUntested": "미검증",
|
||||
"routing_lastWorked": "{when}에 작동",
|
||||
"routing_neverWorked": "아직 작동한 적 없음",
|
||||
"routing_floodDelivery": "플러드 전송",
|
||||
"pathEditor_title": "경로 만들기",
|
||||
"pathEditor_hopCounter": "64개의 홉 중 {count}",
|
||||
"pathEditor_noHops": "현재 홉은 추가되지 않았습니다. 아래의 탭을 사용하여 순서대로 추가하거나, 홉 없이 바로 전송하려면 \"홉 없음\"으로 저장하십시오.",
|
||||
"pathEditor_addHops": "홉을 순서대로 첨가해주세요.",
|
||||
"pathEditor_searchRepeaters": "반복 검색",
|
||||
"pathEditor_advancedHex": "고급: 원시 헥스 경로",
|
||||
"pathEditor_hexLabel": "헥스 접두사",
|
||||
"pathEditor_hexHelper": "각 홉마다 2개의 6자리 숫자, 쉼표로 구분",
|
||||
"pathEditor_hopCounter": "64개 중 {count} 홉",
|
||||
"pathEditor_noHops": "아직 홉이 추가되지 않았습니다. 아래 탭을 사용해 순서대로 추가하거나, 홉 없이 바로 보내려면 \"홉 없음\"으로 저장하세요.",
|
||||
"pathEditor_addHops": "홉을 순서대로 추가하세요.",
|
||||
"pathEditor_searchRepeaters": "리피터 검색",
|
||||
"pathEditor_advancedHex": "고급: 원시 HEX 경로",
|
||||
"pathEditor_hexLabel": "HEX 접두사",
|
||||
"pathEditor_hexHelper": "각 홉마다 2개의 16진수 바이트, 쉼표로 구분",
|
||||
"pathEditor_invalidTokens": "유효하지 않음: {tokens}",
|
||||
"pathEditor_tooManyHops": "최대 64개의 홉",
|
||||
"pathEditor_usePath": "이 경로를 사용하세요",
|
||||
"pathEditor_usePath": "이 경로 사용",
|
||||
"pathEditor_removeHop": "홉 제거",
|
||||
"pathEditor_unknownHop": "알 수 없는 중계기",
|
||||
"map_zoomIn": "줌 인",
|
||||
"routing_deliveryCounts": "{successes} delivered, {failures} failed",
|
||||
"map_zoomOut": "줌 아웃",
|
||||
"map_centerMap": "중심 지도",
|
||||
"chrome_bluetoothRequiresChromium": "웹 블루투스는 크롬 브라우저가 필요합니다.",
|
||||
"map_zoomIn": "확대",
|
||||
"routing_deliveryCounts": "{successes}건 성공, {failures}건 실패",
|
||||
"map_zoomOut": "축소",
|
||||
"map_centerMap": "지도 중앙 맞추기",
|
||||
"chrome_bluetoothRequiresChromium": "웹 블루투스는 Chromium 기반 브라우저가 필요합니다.",
|
||||
"channels_communityShortId": "ID: {id}...",
|
||||
"pathTrace_legendGpsConfirmed": "GPS 확인 완료",
|
||||
"pathTrace_legendInferred": "추론된 위치"
|
||||
"pathTrace_legendGpsConfirmed": "GPS로 확인됨",
|
||||
"pathTrace_legendInferred": "추정된 위치",
|
||||
"@pathMap_hopOf": {
|
||||
"placeholders": {
|
||||
"current": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_observedPaths": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_alternate": {
|
||||
"placeholders": {
|
||||
"index": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_hopCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_gpsCount": {
|
||||
"placeholders": {
|
||||
"confirmed": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_sharedNodeCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_partialAnimation": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"map_activity": "활동",
|
||||
"map_searchHint": "노드 이름 또는 ID 검색",
|
||||
"map_online": "온라인",
|
||||
"scanner_bluetoothWebUnsupported": "브라우저에서는 블루투스를 사용할 수 없습니다. 대신 USB로 연결하세요.",
|
||||
"map_recent": "최근",
|
||||
"map_stale": "오래됨",
|
||||
"map_visible": "보임",
|
||||
"map_hidden": "숨김",
|
||||
"map_centerOnNode": "노드 중심으로 보기",
|
||||
"map_details": "세부 정보",
|
||||
"map_noGps": "GPS 없음",
|
||||
"map_noResults": "일치하는 노드가 없습니다.",
|
||||
"pathMap_viewSingle": "단일",
|
||||
"pathMap_viewCombined": "결합",
|
||||
"pathMap_play": "재생",
|
||||
"pathMap_pause": "일시 정지",
|
||||
"pathMap_replay": "다시 재생",
|
||||
"pathMap_stepBack": "이전 홉",
|
||||
"pathMap_stepForward": "다음 홉",
|
||||
"pathMap_animationOn": "패킷 애니메이션 표시",
|
||||
"pathMap_animationOff": "패킷 애니메이션 숨기기",
|
||||
"pathMap_hopOf": "{current}/{total} 홉",
|
||||
"pathMap_observedPaths": "관찰된 경로: {count}",
|
||||
"pathMap_primary": "주 경로",
|
||||
"pathMap_alternate": "대체 {index}",
|
||||
"pathMap_hopCount": "{count, plural, =1{1 홉} other{{count} 홉}}",
|
||||
"pathMap_legendShared": "공유 구간",
|
||||
"pathMap_legendEstimated": "추정 구간",
|
||||
"pathMap_sharedNodeCount": "{count}개의 경로에서 사용됨",
|
||||
"pathMap_partialAnimation": "{count, plural, =1{1 홉은 위치가 없어 표시된 경로가 일부입니다} other{{count} 홉은 위치가 없어 표시된 경로가 일부입니다}}",
|
||||
"pathMap_showAllPaths": "모두 보기",
|
||||
"pathMap_hidePath": "경로 숨기기",
|
||||
"pathMap_showPath": "경로 표시",
|
||||
"pathMap_collapsePanel": "패널 접기",
|
||||
"pathMap_expandPanel": "패널 펼치기",
|
||||
"pathMap_noLocation": "위치 없음",
|
||||
"pathMap_followPacket": "패킷 고정",
|
||||
"pathMap_unfollowPacket": "패킷 고정 해제",
|
||||
"pathMap_gpsCount": "{confirmed}/{total} GPS",
|
||||
"@channels_cyr2latSettingsDialogWrongJSON": {
|
||||
"placeholders": {
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"@channels_via": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@settings_cyr2latProfileDeleteDscr": {
|
||||
"placeholders": {
|
||||
"name": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@telemetry_altitudeValue": {
|
||||
"placeholders": {
|
||||
"meters": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@telemetry_analogValue": {
|
||||
"placeholders": {
|
||||
"value": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@telemetry_concentrationValue": {
|
||||
"placeholders": {
|
||||
"ppm": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@telemetry_directionValue": {
|
||||
"placeholders": {
|
||||
"degrees": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@telemetry_distanceValue": {
|
||||
"placeholders": {
|
||||
"meters": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@telemetry_energyValue": {
|
||||
"placeholders": {
|
||||
"kilowattHours": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@telemetry_frequencyValue": {
|
||||
"placeholders": {
|
||||
"hertz": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@telemetry_luminosityValue": {
|
||||
"placeholders": {
|
||||
"lux": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@telemetry_percentageValue": {
|
||||
"placeholders": {
|
||||
"percent": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@telemetry_powerValue": {
|
||||
"placeholders": {
|
||||
"watts": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@telemetry_pressureValue": {
|
||||
"placeholders": {
|
||||
"hpa": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+275
-276
File diff suppressed because it is too large
Load Diff
+367
-377
File diff suppressed because it is too large
Load Diff
+293
-295
File diff suppressed because it is too large
Load Diff
+232
-239
File diff suppressed because it is too large
Load Diff
+1087
-1111
File diff suppressed because it is too large
Load Diff
+262
-265
File diff suppressed because it is too large
Load Diff
+388
-396
File diff suppressed because it is too large
Load Diff
+212
-210
File diff suppressed because it is too large
Load Diff
@@ -319,7 +319,7 @@ class AppLocalizationsNl extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get scanner_bluetoothWebUnsupported =>
|
||||
'Bluetooth isn\'t available in the browser. Connect over USB instead.';
|
||||
'Bluetooth is niet beschikbaar in de browser. Verbind dan via USB.';
|
||||
|
||||
@override
|
||||
String get device_quickSwitch => 'Snelle overschakeling';
|
||||
@@ -1726,10 +1726,10 @@ class AppLocalizationsNl extends AppLocalizations {
|
||||
String get map_title => 'Kaart van de knopen';
|
||||
|
||||
@override
|
||||
String get map_searchHint => 'Search node name or ID';
|
||||
String get map_searchHint => 'Zoek op naam of ID van de knoop';
|
||||
|
||||
@override
|
||||
String get map_activity => 'Activity';
|
||||
String get map_activity => 'Activiteit';
|
||||
|
||||
@override
|
||||
String get map_online => 'Online';
|
||||
@@ -1738,25 +1738,25 @@ class AppLocalizationsNl extends AppLocalizations {
|
||||
String get map_recent => 'Recent';
|
||||
|
||||
@override
|
||||
String get map_stale => 'Stale';
|
||||
String get map_stale => 'Verouderd';
|
||||
|
||||
@override
|
||||
String get map_visible => 'Visible';
|
||||
String get map_visible => 'Zichtbaar';
|
||||
|
||||
@override
|
||||
String get map_hidden => 'Hidden';
|
||||
String get map_hidden => 'Verborgen';
|
||||
|
||||
@override
|
||||
String get map_centerOnNode => 'Center on node';
|
||||
String get map_centerOnNode => 'Centreer op node';
|
||||
|
||||
@override
|
||||
String get map_details => 'Details';
|
||||
|
||||
@override
|
||||
String get map_noGps => 'No GPS';
|
||||
String get map_noGps => 'Geen GPS';
|
||||
|
||||
@override
|
||||
String get map_noResults => 'No matching nodes';
|
||||
String get map_noResults => 'Geen overeenkomende nodes';
|
||||
|
||||
@override
|
||||
String get map_lineOfSight => 'Zichtlijn';
|
||||
@@ -4502,48 +4502,48 @@ class AppLocalizationsNl extends AppLocalizations {
|
||||
String get pathTrace_legendInferred => 'Afgeleide positie';
|
||||
|
||||
@override
|
||||
String get pathMap_viewSingle => 'Single';
|
||||
String get pathMap_viewSingle => 'Enkel';
|
||||
|
||||
@override
|
||||
String get pathMap_viewCombined => 'Combined';
|
||||
String get pathMap_viewCombined => 'Gezamenlijk';
|
||||
|
||||
@override
|
||||
String get pathMap_play => 'Play';
|
||||
String get pathMap_play => 'Afspelen';
|
||||
|
||||
@override
|
||||
String get pathMap_pause => 'Pause';
|
||||
String get pathMap_pause => 'Pauze';
|
||||
|
||||
@override
|
||||
String get pathMap_replay => 'Replay';
|
||||
String get pathMap_replay => 'Herhalen';
|
||||
|
||||
@override
|
||||
String get pathMap_stepBack => 'Previous hop';
|
||||
String get pathMap_stepBack => 'Vorige hop';
|
||||
|
||||
@override
|
||||
String get pathMap_stepForward => 'Next hop';
|
||||
String get pathMap_stepForward => 'Volgende hop';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOn => 'Show packet animation';
|
||||
String get pathMap_animationOn => 'Pakketanimatie tonen';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOff => 'Hide packet animation';
|
||||
String get pathMap_animationOff => 'Pakketanimatie verbergen';
|
||||
|
||||
@override
|
||||
String pathMap_hopOf(int current, int total) {
|
||||
return 'Hop $current of $total';
|
||||
return 'Hop $current van $total';
|
||||
}
|
||||
|
||||
@override
|
||||
String pathMap_observedPaths(int count) {
|
||||
return 'Observed paths: $count';
|
||||
return 'Waargenomen paden: $count';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_primary => 'Primary';
|
||||
String get pathMap_primary => 'Primair';
|
||||
|
||||
@override
|
||||
String pathMap_alternate(int index) {
|
||||
return 'Alt $index';
|
||||
return 'Alternatief $index';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4563,14 +4563,14 @@ class AppLocalizationsNl extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_legendShared => 'Shared segment';
|
||||
String get pathMap_legendShared => 'Gedeeld segment';
|
||||
|
||||
@override
|
||||
String get pathMap_legendEstimated => 'Estimated segment';
|
||||
String get pathMap_legendEstimated => 'Geschat segment';
|
||||
|
||||
@override
|
||||
String pathMap_sharedNodeCount(int count) {
|
||||
return 'Used by $count paths';
|
||||
return 'Gebruikt door $count paden';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4578,33 +4578,34 @@ class AppLocalizationsNl extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops have no location — the shown path is partial',
|
||||
one: '1 hop has no location — the shown path is partial',
|
||||
other:
|
||||
'$count hops hebben geen locatie — het weergegeven pad is onvolledig',
|
||||
one: '1 hop heeft geen locatie — het weergegeven pad is onvolledig',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_showAllPaths => 'Show all';
|
||||
String get pathMap_showAllPaths => 'Toon alles';
|
||||
|
||||
@override
|
||||
String get pathMap_hidePath => 'Hide path';
|
||||
String get pathMap_hidePath => 'Verberg pad';
|
||||
|
||||
@override
|
||||
String get pathMap_showPath => 'Show path';
|
||||
String get pathMap_showPath => 'Toon pad';
|
||||
|
||||
@override
|
||||
String get pathMap_collapsePanel => 'Collapse panel';
|
||||
String get pathMap_collapsePanel => 'Paneel inklappen';
|
||||
|
||||
@override
|
||||
String get pathMap_expandPanel => 'Expand panel';
|
||||
String get pathMap_expandPanel => 'Paneel uitklappen';
|
||||
|
||||
@override
|
||||
String get pathMap_noLocation => 'No location';
|
||||
String get pathMap_noLocation => 'Geen locatie';
|
||||
|
||||
@override
|
||||
String get pathMap_followPacket => 'Lock view to packet';
|
||||
String get pathMap_followPacket => 'Weergave vergrendelen op pakket';
|
||||
|
||||
@override
|
||||
String get pathMap_unfollowPacket => 'Unlock view from packet';
|
||||
String get pathMap_unfollowPacket => 'Weergave ontgrendelen van pakket';
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ class AppLocalizationsPl extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get scanner_bluetoothWebUnsupported =>
|
||||
'Bluetooth isn\'t available in the browser. Connect over USB instead.';
|
||||
'Bluetooth nie jest dostępny w przeglądarce. Połącz się przez USB.';
|
||||
|
||||
@override
|
||||
String get device_quickSwitch => 'Szybka zmiana';
|
||||
@@ -1755,37 +1755,37 @@ class AppLocalizationsPl extends AppLocalizations {
|
||||
String get map_title => 'Mapa węzłów';
|
||||
|
||||
@override
|
||||
String get map_searchHint => 'Search node name or ID';
|
||||
String get map_searchHint => 'Wyszukaj nazwę lub identyfikator węzła';
|
||||
|
||||
@override
|
||||
String get map_activity => 'Activity';
|
||||
String get map_activity => 'Aktywność';
|
||||
|
||||
@override
|
||||
String get map_online => 'Online';
|
||||
|
||||
@override
|
||||
String get map_recent => 'Recent';
|
||||
String get map_recent => 'Ostatnie';
|
||||
|
||||
@override
|
||||
String get map_stale => 'Stale';
|
||||
String get map_stale => 'Nieaktualne';
|
||||
|
||||
@override
|
||||
String get map_visible => 'Visible';
|
||||
String get map_visible => 'Widoczny';
|
||||
|
||||
@override
|
||||
String get map_hidden => 'Hidden';
|
||||
String get map_hidden => 'Ukryty';
|
||||
|
||||
@override
|
||||
String get map_centerOnNode => 'Center on node';
|
||||
String get map_centerOnNode => 'Wyśrodkuj na węźle';
|
||||
|
||||
@override
|
||||
String get map_details => 'Details';
|
||||
String get map_details => 'Szczegóły';
|
||||
|
||||
@override
|
||||
String get map_noGps => 'No GPS';
|
||||
String get map_noGps => 'Brak GPS';
|
||||
|
||||
@override
|
||||
String get map_noResults => 'No matching nodes';
|
||||
String get map_noResults => 'Brak pasujących węzłów';
|
||||
|
||||
@override
|
||||
String get map_lineOfSight => 'Linia wzroku';
|
||||
@@ -4540,48 +4540,48 @@ class AppLocalizationsPl extends AppLocalizations {
|
||||
String get pathTrace_legendInferred => 'Wywnioskowana pozycja';
|
||||
|
||||
@override
|
||||
String get pathMap_viewSingle => 'Single';
|
||||
String get pathMap_viewSingle => 'Pojedyncza';
|
||||
|
||||
@override
|
||||
String get pathMap_viewCombined => 'Combined';
|
||||
String get pathMap_viewCombined => 'Połączone';
|
||||
|
||||
@override
|
||||
String get pathMap_play => 'Play';
|
||||
String get pathMap_play => 'Odtwórz';
|
||||
|
||||
@override
|
||||
String get pathMap_pause => 'Pause';
|
||||
String get pathMap_pause => 'Wstrzymaj';
|
||||
|
||||
@override
|
||||
String get pathMap_replay => 'Replay';
|
||||
String get pathMap_replay => 'Odtwórz ponownie';
|
||||
|
||||
@override
|
||||
String get pathMap_stepBack => 'Previous hop';
|
||||
String get pathMap_stepBack => 'Poprzedni skok';
|
||||
|
||||
@override
|
||||
String get pathMap_stepForward => 'Next hop';
|
||||
String get pathMap_stepForward => 'Następny skok';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOn => 'Show packet animation';
|
||||
String get pathMap_animationOn => 'Pokaż animację pakietu';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOff => 'Hide packet animation';
|
||||
String get pathMap_animationOff => 'Ukryj animację pakietu';
|
||||
|
||||
@override
|
||||
String pathMap_hopOf(int current, int total) {
|
||||
return 'Hop $current of $total';
|
||||
return 'Skok $current z $total';
|
||||
}
|
||||
|
||||
@override
|
||||
String pathMap_observedPaths(int count) {
|
||||
return 'Observed paths: $count';
|
||||
return 'Obserwowane trasy: $count';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_primary => 'Primary';
|
||||
String get pathMap_primary => 'Główna';
|
||||
|
||||
@override
|
||||
String pathMap_alternate(int index) {
|
||||
return 'Alt $index';
|
||||
return 'Alt. $index';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4589,8 +4589,10 @@ class AppLocalizationsPl extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops',
|
||||
one: '1 hop',
|
||||
other: '$count skoku',
|
||||
many: '$count skoków',
|
||||
few: '$count skoki',
|
||||
one: '1 skok',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -4601,14 +4603,14 @@ class AppLocalizationsPl extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_legendShared => 'Shared segment';
|
||||
String get pathMap_legendShared => 'Wspólny segment';
|
||||
|
||||
@override
|
||||
String get pathMap_legendEstimated => 'Estimated segment';
|
||||
String get pathMap_legendEstimated => 'Szacunkowy segment';
|
||||
|
||||
@override
|
||||
String pathMap_sharedNodeCount(int count) {
|
||||
return 'Used by $count paths';
|
||||
return 'Wykorzystywane przez $count ścieżek';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4616,33 +4618,38 @@ class AppLocalizationsPl extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops have no location — the shown path is partial',
|
||||
one: '1 hop has no location — the shown path is partial',
|
||||
other:
|
||||
'$count skoku nie ma lokalizacji — pokazana ścieżka jest niekompletna',
|
||||
many:
|
||||
'$count skoków nie ma lokalizacji — pokazana ścieżka jest niekompletna',
|
||||
few:
|
||||
'$count skoki nie mają lokalizacji — pokazana ścieżka jest niekompletna',
|
||||
one: '1 skok nie ma lokalizacji — pokazana ścieżka jest niekompletna',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_showAllPaths => 'Show all';
|
||||
String get pathMap_showAllPaths => 'Pokaż wszystkie';
|
||||
|
||||
@override
|
||||
String get pathMap_hidePath => 'Hide path';
|
||||
String get pathMap_hidePath => 'Ukryj ścieżkę';
|
||||
|
||||
@override
|
||||
String get pathMap_showPath => 'Show path';
|
||||
String get pathMap_showPath => 'Wyświetl trasę';
|
||||
|
||||
@override
|
||||
String get pathMap_collapsePanel => 'Collapse panel';
|
||||
String get pathMap_collapsePanel => 'Zwiń panel';
|
||||
|
||||
@override
|
||||
String get pathMap_expandPanel => 'Expand panel';
|
||||
String get pathMap_expandPanel => 'Rozwiń panel';
|
||||
|
||||
@override
|
||||
String get pathMap_noLocation => 'No location';
|
||||
String get pathMap_noLocation => 'Brak lokalizacji';
|
||||
|
||||
@override
|
||||
String get pathMap_followPacket => 'Lock view to packet';
|
||||
String get pathMap_followPacket => 'Śledź pakiet';
|
||||
|
||||
@override
|
||||
String get pathMap_unfollowPacket => 'Unlock view from packet';
|
||||
String get pathMap_unfollowPacket => 'Przestań śledzić pakiet';
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get scanner_bluetoothWebUnsupported =>
|
||||
'Bluetooth isn\'t available in the browser. Connect over USB instead.';
|
||||
'A funcionalidade Bluetooth não está disponível no navegador. Conecte-se via USB em vez disso.';
|
||||
|
||||
@override
|
||||
String get device_quickSwitch => 'Mudar rapidamente';
|
||||
@@ -1739,37 +1739,37 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String get map_title => 'Mapa de Nós';
|
||||
|
||||
@override
|
||||
String get map_searchHint => 'Search node name or ID';
|
||||
String get map_searchHint => 'Pesquisar por nome ou ID do nó';
|
||||
|
||||
@override
|
||||
String get map_activity => 'Activity';
|
||||
String get map_activity => 'Atividade';
|
||||
|
||||
@override
|
||||
String get map_online => 'Online';
|
||||
|
||||
@override
|
||||
String get map_recent => 'Recent';
|
||||
String get map_recent => 'Recente';
|
||||
|
||||
@override
|
||||
String get map_stale => 'Stale';
|
||||
String get map_stale => 'Vencido';
|
||||
|
||||
@override
|
||||
String get map_visible => 'Visible';
|
||||
String get map_visible => 'Visível';
|
||||
|
||||
@override
|
||||
String get map_hidden => 'Hidden';
|
||||
String get map_hidden => 'Escondido';
|
||||
|
||||
@override
|
||||
String get map_centerOnNode => 'Center on node';
|
||||
String get map_centerOnNode => 'Centralizar no nó';
|
||||
|
||||
@override
|
||||
String get map_details => 'Details';
|
||||
String get map_details => 'Detalhes';
|
||||
|
||||
@override
|
||||
String get map_noGps => 'No GPS';
|
||||
String get map_noGps => 'Sem GPS';
|
||||
|
||||
@override
|
||||
String get map_noResults => 'No matching nodes';
|
||||
String get map_noResults => 'Nenhum nó encontrado';
|
||||
|
||||
@override
|
||||
String get map_lineOfSight => 'Linha de visão';
|
||||
@@ -4519,44 +4519,44 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String get pathTrace_legendInferred => 'Posição inferida';
|
||||
|
||||
@override
|
||||
String get pathMap_viewSingle => 'Single';
|
||||
String get pathMap_viewSingle => 'Único';
|
||||
|
||||
@override
|
||||
String get pathMap_viewCombined => 'Combined';
|
||||
String get pathMap_viewCombined => 'Combinado';
|
||||
|
||||
@override
|
||||
String get pathMap_play => 'Play';
|
||||
String get pathMap_play => 'Reproduzir';
|
||||
|
||||
@override
|
||||
String get pathMap_pause => 'Pause';
|
||||
String get pathMap_pause => 'Pausa';
|
||||
|
||||
@override
|
||||
String get pathMap_replay => 'Replay';
|
||||
String get pathMap_replay => 'Repetir';
|
||||
|
||||
@override
|
||||
String get pathMap_stepBack => 'Previous hop';
|
||||
String get pathMap_stepBack => 'Salto anterior';
|
||||
|
||||
@override
|
||||
String get pathMap_stepForward => 'Next hop';
|
||||
String get pathMap_stepForward => 'Próximo salto';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOn => 'Show packet animation';
|
||||
String get pathMap_animationOn => 'Exibir animação do pacote';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOff => 'Hide packet animation';
|
||||
String get pathMap_animationOff => 'Ocultar a animação do pacote';
|
||||
|
||||
@override
|
||||
String pathMap_hopOf(int current, int total) {
|
||||
return 'Hop $current of $total';
|
||||
return 'Salto $current de $total';
|
||||
}
|
||||
|
||||
@override
|
||||
String pathMap_observedPaths(int count) {
|
||||
return 'Observed paths: $count';
|
||||
return 'Caminhos observados: $count';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_primary => 'Primary';
|
||||
String get pathMap_primary => 'Primário';
|
||||
|
||||
@override
|
||||
String pathMap_alternate(int index) {
|
||||
@@ -4568,8 +4568,8 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops',
|
||||
one: '1 hop',
|
||||
other: '$count saltos',
|
||||
one: '1 salto',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -4580,14 +4580,14 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_legendShared => 'Shared segment';
|
||||
String get pathMap_legendShared => 'Segmento compartilhado';
|
||||
|
||||
@override
|
||||
String get pathMap_legendEstimated => 'Estimated segment';
|
||||
String get pathMap_legendEstimated => 'Segmento estimado';
|
||||
|
||||
@override
|
||||
String pathMap_sharedNodeCount(int count) {
|
||||
return 'Used by $count paths';
|
||||
return 'Utilizado em $count caminhos';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4595,33 +4595,33 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops have no location — the shown path is partial',
|
||||
one: '1 hop has no location — the shown path is partial',
|
||||
other: '$count saltos não têm localização — o caminho mostrado é parcial',
|
||||
one: '1 salto não tem localização — o caminho mostrado é parcial',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_showAllPaths => 'Show all';
|
||||
String get pathMap_showAllPaths => 'Mostrar tudo';
|
||||
|
||||
@override
|
||||
String get pathMap_hidePath => 'Hide path';
|
||||
String get pathMap_hidePath => 'Esconder caminho';
|
||||
|
||||
@override
|
||||
String get pathMap_showPath => 'Show path';
|
||||
String get pathMap_showPath => 'Mostrar o caminho';
|
||||
|
||||
@override
|
||||
String get pathMap_collapsePanel => 'Collapse panel';
|
||||
String get pathMap_collapsePanel => 'Recolher painel';
|
||||
|
||||
@override
|
||||
String get pathMap_expandPanel => 'Expand panel';
|
||||
String get pathMap_expandPanel => 'Expandir painel';
|
||||
|
||||
@override
|
||||
String get pathMap_noLocation => 'No location';
|
||||
String get pathMap_noLocation => 'Sem localização';
|
||||
|
||||
@override
|
||||
String get pathMap_followPacket => 'Lock view to packet';
|
||||
String get pathMap_followPacket => 'Fixar vista no pacote';
|
||||
|
||||
@override
|
||||
String get pathMap_unfollowPacket => 'Unlock view from packet';
|
||||
String get pathMap_unfollowPacket => 'Liberar vista do pacote';
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get scanner_bluetoothWebUnsupported =>
|
||||
'Bluetooth isn\'t available in the browser. Connect over USB instead.';
|
||||
'Bluetooth недоступен в браузере. Подключитесь через USB.';
|
||||
|
||||
@override
|
||||
String get device_quickSwitch => 'Быстрое переключение';
|
||||
@@ -1744,37 +1744,37 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String get map_title => 'Карта нод';
|
||||
|
||||
@override
|
||||
String get map_searchHint => 'Search node name or ID';
|
||||
String get map_searchHint => 'Поиск по имени или ID узла';
|
||||
|
||||
@override
|
||||
String get map_activity => 'Activity';
|
||||
String get map_activity => 'Активность';
|
||||
|
||||
@override
|
||||
String get map_online => 'Online';
|
||||
String get map_online => 'Онлайн';
|
||||
|
||||
@override
|
||||
String get map_recent => 'Recent';
|
||||
String get map_recent => 'Недавно';
|
||||
|
||||
@override
|
||||
String get map_stale => 'Stale';
|
||||
String get map_stale => 'Устаревший';
|
||||
|
||||
@override
|
||||
String get map_visible => 'Visible';
|
||||
String get map_visible => 'Видимый';
|
||||
|
||||
@override
|
||||
String get map_hidden => 'Hidden';
|
||||
String get map_hidden => 'Скрытый';
|
||||
|
||||
@override
|
||||
String get map_centerOnNode => 'Center on node';
|
||||
String get map_centerOnNode => 'Центрировать на узле';
|
||||
|
||||
@override
|
||||
String get map_details => 'Details';
|
||||
String get map_details => 'Детали';
|
||||
|
||||
@override
|
||||
String get map_noGps => 'No GPS';
|
||||
String get map_noGps => 'Без GPS';
|
||||
|
||||
@override
|
||||
String get map_noResults => 'No matching nodes';
|
||||
String get map_noResults => 'Не найдено соответствующих узлов';
|
||||
|
||||
@override
|
||||
String get map_lineOfSight => 'Линия видимости';
|
||||
@@ -4535,48 +4535,48 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String get pathTrace_legendInferred => 'Выведенная позиция';
|
||||
|
||||
@override
|
||||
String get pathMap_viewSingle => 'Single';
|
||||
String get pathMap_viewSingle => 'Одиночный';
|
||||
|
||||
@override
|
||||
String get pathMap_viewCombined => 'Combined';
|
||||
String get pathMap_viewCombined => 'Объединённые';
|
||||
|
||||
@override
|
||||
String get pathMap_play => 'Play';
|
||||
String get pathMap_play => 'Воспроизвести';
|
||||
|
||||
@override
|
||||
String get pathMap_pause => 'Pause';
|
||||
String get pathMap_pause => 'Пауза';
|
||||
|
||||
@override
|
||||
String get pathMap_replay => 'Replay';
|
||||
String get pathMap_replay => 'Повтор';
|
||||
|
||||
@override
|
||||
String get pathMap_stepBack => 'Previous hop';
|
||||
String get pathMap_stepBack => 'Предыдущий хоп';
|
||||
|
||||
@override
|
||||
String get pathMap_stepForward => 'Next hop';
|
||||
String get pathMap_stepForward => 'Следующий хоп';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOn => 'Show packet animation';
|
||||
String get pathMap_animationOn => 'Показать анимацию пакета';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOff => 'Hide packet animation';
|
||||
String get pathMap_animationOff => 'Скрыть анимацию пакета';
|
||||
|
||||
@override
|
||||
String pathMap_hopOf(int current, int total) {
|
||||
return 'Hop $current of $total';
|
||||
return 'Хоп $current из $total';
|
||||
}
|
||||
|
||||
@override
|
||||
String pathMap_observedPaths(int count) {
|
||||
return 'Observed paths: $count';
|
||||
return 'Наблюдаемые маршруты: $count';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_primary => 'Primary';
|
||||
String get pathMap_primary => 'Основной';
|
||||
|
||||
@override
|
||||
String pathMap_alternate(int index) {
|
||||
return 'Alt $index';
|
||||
return 'Альт $index';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4584,8 +4584,10 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops',
|
||||
one: '1 hop',
|
||||
other: '$count хопов',
|
||||
many: '$count хопов',
|
||||
few: '$count хопа',
|
||||
one: '$count хоп',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -4596,14 +4598,14 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_legendShared => 'Shared segment';
|
||||
String get pathMap_legendShared => 'Общий сегмент';
|
||||
|
||||
@override
|
||||
String get pathMap_legendEstimated => 'Estimated segment';
|
||||
String get pathMap_legendEstimated => 'Расчётный сегмент';
|
||||
|
||||
@override
|
||||
String pathMap_sharedNodeCount(int count) {
|
||||
return 'Used by $count paths';
|
||||
return 'Используется в $count маршрутах';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4611,33 +4613,35 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops have no location — the shown path is partial',
|
||||
one: '1 hop has no location — the shown path is partial',
|
||||
other: '$count хопов не имеют координат — показанный путь неполный',
|
||||
many: '$count хопов не имеют координат — показанный путь неполный',
|
||||
few: '$count хопа не имеют координат — показанный путь неполный',
|
||||
one: '$count хоп не имеет координат — показанный путь неполный',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_showAllPaths => 'Show all';
|
||||
String get pathMap_showAllPaths => 'Показать всё';
|
||||
|
||||
@override
|
||||
String get pathMap_hidePath => 'Hide path';
|
||||
String get pathMap_hidePath => 'Скрыть путь';
|
||||
|
||||
@override
|
||||
String get pathMap_showPath => 'Show path';
|
||||
String get pathMap_showPath => 'Показать маршрут';
|
||||
|
||||
@override
|
||||
String get pathMap_collapsePanel => 'Collapse panel';
|
||||
String get pathMap_collapsePanel => 'Скрыть панель';
|
||||
|
||||
@override
|
||||
String get pathMap_expandPanel => 'Expand panel';
|
||||
String get pathMap_expandPanel => 'Расширить панель';
|
||||
|
||||
@override
|
||||
String get pathMap_noLocation => 'No location';
|
||||
String get pathMap_noLocation => 'Нет координат';
|
||||
|
||||
@override
|
||||
String get pathMap_followPacket => 'Lock view to packet';
|
||||
String get pathMap_followPacket => 'Следить за пакетом';
|
||||
|
||||
@override
|
||||
String get pathMap_unfollowPacket => 'Unlock view from packet';
|
||||
String get pathMap_unfollowPacket => 'Не следить за пакетом';
|
||||
}
|
||||
|
||||
@@ -321,7 +321,7 @@ class AppLocalizationsSk extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get scanner_bluetoothWebUnsupported =>
|
||||
'Bluetooth isn\'t available in the browser. Connect over USB instead.';
|
||||
'Funkcia Bluetooth nie je dostupná v prehliadači. Prepojte sa pomocou USB.';
|
||||
|
||||
@override
|
||||
String get device_quickSwitch => 'Rýchle prepínač';
|
||||
@@ -1731,37 +1731,37 @@ class AppLocalizationsSk extends AppLocalizations {
|
||||
String get map_title => 'Mapa uzlov';
|
||||
|
||||
@override
|
||||
String get map_searchHint => 'Search node name or ID';
|
||||
String get map_searchHint => 'Vyhľadajte podľa názvu alebo ID uzla';
|
||||
|
||||
@override
|
||||
String get map_activity => 'Activity';
|
||||
String get map_activity => 'Aktivita';
|
||||
|
||||
@override
|
||||
String get map_online => 'Online';
|
||||
|
||||
@override
|
||||
String get map_recent => 'Recent';
|
||||
String get map_recent => 'Nedávne';
|
||||
|
||||
@override
|
||||
String get map_stale => 'Stale';
|
||||
String get map_stale => 'Neaktuálne';
|
||||
|
||||
@override
|
||||
String get map_visible => 'Visible';
|
||||
String get map_visible => 'Viditeľný';
|
||||
|
||||
@override
|
||||
String get map_hidden => 'Hidden';
|
||||
String get map_hidden => 'Skrytý';
|
||||
|
||||
@override
|
||||
String get map_centerOnNode => 'Center on node';
|
||||
String get map_centerOnNode => 'Nacentrovať na uzol';
|
||||
|
||||
@override
|
||||
String get map_details => 'Details';
|
||||
String get map_details => 'Podrobnosti';
|
||||
|
||||
@override
|
||||
String get map_noGps => 'No GPS';
|
||||
String get map_noGps => 'Bez GPS';
|
||||
|
||||
@override
|
||||
String get map_noResults => 'No matching nodes';
|
||||
String get map_noResults => 'Nenašli sa žiadne zodpovedajúce uzly.';
|
||||
|
||||
@override
|
||||
String get map_lineOfSight => 'Úroveň výhľadu';
|
||||
@@ -4501,48 +4501,48 @@ class AppLocalizationsSk extends AppLocalizations {
|
||||
String get pathTrace_legendInferred => 'Odvodená poloha';
|
||||
|
||||
@override
|
||||
String get pathMap_viewSingle => 'Single';
|
||||
String get pathMap_viewSingle => 'Jednotlivý';
|
||||
|
||||
@override
|
||||
String get pathMap_viewCombined => 'Combined';
|
||||
String get pathMap_viewCombined => 'Spojené';
|
||||
|
||||
@override
|
||||
String get pathMap_play => 'Play';
|
||||
String get pathMap_play => 'Prehrať';
|
||||
|
||||
@override
|
||||
String get pathMap_pause => 'Pause';
|
||||
String get pathMap_pause => 'Pozastaviť';
|
||||
|
||||
@override
|
||||
String get pathMap_replay => 'Replay';
|
||||
String get pathMap_replay => 'Prehrať znova';
|
||||
|
||||
@override
|
||||
String get pathMap_stepBack => 'Previous hop';
|
||||
String get pathMap_stepBack => 'Predchádzajúci skok';
|
||||
|
||||
@override
|
||||
String get pathMap_stepForward => 'Next hop';
|
||||
String get pathMap_stepForward => 'Nasledujúci skok';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOn => 'Show packet animation';
|
||||
String get pathMap_animationOn => 'Zobraziť animáciu paketu';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOff => 'Hide packet animation';
|
||||
String get pathMap_animationOff => 'Skryť animáciu paketu';
|
||||
|
||||
@override
|
||||
String pathMap_hopOf(int current, int total) {
|
||||
return 'Hop $current of $total';
|
||||
return 'Skok $current z $total';
|
||||
}
|
||||
|
||||
@override
|
||||
String pathMap_observedPaths(int count) {
|
||||
return 'Observed paths: $count';
|
||||
return 'Pozorované cesty: $count';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_primary => 'Primary';
|
||||
String get pathMap_primary => 'Primárna';
|
||||
|
||||
@override
|
||||
String pathMap_alternate(int index) {
|
||||
return 'Alt $index';
|
||||
return 'Alternatívny $index';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4550,8 +4550,9 @@ class AppLocalizationsSk extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops',
|
||||
one: '1 hop',
|
||||
other: '$count skokov',
|
||||
few: '$count skoky',
|
||||
one: '1 skok',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -4562,14 +4563,14 @@ class AppLocalizationsSk extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_legendShared => 'Shared segment';
|
||||
String get pathMap_legendShared => 'Spoločný segment';
|
||||
|
||||
@override
|
||||
String get pathMap_legendEstimated => 'Estimated segment';
|
||||
String get pathMap_legendEstimated => 'Odhadovaný segment';
|
||||
|
||||
@override
|
||||
String pathMap_sharedNodeCount(int count) {
|
||||
return 'Used by $count paths';
|
||||
return 'Používané $count cestami';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4577,33 +4578,34 @@ class AppLocalizationsSk extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops have no location — the shown path is partial',
|
||||
one: '1 hop has no location — the shown path is partial',
|
||||
other: '$count skokov nemá polohu — zobrazená trasa je neúplná',
|
||||
few: '$count skoky nemajú polohu — zobrazená trasa je neúplná',
|
||||
one: '1 skok nemá polohu — zobrazená trasa je neúplná',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_showAllPaths => 'Show all';
|
||||
String get pathMap_showAllPaths => 'Zobraziť všetky';
|
||||
|
||||
@override
|
||||
String get pathMap_hidePath => 'Hide path';
|
||||
String get pathMap_hidePath => 'Skryť cestu';
|
||||
|
||||
@override
|
||||
String get pathMap_showPath => 'Show path';
|
||||
String get pathMap_showPath => 'Zobraziť trasu';
|
||||
|
||||
@override
|
||||
String get pathMap_collapsePanel => 'Collapse panel';
|
||||
String get pathMap_collapsePanel => 'Zatvoriť panel';
|
||||
|
||||
@override
|
||||
String get pathMap_expandPanel => 'Expand panel';
|
||||
String get pathMap_expandPanel => 'Rozbaliť panel';
|
||||
|
||||
@override
|
||||
String get pathMap_noLocation => 'No location';
|
||||
String get pathMap_noLocation => 'Bez polohy';
|
||||
|
||||
@override
|
||||
String get pathMap_followPacket => 'Lock view to packet';
|
||||
String get pathMap_followPacket => 'Uzamknúť pohľad na paket';
|
||||
|
||||
@override
|
||||
String get pathMap_unfollowPacket => 'Unlock view from packet';
|
||||
String get pathMap_unfollowPacket => 'Odomknúť pohľad od paketu';
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ class AppLocalizationsSl extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get scanner_bluetoothWebUnsupported =>
|
||||
'Bluetooth isn\'t available in the browser. Connect over USB instead.';
|
||||
'Funkcija Bluetooth v brskalniku ni na voljo. Povežite se preko USB-ja namesto tega.';
|
||||
|
||||
@override
|
||||
String get device_quickSwitch => 'Hitro preklop';
|
||||
@@ -1724,37 +1724,37 @@ class AppLocalizationsSl extends AppLocalizations {
|
||||
String get map_title => 'Mapa omrežja';
|
||||
|
||||
@override
|
||||
String get map_searchHint => 'Search node name or ID';
|
||||
String get map_searchHint => 'Iščite ime ali ID vozlišča';
|
||||
|
||||
@override
|
||||
String get map_activity => 'Activity';
|
||||
String get map_activity => 'Dejavnost';
|
||||
|
||||
@override
|
||||
String get map_online => 'Online';
|
||||
String get map_online => 'V omrežju';
|
||||
|
||||
@override
|
||||
String get map_recent => 'Recent';
|
||||
String get map_recent => 'Nedavni';
|
||||
|
||||
@override
|
||||
String get map_stale => 'Stale';
|
||||
String get map_stale => 'Zastarelo';
|
||||
|
||||
@override
|
||||
String get map_visible => 'Visible';
|
||||
String get map_visible => 'Vidno';
|
||||
|
||||
@override
|
||||
String get map_hidden => 'Hidden';
|
||||
String get map_hidden => 'Skrit';
|
||||
|
||||
@override
|
||||
String get map_centerOnNode => 'Center on node';
|
||||
String get map_centerOnNode => 'Centriraj na vozlišče';
|
||||
|
||||
@override
|
||||
String get map_details => 'Details';
|
||||
String get map_details => 'Podrobnosti';
|
||||
|
||||
@override
|
||||
String get map_noGps => 'No GPS';
|
||||
String get map_noGps => 'Brez GPS';
|
||||
|
||||
@override
|
||||
String get map_noResults => 'No matching nodes';
|
||||
String get map_noResults => 'Ni ujemajočih se vozlišč';
|
||||
|
||||
@override
|
||||
String get map_lineOfSight => 'Linija vida';
|
||||
@@ -4500,48 +4500,48 @@ class AppLocalizationsSl extends AppLocalizations {
|
||||
String get pathTrace_legendInferred => 'Izpeljana lokacija';
|
||||
|
||||
@override
|
||||
String get pathMap_viewSingle => 'Single';
|
||||
String get pathMap_viewSingle => 'Posamično';
|
||||
|
||||
@override
|
||||
String get pathMap_viewCombined => 'Combined';
|
||||
String get pathMap_viewCombined => 'Skupno';
|
||||
|
||||
@override
|
||||
String get pathMap_play => 'Play';
|
||||
String get pathMap_play => 'Predvajaj';
|
||||
|
||||
@override
|
||||
String get pathMap_pause => 'Pause';
|
||||
String get pathMap_pause => 'Premor';
|
||||
|
||||
@override
|
||||
String get pathMap_replay => 'Replay';
|
||||
String get pathMap_replay => 'Ponovitev';
|
||||
|
||||
@override
|
||||
String get pathMap_stepBack => 'Previous hop';
|
||||
String get pathMap_stepBack => 'Prejšnji skok';
|
||||
|
||||
@override
|
||||
String get pathMap_stepForward => 'Next hop';
|
||||
String get pathMap_stepForward => 'Naslednji skok';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOn => 'Show packet animation';
|
||||
String get pathMap_animationOn => 'Prikaži animacijo paketa';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOff => 'Hide packet animation';
|
||||
String get pathMap_animationOff => 'Skrij animacijo paketa';
|
||||
|
||||
@override
|
||||
String pathMap_hopOf(int current, int total) {
|
||||
return 'Hop $current of $total';
|
||||
return 'Skok $current od $total';
|
||||
}
|
||||
|
||||
@override
|
||||
String pathMap_observedPaths(int count) {
|
||||
return 'Observed paths: $count';
|
||||
return 'Opazovane poti: $count';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_primary => 'Primary';
|
||||
String get pathMap_primary => 'Primarna';
|
||||
|
||||
@override
|
||||
String pathMap_alternate(int index) {
|
||||
return 'Alt $index';
|
||||
return 'Alternativa $index';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4549,8 +4549,10 @@ class AppLocalizationsSl extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops',
|
||||
one: '1 hop',
|
||||
other: '$count skokov',
|
||||
few: '$count skoki',
|
||||
two: '2 skoka',
|
||||
one: '1 skok',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -4561,14 +4563,14 @@ class AppLocalizationsSl extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_legendShared => 'Shared segment';
|
||||
String get pathMap_legendShared => 'Deljen segment';
|
||||
|
||||
@override
|
||||
String get pathMap_legendEstimated => 'Estimated segment';
|
||||
String get pathMap_legendEstimated => 'Ocenjen segment';
|
||||
|
||||
@override
|
||||
String pathMap_sharedNodeCount(int count) {
|
||||
return 'Used by $count paths';
|
||||
return 'Uporablja $count poti';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4576,33 +4578,35 @@ class AppLocalizationsSl extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops have no location — the shown path is partial',
|
||||
one: '1 hop has no location — the shown path is partial',
|
||||
other: '$count skokov nima lokacije — prikazana pot je delna',
|
||||
few: '$count skoki nimajo lokacije — prikazana pot je delna',
|
||||
two: '2 skoka nimata lokacije — prikazana pot je delna',
|
||||
one: '1 skok nima lokacije — prikazana pot je delna',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_showAllPaths => 'Show all';
|
||||
String get pathMap_showAllPaths => 'Pokaži vse';
|
||||
|
||||
@override
|
||||
String get pathMap_hidePath => 'Hide path';
|
||||
String get pathMap_hidePath => 'Skrij pot';
|
||||
|
||||
@override
|
||||
String get pathMap_showPath => 'Show path';
|
||||
String get pathMap_showPath => 'Pokaži pot';
|
||||
|
||||
@override
|
||||
String get pathMap_collapsePanel => 'Collapse panel';
|
||||
String get pathMap_collapsePanel => 'Strni ploščo';
|
||||
|
||||
@override
|
||||
String get pathMap_expandPanel => 'Expand panel';
|
||||
String get pathMap_expandPanel => 'Razširi ploščo';
|
||||
|
||||
@override
|
||||
String get pathMap_noLocation => 'No location';
|
||||
String get pathMap_noLocation => 'Brez lokacije';
|
||||
|
||||
@override
|
||||
String get pathMap_followPacket => 'Lock view to packet';
|
||||
String get pathMap_followPacket => 'Zakleni pogled na paket';
|
||||
|
||||
@override
|
||||
String get pathMap_unfollowPacket => 'Unlock view from packet';
|
||||
String get pathMap_unfollowPacket => 'Odkleni pogled od paketa';
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ class AppLocalizationsSv extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get scanner_bluetoothWebUnsupported =>
|
||||
'Bluetooth isn\'t available in the browser. Connect over USB instead.';
|
||||
'Bluetooth är inte tillgängligt i webbläsaren. Anslut istället via USB.';
|
||||
|
||||
@override
|
||||
String get device_quickSwitch => 'Snabb växling';
|
||||
@@ -1717,37 +1717,37 @@ class AppLocalizationsSv extends AppLocalizations {
|
||||
String get map_title => 'Nodkarta';
|
||||
|
||||
@override
|
||||
String get map_searchHint => 'Search node name or ID';
|
||||
String get map_searchHint => 'Sök efter nodens namn eller ID';
|
||||
|
||||
@override
|
||||
String get map_activity => 'Activity';
|
||||
String get map_activity => 'Aktivitet';
|
||||
|
||||
@override
|
||||
String get map_online => 'Online';
|
||||
|
||||
@override
|
||||
String get map_recent => 'Recent';
|
||||
String get map_recent => 'Nyligen';
|
||||
|
||||
@override
|
||||
String get map_stale => 'Stale';
|
||||
String get map_stale => 'Inaktuell';
|
||||
|
||||
@override
|
||||
String get map_visible => 'Visible';
|
||||
String get map_visible => 'Synlig';
|
||||
|
||||
@override
|
||||
String get map_hidden => 'Hidden';
|
||||
String get map_hidden => 'Dold';
|
||||
|
||||
@override
|
||||
String get map_centerOnNode => 'Center on node';
|
||||
String get map_centerOnNode => 'Centrera på nod';
|
||||
|
||||
@override
|
||||
String get map_details => 'Details';
|
||||
String get map_details => 'Detaljer';
|
||||
|
||||
@override
|
||||
String get map_noGps => 'No GPS';
|
||||
String get map_noGps => 'Ingen GPS';
|
||||
|
||||
@override
|
||||
String get map_noResults => 'No matching nodes';
|
||||
String get map_noResults => 'Inga matchande noder';
|
||||
|
||||
@override
|
||||
String get map_lineOfSight => 'Synlinje';
|
||||
@@ -4474,48 +4474,48 @@ class AppLocalizationsSv extends AppLocalizations {
|
||||
String get pathTrace_legendInferred => 'Antagen position';
|
||||
|
||||
@override
|
||||
String get pathMap_viewSingle => 'Single';
|
||||
String get pathMap_viewSingle => 'Enkel';
|
||||
|
||||
@override
|
||||
String get pathMap_viewCombined => 'Combined';
|
||||
String get pathMap_viewCombined => 'Kombinerat';
|
||||
|
||||
@override
|
||||
String get pathMap_play => 'Play';
|
||||
String get pathMap_play => 'Spela';
|
||||
|
||||
@override
|
||||
String get pathMap_pause => 'Pause';
|
||||
String get pathMap_pause => 'Pausa';
|
||||
|
||||
@override
|
||||
String get pathMap_replay => 'Replay';
|
||||
String get pathMap_replay => 'Återspela';
|
||||
|
||||
@override
|
||||
String get pathMap_stepBack => 'Previous hop';
|
||||
String get pathMap_stepBack => 'Föregående hopp';
|
||||
|
||||
@override
|
||||
String get pathMap_stepForward => 'Next hop';
|
||||
String get pathMap_stepForward => 'Nästa hopp';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOn => 'Show packet animation';
|
||||
String get pathMap_animationOn => 'Visa paketanimering';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOff => 'Hide packet animation';
|
||||
String get pathMap_animationOff => 'Dölj paketanimering';
|
||||
|
||||
@override
|
||||
String pathMap_hopOf(int current, int total) {
|
||||
return 'Hop $current of $total';
|
||||
return 'Hopp $current av $total';
|
||||
}
|
||||
|
||||
@override
|
||||
String pathMap_observedPaths(int count) {
|
||||
return 'Observed paths: $count';
|
||||
return 'Observerade vägar: $count';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_primary => 'Primary';
|
||||
String get pathMap_primary => 'Primär';
|
||||
|
||||
@override
|
||||
String pathMap_alternate(int index) {
|
||||
return 'Alt $index';
|
||||
return 'Alternativ $index';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4523,8 +4523,8 @@ class AppLocalizationsSv extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops',
|
||||
one: '1 hop',
|
||||
other: '$count hopp',
|
||||
one: '1 hopp',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -4535,14 +4535,14 @@ class AppLocalizationsSv extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_legendShared => 'Shared segment';
|
||||
String get pathMap_legendShared => 'Delat segment';
|
||||
|
||||
@override
|
||||
String get pathMap_legendEstimated => 'Estimated segment';
|
||||
String get pathMap_legendEstimated => 'Uppskattat segment';
|
||||
|
||||
@override
|
||||
String pathMap_sharedNodeCount(int count) {
|
||||
return 'Used by $count paths';
|
||||
return 'Används av $count vägar';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4550,33 +4550,33 @@ class AppLocalizationsSv extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops have no location — the shown path is partial',
|
||||
one: '1 hop has no location — the shown path is partial',
|
||||
other: '$count hopp saknar position — den visade vägen är ofullständig',
|
||||
one: '1 hopp saknar position — den visade vägen är ofullständig',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_showAllPaths => 'Show all';
|
||||
String get pathMap_showAllPaths => 'Visa allt';
|
||||
|
||||
@override
|
||||
String get pathMap_hidePath => 'Hide path';
|
||||
String get pathMap_hidePath => 'Dölj väg';
|
||||
|
||||
@override
|
||||
String get pathMap_showPath => 'Show path';
|
||||
String get pathMap_showPath => 'Visa väg';
|
||||
|
||||
@override
|
||||
String get pathMap_collapsePanel => 'Collapse panel';
|
||||
String get pathMap_collapsePanel => 'Fäll ihop panel';
|
||||
|
||||
@override
|
||||
String get pathMap_expandPanel => 'Expand panel';
|
||||
String get pathMap_expandPanel => 'Expandera panel';
|
||||
|
||||
@override
|
||||
String get pathMap_noLocation => 'No location';
|
||||
String get pathMap_noLocation => 'Ingen position';
|
||||
|
||||
@override
|
||||
String get pathMap_followPacket => 'Lock view to packet';
|
||||
String get pathMap_followPacket => 'Lås vy till paket';
|
||||
|
||||
@override
|
||||
String get pathMap_unfollowPacket => 'Unlock view from packet';
|
||||
String get pathMap_unfollowPacket => 'Lås upp vy från paket';
|
||||
}
|
||||
|
||||
@@ -321,7 +321,7 @@ class AppLocalizationsUk extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get scanner_bluetoothWebUnsupported =>
|
||||
'Bluetooth isn\'t available in the browser. Connect over USB instead.';
|
||||
'Bluetooth недоступний у браузері. Підключіться через USB.';
|
||||
|
||||
@override
|
||||
String get device_quickSwitch => 'Швидке перемикання';
|
||||
@@ -1737,37 +1737,37 @@ class AppLocalizationsUk extends AppLocalizations {
|
||||
String get map_title => 'Карта вузлів';
|
||||
|
||||
@override
|
||||
String get map_searchHint => 'Search node name or ID';
|
||||
String get map_searchHint => 'Назва або ID вузла';
|
||||
|
||||
@override
|
||||
String get map_activity => 'Activity';
|
||||
String get map_activity => 'Активність';
|
||||
|
||||
@override
|
||||
String get map_online => 'Online';
|
||||
String get map_online => 'Онлайн';
|
||||
|
||||
@override
|
||||
String get map_recent => 'Recent';
|
||||
String get map_recent => 'Нещодавні';
|
||||
|
||||
@override
|
||||
String get map_stale => 'Stale';
|
||||
String get map_stale => 'Застаріло';
|
||||
|
||||
@override
|
||||
String get map_visible => 'Visible';
|
||||
String get map_visible => 'Видимий';
|
||||
|
||||
@override
|
||||
String get map_hidden => 'Hidden';
|
||||
String get map_hidden => 'Прихований';
|
||||
|
||||
@override
|
||||
String get map_centerOnNode => 'Center on node';
|
||||
String get map_centerOnNode => 'Центрувати на вузлі';
|
||||
|
||||
@override
|
||||
String get map_details => 'Details';
|
||||
String get map_details => 'Деталі';
|
||||
|
||||
@override
|
||||
String get map_noGps => 'No GPS';
|
||||
String get map_noGps => 'Без GPS';
|
||||
|
||||
@override
|
||||
String get map_noResults => 'No matching nodes';
|
||||
String get map_noResults => 'Не знайдено відповідних вузлів';
|
||||
|
||||
@override
|
||||
String get map_lineOfSight => 'Пряма видимість';
|
||||
@@ -4534,48 +4534,48 @@ class AppLocalizationsUk extends AppLocalizations {
|
||||
String get pathTrace_legendInferred => 'Висновок щодо положення';
|
||||
|
||||
@override
|
||||
String get pathMap_viewSingle => 'Single';
|
||||
String get pathMap_viewSingle => 'Один';
|
||||
|
||||
@override
|
||||
String get pathMap_viewCombined => 'Combined';
|
||||
String get pathMap_viewCombined => 'Об\'єднаний';
|
||||
|
||||
@override
|
||||
String get pathMap_play => 'Play';
|
||||
String get pathMap_play => 'Відтворити';
|
||||
|
||||
@override
|
||||
String get pathMap_pause => 'Pause';
|
||||
String get pathMap_pause => 'Призупинити';
|
||||
|
||||
@override
|
||||
String get pathMap_replay => 'Replay';
|
||||
String get pathMap_replay => 'Повтор';
|
||||
|
||||
@override
|
||||
String get pathMap_stepBack => 'Previous hop';
|
||||
String get pathMap_stepBack => 'Попередній перехід';
|
||||
|
||||
@override
|
||||
String get pathMap_stepForward => 'Next hop';
|
||||
String get pathMap_stepForward => 'Наступний перехід';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOn => 'Show packet animation';
|
||||
String get pathMap_animationOn => 'Відобразити анімацію пакета';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOff => 'Hide packet animation';
|
||||
String get pathMap_animationOff => 'Приховати анімацію пакета';
|
||||
|
||||
@override
|
||||
String pathMap_hopOf(int current, int total) {
|
||||
return 'Hop $current of $total';
|
||||
return 'Перехід $current з $total';
|
||||
}
|
||||
|
||||
@override
|
||||
String pathMap_observedPaths(int count) {
|
||||
return 'Observed paths: $count';
|
||||
return 'Зафіксовані маршрути: $count';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_primary => 'Primary';
|
||||
String get pathMap_primary => 'Основний';
|
||||
|
||||
@override
|
||||
String pathMap_alternate(int index) {
|
||||
return 'Alt $index';
|
||||
return 'Альт. $index';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4583,8 +4583,10 @@ class AppLocalizationsUk extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops',
|
||||
one: '1 hop',
|
||||
other: '$count переходів',
|
||||
many: '$count переходів',
|
||||
few: '$count переходи',
|
||||
one: '1 перехід',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -4595,14 +4597,14 @@ class AppLocalizationsUk extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_legendShared => 'Shared segment';
|
||||
String get pathMap_legendShared => 'Об\'єднаний сегмент';
|
||||
|
||||
@override
|
||||
String get pathMap_legendEstimated => 'Estimated segment';
|
||||
String get pathMap_legendEstimated => 'Орієнтовний сегмент';
|
||||
|
||||
@override
|
||||
String pathMap_sharedNodeCount(int count) {
|
||||
return 'Used by $count paths';
|
||||
return 'Використовується $count шляхами';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4610,33 +4612,36 @@ class AppLocalizationsUk extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops have no location — the shown path is partial',
|
||||
one: '1 hop has no location — the shown path is partial',
|
||||
other:
|
||||
'$count переходів не мають геопозиції — показаний шлях є частковим',
|
||||
many: '$count переходів не мають геопозиції — показаний шлях є частковим',
|
||||
few: '$count переходи не мають геопозиції — показаний шлях є частковим',
|
||||
one: '1 перехід не має геопозиції — показаний шлях є частковим',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_showAllPaths => 'Show all';
|
||||
String get pathMap_showAllPaths => 'Показати все';
|
||||
|
||||
@override
|
||||
String get pathMap_hidePath => 'Hide path';
|
||||
String get pathMap_hidePath => 'Приховати шлях';
|
||||
|
||||
@override
|
||||
String get pathMap_showPath => 'Show path';
|
||||
String get pathMap_showPath => 'Показати шлях';
|
||||
|
||||
@override
|
||||
String get pathMap_collapsePanel => 'Collapse panel';
|
||||
String get pathMap_collapsePanel => 'Згорнути панель';
|
||||
|
||||
@override
|
||||
String get pathMap_expandPanel => 'Expand panel';
|
||||
String get pathMap_expandPanel => 'Розгорнути панель';
|
||||
|
||||
@override
|
||||
String get pathMap_noLocation => 'No location';
|
||||
String get pathMap_noLocation => 'Без геопозиції';
|
||||
|
||||
@override
|
||||
String get pathMap_followPacket => 'Lock view to packet';
|
||||
String get pathMap_followPacket => 'Прив\'язати вигляд до пакету';
|
||||
|
||||
@override
|
||||
String get pathMap_unfollowPacket => 'Unlock view from packet';
|
||||
String get pathMap_unfollowPacket => 'Відв\'язати вигляд від пакету';
|
||||
}
|
||||
|
||||
@@ -306,8 +306,7 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String get scanner_enableBluetooth => '启用蓝牙';
|
||||
|
||||
@override
|
||||
String get scanner_bluetoothWebUnsupported =>
|
||||
'Bluetooth isn\'t available in the browser. Connect over USB instead.';
|
||||
String get scanner_bluetoothWebUnsupported => '浏览器不支持蓝牙,请改用 USB 连接。';
|
||||
|
||||
@override
|
||||
String get device_quickSwitch => '快速切换';
|
||||
@@ -1639,37 +1638,37 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String get map_title => '节点地图';
|
||||
|
||||
@override
|
||||
String get map_searchHint => 'Search node name or ID';
|
||||
String get map_searchHint => '搜索节点名称或ID';
|
||||
|
||||
@override
|
||||
String get map_activity => 'Activity';
|
||||
String get map_activity => '活动';
|
||||
|
||||
@override
|
||||
String get map_online => 'Online';
|
||||
String get map_online => '在线';
|
||||
|
||||
@override
|
||||
String get map_recent => 'Recent';
|
||||
String get map_recent => '最近';
|
||||
|
||||
@override
|
||||
String get map_stale => 'Stale';
|
||||
String get map_stale => '过时';
|
||||
|
||||
@override
|
||||
String get map_visible => 'Visible';
|
||||
String get map_visible => '可见';
|
||||
|
||||
@override
|
||||
String get map_hidden => 'Hidden';
|
||||
String get map_hidden => '已隐藏';
|
||||
|
||||
@override
|
||||
String get map_centerOnNode => 'Center on node';
|
||||
String get map_centerOnNode => '以节点为中心';
|
||||
|
||||
@override
|
||||
String get map_details => 'Details';
|
||||
String get map_details => '详细信息';
|
||||
|
||||
@override
|
||||
String get map_noGps => 'No GPS';
|
||||
String get map_noGps => '无 GPS';
|
||||
|
||||
@override
|
||||
String get map_noResults => 'No matching nodes';
|
||||
String get map_noResults => '未找到匹配的节点';
|
||||
|
||||
@override
|
||||
String get map_lineOfSight => '视线';
|
||||
@@ -4184,48 +4183,48 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String get pathTrace_legendInferred => '推测的位置';
|
||||
|
||||
@override
|
||||
String get pathMap_viewSingle => 'Single';
|
||||
String get pathMap_viewSingle => '单条';
|
||||
|
||||
@override
|
||||
String get pathMap_viewCombined => 'Combined';
|
||||
String get pathMap_viewCombined => '综合';
|
||||
|
||||
@override
|
||||
String get pathMap_play => 'Play';
|
||||
String get pathMap_play => '播放';
|
||||
|
||||
@override
|
||||
String get pathMap_pause => 'Pause';
|
||||
String get pathMap_pause => '暂停';
|
||||
|
||||
@override
|
||||
String get pathMap_replay => 'Replay';
|
||||
String get pathMap_replay => '重播';
|
||||
|
||||
@override
|
||||
String get pathMap_stepBack => 'Previous hop';
|
||||
String get pathMap_stepBack => '上一跳';
|
||||
|
||||
@override
|
||||
String get pathMap_stepForward => 'Next hop';
|
||||
String get pathMap_stepForward => '下一跳';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOn => 'Show packet animation';
|
||||
String get pathMap_animationOn => '显示数据包动画';
|
||||
|
||||
@override
|
||||
String get pathMap_animationOff => 'Hide packet animation';
|
||||
String get pathMap_animationOff => '隐藏数据包动画';
|
||||
|
||||
@override
|
||||
String pathMap_hopOf(int current, int total) {
|
||||
return 'Hop $current of $total';
|
||||
return '第 $current 跳,共 $total 跳';
|
||||
}
|
||||
|
||||
@override
|
||||
String pathMap_observedPaths(int count) {
|
||||
return 'Observed paths: $count';
|
||||
return '观测到的路径:$count';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_primary => 'Primary';
|
||||
String get pathMap_primary => '主路径';
|
||||
|
||||
@override
|
||||
String pathMap_alternate(int index) {
|
||||
return 'Alt $index';
|
||||
return '备用 $index';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4233,8 +4232,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops',
|
||||
one: '1 hop',
|
||||
other: '$count 跳',
|
||||
one: '1 跳',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -4245,14 +4244,14 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_legendShared => 'Shared segment';
|
||||
String get pathMap_legendShared => '共享路段';
|
||||
|
||||
@override
|
||||
String get pathMap_legendEstimated => 'Estimated segment';
|
||||
String get pathMap_legendEstimated => '估算路段';
|
||||
|
||||
@override
|
||||
String pathMap_sharedNodeCount(int count) {
|
||||
return 'Used by $count paths';
|
||||
return '已被 $count 条路径使用';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -4260,33 +4259,33 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count hops have no location — the shown path is partial',
|
||||
one: '1 hop has no location — the shown path is partial',
|
||||
other: '$count 跳无位置信息 — 显示的路径不完整',
|
||||
one: '1 跳无位置信息 — 显示的路径不完整',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pathMap_showAllPaths => 'Show all';
|
||||
String get pathMap_showAllPaths => '显示全部';
|
||||
|
||||
@override
|
||||
String get pathMap_hidePath => 'Hide path';
|
||||
String get pathMap_hidePath => '隐藏路径';
|
||||
|
||||
@override
|
||||
String get pathMap_showPath => 'Show path';
|
||||
String get pathMap_showPath => '显示路径';
|
||||
|
||||
@override
|
||||
String get pathMap_collapsePanel => 'Collapse panel';
|
||||
String get pathMap_collapsePanel => '收起面板';
|
||||
|
||||
@override
|
||||
String get pathMap_expandPanel => 'Expand panel';
|
||||
String get pathMap_expandPanel => '展开面板';
|
||||
|
||||
@override
|
||||
String get pathMap_noLocation => 'No location';
|
||||
String get pathMap_noLocation => '无位置';
|
||||
|
||||
@override
|
||||
String get pathMap_followPacket => 'Lock view to packet';
|
||||
String get pathMap_followPacket => '锁定视图跟随数据包';
|
||||
|
||||
@override
|
||||
String get pathMap_unfollowPacket => 'Unlock view from packet';
|
||||
String get pathMap_unfollowPacket => '解锁视图跟随';
|
||||
}
|
||||
|
||||
+95
-1
@@ -2446,5 +2446,99 @@
|
||||
"chrome_bluetoothRequiresChromium": "Web Bluetooth vereist een Chromium-browser.",
|
||||
"channels_communityShortId": "ID: {id}...",
|
||||
"pathTrace_legendGpsConfirmed": "GPS-locatie bevestigd",
|
||||
"pathTrace_legendInferred": "Afgeleide positie"
|
||||
"pathTrace_legendInferred": "Afgeleide positie",
|
||||
"@pathMap_hopOf": {
|
||||
"placeholders": {
|
||||
"current": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_observedPaths": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_alternate": {
|
||||
"placeholders": {
|
||||
"index": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_hopCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_gpsCount": {
|
||||
"placeholders": {
|
||||
"confirmed": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_sharedNodeCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_partialAnimation": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"map_activity": "Activiteit",
|
||||
"map_searchHint": "Zoek op naam of ID van de knoop",
|
||||
"scanner_bluetoothWebUnsupported": "Bluetooth is niet beschikbaar in de browser. Verbind dan via USB.",
|
||||
"map_online": "Online",
|
||||
"map_recent": "Recent",
|
||||
"map_stale": "Verouderd",
|
||||
"map_visible": "Zichtbaar",
|
||||
"map_hidden": "Verborgen",
|
||||
"map_centerOnNode": "Centreer op node",
|
||||
"map_details": "Details",
|
||||
"map_noGps": "Geen GPS",
|
||||
"map_noResults": "Geen overeenkomende nodes",
|
||||
"pathMap_viewSingle": "Enkel",
|
||||
"pathMap_viewCombined": "Gezamenlijk",
|
||||
"pathMap_play": "Afspelen",
|
||||
"pathMap_pause": "Pauze",
|
||||
"pathMap_replay": "Herhalen",
|
||||
"pathMap_stepBack": "Vorige hop",
|
||||
"pathMap_stepForward": "Volgende hop",
|
||||
"pathMap_animationOn": "Pakketanimatie tonen",
|
||||
"pathMap_animationOff": "Pakketanimatie verbergen",
|
||||
"pathMap_hopOf": "Hop {current} van {total}",
|
||||
"pathMap_observedPaths": "Waargenomen paden: {count}",
|
||||
"pathMap_primary": "Primair",
|
||||
"pathMap_alternate": "Alternatief {index}",
|
||||
"pathMap_hopCount": "{count, plural, =1{1 hop} other{{count} hops}}",
|
||||
"pathMap_legendShared": "Gedeeld segment",
|
||||
"pathMap_legendEstimated": "Geschat segment",
|
||||
"pathMap_sharedNodeCount": "Gebruikt door {count} paden",
|
||||
"pathMap_partialAnimation": "{count, plural, =1{1 hop heeft geen locatie — het weergegeven pad is onvolledig} other{{count} hops hebben geen locatie — het weergegeven pad is onvolledig}}",
|
||||
"pathMap_showAllPaths": "Toon alles",
|
||||
"pathMap_hidePath": "Verberg pad",
|
||||
"pathMap_showPath": "Toon pad",
|
||||
"pathMap_collapsePanel": "Paneel inklappen",
|
||||
"pathMap_expandPanel": "Paneel uitklappen",
|
||||
"pathMap_noLocation": "Geen locatie",
|
||||
"pathMap_followPacket": "Weergave vergrendelen op pakket",
|
||||
"pathMap_unfollowPacket": "Weergave ontgrendelen van pakket",
|
||||
"pathMap_gpsCount": "{confirmed}/{total} GPS"
|
||||
}
|
||||
|
||||
+95
-1
@@ -2484,5 +2484,99 @@
|
||||
"chrome_bluetoothRequiresChromium": "Web Bluetooth wymaga przeglądarki Chromium.",
|
||||
"channels_communityShortId": "ID: {id}...",
|
||||
"pathTrace_legendGpsConfirmed": "GPS potwierdzone",
|
||||
"pathTrace_legendInferred": "Wywnioskowana pozycja"
|
||||
"pathTrace_legendInferred": "Wywnioskowana pozycja",
|
||||
"@pathMap_hopOf": {
|
||||
"placeholders": {
|
||||
"current": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_observedPaths": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_alternate": {
|
||||
"placeholders": {
|
||||
"index": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_hopCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_gpsCount": {
|
||||
"placeholders": {
|
||||
"confirmed": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_sharedNodeCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_partialAnimation": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"map_online": "Online",
|
||||
"map_searchHint": "Wyszukaj nazwę lub identyfikator węzła",
|
||||
"scanner_bluetoothWebUnsupported": "Bluetooth nie jest dostępny w przeglądarce. Połącz się przez USB.",
|
||||
"map_activity": "Aktywność",
|
||||
"map_recent": "Ostatnie",
|
||||
"map_stale": "Nieaktualne",
|
||||
"map_visible": "Widoczny",
|
||||
"map_hidden": "Ukryty",
|
||||
"map_centerOnNode": "Wyśrodkuj na węźle",
|
||||
"map_details": "Szczegóły",
|
||||
"map_noGps": "Brak GPS",
|
||||
"map_noResults": "Brak pasujących węzłów",
|
||||
"pathMap_viewSingle": "Pojedyncza",
|
||||
"pathMap_viewCombined": "Połączone",
|
||||
"pathMap_play": "Odtwórz",
|
||||
"pathMap_pause": "Wstrzymaj",
|
||||
"pathMap_replay": "Odtwórz ponownie",
|
||||
"pathMap_stepBack": "Poprzedni skok",
|
||||
"pathMap_stepForward": "Następny skok",
|
||||
"pathMap_animationOn": "Pokaż animację pakietu",
|
||||
"pathMap_animationOff": "Ukryj animację pakietu",
|
||||
"pathMap_hopOf": "Skok {current} z {total}",
|
||||
"pathMap_observedPaths": "Obserwowane trasy: {count}",
|
||||
"pathMap_primary": "Główna",
|
||||
"pathMap_alternate": "Alt. {index}",
|
||||
"pathMap_hopCount": "{count, plural, =1{1 skok} few{{count} skoki} many{{count} skoków} other{{count} skoku}}",
|
||||
"pathMap_legendShared": "Wspólny segment",
|
||||
"pathMap_legendEstimated": "Szacunkowy segment",
|
||||
"pathMap_sharedNodeCount": "Wykorzystywane przez {count} ścieżek",
|
||||
"pathMap_partialAnimation": "{count, plural, =1{1 skok nie ma lokalizacji — pokazana ścieżka jest niekompletna} few{{count} skoki nie mają lokalizacji — pokazana ścieżka jest niekompletna} many{{count} skoków nie ma lokalizacji — pokazana ścieżka jest niekompletna} other{{count} skoku nie ma lokalizacji — pokazana ścieżka jest niekompletna}}",
|
||||
"pathMap_showAllPaths": "Pokaż wszystkie",
|
||||
"pathMap_hidePath": "Ukryj ścieżkę",
|
||||
"pathMap_showPath": "Wyświetl trasę",
|
||||
"pathMap_collapsePanel": "Zwiń panel",
|
||||
"pathMap_expandPanel": "Rozwiń panel",
|
||||
"pathMap_noLocation": "Brak lokalizacji",
|
||||
"pathMap_followPacket": "Śledź pakiet",
|
||||
"pathMap_unfollowPacket": "Przestań śledzić pakiet",
|
||||
"pathMap_gpsCount": "{confirmed}/{total} GPS"
|
||||
}
|
||||
|
||||
+95
-1
@@ -2446,5 +2446,99 @@
|
||||
"chrome_bluetoothRequiresChromium": "O Web Bluetooth requer um navegador Chromium.",
|
||||
"channels_communityShortId": "ID: {id}...",
|
||||
"pathTrace_legendGpsConfirmed": "GPS confirmado",
|
||||
"pathTrace_legendInferred": "Posição inferida"
|
||||
"pathTrace_legendInferred": "Posição inferida",
|
||||
"@pathMap_hopOf": {
|
||||
"placeholders": {
|
||||
"current": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_observedPaths": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_alternate": {
|
||||
"placeholders": {
|
||||
"index": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_hopCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_gpsCount": {
|
||||
"placeholders": {
|
||||
"confirmed": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_sharedNodeCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_partialAnimation": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"map_online": "Online",
|
||||
"map_activity": "Atividade",
|
||||
"scanner_bluetoothWebUnsupported": "A funcionalidade Bluetooth não está disponível no navegador. Conecte-se via USB em vez disso.",
|
||||
"map_searchHint": "Pesquisar por nome ou ID do nó",
|
||||
"map_recent": "Recente",
|
||||
"map_stale": "Vencido",
|
||||
"map_visible": "Visível",
|
||||
"map_hidden": "Escondido",
|
||||
"map_centerOnNode": "Centralizar no nó",
|
||||
"map_details": "Detalhes",
|
||||
"map_noGps": "Sem GPS",
|
||||
"map_noResults": "Nenhum nó encontrado",
|
||||
"pathMap_viewSingle": "Único",
|
||||
"pathMap_viewCombined": "Combinado",
|
||||
"pathMap_play": "Reproduzir",
|
||||
"pathMap_pause": "Pausa",
|
||||
"pathMap_stepBack": "Salto anterior",
|
||||
"pathMap_replay": "Repetir",
|
||||
"pathMap_stepForward": "Próximo salto",
|
||||
"pathMap_animationOn": "Exibir animação do pacote",
|
||||
"pathMap_animationOff": "Ocultar a animação do pacote",
|
||||
"pathMap_hopOf": "Salto {current} de {total}",
|
||||
"pathMap_observedPaths": "Caminhos observados: {count}",
|
||||
"pathMap_primary": "Primário",
|
||||
"pathMap_alternate": "Alt {index}",
|
||||
"pathMap_hopCount": "{count, plural, =1{1 salto} other{{count} saltos}}",
|
||||
"pathMap_legendShared": "Segmento compartilhado",
|
||||
"pathMap_legendEstimated": "Segmento estimado",
|
||||
"pathMap_sharedNodeCount": "Utilizado em {count} caminhos",
|
||||
"pathMap_partialAnimation": "{count, plural, =1{1 salto não tem localização — o caminho mostrado é parcial} other{{count} saltos não têm localização — o caminho mostrado é parcial}}",
|
||||
"pathMap_showAllPaths": "Mostrar tudo",
|
||||
"pathMap_hidePath": "Esconder caminho",
|
||||
"pathMap_showPath": "Mostrar o caminho",
|
||||
"pathMap_collapsePanel": "Recolher painel",
|
||||
"pathMap_expandPanel": "Expandir painel",
|
||||
"pathMap_noLocation": "Sem localização",
|
||||
"pathMap_followPacket": "Fixar vista no pacote",
|
||||
"pathMap_unfollowPacket": "Liberar vista do pacote",
|
||||
"pathMap_gpsCount": "{confirmed}/{total} GPS"
|
||||
}
|
||||
|
||||
+95
-1
@@ -1749,5 +1749,99 @@
|
||||
"chrome_bluetoothRequiresChromium": "Для работы Web Bluetooth требуется браузер на основе Chromium.",
|
||||
"channels_communityShortId": "Идентификатор: {id}...",
|
||||
"pathTrace_legendGpsConfirmed": "GPS подтверждено",
|
||||
"pathTrace_legendInferred": "Выведенная позиция"
|
||||
"pathTrace_legendInferred": "Выведенная позиция",
|
||||
"@pathMap_hopOf": {
|
||||
"placeholders": {
|
||||
"current": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_observedPaths": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_alternate": {
|
||||
"placeholders": {
|
||||
"index": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_hopCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_gpsCount": {
|
||||
"placeholders": {
|
||||
"confirmed": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_sharedNodeCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_partialAnimation": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"map_searchHint": "Поиск по имени или ID узла",
|
||||
"map_online": "Онлайн",
|
||||
"scanner_bluetoothWebUnsupported": "Bluetooth недоступен в браузере. Подключитесь через USB.",
|
||||
"map_activity": "Активность",
|
||||
"map_recent": "Недавно",
|
||||
"map_stale": "Устаревший",
|
||||
"map_visible": "Видимый",
|
||||
"map_hidden": "Скрытый",
|
||||
"map_centerOnNode": "Центрировать на узле",
|
||||
"map_details": "Детали",
|
||||
"map_noGps": "Без GPS",
|
||||
"map_noResults": "Не найдено соответствующих узлов",
|
||||
"pathMap_viewSingle": "Одиночный",
|
||||
"pathMap_viewCombined": "Объединённые",
|
||||
"pathMap_play": "Воспроизвести",
|
||||
"pathMap_pause": "Пауза",
|
||||
"pathMap_replay": "Повтор",
|
||||
"pathMap_stepBack": "Предыдущий хоп",
|
||||
"pathMap_stepForward": "Следующий хоп",
|
||||
"pathMap_animationOn": "Показать анимацию пакета",
|
||||
"pathMap_animationOff": "Скрыть анимацию пакета",
|
||||
"pathMap_hopOf": "Хоп {current} из {total}",
|
||||
"pathMap_observedPaths": "Наблюдаемые маршруты: {count}",
|
||||
"pathMap_primary": "Основной",
|
||||
"pathMap_alternate": "Альт {index}",
|
||||
"pathMap_hopCount": "{count, plural, one{{count} хоп} few{{count} хопа} many{{count} хопов} other{{count} хопов}}",
|
||||
"pathMap_legendShared": "Общий сегмент",
|
||||
"pathMap_legendEstimated": "Расчётный сегмент",
|
||||
"pathMap_sharedNodeCount": "Используется в {count} маршрутах",
|
||||
"pathMap_partialAnimation": "{count, plural, one{{count} хоп не имеет координат — показанный путь неполный} few{{count} хопа не имеют координат — показанный путь неполный} many{{count} хопов не имеют координат — показанный путь неполный} other{{count} хопов не имеют координат — показанный путь неполный}}",
|
||||
"pathMap_showAllPaths": "Показать всё",
|
||||
"pathMap_hidePath": "Скрыть путь",
|
||||
"pathMap_collapsePanel": "Скрыть панель",
|
||||
"pathMap_showPath": "Показать маршрут",
|
||||
"pathMap_expandPanel": "Расширить панель",
|
||||
"pathMap_noLocation": "Нет координат",
|
||||
"pathMap_followPacket": "Следить за пакетом",
|
||||
"pathMap_unfollowPacket": "Не следить за пакетом",
|
||||
"pathMap_gpsCount": "{confirmed}/{total} GPS"
|
||||
}
|
||||
|
||||
+95
-1
@@ -2446,5 +2446,99 @@
|
||||
"chrome_bluetoothRequiresChromium": "Web Bluetooth vyžaduje prehliadač Chromium.",
|
||||
"channels_communityShortId": "ID: {id}...",
|
||||
"pathTrace_legendGpsConfirmed": "GPS potvrdilo",
|
||||
"pathTrace_legendInferred": "Odvodená poloha"
|
||||
"pathTrace_legendInferred": "Odvodená poloha",
|
||||
"@pathMap_hopOf": {
|
||||
"placeholders": {
|
||||
"current": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_observedPaths": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_alternate": {
|
||||
"placeholders": {
|
||||
"index": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_hopCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_gpsCount": {
|
||||
"placeholders": {
|
||||
"confirmed": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_sharedNodeCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_partialAnimation": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"map_online": "Online",
|
||||
"scanner_bluetoothWebUnsupported": "Funkcia Bluetooth nie je dostupná v prehliadači. Prepojte sa pomocou USB.",
|
||||
"map_searchHint": "Vyhľadajte podľa názvu alebo ID uzla",
|
||||
"map_activity": "Aktivita",
|
||||
"map_recent": "Nedávne",
|
||||
"map_stale": "Neaktuálne",
|
||||
"map_hidden": "Skrytý",
|
||||
"map_visible": "Viditeľný",
|
||||
"map_centerOnNode": "Nacentrovať na uzol",
|
||||
"map_details": "Podrobnosti",
|
||||
"map_noGps": "Bez GPS",
|
||||
"map_noResults": "Nenašli sa žiadne zodpovedajúce uzly.",
|
||||
"pathMap_viewSingle": "Jednotlivý",
|
||||
"pathMap_viewCombined": "Spojené",
|
||||
"pathMap_play": "Prehrať",
|
||||
"pathMap_pause": "Pozastaviť",
|
||||
"pathMap_replay": "Prehrať znova",
|
||||
"pathMap_stepBack": "Predchádzajúci skok",
|
||||
"pathMap_stepForward": "Nasledujúci skok",
|
||||
"pathMap_animationOn": "Zobraziť animáciu paketu",
|
||||
"pathMap_animationOff": "Skryť animáciu paketu",
|
||||
"pathMap_hopOf": "Skok {current} z {total}",
|
||||
"pathMap_observedPaths": "Pozorované cesty: {count}",
|
||||
"pathMap_primary": "Primárna",
|
||||
"pathMap_alternate": "Alternatívny {index}",
|
||||
"pathMap_hopCount": "{count, plural, =1{1 skok} few{{count} skoky} other{{count} skokov}}",
|
||||
"pathMap_legendShared": "Spoločný segment",
|
||||
"pathMap_legendEstimated": "Odhadovaný segment",
|
||||
"pathMap_sharedNodeCount": "Používané {count} cestami",
|
||||
"pathMap_partialAnimation": "{count, plural, =1{1 skok nemá polohu — zobrazená trasa je neúplná} few{{count} skoky nemajú polohu — zobrazená trasa je neúplná} other{{count} skokov nemá polohu — zobrazená trasa je neúplná}}",
|
||||
"pathMap_showAllPaths": "Zobraziť všetky",
|
||||
"pathMap_hidePath": "Skryť cestu",
|
||||
"pathMap_showPath": "Zobraziť trasu",
|
||||
"pathMap_collapsePanel": "Zatvoriť panel",
|
||||
"pathMap_expandPanel": "Rozbaliť panel",
|
||||
"pathMap_noLocation": "Bez polohy",
|
||||
"pathMap_followPacket": "Uzamknúť pohľad na paket",
|
||||
"pathMap_unfollowPacket": "Odomknúť pohľad od paketu",
|
||||
"pathMap_gpsCount": "{confirmed}/{total} GPS"
|
||||
}
|
||||
|
||||
+95
-1
@@ -2446,5 +2446,99 @@
|
||||
"chrome_bluetoothRequiresChromium": "Web Bluetooth zahteva brskalnik Chromium.",
|
||||
"channels_communityShortId": "ID: {id}...",
|
||||
"pathTrace_legendGpsConfirmed": "GPS potrdilo",
|
||||
"pathTrace_legendInferred": "Izpeljana lokacija"
|
||||
"pathTrace_legendInferred": "Izpeljana lokacija",
|
||||
"@pathMap_hopOf": {
|
||||
"placeholders": {
|
||||
"current": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_observedPaths": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_alternate": {
|
||||
"placeholders": {
|
||||
"index": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_hopCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_gpsCount": {
|
||||
"placeholders": {
|
||||
"confirmed": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_sharedNodeCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_partialAnimation": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scanner_bluetoothWebUnsupported": "Funkcija Bluetooth v brskalniku ni na voljo. Povežite se preko USB-ja namesto tega.",
|
||||
"map_searchHint": "Iščite ime ali ID vozlišča",
|
||||
"map_online": "V omrežju",
|
||||
"map_activity": "Dejavnost",
|
||||
"map_recent": "Nedavni",
|
||||
"map_stale": "Zastarelo",
|
||||
"map_visible": "Vidno",
|
||||
"map_hidden": "Skrit",
|
||||
"map_centerOnNode": "Centriraj na vozlišče",
|
||||
"map_details": "Podrobnosti",
|
||||
"map_noGps": "Brez GPS",
|
||||
"map_noResults": "Ni ujemajočih se vozlišč",
|
||||
"pathMap_viewSingle": "Posamično",
|
||||
"pathMap_viewCombined": "Skupno",
|
||||
"pathMap_play": "Predvajaj",
|
||||
"pathMap_pause": "Premor",
|
||||
"pathMap_replay": "Ponovitev",
|
||||
"pathMap_stepBack": "Prejšnji skok",
|
||||
"pathMap_stepForward": "Naslednji skok",
|
||||
"pathMap_animationOn": "Prikaži animacijo paketa",
|
||||
"pathMap_animationOff": "Skrij animacijo paketa",
|
||||
"pathMap_hopOf": "Skok {current} od {total}",
|
||||
"pathMap_observedPaths": "Opazovane poti: {count}",
|
||||
"pathMap_primary": "Primarna",
|
||||
"pathMap_alternate": "Alternativa {index}",
|
||||
"pathMap_legendShared": "Deljen segment",
|
||||
"pathMap_legendEstimated": "Ocenjen segment",
|
||||
"pathMap_sharedNodeCount": "Uporablja {count} poti",
|
||||
"pathMap_partialAnimation": "{count, plural, =1{1 skok nima lokacije — prikazana pot je delna} =2{2 skoka nimata lokacije — prikazana pot je delna} few{{count} skoki nimajo lokacije — prikazana pot je delna} other{{count} skokov nima lokacije — prikazana pot je delna}}",
|
||||
"pathMap_hopCount": "{count, plural, =1{1 skok} =2{2 skoka} few{{count} skoki} other{{count} skokov}}",
|
||||
"pathMap_showAllPaths": "Pokaži vse",
|
||||
"pathMap_hidePath": "Skrij pot",
|
||||
"pathMap_showPath": "Pokaži pot",
|
||||
"pathMap_collapsePanel": "Strni ploščo",
|
||||
"pathMap_expandPanel": "Razširi ploščo",
|
||||
"pathMap_noLocation": "Brez lokacije",
|
||||
"pathMap_followPacket": "Zakleni pogled na paket",
|
||||
"pathMap_unfollowPacket": "Odkleni pogled od paketa",
|
||||
"pathMap_gpsCount": "{confirmed}/{total} GPS"
|
||||
}
|
||||
|
||||
+95
-1
@@ -2446,5 +2446,99 @@
|
||||
"chrome_bluetoothRequiresChromium": "Web Bluetooth kräver en Chromium-baserad webbläsare.",
|
||||
"channels_communityShortId": "ID: {id}...",
|
||||
"pathTrace_legendGpsConfirmed": "GPS-verifierat",
|
||||
"pathTrace_legendInferred": "Antagen position"
|
||||
"pathTrace_legendInferred": "Antagen position",
|
||||
"@pathMap_hopOf": {
|
||||
"placeholders": {
|
||||
"current": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_observedPaths": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_alternate": {
|
||||
"placeholders": {
|
||||
"index": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_hopCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_gpsCount": {
|
||||
"placeholders": {
|
||||
"confirmed": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_sharedNodeCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_partialAnimation": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"map_online": "Online",
|
||||
"scanner_bluetoothWebUnsupported": "Bluetooth är inte tillgängligt i webbläsaren. Anslut istället via USB.",
|
||||
"map_activity": "Aktivitet",
|
||||
"map_searchHint": "Sök efter nodens namn eller ID",
|
||||
"map_recent": "Nyligen",
|
||||
"map_stale": "Inaktuell",
|
||||
"map_visible": "Synlig",
|
||||
"map_hidden": "Dold",
|
||||
"map_centerOnNode": "Centrera på nod",
|
||||
"map_details": "Detaljer",
|
||||
"map_noGps": "Ingen GPS",
|
||||
"map_noResults": "Inga matchande noder",
|
||||
"pathMap_viewSingle": "Enkel",
|
||||
"pathMap_viewCombined": "Kombinerat",
|
||||
"pathMap_play": "Spela",
|
||||
"pathMap_pause": "Pausa",
|
||||
"pathMap_replay": "Återspela",
|
||||
"pathMap_stepBack": "Föregående hopp",
|
||||
"pathMap_stepForward": "Nästa hopp",
|
||||
"pathMap_animationOn": "Visa paketanimering",
|
||||
"pathMap_animationOff": "Dölj paketanimering",
|
||||
"pathMap_hopOf": "Hopp {current} av {total}",
|
||||
"pathMap_observedPaths": "Observerade vägar: {count}",
|
||||
"pathMap_primary": "Primär",
|
||||
"pathMap_alternate": "Alternativ {index}",
|
||||
"pathMap_hopCount": "{count, plural, =1{1 hopp} other{{count} hopp}}",
|
||||
"pathMap_legendShared": "Delat segment",
|
||||
"pathMap_legendEstimated": "Uppskattat segment",
|
||||
"pathMap_sharedNodeCount": "Används av {count} vägar",
|
||||
"pathMap_partialAnimation": "{count, plural, =1{1 hopp saknar position — den visade vägen är ofullständig} other{{count} hopp saknar position — den visade vägen är ofullständig}}",
|
||||
"pathMap_showAllPaths": "Visa allt",
|
||||
"pathMap_hidePath": "Dölj väg",
|
||||
"pathMap_showPath": "Visa väg",
|
||||
"pathMap_collapsePanel": "Fäll ihop panel",
|
||||
"pathMap_expandPanel": "Expandera panel",
|
||||
"pathMap_noLocation": "Ingen position",
|
||||
"pathMap_unfollowPacket": "Lås upp vy från paket",
|
||||
"pathMap_followPacket": "Lås vy till paket",
|
||||
"pathMap_gpsCount": "{confirmed}/{total} GPS"
|
||||
}
|
||||
|
||||
+95
-1
@@ -2426,5 +2426,99 @@
|
||||
"chrome_bluetoothRequiresChromium": "Web Bluetooth вимагає браузера на основі Chromium",
|
||||
"channels_communityShortId": "ID: {id}...",
|
||||
"pathTrace_legendGpsConfirmed": "GPS підтверджено",
|
||||
"pathTrace_legendInferred": "Висновок щодо положення"
|
||||
"pathTrace_legendInferred": "Висновок щодо положення",
|
||||
"@pathMap_hopOf": {
|
||||
"placeholders": {
|
||||
"current": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_observedPaths": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_alternate": {
|
||||
"placeholders": {
|
||||
"index": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_hopCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_gpsCount": {
|
||||
"placeholders": {
|
||||
"confirmed": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_sharedNodeCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_partialAnimation": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scanner_bluetoothWebUnsupported": "Bluetooth недоступний у браузері. Підключіться через USB.",
|
||||
"map_searchHint": "Назва або ID вузла",
|
||||
"map_activity": "Активність",
|
||||
"map_online": "Онлайн",
|
||||
"map_recent": "Нещодавні",
|
||||
"map_stale": "Застаріло",
|
||||
"map_visible": "Видимий",
|
||||
"map_hidden": "Прихований",
|
||||
"map_centerOnNode": "Центрувати на вузлі",
|
||||
"map_details": "Деталі",
|
||||
"map_noGps": "Без GPS",
|
||||
"map_noResults": "Не знайдено відповідних вузлів",
|
||||
"pathMap_viewSingle": "Один",
|
||||
"pathMap_viewCombined": "Об'єднаний",
|
||||
"pathMap_play": "Відтворити",
|
||||
"pathMap_pause": "Призупинити",
|
||||
"pathMap_replay": "Повтор",
|
||||
"pathMap_stepForward": "Наступний перехід",
|
||||
"pathMap_stepBack": "Попередній перехід",
|
||||
"pathMap_animationOn": "Відобразити анімацію пакета",
|
||||
"pathMap_animationOff": "Приховати анімацію пакета",
|
||||
"pathMap_hopOf": "Перехід {current} з {total}",
|
||||
"pathMap_observedPaths": "Зафіксовані маршрути: {count}",
|
||||
"pathMap_primary": "Основний",
|
||||
"pathMap_alternate": "Альт. {index}",
|
||||
"pathMap_hopCount": "{count, plural, =1{1 перехід} few{{count} переходи} many{{count} переходів} other{{count} переходів}}",
|
||||
"pathMap_legendShared": "Об'єднаний сегмент",
|
||||
"pathMap_legendEstimated": "Орієнтовний сегмент",
|
||||
"pathMap_sharedNodeCount": "Використовується {count} шляхами",
|
||||
"pathMap_partialAnimation": "{count, plural, =1{1 перехід не має геопозиції — показаний шлях є частковим} few{{count} переходи не мають геопозиції — показаний шлях є частковим} many{{count} переходів не мають геопозиції — показаний шлях є частковим} other{{count} переходів не мають геопозиції — показаний шлях є частковим}}",
|
||||
"pathMap_showAllPaths": "Показати все",
|
||||
"pathMap_hidePath": "Приховати шлях",
|
||||
"pathMap_showPath": "Показати шлях",
|
||||
"pathMap_collapsePanel": "Згорнути панель",
|
||||
"pathMap_expandPanel": "Розгорнути панель",
|
||||
"pathMap_noLocation": "Без геопозиції",
|
||||
"pathMap_followPacket": "Прив'язати вигляд до пакету",
|
||||
"pathMap_unfollowPacket": "Відв'язати вигляд від пакету",
|
||||
"pathMap_gpsCount": "{confirmed}/{total} GPS"
|
||||
}
|
||||
|
||||
+95
-1
@@ -2451,5 +2451,99 @@
|
||||
"chrome_bluetoothRequiresChromium": "Web Bluetooth 需要 Chromium 浏览器",
|
||||
"channels_communityShortId": "ID:{id}...",
|
||||
"pathTrace_legendGpsConfirmed": "通过GPS确认",
|
||||
"pathTrace_legendInferred": "推测的位置"
|
||||
"pathTrace_legendInferred": "推测的位置",
|
||||
"@pathMap_hopOf": {
|
||||
"placeholders": {
|
||||
"current": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_observedPaths": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_alternate": {
|
||||
"placeholders": {
|
||||
"index": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_hopCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_gpsCount": {
|
||||
"placeholders": {
|
||||
"confirmed": {
|
||||
"type": "int"
|
||||
},
|
||||
"total": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_sharedNodeCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@pathMap_partialAnimation": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"map_online": "在线",
|
||||
"scanner_bluetoothWebUnsupported": "浏览器不支持蓝牙,请改用 USB 连接。",
|
||||
"map_activity": "活动",
|
||||
"map_searchHint": "搜索节点名称或ID",
|
||||
"map_recent": "最近",
|
||||
"map_visible": "可见",
|
||||
"map_stale": "过时",
|
||||
"map_hidden": "已隐藏",
|
||||
"map_centerOnNode": "以节点为中心",
|
||||
"map_details": "详细信息",
|
||||
"map_noGps": "无 GPS",
|
||||
"map_noResults": "未找到匹配的节点",
|
||||
"pathMap_viewSingle": "单条",
|
||||
"pathMap_viewCombined": "综合",
|
||||
"pathMap_play": "播放",
|
||||
"pathMap_pause": "暂停",
|
||||
"pathMap_replay": "重播",
|
||||
"pathMap_stepBack": "上一跳",
|
||||
"pathMap_stepForward": "下一跳",
|
||||
"pathMap_animationOn": "显示数据包动画",
|
||||
"pathMap_animationOff": "隐藏数据包动画",
|
||||
"pathMap_hopOf": "第 {current} 跳,共 {total} 跳",
|
||||
"pathMap_observedPaths": "观测到的路径:{count}",
|
||||
"pathMap_primary": "主路径",
|
||||
"pathMap_alternate": "备用 {index}",
|
||||
"pathMap_hopCount": "{count, plural, =1{1 跳} other{{count} 跳}}",
|
||||
"pathMap_legendShared": "共享路段",
|
||||
"pathMap_legendEstimated": "估算路段",
|
||||
"pathMap_sharedNodeCount": "已被 {count} 条路径使用",
|
||||
"pathMap_showAllPaths": "显示全部",
|
||||
"pathMap_hidePath": "隐藏路径",
|
||||
"pathMap_showPath": "显示路径",
|
||||
"pathMap_collapsePanel": "收起面板",
|
||||
"pathMap_expandPanel": "展开面板",
|
||||
"pathMap_noLocation": "无位置",
|
||||
"pathMap_followPacket": "锁定视图跟随数据包",
|
||||
"pathMap_unfollowPacket": "解锁视图跟随",
|
||||
"pathMap_gpsCount": "{confirmed}/{total} GPS",
|
||||
"pathMap_partialAnimation": "{count, plural, =1{1 跳无位置信息 — 显示的路径不完整} other{{count} 跳无位置信息 — 显示的路径不完整}}"
|
||||
}
|
||||
|
||||
@@ -1466,114 +1466,136 @@ class _ChannelMessagePathMapScreenState
|
||||
border: Border.all(color: MeshPalette.line2),
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(12, 8, 4, 0),
|
||||
child: Row(
|
||||
child: DefaultTextStyle(
|
||||
style: const TextStyle(color: MeshPalette.ink),
|
||||
child: IconTheme(
|
||||
data: const IconThemeData(color: MeshPalette.ink),
|
||||
child: TextButtonTheme(
|
||||
data: TextButtonThemeData(
|
||||
style: TextButton.styleFrom(foregroundColor: MeshPalette.ink),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(12, 8, 4, 0),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
l10n.channelPath_repeaterHops,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
l10n.channelPath_repeaterHops,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
formatDistance(
|
||||
selectedDisplay?.distanceMeters ??
|
||||
_pathDistance,
|
||||
isImperial: isImperial,
|
||||
),
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 12,
|
||||
color: MeshPalette.ink2,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
formatDistance(
|
||||
selectedDisplay?.distanceMeters ??
|
||||
_pathDistance,
|
||||
isImperial: isImperial,
|
||||
const SizedBox(height: 4),
|
||||
PathMiniLegend(
|
||||
combined: combined,
|
||||
showInferred: false,
|
||||
),
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 12,
|
||||
color: MeshPalette.ink2,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
PathMiniLegend(
|
||||
combined: combined,
|
||||
showInferred: false,
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
icon: Icon(
|
||||
_panelCollapsed
|
||||
? Icons.expand_less
|
||||
: Icons.expand_more,
|
||||
size: 20,
|
||||
),
|
||||
tooltip: _panelCollapsed
|
||||
? l10n.pathMap_expandPanel
|
||||
: l10n.pathMap_collapsePanel,
|
||||
onPressed: () => setState(
|
||||
() => _panelCollapsed = !_panelCollapsed,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
icon: Icon(
|
||||
_panelCollapsed ? Icons.expand_less : Icons.expand_more,
|
||||
size: 20,
|
||||
),
|
||||
tooltip: _panelCollapsed
|
||||
? l10n.pathMap_expandPanel
|
||||
: l10n.pathMap_collapsePanel,
|
||||
onPressed: () =>
|
||||
setState(() => _panelCollapsed = !_panelCollapsed),
|
||||
PathAnimationControls(
|
||||
playback: _playback,
|
||||
selected: selectedDisplay,
|
||||
animationEnabled: _animationEnabled,
|
||||
onToggleAnimation: () => setState(() {
|
||||
_animationEnabled = !_animationEnabled;
|
||||
if (!_animationEnabled) _playback.stop();
|
||||
}),
|
||||
followEnabled: _followPacket,
|
||||
onToggleFollow: _toggleFollowPacket,
|
||||
),
|
||||
if (!_panelCollapsed) ...[
|
||||
if (selectedDisplay != null &&
|
||||
selectedDisplay.unresolvedHops > 0)
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(12, 0, 12, 4),
|
||||
child: Text(
|
||||
l10n.pathMap_partialAnimation(
|
||||
selectedDisplay.unresolvedHops,
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 10.5,
|
||||
color: MeshPalette.warn,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (combined)
|
||||
PathSummaryList(
|
||||
paths: entries.map((e) => e.display).toList(),
|
||||
selectedId: selectedDisplay?.id ?? '',
|
||||
hiddenIds: _hiddenPathIds,
|
||||
isImperial: isImperial,
|
||||
onSelect: (display) {
|
||||
for (final entry in entries) {
|
||||
if (entry.display.id == display.id) {
|
||||
_selectEntry(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
onToggleVisibility: (display) =>
|
||||
_togglePathVisibility(
|
||||
display,
|
||||
entries,
|
||||
selectedDisplay,
|
||||
),
|
||||
onShowAll: () => setState(_hiddenPathIds.clear),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
Expanded(
|
||||
child: _buildHopListView(
|
||||
hops,
|
||||
selectedDisplay,
|
||||
hopUseCount,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
PathAnimationControls(
|
||||
playback: _playback,
|
||||
selected: selectedDisplay,
|
||||
animationEnabled: _animationEnabled,
|
||||
onToggleAnimation: () => setState(() {
|
||||
_animationEnabled = !_animationEnabled;
|
||||
if (!_animationEnabled) _playback.stop();
|
||||
}),
|
||||
followEnabled: _followPacket,
|
||||
onToggleFollow: _toggleFollowPacket,
|
||||
),
|
||||
if (!_panelCollapsed) ...[
|
||||
if (selectedDisplay != null &&
|
||||
selectedDisplay.unresolvedHops > 0)
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(12, 0, 12, 4),
|
||||
child: Text(
|
||||
l10n.pathMap_partialAnimation(
|
||||
selectedDisplay.unresolvedHops,
|
||||
),
|
||||
style: TextStyle(fontSize: 10.5, color: MeshPalette.warn),
|
||||
),
|
||||
),
|
||||
if (combined)
|
||||
PathSummaryList(
|
||||
paths: entries.map((e) => e.display).toList(),
|
||||
selectedId: selectedDisplay?.id ?? '',
|
||||
hiddenIds: _hiddenPathIds,
|
||||
isImperial: isImperial,
|
||||
onSelect: (display) {
|
||||
for (final entry in entries) {
|
||||
if (entry.display.id == display.id) {
|
||||
_selectEntry(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
onToggleVisibility: (display) => _togglePathVisibility(
|
||||
display,
|
||||
entries,
|
||||
selectedDisplay,
|
||||
),
|
||||
onShowAll: () => setState(_hiddenPathIds.clear),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
Expanded(
|
||||
child: _buildHopListView(hops, selectedDisplay, hopUseCount),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -605,8 +605,9 @@ class _RepeaterStatusScreenState extends State<RepeaterStatusScreen> {
|
||||
final batteryMv =
|
||||
connector.getRepeaterBatteryMillivolts(widget.repeater.publicKeyHex) ??
|
||||
_batteryMv;
|
||||
if (batteryMv == null)
|
||||
if (batteryMv == null) {
|
||||
return Theme.of(context).colorScheme.onSurfaceVariant;
|
||||
}
|
||||
final percent = estimateBatteryPercentFromMillivolts(
|
||||
batteryMv,
|
||||
_batteryChemistry(),
|
||||
|
||||
@@ -227,7 +227,13 @@ class MessageRetryService extends ChangeNotifier {
|
||||
void _onMessageResolved(String messageId, String contactKey) {
|
||||
if (_resolvedMessages.contains(messageId)) return;
|
||||
_resolvedMessages.add(messageId);
|
||||
_activeMessages.remove(messageId);
|
||||
// If cleanup already removed this message from the active set, it has
|
||||
// already pumped the queues; avoid double-pumping.
|
||||
if (!_activeMessages.remove(messageId)) return;
|
||||
_pumpQueues(contactKey);
|
||||
}
|
||||
|
||||
void _pumpQueues(String contactKey) {
|
||||
// Pump this contact's queue first, then any other contacts that are waiting.
|
||||
_sendNextForContact(contactKey);
|
||||
for (final key in _sendQueue.keys) {
|
||||
@@ -495,11 +501,17 @@ class MessageRetryService extends ChangeNotifier {
|
||||
(_, mapping) => mapping.messageId == messageId,
|
||||
);
|
||||
_expectedHashToMessageId.removeWhere((_, msgId) => msgId == messageId);
|
||||
final contactKey = _pendingContacts[messageId]?.publicKeyHex;
|
||||
_pendingMessages.remove(messageId);
|
||||
_pendingContacts.remove(messageId);
|
||||
_attemptPathHistory.remove(messageId);
|
||||
_timeoutTimers.remove(messageId);
|
||||
_resolvedMessages.remove(messageId);
|
||||
// Cancellation (and other cleanup paths) must release the active in-flight
|
||||
// slot and pump waiting queues so the global cap does not stall forever.
|
||||
if (_activeMessages.remove(messageId) && contactKey != null) {
|
||||
_pumpQueues(contactKey);
|
||||
}
|
||||
}
|
||||
|
||||
void _handleTimeout(String messageId) {
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 9.0.0+12
|
||||
version: 9.5.0+13
|
||||
|
||||
environment:
|
||||
sdk: ^3.9.2
|
||||
|
||||
+1
-715
@@ -1,715 +1 @@
|
||||
{
|
||||
"bg": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"de": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"es": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"fr": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"hu": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"it": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"ja": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"ko": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"nl": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"pl": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"pt": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"ru": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"sk": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"sl": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"sv": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"uk": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
],
|
||||
|
||||
"zh": [
|
||||
"scanner_bluetoothWebUnsupported",
|
||||
"map_searchHint",
|
||||
"map_activity",
|
||||
"map_online",
|
||||
"map_recent",
|
||||
"map_stale",
|
||||
"map_visible",
|
||||
"map_hidden",
|
||||
"map_centerOnNode",
|
||||
"map_details",
|
||||
"map_noGps",
|
||||
"map_noResults",
|
||||
"pathMap_viewSingle",
|
||||
"pathMap_viewCombined",
|
||||
"pathMap_play",
|
||||
"pathMap_pause",
|
||||
"pathMap_replay",
|
||||
"pathMap_stepBack",
|
||||
"pathMap_stepForward",
|
||||
"pathMap_animationOn",
|
||||
"pathMap_animationOff",
|
||||
"pathMap_hopOf",
|
||||
"pathMap_observedPaths",
|
||||
"pathMap_primary",
|
||||
"pathMap_alternate",
|
||||
"pathMap_hopCount",
|
||||
"pathMap_gpsCount",
|
||||
"pathMap_legendShared",
|
||||
"pathMap_legendEstimated",
|
||||
"pathMap_sharedNodeCount",
|
||||
"pathMap_partialAnimation",
|
||||
"pathMap_showAllPaths",
|
||||
"pathMap_hidePath",
|
||||
"pathMap_showPath",
|
||||
"pathMap_collapsePanel",
|
||||
"pathMap_expandPanel",
|
||||
"pathMap_noLocation",
|
||||
"pathMap_followPacket",
|
||||
"pathMap_unfollowPacket"
|
||||
]
|
||||
}
|
||||
{}
|
||||
Reference in New Issue
Block a user