Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
011ede9966 | ||
|
|
eaf6f3d593 | ||
|
|
6b298d1648 | ||
|
|
f9e6d69ae6 | ||
|
|
7f48db7ddb | ||
|
|
b0ff5f50bf | ||
|
|
a0cda099e7 | ||
|
|
a9c52b8667 | ||
|
|
bbe9a0d5cd | ||
|
|
7a8529b841 | ||
|
|
87043f35cb | ||
|
|
90f8219f8d | ||
|
|
0d08f872b9 | ||
|
|
a364c91f25 | ||
|
|
ca0355c700 | ||
|
|
4118887cda | ||
|
|
3be19bb7a4 | ||
|
|
fbbfac6e5c | ||
|
|
bdee96fe97 | ||
|
|
70edffeeae | ||
|
|
569c990575 | ||
|
|
20dbcf06c1 | ||
|
|
e0d4504bca | ||
|
|
0060a01824 | ||
|
|
dbf7f5b18d | ||
|
|
25e70512ce | ||
|
|
af499556bb | ||
|
|
dc3da4c9d8 | ||
|
|
d492e1d4f2 | ||
|
|
fa902e6fb8 | ||
|
|
d35ccdf7a6 | ||
|
|
801e70f201 | ||
|
|
24ec09dd43 | ||
|
|
22d125a750 | ||
|
|
28029ba17f | ||
|
|
79f936c310 | ||
|
|
8cd8b0bf01 | ||
|
|
d6172fd6dd | ||
|
|
cd5cb28132 | ||
|
|
78f11dd0ee | ||
|
|
379c8773dc | ||
|
|
2f78b64dfd | ||
|
|
9a4820523f | ||
|
|
356b8a2331 | ||
|
|
cf1ab96c93 | ||
|
|
28d36dde31 | ||
|
|
9998c82ba0 | ||
|
|
6535c96e81 | ||
|
|
080cce1bf0 | ||
|
|
3c1c23c1b9 | ||
|
|
c729d3b25e | ||
|
|
a90df07ebe | ||
|
|
0579ec523e | ||
|
|
9ebee7a8f4 | ||
|
|
2b03bce0d5 | ||
|
|
948146ddc8 | ||
|
|
ce06bc4128 | ||
|
|
765e4afe4d | ||
|
|
0108494bd8 | ||
|
|
3ecea59da8 | ||
|
|
0b2fdb6439 | ||
|
|
94220e729b | ||
|
|
020e9d6b63 | ||
|
|
6a7be99a6a | ||
|
|
5debdb4689 | ||
|
|
057043864f | ||
|
|
8918603f96 | ||
|
|
68cea2e858 | ||
|
|
06cc266acd | ||
|
|
295755ec4c | ||
|
|
b99057df69 | ||
|
|
390b46f026 | ||
|
|
94d51912e6 | ||
|
|
ac28fbc53d | ||
|
|
648a9c3640 | ||
|
|
7f21b3b531 | ||
|
|
d1597ce00f | ||
|
|
0c8fcec23d | ||
|
|
2e03b4a413 | ||
|
|
a00cb2098b | ||
|
|
6aeaed988e | ||
|
|
7c9013a217 | ||
|
|
ab0308701c | ||
|
|
e13d543e73 | ||
|
|
d8ad0efcdf | ||
|
|
2e60af1e29 | ||
|
|
1af1295b8f | ||
|
|
a1a646983e | ||
|
|
4386854e9d | ||
|
|
e821a65dd4 | ||
|
|
3392c9db08 | ||
|
|
e53edfb00f | ||
|
|
1df63bb84b | ||
|
|
679f7986cc | ||
|
|
f375911c4a | ||
|
|
68ad535259 | ||
|
|
0cf677c8d5 | ||
|
|
ff02b1455d | ||
|
|
cdad811295 | ||
|
|
fc1e327b74 | ||
|
|
af2fac1465 | ||
|
|
15daa0270c | ||
|
|
80c9306db3 | ||
|
|
c3f073a380 | ||
|
|
fe35376450 | ||
|
|
64d1f0f7aa | ||
|
|
a61bb2dfb6 |
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$SKIP_SIMPLE_GIT_HOOKS" = "1" ]; then
|
||||
echo "[INFO] SKIP_SIMPLE_GIT_HOOKS is set to 1, skipping hook."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f "$SIMPLE_GIT_HOOKS_RC" ]; then
|
||||
. "$SIMPLE_GIT_HOOKS_RC"
|
||||
fi
|
||||
|
||||
# cd packages/web && bun run lint && bun run format
|
||||
@@ -0,0 +1,3 @@
|
||||
## Design Standards
|
||||
|
||||
All UI must comply with the [Meshtastic Client Design Standards](https://raw.githubusercontent.com/meshtastic/design/refs/heads/master/standards/meshtastic_design_standards_latest.md). Fetch and review this document before making any UI changes.
|
||||
@@ -0,0 +1,21 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
cooldown:
|
||||
default-days: 3 # 1 day after pnpm's cutoff, prevent a race
|
||||
groups:
|
||||
tanstack:
|
||||
patterns:
|
||||
- "@tanstack/*"
|
||||
react-ecosystem:
|
||||
patterns:
|
||||
- react
|
||||
- react-dom
|
||||
- "@types/react*"
|
||||
@@ -14,19 +14,17 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: latest
|
||||
uses: pnpm/action-setup@v6
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
node-version: 24
|
||||
cache: pnpm
|
||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||
cache-dependency-path: "**/pnpm-lock.yaml"
|
||||
|
||||
- name: Prewarm & Install (workspace)
|
||||
run: |
|
||||
@@ -40,7 +38,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" "packages/web")
|
||||
|
||||
is_excluded() {
|
||||
local dir="$1"
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Download translations with Crowdin
|
||||
uses: crowdin/github-action@v2
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Upload sources with Crowdin
|
||||
uses: crowdin/github-action@v2
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Upload translations with Crowdin
|
||||
uses: crowdin/github-action@v2
|
||||
|
||||
@@ -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
|
||||
@@ -3,7 +3,7 @@ name: Nightly Release
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 5 * * *" # 05:00 UTC daily
|
||||
workflow_dispatch: {} # allow manual runs too
|
||||
workflow_dispatch: {} # allow manual runs too
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -18,19 +18,17 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: latest
|
||||
uses: pnpm/action-setup@v6
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
node-version: 24
|
||||
cache: pnpm
|
||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||
cache-dependency-path: "**/pnpm-lock.yaml"
|
||||
|
||||
- name: Install dependencies (root)
|
||||
run: pnpm install --frozen-lockfile
|
||||
@@ -39,18 +37,18 @@ jobs:
|
||||
run: pnpm run test
|
||||
|
||||
- name: Build web package
|
||||
working-directory: packages/web
|
||||
working-directory: apps/web
|
||||
run: pnpm run build
|
||||
|
||||
- name: Package output
|
||||
working-directory: packages/web
|
||||
working-directory: apps/web
|
||||
run: pnpm run package
|
||||
|
||||
- name: Upload compressed build (artifact)
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: web-build-nightly
|
||||
path: packages/web/dist/build.tar
|
||||
path: apps/web/dist/build.tar
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Compute tags and labels
|
||||
@@ -66,8 +64,8 @@ jobs:
|
||||
|
||||
# Try to use latest release tag if it exists; fallback to package version; else date
|
||||
LATEST_TAG="$(gh release view --json tagName --jq .tagName 2>/dev/null || true)"
|
||||
if [ -z "$LATEST_TAG" ] && [ -f packages/web/package.json ]; then
|
||||
LATEST_TAG="v$(jq -r .version packages/web/package.json)"
|
||||
if [ -z "$LATEST_TAG" ] && [ -f apps/web/package.json ]; then
|
||||
LATEST_TAG="v$(jq -r .version apps/web/package.json)"
|
||||
fi
|
||||
|
||||
if [ -n "${LATEST_TAG:-}" ] && [ "$LATEST_TAG" != "vnull" ]; then
|
||||
@@ -84,20 +82,20 @@ jobs:
|
||||
echo "Resolved tags: nightly and ${IMMUTABLE}"
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Build Container Image (multi-arch)
|
||||
id: build-container
|
||||
uses: redhat-actions/buildah-build@v2
|
||||
with:
|
||||
containerfiles: |
|
||||
./packages/web/infra/Containerfile
|
||||
./apps/web/infra/Containerfile
|
||||
image: ${{ env.REGISTRY_IMAGE }}
|
||||
tags: |
|
||||
${{ 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 }}
|
||||
|
||||
@@ -17,24 +17,32 @@ env:
|
||||
jobs:
|
||||
build-and-package:
|
||||
runs-on: ubuntu-latest
|
||||
# Skip for draft PRs; remove this line if you want to run on drafts too
|
||||
if: ${{ github.event.pull_request.draft == false }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: latest
|
||||
uses: pnpm/action-setup@v6
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
node-version: 24
|
||||
cache: pnpm
|
||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||
cache-dependency-path: pnpm-lock.yaml
|
||||
|
||||
- name: Debug dependency state
|
||||
run: |
|
||||
set -euo pipefail
|
||||
echo "GITHUB_SHA=${GITHUB_SHA}"
|
||||
git log --oneline -1
|
||||
pnpm --version
|
||||
node --version
|
||||
grep -n "meshtastic__protobufs" pnpm-lock.yaml || true
|
||||
grep -n "2.7.18" pnpm-lock.yaml || true
|
||||
grep -n "2.7.20" pnpm-lock.yaml || true
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
@@ -49,4 +57,4 @@ jobs:
|
||||
run: pnpm run test
|
||||
|
||||
- name: Build web package
|
||||
run: pnpm --filter "./packages/web" run build
|
||||
run: pnpm --filter "./apps/web" run build
|
||||
|
||||
@@ -6,36 +6,34 @@ on:
|
||||
packages:
|
||||
description: 'Packages to release (comma-separated, or "all")'
|
||||
required: false
|
||||
default: 'all'
|
||||
default: "all"
|
||||
bump:
|
||||
description: 'Semver bump (patch | minor | major)'
|
||||
description: "Semver bump (patch | minor | major)"
|
||||
required: false
|
||||
default: 'patch'
|
||||
default: "patch"
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write # we commit the bumped versions back
|
||||
id-token: write # required for JSR OIDC
|
||||
contents: write # we commit the bumped versions back
|
||||
id-token: write # required for JSR OIDC
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: latest
|
||||
uses: pnpm/action-setup@v6
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
node-version: 24
|
||||
cache: pnpm
|
||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache-dependency-path: "**/pnpm-lock.yaml"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
@@ -82,7 +80,6 @@ jobs:
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
- name: Commit version bumps
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -69,9 +69,7 @@ jobs:
|
||||
github_token: ${{ github.token }}
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: latest
|
||||
uses: pnpm/action-setup@v6
|
||||
|
||||
- name: Install workspace dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
@@ -108,7 +106,7 @@ jobs:
|
||||
cp README.md $PROTOBUF_DIR/packages/ts
|
||||
|
||||
- name: Upload TypeScript code
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ts_code
|
||||
path: ${{ env.PROTOBUF_DIR }}/packages/ts
|
||||
@@ -123,7 +121,7 @@ jobs:
|
||||
DRY_RUN: ${{ inputs.dry_run }}
|
||||
steps:
|
||||
- name: Download TypeScript code
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: ts_code
|
||||
|
||||
|
||||
@@ -31,45 +31,43 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.ref != '' && inputs.ref || github.ref }}
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: latest
|
||||
uses: pnpm/action-setup@v6
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
node-version: 24
|
||||
cache: pnpm
|
||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||
cache-dependency-path: "**/pnpm-lock.yaml"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build web package
|
||||
working-directory: packages/web
|
||||
working-directory: apps/web
|
||||
run: pnpm run build
|
||||
|
||||
- name: Create release archive
|
||||
working-directory: packages/web
|
||||
working-directory: apps/web
|
||||
run: pnpm run package
|
||||
|
||||
- name: Upload archive (artifact)
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: web-build
|
||||
path: packages/web/dist/build.tar
|
||||
path: apps/web/dist/build.tar
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Attach archive to GitHub Release
|
||||
if: ${{ github.event_name == 'release' || inputs.attach_to_release == true }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@v3
|
||||
with:
|
||||
files: packages/web/dist/build.tar
|
||||
files: apps/web/dist/build.tar
|
||||
tag_name: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.tag_name }}
|
||||
fail_on_unmatched_files: true
|
||||
env:
|
||||
@@ -91,7 +89,7 @@ jobs:
|
||||
# * else: adhoc-<shortsha>
|
||||
- name: Docker metadata (tags & labels)
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: ${{ env.REGISTRY_IMAGE }}
|
||||
labels: |
|
||||
@@ -115,13 +113,13 @@ jobs:
|
||||
type=raw,value=sha-${{ steps.gen.outputs.shortsha }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Set up Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@@ -131,15 +129,15 @@ jobs:
|
||||
# - release (released or prereleased)
|
||||
# - manual with a tag_name (adhoc builds can still be pushed by name)
|
||||
- name: Build and push image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
file: ./packages/web/infra/Containerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
file: ./apps/web/infra/Containerfile
|
||||
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 }}
|
||||
provenance: false
|
||||
provenance: false
|
||||
|
||||
- name: Output image refs
|
||||
if: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.tag_name != '') }}
|
||||
|
||||
@@ -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
|
||||
uses: actions/checkout@v6
|
||||
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
|
||||
|
||||
@@ -9,5 +9,12 @@ __screenshots__*
|
||||
npm/
|
||||
.idea
|
||||
**/LICENSE
|
||||
.DS_Store
|
||||
|
||||
packages/protobufs/packages/ts/dist
|
||||
.pnpm-store/
|
||||
|
||||
# Local dev certs
|
||||
*.pem
|
||||
*.crt
|
||||
*.key
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
[submodule "packages/packages/protobufs"]
|
||||
path = packages/packages/protobufs
|
||||
url = https://github.com/meshtastic/protobufs
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
pnpm lint-staged
|
||||
@@ -1,10 +1,6 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.biome": "explicit"
|
||||
},
|
||||
"search.exclude": {
|
||||
"**/i18n/locales/*-*/**": true
|
||||
},
|
||||
"vitest.workspaceConfig": "vitest.config.ts"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
# Protobuf catch-up to firmware-current
|
||||
|
||||
> Draft PR description + the one decision for maintainers. This file is **untracked** —
|
||||
> use it as the PR body, then delete it (or leave it, it won't be committed).
|
||||
|
||||
## What this does
|
||||
|
||||
- Syncs the vendored `.proto` sources in `packages/protobufs/meshtastic/` from ~v2.7.20 to
|
||||
**firmware-current (v2.7.25 + 48 commits)** — +2 new files (`deviceonly_legacy`, `serial_hal`)
|
||||
and additions across `config` / `module_config` / `mesh` / `admin` / `portnums` / `telemetry`.
|
||||
- Regenerates the v2 TS bindings (`buf generate`).
|
||||
- Makes the app consume the **workspace** protobufs (`workspace:*`) instead of the stale JSR
|
||||
`@meshtastic/protobufs@2.7.20`, finishing the monorepo migration that was half-done
|
||||
(`@meshtastic/core` was already `workspace:*`; protobufs was still on JSR).
|
||||
- One breaking-change fix: `admin.proto` `nodedb_reset` changed `int32 → bool`, so
|
||||
`MeshDevice.resetNodes()` now sends `value: true` (the oneof-case presence triggers the
|
||||
reset; `true` preserves favorites through it).
|
||||
|
||||
## Free wins (dynamic enum dropdowns — no UI code)
|
||||
|
||||
New LoRa regions (ITU/EU amateur bands), modem presets (LONG_TURBO, LITE/NARROW/TINY_*),
|
||||
~25 hardware names, `OLED_SH1107_ROTATED`, serial `LOG`/`LOGTEXT` — they flow into the
|
||||
existing enum-bound `<select>`s automatically once the bindings regenerate.
|
||||
|
||||
## Breaking proto changes that DON'T break us (verified)
|
||||
|
||||
- `deviceonly.proto` `NodeInfoLite` restructure — core never imports `NodeInfoLite`.
|
||||
- `channel.proto` `is_client_muted → is_muted` + `mute` removed — neither web nor core
|
||||
references those fields yet.
|
||||
|
||||
## The one decision for maintainers — how to consume the protobufs
|
||||
|
||||
This changeset takes **Option A (workspace consumption):** rename the workspace package
|
||||
`@meshtastic/protobufs-ws → @meshtastic/protobufs` (still `private`), point its `exports` at the
|
||||
TS source, and depend on it via `workspace:*` from root + core.
|
||||
|
||||
- ✅ Monorepo is self-consuming and always firmware-current; no publish round-trip; matches
|
||||
the already-migrated `@meshtastic/core`.
|
||||
- ⚠️ Diverges from the JSR publish flow; the published JSR `@meshtastic/protobufs`
|
||||
(latest 2.7.23) is no longer what the app builds against.
|
||||
|
||||
**Option B (canonical publish flow):** keep the package JSR-published — sync the `.proto`
|
||||
sources here, publish a new `@meshtastic/protobufs` to JSR, then bump the root range.
|
||||
|
||||
- ✅ Stays on the established pipeline; one source of truth on JSR.
|
||||
- ⚠️ Needs a JSR publish, and can't reach firmware-current until that release lands
|
||||
(JSR tops out at 2.7.23, still behind firmware).
|
||||
|
||||
If you prefer **B**, everything except the 3 dependency-wiring edits still applies — the
|
||||
`.proto` sync, the regen, and the `nodedbReset` fix are identical; only the root dep, the core
|
||||
dep, and the protobufs `package.json` name/exports get swapped for a JSR publish + range bump.
|
||||
|
||||
## Regenerating bindings
|
||||
|
||||
```
|
||||
pnpm --filter @meshtastic/protobufs gen
|
||||
```
|
||||
|
||||
Output lands in `packages/protobufs/packages/ts/dist/` (gitignored).
|
||||
|
||||
## Verified in isolation (this branch only — no feature/demo code)
|
||||
|
||||
- `packages/core` typecheck: clean except 2 **pre-existing** `queue.ts` strict-catch errors.
|
||||
- `packages/web` `vite build`: green.
|
||||
- 36 config/module validation tests: pass.
|
||||
@@ -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! Here’s 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>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxfmt/configuration_schema.json",
|
||||
"useTabs": false,
|
||||
"tabWidth": 2,
|
||||
"printWidth": 80,
|
||||
"ignorePatterns": [
|
||||
"node_modules",
|
||||
"dist",
|
||||
"protobufs",
|
||||
"**/locales/*-*/*.json",
|
||||
"**/packages/ui/"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json",
|
||||
"plugins": ["react", "react-perf", "jsx-a11y", "typescript", "import"],
|
||||
"rules": {
|
||||
"no-debugger": "error",
|
||||
"@typescript-eslint/no-explicit-any": "error",
|
||||
"@typescript-eslint/no-unused-vars": "error",
|
||||
"import/no-unused-modules": "error"
|
||||
},
|
||||
"ignorePatterns": [
|
||||
"node_modules",
|
||||
"dist",
|
||||
"protobufs",
|
||||
"**/locales/*-*/*.json",
|
||||
"**/packages/ui/"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/*.test.ts", "**/*.test.tsx", "**/__tests__/**/*.{ts,tsx}"],
|
||||
"rules": {
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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"
|
||||
@@ -6,9 +6,9 @@ RUN rm -r /usr/share/nginx/html \
|
||||
|
||||
WORKDIR /usr/share/nginx/html
|
||||
|
||||
ADD ./packages/web/dist .
|
||||
ADD ./apps/web/dist .
|
||||
|
||||
COPY ./packages/web/infra/default.conf /etc/nginx/conf.d/default.conf
|
||||
COPY ./apps/web/infra/default.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
@@ -14,16 +14,21 @@
|
||||
"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",
|
||||
"check": "biome check src/",
|
||||
"check:fix": "biome check --write src/",
|
||||
"build:analyze": "BUNDLE_ANALYZE=true pnpm run build",
|
||||
"lint": "oxlint",
|
||||
"lint:fix": "oxlint --fix",
|
||||
"format": "oxfmt --check .",
|
||||
"format:fix": "oxfmt .",
|
||||
"check": "pnpm lint && pnpm format",
|
||||
"check:fix": "pnpm lint:fix && pnpm format:fix",
|
||||
"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": {
|
||||
@@ -33,12 +38,15 @@
|
||||
"@meshtastic/transport-web-bluetooth": "workspace:*",
|
||||
"@meshtastic/transport-web-serial": "workspace:*",
|
||||
"@noble/curves": "^1.9.2",
|
||||
"@radix-ui/react-accordion": "^1.2.12",
|
||||
"@preact/signals-core": "^1.8.0",
|
||||
"better-result": "^1.0.0",
|
||||
"@radix-ui/react-accordion": "^1.2.13",
|
||||
"@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",
|
||||
"@radix-ui/react-label": "^2.1.7",
|
||||
"@radix-ui/react-menubar": "^1.1.16",
|
||||
"@radix-ui/react-menubar": "^1.1.17",
|
||||
"@radix-ui/react-popover": "^1.1.15",
|
||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
@@ -51,10 +59,10 @@
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@radix-ui/react-visually-hidden": "^1.2.3",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
"@tanstack/react-router": "^1.132.47",
|
||||
"@tanstack/react-router-devtools": "^1.132.47",
|
||||
"@tanstack/router-cli": "^1.132.47",
|
||||
"@tanstack/router-devtools": "^1.132.47",
|
||||
"@tanstack/react-router": "^1.170.15",
|
||||
"@tanstack/react-router-devtools": "^1.167.0",
|
||||
"@tanstack/router-cli": "^1.167.17",
|
||||
"@tanstack/router-devtools": "^1.167.0",
|
||||
"@turf/turf": "^7.2.0",
|
||||
"@types/node": "^24.7.0",
|
||||
"@types/web-bluetooth": "^0.0.21",
|
||||
@@ -63,30 +71,30 @@
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.1.1",
|
||||
"crypto-random-string": "^5.0.0",
|
||||
"i18next": "^25.5.3",
|
||||
"i18next": "^26.3.1",
|
||||
"i18next-browser-languagedetector": "^8.2.0",
|
||||
"i18next-http-backend": "^3.0.2",
|
||||
"i18next-http-backend": "^4.0.0",
|
||||
"idb-keyval": "^6.2.2",
|
||||
"immer": "^10.1.3",
|
||||
"js-cookie": "^3.0.5",
|
||||
"lucide-react": "^0.545.0",
|
||||
"immer": "^11.1.8",
|
||||
"js-cookie": "^3.0.7",
|
||||
"lucide-react": "^1.17.0",
|
||||
"maplibre-gl": "5.8.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-error-boundary": "^6.0.0",
|
||||
"react-hook-form": "^7.64.0",
|
||||
"react-i18next": "^16.0.0",
|
||||
"react-hook-form": "^7.78.0",
|
||||
"react-i18next": "^17.0.8",
|
||||
"react-map-gl": "8.1.0",
|
||||
"react-qrcode-logo": "^4.0.0",
|
||||
"rfc4648": "^1.5.4",
|
||||
"vite": "^7.1.9",
|
||||
"vite": "^7.3.5",
|
||||
"vite-plugin-html": "^3.2.2",
|
||||
"vite-plugin-pwa": "^1.0.3",
|
||||
"vite-plugin-pwa": "^1.3.0",
|
||||
"zod": "^4.1.12",
|
||||
"zustand": "5.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tanstack/router-plugin": "^1.132.47",
|
||||
"@tanstack/router-plugin": "^1.168.18",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@testing-library/user-event": "^14.6.1",
|
||||
@@ -97,17 +105,19 @@
|
||||
"@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",
|
||||
"simple-git-hooks": "^2.13.1",
|
||||
"happy-dom": "^20.8.9",
|
||||
"oxfmt": "^0.16.0",
|
||||
"oxlint": "^1.41.0",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"tar": "^7.5.1",
|
||||
"tar": "^7.5.16",
|
||||
"testing-library": "^0.0.2",
|
||||
"typescript": "^5.9.3",
|
||||
"vitest": "^3.2.4"
|
||||
"vitest": "^4.1.8"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 164 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
@@ -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": {
|
||||
@@ -3,32 +3,20 @@
|
||||
"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": "Import a Channel Set from a Meshtastic URL. <br />Valid Meshtasic URLs start with \"<italic>https://meshtastic.org/e/...</italic>\"",
|
||||
"description": "The current LoRa configuration will be overridden.",
|
||||
"error": {
|
||||
"invalidUrl": "Invalid Meshtastic URL"
|
||||
},
|
||||
"channelPrefix": "Channel ",
|
||||
"channelPrefix": "Channel: ",
|
||||
"primary": "Primary ",
|
||||
"doNotImport": "No not import",
|
||||
"channelName": "Name",
|
||||
"channelName": "Назва",
|
||||
"channelSlot": "Slot",
|
||||
"channelSetUrl": "Channel Set/QR Code URL",
|
||||
"useLoraConfig": "Import LoRa Config",
|
||||
"presetDescription": "The current LoRa Config will be replaced.",
|
||||
"title": "Import Channels"
|
||||
"title": "Import Channel Set"
|
||||
},
|
||||
"locationResponse": {
|
||||
"title": "Location: {{identifier}}",
|
||||
@@ -41,49 +29,77 @@
|
||||
"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"
|
||||
},
|
||||
"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 HTTPS",
|
||||
"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": {
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,7 +398,7 @@
|
||||
},
|
||||
"historyReturnWindow": {
|
||||
"label": "History return window",
|
||||
"description": "Max number of records to return"
|
||||
"description": "Return records from this time window (minutes)"
|
||||
}
|
||||
},
|
||||
"telemetry": {
|
||||
@@ -49,7 +49,6 @@
|
||||
"viaMqtt": ", via MQTT"
|
||||
}
|
||||
},
|
||||
|
||||
"actions": {
|
||||
"added": "Added",
|
||||
"removed": "Removed",
|
||||
@@ -0,0 +1,230 @@
|
||||
{
|
||||
"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}}"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"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 фута"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
"messages": "Съобщения",
|
||||
"map": "Карта",
|
||||
"config": "Конфигурация",
|
||||
"channels": "Канали",
|
||||
"nodes": "Възли"
|
||||
}
|
||||
},
|
||||
@@ -45,7 +44,8 @@
|
||||
"label": "Отстраняване на грешки",
|
||||
"command": {
|
||||
"reconfigure": "Преконфигуриране",
|
||||
"clearAllStoredMessages": "Изчистване на всички съхранени съобщения"
|
||||
"clearAllStoredMessages": "Изчистване на всички съхранени съобщения",
|
||||
"clearAllStores": "Clear All Local Storage"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
{
|
||||
"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": "Не"
|
||||
}
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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": "Връзката беше запазена, но не можа да се осъществи свързване."
|
||||
}
|
||||
}
|
||||
@@ -122,7 +122,7 @@
|
||||
"title": "Настройки на Mesh",
|
||||
"description": "Настройки за LoRa mesh",
|
||||
"bandwidth": {
|
||||
"description": "Широчина на канала в MHz",
|
||||
"description": "Широчина на канала в kHz",
|
||||
"label": "Широчина на честотната лента"
|
||||
},
|
||||
"boostedRxGain": {
|
||||
@@ -0,0 +1,238 @@
|
||||
{
|
||||
"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."
|
||||
}
|
||||
}
|
||||
@@ -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": "Това устройство"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +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": "Чака доставка"
|
||||
}
|
||||
}
|
||||
}
|
||||