49 Commits
v2.6.7 ... main

Author SHA1 Message Date
Wessel
0108494bd8 Channel bandwidth is kHz, not MHz (#983) 2025-12-08 23:03:41 -05:00
rj-xy
3ecea59da8 Update README with Buf CLI installation instructions (#981)
Added instructions for installing the Buf CLI.
2025-12-04 22:59:37 -05:00
Dan Ditomaso
0b2fdb6439 Revert "feat(ui): add SNR, RSSI, hops info for messages (#963)" (#974)
This reverts commit 020e9d6b63.
2025-12-02 10:10:19 -05:00
Dan Ditomaso
94220e729b feat(map): add heatmap layer (#969)
* feat: add heatmap layer

* Update packages/web/src/components/PageComponents/Map/Layers/HeatmapLayer.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/web/src/components/PageComponents/Map/Tools/MapLayerTool.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/web/src/pages/Map/index.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/web/src/pages/Map/index.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/web/src/components/PageComponents/Map/Layers/HeatmapLayer.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* lint/formatting fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-28 19:58:05 -05:00
Alexey Stepanov
020e9d6b63 feat(ui): add SNR, RSSI, hops info for messages (#963)
* feat(ui): add SNR, RSSI, hops, MQTT info for messages

* review fixes

* zeros for new fields

* Move label under the message

---------

Co-authored-by: Pmmlabs <meshtastic@pmmlabs.ru>
2025-11-27 15:42:11 -05:00
Kamil Dzieniszewski
6a7be99a6a feat: add fixed position coordinate picker (#909)
* chore: remove unused logo SVG files

* feat: add interactive fixed position picker with map interface

- Created new FixedPositionPicker component with clickable map for setting device coordinates
- Added form field type for fixed position picker that appears when fixedPosition toggle is enabled
- Implemented position request functionality to retrieve current device location

* feat: display altitude unit based on user's display settings

- Added dynamic altitude unit (Meters/Feet) that respects the user's imperial/metric display preference
- Updated altitude field description to show the appropriate unit instead of hardcoded "Meters"

* refactor: replace any type with MapLayerMouseEvent in map click handler

* refactor: improve accessibility and code quality in FixedPositionPicker

- Replace hardcoded IDs with useId() hook for proper accessibility
- Use Number.isNaN() instead of isNaN() for more reliable type checking
- Add radix parameter to parseInt() and remove unnecessary fragment wrapper

* refactor: simplify fixed position picker integration

- Removed dedicated FixedPositionPicker form field type in favor of toggle's additionalContent prop
- Moved FixedPositionPicker to render conditionally within toggle field instead of as separate dynamic field
- Streamlined form field types by eliminating FixedPositionPickerFieldProps

* style: format code with consistent line breaks and import ordering

* refactor: simplify fixed position picker container styling

* feat: disable fixed position toggle when GPS is enabled

* refactor: use ComponentRef instead of ElementRef in Switch component

* refactor: replace interactive map picker with inline coordinate fields for fixed position

- Removed FixedPositionPicker component with map interface
- Added latitude, longitude, and altitude fields directly to position form
- Moved coordinate validation into PositionValidationSchema with proper min/max bounds
- Updated translation strings to include coordinate ranges and improved altitude description
- Coordinates now sent via setFixedPosition admin message on form submit when fixedPosition is enabled

* refactor: simplify toggle field by removing additionalContent prop and unused field spreading

- Removed additionalContent prop and its JSDoc documentation from ToggleFieldProps
- Removed rendering of additionalContent below toggle switch
- Cleaned up Controller render function by removing unused rest spread operator
- Renamed field destructuring to controllerField for clarity

* refactor: improve fixed position handling and add position broadcast request

- Restructure onSubmit to save config before sending admin message
- Add position broadcast request after setting fixed position to immediately update display
- Add comprehensive debug logging throughout submission flow
- Extract coordinate exclusion logic earlier in submission process for clarity
- Add 1 second delay before requesting position broadcast to allow fixed position processing

* feat: add max length constraint to latitude and longitude fields

- Set fieldLength.max to 10 for both latitude and longitude inputs
- Prevents excessive decimal precision while maintaining 7 decimal places (±1.1cm accuracy)
2025-11-27 15:40:57 -05:00
Alexey Stepanov
5debdb4689 fix(ui): add "never" i18n string, fix "Favorite" tooltip (#965)
* fix(ui): add "never" i18n string, fix "Favorite" tooltip

* format

* format

---------

Co-authored-by: Pmmlabs <meshtastic@pmmlabs.ru>
2025-11-27 15:40:41 -05:00
dependabot[bot]
057043864f chore(deps-dev): bump happy-dom from 20.0.0 to 20.0.2 (#968)
Bumps [happy-dom](https://github.com/capricorn86/happy-dom) from 20.0.0 to 20.0.2.
- [Release notes](https://github.com/capricorn86/happy-dom/releases)
- [Commits](https://github.com/capricorn86/happy-dom/compare/v20.0.0...v20.0.2)

---
updated-dependencies:
- dependency-name: happy-dom
  dependency-version: 20.0.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-27 14:59:28 -05:00
Kamil Dzieniszewski
8918603f96 fix(ui): correct typo in languagePicker key and adjust description width (#961)
Fixed typo 'languagePickeer' to 'languagePicker' in DeviceInfoPanel and corrected responsive width class from 'md:w-6' to 'md:w-5/6' in Connections page description.
2025-11-24 21:02:28 -05:00
github-actions[bot]
68cea2e858 chore(i18n): New Crowdin Translations by GitHub Action (#962)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-11-22 20:54:06 -05:00
Dan Ditomaso
06cc266acd fix(ui): removed internet hosted fonts from app (#955)
* fix(ui): removed internet hosted fonts from app

* Update packages/web/src/components/generic/Mono.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/web/src/components/UI/Typography/Code.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* removed unsupported font extention

* formatter fix

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-19 17:52:26 -05:00
zeo
295755ec4c fix: interpolate longName and shortName in PKI backup download (#959)
This caused {{shortName}} and {{longName}} to appear unformatted in the
exported key files:

``` === MESHTASTIC KEYS FOR {{longName}} ({{shortName}}) ===

Private Key: <censored>

Public Key: <censored>

=== END OF KEYS === ```

The fix simply replicates the behaviour used elsewhere in
PKIIBackupDialog.
2025-11-18 18:04:40 -05:00
github-actions[bot]
b99057df69 chore(i18n): New Crowdin Translations by GitHub Action (#958)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-11-17 21:28:28 -05:00
Dan Ditomaso
390b46f026 fix(ui): add language switcher to connections page (#954)
* fix(ui): add language switcher to connections page

* desciption length fix

* Update packages/web/src/pages/Connections/index.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* add new language picker key

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-13 13:06:20 -05:00
jsacrist
94d51912e6 feat: add devcontainer (#953) 2025-11-13 12:37:11 -05:00
Dan Ditomaso
ac28fbc53d fix: removed duplicate images (#951) 2025-11-12 11:20:53 -05:00
Dan Ditomaso
648a9c3640 refactor: device connection logic, added nonce to get config only (#946)
* refactor: device connection logic, added nonce to get config only on connect.

* Update packages/web/src/core/services/MeshService.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/web/src/pages/Connections/useConnections.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* code review fixes

* fixes from code review

* ui fixes

* refactored meshService, moved code into deviceStore. Fixed some connnection issues

* formatting fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-11 20:56:22 -05:00
Dan Ditomaso
7f21b3b531 Add 'packages/web' to excluded directories (#947) 2025-11-09 20:45:24 -05:00
github-actions[bot]
d1597ce00f chore(i18n): New Crowdin Translations by GitHub Action (#941)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-11-09 20:38:31 -05:00
Jeremy Gallant
0c8fcec23d fix(i18n): Correct 'disconnected' typo in connections.json (#943)
* fix(i18n): Correct 'disconnected' typo in connections.json

* fix(i18n): Correct typo 'checkConnetion' to 'checkConnection'

* Fix(i18n): Correct typo in connection test description

---------

Co-authored-by: philon- <philon-@users.noreply.github.com>
2025-11-09 20:38:18 -05:00
Dan Ditomaso
2e03b4a413 fix(ui): fix add connection dialog typo (#938) 2025-11-06 12:41:04 -05:00
Dan Ditomaso
a00cb2098b feat(ui): match avatar color other platforms (#933)
* feat(ui): match avatar color other platforms

* Update packages/web/src/components/UI/Avatar.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/web/src/components/DeviceInfoPanel.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-05 21:53:55 -05:00
Dan Ditomaso
6aeaed988e feat(docker): add arm v7 support (#934) 2025-11-05 21:53:41 -05:00
Dan Ditomaso
7c9013a217 fix(connection): support port on HTTP connection (#935) 2025-11-05 21:53:26 -05:00
Dan Ditomaso
ab0308701c fix(connections): ensure connections reflect actual status. (#930) 2025-11-04 16:09:30 -05:00
github-actions[bot]
e13d543e73 chore(i18n): New Crowdin Translations by GitHub Action (#924)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-11-04 15:23:20 -05:00
Dan Ditomaso
d8ad0efcdf fix(config): update change registry channel value (#929)
* fix(config): update change registry channel value

* format/linting
2025-11-04 15:12:35 -05:00
Dan Ditomaso
2e60af1e29 fix(ci): add ui library to excluded list (#928) 2025-11-03 21:59:40 -05:00
Dan Ditomaso
1af1295b8f feat(connections): Add connections page (replaces new device dialog) (#919)
* feat(conn): add connection screen and logic

* fixes from code review

* force https

* code review fixes

* add http for self testing

* enable deviceStore persistance

* added translations

* disabled feature flag

* i18n updates

* chore: add new folders to biome config (#910)

* chore(i18n): New Crowdin Translations by GitHub Action (#908)

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>

* fix: use correct deprecated GPS coordinate format enum (#917)

The Config_DisplayConfig_GpsCoordinateFormat export doesn't exist in the protobufs package. The correct export is Config_DisplayConfig_DeprecatedGpsCoordinateFormat, which matches what's used in the validation schema.

Added TODO comment explaining that this field is deprecated since protobufs 2.7.4 and should be migrated to DeviceUIConfig.gps_format when DeviceUI settings are implemented.

* style: fix line wrapping for GPS coordinate format enum (#918)

- Split long enum reference across multiple lines to improve code readability
- Maintains consistent code formatting standards without changing functionality

* fix(core): ensure core package works in browser (#923)

* fix(core): ensure core package works in browser

* style(core): revert new line removal

* fix: add @serialport/bindings-cpp to onlyBuiltDependencies (#914)

* feat(ui): Add UI library (#900)

* feat: scaffold UI library

* Update packages/ui/src/components/theme-provider.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* add lock file

* lint/formatting fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* formatting/linting fixes

* fixed some paring logic

* fixed connection issue with serial

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Kamil Dzieniszewski <kamil.dzieniszewski@gmail.com>
Co-authored-by: Azarattum <43073346+Azarattum@users.noreply.github.com>
Co-authored-by: Ben Allfree <ben@benallfree.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-03 20:24:24 -05:00
Dan Ditomaso
a1a646983e fix: added skelton loader for message items (#927) 2025-11-03 19:08:53 -05:00
Dan Ditomaso
4386854e9d feat(ui): Add UI library (#900)
* feat: scaffold UI library

* Update packages/ui/src/components/theme-provider.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* add lock file

* lint/formatting fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-31 14:37:34 -04:00
Ben Allfree
e821a65dd4 fix: add @serialport/bindings-cpp to onlyBuiltDependencies (#914) 2025-10-31 14:37:11 -04:00
Azarattum
3392c9db08 fix(core): ensure core package works in browser (#923)
* fix(core): ensure core package works in browser

* style(core): revert new line removal
2025-10-31 11:58:42 -04:00
Dan Ditomaso
e53edfb00f feat(state): enable deviceStore persistance (#922) 2025-10-31 08:26:21 -04:00
Kamil Dzieniszewski
1df63bb84b style: fix line wrapping for GPS coordinate format enum (#918)
- Split long enum reference across multiple lines to improve code readability
- Maintains consistent code formatting standards without changing functionality
2025-10-29 10:17:38 -04:00
Kamil Dzieniszewski
679f7986cc fix: use correct deprecated GPS coordinate format enum (#917)
The Config_DisplayConfig_GpsCoordinateFormat export doesn't exist in the protobufs package. The correct export is Config_DisplayConfig_DeprecatedGpsCoordinateFormat, which matches what's used in the validation schema.

Added TODO comment explaining that this field is deprecated since protobufs 2.7.4 and should be migrated to DeviceUIConfig.gps_format when DeviceUI settings are implemented.
2025-10-29 10:12:04 -04:00
github-actions[bot]
f375911c4a chore(i18n): New Crowdin Translations by GitHub Action (#908)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-10-28 11:19:36 -04:00
Dan Ditomaso
68ad535259 chore: add new folders to biome config (#910) 2025-10-28 01:54:06 -04:00
Dan Ditomaso
0cf677c8d5 Feat(config): Align settings menu to match android/ios (#906)
* feat: aligned settings menu to match android/ios

* updated sidebar text size.

* Update packages/web/public/i18n/locales/en/config.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/web/public/i18n/locales/en/config.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/web/src/components/PageComponents/Settings/User.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/web/src/components/PageComponents/ModuleConfig/Telemetry.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* linting/formatting fixes

* fixed formatting issue

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-24 13:31:22 -04:00
Wessel
ff02b1455d Fix description for historyReturnWindow (#907)
It's not number of records but the time window...
2025-10-24 13:31:07 -04:00
Jeremy Gallant
cdad811295 Persists device and app stores across sessions (#860)
* Persistence for device and app data

* esphemeral -> ephemeral

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* devices -> app

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Additional waypoint methods, update mock, update tests

---------

Co-authored-by: philon- <philon-@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-23 17:27:41 -04:00
Dan Ditomaso
fc1e327b74 Update inactive issue workflow schedule and settings (#905)
* Update inactive issue workflow schedule and settings

* Update .github/workflows/inactive-issue.yml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-23 15:52:36 -04:00
dependabot[bot]
af2fac1465 chore(deps): bump vite from 7.1.9 to 7.1.11 (#903)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.1.9 to 7.1.11.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.1.11/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.1.11
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-23 12:29:39 -04:00
Dan Ditomaso
15daa0270c feat(ci): add CI workflow to automatically close issue after 60 days (#897)
* feat(ci): add CI workflow to automatically close issue after 60 days

* run once pe github issue to run once per day
2025-10-22 19:39:10 -04:00
Dan Ditomaso
80c9306db3 feat(i18n): add fr localization support (#902)
* feat: add fr support

* fix(i18n): ensure langs are sorted before being displayed.
2025-10-21 19:42:56 -04:00
Dan Ditomaso
c3f073a380 Update readme with new widgets (#901)
* chore: add new widgets to readme

* add docs url

* Update README.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-21 14:31:28 -04:00
github-actions[bot]
fe35376450 chore(i18n): New Crowdin Translations by GitHub Action (#899)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-10-21 08:39:30 -04:00
Dan Ditomaso
64d1f0f7aa fix(ui): logic on waypoint layer component caused 0 to be shown in UI (#896)
* fix(ui): logic on waypoint layer component caused 0 to be shown in UI

* Update packages/web/src/components/PageComponents/Map/Popups/WaypointDetail.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-17 21:28:17 -04:00
Dan Ditomaso
a61bb2dfb6 fix(actions): improve main to stable release workflow (#895)
* fix(actions): improve main to stable release workflow

* Update .github/workflows/update-stable-from-master.yml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update .github/workflows/update-stable-from-master.yml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-17 10:06:17 -04:00
431 changed files with 47995 additions and 25881 deletions

View File

@@ -0,0 +1,13 @@
{
"name": "meshtastic-web",
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
"features": {
"ghcr.io/r3dpoint/devcontainer-features/tailwindcss-standalone-cli:1": {
"version": "latest"
},
"ghcr.io/devcontainers-extra/features/pnpm:2": {
"version": "latest"
}
}
}

View File

@@ -40,7 +40,7 @@ jobs:
set -euo pipefail
# List packages to exclude (full paths under repo root)
EXCLUDED_DIRS=("packages/protobufs" "packages/transport-deno")
EXCLUDED_DIRS=("packages/protobufs" "packages/transport-deno" "packages/ui" "pacakges/web")
is_excluded() {
local dir="$1"

24
.github/workflows/inactive-issue.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: Close inactive issues
on:
schedule:
- cron: "0 */4 * * *" # every 4 hours
workflow_dispatch: # allow manual runs
jobs:
close-issues:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-issue-stale: 60
days-before-issue-close: 14
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 60 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
days-before-pr-stale: -1
days-before-pr-close: -1
only-issue-labels: "Bug"
remove-stale-when-updated: true

View File

@@ -97,7 +97,7 @@ jobs:
${{ steps.meta.outputs.moving_tag }}
${{ steps.meta.outputs.immutable_tag }}
oci: true
platforms: linux/amd64,linux/arm64
platforms: linux/amd64,linux/arm64,linux/arm/v7
labels: |
org.opencontainers.image.source=${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}

View File

@@ -135,7 +135,7 @@ jobs:
with:
context: .
file: ./packages/web/infra/Containerfile
platforms: linux/amd64,linux/arm64
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.tag_name != '') }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -15,59 +15,81 @@ jobs:
update-stable-branch:
name: Update stable from latest release source
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # need full history for reset/push
fetch-depth: 0
fetch-tags: true # IMPORTANT: we need tags to resolve the release commit
- name: Configure Git author
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Determine source ref & SHA
- name: Determine source SHA (prefer tag)
id: meta
shell: bash
run: |
set -euo pipefail
SRC="${{ github.event.release.target_commitish }}"
if [ -z "$SRC" ] || ! git ls-remote --exit-code origin "refs/heads/$SRC" >/dev/null 2>&1; then
# Fallback to main if target_commitish is empty or not a branch
SRC="main"
TAG="${{ github.event.release.tag_name }}"
TARGET="${{ github.event.release.target_commitish || '' }}"
# Always ensure we have latest remote heads/tags
git fetch --tags --prune origin
SHA=""
SRC_DESC=""
# 1) Prefer the release tag commit
if [ -n "${TAG}" ] && git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then
SHA="$(git rev-list -n1 "${TAG}")"
SRC_DESC="tag:${TAG}"
fi
echo "Using source branch: $SRC"
git fetch origin "$SRC":"refs/remotes/origin/$SRC" --prune
SHA="$(git rev-parse "origin/$SRC")"
echo "sha=$SHA" >> "$GITHUB_OUTPUT"
echo "src=$SRC" >> "$GITHUB_OUTPUT"
# 2) Fall back to target_commitish if it points to a branch on origin
if [ -z "${SHA}" ] && [ -n "${TARGET}" ] && git ls-remote --exit-code --heads origin "${TARGET}" >/dev/null 2>&1; then
git fetch origin "${TARGET}:${TARGET}" --prune
SHA="$(git rev-parse "${TARGET}^{commit}")"
SRC_DESC="branch:${TARGET}"
fi
- name: Prepare local stable branch
# 3) Fall back to main if present
if [ -z "${SHA}" ] && git ls-remote --exit-code --heads origin "main" >/dev/null 2>&1; then
git fetch origin "main:main" --prune
SHA="$(git rev-parse "main^{commit}")"
SRC_DESC="branch:main"
fi
if [ -z "${SHA}" ]; then
echo "::error::Unable to resolve source commit from tag (${TAG}), target_commitish (${TARGET}), or main."
exit 1
fi
echo "Using source: ${SRC_DESC}"
echo "sha=${SHA}" >> "$GITHUB_OUTPUT"
echo "source=${SRC_DESC}" >> "$GITHUB_OUTPUT"
- name: Create/reset local stable to SHA
shell: bash
run: |
set -euo pipefail
# Ensure we have the remote stable ref if it exists
# Make sure we know if remote stable exists (non-fatal if not)
git fetch origin stable:refs/remotes/origin/stable || true
if git show-ref --verify --quiet refs/heads/stable; then
echo "Local stable exists."
elif git show-ref --verify --quiet refs/remotes/origin/stable; then
echo "Creating local stable tracking branch from remote."
git checkout -b stable --track origin/stable
else
echo "Creating new local stable branch at source SHA."
git checkout -b stable "${{ steps.meta.outputs.sha }}"
fi
- name: Reset stable to source SHA
run: |
git checkout stable
git reset --hard "${{ steps.meta.outputs.sha }}"
# Create or reset local stable in one command
git checkout -B stable "${{ steps.meta.outputs.sha }}"
git status --short --branch
- name: Push stable (force-with-lease)
run: |
# Safer than --force; refuses if remote moved unexpectedly
git push origin stable --force-with-lease
# Safer than --force; refuses if remote moved unexpectedly (protects against races)
REMOTE_STABLE_SHA="$(git rev-parse refs/remotes/origin/stable || echo '')"
if [ -z "$REMOTE_STABLE_SHA" ]; then
# If remote stable doesn't exist, just use --force-with-lease=stable (no SHA)
git push origin stable:stable --force-with-lease=stable
else
# Use the specific SHA for maximum safety
git push origin stable:stable --force-with-lease=stable:$REMOTE_STABLE_SHA
fi

7
.gitignore vendored
View File

@@ -9,5 +9,12 @@ __screenshots__*
npm/
.idea
**/LICENSE
.DS_Store
packages/protobufs/packages/ts/dist
.pnpm-store/
# Local dev certs
*.pem
*.crt
*.key

View File

@@ -12,6 +12,9 @@ This monorepo consolidates the official [Meshtastic](https://meshtastic.org) web
interface and its supporting JavaScript libraries. It aims to provide a unified
development experience for interacting with Meshtastic devices.
> [!NOTE]
> You can find the main Meshtastic documentation at https://meshtastic.org/docs/introduction/.
### Projects within this Monorepo (`packages/`)
All projects are located within the `packages/` directory:
@@ -33,7 +36,7 @@ All `Meshtastic JS` packages (core and transports) are published both to
---
## Stats
## Repository activity
| Project | Repobeats |
| :------------- | :-------------------------------------------------------------------------------------------------------------------- |
@@ -74,6 +77,9 @@ Follow the installation instructions on their home page.
```
This command installs all necessary dependencies for all packages within the
monorepo.
3. **Install the Buf CLI**
Required for building `packages/protobufs`
https://buf.build/docs/cli/installation/
### Running Projects
@@ -87,28 +93,18 @@ If you encounter any issues, please report them in our
[issues tracker](https://github.com/meshtastic/web/issues). Your feedback helps
improve the stability of future releases
### Contributing
## Star history
We welcome contributions! Heres how the deployment flow works for pull
requests:
<a href="https://star-history.com/#meshtastic/web&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=meshtastic/web&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=meshtastic/web&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=meshtastic/web&type=Date" width="100%" />
</picture>
</a>
- **Preview Deployments:**\
Every pull request automatically generates a preview deployment on Vercel.
This allows you and reviewers to easily preview changes before merging.
## Contributors
- **Staging Environment (`client-test`):**\
Once your PR is merged, your changes will be available on our staging site:
[client-test.meshtastic.org](https://client-test.meshtastic.org/).\
This environment supports rapid feature iteration and testing without
impacting the production site.
- **Production Releases:**\
At regular intervals, stable and fully tested releases are promoted to our
production site: [client.meshtastic.org](https://client.meshtastic.org/).\
This is the primary interface used by the public to connect with their
Meshtastic nodes.
Please review our
[Contribution Guidelines](https://github.com/meshtastic/web/blob/main/CONTRIBUTING.md)
before submitting a pull request. We appreciate your help in making the project
better!
<a href="https://github.com/meshtastic/web/graphs/contributors">
<img src="https://contrib.rocks/image?repo=meshtastic/web" width="100%"/>
</a>

View File

@@ -4,10 +4,13 @@
"**/*.ts",
"**/*.tsx",
"!npm_modules",
"!dist",
"!**/dist",
"!**/protobufs",
"!**/.*",
"!npm",
"**/*.json",
"!**/locales/*-*/*.json"
"!**/locales/*-*/*.json",
"!**/packages/ui/"
],
"ignoreUnknown": false
},
@@ -21,7 +24,7 @@
},
"linter": {
"enabled": true,
"includes": ["**", "!test/**"],
"includes": ["**", "!test/**", "!**/dist/**"],
"rules": {
"recommended": true,
"suspicious": {

View File

@@ -35,14 +35,15 @@
"tslog": "^4.9.3"
},
"devDependencies": {
"@types/node": "^24.3.1",
"@biomejs/biome": "2.2.4",
"@types/node": "^24.3.1",
"tsdown": "^0.15.0",
"typescript": "^5.9.2",
"vitest": "^3.2.4"
},
"pnpm": {
"onlyBuiltDependencies": [
"@serialport/bindings-cpp",
"@tailwindcss/oxide",
"core-js",
"esbuild",

View File

@@ -12,6 +12,7 @@
"license": "GPL-3.0-only",
"tsdown": {
"entry": "mod.ts",
"platform": "browser",
"dts": true,
"format": [
"esm"

View File

@@ -46,6 +46,7 @@ export enum DeviceStatusEnum {
DeviceConnected = 5,
DeviceConfiguring = 6,
DeviceConfigured = 7,
DeviceError = 8,
}
export type LogEventPacket = LogEvent & { date: Date };

View File

@@ -387,4 +387,12 @@ export class EventSystem {
*/
public readonly onQueueStatus: SimpleEventDispatcher<Protobuf.Mesh.QueueStatus> =
new SimpleEventDispatcher<Protobuf.Mesh.QueueStatus>();
/**
* Fires when a configCompleteId message is received from the device
*
* @event onConfigComplete
*/
public readonly onConfigComplete: SimpleEventDispatcher<number> =
new SimpleEventDispatcher<number>();
}

View File

@@ -135,21 +135,27 @@ export const decodePacket = (device: MeshDevice) =>
}
case "configCompleteId": {
if (decodedMessage.payloadVariant.value !== device.configId) {
device.log.error(
Types.Emitter[Types.Emitter.HandleFromRadio],
`❌ Invalid config id received from device, expected ${device.configId} but received ${decodedMessage.payloadVariant.value}`,
);
}
device.log.info(
Types.Emitter[Types.Emitter.HandleFromRadio],
`⚙️ Valid config id received from device: ${device.configId}`,
`⚙️ Received config complete id: ${decodedMessage.payloadVariant.value}`,
);
device.updateDeviceStatus(
Types.DeviceStatusEnum.DeviceConfigured,
// Emit the configCompleteId event for MeshService to handle two-stage flow
device.events.onConfigComplete.dispatch(
decodedMessage.payloadVariant.value,
);
// For backward compatibility: if configId matches, update device status
// MeshService will override this behavior for two-stage flow
if (decodedMessage.payloadVariant.value === device.configId) {
device.log.info(
Types.Emitter[Types.Emitter.HandleFromRadio],
`⚙️ Config id matches device.configId: ${device.configId}`,
);
device.updateDeviceStatus(
Types.DeviceStatusEnum.DeviceConfigured,
);
}
break;
}

View File

@@ -0,0 +1,22 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/base.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}

76
packages/ui/package.json Normal file
View File

@@ -0,0 +1,76 @@
{
"name": "@meshtastic/ui",
"version": "0.1.0",
"license": "GPL-3.0-only",
"repository": {
"type": "git",
"url": "git+https://github.com/meshtastic/web.git"
},
"type": "module",
"files": [
"dist",
"!dist/**/*.test.*"
],
"sideEffects": [
"**/*.css"
],
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./theme/default.css": "./dist/theme/default.css"
},
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"start": "npm run dev",
"dev": "vite dev",
"watch": "vite build --watch",
"build": "vite build && publint",
"typecheck": "tsc -p tsconfig.json --noEmit",
"preview": "vite preview",
"lint": "eslint . --max-warnings 0",
"lint:fix": "npm run lint -- --fix",
"format": "prettier --check .",
"format:fix": "prettier --write .",
"test": "vitest"
},
"peerDependencies": {
"@radix-ui/react-slot": ">=1.0.2",
"class-variance-authority": ">=0.7.0",
"react": ">=19",
"react-dom": ">=19",
"tailwind-merge": ">=2.5.0",
"tailwindcss": "^4.1.7"
},
"dependencies": {
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tooltip": "^1.2.8",
"@tanstack/react-router": "^1.132.47",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.545.0",
"tailwind-merge": "^2.6.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.7",
"@tailwindcss/vite": "^4.1.14",
"@types/react": "^18.3.5",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.4",
"publint": "^0.3.14",
"tailwindcss": "^4.1.14",
"tw-animate-css": "^1.4.0",
"typescript": "^5.6.3",
"vite": "^7.0.0",
"vite-plugin-dts": "^4.5.4",
"vite-plugin-static-copy": "^3.1.4",
"vitest": "^3.0.0"
}
}

7
packages/ui/src/app.css Normal file
View File

@@ -0,0 +1,7 @@
body.dark {
color-scheme: dark;
}
body:not(.dark) {
color-scheme: light;
}

View File

@@ -0,0 +1,77 @@
import { createContext, useContext, useEffect, useState } from "react";
type Theme = "dark" | "light" | "system";
type ThemeProviderProps = {
children: React.ReactNode;
defaultTheme?: Theme;
storageKey?: string;
};
type ThemeProviderState = {
theme: Theme;
setTheme: (theme: Theme) => void;
};
const initialState: ThemeProviderState = {
theme: "system",
setTheme: () => null,
};
const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
export function ThemeProvider({
children,
defaultTheme = "system",
storageKey = "vite-ui-theme",
...props
}: ThemeProviderProps) {
const [theme, setTheme] = useState<Theme>(
() => (localStorage.getItem(storageKey) as Theme) || defaultTheme,
);
useEffect(() => {
const root = window.document.documentElement;
root.classList.remove("light", "dark");
if (theme === "system") {
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
.matches
? "dark"
: "light";
root.classList.add(systemTheme);
return;
}
root.classList.add(theme);
}, [theme]);
const value = {
theme,
setTheme: (theme: Theme) => {
localStorage.setItem(storageKey, theme);
setTheme(theme);
},
};
return (
<ThemeProviderContext.Provider {...props} value={value}>
{children}
</ThemeProviderContext.Provider>
);
}
export const useTheme = () => {
const context = useContext(ThemeProviderContext);
// If the provider is missing, context will be initialState (setTheme is a no-op)
if (context.setTheme === initialState.setTheme) {
throw new Error(
"useTheme must be used within a ThemeProvider: provider is missing",
);
}
return context;
};

View File

@@ -0,0 +1,46 @@
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import type * as React from "react";
import { cn } from "@/lib/utils";
const badgeVariants = cva(
"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
{
variants: {
variant: {
default:
"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
secondary:
"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
destructive:
"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
outline:
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
},
},
defaultVariants: {
variant: "default",
},
},
);
function Badge({
className,
variant,
asChild = false,
...props
}: React.ComponentProps<"span"> &
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
const Comp = asChild ? Slot : "span";
return (
<Comp
data-slot="badge"
className={cn(badgeVariants({ variant }), className)}
{...props}
/>
);
}
export { Badge, badgeVariants };

View File

@@ -0,0 +1,60 @@
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import type * as React from "react";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
outline:
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost:
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2 has-[>svg]:px-3",
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
icon: "size-9",
"icon-sm": "size-8",
"icon-lg": "size-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);
function Button({
className,
variant,
size,
asChild = false,
...props
}: React.ComponentProps<"button"> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean;
}) {
const Comp = asChild ? Slot : "button";
return (
<Comp
data-slot="button"
className={cn(buttonVariants({ variant, size, className }))}
{...props}
/>
);
}
export { Button, buttonVariants };

View File

@@ -0,0 +1,31 @@
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
function Collapsible({
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
}
function CollapsibleTrigger({
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
return (
<CollapsiblePrimitive.CollapsibleTrigger
data-slot="collapsible-trigger"
{...props}
/>
);
}
function CollapsibleContent({
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
return (
<CollapsiblePrimitive.CollapsibleContent
data-slot="collapsible-content"
{...props}
/>
);
}
export { Collapsible, CollapsibleTrigger, CollapsibleContent };

View File

@@ -0,0 +1,255 @@
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
import type * as React from "react";
import { cn } from "@/lib/utils";
function DropdownMenu({
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
}
function DropdownMenuPortal({
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
return (
<DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
);
}
function DropdownMenuTrigger({
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
return (
<DropdownMenuPrimitive.Trigger
data-slot="dropdown-menu-trigger"
{...props}
/>
);
}
function DropdownMenuContent({
className,
sideOffset = 4,
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
return (
<DropdownMenuPrimitive.Portal>
<DropdownMenuPrimitive.Content
data-slot="dropdown-menu-content"
sideOffset={sideOffset}
className={cn(
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
className,
)}
{...props}
/>
</DropdownMenuPrimitive.Portal>
);
}
function DropdownMenuGroup({
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
return (
<DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
);
}
function DropdownMenuItem({
className,
inset,
variant = "default",
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
inset?: boolean;
variant?: "default" | "destructive";
}) {
return (
<DropdownMenuPrimitive.Item
data-slot="dropdown-menu-item"
data-inset={inset}
data-variant={variant}
className={cn(
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
{...props}
/>
);
}
function DropdownMenuCheckboxItem({
className,
children,
checked,
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
return (
<DropdownMenuPrimitive.CheckboxItem
data-slot="dropdown-menu-checkbox-item"
className={cn(
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
checked={checked}
{...props}
>
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<CheckIcon className="size-4" />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.CheckboxItem>
);
}
function DropdownMenuRadioGroup({
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
return (
<DropdownMenuPrimitive.RadioGroup
data-slot="dropdown-menu-radio-group"
{...props}
/>
);
}
function DropdownMenuRadioItem({
className,
children,
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
return (
<DropdownMenuPrimitive.RadioItem
data-slot="dropdown-menu-radio-item"
className={cn(
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
{...props}
>
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<CircleIcon className="size-2 fill-current" />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.RadioItem>
);
}
function DropdownMenuLabel({
className,
inset,
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
inset?: boolean;
}) {
return (
<DropdownMenuPrimitive.Label
data-slot="dropdown-menu-label"
data-inset={inset}
className={cn(
"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
className,
)}
{...props}
/>
);
}
function DropdownMenuSeparator({
className,
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
return (
<DropdownMenuPrimitive.Separator
data-slot="dropdown-menu-separator"
className={cn("bg-border -mx-1 my-1 h-px", className)}
{...props}
/>
);
}
function DropdownMenuShortcut({
className,
...props
}: React.ComponentProps<"span">) {
return (
<span
data-slot="dropdown-menu-shortcut"
className={cn(
"text-muted-foreground ml-auto text-xs tracking-widest",
className,
)}
{...props}
/>
);
}
function DropdownMenuSub({
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
}
function DropdownMenuSubTrigger({
className,
inset,
children,
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
inset?: boolean;
}) {
return (
<DropdownMenuPrimitive.SubTrigger
data-slot="dropdown-menu-sub-trigger"
data-inset={inset}
className={cn(
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
{...props}
>
{children}
<ChevronRightIcon className="ml-auto size-4" />
</DropdownMenuPrimitive.SubTrigger>
);
}
function DropdownMenuSubContent({
className,
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
return (
<DropdownMenuPrimitive.SubContent
data-slot="dropdown-menu-sub-content"
className={cn(
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
className,
)}
{...props}
/>
);
}
export {
DropdownMenu,
DropdownMenuPortal,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuLabel,
DropdownMenuItem,
DropdownMenuCheckboxItem,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubTrigger,
DropdownMenuSubContent,
};

View File

@@ -0,0 +1,21 @@
import type * as React from "react";
import { cn } from "@/lib/utils";
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
return (
<input
type={type}
data-slot="input"
className={cn(
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
className,
)}
{...props}
/>
);
}
export { Input };

View File

@@ -0,0 +1,26 @@
import * as SeparatorPrimitive from "@radix-ui/react-separator";
import type * as React from "react";
import { cn } from "@/lib/utils";
function Separator({
className,
orientation = "horizontal",
decorative = true,
...props
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
return (
<SeparatorPrimitive.Root
data-slot="separator"
decorative={decorative}
orientation={orientation}
className={cn(
"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
className,
)}
{...props}
/>
);
}
export { Separator };

View File

@@ -0,0 +1,139 @@
"use client";
import * as SheetPrimitive from "@radix-ui/react-dialog";
import { XIcon } from "lucide-react";
import type * as React from "react";
import { cn } from "@/lib/utils";
function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
return <SheetPrimitive.Root data-slot="sheet" {...props} />;
}
function SheetTrigger({
...props
}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
}
function SheetClose({
...props
}: React.ComponentProps<typeof SheetPrimitive.Close>) {
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
}
function SheetPortal({
...props
}: React.ComponentProps<typeof SheetPrimitive.Portal>) {
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />;
}
function SheetOverlay({
className,
...props
}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
return (
<SheetPrimitive.Overlay
data-slot="sheet-overlay"
className={cn(
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
className,
)}
{...props}
/>
);
}
function SheetContent({
className,
children,
side = "right",
...props
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
side?: "top" | "right" | "bottom" | "left";
}) {
return (
<SheetPortal>
<SheetOverlay />
<SheetPrimitive.Content
data-slot="sheet-content"
className={cn(
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
side === "right" &&
"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
side === "left" &&
"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
side === "top" &&
"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
side === "bottom" &&
"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
className,
)}
{...props}
>
{children}
<SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
<XIcon className="size-4" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>
);
}
function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="sheet-header"
className={cn("flex flex-col gap-1.5 p-4", className)}
{...props}
/>
);
}
function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="sheet-footer"
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
{...props}
/>
);
}
function SheetTitle({
className,
...props
}: React.ComponentProps<typeof SheetPrimitive.Title>) {
return (
<SheetPrimitive.Title
data-slot="sheet-title"
className={cn("text-foreground font-semibold", className)}
{...props}
/>
);
}
function SheetDescription({
className,
...props
}: React.ComponentProps<typeof SheetPrimitive.Description>) {
return (
<SheetPrimitive.Description
data-slot="sheet-description"
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
);
}
export {
Sheet,
SheetTrigger,
SheetClose,
SheetContent,
SheetHeader,
SheetFooter,
SheetTitle,
SheetDescription,
};

View File

@@ -0,0 +1,726 @@
"use client";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { PanelLeftIcon } from "lucide-react";
import * as React from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Separator } from "@/components/ui/separator";
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
} from "@/components/ui/sheet";
import { Skeleton } from "@/components/ui/skeleton";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { useIsMobile } from "@/hooks/use-mobile";
import { cn } from "@/lib/utils";
const SIDEBAR_COOKIE_NAME = "sidebar_state";
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
const SIDEBAR_WIDTH = "16rem";
const SIDEBAR_WIDTH_MOBILE = "18rem";
const SIDEBAR_WIDTH_ICON = "3rem";
const SIDEBAR_KEYBOARD_SHORTCUT = "b";
type SidebarContextProps = {
state: "expanded" | "collapsed";
open: boolean;
setOpen: (open: boolean) => void;
openMobile: boolean;
setOpenMobile: (open: boolean) => void;
isMobile: boolean;
toggleSidebar: () => void;
};
const SidebarContext = React.createContext<SidebarContextProps | null>(null);
function useSidebar() {
const context = React.useContext(SidebarContext);
if (!context) {
throw new Error("useSidebar must be used within a SidebarProvider.");
}
return context;
}
function SidebarProvider({
defaultOpen = true,
open: openProp,
onOpenChange: setOpenProp,
className,
style,
children,
...props
}: React.ComponentProps<"div"> & {
defaultOpen?: boolean;
open?: boolean;
onOpenChange?: (open: boolean) => void;
}) {
const isMobile = useIsMobile();
const [openMobile, setOpenMobile] = React.useState(false);
// This is the internal state of the sidebar.
// We use openProp and setOpenProp for control from outside the component.
const [_open, _setOpen] = React.useState(defaultOpen);
const open = openProp ?? _open;
const setOpen = React.useCallback(
(value: boolean | ((value: boolean) => boolean)) => {
const openState = typeof value === "function" ? value(open) : value;
if (setOpenProp) {
setOpenProp(openState);
} else {
_setOpen(openState);
}
// This sets the cookie to keep the sidebar state.
// biome-ignore lint/suspicious/noDocumentCookie: this was from a shadcn template
document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
},
[setOpenProp, open],
);
// Helper to toggle the sidebar.
const toggleSidebar = React.useCallback(() => {
return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
}, [isMobile, setOpen]);
// Adds a keyboard shortcut to toggle the sidebar.
React.useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (
event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
(event.metaKey || event.ctrlKey)
) {
event.preventDefault();
toggleSidebar();
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [toggleSidebar]);
// We add a state so that we can do data-state="expanded" or "collapsed".
// This makes it easier to style the sidebar with Tailwind classes.
const state = open ? "expanded" : "collapsed";
const contextValue = React.useMemo<SidebarContextProps>(
() => ({
state,
open,
setOpen,
isMobile,
openMobile,
setOpenMobile,
toggleSidebar,
}),
[state, open, setOpen, isMobile, openMobile, toggleSidebar],
);
return (
<SidebarContext.Provider value={contextValue}>
<TooltipProvider delayDuration={0}>
<div
data-slot="sidebar-wrapper"
style={
{
"--sidebar-width": SIDEBAR_WIDTH,
"--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
...style,
} as React.CSSProperties
}
className={cn(
"group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full",
className,
)}
{...props}
>
{children}
</div>
</TooltipProvider>
</SidebarContext.Provider>
);
}
function Sidebar({
side = "left",
variant = "sidebar",
collapsible = "offcanvas",
className,
children,
...props
}: React.ComponentProps<"div"> & {
side?: "left" | "right";
variant?: "sidebar" | "floating" | "inset";
collapsible?: "offcanvas" | "icon" | "none";
}) {
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
if (collapsible === "none") {
return (
<div
data-slot="sidebar"
className={cn(
"bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col",
className,
)}
{...props}
>
{children}
</div>
);
}
if (isMobile) {
return (
<Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
<SheetContent
data-sidebar="sidebar"
data-slot="sidebar"
data-mobile="true"
className="bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden"
style={
{
"--sidebar-width": SIDEBAR_WIDTH_MOBILE,
} as React.CSSProperties
}
side={side}
>
<SheetHeader className="sr-only">
<SheetTitle>Sidebar</SheetTitle>
<SheetDescription>Displays the mobile sidebar.</SheetDescription>
</SheetHeader>
<div className="flex h-full w-full flex-col">{children}</div>
</SheetContent>
</Sheet>
);
}
return (
<div
className="group peer text-sidebar-foreground hidden md:block"
data-state={state}
data-collapsible={state === "collapsed" ? collapsible : ""}
data-variant={variant}
data-side={side}
data-slot="sidebar"
>
{/* This is what handles the sidebar gap on desktop */}
<div
data-slot="sidebar-gap"
className={cn(
"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear",
"group-data-[collapsible=offcanvas]:w-0",
"group-data-[side=right]:rotate-180",
variant === "floating" || variant === "inset"
? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]"
: "group-data-[collapsible=icon]:w-(--sidebar-width-icon)",
)}
/>
<div
data-slot="sidebar-container"
className={cn(
"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex",
side === "left"
? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"
: "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
// Adjust the padding for floating and inset variants.
variant === "floating" || variant === "inset"
? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"
: "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l border-sidebar-border",
className,
)}
{...props}
>
<div
data-sidebar="sidebar"
data-slot="sidebar-inner"
className="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
>
{children}
</div>
</div>
</div>
);
}
function SidebarTrigger({
className,
onClick,
...props
}: React.ComponentProps<typeof Button>) {
const { toggleSidebar } = useSidebar();
return (
<Button
data-sidebar="trigger"
data-slot="sidebar-trigger"
variant="ghost"
size="icon"
className={cn("size-7", className)}
onClick={(event) => {
onClick?.(event);
toggleSidebar();
}}
{...props}
>
<PanelLeftIcon />
<span className="sr-only">Toggle Sidebar</span>
</Button>
);
}
function SidebarRail({ className, ...props }: React.ComponentProps<"button">) {
const { toggleSidebar } = useSidebar();
return (
<button
data-sidebar="rail"
data-slot="sidebar-rail"
aria-label="Toggle Sidebar"
tabIndex={-1}
onClick={toggleSidebar}
title="Toggle Sidebar"
className={cn(
"hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex",
"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize",
"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
"hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full",
"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
className,
)}
{...props}
/>
);
}
function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
return (
<main
data-slot="sidebar-inset"
className={cn(
"bg-background relative flex w-full flex-1 flex-col",
"md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2",
className,
)}
{...props}
/>
);
}
function SidebarInput({
className,
...props
}: React.ComponentProps<typeof Input>) {
return (
<Input
data-slot="sidebar-input"
data-sidebar="input"
className={cn("bg-background h-8 w-full shadow-none", className)}
{...props}
/>
);
}
function SidebarHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="sidebar-header"
data-sidebar="header"
className={cn("flex flex-col gap-2 p-2", className)}
{...props}
/>
);
}
function SidebarFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="sidebar-footer"
data-sidebar="footer"
className={cn("flex flex-col gap-2 p-2", className)}
{...props}
/>
);
}
function SidebarSeparator({
className,
...props
}: React.ComponentProps<typeof Separator>) {
return (
<Separator
data-slot="sidebar-separator"
data-sidebar="separator"
className={cn("bg-sidebar-border mx-2 w-auto", className)}
{...props}
/>
);
}
function SidebarContent({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="sidebar-content"
data-sidebar="content"
className={cn(
"flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
className,
)}
{...props}
/>
);
}
function SidebarGroup({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="sidebar-group"
data-sidebar="group"
className={cn("relative flex w-full min-w-0 flex-col p-2", className)}
{...props}
/>
);
}
function SidebarGroupLabel({
className,
asChild = false,
...props
}: React.ComponentProps<"div"> & { asChild?: boolean }) {
const Comp = asChild ? Slot : "div";
return (
<Comp
data-slot="sidebar-group-label"
data-sidebar="group-label"
className={cn(
"text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
className,
)}
{...props}
/>
);
}
function SidebarGroupAction({
className,
asChild = false,
...props
}: React.ComponentProps<"button"> & { asChild?: boolean }) {
const Comp = asChild ? Slot : "button";
return (
<Comp
data-slot="sidebar-group-action"
data-sidebar="group-action"
className={cn(
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
// Increases the hit area of the button on mobile.
"after:absolute after:-inset-2 md:after:hidden",
"group-data-[collapsible=icon]:hidden",
className,
)}
{...props}
/>
);
}
function SidebarGroupContent({
className,
...props
}: React.ComponentProps<"div">) {
return (
<div
data-slot="sidebar-group-content"
data-sidebar="group-content"
className={cn("w-full text-sm", className)}
{...props}
/>
);
}
function SidebarMenu({ className, ...props }: React.ComponentProps<"ul">) {
return (
<ul
data-slot="sidebar-menu"
data-sidebar="menu"
className={cn("flex w-full min-w-0 flex-col gap-1", className)}
{...props}
/>
);
}
function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
return (
<li
data-slot="sidebar-menu-item"
data-sidebar="menu-item"
className={cn("group/menu-item relative", className)}
{...props}
/>
);
}
const sidebarMenuButtonVariants = cva(
"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
{
variants: {
variant: {
default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
outline:
"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
},
size: {
default: "h-8 text-sm",
sm: "h-7 text-xs",
lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);
function SidebarMenuButton({
asChild = false,
isActive = false,
variant = "default",
size = "default",
tooltip,
className,
...props
}: React.ComponentProps<"button"> & {
asChild?: boolean;
isActive?: boolean;
tooltip?: string | React.ComponentProps<typeof TooltipContent>;
} & VariantProps<typeof sidebarMenuButtonVariants>) {
const Comp = asChild ? Slot : "button";
const { isMobile, state } = useSidebar();
const button = (
<Comp
data-slot="sidebar-menu-button"
data-sidebar="menu-button"
data-size={size}
data-active={isActive}
className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
{...props}
/>
);
if (!tooltip) {
return button;
}
if (typeof tooltip === "string") {
tooltip = {
children: tooltip,
};
}
return (
<Tooltip>
<TooltipTrigger asChild>{button}</TooltipTrigger>
<TooltipContent
side="right"
align="center"
hidden={state !== "collapsed" || isMobile}
{...tooltip}
/>
</Tooltip>
);
}
function SidebarMenuAction({
className,
asChild = false,
showOnHover = false,
...props
}: React.ComponentProps<"button"> & {
asChild?: boolean;
showOnHover?: boolean;
}) {
const Comp = asChild ? Slot : "button";
return (
<Comp
data-slot="sidebar-menu-action"
data-sidebar="menu-action"
className={cn(
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
// Increases the hit area of the button on mobile.
"after:absolute after:-inset-2 md:after:hidden",
"peer-data-[size=sm]/menu-button:top-1",
"peer-data-[size=default]/menu-button:top-1.5",
"peer-data-[size=lg]/menu-button:top-2.5",
"group-data-[collapsible=icon]:hidden",
showOnHover &&
"peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0",
className,
)}
{...props}
/>
);
}
function SidebarMenuBadge({
className,
...props
}: React.ComponentProps<"div">) {
return (
<div
data-slot="sidebar-menu-badge"
data-sidebar="menu-badge"
className={cn(
"text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none",
"peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
"peer-data-[size=sm]/menu-button:top-1",
"peer-data-[size=default]/menu-button:top-1.5",
"peer-data-[size=lg]/menu-button:top-2.5",
"group-data-[collapsible=icon]:hidden",
className,
)}
{...props}
/>
);
}
function SidebarMenuSkeleton({
className,
showIcon = false,
...props
}: React.ComponentProps<"div"> & {
showIcon?: boolean;
}) {
// Random width between 50 to 90%.
const width = React.useMemo(() => {
return `${Math.floor(Math.random() * 40) + 50}%`;
}, []);
return (
<div
data-slot="sidebar-menu-skeleton"
data-sidebar="menu-skeleton"
className={cn("flex h-8 items-center gap-2 rounded-md px-2", className)}
{...props}
>
{showIcon && (
<Skeleton
className="size-4 rounded-md"
data-sidebar="menu-skeleton-icon"
/>
)}
<Skeleton
className="h-4 max-w-(--skeleton-width) flex-1"
data-sidebar="menu-skeleton-text"
style={
{
"--skeleton-width": width,
} as React.CSSProperties
}
/>
</div>
);
}
function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">) {
return (
<ul
data-slot="sidebar-menu-sub"
data-sidebar="menu-sub"
className={cn(
"border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5",
"group-data-[collapsible=icon]:hidden",
className,
)}
{...props}
/>
);
}
function SidebarMenuSubItem({
className,
...props
}: React.ComponentProps<"li">) {
return (
<li
data-slot="sidebar-menu-sub-item"
data-sidebar="menu-sub-item"
className={cn("group/menu-sub-item relative", className)}
{...props}
/>
);
}
function SidebarMenuSubButton({
asChild = false,
size = "md",
isActive = false,
className,
...props
}: React.ComponentProps<"a"> & {
asChild?: boolean;
size?: "sm" | "md";
isActive?: boolean;
}) {
const Comp = asChild ? Slot : "a";
return (
<Comp
data-slot="sidebar-menu-sub-button"
data-sidebar="menu-sub-button"
data-size={size}
data-active={isActive}
className={cn(
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
"data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground",
size === "sm" && "text-xs",
size === "md" && "text-sm",
"group-data-[collapsible=icon]:hidden",
className,
)}
{...props}
/>
);
}
export {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarGroupAction,
SidebarGroupContent,
SidebarGroupLabel,
SidebarHeader,
SidebarInput,
SidebarInset,
SidebarMenu,
SidebarMenuAction,
SidebarMenuBadge,
SidebarMenuButton,
SidebarMenuItem,
SidebarMenuSkeleton,
SidebarMenuSub,
SidebarMenuSubButton,
SidebarMenuSubItem,
SidebarProvider,
SidebarRail,
SidebarSeparator,
SidebarTrigger,
useSidebar,
};

View File

@@ -0,0 +1,13 @@
import { cn } from "@/lib/utils";
function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="skeleton"
className={cn("bg-accent animate-pulse rounded-md", className)}
{...props}
/>
);
}
export { Skeleton };

View File

@@ -0,0 +1,59 @@
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
import type * as React from "react";
import { cn } from "@/lib/utils";
function TooltipProvider({
delayDuration = 0,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
return (
<TooltipPrimitive.Provider
data-slot="tooltip-provider"
delayDuration={delayDuration}
{...props}
/>
);
}
function Tooltip({
...props
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
return (
<TooltipProvider>
<TooltipPrimitive.Root data-slot="tooltip" {...props} />
</TooltipProvider>
);
}
function TooltipTrigger({
...props
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
}
function TooltipContent({
className,
sideOffset = 0,
children,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
return (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content
data-slot="tooltip-content"
sideOffset={sideOffset}
className={cn(
"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
className,
)}
{...props}
>
{children}
<TooltipPrimitive.Arrow className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
</TooltipPrimitive.Content>
</TooltipPrimitive.Portal>
);
}
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };

View File

@@ -0,0 +1,21 @@
import * as React from "react";
const MOBILE_BREAKPOINT = 768;
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined,
);
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
};
mql.addEventListener("change", onChange);
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
return () => mql.removeEventListener("change", onChange);
}, []);
return !!isMobile;
}

13
packages/ui/src/index.ts Normal file
View File

@@ -0,0 +1,13 @@
export { ThemeProvider, useTheme } from "@/components/theme-provider";
export * from "@/components/ui/badge.tsx";
export * from "@/components/ui/sidebar";
export { AppSidebar } from "./lib/components/index.ts";
// Types
export type {
AppSidebarProps,
NavLink,
SidebarSectionProps,
} from "./lib/components/Sidebar/AppSidebar.tsx";
export { ThemeToggle } from "./lib/components/theme-toggle.tsx";

View File

@@ -0,0 +1,218 @@
import type { LucideIcon } from "lucide-react";
import { ChevronRight } from "lucide-react";
import type * as React from "react";
import { Badge } from "@/components/ui/badge";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarHeader,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarMenuSub,
SidebarMenuSubButton,
SidebarMenuSubItem,
useSidebar,
} from "@/components/ui/sidebar";
import { cn } from "@/lib/utils";
export interface AppSidebarProps {
children?: React.ReactNode;
logo?: {
src: string;
alt: string;
};
title?: string;
navigationLabel?: string;
variant?: "sidebar" | "inset";
footer?: React.ReactNode;
}
export interface NavLink {
name: string;
icon: LucideIcon;
page: string;
count?: number;
active?: boolean;
disabled?: boolean;
items?: NavLink[];
onClick?: () => void;
}
export interface SidebarSectionProps {
label?: string;
items: NavLink[];
}
const AppSidebar = ({
children,
logo,
title,
navigationLabel,
items,
footer,
variant,
...props
}: SidebarSectionProps & AppSidebarProps) => {
const { state } = useSidebar();
const isCollapsed = state === "collapsed";
return (
<Sidebar collapsible="icon" variant="sidebar" {...props}>
<SidebarHeader
className={cn(
"h-14 mt-2 flex-shrink-0 transition-all duration-300 ease-in-out",
)}
>
<div className="flex items-center">
{logo && (
<img
src={logo.src}
alt={logo.alt}
className="size-10 flex-shrink-0 rounded-xl"
/>
)}
{title && (
<h2
className={cn(
"text-xl font-semibold whitespace-nowrap",
"transition-all duration-300 ease-in-out",
isCollapsed
? "opacity-0 max-w-0 invisible ml-0"
: "opacity-100 max-w-xs visible ml-2",
)}
>
{title}
</h2>
)}
</div>
</SidebarHeader>
<SidebarContent>
<SidebarGroup className="mt-4">
{navigationLabel && (
<SidebarGroupLabel
className={cn(
"transition-all duration-300 ease-in-out",
"whitespace-nowrap overflow-hidden",
isCollapsed ? "max-w-0 opacity-0 invisible" : "max-w-full",
)}
>
{navigationLabel}
</SidebarGroupLabel>
)}
<SidebarGroupContent>
<SidebarMenu>
{items.map((link) => {
// Check if this item has sub-items
if (link.items && link.items.length > 0) {
return (
<Collapsible
key={link.name}
asChild
defaultOpen={link.active}
className="group/collapsible"
>
<SidebarMenuItem>
<CollapsibleTrigger asChild>
<SidebarMenuButton
onClick={link.onClick}
disabled={link.disabled}
tooltip={isCollapsed ? link.name : undefined}
>
{link.icon && <link.icon className="size-5" />}
<span>{link.name}</span>
{link.count !== undefined && link.count > 0 && (
<Badge
variant="default"
className="ml-auto bg-blue-500 text-white text-xs"
>
{link.count}
</Badge>
)}
<ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
</SidebarMenuButton>
</CollapsibleTrigger>
<CollapsibleContent>
<SidebarMenuSub>
{link.items.map((subLink) => (
<SidebarMenuSubItem key={subLink.name}>
<SidebarMenuSubButton
onClick={subLink.onClick}
isActive={subLink.active}
>
{subLink.icon && (
<subLink.icon className="size-4" />
)}
<span>{subLink.name}</span>
{subLink.count !== undefined &&
subLink.count > 0 && (
<Badge
variant="default"
className="ml-auto bg-blue-500 text-white text-xs"
>
{subLink.count}
</Badge>
)}
</SidebarMenuSubButton>
</SidebarMenuSubItem>
))}
</SidebarMenuSub>
</CollapsibleContent>
</SidebarMenuItem>
</Collapsible>
);
}
return (
<SidebarMenuItem key={link.name}>
<SidebarMenuButton
onClick={link.onClick}
isActive={link.active}
disabled={link.disabled}
tooltip={isCollapsed ? link.name : undefined}
>
{link.icon && <link.icon className="size-5" />}
<span>{link.name}</span>
{link.count !== undefined && link.count > 0 && (
<Badge
variant="default"
className="ml-auto bg-blue-500 text-white text-xs"
>
{link.count}
</Badge>
)}
</SidebarMenuButton>
</SidebarMenuItem>
);
})}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
{children && (
<div
className={cn("flex-1 min-h-0", isCollapsed && "overflow-hidden")}
>
{children}
</div>
)}
</SidebarContent>
{footer && <SidebarFooter className="pt-4">{footer}</SidebarFooter>}
</Sidebar>
);
};
AppSidebar.displayName = "AppSidebar";
export default AppSidebar;

View File

@@ -0,0 +1 @@
export { default as AppSidebar } from "./Sidebar/AppSidebar.tsx";

View File

@@ -0,0 +1,36 @@
import { Moon, Sun } from "lucide-react";
import { useTheme } from "@/components/theme-provider";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
export function ThemeToggle() {
const { setTheme } = useTheme();
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<Sun className="size-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute size-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme("light")}>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("dark")}>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("system")}>
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}

View File

@@ -0,0 +1,124 @@
@import "tailwindcss";
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--destructive-foreground: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--radius: 0.625rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.145 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.145 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.985 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.396 0.141 25.723);
--destructive-foreground: oklch(0.637 0.237 25.331);
--border: oklch(0.269 0 0);
--input: oklch(0.269 0 0);
--ring: oklch(0.439 0 0);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(0.269 0 0);
--sidebar-ring: oklch(0.439 0 0);
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}

View File

@@ -0,0 +1,6 @@
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}

25
packages/ui/tsconfig.json Normal file
View File

@@ -0,0 +1,25 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"target": "ES2021",
"lib": ["ES2021", "DOM"],
"jsx": "react-jsx",
"module": "ESNext",
"moduleResolution": "Bundler",
"skipLibCheck": true,
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": false,
"noUncheckedIndexedAccess": true,
"erasableSyntaxOnly": true,
"outDir": "dist",
"rootDir": "src",
"strict": true,
"types": ["react", "react-dom"],
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src"]
}

View File

@@ -0,0 +1,53 @@
import path from "node:path";
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
import dts from "vite-plugin-dts";
import { viteStaticCopy } from "vite-plugin-static-copy";
export default defineConfig({
plugins: [
react(),
tailwindcss(),
dts({
entryRoot: "src",
outDir: "dist",
insertTypesEntry: true,
copyDtsFiles: true,
}),
viteStaticCopy({
targets: [
{
src: "src/lib/theme/default.css",
dest: "theme",
},
],
}),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
build: {
emptyOutDir: true,
lib: {
entry: "src/index.ts",
name: "MeshtasticUI",
formats: ["es"],
fileName: () => "index.js",
},
rollupOptions: {
external: [
"react",
"react-dom",
"tailwindcss",
"class-variance-authority",
"tailwind-merge",
"@radix-ui/react-slot",
],
},
sourcemap: true,
target: "es2021",
},
});

View File

@@ -11,16 +11,6 @@
<link rel="manifest" href="site.webmanifest" />
<link rel="mask-icon" href="logo_black.svg" color="#67ea94" />
<link
rel="stylesheet"
href="https://rsms.me/inter/inter.css"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@xz/fonts@1/serve/cascadia-code.min.css"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="src/index.css"

View File

@@ -14,16 +14,17 @@
"homepage": "https://meshtastic.org",
"scripts": {
"preinstall": "npx only-allow pnpm",
"setup:certs": "mkcert localhost 127.0.0.1 ::1",
"build": "vite build",
"build:analyze": "BUNDLE_ANALYZE=true bun run build",
"build:analyze": "BUNDLE_ANALYZE=true pnpm run build",
"check": "biome check src/",
"check:fix": "biome check --write src/",
"dev": "vite",
"dev:https": "USE_HTTPS=true vite",
"test": "vitest",
"ts:check": "bun run tsc --noEmit",
"typecheck": "pnpm run tsc --noEmit",
"preview": "vite preview",
"docker:build": "docker build -t meshtastic-web:latest -f ./infra/Containerfile .",
"generate:routes": "bun @tanstack/router-cli generate --outDir src/ routes --rootRoutePath /",
"package": "gzipper c -i html,js,css,png,ico,svg,json,webmanifest,txt dist dist/output && tar -cvf dist/build.tar -C ./dist/output/ ."
},
"dependencies": {
@@ -34,6 +35,7 @@
"@meshtastic/transport-web-serial": "workspace:*",
"@noble/curves": "^1.9.2",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-alert-dialog": "^1.1.15",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
@@ -79,7 +81,7 @@
"react-map-gl": "8.1.0",
"react-qrcode-logo": "^4.0.0",
"rfc4648": "^1.5.4",
"vite": "^7.1.9",
"vite": "^7.1.11",
"vite-plugin-html": "^3.2.2",
"vite-plugin-pwa": "^1.0.3",
"zod": "^4.1.12",
@@ -97,10 +99,11 @@
"@types/react-dom": "^19.2.0",
"@types/serviceworker": "^0.0.158",
"@types/w3c-web-serial": "^1.0.8",
"@vitejs/plugin-basic-ssl": "^2.1.0",
"@vitejs/plugin-react": "^5.0.4",
"autoprefixer": "^10.4.21",
"gzipper": "^8.2.1",
"happy-dom": "^20.0.0",
"happy-dom": "^20.0.2",
"simple-git-hooks": "^2.13.1",
"tailwind-merge": "^3.3.1",
"tailwindcss": "^4.1.14",

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="512"
height="512"
viewBox="0 0 512 512"
xml:space="preserve"
>
<desc>Created with Fabric.js 4.6.0</desc>
<defs> </defs>
<g transform="matrix(1 0 0 1 256 256)" id="xYQ9Gk9Jwpgj_HMOXB3F_">
<path
style="stroke: rgb(213, 130, 139); stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(103, 234, 148); fill-rule: nonzero; opacity: 1"
vector-effect="non-scaling-stroke"
transform=" translate(-256, -256)"
d="M 0 0 L 512 0 L 512 512 L 0 512 z"
stroke-linecap="round"
/>
</g>
<g transform="matrix(1.79 0 0 1.79 313.74 258.36)" id="1xBsk2n9FZp60Rz1O-ceJ">
<path
style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: round; stroke-miterlimit: 2; fill: rgb(44, 45, 60); fill-rule: evenodd; opacity: 1"
vector-effect="non-scaling-stroke"
transform=" translate(-250.97, -362.41)"
d="M 250.908 330.267 L 193.126 415.005 L 180.938 406.694 L 244.802 313.037 C 246.174 311.024 248.453 309.819 250.889 309.816 C 253.326 309.814 255.606 311.015 256.982 313.026 L 320.994 406.536 L 308.821 414.869 L 250.908 330.267 Z"
stroke-linecap="round"
/>
</g>
<g transform="matrix(1.81 0 0 1.81 145 256.15)" id="KxN7E9YpbyPgz0S4z4Cl6">
<path
style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: round; stroke-miterlimit: 2; fill: rgb(44, 45, 60); fill-rule: evenodd; opacity: 1"
vector-effect="non-scaling-stroke"
transform=" translate(-115.14, -528.06)"
d="M 87.642 581.398 L 154.757 482.977 L 142.638 474.713 L 75.523 573.134 L 87.642 581.398 Z"
stroke-linecap="round"
/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
width="100%"
height="100%"
viewBox="0 0 100 55"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve"
xmlns:serif="http://www.serif.com/"
style="fill-rule: evenodd; clip-rule: evenodd; stroke-linejoin: round; stroke-miterlimit: 2"
>
<g transform="matrix(0.802386,0,0,0.460028,-421.748,-122.127)">
<g transform="matrix(0.579082,0,0,1.01004,460.975,-39.6867)">
<path
d="M250.908,330.267L193.126,415.005L180.938,406.694L244.802,313.037C246.174,311.024 248.453,309.819 250.889,309.816C253.326,309.814 255.606,311.015 256.982,313.026L320.994,406.536L308.821,414.869L250.908,330.267Z"
/>
</g>
<g transform="matrix(0.582378,0,0,1.01579,485.019,-211.182)">
<path
d="M87.642,581.398L154.757,482.977L142.638,474.713L75.523,573.134L87.642,581.398Z"
/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
width="100%"
height="100%"
viewBox="0 0 100 55"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve"
xmlns:serif="http://www.serif.com/"
style="fill-rule: evenodd; clip-rule: evenodd; stroke-linejoin: round; stroke-miterlimit: 2"
>
<g transform="matrix(0.802386,0,0,0.460028,-421.748,-122.127)">
<g transform="matrix(0.579082,0,0,1.01004,460.975,-39.6867)">
<path
d="M250.908,330.267L193.126,415.005L180.938,406.694L244.802,313.037C246.174,311.024 248.453,309.819 250.889,309.816C253.326,309.814 255.606,311.015 256.982,313.026L320.994,406.536L308.821,414.869L250.908,330.267Z"
style="fill: white"
/>
</g>
<g transform="matrix(0.582378,0,0,1.01579,485.019,-211.182)">
<path
d="M87.642,581.398L154.757,482.977L142.638,474.713L75.523,573.134L87.642,581.398Z"
style="fill: white"
/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

Binary file not shown.

View File

Binary file not shown.

View File

@@ -1,69 +1,71 @@
{
"page": {
"sectionLabel": "Channels",
"channelName": "Channel: {{channelName}}",
"broadcastLabel": "Primary",
"channelIndex": "Ch {{index}}"
},
"validation": {
"pskInvalid": "Please enter a valid {{bits}} bit PSK."
},
"settings": {
"label": "Channel Settings",
"description": "Crypto, MQTT & misc settings"
},
"role": {
"label": "Role",
"description": "Device telemetry is sent over PRIMARY. Only one PRIMARY allowed",
"options": {
"primary": "PRIMARY",
"disabled": "DISABLED",
"secondary": "SECONDARY"
}
},
"psk": {
"label": "Pre-Shared Key",
"description": "Supported PSK lengths: 256-bit, 128-bit, 8-bit, Empty (0-bit)",
"generate": "Generate"
},
"name": {
"label": "Name",
"description": "A unique name for the channel <12 bytes, leave blank for default"
},
"uplinkEnabled": {
"label": "Uplink Enabled",
"description": "Send messages from the local mesh to MQTT"
},
"downlinkEnabled": {
"label": "Downlink Enabled",
"description": "Send messages from MQTT to the local mesh"
},
"positionPrecision": {
"label": "Location",
"description": "The precision of the location to share with the channel. Can be disabled.",
"options": {
"none": "Do not share location",
"precise": "Precise Location",
"metric_km23": "Within 23 kilometers",
"metric_km12": "Within 12 kilometers",
"metric_km5_8": "Within 5.8 kilometers",
"metric_km2_9": "Within 2.9 kilometers",
"metric_km1_5": "Within 1.5 kilometers",
"metric_m700": "Within 700 meters",
"metric_m350": "Within 350 meters",
"metric_m200": "Within 200 meters",
"metric_m90": "Within 90 meters",
"metric_m50": "Within 50 meters",
"imperial_mi15": "Within 15 miles",
"imperial_mi7_3": "Within 7.3 miles",
"imperial_mi3_6": "Within 3.6 miles",
"imperial_mi1_8": "Within 1.8 miles",
"imperial_mi0_9": "Within 0.9 miles",
"imperial_mi0_5": "Within 0.5 miles",
"imperial_mi0_2": "Within 0.2 miles",
"imperial_ft600": "Within 600 feet",
"imperial_ft300": "Within 300 feet",
"imperial_ft150": "Within 150 feet"
}
}
"page": {
"sectionLabel": "Channels",
"channelName": "Channel: {{channelName}}",
"broadcastLabel": "Primary",
"channelIndex": "Ch {{index}}",
"import": "Import",
"export": "Export"
},
"validation": {
"pskInvalid": "Please enter a valid {{bits}} bit PSK."
},
"settings": {
"label": "Channel Settings",
"description": "Crypto, MQTT & misc settings"
},
"role": {
"label": "Role",
"description": "Device telemetry is sent over PRIMARY. Only one PRIMARY allowed",
"options": {
"primary": "PRIMARY",
"disabled": "DISABLED",
"secondary": "SECONDARY"
}
},
"psk": {
"label": "Pre-Shared Key",
"description": "Supported PSK lengths: 256-bit, 128-bit, 8-bit, Empty (0-bit)",
"generate": "Generate"
},
"name": {
"label": "Name",
"description": "A unique name for the channel <12 bytes, leave blank for default"
},
"uplinkEnabled": {
"label": "Uplink Enabled",
"description": "Send messages from the local mesh to MQTT"
},
"downlinkEnabled": {
"label": "Downlink Enabled",
"description": "Send messages from MQTT to the local mesh"
},
"positionPrecision": {
"label": "Location",
"description": "The precision of the location to share with the channel. Can be disabled.",
"options": {
"none": "Do not share location",
"precise": "Precise Location",
"metric_km23": "Within 23 kilometers",
"metric_km12": "Within 12 kilometers",
"metric_km5_8": "Within 5.8 kilometers",
"metric_km2_9": "Within 2.9 kilometers",
"metric_km1_5": "Within 1.5 kilometers",
"metric_m700": "Within 700 meters",
"metric_m350": "Within 350 meters",
"metric_m200": "Within 200 meters",
"metric_m90": "Within 90 meters",
"metric_m50": "Within 50 meters",
"imperial_mi15": "Within 15 miles",
"imperial_mi7_3": "Within 7.3 miles",
"imperial_mi3_6": "Within 3.6 miles",
"imperial_mi1_8": "Within 1.8 miles",
"imperial_mi0_9": "Within 0.9 miles",
"imperial_mi0_5": "Within 0.5 miles",
"imperial_mi0_2": "Within 0.2 miles",
"imperial_ft600": "Within 600 feet",
"imperial_ft300": "Within 300 feet",
"imperial_ft150": "Within 150 feet"
}
}
}

View File

@@ -15,7 +15,6 @@
"messages": "Messages",
"map": "Map",
"config": "Config",
"channels": "Channels",
"nodes": "Nodes"
}
},
@@ -45,7 +44,8 @@
"label": "Debug",
"command": {
"reconfigure": "Reconfigure",
"clearAllStoredMessages": "Clear All Stored Message"
"clearAllStoredMessages": "Clear All Stored Message",
"clearAllStores": "Clear All Local Storage"
}
}
}

View File

@@ -1,142 +1,165 @@
{
"button": {
"apply": "Apply",
"backupKey": "Backup Key",
"cancel": "Cancel",
"clearMessages": "Clear Messages",
"close": "Close",
"confirm": "Confirm",
"delete": "Delete",
"dismiss": "Dismiss",
"download": "Download",
"export": "Export",
"generate": "Generate",
"regenerate": "Regenerate",
"import": "Import",
"message": "Message",
"now": "Now",
"ok": "OK",
"print": "Print",
"remove": "Remove",
"requestNewKeys": "Request New Keys",
"requestPosition": "Request Position",
"reset": "Reset",
"save": "Save",
"scanQr": "Scan QR Code",
"traceRoute": "Trace Route",
"submit": "Submit"
},
"app": {
"title": "Meshtastic",
"fullTitle": "Meshtastic Web Client"
},
"loading": "Loading...",
"unit": {
"cps": "CPS",
"dbm": "dBm",
"hertz": "Hz",
"hop": {
"one": "Hop",
"plural": "Hops"
},
"hopsAway": {
"one": "{{count}} hop away",
"plural": "{{count}} hops away",
"unknown": "Unknown hops away"
},
"megahertz": "MHz",
"raw": "raw",
"meter": {
"one": "Meter",
"plural": "Meters",
"suffix": "m"
},
"minute": {
"one": "Minute",
"plural": "Minutes"
},
"hour": {
"one": "Hour",
"plural": "Hours"
},
"millisecond": {
"one": "Millisecond",
"plural": "Milliseconds",
"suffix": "ms"
},
"second": {
"one": "Second",
"plural": "Seconds"
},
"day": {
"one": "Day",
"plural": "Days"
},
"month": {
"one": "Month",
"plural": "Months"
},
"year": {
"one": "Year",
"plural": "Years"
},
"snr": "SNR",
"volt": {
"one": "Volt",
"plural": "Volts",
"suffix": "V"
},
"record": {
"one": "Records",
"plural": "Records"
}
},
"security": {
"0bit": "Empty",
"8bit": "8 bit",
"128bit": "128 bit",
"256bit": "256 bit"
},
"unknown": {
"longName": "Unknown",
"shortName": "UNK",
"notAvailable": "N/A",
"num": "??"
},
"nodeUnknownPrefix": "!",
"unset": "UNSET",
"fallbackName": "Meshtastic {{last4}}",
"node": "Node",
"formValidation": {
"unsavedChanges": "Unsaved changes",
"tooBig": {
"string": "Too long, expected less than or equal to {{maximum}} characters.",
"number": "Too big, expected a number smaller than or equal to {{maximum}}.",
"bytes": "Too big, expected less than or equal to {{params.maximum}} bytes."
},
"tooSmall": {
"string": "Too short, expected more than or equal to {{minimum}} characters.",
"number": "Too small, expected a number larger than or equal to {{minimum}}."
},
"invalidFormat": {
"ipv4": "Invalid format, expected an IPv4 address.",
"key": "Invalid format, expected a Base64 encoded pre-shared key (PSK)."
},
"invalidType": {
"number": "Invalid type, expected a number."
},
"pskLength": {
"0bit": "Key is required to be empty.",
"8bit": "Key is required to be an 8 bit pre-shared key (PSK).",
"128bit": "Key is required to be a 128 bit pre-shared key (PSK).",
"256bit": "Key is required to be a 256 bit pre-shared key (PSK)."
},
"required": {
"generic": "This field is required.",
"managed": "At least one admin key is requred if the node is managed.",
"key": "Key is required."
}
},
"yes": "Yes",
"no": "No"
"button": {
"apply": "Apply",
"addConnection": "Add Connection",
"saveConnection": "Save connection",
"backupKey": "Backup Key",
"cancel": "Cancel",
"connect": "Connect",
"clearMessages": "Clear Messages",
"close": "Close",
"confirm": "Confirm",
"delete": "Delete",
"dismiss": "Dismiss",
"download": "Download",
"disconnect": "Disconnect",
"export": "Export",
"generate": "Generate",
"regenerate": "Regenerate",
"import": "Import",
"message": "Message",
"now": "Now",
"ok": "OK",
"print": "Print",
"remove": "Remove",
"requestNewKeys": "Request New Keys",
"requestPosition": "Request Position",
"reset": "Reset",
"retry": "Retry",
"save": "Save",
"setDefault": "Set as default",
"unsetDefault": "Unset default",
"scanQr": "Scan QR Code",
"traceRoute": "Trace Route",
"submit": "Submit"
},
"app": {
"title": "Meshtastic",
"fullTitle": "Meshtastic Web Client"
},
"loading": "Loading...",
"unit": {
"cps": "CPS",
"dbm": "dBm",
"hertz": "Hz",
"hop": {
"one": "Hop",
"plural": "Hops"
},
"hopsAway": {
"one": "{{count}} hop away",
"plural": "{{count}} hops away",
"unknown": "Unknown hops away"
},
"megahertz": "MHz",
"kilohertz": "kHz",
"raw": "raw",
"meter": {
"one": "Meter",
"plural": "Meters",
"suffix": "m"
},
"kilometer": {
"one": "Kilometer",
"plural": "Kilometers",
"suffix": "km"
},
"minute": {
"one": "Minute",
"plural": "Minutes"
},
"hour": {
"one": "Hour",
"plural": "Hours"
},
"millisecond": {
"one": "Millisecond",
"plural": "Milliseconds",
"suffix": "ms"
},
"second": {
"one": "Second",
"plural": "Seconds"
},
"day": {
"one": "Day",
"plural": "Days",
"today": "Today",
"yesterday": "Yesterday"
},
"month": {
"one": "Month",
"plural": "Months"
},
"year": {
"one": "Year",
"plural": "Years"
},
"snr": "SNR",
"volt": {
"one": "Volt",
"plural": "Volts",
"suffix": "V"
},
"record": {
"one": "Records",
"plural": "Records"
},
"degree": {
"one": "Degree",
"plural": "Degrees",
"suffix": "°"
}
},
"security": {
"0bit": "Empty",
"8bit": "8 bit",
"128bit": "128 bit",
"256bit": "256 bit"
},
"unknown": {
"longName": "Unknown",
"shortName": "UNK",
"notAvailable": "N/A",
"num": "??"
},
"nodeUnknownPrefix": "!",
"unset": "UNSET",
"fallbackName": "Meshtastic {{last4}}",
"node": "Node",
"formValidation": {
"unsavedChanges": "Unsaved changes",
"tooBig": {
"string": "Too long, expected less than or equal to {{maximum}} characters.",
"number": "Too big, expected a number smaller than or equal to {{maximum}}.",
"bytes": "Too big, expected less than or equal to {{params.maximum}} bytes."
},
"tooSmall": {
"string": "Too short, expected more than or equal to {{minimum}} characters.",
"number": "Too small, expected a number larger than or equal to {{minimum}}."
},
"invalidFormat": {
"ipv4": "Invalid format, expected an IPv4 address.",
"key": "Invalid format, expected a Base64 encoded pre-shared key (PSK)."
},
"invalidType": {
"number": "Invalid type, expected a number."
},
"pskLength": {
"0bit": "Key is required to be empty.",
"8bit": "Key is required to be an 8 bit pre-shared key (PSK).",
"128bit": "Key is required to be a 128 bit pre-shared key (PSK).",
"256bit": "Key is required to be a 256 bit pre-shared key (PSK)."
},
"required": {
"generic": "This field is required.",
"managed": "At least one admin key is requred if the node is managed.",
"key": "Key is required."
},
"invalidOverrideFreq": {
"number": "Invalid format, expected a value in the range 410-930 MHz or 0 (use default)."
}
},
"yes": "Yes",
"no": "No"
}

View File

@@ -1,17 +1,19 @@
{
"page": {
"title": "Configuration",
"title": "Settings",
"tabUser": "Карыстальнік",
"tabChannels": "Каналы",
"tabBluetooth": "Bluetooth",
"tabDevice": "Device",
"tabDisplay": "Display",
"tabDevice": "Прылада",
"tabDisplay": "Экран",
"tabLora": "LoRa",
"tabNetwork": "Network",
"tabPosition": "Position",
"tabNetwork": "Сетка",
"tabPosition": "Месцазнаходжанне",
"tabPower": "Power",
"tabSecurity": "Security"
"tabSecurity": "Бяспека"
},
"sidebar": {
"label": "Modules"
"label": "Configuration"
},
"device": {
"title": "Device Settings",
@@ -59,7 +61,7 @@
"note": "Note: Some devices (ESP32) cannot use both Bluetooth and WiFi at the same time.",
"enabled": {
"description": "Enable or disable Bluetooth",
"label": "Enabled"
"label": "Уключана"
},
"pairingMode": {
"description": "Pin selection behaviour.",
@@ -122,7 +124,7 @@
"title": "Mesh Settings",
"description": "Settings for the LoRa mesh",
"bandwidth": {
"description": "Channel bandwidth in MHz",
"description": "Channel bandwidth in kHz",
"label": "Bandwidth"
},
"boostedRxGain": {
@@ -167,7 +169,7 @@
},
"region": {
"description": "Sets the region for your node",
"label": "Region"
"label": "Рэгіён"
},
"spreadingFactor": {
"description": "Indicates the number of chirps per symbol",
@@ -212,7 +214,7 @@
},
"ethernetEnabled": {
"description": "Enable or disable the Ethernet port",
"label": "Enabled"
"label": "Уключана"
},
"gateway": {
"description": "Default Gateway",
@@ -236,7 +238,7 @@
},
"wifiEnabled": {
"description": "Enable or disable the WiFi radio",
"label": "Enabled"
"label": "Уключана"
},
"meshViaUdp": {
"label": "Mesh via UDP"
@@ -424,5 +426,33 @@
"description": "Settings for Logging",
"label": "Logging Settings"
}
},
"user": {
"title": "User Settings",
"description": "Configure your device name and identity settings",
"longName": {
"label": "Long Name",
"description": "Your full display name (1-40 characters)",
"validation": {
"min": "Long name must be at least 1 character",
"max": "Long name must be at most 40 characters"
}
},
"shortName": {
"label": "Short Name",
"description": "Your abbreviated name (2-4 characters)",
"validation": {
"min": "Short name must be at least 2 characters",
"max": "Short name must be at most 4 characters"
}
},
"isUnmessageable": {
"label": "Unmessageable",
"description": "Used to identify unmonitored or infrastructure nodes so that messaging is not available to nodes that will never respond."
},
"isLicensed": {
"label": "Licensed amateur radio (HAM)",
"description": "Enable if you are a licensed amateur radio operator, enabling this option disables encryption and is not compatible with the default Meshtastic network."
}
}
}

View File

@@ -0,0 +1,34 @@
{
"page": {
"title": "Connect to a Meshtastic device",
"description": "Add a device connection via HTTP, Bluetooth, or Serial. Your saved connections will be saved in your browser."
},
"connectionType_ble": "BLE",
"connectionType_serial": "Serial",
"connectionType_network": "Сетка",
"deleteConnection": "Delete connection",
"areYouSure": "This will remove {{name}}. You canot undo this action.",
"moreActions": "More actions",
"noConnections": {
"title": "No connections yet.",
"description": "Create your first connection. It will connect immediately and be saved for later."
},
"lastConnectedAt": "Last connected: {{date}}",
"neverConnected": "Never connected",
"toasts": {
"connected": "Злучаны",
"nowConnected": "{{name}} is now connected",
"nowDisconnected": "{{name}} are now disconnecte",
"disconnected": "Адлучана",
"failed": "Failed to connect",
"checkConnetion": "Check your device or settings and try again",
"defaultSet": "Default set",
"defaultConnection": "Default connection is now {{nameisconnected}}",
"deleted": "Deleted",
"deletedByName": "{{name}} was removed",
"pickConnectionAgain": "Could not connect. You may need to reselect the device/port.",
"added": "Connection added",
"savedByName": "{{name}} saved.",
"savedCantConnect": "The connection was saved but could not connect."
}
}

View File

@@ -1,12 +0,0 @@
{
"dashboard": {
"title": "Connected Devices",
"description": "Manage your connected Meshtastic devices.",
"connectionType_ble": "BLE",
"connectionType_serial": "Serial",
"connectionType_network": "Network",
"noDevicesTitle": "No devices connected",
"noDevicesDescription": "Connect a new device to get started.",
"button_newConnection": "New Connection"
}
}

View File

@@ -122,7 +122,7 @@
"title": "Mesh Settings",
"description": "Settings for the LoRa mesh",
"bandwidth": {
"description": "Channel bandwidth in MHz",
"description": "Channel bandwidth in kHz",
"label": "Bandwidth"
},
"boostedRxGain": {

View File

@@ -1,193 +1,238 @@
{
"deleteMessages": {
"description": "This action will clear all message history. This cannot be undone. Are you sure you want to continue?",
"title": "Clear All Messages"
},
"deviceName": {
"description": "The Device will restart once the config is saved.",
"longName": "Long Name",
"shortName": "Short Name",
"title": "Change Device Name",
"validation": {
"longNameMax": "Long name must not be more than 40 characters",
"shortNameMax": "Short name must not be more than 4 characters",
"longNameMin": "Long name must have at least 1 character",
"shortNameMin": "Short name must have at least 1 character"
}
},
"import": {
"description": "The current LoRa configuration will be overridden.",
"error": {
"invalidUrl": "Invalid Meshtastic URL"
},
"channelPrefix": "Channel: ",
"channelSetUrl": "Channel Set/QR Code URL",
"channels": "Channels:",
"usePreset": "Use Preset?",
"title": "Import Channel Set"
},
"locationResponse": {
"title": "Location: {{identifier}}",
"altitude": "Altitude: ",
"coordinates": "Coordinates: ",
"noCoordinates": "No Coordinates"
},
"pkiRegenerateDialog": {
"title": "Regenerate Pre-Shared Key?",
"description": "Are you sure you want to regenerate the pre-shared key?",
"regenerate": "Regenerate"
},
"newDeviceDialog": {
"title": "Connect New Device",
"https": "https",
"http": "http",
"tabHttp": "HTTP",
"tabBluetooth": "Bluetooth",
"tabSerial": "Serial",
"useHttps": "Use HTTPS",
"connecting": "Connecting...",
"connect": "Connect",
"connectionFailedAlert": {
"title": "Connection Failed",
"descriptionPrefix": "Could not connect to the device. ",
"httpsHint": "If using HTTPS, you may need to accept a self-signed certificate first. ",
"openLinkPrefix": "Please open ",
"openLinkSuffix": " in a new tab",
"acceptTlsWarningSuffix": ", accept any TLS warnings if prompted, then try again",
"learnMoreLink": "Learn more"
},
"httpConnection": {
"label": "IP Address/Hostname",
"placeholder": "000.000.000.000 / meshtastic.local"
},
"serialConnection": {
"noDevicesPaired": "No devices paired yet.",
"newDeviceButton": "New device",
"deviceIdentifier": "# {{index}} - {{vendorId}} - {{productId}}"
},
"bluetoothConnection": {
"noDevicesPaired": "No devices paired yet.",
"newDeviceButton": "New device",
"connectionFailed": "Connection failed",
"deviceDisconnected": "Device disconnected",
"unknownDevice": "Unknown Device",
"errorLoadingDevices": "Error loading devices",
"unknownErrorLoadingDevices": "Unknown error loading devices"
},
"validation": {
"requiresWebBluetooth": "This connection type requires <0>Web Bluetooth</0>. Please use a supported browser, like Chrome or Edge.",
"requiresWebSerial": "This connection type requires <0>Web Serial</0>. Please use a supported browser, like Chrome or Edge.",
"requiresSecureContext": "This application requires a <0>secure context</0>. Please connect using HTTPS or localhost.",
"additionallyRequiresSecureContext": "Additionally, it requires a <0>secure context</0>. Please connect using HTTPS or localhost."
}
},
"nodeDetails": {
"message": "Message",
"requestPosition": "Request Position",
"traceRoute": "Trace Route",
"airTxUtilization": "Air TX utilization",
"allRawMetrics": "All Raw Metrics:",
"batteryLevel": "Battery level",
"channelUtilization": "Channel utilization",
"details": "Details:",
"deviceMetrics": "Device Metrics:",
"hardware": "Hardware: ",
"lastHeard": "Last Heard: ",
"nodeHexPrefix": "Node Hex: ",
"nodeNumber": "Node Number: ",
"position": "Position:",
"role": "Role: ",
"uptime": "Uptime: ",
"voltage": "Voltage",
"title": "Node Details for {{identifier}}",
"ignoreNode": "Ignore node",
"removeNode": "Remove node",
"unignoreNode": "Unignore node",
"security": "Security:",
"publicKey": "Public Key: ",
"messageable": "Messageable: ",
"KeyManuallyVerifiedTrue": "Public Key has been manually verified",
"KeyManuallyVerifiedFalse": "Public Key is not manually verified"
},
"pkiBackup": {
"loseKeysWarning": "If you lose your keys, you will need to reset your device.",
"secureBackup": "Its important to backup your public and private keys and store your backup securely!",
"footer": "=== END OF KEYS ===",
"header": "=== MESHTASTIC KEYS FOR {{longName}} ({{shortName}}) ===",
"privateKey": "Private Key:",
"publicKey": "Public Key:",
"fileName": "meshtastic_keys_{{longName}}_{{shortName}}.txt",
"title": "Backup Keys"
},
"pkiBackupReminder": {
"description": "We recommend backing up your key data regularly. Would you like to back up now?",
"title": "Backup Reminder",
"remindLaterPrefix": "Remind me in",
"remindNever": "Never remind me",
"backupNow": "Back up now"
},
"pkiRegenerate": {
"description": "Are you sure you want to regenerate key pair?",
"title": "Regenerate Key Pair"
},
"qr": {
"addChannels": "Add Channels",
"replaceChannels": "Replace Channels",
"description": "The current LoRa configuration will also be shared.",
"sharableUrl": "Sharable URL",
"title": "Generate QR Code"
},
"reboot": {
"title": "Reboot device",
"description": "Reboot now or schedule a reboot of the connected node. Optionally, you can choose to reboot into OTA (Over-the-Air) mode.",
"ota": "Reboot into OTA mode",
"enterDelay": "Enter delay",
"scheduled": "Reboot has been scheduled",
"schedule": "Schedule reboot",
"now": "Reboot now",
"cancel": "Cancel scheduled reboot"
},
"refreshKeys": {
"description": {
"acceptNewKeys": "This will remove the node from device and request new keys.",
"keyMismatchReasonSuffix": ". This is due to the remote node's current public key does not match the previously stored key for this node.",
"unableToSendDmPrefix": "Your node is unable to send a direct message to node: "
},
"acceptNewKeys": "Accept New Keys",
"title": "Keys Mismatch - {{identifier}}"
},
"removeNode": {
"description": "Are you sure you want to remove this Node?",
"title": "Remove Node?"
},
"shutdown": {
"title": "Schedule Shutdown",
"description": "Turn off the connected node after x minutes."
},
"traceRoute": {
"routeToDestination": "Route to destination:",
"routeBack": "Route back:"
},
"tracerouteResponse": {
"title": "Traceroute: {{identifier}}"
},
"unsafeRoles": {
"confirmUnderstanding": "Yes, I know what I'm doing",
"conjunction": " and the blog post about ",
"postamble": " and understand the implications of changing the role.",
"preamble": "I have read the ",
"choosingRightDeviceRole": "Choosing The Right Device Role",
"deviceRoleDocumentation": "Device Role Documentation",
"title": "Are you sure?"
},
"managedMode": {
"confirmUnderstanding": "Yes, I know what I'm doing",
"title": "Are you sure?",
"description": "Enabling Managed Mode blocks client applications (including the web client) from writing configurations to a radio. Once enabled, radio configurations can only be changed through Remote Admin messages. This setting is not required for remote node administration."
},
"clientNotification": {
"title": "Client Notification",
"TraceRoute can only be sent once every 30 seconds": "TraceRoute can only be sent once every 30 seconds",
"Compromised keys were detected and regenerated.": "Compromised keys were detected and regenerated."
}
"deleteMessages": {
"description": "This action will clear all message history. This cannot be undone. Are you sure you want to continue?",
"title": "Clear All Messages"
},
"import": {
"description": "The current LoRa configuration will be overridden.",
"error": {
"invalidUrl": "Invalid Meshtastic URL"
},
"channelPrefix": "Channel: ",
"primary": "Primary ",
"doNotImport": "No not import",
"channelName": "Назва",
"channelSlot": "Slot",
"channelSetUrl": "Channel Set/QR Code URL",
"useLoraConfig": "Import LoRa Config",
"presetDescription": "The current LoRa Config will be replaced.",
"title": "Import Channel Set"
},
"locationResponse": {
"title": "Location: {{identifier}}",
"altitude": "Altitude: ",
"coordinates": "Coordinates: ",
"noCoordinates": "No Coordinates"
},
"pkiRegenerateDialog": {
"title": "Regenerate Pre-Shared Key?",
"description": "Are you sure you want to regenerate the pre-shared key?",
"regenerate": "Regenerate"
},
"addConnection": {
"title": "Add connection",
"description": "Choose a connection type and fill in the details",
"validation": {
"requiresWebBluetooth": "This connection type requires <0>Web Bluetooth</0>. Please use a supported browser, like Chrome or Edge.",
"requiresWebSerial": "This connection type requires <0>Web Serial</0>. Please use a supported browser, like Chrome or Edge.",
"requiresSecureContext": "This application requires a <0>secure context</0>. Please connect using HTTPS or localhost.",
"additionallyRequiresSecureContext": "Additionally, it requires a <0>secure context</0>. Please connect using HTTPS or localhost."
},
"bluetoothConnection": {
"namePlaceholder": "My Bluetooth Node",
"supported": {
"title": "Web Bluetooth supported"
},
"notSupported": {
"title": "Web Bluetooth not supported",
"description": "Your browser or device does not support Web Bluetooth"
},
"short": "BT: {{deviceName}}",
"long": "Bluetooth Device",
"device": "Прылада",
"selectDevice": "Select device",
"selected": "Bluetooth device selected",
"notSelected": "No device selected",
"helperText": "Uses the Meshtastic Bluetooth service for discovery."
},
"serialConnection": {
"namePlaceholder": "My Serial Node",
"helperText": "Selecting a port grants permission so the app can open it to connect.",
"supported": {
"title": "Web Serial supported"
},
"notSupported": {
"title": "Web Serial not supported",
"description": "Your browser or device does not support Web Serial"
},
"portSelected": {
"title": "Serial port selected",
"description": "Port permissions granted."
},
"port": "Port",
"selectPort": "Select port",
"deviceName": "USB {{vendorId}}:{{productId}}",
"notSelected": "No port selected"
},
"httpConnection": {
"namePlaceholder": "My HTTP Node",
"inputPlaceholder": "192.168.1.10 or meshtastic.local",
"heading": "URL or IP",
"useHttps": "Use HTTTPS",
"invalidUrl": {
"title": "Invalid URL",
"description": "Please enter a valid HTTP or HTTPS URL."
},
"connectionTest": {
"description": "Test the connetion before saving to verify the device is reachable.",
"button": {
"loading": "Testing...",
"label": "Test connection"
},
"reachable": "Reachable",
"notReachable": "Not reachable",
"success": {
"title": "Connection test successful",
"description": "The device appears to be reachable."
},
"failure": {
"title": "Connection test failed",
"description": "Could not reach the device. Check the URL and try again."
}
}
}
},
"nodeDetails": {
"message": "Message",
"requestPosition": "Request Position",
"traceRoute": "Trace Route",
"airTxUtilization": "Air TX utilization",
"allRawMetrics": "All Raw Metrics:",
"batteryLevel": "Battery level",
"channelUtilization": "Channel utilization",
"details": "Details:",
"deviceMetrics": "Device Metrics:",
"hardware": "Hardware: ",
"lastHeard": "Last Heard: ",
"nodeHexPrefix": "Node Hex: ",
"nodeNumber": "Node Number: ",
"position": "Position:",
"role": "Role: ",
"uptime": "Uptime: ",
"voltage": "Voltage",
"title": "Node Details for {{identifier}}",
"ignoreNode": "Ignore node",
"removeNode": "Remove node",
"unignoreNode": "Unignore node",
"security": "Security:",
"publicKey": "Public Key: ",
"messageable": "Messageable: ",
"KeyManuallyVerifiedTrue": "Public Key has been manually verified",
"KeyManuallyVerifiedFalse": "Public Key is not manually verified"
},
"pkiBackup": {
"loseKeysWarning": "If you lose your keys, you will need to reset your device.",
"secureBackup": "Its important to backup your public and private keys and store your backup securely!",
"footer": "=== END OF KEYS ===",
"header": "=== MESHTASTIC KEYS FOR {{longName}} ({{shortName}}) ===",
"privateKey": "Private Key:",
"publicKey": "Public Key:",
"fileName": "meshtastic_keys_{{longName}}_{{shortName}}.txt",
"title": "Backup Keys"
},
"pkiBackupReminder": {
"description": "We recommend backing up your key data regularly. Would you like to back up now?",
"title": "Backup Reminder",
"remindLaterPrefix": "Remind me in",
"remindNever": "Never remind me",
"backupNow": "Back up now"
},
"pkiRegenerate": {
"description": "Are you sure you want to regenerate key pair?",
"title": "Regenerate Key Pair"
},
"qr": {
"addChannels": "Add Channels",
"replaceChannels": "Replace Channels",
"description": "The current LoRa configuration will also be shared.",
"sharableUrl": "Sharable URL",
"title": "Generate QR Code"
},
"reboot": {
"title": "Reboot device",
"description": "Reboot now or schedule a reboot of the connected node. Optionally, you can choose to reboot into OTA (Over-the-Air) mode.",
"ota": "Reboot into OTA mode",
"enterDelay": "Enter delay",
"scheduled": "Reboot has been scheduled",
"schedule": "Schedule reboot",
"now": "Reboot now",
"cancel": "Cancel scheduled reboot"
},
"refreshKeys": {
"description": {
"acceptNewKeys": "This will remove the node from device and request new keys.",
"keyMismatchReasonSuffix": ". This is due to the remote node's current public key does not match the previously stored key for this node.",
"unableToSendDmPrefix": "Your node is unable to send a direct message to node: "
},
"acceptNewKeys": "Accept New Keys",
"title": "Keys Mismatch - {{identifier}}"
},
"removeNode": {
"description": "Are you sure you want to remove this Node?",
"title": "Remove Node?"
},
"shutdown": {
"title": "Schedule Shutdown",
"description": "Turn off the connected node after x minutes."
},
"traceRoute": {
"routeToDestination": "Route to destination:",
"routeBack": "Route back:"
},
"tracerouteResponse": {
"title": "Traceroute: {{identifier}}"
},
"unsafeRoles": {
"confirmUnderstanding": "Yes, I know what I'm doing",
"conjunction": " and the blog post about ",
"postamble": " and understand the implications of changing the role.",
"preamble": "I have read the ",
"choosingRightDeviceRole": "Choosing The Right Device Role",
"deviceRoleDocumentation": "Device Role Documentation",
"title": "Are you sure?"
},
"managedMode": {
"confirmUnderstanding": "Yes, I know what I'm doing",
"title": "Are you sure?",
"description": "Enabling Managed Mode blocks client applications (including the web client) from writing configurations to a radio. Once enabled, radio configurations can only be changed through Remote Admin messages. This setting is not required for remote node administration."
},
"clientNotification": {
"title": "Client Notification",
"TraceRoute can only be sent once every 30 seconds": "TraceRoute can only be sent once every 30 seconds",
"Compromised keys were detected and regenerated.": "Compromised keys were detected and regenerated."
},
"resetNodeDb": {
"title": "Reset Node Database",
"description": "This will clear all nodes from the connected device's node database and clear all message history in the client. This cannot be undone. Are you sure you want to continue?",
"confirm": "Reset Node Database",
"failedTitle": "There was an error resetting the Node DB. Please try again."
},
"clearAllStores": {
"title": "Clear All Local Storage",
"description": "This will clear all locally stored data, including message history and node databases for all previously connected devices. This will require you to reconnect to your node once complete and cannot be undone. Are you sure you want to continue?",
"confirm": "Clear all local storage",
"failedTitle": "There was an error clearing local storage. Please try again."
},
"factoryResetDevice": {
"title": "Factory Reset Device",
"description": "This will factory reset the connected device, erasing all configurations and data on the device as well as all nodes and messages saved in the client. This cannot be undone. Are you sure you want to continue?",
"confirm": "Factory Reset Device",
"failedTitle": "There was an error performing the factory reset. Please try again."
},
"factoryResetConfig": {
"title": "Factory Reset Config",
"description": "This will factory reset the configuration on the connected device, erasing all configurations on the device. This cannot be undone. Are you sure you want to continue?",
"confirm": "Factory Reset Config",
"failedTitle": "There was an error performing the factory reset. Please try again."
}
}

View File

@@ -0,0 +1,38 @@
{
"maplibre": {
"GeolocateControl.FindMyLocation": "Find my location",
"NavigationControl.ZoomIn": "Zoom in",
"NavigationControl.ZoomOut": "Zoom out",
"CooperativeGesturesHandler.WindowsHelpText": "Use Ctrl + scroll to zoom the map",
"CooperativeGesturesHandler.MacHelpText": "Use ⌘ + scroll to zoom the map",
"CooperativeGesturesHandler.MobileHelpText": "Use two fingers to move the map"
},
"layerTool": {
"nodeMarkers": "Show nodes",
"directNeighbors": "Show direct connections",
"remoteNeighbors": "Show remote connections",
"positionPrecision": "Show position precision",
"traceroutes": "Show traceroutes",
"waypoints": "Show waypoints"
},
"mapMenu": {
"locateAria": "Locate my node",
"layersAria": "Change map style"
},
"waypointDetail": {
"edit": "Змяніць",
"description": "Description:",
"createdBy": "Edited by:",
"createdDate": "Created:",
"updated": "Updated:",
"expires": "Expires:",
"distance": "Distance:",
"bearing": "Absolute bearing:",
"lockedTo": "Locked by:",
"latitude": "Latitude:",
"longitude": "Longitude:"
},
"myNode": {
"tooltip": "This device"
}
}

View File

@@ -1,39 +1,39 @@
{
"page": {
"title": "Messages: {{chatName}}",
"placeholder": "Enter Message"
},
"emptyState": {
"title": "Select a Chat",
"text": "No messages yet."
},
"selectChatPrompt": {
"text": "Select a channel or node to start messaging."
},
"sendMessage": {
"placeholder": "Enter your message here...",
"sendButton": "Send"
},
"actionsMenu": {
"addReactionLabel": "Add Reaction",
"replyLabel": "Reply"
},
"deliveryStatus": {
"delivered": {
"label": "Message delivered",
"displayText": "Message delivered"
},
"failed": {
"label": "Message delivery failed",
"displayText": "Delivery failed"
},
"unknown": {
"label": "Message status unknown",
"displayText": "Unknown state"
},
"waiting": {
"label": "Sending message",
"displayText": "Waiting for delivery"
}
}
"page": {
"title": "Messages: {{chatName}}",
"placeholder": "Enter Message"
},
"emptyState": {
"title": "Select a Chat",
"text": "No messages yet."
},
"selectChatPrompt": {
"text": "Select a channel or node to start messaging."
},
"sendMessage": {
"placeholder": "Enter your message here...",
"sendButton": "Send"
},
"actionsMenu": {
"addReactionLabel": "Add Reaction",
"replyLabel": "Reply"
},
"deliveryStatus": {
"delivered": {
"label": "Message delivered",
"displayText": "Message delivered"
},
"failed": {
"label": "Message delivery failed",
"displayText": "Delivery failed"
},
"unknown": {
"label": "Message status unknown",
"displayText": "Unknown state"
},
"waiting": {
"label": "Sending message",
"displayText": "Waiting for delivery"
}
}
}

View File

@@ -1,448 +1,448 @@
{
"page": {
"tabAmbientLighting": "Ambient Lighting",
"tabAudio": "Audio",
"tabCannedMessage": "Canned",
"tabDetectionSensor": "Detection Sensor",
"tabExternalNotification": "Ext Notif",
"tabMqtt": "MQTT",
"tabNeighborInfo": "Neighbor Info",
"tabPaxcounter": "Paxcounter",
"tabRangeTest": "Range Test",
"tabSerial": "Serial",
"tabStoreAndForward": "S&F",
"tabTelemetry": "Telemetry"
},
"ambientLighting": {
"title": "Ambient Lighting Settings",
"description": "Settings for the Ambient Lighting module",
"ledState": {
"label": "LED State",
"description": "Sets LED to on or off"
},
"current": {
"label": "Current",
"description": "Sets the current for the LED output. Default is 10"
},
"red": {
"label": "Red",
"description": "Sets the red LED level. Values are 0-255"
},
"green": {
"label": "Green",
"description": "Sets the green LED level. Values are 0-255"
},
"blue": {
"label": "Blue",
"description": "Sets the blue LED level. Values are 0-255"
}
},
"audio": {
"title": "Audio Settings",
"description": "Settings for the Audio module",
"codec2Enabled": {
"label": "Codec 2 Enabled",
"description": "Enable Codec 2 audio encoding"
},
"pttPin": {
"label": "PTT Pin",
"description": "GPIO pin to use for PTT"
},
"bitrate": {
"label": "Bitrate",
"description": "Bitrate to use for audio encoding"
},
"i2sWs": {
"label": "i2S WS",
"description": "GPIO pin to use for i2S WS"
},
"i2sSd": {
"label": "i2S SD",
"description": "GPIO pin to use for i2S SD"
},
"i2sDin": {
"label": "i2S DIN",
"description": "GPIO pin to use for i2S DIN"
},
"i2sSck": {
"label": "i2S SCK",
"description": "GPIO pin to use for i2S SCK"
}
},
"cannedMessage": {
"title": "Canned Message Settings",
"description": "Settings for the Canned Message module",
"moduleEnabled": {
"label": "Module Enabled",
"description": "Enable Canned Message"
},
"rotary1Enabled": {
"label": "Rotary Encoder #1 Enabled",
"description": "Enable the rotary encoder"
},
"inputbrokerPinA": {
"label": "Encoder Pin A",
"description": "GPIO Pin Value (1-39) For encoder port A"
},
"inputbrokerPinB": {
"label": "Encoder Pin B",
"description": "GPIO Pin Value (1-39) For encoder port B"
},
"inputbrokerPinPress": {
"label": "Encoder Pin Press",
"description": "GPIO Pin Value (1-39) For encoder Press"
},
"inputbrokerEventCw": {
"label": "Clockwise event",
"description": "Select input event."
},
"inputbrokerEventCcw": {
"label": "Counter Clockwise event",
"description": "Select input event."
},
"inputbrokerEventPress": {
"label": "Press event",
"description": "Select input event"
},
"updown1Enabled": {
"label": "Up Down enabled",
"description": "Enable the up / down encoder"
},
"allowInputSource": {
"label": "Allow Input Source",
"description": "Select from: '_any', 'rotEnc1', 'upDownEnc1', 'cardkb'"
},
"sendBell": {
"label": "Send Bell",
"description": "Sends a bell character with each message"
}
},
"detectionSensor": {
"title": "Detection Sensor Settings",
"description": "Settings for the Detection Sensor module",
"enabled": {
"label": "Enabled",
"description": "Enable or disable Detection Sensor Module"
},
"minimumBroadcastSecs": {
"label": "Minimum Broadcast Seconds",
"description": "The interval in seconds of how often we can send a message to the mesh when a state change is detected"
},
"stateBroadcastSecs": {
"label": "State Broadcast Seconds",
"description": "The interval in seconds of how often we should send a message to the mesh with the current state regardless of changes"
},
"sendBell": {
"label": "Send Bell",
"description": "Send ASCII bell with alert message"
},
"name": {
"label": "Friendly Name",
"description": "Used to format the message sent to mesh, max 20 Characters"
},
"monitorPin": {
"label": "Monitor Pin",
"description": "The GPIO pin to monitor for state changes"
},
"detectionTriggerType": {
"label": "Detection Triggered Type",
"description": "The type of trigger event to be used"
},
"usePullup": {
"label": "Use Pullup",
"description": "Whether or not use INPUT_PULLUP mode for GPIO pin"
}
},
"externalNotification": {
"title": "External Notification Settings",
"description": "Configure the external notification module",
"enabled": {
"label": "Module Enabled",
"description": "Enable External Notification"
},
"outputMs": {
"label": "Output MS",
"description": "Output MS"
},
"output": {
"label": "Output",
"description": "Output"
},
"outputVibra": {
"label": "Output Vibrate",
"description": "Output Vibrate"
},
"outputBuzzer": {
"label": "Output Buzzer",
"description": "Output Buzzer"
},
"active": {
"label": "Active",
"description": "Active"
},
"alertMessage": {
"label": "Alert Message",
"description": "Alert Message"
},
"alertMessageVibra": {
"label": "Alert Message Vibrate",
"description": "Alert Message Vibrate"
},
"alertMessageBuzzer": {
"label": "Alert Message Buzzer",
"description": "Alert Message Buzzer"
},
"alertBell": {
"label": "Alert Bell",
"description": "Should an alert be triggered when receiving an incoming bell?"
},
"alertBellVibra": {
"label": "Alert Bell Vibrate",
"description": "Alert Bell Vibrate"
},
"alertBellBuzzer": {
"label": "Alert Bell Buzzer",
"description": "Alert Bell Buzzer"
},
"usePwm": {
"label": "Use PWM",
"description": "Use PWM"
},
"nagTimeout": {
"label": "Nag Timeout",
"description": "Nag Timeout"
},
"useI2sAsBuzzer": {
"label": "Use I²S Pin as Buzzer",
"description": "Designate I²S Pin as Buzzer Output"
}
},
"mqtt": {
"title": "MQTT Settings",
"description": "Settings for the MQTT module",
"enabled": {
"label": "Enabled",
"description": "Enable or disable MQTT"
},
"address": {
"label": "MQTT Server Address",
"description": "MQTT server address to use for default/custom servers"
},
"username": {
"label": "MQTT Username",
"description": "MQTT username to use for default/custom servers"
},
"password": {
"label": "MQTT Password",
"description": "MQTT password to use for default/custom servers"
},
"encryptionEnabled": {
"label": "Encryption Enabled",
"description": "Enable or disable MQTT encryption. Note: All messages are sent to the MQTT broker unencrypted if this option is not enabled, even when your uplink channels have encryption keys set. This includes position data."
},
"jsonEnabled": {
"label": "JSON Enabled",
"description": "Whether to send/consume JSON packets on MQTT"
},
"tlsEnabled": {
"label": "TLS Enabled",
"description": "Enable or disable TLS"
},
"root": {
"label": "Root topic",
"description": "MQTT root topic to use for default/custom servers"
},
"proxyToClientEnabled": {
"label": "MQTT Client Proxy Enabled",
"description": "Utilizes the network connection to proxy MQTT messages to the client."
},
"mapReportingEnabled": {
"label": "Map Reporting Enabled",
"description": "Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, short and long name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name."
},
"mapReportSettings": {
"publishIntervalSecs": {
"label": "Map Report Publish Interval (s)",
"description": "Interval in seconds to publish map reports"
},
"positionPrecision": {
"label": "Approximate Location",
"description": "Position shared will be accurate within this distance",
"options": {
"metric_km23": "Within 23 km",
"metric_km12": "Within 12 km",
"metric_km5_8": "Within 5.8 km",
"metric_km2_9": "Within 2.9 km",
"metric_km1_5": "Within 1.5 km",
"metric_m700": "Within 700 m",
"metric_m350": "Within 350 m",
"metric_m200": "Within 200 m",
"metric_m90": "Within 90 m",
"metric_m50": "Within 50 m",
"imperial_mi15": "Within 15 miles",
"imperial_mi7_3": "Within 7.3 miles",
"imperial_mi3_6": "Within 3.6 miles",
"imperial_mi1_8": "Within 1.8 miles",
"imperial_mi0_9": "Within 0.9 miles",
"imperial_mi0_5": "Within 0.5 miles",
"imperial_mi0_2": "Within 0.2 miles",
"imperial_ft600": "Within 600 feet",
"imperial_ft300": "Within 300 feet",
"imperial_ft150": "Within 150 feet"
}
}
}
},
"neighborInfo": {
"title": "Neighbor Info Settings",
"description": "Settings for the Neighbor Info module",
"enabled": {
"label": "Enabled",
"description": "Enable or disable Neighbor Info Module"
},
"updateInterval": {
"label": "Update Interval",
"description": "Interval in seconds of how often we should try to send our Neighbor Info to the mesh"
}
},
"paxcounter": {
"title": "Paxcounter Settings",
"description": "Settings for the Paxcounter module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Paxcounter"
},
"paxcounterUpdateInterval": {
"label": "Update Interval (seconds)",
"description": "How long to wait between sending paxcounter packets"
},
"wifiThreshold": {
"label": "WiFi RSSI Threshold",
"description": "At what WiFi RSSI level should the counter increase. Defaults to -80."
},
"bleThreshold": {
"label": "BLE RSSI Threshold",
"description": "At what BLE RSSI level should the counter increase. Defaults to -80."
}
},
"rangeTest": {
"title": "Range Test Settings",
"description": "Settings for the Range Test module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Range Test"
},
"sender": {
"label": "Message Interval",
"description": "How long to wait between sending test packets"
},
"save": {
"label": "Save CSV to storage",
"description": "ESP32 Only"
}
},
"serial": {
"title": "Serial Settings",
"description": "Settings for the Serial module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Serial output"
},
"echo": {
"label": "Echo",
"description": "Any packets you send will be echoed back to your device"
},
"rxd": {
"label": "Receive Pin",
"description": "Set the GPIO pin to the RXD pin you have set up."
},
"txd": {
"label": "Transmit Pin",
"description": "Set the GPIO pin to the TXD pin you have set up."
},
"baud": {
"label": "Baud Rate",
"description": "The serial baud rate"
},
"timeout": {
"label": "Timeout",
"description": "Seconds to wait before we consider your packet as 'done'"
},
"mode": {
"label": "Mode",
"description": "Select Mode"
},
"overrideConsoleSerialPort": {
"label": "Override Console Serial Port",
"description": "If you have a serial port connected to the console, this will override it."
}
},
"storeForward": {
"title": "Store & Forward Settings",
"description": "Settings for the Store & Forward module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Store & Forward"
},
"heartbeat": {
"label": "Heartbeat Enabled",
"description": "Enable Store & Forward heartbeat"
},
"records": {
"label": "Number of records",
"description": "Number of records to store"
},
"historyReturnMax": {
"label": "History return max",
"description": "Max number of records to return"
},
"historyReturnWindow": {
"label": "History return window",
"description": "Max number of records to return"
}
},
"telemetry": {
"title": "Telemetry Settings",
"description": "Settings for the Telemetry module",
"deviceUpdateInterval": {
"label": "Device Metrics",
"description": "Device metrics update interval (seconds)"
},
"environmentUpdateInterval": {
"label": "Environment metrics update interval (seconds)",
"description": ""
},
"environmentMeasurementEnabled": {
"label": "Module Enabled",
"description": "Enable the Environment Telemetry"
},
"environmentScreenEnabled": {
"label": "Displayed on Screen",
"description": "Show the Telemetry Module on the OLED"
},
"environmentDisplayFahrenheit": {
"label": "Display Fahrenheit",
"description": "Display temp in Fahrenheit"
},
"airQualityEnabled": {
"label": "Air Quality Enabled",
"description": "Enable the Air Quality Telemetry"
},
"airQualityInterval": {
"label": "Air Quality Update Interval",
"description": "How often to send Air Quality data over the mesh"
},
"powerMeasurementEnabled": {
"label": "Power Measurement Enabled",
"description": "Enable the Power Measurement Telemetry"
},
"powerUpdateInterval": {
"label": "Power Update Interval",
"description": "How often to send Power data over the mesh"
},
"powerScreenEnabled": {
"label": "Power Screen Enabled",
"description": "Enable the Power Telemetry Screen"
}
}
"page": {
"tabAmbientLighting": "Ambient Lighting",
"tabAudio": "Audio",
"tabCannedMessage": "Canned",
"tabDetectionSensor": "Detection Sensor",
"tabExternalNotification": "Ext Notif",
"tabMqtt": "MQTT",
"tabNeighborInfo": "Neighbor Info",
"tabPaxcounter": "Paxcounter",
"tabRangeTest": "Range Test",
"tabSerial": "Serial",
"tabStoreAndForward": "S&F",
"tabTelemetry": "Telemetry"
},
"ambientLighting": {
"title": "Ambient Lighting Settings",
"description": "Settings for the Ambient Lighting module",
"ledState": {
"label": "LED State",
"description": "Sets LED to on or off"
},
"current": {
"label": "Current",
"description": "Sets the current for the LED output. Default is 10"
},
"red": {
"label": "Red",
"description": "Sets the red LED level. Values are 0-255"
},
"green": {
"label": "Green",
"description": "Sets the green LED level. Values are 0-255"
},
"blue": {
"label": "Blue",
"description": "Sets the blue LED level. Values are 0-255"
}
},
"audio": {
"title": "Audio Settings",
"description": "Settings for the Audio module",
"codec2Enabled": {
"label": "Codec 2 Enabled",
"description": "Enable Codec 2 audio encoding"
},
"pttPin": {
"label": "PTT Pin",
"description": "GPIO pin to use for PTT"
},
"bitrate": {
"label": "Bitrate",
"description": "Bitrate to use for audio encoding"
},
"i2sWs": {
"label": "i2S WS",
"description": "GPIO pin to use for i2S WS"
},
"i2sSd": {
"label": "i2S SD",
"description": "GPIO pin to use for i2S SD"
},
"i2sDin": {
"label": "i2S DIN",
"description": "GPIO pin to use for i2S DIN"
},
"i2sSck": {
"label": "i2S SCK",
"description": "GPIO pin to use for i2S SCK"
}
},
"cannedMessage": {
"title": "Canned Message Settings",
"description": "Settings for the Canned Message module",
"moduleEnabled": {
"label": "Module Enabled",
"description": "Enable Canned Message"
},
"rotary1Enabled": {
"label": "Rotary Encoder #1 Enabled",
"description": "Enable the rotary encoder"
},
"inputbrokerPinA": {
"label": "Encoder Pin A",
"description": "GPIO Pin Value (1-39) For encoder port A"
},
"inputbrokerPinB": {
"label": "Encoder Pin B",
"description": "GPIO Pin Value (1-39) For encoder port B"
},
"inputbrokerPinPress": {
"label": "Encoder Pin Press",
"description": "GPIO Pin Value (1-39) For encoder Press"
},
"inputbrokerEventCw": {
"label": "Clockwise event",
"description": "Select input event."
},
"inputbrokerEventCcw": {
"label": "Counter Clockwise event",
"description": "Select input event."
},
"inputbrokerEventPress": {
"label": "Press event",
"description": "Select input event"
},
"updown1Enabled": {
"label": "Up Down enabled",
"description": "Enable the up / down encoder"
},
"allowInputSource": {
"label": "Allow Input Source",
"description": "Select from: '_any', 'rotEnc1', 'upDownEnc1', 'cardkb'"
},
"sendBell": {
"label": "Send Bell",
"description": "Sends a bell character with each message"
}
},
"detectionSensor": {
"title": "Detection Sensor Settings",
"description": "Settings for the Detection Sensor module",
"enabled": {
"label": "Enabled",
"description": "Enable or disable Detection Sensor Module"
},
"minimumBroadcastSecs": {
"label": "Minimum Broadcast Seconds",
"description": "The interval in seconds of how often we can send a message to the mesh when a state change is detected"
},
"stateBroadcastSecs": {
"label": "State Broadcast Seconds",
"description": "The interval in seconds of how often we should send a message to the mesh with the current state regardless of changes"
},
"sendBell": {
"label": "Send Bell",
"description": "Send ASCII bell with alert message"
},
"name": {
"label": "Friendly Name",
"description": "Used to format the message sent to mesh, max 20 Characters"
},
"monitorPin": {
"label": "Monitor Pin",
"description": "The GPIO pin to monitor for state changes"
},
"detectionTriggerType": {
"label": "Detection Triggered Type",
"description": "The type of trigger event to be used"
},
"usePullup": {
"label": "Use Pullup",
"description": "Whether or not use INPUT_PULLUP mode for GPIO pin"
}
},
"externalNotification": {
"title": "External Notification Settings",
"description": "Configure the external notification module",
"enabled": {
"label": "Module Enabled",
"description": "Enable External Notification"
},
"outputMs": {
"label": "Output MS",
"description": "Output MS"
},
"output": {
"label": "Output",
"description": "Output"
},
"outputVibra": {
"label": "Output Vibrate",
"description": "Output Vibrate"
},
"outputBuzzer": {
"label": "Output Buzzer",
"description": "Output Buzzer"
},
"active": {
"label": "Active",
"description": "Active"
},
"alertMessage": {
"label": "Alert Message",
"description": "Alert Message"
},
"alertMessageVibra": {
"label": "Alert Message Vibrate",
"description": "Alert Message Vibrate"
},
"alertMessageBuzzer": {
"label": "Alert Message Buzzer",
"description": "Alert Message Buzzer"
},
"alertBell": {
"label": "Alert Bell",
"description": "Should an alert be triggered when receiving an incoming bell?"
},
"alertBellVibra": {
"label": "Alert Bell Vibrate",
"description": "Alert Bell Vibrate"
},
"alertBellBuzzer": {
"label": "Alert Bell Buzzer",
"description": "Alert Bell Buzzer"
},
"usePwm": {
"label": "Use PWM",
"description": "Use PWM"
},
"nagTimeout": {
"label": "Nag Timeout",
"description": "Nag Timeout"
},
"useI2sAsBuzzer": {
"label": "Use I²S Pin as Buzzer",
"description": "Designate I²S Pin as Buzzer Output"
}
},
"mqtt": {
"title": "MQTT Settings",
"description": "Settings for the MQTT module",
"enabled": {
"label": "Enabled",
"description": "Enable or disable MQTT"
},
"address": {
"label": "MQTT Server Address",
"description": "MQTT server address to use for default/custom servers"
},
"username": {
"label": "MQTT Username",
"description": "MQTT username to use for default/custom servers"
},
"password": {
"label": "MQTT Password",
"description": "MQTT password to use for default/custom servers"
},
"encryptionEnabled": {
"label": "Encryption Enabled",
"description": "Enable or disable MQTT encryption. Note: All messages are sent to the MQTT broker unencrypted if this option is not enabled, even when your uplink channels have encryption keys set. This includes position data."
},
"jsonEnabled": {
"label": "JSON Enabled",
"description": "Whether to send/consume JSON packets on MQTT"
},
"tlsEnabled": {
"label": "TLS Enabled",
"description": "Enable or disable TLS"
},
"root": {
"label": "Root topic",
"description": "MQTT root topic to use for default/custom servers"
},
"proxyToClientEnabled": {
"label": "MQTT Client Proxy Enabled",
"description": "Utilizes the network connection to proxy MQTT messages to the client."
},
"mapReportingEnabled": {
"label": "Map Reporting Enabled",
"description": "Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, short and long name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name."
},
"mapReportSettings": {
"publishIntervalSecs": {
"label": "Map Report Publish Interval (s)",
"description": "Interval in seconds to publish map reports"
},
"positionPrecision": {
"label": "Approximate Location",
"description": "Position shared will be accurate within this distance",
"options": {
"metric_km23": "Within 23 km",
"metric_km12": "Within 12 km",
"metric_km5_8": "Within 5.8 km",
"metric_km2_9": "Within 2.9 km",
"metric_km1_5": "Within 1.5 km",
"metric_m700": "Within 700 m",
"metric_m350": "Within 350 m",
"metric_m200": "Within 200 m",
"metric_m90": "Within 90 m",
"metric_m50": "Within 50 m",
"imperial_mi15": "Within 15 miles",
"imperial_mi7_3": "Within 7.3 miles",
"imperial_mi3_6": "Within 3.6 miles",
"imperial_mi1_8": "Within 1.8 miles",
"imperial_mi0_9": "Within 0.9 miles",
"imperial_mi0_5": "Within 0.5 miles",
"imperial_mi0_2": "Within 0.2 miles",
"imperial_ft600": "Within 600 feet",
"imperial_ft300": "Within 300 feet",
"imperial_ft150": "Within 150 feet"
}
}
}
},
"neighborInfo": {
"title": "Neighbor Info Settings",
"description": "Settings for the Neighbor Info module",
"enabled": {
"label": "Enabled",
"description": "Enable or disable Neighbor Info Module"
},
"updateInterval": {
"label": "Update Interval",
"description": "Interval in seconds of how often we should try to send our Neighbor Info to the mesh"
}
},
"paxcounter": {
"title": "Paxcounter Settings",
"description": "Settings for the Paxcounter module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Paxcounter"
},
"paxcounterUpdateInterval": {
"label": "Update Interval (seconds)",
"description": "How long to wait between sending paxcounter packets"
},
"wifiThreshold": {
"label": "WiFi RSSI Threshold",
"description": "At what WiFi RSSI level should the counter increase. Defaults to -80."
},
"bleThreshold": {
"label": "BLE RSSI Threshold",
"description": "At what BLE RSSI level should the counter increase. Defaults to -80."
}
},
"rangeTest": {
"title": "Range Test Settings",
"description": "Settings for the Range Test module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Range Test"
},
"sender": {
"label": "Message Interval",
"description": "How long to wait between sending test packets"
},
"save": {
"label": "Save CSV to storage",
"description": "ESP32 Only"
}
},
"serial": {
"title": "Serial Settings",
"description": "Settings for the Serial module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Serial output"
},
"echo": {
"label": "Echo",
"description": "Any packets you send will be echoed back to your device"
},
"rxd": {
"label": "Receive Pin",
"description": "Set the GPIO pin to the RXD pin you have set up."
},
"txd": {
"label": "Transmit Pin",
"description": "Set the GPIO pin to the TXD pin you have set up."
},
"baud": {
"label": "Baud Rate",
"description": "The serial baud rate"
},
"timeout": {
"label": "Timeout",
"description": "Seconds to wait before we consider your packet as 'done'"
},
"mode": {
"label": "Mode",
"description": "Select Mode"
},
"overrideConsoleSerialPort": {
"label": "Override Console Serial Port",
"description": "If you have a serial port connected to the console, this will override it."
}
},
"storeForward": {
"title": "Store & Forward Settings",
"description": "Settings for the Store & Forward module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Store & Forward"
},
"heartbeat": {
"label": "Heartbeat Enabled",
"description": "Enable Store & Forward heartbeat"
},
"records": {
"label": "Number of records",
"description": "Number of records to store"
},
"historyReturnMax": {
"label": "History return max",
"description": "Max number of records to return"
},
"historyReturnWindow": {
"label": "History return window",
"description": "Return records from this time window (minutes)"
}
},
"telemetry": {
"title": "Telemetry Settings",
"description": "Settings for the Telemetry module",
"deviceUpdateInterval": {
"label": "Device Metrics",
"description": "Device metrics update interval (seconds)"
},
"environmentUpdateInterval": {
"label": "Environment metrics update interval (seconds)",
"description": ""
},
"environmentMeasurementEnabled": {
"label": "Module Enabled",
"description": "Enable the Environment Telemetry"
},
"environmentScreenEnabled": {
"label": "Displayed on Screen",
"description": "Show the Telemetry Module on the OLED"
},
"environmentDisplayFahrenheit": {
"label": "Display Fahrenheit",
"description": "Display temp in Fahrenheit"
},
"airQualityEnabled": {
"label": "Air Quality Enabled",
"description": "Enable the Air Quality Telemetry"
},
"airQualityInterval": {
"label": "Air Quality Update Interval",
"description": "How often to send Air Quality data over the mesh"
},
"powerMeasurementEnabled": {
"label": "Power Measurement Enabled",
"description": "Enable the Power Measurement Telemetry"
},
"powerUpdateInterval": {
"label": "Power Update Interval",
"description": "How often to send Power data over the mesh"
},
"powerScreenEnabled": {
"label": "Power Screen Enabled",
"description": "Enable the Power Telemetry Screen"
}
}
}

View File

@@ -1,63 +1,59 @@
{
"nodeDetail": {
"publicKeyEnabled": {
"label": "Public Key Enabled"
},
"noPublicKey": {
"label": "No Public Key"
},
"directMessage": {
"label": "Direct Message {{shortName}}"
},
"favorite": {
"label": "Favorite",
"tooltip": "Add or remove this node from your favorites"
},
"notFavorite": {
"label": "Not a Favorite"
},
"error": {
"label": "Error",
"text": "An error occurred while fetching node details. Please try again later."
},
"status": {
"heard": "Heard",
"mqtt": "MQTT"
},
"elevation": {
"label": "Elevation"
},
"channelUtil": {
"label": "Channel Util"
},
"airtimeUtil": {
"label": "Airtime Util"
}
},
"nodesTable": {
"headings": {
"longName": "Long Name",
"connection": "Connection",
"lastHeard": "Last Heard",
"encryption": "Encryption",
"model": "Model",
"macAddress": "MAC Address"
},
"connectionStatus": {
"direct": "Direct",
"away": "away",
"unknown": "-",
"viaMqtt": ", via MQTT"
},
"lastHeardStatus": {
"never": "Never"
}
},
"actions": {
"added": "Added",
"removed": "Removed",
"ignoreNode": "Ignore Node",
"unignoreNode": "Unignore Node",
"requestPosition": "Request Position"
}
"nodeDetail": {
"publicKeyEnabled": {
"label": "Public Key Enabled"
},
"noPublicKey": {
"label": "No Public Key"
},
"directMessage": {
"label": "Direct Message {{shortName}}"
},
"favorite": {
"label": "Favorite",
"tooltip": "Add or remove this node from your favorites"
},
"notFavorite": {
"label": "Not a Favorite"
},
"error": {
"label": "Error",
"text": "An error occurred while fetching node details. Please try again later."
},
"status": {
"heard": "Heard",
"mqtt": "MQTT"
},
"elevation": {
"label": "Elevation"
},
"channelUtil": {
"label": "Channel Util"
},
"airtimeUtil": {
"label": "Airtime Util"
}
},
"nodesTable": {
"headings": {
"longName": "Long Name",
"connection": "Connection",
"lastHeard": "Last Heard",
"encryption": "Encryption",
"model": "Model",
"macAddress": "MAC Address"
},
"connectionStatus": {
"direct": "Direct",
"away": "away",
"viaMqtt": ", via MQTT"
}
},
"actions": {
"added": "Added",
"removed": "Removed",
"ignoreNode": "Ignore Node",
"unignoreNode": "Unignore Node",
"requestPosition": "Request Position"
}
}

View File

@@ -1,228 +1,230 @@
{
"navigation": {
"title": "Navigation",
"messages": "Messages",
"map": "Map",
"config": "Config",
"radioConfig": "Radio Config",
"moduleConfig": "Module Config",
"channels": "Channels",
"nodes": "Nodes"
},
"app": {
"title": "Meshtastic",
"logo": "Meshtastic Logo"
},
"sidebar": {
"collapseToggle": {
"button": {
"open": "Open sidebar",
"close": "Close sidebar"
}
},
"deviceInfo": {
"volts": "{{voltage}} volts",
"firmware": {
"title": "Firmware",
"version": "v{{version}}",
"buildDate": "Build date: {{date}}"
},
"deviceName": {
"title": "Device Name",
"changeName": "Change Device Name",
"placeholder": "Enter device name"
},
"editDeviceName": "Edit device name"
}
},
"batteryStatus": {
"charging": "{{level}}% charging",
"pluggedIn": "Plugged in",
"title": "Battery"
},
"search": {
"nodes": "Search nodes...",
"channels": "Search channels...",
"commandPalette": "Search commands..."
},
"toast": {
"positionRequestSent": {
"title": "Position request sent."
},
"requestingPosition": {
"title": "Requesting position, please wait..."
},
"sendingTraceroute": {
"title": "Sending Traceroute, please wait..."
},
"tracerouteSent": {
"title": "Traceroute sent."
},
"savedChannel": {
"title": "Saved Channel: {{channelName}}"
},
"messages": {
"pkiEncryption": {
"title": "Chat is using PKI encryption."
},
"pskEncryption": {
"title": "Chat is using PSK encryption."
}
},
"configSaveError": {
"title": "Error Saving Config",
"description": "An error occurred while saving the configuration."
},
"validationError": {
"title": "Config Errors Exist",
"description": "Please fix the configuration errors before saving."
},
"saveSuccess": {
"title": "Saving Config",
"description": "The configuration change {{case}} has been saved."
},
"favoriteNode": {
"title": "{{action}} {{nodeName}} {{direction}} favorites.",
"action": {
"added": "Added",
"removed": "Removed",
"to": "to",
"from": "from"
}
},
"ignoreNode": {
"title": "{{action}} {{nodeName}} {{direction}} ignore list",
"action": {
"added": "Added",
"removed": "Removed",
"to": "to",
"from": "from"
}
}
},
"notifications": {
"copied": {
"label": "Copied!"
},
"copyToClipboard": {
"label": "Copy to clipboard"
},
"hidePassword": {
"label": "Hide password"
},
"showPassword": {
"label": "Show password"
},
"deliveryStatus": {
"delivered": "Delivered",
"failed": "Delivery Failed",
"waiting": "Waiting",
"unknown": "Unknown"
}
},
"general": {
"label": "General"
},
"hardware": {
"label": "Hardware"
},
"metrics": {
"label": "Metrics"
},
"role": {
"label": "Role"
},
"filter": {
"label": "Filter"
},
"advanced": {
"label": "Advanced"
},
"clearInput": {
"label": "Clear input"
},
"resetFilters": {
"label": "Reset Filters"
},
"nodeName": {
"label": "Node name/number",
"placeholder": "Meshtastic 1234"
},
"airtimeUtilization": {
"label": "Airtime Utilization (%)"
},
"batteryLevel": {
"label": "Battery level (%)",
"labelText": "Battery level (%): {{value}}"
},
"batteryVoltage": {
"label": "Battery voltage (V)",
"title": "Voltage"
},
"channelUtilization": {
"label": "Channel Utilization (%)"
},
"hops": {
"direct": "Direct",
"label": "Number of hops",
"text": "Number of hops: {{value}}"
},
"lastHeard": {
"label": "Last heard",
"labelText": "Last heard: {{value}}",
"nowLabel": "Now"
},
"snr": {
"label": "SNR (db)"
},
"favorites": {
"label": "Favorites"
},
"hide": {
"label": "Hide"
},
"showOnly": {
"label": "Show Only"
},
"viaMqtt": {
"label": "Connected via MQTT"
},
"hopsUnknown": {
"label": "Unknown number of hops"
},
"showUnheard": {
"label": "Never heard"
},
"language": {
"label": "Language",
"changeLanguage": "Change Language"
},
"theme": {
"dark": "Dark",
"light": "Light",
"system": "Automatic",
"changeTheme": "Change Color Scheme"
},
"errorPage": {
"title": "This is a little embarrassing...",
"description1": "We are really sorry but an error occurred in the web client that caused it to crash. <br /> This is not supposed to happen, and we are working hard to fix it.",
"description2": "The best way to prevent this from happening again to you or anyone else is to report the issue to us.",
"reportInstructions": "Please include the following information in your report:",
"reportSteps": {
"step1": "What you were doing when the error occurred",
"step2": "What you expected to happen",
"step3": "What actually happened",
"step4": "Any other relevant information"
},
"reportLink": "You can report the issue to our <0>GitHub</0>",
"dashboardLink": "Return to the <0>dashboard</0>",
"detailsSummary": "Error Details",
"errorMessageLabel": "Error message:",
"stackTraceLabel": "Stack trace:",
"fallbackError": "{{error}}"
},
"footer": {
"text": "Powered by <0>▲ Vercel</0> | Meshtastic® is a registered trademark of Meshtastic LLC. | <1>Legal Information</1>",
"commitSha": "Commit SHA: {{sha}}"
}
"navigation": {
"title": "Navigation",
"messages": "Messages",
"map": "Map",
"settings": "Settings",
"channels": "Channels",
"radioConfig": "Radio Config",
"deviceConfig": "Device Config",
"moduleConfig": "Module Config",
"manageConnections": "Manage Connections",
"nodes": "Nodes"
},
"app": {
"title": "Meshtastic",
"logo": "Meshtastic Logo"
},
"sidebar": {
"collapseToggle": {
"button": {
"open": "Open sidebar",
"close": "Close sidebar"
}
},
"deviceInfo": {
"volts": "{{voltage}} volts",
"firmware": {
"title": "Firmware",
"version": "v{{version}}",
"buildDate": "Build date: {{date}}"
}
}
},
"batteryStatus": {
"charging": "{{level}}% charging",
"pluggedIn": "Plugged in",
"title": "Battery"
},
"search": {
"nodes": "Search nodes...",
"channels": "Search channels...",
"commandPalette": "Search commands..."
},
"toast": {
"positionRequestSent": {
"title": "Position request sent."
},
"requestingPosition": {
"title": "Requesting position, please wait..."
},
"sendingTraceroute": {
"title": "Sending Traceroute, please wait..."
},
"tracerouteSent": {
"title": "Traceroute sent."
},
"savedChannel": {
"title": "Saved Channel: {{channelName}}"
},
"messages": {
"pkiEncryption": {
"title": "Chat is using PKI encryption."
},
"pskEncryption": {
"title": "Chat is using PSK encryption."
}
},
"configSaveError": {
"title": "Error Saving Config",
"description": "An error occurred while saving the configuration."
},
"validationError": {
"title": "Config Errors Exist",
"description": "Please fix the configuration errors before saving."
},
"saveSuccess": {
"title": "Saving Config",
"description": "The configuration change {{case}} has been saved."
},
"saveAllSuccess": {
"title": "Saved",
"description": "All configuration changes have been saved."
},
"favoriteNode": {
"title": "{{action}} {{nodeName}} {{direction}} favorites.",
"action": {
"added": "Added",
"removed": "Removed",
"to": "to",
"from": "from"
}
},
"ignoreNode": {
"title": "{{action}} {{nodeName}} {{direction}} ignore list",
"action": {
"added": "Added",
"removed": "Removed",
"to": "to",
"from": "from"
}
}
},
"notifications": {
"copied": {
"label": "Copied!"
},
"copyToClipboard": {
"label": "Copy to clipboard"
},
"hidePassword": {
"label": "Hide password"
},
"showPassword": {
"label": "Show password"
},
"deliveryStatus": {
"delivered": "Delivered",
"failed": "Delivery Failed",
"waiting": "Waiting",
"unknown": "Unknown"
}
},
"general": {
"label": "General"
},
"hardware": {
"label": "Hardware"
},
"metrics": {
"label": "Metrics"
},
"role": {
"label": "Role"
},
"filter": {
"label": "Filter"
},
"advanced": {
"label": "Advanced"
},
"clearInput": {
"label": "Clear input"
},
"resetFilters": {
"label": "Reset Filters"
},
"nodeName": {
"label": "Node name/number",
"placeholder": "Meshtastic 1234"
},
"airtimeUtilization": {
"label": "Airtime Utilization (%)",
"short": "Airtime Util. (%)"
},
"batteryLevel": {
"label": "Battery level (%)",
"labelText": "Battery level (%): {{value}}"
},
"batteryVoltage": {
"label": "Battery voltage (V)",
"title": "Voltage"
},
"channelUtilization": {
"label": "Channel Utilization (%)",
"short": "Channel Util. (%)"
},
"hops": {
"direct": "Direct",
"label": "Number of hops",
"text": "Number of hops: {{value}}"
},
"lastHeard": {
"label": "Last heard",
"labelText": "Last heard: {{value}}",
"nowLabel": "Now"
},
"snr": {
"label": "SNR (db)"
},
"favorites": {
"label": "Favorites"
},
"hide": {
"label": "Hide"
},
"showOnly": {
"label": "Show Only"
},
"viaMqtt": {
"label": "Connected via MQTT"
},
"hopsUnknown": {
"label": "Unknown number of hops"
},
"showUnheard": {
"label": "Never heard"
},
"language": {
"label": "Language",
"changeLanguage": "Change Language"
},
"theme": {
"dark": "Dark",
"light": "Light",
"system": "Automatic",
"changeTheme": "Change Color Scheme"
},
"errorPage": {
"title": "This is a little embarrassing...",
"description1": "We are really sorry but an error occurred in the web client that caused it to crash. <br /> This is not supposed to happen, and we are working hard to fix it.",
"description2": "The best way to prevent this from happening again to you or anyone else is to report the issue to us.",
"reportInstructions": "Please include the following information in your report:",
"reportSteps": {
"step1": "What you were doing when the error occurred",
"step2": "What you expected to happen",
"step3": "What actually happened",
"step4": "Any other relevant information"
},
"reportLink": "You can report the issue to our <0>GitHub</0>",
"connectionsLink": "Return to the <0>connections</0>",
"detailsSummary": "Error Details",
"errorMessageLabel": "Error message:",
"stackTraceLabel": "Stack trace:",
"fallbackError": "{{error}}"
},
"footer": {
"text": "Powered by <0>▲ Vercel</0> | Meshtastic® is a registered trademark of Meshtastic LLC. | <1>Legal Information</1>",
"commitSha": "Commit SHA: {{sha}}"
}
}

View File

@@ -1,69 +1,71 @@
{
"page": {
"sectionLabel": "Канали",
"channelName": "Канал: {{channelName}}",
"broadcastLabel": "Първичен",
"channelIndex": "Ch {{index}}"
},
"validation": {
"pskInvalid": "Моля, въведете валиден {{bits}} bit PSK."
},
"settings": {
"label": "Настройки на канала",
"description": "Крипто, MQTT и други настройки"
},
"role": {
"label": "Роля",
"description": "Телеметрията на устройството се изпраща през ПЪРВИЧЕН. Разрешен е само един ПЪРВИЧЕН.",
"options": {
"primary": "ПЪРВИЧЕН",
"disabled": "ДЕЗАКТИВИРАН",
"secondary": "ВТОРИЧЕН"
}
},
"psk": {
"label": "Предварително споделен ключ",
"description": "Поддържани дължини на PSK: 256-битова, 128-битова, 8-битова, празна (0-битова)",
"generate": "Генериране"
},
"name": {
"label": "Име",
"description": "Уникално име за канала <12 байта, оставете празно за подразбиране"
},
"uplinkEnabled": {
"label": "Uplink Enabled",
"description": "Изпращане на съобщения от локалната mesh към MQTT"
},
"downlinkEnabled": {
"label": "Downlink Enabled",
"description": "Изпращане на съобщения от MQTT към локалната mesh"
},
"positionPrecision": {
"label": "Местоположение",
"description": "Точността на местоположението, което да се споделя с канала. Може да бъде дезактивирано.",
"options": {
"none": "Да не се споделя местоположението",
"precise": "Точно местоположение",
"metric_km23": "В рамките на 23 километра",
"metric_km12": "В рамките на 12 километра",
"metric_km5_8": "В рамките на 5.8 километра",
"metric_km2_9": "В рамките на 2.9 километра",
"metric_km1_5": "В рамките на 1.5 километра",
"metric_m700": "В рамките на 700 метра",
"metric_m350": "В рамките на 350 метра",
"metric_m200": "В рамките на 200 метра",
"metric_m90": "В рамките на 90 метра",
"metric_m50": "В рамките на 50 метра",
"imperial_mi15": "В рамките на 15 мили",
"imperial_mi7_3": "В рамките на 7.3 мили",
"imperial_mi3_6": "В рамките на 3.6 мили",
"imperial_mi1_8": "В рамките на 1.8 мили",
"imperial_mi0_9": "В рамките на 0.9 мили",
"imperial_mi0_5": "В рамките на 0.5 мили",
"imperial_mi0_2": "В рамките на 0.2 мили",
"imperial_ft600": "В рамките на 600 фута",
"imperial_ft300": "В рамките на 300 фута",
"imperial_ft150": "В рамките на 150 фута"
}
}
"page": {
"sectionLabel": "Канали",
"channelName": "Канал: {{channelName}}",
"broadcastLabel": "Първичен",
"channelIndex": "К {{index}}",
"import": "Импортиране",
"export": "Експортиране"
},
"validation": {
"pskInvalid": "Моля, въведете валиден {{bits}} bit PSK."
},
"settings": {
"label": "Настройки на канала",
"description": "Крипто, MQTT и други настройки"
},
"role": {
"label": "Роля",
"description": "Телеметрията на устройството се изпраща през ПЪРВИЧЕН. Разрешен е само един ПЪРВИЧЕН.",
"options": {
"primary": "ПЪРВИЧЕН",
"disabled": "ДЕЗАКТИВИРАН",
"secondary": "ВТОРИЧЕН"
}
},
"psk": {
"label": "Предварително споделен ключ",
"description": "Поддържани дължини на PSK: 256-битова, 128-битова, 8-битова, празна (0-битова)",
"generate": "Генериране"
},
"name": {
"label": "Име",
"description": "Уникално име за канала <12 байта, оставете празно за подразбиране"
},
"uplinkEnabled": {
"label": "Uplink е активиран",
"description": "Изпращане на съобщения от локалната mesh към MQTT"
},
"downlinkEnabled": {
"label": "Downlink е активиран",
"description": "Изпращане на съобщения от MQTT към локалната mesh"
},
"positionPrecision": {
"label": "Местоположение",
"description": "Точността на местоположението, което да се споделя с канала. Може да бъде дезактивирано.",
"options": {
"none": "Да не се споделя местоположението",
"precise": "Точно местоположение",
"metric_km23": "В рамките на 23 километра",
"metric_km12": "В рамките на 12 километра",
"metric_km5_8": "В рамките на 5.8 километра",
"metric_km2_9": "В рамките на 2.9 километра",
"metric_km1_5": "В рамките на 1.5 километра",
"metric_m700": "В рамките на 700 метра",
"metric_m350": "В рамките на 350 метра",
"metric_m200": "В рамките на 200 метра",
"metric_m90": "В рамките на 90 метра",
"metric_m50": "В рамките на 50 метра",
"imperial_mi15": "В рамките на 15 мили",
"imperial_mi7_3": "В рамките на 7.3 мили",
"imperial_mi3_6": "В рамките на 3.6 мили",
"imperial_mi1_8": "В рамките на 1.8 мили",
"imperial_mi0_9": "В рамките на 0.9 мили",
"imperial_mi0_5": "В рамките на 0.5 мили",
"imperial_mi0_2": "В рамките на 0.2 мили",
"imperial_ft600": "В рамките на 600 фута",
"imperial_ft300": "В рамките на 300 фута",
"imperial_ft150": "В рамките на 150 фута"
}
}
}

View File

@@ -15,7 +15,6 @@
"messages": "Съобщения",
"map": "Карта",
"config": "Конфигурация",
"channels": "Канали",
"nodes": "Възли"
}
},
@@ -45,7 +44,8 @@
"label": "Отстраняване на грешки",
"command": {
"reconfigure": "Преконфигуриране",
"clearAllStoredMessages": "Изчистване на всички съхранени съобщения"
"clearAllStoredMessages": "Изчистване на всички съхранени съобщения",
"clearAllStores": "Clear All Local Storage"
}
}
}

View File

@@ -1,142 +1,165 @@
{
"button": {
"apply": "Приложи",
"backupKey": "Резервно копие на ключа",
"cancel": "Отказ",
"clearMessages": "Изчистване на съобщенията",
"close": "Затвори",
"confirm": "Потвърждаване",
"delete": "Изтриване",
"dismiss": "Отхвърляне",
"download": "Изтегляне",
"export": "Експортиране",
"generate": "Генериране",
"regenerate": "Регенериране",
"import": "Импортиране",
"message": "Съобщение",
"now": "Сега",
"ok": "Добре",
"print": "Отпечатване",
"remove": "Изтрий",
"requestNewKeys": "Заявка за нови ключове",
"requestPosition": "Request Position",
"reset": "Нулиране",
"save": "Запис",
"scanQr": "Сканиране на QR кода",
"traceRoute": "Trace Route",
"submit": "Изпращане"
},
"app": {
"title": "Meshtastic",
"fullTitle": "Meshtastic Web клиент"
},
"loading": "Зареждане...",
"unit": {
"cps": "CPS",
"dbm": "dBm",
"hertz": "Hz",
"hop": {
"one": "Хоп",
"plural": "Хопа"
},
"hopsAway": {
"one": "{{count}} hop away",
"plural": "{{count}} hops away",
"unknown": "Unknown hops away"
},
"megahertz": "MHz",
"raw": "raw",
"meter": {
"one": "Метър",
"plural": "Метри",
"suffix": "m"
},
"minute": {
"one": "Минута",
"plural": "Минути"
},
"hour": {
"one": "Час",
"plural": "Часа"
},
"millisecond": {
"one": "Милисекунда",
"plural": "Милисекунди",
"suffix": "ms"
},
"second": {
"one": "Секунда",
"plural": "Секунди"
},
"day": {
"one": "Ден",
"plural": "Дни"
},
"month": {
"one": "Месец",
"plural": "Месеца"
},
"year": {
"one": "Година",
"plural": "Години"
},
"snr": "SNR",
"volt": {
"one": "Волт",
"plural": "Волта",
"suffix": "V"
},
"record": {
"one": "Записи",
"plural": "Записи"
}
},
"security": {
"0bit": "Празен",
"8bit": "8 bit",
"128bit": "128 bit",
"256bit": "256 bit"
},
"unknown": {
"longName": "Неизвестно",
"shortName": "НЕИЗВ.",
"notAvailable": "N/A",
"num": "??"
},
"nodeUnknownPrefix": "!",
"unset": "НЕЗАДАДЕН",
"fallbackName": "Meshtastic {{last4}}",
"node": "Възел",
"formValidation": {
"unsavedChanges": "Незапазени промени",
"tooBig": {
"string": "Твърде дълъг, очаква се по-малко или равно на {{maximum}} знака.",
"number": "Твърде голям, очаква се число по-малко или равно на {{maximum}}.",
"bytes": "Твърде голям, очаква се по-малък или равен на {{params.maximum}} байта."
},
"tooSmall": {
"string": "Твърде кратък, очаква се повече или равно на {{minimum}} знака.",
"number": "Твърде малък, очаква се число, по-голямо или равно на {{minimum}}."
},
"invalidFormat": {
"ipv4": "Невалиден формат, очаква се IPv4 адрес.",
"key": "Невалиден формат, очаква се предварително споделен ключ (PSK), кодиран с Base64."
},
"invalidType": {
"number": "Невалиден тип, очаква се число."
},
"pskLength": {
"0bit": "Ключът трябва да е празен.",
"8bit": "Ключът трябва да бъде 8-битов предварително споделен ключ (PSK).",
"128bit": "Ключът трябва да бъде 128-битов предварително споделен ключ (PSK).",
"256bit": "Ключът трябва да бъде 256-битов предварително споделен ключ (PSK)."
},
"required": {
"generic": "Това поле е задължително.",
"managed": "Изисква се поне един администраторски ключ, ако възелът е управляван.",
"key": "Ключът е задължителен."
}
},
"yes": "Да",
"no": "Не"
"button": {
"apply": "Приложи",
"addConnection": "Добавяне на връзка",
"saveConnection": "Запазване на връзката",
"backupKey": "Резервно копие на ключа",
"cancel": "Отказ",
"connect": "Свързване",
"clearMessages": "Изчистване на съобщенията",
"close": "Затвори",
"confirm": "Потвърждаване",
"delete": "Изтриване",
"dismiss": "Отхвърляне",
"download": "Изтегляне",
"disconnect": "Прекъсване на връзката",
"export": "Експортиране",
"generate": "Генериране",
"regenerate": "Регенериране",
"import": "Импортиране",
"message": "Съобщение",
"now": "Сега",
"ok": "Добре",
"print": "Отпечатване",
"remove": "Изтрий",
"requestNewKeys": "Заявка за нови ключове",
"requestPosition": "Request Position",
"reset": "Нулиране",
"retry": "Retry",
"save": "Запис",
"setDefault": "Задаване по подразбиране",
"unsetDefault": "Unset default",
"scanQr": "Сканиране на QR кода",
"traceRoute": "Trace Route",
"submit": "Изпращане"
},
"app": {
"title": "Meshtastic",
"fullTitle": "Meshtastic Web клиент"
},
"loading": "Зареждане...",
"unit": {
"cps": "CPS",
"dbm": "dBm",
"hertz": "Hz",
"hop": {
"one": "Хоп",
"plural": "Хопа"
},
"hopsAway": {
"one": "{{count}} hop away",
"plural": "{{count}} hops away",
"unknown": "Unknown hops away"
},
"megahertz": "MHz",
"kilohertz": "kHz",
"raw": "raw",
"meter": {
"one": "Метър",
"plural": "Метри",
"suffix": "m"
},
"kilometer": {
"one": "Километър",
"plural": "Километри",
"suffix": "км"
},
"minute": {
"one": "Минута",
"plural": "Минути"
},
"hour": {
"one": "Час",
"plural": "Часа"
},
"millisecond": {
"one": "Милисекунда",
"plural": "Милисекунди",
"suffix": "ms"
},
"second": {
"one": "Секунда",
"plural": "Секунди"
},
"day": {
"one": "Ден",
"plural": "Дни",
"today": "Днес",
"yesterday": "Вчера"
},
"month": {
"one": "Месец",
"plural": "Месеца"
},
"year": {
"one": "Година",
"plural": "Години"
},
"snr": "SNR",
"volt": {
"one": "Волт",
"plural": "Волта",
"suffix": "V"
},
"record": {
"one": "Записи",
"plural": "Записи"
},
"degree": {
"one": "Градус",
"plural": "Градуса",
"suffix": "°"
}
},
"security": {
"0bit": разен",
"8bit": "8 bit",
"128bit": "128 bit",
"256bit": "256 bit"
},
"unknown": {
"longName": "Неизвестно",
"shortName": "НЕИЗВ.",
"notAvailable": "N/A",
"num": "??"
},
"nodeUnknownPrefix": "!",
"unset": "НЕЗАДАДЕН",
"fallbackName": "Meshtastic {{last4}}",
"node": "Възел",
"formValidation": {
"unsavedChanges": "Незапазени промени",
"tooBig": {
"string": "Твърде дълъг, очаква се по-малко или равно на {{maximum}} знака.",
"number": "Твърде голям, очаква се число по-малко или равно на {{maximum}}.",
"bytes": "Твърде голям, очаква се по-малък или равен на {{params.maximum}} байта."
},
"tooSmall": {
"string": "Твърде кратък, очаква се повече или равно на {{minimum}} знака.",
"number": "Твърде малък, очаква се число, по-голямо или равно на {{minimum}}."
},
"invalidFormat": {
"ipv4": "Невалиден формат, очаква се IPv4 адрес.",
"key": "Невалиден формат, очаква се предварително споделен ключ (PSK), кодиран с Base64."
},
"invalidType": {
"number": "Невалиден тип, очаква се число."
},
"pskLength": {
"0bit": "Ключът трябва да е празен.",
"8bit": "Ключът трябва да бъде 8-битов предварително споделен ключ (PSK).",
"128bit": "Ключът трябва да бъде 128-битов предварително споделен ключ (PSK).",
"256bit": "Ключът трябва да бъде 256-битов предварително споделен ключ (PSK)."
},
"required": {
"generic": "Това поле е задължително.",
"managed": "Изисква се поне един администраторски ключ, ако възелът е управляван.",
"key": "Ключът е задължителен."
},
"invalidOverrideFreq": {
"number": "Невалиден формат, очаквана е стойност в диапазона 410-930 MHz или 0 (използвайте стойността по подразбиране)."
}
},
"yes": "Да",
"no": "Не"
}

View File

@@ -0,0 +1,458 @@
{
"page": {
"title": "Настройки",
"tabUser": "Потребител",
"tabChannels": "Канали",
"tabBluetooth": "Bluetooth",
"tabDevice": "Устройство",
"tabDisplay": "Дисплей",
"tabLora": "LoRa",
"tabNetwork": "Мрежа",
"tabPosition": "Позиция",
"tabPower": "Захранване",
"tabSecurity": "Сигурност"
},
"sidebar": {
"label": "Конфигурация"
},
"device": {
"title": "Настройки на устройството",
"description": "Настройки за устройството",
"buttonPin": {
"description": "Button pin override",
"label": "Пин за бутон"
},
"buzzerPin": {
"description": "Buzzer pin override",
"label": "Пин за зумер"
},
"disableTripleClick": {
"description": "Дезактивиране на трикратното щракване",
"label": "Дезактивиране на трикратното щракване"
},
"doubleTapAsButtonPress": {
"description": "Treat double tap as button press",
"label": "Double Tap as Button Press"
},
"ledHeartbeatDisabled": {
"description": "Дезактивиране на мигащия светодиод по подразбиране",
"label": "LED Heartbeat Disabled"
},
"nodeInfoBroadcastInterval": {
"description": "How often to broadcast node info",
"label": "Node Info Broadcast Interval"
},
"posixTimezone": {
"description": "The POSIX timezone string for the device",
"label": "POSIX часова зона"
},
"rebroadcastMode": {
"description": "How to handle rebroadcasting",
"label": "Режим на препредаване"
},
"role": {
"description": "Каква роля изпълнява устройството в mesh",
"label": "Роля"
}
},
"bluetooth": {
"title": "Настройки за Bluetooth",
"description": "Настройки за Bluetooth модула",
"note": "Забележка: Някои устройства (ESP32) не могат да използват едновременно Bluetooth и WiFi.",
"enabled": {
"description": "Активиране или дезактивиране на Bluetooth",
"label": "Активиран"
},
"pairingMode": {
"description": "Поведение при избор на ПИН.",
"label": "Режим на сдвояване"
},
"pin": {
"description": "Pin to use when pairing",
"label": "ПИН"
}
},
"display": {
"description": "Настройки за дисплея на устройството",
"title": "Настройки на дисплея",
"headingBold": {
"description": "Bolden the heading text",
"label": "Удебелен заглавен шрифт"
},
"carouselDelay": {
"description": "Колко бързо да се превключва между прозорците",
"label": "Carousel Delay"
},
"compassNorthTop": {
"description": "Фиксиране на север към горната част на компаса",
"label": "Север на компаса отгоре"
},
"displayMode": {
"description": "Screen layout variant",
"label": "Display Mode"
},
"displayUnits": {
"description": "Показване на метрични или имперски мерни единици",
"label": "Display Units"
},
"flipScreen": {
"description": "Обръщане на дисплея на 180 градуса",
"label": "Обръщане на дисплея"
},
"gpsDisplayUnits": {
"description": "Coordinate display format",
"label": "GPS Display Units"
},
"oledType": {
"description": "Тип на OLED екрана, прикрепен към устройството",
"label": "Тип OLED"
},
"screenTimeout": {
"description": "Turn off the display after this long",
"label": "Screen Timeout"
},
"twelveHourClock": {
"description": "Използване на 12-часов формат на часовника",
"label": "12-часов часовник"
},
"wakeOnTapOrMotion": {
"description": "Събуждане на устройството при докосване или движение",
"label": "Събуждане при докосване или движение"
}
},
"lora": {
"title": "Настройки на Mesh",
"description": "Настройки за LoRa mesh",
"bandwidth": {
"description": "Широчина на канала в kHz",
"label": "Широчина на честотната лента"
},
"boostedRxGain": {
"description": "Boosted RX gain",
"label": "Boosted RX Gain"
},
"codingRate": {
"description": "The denominator of the coding rate",
"label": "Coding Rate"
},
"frequencyOffset": {
"description": "Frequency offset to correct for crystal calibration errors",
"label": "Отместване на честотата"
},
"frequencySlot": {
"description": "Номер на LoRa честотен канал",
"label": "Честотен слот"
},
"hopLimit": {
"description": "Максимален брой хопове",
"label": "Лимит на хопове"
},
"ignoreMqtt": {
"description": "Да не се препращат MQTT съобщения през mesh",
"label": "Игнориране на MQTT"
},
"modemPreset": {
"description": "Използване на предварително настроен модем",
"label": "Предварително настроен модем"
},
"okToMqtt": {
"description": "When set to true, this configuration indicates that the user approves the packet to be uploaded to MQTT. If set to false, remote nodes are requested not to forward packets to MQTT",
"label": "OK to MQTT"
},
"overrideDutyCycle": {
"description": "Override Duty Cycle",
"label": "Override Duty Cycle"
},
"overrideFrequency": {
"description": "Override frequency",
"label": "Override Frequency"
},
"region": {
"description": "Задаване на региона за вашия възел",
"label": "Регион"
},
"spreadingFactor": {
"description": "Indicates the number of chirps per symbol",
"label": "Spreading Factor"
},
"transmitEnabled": {
"description": "Активиране/дезактивиране на предаването (TX) от LoRa радиото",
"label": "Предаването е активирано"
},
"transmitPower": {
"description": "Максимална мощност на предаване",
"label": "Мощност на предаване"
},
"usePreset": {
"description": "Използване на една от предварително зададените настройки на модема",
"label": "Използване на предварително зададени настройки"
},
"meshSettings": {
"description": "Настройки за LoRa mesh",
"label": "Настройки на Mesh"
},
"waveformSettings": {
"description": "Settings for the LoRa waveform",
"label": "Waveform Settings"
},
"radioSettings": {
"label": "Настройки на радиото",
"description": "Настройки за LoRa радиото"
}
},
"network": {
"title": "Конфигурация на WiFi",
"description": "Конфигурация на WiFi радиото",
"note": "Забележка: Някои устройства (ESP32) не могат да използват едновременно Bluetooth и WiFi.",
"addressMode": {
"description": "Address assignment selection",
"label": "Режим на адреса"
},
"dns": {
"description": "DNS сървър",
"label": "DNS"
},
"ethernetEnabled": {
"description": "Активиране или дезактивиране на Ethernet порта",
"label": "Активиран"
},
"gateway": {
"description": "Шлюз по подразбиране",
"label": "Шлюз"
},
"ip": {
"description": "IP адрес",
"label": "IP"
},
"psk": {
"description": "Парола за мрежата",
"label": "PSK"
},
"ssid": {
"description": "Име на мрежата",
"label": "SSID"
},
"subnet": {
"description": "Подмрежова маска",
"label": "Подмрежа"
},
"wifiEnabled": {
"description": "Активиране или дезактивиране на WiFi радиото",
"label": "Активиран"
},
"meshViaUdp": {
"label": "Mesh чрез UDP"
},
"ntpServer": {
"label": "NTP сървър"
},
"rsyslogServer": {
"label": "Сървър Rsyslog"
},
"ethernetConfigSettings": {
"description": "Конфигуриране на Ethernet порта",
"label": "Конфигурация на Ethernet "
},
"ipConfigSettings": {
"description": "Конфигуриране на IP",
"label": "Конфигурация на IP"
},
"ntpConfigSettings": {
"description": "Конфигуриране на NTP",
"label": "Конфигурация на NTP"
},
"rsyslogConfigSettings": {
"description": "Конфигуриране на Rsyslog",
"label": "Конфиг. на Rsyslog"
},
"udpConfigSettings": {
"description": "Конфигуриране на UDP през Mesh",
"label": "Конфигуриране на UDP"
}
},
"position": {
"title": "Настройки на позицията",
"description": "Настройки за модула за позиция",
"broadcastInterval": {
"description": "How often your position is sent out over the mesh",
"label": "Интервал на излъчване"
},
"enablePin": {
"description": "GPS module enable pin override",
"label": "Активиране на пин"
},
"fixedPosition": {
"description": "Да не се докладва GPS позиция, а ръчно зададена такава",
"label": "Фиксирана позиция"
},
"gpsMode": {
"description": "Конфигуриране дали GPS на устройството е активиран, деактивиран или липсва",
"label": "Режим на GPS"
},
"gpsUpdateInterval": {
"description": "Колко често трябва да се получава GPS сигнал",
"label": "Интервал на актуализиране на GPS"
},
"positionFlags": {
"description": "Optional fields to include when assembling position messages. The more fields are selected, the larger the message will be leading to longer airtime usage and a higher risk of packet loss.",
"label": "Position Flags"
},
"receivePin": {
"description": "GPS module RX pin override",
"label": "Receive Pin"
},
"smartPositionEnabled": {
"description": "Only send position when there has been a meaningful change in location",
"label": "Enable Smart Position"
},
"smartPositionMinDistance": {
"description": "Минималното разстояние (в метри), което трябва да се измине, преди да се изпрати актуализация на местоположението",
"label": "Минимално разстояние за интелигентна позиция"
},
"smartPositionMinInterval": {
"description": "Minimum interval (in seconds) that must pass before a position update is sent",
"label": "Smart Position Minimum Interval"
},
"transmitPin": {
"description": "GPS module TX pin override",
"label": "Transmit Pin"
},
"intervalsSettings": {
"description": "Колко често да се изпращат актуализации на позицията",
"label": "Интервали"
},
"flags": {
"placeholder": "Select position flags...",
"altitude": "Надморска височина",
"altitudeGeoidalSeparation": "Altitude Geoidal Separation",
"altitudeMsl": "Altitude is Mean Sea Level",
"dop": "Dilution of precision (DOP) PDOP used by default",
"hdopVdop": "If DOP is set, use HDOP / VDOP values instead of PDOP",
"numSatellites": "Брой сателити",
"sequenceNumber": "Пореден номер",
"timestamp": "Времево клеймо",
"unset": "Не е зададен",
"vehicleHeading": "Посока на движение на превозното средство",
"vehicleSpeed": "Скорост на превозното средство"
}
},
"power": {
"adcMultiplierOverride": {
"description": "Използва се за настройване на отчитането на напрежението на батерията",
"label": "ADC Multiplier Override ratio"
},
"ina219Address": {
"description": "Address of the INA219 battery monitor",
"label": "INA219 адрес"
},
"lightSleepDuration": {
"description": "Колко дълго устройството ще бъде в лек сън",
"label": "Продължителност на лекия сън"
},
"minimumWakeTime": {
"description": "Минималното време, през което устройството ще остане активно след получаване на пакет",
"label": "Минимално време за събуждане"
},
"noConnectionBluetoothDisabled": {
"description": "If the device does not receive a Bluetooth connection, the BLE radio will be disabled after this long",
"label": "Няма връзка Bluetooth е дезактивиран"
},
"powerSavingEnabled": {
"description": "Изберете, ако се захранва от източник с малък ток (напр. слънчева енергия), за да се намали максимално консумацията на енергия.",
"label": "Активиране на енергоспестяващ режим"
},
"shutdownOnBatteryDelay": {
"description": "Automatically shutdown node after this long when on battery, 0 for indefinite",
"label": "Shutdown on battery delay"
},
"superDeepSleepDuration": {
"description": "Колко дълго устройството ще бъде в супер дълбок сън",
"label": "Продължителност на супер дълбокия сън"
},
"powerConfigSettings": {
"description": "Настройки за захранващия модул",
"label": "Конфигуриране на захранването"
},
"sleepSettings": {
"description": "Настройки за спящ режим за захранващия модул",
"label": "Настройки за сън"
}
},
"security": {
"description": "Настройки за конфигурацията за сигурност",
"title": "Насртойки на сигурността",
"button_backupKey": "Резервно копие на ключа",
"adminChannelEnabled": {
"description": "Allow incoming device control over the insecure legacy admin channel",
"label": "Allow Legacy Admin"
},
"enableDebugLogApi": {
"description": "Output live debug logging over serial, view and export position-redacted device logs over Bluetooth",
"label": "Enable Debug Log API"
},
"managed": {
"description": "Ако е активирана, опциите за конфигурация на устройството могат да се променят дистанционно само от възел за отдалечено администриране чрез администраторски съобщения. Не активирайте тази опция, освен ако не е настроен поне един подходящ възел за отдалечено администриране и публичният ключ е съхранен в едно от полетата по-горе.",
"label": "Управлява се"
},
"privateKey": {
"description": "Използва се за създаване на споделен ключ с отдалечено устройство",
"label": "Частен ключ"
},
"publicKey": {
"description": "Изпраща се до други възли в mesh, за да им позволи да изчислят споделения секретен ключ",
"label": "Публичен ключ"
},
"primaryAdminKey": {
"description": "Основният публичен ключ, оторизиран за изпращане на администраторски съобщения до този възел",
"label": "Основен администраторски ключ"
},
"secondaryAdminKey": {
"description": "Вторичният публичен ключ, оторизиран за изпращане на администраторски съобщения до този възел.",
"label": "Вторичен администраторски ключ"
},
"serialOutputEnabled": {
"description": "Serial Console over the Stream API",
"label": "Serial Output Enabled"
},
"tertiaryAdminKey": {
"description": "Третичният публичен ключ, оторизиран за изпращане на администраторски съобщения до този възел",
"label": "Третичен администраторски ключ"
},
"adminSettings": {
"description": "Настройки за Admin",
"label": "Администраторски настройки"
},
"loggingSettings": {
"description": "Settings for Logging",
"label": "Logging Settings"
}
},
"user": {
"title": "User Settings",
"description": "Configure your device name and identity settings",
"longName": {
"label": "Дълго име",
"description": "Your full display name (1-40 characters)",
"validation": {
"min": "Long name must be at least 1 character",
"max": "Long name must be at most 40 characters"
}
},
"shortName": {
"label": "Кратко име",
"description": "Your abbreviated name (2-4 characters)",
"validation": {
"min": "Short name must be at least 2 characters",
"max": "Short name must be at most 4 characters"
}
},
"isUnmessageable": {
"label": "Без съобщения",
"description": "Used to identify unmonitored or infrastructure nodes so that messaging is not available to nodes that will never respond."
},
"isLicensed": {
"label": "Лицензиран радиолюбител (HAM)",
"description": "Enable if you are a licensed amateur radio operator, enabling this option disables encryption and is not compatible with the default Meshtastic network."
}
}
}

View File

@@ -0,0 +1,34 @@
{
"page": {
"title": "Свързване с устройство Meshtastic",
"description": "Добавете връзка с устройството чрез HTTP, Bluetooth или сериен порт. Запазените ви връзки ще бъдат запазени във вашия браузър."
},
"connectionType_ble": "BLE",
"connectionType_serial": "Серийна",
"connectionType_network": "Мрежа",
"deleteConnection": "Изтриване на връзката",
"areYouSure": "Това ще премахне {{name}}. Не можете да отмените това действие.",
"moreActions": "Още действия",
"noConnections": {
"title": "Все още няма връзки.",
"description": "Създайте първата си връзка. Тя ще се свърже веднага и ще бъде запазена за по-късно."
},
"lastConnectedAt": "Последно свързване: {{date}}",
"neverConnected": "Никога не е бил свързан",
"toasts": {
"connected": "Свързано",
"nowConnected": "{{name}} е свързан сега",
"nowDisconnected": "{{name}} are now disconnecte",
"disconnected": "Прекъсната връзка",
"failed": "Свързването не е успешно",
"checkConnetion": "Проверете устройството или настройките си и опитайте отново",
"defaultSet": "Default set",
"defaultConnection": "Default connection is now {{nameisconnected}}",
"deleted": "Изтрит",
"deletedByName": "{{name}} беше премахнат",
"pickConnectionAgain": "Не можа да се свърже. Може да се наложи да изберете отново устройството/порта.",
"added": "Връзката е добавена",
"savedByName": "{{name}} е запазен.",
"savedCantConnect": "Връзката беше запазена, но не можа да се осъществи свързване."
}
}

View File

@@ -1,12 +0,0 @@
{
"dashboard": {
"title": "Свързани устройства",
"description": "Управлявайте свързаните си устройства Meshtastic.",
"connectionType_ble": "BLE",
"connectionType_serial": "Серийна",
"connectionType_network": "Мрежа",
"noDevicesTitle": "Няма свързани устройства",
"noDevicesDescription": "Свържете ново устройство, за да започнете.",
"button_newConnection": "Нова връзка"
}
}

View File

@@ -122,7 +122,7 @@
"title": "Настройки на Mesh",
"description": "Настройки за LoRa mesh",
"bandwidth": {
"description": "Широчина на канала в MHz",
"description": "Широчина на канала в kHz",
"label": "Широчина на честотната лента"
},
"boostedRxGain": {

View File

@@ -1,193 +1,238 @@
{
"deleteMessages": {
"description": "Това действие ще изчисти цялата история на съобщенията. Това не може да бъде отменено. Сигурни ли сте, че искате да продължите?",
"title": "Изчистване на всички съобщения"
},
"deviceName": {
"description": "Устройството ще се рестартира, след като конфигурацията бъде запазена.",
"longName": "Дълго име",
"shortName": "Кратко име",
"title": "Промяна на името на устройството",
"validation": {
"longNameMax": "Дългото име не трябва да е повече от 40 знака",
"shortNameMax": "Краткото име не трябва да е повече от 4 знака",
"longNameMin": "Дългото име трябва да съдържа поне 1 символ",
"shortNameMin": "Краткото име трябва да съдържа поне 1 символ"
}
},
"import": {
"description": "Текущата конфигурация на LoRa ще бъде презаписана.",
"error": {
"invalidUrl": "Невалиден Meshtastic URL"
},
"channelPrefix": "Канал: ",
"channelSetUrl": "Channel Set/QR Code URL",
"channels": "Канали:",
"usePreset": "Използване на предварително зададени настройки?",
"title": "Import Channel Set"
},
"locationResponse": {
"title": "Местоположение: {{identifier}}",
"altitude": "Надморска височина: ",
"coordinates": "Координати:",
"noCoordinates": "Няма координати"
},
"pkiRegenerateDialog": {
"title": "Регенериране на предварително споделения ключ?",
"description": "Сигурни ли сте, че искате да регенерирате предварително споделения ключ?",
"regenerate": "Регенериране"
},
"newDeviceDialog": {
"title": "Свързване на ново устройство",
"https": "https",
"http": "http",
"tabHttp": "HTTP",
"tabBluetooth": "Bluetooth",
"tabSerial": "Серийна",
"useHttps": "Използване на HTTPS",
"connecting": "Свързване...",
"connect": "Свързване",
"connectionFailedAlert": {
"title": "Връзката е неуспешна",
"descriptionPrefix": "Не може да се свърже с устройството.",
"httpsHint": "Ако използвате HTTPS, може да се наложи първо да приемете самоподписан сертификат. ",
"openLinkPrefix": "Моля, отворете",
"openLinkSuffix": "в нов раздел",
"acceptTlsWarningSuffix": ", accept any TLS warnings if prompted, then try again",
"learnMoreLink": "Научете повече"
},
"httpConnection": {
"label": "IP адрес/Име на хост",
"placeholder": "000.000.000.000 / meshtastic.local"
},
"serialConnection": {
"noDevicesPaired": "Все още няма сдвоени устройства.",
"newDeviceButton": "Ново устройство",
"deviceIdentifier": "# {{index}} - {{vendorId}} - {{productId}}"
},
"bluetoothConnection": {
"noDevicesPaired": "Все още няма сдвоени устройства.",
"newDeviceButton": "Ново устройство",
"connectionFailed": "Връзката е неуспешна",
"deviceDisconnected": "Устройството не е свързано",
"unknownDevice": "Неизвестно устройство",
"errorLoadingDevices": "Грешка при зареждане на устройствата",
"unknownErrorLoadingDevices": "Неизвестна грешка при зареждане на устройствата"
},
"validation": {
"requiresWebBluetooth": "Този тип връзка изисква <0>Web Bluetooth</0>. Моля, използвайте поддържан браузър, като Chrome или Edge.",
"requiresWebSerial": "Този тип връзка изисква <0>Web Serial</0>. Моля, използвайте поддържан браузър, като Chrome или Edge.",
"requiresSecureContext": "Това приложение изисква <0>secure context</0>. Моля, свържете се чрез HTTPS или localhost.",
"additionallyRequiresSecureContext": "Освен това, изисква <0>secure context</0>. Моля, свържете се чрез HTTPS или localhost."
}
},
"nodeDetails": {
"message": "Съобщение",
"requestPosition": "Request Position",
"traceRoute": "Trace Route",
"airTxUtilization": "Air TX utilization",
"allRawMetrics": "All Raw Metrics:",
"batteryLevel": "Ниво на батерията",
"channelUtilization": "Използване на канала",
"details": "Подробности:",
"deviceMetrics": "Device Metrics:",
"hardware": "Хардуер: ",
"lastHeard": "Последно чут: ",
"nodeHexPrefix": "Node Hex: ",
"nodeNumber": "Номер на възела: ",
"position": "Позиция:",
"role": "Роля: ",
"uptime": "Време на работа: ",
"voltage": "Напрежение",
"title": "Подробности за възел за {{identifier}}",
"ignoreNode": "Игнориране на възела",
"removeNode": "Премахване на възела",
"unignoreNode": "Премахване на игнорирането на възела",
"security": "Сигурност:",
"publicKey": "Public Key: ",
"messageable": "Messageable: ",
"KeyManuallyVerifiedTrue": "Публичният ключ е проверен ръчно",
"KeyManuallyVerifiedFalse": "Публичният ключ не е проверен ръчно"
},
"pkiBackup": {
"loseKeysWarning": "Ако загубите ключовете си, ще трябва да нулирате устройството си.",
"secureBackup": "Важно е да направите резервно копие на публичните и частните си ключове и да съхранявате резервното си копие сигурно!",
"footer": "=== КРАЙ НА КЛЮЧОВЕТЕ ===",
"header": "=== MESHTASTIC КЛЮЧОВЕ ЗА {{longName}} ({{shortName}}) ===",
"privateKey": "Частен ключ:",
"publicKey": "Публичен ключ:",
"fileName": "meshtastic_keys_{{longName}}_{{shortName}}.txt",
"title": "Backup Keys"
},
"pkiBackupReminder": {
"description": "Препоръчваме редовно да правите резервни копия на данните с вашите ключове. Искате ли да направите резервно копие сега?",
"title": "Напомняне за резервно копие",
"remindLaterPrefix": "Напомни ми в",
"remindNever": "Никога не ми напомняй",
"backupNow": "Създаване на резервно копие сега"
},
"pkiRegenerate": {
"description": "Сигурни ли сте, че искате да регенерирате двойката ключове?",
"title": "Регенериране на двойката ключове"
},
"qr": {
"addChannels": "Добавяне на канали",
"replaceChannels": "Замяна на канали",
"description": "Текущата конфигурация на LoRa също ще бъде споделена.",
"sharableUrl": "Sharable URL",
"title": "Генериране на QR код"
},
"reboot": {
"title": "Рестартиране на устройството",
"description": "Reboot now or schedule a reboot of the connected node. Optionally, you can choose to reboot into OTA (Over-the-Air) mode.",
"ota": "Reboot into OTA mode",
"enterDelay": "Въведете забавяне",
"scheduled": "Насрочено е рестартиране",
"schedule": "Планиране на рестартиране",
"now": "Рестартиране сега",
"cancel": "Cancel scheduled reboot"
},
"refreshKeys": {
"description": {
"acceptNewKeys": "This will remove the node from device and request new keys.",
"keyMismatchReasonSuffix": ". This is due to the remote node's current public key does not match the previously stored key for this node.",
"unableToSendDmPrefix": "Your node is unable to send a direct message to node: "
},
"acceptNewKeys": "риемане на нови ключове",
"title": "Keys Mismatch - {{identifier}}"
},
"removeNode": {
"description": "Сигурни ли сте, че искате да премахнете този възел?",
"title": "Премахване на възела?"
},
"shutdown": {
"title": "Планирано изключване",
"description": "Изключване на свързания възел след x минути."
},
"traceRoute": {
"routeToDestination": "Route to destination:",
"routeBack": "Route back:"
},
"tracerouteResponse": {
"title": "Traceroute: {{identifier}}"
},
"unsafeRoles": {
"confirmUnderstanding": "Да, знам какво правя",
"conjunction": "и публикацията в блога за ",
"postamble": " и разберам последиците от промяната на ролята.",
"preamble": "Аз прочетох ",
"choosingRightDeviceRole": "Избор на правилната роля на устройството",
"deviceRoleDocumentation": "Документация за ролите на устройството",
"title": "Сигурни ли сте?"
},
"managedMode": {
"confirmUnderstanding": "Да, знам какво правя",
"title": "Сигурни ли сте?",
"description": "Enabling Managed Mode blocks client applications (including the web client) from writing configurations to a radio. Once enabled, radio configurations can only be changed through Remote Admin messages. This setting is not required for remote node administration."
},
"clientNotification": {
"title": "Client Notification",
"TraceRoute can only be sent once every 30 seconds": "TraceRoute can only be sent once every 30 seconds",
"Compromised keys were detected and regenerated.": "Бяха открити и регенерирани компрометирани ключове."
}
"deleteMessages": {
"description": "Това действие ще изчисти цялата история на съобщенията. Това не може да бъде отменено. Сигурни ли сте, че искате да продължите?",
"title": "Изчистване на всички съобщения"
},
"import": {
"description": "Текущата конфигурация на LoRa ще бъде презаписана.",
"error": {
"invalidUrl": "Невалиден Meshtastic URL"
},
"channelPrefix": "Канал: ",
"primary": "Първичен ",
"doNotImport": "No not import",
"channelName": "Име",
"channelSlot": "Слот",
"channelSetUrl": "Channel Set/QR Code URL",
"useLoraConfig": "Импортиране на конфигурация на LoRa",
"presetDescription": "Текущата конфигурация na LoRa ще бъде заменена.",
"title": "Import Channel Set"
},
"locationResponse": {
"title": "Местоположение: {{identifier}}",
"altitude": "Надморска височина: ",
"coordinates": "Координати:",
"noCoordinates": "Няма координати"
},
"pkiRegenerateDialog": {
"title": "Регенериране на предварително споделения ключ?",
"description": "Сигурни ли сте, че искате да регенерирате предварително споделения ключ?",
"regenerate": "Регенериране"
},
"addConnection": {
"title": "Добавяне на връзка",
"description": "Изберете тип връзка и попълнете данните",
"validation": {
"requiresWebBluetooth": "Този тип връзка изисква <0>Web Bluetooth</0>. Моля, използвайте поддържан браузър, като Chrome или Edge.",
"requiresWebSerial": "Този тип връзка изисква <0>Web Serial</0>. Моля, използвайте поддържан браузър, като Chrome или Edge.",
"requiresSecureContext": "Това приложение изисква <0>secure context</0>. Моля, свържете се чрез HTTPS или localhost.",
"additionallyRequiresSecureContext": "Освен това, изисква <0>secure context</0>. Моля, свържете се чрез HTTPS или localhost."
},
"bluetoothConnection": {
"namePlaceholder": "Моят Bluetooth възел",
"supported": {
"title": "Поддържа се Web Bluetooth"
},
"notSupported": {
"title": "Не се поддържа Web Bluetooth",
"description": "Вашият браузър или устройство не поддържа Web Bluetooth"
},
"short": "BT: {{deviceName}}",
"long": "Bluetooth устройство",
"device": "Устройство",
"selectDevice": "Изберете устройство",
"selected": "Избрано Bluetooth устройство",
"notSelected": "Няма избрано устройство",
"helperText": "Използва услугата Meshtastic Bluetooth за откриване."
},
"serialConnection": {
"namePlaceholder": "Моят сериен възел",
"helperText": "Selecting a port grants permission so the app can open it to connect.",
"supported": {
"title": "Web Serial supported"
},
"notSupported": {
"title": "Web Serial not supported",
"description": "Your browser or device does not support Web Serial"
},
"portSelected": {
"title": "Serial port selected",
"description": "Port permissions granted."
},
"port": "Порт",
"selectPort": "Изберете порт",
"deviceName": "USB {{vendorId}}:{{productId}}",
"notSelected": "Няма избран порт"
},
"httpConnection": {
"namePlaceholder": "Моят HTTP възел",
"inputPlaceholder": "192.168.1.10 или meshtastic.local",
"heading": "URL или IP",
"useHttps": "Използване на HTTPS",
"invalidUrl": {
"title": "Невалиден URL",
"description": "Моля, въведете валиден HTTP или HTTPS URL."
},
"connectionTest": {
"description": "Тествайте връзката, преди да я запазите, за да се уверите, че устройството е достъпно.",
"button": {
"loading": "Тестване...",
"label": "Тестване на връзката"
},
"reachable": "Достъпно",
"notReachable": "Не е достъпно",
"success": {
"title": "Тестът на връзката е успешен",
"description": "Устройството изглежда е достъпно."
},
"failure": {
"title": "Тестът на връзката не е успешен",
"description": "Не можа да се осъществи връзка с устройството. Проверете URL-а и опитайте отново."
}
}
}
},
"nodeDetails": {
"message": "Съобщение",
"requestPosition": "Request Position",
"traceRoute": "Trace Route",
"airTxUtilization": "Air TX utilization",
"allRawMetrics": "All Raw Metrics:",
"batteryLevel": "Ниво на батерията",
"channelUtilization": "Използване на канала",
"details": "Подробности:",
"deviceMetrics": "Device Metrics:",
"hardware": "Хардуер: ",
"lastHeard": "Последно чут: ",
"nodeHexPrefix": "Node Hex: ",
"nodeNumber": "Номер на възела: ",
"position": "Позиция:",
"role": "Роля: ",
"uptime": "Време на работа: ",
"voltage": "Напрежение",
"title": "Подробности за възел за {{identifier}}",
"ignoreNode": "Игнориране на възела",
"removeNode": "Премахване на възела",
"unignoreNode": "Премахване на игнорирането на възела",
"security": "Сигурност:",
"publicKey": "Публичен ключ:",
"messageable": "Messageable: ",
"KeyManuallyVerifiedTrue": "Публичният ключ е проверен ръчно",
"KeyManuallyVerifiedFalse": "Публичният ключ не е проверен ръчно"
},
"pkiBackup": {
"loseKeysWarning": "Ако загубите ключовете си, ще трябва да нулирате устройството си.",
"secureBackup": "Важно е да направите резервно копие на публичните и частните си ключове и да съхранявате резервното си копие сигурно!",
"footer": "=== КРАЙ НА КЛЮЧОВЕТЕ ===",
"header": "=== MESHTASTIC КЛЮЧОВЕ ЗА {{longName}} ({{shortName}}) ===",
"privateKey": "Частен ключ:",
"publicKey": "Публичен ключ:",
"fileName": "meshtastic_keys_{{longName}}_{{shortName}}.txt",
"title": "Backup Keys"
},
"pkiBackupReminder": {
"description": "Препоръчваме редовно да правите резервни копия на данните с вашите ключове. Искате ли да направите резервно копие сега?",
"title": "Напомняне за резервно копие",
"remindLaterPrefix": "Напомни ми в",
"remindNever": "Никога не ми напомняй",
"backupNow": "Създаване на резервно копие сега"
},
"pkiRegenerate": {
"description": "Сигурни ли сте, че искате да регенерирате двойката ключове?",
"title": "Регенериране на двойката ключове"
},
"qr": {
"addChannels": "Добавяне на канали",
"replaceChannels": "Замяна на канали",
"description": "Текущата конфигурация на LoRa също ще бъде споделена.",
"sharableUrl": "Sharable URL",
"title": "Генериране на QR код"
},
"reboot": {
"title": "Рестартиране на устройството",
"description": "Reboot now or schedule a reboot of the connected node. Optionally, you can choose to reboot into OTA (Over-the-Air) mode.",
"ota": "Reboot into OTA mode",
"enterDelay": "Въведете забавяне",
"scheduled": "Насрочено е рестартиране",
"schedule": "Планиране на рестартиране",
"now": "Рестартиране сега",
"cancel": "Cancel scheduled reboot"
},
"refreshKeys": {
"description": {
"acceptNewKeys": "This will remove the node from device and request new keys.",
"keyMismatchReasonSuffix": ". This is due to the remote node's current public key does not match the previously stored key for this node.",
"unableToSendDmPrefix": "Вашият възел не може да изпрати директно съобщение до възел:"
},
"acceptNewKeys": "риемане на нови ключове",
"title": "Keys Mismatch - {{identifier}}"
},
"removeNode": {
"description": "Сигурни ли сте, че искате да премахнете този възел?",
"title": "Премахване на възела?"
},
"shutdown": {
"title": "Планирано изключване",
"description": "Изключване на свързания възел след x минути."
},
"traceRoute": {
"routeToDestination": "Route to destination:",
"routeBack": "Route back:"
},
"tracerouteResponse": {
"title": "Traceroute: {{identifier}}"
},
"unsafeRoles": {
"confirmUnderstanding": "Да, знам какво правя",
"conjunction": "и публикацията в блога за ",
"postamble": " и разберам последиците от промяната на ролята.",
"preamble": "Аз прочетох ",
"choosingRightDeviceRole": "Избор на правилната роля на устройството",
"deviceRoleDocumentation": "Документация за ролите на устройството",
"title": "Сигурни ли сте?"
},
"managedMode": {
"confirmUnderstanding": "Да, знам какво правя",
"title": "Сигурни ли сте?",
"description": "Enabling Managed Mode blocks client applications (including the web client) from writing configurations to a radio. Once enabled, radio configurations can only be changed through Remote Admin messages. This setting is not required for remote node administration."
},
"clientNotification": {
"title": "Client Notification",
"TraceRoute can only be sent once every 30 seconds": "TraceRoute can only be sent once every 30 seconds",
"Compromised keys were detected and regenerated.": "Бяха открити и регенерирани компрометирани ключове."
},
"resetNodeDb": {
"title": "Reset Node Database",
"description": "This will clear all nodes from the connected device's node database and clear all message history in the client. This cannot be undone. Are you sure you want to continue?",
"confirm": "Reset Node Database",
"failedTitle": "There was an error resetting the Node DB. Please try again."
},
"clearAllStores": {
"title": "Clear All Local Storage",
"description": "This will clear all locally stored data, including message history and node databases for all previously connected devices. This will require you to reconnect to your node once complete and cannot be undone. Are you sure you want to continue?",
"confirm": "Clear all local storage",
"failedTitle": "There was an error clearing local storage. Please try again."
},
"factoryResetDevice": {
"title": "Фабрично нулиране на устройството",
"description": "This will factory reset the connected device, erasing all configurations and data on the device as well as all nodes and messages saved in the client. This cannot be undone. Are you sure you want to continue?",
"confirm": "Фабрично нулиране на устройството",
"failedTitle": "There was an error performing the factory reset. Please try again."
},
"factoryResetConfig": {
"title": "Фабрично нулиране на конфигурацията",
"description": "This will factory reset the configuration on the connected device, erasing all configurations on the device. This cannot be undone. Are you sure you want to continue?",
"confirm": "Фабрично нулиране на конфигурацията",
"failedTitle": "There was an error performing the factory reset. Please try again."
}
}

View File

@@ -0,0 +1,38 @@
{
"maplibre": {
"GeolocateControl.FindMyLocation": "Намиране на местоположението ми",
"NavigationControl.ZoomIn": "Увеличаване",
"NavigationControl.ZoomOut": "Намаляване",
"CooperativeGesturesHandler.WindowsHelpText": "Use Ctrl + scroll to zoom the map",
"CooperativeGesturesHandler.MacHelpText": "Use ⌘ + scroll to zoom the map",
"CooperativeGesturesHandler.MobileHelpText": "Използвайте два пръста, за да местите картата"
},
"layerTool": {
"nodeMarkers": "Показване на възли",
"directNeighbors": "Показване на директни връзки",
"remoteNeighbors": "Показване на отдалечени връзки",
"positionPrecision": "Show position precision",
"traceroutes": "Show traceroutes",
"waypoints": "Show waypoints"
},
"mapMenu": {
"locateAria": "Locate my node",
"layersAria": "Промяна на стила на картата"
},
"waypointDetail": {
"edit": "Редактирай",
"description": "Описание:",
"createdBy": "Редактирано от:",
"createdDate": "Създадено:",
"updated": "Актуализирано:",
"expires": "Изтича:",
"distance": "Разстояние:",
"bearing": "Absolute bearing:",
"lockedTo": "Заключено от:",
"latitude": "Географска ширина:",
"longitude": "Географска дължина:"
},
"myNode": {
"tooltip": "Това устройство"
}
}

View File

@@ -1,39 +1,39 @@
{
"page": {
"title": "Съобщения: {{chatName}}",
"placeholder": "Въведете съобщение"
},
"emptyState": {
"title": "Изберете чат",
"text": "Все още няма съобщения."
},
"selectChatPrompt": {
"text": "Изберете канал или възел, за да стартирате съобщения."
},
"sendMessage": {
"placeholder": "Въведете Вашето съобщение тук...",
"sendButton": "Изпрати"
},
"actionsMenu": {
"addReactionLabel": "Добавяне на реакция",
"replyLabel": "Отговор"
},
"deliveryStatus": {
"delivered": {
"label": "Съобщението е доставено",
"displayText": "Съобщението е доставено"
},
"failed": {
"label": "Доставката на съобщението не е успешна",
"displayText": "Неуспешна доставка"
},
"unknown": {
"label": "Статусът на съобщението е неизвестен",
"displayText": "Неизвестно състояние"
},
"waiting": {
"label": "Изпращане на съобщение",
"displayText": "Чака доставка"
}
}
"page": {
"title": "Съобщения: {{chatName}}",
"placeholder": "Въведете съобщение"
},
"emptyState": {
"title": "Изберете чат",
"text": "Все още няма съобщения."
},
"selectChatPrompt": {
"text": "Изберете канал или възел, за да стартирате съобщения."
},
"sendMessage": {
"placeholder": "Въведете Вашето съобщение тук...",
"sendButton": "Изпрати"
},
"actionsMenu": {
"addReactionLabel": "Добавяне на реакция",
"replyLabel": "Отговор"
},
"deliveryStatus": {
"delivered": {
"label": "Съобщението е доставено",
"displayText": "Съобщението е доставено"
},
"failed": {
"label": "Доставката на съобщението не е успешна",
"displayText": "Неуспешна доставка"
},
"unknown": {
"label": "Статусът на съобщението е неизвестен",
"displayText": "Неизвестно състояние"
},
"waiting": {
"label": "Изпращане на съобщение",
"displayText": "Чака доставка"
}
}
}

View File

@@ -1,448 +1,448 @@
{
"page": {
"tabAmbientLighting": "Ambient Lighting",
"tabAudio": "Аудио",
"tabCannedMessage": "Canned",
"tabDetectionSensor": "Detection Sensor",
"tabExternalNotification": "Ext Notif",
"tabMqtt": "MQTT",
"tabNeighborInfo": "Neighbor Info",
"tabPaxcounter": "Paxcounter",
"tabRangeTest": "Тест на обхвата",
"tabSerial": "Серийна",
"tabStoreAndForward": "S&F",
"tabTelemetry": "Телеметрия"
},
"ambientLighting": {
"title": "Ambient Lighting Settings",
"description": "Settings for the Ambient Lighting module",
"ledState": {
"label": "LED State",
"description": "Sets LED to on or off"
},
"current": {
"label": "Текущ",
"description": "Sets the current for the LED output. Default is 10"
},
"red": {
"label": "Червен",
"description": "Sets the red LED level. Values are 0-255"
},
"green": {
"label": "Зелен",
"description": "Sets the green LED level. Values are 0-255"
},
"blue": {
"label": "Син",
"description": "Sets the blue LED level. Values are 0-255"
}
},
"audio": {
"title": "Настройки на аудиото",
"description": "Настройки за аудио модула",
"codec2Enabled": {
"label": "Codec 2 е активиран",
"description": "Enable Codec 2 audio encoding"
},
"pttPin": {
"label": "Пин за РТТ",
"description": "GPIO пин, който да се използва за PTT"
},
"bitrate": {
"label": "Bitrate",
"description": "Bitrate to use for audio encoding"
},
"i2sWs": {
"label": "i2S WS",
"description": "GPIO pin to use for i2S WS"
},
"i2sSd": {
"label": "i2S SD",
"description": "GPIO pin to use for i2S SD"
},
"i2sDin": {
"label": "i2S DIN",
"description": "GPIO pin to use for i2S DIN"
},
"i2sSck": {
"label": "i2S SCK",
"description": "GPIO pin to use for i2S SCK"
}
},
"cannedMessage": {
"title": "Canned Message Settings",
"description": "Settings for the Canned Message module",
"moduleEnabled": {
"label": "Модулът е активиран",
"description": "Enable Canned Message"
},
"rotary1Enabled": {
"label": "Ротационен енкодер #1 е активиран",
"description": "Активиране на ротационния енкодер"
},
"inputbrokerPinA": {
"label": "Encoder Pin A",
"description": "GPIO Pin Value (1-39) For encoder port A"
},
"inputbrokerPinB": {
"label": "Encoder Pin B",
"description": "GPIO Pin Value (1-39) For encoder port B"
},
"inputbrokerPinPress": {
"label": "Encoder Pin Press",
"description": "GPIO Pin Value (1-39) For encoder Press"
},
"inputbrokerEventCw": {
"label": "Clockwise event",
"description": "Select input event."
},
"inputbrokerEventCcw": {
"label": "Counter Clockwise event",
"description": "Select input event."
},
"inputbrokerEventPress": {
"label": "Press event",
"description": "Select input event"
},
"updown1Enabled": {
"label": "Up Down enabled",
"description": "Enable the up / down encoder"
},
"allowInputSource": {
"label": "Allow Input Source",
"description": "Изберете от: '_any', 'rotEnc1', 'upDownEnc1', 'cardkb'"
},
"sendBell": {
"label": "Send Bell",
"description": "Sends a bell character with each message"
}
},
"detectionSensor": {
"title": "Detection Sensor Settings",
"description": "Settings for the Detection Sensor module",
"enabled": {
"label": "Активиран",
"description": "Enable or disable Detection Sensor Module"
},
"minimumBroadcastSecs": {
"label": "Minimum Broadcast Seconds",
"description": "The interval in seconds of how often we can send a message to the mesh when a state change is detected"
},
"stateBroadcastSecs": {
"label": "State Broadcast Seconds",
"description": "The interval in seconds of how often we should send a message to the mesh with the current state regardless of changes"
},
"sendBell": {
"label": "Send Bell",
"description": "Send ASCII bell with alert message"
},
"name": {
"label": "Приятелско име",
"description": "Използва се за форматиране на съобщението, изпратено до mesh, максимум 20 знака"
},
"monitorPin": {
"label": "Monitor Pin",
"description": "The GPIO pin to monitor for state changes"
},
"detectionTriggerType": {
"label": "Detection Triggered Type",
"description": "The type of trigger event to be used"
},
"usePullup": {
"label": "Use Pullup",
"description": "Whether or not use INPUT_PULLUP mode for GPIO pin"
}
},
"externalNotification": {
"title": "External Notification Settings",
"description": "Configure the external notification module",
"enabled": {
"label": "Модулът е активиран",
"description": "Enable External Notification"
},
"outputMs": {
"label": "Output MS",
"description": "Output MS"
},
"output": {
"label": "Output",
"description": "Output"
},
"outputVibra": {
"label": "Output Vibrate",
"description": "Output Vibrate"
},
"outputBuzzer": {
"label": "Output Buzzer",
"description": "Output Buzzer"
},
"active": {
"label": "Активно",
"description": "Активно"
},
"alertMessage": {
"label": "Предупредително съобщение",
"description": "Предупредително съобщение"
},
"alertMessageVibra": {
"label": "Alert Message Vibrate",
"description": "Alert Message Vibrate"
},
"alertMessageBuzzer": {
"label": "Alert Message Buzzer",
"description": "Alert Message Buzzer"
},
"alertBell": {
"label": "Alert Bell",
"description": "Should an alert be triggered when receiving an incoming bell?"
},
"alertBellVibra": {
"label": "Alert Bell Vibrate",
"description": "Alert Bell Vibrate"
},
"alertBellBuzzer": {
"label": "Alert Bell Buzzer",
"description": "Alert Bell Buzzer"
},
"usePwm": {
"label": "Use PWM",
"description": "Use PWM"
},
"nagTimeout": {
"label": "Nag Timeout",
"description": "Nag Timeout"
},
"useI2sAsBuzzer": {
"label": "Use I²S Pin as Buzzer",
"description": "Designate I²S Pin as Buzzer Output"
}
},
"mqtt": {
"title": "Настройки на MQTT",
"description": "Настройки за MQTT модула",
"enabled": {
"label": "Активиран",
"description": "Активиране или дезактивиране на MQTT"
},
"address": {
"label": "Адрес на MQTT сървъра",
"description": "Адрес на MQTT сървъра, който да се използва за сървъри по подразбиране/персонализирани сървъри"
},
"username": {
"label": "Потребителско име за MQTT",
"description": "Потребителско име за MQTT, което да се използва за сървъри по подразбиране/персонализирани сървъри"
},
"password": {
"label": "Парола за MQTT",
"description": "Парола за MQTT, която да се използва за сървъри по подразбиране/персонализирани сървъри"
},
"encryptionEnabled": {
"label": "Криптирането е активирано",
"description": "Enable or disable MQTT encryption. Note: All messages are sent to the MQTT broker unencrypted if this option is not enabled, even when your uplink channels have encryption keys set. This includes position data."
},
"jsonEnabled": {
"label": "JSON е активиран",
"description": "Whether to send/consume JSON packets on MQTT"
},
"tlsEnabled": {
"label": "TLS е активиран",
"description": "Активиране или дезактивиране на TLS"
},
"root": {
"label": "Root topic",
"description": "MQTT root topic to use for default/custom servers"
},
"proxyToClientEnabled": {
"label": "MQTT Client Proxy Enabled",
"description": "Utilizes the network connection to proxy MQTT messages to the client."
},
"mapReportingEnabled": {
"label": "Map Reporting Enabled",
"description": "Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, short and long name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name."
},
"mapReportSettings": {
"publishIntervalSecs": {
"label": "Map Report Publish Interval (s)",
"description": "Interval in seconds to publish map reports"
},
"positionPrecision": {
"label": "Приблизително местоположение",
"description": "Position shared will be accurate within this distance",
"options": {
"metric_km23": "В рамките на 23 км",
"metric_km12": "В рамките на 12 км",
"metric_km5_8": "В рамките на 5.8 км",
"metric_km2_9": "В рамките на 2.9 км",
"metric_km1_5": "В рамките на 1.5 км",
"metric_m700": "В рамките на 700 м",
"metric_m350": "В рамките на 350 м",
"metric_m200": "В рамките на 200 м",
"metric_m90": "В рамките на 90 м",
"metric_m50": "В рамките на 50 м",
"imperial_mi15": "В рамките на 15 мили",
"imperial_mi7_3": "В рамките на 7.3 мили",
"imperial_mi3_6": "В рамките на 3.6 мили",
"imperial_mi1_8": "В рамките на 1.8 мили",
"imperial_mi0_9": "В рамките на 0.9 мили",
"imperial_mi0_5": "В рамките на 0.5 мили",
"imperial_mi0_2": "В рамките на 0.2 мили",
"imperial_ft600": "В рамките на 600 фута",
"imperial_ft300": "В рамките на 300 фута",
"imperial_ft150": "В рамките на 150 фута"
}
}
}
},
"neighborInfo": {
"title": "Neighbor Info Settings",
"description": "Settings for the Neighbor Info module",
"enabled": {
"label": "Активиран",
"description": "Enable or disable Neighbor Info Module"
},
"updateInterval": {
"label": "Интервал на актуализиране",
"description": "Interval in seconds of how often we should try to send our Neighbor Info to the mesh"
}
},
"paxcounter": {
"title": "Paxcounter Settings",
"description": "Настройки за модула Paxcounter",
"enabled": {
"label": "Модулът е активиран",
"description": "Активиране на Paxcounter"
},
"paxcounterUpdateInterval": {
"label": "Интервал на актуализиране (секунди)",
"description": "How long to wait between sending paxcounter packets"
},
"wifiThreshold": {
"label": "WiFi RSSI Threshold",
"description": "At what WiFi RSSI level should the counter increase. Defaults to -80."
},
"bleThreshold": {
"label": "BLE RSSI Threshold",
"description": "At what BLE RSSI level should the counter increase. Defaults to -80."
}
},
"rangeTest": {
"title": "Настройки за тест на обхвата",
"description": "Настройки на модула за тестване на обхвата",
"enabled": {
"label": "Модулът е активиран",
"description": "Enable Range Test"
},
"sender": {
"label": "Интервал на съобщенията",
"description": "Колко време да се чака между изпращането на тестови пакети"
},
"save": {
"label": "Запазване на CSV в хранилището",
"description": "Само ESP32"
}
},
"serial": {
"title": "Серийни настройки",
"description": "Настройки на серийния модул",
"enabled": {
"label": "Модулът е активиран",
"description": "Активиране на сериен изход"
},
"echo": {
"label": "Echo",
"description": "Any packets you send will be echoed back to your device"
},
"rxd": {
"label": "Receive Pin",
"description": "Set the GPIO pin to the RXD pin you have set up."
},
"txd": {
"label": "Transmit Pin",
"description": "Set the GPIO pin to the TXD pin you have set up."
},
"baud": {
"label": "Baud Rate",
"description": "The serial baud rate"
},
"timeout": {
"label": "Timeout",
"description": "Seconds to wait before we consider your packet as 'done'"
},
"mode": {
"label": "Режим",
"description": "Избор на режим"
},
"overrideConsoleSerialPort": {
"label": "Override Console Serial Port",
"description": "If you have a serial port connected to the console, this will override it."
}
},
"storeForward": {
"title": "Store & Forward Settings",
"description": "Settings for the Store & Forward module",
"enabled": {
"label": "Модулът е активиран",
"description": "Enable Store & Forward"
},
"heartbeat": {
"label": "Heartbeat Enabled",
"description": "Enable Store & Forward heartbeat"
},
"records": {
"label": "Брой записи",
"description": "Number of records to store"
},
"historyReturnMax": {
"label": "History return max",
"description": "Max number of records to return"
},
"historyReturnWindow": {
"label": "History return window",
"description": "Max number of records to return"
}
},
"telemetry": {
"title": "Настройки на телеметрията",
"description": "Настройки за модула за телеметрия",
"deviceUpdateInterval": {
"label": "Метрики на устройството",
"description": "Интервал на актуализиране на показателите на устройството (секунди)"
},
"environmentUpdateInterval": {
"label": "Интервал на актуализиране на показателите на околната среда (секунди)",
"description": ""
},
"environmentMeasurementEnabled": {
"label": "Модулът е активиран",
"description": "Enable the Environment Telemetry"
},
"environmentScreenEnabled": {
"label": "Показва се на екрана",
"description": "Show the Telemetry Module on the OLED"
},
"environmentDisplayFahrenheit": {
"label": "Показване на Фаренхайт",
"description": "Показване на температурата във Фаренхайт"
},
"airQualityEnabled": {
"label": "Качество на въздуха е активирано",
"description": "Активиране на телеметрията за качеството на въздуха"
},
"airQualityInterval": {
"label": "Air Quality Update Interval",
"description": "How often to send Air Quality data over the mesh"
},
"powerMeasurementEnabled": {
"label": "Power Measurement Enabled",
"description": "Enable the Power Measurement Telemetry"
},
"powerUpdateInterval": {
"label": "Power Update Interval",
"description": "How often to send Power data over the mesh"
},
"powerScreenEnabled": {
"label": "Power Screen Enabled",
"description": "Enable the Power Telemetry Screen"
}
}
"page": {
"tabAmbientLighting": "Ambient Lighting",
"tabAudio": "Аудио",
"tabCannedMessage": "Canned",
"tabDetectionSensor": "Detection Sensor",
"tabExternalNotification": "Ext Notif",
"tabMqtt": "MQTT",
"tabNeighborInfo": "Neighbor Info",
"tabPaxcounter": "Paxcounter",
"tabRangeTest": "Тест на обхвата",
"tabSerial": "Серийна",
"tabStoreAndForward": "S&F",
"tabTelemetry": "Телеметрия"
},
"ambientLighting": {
"title": "Ambient Lighting Settings",
"description": "Settings for the Ambient Lighting module",
"ledState": {
"label": "LED State",
"description": "Sets LED to on or off"
},
"current": {
"label": "Текущ",
"description": "Sets the current for the LED output. Default is 10"
},
"red": {
"label": "Червен",
"description": "Sets the red LED level. Values are 0-255"
},
"green": {
"label": "Зелен",
"description": "Sets the green LED level. Values are 0-255"
},
"blue": {
"label": "Син",
"description": "Sets the blue LED level. Values are 0-255"
}
},
"audio": {
"title": "Настройки на аудиото",
"description": "Настройки за аудио модула",
"codec2Enabled": {
"label": "Codec 2 е активиран",
"description": "Enable Codec 2 audio encoding"
},
"pttPin": {
"label": "Пин за РТТ",
"description": "GPIO пин, който да се използва за PTT"
},
"bitrate": {
"label": "Bitrate",
"description": "Bitrate to use for audio encoding"
},
"i2sWs": {
"label": "i2S WS",
"description": "GPIO pin to use for i2S WS"
},
"i2sSd": {
"label": "i2S SD",
"description": "GPIO pin to use for i2S SD"
},
"i2sDin": {
"label": "i2S DIN",
"description": "GPIO pin to use for i2S DIN"
},
"i2sSck": {
"label": "i2S SCK",
"description": "GPIO pin to use for i2S SCK"
}
},
"cannedMessage": {
"title": "Canned Message Settings",
"description": "Settings for the Canned Message module",
"moduleEnabled": {
"label": "Модулът е активиран",
"description": "Enable Canned Message"
},
"rotary1Enabled": {
"label": "Ротационен енкодер #1 е активиран",
"description": "Активиране на ротационния енкодер"
},
"inputbrokerPinA": {
"label": "Encoder Pin A",
"description": "GPIO Pin Value (1-39) For encoder port A"
},
"inputbrokerPinB": {
"label": "Encoder Pin B",
"description": "GPIO Pin Value (1-39) For encoder port B"
},
"inputbrokerPinPress": {
"label": "Encoder Pin Press",
"description": "GPIO Pin Value (1-39) For encoder Press"
},
"inputbrokerEventCw": {
"label": "Clockwise event",
"description": "Select input event."
},
"inputbrokerEventCcw": {
"label": "Counter Clockwise event",
"description": "Select input event."
},
"inputbrokerEventPress": {
"label": "Press event",
"description": "Select input event"
},
"updown1Enabled": {
"label": "Up Down enabled",
"description": "Enable the up / down encoder"
},
"allowInputSource": {
"label": "Allow Input Source",
"description": "Изберете от: '_any', 'rotEnc1', 'upDownEnc1', 'cardkb'"
},
"sendBell": {
"label": "Send Bell",
"description": "Sends a bell character with each message"
}
},
"detectionSensor": {
"title": "Detection Sensor Settings",
"description": "Settings for the Detection Sensor module",
"enabled": {
"label": "Активиран",
"description": "Enable or disable Detection Sensor Module"
},
"minimumBroadcastSecs": {
"label": "Minimum Broadcast Seconds",
"description": "The interval in seconds of how often we can send a message to the mesh when a state change is detected"
},
"stateBroadcastSecs": {
"label": "State Broadcast Seconds",
"description": "The interval in seconds of how often we should send a message to the mesh with the current state regardless of changes"
},
"sendBell": {
"label": "Send Bell",
"description": "Send ASCII bell with alert message"
},
"name": {
"label": "Приятелско име",
"description": "Използва се за форматиране на съобщението, изпратено до mesh, максимум 20 знака"
},
"monitorPin": {
"label": "Monitor Pin",
"description": "The GPIO pin to monitor for state changes"
},
"detectionTriggerType": {
"label": "Detection Triggered Type",
"description": "The type of trigger event to be used"
},
"usePullup": {
"label": "Use Pullup",
"description": "Whether or not use INPUT_PULLUP mode for GPIO pin"
}
},
"externalNotification": {
"title": "External Notification Settings",
"description": "Configure the external notification module",
"enabled": {
"label": "Модулът е активиран",
"description": "Enable External Notification"
},
"outputMs": {
"label": "Output MS",
"description": "Output MS"
},
"output": {
"label": "Output",
"description": "Output"
},
"outputVibra": {
"label": "Output Vibrate",
"description": "Output Vibrate"
},
"outputBuzzer": {
"label": "Output Buzzer",
"description": "Output Buzzer"
},
"active": {
"label": "Активно",
"description": "Активно"
},
"alertMessage": {
"label": "Предупредително съобщение",
"description": "Предупредително съобщение"
},
"alertMessageVibra": {
"label": "Alert Message Vibrate",
"description": "Alert Message Vibrate"
},
"alertMessageBuzzer": {
"label": "Alert Message Buzzer",
"description": "Alert Message Buzzer"
},
"alertBell": {
"label": "Alert Bell",
"description": "Should an alert be triggered when receiving an incoming bell?"
},
"alertBellVibra": {
"label": "Alert Bell Vibrate",
"description": "Alert Bell Vibrate"
},
"alertBellBuzzer": {
"label": "Alert Bell Buzzer",
"description": "Alert Bell Buzzer"
},
"usePwm": {
"label": "Use PWM",
"description": "Use PWM"
},
"nagTimeout": {
"label": "Nag Timeout",
"description": "Nag Timeout"
},
"useI2sAsBuzzer": {
"label": "Use I²S Pin as Buzzer",
"description": "Designate I²S Pin as Buzzer Output"
}
},
"mqtt": {
"title": "Настройки на MQTT",
"description": "Настройки за MQTT модула",
"enabled": {
"label": "Активиран",
"description": "Активиране или дезактивиране на MQTT"
},
"address": {
"label": "Адрес на MQTT сървъра",
"description": "Адрес на MQTT сървъра, който да се използва за сървъри по подразбиране/персонализирани сървъри"
},
"username": {
"label": "Потребителско име за MQTT",
"description": "Потребителско име за MQTT, което да се използва за сървъри по подразбиране/персонализирани сървъри"
},
"password": {
"label": "Парола за MQTT",
"description": "Парола за MQTT, която да се използва за сървъри по подразбиране/персонализирани сървъри"
},
"encryptionEnabled": {
"label": "Криптирането е активирано",
"description": "Enable or disable MQTT encryption. Note: All messages are sent to the MQTT broker unencrypted if this option is not enabled, even when your uplink channels have encryption keys set. This includes position data."
},
"jsonEnabled": {
"label": "JSON е активиран",
"description": "Whether to send/consume JSON packets on MQTT"
},
"tlsEnabled": {
"label": "TLS е активиран",
"description": "Активиране или дезактивиране на TLS"
},
"root": {
"label": "Root topic",
"description": "MQTT root topic to use for default/custom servers"
},
"proxyToClientEnabled": {
"label": "MQTT Client Proxy Enabled",
"description": "Utilizes the network connection to proxy MQTT messages to the client."
},
"mapReportingEnabled": {
"label": "Map Reporting Enabled",
"description": "Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, short and long name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name."
},
"mapReportSettings": {
"publishIntervalSecs": {
"label": "Map Report Publish Interval (s)",
"description": "Interval in seconds to publish map reports"
},
"positionPrecision": {
"label": "Приблизително местоположение",
"description": "Position shared will be accurate within this distance",
"options": {
"metric_km23": "В рамките на 23 км",
"metric_km12": "В рамките на 12 км",
"metric_km5_8": "В рамките на 5.8 км",
"metric_km2_9": "В рамките на 2.9 км",
"metric_km1_5": "В рамките на 1.5 км",
"metric_m700": "В рамките на 700 м",
"metric_m350": "В рамките на 350 м",
"metric_m200": "В рамките на 200 м",
"metric_m90": "В рамките на 90 м",
"metric_m50": "В рамките на 50 м",
"imperial_mi15": "В рамките на 15 мили",
"imperial_mi7_3": "В рамките на 7.3 мили",
"imperial_mi3_6": "В рамките на 3.6 мили",
"imperial_mi1_8": "В рамките на 1.8 мили",
"imperial_mi0_9": "В рамките на 0.9 мили",
"imperial_mi0_5": "В рамките на 0.5 мили",
"imperial_mi0_2": "В рамките на 0.2 мили",
"imperial_ft600": "В рамките на 600 фута",
"imperial_ft300": "В рамките на 300 фута",
"imperial_ft150": "В рамките на 150 фута"
}
}
}
},
"neighborInfo": {
"title": "Neighbor Info Settings",
"description": "Settings for the Neighbor Info module",
"enabled": {
"label": "Активиран",
"description": "Enable or disable Neighbor Info Module"
},
"updateInterval": {
"label": "Интервал на актуализиране",
"description": "Interval in seconds of how often we should try to send our Neighbor Info to the mesh"
}
},
"paxcounter": {
"title": "Paxcounter Settings",
"description": "Настройки за модула Paxcounter",
"enabled": {
"label": "Модулът е активиран",
"description": "Активиране на Paxcounter"
},
"paxcounterUpdateInterval": {
"label": "Интервал на актуализиране (секунди)",
"description": "How long to wait between sending paxcounter packets"
},
"wifiThreshold": {
"label": "WiFi RSSI Threshold",
"description": "At what WiFi RSSI level should the counter increase. Defaults to -80."
},
"bleThreshold": {
"label": "BLE RSSI Threshold",
"description": "At what BLE RSSI level should the counter increase. Defaults to -80."
}
},
"rangeTest": {
"title": "Настройки за тест на обхвата",
"description": "Настройки на модула за тестване на обхвата",
"enabled": {
"label": "Модулът е активиран",
"description": "Enable Range Test"
},
"sender": {
"label": "Интервал на съобщенията",
"description": "Колко време да се чака между изпращането на тестови пакети"
},
"save": {
"label": "Запазване на CSV в хранилището",
"description": "Само ESP32"
}
},
"serial": {
"title": "Серийни настройки",
"description": "Настройки на серийния модул",
"enabled": {
"label": "Модулът е активиран",
"description": "Активиране на сериен изход"
},
"echo": {
"label": "Echo",
"description": "Any packets you send will be echoed back to your device"
},
"rxd": {
"label": "Receive Pin",
"description": "Set the GPIO pin to the RXD pin you have set up."
},
"txd": {
"label": "Transmit Pin",
"description": "Set the GPIO pin to the TXD pin you have set up."
},
"baud": {
"label": "Baud Rate",
"description": "The serial baud rate"
},
"timeout": {
"label": "Timeout",
"description": "Seconds to wait before we consider your packet as 'done'"
},
"mode": {
"label": "Режим",
"description": "Избор на режим"
},
"overrideConsoleSerialPort": {
"label": "Override Console Serial Port",
"description": "If you have a serial port connected to the console, this will override it."
}
},
"storeForward": {
"title": "Store & Forward Settings",
"description": "Settings for the Store & Forward module",
"enabled": {
"label": "Модулът е активиран",
"description": "Enable Store & Forward"
},
"heartbeat": {
"label": "Heartbeat Enabled",
"description": "Enable Store & Forward heartbeat"
},
"records": {
"label": "Брой записи",
"description": "Number of records to store"
},
"historyReturnMax": {
"label": "History return max",
"description": "Max number of records to return"
},
"historyReturnWindow": {
"label": "History return window",
"description": "Return records from this time window (minutes)"
}
},
"telemetry": {
"title": "Настройки на телеметрията",
"description": "Настройки за модула за телеметрия",
"deviceUpdateInterval": {
"label": "Метрики на устройството",
"description": "Интервал на актуализиране на показателите на устройството (секунди)"
},
"environmentUpdateInterval": {
"label": "Интервал на актуализиране на показателите на околната среда (секунди)",
"description": ""
},
"environmentMeasurementEnabled": {
"label": "Модулът е активиран",
"description": "Enable the Environment Telemetry"
},
"environmentScreenEnabled": {
"label": "Показва се на екрана",
"description": "Show the Telemetry Module on the OLED"
},
"environmentDisplayFahrenheit": {
"label": "Показване на Фаренхайт",
"description": "Показване на температурата във Фаренхайт"
},
"airQualityEnabled": {
"label": "Качество на въздуха е активирано",
"description": "Активиране на телеметрията за качеството на въздуха"
},
"airQualityInterval": {
"label": "Air Quality Update Interval",
"description": "How often to send Air Quality data over the mesh"
},
"powerMeasurementEnabled": {
"label": "Power Measurement Enabled",
"description": "Enable the Power Measurement Telemetry"
},
"powerUpdateInterval": {
"label": "Power Update Interval",
"description": "How often to send Power data over the mesh"
},
"powerScreenEnabled": {
"label": "Power Screen Enabled",
"description": "Enable the Power Telemetry Screen"
}
}
}

View File

@@ -1,63 +1,59 @@
{
"nodeDetail": {
"publicKeyEnabled": {
"label": "Публичният ключ е активиран"
},
"noPublicKey": {
"label": "Няма публичен ключ"
},
"directMessage": {
"label": "Директно съобщение {{shortName}}"
},
"favorite": {
"label": "Любим",
"tooltip": "Добавяне или премахване на този възел от любимите ви"
},
"notFavorite": {
"label": "Не е любим"
},
"error": {
"label": "Грешка",
"text": "Възникна грешка при извличането на подробности за възела. Моля, опитайте отново по-късно."
},
"status": {
"heard": "Heard",
"mqtt": "MQTT"
},
"elevation": {
"label": "Височина"
},
"channelUtil": {
"label": "Използване на канала"
},
"airtimeUtil": {
"label": "Използване на ефирно време"
}
},
"nodesTable": {
"headings": {
"longName": "Дълго име",
"connection": "Connection",
"lastHeard": "Последно чут",
"encryption": "Криптиране",
"model": "Модел",
"macAddress": "MAC адрес"
},
"connectionStatus": {
"direct": "Директно",
"away": "away",
"unknown": "-",
"viaMqtt": ", чрез MQTT"
},
"lastHeardStatus": {
"never": "Никога"
}
},
"actions": {
"added": "Добавен",
"removed": "Премахнат",
"ignoreNode": "Игнориране на възела",
"unignoreNode": "Премахване на игнорирането на възела",
"requestPosition": "Request Position"
}
"nodeDetail": {
"publicKeyEnabled": {
"label": "Публичният ключ е активиран"
},
"noPublicKey": {
"label": "Няма публичен ключ"
},
"directMessage": {
"label": "Директно съобщение {{shortName}}"
},
"favorite": {
"label": "Любим",
"tooltip": "Добавяне или премахване на този възел от любимите ви"
},
"notFavorite": {
"label": "Не е любим"
},
"error": {
"label": "Грешка",
"text": "Възникна грешка при извличането на подробности за възела. Моля, опитайте отново по-късно."
},
"status": {
"heard": "Heard",
"mqtt": "MQTT"
},
"elevation": {
"label": "Височина"
},
"channelUtil": {
"label": "Използване на канала"
},
"airtimeUtil": {
"label": "Използване на ефирно време"
}
},
"nodesTable": {
"headings": {
"longName": "Дълго име",
"connection": "Connection",
"lastHeard": "Последно чут",
"encryption": "Криптиране",
"model": "Модел",
"macAddress": "MAC адрес"
},
"connectionStatus": {
"direct": "Директно",
"away": "away",
"viaMqtt": ", чрез MQTT"
}
},
"actions": {
"added": "Добавен",
"removed": "Премахнат",
"ignoreNode": "Игнориране на възела",
"unignoreNode": "Премахване на игнорирането на възела",
"requestPosition": "Request Position"
}
}

View File

@@ -1,228 +1,230 @@
{
"navigation": {
"title": "Навигация",
"messages": "Съобщения",
"map": "Карта",
"config": "Конфигурация",
"radioConfig": "Конфигурация на радиото",
"moduleConfig": "Конфигурация на модула",
"channels": "Канали",
"nodes": "Възли"
},
"app": {
"title": "Meshtastic",
"logo": "Лого на Meshtastic"
},
"sidebar": {
"collapseToggle": {
"button": {
"open": "Отваряне на страничната лента",
"close": "Затваряне на страничната лента"
}
},
"deviceInfo": {
"volts": "{{voltage}} волта",
"firmware": {
"title": "Фърмуер",
"version": "v{{version}}",
"buildDate": "Дата на компилация: {{date}}"
},
"deviceName": {
"title": "Име на устройството",
"changeName": "Промяна на името на устройството",
"placeholder": "Въвеждане на име на устройството"
},
"editDeviceName": "Редактиране на името на устройство"
}
},
"batteryStatus": {
"charging": "{{level}}% зареждане",
"pluggedIn": "Включен в ел. мрежа",
"title": "Батерия"
},
"search": {
"nodes": "Търсене на възли...",
"channels": "Търсене на канали...",
"commandPalette": "Търсене на команди..."
},
"toast": {
"positionRequestSent": {
"title": "Position request sent."
},
"requestingPosition": {
"title": "Requesting position, please wait..."
},
"sendingTraceroute": {
"title": "Sending Traceroute, please wait..."
},
"tracerouteSent": {
"title": "Traceroute sent."
},
"savedChannel": {
"title": "Запазен канал: {{channelName}}"
},
"messages": {
"pkiEncryption": {
"title": "Чатът използва PKI криптиране."
},
"pskEncryption": {
"title": "Чатът използва PSK криптиране."
}
},
"configSaveError": {
"title": "Грешка при запазване на конфигурацията",
"description": "Възникна грешка при запазване на конфигурацията."
},
"validationError": {
"title": "Съществуват грешки в конфигурацията",
"description": "Моля, коригирайте грешките в конфигурацията, преди да я запазите."
},
"saveSuccess": {
"title": "Запазване на конфигурацията",
"description": "Промяната в конфигурацията {{case}} е запазена."
},
"favoriteNode": {
"title": "{{action}} {{nodeName}} {{direction}} любими.",
"action": {
"added": "Добавен",
"removed": "Премахнат",
"to": "в",
"from": "от"
}
},
"ignoreNode": {
"title": "{{action}} {{nodeName}} {{direction}} списък с игнорирани",
"action": {
"added": "Добавен",
"removed": "Премахнат",
"to": "в",
"from": "от"
}
}
},
"notifications": {
"copied": {
"label": "Копирано!"
},
"copyToClipboard": {
"label": "Копиране в клипборда"
},
"hidePassword": {
"label": "Скриване на паролата"
},
"showPassword": {
"label": "Показване на паролата"
},
"deliveryStatus": {
"delivered": "Доставено",
"failed": "Неуспешна доставка",
"waiting": "Изчакване",
"unknown": "Неизвестно"
}
},
"general": {
"label": "General"
},
"hardware": {
"label": "Хардуер"
},
"metrics": {
"label": "Метрики"
},
"role": {
"label": "Роля"
},
"filter": {
"label": "Филтър"
},
"advanced": {
"label": "Разширени"
},
"clearInput": {
"label": "Clear input"
},
"resetFilters": {
"label": "Нулиране на филтрите"
},
"nodeName": {
"label": "Име/номер на възел",
"placeholder": "Meshtastic 1234"
},
"airtimeUtilization": {
"label": "Използване на ефира (%)"
},
"batteryLevel": {
"label": "Ниво на батерията (%)",
"labelText": "Ниво на батерията (%): {{value}}"
},
"batteryVoltage": {
"label": "Напрежение на батерията (V)",
"title": "Напрежение"
},
"channelUtilization": {
"label": "Използване на канала (%)"
},
"hops": {
"direct": "Директно",
"label": "Брой хопове",
"text": "Брой хопове: {{value}}"
},
"lastHeard": {
"label": "Последно чут",
"labelText": "Последно чут: {{value}}",
"nowLabel": "Сега"
},
"snr": {
"label": "SNR (db)"
},
"favorites": {
"label": "Любими"
},
"hide": {
"label": "Скриване"
},
"showOnly": {
"label": "Показване само"
},
"viaMqtt": {
"label": "Свързан чрез MQTT"
},
"hopsUnknown": {
"label": "Неизвестен брой хопове"
},
"showUnheard": {
"label": "Никога не е чуван"
},
"language": {
"label": "Език",
"changeLanguage": "Промяна на езика"
},
"theme": {
"dark": "Тъмна",
"light": "Светла",
"system": "Автоматично",
"changeTheme": "Промяна на цветовата схема"
},
"errorPage": {
"title": "Това е малко смущаващо...",
"description1": "Наистина съжаляваме, но възникна грешка в web клиента, която доведе до срив. <br /> Това не би трябвало да се случва и работим усилено, за да го поправим.",
"description2": "Най-добрият начин да предотвратите това да се случи отново с вас или с някой друг е да ни съобщите за проблема.",
"reportInstructions": "Моля, включете следната информация в доклада си:",
"reportSteps": {
"step1": "Какво правехте, когато възникна грешката",
"step2": "Какво очаквахте да се случи",
"step3": "Какво всъщност се случи",
"step4": "Всяка друга подходяща информация"
},
"reportLink": "Можете да съобщите за проблема в нашия <0>GitHub</0>",
"dashboardLink": "Връщане към <0>таблото</0>",
"detailsSummary": "Подробности за грешката",
"errorMessageLabel": "Съобщение за грешка:",
"stackTraceLabel": "Stack trace:",
"fallbackError": "{{error}}"
},
"footer": {
"text": "Задвижвано от <0>▲ Vercel</0> | Meshtastic® е регистрирана търговска марка на Meshtastic LLC. | <1>Правна информация</1>",
"commitSha": "Commit SHA: {{sha}}"
}
"navigation": {
"title": "Навигация",
"messages": "Съобщения",
"map": "Карта",
"settings": "Настройки",
"channels": "Канали",
"radioConfig": "Конфигурация на радиото",
"deviceConfig": "Конфигуриране на устройството",
"moduleConfig": "Конфигурация на модула",
"manageConnections": "Управление на връзките",
"nodes": "Възли"
},
"app": {
"title": "Meshtastic",
"logo": "Лого на Meshtastic"
},
"sidebar": {
"collapseToggle": {
"button": {
"open": "Отваряне на страничната лента",
"close": "Затваряне на страничната лента"
}
},
"deviceInfo": {
"volts": "{{voltage}} волта",
"firmware": {
"title": "Фърмуер",
"version": "v{{version}}",
"buildDate": "Дата на компилация: {{date}}"
}
}
},
"batteryStatus": {
"charging": "{{level}}% зареждане",
"pluggedIn": "Включен в ел. мрежа",
"title": "Батерия"
},
"search": {
"nodes": "Търсене на възли...",
"channels": "Търсене на канали...",
"commandPalette": "Търсене на команди..."
},
"toast": {
"positionRequestSent": {
"title": "Заявката за позиция е изпратена."
},
"requestingPosition": {
"title": "Запитване за позиция, моля изчакайте..."
},
"sendingTraceroute": {
"title": "Sending Traceroute, please wait..."
},
"tracerouteSent": {
"title": "Traceroute sent."
},
"savedChannel": {
"title": "Запазен канал: {{channelName}}"
},
"messages": {
"pkiEncryption": {
"title": "Чатът използва PKI криптиране."
},
"pskEncryption": {
"title": "Чатът използва PSK криптиране."
}
},
"configSaveError": {
"title": "Грешка при запазване на конфигурацията",
"description": "Възникна грешка при запазване на конфигурацията."
},
"validationError": {
"title": "Съществуват грешки в конфигурацията",
"description": "Моля, коригирайте грешките в конфигурацията, преди да я запазите."
},
"saveSuccess": {
"title": "Запазване на конфигурацията",
"description": "Промяната в конфигурацията {{case}} е запазена."
},
"saveAllSuccess": {
"title": "Запазено",
"description": "Всички промени в конфигурацията са запазени."
},
"favoriteNode": {
"title": "{{action}} {{nodeName}} {{direction}} любими.",
"action": {
"added": "Добавен",
"removed": "Премахнат",
"to": "в",
"from": "от"
}
},
"ignoreNode": {
"title": "{{action}} {{nodeName}} {{direction}} списък с игнорирани",
"action": {
"added": "Добавен",
"removed": "Премахнат",
"to": "в",
"from": "от"
}
}
},
"notifications": {
"copied": {
"label": "Копирано!"
},
"copyToClipboard": {
"label": "Копиране в клипборда"
},
"hidePassword": {
"label": "Скриване на паролата"
},
"showPassword": {
"label": "Показване на паролата"
},
"deliveryStatus": {
"delivered": "Доставено",
"failed": "Неуспешна доставка",
"waiting": "Изчакване",
"unknown": "Неизвестно"
}
},
"general": {
"label": "General"
},
"hardware": {
"label": "Хардуер"
},
"metrics": {
"label": "Метрики"
},
"role": {
"label": "Роля"
},
"filter": {
"label": "Филтър"
},
"advanced": {
"label": "Разширени"
},
"clearInput": {
"label": "Clear input"
},
"resetFilters": {
"label": "Нулиране на филтрите"
},
"nodeName": {
"label": "Име/номер на възел",
"placeholder": "Meshtastic 1234"
},
"airtimeUtilization": {
"label": "Използване на ефира (%)",
"short": "Airtime Util. (%)"
},
"batteryLevel": {
"label": "Ниво на батерията (%)",
"labelText": "Ниво на батерията (%): {{value}}"
},
"batteryVoltage": {
"label": "Напрежение на батерията (V)",
"title": "Напрежение"
},
"channelUtilization": {
"label": "Използване на канала (%)",
"short": "Channel Util. (%)"
},
"hops": {
"direct": "Директно",
"label": "Брой хопове",
"text": "Брой хопове: {{value}}"
},
"lastHeard": {
"label": "Последно чут",
"labelText": "Последно чут: {{value}}",
"nowLabel": "Сега"
},
"snr": {
"label": "SNR (db)"
},
"favorites": {
"label": "Любими"
},
"hide": {
"label": "Скриване"
},
"showOnly": {
"label": "Показване само"
},
"viaMqtt": {
"label": "Свързан чрез MQTT"
},
"hopsUnknown": {
"label": "Неизвестен брой хопове"
},
"showUnheard": {
"label": "Никога не е чуван"
},
"language": {
"label": "Език",
"changeLanguage": "Промяна на езика"
},
"theme": {
"dark": "Тъмна",
"light": "Светла",
"system": "Автоматично",
"changeTheme": "Промяна на цветовата схема"
},
"errorPage": {
"title": "Това е малко смущаващо...",
"description1": "Наистина съжаляваме, но възникна грешка в web клиента, която доведе до срив. <br /> Това не би трябвало да се случва и работим усилено, за да го поправим.",
"description2": "Най-добрият начин да предотвратите това да се случи отново с вас или с някой друг е да ни съобщите за проблема.",
"reportInstructions": "Моля, включете следната информация в доклада си:",
"reportSteps": {
"step1": "Какво правехте, когато възникна грешката",
"step2": "Какво очаквахте да се случи",
"step3": "Какво всъщност се случи",
"step4": "Всяка друга подходяща информация"
},
"reportLink": "Можете да съобщите за проблема в нашия <0>GitHub</0>",
"connectionsLink": "Return to the <0>connections</0>",
"detailsSummary": "Подробности за грешката",
"errorMessageLabel": "Съобщение за грешка:",
"stackTraceLabel": "Stack trace:",
"fallbackError": "{{error}}"
},
"footer": {
"text": "Задвижвано от <0>▲ Vercel</0> | Meshtastic® е регистрирана търговска марка на Meshtastic LLC. | <1>Правна информация</1>",
"commitSha": "Commit SHA: {{sha}}"
}
}

View File

@@ -1,69 +1,71 @@
{
"page": {
"sectionLabel": "Kanály",
"channelName": "Channel: {{channelName}}",
"broadcastLabel": "Primární",
"channelIndex": "Ch {{index}}"
},
"validation": {
"pskInvalid": "Please enter a valid {{bits}} bit PSK."
},
"settings": {
"label": "Nastavení kanálu",
"description": "Crypto, MQTT & misc settings"
},
"role": {
"label": "Role",
"description": "Device telemetry is sent over PRIMARY. Only one PRIMARY allowed",
"options": {
"primary": "PRIMARY",
"disabled": "DISABLED",
"secondary": "SECONDARY"
}
},
"psk": {
"label": "Pre-Shared Key",
"description": "Supported PSK lengths: 256-bit, 128-bit, 8-bit, Empty (0-bit)",
"generate": "Generate"
},
"name": {
"label": "Jméno",
"description": "A unique name for the channel <12 bytes, leave blank for default"
},
"uplinkEnabled": {
"label": "Uplink Enabled",
"description": "Send messages from the local mesh to MQTT"
},
"downlinkEnabled": {
"label": "Downlink Enabled",
"description": "Send messages from MQTT to the local mesh"
},
"positionPrecision": {
"label": "Location",
"description": "The precision of the location to share with the channel. Can be disabled.",
"options": {
"none": "Do not share location",
"precise": "Precise Location",
"metric_km23": "Within 23 kilometers",
"metric_km12": "Within 12 kilometers",
"metric_km5_8": "Within 5.8 kilometers",
"metric_km2_9": "Within 2.9 kilometers",
"metric_km1_5": "Within 1.5 kilometers",
"metric_m700": "Within 700 meters",
"metric_m350": "Within 350 meters",
"metric_m200": "Within 200 meters",
"metric_m90": "Within 90 meters",
"metric_m50": "Within 50 meters",
"imperial_mi15": "Within 15 miles",
"imperial_mi7_3": "Within 7.3 miles",
"imperial_mi3_6": "Within 3.6 miles",
"imperial_mi1_8": "Within 1.8 miles",
"imperial_mi0_9": "Within 0.9 miles",
"imperial_mi0_5": "Within 0.5 miles",
"imperial_mi0_2": "Within 0.2 miles",
"imperial_ft600": "Within 600 feet",
"imperial_ft300": "Within 300 feet",
"imperial_ft150": "Within 150 feet"
}
}
"page": {
"sectionLabel": "Kanály",
"channelName": "Kanál: {{channelName}}",
"broadcastLabel": "Primární",
"channelIndex": "K {{index}}",
"import": "Import",
"export": "Export"
},
"validation": {
"pskInvalid": "Prosím zadejte platný {{bits}} bit PSK."
},
"settings": {
"label": "Nastavení kanálu",
"description": "Krypto, MQTT a další nastavení"
},
"role": {
"label": "Role",
"description": "Telemetrie zařízení je posílána přes PRIMÁRNÍ. Je povolena pouze jedna PRIMÁRNÍ",
"options": {
"primary": "PRIMÁRNÍ",
"disabled": "VYPNUTO",
"secondary": "SEKUNDÁRNÍ"
}
},
"psk": {
"label": "Sdílený klíč",
"description": "Podporované délky PSK: 256-bit, 128-bit, 8-bit, prázdné (0-bit)",
"generate": "Generovat"
},
"name": {
"label": "Jméno",
"description": "Jedinečný název kanálu <12 bytů, ponechte prázdné pro výchozí"
},
"uplinkEnabled": {
"label": "Odesílání povoleno",
"description": "Odesílat zprávy z místní sítě do MQTT"
},
"downlinkEnabled": {
"label": "Stahování povoleno",
"description": "Odesílat zprávy z MQTT do místní sítě"
},
"positionPrecision": {
"label": "Poloha",
"description": "Přesnost umístění, které chcete sdílet s kanálem. Může být vypnuto.",
"options": {
"none": "Nesdílet polohu",
"precise": "Přesná poloha",
"metric_km23": "Okruh 23 kilomet",
"metric_km12": "Okruh 12 kilomet",
"metric_km5_8": "Okruh 5,8 kilomet",
"metric_km2_9": "Okruh 2,9 kilometrů",
"metric_km1_5": "Okruh 1,5 kilometru",
"metric_m700": "Okruh 700 met",
"metric_m350": "Okruh 350 met",
"metric_m200": "Okruh 200 met",
"metric_m90": "Okruh 90 metrů",
"metric_m50": "Okruh 50 metrů",
"imperial_mi15": "Okruh 15 mil",
"imperial_mi7_3": "Okruh 7,3 mil",
"imperial_mi3_6": "Okruh 3,6 mil",
"imperial_mi1_8": "Okruh 1,8 mil",
"imperial_mi0_9": "Okruh 0,9 míle",
"imperial_mi0_5": "Okruh 0,5 míle",
"imperial_mi0_2": "Okruh 0,2 míle",
"imperial_ft600": "Okruh 600 stop",
"imperial_ft300": "Okruh 300 stop",
"imperial_ft150": "Okruh 150 stop"
}
}
}

View File

@@ -15,7 +15,6 @@
"messages": "Zprávy",
"map": "Mapa",
"config": "Config",
"channels": "Kanály",
"nodes": "Uzly"
}
},
@@ -45,7 +44,8 @@
"label": "Debug",
"command": {
"reconfigure": "Reconfigure",
"clearAllStoredMessages": "Clear All Stored Message"
"clearAllStoredMessages": "Clear All Stored Message",
"clearAllStores": "Clear All Local Storage"
}
}
}

View File

@@ -1,142 +1,165 @@
{
"button": {
"apply": "Použít",
"backupKey": "Backup Key",
"cancel": "Zrušit",
"clearMessages": "Clear Messages",
"close": "Zavřít",
"confirm": "Confirm",
"delete": "Smazat",
"dismiss": "Dismiss",
"download": "Download",
"export": "Export",
"generate": "Generate",
"regenerate": "Regenerate",
"import": "Import",
"message": "Zpráva",
"now": "Now",
"ok": "OK",
"print": "Print",
"remove": "Odstranit",
"requestNewKeys": "Request New Keys",
"requestPosition": "Request Position",
"reset": "Reset",
"save": "Uložit",
"scanQr": "Naskenovat QR kód",
"traceRoute": "Trace Route",
"submit": "Submit"
},
"app": {
"title": "Meshtastic",
"fullTitle": "Meshtastic Web Client"
},
"loading": "Loading...",
"unit": {
"cps": "CPS",
"dbm": "dBm",
"hertz": "Hz",
"hop": {
"one": "Hop",
"plural": "Hops"
},
"hopsAway": {
"one": "{{count}} hop away",
"plural": "{{count}} hops away",
"unknown": "Unknown hops away"
},
"megahertz": "MHz",
"raw": "raw",
"meter": {
"one": "Meter",
"plural": "Meters",
"suffix": "m"
},
"minute": {
"one": "Minute",
"plural": "Minutes"
},
"hour": {
"one": "Hour",
"plural": "Hours"
},
"millisecond": {
"one": "Millisecond",
"plural": "Milliseconds",
"suffix": "ms"
},
"second": {
"one": "Second",
"plural": "Seconds"
},
"day": {
"one": "Day",
"plural": "Days"
},
"month": {
"one": "Month",
"plural": "Months"
},
"year": {
"one": "Year",
"plural": "Years"
},
"snr": "SNR",
"volt": {
"one": "Volt",
"plural": "Volts",
"suffix": "V"
},
"record": {
"one": "Records",
"plural": "Records"
}
},
"security": {
"0bit": "Empty",
"8bit": "8 bit",
"128bit": "128 bit",
"256bit": "256 bit"
},
"unknown": {
"longName": "Unknown",
"shortName": "UNK",
"notAvailable": "N/A",
"num": "??"
},
"nodeUnknownPrefix": "!",
"unset": "UNSET",
"fallbackName": "Meshtastic {{last4}}",
"node": "Node",
"formValidation": {
"unsavedChanges": "Unsaved changes",
"tooBig": {
"string": "Too long, expected less than or equal to {{maximum}} characters.",
"number": "Too big, expected a number smaller than or equal to {{maximum}}.",
"bytes": "Too big, expected less than or equal to {{params.maximum}} bytes."
},
"tooSmall": {
"string": "Too short, expected more than or equal to {{minimum}} characters.",
"number": "Too small, expected a number larger than or equal to {{minimum}}."
},
"invalidFormat": {
"ipv4": "Invalid format, expected an IPv4 address.",
"key": "Invalid format, expected a Base64 encoded pre-shared key (PSK)."
},
"invalidType": {
"number": "Invalid type, expected a number."
},
"pskLength": {
"0bit": "Key is required to be empty.",
"8bit": "Key is required to be an 8 bit pre-shared key (PSK).",
"128bit": "Key is required to be a 128 bit pre-shared key (PSK).",
"256bit": "Key is required to be a 256 bit pre-shared key (PSK)."
},
"required": {
"generic": "This field is required.",
"managed": "At least one admin key is requred if the node is managed.",
"key": "Key is required."
}
},
"yes": "Ano",
"no": "Ne"
"button": {
"apply": "Použít",
"addConnection": "Add Connection",
"saveConnection": "Save connection",
"backupKey": "Backup Key",
"cancel": "Zrušit",
"connect": "Připojit",
"clearMessages": "Clear Messages",
"close": "Zavřít",
"confirm": "Confirm",
"delete": "Smazat",
"dismiss": "Dismiss",
"download": "Download",
"disconnect": "Odpojit",
"export": "Export",
"generate": "Generate",
"regenerate": "Regenerate",
"import": "Import",
"message": "Zpráva",
"now": "Now",
"ok": "OK",
"print": "Print",
"remove": "Odstranit",
"requestNewKeys": "Request New Keys",
"requestPosition": "Request Position",
"reset": "Reset",
"retry": "Retry",
"save": "Uložit",
"setDefault": "Set as default",
"unsetDefault": "Unset default",
"scanQr": "Naskenovat QR kód",
"traceRoute": "Trace Route",
"submit": "Submit"
},
"app": {
"title": "Meshtastic",
"fullTitle": "Meshtastic Web Client"
},
"loading": "Loading...",
"unit": {
"cps": "CPS",
"dbm": "dBm",
"hertz": "Hz",
"hop": {
"one": "Hop",
"plural": "Hops"
},
"hopsAway": {
"one": "{{count}} hop away",
"plural": "{{count}} hops away",
"unknown": "Unknown hops away"
},
"megahertz": "MHz",
"kilohertz": "kHz",
"raw": "raw",
"meter": {
"one": "Meter",
"plural": "Meters",
"suffix": "m"
},
"kilometer": {
"one": "Kilometer",
"plural": "Kilometers",
"suffix": "km"
},
"minute": {
"one": "Minute",
"plural": "Minutes"
},
"hour": {
"one": "Hour",
"plural": "Hours"
},
"millisecond": {
"one": "Millisecond",
"plural": "Milliseconds",
"suffix": "ms"
},
"second": {
"one": "Second",
"plural": "Seconds"
},
"day": {
"one": "Day",
"plural": "Days",
"today": "Today",
"yesterday": "Yesterday"
},
"month": {
"one": "Month",
"plural": "Months"
},
"year": {
"one": "Year",
"plural": "Years"
},
"snr": "SNR",
"volt": {
"one": "Volt",
"plural": "Volts",
"suffix": "V"
},
"record": {
"one": "Records",
"plural": "Records"
},
"degree": {
"one": "Degree",
"plural": "Degrees",
"suffix": "°"
}
},
"security": {
"0bit": "Empty",
"8bit": "8 bit",
"128bit": "128 bit",
"256bit": "256 bit"
},
"unknown": {
"longName": "Unknown",
"shortName": "UNK",
"notAvailable": "N/A",
"num": "??"
},
"nodeUnknownPrefix": "!",
"unset": "UNSET",
"fallbackName": "Meshtastic {{last4}}",
"node": "Node",
"formValidation": {
"unsavedChanges": "Unsaved changes",
"tooBig": {
"string": "Too long, expected less than or equal to {{maximum}} characters.",
"number": "Too big, expected a number smaller than or equal to {{maximum}}.",
"bytes": "Too big, expected less than or equal to {{params.maximum}} bytes."
},
"tooSmall": {
"string": "Too short, expected more than or equal to {{minimum}} characters.",
"number": "Too small, expected a number larger than or equal to {{minimum}}."
},
"invalidFormat": {
"ipv4": "Invalid format, expected an IPv4 address.",
"key": "Invalid format, expected a Base64 encoded pre-shared key (PSK)."
},
"invalidType": {
"number": "Invalid type, expected a number."
},
"pskLength": {
"0bit": "Key is required to be empty.",
"8bit": "Key is required to be an 8 bit pre-shared key (PSK).",
"128bit": "Key is required to be a 128 bit pre-shared key (PSK).",
"256bit": "Key is required to be a 256 bit pre-shared key (PSK)."
},
"required": {
"generic": "This field is required.",
"managed": "At least one admin key is requred if the node is managed.",
"key": "Key is required."
},
"invalidOverrideFreq": {
"number": "Invalid format, expected a value in the range 410-930 MHz or 0 (use default)."
}
},
"yes": "Ano",
"no": "Ne"
}

View File

@@ -0,0 +1,458 @@
{
"page": {
"title": "Nastavení",
"tabUser": "Uživatel",
"tabChannels": "Kanály",
"tabBluetooth": "Bluetooth",
"tabDevice": "Zařízení",
"tabDisplay": "Obrazovka",
"tabLora": "LoRa",
"tabNetwork": "Síť",
"tabPosition": "Pozice",
"tabPower": "Napájení",
"tabSecurity": "Zabezpečení"
},
"sidebar": {
"label": "Configuration"
},
"device": {
"title": "Device Settings",
"description": "Settings for the device",
"buttonPin": {
"description": "Button pin override",
"label": "Button Pin"
},
"buzzerPin": {
"description": "Buzzer pin override",
"label": "Buzzer Pin"
},
"disableTripleClick": {
"description": "Disable triple click",
"label": "Disable Triple Click"
},
"doubleTapAsButtonPress": {
"description": "Treat double tap as button press",
"label": "Dvojité klepnutí jako stisk tlačítka"
},
"ledHeartbeatDisabled": {
"description": "Disable default blinking LED",
"label": "LED Heartbeat Disabled"
},
"nodeInfoBroadcastInterval": {
"description": "How often to broadcast node info",
"label": "Interval vysílání NodeInfo (v sekundách)"
},
"posixTimezone": {
"description": "The POSIX timezone string for the device",
"label": "POSIX časové pásmo"
},
"rebroadcastMode": {
"description": "How to handle rebroadcasting",
"label": "Režim opětovného vysílání"
},
"role": {
"description": "What role the device performs on the mesh",
"label": "Role"
}
},
"bluetooth": {
"title": "Nastavení Bluetooth",
"description": "Settings for the Bluetooth module",
"note": "Note: Some devices (ESP32) cannot use both Bluetooth and WiFi at the same time.",
"enabled": {
"description": "Enable or disable Bluetooth",
"label": "Povoleno"
},
"pairingMode": {
"description": "Pin selection behaviour.",
"label": "Režim párování"
},
"pin": {
"description": "Pin to use when pairing",
"label": "Pin"
}
},
"display": {
"description": "Settings for the device display",
"title": "Display Settings",
"headingBold": {
"description": "Bolden the heading text",
"label": "Tučný nadpis"
},
"carouselDelay": {
"description": "How fast to cycle through windows",
"label": "Carousel Delay"
},
"compassNorthTop": {
"description": "Fix north to the top of compass",
"label": "Compass North Top"
},
"displayMode": {
"description": "Screen layout variant",
"label": "Display Mode"
},
"displayUnits": {
"description": "Display metric or imperial units",
"label": "Display Units"
},
"flipScreen": {
"description": "Flip display 180 degrees",
"label": "Flip Screen"
},
"gpsDisplayUnits": {
"description": "Coordinate display format",
"label": "GPS Display Units"
},
"oledType": {
"description": "Type of OLED screen attached to the device",
"label": "OLED Type"
},
"screenTimeout": {
"description": "Turn off the display after this long",
"label": "Screen Timeout"
},
"twelveHourClock": {
"description": "Use 12-hour clock format",
"label": "12-Hour Clock"
},
"wakeOnTapOrMotion": {
"description": "Wake the device on tap or motion",
"label": "Wake on Tap or Motion"
}
},
"lora": {
"title": "Mesh Settings",
"description": "Settings for the LoRa mesh",
"bandwidth": {
"description": "Channel bandwidth in kHz",
"label": "Šířka pásma"
},
"boostedRxGain": {
"description": "Boosted RX gain",
"label": "Boosted RX Gain"
},
"codingRate": {
"description": "The denominator of the coding rate",
"label": "Coding Rate"
},
"frequencyOffset": {
"description": "Frequency offset to correct for crystal calibration errors",
"label": "Frequency Offset"
},
"frequencySlot": {
"description": "LoRa frequency channel number",
"label": "Frekvenční slot"
},
"hopLimit": {
"description": "Maximum number of hops",
"label": "Hop Limit"
},
"ignoreMqtt": {
"description": "Don't forward MQTT messages over the mesh",
"label": "Ignorovat MQTT"
},
"modemPreset": {
"description": "Modem preset to use",
"label": "Předvolba modemu"
},
"okToMqtt": {
"description": "When set to true, this configuration indicates that the user approves the packet to be uploaded to MQTT. If set to false, remote nodes are requested not to forward packets to MQTT",
"label": "OK do MQTT"
},
"overrideDutyCycle": {
"description": "Přepsat střídu",
"label": "Přepsat střídu"
},
"overrideFrequency": {
"description": "Override frequency",
"label": "Override Frequency"
},
"region": {
"description": "Sets the region for your node",
"label": "Region"
},
"spreadingFactor": {
"description": "Indicates the number of chirps per symbol",
"label": "Spreading Factor"
},
"transmitEnabled": {
"description": "Enable/Disable transmit (TX) from the LoRa radio",
"label": "Vysílání povoleno"
},
"transmitPower": {
"description": "Max transmit power",
"label": "Vysílací výkon"
},
"usePreset": {
"description": "Use one of the predefined modem presets",
"label": "Použít předvolbu"
},
"meshSettings": {
"description": "Settings for the LoRa mesh",
"label": "Mesh Settings"
},
"waveformSettings": {
"description": "Settings for the LoRa waveform",
"label": "Waveform Settings"
},
"radioSettings": {
"label": "Radio Settings",
"description": "Settings for the LoRa radio"
}
},
"network": {
"title": "WiFi Config",
"description": "WiFi radio configuration",
"note": "Note: Some devices (ESP32) cannot use both Bluetooth and WiFi at the same time.",
"addressMode": {
"description": "Address assignment selection",
"label": "Address Mode"
},
"dns": {
"description": "DNS Server",
"label": "DNS"
},
"ethernetEnabled": {
"description": "Enable or disable the Ethernet port",
"label": "Povoleno"
},
"gateway": {
"description": "Default Gateway",
"label": "Gateway/Brána"
},
"ip": {
"description": "IP Address",
"label": "IP adresa"
},
"psk": {
"description": "Network password",
"label": "PSK"
},
"ssid": {
"description": "Network name",
"label": "SSID"
},
"subnet": {
"description": "Subnet Mask",
"label": "Podsíť"
},
"wifiEnabled": {
"description": "Enable or disable the WiFi radio",
"label": "Povoleno"
},
"meshViaUdp": {
"label": "Mesh via UDP"
},
"ntpServer": {
"label": "NTP Server"
},
"rsyslogServer": {
"label": "Rsyslog Server"
},
"ethernetConfigSettings": {
"description": "Ethernet port configuration",
"label": "Ethernet Config"
},
"ipConfigSettings": {
"description": "IP configuration",
"label": "IP Config"
},
"ntpConfigSettings": {
"description": "NTP configuration",
"label": "NTP Config"
},
"rsyslogConfigSettings": {
"description": "Rsyslog configuration",
"label": "Rsyslog Config"
},
"udpConfigSettings": {
"description": "UDP over Mesh configuration",
"label": "UDP Konfigurace"
}
},
"position": {
"title": "Position Settings",
"description": "Settings for the position module",
"broadcastInterval": {
"description": "How often your position is sent out over the mesh",
"label": "Interval vysílání"
},
"enablePin": {
"description": "GPS module enable pin override",
"label": "Enable Pin"
},
"fixedPosition": {
"description": "Don't report GPS position, but a manually-specified one",
"label": "Pevná poloha"
},
"gpsMode": {
"description": "Configure whether device GPS is Enabled, Disabled, or Not Present",
"label": "GPS Mode"
},
"gpsUpdateInterval": {
"description": "How often a GPS fix should be acquired",
"label": "GPS Update Interval"
},
"positionFlags": {
"description": "Optional fields to include when assembling position messages. The more fields are selected, the larger the message will be leading to longer airtime usage and a higher risk of packet loss.",
"label": "Příznaky polohy"
},
"receivePin": {
"description": "GPS module RX pin override",
"label": "Receive Pin"
},
"smartPositionEnabled": {
"description": "Only send position when there has been a meaningful change in location",
"label": "Enable Smart Position"
},
"smartPositionMinDistance": {
"description": "Minimum distance (in meters) that must be traveled before a position update is sent",
"label": "Smart Position Minimum Distance"
},
"smartPositionMinInterval": {
"description": "Minimum interval (in seconds) that must pass before a position update is sent",
"label": "Smart Position Minimum Interval"
},
"transmitPin": {
"description": "GPS module TX pin override",
"label": "Transmit Pin"
},
"intervalsSettings": {
"description": "How often to send position updates",
"label": "Intervals"
},
"flags": {
"placeholder": "Select position flags...",
"altitude": "Altitude",
"altitudeGeoidalSeparation": "Altitude Geoidal Separation",
"altitudeMsl": "Altitude is Mean Sea Level",
"dop": "Dilution of precision (DOP) PDOP used by default",
"hdopVdop": "If DOP is set, use HDOP / VDOP values instead of PDOP",
"numSatellites": "Number of satellites",
"sequenceNumber": "Sequence number",
"timestamp": "Časová značka",
"unset": "Zrušit nastavení",
"vehicleHeading": "Vehicle heading",
"vehicleSpeed": "Vehicle speed"
}
},
"power": {
"adcMultiplierOverride": {
"description": "Used for tweaking battery voltage reading",
"label": "ADC Multiplier Override ratio"
},
"ina219Address": {
"description": "Address of the INA219 battery monitor",
"label": "INA219 Address"
},
"lightSleepDuration": {
"description": "How long the device will be in light sleep for",
"label": "Light Sleep Duration"
},
"minimumWakeTime": {
"description": "Minimum amount of time the device will stay awake for after receiving a packet",
"label": "Minimum Wake Time"
},
"noConnectionBluetoothDisabled": {
"description": "If the device does not receive a Bluetooth connection, the BLE radio will be disabled after this long",
"label": "No Connection Bluetooth Disabled"
},
"powerSavingEnabled": {
"description": "Select if powered from a low-current source (i.e. solar), to minimize power consumption as much as possible.",
"label": "Povolit úsporný režim"
},
"shutdownOnBatteryDelay": {
"description": "Automatically shutdown node after this long when on battery, 0 for indefinite",
"label": "Shutdown on battery delay"
},
"superDeepSleepDuration": {
"description": "How long the device will be in super deep sleep for",
"label": "Super Deep Sleep Duration"
},
"powerConfigSettings": {
"description": "Settings for the power module",
"label": "Nastavení napájení"
},
"sleepSettings": {
"description": "Sleep settings for the power module",
"label": "Sleep Settings"
}
},
"security": {
"description": "Settings for the Security configuration",
"title": "Security Settings",
"button_backupKey": "Backup Key",
"adminChannelEnabled": {
"description": "Allow incoming device control over the insecure legacy admin channel",
"label": "Allow Legacy Admin"
},
"enableDebugLogApi": {
"description": "Output live debug logging over serial, view and export position-redacted device logs over Bluetooth",
"label": "Enable Debug Log API"
},
"managed": {
"description": "If enabled, device configuration options are only able to be changed remotely by a Remote Admin node via admin messages. Do not enable this option unless at least one suitable Remote Admin node has been setup, and the public key is stored in one of the fields above.",
"label": "Managed"
},
"privateKey": {
"description": "Used to create a shared key with a remote device",
"label": "Soukromý klíč"
},
"publicKey": {
"description": "Sent out to other nodes on the mesh to allow them to compute a shared secret key",
"label": "Veřejný klíč"
},
"primaryAdminKey": {
"description": "The primary public key authorized to send admin messages to this node",
"label": "Primary Admin Key"
},
"secondaryAdminKey": {
"description": "The secondary public key authorized to send admin messages to this node",
"label": "Secondary Admin Key"
},
"serialOutputEnabled": {
"description": "Serial Console over the Stream API",
"label": "Serial Output Enabled"
},
"tertiaryAdminKey": {
"description": "The tertiary public key authorized to send admin messages to this node",
"label": "Tertiary Admin Key"
},
"adminSettings": {
"description": "Settings for Admin",
"label": "Admin Settings"
},
"loggingSettings": {
"description": "Settings for Logging",
"label": "Logging Settings"
}
},
"user": {
"title": "User Settings",
"description": "Configure your device name and identity settings",
"longName": {
"label": "Dlouhé jméno",
"description": "Your full display name (1-40 characters)",
"validation": {
"min": "Long name must be at least 1 character",
"max": "Long name must be at most 40 characters"
}
},
"shortName": {
"label": "Krátké jméno",
"description": "Your abbreviated name (2-4 characters)",
"validation": {
"min": "Short name must be at least 2 characters",
"max": "Short name must be at most 4 characters"
}
},
"isUnmessageable": {
"label": "Nepřijímá zprávy",
"description": "Used to identify unmonitored or infrastructure nodes so that messaging is not available to nodes that will never respond."
},
"isLicensed": {
"label": "Licencované amatérské rádio (HAM)",
"description": "Enable if you are a licensed amateur radio operator, enabling this option disables encryption and is not compatible with the default Meshtastic network."
}
}
}

View File

@@ -0,0 +1,34 @@
{
"page": {
"title": "Connect to a Meshtastic device",
"description": "Add a device connection via HTTP, Bluetooth, or Serial. Your saved connections will be saved in your browser."
},
"connectionType_ble": "BLE",
"connectionType_serial": "Sériový",
"connectionType_network": "Síť",
"deleteConnection": "Delete connection",
"areYouSure": "This will remove {{name}}. You canot undo this action.",
"moreActions": "More actions",
"noConnections": {
"title": "No connections yet.",
"description": "Create your first connection. It will connect immediately and be saved for later."
},
"lastConnectedAt": "Last connected: {{date}}",
"neverConnected": "Never connected",
"toasts": {
"connected": "Připojeno",
"nowConnected": "{{name}} is now connected",
"nowDisconnected": "{{name}} are now disconnecte",
"disconnected": "Odpojeno",
"failed": "Failed to connect",
"checkConnetion": "Check your device or settings and try again",
"defaultSet": "Default set",
"defaultConnection": "Default connection is now {{nameisconnected}}",
"deleted": "Deleted",
"deletedByName": "{{name}} was removed",
"pickConnectionAgain": "Could not connect. You may need to reselect the device/port.",
"added": "Connection added",
"savedByName": "{{name}} saved.",
"savedCantConnect": "The connection was saved but could not connect."
}
}

View File

@@ -1,12 +0,0 @@
{
"dashboard": {
"title": "Connected Devices",
"description": "Manage your connected Meshtastic devices.",
"connectionType_ble": "BLE",
"connectionType_serial": "Sériový",
"connectionType_network": "Síť",
"noDevicesTitle": "No devices connected",
"noDevicesDescription": "Connect a new device to get started.",
"button_newConnection": "New Connection"
}
}

View File

@@ -122,7 +122,7 @@
"title": "Mesh Settings",
"description": "Settings for the LoRa mesh",
"bandwidth": {
"description": "Channel bandwidth in MHz",
"description": "Channel bandwidth in kHz",
"label": "Šířka pásma"
},
"boostedRxGain": {

View File

@@ -1,193 +1,238 @@
{
"deleteMessages": {
"description": "This action will clear all message history. This cannot be undone. Are you sure you want to continue?",
"title": "Clear All Messages"
},
"deviceName": {
"description": "The Device will restart once the config is saved.",
"longName": "Long Name",
"shortName": "Short Name",
"title": "Change Device Name",
"validation": {
"longNameMax": "Long name must not be more than 40 characters",
"shortNameMax": "Short name must not be more than 4 characters",
"longNameMin": "Long name must have at least 1 character",
"shortNameMin": "Short name must have at least 1 character"
}
},
"import": {
"description": "The current LoRa configuration will be overridden.",
"error": {
"invalidUrl": "Invalid Meshtastic URL"
},
"channelPrefix": "Channel: ",
"channelSetUrl": "Channel Set/QR Code URL",
"channels": "Channels:",
"usePreset": "Use Preset?",
"title": "Import Channel Set"
},
"locationResponse": {
"title": "Location: {{identifier}}",
"altitude": "Altitude: ",
"coordinates": "Coordinates: ",
"noCoordinates": "No Coordinates"
},
"pkiRegenerateDialog": {
"title": "Regenerate Pre-Shared Key?",
"description": "Are you sure you want to regenerate the pre-shared key?",
"regenerate": "Regenerate"
},
"newDeviceDialog": {
"title": "Connect New Device",
"https": "https",
"http": "http",
"tabHttp": "HTTP",
"tabBluetooth": "Bluetooth",
"tabSerial": "Sériový",
"useHttps": "Use HTTPS",
"connecting": "Connecting...",
"connect": "Connect",
"connectionFailedAlert": {
"title": "Connection Failed",
"descriptionPrefix": "Could not connect to the device. ",
"httpsHint": "If using HTTPS, you may need to accept a self-signed certificate first. ",
"openLinkPrefix": "Please open ",
"openLinkSuffix": " in a new tab",
"acceptTlsWarningSuffix": ", accept any TLS warnings if prompted, then try again",
"learnMoreLink": "Learn more"
},
"httpConnection": {
"label": "IP Address/Hostname",
"placeholder": "000.000.000.000 / meshtastic.local"
},
"serialConnection": {
"noDevicesPaired": "No devices paired yet.",
"newDeviceButton": "New device",
"deviceIdentifier": "# {{index}} - {{vendorId}} - {{productId}}"
},
"bluetoothConnection": {
"noDevicesPaired": "No devices paired yet.",
"newDeviceButton": "New device",
"connectionFailed": "Connection failed",
"deviceDisconnected": "Device disconnected",
"unknownDevice": "Unknown Device",
"errorLoadingDevices": "Error loading devices",
"unknownErrorLoadingDevices": "Unknown error loading devices"
},
"validation": {
"requiresWebBluetooth": "This connection type requires <0>Web Bluetooth</0>. Please use a supported browser, like Chrome or Edge.",
"requiresWebSerial": "This connection type requires <0>Web Serial</0>. Please use a supported browser, like Chrome or Edge.",
"requiresSecureContext": "This application requires a <0>secure context</0>. Please connect using HTTPS or localhost.",
"additionallyRequiresSecureContext": "Additionally, it requires a <0>secure context</0>. Please connect using HTTPS or localhost."
}
},
"nodeDetails": {
"message": "Zpráva",
"requestPosition": "Request Position",
"traceRoute": "Trace Route",
"airTxUtilization": "Air TX utilization",
"allRawMetrics": "All Raw Metrics:",
"batteryLevel": "Battery level",
"channelUtilization": "Channel utilization",
"details": "Details:",
"deviceMetrics": "Device Metrics:",
"hardware": "Hardware: ",
"lastHeard": "Last Heard: ",
"nodeHexPrefix": "Node Hex: ",
"nodeNumber": "Node Number: ",
"position": "Position:",
"role": "Role: ",
"uptime": "Uptime: ",
"voltage": "Napětí",
"title": "Node Details for {{identifier}}",
"ignoreNode": "Ignore node",
"removeNode": "Remove node",
"unignoreNode": "Unignore node",
"security": "Security:",
"publicKey": "Public Key: ",
"messageable": "Messageable: ",
"KeyManuallyVerifiedTrue": "Public Key has been manually verified",
"KeyManuallyVerifiedFalse": "Public Key is not manually verified"
},
"pkiBackup": {
"loseKeysWarning": "If you lose your keys, you will need to reset your device.",
"secureBackup": "Its important to backup your public and private keys and store your backup securely!",
"footer": "=== END OF KEYS ===",
"header": "=== MESHTASTIC KEYS FOR {{longName}} ({{shortName}}) ===",
"privateKey": "Private Key:",
"publicKey": "Public Key:",
"fileName": "meshtastic_keys_{{longName}}_{{shortName}}.txt",
"title": "Backup Keys"
},
"pkiBackupReminder": {
"description": "We recommend backing up your key data regularly. Would you like to back up now?",
"title": "Backup Reminder",
"remindLaterPrefix": "Remind me in",
"remindNever": "Never remind me",
"backupNow": "Back up now"
},
"pkiRegenerate": {
"description": "Are you sure you want to regenerate key pair?",
"title": "Regenerate Key Pair"
},
"qr": {
"addChannels": "Add Channels",
"replaceChannels": "Replace Channels",
"description": "The current LoRa configuration will also be shared.",
"sharableUrl": "Sharable URL",
"title": "Generate QR Code"
},
"reboot": {
"title": "Reboot device",
"description": "Reboot now or schedule a reboot of the connected node. Optionally, you can choose to reboot into OTA (Over-the-Air) mode.",
"ota": "Reboot into OTA mode",
"enterDelay": "Enter delay",
"scheduled": "Reboot has been scheduled",
"schedule": "Schedule reboot",
"now": "Reboot now",
"cancel": "Cancel scheduled reboot"
},
"refreshKeys": {
"description": {
"acceptNewKeys": "This will remove the node from device and request new keys.",
"keyMismatchReasonSuffix": ". This is due to the remote node's current public key does not match the previously stored key for this node.",
"unableToSendDmPrefix": "Your node is unable to send a direct message to node: "
},
"acceptNewKeys": "Accept New Keys",
"title": "Keys Mismatch - {{identifier}}"
},
"removeNode": {
"description": "Are you sure you want to remove this Node?",
"title": "Remove Node?"
},
"shutdown": {
"title": "Schedule Shutdown",
"description": "Turn off the connected node after x minutes."
},
"traceRoute": {
"routeToDestination": "Route to destination:",
"routeBack": "Route back:"
},
"tracerouteResponse": {
"title": "Traceroute: {{identifier}}"
},
"unsafeRoles": {
"confirmUnderstanding": "Yes, I know what I'm doing",
"conjunction": " and the blog post about ",
"postamble": " and understand the implications of changing the role.",
"preamble": "I have read the ",
"choosingRightDeviceRole": "Choosing The Right Device Role",
"deviceRoleDocumentation": "Device Role Documentation",
"title": "Jste si jistý?"
},
"managedMode": {
"confirmUnderstanding": "Yes, I know what I'm doing",
"title": "Jste si jistý?",
"description": "Enabling Managed Mode blocks client applications (including the web client) from writing configurations to a radio. Once enabled, radio configurations can only be changed through Remote Admin messages. This setting is not required for remote node administration."
},
"clientNotification": {
"title": "Oznámení klienta",
"TraceRoute can only be sent once every 30 seconds": "TraceRoute can only be sent once every 30 seconds",
"Compromised keys were detected and regenerated.": "Compromised keys were detected and regenerated."
}
"deleteMessages": {
"description": "This action will clear all message history. This cannot be undone. Are you sure you want to continue?",
"title": "Clear All Messages"
},
"import": {
"description": "The current LoRa configuration will be overridden.",
"error": {
"invalidUrl": "Invalid Meshtastic URL"
},
"channelPrefix": "Channel: ",
"primary": "Primary ",
"doNotImport": "No not import",
"channelName": "Jméno",
"channelSlot": "Slot",
"channelSetUrl": "Channel Set/QR Code URL",
"useLoraConfig": "Import LoRa Config",
"presetDescription": "The current LoRa Config will be replaced.",
"title": "Import Channel Set"
},
"locationResponse": {
"title": "Location: {{identifier}}",
"altitude": "Altitude: ",
"coordinates": "Coordinates: ",
"noCoordinates": "No Coordinates"
},
"pkiRegenerateDialog": {
"title": "Regenerate Pre-Shared Key?",
"description": "Are you sure you want to regenerate the pre-shared key?",
"regenerate": "Regenerate"
},
"addConnection": {
"title": "Add connection",
"description": "Choose a connection type and fill in the details",
"validation": {
"requiresWebBluetooth": "This connection type requires <0>Web Bluetooth</0>. Please use a supported browser, like Chrome or Edge.",
"requiresWebSerial": "This connection type requires <0>Web Serial</0>. Please use a supported browser, like Chrome or Edge.",
"requiresSecureContext": "This application requires a <0>secure context</0>. Please connect using HTTPS or localhost.",
"additionallyRequiresSecureContext": "Additionally, it requires a <0>secure context</0>. Please connect using HTTPS or localhost."
},
"bluetoothConnection": {
"namePlaceholder": "My Bluetooth Node",
"supported": {
"title": "Web Bluetooth supported"
},
"notSupported": {
"title": "Web Bluetooth not supported",
"description": "Your browser or device does not support Web Bluetooth"
},
"short": "BT: {{deviceName}}",
"long": "Bluetooth Device",
"device": "Zařízení",
"selectDevice": "Select device",
"selected": "Bluetooth device selected",
"notSelected": "No device selected",
"helperText": "Uses the Meshtastic Bluetooth service for discovery."
},
"serialConnection": {
"namePlaceholder": "My Serial Node",
"helperText": "Selecting a port grants permission so the app can open it to connect.",
"supported": {
"title": "Web Serial supported"
},
"notSupported": {
"title": "Web Serial not supported",
"description": "Your browser or device does not support Web Serial"
},
"portSelected": {
"title": "Serial port selected",
"description": "Port permissions granted."
},
"port": "Port",
"selectPort": "Select port",
"deviceName": "USB {{vendorId}}:{{productId}}",
"notSelected": "No port selected"
},
"httpConnection": {
"namePlaceholder": "My HTTP Node",
"inputPlaceholder": "192.168.1.10 or meshtastic.local",
"heading": "URL or IP",
"useHttps": "Use HTTTPS",
"invalidUrl": {
"title": "Invalid URL",
"description": "Please enter a valid HTTP or HTTPS URL."
},
"connectionTest": {
"description": "Test the connetion before saving to verify the device is reachable.",
"button": {
"loading": "Testing...",
"label": "Test connection"
},
"reachable": "Reachable",
"notReachable": "Not reachable",
"success": {
"title": "Connection test successful",
"description": "The device appears to be reachable."
},
"failure": {
"title": "Connection test failed",
"description": "Could not reach the device. Check the URL and try again."
}
}
}
},
"nodeDetails": {
"message": "Zpráva",
"requestPosition": "Request Position",
"traceRoute": "Trace Route",
"airTxUtilization": "Air TX utilization",
"allRawMetrics": "All Raw Metrics:",
"batteryLevel": "Battery level",
"channelUtilization": "Channel utilization",
"details": "Details:",
"deviceMetrics": "Device Metrics:",
"hardware": "Hardware: ",
"lastHeard": "Last Heard: ",
"nodeHexPrefix": "Node Hex: ",
"nodeNumber": "Node Number: ",
"position": "Position:",
"role": "Role: ",
"uptime": "Uptime: ",
"voltage": "Napětí",
"title": "Node Details for {{identifier}}",
"ignoreNode": "Ignore node",
"removeNode": "Remove node",
"unignoreNode": "Unignore node",
"security": "Security:",
"publicKey": "Public Key: ",
"messageable": "Messageable: ",
"KeyManuallyVerifiedTrue": "Public Key has been manually verified",
"KeyManuallyVerifiedFalse": "Public Key is not manually verified"
},
"pkiBackup": {
"loseKeysWarning": "If you lose your keys, you will need to reset your device.",
"secureBackup": "Its important to backup your public and private keys and store your backup securely!",
"footer": "=== END OF KEYS ===",
"header": "=== MESHTASTIC KEYS FOR {{longName}} ({{shortName}}) ===",
"privateKey": "Private Key:",
"publicKey": "Public Key:",
"fileName": "meshtastic_keys_{{longName}}_{{shortName}}.txt",
"title": "Backup Keys"
},
"pkiBackupReminder": {
"description": "We recommend backing up your key data regularly. Would you like to back up now?",
"title": "Backup Reminder",
"remindLaterPrefix": "Remind me in",
"remindNever": "Never remind me",
"backupNow": "Back up now"
},
"pkiRegenerate": {
"description": "Are you sure you want to regenerate key pair?",
"title": "Regenerate Key Pair"
},
"qr": {
"addChannels": "Add Channels",
"replaceChannels": "Replace Channels",
"description": "The current LoRa configuration will also be shared.",
"sharableUrl": "Sharable URL",
"title": "Generate QR Code"
},
"reboot": {
"title": "Reboot device",
"description": "Reboot now or schedule a reboot of the connected node. Optionally, you can choose to reboot into OTA (Over-the-Air) mode.",
"ota": "Reboot into OTA mode",
"enterDelay": "Enter delay",
"scheduled": "Reboot has been scheduled",
"schedule": "Schedule reboot",
"now": "Reboot now",
"cancel": "Cancel scheduled reboot"
},
"refreshKeys": {
"description": {
"acceptNewKeys": "This will remove the node from device and request new keys.",
"keyMismatchReasonSuffix": ". This is due to the remote node's current public key does not match the previously stored key for this node.",
"unableToSendDmPrefix": "Your node is unable to send a direct message to node: "
},
"acceptNewKeys": "Accept New Keys",
"title": "Keys Mismatch - {{identifier}}"
},
"removeNode": {
"description": "Are you sure you want to remove this Node?",
"title": "Remove Node?"
},
"shutdown": {
"title": "Schedule Shutdown",
"description": "Turn off the connected node after x minutes."
},
"traceRoute": {
"routeToDestination": "Route to destination:",
"routeBack": "Route back:"
},
"tracerouteResponse": {
"title": "Traceroute: {{identifier}}"
},
"unsafeRoles": {
"confirmUnderstanding": "Yes, I know what I'm doing",
"conjunction": " and the blog post about ",
"postamble": " and understand the implications of changing the role.",
"preamble": "I have read the ",
"choosingRightDeviceRole": "Choosing The Right Device Role",
"deviceRoleDocumentation": "Device Role Documentation",
"title": "Jste si jistý?"
},
"managedMode": {
"confirmUnderstanding": "Yes, I know what I'm doing",
"title": "Jste si jistý?",
"description": "Enabling Managed Mode blocks client applications (including the web client) from writing configurations to a radio. Once enabled, radio configurations can only be changed through Remote Admin messages. This setting is not required for remote node administration."
},
"clientNotification": {
"title": "Oznámení klienta",
"TraceRoute can only be sent once every 30 seconds": "TraceRoute can only be sent once every 30 seconds",
"Compromised keys were detected and regenerated.": "Compromised keys were detected and regenerated."
},
"resetNodeDb": {
"title": "Reset Node Database",
"description": "This will clear all nodes from the connected device's node database and clear all message history in the client. This cannot be undone. Are you sure you want to continue?",
"confirm": "Reset Node Database",
"failedTitle": "There was an error resetting the Node DB. Please try again."
},
"clearAllStores": {
"title": "Clear All Local Storage",
"description": "This will clear all locally stored data, including message history and node databases for all previously connected devices. This will require you to reconnect to your node once complete and cannot be undone. Are you sure you want to continue?",
"confirm": "Clear all local storage",
"failedTitle": "There was an error clearing local storage. Please try again."
},
"factoryResetDevice": {
"title": "Factory Reset Device",
"description": "This will factory reset the connected device, erasing all configurations and data on the device as well as all nodes and messages saved in the client. This cannot be undone. Are you sure you want to continue?",
"confirm": "Factory Reset Device",
"failedTitle": "There was an error performing the factory reset. Please try again."
},
"factoryResetConfig": {
"title": "Factory Reset Config",
"description": "This will factory reset the configuration on the connected device, erasing all configurations on the device. This cannot be undone. Are you sure you want to continue?",
"confirm": "Factory Reset Config",
"failedTitle": "There was an error performing the factory reset. Please try again."
}
}

View File

@@ -0,0 +1,38 @@
{
"maplibre": {
"GeolocateControl.FindMyLocation": "Find my location",
"NavigationControl.ZoomIn": "Zoom in",
"NavigationControl.ZoomOut": "Zoom out",
"CooperativeGesturesHandler.WindowsHelpText": "Use Ctrl + scroll to zoom the map",
"CooperativeGesturesHandler.MacHelpText": "Use ⌘ + scroll to zoom the map",
"CooperativeGesturesHandler.MobileHelpText": "Use two fingers to move the map"
},
"layerTool": {
"nodeMarkers": "Show nodes",
"directNeighbors": "Show direct connections",
"remoteNeighbors": "Show remote connections",
"positionPrecision": "Show position precision",
"traceroutes": "Show traceroutes",
"waypoints": "Show waypoints"
},
"mapMenu": {
"locateAria": "Locate my node",
"layersAria": "Change map style"
},
"waypointDetail": {
"edit": "Upravit",
"description": "Description:",
"createdBy": "Edited by:",
"createdDate": "Created:",
"updated": "Updated:",
"expires": "Expires:",
"distance": "Distance:",
"bearing": "Absolute bearing:",
"lockedTo": "Locked by:",
"latitude": "Latitude:",
"longitude": "Longitude:"
},
"myNode": {
"tooltip": "This device"
}
}

View File

@@ -1,39 +1,39 @@
{
"page": {
"title": "Messages: {{chatName}}",
"placeholder": "Enter Message"
},
"emptyState": {
"title": "Select a Chat",
"text": "No messages yet."
},
"selectChatPrompt": {
"text": "Select a channel or node to start messaging."
},
"sendMessage": {
"placeholder": "Enter your message here...",
"sendButton": "Odeslat"
},
"actionsMenu": {
"addReactionLabel": "Add Reaction",
"replyLabel": "Reply"
},
"deliveryStatus": {
"delivered": {
"label": "Message delivered",
"displayText": "Message delivered"
},
"failed": {
"label": "Message delivery failed",
"displayText": "Delivery failed"
},
"unknown": {
"label": "Message status unknown",
"displayText": "Unknown state"
},
"waiting": {
"label": "Sending message",
"displayText": "Waiting for delivery"
}
}
"page": {
"title": "Messages: {{chatName}}",
"placeholder": "Enter Message"
},
"emptyState": {
"title": "Select a Chat",
"text": "No messages yet."
},
"selectChatPrompt": {
"text": "Select a channel or node to start messaging."
},
"sendMessage": {
"placeholder": "Enter your message here...",
"sendButton": "Odeslat"
},
"actionsMenu": {
"addReactionLabel": "Add Reaction",
"replyLabel": "Reply"
},
"deliveryStatus": {
"delivered": {
"label": "Message delivered",
"displayText": "Message delivered"
},
"failed": {
"label": "Message delivery failed",
"displayText": "Delivery failed"
},
"unknown": {
"label": "Message status unknown",
"displayText": "Unknown state"
},
"waiting": {
"label": "Sending message",
"displayText": "Waiting for delivery"
}
}
}

View File

@@ -1,448 +1,448 @@
{
"page": {
"tabAmbientLighting": "Ambientní osvětlení",
"tabAudio": "Zvuk",
"tabCannedMessage": "Canned",
"tabDetectionSensor": "Detekční senzor",
"tabExternalNotification": "Ext Notif",
"tabMqtt": "MQTT",
"tabNeighborInfo": "Informace o sousedech",
"tabPaxcounter": "Paxcounter",
"tabRangeTest": "Zkouška dosahu",
"tabSerial": "Sériový",
"tabStoreAndForward": "S&F",
"tabTelemetry": "Telemetrie"
},
"ambientLighting": {
"title": "Ambient Lighting Settings",
"description": "Settings for the Ambient Lighting module",
"ledState": {
"label": "LED State",
"description": "Sets LED to on or off"
},
"current": {
"label": "Proud",
"description": "Sets the current for the LED output. Default is 10"
},
"red": {
"label": "Červená",
"description": "Sets the red LED level. Values are 0-255"
},
"green": {
"label": "Zelená",
"description": "Sets the green LED level. Values are 0-255"
},
"blue": {
"label": "Modrá",
"description": "Sets the blue LED level. Values are 0-255"
}
},
"audio": {
"title": "Audio Settings",
"description": "Settings for the Audio module",
"codec2Enabled": {
"label": "Codec 2 Enabled",
"description": "Enable Codec 2 audio encoding"
},
"pttPin": {
"label": "PTT Pin",
"description": "GPIO pin to use for PTT"
},
"bitrate": {
"label": "Bitrate",
"description": "Bitrate to use for audio encoding"
},
"i2sWs": {
"label": "i2S WS",
"description": "GPIO pin to use for i2S WS"
},
"i2sSd": {
"label": "i2S SD",
"description": "GPIO pin to use for i2S SD"
},
"i2sDin": {
"label": "i2S DIN",
"description": "GPIO pin to use for i2S DIN"
},
"i2sSck": {
"label": "i2S SCK",
"description": "GPIO pin to use for i2S SCK"
}
},
"cannedMessage": {
"title": "Canned Message Settings",
"description": "Settings for the Canned Message module",
"moduleEnabled": {
"label": "Module Enabled",
"description": "Enable Canned Message"
},
"rotary1Enabled": {
"label": "Rotary Encoder #1 Enabled",
"description": "Enable the rotary encoder"
},
"inputbrokerPinA": {
"label": "Encoder Pin A",
"description": "GPIO Pin Value (1-39) For encoder port A"
},
"inputbrokerPinB": {
"label": "Encoder Pin B",
"description": "GPIO Pin Value (1-39) For encoder port B"
},
"inputbrokerPinPress": {
"label": "Encoder Pin Press",
"description": "GPIO Pin Value (1-39) For encoder Press"
},
"inputbrokerEventCw": {
"label": "Clockwise event",
"description": "Select input event."
},
"inputbrokerEventCcw": {
"label": "Counter Clockwise event",
"description": "Select input event."
},
"inputbrokerEventPress": {
"label": "Press event",
"description": "Select input event"
},
"updown1Enabled": {
"label": "Up Down enabled",
"description": "Enable the up / down encoder"
},
"allowInputSource": {
"label": "Allow Input Source",
"description": "Select from: '_any', 'rotEnc1', 'upDownEnc1', 'cardkb'"
},
"sendBell": {
"label": "Send Bell",
"description": "Sends a bell character with each message"
}
},
"detectionSensor": {
"title": "Detection Sensor Settings",
"description": "Settings for the Detection Sensor module",
"enabled": {
"label": "Povoleno",
"description": "Enable or disable Detection Sensor Module"
},
"minimumBroadcastSecs": {
"label": "Minimum Broadcast Seconds",
"description": "The interval in seconds of how often we can send a message to the mesh when a state change is detected"
},
"stateBroadcastSecs": {
"label": "State Broadcast Seconds",
"description": "The interval in seconds of how often we should send a message to the mesh with the current state regardless of changes"
},
"sendBell": {
"label": "Send Bell",
"description": "Send ASCII bell with alert message"
},
"name": {
"label": "Friendly Name",
"description": "Used to format the message sent to mesh, max 20 Characters"
},
"monitorPin": {
"label": "Monitor Pin",
"description": "The GPIO pin to monitor for state changes"
},
"detectionTriggerType": {
"label": "Detection Triggered Type",
"description": "The type of trigger event to be used"
},
"usePullup": {
"label": "Use Pullup",
"description": "Whether or not use INPUT_PULLUP mode for GPIO pin"
}
},
"externalNotification": {
"title": "External Notification Settings",
"description": "Configure the external notification module",
"enabled": {
"label": "Module Enabled",
"description": "Enable External Notification"
},
"outputMs": {
"label": "Output MS",
"description": "Output MS"
},
"output": {
"label": "Output",
"description": "Output"
},
"outputVibra": {
"label": "Output Vibrate",
"description": "Output Vibrate"
},
"outputBuzzer": {
"label": "Output Buzzer",
"description": "Output Buzzer"
},
"active": {
"label": "Active",
"description": "Active"
},
"alertMessage": {
"label": "Alert Message",
"description": "Alert Message"
},
"alertMessageVibra": {
"label": "Alert Message Vibrate",
"description": "Alert Message Vibrate"
},
"alertMessageBuzzer": {
"label": "Alert Message Buzzer",
"description": "Alert Message Buzzer"
},
"alertBell": {
"label": "Alert Bell",
"description": "Should an alert be triggered when receiving an incoming bell?"
},
"alertBellVibra": {
"label": "Alert Bell Vibrate",
"description": "Alert Bell Vibrate"
},
"alertBellBuzzer": {
"label": "Alert Bell Buzzer",
"description": "Alert Bell Buzzer"
},
"usePwm": {
"label": "Use PWM",
"description": "Use PWM"
},
"nagTimeout": {
"label": "Nag Timeout",
"description": "Nag Timeout"
},
"useI2sAsBuzzer": {
"label": "Use I²S Pin as Buzzer",
"description": "Designate I²S Pin as Buzzer Output"
}
},
"mqtt": {
"title": "MQTT Settings",
"description": "Settings for the MQTT module",
"enabled": {
"label": "Povoleno",
"description": "Enable or disable MQTT"
},
"address": {
"label": "MQTT Server Address",
"description": "MQTT server address to use for default/custom servers"
},
"username": {
"label": "MQTT Username",
"description": "MQTT username to use for default/custom servers"
},
"password": {
"label": "MQTT Password",
"description": "MQTT password to use for default/custom servers"
},
"encryptionEnabled": {
"label": "Encryption Enabled",
"description": "Enable or disable MQTT encryption. Note: All messages are sent to the MQTT broker unencrypted if this option is not enabled, even when your uplink channels have encryption keys set. This includes position data."
},
"jsonEnabled": {
"label": "JSON Enabled",
"description": "Whether to send/consume JSON packets on MQTT"
},
"tlsEnabled": {
"label": "TLS povoleno",
"description": "Enable or disable TLS"
},
"root": {
"label": "Kořenové téma",
"description": "MQTT root topic to use for default/custom servers"
},
"proxyToClientEnabled": {
"label": "MQTT Client Proxy Enabled",
"description": "Utilizes the network connection to proxy MQTT messages to the client."
},
"mapReportingEnabled": {
"label": "Map Reporting Enabled",
"description": "Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, short and long name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name."
},
"mapReportSettings": {
"publishIntervalSecs": {
"label": "Map Report Publish Interval (s)",
"description": "Interval in seconds to publish map reports"
},
"positionPrecision": {
"label": "Approximate Location",
"description": "Position shared will be accurate within this distance",
"options": {
"metric_km23": "Within 23 km",
"metric_km12": "Within 12 km",
"metric_km5_8": "Within 5.8 km",
"metric_km2_9": "Within 2.9 km",
"metric_km1_5": "Within 1.5 km",
"metric_m700": "Within 700 m",
"metric_m350": "Within 350 m",
"metric_m200": "Within 200 m",
"metric_m90": "Within 90 m",
"metric_m50": "Within 50 m",
"imperial_mi15": "Within 15 miles",
"imperial_mi7_3": "Within 7.3 miles",
"imperial_mi3_6": "Within 3.6 miles",
"imperial_mi1_8": "Within 1.8 miles",
"imperial_mi0_9": "Within 0.9 miles",
"imperial_mi0_5": "Within 0.5 miles",
"imperial_mi0_2": "Within 0.2 miles",
"imperial_ft600": "Within 600 feet",
"imperial_ft300": "Within 300 feet",
"imperial_ft150": "Within 150 feet"
}
}
}
},
"neighborInfo": {
"title": "Neighbor Info Settings",
"description": "Settings for the Neighbor Info module",
"enabled": {
"label": "Povoleno",
"description": "Enable or disable Neighbor Info Module"
},
"updateInterval": {
"label": "Update Interval",
"description": "Interval in seconds of how often we should try to send our Neighbor Info to the mesh"
}
},
"paxcounter": {
"title": "Paxcounter Settings",
"description": "Settings for the Paxcounter module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Paxcounter"
},
"paxcounterUpdateInterval": {
"label": "Update Interval (seconds)",
"description": "How long to wait between sending paxcounter packets"
},
"wifiThreshold": {
"label": "WiFi RSSI Threshold",
"description": "At what WiFi RSSI level should the counter increase. Defaults to -80."
},
"bleThreshold": {
"label": "BLE RSSI Threshold",
"description": "At what BLE RSSI level should the counter increase. Defaults to -80."
}
},
"rangeTest": {
"title": "Range Test Settings",
"description": "Settings for the Range Test module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Range Test"
},
"sender": {
"label": "Message Interval",
"description": "How long to wait between sending test packets"
},
"save": {
"label": "Save CSV to storage",
"description": "ESP32 Only"
}
},
"serial": {
"title": "Serial Settings",
"description": "Settings for the Serial module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Serial output"
},
"echo": {
"label": "Echo",
"description": "Any packets you send will be echoed back to your device"
},
"rxd": {
"label": "Receive Pin",
"description": "Set the GPIO pin to the RXD pin you have set up."
},
"txd": {
"label": "Transmit Pin",
"description": "Set the GPIO pin to the TXD pin you have set up."
},
"baud": {
"label": "Baud Rate",
"description": "The serial baud rate"
},
"timeout": {
"label": "Vypršel čas spojení",
"description": "Seconds to wait before we consider your packet as 'done'"
},
"mode": {
"label": "Mode",
"description": "Select Mode"
},
"overrideConsoleSerialPort": {
"label": "Override Console Serial Port",
"description": "If you have a serial port connected to the console, this will override it."
}
},
"storeForward": {
"title": "Store & Forward Settings",
"description": "Settings for the Store & Forward module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Store & Forward"
},
"heartbeat": {
"label": "Heartbeat Enabled",
"description": "Enable Store & Forward heartbeat"
},
"records": {
"label": "Počet záznamů",
"description": "Number of records to store"
},
"historyReturnMax": {
"label": "History return max",
"description": "Max number of records to return"
},
"historyReturnWindow": {
"label": "History return window",
"description": "Max number of records to return"
}
},
"telemetry": {
"title": "Telemetry Settings",
"description": "Settings for the Telemetry module",
"deviceUpdateInterval": {
"label": "Device Metrics",
"description": "Interval aktualizace metrik zařízení (v sekundách)"
},
"environmentUpdateInterval": {
"label": "Interval aktualizace metrik životního prostředí (v sekundách)",
"description": ""
},
"environmentMeasurementEnabled": {
"label": "Module Enabled",
"description": "Enable the Environment Telemetry"
},
"environmentScreenEnabled": {
"label": "Displayed on Screen",
"description": "Show the Telemetry Module on the OLED"
},
"environmentDisplayFahrenheit": {
"label": "Display Fahrenheit",
"description": "Display temp in Fahrenheit"
},
"airQualityEnabled": {
"label": "Air Quality Enabled",
"description": "Enable the Air Quality Telemetry"
},
"airQualityInterval": {
"label": "Air Quality Update Interval",
"description": "How often to send Air Quality data over the mesh"
},
"powerMeasurementEnabled": {
"label": "Power Measurement Enabled",
"description": "Enable the Power Measurement Telemetry"
},
"powerUpdateInterval": {
"label": "Power Update Interval",
"description": "How often to send Power data over the mesh"
},
"powerScreenEnabled": {
"label": "Power Screen Enabled",
"description": "Enable the Power Telemetry Screen"
}
}
"page": {
"tabAmbientLighting": "Ambientní osvětlení",
"tabAudio": "Zvuk",
"tabCannedMessage": "Canned",
"tabDetectionSensor": "Detekční senzor",
"tabExternalNotification": "Ext Notif",
"tabMqtt": "MQTT",
"tabNeighborInfo": "Informace o sousedech",
"tabPaxcounter": "Paxcounter",
"tabRangeTest": "Zkouška dosahu",
"tabSerial": "Sériový",
"tabStoreAndForward": "S&F",
"tabTelemetry": "Telemetrie"
},
"ambientLighting": {
"title": "Ambient Lighting Settings",
"description": "Settings for the Ambient Lighting module",
"ledState": {
"label": "LED State",
"description": "Sets LED to on or off"
},
"current": {
"label": "Proud",
"description": "Sets the current for the LED output. Default is 10"
},
"red": {
"label": "Červená",
"description": "Sets the red LED level. Values are 0-255"
},
"green": {
"label": "Zelená",
"description": "Sets the green LED level. Values are 0-255"
},
"blue": {
"label": "Modrá",
"description": "Sets the blue LED level. Values are 0-255"
}
},
"audio": {
"title": "Audio Settings",
"description": "Settings for the Audio module",
"codec2Enabled": {
"label": "Codec 2 Enabled",
"description": "Enable Codec 2 audio encoding"
},
"pttPin": {
"label": "PTT Pin",
"description": "GPIO pin to use for PTT"
},
"bitrate": {
"label": "Bitrate",
"description": "Bitrate to use for audio encoding"
},
"i2sWs": {
"label": "i2S WS",
"description": "GPIO pin to use for i2S WS"
},
"i2sSd": {
"label": "i2S SD",
"description": "GPIO pin to use for i2S SD"
},
"i2sDin": {
"label": "i2S DIN",
"description": "GPIO pin to use for i2S DIN"
},
"i2sSck": {
"label": "i2S SCK",
"description": "GPIO pin to use for i2S SCK"
}
},
"cannedMessage": {
"title": "Canned Message Settings",
"description": "Settings for the Canned Message module",
"moduleEnabled": {
"label": "Module Enabled",
"description": "Enable Canned Message"
},
"rotary1Enabled": {
"label": "Rotary Encoder #1 Enabled",
"description": "Enable the rotary encoder"
},
"inputbrokerPinA": {
"label": "Encoder Pin A",
"description": "GPIO Pin Value (1-39) For encoder port A"
},
"inputbrokerPinB": {
"label": "Encoder Pin B",
"description": "GPIO Pin Value (1-39) For encoder port B"
},
"inputbrokerPinPress": {
"label": "Encoder Pin Press",
"description": "GPIO Pin Value (1-39) For encoder Press"
},
"inputbrokerEventCw": {
"label": "Clockwise event",
"description": "Select input event."
},
"inputbrokerEventCcw": {
"label": "Counter Clockwise event",
"description": "Select input event."
},
"inputbrokerEventPress": {
"label": "Press event",
"description": "Select input event"
},
"updown1Enabled": {
"label": "Up Down enabled",
"description": "Enable the up / down encoder"
},
"allowInputSource": {
"label": "Allow Input Source",
"description": "Select from: '_any', 'rotEnc1', 'upDownEnc1', 'cardkb'"
},
"sendBell": {
"label": "Send Bell",
"description": "Sends a bell character with each message"
}
},
"detectionSensor": {
"title": "Detection Sensor Settings",
"description": "Settings for the Detection Sensor module",
"enabled": {
"label": "Povoleno",
"description": "Enable or disable Detection Sensor Module"
},
"minimumBroadcastSecs": {
"label": "Minimum Broadcast Seconds",
"description": "The interval in seconds of how often we can send a message to the mesh when a state change is detected"
},
"stateBroadcastSecs": {
"label": "State Broadcast Seconds",
"description": "The interval in seconds of how often we should send a message to the mesh with the current state regardless of changes"
},
"sendBell": {
"label": "Send Bell",
"description": "Send ASCII bell with alert message"
},
"name": {
"label": "Friendly Name",
"description": "Used to format the message sent to mesh, max 20 Characters"
},
"monitorPin": {
"label": "Monitor Pin",
"description": "The GPIO pin to monitor for state changes"
},
"detectionTriggerType": {
"label": "Detection Triggered Type",
"description": "The type of trigger event to be used"
},
"usePullup": {
"label": "Use Pullup",
"description": "Whether or not use INPUT_PULLUP mode for GPIO pin"
}
},
"externalNotification": {
"title": "External Notification Settings",
"description": "Configure the external notification module",
"enabled": {
"label": "Module Enabled",
"description": "Enable External Notification"
},
"outputMs": {
"label": "Output MS",
"description": "Output MS"
},
"output": {
"label": "Output",
"description": "Output"
},
"outputVibra": {
"label": "Output Vibrate",
"description": "Output Vibrate"
},
"outputBuzzer": {
"label": "Output Buzzer",
"description": "Output Buzzer"
},
"active": {
"label": "Active",
"description": "Active"
},
"alertMessage": {
"label": "Alert Message",
"description": "Alert Message"
},
"alertMessageVibra": {
"label": "Alert Message Vibrate",
"description": "Alert Message Vibrate"
},
"alertMessageBuzzer": {
"label": "Alert Message Buzzer",
"description": "Alert Message Buzzer"
},
"alertBell": {
"label": "Alert Bell",
"description": "Should an alert be triggered when receiving an incoming bell?"
},
"alertBellVibra": {
"label": "Alert Bell Vibrate",
"description": "Alert Bell Vibrate"
},
"alertBellBuzzer": {
"label": "Alert Bell Buzzer",
"description": "Alert Bell Buzzer"
},
"usePwm": {
"label": "Use PWM",
"description": "Use PWM"
},
"nagTimeout": {
"label": "Nag Timeout",
"description": "Nag Timeout"
},
"useI2sAsBuzzer": {
"label": "Use I²S Pin as Buzzer",
"description": "Designate I²S Pin as Buzzer Output"
}
},
"mqtt": {
"title": "MQTT Settings",
"description": "Settings for the MQTT module",
"enabled": {
"label": "Povoleno",
"description": "Enable or disable MQTT"
},
"address": {
"label": "MQTT Server Address",
"description": "MQTT server address to use for default/custom servers"
},
"username": {
"label": "MQTT Username",
"description": "MQTT username to use for default/custom servers"
},
"password": {
"label": "MQTT Password",
"description": "MQTT password to use for default/custom servers"
},
"encryptionEnabled": {
"label": "Encryption Enabled",
"description": "Enable or disable MQTT encryption. Note: All messages are sent to the MQTT broker unencrypted if this option is not enabled, even when your uplink channels have encryption keys set. This includes position data."
},
"jsonEnabled": {
"label": "JSON Enabled",
"description": "Whether to send/consume JSON packets on MQTT"
},
"tlsEnabled": {
"label": "TLS povoleno",
"description": "Enable or disable TLS"
},
"root": {
"label": "Kořenové téma",
"description": "MQTT root topic to use for default/custom servers"
},
"proxyToClientEnabled": {
"label": "MQTT Client Proxy Enabled",
"description": "Utilizes the network connection to proxy MQTT messages to the client."
},
"mapReportingEnabled": {
"label": "Map Reporting Enabled",
"description": "Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, short and long name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name."
},
"mapReportSettings": {
"publishIntervalSecs": {
"label": "Map Report Publish Interval (s)",
"description": "Interval in seconds to publish map reports"
},
"positionPrecision": {
"label": "Approximate Location",
"description": "Position shared will be accurate within this distance",
"options": {
"metric_km23": "Within 23 km",
"metric_km12": "Within 12 km",
"metric_km5_8": "Within 5.8 km",
"metric_km2_9": "Within 2.9 km",
"metric_km1_5": "Within 1.5 km",
"metric_m700": "Within 700 m",
"metric_m350": "Within 350 m",
"metric_m200": "Within 200 m",
"metric_m90": "Within 90 m",
"metric_m50": "Within 50 m",
"imperial_mi15": "Within 15 miles",
"imperial_mi7_3": "Within 7.3 miles",
"imperial_mi3_6": "Within 3.6 miles",
"imperial_mi1_8": "Within 1.8 miles",
"imperial_mi0_9": "Within 0.9 miles",
"imperial_mi0_5": "Within 0.5 miles",
"imperial_mi0_2": "Within 0.2 miles",
"imperial_ft600": "Within 600 feet",
"imperial_ft300": "Within 300 feet",
"imperial_ft150": "Within 150 feet"
}
}
}
},
"neighborInfo": {
"title": "Neighbor Info Settings",
"description": "Settings for the Neighbor Info module",
"enabled": {
"label": "Povoleno",
"description": "Enable or disable Neighbor Info Module"
},
"updateInterval": {
"label": "Update Interval",
"description": "Interval in seconds of how often we should try to send our Neighbor Info to the mesh"
}
},
"paxcounter": {
"title": "Paxcounter Settings",
"description": "Settings for the Paxcounter module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Paxcounter"
},
"paxcounterUpdateInterval": {
"label": "Update Interval (seconds)",
"description": "How long to wait between sending paxcounter packets"
},
"wifiThreshold": {
"label": "WiFi RSSI Threshold",
"description": "At what WiFi RSSI level should the counter increase. Defaults to -80."
},
"bleThreshold": {
"label": "BLE RSSI Threshold",
"description": "At what BLE RSSI level should the counter increase. Defaults to -80."
}
},
"rangeTest": {
"title": "Range Test Settings",
"description": "Settings for the Range Test module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Range Test"
},
"sender": {
"label": "Message Interval",
"description": "How long to wait between sending test packets"
},
"save": {
"label": "Save CSV to storage",
"description": "ESP32 Only"
}
},
"serial": {
"title": "Serial Settings",
"description": "Settings for the Serial module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Serial output"
},
"echo": {
"label": "Echo",
"description": "Any packets you send will be echoed back to your device"
},
"rxd": {
"label": "Receive Pin",
"description": "Set the GPIO pin to the RXD pin you have set up."
},
"txd": {
"label": "Transmit Pin",
"description": "Set the GPIO pin to the TXD pin you have set up."
},
"baud": {
"label": "Baud Rate",
"description": "The serial baud rate"
},
"timeout": {
"label": "Vypršel čas spojení",
"description": "Seconds to wait before we consider your packet as 'done'"
},
"mode": {
"label": "Mode",
"description": "Select Mode"
},
"overrideConsoleSerialPort": {
"label": "Override Console Serial Port",
"description": "If you have a serial port connected to the console, this will override it."
}
},
"storeForward": {
"title": "Store & Forward Settings",
"description": "Settings for the Store & Forward module",
"enabled": {
"label": "Module Enabled",
"description": "Enable Store & Forward"
},
"heartbeat": {
"label": "Heartbeat Enabled",
"description": "Enable Store & Forward heartbeat"
},
"records": {
"label": "Počet záznamů",
"description": "Number of records to store"
},
"historyReturnMax": {
"label": "History return max",
"description": "Max number of records to return"
},
"historyReturnWindow": {
"label": "History return window",
"description": "Return records from this time window (minutes)"
}
},
"telemetry": {
"title": "Telemetry Settings",
"description": "Settings for the Telemetry module",
"deviceUpdateInterval": {
"label": "Device Metrics",
"description": "Interval aktualizace metrik zařízení (v sekundách)"
},
"environmentUpdateInterval": {
"label": "Interval aktualizace metrik životního prostředí (v sekundách)",
"description": ""
},
"environmentMeasurementEnabled": {
"label": "Module Enabled",
"description": "Enable the Environment Telemetry"
},
"environmentScreenEnabled": {
"label": "Displayed on Screen",
"description": "Show the Telemetry Module on the OLED"
},
"environmentDisplayFahrenheit": {
"label": "Display Fahrenheit",
"description": "Display temp in Fahrenheit"
},
"airQualityEnabled": {
"label": "Air Quality Enabled",
"description": "Enable the Air Quality Telemetry"
},
"airQualityInterval": {
"label": "Air Quality Update Interval",
"description": "How often to send Air Quality data over the mesh"
},
"powerMeasurementEnabled": {
"label": "Power Measurement Enabled",
"description": "Enable the Power Measurement Telemetry"
},
"powerUpdateInterval": {
"label": "Power Update Interval",
"description": "How often to send Power data over the mesh"
},
"powerScreenEnabled": {
"label": "Power Screen Enabled",
"description": "Enable the Power Telemetry Screen"
}
}
}

View File

@@ -1,63 +1,59 @@
{
"nodeDetail": {
"publicKeyEnabled": {
"label": "Public Key Enabled"
},
"noPublicKey": {
"label": "No Public Key"
},
"directMessage": {
"label": "Direct Message {{shortName}}"
},
"favorite": {
"label": "Oblíbené",
"tooltip": "Add or remove this node from your favorites"
},
"notFavorite": {
"label": "Not a Favorite"
},
"error": {
"label": "Chyba",
"text": "An error occurred while fetching node details. Please try again later."
},
"status": {
"heard": "Heard",
"mqtt": "MQTT"
},
"elevation": {
"label": "Elevation"
},
"channelUtil": {
"label": "Channel Util"
},
"airtimeUtil": {
"label": "Airtime Util"
}
},
"nodesTable": {
"headings": {
"longName": "Long Name",
"connection": "Connection",
"lastHeard": "Last Heard",
"encryption": "Encryption",
"model": "Model",
"macAddress": "MAC Address"
},
"connectionStatus": {
"direct": "Přímý",
"away": "away",
"unknown": "-",
"viaMqtt": ", via MQTT"
},
"lastHeardStatus": {
"never": "Never"
}
},
"actions": {
"added": "Added",
"removed": "Removed",
"ignoreNode": "Ignore Node",
"unignoreNode": "Unignore Node",
"requestPosition": "Request Position"
}
"nodeDetail": {
"publicKeyEnabled": {
"label": "Public Key Enabled"
},
"noPublicKey": {
"label": "No Public Key"
},
"directMessage": {
"label": "Direct Message {{shortName}}"
},
"favorite": {
"label": "Oblíbené",
"tooltip": "Add or remove this node from your favorites"
},
"notFavorite": {
"label": "Not a Favorite"
},
"error": {
"label": "Chyba",
"text": "An error occurred while fetching node details. Please try again later."
},
"status": {
"heard": "Heard",
"mqtt": "MQTT"
},
"elevation": {
"label": "Elevation"
},
"channelUtil": {
"label": "Channel Util"
},
"airtimeUtil": {
"label": "Airtime Util"
}
},
"nodesTable": {
"headings": {
"longName": "Long Name",
"connection": "Connection",
"lastHeard": "Last Heard",
"encryption": "Encryption",
"model": "Model",
"macAddress": "MAC Address"
},
"connectionStatus": {
"direct": "Přímý",
"away": "away",
"viaMqtt": ", via MQTT"
}
},
"actions": {
"added": "Added",
"removed": "Removed",
"ignoreNode": "Ignore Node",
"unignoreNode": "Unignore Node",
"requestPosition": "Request Position"
}
}

View File

@@ -1,228 +1,230 @@
{
"navigation": {
"title": "Navigation",
"messages": "Zprávy",
"map": "Mapa",
"config": "Config",
"radioConfig": "Radio Config",
"moduleConfig": "Module Config",
"channels": "Kanály",
"nodes": "Uzly"
},
"app": {
"title": "Meshtastic",
"logo": "Meshtastic Logo"
},
"sidebar": {
"collapseToggle": {
"button": {
"open": "Open sidebar",
"close": "Close sidebar"
}
},
"deviceInfo": {
"volts": "{{voltage}} volts",
"firmware": {
"title": "Firmware",
"version": "v{{version}}",
"buildDate": "Build date: {{date}}"
},
"deviceName": {
"title": "Device Name",
"changeName": "Change Device Name",
"placeholder": "Enter device name"
},
"editDeviceName": "Edit device name"
}
},
"batteryStatus": {
"charging": "{{level}}% charging",
"pluggedIn": "Plugged in",
"title": "Baterie"
},
"search": {
"nodes": "Search nodes...",
"channels": "Search channels...",
"commandPalette": "Search commands..."
},
"toast": {
"positionRequestSent": {
"title": "Position request sent."
},
"requestingPosition": {
"title": "Requesting position, please wait..."
},
"sendingTraceroute": {
"title": "Sending Traceroute, please wait..."
},
"tracerouteSent": {
"title": "Traceroute sent."
},
"savedChannel": {
"title": "Saved Channel: {{channelName}}"
},
"messages": {
"pkiEncryption": {
"title": "Chat is using PKI encryption."
},
"pskEncryption": {
"title": "Chat is using PSK encryption."
}
},
"configSaveError": {
"title": "Error Saving Config",
"description": "An error occurred while saving the configuration."
},
"validationError": {
"title": "Config Errors Exist",
"description": "Please fix the configuration errors before saving."
},
"saveSuccess": {
"title": "Saving Config",
"description": "The configuration change {{case}} has been saved."
},
"favoriteNode": {
"title": "{{action}} {{nodeName}} {{direction}} favorites.",
"action": {
"added": "Added",
"removed": "Removed",
"to": "to",
"from": "from"
}
},
"ignoreNode": {
"title": "{{action}} {{nodeName}} {{direction}} ignore list",
"action": {
"added": "Added",
"removed": "Removed",
"to": "to",
"from": "from"
}
}
},
"notifications": {
"copied": {
"label": "Copied!"
},
"copyToClipboard": {
"label": "Copy to clipboard"
},
"hidePassword": {
"label": "Skrýt heslo"
},
"showPassword": {
"label": "Zobrazit heslo"
},
"deliveryStatus": {
"delivered": "Delivered",
"failed": "Delivery Failed",
"waiting": "Waiting",
"unknown": "Unknown"
}
},
"general": {
"label": "General"
},
"hardware": {
"label": "Hardware"
},
"metrics": {
"label": "Metriky"
},
"role": {
"label": "Role"
},
"filter": {
"label": "Filtr"
},
"advanced": {
"label": "Advanced"
},
"clearInput": {
"label": "Clear input"
},
"resetFilters": {
"label": "Reset Filters"
},
"nodeName": {
"label": "Node name/number",
"placeholder": "Meshtastic 1234"
},
"airtimeUtilization": {
"label": "Airtime Utilization (%)"
},
"batteryLevel": {
"label": "Battery level (%)",
"labelText": "Battery level (%): {{value}}"
},
"batteryVoltage": {
"label": "Battery voltage (V)",
"title": "Napětí"
},
"channelUtilization": {
"label": "Channel Utilization (%)"
},
"hops": {
"direct": "Přímý",
"label": "Number of hops",
"text": "Number of hops: {{value}}"
},
"lastHeard": {
"label": "Naposledy slyšen",
"labelText": "Last heard: {{value}}",
"nowLabel": "Now"
},
"snr": {
"label": "SNR (db)"
},
"favorites": {
"label": "Favorites"
},
"hide": {
"label": "Hide"
},
"showOnly": {
"label": "Show Only"
},
"viaMqtt": {
"label": "Connected via MQTT"
},
"hopsUnknown": {
"label": "Unknown number of hops"
},
"showUnheard": {
"label": "Never heard"
},
"language": {
"label": "Jazyk",
"changeLanguage": "Change Language"
},
"theme": {
"dark": "Tmavý",
"light": "Světlý",
"system": "Automatic",
"changeTheme": "Change Color Scheme"
},
"errorPage": {
"title": "This is a little embarrassing...",
"description1": "We are really sorry but an error occurred in the web client that caused it to crash. <br /> This is not supposed to happen, and we are working hard to fix it.",
"description2": "The best way to prevent this from happening again to you or anyone else is to report the issue to us.",
"reportInstructions": "Please include the following information in your report:",
"reportSteps": {
"step1": "What you were doing when the error occurred",
"step2": "What you expected to happen",
"step3": "What actually happened",
"step4": "Any other relevant information"
},
"reportLink": "You can report the issue to our <0>GitHub</0>",
"dashboardLink": "Return to the <0>dashboard</0>",
"detailsSummary": "Error Details",
"errorMessageLabel": "Error message:",
"stackTraceLabel": "Stack trace:",
"fallbackError": "{{error}}"
},
"footer": {
"text": "Powered by <0>▲ Vercel</0> | Meshtastic® is a registered trademark of Meshtastic LLC. | <1>Legal Information</1>",
"commitSha": "Commit SHA: {{sha}}"
}
"navigation": {
"title": "Navigation",
"messages": "Zprávy",
"map": "Mapa",
"settings": "Nastavení",
"channels": "Kanály",
"radioConfig": "Radio Config",
"deviceConfig": "Nastavení zařízení",
"moduleConfig": "Module Config",
"manageConnections": "Manage Connections",
"nodes": "Uzly"
},
"app": {
"title": "Meshtastic",
"logo": "Meshtastic Logo"
},
"sidebar": {
"collapseToggle": {
"button": {
"open": "Open sidebar",
"close": "Close sidebar"
}
},
"deviceInfo": {
"volts": "{{voltage}} volts",
"firmware": {
"title": "Firmware",
"version": "v{{version}}",
"buildDate": "Build date: {{date}}"
}
}
},
"batteryStatus": {
"charging": "{{level}}% charging",
"pluggedIn": "Plugged in",
"title": "Baterie"
},
"search": {
"nodes": "Search nodes...",
"channels": "Search channels...",
"commandPalette": "Search commands..."
},
"toast": {
"positionRequestSent": {
"title": "Position request sent."
},
"requestingPosition": {
"title": "Requesting position, please wait..."
},
"sendingTraceroute": {
"title": "Sending Traceroute, please wait..."
},
"tracerouteSent": {
"title": "Traceroute sent."
},
"savedChannel": {
"title": "Saved Channel: {{channelName}}"
},
"messages": {
"pkiEncryption": {
"title": "Chat is using PKI encryption."
},
"pskEncryption": {
"title": "Chat is using PSK encryption."
}
},
"configSaveError": {
"title": "Error Saving Config",
"description": "An error occurred while saving the configuration."
},
"validationError": {
"title": "Config Errors Exist",
"description": "Please fix the configuration errors before saving."
},
"saveSuccess": {
"title": "Saving Config",
"description": "The configuration change {{case}} has been saved."
},
"saveAllSuccess": {
"title": "Saved",
"description": "All configuration changes have been saved."
},
"favoriteNode": {
"title": "{{action}} {{nodeName}} {{direction}} favorites.",
"action": {
"added": "Added",
"removed": "Removed",
"to": "to",
"from": "from"
}
},
"ignoreNode": {
"title": "{{action}} {{nodeName}} {{direction}} ignore list",
"action": {
"added": "Added",
"removed": "Removed",
"to": "to",
"from": "from"
}
}
},
"notifications": {
"copied": {
"label": "Copied!"
},
"copyToClipboard": {
"label": "Copy to clipboard"
},
"hidePassword": {
"label": "Skrýt heslo"
},
"showPassword": {
"label": "Zobrazit heslo"
},
"deliveryStatus": {
"delivered": "Delivered",
"failed": "Delivery Failed",
"waiting": "Waiting",
"unknown": "Unknown"
}
},
"general": {
"label": "General"
},
"hardware": {
"label": "Hardware"
},
"metrics": {
"label": "Metriky"
},
"role": {
"label": "Role"
},
"filter": {
"label": "Filtr"
},
"advanced": {
"label": "Advanced"
},
"clearInput": {
"label": "Clear input"
},
"resetFilters": {
"label": "Reset Filters"
},
"nodeName": {
"label": "Node name/number",
"placeholder": "Meshtastic 1234"
},
"airtimeUtilization": {
"label": "Airtime Utilization (%)",
"short": "Airtime Util. (%)"
},
"batteryLevel": {
"label": "Battery level (%)",
"labelText": "Battery level (%): {{value}}"
},
"batteryVoltage": {
"label": "Battery voltage (V)",
"title": "Napětí"
},
"channelUtilization": {
"label": "Channel Utilization (%)",
"short": "Channel Util. (%)"
},
"hops": {
"direct": "Přímý",
"label": "Number of hops",
"text": "Number of hops: {{value}}"
},
"lastHeard": {
"label": "Naposledy slyšen",
"labelText": "Last heard: {{value}}",
"nowLabel": "Now"
},
"snr": {
"label": "SNR (db)"
},
"favorites": {
"label": "Favorites"
},
"hide": {
"label": "Hide"
},
"showOnly": {
"label": "Show Only"
},
"viaMqtt": {
"label": "Connected via MQTT"
},
"hopsUnknown": {
"label": "Unknown number of hops"
},
"showUnheard": {
"label": "Never heard"
},
"language": {
"label": "Jazyk",
"changeLanguage": "Change Language"
},
"theme": {
"dark": "Tmavý",
"light": "Světlý",
"system": "Automatic",
"changeTheme": "Change Color Scheme"
},
"errorPage": {
"title": "This is a little embarrassing...",
"description1": "We are really sorry but an error occurred in the web client that caused it to crash. <br /> This is not supposed to happen, and we are working hard to fix it.",
"description2": "The best way to prevent this from happening again to you or anyone else is to report the issue to us.",
"reportInstructions": "Please include the following information in your report:",
"reportSteps": {
"step1": "What you were doing when the error occurred",
"step2": "What you expected to happen",
"step3": "What actually happened",
"step4": "Any other relevant information"
},
"reportLink": "You can report the issue to our <0>GitHub</0>",
"connectionsLink": "Return to the <0>connections</0>",
"detailsSummary": "Error Details",
"errorMessageLabel": "Error message:",
"stackTraceLabel": "Stack trace:",
"fallbackError": "{{error}}"
},
"footer": {
"text": "Powered by <0>▲ Vercel</0> | Meshtastic® is a registered trademark of Meshtastic LLC. | <1>Legal Information</1>",
"commitSha": "Commit SHA: {{sha}}"
}
}

View File

@@ -1,69 +1,71 @@
{
"page": {
"sectionLabel": "Kanäle",
"channelName": "Kanal {{channelName}}",
"broadcastLabel": "Primär",
"channelIndex": "Kanal {{index}}"
},
"validation": {
"pskInvalid": "Bitte geben Sie einen gültigen {{bits}} Bit PSK Schlüssel ein."
},
"settings": {
"label": "Kanaleinstellungen",
"description": "Verschlüsselung, MQTT & sonstige Einstellungen"
},
"role": {
"label": "Rolle",
"description": "Gerätetelemetrie wird über den PRIMÄR Kanal gesendet. Nur ein PRIMÄR Kanal ist erlaubt.",
"options": {
"primary": "PRIMÄR",
"disabled": "DEAKTIVIERT",
"secondary": "SEKUNDÄR"
}
},
"psk": {
"label": "Vorher verteilter Schlüssel",
"description": "Unterstützte PSK-Längen: 256-Bit, 128-Bit, 8-Bit, leer (0-Bit)",
"generate": "Erzeugen"
},
"name": {
"label": "Name",
"description": "Ein eindeutiger Name für den Kanal <12 Bytes. Leer lassen für Standard."
},
"uplinkEnabled": {
"label": "Uplink aktiviert",
"description": "Nachrichten vom lokalen Netz über MQTT versenden"
},
"downlinkEnabled": {
"label": "Downlink aktiviert",
"description": "Nachrichten von MQTT im lokalen Netz versenden"
},
"positionPrecision": {
"label": "Standort",
"description": "Die Genauigkeit des Standorts, die in diesem Kanal geteilt werden soll. Kann deaktiviert werden.",
"options": {
"none": "Standort nicht freigeben",
"precise": "Genauer Standort",
"metric_km23": "Innerhalb von 23 Kilometern",
"metric_km12": "Innerhalb von 12 Kilometern",
"metric_km5_8": "Innerhalb von 5,8 Kilometern",
"metric_km2_9": "Innerhalb von 2,9 Kilometern",
"metric_km1_5": "Innerhalb von 1,5 Kilometern",
"metric_m700": "Innerhalb von 700 Metern",
"metric_m350": "Innerhalb von 350 Metern",
"metric_m200": "Innerhalb von 200 Metern",
"metric_m90": "Innerhalb von 90 Metern",
"metric_m50": "Innerhalb von 50 Metern",
"imperial_mi15": "Innerhalb von 15 Meilen",
"imperial_mi7_3": "Innerhalb von 7,3 Meilen",
"imperial_mi3_6": "Innerhalb von 3,6 Meilen",
"imperial_mi1_8": "Innerhalb von 1,8 Meilen",
"imperial_mi0_9": "Innerhalb von 0,9 Meilen",
"imperial_mi0_5": "Innerhalb von 0,5 Meilen",
"imperial_mi0_2": "Innerhalb von 0,2 Meilen",
"imperial_ft600": "Innerhalb von 600 Fuß",
"imperial_ft300": "Innerhalb von 300 Fuß",
"imperial_ft150": "Innerhalb von 150 Fuß"
}
}
"page": {
"sectionLabel": "Kanäle",
"channelName": "Kanal {{channelName}}",
"broadcastLabel": "Primär",
"channelIndex": "Kanal {{index}}",
"import": "Importieren",
"export": "Exportieren"
},
"validation": {
"pskInvalid": "Bitte geben Sie einen gültigen {{bits}} Bit PSK Schlüssel ein."
},
"settings": {
"label": "Kanaleinstellungen",
"description": "Verschlüsselung, MQTT & sonstige Einstellungen"
},
"role": {
"label": "Rolle",
"description": "Gerätetelemetrie wird über den PRIMÄR Kanal gesendet. Nur ein PRIMÄR Kanal ist erlaubt.",
"options": {
"primary": "PRIMÄR",
"disabled": "DEAKTIVIERT",
"secondary": "SEKUNDÄR"
}
},
"psk": {
"label": "Vorher verteilter Schlüssel",
"description": "Unterstützte PSK-Längen: 256-Bit, 128-Bit, 8-Bit, leer (0-Bit)",
"generate": "Erzeugen"
},
"name": {
"label": "Name",
"description": "Ein eindeutiger Name für den Kanal <12 Bytes. Leer lassen für Standard."
},
"uplinkEnabled": {
"label": "Uplink aktiviert",
"description": "Nachrichten vom lokalen Netz über MQTT versenden"
},
"downlinkEnabled": {
"label": "Downlink aktiviert",
"description": "Nachrichten von MQTT im lokalen Netz versenden"
},
"positionPrecision": {
"label": "Standort",
"description": "Die Genauigkeit des Standorts, die in diesem Kanal geteilt werden soll. Kann deaktiviert werden.",
"options": {
"none": "Standort nicht freigeben",
"precise": "Genauer Standort",
"metric_km23": "Innerhalb von 23 Kilometern",
"metric_km12": "Innerhalb von 12 Kilometern",
"metric_km5_8": "Innerhalb von 5,8 Kilometern",
"metric_km2_9": "Innerhalb von 2,9 Kilometern",
"metric_km1_5": "Innerhalb von 1,5 Kilometern",
"metric_m700": "Innerhalb von 700 Metern",
"metric_m350": "Innerhalb von 350 Metern",
"metric_m200": "Innerhalb von 200 Metern",
"metric_m90": "Innerhalb von 90 Metern",
"metric_m50": "Innerhalb von 50 Metern",
"imperial_mi15": "Innerhalb von 15 Meilen",
"imperial_mi7_3": "Innerhalb von 7,3 Meilen",
"imperial_mi3_6": "Innerhalb von 3,6 Meilen",
"imperial_mi1_8": "Innerhalb von 1,8 Meilen",
"imperial_mi0_9": "Innerhalb von 0,9 Meilen",
"imperial_mi0_5": "Innerhalb von 0,5 Meilen",
"imperial_mi0_2": "Innerhalb von 0,2 Meilen",
"imperial_ft600": "Innerhalb von 600 Fuß",
"imperial_ft300": "Innerhalb von 300 Fuß",
"imperial_ft150": "Innerhalb von 150 Fuß"
}
}
}

View File

@@ -15,7 +15,6 @@
"messages": "Nachrichten",
"map": "Karte",
"config": "Einstellungen",
"channels": "Kanäle",
"nodes": "Knoten"
}
},
@@ -45,7 +44,8 @@
"label": "Debug",
"command": {
"reconfigure": "Neu einrichten",
"clearAllStoredMessages": "Alle gespeicherten Nachrichten löschen"
"clearAllStoredMessages": "Alle gespeicherten Nachrichten löschen",
"clearAllStores": "Lösche den gesamten lokalen Speicher"
}
}
}

View File

@@ -1,142 +1,165 @@
{
"button": {
"apply": "Anwenden",
"backupKey": "Schlüssel sichern",
"cancel": "Abbrechen",
"clearMessages": "Nachrichten löschen",
"close": "Schließen",
"confirm": "Bestätigen",
"delete": "Löschen",
"dismiss": "Tastatur ausblenden",
"download": "Herunterladen",
"export": "Exportieren",
"generate": "Erzeugen",
"regenerate": "Neu erzeugen",
"import": "Importieren",
"message": "Nachricht",
"now": "Jetzt",
"ok": "Ok",
"print": "Drucken",
"remove": "Entfernen",
"requestNewKeys": "Neue Schlüssel anfordern",
"requestPosition": "Standort anfordern",
"reset": "Zurücksetzen",
"save": "Speichern",
"scanQr": "QR Code scannen",
"traceRoute": "Route verfolgen",
"submit": "Absenden"
},
"app": {
"title": "Meshtastic",
"fullTitle": "Meshtastic Web-Applikation"
},
"loading": "Wird geladen...",
"unit": {
"cps": "CPS",
"dbm": "dBm",
"hertz": "Hz",
"hop": {
"one": "Sprung",
"plural": "Sprünge"
},
"hopsAway": {
"one": "{{count}} Sprung entfernt",
"plural": "{{count}} Sprünge entfernt",
"unknown": "Sprungweite unbekannt"
},
"megahertz": "MHz",
"raw": "Einheitslos",
"meter": {
"one": "Meter",
"plural": "Meter",
"suffix": "m"
},
"minute": {
"one": "Minute",
"plural": "Minuten"
},
"hour": {
"one": "Stunde",
"plural": "Stunden"
},
"millisecond": {
"one": "Millisekunde",
"plural": "Millisekunden",
"suffix": "ms"
},
"second": {
"one": "Sekunde",
"plural": "Sekunden"
},
"day": {
"one": "Tag",
"plural": "Tage"
},
"month": {
"one": "Monat",
"plural": "Monate"
},
"year": {
"one": "Jahr",
"plural": "Jahre"
},
"snr": "SNR",
"volt": {
"one": "Volt",
"plural": "Volt",
"suffix": "V"
},
"record": {
"one": "Datensatz",
"plural": "Datensätze"
}
},
"security": {
"0bit": "Leer",
"8bit": "8 Bit",
"128bit": "128 Bit",
"256bit": "256 Bit"
},
"unknown": {
"longName": "Unbekannt",
"shortName": "UNB",
"notAvailable": "Keine Angaben",
"num": "???"
},
"nodeUnknownPrefix": "!",
"unset": "NICHT GESETZT",
"fallbackName": "Meshtastic {{last4}}",
"node": "Knoten",
"formValidation": {
"unsavedChanges": "Ungespeicherte Änderungen",
"tooBig": {
"string": "Zu lang, erwarte maximal {{maximum}} Zeichen.",
"number": "Zu groß, erwartete eine Zahl kleiner oder gleich {{maximum}}.",
"bytes": "Zu groß, erwarte maximal {{params.maximum}} Bytes."
},
"tooSmall": {
"string": "Zu kurz, erwartete mindestens {{minimum}} Zeichen.",
"number": "Zu klein, erwartete eine Zahl größer oder gleich {{minimum}}."
},
"invalidFormat": {
"ipv4": "Ungültiges Format, erwartete eine IPv4 Adresse.",
"key": "Ungültiges Format, erwartet einen Base64-kodierten vor verteilten Schlüssel (PSK)."
},
"invalidType": {
"number": "Ungültiger Typ, erwartete eine Zahl."
},
"pskLength": {
"0bit": "Der Schlüssel muss leer sein.",
"8bit": "Der administrative Schlüssel muss ein vor verteilter 8 Bit Schlüssel (PSK) sein.",
"128bit": "Der administrative Schlüssel muss ein vor verteilter 128 Bit Schlüssel (PSK) sein.",
"256bit": "Der administrative Schlüssel muss ein vor verteilter 256 Bit Schlüssel (PSK) sein."
},
"required": {
"generic": "Dies ist ein Pflichtfeld.",
"managed": "Mindestens ein administrativer Schlüssel wird benötigt, um diesen Knoten zu verwalten",
"key": "Schlüssel erforderlich."
}
},
"yes": "Ja",
"no": "Nein"
"button": {
"apply": "Anwenden",
"addConnection": "Verbindung hinzufügen",
"saveConnection": "Verbindung speichern",
"backupKey": "Schlüssel sichern",
"cancel": "Abbrechen",
"connect": "Verbindung herstellen",
"clearMessages": "Nachrichten löschen",
"close": "Schließen",
"confirm": "Bestätigen",
"delete": "Löschen",
"dismiss": "Tastatur ausblenden",
"download": "Herunterladen",
"disconnect": "Verbindung trennen",
"export": "Exportieren",
"generate": "Erzeugen",
"regenerate": "Neu erzeugen",
"import": "Importieren",
"message": "Nachricht",
"now": "Jetzt",
"ok": "Ok",
"print": "Drucken",
"remove": "Entfernen",
"requestNewKeys": "Neue Schlüssel anfordern",
"requestPosition": "Standort anfordern",
"reset": "Zurücksetzen",
"retry": "Erneut versuchen",
"save": "Speichern",
"setDefault": "Als Standard festlegen",
"unsetDefault": "Standard entfernen",
"scanQr": "QR Code scannen",
"traceRoute": "Route verfolgen",
"submit": "Absenden"
},
"app": {
"title": "Meshtastic",
"fullTitle": "Meshtastic Web-Applikation"
},
"loading": "Wird geladen...",
"unit": {
"cps": "CPS",
"dbm": "dBm",
"hertz": "Hz",
"hop": {
"one": "Sprung",
"plural": "Sprünge"
},
"hopsAway": {
"one": "{{count}} Sprung entfernt",
"plural": "{{count}} Sprünge entfernt",
"unknown": "Sprungweite unbekannt"
},
"megahertz": "MHz",
"kilohertz": "kHz",
"raw": "Einheitslos",
"meter": {
"one": "Meter",
"plural": "Meter",
"suffix": "m"
},
"kilometer": {
"one": "Kilometer",
"plural": "Kilometer",
"suffix": "km"
},
"minute": {
"one": "Minute",
"plural": "Minuten"
},
"hour": {
"one": "Stunde",
"plural": "Stunden"
},
"millisecond": {
"one": "Millisekunde",
"plural": "Millisekunden",
"suffix": "ms"
},
"second": {
"one": "Sekunde",
"plural": "Sekunden"
},
"day": {
"one": "Tag",
"plural": "Tage",
"today": "Heute",
"yesterday": "Gestern"
},
"month": {
"one": "Monat",
"plural": "Monate"
},
"year": {
"one": "Jahr",
"plural": "Jahre"
},
"snr": "SNR",
"volt": {
"one": "Volt",
"plural": "Volt",
"suffix": "V"
},
"record": {
"one": "Datensatz",
"plural": "Datensätze"
},
"degree": {
"one": "Grad",
"plural": "Grad",
"suffix": "°"
}
},
"security": {
"0bit": "Leer",
"8bit": "8 Bit",
"128bit": "128 Bit",
"256bit": "256 Bit"
},
"unknown": {
"longName": "Unbekannt",
"shortName": "UNB",
"notAvailable": "Keine Angaben",
"num": "???"
},
"nodeUnknownPrefix": "!",
"unset": "NICHT GESETZT",
"fallbackName": "Meshtastic {{last4}}",
"node": "Knoten",
"formValidation": {
"unsavedChanges": "Ungespeicherte Änderungen",
"tooBig": {
"string": "Zu lang, erwarte maximal {{maximum}} Zeichen.",
"number": "Zu groß, erwartete eine Zahl kleiner oder gleich {{maximum}}.",
"bytes": "Zu groß, erwarte maximal {{params.maximum}} Bytes."
},
"tooSmall": {
"string": "Zu kurz, erwartete mindestens {{minimum}} Zeichen.",
"number": "Zu klein, erwartete eine Zahl größer oder gleich {{minimum}}."
},
"invalidFormat": {
"ipv4": "Ungültiges Format, erwartete eine IPv4 Adresse.",
"key": "Ungültiges Format, erwartet einen Base64-kodierten vor verteilten Schlüssel (PSK)."
},
"invalidType": {
"number": "Ungültiger Typ, erwartete eine Zahl."
},
"pskLength": {
"0bit": "Der Schlüssel muss leer sein.",
"8bit": "Der administrative Schlüssel muss ein vor verteilter 8 Bit Schlüssel (PSK) sein.",
"128bit": "Der administrative Schlüssel muss ein vor verteilter 128 Bit Schlüssel (PSK) sein.",
"256bit": "Der administrative Schlüssel muss ein vor verteilter 256 Bit Schlüssel (PSK) sein."
},
"required": {
"generic": "Dies ist ein Pflichtfeld.",
"managed": "Mindestens ein administrativer Schlüssel wird benötigt, um diesen Knoten zu verwalten",
"key": "Schlüssel erforderlich."
},
"invalidOverrideFreq": {
"number": "Ungültiges Format, erwartet wurde ein Wert im Bereich 410930 MHz oder 0 (Standard verwenden)."
}
},
"yes": "Ja",
"no": "Nein"
}

View File

@@ -0,0 +1,458 @@
{
"page": {
"title": "Einstellungen",
"tabUser": "Benutzer",
"tabChannels": "Kanäle",
"tabBluetooth": "Bluetooth",
"tabDevice": "Gerät",
"tabDisplay": "Display",
"tabLora": "LoRa",
"tabNetwork": "Netzwerk",
"tabPosition": "Standort",
"tabPower": "Leistung",
"tabSecurity": "Sicherheit"
},
"sidebar": {
"label": "Einstellungen"
},
"device": {
"title": "Geräteeinstellungen",
"description": "Einstellungen für dieses Gerät",
"buttonPin": {
"description": "GPIO für Taste überschreiben",
"label": "GPIO Taste"
},
"buzzerPin": {
"description": "GPIO für Summer überschreiben",
"label": "GPIO Summer"
},
"disableTripleClick": {
"description": "Dreifachklick deaktivieren",
"label": "Dreifachklick deaktivieren"
},
"doubleTapAsButtonPress": {
"description": "Doppeltes Tippen als Taste verwenden",
"label": "Doppelklick als Tastendruck"
},
"ledHeartbeatDisabled": {
"description": "Puls LED deaktivieren",
"label": "Herzschlag LED deaktivieren"
},
"nodeInfoBroadcastInterval": {
"description": "Häufigkeit der Übertragung von Knoteninformationen",
"label": "Knoteninfo Übertragungsintervall"
},
"posixTimezone": {
"description": "Zeichenfolge der POSIX Zeitzone für dieses Gerät",
"label": "POSIX Zeitzone"
},
"rebroadcastMode": {
"description": "Wie Weiterleitungen behandelt werden",
"label": "Weiterleitungsmodus"
},
"role": {
"description": "In welcher Rolle das Gerät im Netz arbeitet",
"label": "Rolle"
}
},
"bluetooth": {
"title": "Bluetooth Einstellungen",
"description": "Einstellungen für das Bluetooth Modul",
"note": "Hinweis: Einige Geräte (ESP32) können nicht gleichzeitig Bluetooth und WLAN verwenden.",
"enabled": {
"description": "Bluetooth aktivieren oder deaktivieren",
"label": "Aktiviert"
},
"pairingMode": {
"description": "PIN Nummer Auswahlverhalten",
"label": "Kopplungsmodus"
},
"pin": {
"description": "PIN Nummer zum Verbinden verwenden",
"label": "PIN Nummer"
}
},
"display": {
"description": "Einstellungen für die Geräteanzeige",
"title": "Anzeigeeinstellungen",
"headingBold": {
"description": "Überschrifttext fett darstellen",
"label": "Fette Überschrift"
},
"carouselDelay": {
"description": "Bestimmt wie schnell die Fenster durch gewechselt werden",
"label": "Karussellintervall"
},
"compassNorthTop": {
"description": "Norden im Kompass immer oben anzeigen",
"label": "Kompass Norden oben"
},
"displayMode": {
"description": "Variante des Anzeigelayout",
"label": "Anzeigemodus"
},
"displayUnits": {
"description": "Zeige metrische oder imperiale Einheiten",
"label": "Anzeigeeinheiten"
},
"flipScreen": {
"description": "Anzeige um 180 Grad drehen",
"label": "Anzeige drehen"
},
"gpsDisplayUnits": {
"description": "Anzeigeformat der Koordinaten",
"label": "GPS Anzeigeformat"
},
"oledType": {
"description": "Art des OLED Anzeige, die an dem Gerät angeschlossen ist",
"label": "OLED Typ"
},
"screenTimeout": {
"description": "Anzeige nach dieser Zeit automatisch ausschalten",
"label": "Anzeigeabschaltung"
},
"twelveHourClock": {
"description": "12-Stunden Format benutzen",
"label": "12-Stunden Uhr"
},
"wakeOnTapOrMotion": {
"description": "Gerät durch Tippen oder Bewegung aufwecken",
"label": "Aufwachen durch Tippen oder Bewegung"
}
},
"lora": {
"title": "Netzeinstellungen",
"description": "Einstellungen für das LoRa Netz",
"bandwidth": {
"description": "Kanalbandbreite in kHz",
"label": "Bandbreite"
},
"boostedRxGain": {
"description": "Erhöhte Empfangsverstärkung",
"label": "Erhöhte Empfangsverstärkung"
},
"codingRate": {
"description": "Kodierrate",
"label": "Fehlerkorrektur"
},
"frequencyOffset": {
"description": "Frequenzversatz zur Kalibrierung von Oszillatorfehlern",
"label": "Frequenzversatz"
},
"frequencySlot": {
"description": "LoRa Frequenzschlitz",
"label": "Frequenzschlitz"
},
"hopLimit": {
"description": "Maximale Sprungweite",
"label": "Sprungweite"
},
"ignoreMqtt": {
"description": "MQTT Nachrichten nicht über das Netz weiterleiten",
"label": "MQTT ignorieren"
},
"modemPreset": {
"description": "Modem Voreinstellung die verwendet wird",
"label": "Modem Voreinstellungen"
},
"okToMqtt": {
"description": "Wenn auf aktiviert, zeigt diese Einstellung an, dass der Benutzer das Weiterleiten von Nachrichten über MQTT akzeptiert. Wenn deaktiviert, werden entfernte Knoten aufgefordert, Nachrichten nicht über MQTT weiterzuleiten",
"label": "OK für MQTT"
},
"overrideDutyCycle": {
"description": "Duty-Cycle überschreiben",
"label": "Duty-Cycle überschreiben"
},
"overrideFrequency": {
"description": "Sendefrequenz überschreiben (MHz)",
"label": "Sendefrequenz überschreiben"
},
"region": {
"description": "Legt die Region für Ihren Knoten fest",
"label": "Region"
},
"spreadingFactor": {
"description": "Anzahl der Symbole zur Kodierung der Nutzdaten",
"label": "Spreizfaktor"
},
"transmitEnabled": {
"description": "Sender (TX) des LoRa Funkgerätes aktivieren/deaktivieren",
"label": "Senden aktiviert"
},
"transmitPower": {
"description": "Maximale Sendeleistung",
"label": "Sendeleistung"
},
"usePreset": {
"description": "Eine der vordefinierten Modem Voreinstellungen verwenden",
"label": "Voreinstellung verwenden"
},
"meshSettings": {
"description": "Einstellungen für das LoRa Netz",
"label": "Netzeinstellungen"
},
"waveformSettings": {
"description": "Einstellungen für die LoRa Wellenform",
"label": "Einstellungen der Wellenform"
},
"radioSettings": {
"label": "Funkeinstellungen",
"description": "Einstellungen für das LoRa Funkgerät"
}
},
"network": {
"title": "WLAN Einstellungen",
"description": "WLAN Funkeinstellungen",
"note": "Hinweis: Einige Geräte (ESP32) können nicht gleichzeitig Bluetooth und WLAN verwenden.",
"addressMode": {
"description": "Auswahl der IP Adressenzuweisung",
"label": "IP Adressenmodus"
},
"dns": {
"description": "DNS Server",
"label": "DNS"
},
"ethernetEnabled": {
"description": "Aktivieren oder deaktivieren sie den Ethernet Anschluss",
"label": "Aktiviert"
},
"gateway": {
"description": "Standard Gateway",
"label": "Gateway"
},
"ip": {
"description": "IP Adresse",
"label": "IP"
},
"psk": {
"description": "Netzwerkpasswort",
"label": "PSK"
},
"ssid": {
"description": "Netzwerkname",
"label": "SSID"
},
"subnet": {
"description": "Subnetzmaske",
"label": "Subnetz"
},
"wifiEnabled": {
"description": "Aktivieren oder deaktivieren Sie die WLAN Übertragung",
"label": "Aktiviert"
},
"meshViaUdp": {
"label": "Netz über UDP"
},
"ntpServer": {
"label": "NTP Server"
},
"rsyslogServer": {
"label": "Rsyslog Server"
},
"ethernetConfigSettings": {
"description": "Einstellung des Ethernet Ports",
"label": "Ethernet Einstellung"
},
"ipConfigSettings": {
"description": "Einstellung der IP Adresse",
"label": "IP Adresseinstellungen"
},
"ntpConfigSettings": {
"description": "NTP Server Einstellungen",
"label": "NTP Einstellungen"
},
"rsyslogConfigSettings": {
"description": "Rsyslog Einstellung",
"label": "Rsyslog Einstellung"
},
"udpConfigSettings": {
"description": "UDP über Netz Einstellung",
"label": "UDP Konfiguration"
}
},
"position": {
"title": "Standorteinstellung",
"description": "Einstellungen für das Standortmodul",
"broadcastInterval": {
"description": "Wie oft Ihr Standort über das Netz gesendet wird",
"label": "Übertragungsintervall"
},
"enablePin": {
"description": "Überschreiben des GPIO der das GPS-Modul aktiviert",
"label": "GPIO GPS aktivieren"
},
"fixedPosition": {
"description": "GPS Standort nicht senden, sondern manuell angegeben",
"label": "Fester Standort"
},
"gpsMode": {
"description": "Einstellung, ob GPS des Geräts aktiviert, deaktiviert oder nicht vorhanden ist",
"label": "GPS Modus"
},
"gpsUpdateInterval": {
"description": "Wie oft ein GPS Standort ermittelt werden soll",
"label": "GPS Aktualisierungsintervall"
},
"positionFlags": {
"description": "Optionalen, die bei der Zusammenstellung von Standortnachrichten enthalten sein sollen. Je mehr Optionen ausgewählt werden, desto größer wird die Nachricht und die längere Übertragungszeit erhöht das Risiko für einen Nachrichtenverlust.",
"label": "Standort Optionen"
},
"receivePin": {
"description": "GPIO Pin für serielles Empfangen (RX) des GPS-Moduls überschreiben",
"label": "GPIO Empfangen"
},
"smartPositionEnabled": {
"description": "Standort nur verschicken, wenn eine sinnvolle Standortänderung stattgefunden hat",
"label": "Intelligenten Standort aktivieren"
},
"smartPositionMinDistance": {
"description": "Mindestabstand (in Meter), die vor dem Senden einer Standortaktualisierung zurückgelegt werden muss",
"label": "Minimale Entfernung für intelligenten Standort"
},
"smartPositionMinInterval": {
"description": "Minimales Intervall (in Sekunden), das vor dem Senden einer Standortaktualisierung vergangen sein muss",
"label": "Minimales Intervall für intelligenten Standort"
},
"transmitPin": {
"description": "GPIO Pin für serielles Senden (TX) des GPS-Moduls überschreiben",
"label": "GPIO Senden"
},
"intervalsSettings": {
"description": "Wie oft Standortaktualisierungen gesendet werden",
"label": "Intervalle"
},
"flags": {
"placeholder": "Standort Optionen auswählen",
"altitude": "Höhe",
"altitudeGeoidalSeparation": "Geoidale Höhentrennung",
"altitudeMsl": "Höhe in Bezug auf Meeresspiegel",
"dop": "Dilution of Präzision (DOP) PDOP standardmäßig verwenden",
"hdopVdop": "Wenn DOP gesetzt ist, wird HDOP / VDOP anstelle von PDOP verwendet",
"numSatellites": "Anzahl Satelliten",
"sequenceNumber": "Sequenznummer",
"timestamp": "Zeitstempel",
"unset": "Nicht konfiguriert",
"vehicleHeading": "Fahrzeugsteuerkurs",
"vehicleSpeed": "Fahrzeuggeschwindigkeit"
}
},
"power": {
"adcMultiplierOverride": {
"description": "Zur Optimierung der Genauigkeit bei der Akkuspannungsmessung",
"label": "ADC Multiplikationsfaktor"
},
"ina219Address": {
"description": "Adresse des INA219 Stromsensors",
"label": "INA219 Adresse"
},
"lightSleepDuration": {
"description": "Wie lange das Gerät im leichten Schlafmodus ist",
"label": "Dauer leichter Schlafmodus"
},
"minimumWakeTime": {
"description": "Minimale Zeitspanne für die das Gerät aktiv bleibt, nachdem es eine Nachricht empfangen hat",
"label": "Minimale Aufwachzeit"
},
"noConnectionBluetoothDisabled": {
"description": "Wenn das Gerät keine Bluetooth-Verbindung erhält, wird BLE nach dieser Zeit deaktiviert",
"label": "Keine Verbindung, Bluetooth deaktiviert"
},
"powerSavingEnabled": {
"description": "Auswählen, wenn aus einer Stromquelle mit niedriger Kapazität (z.B. Solar) betrieben wird, um den Stromverbrauch so weit wie möglich zu minimieren.",
"label": "Energiesparmodus aktivieren"
},
"shutdownOnBatteryDelay": {
"description": "Verzögerung bis zum Abschalten der Knoten sich im Akkubetrieb befindet. 0 für unbegrenzt",
"label": "Verzögerung Akkuabschaltung"
},
"superDeepSleepDuration": {
"description": "Wie lange das Gerät im supertiefen Schlafmodus ist",
"label": "Dauer Supertiefschlaf"
},
"powerConfigSettings": {
"description": "Einstellungen für das Energiemodul",
"label": "Energie Einstellungen"
},
"sleepSettings": {
"description": "Einstellungen Ruhezustand für das Energiemodul",
"label": "Einstellung Ruhezustand"
}
},
"security": {
"description": "Sicherheitseinstellungen",
"title": "Sicherheitseinstellungen",
"button_backupKey": "Schlüssel sichern",
"adminChannelEnabled": {
"description": "Erlaubt die Gerätesteuerung über den unsicheren, veralteten administrativen Kanal",
"label": "Veraltete Administrierung erlauben"
},
"enableDebugLogApi": {
"description": "Ausgabe von Fehlerprotokollen in Echtzeit über die serielle Schnittstelle, Anzeige und Export von Standort reduzierten Geräteprotokollen über Bluetooth",
"label": "Debug-Protokoll API aktivieren"
},
"managed": {
"description": "Wenn aktiviert, können die Geräteeinstellungen nur von einem entfernten Administratorknoten über administrative Nachrichten geändert werden. Aktivieren Sie diese Option nur, wenn mindestens ein geeigneter Administratorknoten eingerichtet wurde, und dessen öffentlicher Schlüssel in einem der obigen Felder gespeichert wurde.\n",
"label": "Verwaltet"
},
"privateKey": {
"description": "Wird verwendet, um einen gemeinsamen Schlüssel mit einem entfernten Gerät zu erstellen",
"label": "Privater Schlüssel"
},
"publicKey": {
"description": "Wird an andere Knoten im Netz gesendet, damit diese einen gemeinsamen geheimen Schlüssel berechnen können",
"label": "Öffentlicher Schlüssel"
},
"primaryAdminKey": {
"description": "Erster öffentlicher Schlüssel, der berechtigt ist, administrative Nachrichten an diesen Knoten zu senden",
"label": "Erster Admin-Schlüssel"
},
"secondaryAdminKey": {
"description": "Zweiter öffentlicher Schlüssel, der berechtigt ist, administrative Nachrichten an diesen Knoten zu senden",
"label": "Zweiter Admin-Schlüssel"
},
"serialOutputEnabled": {
"description": "Serielle Konsole über die Stream-API",
"label": "Serielle Ausgabe aktiviert"
},
"tertiaryAdminKey": {
"description": "Dritter öffentlicher Schlüssel, der berechtigt ist, administrative Nachrichten an diesen Knoten zu senden",
"label": "Dritter Admin-Schlüssel"
},
"adminSettings": {
"description": "Administrator Einstellungen",
"label": "Administrator Einstellungen"
},
"loggingSettings": {
"description": "Einstellungen für die Protokollierung",
"label": "Protokolleinstellungen"
}
},
"user": {
"title": "Benutzereinstellungen",
"description": "Konfigurieren Sie Ihren Gerätenamen und Identitätseinstellungen",
"longName": {
"label": "Langer Name",
"description": "Ihr vollständiger Anzeigename (1-40 Zeichen)",
"validation": {
"min": "Langer Name muss mindestens 1 Zeichen lang sein",
"max": "Langer Name muss mindestens 40 Zeichen lang sein"
}
},
"shortName": {
"label": "Kurzname",
"description": "Ihr abgekürzter Name (2-4 Zeichen)",
"validation": {
"min": "Kurzname muss mindestens 2 Zeichen lang sein",
"max": "Kurzname muss mindestens 4 Zeichen lang sein"
}
},
"isUnmessageable": {
"label": "Nicht erreichbar",
"description": "Wird verwendet, um nicht überwachte Knoten oder Infrastrukturknoten zu identifizieren, sodass Nachrichten nicht an Knoten gesendet werden können, die niemals antworten."
},
"isLicensed": {
"label": "Amateurfunk lizenziert",
"description": "Aktivieren Sie diese Option, wenn Sie ein lizenzierter Amateurfunker sind. Durch Aktivieren dieser Option wird die Verschlüsselung deaktiviert und sie ist nicht mit dem standardmäßigen Meshtastic Netzwerk kompatibel."
}
}
}

View File

@@ -0,0 +1,34 @@
{
"page": {
"title": "Mit einem Meshtastic Gerät verbinden",
"description": "Fügen Sie eine Geräteverbindung über HTTP, Bluetooth oder serielle Schnittstelle hinzu. Ihre gespeicherten Verbindungen werden in Ihrem Browser gespeichert."
},
"connectionType_ble": "BLE",
"connectionType_serial": "Seriell",
"connectionType_network": "Netzwerk",
"deleteConnection": "Verbindung löschen",
"areYouSure": "Dies entfernt {{name}}. Sie können diese Aktion nicht rückgängig machen.",
"moreActions": "Weitere Aktionen",
"noConnections": {
"title": "Noch keine Verbindungen.",
"description": "Erstellen Sie Ihre erste Verbindung. Sie wird sofort verbunden und später gespeichert."
},
"lastConnectedAt": "Letzte Verbindung: {{date}}",
"neverConnected": "Nie verbunden",
"toasts": {
"connected": "Verbunden",
"nowConnected": "{{name}} ist jetzt verbunden",
"nowDisconnected": "{{name}} ist jetzt getrennt",
"disconnected": "Verbindung getrennt",
"failed": "Verbindung fehlgeschlagen",
"checkConnetion": "Überprüfen Sie Ihr Gerät oder Ihre Einstellungen und versuchen Sie es erneut",
"defaultSet": "Standard festgelegt",
"defaultConnection": "Standardverbindung ist jetzt {{nameisconnected}}",
"deleted": "Gelöscht",
"deletedByName": "{{name}} wurde entfernt",
"pickConnectionAgain": "Verbindung fehlgeschlagen. Eventuell müssen Sie das Gerät/den Anschluss neu wählen.",
"added": "Verbindung hinzugefügt",
"savedByName": "{{name}} gespeichert.",
"savedCantConnect": "Die Verbindung wurde gespeichert, konnte sich aber nicht verbinden."
}
}

View File

@@ -1,12 +0,0 @@
{
"dashboard": {
"title": "Verbundene Geräte",
"description": "Verwalten Sie Ihre verbundenen Meshtastic Geräte.",
"connectionType_ble": "BLE",
"connectionType_serial": "Seriell",
"connectionType_network": "Netzwerk",
"noDevicesTitle": "Keine Geräte verbunden",
"noDevicesDescription": "Verbinden Sie ein neues Gerät, um zu beginnen.",
"button_newConnection": "Neue Verbindung"
}
}

View File

@@ -122,7 +122,7 @@
"title": "Netzeinstellungen",
"description": "Einstellungen für das LoRa Netz",
"bandwidth": {
"description": "Kanalbandbreite in MHz",
"description": "Kanalbandbreite in kHz",
"label": "Bandbreite"
},
"boostedRxGain": {

View File

@@ -1,193 +1,238 @@
{
"deleteMessages": {
"description": "Diese Aktion wird den Nachrichtenverlauf löschen. Dies kann nicht rückgängig gemacht werden. Sind Sie sicher, dass Sie fortfahren möchten?",
"title": "Alle Nachrichten löschen"
},
"deviceName": {
"description": "Das Gerät wird neu gestartet, sobald die Einstellung gespeichert ist.",
"longName": "Langer Name",
"shortName": "Kurzname",
"title": "Gerätename ändern",
"validation": {
"longNameMax": "Lange Name darf nicht mehr als 40 Zeichen lang sein",
"shortNameMax": "Kurzname darf nicht mehr als 4 Zeichen lang sein",
"longNameMin": "Langer Name muss mindestens 1 Zeichen lang sein",
"shortNameMin": "Kurzname muss mindestens 1 Zeichen lang sein"
}
},
"import": {
"description": "Die aktuelle LoRa Einstellung wird überschrieben.",
"error": {
"invalidUrl": "Ungültige Meshtastic URL"
},
"channelPrefix": "Kanal: ",
"channelSetUrl": "Kanalsammlung / QR-Code URL",
"channels": "Kanäle:",
"usePreset": "Voreinstellung verwenden?",
"title": "Kanalsammlung importieren"
},
"locationResponse": {
"title": "Standort: {{identifier}}",
"altitude": "Höhe: ",
"coordinates": "Koordinaten: ",
"noCoordinates": "Keine Koordinaten"
},
"pkiRegenerateDialog": {
"title": "Vorab verteilten Schlüssel (PSK) neu erstellen?",
"description": "Sind Sie sicher, dass Sie den vorab verteilten Schlüssel neu erstellen möchten?",
"regenerate": "Neu erstellen"
},
"newDeviceDialog": {
"title": "Neues Gerät verbinden",
"https": "https",
"http": "http",
"tabHttp": "HTTP",
"tabBluetooth": "Bluetooth",
"tabSerial": "Seriell",
"useHttps": "HTTPS verwenden",
"connecting": "Wird verbunden...",
"connect": "Verbindung herstellen",
"connectionFailedAlert": {
"title": "Verbindung fehlgeschlagen",
"descriptionPrefix": "Verbindung zum Gerät fehlgeschlagen. ",
"httpsHint": "Wenn Sie HTTPS verwenden, müssen Sie möglicherweise zuerst ein selbstsigniertes Zertifikat akzeptieren. ",
"openLinkPrefix": "Öffnen Sie ",
"openLinkSuffix": "in einem neuen Tab",
"acceptTlsWarningSuffix": ", akzeptieren Sie alle TLS-Warnungen, wenn Sie dazu aufgefordert werden, dann versuchen Sie es erneut",
"learnMoreLink": "Mehr erfahren"
},
"httpConnection": {
"label": "IP Adresse/Hostname",
"placeholder": "000.000.000.000 / meshtastic.local"
},
"serialConnection": {
"noDevicesPaired": "Noch keine Geräte gekoppelt.",
"newDeviceButton": "Neues Gerät",
"deviceIdentifier": "# {{index}} - {{vendorId}} - {{productId}}"
},
"bluetoothConnection": {
"noDevicesPaired": "Noch keine Geräte gekoppelt.",
"newDeviceButton": "Neues Gerät",
"connectionFailed": "Verbindung fehlgeschlagen",
"deviceDisconnected": "Verbindung getrennt",
"unknownDevice": "Unbekanntes Gerät",
"errorLoadingDevices": "Fehler beim Laden der Geräte",
"unknownErrorLoadingDevices": "Unbekannter Fehler beim Laden der Geräte"
},
"validation": {
"requiresWebBluetooth": "Dieser Verbindungstyp erfordert <0>Bluetooth</0> im Browser. Bitte verwenden Sie einen unterstützten Browser, wie Chrome oder Edge.",
"requiresWebSerial": "Dieser Verbindungstyp erfordert <0>Serielle Schnittstelle</0> im Browser. Bitte verwenden Sie einen unterstützten Browser, wie Chrome oder Edge.",
"requiresSecureContext": "Diese Anwendung erfordert einen <0>sicheren Kontext</0>. Bitte verbinden Sie sich über HTTPS oder localhost.",
"additionallyRequiresSecureContext": "Zusätzlich erfordert es einen <0>sicheren Kontext</0>. Bitte verbinden Sie sich über HTTPS oder localhost."
}
},
"nodeDetails": {
"message": "Nachricht",
"requestPosition": "Standort anfordern",
"traceRoute": "Route verfolgen",
"airTxUtilization": "Auslastung Sendezeit",
"allRawMetrics": "Alle Rohdaten",
"batteryLevel": "Akkustand",
"channelUtilization": "Kanalauslastung",
"details": "Details:",
"deviceMetrics": "Gerätekennzahlen:",
"hardware": "Hardware: ",
"lastHeard": "Zuletzt gehört: ",
"nodeHexPrefix": "Knoten ID:",
"nodeNumber": "Knotennummer: ",
"position": "Standort:",
"role": "Rolle: ",
"uptime": "Laufzeit: ",
"voltage": "Spannung",
"title": "Knotendetails für {{identifier}}",
"ignoreNode": "Knoten ignorieren",
"removeNode": "Knoten entfernen",
"unignoreNode": "Knoten akzeptieren",
"security": "Sicherheit:",
"publicKey": "Öffentlicher Schlüssel:",
"messageable": "Ansprechbar:",
"KeyManuallyVerifiedTrue": "Öffentlicher Schlüssel wurde manuell geprüft",
"KeyManuallyVerifiedFalse": "Öffentlicher Schlüssel ist nicht manuell geprüft"
},
"pkiBackup": {
"loseKeysWarning": "Wenn Sie Ihre Schlüssel verlieren, müssen Sie Ihr Gerät zurücksetzen.",
"secureBackup": "Es ist wichtig, dass Sie Ihre öffentlichen und privaten Schlüssel sichern und diese sicher speichern!",
"footer": "=== END OF KEYS ===",
"header": "=== MESHTASTIC KEYS FOR {{longName}} ({{shortName}}) ===",
"privateKey": "Privater Schlüssel:",
"publicKey": "Öffentlicher Schlüssel:",
"fileName": "meshtastic_keys_{{longName}}_{{shortName}}.txt",
"title": "Schlüssel sichern"
},
"pkiBackupReminder": {
"description": "Wir empfehlen die regelmäßige Sicherung Ihrer Schlüsseldaten. Möchten Sie jetzt sicheren?",
"title": "Erinnerungen für Sicherungen",
"remindLaterPrefix": "Erinnerung in:",
"remindNever": "Nie erinnern",
"backupNow": "Jetzt sichern"
},
"pkiRegenerate": {
"description": "Sind Sie sicher, dass Sie Schlüsselpaar neu erstellen möchten?",
"title": "Schlüsselpaar neu erstellen"
},
"qr": {
"addChannels": "Kanäle hinzufügen",
"replaceChannels": "Kanäle ersetzen",
"description": "Die aktuelle LoRa Einstellung wird ebenfalls geteilt.",
"sharableUrl": "Teilbare URL",
"title": "QR Code Erzeugen"
},
"reboot": {
"title": "Gerät neustarten",
"description": "Starten Sie jetzt neu oder planen Sie einen Neustart des verbundenen Knotens. Optional können Sie einen Neustart in den OTA (Over-the-Air) Modus wählen.",
"ota": "Neustart in den OTA Modus",
"enterDelay": "Verzögerung eingeben",
"scheduled": "Neustart wurde geplant",
"schedule": "Neustart planen",
"now": "Jetzt neustarten",
"cancel": "Geplanten Neustart abbrechen"
},
"refreshKeys": {
"description": {
"acceptNewKeys": "Dies entfernt den Knoten vom Gerät und fordert neue Schlüssel an.",
"keyMismatchReasonSuffix": ". Dies liegt daran, dass der aktuelle öffentliche Schlüssel des entfernten Knotens nicht mit dem zuvor gespeicherten Schlüssel für diesen Knoten übereinstimmt.",
"unableToSendDmPrefix": "Ihr Knoten kann keine Direktnachricht an folgenden Knoten senden: "
},
"acceptNewKeys": "Neue Schlüssel akzeptieren",
"title": "Schlüsselfehler - {{identifier}}"
},
"removeNode": {
"description": "Sind Sie sicher, dass Sie diesen Knoten entfernen möchten?",
"title": "Knoten entfernen?"
},
"shutdown": {
"title": "Herunterfahren planen",
"description": "Schaltet den verbundenen Knoten nach x Minuten aus."
},
"traceRoute": {
"routeToDestination": "Route zum Ziel:",
"routeBack": "Route zurück:"
},
"tracerouteResponse": {
"title": "Traceroute: {{identifier}}"
},
"unsafeRoles": {
"confirmUnderstanding": "Ja, ich weiß, was ich tue!",
"conjunction": " und der Blog-Beitrag über ",
"postamble": " und verstehen die Auswirkungen einer Veränderung der Rolle.",
"preamble": "Ich habe die",
"choosingRightDeviceRole": "Wahl der richtigen Geräterolle",
"deviceRoleDocumentation": "Dokumentation der Geräterolle",
"title": "Sind Sie sicher?"
},
"managedMode": {
"confirmUnderstanding": "Ja, ich weiß, was ich tue!",
"title": "Sind Sie sicher?",
"description": "Das Aktivieren des verwalteten Modus blockiert das Schreiben der Einstellungen in das Funkgerät durch alle Anwendungen (einschließlich der Webanwendung). Einmal aktiviert, können die Einstellungen nur durch administrative Nachrichten geändert werden. Diese Einstellung ist für die Fernverwaltung von abgesetzten Knoten nicht erforderlich."
},
"clientNotification": {
"title": "Warnmeldung",
"TraceRoute can only be sent once every 30 seconds": "TraceRoute kann nur einmal alle 30 Sekunden versendet werden.",
"Compromised keys were detected and regenerated.": "Kompromittierte Schlüssel wurden erkannt und neu generiert."
}
"deleteMessages": {
"description": "Diese Aktion wird den Nachrichtenverlauf löschen. Dies kann nicht rückgängig gemacht werden. Sind Sie sicher, dass Sie fortfahren möchten?",
"title": "Alle Nachrichten löschen"
},
"import": {
"description": "Die aktuelle LoRa Einstellung wird überschrieben.",
"error": {
"invalidUrl": "Ungültige Meshtastic URL"
},
"channelPrefix": "Kanal: ",
"primary": "Primär ",
"doNotImport": "Nicht importieren",
"channelName": "Name",
"channelSlot": "Position",
"channelSetUrl": "Kanalsammlung / QR-Code URL",
"useLoraConfig": "LoRa Konfiguration importieren",
"presetDescription": "Die aktuelle LoRa Konfiguration wird ersetzt.",
"title": "Kanalsammlung importieren"
},
"locationResponse": {
"title": "Standort: {{identifier}}",
"altitude": "Höhe: ",
"coordinates": "Koordinaten: ",
"noCoordinates": "Keine Koordinaten"
},
"pkiRegenerateDialog": {
"title": "Vorab verteilten Schlüssel (PSK) neu erstellen?",
"description": "Sind Sie sicher, dass Sie den vorab verteilten Schlüssel neu erstellen möchten?",
"regenerate": "Neu erstellen"
},
"addConnection": {
"title": "Verbindung hinzufügen",
"description": "Wählen Sie einen Verbindungstyp aus und geben Sie die Details ein",
"validation": {
"requiresWebBluetooth": "Dieser Verbindungstyp erfordert <0>Bluetooth</0> im Browser. Bitte verwenden Sie einen unterstützten Browser, wie Chrome oder Edge.",
"requiresWebSerial": "Dieser Verbindungstyp erfordert <0>Serielle Schnittstelle</0> im Browser. Bitte verwenden Sie einen unterstützten Browser, wie Chrome oder Edge.",
"requiresSecureContext": "Diese Anwendung erfordert einen <0>sicheren Kontext</0>. Bitte verbinden Sie sich über HTTPS oder localhost.",
"additionallyRequiresSecureContext": "Zusätzlich erfordert es einen <0>sicheren Kontext</0>. Bitte verbinden Sie sich über HTTPS oder localhost."
},
"bluetoothConnection": {
"namePlaceholder": "Mein Bluetooth Knoten",
"supported": {
"title": "Web Bluetooth wird unterstützt"
},
"notSupported": {
"title": "Web Bluetooth wird nicht unterstützt",
"description": "Ihr Browser oder Ihr Gerät unterstützt kein Bluetooth im Web"
},
"short": "BT: {{deviceName}}",
"long": "Bluetooth Gerät",
"device": "Gerät",
"selectDevice": "Gerät auswählen",
"selected": "Bluetooth Gerät ausgewählt",
"notSelected": "Kein Gerät ausgewählt",
"helperText": "Verwendet den Meshtastic Bluetooth Dienst zur Erkennung."
},
"serialConnection": {
"namePlaceholder": "Mein serieller Knoten",
"helperText": "Die Auswahl eines Anschlusses erteilt der App die Berechtigung, diesen zu öffnen und eine Verbindung herzustellen.",
"supported": {
"title": "Web Seriell unterstützt"
},
"notSupported": {
"title": "Web Seriell nicht unterstützt",
"description": "Ihr Browser oder Ihr Gerät unterstützt kein Web Seriell"
},
"portSelected": {
"title": "Serieller Anschluss ausgewählt",
"description": "Anschlussberechtigungen gewährt."
},
"port": "Anschluss",
"selectPort": "Anschluss auswählen",
"deviceName": "USB {{vendorId}}:{{productId}}",
"notSelected": "Kein Anschluss ausgewählt"
},
"httpConnection": {
"namePlaceholder": "Mein HTTP Knoten",
"inputPlaceholder": "192.168.1.10 oder meshtastic.local",
"heading": "URL oder IP",
"useHttps": "HTTPS verwenden",
"invalidUrl": {
"title": "Ungültige URL",
"description": "Bitte geben Sie eine gültige HTTP oder HTTPS URL ein."
},
"connectionTest": {
"description": "Testen Sie die Verbindung, bevor Sie speichern um zu überprüfen, dass das Gerät erreichbar ist.",
"button": {
"loading": "Wird getestet...",
"label": "Verbindung testen"
},
"reachable": "Erreichbar",
"notReachable": "Nicht erreichbar",
"success": {
"title": "Verbindungstest erfolgreich",
"description": "Das Gerät scheint erreichbar zu sein."
},
"failure": {
"title": "Verbindungstest fehlgeschlagen",
"description": "Das Gerät konnte nicht erreicht werden. Überprüfen Sie die URL und versuchen Sie es erneut."
}
}
}
},
"nodeDetails": {
"message": "Nachricht",
"requestPosition": "Standort anfordern",
"traceRoute": "Route verfolgen",
"airTxUtilization": "Auslastung Sendezeit",
"allRawMetrics": "Alle Rohdaten",
"batteryLevel": "Akkustand",
"channelUtilization": "Kanalauslastung",
"details": "Details:",
"deviceMetrics": "Gerätekennzahlen:",
"hardware": "Hardware: ",
"lastHeard": "Zuletzt gehört: ",
"nodeHexPrefix": "Knoten ID:",
"nodeNumber": "Knotennummer: ",
"position": "Standort:",
"role": "Rolle: ",
"uptime": "Laufzeit: ",
"voltage": "Spannung",
"title": "Knotendetails für {{identifier}}",
"ignoreNode": "Knoten ignorieren",
"removeNode": "Knoten entfernen",
"unignoreNode": "Knoten akzeptieren",
"security": "Sicherheit:",
"publicKey": "Öffentlicher Schlüssel:",
"messageable": "Ansprechbar:",
"KeyManuallyVerifiedTrue": "Öffentlicher Schlüssel wurde manuell geprüft",
"KeyManuallyVerifiedFalse": "Öffentlicher Schlüssel ist nicht manuell geprüft"
},
"pkiBackup": {
"loseKeysWarning": "Wenn Sie Ihre Schlüssel verlieren, müssen Sie Ihr Gerät zurücksetzen.",
"secureBackup": "Es ist wichtig, dass Sie Ihre öffentlichen und privaten Schlüssel sichern und diese sicher speichern!",
"footer": "=== END OF KEYS ===",
"header": "=== MESHTASTIC KEYS FOR {{longName}} ({{shortName}}) ===",
"privateKey": "Privater Schlüssel:",
"publicKey": "Öffentlicher Schlüssel:",
"fileName": "meshtastic_keys_{{longName}}_{{shortName}}.txt",
"title": "Schlüssel sichern"
},
"pkiBackupReminder": {
"description": "Wir empfehlen die regelmäßige Sicherung Ihrer Schlüsseldaten. Möchten Sie jetzt sicheren?",
"title": "Erinnerungen für Sicherungen",
"remindLaterPrefix": "Erinnerung in:",
"remindNever": "Nie erinnern",
"backupNow": "Jetzt sichern"
},
"pkiRegenerate": {
"description": "Sind Sie sicher, dass Sie Schlüsselpaar neu erstellen möchten?",
"title": "Schlüsselpaar neu erstellen"
},
"qr": {
"addChannels": "Kanäle hinzufügen",
"replaceChannels": "Kanäle ersetzen",
"description": "Die aktuelle LoRa Einstellung wird ebenfalls geteilt.",
"sharableUrl": "Teilbare URL",
"title": "QR Code Erzeugen"
},
"reboot": {
"title": "Gerät neustarten",
"description": "Starten Sie jetzt neu oder planen Sie einen Neustart des verbundenen Knotens. Optional können Sie einen Neustart in den OTA (Over-the-Air) Modus wählen.",
"ota": "Neustart in den OTA Modus",
"enterDelay": "Verzögerung eingeben",
"scheduled": "Neustart wurde geplant",
"schedule": "Neustart planen",
"now": "Jetzt neustarten",
"cancel": "Geplanten Neustart abbrechen"
},
"refreshKeys": {
"description": {
"acceptNewKeys": "Dies entfernt den Knoten vom Gerät und fordert neue Schlüssel an.",
"keyMismatchReasonSuffix": ". Dies liegt daran, dass der aktuelle öffentliche Schlüssel des entfernten Knotens nicht mit dem zuvor gespeicherten Schlüssel für diesen Knoten übereinstimmt.",
"unableToSendDmPrefix": "Ihr Knoten kann keine Direktnachricht an folgenden Knoten senden: "
},
"acceptNewKeys": "Neue Schlüssel akzeptieren",
"title": "Schlüsselfehler - {{identifier}}"
},
"removeNode": {
"description": "Sind Sie sicher, dass Sie diesen Knoten entfernen möchten?",
"title": "Knoten entfernen?"
},
"shutdown": {
"title": "Herunterfahren planen",
"description": "Schaltet den verbundenen Knoten nach x Minuten aus."
},
"traceRoute": {
"routeToDestination": "Route zum Ziel:",
"routeBack": "Route zurück:"
},
"tracerouteResponse": {
"title": "Traceroute: {{identifier}}"
},
"unsafeRoles": {
"confirmUnderstanding": "Ja, ich weiß, was ich tue!",
"conjunction": " und der Blog-Beitrag über ",
"postamble": " und verstehen die Auswirkungen einer Veränderung der Rolle.",
"preamble": "Ich habe die",
"choosingRightDeviceRole": "Wahl der richtigen Geräterolle",
"deviceRoleDocumentation": "Dokumentation der Geräterolle",
"title": "Sind Sie sicher?"
},
"managedMode": {
"confirmUnderstanding": "Ja, ich weiß, was ich tue!",
"title": "Sind Sie sicher?",
"description": "Das Aktivieren des verwalteten Modus blockiert das Schreiben der Einstellungen in das Funkgerät durch alle Anwendungen (einschließlich der Webanwendung). Einmal aktiviert, können die Einstellungen nur durch administrative Nachrichten geändert werden. Diese Einstellung ist für die Fernverwaltung von abgesetzten Knoten nicht erforderlich."
},
"clientNotification": {
"title": "Warnmeldung",
"TraceRoute can only be sent once every 30 seconds": "TraceRoute kann nur einmal alle 30 Sekunden versendet werden.",
"Compromised keys were detected and regenerated.": "Kompromittierte Schlüssel wurden erkannt und neu generiert."
},
"resetNodeDb": {
"title": "Knotendatenbank zurücksetzen",
"description": "Dadurch werden alle Knoten aus der Knotendatenbank des verbundenen Geräts und der gesamte Nachrichtenverlauf im Client gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden. Möchten Sie wirklich fortfahren?",
"confirm": "Knotendatenbank zurücksetzen",
"failedTitle": "Beim Zurücksetzen der Knoten-Datenbank ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut."
},
"clearAllStores": {
"title": "Lösche den gesamten lokalen Speicher",
"description": "Dadurch werden alle lokal gespeicherten Daten gelöscht, einschließlich des Nachrichtenverlaufs und der Knotendatenbanken aller zuvor verbundenen Geräte. Nach Abschluss des Vorgangs müssen Sie die Verbindung zu Ihrem Knoten erneut herstellen. Dieser Vorgang kann nicht rückgängig gemacht werden. Möchten Sie wirklich fortfahren?",
"confirm": "Lösche den gesamten lokalen Speicher",
"failedTitle": "Beim Löschen des lokalen Speichers ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut."
},
"factoryResetDevice": {
"title": "Gerät auf Werkseinstellungen zurücksetzen",
"description": "Dadurch wird das verbundene Gerät auf die Werkseinstellungen zurückgesetzt. Alle Konfigurationen und Daten auf dem Gerät sowie alle im Client gespeicherten Knoten und Nachrichten werden gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden. Möchten Sie wirklich fortfahren?",
"confirm": "Gerät auf Werkseinstellungen zurücksetzen",
"failedTitle": "Beim Zurücksetzen auf die Werkseinstellungen ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut."
},
"factoryResetConfig": {
"title": "Auf Werkseinstellungen zurücksetzen",
"description": "Dadurch wird die Konfiguration des verbundenen Geräts auf die Werkseinstellungen zurückgesetzt und alle Konfigurationen auf dem Gerät gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden. Möchten Sie wirklich fortfahren?",
"confirm": "Auf Werkseinstellungen zurücksetzen",
"failedTitle": "Beim Zurücksetzen auf die Werkseinstellungen ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut."
}
}

View File

@@ -0,0 +1,38 @@
{
"maplibre": {
"GeolocateControl.FindMyLocation": "Meinen Standort ermitteln",
"NavigationControl.ZoomIn": "Vergrößern",
"NavigationControl.ZoomOut": "Verkleinern",
"CooperativeGesturesHandler.WindowsHelpText": "Verwenden Sie STRG + Scrollen zum Zoomen der Karte",
"CooperativeGesturesHandler.MacHelpText": "Verwenden Sie ⌘ + Scrollen zum Zoomen der Karte",
"CooperativeGesturesHandler.MobileHelpText": "Verwenden Sie zwei Finger, um die Karte zu bewegen."
},
"layerTool": {
"nodeMarkers": "Zeige Knoten",
"directNeighbors": "Direkte Verbindungen anzeigen",
"remoteNeighbors": "Entfernte Verbindungen anzeigen",
"positionPrecision": "Positionsgenauigkeit anzeigen",
"traceroutes": "Traceroutes anzeigen",
"waypoints": "Wegpunkte anzeigen"
},
"mapMenu": {
"locateAria": "Meinen Knoten suchen",
"layersAria": "Kartenformat ändern"
},
"waypointDetail": {
"edit": "Bearbeiten",
"description": "Beschreibung:",
"createdBy": "Bearbeitet:",
"createdDate": "Erstellt:",
"updated": "Aktualisiert:",
"expires": "Gültig bis:",
"distance": "Entfernung:",
"bearing": "Absolute Peilung:",
"lockedTo": "Gesperrt:",
"latitude": "Breitengrad:",
"longitude": "Längengrad:"
},
"myNode": {
"tooltip": "Dieses Gerät"
}
}

View File

@@ -1,39 +1,39 @@
{
"page": {
"title": "Nachrichten: {{chatName}}",
"placeholder": "Nachricht eingeben"
},
"emptyState": {
"title": "Einen Chat auswählen",
"text": "Noch keine Nachrichten."
},
"selectChatPrompt": {
"text": "Wählen Sie einen Kanal oder Knoten, um Nachrichten zu schreiben."
},
"sendMessage": {
"placeholder": "Geben Sie hier Ihre Nachricht ein...",
"sendButton": "Senden"
},
"actionsMenu": {
"addReactionLabel": "Reaktion hinzufügen",
"replyLabel": "Antworten"
},
"deliveryStatus": {
"delivered": {
"label": "Nachricht zugestellt",
"displayText": "Nachricht zugestellt"
},
"failed": {
"label": "Nachrichtenübermittlung fehlgeschlagen",
"displayText": "Zustellung fehlgeschlagen"
},
"unknown": {
"label": "Nachrichtenstatus unbekannt",
"displayText": "Unbekannter Status"
},
"waiting": {
"label": "Nachricht wird gesendet",
"displayText": "Warte auf Zustellung"
}
}
"page": {
"title": "Nachrichten: {{chatName}}",
"placeholder": "Nachricht eingeben"
},
"emptyState": {
"title": "Einen Chat auswählen",
"text": "Noch keine Nachrichten."
},
"selectChatPrompt": {
"text": "Wählen Sie einen Kanal oder Knoten, um Nachrichten zu schreiben."
},
"sendMessage": {
"placeholder": "Geben Sie hier Ihre Nachricht ein...",
"sendButton": "Senden"
},
"actionsMenu": {
"addReactionLabel": "Reaktion hinzufügen",
"replyLabel": "Antworten"
},
"deliveryStatus": {
"delivered": {
"label": "Nachricht zugestellt",
"displayText": "Nachricht zugestellt"
},
"failed": {
"label": "Nachrichtenübermittlung fehlgeschlagen",
"displayText": "Zustellung fehlgeschlagen"
},
"unknown": {
"label": "Nachrichtenstatus unbekannt",
"displayText": "Unbekannter Status"
},
"waiting": {
"label": "Nachricht wird gesendet",
"displayText": "Warte auf Zustellung"
}
}
}

View File

@@ -1,448 +1,448 @@
{
"page": {
"tabAmbientLighting": "Umgebungslicht",
"tabAudio": "Audio",
"tabCannedMessage": "Vordefinierte Nachrichten",
"tabDetectionSensor": "Erkennungssensor",
"tabExternalNotification": "Externe Benachrichtigung",
"tabMqtt": "MQTT",
"tabNeighborInfo": "Nachbarinformation",
"tabPaxcounter": "Pax Zähler",
"tabRangeTest": "Reichweitentest",
"tabSerial": "Seriell",
"tabStoreAndForward": "Speichern&Weiterleiten",
"tabTelemetry": "Telemetrie"
},
"ambientLighting": {
"title": "Einstellung Umgebungsbeleuchtung",
"description": "Einstellungen für das Modul Umgebungsbeleuchtung",
"ledState": {
"label": "LED Status",
"description": "Setzt die LED auf ein oder aus"
},
"current": {
"label": "Stromstärke",
"description": "Legt den Strom für den LED Ausgang fest. Standard ist 10"
},
"red": {
"label": "Rot",
"description": "Legt den roten LED Wert fest. Bereich 0-255"
},
"green": {
"label": "Grün",
"description": "Legt den grünen LED Wert fest. Bereich 0-255"
},
"blue": {
"label": "Blau",
"description": "Legt den blauen LED Wert fest. Bereich 0-255"
}
},
"audio": {
"title": "Audioeinstellungen",
"description": "Einstellungen für das Audiomodul",
"codec2Enabled": {
"label": "Codec 2 aktiviert",
"description": "Codec 2 Audiokodierung aktivieren"
},
"pttPin": {
"label": "GPIO PTT",
"description": "Für PTT verwendeter GPIO Pin"
},
"bitrate": {
"label": "Bitrate",
"description": "Bitrate zur Audiokodierung"
},
"i2sWs": {
"label": "i2S WS",
"description": "GPIO Pin für i2S WS"
},
"i2sSd": {
"label": "i2S SD",
"description": "GPIO Pin für i2S SD"
},
"i2sDin": {
"label": "i2S DIN",
"description": "GPIO Pin für i2S DIN"
},
"i2sSck": {
"label": "i2S SCK",
"description": "GPIO Pin für i2S SCK"
}
},
"cannedMessage": {
"title": "Einstellungen für vordefinierte Nachrichten",
"description": "Einstellungen für das Modul vordefinierte Nachrichten",
"moduleEnabled": {
"label": "Modul aktiviert",
"description": "Vordefinierte Nachrichten aktivieren"
},
"rotary1Enabled": {
"label": "Drehgeber #1 aktiviert",
"description": "Drehgeber aktivieren"
},
"inputbrokerPinA": {
"label": "Drehgeber Pin A",
"description": "GPIO Pin Wert (1-39) für Drehgeber Pin A"
},
"inputbrokerPinB": {
"label": "Drehgeber Pin B",
"description": "GPIO Pin Wert (1-39) für Drehgeber Pin B"
},
"inputbrokerPinPress": {
"label": "Drehgeber Pin Taste",
"description": "GPIO Pin Wert (1-39) für Drehgeber Pin Taste"
},
"inputbrokerEventCw": {
"label": "Ereignis im Uhrzeigersinn",
"description": "Eingabeereignis auswählen."
},
"inputbrokerEventCcw": {
"label": "Ereignis gegen Uhrzeigersinn",
"description": "Eingabeereignis auswählen."
},
"inputbrokerEventPress": {
"label": "Ereignis Tastendruck",
"description": "Eingabeereignis auswählen."
},
"updown1Enabled": {
"label": "Geber Hoch/Runter aktiviert",
"description": "Aktiviere Geber Hoch/Runter"
},
"allowInputSource": {
"label": "Eingabequelle zulassen",
"description": "Wählen Sie aus: '_any', 'rotEnc1', 'upDownEnc1', 'cardkb'"
},
"sendBell": {
"label": "Sende Glocke",
"description": "Sendet ein Klingelzeichen (Glocke) mit jeder Nachricht"
}
},
"detectionSensor": {
"title": "Sensoreinstellungen für Erkennung",
"description": "Einstellungen für das Erkennungssensormodul",
"enabled": {
"label": "Aktiviert",
"description": "Erkennungssensormodul aktivieren oder deaktivieren"
},
"minimumBroadcastSecs": {
"label": "Minimale Übertragungszeit alle Sekunden",
"description": "Das Intervall in Sekunden, wie oft eine Nachricht an das Netz gesendet wird, wenn eine Statusänderung erkannt wurde"
},
"stateBroadcastSecs": {
"label": "Statusübertragung alle Sekunden",
"description": "Das Intervall in Sekunden, wie oft eine Nachricht mit dem aktuellen Status an das Netz gesendet wird, unabhängig von Änderungen"
},
"sendBell": {
"label": "Sende Glocke",
"description": "ASCII-Glocke mit Warnmeldung senden"
},
"name": {
"label": "Anzeigename",
"description": "Formatierte Nachricht die an das Netz gesendet wird, maximal 20 Zeichen"
},
"monitorPin": {
"label": "GPIO Pin überwachen",
"description": "Der GPIO Pin zur Überwachung von Statusänderungen"
},
"detectionTriggerType": {
"label": "Auslösetyp der Erkennung",
"description": "Die Art des zu verwendenden Auslöseereignisses"
},
"usePullup": {
"label": "Pullup verwenden",
"description": "Gibt an, ob der INPUT_PULLUP Modus für GPIO Pin verwendet wird oder nicht"
}
},
"externalNotification": {
"title": "Einstellungen für externe Benachrichtigungen",
"description": "Einstellung für das Modul externe Benachrichtigung",
"enabled": {
"label": "Modul aktiviert",
"description": "Externe Benachrichtigung aktivieren"
},
"outputMs": {
"label": "Ausgabe MS",
"description": "Ausgabe MS"
},
"output": {
"label": "Ausgabe",
"description": "Ausgabe"
},
"outputVibra": {
"label": "Ausgabe Vibration",
"description": "Ausgabe Vibration"
},
"outputBuzzer": {
"label": "Ausgabe Summer",
"description": "Ausgabe Summer"
},
"active": {
"label": "Aktiv",
"description": "Aktiv"
},
"alertMessage": {
"label": "Warnmeldung",
"description": "Warnmeldung"
},
"alertMessageVibra": {
"label": "Vibration bei Warnmeldung",
"description": "Vibration bei Warnmeldung"
},
"alertMessageBuzzer": {
"label": "Summer bei Warnmeldung",
"description": "Summer bei Warnmeldung"
},
"alertBell": {
"label": "Warnglocke",
"description": "Soll beim Empfang eines eingehenden Klingelzeichens (Glocke) eine Warnung ausgelöst werden?"
},
"alertBellVibra": {
"label": "Vibration bei Klingelzeichen",
"description": "Vibration bei Klingelzeichen"
},
"alertBellBuzzer": {
"label": "Summer bei Klingelzeichen",
"description": "Summer bei Klingelzeichen"
},
"usePwm": {
"label": "PWM verwenden",
"description": "PWM verwenden"
},
"nagTimeout": {
"label": "Nervige Verzögerung",
"description": "Nervige Verzögerung"
},
"useI2sAsBuzzer": {
"label": "I2S GPIO Pin als Summer verwenden",
"description": "I2S GPIO Pin als Summerausgang definieren"
}
},
"mqtt": {
"title": "MQTT Einstellungen",
"description": "Einstellungen für das MQTT Modul",
"enabled": {
"label": "Aktiviert",
"description": "MQTT aktivieren oder deaktivieren"
},
"address": {
"label": "MQTT Server Adresse",
"description": "MQTT Serveradresse für Standard/benutzerdefinierte Server"
},
"username": {
"label": "MQTT Benutzername",
"description": "MQTT Benutzername für Standard/benutzerdefinierte Server"
},
"password": {
"label": "MQTT Passwort",
"description": "MQTT Passwort für Standard/benutzerdefinierte Server"
},
"encryptionEnabled": {
"label": "Verschlüsselung aktiviert",
"description": "MQTT-Verschlüsselung aktivieren oder deaktivieren. Hinweis: Alle Nachrichten werden unverschlüsselt an den MQTT-Broker gesendet, wenn diese Option nicht aktiviert ist. Unabhängig von der eingestellten Kanalverschlüsselung. Einschließlich der Standortdaten."
},
"jsonEnabled": {
"label": "JSON aktiviert",
"description": "Gibt an, ob JSON Nachrichten über MQTT gesendet oder empfangen werden sollen"
},
"tlsEnabled": {
"label": "TLS aktiviert",
"description": "TLS aktivieren oder deaktivieren"
},
"root": {
"label": "Hauptthema",
"description": "MQTT Hauptthema für Standard/Benutzerdefinierte Server"
},
"proxyToClientEnabled": {
"label": "MQTT Client Proxy aktiviert",
"description": "Verwendet die Netzwerkverbindung zum Austausch von MQTT Nachrichten mit dem Client."
},
"mapReportingEnabled": {
"label": "Kartenberichte aktiviert",
"description": "Ihr Knoten sendet in regelmäßigen Abständen eine unverschlüsselte Nachricht mit Kartenbericht an den konfigurierten MQTT-Server. Einschließlich ID, langen und kurzen Namen, ungefährer Standort, Hardwaremodell, Geräterolle, Firmware-Version, LoRa Region, Modem-Voreinstellung und Name des Primärkanal."
},
"mapReportSettings": {
"publishIntervalSecs": {
"label": "Veröffentlichungsintervall Kartenbericht (s)",
"description": "Intervall in Sekunden, um Kartenberichte zu veröffentlichen"
},
"positionPrecision": {
"label": "Ungefährer Standort",
"description": "Der geteilte Standort mit einer Genauigkeit innerhalb dieser Entfernung",
"options": {
"metric_km23": "Innerhalb von 23 km",
"metric_km12": "Innerhalb von 12 km",
"metric_km5_8": "Innerhalb von 5,8 km",
"metric_km2_9": "Innerhalb von 2,9 km",
"metric_km1_5": "Innerhalb von 1,5 km",
"metric_m700": "Innerhalb von 700 m",
"metric_m350": "Innerhalb von 350 m",
"metric_m200": "Innerhalb von 200 m",
"metric_m90": "Innerhalb von 90 m",
"metric_m50": "Innerhalb von 50 m",
"imperial_mi15": "Innerhalb von 15 Meilen",
"imperial_mi7_3": "Innerhalb von 7,3 Meilen",
"imperial_mi3_6": "Innerhalb von 3,6 Meilen",
"imperial_mi1_8": "Innerhalb von 1,8 Meilen",
"imperial_mi0_9": "Innerhalb von 0,9 Meilen",
"imperial_mi0_5": "Innerhalb von 0,5 Meilen",
"imperial_mi0_2": "Innerhalb von 0,2 Meilen",
"imperial_ft600": "Innerhalb von 600 Fuß",
"imperial_ft300": "Innerhalb von 300 Fuß",
"imperial_ft150": "Innerhalb von 150 Fuß"
}
}
}
},
"neighborInfo": {
"title": "Einstellung Nachbarinformation",
"description": "Einstellungen für das Modul Nachbarinformation",
"enabled": {
"label": "Aktiviert",
"description": "Nachbarinformation Modul aktivieren oder deaktivieren"
},
"updateInterval": {
"label": "Aktualisierungsintervall",
"description": "Intervall in Sekunden, wie oft die Nachbarinformation an das Netz gesendet wird"
}
},
"paxcounter": {
"title": "Einstellung für Pax Zähler",
"description": "Einstellungen für das Modul Pax Zähler",
"enabled": {
"label": "Modul aktiviert",
"description": "Aktiviere Pax Zähler"
},
"paxcounterUpdateInterval": {
"label": "Aktualisierungsintervall (Sekunden)",
"description": "Wie lange soll zwischen dem Senden von Pax Zählernachrichten gewartet werden"
},
"wifiThreshold": {
"label": "WLAN RSSI Grenzwert",
"description": "Bei welchem WLAN RSSI Grenzwert sollte der Zähler erhöht werden. Standardwert -80"
},
"bleThreshold": {
"label": "BLE RSSI Grenzwert",
"description": "Bei welchem BLE RSSI Grenzwert sollte der Zähler erhöht werden. Standardwert -80"
}
},
"rangeTest": {
"title": "Einstellung Reichweitentest",
"description": "Einstellungen für das Modul Reichweitentest",
"enabled": {
"label": "Modul aktiviert",
"description": "Reichweitentest aktivieren"
},
"sender": {
"label": "Nachrichtenintervall",
"description": "Wie lange soll zwischen dem Senden von Testnachrichten gewartet werden"
},
"save": {
"label": "CSV im internen Speicher abspeichern",
"description": "Nur für ESP32"
}
},
"serial": {
"title": "Serielle Einstellungen",
"description": "Einstellungen für das serielle Modul",
"enabled": {
"label": "Modul aktiviert",
"description": "Serielle Ausgabe aktivieren"
},
"echo": {
"label": "Echo",
"description": "Wenn aktiviert, werden alle Nachrichten, die Sie senden, an Ihr Gerät zurückgesendet"
},
"rxd": {
"label": "GPIO Empfangen",
"description": "Setzen Sie den GPIO Pin, den Sie eingerichtet haben, als RXD Pin."
},
"txd": {
"label": "GPIO Senden",
"description": "Setzen Sie den GPIO Pin, den Sie eingerichtet haben, als TXD Pin."
},
"baud": {
"label": "Baudrate",
"description": "Serielle Baudrate"
},
"timeout": {
"label": "Zeitlimit erreicht",
"description": "Wartezeit in Sekunden bis eine Nachricht als gesendet angenommen wird"
},
"mode": {
"label": "Betriebsmodus",
"description": "Modus auswählen"
},
"overrideConsoleSerialPort": {
"label": "Seriellen Port der Konsole überschreiben",
"description": "Wenn Sie einen seriellen Port an die Konsole angeschlossen haben, wird diese überschrieben."
}
},
"storeForward": {
"title": "Speichern & Weiterleiten Einstellungen",
"description": "Einstellungen für das Modul Speichern & Weiterleiten",
"enabled": {
"label": "Modul aktiviert",
"description": "Speichern & Weiterleiten aktivieren"
},
"heartbeat": {
"label": "Herzschlag aktiviert",
"description": "Herzschlag für Speichern & Weiterleiten aktivieren"
},
"records": {
"label": "Anzahl Einträge",
"description": "Anzahl der zu speichernden Datensätze"
},
"historyReturnMax": {
"label": "Verlauf Rückgabewert maximal",
"description": "Maximale Anzahl an zurückzugebenden Datensätzen"
},
"historyReturnWindow": {
"label": "Zeitraum Rückgabewert",
"description": "Maximale Anzahl an zurückzugebenden Datensätzen"
}
},
"telemetry": {
"title": "Telemetrieeinstellungen",
"description": "Einstellungen für das Telemetriemodul",
"deviceUpdateInterval": {
"label": "Gerätekennzahlen",
"description": "Aktualisierungsintervall für Gerätekennzahlen (Sekunden)"
},
"environmentUpdateInterval": {
"label": "Aktualisierungsintervall für Umweltdaten (Sekunden)",
"description": ""
},
"environmentMeasurementEnabled": {
"label": "Modul aktiviert",
"description": "Aktiviert die Telemetrie für Umweltdaten"
},
"environmentScreenEnabled": {
"label": "OLED Anzeige aktivieren",
"description": "Zeige das Telemetriemodul auf der OLED Anzeige"
},
"environmentDisplayFahrenheit": {
"label": "Temperatur in Fahrenheit",
"description": "Temperatur in Fahrenheit anzeigen"
},
"airQualityEnabled": {
"label": "Luftqualität aktiviert",
"description": "Telemetrie für Luftqualität aktivieren"
},
"airQualityInterval": {
"label": "Aktualisierungsintervall Luftqualität",
"description": "Wie oft werden Luftqualitätsdaten über das Netz gesendet"
},
"powerMeasurementEnabled": {
"label": "Energiemessung aktiviert",
"description": "Aktiviere die Telemetrie für die Energiemessung"
},
"powerUpdateInterval": {
"label": "Aktualisierungsintervall Energie",
"description": "Wie oft werden Energiedaten an das Netz gesendet"
},
"powerScreenEnabled": {
"label": "Energieanzeige aktiviert",
"description": "Aktiviere die Anzeige für Energietelemetrie"
}
}
"page": {
"tabAmbientLighting": "Umgebungslicht",
"tabAudio": "Audio",
"tabCannedMessage": "Vordefinierte Nachrichten",
"tabDetectionSensor": "Erkennungssensor",
"tabExternalNotification": "Externe Benachrichtigung",
"tabMqtt": "MQTT",
"tabNeighborInfo": "Nachbarinformation",
"tabPaxcounter": "Pax Zähler",
"tabRangeTest": "Reichweitentest",
"tabSerial": "Seriell",
"tabStoreAndForward": "Speichern&Weiterleiten",
"tabTelemetry": "Telemetrie"
},
"ambientLighting": {
"title": "Einstellung Umgebungsbeleuchtung",
"description": "Einstellungen für das Modul Umgebungsbeleuchtung",
"ledState": {
"label": "LED Status",
"description": "Setzt die LED auf ein oder aus"
},
"current": {
"label": "Stromstärke",
"description": "Legt den Strom für den LED Ausgang fest. Standard ist 10"
},
"red": {
"label": "Rot",
"description": "Legt den roten LED Wert fest. Bereich 0-255"
},
"green": {
"label": "Grün",
"description": "Legt den grünen LED Wert fest. Bereich 0-255"
},
"blue": {
"label": "Blau",
"description": "Legt den blauen LED Wert fest. Bereich 0-255"
}
},
"audio": {
"title": "Audioeinstellungen",
"description": "Einstellungen für das Audiomodul",
"codec2Enabled": {
"label": "Codec 2 aktiviert",
"description": "Codec 2 Audiokodierung aktivieren"
},
"pttPin": {
"label": "GPIO PTT",
"description": "Für PTT verwendeter GPIO Pin"
},
"bitrate": {
"label": "Bitrate",
"description": "Bitrate zur Audiokodierung"
},
"i2sWs": {
"label": "i2S WS",
"description": "GPIO Pin für i2S WS"
},
"i2sSd": {
"label": "i2S SD",
"description": "GPIO Pin für i2S SD"
},
"i2sDin": {
"label": "i2S DIN",
"description": "GPIO Pin für i2S DIN"
},
"i2sSck": {
"label": "i2S SCK",
"description": "GPIO Pin für i2S SCK"
}
},
"cannedMessage": {
"title": "Einstellungen für vordefinierte Nachrichten",
"description": "Einstellungen für das Modul vordefinierte Nachrichten",
"moduleEnabled": {
"label": "Modul aktiviert",
"description": "Vordefinierte Nachrichten aktivieren"
},
"rotary1Enabled": {
"label": "Drehgeber #1 aktiviert",
"description": "Drehgeber aktivieren"
},
"inputbrokerPinA": {
"label": "Drehgeber Pin A",
"description": "GPIO Pin Wert (1-39) für Drehgeber Pin A"
},
"inputbrokerPinB": {
"label": "Drehgeber Pin B",
"description": "GPIO Pin Wert (1-39) für Drehgeber Pin B"
},
"inputbrokerPinPress": {
"label": "Drehgeber Pin Taste",
"description": "GPIO Pin Wert (1-39) für Drehgeber Pin Taste"
},
"inputbrokerEventCw": {
"label": "Ereignis im Uhrzeigersinn",
"description": "Eingabeereignis auswählen."
},
"inputbrokerEventCcw": {
"label": "Ereignis gegen Uhrzeigersinn",
"description": "Eingabeereignis auswählen."
},
"inputbrokerEventPress": {
"label": "Ereignis Tastendruck",
"description": "Eingabeereignis auswählen."
},
"updown1Enabled": {
"label": "Geber Hoch/Runter aktiviert",
"description": "Aktiviere Geber Hoch/Runter"
},
"allowInputSource": {
"label": "Eingabequelle zulassen",
"description": "Wählen Sie aus: '_any', 'rotEnc1', 'upDownEnc1', 'cardkb'"
},
"sendBell": {
"label": "Sende Glocke",
"description": "Sendet ein Klingelzeichen (Glocke) mit jeder Nachricht"
}
},
"detectionSensor": {
"title": "Sensoreinstellungen für Erkennung",
"description": "Einstellungen für das Erkennungssensormodul",
"enabled": {
"label": "Aktiviert",
"description": "Erkennungssensormodul aktivieren oder deaktivieren"
},
"minimumBroadcastSecs": {
"label": "Minimale Übertragungszeit alle Sekunden",
"description": "Das Intervall in Sekunden, wie oft eine Nachricht an das Netz gesendet wird, wenn eine Statusänderung erkannt wurde"
},
"stateBroadcastSecs": {
"label": "Statusübertragung alle Sekunden",
"description": "Das Intervall in Sekunden, wie oft eine Nachricht mit dem aktuellen Status an das Netz gesendet wird, unabhängig von Änderungen"
},
"sendBell": {
"label": "Sende Glocke",
"description": "ASCII-Glocke mit Warnmeldung senden"
},
"name": {
"label": "Anzeigename",
"description": "Formatierte Nachricht die an das Netz gesendet wird, maximal 20 Zeichen"
},
"monitorPin": {
"label": "GPIO Pin überwachen",
"description": "Der GPIO Pin zur Überwachung von Statusänderungen"
},
"detectionTriggerType": {
"label": "Auslösetyp der Erkennung",
"description": "Die Art des zu verwendenden Auslöseereignisses"
},
"usePullup": {
"label": "Pullup verwenden",
"description": "Gibt an, ob der INPUT_PULLUP Modus für GPIO Pin verwendet wird oder nicht"
}
},
"externalNotification": {
"title": "Einstellungen für externe Benachrichtigungen",
"description": "Einstellung für das Modul externe Benachrichtigung",
"enabled": {
"label": "Modul aktiviert",
"description": "Externe Benachrichtigung aktivieren"
},
"outputMs": {
"label": "Ausgabe MS",
"description": "Ausgabe MS"
},
"output": {
"label": "Ausgabe",
"description": "Ausgabe"
},
"outputVibra": {
"label": "Ausgabe Vibration",
"description": "Ausgabe Vibration"
},
"outputBuzzer": {
"label": "Ausgabe Summer",
"description": "Ausgabe Summer"
},
"active": {
"label": "Aktiv",
"description": "Aktiv"
},
"alertMessage": {
"label": "Warnmeldung",
"description": "Warnmeldung"
},
"alertMessageVibra": {
"label": "Vibration bei Warnmeldung",
"description": "Vibration bei Warnmeldung"
},
"alertMessageBuzzer": {
"label": "Summer bei Warnmeldung",
"description": "Summer bei Warnmeldung"
},
"alertBell": {
"label": "Warnglocke",
"description": "Soll beim Empfang eines eingehenden Klingelzeichens (Glocke) eine Warnung ausgelöst werden?"
},
"alertBellVibra": {
"label": "Vibration bei Klingelzeichen",
"description": "Vibration bei Klingelzeichen"
},
"alertBellBuzzer": {
"label": "Summer bei Klingelzeichen",
"description": "Summer bei Klingelzeichen"
},
"usePwm": {
"label": "PWM verwenden",
"description": "PWM verwenden"
},
"nagTimeout": {
"label": "Nervige Verzögerung",
"description": "Nervige Verzögerung"
},
"useI2sAsBuzzer": {
"label": "I2S GPIO Pin als Summer verwenden",
"description": "I2S GPIO Pin als Summerausgang definieren"
}
},
"mqtt": {
"title": "MQTT Einstellungen",
"description": "Einstellungen für das MQTT Modul",
"enabled": {
"label": "Aktiviert",
"description": "MQTT aktivieren oder deaktivieren"
},
"address": {
"label": "MQTT Server Adresse",
"description": "MQTT Serveradresse für Standard/benutzerdefinierte Server"
},
"username": {
"label": "MQTT Benutzername",
"description": "MQTT Benutzername für Standard/benutzerdefinierte Server"
},
"password": {
"label": "MQTT Passwort",
"description": "MQTT Passwort für Standard/benutzerdefinierte Server"
},
"encryptionEnabled": {
"label": "Verschlüsselung aktiviert",
"description": "MQTT-Verschlüsselung aktivieren oder deaktivieren. Hinweis: Alle Nachrichten werden unverschlüsselt an den MQTT-Broker gesendet, wenn diese Option nicht aktiviert ist. Unabhängig von der eingestellten Kanalverschlüsselung. Einschließlich der Standortdaten."
},
"jsonEnabled": {
"label": "JSON aktiviert",
"description": "Gibt an, ob JSON Nachrichten über MQTT gesendet oder empfangen werden sollen"
},
"tlsEnabled": {
"label": "TLS aktiviert",
"description": "TLS aktivieren oder deaktivieren"
},
"root": {
"label": "Hauptthema",
"description": "MQTT Hauptthema für Standard/Benutzerdefinierte Server"
},
"proxyToClientEnabled": {
"label": "MQTT Client Proxy aktiviert",
"description": "Verwendet die Netzwerkverbindung zum Austausch von MQTT Nachrichten mit dem Client."
},
"mapReportingEnabled": {
"label": "Kartenberichte aktiviert",
"description": "Ihr Knoten sendet in regelmäßigen Abständen eine unverschlüsselte Nachricht mit Kartenbericht an den konfigurierten MQTT-Server. Einschließlich ID, langen und kurzen Namen, ungefährer Standort, Hardwaremodell, Geräterolle, Firmware-Version, LoRa Region, Modem-Voreinstellung und Name des Primärkanal."
},
"mapReportSettings": {
"publishIntervalSecs": {
"label": "Veröffentlichungsintervall Kartenbericht (s)",
"description": "Intervall in Sekunden, um Kartenberichte zu veröffentlichen"
},
"positionPrecision": {
"label": "Ungefährer Standort",
"description": "Der geteilte Standort mit einer Genauigkeit innerhalb dieser Entfernung",
"options": {
"metric_km23": "Innerhalb von 23 km",
"metric_km12": "Innerhalb von 12 km",
"metric_km5_8": "Innerhalb von 5,8 km",
"metric_km2_9": "Innerhalb von 2,9 km",
"metric_km1_5": "Innerhalb von 1,5 km",
"metric_m700": "Innerhalb von 700 m",
"metric_m350": "Innerhalb von 350 m",
"metric_m200": "Innerhalb von 200 m",
"metric_m90": "Innerhalb von 90 m",
"metric_m50": "Innerhalb von 50 m",
"imperial_mi15": "Innerhalb von 15 Meilen",
"imperial_mi7_3": "Innerhalb von 7,3 Meilen",
"imperial_mi3_6": "Innerhalb von 3,6 Meilen",
"imperial_mi1_8": "Innerhalb von 1,8 Meilen",
"imperial_mi0_9": "Innerhalb von 0,9 Meilen",
"imperial_mi0_5": "Innerhalb von 0,5 Meilen",
"imperial_mi0_2": "Innerhalb von 0,2 Meilen",
"imperial_ft600": "Innerhalb von 600 Fuß",
"imperial_ft300": "Innerhalb von 300 Fuß",
"imperial_ft150": "Innerhalb von 150 Fuß"
}
}
}
},
"neighborInfo": {
"title": "Einstellung Nachbarinformation",
"description": "Einstellungen für das Modul Nachbarinformation",
"enabled": {
"label": "Aktiviert",
"description": "Nachbarinformation Modul aktivieren oder deaktivieren"
},
"updateInterval": {
"label": "Aktualisierungsintervall",
"description": "Intervall in Sekunden, wie oft die Nachbarinformation an das Netz gesendet wird"
}
},
"paxcounter": {
"title": "Einstellung für Pax Zähler",
"description": "Einstellungen für das Modul Pax Zähler",
"enabled": {
"label": "Modul aktiviert",
"description": "Aktiviere Pax Zähler"
},
"paxcounterUpdateInterval": {
"label": "Aktualisierungsintervall (Sekunden)",
"description": "Wie lange soll zwischen dem Senden von Pax Zählernachrichten gewartet werden"
},
"wifiThreshold": {
"label": "WLAN RSSI Grenzwert",
"description": "Bei welchem WLAN RSSI Grenzwert sollte der Zähler erhöht werden. Standardwert -80"
},
"bleThreshold": {
"label": "BLE RSSI Grenzwert",
"description": "Bei welchem BLE RSSI Grenzwert sollte der Zähler erhöht werden. Standardwert -80"
}
},
"rangeTest": {
"title": "Einstellung Reichweitentest",
"description": "Einstellungen für das Modul Reichweitentest",
"enabled": {
"label": "Modul aktiviert",
"description": "Reichweitentest aktivieren"
},
"sender": {
"label": "Nachrichtenintervall",
"description": "Wie lange soll zwischen dem Senden von Testnachrichten gewartet werden"
},
"save": {
"label": "CSV im internen Speicher abspeichern",
"description": "Nur für ESP32"
}
},
"serial": {
"title": "Serielle Einstellungen",
"description": "Einstellungen für das serielle Modul",
"enabled": {
"label": "Modul aktiviert",
"description": "Serielle Ausgabe aktivieren"
},
"echo": {
"label": "Echo",
"description": "Wenn aktiviert, werden alle Nachrichten, die Sie senden, an Ihr Gerät zurückgesendet"
},
"rxd": {
"label": "GPIO Empfangen",
"description": "Setzen Sie den GPIO Pin, den Sie eingerichtet haben, als RXD Pin."
},
"txd": {
"label": "GPIO Senden",
"description": "Setzen Sie den GPIO Pin, den Sie eingerichtet haben, als TXD Pin."
},
"baud": {
"label": "Baudrate",
"description": "Serielle Baudrate"
},
"timeout": {
"label": "Zeitlimit erreicht",
"description": "Wartezeit in Sekunden bis eine Nachricht als gesendet angenommen wird"
},
"mode": {
"label": "Betriebsmodus",
"description": "Modus auswählen"
},
"overrideConsoleSerialPort": {
"label": "Seriellen Port der Konsole überschreiben",
"description": "Wenn Sie einen seriellen Port an die Konsole angeschlossen haben, wird diese überschrieben."
}
},
"storeForward": {
"title": "Speichern & Weiterleiten Einstellungen",
"description": "Einstellungen für das Modul Speichern & Weiterleiten",
"enabled": {
"label": "Modul aktiviert",
"description": "Speichern & Weiterleiten aktivieren"
},
"heartbeat": {
"label": "Herzschlag aktiviert",
"description": "Herzschlag für Speichern & Weiterleiten aktivieren"
},
"records": {
"label": "Anzahl Einträge",
"description": "Anzahl der zu speichernden Datensätze"
},
"historyReturnMax": {
"label": "Verlauf Rückgabewert maximal",
"description": "Maximale Anzahl an zurückzugebenden Datensätzen"
},
"historyReturnWindow": {
"label": "Zeitraum Rückgabewert",
"description": "Datensätze aus diesem Zeitfenster zurückgeben (Minuten)"
}
},
"telemetry": {
"title": "Telemetrieeinstellungen",
"description": "Einstellungen für das Telemetriemodul",
"deviceUpdateInterval": {
"label": "Gerätekennzahlen",
"description": "Aktualisierungsintervall für Gerätekennzahlen (Sekunden)"
},
"environmentUpdateInterval": {
"label": "Aktualisierungsintervall für Umweltdaten (Sekunden)",
"description": ""
},
"environmentMeasurementEnabled": {
"label": "Modul aktiviert",
"description": "Aktiviert die Telemetrie für Umweltdaten"
},
"environmentScreenEnabled": {
"label": "OLED Anzeige aktivieren",
"description": "Zeige das Telemetriemodul auf der OLED Anzeige"
},
"environmentDisplayFahrenheit": {
"label": "Temperatur in Fahrenheit",
"description": "Temperatur in Fahrenheit anzeigen"
},
"airQualityEnabled": {
"label": "Luftqualität aktiviert",
"description": "Telemetrie für Luftqualität aktivieren"
},
"airQualityInterval": {
"label": "Aktualisierungsintervall Luftqualität",
"description": "Wie oft werden Luftqualitätsdaten über das Netz gesendet"
},
"powerMeasurementEnabled": {
"label": "Energiemessung aktiviert",
"description": "Aktiviere die Telemetrie für die Energiemessung"
},
"powerUpdateInterval": {
"label": "Aktualisierungsintervall Energie",
"description": "Wie oft werden Energiedaten an das Netz gesendet"
},
"powerScreenEnabled": {
"label": "Energieanzeige aktiviert",
"description": "Aktiviere die Anzeige für Energietelemetrie"
}
}
}

View File

@@ -1,63 +1,59 @@
{
"nodeDetail": {
"publicKeyEnabled": {
"label": "Öffentlicher Schlüssel aktiviert"
},
"noPublicKey": {
"label": "Kein öffentlicher Schlüssel"
},
"directMessage": {
"label": "Direktnachricht {{shortName}}"
},
"favorite": {
"label": "Favorit",
"tooltip": "Diesen Knoten zu Favoriten hinzufügen oder entfernen"
},
"notFavorite": {
"label": "Kein Favorit"
},
"error": {
"label": "Fehler",
"text": "Beim Abrufen der Knotendetails ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut."
},
"status": {
"heard": "Gehört",
"mqtt": "MQTT"
},
"elevation": {
"label": "Höhe"
},
"channelUtil": {
"label": "Kanal-Auslastung"
},
"airtimeUtil": {
"label": "Sendezeit-Auslastung"
}
},
"nodesTable": {
"headings": {
"longName": "Langer Name",
"connection": "Verbindung",
"lastHeard": "Zuletzt gehört",
"encryption": "Verschlüsselung",
"model": "Modell",
"macAddress": "MAC Adresse"
},
"connectionStatus": {
"direct": "Direkt",
"away": "entfernt",
"unknown": "-",
"viaMqtt": ", über MQTT"
},
"lastHeardStatus": {
"never": "Nie"
}
},
"actions": {
"added": "Hinzugefügt",
"removed": "Entfernt",
"ignoreNode": "Knoten ignorieren",
"unignoreNode": "Knoten akzeptieren",
"requestPosition": "Standort anfordern"
}
"nodeDetail": {
"publicKeyEnabled": {
"label": "Öffentlicher Schlüssel aktiviert"
},
"noPublicKey": {
"label": "Kein öffentlicher Schlüssel"
},
"directMessage": {
"label": "Direktnachricht {{shortName}}"
},
"favorite": {
"label": "Favorit",
"tooltip": "Diesen Knoten zu Favoriten hinzufügen oder entfernen"
},
"notFavorite": {
"label": "Kein Favorit"
},
"error": {
"label": "Fehler",
"text": "Beim Abrufen der Knotendetails ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut."
},
"status": {
"heard": "Gehört",
"mqtt": "MQTT"
},
"elevation": {
"label": "Höhe"
},
"channelUtil": {
"label": "Kanal-Auslastung"
},
"airtimeUtil": {
"label": "Sendezeit-Auslastung"
}
},
"nodesTable": {
"headings": {
"longName": "Langer Name",
"connection": "Verbindung",
"lastHeard": "Zuletzt gehört",
"encryption": "Verschlüsselung",
"model": "Modell",
"macAddress": "MAC Adresse"
},
"connectionStatus": {
"direct": "Direkt",
"away": "entfernt",
"viaMqtt": ", über MQTT"
}
},
"actions": {
"added": "Hinzugefügt",
"removed": "Entfernt",
"ignoreNode": "Knoten ignorieren",
"unignoreNode": "Knoten akzeptieren",
"requestPosition": "Standort anfordern"
}
}

View File

@@ -1,228 +1,230 @@
{
"navigation": {
"title": "Navigation",
"messages": "Nachrichten",
"map": "Karte",
"config": "Einstellungen",
"radioConfig": "Funkgerätekonfiguration",
"moduleConfig": "Moduleinstellungen",
"channels": "Kanäle",
"nodes": "Knoten"
},
"app": {
"title": "Meshtastic",
"logo": "Meshtastic Logo"
},
"sidebar": {
"collapseToggle": {
"button": {
"open": "Seitenleiste öffnen",
"close": "Seitenleiste schließen"
}
},
"deviceInfo": {
"volts": "{{voltage}} Volt",
"firmware": {
"title": "Firmware",
"version": "v{{version}}",
"buildDate": "Erstelldatum: {{date}}"
},
"deviceName": {
"title": "Gerätename",
"changeName": "Gerätenamen ändern",
"placeholder": "Gerätenamen eingeben"
},
"editDeviceName": "Gerätenamen bearbeiten"
}
},
"batteryStatus": {
"charging": "{{level}}% Ladung",
"pluggedIn": "Wird geladen",
"title": "Batterie"
},
"search": {
"nodes": "Knoten suchen...",
"channels": "Kanäle suchen...",
"commandPalette": "Befehle suchen..."
},
"toast": {
"positionRequestSent": {
"title": "Standortanfrage gesendet."
},
"requestingPosition": {
"title": "Standort wird angefordert, bitte warten..."
},
"sendingTraceroute": {
"title": "Sende Traceroute, bitte warten..."
},
"tracerouteSent": {
"title": "Traceroute gesendet."
},
"savedChannel": {
"title": "Gespeicherter Kanal: {{channelName}}"
},
"messages": {
"pkiEncryption": {
"title": "Der Chat verwendet PKI-Verschlüsselung."
},
"pskEncryption": {
"title": "Chat verwendet PSK-Verschlüsselung."
}
},
"configSaveError": {
"title": "Fehler beim Speichern von Einstellung",
"description": "Beim Speichern der Einstellungen ist ein Fehler aufgetreten."
},
"validationError": {
"title": "Einstellungsfehler vorhanden",
"description": "Bitte korrigieren Sie die Einstellungsfehler vor dem Speichern."
},
"saveSuccess": {
"title": "Einstellungen speichern",
"description": "Die Einstellungsänderung {{case}} wurde gespeichert."
},
"favoriteNode": {
"title": "{{action}} {{nodeName}} {{direction}} Favoriten.",
"action": {
"added": "Hinzugefügt",
"removed": "Entfernt",
"to": "bis",
"from": "von"
}
},
"ignoreNode": {
"title": "{{action}} {{nodeName}} {{direction}} Ignorierliste",
"action": {
"added": "Hinzugefügt",
"removed": "Entfernt",
"to": "bis",
"from": "von"
}
}
},
"notifications": {
"copied": {
"label": "Kopiert!"
},
"copyToClipboard": {
"label": "In die Zwischenablage kopieren"
},
"hidePassword": {
"label": "Passwort verbergen"
},
"showPassword": {
"label": "Passwort anzeigen"
},
"deliveryStatus": {
"delivered": "Zugestellt",
"failed": "Zustellung fehlgeschlagen",
"waiting": "Warte...",
"unknown": "Unbekannt"
}
},
"general": {
"label": "Allgemein"
},
"hardware": {
"label": "Hardware"
},
"metrics": {
"label": "Messgrößen"
},
"role": {
"label": "Rolle"
},
"filter": {
"label": "Filter"
},
"advanced": {
"label": "Fortgeschritten"
},
"clearInput": {
"label": "Eingabe löschen"
},
"resetFilters": {
"label": "Filter zurücksetzen"
},
"nodeName": {
"label": "Knotenname/-nummer",
"placeholder": "Meshtastic 1234"
},
"airtimeUtilization": {
"label": "Sendezeit-Auslastung (%)"
},
"batteryLevel": {
"label": "Akkustand (%)",
"labelText": "Akkustand (%): {{value}}"
},
"batteryVoltage": {
"label": "Batteriespannung (V)",
"title": "Spannung"
},
"channelUtilization": {
"label": "Kanalauslastung (%)"
},
"hops": {
"direct": "Direkt",
"label": "Anzahl Hops",
"text": "Sprungweite: {{value}}"
},
"lastHeard": {
"label": "Zuletzt gehört",
"labelText": "Zuletzt gehört: {{value}}",
"nowLabel": "Jetzt"
},
"snr": {
"label": "SNR (dB)"
},
"favorites": {
"label": "Favoriten"
},
"hide": {
"label": "Ausblenden"
},
"showOnly": {
"label": "Zeige nur"
},
"viaMqtt": {
"label": "Über MQTT verbunden"
},
"hopsUnknown": {
"label": "Unbekannte Sprungweite"
},
"showUnheard": {
"label": "Nie gehört"
},
"language": {
"label": "Sprache",
"changeLanguage": "Sprache ändern"
},
"theme": {
"dark": "Dunkel",
"light": "Hell",
"system": "Automatisch",
"changeTheme": "Farbschema ändern"
},
"errorPage": {
"title": "Das ist ein wenig peinlich...",
"description1": "Es tut uns wirklich leid, aber im Webclient ist ein Fehler aufgetreten, der es zum Absturz gebracht hat. <br /> Das soll nicht passieren, und wir arbeiten hart daran, es zu beheben.",
"description2": "Der beste Weg, um zu verhindern, dass sich dies Ihnen oder irgendjemand anderem wiederholt, besteht darin, uns über dieses Problem zu berichten.",
"reportInstructions": "Bitte fügen Sie folgende Informationen in Ihren Bericht ein:",
"reportSteps": {
"step1": "Was haben Sie getan, als der Fehler aufgetreten ist",
"step2": "Was haben Sie erwartet",
"step3": "Was tatsächlich passiert ist",
"step4": "Sonstige relevante Informationen"
},
"reportLink": "Sie können das Problem auf unserem <0>GitHub</0> melden",
"dashboardLink": "Zurück zum <0>Dashboard</0>",
"detailsSummary": "Fehlerdetails",
"errorMessageLabel": "Fehlermeldungen:",
"stackTraceLabel": "Stapelabzug:",
"fallbackError": "{{error}}"
},
"footer": {
"text": "Powered by <0>▲ Vercel</0> | Meshtastic® ist eine eingetragene Marke der Meshtastic LLC. | <1>Rechtliche Informationen</1>",
"commitSha": "Commit SHA: {{sha}}"
}
"navigation": {
"title": "Navigation",
"messages": "Nachrichten",
"map": "Karte",
"settings": "Einstellungen",
"channels": "Kanäle",
"radioConfig": "Funkgerätekonfiguration",
"deviceConfig": "Geräteeinstellungen",
"moduleConfig": "Moduleinstellungen",
"manageConnections": "Verbindungen verwalten",
"nodes": "Knoten"
},
"app": {
"title": "Meshtastic",
"logo": "Meshtastic Logo"
},
"sidebar": {
"collapseToggle": {
"button": {
"open": "Seitenleiste öffnen",
"close": "Seitenleiste schließen"
}
},
"deviceInfo": {
"volts": "{{voltage}} Volt",
"firmware": {
"title": "Firmware",
"version": "v{{version}}",
"buildDate": "Erstelldatum: {{date}}"
}
}
},
"batteryStatus": {
"charging": "{{level}}% Ladung",
"pluggedIn": "Wird geladen",
"title": "Batterie"
},
"search": {
"nodes": "Knoten suchen...",
"channels": "Kanäle suchen...",
"commandPalette": "Befehle suchen..."
},
"toast": {
"positionRequestSent": {
"title": "Standortanfrage gesendet."
},
"requestingPosition": {
"title": "Standort wird angefordert, bitte warten..."
},
"sendingTraceroute": {
"title": "Sende Traceroute, bitte warten..."
},
"tracerouteSent": {
"title": "Traceroute gesendet."
},
"savedChannel": {
"title": "Gespeicherter Kanal: {{channelName}}"
},
"messages": {
"pkiEncryption": {
"title": "Der Chat verwendet PKI-Verschlüsselung."
},
"pskEncryption": {
"title": "Chat verwendet PSK-Verschlüsselung."
}
},
"configSaveError": {
"title": "Fehler beim Speichern von Einstellung",
"description": "Beim Speichern der Einstellungen ist ein Fehler aufgetreten."
},
"validationError": {
"title": "Einstellungsfehler vorhanden",
"description": "Bitte korrigieren Sie die Einstellungsfehler vor dem Speichern."
},
"saveSuccess": {
"title": "Einstellungen speichern",
"description": "Die Einstellungsänderung {{case}} wurde gespeichert."
},
"saveAllSuccess": {
"title": "Gespeichert",
"description": "Alle Einstellungsänderungen wurden gespeichert."
},
"favoriteNode": {
"title": "{{action}} {{nodeName}} {{direction}} Favoriten.",
"action": {
"added": "Hinzugefügt",
"removed": "Entfernt",
"to": "bis",
"from": "von"
}
},
"ignoreNode": {
"title": "{{action}} {{nodeName}} {{direction}} Ignorierliste",
"action": {
"added": "Hinzugefügt",
"removed": "Entfernt",
"to": "bis",
"from": "von"
}
}
},
"notifications": {
"copied": {
"label": "Kopiert!"
},
"copyToClipboard": {
"label": "In die Zwischenablage kopieren"
},
"hidePassword": {
"label": "Passwort verbergen"
},
"showPassword": {
"label": "Passwort anzeigen"
},
"deliveryStatus": {
"delivered": "Zugestellt",
"failed": "Zustellung fehlgeschlagen",
"waiting": "Warte...",
"unknown": "Unbekannt"
}
},
"general": {
"label": "Allgemein"
},
"hardware": {
"label": "Hardware"
},
"metrics": {
"label": "Messgrößen"
},
"role": {
"label": "Rolle"
},
"filter": {
"label": "Filter"
},
"advanced": {
"label": "Fortgeschritten"
},
"clearInput": {
"label": "Eingabe löschen"
},
"resetFilters": {
"label": "Filter zurücksetzen"
},
"nodeName": {
"label": "Knotenname/-nummer",
"placeholder": "Meshtastic 1234"
},
"airtimeUtilization": {
"label": "Sendezeit-Auslastung (%)",
"short": "Sendezeit-Auslastung. (%)"
},
"batteryLevel": {
"label": "Akkustand (%)",
"labelText": "Akkustand (%): {{value}}"
},
"batteryVoltage": {
"label": "Batteriespannung (V)",
"title": "Spannung"
},
"channelUtilization": {
"label": "Kanalauslastung (%)",
"short": "Kanal-Auslastung. (%)"
},
"hops": {
"direct": "Direkt",
"label": "Anzahl Hops",
"text": "Sprungweite: {{value}}"
},
"lastHeard": {
"label": "Zuletzt gehört",
"labelText": "Zuletzt gehört: {{value}}",
"nowLabel": "Jetzt"
},
"snr": {
"label": "SNR (dB)"
},
"favorites": {
"label": "Favoriten"
},
"hide": {
"label": "Ausblenden"
},
"showOnly": {
"label": "Zeige nur"
},
"viaMqtt": {
"label": "Über MQTT verbunden"
},
"hopsUnknown": {
"label": "Unbekannte Sprungweite"
},
"showUnheard": {
"label": "Nie gehört"
},
"language": {
"label": "Sprache",
"changeLanguage": "Sprache ändern"
},
"theme": {
"dark": "Dunkel",
"light": "Hell",
"system": "Automatisch",
"changeTheme": "Farbschema ändern"
},
"errorPage": {
"title": "Das ist ein wenig peinlich...",
"description1": "Es tut uns wirklich leid, aber im Webclient ist ein Fehler aufgetreten, der es zum Absturz gebracht hat. <br /> Das soll nicht passieren, und wir arbeiten hart daran, es zu beheben.",
"description2": "Der beste Weg, um zu verhindern, dass sich dies Ihnen oder irgendjemand anderem wiederholt, besteht darin, uns über dieses Problem zu berichten.",
"reportInstructions": "Bitte fügen Sie folgende Informationen in Ihren Bericht ein:",
"reportSteps": {
"step1": "Was haben Sie getan, als der Fehler aufgetreten ist",
"step2": "Was haben Sie erwartet",
"step3": "Was tatsächlich passiert ist",
"step4": "Sonstige relevante Informationen"
},
"reportLink": "Sie können das Problem auf unserem <0>GitHub</0> melden",
"connectionsLink": "Zurück zu den <0>Verbindungen</0>",
"detailsSummary": "Fehlerdetails",
"errorMessageLabel": "Fehlermeldungen:",
"stackTraceLabel": "Stapelabzug:",
"fallbackError": "{{error}}"
},
"footer": {
"text": "Powered by <0>▲ Vercel</0> | Meshtastic® ist eine eingetragene Marke der Meshtastic LLC. | <1>Rechtliche Informationen</1>",
"commitSha": "Commit SHA: {{sha}}"
}
}

View File

@@ -1,14 +1,18 @@
{
"button": {
"apply": "Apply",
"addConnection": "Add Connection",
"saveConnection": "Save connection",
"backupKey": "Backup Key",
"cancel": "Cancel",
"connect": "Connect",
"clearMessages": "Clear Messages",
"close": "Close",
"confirm": "Confirm",
"delete": "Delete",
"dismiss": "Dismiss",
"download": "Download",
"disconnect": "Disconnect",
"export": "Export",
"generate": "Generate",
"regenerate": "Regenerate",
@@ -21,7 +25,10 @@
"requestNewKeys": "Request New Keys",
"requestPosition": "Request Position",
"reset": "Reset",
"retry": "Retry",
"save": "Save",
"setDefault": "Set as default",
"unsetDefault": "Unset default",
"scanQr": "Scan QR Code",
"traceRoute": "Trace Route",
"submit": "Submit"
@@ -45,6 +52,7 @@
"unknown": "Unknown hops away"
},
"megahertz": "MHz",
"kilohertz": "kHz",
"raw": "raw",
"meter": { "one": "Meter", "plural": "Meters", "suffix": "m" },
"kilometer": { "one": "Kilometer", "plural": "Kilometers", "suffix": "km" },

View File

@@ -0,0 +1,470 @@
{
"page": {
"title": "Settings",
"tabUser": "User",
"tabChannels": "Channels",
"tabBluetooth": "Bluetooth",
"tabDevice": "Device",
"tabDisplay": "Display",
"tabLora": "LoRa",
"tabNetwork": "Network",
"tabPosition": "Position",
"tabPower": "Power",
"tabSecurity": "Security"
},
"sidebar": {
"label": "Configuration"
},
"device": {
"title": "Device Settings",
"description": "Settings for the device",
"buttonPin": {
"description": "Button pin override",
"label": "Button Pin"
},
"buzzerPin": {
"description": "Buzzer pin override",
"label": "Buzzer Pin"
},
"disableTripleClick": {
"description": "Disable triple click",
"label": "Disable Triple Click"
},
"doubleTapAsButtonPress": {
"description": "Treat double tap as button press",
"label": "Double Tap as Button Press"
},
"ledHeartbeatDisabled": {
"description": "Disable default blinking LED",
"label": "LED Heartbeat Disabled"
},
"nodeInfoBroadcastInterval": {
"description": "How often to broadcast node info",
"label": "Node Info Broadcast Interval"
},
"posixTimezone": {
"description": "The POSIX timezone string for the device",
"label": "POSIX Timezone"
},
"rebroadcastMode": {
"description": "How to handle rebroadcasting",
"label": "Rebroadcast Mode"
},
"role": {
"description": "What role the device performs on the mesh",
"label": "Role"
}
},
"bluetooth": {
"title": "Bluetooth Settings",
"description": "Settings for the Bluetooth module",
"note": "Note: Some devices (ESP32) cannot use both Bluetooth and WiFi at the same time.",
"enabled": {
"description": "Enable or disable Bluetooth",
"label": "Enabled"
},
"pairingMode": {
"description": "Pin selection behaviour.",
"label": "Pairing mode"
},
"pin": {
"description": "Pin to use when pairing",
"label": "Pin"
}
},
"display": {
"description": "Settings for the device display",
"title": "Display Settings",
"headingBold": {
"description": "Bolden the heading text",
"label": "Bold Heading"
},
"carouselDelay": {
"description": "How fast to cycle through windows",
"label": "Carousel Delay"
},
"compassNorthTop": {
"description": "Fix north to the top of compass",
"label": "Compass North Top"
},
"displayMode": {
"description": "Screen layout variant",
"label": "Display Mode"
},
"displayUnits": {
"description": "Display metric or imperial units",
"label": "Display Units"
},
"flipScreen": {
"description": "Flip display 180 degrees",
"label": "Flip Screen"
},
"gpsDisplayUnits": {
"description": "Coordinate display format",
"label": "GPS Display Units"
},
"oledType": {
"description": "Type of OLED screen attached to the device",
"label": "OLED Type"
},
"screenTimeout": {
"description": "Turn off the display after this long",
"label": "Screen Timeout"
},
"twelveHourClock": {
"description": "Use 12-hour clock format",
"label": "12-Hour Clock"
},
"wakeOnTapOrMotion": {
"description": "Wake the device on tap or motion",
"label": "Wake on Tap or Motion"
}
},
"lora": {
"title": "Mesh Settings",
"description": "Settings for the LoRa mesh",
"bandwidth": {
"description": "Channel bandwidth in kHz",
"label": "Bandwidth"
},
"boostedRxGain": {
"description": "Boosted RX gain",
"label": "Boosted RX Gain"
},
"codingRate": {
"description": "The denominator of the coding rate",
"label": "Coding Rate"
},
"frequencyOffset": {
"description": "Frequency offset to correct for crystal calibration errors",
"label": "Frequency Offset"
},
"frequencySlot": {
"description": "LoRa frequency channel number",
"label": "Frequency Slot"
},
"hopLimit": {
"description": "Maximum number of hops",
"label": "Hop Limit"
},
"ignoreMqtt": {
"description": "Don't forward MQTT messages over the mesh",
"label": "Ignore MQTT"
},
"modemPreset": {
"description": "Modem preset to use",
"label": "Modem Preset"
},
"okToMqtt": {
"description": "When set to true, this configuration indicates that the user approves the packet to be uploaded to MQTT. If set to false, remote nodes are requested not to forward packets to MQTT",
"label": "OK to MQTT"
},
"overrideDutyCycle": {
"description": "Override Duty Cycle",
"label": "Override Duty Cycle"
},
"overrideFrequency": {
"description": "Override frequency",
"label": "Override Frequency"
},
"region": {
"description": "Sets the region for your node",
"label": "Region"
},
"spreadingFactor": {
"description": "Indicates the number of chirps per symbol",
"label": "Spreading Factor"
},
"transmitEnabled": {
"description": "Enable/Disable transmit (TX) from the LoRa radio",
"label": "Transmit Enabled"
},
"transmitPower": {
"description": "Max transmit power",
"label": "Transmit Power"
},
"usePreset": {
"description": "Use one of the predefined modem presets",
"label": "Use Preset"
},
"meshSettings": {
"description": "Settings for the LoRa mesh",
"label": "Mesh Settings"
},
"waveformSettings": {
"description": "Settings for the LoRa waveform",
"label": "Waveform Settings"
},
"radioSettings": {
"label": "Radio Settings",
"description": "Settings for the LoRa radio"
}
},
"network": {
"title": "WiFi Config",
"description": "WiFi radio configuration",
"note": "Note: Some devices (ESP32) cannot use both Bluetooth and WiFi at the same time.",
"addressMode": {
"description": "Address assignment selection",
"label": "Address Mode"
},
"dns": {
"description": "DNS Server",
"label": "DNS"
},
"ethernetEnabled": {
"description": "Enable or disable the Ethernet port",
"label": "Enabled"
},
"gateway": {
"description": "Default Gateway",
"label": "Gateway"
},
"ip": {
"description": "IP Address",
"label": "IP"
},
"psk": {
"description": "Network password",
"label": "PSK"
},
"ssid": {
"description": "Network name",
"label": "SSID"
},
"subnet": {
"description": "Subnet Mask",
"label": "Subnet"
},
"wifiEnabled": {
"description": "Enable or disable the WiFi radio",
"label": "Enabled"
},
"meshViaUdp": {
"label": "Mesh via UDP"
},
"ntpServer": {
"label": "NTP Server"
},
"rsyslogServer": {
"label": "Rsyslog Server"
},
"ethernetConfigSettings": {
"description": "Ethernet port configuration",
"label": "Ethernet Config"
},
"ipConfigSettings": {
"description": "IP configuration",
"label": "IP Config"
},
"ntpConfigSettings": {
"description": "NTP configuration",
"label": "NTP Config"
},
"rsyslogConfigSettings": {
"description": "Rsyslog configuration",
"label": "Rsyslog Config"
},
"udpConfigSettings": {
"description": "UDP over Mesh configuration",
"label": "UDP Config"
}
},
"position": {
"title": "Position Settings",
"description": "Settings for the position module",
"broadcastInterval": {
"description": "How often your position is sent out over the mesh",
"label": "Broadcast Interval"
},
"enablePin": {
"description": "GPS module enable pin override",
"label": "Enable Pin"
},
"fixedPosition": {
"description": "Don't report GPS position, but a manually-specified one",
"label": "Fixed Position",
"latitude": {
"label": "Latitude",
"description": "Decimal degrees between -90 and 90 (e.g., 37.7749)"
},
"longitude": {
"label": "Longitude",
"description": "Decimal degrees between -180 and 180 (e.g., -122.4194)"
},
"altitude": {
"label": "Altitude",
"description": "Optional — enter the altitude in {{unit}} above sea level (e.g., 100). Leave blank if unknown or add extra height for antennas/masts."
}
},
"gpsMode": {
"description": "Configure whether device GPS is Enabled, Disabled, or Not Present",
"label": "GPS Mode"
},
"gpsUpdateInterval": {
"description": "How often a GPS fix should be acquired",
"label": "GPS Update Interval"
},
"positionFlags": {
"description": "Optional fields to include when assembling position messages. The more fields are selected, the larger the message will be leading to longer airtime usage and a higher risk of packet loss.",
"label": "Position Flags"
},
"receivePin": {
"description": "GPS module RX pin override",
"label": "Receive Pin"
},
"smartPositionEnabled": {
"description": "Only send position when there has been a meaningful change in location",
"label": "Enable Smart Position"
},
"smartPositionMinDistance": {
"description": "Minimum distance (in meters) that must be traveled before a position update is sent",
"label": "Smart Position Minimum Distance"
},
"smartPositionMinInterval": {
"description": "Minimum interval (in seconds) that must pass before a position update is sent",
"label": "Smart Position Minimum Interval"
},
"transmitPin": {
"description": "GPS module TX pin override",
"label": "Transmit Pin"
},
"intervalsSettings": {
"description": "How often to send position updates",
"label": "Intervals"
},
"flags": {
"placeholder": "Select position flags...",
"altitude": "Altitude",
"altitudeGeoidalSeparation": "Altitude Geoidal Separation",
"altitudeMsl": "Altitude is Mean Sea Level",
"dop": "Dilution of precision (DOP) PDOP used by default",
"hdopVdop": "If DOP is set, use HDOP / VDOP values instead of PDOP",
"numSatellites": "Number of satellites",
"sequenceNumber": "Sequence number",
"timestamp": "Timestamp",
"unset": "Unset",
"vehicleHeading": "Vehicle heading",
"vehicleSpeed": "Vehicle speed"
}
},
"power": {
"adcMultiplierOverride": {
"description": "Used for tweaking battery voltage reading",
"label": "ADC Multiplier Override ratio"
},
"ina219Address": {
"description": "Address of the INA219 battery monitor",
"label": "INA219 Address"
},
"lightSleepDuration": {
"description": "How long the device will be in light sleep for",
"label": "Light Sleep Duration"
},
"minimumWakeTime": {
"description": "Minimum amount of time the device will stay awake for after receiving a packet",
"label": "Minimum Wake Time"
},
"noConnectionBluetoothDisabled": {
"description": "If the device does not receive a Bluetooth connection, the BLE radio will be disabled after this long",
"label": "No Connection Bluetooth Disabled"
},
"powerSavingEnabled": {
"description": "Select if powered from a low-current source (i.e. solar), to minimize power consumption as much as possible.",
"label": "Enable power saving mode"
},
"shutdownOnBatteryDelay": {
"description": "Automatically shutdown node after this long when on battery, 0 for indefinite",
"label": "Shutdown on battery delay"
},
"superDeepSleepDuration": {
"description": "How long the device will be in super deep sleep for",
"label": "Super Deep Sleep Duration"
},
"powerConfigSettings": {
"description": "Settings for the power module",
"label": "Power Config"
},
"sleepSettings": {
"description": "Sleep settings for the power module",
"label": "Sleep Settings"
}
},
"security": {
"description": "Settings for the Security configuration",
"title": "Security Settings",
"button_backupKey": "Backup Key",
"adminChannelEnabled": {
"description": "Allow incoming device control over the insecure legacy admin channel",
"label": "Allow Legacy Admin"
},
"enableDebugLogApi": {
"description": "Output live debug logging over serial, view and export position-redacted device logs over Bluetooth",
"label": "Enable Debug Log API"
},
"managed": {
"description": "If enabled, device configuration options are only able to be changed remotely by a Remote Admin node via admin messages. Do not enable this option unless at least one suitable Remote Admin node has been setup, and the public key is stored in one of the fields above.",
"label": "Managed"
},
"privateKey": {
"description": "Used to create a shared key with a remote device",
"label": "Private Key"
},
"publicKey": {
"description": "Sent out to other nodes on the mesh to allow them to compute a shared secret key",
"label": "Public Key"
},
"primaryAdminKey": {
"description": "The primary public key authorized to send admin messages to this node",
"label": "Primary Admin Key"
},
"secondaryAdminKey": {
"description": "The secondary public key authorized to send admin messages to this node",
"label": "Secondary Admin Key"
},
"serialOutputEnabled": {
"description": "Serial Console over the Stream API",
"label": "Serial Output Enabled"
},
"tertiaryAdminKey": {
"description": "The tertiary public key authorized to send admin messages to this node",
"label": "Tertiary Admin Key"
},
"adminSettings": {
"description": "Settings for Admin",
"label": "Admin Settings"
},
"loggingSettings": {
"description": "Settings for Logging",
"label": "Logging Settings"
}
},
"user": {
"title": "User Settings",
"description": "Configure your device name and identity settings",
"longName": {
"label": "Long Name",
"description": "Your full display name (1-40 characters)",
"validation": {
"min": "Long name must be at least 1 character",
"max": "Long name must be at most 40 characters"
}
},
"shortName": {
"label": "Short Name",
"description": "Your abbreviated name (2-4 characters)",
"validation": {
"min": "Short name must be at least 2 characters",
"max": "Short name must be at most 4 characters"
}
},
"isUnmessageable": {
"label": "Unmessageable",
"description": "Used to identify unmonitored or infrastructure nodes so that messaging is not available to nodes that will never respond."
},
"isLicensed": {
"label": "Licensed amateur radio (HAM)",
"description": "Enable if you are a licensed amateur radio operator, enabling this option disables encryption and is not compatible with the default Meshtastic network."
}
}
}

View File

@@ -0,0 +1,34 @@
{
"page": {
"title": "Connect to a Meshtastic device",
"description": "Add a device connection via HTTP, Bluetooth, or Serial. Your saved connections will be saved in your browser."
},
"connectionType_ble": "BLE",
"connectionType_serial": "Serial",
"connectionType_network": "Network",
"deleteConnection": "Delete connection",
"areYouSure": "This will remove {{name}}. You canot undo this action.",
"moreActions": "More actions",
"noConnections": {
"title": "No connections yet.",
"description": "Create your first connection. It will connect immediately and be saved for later."
},
"lastConnectedAt": "Last connected: {{date}}",
"neverConnected": "Never connected",
"toasts": {
"connected": "Connected",
"nowConnected": "{{name}} is now connected",
"nowDisconnected": "{{name}} is now disconnected",
"disconnected": "Disconnected",
"failed": "Failed to connect",
"checkConnection": "Check your device or settings and try again",
"defaultSet": "Default set",
"defaultConnection": "Default connection is now {{nameisconnected}}",
"deleted": "Deleted",
"deletedByName": "{{name}} was removed",
"pickConnectionAgain": "Could not connect. You may need to reselect the device/port.",
"added": "Connection added",
"savedByName": "{{name}} saved.",
"savedCantConnect": "The connection was saved but could not connect."
}
}

View File

@@ -1,12 +0,0 @@
{
"dashboard": {
"title": "Connected Devices",
"description": "Manage your connected Meshtastic devices.",
"connectionType_ble": "BLE",
"connectionType_serial": "Serial",
"connectionType_network": "Network",
"noDevicesTitle": "No devices connected",
"noDevicesDescription": "Connect a new device to get started.",
"button_newConnection": "New Connection"
}
}

Some files were not shown because too many files have changed in this diff Show More