mirror of
https://github.com/syncthing/syncthing.git
synced 2026-01-03 19:39:20 -05:00
Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4704d3bc48 | ||
|
|
2794b04243 | ||
|
|
1ce64971fd | ||
|
|
eb6d80eac4 | ||
|
|
a8db3351ae | ||
|
|
23a900e096 | ||
|
|
5a304cf295 | ||
|
|
136b3742bf | ||
|
|
21e0f98fe2 | ||
|
|
2bb5b2244b | ||
|
|
2f281799c1 | ||
|
|
18a58a2ddc | ||
|
|
f283215fce | ||
|
|
495809ac9e | ||
|
|
9ca8addcf7 | ||
|
|
94181ade23 | ||
|
|
e50933433e | ||
|
|
a2b8f2361e | ||
|
|
4b60e86d02 | ||
|
|
d6b5676603 | ||
|
|
3821b6ceee | ||
|
|
973585e97d | ||
|
|
ba6ac2f604 | ||
|
|
57d399317e | ||
|
|
f2d6722348 | ||
|
|
7b1b77e50d | ||
|
|
06914b872b | ||
|
|
f6df8b40b4 | ||
|
|
e057f5ee9a | ||
|
|
a5bf110d90 | ||
|
|
debbe726e0 | ||
|
|
ec3e474a53 | ||
|
|
ebb1edc652 | ||
|
|
6204670c66 | ||
|
|
ff9b24f388 | ||
|
|
01b820dc78 | ||
|
|
79ae24df76 | ||
|
|
61b94b9ea5 | ||
|
|
6fb3c5ccf2 | ||
|
|
2e7c03420f | ||
|
|
faa56b4bb7 | ||
|
|
d7ba5316b8 | ||
|
|
bdfd0f0548 | ||
|
|
5d27185083 | ||
|
|
4dfb9d7c83 | ||
|
|
2f15670094 | ||
|
|
b49137ce36 | ||
|
|
7e4e65ebf5 | ||
|
|
8c8167a4ab | ||
|
|
73cc5553b6 | ||
|
|
2ab2488274 | ||
|
|
eb9cd363d0 | ||
|
|
7fe3906534 | ||
|
|
5fdab1bf11 | ||
|
|
13a6d43f0b | ||
|
|
ac942e2481 | ||
|
|
bbd2a7fbc5 |
13
.github/ISSUE_TEMPLATE/01-feature.md
vendored
13
.github/ISSUE_TEMPLATE/01-feature.md
vendored
@@ -1,13 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: If you're just not sure how to do something, see "ask a question".
|
||||
labels: enhancement, needs-triage
|
||||
---
|
||||
|
||||
### Include required information
|
||||
|
||||
Please be sure to include at least:
|
||||
|
||||
- what problem your new feature would solve
|
||||
- how or why you think it is generally useful (i.e., not just for you)
|
||||
- what alternatives or workarounds you considered
|
||||
28
.github/ISSUE_TEMPLATE/01-feature.yml
vendored
Normal file
28
.github/ISSUE_TEMPLATE/01-feature.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Feature request
|
||||
description: File a new feature request
|
||||
labels: ["enhancement", "needs-triage"]
|
||||
body:
|
||||
|
||||
- type: textarea
|
||||
id: feature
|
||||
attributes:
|
||||
label: Feature description
|
||||
description: Please describe the behavior you'd like to see.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: problem-usecase
|
||||
attributes:
|
||||
label: Problem or use case
|
||||
description: Please explain which problem this would solve, or what the use case is for the feature. Keep in mind that it's more likely to be implemented if it's generally useful for a larger number of users.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
attributes:
|
||||
label: Alternatives or workarounds
|
||||
description: Please describe any alternatives or workarounds you have considered and, possibly, rejected.
|
||||
validations:
|
||||
required: true
|
||||
23
.github/ISSUE_TEMPLATE/02-bug.md
vendored
23
.github/ISSUE_TEMPLATE/02-bug.md
vendored
@@ -1,23 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: If you're actually looking for support, see "ask a question".
|
||||
labels: bug, needs-triage
|
||||
---
|
||||
|
||||
### Does your log mention database corruption?
|
||||
|
||||
If your Syncthing log reports panics because of database corruption it is
|
||||
most likely a fault with your system's storage or memory. Affected log
|
||||
entries will contain lines starting with `panic: leveldb`. You will need to
|
||||
delete the index database to clear this, by running `syncthing
|
||||
-reset-database`.
|
||||
|
||||
### Include required information
|
||||
|
||||
Please be sure to include at least:
|
||||
|
||||
- which version of Syncthing and what operating system you are using
|
||||
- browser and version, if applicable
|
||||
- what happened,
|
||||
- what you expected to happen instead, and
|
||||
- any steps to reproduce the problem.
|
||||
51
.github/ISSUE_TEMPLATE/02-bug.yml
vendored
Normal file
51
.github/ISSUE_TEMPLATE/02-bug.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
name: Bug report
|
||||
description: If you're actually looking for support instead, see "I need help / I have a question".
|
||||
labels: ["bug", "needs-triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
:no_entry_sign: If you want to report a security issue, please see [our Security Policy](https://syncthing.net/security/) and do not report the issue here.
|
||||
|
||||
:interrobang: If you are not sure if there is a bug, but something isn't working right and you need help, please [use the forum](https://forum.syncthing.net/).
|
||||
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: Also tell us, what did you expect to happen, and any steps we might use to reproduce the problem.
|
||||
placeholder: Tell us what you see!
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Syncthing version
|
||||
description: What version of Syncthing are you running?
|
||||
placeholder: v1.27.4
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: platform
|
||||
attributes:
|
||||
label: Platform & operating system
|
||||
description: On what platform(s) are you seeing the problem?
|
||||
placeholder: Linux arm64
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: browser
|
||||
attributes:
|
||||
label: Browser version
|
||||
description: If the problem is related to the GUI, describe your browser and version.
|
||||
placeholder: Safari 17.3.1
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output or crash backtrace. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
2
.github/workflows/build-infra-dockers.yaml
vendored
2
.github/workflows/build-infra-dockers.yaml
vendored
@@ -7,7 +7,7 @@ on:
|
||||
- infra-*
|
||||
|
||||
env:
|
||||
GO_VERSION: "~1.22.0"
|
||||
GO_VERSION: "~1.22.3"
|
||||
CGO_ENABLED: "0"
|
||||
BUILD_USER: docker
|
||||
BUILD_HOST: github.syncthing.net
|
||||
|
||||
55
.github/workflows/build-syncthing.yaml
vendored
55
.github/workflows/build-syncthing.yaml
vendored
@@ -12,7 +12,7 @@ env:
|
||||
# The go version to use for builds. We set check-latest to true when
|
||||
# installing, so we get the latest patch version that matches the
|
||||
# expression.
|
||||
GO_VERSION: "~1.22.0"
|
||||
GO_VERSION: "~1.22.3"
|
||||
|
||||
# Optimize compatibility on the slow archictures.
|
||||
GO386: softfloat
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
runner: ["windows-latest", "ubuntu-latest", "macos-latest"]
|
||||
# The oldest version in this list should match what we have in our go.mod.
|
||||
# Variables don't seem to be supported here, or we could have done something nice.
|
||||
go: ["~1.21.7", "~1.22.0"]
|
||||
go: ["~1.21.7", "~1.22.3"]
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- name: Set git to use LF
|
||||
@@ -642,19 +642,20 @@ jobs:
|
||||
cd packages
|
||||
"$GITHUB_WORKSPACE/tools/generate-release-json" "$BASE_URL" > nightly.json
|
||||
env:
|
||||
BASE_URL: https://syncthing.ams3.digitaloceanspaces.com/nightly/
|
||||
BASE_URL: ${{ secrets.NIGHTLY_BASE_URL }}
|
||||
|
||||
- name: Push artifacts
|
||||
uses: docker://docker.io/rclone/rclone:latest
|
||||
env:
|
||||
RCLONE_CONFIG_SPACES_TYPE: s3
|
||||
RCLONE_CONFIG_SPACES_PROVIDER: DigitalOcean
|
||||
RCLONE_CONFIG_SPACES_ACCESS_KEY_ID: ${{ secrets.SPACES_KEY }}
|
||||
RCLONE_CONFIG_SPACES_SECRET_ACCESS_KEY: ${{ secrets.SPACES_SECRET }}
|
||||
RCLONE_CONFIG_SPACES_ENDPOINT: ams3.digitaloceanspaces.com
|
||||
RCLONE_CONFIG_SPACES_ACL: public-read
|
||||
RCLONE_CONFIG_OBJSTORE_TYPE: s3
|
||||
RCLONE_CONFIG_OBJSTORE_PROVIDER: ${{ secrets.S3_PROVIDER }}
|
||||
RCLONE_CONFIG_OBJSTORE_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }}
|
||||
RCLONE_CONFIG_OBJSTORE_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }}
|
||||
RCLONE_CONFIG_OBJSTORE_ENDPOINT: ${{ secrets.S3_ENDPOINT }}
|
||||
RCLONE_CONFIG_OBJSTORE_REGION: ${{ secrets.S3_REGION }}
|
||||
RCLONE_CONFIG_OBJSTORE_ACL: public-read
|
||||
with:
|
||||
args: sync packages spaces:syncthing/nightly
|
||||
args: sync packages objstore:${{ secrets.S3_BUCKET }}/nightly
|
||||
|
||||
#
|
||||
# Push release artifacts to Spaces
|
||||
@@ -696,29 +697,31 @@ jobs:
|
||||
version=$(go run build.go version)
|
||||
echo "VERSION=$version" >> $GITHUB_ENV
|
||||
|
||||
- name: Push to Spaces (${{ env.VERSION }})
|
||||
- name: Push to object store (${{ env.VERSION }})
|
||||
uses: docker://docker.io/rclone/rclone:latest
|
||||
env:
|
||||
RCLONE_CONFIG_SPACES_TYPE: s3
|
||||
RCLONE_CONFIG_SPACES_PROVIDER: DigitalOcean
|
||||
RCLONE_CONFIG_SPACES_ACCESS_KEY_ID: ${{ secrets.SPACES_KEY }}
|
||||
RCLONE_CONFIG_SPACES_SECRET_ACCESS_KEY: ${{ secrets.SPACES_SECRET }}
|
||||
RCLONE_CONFIG_SPACES_ENDPOINT: ams3.digitaloceanspaces.com
|
||||
RCLONE_CONFIG_SPACES_ACL: public-read
|
||||
RCLONE_CONFIG_OBJSTORE_TYPE: s3
|
||||
RCLONE_CONFIG_OBJSTORE_PROVIDER: ${{ secrets.S3_PROVIDER }}
|
||||
RCLONE_CONFIG_OBJSTORE_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }}
|
||||
RCLONE_CONFIG_OBJSTORE_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }}
|
||||
RCLONE_CONFIG_OBJSTORE_ENDPOINT: ${{ secrets.S3_ENDPOINT }}
|
||||
RCLONE_CONFIG_OBJSTORE_REGION: ${{ secrets.S3_REGION }}
|
||||
RCLONE_CONFIG_OBJSTORE_ACL: public-read
|
||||
with:
|
||||
args: sync packages spaces:syncthing/release/${{ env.VERSION }}
|
||||
args: sync packages objstore:${{ secrets.S3_BUCKET }}/release/${{ env.VERSION }}
|
||||
|
||||
- name: Push to Spaces (latest)
|
||||
- name: Push to object store (latest)
|
||||
uses: docker://docker.io/rclone/rclone:latest
|
||||
env:
|
||||
RCLONE_CONFIG_SPACES_TYPE: s3
|
||||
RCLONE_CONFIG_SPACES_PROVIDER: DigitalOcean
|
||||
RCLONE_CONFIG_SPACES_ACCESS_KEY_ID: ${{ secrets.SPACES_KEY }}
|
||||
RCLONE_CONFIG_SPACES_SECRET_ACCESS_KEY: ${{ secrets.SPACES_SECRET }}
|
||||
RCLONE_CONFIG_SPACES_ENDPOINT: ams3.digitaloceanspaces.com
|
||||
RCLONE_CONFIG_SPACES_ACL: public-read
|
||||
RCLONE_CONFIG_OBJSTORE_TYPE: s3
|
||||
RCLONE_CONFIG_OBJSTORE_PROVIDER: ${{ secrets.S3_PROVIDER }}
|
||||
RCLONE_CONFIG_OBJSTORE_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }}
|
||||
RCLONE_CONFIG_OBJSTORE_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }}
|
||||
RCLONE_CONFIG_OBJSTORE_ENDPOINT: ${{ secrets.S3_ENDPOINT }}
|
||||
RCLONE_CONFIG_OBJSTORE_REGION: ${{ secrets.S3_REGION }}
|
||||
RCLONE_CONFIG_OBJSTORE_ACL: public-read
|
||||
with:
|
||||
args: sync spaces:syncthing/release/${{ env.VERSION }} spaces:syncthing/release/latest
|
||||
args: sync objstore:${{ secrets.S3_BUCKET }}/release/${{ env.VERSION }} objstore:${{ secrets.S3_BUCKET }}/release/latest
|
||||
|
||||
#
|
||||
# Build and push to Docker Hub
|
||||
|
||||
9
AUTHORS
9
AUTHORS
@@ -157,13 +157,14 @@ Jacek Szafarkiewicz (hadogenes) <szafar@linux.pl>
|
||||
Jack Croft <jccroft1@users.noreply.github.com>
|
||||
Jacob <jyundt@gmail.com>
|
||||
Jake Peterson (acogdev) <jake@acogdev.com>
|
||||
Jakob Borg (calmh) <jakob@nym.se> <jakob@kastelo.net>
|
||||
Jakob Borg (calmh) <jakob@nym.se> <jakob@kastelo.net> <jborg@coreweave.com>
|
||||
James O'Beirne <wild-github@au92.org>
|
||||
James Patterson (jpjp) <jamespatterson@operamail.com> <jpjp@users.noreply.github.com>
|
||||
janost <janost@tuta.io>
|
||||
Jaroslav Lichtblau <svetlemodry@users.noreply.github.com>
|
||||
Jaroslav Malec (dzarda) <dzardacz@gmail.com>
|
||||
jaseg <githubaccount@jaseg.net>
|
||||
Jaspitta <ste.scarpitta@gmail.com>
|
||||
Jauder Ho <jauderho@users.noreply.github.com>
|
||||
Jaya Chithra (jayachithra) <s.k.jayachithra@gmail.com>
|
||||
Jaya Kumar <jaya.kumar@ict.nl>
|
||||
@@ -208,7 +209,9 @@ Liu Siyuan (liusy182) <liusy182@gmail.com> <liusy182@hotmail.com>
|
||||
Lode Hoste (Zillode) <zillode@zillode.be>
|
||||
Lord Landon Agahnim (LordLandon) <lordlandon@gmail.com>
|
||||
LSmithx2 <42276854+lsmithx2@users.noreply.github.com>
|
||||
luchenhan <168071714+luchenhan@users.noreply.github.com>
|
||||
Lukas Lihotzki <lukas@lihotzki.de>
|
||||
Luke Hamburg <1992842+luckman212@users.noreply.github.com>
|
||||
luzpaz <luzpaz@users.noreply.github.com>
|
||||
Majed Abdulaziz (majedev) <majed.alhajry@gmail.com>
|
||||
Marc Laporte (marclaporte) <marc@marclaporte.com> <marc@laporte.name>
|
||||
@@ -298,6 +301,7 @@ Scott Klupfel (kluppy) <kluppy@going2blue.com>
|
||||
sec65 <106604020+sec65@users.noreply.github.com>
|
||||
Sergey Mishin (ralder) <ralder@yandex.ru>
|
||||
Sertonix <83883937+Sertonix@users.noreply.github.com>
|
||||
Severin von Wnuck-Lipinski <ss7@live.de>
|
||||
Shaarad Dalvi <60266155+shaaraddalvi@users.noreply.github.com> <shdalv@microsoft.com>
|
||||
Simon Frei (imsodin) <freisim93@gmail.com>
|
||||
Simon Mwepu <simonmwepu@gmail.com>
|
||||
@@ -310,9 +314,11 @@ Sven Bachmann <dev@mcbachmann.de>
|
||||
Syncthing Automation <automation@syncthing.net>
|
||||
Syncthing Release Automation <release@syncthing.net>
|
||||
Taylor Khan (nelsonkhan) <nelsonkhan@gmail.com>
|
||||
Thomas <9749173+uhthomas@users.noreply.github.com>
|
||||
Thomas Hipp <thomashipp@gmail.com>
|
||||
Tim Abell (timabell) <tim@timwise.co.uk>
|
||||
Tim Howes (timhowes) <timhowes@berkeley.edu>
|
||||
Tim Nordenfur <tim@gurka.se>
|
||||
Tobias Klauser <tobias.klauser@gmail.com>
|
||||
Tobias Nygren (tnn2) <tnn@nygren.pp.se>
|
||||
Tobias Tom (tobiastom) <t.tom@succont.de>
|
||||
@@ -331,6 +337,7 @@ Vil Brekin (Vilbrekin) <vilbrekin@gmail.com>
|
||||
villekalliomaki <53118179+villekalliomaki@users.noreply.github.com>
|
||||
Vladimir Rusinov <vrusinov@google.com> <vladimir.rusinov@gmail.com>
|
||||
wangguoliang <liangcszzu@163.com>
|
||||
WangXi <xib1102@icloud.com>
|
||||
Will Rouesnel <wrouesnel@wrouesnel.com>
|
||||
William A. Kennington III (wkennington) <william@wkennington.com>
|
||||
wouter bolsterlee <wouter@bolsterl.ee>
|
||||
|
||||
@@ -11,14 +11,6 @@ LABEL org.opencontainers.image.authors="The Syncthing Project" \
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
RUN apk add --no-cache ca-certificates su-exec curl
|
||||
ENV PUID=1000 PGID=1000 MAXMIND_KEY=
|
||||
|
||||
RUN mkdir /var/strelaypoolsrv && chown 1000 /var/strelaypoolsrv
|
||||
USER 1000
|
||||
|
||||
COPY strelaypoolsrv-linux-${TARGETARCH} /bin/strelaypoolsrv
|
||||
COPY script/strelaypoolsrv-entrypoint.sh /bin/entrypoint.sh
|
||||
|
||||
WORKDIR /var/strelaypoolsrv
|
||||
ENTRYPOINT ["/bin/entrypoint.sh", "/bin/strelaypoolsrv", "-listen", ":8080"]
|
||||
ENTRYPOINT ["/bin/strelaypoolsrv", "-listen", ":8080"]
|
||||
|
||||
@@ -63,12 +63,6 @@ implementations][11] for Windows, Mac, and Linux.
|
||||
|
||||
To run Syncthing in Docker, see [the Docker README][16].
|
||||
|
||||
## Vote on features/bugs
|
||||
|
||||
We'd like to encourage you to [vote][12] on issues that matter to you.
|
||||
This helps the team understand what are the biggest pain points for our
|
||||
users, and could potentially influence what is being worked on next.
|
||||
|
||||
## Getting in Touch
|
||||
|
||||
The first and best point of contact is the [Forum][8].
|
||||
@@ -111,7 +105,6 @@ All code is licensed under the [MPLv2 License][7].
|
||||
[8]: https://forum.syncthing.net/
|
||||
[10]: https://github.com/syncthing/syncthing/issues
|
||||
[11]: https://docs.syncthing.net/users/contrib.html#gui-wrappers
|
||||
[12]: https://www.bountysource.com/teams/syncthing/issues
|
||||
[13]: https://github.com/syncthing/syncthing/blob/main/GOALS.md
|
||||
[14]: assets/logo-text-128.png
|
||||
[15]: https://syncthing.net/
|
||||
|
||||
1
build.go
1
build.go
@@ -33,7 +33,6 @@ import (
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
_ "github.com/syncthing/syncthing/lib/automaxprocs"
|
||||
buildpkg "github.com/syncthing/syncthing/lib/build"
|
||||
)
|
||||
|
||||
|
||||
@@ -21,11 +21,14 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kong"
|
||||
raven "github.com/getsentry/raven-go"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
_ "github.com/syncthing/syncthing/lib/automaxprocs"
|
||||
"github.com/syncthing/syncthing/lib/build"
|
||||
"github.com/syncthing/syncthing/lib/sha256"
|
||||
"github.com/syncthing/syncthing/lib/ur"
|
||||
)
|
||||
@@ -33,13 +36,15 @@ import (
|
||||
const maxRequestSize = 1 << 20 // 1 MiB
|
||||
|
||||
type cli struct {
|
||||
Dir string `help:"Parent directory to store crash and failure reports in" env:"REPORTS_DIR" default:"."`
|
||||
DSN string `help:"Sentry DSN" env:"SENTRY_DSN"`
|
||||
Listen string `help:"HTTP listen address" default:":8080" env:"LISTEN_ADDRESS"`
|
||||
MaxDiskFiles int `help:"Maximum number of reports on disk" default:"100000" env:"MAX_DISK_FILES"`
|
||||
MaxDiskSizeMB int64 `help:"Maximum disk space to use for reports" default:"1024" env:"MAX_DISK_SIZE_MB"`
|
||||
SentryQueue int `help:"Maximum number of reports to queue for sending to Sentry" default:"64" env:"SENTRY_QUEUE"`
|
||||
DiskQueue int `help:"Maximum number of reports to queue for writing to disk" default:"64" env:"DISK_QUEUE"`
|
||||
Dir string `help:"Parent directory to store crash and failure reports in" env:"REPORTS_DIR" default:"."`
|
||||
DSN string `help:"Sentry DSN" env:"SENTRY_DSN"`
|
||||
Listen string `help:"HTTP listen address" default:":8080" env:"LISTEN_ADDRESS"`
|
||||
MaxDiskFiles int `help:"Maximum number of reports on disk" default:"100000" env:"MAX_DISK_FILES"`
|
||||
MaxDiskSizeMB int64 `help:"Maximum disk space to use for reports" default:"1024" env:"MAX_DISK_SIZE_MB"`
|
||||
SentryQueue int `help:"Maximum number of reports to queue for sending to Sentry" default:"64" env:"SENTRY_QUEUE"`
|
||||
DiskQueue int `help:"Maximum number of reports to queue for writing to disk" default:"64" env:"DISK_QUEUE"`
|
||||
MetricsListen string `help:"HTTP listen address for metrics" default:":8081" env:"METRICS_LISTEN_ADDRESS"`
|
||||
IngorePatterns string `help:"File containing ignore patterns (regexp)" env:"IGNORE_PATTERNS" type:"existingfile"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -62,19 +67,38 @@ func main() {
|
||||
}
|
||||
go ss.Serve(context.Background())
|
||||
|
||||
var ip *ignorePatterns
|
||||
if params.IngorePatterns != "" {
|
||||
var err error
|
||||
ip, err = loadIgnorePatterns(params.IngorePatterns)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load ignore patterns: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
cr := &crashReceiver{
|
||||
store: ds,
|
||||
sentry: ss,
|
||||
ignore: ip,
|
||||
}
|
||||
|
||||
mux.Handle("/", cr)
|
||||
mux.HandleFunc("/ping", func(w http.ResponseWriter, req *http.Request) {
|
||||
w.Write([]byte("OK"))
|
||||
})
|
||||
mux.Handle("/metrics", promhttp.Handler())
|
||||
|
||||
if params.MetricsListen != "" {
|
||||
mmux := http.NewServeMux()
|
||||
mmux.Handle("/metrics", promhttp.Handler())
|
||||
go func() {
|
||||
if err := http.ListenAndServe(params.MetricsListen, mmux); err != nil {
|
||||
log.Fatalln("HTTP serve metrics:", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if params.DSN != "" {
|
||||
mux.HandleFunc("/newcrash/failure", handleFailureFn(params.DSN, filepath.Join(params.Dir, "failure_reports")))
|
||||
mux.HandleFunc("/newcrash/failure", handleFailureFn(params.DSN, filepath.Join(params.Dir, "failure_reports"), ip))
|
||||
}
|
||||
|
||||
log.SetOutput(os.Stdout)
|
||||
@@ -83,7 +107,7 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func handleFailureFn(dsn, failureDir string) func(w http.ResponseWriter, req *http.Request) {
|
||||
func handleFailureFn(dsn, failureDir string, ignore *ignorePatterns) func(w http.ResponseWriter, req *http.Request) {
|
||||
return func(w http.ResponseWriter, req *http.Request) {
|
||||
result := "failure"
|
||||
defer func() {
|
||||
@@ -98,6 +122,11 @@ func handleFailureFn(dsn, failureDir string) func(w http.ResponseWriter, req *ht
|
||||
return
|
||||
}
|
||||
|
||||
if ignore.match(bs) {
|
||||
result = "ignored"
|
||||
return
|
||||
}
|
||||
|
||||
var reports []ur.FailureReport
|
||||
err = json.Unmarshal(bs, &reports)
|
||||
if err != nil {
|
||||
@@ -110,7 +139,7 @@ func handleFailureFn(dsn, failureDir string) func(w http.ResponseWriter, req *ht
|
||||
return
|
||||
}
|
||||
|
||||
version, err := parseVersion(reports[0].Version)
|
||||
version, err := build.ParseVersion(reports[0].Version)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), 400)
|
||||
return
|
||||
@@ -158,3 +187,42 @@ func saveFailureWithGoroutines(data ur.FailureData, failureDir string) (string,
|
||||
}
|
||||
return reportServer + path, nil
|
||||
}
|
||||
|
||||
type ignorePatterns struct {
|
||||
patterns []*regexp.Regexp
|
||||
}
|
||||
|
||||
func loadIgnorePatterns(path string) (*ignorePatterns, error) {
|
||||
bs, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var patterns []*regexp.Regexp
|
||||
for _, line := range strings.Split(string(bs), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
re, err := regexp.Compile(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
patterns = append(patterns, re)
|
||||
}
|
||||
|
||||
log.Printf("Loaded %d ignore patterns", len(patterns))
|
||||
return &ignorePatterns{patterns: patterns}, nil
|
||||
}
|
||||
|
||||
func (i *ignorePatterns) match(report []byte) bool {
|
||||
if i == nil {
|
||||
return false
|
||||
}
|
||||
for _, re := range i.patterns {
|
||||
if re.Match(report) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
|
||||
raven "github.com/getsentry/raven-go"
|
||||
"github.com/maruel/panicparse/v2/stack"
|
||||
"github.com/syncthing/syncthing/lib/build"
|
||||
)
|
||||
|
||||
const reportServer = "https://crash.syncthing.net/report/"
|
||||
@@ -105,7 +106,7 @@ func parseCrashReport(path string, report []byte) (*raven.Packet, error) {
|
||||
return nil, errors.New("no first line")
|
||||
}
|
||||
|
||||
version, err := parseVersion(string(parts[0]))
|
||||
version, err := build.ParseVersion(string(parts[0]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -143,12 +144,12 @@ func parseCrashReport(path string, report []byte) (*raven.Packet, error) {
|
||||
}
|
||||
|
||||
// Lock the source code loader to the version we are processing here.
|
||||
if version.commit != "" {
|
||||
if version.Commit != "" {
|
||||
// We have a commit hash, so we know exactly which source to use
|
||||
loader.LockWithVersion(version.commit)
|
||||
} else if strings.HasPrefix(version.tag, "v") {
|
||||
loader.LockWithVersion(version.Commit)
|
||||
} else if strings.HasPrefix(version.Tag, "v") {
|
||||
// Lets hope the tag is close enough
|
||||
loader.LockWithVersion(version.tag)
|
||||
loader.LockWithVersion(version.Tag)
|
||||
} else {
|
||||
// Last resort
|
||||
loader.LockWithVersion("main")
|
||||
@@ -215,106 +216,26 @@ func crashReportFingerprint(message string) []string {
|
||||
return []string{"{{ default }}", message}
|
||||
}
|
||||
|
||||
// syncthing v1.1.4-rc.1+30-g6aaae618-dirty-crashrep "Erbium Earthworm" (go1.12.5 darwin-amd64) jb@kvin.kastelo.net 2019-05-23 16:08:14 UTC [foo, bar]
|
||||
// or, somewhere along the way the "+" in the version tag disappeared:
|
||||
// syncthing v1.23.7-dev.26.gdf7b56ae.dirty-stversionextra "Fermium Flea" (go1.20.5 darwin-arm64) jb@ok.kastelo.net 2023-07-12 06:55:26 UTC [Some Wrapper, purego, stnoupgrade]
|
||||
var (
|
||||
longVersionRE = regexp.MustCompile(`syncthing\s+(v[^\s]+)\s+"([^"]+)"\s\(([^\s]+)\s+([^-]+)-([^)]+)\)\s+([^\s]+)[^\[]*(?:\[(.+)\])?$`)
|
||||
gitExtraRE = regexp.MustCompile(`\.\d+\.g[0-9a-f]+`) // ".1.g6aaae618"
|
||||
gitExtraSepRE = regexp.MustCompile(`[.-]`) // dot or dash
|
||||
)
|
||||
|
||||
type version struct {
|
||||
version string // "v1.1.4-rc.1+30-g6aaae618-dirty-crashrep"
|
||||
tag string // "v1.1.4-rc.1"
|
||||
commit string // "6aaae618", blank when absent
|
||||
codename string // "Erbium Earthworm"
|
||||
runtime string // "go1.12.5"
|
||||
goos string // "darwin"
|
||||
goarch string // "amd64"
|
||||
builder string // "jb@kvin.kastelo.net"
|
||||
extra []string // "foo", "bar"
|
||||
}
|
||||
|
||||
func (v version) environment() string {
|
||||
if v.commit != "" {
|
||||
return "Development"
|
||||
}
|
||||
if strings.Contains(v.tag, "-rc.") {
|
||||
return "Candidate"
|
||||
}
|
||||
if strings.Contains(v.tag, "-") {
|
||||
return "Beta"
|
||||
}
|
||||
return "Stable"
|
||||
}
|
||||
|
||||
func parseVersion(line string) (version, error) {
|
||||
m := longVersionRE.FindStringSubmatch(line)
|
||||
if len(m) == 0 {
|
||||
return version{}, errors.New("unintelligeble version string")
|
||||
}
|
||||
|
||||
v := version{
|
||||
version: m[1],
|
||||
codename: m[2],
|
||||
runtime: m[3],
|
||||
goos: m[4],
|
||||
goarch: m[5],
|
||||
builder: m[6],
|
||||
}
|
||||
|
||||
// Split the version tag into tag and commit. This is old style
|
||||
// v1.2.3-something.4+11-g12345678 or newer with just dots
|
||||
// v1.2.3-something.4.11.g12345678 or v1.2.3-dev.11.g12345678.
|
||||
parts := []string{v.version}
|
||||
if strings.Contains(v.version, "+") {
|
||||
parts = strings.Split(v.version, "+")
|
||||
} else {
|
||||
idxs := gitExtraRE.FindStringIndex(v.version)
|
||||
if len(idxs) > 0 {
|
||||
parts = []string{v.version[:idxs[0]], v.version[idxs[0]+1:]}
|
||||
}
|
||||
}
|
||||
v.tag = parts[0]
|
||||
if len(parts) > 1 {
|
||||
fields := gitExtraSepRE.Split(parts[1], -1)
|
||||
if len(fields) >= 2 && strings.HasPrefix(fields[1], "g") {
|
||||
v.commit = fields[1][1:]
|
||||
}
|
||||
}
|
||||
|
||||
if len(m) >= 8 && m[7] != "" {
|
||||
tags := strings.Split(m[7], ",")
|
||||
for i := range tags {
|
||||
tags[i] = strings.TrimSpace(tags[i])
|
||||
}
|
||||
v.extra = tags
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func packet(version version, reportType string) *raven.Packet {
|
||||
func packet(version build.VersionParts, reportType string) *raven.Packet {
|
||||
pkt := &raven.Packet{
|
||||
Platform: "go",
|
||||
Release: version.tag,
|
||||
Environment: version.environment(),
|
||||
Release: version.Tag,
|
||||
Environment: version.Environment(),
|
||||
Tags: raven.Tags{
|
||||
raven.Tag{Key: "version", Value: version.version},
|
||||
raven.Tag{Key: "tag", Value: version.tag},
|
||||
raven.Tag{Key: "codename", Value: version.codename},
|
||||
raven.Tag{Key: "runtime", Value: version.runtime},
|
||||
raven.Tag{Key: "goos", Value: version.goos},
|
||||
raven.Tag{Key: "goarch", Value: version.goarch},
|
||||
raven.Tag{Key: "builder", Value: version.builder},
|
||||
raven.Tag{Key: "version", Value: version.Version},
|
||||
raven.Tag{Key: "tag", Value: version.Tag},
|
||||
raven.Tag{Key: "codename", Value: version.Codename},
|
||||
raven.Tag{Key: "runtime", Value: version.Runtime},
|
||||
raven.Tag{Key: "goos", Value: version.GOOS},
|
||||
raven.Tag{Key: "goarch", Value: version.GOARCH},
|
||||
raven.Tag{Key: "builder", Value: version.Builder},
|
||||
raven.Tag{Key: "report_type", Value: reportType},
|
||||
},
|
||||
}
|
||||
if version.commit != "" {
|
||||
pkt.Tags = append(pkt.Tags, raven.Tag{Key: "commit", Value: version.commit})
|
||||
if version.Commit != "" {
|
||||
pkt.Tags = append(pkt.Tags, raven.Tag{Key: "commit", Value: version.Commit})
|
||||
}
|
||||
for _, tag := range version.extra {
|
||||
for _, tag := range version.Extra {
|
||||
pkt.Tags = append(pkt.Tags, raven.Tag{Key: tag, Value: "1"})
|
||||
}
|
||||
return pkt
|
||||
|
||||
@@ -12,66 +12,6 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseVersion(t *testing.T) {
|
||||
cases := []struct {
|
||||
longVersion string
|
||||
parsed version
|
||||
}{
|
||||
{
|
||||
longVersion: `syncthing v1.1.4-rc.1+30-g6aaae618-dirty-crashrep "Erbium Earthworm" (go1.12.5 darwin-amd64) jb@kvin.kastelo.net 2019-05-23 16:08:14 UTC`,
|
||||
parsed: version{
|
||||
version: "v1.1.4-rc.1+30-g6aaae618-dirty-crashrep",
|
||||
tag: "v1.1.4-rc.1",
|
||||
commit: "6aaae618",
|
||||
codename: "Erbium Earthworm",
|
||||
runtime: "go1.12.5",
|
||||
goos: "darwin",
|
||||
goarch: "amd64",
|
||||
builder: "jb@kvin.kastelo.net",
|
||||
},
|
||||
},
|
||||
{
|
||||
longVersion: `syncthing v1.1.4-rc.1+30-g6aaae618-dirty-crashrep "Erbium Earthworm" (go1.12.5 darwin-amd64) jb@kvin.kastelo.net 2019-05-23 16:08:14 UTC [foo, bar]`,
|
||||
parsed: version{
|
||||
version: "v1.1.4-rc.1+30-g6aaae618-dirty-crashrep",
|
||||
tag: "v1.1.4-rc.1",
|
||||
commit: "6aaae618",
|
||||
codename: "Erbium Earthworm",
|
||||
runtime: "go1.12.5",
|
||||
goos: "darwin",
|
||||
goarch: "amd64",
|
||||
builder: "jb@kvin.kastelo.net",
|
||||
extra: []string{"foo", "bar"},
|
||||
},
|
||||
},
|
||||
{
|
||||
longVersion: `syncthing v1.23.7-dev.26.gdf7b56ae-stversionextra "Fermium Flea" (go1.20.5 darwin-arm64) jb@ok.kastelo.net 2023-07-12 06:55:26 UTC [Some Wrapper, purego, stnoupgrade]`,
|
||||
parsed: version{
|
||||
version: "v1.23.7-dev.26.gdf7b56ae-stversionextra",
|
||||
tag: "v1.23.7-dev",
|
||||
commit: "df7b56ae",
|
||||
codename: "Fermium Flea",
|
||||
runtime: "go1.20.5",
|
||||
goos: "darwin",
|
||||
goarch: "arm64",
|
||||
builder: "jb@ok.kastelo.net",
|
||||
extra: []string{"Some Wrapper", "purego", "stnoupgrade"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
v, err := parseVersion(tc.longVersion)
|
||||
if err != nil {
|
||||
t.Errorf("%s\nerror: %v\n", tc.longVersion, err)
|
||||
continue
|
||||
}
|
||||
if fmt.Sprint(v) != fmt.Sprint(tc.parsed) {
|
||||
t.Errorf("%s\nA: %v\nE: %v\n", tc.longVersion, v, tc.parsed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseReport(t *testing.T) {
|
||||
bs, err := os.ReadFile("_testdata/panic.log")
|
||||
if err != nil {
|
||||
|
||||
@@ -12,11 +12,16 @@ import (
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type crashReceiver struct {
|
||||
store *diskStore
|
||||
sentry *sentryService
|
||||
ignore *ignorePatterns
|
||||
|
||||
ignoredMut sync.RWMutex
|
||||
ignored map[string]struct{}
|
||||
}
|
||||
|
||||
func (r *crashReceiver) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
@@ -64,6 +69,12 @@ func (r *crashReceiver) serveGet(reportID string, w http.ResponseWriter, _ *http
|
||||
// serveHead responds to HEAD requests by checking if the named report
|
||||
// already exists in the system.
|
||||
func (r *crashReceiver) serveHead(reportID string, w http.ResponseWriter, _ *http.Request) {
|
||||
r.ignoredMut.RLock()
|
||||
_, ignored := r.ignored[reportID]
|
||||
r.ignoredMut.RUnlock()
|
||||
if ignored {
|
||||
return // found
|
||||
}
|
||||
if !r.store.Exists(reportID) {
|
||||
http.Error(w, "Not found", http.StatusNotFound)
|
||||
}
|
||||
@@ -76,6 +87,15 @@ func (r *crashReceiver) servePut(reportID string, w http.ResponseWriter, req *ht
|
||||
metricCrashReportsTotal.WithLabelValues(result).Inc()
|
||||
}()
|
||||
|
||||
r.ignoredMut.RLock()
|
||||
_, ignored := r.ignored[reportID]
|
||||
r.ignoredMut.RUnlock()
|
||||
if ignored {
|
||||
result = "ignored_cached"
|
||||
io.Copy(io.Discard, req.Body)
|
||||
return // found
|
||||
}
|
||||
|
||||
// Read at most maxRequestSize of report data.
|
||||
log.Println("Receiving report", reportID)
|
||||
lr := io.LimitReader(req.Body, maxRequestSize)
|
||||
@@ -86,6 +106,17 @@ func (r *crashReceiver) servePut(reportID string, w http.ResponseWriter, req *ht
|
||||
return
|
||||
}
|
||||
|
||||
if r.ignore.match(bs) {
|
||||
r.ignoredMut.Lock()
|
||||
if r.ignored == nil {
|
||||
r.ignored = make(map[string]struct{})
|
||||
}
|
||||
r.ignored[reportID] = struct{}{}
|
||||
r.ignoredMut.Unlock()
|
||||
result = "ignored"
|
||||
return
|
||||
}
|
||||
|
||||
result = "success"
|
||||
|
||||
// Store the report
|
||||
|
||||
246
cmd/stdiscosrv/amqp.go
Normal file
246
cmd/stdiscosrv/amqp.go
Normal file
@@ -0,0 +1,246 @@
|
||||
// Copyright (C) 2024 The Syncthing Authors.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
amqp "github.com/rabbitmq/amqp091-go"
|
||||
"github.com/thejerf/suture/v4"
|
||||
)
|
||||
|
||||
type amqpReplicator struct {
|
||||
suture.Service
|
||||
broker string
|
||||
sender *amqpSender
|
||||
receiver *amqpReceiver
|
||||
outbox chan ReplicationRecord
|
||||
}
|
||||
|
||||
func newAMQPReplicator(broker, clientID string, db database) *amqpReplicator {
|
||||
svc := suture.New("amqpReplicator", suture.Spec{PassThroughPanics: true})
|
||||
|
||||
sender := &amqpSender{
|
||||
broker: broker,
|
||||
clientID: clientID,
|
||||
outbox: make(chan ReplicationRecord, replicationOutboxSize),
|
||||
}
|
||||
svc.Add(sender)
|
||||
|
||||
receiver := &amqpReceiver{
|
||||
broker: broker,
|
||||
clientID: clientID,
|
||||
db: db,
|
||||
}
|
||||
svc.Add(receiver)
|
||||
|
||||
return &amqpReplicator{
|
||||
Service: svc,
|
||||
broker: broker,
|
||||
sender: sender,
|
||||
receiver: receiver,
|
||||
outbox: make(chan ReplicationRecord, replicationOutboxSize),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *amqpReplicator) send(key string, ps []DatabaseAddress, seen int64) {
|
||||
s.sender.send(key, ps, seen)
|
||||
}
|
||||
|
||||
type amqpSender struct {
|
||||
broker string
|
||||
clientID string
|
||||
outbox chan ReplicationRecord
|
||||
}
|
||||
|
||||
func (s *amqpSender) Serve(ctx context.Context) error {
|
||||
conn, ch, err := amqpChannel(s.broker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer ch.Close()
|
||||
defer conn.Close()
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
for {
|
||||
select {
|
||||
case rec := <-s.outbox:
|
||||
size := rec.Size()
|
||||
if len(buf) < size {
|
||||
buf = make([]byte, size)
|
||||
}
|
||||
|
||||
n, err := rec.MarshalTo(buf)
|
||||
if err != nil {
|
||||
replicationSendsTotal.WithLabelValues("error").Inc()
|
||||
return fmt.Errorf("replication marshal: %w", err)
|
||||
}
|
||||
|
||||
err = ch.PublishWithContext(ctx,
|
||||
"discovery", // exchange
|
||||
"", // routing key
|
||||
false, // mandatory
|
||||
false, // immediate
|
||||
amqp.Publishing{
|
||||
ContentType: "application/protobuf",
|
||||
Body: buf[:n],
|
||||
AppId: s.clientID,
|
||||
})
|
||||
if err != nil {
|
||||
replicationSendsTotal.WithLabelValues("error").Inc()
|
||||
return fmt.Errorf("replication publish: %w", err)
|
||||
}
|
||||
|
||||
replicationSendsTotal.WithLabelValues("success").Inc()
|
||||
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *amqpSender) String() string {
|
||||
return fmt.Sprintf("amqpSender(%q)", s.broker)
|
||||
}
|
||||
|
||||
func (s *amqpSender) send(key string, ps []DatabaseAddress, seen int64) {
|
||||
item := ReplicationRecord{
|
||||
Key: key,
|
||||
Addresses: ps,
|
||||
Seen: seen,
|
||||
}
|
||||
|
||||
// The send should never block. The inbox is suitably buffered for at
|
||||
// least a few seconds of stalls, which shouldn't happen in practice.
|
||||
select {
|
||||
case s.outbox <- item:
|
||||
default:
|
||||
replicationSendsTotal.WithLabelValues("drop").Inc()
|
||||
}
|
||||
}
|
||||
|
||||
type amqpReceiver struct {
|
||||
broker string
|
||||
clientID string
|
||||
db database
|
||||
}
|
||||
|
||||
func (s *amqpReceiver) Serve(ctx context.Context) error {
|
||||
conn, ch, err := amqpChannel(s.broker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer ch.Close()
|
||||
defer conn.Close()
|
||||
|
||||
msgs, err := amqpConsume(ch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case msg, ok := <-msgs:
|
||||
if !ok {
|
||||
return fmt.Errorf("subscription closed: %w", io.EOF)
|
||||
}
|
||||
|
||||
// ignore messages from ourself
|
||||
if msg.AppId == s.clientID {
|
||||
continue
|
||||
}
|
||||
|
||||
var rec ReplicationRecord
|
||||
if err := rec.Unmarshal(msg.Body); err != nil {
|
||||
replicationRecvsTotal.WithLabelValues("error").Inc()
|
||||
return fmt.Errorf("replication unmarshal: %w", err)
|
||||
}
|
||||
|
||||
if err := s.db.merge(rec.Key, rec.Addresses, rec.Seen); err != nil {
|
||||
return fmt.Errorf("replication database merge: %w", err)
|
||||
}
|
||||
|
||||
replicationRecvsTotal.WithLabelValues("success").Inc()
|
||||
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *amqpReceiver) String() string {
|
||||
return fmt.Sprintf("amqpReceiver(%q)", s.broker)
|
||||
}
|
||||
|
||||
func amqpChannel(dst string) (*amqp.Connection, *amqp.Channel, error) {
|
||||
conn, err := amqp.Dial(dst)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("AMQP dial: %w", err)
|
||||
}
|
||||
|
||||
ch, err := conn.Channel()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("AMQP channel: %w", err)
|
||||
}
|
||||
|
||||
err = ch.ExchangeDeclare(
|
||||
"discovery", // name
|
||||
"fanout", // type
|
||||
false, // durable
|
||||
false, // auto-deleted
|
||||
false, // internal
|
||||
false, // no-wait
|
||||
nil, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("AMQP declare exchange: %w", err)
|
||||
}
|
||||
|
||||
return conn, ch, nil
|
||||
}
|
||||
|
||||
func amqpConsume(ch *amqp.Channel) (<-chan amqp.Delivery, error) {
|
||||
q, err := ch.QueueDeclare(
|
||||
"", // name
|
||||
false, // durable
|
||||
false, // delete when unused
|
||||
true, // exclusive
|
||||
false, // no-wait
|
||||
nil, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AMQP declare queue: %w", err)
|
||||
}
|
||||
|
||||
err = ch.QueueBind(
|
||||
q.Name, // queue name
|
||||
"", // routing key
|
||||
"discovery", // exchange
|
||||
false,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AMQP bind queue: %w", err)
|
||||
}
|
||||
|
||||
msgs, err := ch.Consume(
|
||||
q.Name, // queue
|
||||
"", // consumer
|
||||
true, // auto-ack
|
||||
false, // exclusive
|
||||
false, // no-local
|
||||
false, // no-wait
|
||||
nil, // args
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AMQP consume: %w", err)
|
||||
}
|
||||
|
||||
return msgs, nil
|
||||
}
|
||||
@@ -39,12 +39,13 @@ type announcement struct {
|
||||
}
|
||||
|
||||
type apiSrv struct {
|
||||
addr string
|
||||
cert tls.Certificate
|
||||
db database
|
||||
listener net.Listener
|
||||
repl replicator // optional
|
||||
useHTTP bool
|
||||
addr string
|
||||
cert tls.Certificate
|
||||
db database
|
||||
listener net.Listener
|
||||
repl replicator // optional
|
||||
useHTTP bool
|
||||
missesIncrease int
|
||||
|
||||
mapsMut sync.Mutex
|
||||
misses map[string]int32
|
||||
@@ -60,14 +61,15 @@ type contextKey int
|
||||
|
||||
const idKey contextKey = iota
|
||||
|
||||
func newAPISrv(addr string, cert tls.Certificate, db database, repl replicator, useHTTP bool) *apiSrv {
|
||||
func newAPISrv(addr string, cert tls.Certificate, db database, repl replicator, useHTTP bool, missesIncrease int) *apiSrv {
|
||||
return &apiSrv{
|
||||
addr: addr,
|
||||
cert: cert,
|
||||
db: db,
|
||||
repl: repl,
|
||||
useHTTP: useHTTP,
|
||||
misses: make(map[string]int32),
|
||||
addr: addr,
|
||||
cert: cert,
|
||||
db: db,
|
||||
repl: repl,
|
||||
useHTTP: useHTTP,
|
||||
misses: make(map[string]int32),
|
||||
missesIncrease: missesIncrease,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,14 +199,13 @@ func (s *apiSrv) handleGET(w http.ResponseWriter, req *http.Request) {
|
||||
s.mapsMut.Lock()
|
||||
misses := s.misses[key]
|
||||
if misses < rec.Misses {
|
||||
misses = rec.Misses + 1
|
||||
} else {
|
||||
misses++
|
||||
misses = rec.Misses
|
||||
}
|
||||
misses += int32(s.missesIncrease)
|
||||
s.misses[key] = misses
|
||||
s.mapsMut.Unlock()
|
||||
|
||||
if misses%notFoundMissesWriteInterval == 0 {
|
||||
if misses >= notFoundMissesWriteInterval {
|
||||
rec.Misses = misses
|
||||
rec.Missed = time.Now().UnixNano()
|
||||
rec.Addresses = nil
|
||||
@@ -444,7 +445,6 @@ func fixupAddresses(remote *net.TCPAddr, addresses []string) []string {
|
||||
// remote is nil, unable to determine host IP
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If zero port was specified, use remote port.
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
_ "github.com/syncthing/syncthing/lib/automaxprocs"
|
||||
"github.com/syncthing/syncthing/lib/build"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
"github.com/syncthing/syncthing/lib/rand"
|
||||
"github.com/syncthing/syncthing/lib/tlsutil"
|
||||
"github.com/syndtr/goleveldb/leveldb/opt"
|
||||
"github.com/thejerf/suture/v4"
|
||||
@@ -80,6 +81,8 @@ func main() {
|
||||
var replKeyFile string
|
||||
var useHTTP bool
|
||||
var largeDB bool
|
||||
var amqpAddress string
|
||||
missesIncrease := 1
|
||||
|
||||
log.SetOutput(os.Stdout)
|
||||
log.SetFlags(0)
|
||||
@@ -96,6 +99,8 @@ func main() {
|
||||
flag.StringVar(&replCertFile, "replication-cert", "", "Certificate file for replication")
|
||||
flag.StringVar(&replKeyFile, "replication-key", "", "Key file for replication")
|
||||
flag.BoolVar(&largeDB, "large-db", false, "Use larger database settings")
|
||||
flag.StringVar(&amqpAddress, "amqp-address", "", "Address to AMQP broker")
|
||||
flag.IntVar(&missesIncrease, "misses-increase", 1, "How many times to increase the misses counter on each miss")
|
||||
showVersion := flag.Bool("version", false, "Show version")
|
||||
flag.Parse()
|
||||
|
||||
@@ -203,8 +208,24 @@ func main() {
|
||||
main.Add(rl)
|
||||
}
|
||||
|
||||
// If we have an AMQP broker, start that
|
||||
if amqpAddress != "" {
|
||||
clientID := rand.String(10)
|
||||
kr := newAMQPReplicator(amqpAddress, clientID, db)
|
||||
repl = append(repl, kr)
|
||||
main.Add(kr)
|
||||
}
|
||||
|
||||
go func() {
|
||||
for range time.NewTicker(time.Second).C {
|
||||
for _, r := range repl {
|
||||
r.send("<heartbeat>", nil, time.Now().UnixNano())
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Start the main API server.
|
||||
qs := newAPISrv(listen, cert, db, repl, useHTTP)
|
||||
qs := newAPISrv(listen, cert, db, repl, useHTTP, missesIncrease)
|
||||
main.Add(qs)
|
||||
|
||||
// If we have a metrics port configured, start a metrics handler.
|
||||
|
||||
@@ -144,10 +144,11 @@ func (s *replicationSender) String() string {
|
||||
return fmt.Sprintf("replicationSender(%q)", s.dst)
|
||||
}
|
||||
|
||||
func (s *replicationSender) send(key string, ps []DatabaseAddress, _ int64) {
|
||||
func (s *replicationSender) send(key string, ps []DatabaseAddress, seen int64) {
|
||||
item := ReplicationRecord{
|
||||
Key: key,
|
||||
Addresses: ps,
|
||||
Seen: seen,
|
||||
}
|
||||
|
||||
// The send should never block. The inbox is suitably buffered for at
|
||||
|
||||
@@ -7,10 +7,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -127,15 +124,4 @@ func init() {
|
||||
databaseKeys, databaseStatisticsSeconds,
|
||||
databaseOperations, databaseOperationSeconds,
|
||||
retryAfterHistogram)
|
||||
|
||||
processCollectorOpts := collectors.ProcessCollectorOpts{
|
||||
Namespace: "syncthing_discovery",
|
||||
PidFn: func() (int, error) {
|
||||
return os.Getpid(), nil
|
||||
},
|
||||
}
|
||||
|
||||
prometheus.MustRegister(
|
||||
collectors.NewProcessCollector(processCollectorOpts),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
return a.value > b.value ? 1 : -1;
|
||||
}
|
||||
|
||||
$http.get("/endpoint").then(function(response) {
|
||||
$http.get("/endpoint/full").then(function(response) {
|
||||
$scope.relays = response.data.relays;
|
||||
|
||||
angular.forEach($scope.relays, function(relay) {
|
||||
@@ -338,7 +338,7 @@
|
||||
relay.showMarker = function() {
|
||||
relay.marker.openPopup();
|
||||
}
|
||||
|
||||
|
||||
relay.hideMarker = function() {
|
||||
relay.marker.closePopup();
|
||||
}
|
||||
@@ -347,7 +347,7 @@
|
||||
|
||||
function addCircleToMap(relay) {
|
||||
console.log(relay.location.latitude)
|
||||
L.circle([relay.location.latitude, relay.location.longitude],
|
||||
L.circle([relay.location.latitude, relay.location.longitude],
|
||||
{
|
||||
radius: ((relay.stats.bytesProxied * 100) / $scope.totals.bytesProxied) * 10000,
|
||||
color: "FF0000",
|
||||
|
||||
@@ -21,15 +21,13 @@ import (
|
||||
"time"
|
||||
|
||||
lru "github.com/hashicorp/golang-lru/v2"
|
||||
"github.com/oschwald/geoip2-golang"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/syncthing/syncthing/cmd/strelaypoolsrv/auto"
|
||||
"github.com/syncthing/syncthing/lib/assets"
|
||||
_ "github.com/syncthing/syncthing/lib/automaxprocs"
|
||||
"github.com/syncthing/syncthing/lib/httpcache"
|
||||
"github.com/syncthing/syncthing/lib/geoip"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
"github.com/syncthing/syncthing/lib/rand"
|
||||
"github.com/syncthing/syncthing/lib/relay/client"
|
||||
"github.com/syncthing/syncthing/lib/sync"
|
||||
"github.com/syncthing/syncthing/lib/tlsutil"
|
||||
@@ -51,6 +49,10 @@ type relay struct {
|
||||
StatsRetrieved time.Time `json:"statsRetrieved"`
|
||||
}
|
||||
|
||||
type relayShort struct {
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
type stats struct {
|
||||
StartTime time.Time `json:"startTime"`
|
||||
UptimeSeconds int `json:"uptimeSeconds"`
|
||||
@@ -95,16 +97,18 @@ var (
|
||||
testCert tls.Certificate
|
||||
knownRelaysFile = filepath.Join(os.TempDir(), "strelaypoolsrv_known_relays")
|
||||
listen = ":80"
|
||||
metricsListen = ":8081"
|
||||
dir string
|
||||
evictionTime = time.Hour
|
||||
debug bool
|
||||
permRelaysFile string
|
||||
ipHeader string
|
||||
geoipPath string
|
||||
proto string
|
||||
statsRefresh = time.Minute
|
||||
requestQueueLen = 64
|
||||
requestProcessors = 8
|
||||
geoipLicenseKey = os.Getenv("GEOIP_LICENSE_KEY")
|
||||
geoipAccountID, _ = strconv.Atoi(os.Getenv("GEOIP_ACCOUNT_ID"))
|
||||
|
||||
requests chan request
|
||||
|
||||
@@ -124,40 +128,45 @@ func main() {
|
||||
log.SetFlags(log.Lshortfile)
|
||||
|
||||
flag.StringVar(&listen, "listen", listen, "Listen address")
|
||||
flag.StringVar(&metricsListen, "metrics-listen", metricsListen, "Metrics listen address")
|
||||
flag.StringVar(&dir, "keys", dir, "Directory where http-cert.pem and http-key.pem is stored for TLS listening")
|
||||
flag.BoolVar(&debug, "debug", debug, "Enable debug output")
|
||||
flag.DurationVar(&evictionTime, "eviction", evictionTime, "After how long the relay is evicted")
|
||||
flag.StringVar(&permRelaysFile, "perm-relays", "", "Path to list of permanent relays")
|
||||
flag.StringVar(&knownRelaysFile, "known-relays", knownRelaysFile, "Path to list of current relays")
|
||||
flag.StringVar(&ipHeader, "ip-header", "", "Name of header which holds clients ip:port. Only meaningful when running behind a reverse proxy.")
|
||||
flag.StringVar(&geoipPath, "geoip", "GeoLite2-City.mmdb", "Path to GeoLite2-City database")
|
||||
flag.StringVar(&proto, "protocol", "tcp", "Protocol used for listening. 'tcp' for IPv4 and IPv6, 'tcp4' for IPv4, 'tcp6' for IPv6")
|
||||
flag.DurationVar(&statsRefresh, "stats-refresh", statsRefresh, "Interval at which to refresh relay stats")
|
||||
flag.IntVar(&requestQueueLen, "request-queue", requestQueueLen, "Queue length for incoming test requests")
|
||||
flag.IntVar(&requestProcessors, "request-processors", requestProcessors, "Number of request processor routines")
|
||||
flag.StringVar(&geoipLicenseKey, "geoip-license-key", geoipLicenseKey, "License key for GeoIP database")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
requests = make(chan request, requestQueueLen)
|
||||
geoip, err := geoip.NewGeoLite2CityProvider(context.Background(), geoipAccountID, geoipLicenseKey, os.TempDir())
|
||||
if err != nil {
|
||||
log.Fatalln("Failed to create GeoIP provider:", err)
|
||||
}
|
||||
go geoip.Serve(context.TODO())
|
||||
|
||||
var listener net.Listener
|
||||
var err error
|
||||
|
||||
if permRelaysFile != "" {
|
||||
permanentRelays = loadRelays(permRelaysFile)
|
||||
permanentRelays = loadRelays(permRelaysFile, geoip)
|
||||
}
|
||||
|
||||
testCert = createTestCertificate()
|
||||
|
||||
for i := 0; i < requestProcessors; i++ {
|
||||
go requestProcessor()
|
||||
go requestProcessor(geoip)
|
||||
}
|
||||
|
||||
// Load relays from cache in the background.
|
||||
// Load them in a serial fashion to make sure any genuine requests
|
||||
// are not dropped.
|
||||
go func() {
|
||||
for _, relay := range loadRelays(knownRelaysFile) {
|
||||
for _, relay := range loadRelays(knownRelaysFile, geoip) {
|
||||
resultChan := make(chan result)
|
||||
requests <- request{relay, resultChan, nil}
|
||||
result := <-resultChan
|
||||
@@ -213,15 +222,40 @@ func main() {
|
||||
log.Fatalln("listen:", err)
|
||||
}
|
||||
|
||||
handler := http.NewServeMux()
|
||||
handler.HandleFunc("/", handleAssets)
|
||||
handler.Handle("/endpoint", httpcache.SinglePath(http.HandlerFunc(handleRequest), 15*time.Second))
|
||||
handler.HandleFunc("/metrics", handleMetrics)
|
||||
if metricsListen != "" {
|
||||
mmux := http.NewServeMux()
|
||||
mmux.HandleFunc("/metrics", handleMetrics)
|
||||
go func() {
|
||||
if err := http.ListenAndServe(metricsListen, mmux); err != nil {
|
||||
log.Fatalln("HTTP serve metrics:", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
getMux := http.NewServeMux()
|
||||
getMux.HandleFunc("/", handleAssets)
|
||||
getMux.HandleFunc("/endpoint", withAPIMetrics(handleEndpointShort))
|
||||
getMux.HandleFunc("/endpoint/full", withAPIMetrics(handleEndpointFull))
|
||||
|
||||
postMux := http.NewServeMux()
|
||||
postMux.HandleFunc("/endpoint", withAPIMetrics(handleRegister))
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet, http.MethodHead, http.MethodOptions:
|
||||
getMux.ServeHTTP(w, r)
|
||||
case http.MethodPost:
|
||||
postMux.ServeHTTP(w, r)
|
||||
default:
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
})
|
||||
|
||||
srv := http.Server{
|
||||
Handler: handler,
|
||||
ReadTimeout: 10 * time.Second,
|
||||
}
|
||||
srv.SetKeepAlivesEnabled(false)
|
||||
|
||||
err = srv.Serve(listener)
|
||||
if err != nil {
|
||||
@@ -255,39 +289,24 @@ func handleAssets(w http.ResponseWriter, r *http.Request) {
|
||||
assets.Serve(w, r, as)
|
||||
}
|
||||
|
||||
func handleRequest(w http.ResponseWriter, r *http.Request) {
|
||||
timer := prometheus.NewTimer(apiRequestsSeconds.WithLabelValues(r.Method))
|
||||
|
||||
w = NewLoggingResponseWriter(w)
|
||||
defer func() {
|
||||
timer.ObserveDuration()
|
||||
lw := w.(*loggingResponseWriter)
|
||||
apiRequestsTotal.WithLabelValues(r.Method, strconv.Itoa(lw.statusCode)).Inc()
|
||||
}()
|
||||
|
||||
if ipHeader != "" {
|
||||
hdr := r.Header.Get(ipHeader)
|
||||
fields := strings.Split(hdr, ",")
|
||||
if len(fields) > 0 {
|
||||
r.RemoteAddr = strings.TrimSpace(fields[len(fields)-1])
|
||||
}
|
||||
}
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
handleGetRequest(w, r)
|
||||
case "POST":
|
||||
handlePostRequest(w, r)
|
||||
default:
|
||||
if debug {
|
||||
log.Println("Unhandled HTTP method", r.Method)
|
||||
}
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
func withAPIMetrics(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
timer := prometheus.NewTimer(apiRequestsSeconds.WithLabelValues(r.Method))
|
||||
w = NewLoggingResponseWriter(w)
|
||||
defer func() {
|
||||
timer.ObserveDuration()
|
||||
lw := w.(*loggingResponseWriter)
|
||||
apiRequestsTotal.WithLabelValues(r.Method, strconv.Itoa(lw.statusCode)).Inc()
|
||||
}()
|
||||
next(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func handleGetRequest(rw http.ResponseWriter, r *http.Request) {
|
||||
// handleEndpointFull returns the relay list with full metadata and
|
||||
// statistics. Large, and expensive.
|
||||
func handleEndpointFull(rw http.ResponseWriter, r *http.Request) {
|
||||
rw.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
rw.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
|
||||
mut.RLock()
|
||||
relays := make([]*relay, len(permanentRelays)+len(knownRelays))
|
||||
@@ -295,17 +314,38 @@ func handleGetRequest(rw http.ResponseWriter, r *http.Request) {
|
||||
copy(relays[n:], knownRelays)
|
||||
mut.RUnlock()
|
||||
|
||||
// Shuffle
|
||||
rand.Shuffle(relays)
|
||||
|
||||
_ = json.NewEncoder(rw).Encode(map[string][]*relay{
|
||||
"relays": relays,
|
||||
})
|
||||
}
|
||||
|
||||
func handlePostRequest(w http.ResponseWriter, r *http.Request) {
|
||||
// handleEndpointShort returns the relay list with only the URL.
|
||||
func handleEndpointShort(rw http.ResponseWriter, r *http.Request) {
|
||||
rw.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
rw.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
|
||||
mut.RLock()
|
||||
relays := make([]relayShort, 0, len(permanentRelays)+len(knownRelays))
|
||||
for _, r := range append(permanentRelays, knownRelays...) {
|
||||
relays = append(relays, relayShort{URL: slimURL(r.URL)})
|
||||
}
|
||||
mut.RUnlock()
|
||||
|
||||
_ = json.NewEncoder(rw).Encode(map[string][]relayShort{
|
||||
"relays": relays,
|
||||
})
|
||||
}
|
||||
|
||||
func handleRegister(w http.ResponseWriter, r *http.Request) {
|
||||
// Get the IP address of the client
|
||||
rhost := r.RemoteAddr
|
||||
if ipHeader != "" {
|
||||
hdr := r.Header.Get(ipHeader)
|
||||
fields := strings.Split(hdr, ",")
|
||||
if len(fields) > 0 {
|
||||
rhost = strings.TrimSpace(fields[len(fields)-1])
|
||||
}
|
||||
}
|
||||
if host, _, err := net.SplitHostPort(rhost); err == nil {
|
||||
rhost = host
|
||||
}
|
||||
@@ -425,19 +465,19 @@ func handlePostRequest(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func requestProcessor() {
|
||||
func requestProcessor(geoip *geoip.Provider) {
|
||||
for request := range requests {
|
||||
if request.queueTimer != nil {
|
||||
request.queueTimer.ObserveDuration()
|
||||
}
|
||||
|
||||
timer := prometheus.NewTimer(relayTestActionsSeconds.WithLabelValues("test"))
|
||||
handleRelayTest(request)
|
||||
handleRelayTest(request, geoip)
|
||||
timer.ObserveDuration()
|
||||
}
|
||||
}
|
||||
|
||||
func handleRelayTest(request request) {
|
||||
func handleRelayTest(request request, geoip *geoip.Provider) {
|
||||
if debug {
|
||||
log.Println("Request for", request.relay)
|
||||
}
|
||||
@@ -450,7 +490,7 @@ func handleRelayTest(request request) {
|
||||
}
|
||||
|
||||
stats := fetchStats(request.relay)
|
||||
location := getLocation(request.relay.uri.Host)
|
||||
location := getLocation(request.relay.uri.Host, geoip)
|
||||
|
||||
mut.Lock()
|
||||
if stats != nil {
|
||||
@@ -523,7 +563,7 @@ func evict(relay *relay) func() {
|
||||
}
|
||||
}
|
||||
|
||||
func loadRelays(file string) []*relay {
|
||||
func loadRelays(file string, geoip *geoip.Provider) []*relay {
|
||||
content, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
log.Println("Failed to load relays: " + err.Error())
|
||||
@@ -547,7 +587,7 @@ func loadRelays(file string) []*relay {
|
||||
|
||||
relays = append(relays, &relay{
|
||||
URL: line,
|
||||
Location: getLocation(uri.Host),
|
||||
Location: getLocation(uri.Host, geoip),
|
||||
uri: uri,
|
||||
})
|
||||
if debug {
|
||||
@@ -580,21 +620,16 @@ func createTestCertificate() tls.Certificate {
|
||||
return cert
|
||||
}
|
||||
|
||||
func getLocation(host string) location {
|
||||
func getLocation(host string, geoip *geoip.Provider) location {
|
||||
timer := prometheus.NewTimer(locationLookupSeconds)
|
||||
defer timer.ObserveDuration()
|
||||
db, err := geoip2.Open(geoipPath)
|
||||
if err != nil {
|
||||
return location{}
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
addr, err := net.ResolveTCPAddr("tcp", host)
|
||||
if err != nil {
|
||||
return location{}
|
||||
}
|
||||
|
||||
city, err := db.City(addr.IP)
|
||||
city, err := geoip.City(addr.IP)
|
||||
if err != nil {
|
||||
return location{}
|
||||
}
|
||||
@@ -660,3 +695,16 @@ func (b *errorTracker) IsBlocked(host string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func slimURL(u string) string {
|
||||
p, err := url.Parse(u)
|
||||
if err != nil {
|
||||
return u
|
||||
}
|
||||
newQuery := url.Values{}
|
||||
if id := p.Query().Get("id"); id != "" {
|
||||
newQuery.Set("id", id)
|
||||
}
|
||||
p.RawQuery = newQuery.Encode()
|
||||
return p.String()
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ func TestHandleGetRequest(t *testing.T) {
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
w.Body = new(bytes.Buffer)
|
||||
handleGetRequest(w, httptest.NewRequest("GET", "/", nil))
|
||||
handleEndpointFull(w, httptest.NewRequest("GET", "/", nil))
|
||||
|
||||
result := make(map[string][]*relay)
|
||||
err := json.NewDecoder(w.Body).Decode(&result)
|
||||
@@ -92,3 +92,18 @@ func TestCanonicalizeQueryValues(t *testing.T) {
|
||||
t.Errorf("expected %q, got %q", exp, str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSlimURL(t *testing.T) {
|
||||
cases := []struct {
|
||||
in, out string
|
||||
}{
|
||||
{"http://example.com/", "http://example.com/"},
|
||||
{"relay://192.0.2.42:22067/?globalLimitBps=0&id=EIC6B3M-EIC6B3M-EIC6B3M-EIC6B3M-EIC6B3M-EIC6B3M-EIC6B3M-EIC6B3M&networkTimeout=2m0s&pingInterval=1m0s&providedBy=Test&sessionLimitBps=0&statusAddr=%3A22070", "relay://192.0.2.42:22067/?id=EIC6B3M-EIC6B3M-EIC6B3M-EIC6B3M-EIC6B3M-EIC6B3M-EIC6B3M-EIC6B3M"},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
if got := slimURL(c.in); got != c.out {
|
||||
t.Errorf("expected %q, got %q", c.out, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,27 +6,12 @@ import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||
"github.com/syncthing/syncthing/lib/sync"
|
||||
)
|
||||
|
||||
func init() {
|
||||
processCollectorOpts := collectors.ProcessCollectorOpts{
|
||||
Namespace: "syncthing_relaypoolsrv",
|
||||
PidFn: func() (int, error) {
|
||||
return os.Getpid(), nil
|
||||
},
|
||||
}
|
||||
|
||||
prometheus.MustRegister(
|
||||
collectors.NewProcessCollector(processCollectorOpts),
|
||||
)
|
||||
}
|
||||
|
||||
var (
|
||||
statusClient = http.Client{
|
||||
Timeout: 5 * time.Second,
|
||||
|
||||
@@ -19,16 +19,18 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/alecthomas/kong"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
_ "github.com/syncthing/syncthing/lib/automaxprocs"
|
||||
"github.com/syncthing/syncthing/lib/httpcache"
|
||||
"github.com/syncthing/syncthing/lib/upgrade"
|
||||
)
|
||||
|
||||
type cli struct {
|
||||
Listen string `default:":8080" help:"Listen address"`
|
||||
URL string `short:"u" default:"https://api.github.com/repos/syncthing/syncthing/releases?per_page=25" help:"GitHub releases url"`
|
||||
Forward []string `short:"f" help:"Forwarded pages, format: /path->https://example/com/url"`
|
||||
CacheTime time.Duration `default:"15m" help:"Cache time"`
|
||||
Listen string `default:":8080" help:"Listen address"`
|
||||
MetricsListen string `default:":8081" help:"Listen address for metrics"`
|
||||
URL string `short:"u" default:"https://api.github.com/repos/syncthing/syncthing/releases?per_page=25" help:"GitHub releases url"`
|
||||
Forward []string `short:"f" help:"Forwarded pages, format: /path->https://example/com/url"`
|
||||
CacheTime time.Duration `default:"15m" help:"Cache time"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -41,17 +43,37 @@ func main() {
|
||||
}
|
||||
|
||||
func server(params *cli) error {
|
||||
http.Handle("/meta.json", httpcache.SinglePath(&githubReleases{url: params.URL}, params.CacheTime))
|
||||
if params.MetricsListen != "" {
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/metrics", promhttp.Handler())
|
||||
go func() {
|
||||
log.Println("Listening for metrics on", params.MetricsListen)
|
||||
if err := http.ListenAndServe(params.MetricsListen, mux); err != nil {
|
||||
log.Fatalf("Failed to start metrics server: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/meta.json", httpcache.SinglePath(&githubReleases{url: params.URL}, params.CacheTime))
|
||||
|
||||
for _, fwd := range params.Forward {
|
||||
path, url, ok := strings.Cut(fwd, "->")
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid forward: %q", fwd)
|
||||
}
|
||||
http.Handle(path, httpcache.SinglePath(&proxy{url: url}, params.CacheTime))
|
||||
log.Println("Forwarding", path, "to", url)
|
||||
mux.Handle(path, httpcache.SinglePath(&proxy{url: url}, params.CacheTime))
|
||||
}
|
||||
|
||||
return http.ListenAndServe(params.Listen, nil)
|
||||
srv := &http.Server{
|
||||
Addr: params.Listen,
|
||||
Handler: mux,
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
}
|
||||
srv.SetKeepAlivesEnabled(false)
|
||||
return srv.ListenAndServe()
|
||||
}
|
||||
|
||||
type githubReleases struct {
|
||||
|
||||
@@ -8,6 +8,7 @@ package serve
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"database/sql"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
@@ -26,20 +28,21 @@ import (
|
||||
"unicode"
|
||||
|
||||
_ "github.com/lib/pq" // PostgreSQL driver
|
||||
"github.com/oschwald/geoip2-golang"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/geoip"
|
||||
"github.com/syncthing/syncthing/lib/upgrade"
|
||||
"github.com/syncthing/syncthing/lib/ur/contract"
|
||||
)
|
||||
|
||||
type CLI struct {
|
||||
Debug bool `env:"UR_DEBUG"`
|
||||
DBConn string `env:"UR_DB_URL" default:"postgres://user:password@localhost/ur?sslmode=disable"`
|
||||
Listen string `env:"UR_LISTEN" default:"0.0.0.0:8080"`
|
||||
GeoIPPath string `env:"UR_GEOIP" default:"GeoLite2-City.mmdb"`
|
||||
Debug bool `env:"UR_DEBUG"`
|
||||
DBConn string `env:"UR_DB_URL" default:"postgres://user:password@localhost/ur?sslmode=disable"`
|
||||
Listen string `env:"UR_LISTEN" default:"0.0.0.0:8080"`
|
||||
GeoIPLicenseKey string `env:"UR_GEOIP_LICENSE_KEY"`
|
||||
GeoIPAccountID int `env:"UR_GEOIP_ACCOUNT_ID"`
|
||||
}
|
||||
|
||||
//go:embed static
|
||||
@@ -189,10 +192,16 @@ func (cli *CLI) Run() error {
|
||||
log.Fatalln("listen:", err)
|
||||
}
|
||||
|
||||
geoip, err := geoip.NewGeoLite2CityProvider(context.Background(), cli.GeoIPAccountID, cli.GeoIPLicenseKey, os.TempDir())
|
||||
if err != nil {
|
||||
log.Fatalln("geoip:", err)
|
||||
}
|
||||
go geoip.Serve(context.TODO())
|
||||
|
||||
srv := &server{
|
||||
db: db,
|
||||
debug: cli.Debug,
|
||||
geoIPPath: cli.GeoIPPath,
|
||||
db: db,
|
||||
debug: cli.Debug,
|
||||
geoip: geoip,
|
||||
}
|
||||
http.HandleFunc("/", srv.rootHandler)
|
||||
http.HandleFunc("/newdata", srv.newDataHandler)
|
||||
@@ -213,9 +222,9 @@ func (cli *CLI) Run() error {
|
||||
}
|
||||
|
||||
type server struct {
|
||||
debug bool
|
||||
db *sql.DB
|
||||
geoIPPath string
|
||||
debug bool
|
||||
db *sql.DB
|
||||
geoip *geoip.Provider
|
||||
|
||||
cacheMut sync.Mutex
|
||||
cachedIndex []byte
|
||||
@@ -238,7 +247,7 @@ func (s *server) cacheRefresher() {
|
||||
}
|
||||
|
||||
func (s *server) refreshCacheLocked() error {
|
||||
rep := getReport(s.db, s.geoIPPath)
|
||||
rep := getReport(s.db, s.geoip)
|
||||
buf := new(bytes.Buffer)
|
||||
err := tpl.Execute(buf, rep)
|
||||
if err != nil {
|
||||
@@ -492,15 +501,7 @@ type weightedLocation struct {
|
||||
Weight int `json:"weight"`
|
||||
}
|
||||
|
||||
func getReport(db *sql.DB, geoIPPath string) map[string]interface{} {
|
||||
geoip, err := geoip2.Open(geoIPPath)
|
||||
if err != nil {
|
||||
log.Println("opening geoip db", err)
|
||||
geoip = nil
|
||||
} else {
|
||||
defer geoip.Close()
|
||||
}
|
||||
|
||||
func getReport(db *sql.DB, geoip *geoip.Provider) map[string]interface{} {
|
||||
nodes := 0
|
||||
countriesTotal := 0
|
||||
var versions []string
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Increase maximum socket buffer sizes to 2.5MiB for QUIC connections
|
||||
# Increase maximum socket buffer sizes to 7MiB for QUIC connections
|
||||
# see https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes
|
||||
net.core.rmem_max = 2621440
|
||||
net.core.wmem_max = 2621440
|
||||
net.core.rmem_max = 7340032
|
||||
net.core.wmem_max = 7340032
|
||||
|
||||
75
go.mod
75
go.mod
@@ -4,7 +4,7 @@ go 1.21.0
|
||||
|
||||
require (
|
||||
github.com/AudriusButkevicius/recli v0.0.7-0.20220911121932-d000ce8fbf0f
|
||||
github.com/alecthomas/kong v0.8.1
|
||||
github.com/alecthomas/kong v0.9.0
|
||||
github.com/calmh/incontainer v1.0.0
|
||||
github.com/calmh/xdr v1.1.0
|
||||
github.com/ccding/go-stun v0.1.4
|
||||
@@ -12,83 +12,82 @@ require (
|
||||
github.com/d4l3k/messagediff v1.2.1
|
||||
github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568
|
||||
github.com/getsentry/raven-go v0.2.0
|
||||
github.com/go-ldap/ldap/v3 v3.4.6
|
||||
github.com/go-ldap/ldap/v3 v3.4.8
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/greatroar/blobloom v0.7.2
|
||||
github.com/greatroar/blobloom v0.8.0
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||
github.com/jackpal/gateway v1.0.13
|
||||
github.com/jackpal/gateway v1.0.15
|
||||
github.com/jackpal/go-nat-pmp v1.0.2
|
||||
github.com/julienschmidt/httprouter v1.3.0
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/maruel/panicparse/v2 v2.3.1
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.8.1
|
||||
github.com/maxmind/geoipupdate/v6 v6.1.0
|
||||
github.com/minio/sha256-simd v1.0.1
|
||||
github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75
|
||||
github.com/oschwald/geoip2-golang v1.9.0
|
||||
github.com/oschwald/geoip2-golang v1.11.0
|
||||
github.com/pierrec/lz4/v4 v4.1.21
|
||||
github.com/prometheus/client_golang v1.18.0
|
||||
github.com/quic-go/quic-go v0.41.0
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/quic-go/quic-go v0.44.0
|
||||
github.com/rabbitmq/amqp091-go v1.10.0
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475
|
||||
github.com/shirou/gopsutil/v3 v3.24.1
|
||||
github.com/shirou/gopsutil/v3 v3.24.5
|
||||
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d
|
||||
github.com/thejerf/suture/v4 v4.0.2
|
||||
github.com/urfave/cli v1.22.14
|
||||
github.com/thejerf/suture/v4 v4.0.5
|
||||
github.com/urfave/cli v1.22.15
|
||||
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0
|
||||
github.com/willabides/kongplete v0.4.0
|
||||
go.uber.org/automaxprocs v1.5.3
|
||||
golang.org/x/crypto v0.19.0
|
||||
golang.org/x/net v0.21.0
|
||||
golang.org/x/sys v0.17.0
|
||||
golang.org/x/text v0.14.0
|
||||
golang.org/x/crypto v0.23.0
|
||||
golang.org/x/net v0.25.0
|
||||
golang.org/x/sys v0.20.0
|
||||
golang.org/x/text v0.15.0
|
||||
golang.org/x/time v0.5.0
|
||||
golang.org/x/tools v0.17.0
|
||||
google.golang.org/protobuf v1.32.0
|
||||
golang.org/x/tools v0.21.0
|
||||
google.golang.org/protobuf v1.34.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
||||
github.com/alecthomas/assert/v2 v2.5.0 // indirect
|
||||
github.com/alecthomas/repr v0.3.0 // indirect
|
||||
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect
|
||||
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/nxadm/tail v1.4.11 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.15.0 // indirect
|
||||
github.com/onsi/gomega v1.31.1 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.19.0 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.13.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/posener/complete v1.2.3 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.46.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.54.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/stretchr/objx v0.5.1 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/stretchr/testify v1.9.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 // indirect
|
||||
golang.org/x/mod v0.15.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
|
||||
197
go.sum
197
go.sum
@@ -3,13 +3,12 @@ github.com/AudriusButkevicius/recli v0.0.7-0.20220911121932-d000ce8fbf0f/go.mod
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/alecthomas/assert/v2 v2.5.0 h1:OJKYg53BQx06/bMRBSPDCO49CbCDNiUQXwdoNrt6x5w=
|
||||
github.com/alecthomas/assert/v2 v2.5.0/go.mod h1:fw5suVxB+wfYJ3291t0hRTqtGzFYdSwstnRQdaQx2DM=
|
||||
github.com/alecthomas/kong v0.8.1 h1:acZdn3m4lLRobeh3Zi2S2EpnXTd1mOL6U7xVml+vfkY=
|
||||
github.com/alecthomas/kong v0.8.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U=
|
||||
github.com/alecthomas/repr v0.3.0 h1:NeYzUPfjjlqHY4KtzgKJiWd6sVq2eNUPTi34PiFGjY8=
|
||||
github.com/alecthomas/repr v0.3.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
|
||||
github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU=
|
||||
github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/kong v0.9.0 h1:G5diXxc85KvoV2f0ZRVuMsi45IrBgx9zDNGNj165aPA=
|
||||
github.com/alecthomas/kong v0.9.0/go.mod h1:Y47y5gKfHp1hDc7CH7OeXgLIpp+Q2m1Ni0L5s3bI8Os=
|
||||
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI=
|
||||
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
@@ -22,19 +21,19 @@ github.com/calmh/xdr v1.1.0 h1:U/Dd4CXNLoo8EiQ4ulJUXkgO1/EyQLgDKLgpY1SOoJE=
|
||||
github.com/calmh/xdr v1.1.0/go.mod h1:E8sz2ByAdXC8MbANf1LCRYzedSnnc+/sXXJs/PVqoeg=
|
||||
github.com/ccding/go-stun v0.1.4 h1:lC0co3Q3vjAuu2Jz098WivVPBPbemYFqbwE1syoka4M=
|
||||
github.com/ccding/go-stun v0.1.4/go.mod h1:cCZjJ1J3WFSJV6Wj8Y9Di8JMTsEXh6uv2eNmLzKaUeM=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d h1:S2NE3iHSwP0XV47EEXL8mWmRdEfGscSJ+7EgePNgt0s=
|
||||
github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chmduquesne/rollinghash v4.0.0+incompatible h1:hnREQO+DXjqIw3rUTzWN7/+Dpw+N5Um8zpKV0JOEgbo=
|
||||
github.com/chmduquesne/rollinghash v4.0.0+incompatible/go.mod h1:Uc2I36RRfTAf7Dge82bi3RU0OQUmXT9iweIcPqvr8A0=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
|
||||
github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -50,18 +49,21 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
|
||||
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-ldap/ldap/v3 v3.4.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A=
|
||||
github.com/go-ldap/ldap/v3 v3.4.6/go.mod h1:IGMQANNtxpsOzj7uUAMjpGBaOVTC4DYyIy8VsTdxmtc=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7 h1:DTX+lbVTWaTw1hQ+PbZPlnDZPEIs0SS/GCZAl535dDk=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-ldap/ldap/v3 v3.4.8 h1:loKJyspcRezt2Q3ZRMq2p/0v8iOurlmeXDPw6fikSvQ=
|
||||
github.com/go-ldap/ldap/v3 v3.4.8/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -73,64 +75,77 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo=
|
||||
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba h1:ql1qNgCyOB7iAEk8JTNM+zJrgIbnyCKX/wdlyPufP5g=
|
||||
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/greatroar/blobloom v0.7.2 h1:F30MGLHOcb4zr0pwCPTcKdlTM70rEgkf+LzdUPc5ss8=
|
||||
github.com/greatroar/blobloom v0.7.2/go.mod h1:mjMJ1hh1wjGVfr93QIHJ6FfDNVrA0IELv8OvMHJxHKs=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/greatroar/blobloom v0.8.0 h1:I9RlEkfqK9/6f1v9mFmDYegDQ/x0mISCpiNpAm23Pt4=
|
||||
github.com/greatroar/blobloom v0.8.0/go.mod h1:mjMJ1hh1wjGVfr93QIHJ6FfDNVrA0IELv8OvMHJxHKs=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jackpal/gateway v1.0.13 h1:fJccMvawxx0k7S1q7Fy/SXFE0R3hMXkMuw8y9SofWAk=
|
||||
github.com/jackpal/gateway v1.0.13/go.mod h1:6c8LjW+FVESFmwxaXySkt7fU98Yv806ADS3OY6Cvh2U=
|
||||
github.com/jackpal/gateway v1.0.15 h1:yb4Gltgr8ApHWWnSyybnDL1vURbqw7ooo7IIL5VZSeg=
|
||||
github.com/jackpal/gateway v1.0.15/go.mod h1:dbyEDcDhHUh9EmjB9ung81elMUZfG0SoNc2TfTbcj4c=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
|
||||
github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg=
|
||||
github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8=
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/maruel/panicparse/v2 v2.3.1 h1:NtJavmbMn0DyzmmSStE8yUsmPZrZmudPH7kplxBinOA=
|
||||
github.com/maruel/panicparse/v2 v2.3.1/go.mod h1:s3UmQB9Fm/n7n/prcD2xBGDkwXD6y2LeZnhbEXvs9Dg=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.8.1 h1:NicmruxkeqHjDv03SfSxqmaLuisddudfP3h5wdXFbhM=
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.8.1/go.mod h1:eyp4DdUJAKkr9tvxR3jWhw2mDK7CWABMG5r9uyaKC7I=
|
||||
github.com/maxmind/geoipupdate/v6 v6.1.0 h1:sdtTHzzQNJlXF5+fd/EoPTucRHyMonYt/Cok8xzzfqA=
|
||||
github.com/maxmind/geoipupdate/v6 v6.1.0/go.mod h1:cZYCDzfMzTY4v6dKRdV7KTB6SStxtn3yFkiJ1btTGGc=
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
@@ -146,18 +161,18 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo=
|
||||
github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0=
|
||||
github.com/oschwald/geoip2-golang v1.9.0 h1:uvD3O6fXAXs+usU+UGExshpdP13GAqp4GBrzN7IgKZc=
|
||||
github.com/oschwald/geoip2-golang v1.9.0/go.mod h1:BHK6TvDyATVQhKNbQBdrj9eAvuwOMi2zSFXizL3K81Y=
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs=
|
||||
github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY=
|
||||
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
|
||||
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
|
||||
github.com/oschwald/geoip2-golang v1.11.0 h1:hNENhCn1Uyzhf9PTmquXENiWS6AlxAEnBII6r8krA3w=
|
||||
github.com/oschwald/geoip2-golang v1.11.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
|
||||
github.com/oschwald/maxminddb-golang v1.13.0 h1:R8xBorY71s84yO06NgTmQvqvTvlS/bnYZrrWX1MElnU=
|
||||
github.com/oschwald/maxminddb-golang v1.13.0/go.mod h1:BU0z8BfFVhi1LQaonTwwGQlsHUEu9pWNdMfmq4ztm0o=
|
||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -167,21 +182,22 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig=
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||
github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
|
||||
github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
|
||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
||||
github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y=
|
||||
github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k=
|
||||
github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA=
|
||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8=
|
||||
github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0=
|
||||
github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek=
|
||||
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
|
||||
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab h1:ZjX6I48eZSFetPb41dHudEyVr5v953N15TsNZXlkcWY=
|
||||
@@ -192,35 +208,31 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
|
||||
github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM=
|
||||
github.com/shirou/gopsutil/v3 v3.24.1 h1:R3t6ondCEvmARp3wxODhXMTLC/klMa87h2PHUw5m7QI=
|
||||
github.com/shirou/gopsutil/v3 v3.24.1/go.mod h1:UU7a2MSBQa+kW1uuDq8DeEBS8kmrnQwsv2b5O513rwU=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
|
||||
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0=
|
||||
github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2 h1:F4snRP//nIuTTW9LYEzVH4HVwDG9T3M4t8y/2nqMbiY=
|
||||
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2/go.mod h1:J0q59IWjLtpRIJulohwqEZvjzwOfTEPp8SVhDJl+y0Y=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48=
|
||||
github.com/thejerf/suture/v4 v4.0.2 h1:VxIH/J8uYvqJY1+9fxi5GBfGRkRZ/jlSOP6x9HijFQc=
|
||||
github.com/thejerf/suture/v4 v4.0.2/go.mod h1:g0e8vwskm9tI0jRjxrnA6lSr0q6OfPdWJVX7G5bVWRs=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/thejerf/suture/v4 v4.0.5 h1:F1E/4FZwXWqvlWDKEUo6/ndLtxGAUzMmNqkrMknZbAA=
|
||||
github.com/thejerf/suture/v4 v4.0.5/go.mod h1:gu9Y4dXNUWFrByqRt30Rm9/UZ0wzRSt9AJS6xu/ZGxU=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=
|
||||
github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA=
|
||||
github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM=
|
||||
github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0=
|
||||
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0 h1:okhMind4q9H1OxF44gNegWkiP4H/gsTFLalHFa4OOUI=
|
||||
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0/go.mod h1:TTbGUfE+cXXceWtbTHq6lqcTvYPBKLNejBEbnUsQJtU=
|
||||
github.com/willabides/kongplete v0.4.0 h1:eivXxkp5ud5+4+NVN9e4goxC5mSh3n1RHov+gsblM2g=
|
||||
@@ -228,31 +240,35 @@ github.com/willabides/kongplete v0.4.0/go.mod h1:0P0jtWD9aTsqPSUAl4de35DLghrr57X
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
|
||||
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo=
|
||||
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg=
|
||||
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
@@ -262,17 +278,20 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su
|
||||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -300,25 +319,25 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -328,8 +347,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
|
||||
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
|
||||
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
|
||||
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -343,8 +362,8 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
||||
@@ -189,6 +189,13 @@ input[type="checkbox"].extended-attributes-filter-rule-checkbox {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* Break up long words in paragraphs only if necessary to prevent text overflow. */
|
||||
.overflow-break-word {
|
||||
overflow-wrap: break-word;
|
||||
/* Legacy name alias */
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.folder-advanced {
|
||||
padding: 1rem;
|
||||
margin-bottom: 15px;
|
||||
|
||||
@@ -15,19 +15,19 @@
|
||||
"Add filter entry": "إضافة عامل التصفية",
|
||||
"Add ignore patterns": "أضف أنماط التجاهل",
|
||||
"Add new folder?": "إضافة مجلد جديد؟",
|
||||
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "بالإضافة إلى ذلك ، سيتم زيادة الفاصل الزمني لإعادة الفحص الكامل (60 مرة، وهو الافتراضي الجديد من 1H). يمكنك أيضًا التحكم بالإعدادات وتعديلها يدويًا لكل مجلد لاحقًا بعد اختيار \"لا\".",
|
||||
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "بالإضافة إلى ذلك ، سيُزاد الفاصل الزمني لإعادة الفحص الكامل (60 مرة، وهو الافتراضي الجديد من 1H). يمكنك أيضًا التحكم بالإعدادات وتعديلها يدويًا لكل مجلد لاحقًا بعد اختيار \"لا\".",
|
||||
"Address": "العنوان",
|
||||
"Addresses": "العناوين",
|
||||
"Advanced": "متقدم",
|
||||
"Advanced Configuration": "ضبط متقدم",
|
||||
"All Data": "كل البيانات",
|
||||
"All Time": "كل الوقت",
|
||||
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "يجب حماية جميع المجلدات التي تمت مشاركتها مع هذا الجهاز بكلمة مرور ، بحيث تكون جميع البيانات المرسلة غير قابلة للقراءة بدون كلمة المرور المقدمة.",
|
||||
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "يجب حماية جميع المجلدات التي شاركتها مع هذا الجهاز بكلمة مرور ، بحيث تكون جميع البيانات المرسلة غير قابلة للقراءة بدون كلمة المرور المقدمة.",
|
||||
"Allow Anonymous Usage Reporting?": "السماح بإرسال تقارير الإستخدام المجهولة؟",
|
||||
"Allowed Networks": "الشبكات المسموح بها",
|
||||
"Alphabetic": "أبجدية",
|
||||
"Altered by ignoring deletes.": "تم التغيير بتجاهل عمليات الحذف.",
|
||||
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "الإصدار يتم معالجته بواسطة أمر خارجي. يجب إزالة الملف من المجلدات المشتركة. إذا كان المسار للتطبيق يحتوي على مسافات، يجب وضعها بين علامتي تنصيص دلالة على الاقتباس.",
|
||||
"Altered by ignoring deletes.": "تغير بتجاهل عمليات الحذف.",
|
||||
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "الإصدار يعالج بواسطة أمر خارجي. يجب إزالة الملف من المجلدات المشتركة. إذا كان المسار للتطبيق يحتوي على مسافات، يجب وضعها بين علامتي تنصيص دلالة على الاقتباس.",
|
||||
"Anonymous Usage Reporting": "تقارير الإستخدام المجهولة",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "هل تريد الانتقال الى التصميم الجديد لتقرير الاستخدام المجهول ؟",
|
||||
"Applied to LAN": "الشبكة المحلية",
|
||||
@@ -70,13 +70,13 @@
|
||||
"Connection Type": "نوع الاتصال",
|
||||
"Connections": "اتصالات",
|
||||
"Connections via relays might be rate limited by the relay": "قد يكون معدل التوصيلات عبر المرحلات محدودًا بواسطة المرحل",
|
||||
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "مراقبة الملفات بشكل مستمر متوفر في Syncthing. يتم فحص الملفات التي تم تغييرها في المسار فقط. هذا يساعد على تجنب فحص كامل المسار لأداء اسرع.",
|
||||
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "مراقبة الملفات بشكل مستمر متوفر في Syncthing. تفحص الملفات التي تغيرت في المسار فقط. هذا يساعد على تجنب فحص كامل المسار لأداء اسرع.",
|
||||
"Copied from elsewhere": "منسوخ من مكان أخر",
|
||||
"Copied from original": "منسوخ من الأصل",
|
||||
"Copied!": "تم النسخ!",
|
||||
"Copied!": "نُسِخَ!",
|
||||
"Copy": "نسخ",
|
||||
"Copy failed! Try to select and copy manually.": "فشل النسخ! حاول التحديد والنسخ يدويًا.",
|
||||
"Currently Shared With Devices": "حاليًا تم مشاركته مع الأجهزة",
|
||||
"Currently Shared With Devices": "مُشارَك مع الأجهزة حاليا",
|
||||
"Custom Range": "نطاق مخصص",
|
||||
"Danger!": "خطر!",
|
||||
"Database Location": "موقع قاعدة البيانات",
|
||||
@@ -158,9 +158,9 @@
|
||||
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "يُتوقع فشل الاتصال بخوادم IPv6، إذا لم يكن IPv6 متاحا.",
|
||||
"File Pull Order": "ترتيب استيراد الملفات",
|
||||
"File Versioning": "إصدارات الملف",
|
||||
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "الملفات يتم نقلها إلى مجلد `.stversions` عند الاستبدال أو الحذف بواسطة البرنامج.",
|
||||
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "يتم نقل الملفات إلى الإصدارات المؤرخة المختومة في مجلد `.stversions` عند استبدالها أو حذفها بواسطة Syncthing.",
|
||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "الملفات محمية من التغييرات التي تم إجراؤها على الأجهزة الأخرى ، ولكن سيتم إرسال التغييرات التي تم إجراؤها على هذا الجهاز إلى بقية الأجهزة.",
|
||||
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "تنقل الملفات إلى مجلد `.stversions` عند الاستبدال أو الحذف بواسطة البرنامج.",
|
||||
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "تنقل الملفات إلى الإصدارات المؤرخة المختومة في مجلد `.stversions` عند استبدالها أو حذفها بواسطة Syncthing.",
|
||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "الملفات محمية من التغييرات التي أجريت على الأجهزة الأخرى ، ولكن سترسل التغييرات التي أجريت على هذا الجهاز إلى بقية الأجهزة.",
|
||||
"Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.": "تُزامَنُ الملفات من العنقود، لكن التغيرات المحلية على هذا الجهاز لاتُطَبَّقُ على غيره من الأجهزة.",
|
||||
"Filesystem Watcher Errors": "أخطاء مراقب نظام الملفات",
|
||||
"Filter by date": "فلترة بالتاريخ",
|
||||
@@ -174,7 +174,7 @@
|
||||
"Folder type \"{%receiveEncrypted%}\" can only be set when adding a new folder.": "نوع المجلد \"{{receiveEncrypted}}\" لا يمكن إعداده إلا أثناء إنشاء الملف.",
|
||||
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "نوع المجلد \"{{receiveEncrypted}}\" لا يمكن إعداده بعد إضافة المجلد. يجب أن تحذف المجلد وأن تفك تشفير البيانات على قرص التخزين أو تحذفها، بعدها تنشئ المجلد مجددا.",
|
||||
"Folders": "المجلدات",
|
||||
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "للمجلدات التالية، حدث خطأ قبل بدء مشاهدة التغييرات. ستتم إعادة المحاولة كل دقيقة، نظرًا لذلك قد تختفي الأخطاء قريبًا. لكن إذا استمرت، فحاول حل المشكلة واطلب المساعدة إذا لم تستطع حل المشكلة.",
|
||||
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "للمجلدات التالية، حدث خطأ قبل بدء مشاهدة التغييرات. ستعاد المحاولة كل دقيقة، نظرًا لذلك قد تختفي الأخطاء قريبًا. لكن إذا استمرت، فحاول حل المشكلة واطلب المساعدة إذا لم تستطع حل المشكلة.",
|
||||
"Forever": "للأبد",
|
||||
"Full Rescan Interval (s)": "مدة إعادة الفحص الكامل (ثانية)",
|
||||
"GUI": "واجهة المستخدم الرسومية",
|
||||
@@ -182,7 +182,7 @@
|
||||
"GUI Authentication Password": "كلمة السر لتوثيق الواجهة",
|
||||
"GUI Authentication User": "اسم المستخدم لدخول واجهة الرسومية",
|
||||
"GUI Authentication: Set User and Password": "توثيق الواجهة: أنشئ كلمة مرور للمستخدم",
|
||||
"GUI Listen Address": "واجهة الرسومية الاستماع الى العنوان",
|
||||
"GUI Listen Address": "عنوان ترقب الواجهة الرسومية",
|
||||
"GUI Override Directory": "مجلد إحلال الواجهة",
|
||||
"GUI Theme": "شكل الواجهة",
|
||||
"General": "عام",
|
||||
@@ -193,7 +193,7 @@
|
||||
"Help": "مساعدة",
|
||||
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "ملحوظة: إذا كان الإعداد الافتراضي هو الرفض، وحدها قواعد الرفض تُرصد. جرب إضافة \"السماح للكل\" كخيار أخير.",
|
||||
"Home page": "الصفحة الرئيسية",
|
||||
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "ومع ذلك، تشير إعداداتك الحالية إلى أنك قد لا ترغب في تمكينه. لذلك تم تعطيل الإبلاغ التلقائي عن الأعطال.",
|
||||
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "ومع ذلك، تشير إعداداتك الحالية إلى أنك قد لا ترغب في تمكينه. لذلك توقف الإبلاغ التلقائي عن الأعطال.",
|
||||
"Identification": "المُعرِّف",
|
||||
"If untrusted, enter encryption password": "في حالة الرِّيبة، أدخل كلمة سر التشفير",
|
||||
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "إذا أردت منع المستخدمين الآخرين على هذا الحاسب من الوصول لملفاتك من خلال Syncthing، يُنصَح بإعداد وثائق الملكية.",
|
||||
@@ -225,9 +225,9 @@
|
||||
"Learn more": "اعرف أكثر",
|
||||
"Learn more at {%url%}": "اطلع على المزيد في {{url}}",
|
||||
"Limit": "الحد",
|
||||
"Listener Failures": "فشل المستمع",
|
||||
"Listener Status": "حالة المستمع",
|
||||
"Listeners": "المستمعين",
|
||||
"Listener Failures": "أعطال المنصت",
|
||||
"Listener Status": "حالة المنصت",
|
||||
"Listeners": "المنصتين",
|
||||
"Loading data...": "تحميل بيانات...",
|
||||
"Loading...": "تحميل...",
|
||||
"Local Additions": "الإضافات المحلِّيَّة",
|
||||
@@ -264,7 +264,7 @@
|
||||
"Newest First": "الأحدث أولا",
|
||||
"No": "لا",
|
||||
"No File Versioning": "لا تقسيم لإصدارات الملفات",
|
||||
"No files will be deleted as a result of this operation.": "لن يتم حذف أي ملفات بسبب هذا العملية.",
|
||||
"No files will be deleted as a result of this operation.": "لن يحذف أي ملف بسبب هذه العملية.",
|
||||
"No rules set": "لم تحدد قواعد",
|
||||
"No upgrades": "لا يوجد ترقيات",
|
||||
"Not shared": "لم يُشارَك",
|
||||
@@ -328,7 +328,7 @@
|
||||
"Rescans": "يعيد الفحص",
|
||||
"Restart": "إعادة تشغيل",
|
||||
"Restart Needed": "مطلوب أعادة تشغيل",
|
||||
"Restarting": "يتم إعادة التشغيل",
|
||||
"Restarting": "يُعاد التشغيل",
|
||||
"Restore": "استعادة",
|
||||
"Restore Versions": "استعادة إصدارات",
|
||||
"Resume": "استرد",
|
||||
@@ -339,7 +339,7 @@
|
||||
"Save": "حفظ",
|
||||
"Saving changes": "تُحفَظ التعديلات",
|
||||
"Scan Time Remaining": "فحص الوقت المتبقي",
|
||||
"Scanning": "يتم الفحص",
|
||||
"Scanning": "جار الفحص",
|
||||
"See external versioning help for supported templated command line parameters.": "راجع تعليمات الإصدارات الخارجية لمعرفة القيم المدعومة في سطر الأوامر.",
|
||||
"Select All": "تحديد الكل",
|
||||
"Select a version": "اختر إصداراً",
|
||||
@@ -364,12 +364,12 @@
|
||||
"Show ID": "عرض المُعرِّف",
|
||||
"Show QR": "اظهار QR",
|
||||
"Show detailed discovery status": "اعرض حالة الاكتشاف تفصيليا",
|
||||
"Show detailed listener status": "اعرض حالة الاستماع تفصيليا",
|
||||
"Show detailed listener status": "اعرض حالة الإنصات تفصيليا",
|
||||
"Show diff with previous version": "أظهر الفرق مقارنةً بالنسخة السابقة",
|
||||
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "يُعرَض بدلا من المُعرِّف ضمن العناقيد. سيُروَّج للأجهزة الأخرى على أنه اسم أساسي محتمل.",
|
||||
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "يُعرَض بدلا من المُعرِّف ضمن العناقيد. إذا تُرك فارغا، سيُحدَّث إلى الاسم المختار من قِبَل الجهاز.",
|
||||
"Shutdown": "إغلاق",
|
||||
"Shutdown Complete": "تم الإغلاق",
|
||||
"Shutdown Complete": "أُغلِق",
|
||||
"Simple": "بسيط",
|
||||
"Simple File Versioning": "التقسيم البسيط لإصدارات الملفات",
|
||||
"Single level wildcard (matches within a directory only)": "المقارنة على مستوى واحد (المقارنة مع الملفات في المجلد الحالي فقط)",
|
||||
@@ -377,10 +377,10 @@
|
||||
"Smallest First": "الأصغر أولا",
|
||||
"Some discovery methods could not be established for finding other devices or announcing this device:": "بعض أساليب الاستكشاف يمكن استخدامها للبحث عن أجهزة أخرى أو الإعلان عن هذا الجهاز:",
|
||||
"Some items could not be restored:": "بعض العناصر لا يمكن استرجاعها:",
|
||||
"Some listening addresses could not be enabled to accept connections:": "بعض عناوين الاستماع لا يمكن تفعيلها لقبول الاتصالات:",
|
||||
"Some listening addresses could not be enabled to accept connections:": "بعض عناوين الإنصات لا يمكن تفعيلها لقبول الاتصالات:",
|
||||
"Source Code": "مصدر الشفرة",
|
||||
"Stable releases and release candidates": "الإصدارات المستقرة والإصدارات المرشحة",
|
||||
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "الإصدارات المستقرة تأخرت بنحو أسبوعين. خلال هذه الفترة يتم إجراء الاختبارات كإصدارات مرشحة.",
|
||||
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "الإصدارات المستقرة تأخرت نحو أسبوعين. خلال هذه الفترة نُجري الاختبارات عن طريق الإصدارات المرشحة.",
|
||||
"Stable releases only": "الإصدارات المستقرة فقط",
|
||||
"Staggered": "مترنِّح",
|
||||
"Staggered File Versioning": "تقسمات إصدارات الملف مهترئة",
|
||||
@@ -396,17 +396,17 @@
|
||||
"Sync Ownership": "زامن الملكية",
|
||||
"Sync Protocol Listen Addresses": "عناوين بروتوكول استقبال المزامنة",
|
||||
"Sync Status": "وضع المزامنة",
|
||||
"Syncing": "يتم التزامن",
|
||||
"Syncing": "يُزامَن",
|
||||
"Syncthing device ID for \"{%devicename%}\"": "مُعرِّف Syncthing للجهاز {{devicename}}",
|
||||
"Syncthing has been shut down.": "تم إيقاف Syncthing.",
|
||||
"Syncthing has been shut down.": "أُوقِف Syncthing.",
|
||||
"Syncthing includes the following software or portions thereof:": "المزامنة تتضمن البرامج التالية أو أجزائها:",
|
||||
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing هو برنامج حر مفتوح المصدر تحت ترخيص MPL v2.0 (ترخيص موزيلا العام النسخة الثانية).",
|
||||
"Syncthing is a continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it's transmitted over the internet.": "Syncthing هو تطبيق للمزامنة المستمرة للملفات. يزامن الملفات بين جهازين أو أكثر بشكل لحظي، آمن من الأعين المتربصة. بياناتك ملك لك وحدك، من حقك أن تختار أين تُخَزَّن، وهل يطلع عليها طرف ثالث أم لا، وكيف تتنقل عبر الشبكة.",
|
||||
"Syncthing is a continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it's transmitted over the internet.": "Syncthing هو تطبيق للمزامنة المستمرة للملفات. يزامن الملفات بين جهازين أو أكثر بشكل لحظي، آمن من الأعين المتربصة. بياناتك ملك لك وحدك، من حقك أن تختار أين تُخَزَّن، وهل يطلع عليها غيرك أم لا، وكيف تتنقل عبر الشبكة.",
|
||||
"Syncthing is listening on the following network addresses for connection attempts from other devices:": "Syncthing يترقب محاولات الاتصال على العنوان التالي:",
|
||||
"Syncthing is not listening for connection attempts from other devices on any address. Only outgoing connections from this device may work.": "Syncthing لا يترقب أي محاولة للاتصال على أي من عناوين الشبكة. الاتصالات الصادرة فقط هي التي يمكن أن تعمل.",
|
||||
"Syncthing is restarting.": "يتم إعادة تشغيل Syncthing.",
|
||||
"Syncthing is restarting.": "يعاد تشغيل Syncthing.",
|
||||
"Syncthing is saving changes.": "Syncthing يحفظ التعديلات.",
|
||||
"Syncthing is upgrading.": "يتم تطوير Syncthing.",
|
||||
"Syncthing is upgrading.": "نطور Syncthing.",
|
||||
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing يدعم إعادة التشغيل التلقائي للمطورين. هذه الخاصية مفعلة بشكل افتراضي.",
|
||||
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing معطل على ما يبدو، ربما يكون العطل في شبكتك. إعادة المحاولة…",
|
||||
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing يواجه مشكلة في معالجة طلبك. إذا استعصت المشكلة، أعد تحميل الصفحة رجاء.",
|
||||
@@ -418,7 +418,7 @@
|
||||
"The Syncthing admin interface is configured to allow remote access without a password.": "واجهة مدير Syncthing معدة للسماح بالوصول بغير كلمة مرور.",
|
||||
"The aggregated statistics are publicly available at the URL below.": "الإحصاءات المجمعة متاحة للجميع على العنوان التالي.",
|
||||
"The cleanup interval cannot be blank.": "المدة بين عمليات التنظيف لا يمكن تركها فارغة.",
|
||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "تم حفظ الإعدادات ولكن لم يتم تفعيلها بعد. يجب أعادة تشغيل Syncthing حتى تم تفعيل الإعدادات.",
|
||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "حفظت الإعدادات ولكن لم تفعَّل بعد. يجب أعادة تشغيل Syncthing حتى تفعَّل الإعدادات.",
|
||||
"The device ID cannot be blank.": "مُعرِّف الجهاز لا يمكن أن يكون فارغاً.",
|
||||
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "يمكنك أن تجد مُعرِّف الجهاز الذي ينبغي استخدامه هنا في قائمة \"الإجراءات > عرض المُعرِّف\" على الجهاز الآخر. المسافات والخطوط الاعتراضية تُتجاهَل.",
|
||||
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes, and app versions. If the reported data set is changed you will be prompted with this dialog again.": "تقارير الاستخدام المشفرة ترسل يوميا. تُستخدم هذه التقارير لتتبع المنصات الشائعة، أحجام المجلدات، إصدارات التطبيق. إذا تغيرت بنود هذا التقرير، ستواجَهُ بهذه النافذة مرة أخرى.",
|
||||
@@ -452,7 +452,7 @@
|
||||
"There are no devices to share this folder with.": "لا توجد أجهزة أخرى لتشاركها هذا المجلد.",
|
||||
"There are no file versions to restore.": "لا توجد إصدارات يمكن استعادتها لهذا الملف.",
|
||||
"There are no folders to share with this device.": "لا توجد مجلدات لمشاركتها مع هذا الجهاز.",
|
||||
"They are retried automatically and will be synced when the error is resolved.": "تتم إعادة المحاولة تلقائيًا وسيتم مزامنتها عند إصلاح الخطأ.",
|
||||
"They are retried automatically and will be synced when the error is resolved.": "تُعاد المحاولة تلقائيًا وستزامن عند إصلاح الخطأ.",
|
||||
"This Device": "هذا الجهاز",
|
||||
"This Month": "هذا الشهر",
|
||||
"This can easily give hackers access to read and change any files on your computer.": "هذا قد يسبب في اختراق جهازك.",
|
||||
@@ -473,7 +473,7 @@
|
||||
"Undecided (will prompt)": "غير محدد ( ستظهر نافذة للتحديد لاحقًا )",
|
||||
"Unexpected Items": "المحتويات المفاجِئة",
|
||||
"Unexpected items have been found in this folder.": "عُثِر على محتويات غير متوقعة في هذا المجلد.",
|
||||
"Unignore": "لا يتم التجاهل",
|
||||
"Unignore": "لا تتجاهل",
|
||||
"Unknown": "غير معرف",
|
||||
"Unshared": "غير مشترك",
|
||||
"Unshared Devices": "الأجهزة غير المُشَارَكة",
|
||||
@@ -499,7 +499,7 @@
|
||||
"Version": "الإصدار",
|
||||
"Versions": "نسخ",
|
||||
"Versions Path": "مسار النسخ",
|
||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "يتم حذف الإصدارات تلقائيًا إذا تجاوزت العمر الأقصى أو تجاوزت عدد الملفات المسموح بها خلال فاصل زمني محدد.",
|
||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "تحذف الإصدارات تلقائيًا إذا تجاوزت العمر الأقصى أو تجاوزت عدد الملفات المسموح بها خلال فاصل زمني محدد.",
|
||||
"Waiting to Clean": "في انتظار التنظيف",
|
||||
"Waiting to Scan": "في انتظار الفحص",
|
||||
"Waiting to Sync": "في انتظار المزامنة",
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
"Generate": "Подновяване",
|
||||
"Global Discovery": "Глобално откриване",
|
||||
"Global Discovery Servers": "Сървъри за глобално откриване",
|
||||
"Global State": "Глобално състояние",
|
||||
"Global State": "Общо състояние",
|
||||
"Help": "Помощ",
|
||||
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "Подсказка: има само забрабяващи правила, а по подразбиране е „забранено“. Помислете дали да не добавите „permit any“ като последно правило.",
|
||||
"Home page": "Страница",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"Add devices from the introducer to our device list, for mutually shared folders.": "Afegiu dispositius de l'introductor a la nostra llista de dispositius, per a carpetes compartides mútuament.",
|
||||
"Add filter entry": "Afegeix una entrada de filtre",
|
||||
"Add ignore patterns": "Afegiu patrons per ignorar",
|
||||
"Add new folder?": "Vols afegir una carpeta nova?",
|
||||
"Add new folder?": "Voleu afegir una carpeta nova?",
|
||||
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "A més, s'augmentarà l'interval de reexploració complet (vegades 60, és a dir, el nou predeterminat d'1 h). També podeu configurar-lo manualment per a cada carpeta més tard després de triar No.",
|
||||
"Address": "Adreça",
|
||||
"Addresses": "Adreces",
|
||||
@@ -29,13 +29,13 @@
|
||||
"Altered by ignoring deletes.": "S'ha alterat ignorant les supressions.",
|
||||
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Una ordre externa gestiona la versió. Ha d'eliminar el fitxer de la carpeta compartida. Si el camí a l'aplicació conté espais, s'ha de citar.",
|
||||
"Anonymous Usage Reporting": "Informe anònim d'ús",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "El format de l'informe d'ús anònim ha canviat. Vols canviar a aquest nou format?",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "El format de l'informe d'ús anònim ha canviat. Voleu canviar a aquest nou format?",
|
||||
"Apply": "Aplica",
|
||||
"Are you sure you want to override all remote changes?": "Esteu segur que voleu anul·lar tots els canvis remots?",
|
||||
"Are you sure you want to permanently delete all these files?": "Estàs segur que vols esborrar tots aquests fitxers permanentment?",
|
||||
"Are you sure you want to remove device {%name%}?": "Estàs segur que vols esborrar el dispositiu {{name}}?",
|
||||
"Are you sure you want to remove folder {%label%}?": "Estàs segur que vols esborrar la carpeta {{label}}?",
|
||||
"Are you sure you want to restore {%count%} files?": "Estàs segur que vols restaurar {{count}} fitxers?",
|
||||
"Are you sure you want to permanently delete all these files?": "Segur que voleu esborrar tots aquests fitxers permanentment?",
|
||||
"Are you sure you want to remove device {%name%}?": "Segur que voleu eliminar el dispositiu {{name}}?",
|
||||
"Are you sure you want to remove folder {%label%}?": "Segur que voleu eliminar la carpeta {{label}}?",
|
||||
"Are you sure you want to restore {%count%} files?": "Segur que voleu restaurar {{count}} fitxers?",
|
||||
"Are you sure you want to revert all local changes?": "Esteu segur que voleu revertir tots els canvis locals?",
|
||||
"Are you sure you want to upgrade?": "Esteu segur que voleu actualitzar?",
|
||||
"Authors": "Autors",
|
||||
@@ -55,7 +55,7 @@
|
||||
"Cleaning Versions": "Netejant versions",
|
||||
"Cleanup Interval": "Interval de neteja",
|
||||
"Click to see full identification string and QR code.": "Feu clic per veure la cadena d'identificació completa i el codi QR.",
|
||||
"Close": "Tancar",
|
||||
"Close": "Tanca",
|
||||
"Command": "Comando",
|
||||
"Comment, when used at the start of a line": "Comentari quan és usat al principi d'una línia",
|
||||
"Compression": "Compressió",
|
||||
@@ -64,6 +64,7 @@
|
||||
"Configured": "Configurat",
|
||||
"Connected (Unused)": "Connectat (no utilitzat)",
|
||||
"Connection Error": "Error de connexió",
|
||||
"Connection Management": "Gestió de connexions",
|
||||
"Connection Type": "Tipus de connexió",
|
||||
"Connections": "Connexions",
|
||||
"Connections via relays might be rate limited by the relay": "Les connexions mitjançant relés poden estar limitades pel relé",
|
||||
@@ -91,11 +92,12 @@
|
||||
"Deselect devices to stop sharing this folder with.": "Desseleccioneu els dispositius amb els quals deixar de compartir aquesta carpeta.",
|
||||
"Deselect folders to stop sharing with this device.": "Desseleccioneu les carpetes per deixar de compartir-les amb aquest dispositiu.",
|
||||
"Device": "Dispositiu",
|
||||
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "El dispositiu \"{{name}}\" ({{device}} a {{address}}) vol connectar-se. Vols afegir un dispositiu nou?",
|
||||
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "El dispositiu «{{name}}» ({{device}} a {{address}}) vol connectar-se. Voleu afegir un dispositiu nou?",
|
||||
"Device Certificate": "Certificat del dispositiu",
|
||||
"Device ID": "ID del dispositiu",
|
||||
"Device Identification": "Identificació del dispositiu",
|
||||
"Device Name": "Nom del dispositiu",
|
||||
"Device Status": "Estat del dispositiu",
|
||||
"Device is untrusted, enter encryption password": "El dispositiu no és de confiança, introduïu la contrasenya d'encriptació",
|
||||
"Device rate limits": "Límits de velocitat del dispositiu",
|
||||
"Device that last modified the item": "Dispositiu que ha modificat el fitxer per última vegada",
|
||||
@@ -118,13 +120,13 @@
|
||||
"Do not add it to the ignore list, so this notification may recur.": "No l'afegiu a la llista d'ignorar, de manera que aquesta notificació pot repetir-se.",
|
||||
"Do not restore": "No restaurar",
|
||||
"Do not restore all": "No restaurar-ho tot",
|
||||
"Do you want to enable watching for changes for all your folders?": "Vols activar la cerca de canvis a totes les teves carpetes?",
|
||||
"Do you want to enable watching for changes for all your folders?": "Voleu activar el control de canvis a totes les carpetes?",
|
||||
"Documentation": "Documentació",
|
||||
"Download Rate": "Tasca de descarrega",
|
||||
"Downloaded": "Descarregat",
|
||||
"Downloading": "Descarregant",
|
||||
"Edit": "Editar",
|
||||
"Edit Device": "Editar dispositiu",
|
||||
"Edit": "Edita",
|
||||
"Edit Device": "Edita el dispositiu",
|
||||
"Edit Device Defaults": "Edita els valors predeterminats del dispositiu",
|
||||
"Edit Folder": "Modificar carpeta",
|
||||
"Edit Folder Defaults": "Edita els valors per defecte de la carpeta",
|
||||
@@ -165,8 +167,9 @@
|
||||
"Folder ID": "ID de carpeta",
|
||||
"Folder Label": "Etiqueta de la carpeta",
|
||||
"Folder Path": "Camí de carpeta",
|
||||
"Folder Status": "Estat de la carpeta",
|
||||
"Folder Type": "Tipus de carpeta",
|
||||
"Folder type \"{%receiveEncrypted%}\" can only be set when adding a new folder.": "El tipus de carpeta \"{{receiveEncrypted}}\" només es pot definir quan s'afegeix una carpeta nova.",
|
||||
"Folder type \"{%receiveEncrypted%}\" can only be set when adding a new folder.": "El tipus de carpeta «{{receiveEncrypted}}» només es pot definir quan s'afegeix una carpeta nova.",
|
||||
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "El tipus de carpeta \"{{receiveEncrypted}}\" no es pot canviar després d'afegir la carpeta. Heu d'eliminar la carpeta, suprimir o desxifrar les dades del disc i tornar a afegir la carpeta.",
|
||||
"Folders": "Carpetes",
|
||||
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "A les carpetes següents s'ha produït un error en començar a buscar canvis. Es tornarà a provar cada minut, de manera que els errors poden desaparèixer aviat. Si persisteixen, intenteu solucionar el problema subjacent i demaneu ajuda si no podeu.",
|
||||
@@ -182,8 +185,8 @@
|
||||
"GUI Theme": "Tema de la GUI",
|
||||
"General": "General",
|
||||
"Generate": "Generar",
|
||||
"Global Discovery": "Descobriment Global",
|
||||
"Global Discovery Servers": "Servidors de Descobriment Global",
|
||||
"Global Discovery": "Descobriment global",
|
||||
"Global Discovery Servers": "Servidors de descobriment global",
|
||||
"Global State": "Estat global",
|
||||
"Help": "Ajuda",
|
||||
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "Suggeriment: només s'han detectat regles de denegació mentre el valor predeterminat és denegació. Penseu a afegir \"permet qualsevol\" com a darrera regla.",
|
||||
@@ -205,6 +208,7 @@
|
||||
"Internally used paths:": "Camins utilitzats internament:",
|
||||
"Introduced By": "Introduït per",
|
||||
"Introducer": "Introductor",
|
||||
"Introduction": "Introducció",
|
||||
"Inversion of the given condition (i.e. do not exclude)": "Inversió del patrò introduït",
|
||||
"Keep Versions": "Mantenir Versions",
|
||||
"LDAP": "LDAP",
|
||||
@@ -224,12 +228,14 @@
|
||||
"Loading data...": "Carregant dades...",
|
||||
"Loading...": "Carregant...",
|
||||
"Local Additions": "Addicions locals",
|
||||
"Local Discovery": "Descobriment Local",
|
||||
"Local Discovery": "Descobriment local",
|
||||
"Local State": "Estat local",
|
||||
"Local State (Total)": "Estat local (Total)",
|
||||
"Locally Changed Items": "Elements canviats localment",
|
||||
"Log": "Registre",
|
||||
"Log File": "Fitxer de registre",
|
||||
"Log In": "Inicia la sessió",
|
||||
"Log Out": "Tanca la sessió",
|
||||
"Log tailing paused. Scroll to the bottom to continue.": "S'ha posat en pausa el seguiment del registre. Desplaceu-vos cap a la part inferior per continuar.",
|
||||
"Logs": "Registres",
|
||||
"Major Upgrade": "Actualització major",
|
||||
@@ -255,8 +261,9 @@
|
||||
"No files will be deleted as a result of this operation.": "No se suprimirà cap fitxer com a resultat d'aquesta operació.",
|
||||
"No rules set": "No hi ha regles establertes",
|
||||
"No upgrades": "No hi ha actualitzacions",
|
||||
"Not shared": "No compartit",
|
||||
"Not shared": "Sense compartir",
|
||||
"Notice": "Avís",
|
||||
"Number of Connections": "Nombre de connexions",
|
||||
"OK": "D'acord",
|
||||
"Off": "Desactivar",
|
||||
"Oldest First": "Més antic primer",
|
||||
@@ -268,13 +275,14 @@
|
||||
"Override": "Sobreescriu",
|
||||
"Override Changes": "Sobreescriure Canvis",
|
||||
"Ownership": "Propietat",
|
||||
"Password": "Contrasenya",
|
||||
"Path": "Ruta",
|
||||
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Ruta de la carpeta a l'equip local. Si no existeix serà creada. El caràcter (~) es pot fer servir com a drecera de",
|
||||
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Ruta on s'han d'emmagatzemar les versions (deixeu buit per al directori predeterminat .stversions a la carpeta compartida).",
|
||||
"Paths": "Rutes",
|
||||
"Pause": "Pausa",
|
||||
"Pause": "Posa-ho en pausa",
|
||||
"Pause All": "Posa-ho tot en pausa",
|
||||
"Paused": "Pausat",
|
||||
"Paused": "En pausa",
|
||||
"Paused (Unused)": "En pausa (no utilitzat)",
|
||||
"Pending changes": "Canvis pendents",
|
||||
"Periodic scanning at given interval and disabled watching for changes": "Escaneig periòdic a un interval determinat i vigilància desactivada dels canvis",
|
||||
@@ -294,8 +302,8 @@
|
||||
"QUIC WAN": "Connexió QUIC WAN",
|
||||
"Quick guide to supported patterns": "Guia ràpida per als possibles patrons",
|
||||
"Random": "Aleatori",
|
||||
"Receive Encrypted": "Rebre xifrat",
|
||||
"Receive Only": "Només rebre",
|
||||
"Receive Encrypted": "Rep xifrat",
|
||||
"Receive Only": "Només rep",
|
||||
"Received data is already encrypted": "Les dades rebudes ja estan xifrades",
|
||||
"Recent Changes": "Canvis recents",
|
||||
"Reduced by ignore patterns": "Reduït per ignorar patrons",
|
||||
@@ -309,20 +317,21 @@
|
||||
"Remove Device": "Elimina el dispositiu",
|
||||
"Remove Folder": "Elimina la carpeta",
|
||||
"Required identifier for the folder. Must be the same on all cluster devices.": "Identificador obligatori per a la carpeta. Ha de ser el mateix en tots els dispositius del clúster.",
|
||||
"Rescan": "Re-escanejar",
|
||||
"Rescan All": "Re-escanejar tot",
|
||||
"Rescan": "Reescaneja",
|
||||
"Rescan All": "Reescaneja-ho tot",
|
||||
"Rescans": "Escaneja de nou",
|
||||
"Restart": "Reiniciar",
|
||||
"Restart Needed": "És Necessari Reiniciar",
|
||||
"Restarting": "Reiniciant",
|
||||
"Restart": "Reinicia",
|
||||
"Restart Needed": "Cal un reinici",
|
||||
"Restarting": "S'està reiniciant",
|
||||
"Restore": "Restaura",
|
||||
"Restore Versions": "Restaura versions",
|
||||
"Resume": "Reprendre",
|
||||
"Resume All": "Reprèn tot",
|
||||
"Resume": "Reprèn-ho",
|
||||
"Resume All": "Reprèn-ho tot",
|
||||
"Reused": "Reutilitzat",
|
||||
"Revert": "Reverteix",
|
||||
"Revert Local Changes": "Reverteix els canvis locals",
|
||||
"Save": "Guardar",
|
||||
"Save": "Desa",
|
||||
"Saving changes": "S'estan desant els canvis",
|
||||
"Scan Time Remaining": "Temps d'escanejat restant",
|
||||
"Scanning": "Escanejant",
|
||||
"See external versioning help for supported templated command line parameters.": "Consulteu l'ajuda de versions externa per als paràmetres de línia d'ordres de plantilla compatibles.",
|
||||
@@ -332,28 +341,28 @@
|
||||
"Select additional folders to share with this device.": "Seleccioneu carpetes addicionals per compartir amb aquest dispositiu.",
|
||||
"Select latest version": "Seleccioneu la darrera versió",
|
||||
"Select oldest version": "Seleccioneu la versió més antiga",
|
||||
"Send & Receive": "Enviar i rebre",
|
||||
"Send & Receive": "Envia i rep",
|
||||
"Send Extended Attributes": "Envia atributs ampliats",
|
||||
"Send Only": "Només enviar",
|
||||
"Send Only": "Només envia",
|
||||
"Send Ownership": "Envia la propietat",
|
||||
"Set Ignores on Added Folder": "Estableix filtres per ignorar a la carpeta afegida",
|
||||
"Settings": "Preferències",
|
||||
"Share": "Compartir",
|
||||
"Share Folder": "Compartir carpeta",
|
||||
"Share": "Comparteix",
|
||||
"Share Folder": "Comparteix la carpeta",
|
||||
"Share by Email": "Comparteix per correu electrònic",
|
||||
"Share by SMS": "Comparteix per SMS",
|
||||
"Share this folder?": "Compartir aquesta carpeta?",
|
||||
"Share this folder?": "Voleu compartir la carpeta?",
|
||||
"Shared Folders": "Carpetes compartides",
|
||||
"Shared With": "Compartir Amb",
|
||||
"Shared With": "Compartida amb",
|
||||
"Sharing": "Compartint",
|
||||
"Show ID": "Mostrar ID",
|
||||
"Show ID": "Mostra l'ID",
|
||||
"Show QR": "Mostra QR",
|
||||
"Show detailed discovery status": "Mostra l'estat detallat del descobriment",
|
||||
"Show detailed listener status": "Mostra l'estat detallat de l'oient",
|
||||
"Show diff with previous version": "Mostra la diferència amb la versió anterior",
|
||||
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Mostrat en comptes del ID del Node en l'estat del cluster. Serà advertit als altres dispositius com un nom opcional per defecte.",
|
||||
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Mostrat en comptes del ID del Node en l'estat del cluster. S'actualitzarà al nom del dispositiu si es deixa buit.",
|
||||
"Shutdown": "Apagar",
|
||||
"Shutdown": "Apaga",
|
||||
"Shutdown Complete": "Apagat complet",
|
||||
"Simple": "Simple",
|
||||
"Simple File Versioning": "Versionat de Fitxers Senzill",
|
||||
@@ -369,8 +378,9 @@
|
||||
"Stable releases only": "Només versions estables",
|
||||
"Staggered": "Esglaonat",
|
||||
"Staggered File Versioning": "Versionat de Fitxers Esglaonat",
|
||||
"Start Browser": "Arrancar Navegador",
|
||||
"Start Browser": "Inicia el navegador",
|
||||
"Statistics": "Estadístiques",
|
||||
"Stay logged in": "Mantén la sessió iniciada",
|
||||
"Stopped": "Aturat",
|
||||
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Emmagatzema i sincronitza només dades encriptades. Les carpetes de tots els dispositius connectats s'han de configurar amb la mateixa contrasenya o també ser del tipus \"{{receiveEncrypted}}\".",
|
||||
"Subject:": "Assumpte:",
|
||||
@@ -382,17 +392,18 @@
|
||||
"Sync Status": "Estat de sincronització",
|
||||
"Syncing": "Synthing",
|
||||
"Syncthing device ID for \"{%devicename%}\"": "ID del dispositiu Syncthing amb el nom \"{{devicename}}\"",
|
||||
"Syncthing has been shut down.": "S'ha aturat el synthing.",
|
||||
"Syncthing has been shut down.": "Synthing s'ha aturat.",
|
||||
"Syncthing includes the following software or portions thereof:": "Syncthing inclou el següent programari o parts dels mateixos:",
|
||||
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing és un programari lliure i de codi obert amb llicència MPL v2.0.",
|
||||
"Syncthing is a continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it's transmitted over the internet.": "Syncthing és un programa de sincronització contínua de fitxers. Sincronitza fitxers entre dos o més ordinadors en temps real, protegit de manera segura de mirades indiscretes. Les vostres dades són només les vostres i mereixeu triar on s'emmagatzemen, si es comparteixen amb un tercer i com es transmeten per Internet.",
|
||||
"Syncthing is listening on the following network addresses for connection attempts from other devices:": "La sincronització està escoltant a les adreces de xarxa següents els intents de connexió des d'altres dispositius:",
|
||||
"Syncthing is not listening for connection attempts from other devices on any address. Only outgoing connections from this device may work.": "La sincronització no és escoltar els intents de connexió d'altres dispositius a cap adreça. Només poden funcionar les connexions sortints d'aquest dispositiu.",
|
||||
"Syncthing is restarting.": "Reiniciant syncthing.",
|
||||
"Syncthing is restarting.": "Syncthing s'està reiniciant.",
|
||||
"Syncthing is saving changes.": "Syncthing està desant els canvis.",
|
||||
"Syncthing is upgrading.": "Actualitzant syncthing.",
|
||||
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing ara admet la notificació automàtica d'errors als desenvolupadors. Aquesta funció està activada per defecte.",
|
||||
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Sembla que Syncthing no està funcionant o hi ha un problema amb la connexió a Internet. S'està tornant a provar…",
|
||||
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Sembla ser que Syncthing està tinguent problemes per processar la teva petició. Si us plau, refresca la pàgina o reinicia Syncthing si el problema persisteix.",
|
||||
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Sembla que Syncthing està tenint problemes per a processar la petició. Recarregueu la pàgina o reinicieu Syncthing si el problema persisteix.",
|
||||
"TCP LAN": "Connexió TCP LAN",
|
||||
"TCP WAN": "Connexió TCP WAN",
|
||||
"Take me back": "Porta'm enrere",
|
||||
@@ -401,7 +412,7 @@
|
||||
"The Syncthing admin interface is configured to allow remote access without a password.": "La interfície d'administració de Syncthing està configurada per permetre l'accés remot sense contrasenya.",
|
||||
"The aggregated statistics are publicly available at the URL below.": "Les estadístiques agregades estan disponibles públicament a l'URL següent.",
|
||||
"The cleanup interval cannot be blank.": "L'interval de neteja no pot estar en blanc.",
|
||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "La configuració s'ha guardar però no s'ha activat. S'ha de reiniciar el synthing per activar la nova configuració.",
|
||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "La configuració s'ha desat, però no s'ha activat. S'ha de reiniciar el Synthing per a activar la configuració nova.",
|
||||
"The device ID cannot be blank.": "El ID del dispositiu no pot estar en blanc.",
|
||||
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "L'identificador del dispositiu que cal introduir aquí es pot trobar al diàleg \"Accions > Mostra l'ID\" de l'altre dispositiu. Els espais i els guions són opcionals (ignorats).",
|
||||
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes, and app versions. If the reported data set is changed you will be prompted with this dialog again.": "L'informe d'ús encriptat s'envia diàriament. Es fa servir per rastrejar plataformes habituals, mides de carpetes i versions de l'aplicació. Si es canvia el conjunt de dades reportades es demanarà amb aquest diàleg de nou.",
|
||||
@@ -456,7 +467,7 @@
|
||||
"Unexpected items have been found in this folder.": "S'han trobat elements inesperats en aquesta carpeta.",
|
||||
"Unignore": "No ignorar",
|
||||
"Unknown": "Desconegut",
|
||||
"Unshared": "No compartit",
|
||||
"Unshared": "Sense compartir",
|
||||
"Unshared Devices": "Dispositius no compartits",
|
||||
"Unshared Folders": "Carpetes no compartides",
|
||||
"Untrusted": "No fiable",
|
||||
@@ -470,8 +481,9 @@
|
||||
"Usage reporting is always enabled for candidate releases.": "Els informes d'ús sempre estan activats per a les versions candidates.",
|
||||
"Use HTTPS for GUI": "Utilitzar HTTPS pel GUI",
|
||||
"Use notifications from the filesystem to detect changed items.": "Utilitzeu les notificacions del sistema de fitxers per detectar elements canviats.",
|
||||
"User": "Usuari",
|
||||
"User Home": "Carpeta d'inici de l'usuari",
|
||||
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "El nom d'usuari/contrasenya no s'ha establert per a l'autenticació de la GUI. Penseu en configurar-lo.",
|
||||
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "El nom d'usuari/contrasenya no s'ha establert per a l'autenticació de la GUI. Penseu a configurar-lo.",
|
||||
"Using a direct TCP connection over LAN": "Utilitzant una connexió TCP directa per LAN",
|
||||
"Using a direct TCP connection over WAN": "Utilitzant una connexió TCP directa a través de WAN",
|
||||
"Version": "Versió",
|
||||
@@ -499,8 +511,8 @@
|
||||
"You can change your choice at any time in the Settings dialog.": "Pots canviar la teva elecció en qualsevol moment al quadre de preferències.",
|
||||
"You can read more about the two release channels at the link below.": "Podeu llegir més sobre els dos canals de llançament a l'enllaç següent.",
|
||||
"You have no ignored devices.": "No teniu cap dispositiu ignorat.",
|
||||
"You have no ignored folders.": "No tens carpetes compartides.",
|
||||
"You have unsaved changes. Do you really want to discard them?": "Tens canvis no desats. Realment les voleu descartar?",
|
||||
"You have no ignored folders.": "No teniu carpetes ignorades.",
|
||||
"You have unsaved changes. Do you really want to discard them?": "Teniu canvis no desats. Realment els voleu descartar?",
|
||||
"You must keep at least one version.": "Has de mantenir com a mínim una versió.",
|
||||
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "Mai no hauríeu d'afegir ni canviar res localment a una carpeta \"{{receiveEncrypted}}\".",
|
||||
"Your SMS app should open to let you choose the recipient and send it from your own number.": "La vostra aplicació SMS s'hauria d'obrir per permetre't triar el destinatari i enviar-lo des del teu propi número.",
|
||||
@@ -525,6 +537,7 @@
|
||||
"light": "Clar"
|
||||
}
|
||||
},
|
||||
"unknown device": "dispositiu desconegut",
|
||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vol compartir la carpeta \"{{folder}}\".",
|
||||
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} vol compartir la carpeta \"{{folderlabel}}\" ({{folder}}).",
|
||||
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} podria tornar a introduir aquest dispositiu."
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"A device with that ID is already added.": "Zařízení s takovým identifikátorem už je přidáno.",
|
||||
"A device with that ID is already added.": "Zařízení s takovým identifikátorem už již přidáno.",
|
||||
"A negative number of days doesn't make sense.": "Záporný počet dní nedává smysl.",
|
||||
"A new major version may not be compatible with previous versions.": "Nová hlavní verze nemusí být kompatibilní s předchozími verzemi.",
|
||||
"API Key": "Klíč k API",
|
||||
@@ -11,93 +11,95 @@
|
||||
"Add Device": "Přidat zařízení",
|
||||
"Add Folder": "Přidat složku",
|
||||
"Add Remote Device": "Přidat vzdálené zařízení",
|
||||
"Add devices from the introducer to our device list, for mutually shared folders.": "Přidat zařízení z uvaděče do místního seznamu zařízení a získat tak vzájemně sdílené složky.",
|
||||
"Add filter entry": "Přidej filtr",
|
||||
"Add ignore patterns": "Přidat vzory ignorovaného",
|
||||
"Add devices from the introducer to our device list, for mutually shared folders.": "Přidat zařízení od zavaděče do našeho seznamu zařízení pro vzájemné sdílení složek.",
|
||||
"Add filter entry": "Přidat položku filtru",
|
||||
"Add ignore patterns": "Přidat vzory ignorování",
|
||||
"Add new folder?": "Přidat novou složku?",
|
||||
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "Dále bude prodloužen interval mezi plnými skeny (60krát, t.j. nová výchozí hodnota 1h). V případě, že nyní zvolíte Ne, stále ještě toto později můžete u každé složky jednotlivě ručně upravit.",
|
||||
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "Kromě toho se prodlouží interval úplného opětovného skenování (60krát, t.j. nová výchozí hodnota 1h). Také to můžete později nastavit ručně pro každou složku, pokud zvolíte Ne.",
|
||||
"Address": "Adresa",
|
||||
"Addresses": "Adresy",
|
||||
"Advanced": "Pokročilé",
|
||||
"Advanced Configuration": "Pokročilá nastavení",
|
||||
"Advanced": "Rozšířené",
|
||||
"Advanced Configuration": "Rozšířená nastavení",
|
||||
"All Data": "Všechna data",
|
||||
"All Time": "Celou dobu",
|
||||
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Všechny složky sdílené s tímto zařízením musí být chráněna heslem, aby byla odesílaná data bez hesla nečitelná.",
|
||||
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Všechny složky sdílené s tímto zařízením musí být chráněny heslem, aby všechna odesílaná data byla bez zadaného hesla nečitelná.",
|
||||
"Allow Anonymous Usage Reporting?": "Povolit anonymní hlášení o používání?",
|
||||
"Allowed Networks": "Sítě, ze kterých je umožněn přístup",
|
||||
"Alphabetic": "Abecední",
|
||||
"Altered by ignoring deletes.": "Změněno pomocí vzorů ignorovaného.",
|
||||
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Správu verzí obstarává externí příkaz. U toho je třeba, aby neaktuální soubory jím byly odsouvány pryč ze sdílené složky. Pokud popis umístění tohoto příkazu obsahuje mezeru, je třeba popis umístění uzavřít do uvozovek.",
|
||||
"Allowed Networks": "Povolené sítě",
|
||||
"Alphabetic": "Abecedně",
|
||||
"Altered by ignoring deletes.": "Změněno ignorováním odstraněných.",
|
||||
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Verzování obstarává externí příkaz. Ten musí odebrat soubor ze sdílené složky. Pokud cesta k aplikaci obsahuje mezery, je potřeba ji uvést v uvozovkách.",
|
||||
"Anonymous Usage Reporting": "Anonymní hlášení o používání",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "Formát anonymního hlášení o používání byl změněn. Chcete přejít na nový formát?",
|
||||
"Applied to LAN": "Použité pro místní síť",
|
||||
"Apply": "Aplikovat",
|
||||
"Are you sure you want to override all remote changes?": "Skutečně si přejete přebít všechny vzdálené změny?",
|
||||
"Are you sure you want to permanently delete all these files?": "Skutečně chcete smazat všechny tyto soubory?",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "Formát anonymního hlášení o používání se změnil. Chcete přejít na nový formát?",
|
||||
"Applied to LAN": "Použité pro LAN",
|
||||
"Apply": "Použít",
|
||||
"Are you sure you want to override all remote changes?": "Opravdu chcete přepsat všechny vzdálené změny?",
|
||||
"Are you sure you want to permanently delete all these files?": "Opravdu chcete trvale odstranit všechny tyto soubory?",
|
||||
"Are you sure you want to remove device {%name%}?": "Opravdu chcete odebrat zařízení {{name}}?",
|
||||
"Are you sure you want to remove folder {%label%}?": "Opravdu chcete odebrat složku {{label}}?",
|
||||
"Are you sure you want to restore {%count%} files?": "Opravdu chcete obnovit {{count}} souborů?",
|
||||
"Are you sure you want to revert all local changes?": "Skutečně si přejete vrátit všechny lokální změny?",
|
||||
"Are you sure you want to upgrade?": "Skutečně chcete provést aktualizaci?",
|
||||
"Authentication Required": "Autentizace vyžadována",
|
||||
"Are you sure you want to revert all local changes?": "Opravdu chcete vrátit všechny místní změny?",
|
||||
"Are you sure you want to upgrade?": "Opravdu chcete provést aktualizaci?",
|
||||
"Authentication Required": "Požadováno ověření",
|
||||
"Authors": "Autoři",
|
||||
"Auto Accept": "Přijmout automaticky",
|
||||
"Automatic Crash Reporting": "Automatické hlášení pádů",
|
||||
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Automatická aktualizace nyní nabízí volbu mezi stabilními vydáními a kandidáty na ně.",
|
||||
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Automatická aktualizace nyní nabízí výběr mezi stabilními vydáními a kandidáty na vydání.",
|
||||
"Automatic upgrades": "Automatické aktualizace",
|
||||
"Automatic upgrades are always enabled for candidate releases.": "Automatické aktualizace jsou vždy povolené u kandidátů na vydání.",
|
||||
"Automatically create or share folders that this device advertises at the default path.": "Automaticky vytvářet nebo sdílet složky, které toto zařízení propaguje ve výchozím popisu umístění.",
|
||||
"Available debug logging facilities:": "Dostupná logovací zařízení pro ladění:",
|
||||
"Automatically create or share folders that this device advertises at the default path.": "Automaticky vytvářet nebo sdílet složky, které toto zařízení propaguje ve výchozí cestě.",
|
||||
"Available debug logging facilities:": "Dostupné možnosti protokolování ladění:",
|
||||
"Be careful!": "Buďte opatrní!",
|
||||
"Body:": "Obsah:",
|
||||
"Bugs": "Chyby",
|
||||
"Cancel": "Zrušit",
|
||||
"Changelog": "Seznam změn",
|
||||
"Clean out after": "Vyčistit po",
|
||||
"Cleaning Versions": "Mazání verzí",
|
||||
"Cleanup Interval": "Interval mazání",
|
||||
"Click to see full identification string and QR code.": "Kliknutím zobrazíte úplnou identifikaci a QR kód.",
|
||||
"Cleaning Versions": "Čištění verzí",
|
||||
"Cleanup Interval": "Interval čištění",
|
||||
"Click to see full identification string and QR code.": "Kliknutím zobrazíte celý identifikační řetězec a QR kód.",
|
||||
"Close": "Zavřít",
|
||||
"Command": "Příkaz",
|
||||
"Comment, when used at the start of a line": "Pokud použito na jeho začátku, je řádek považován za komentář",
|
||||
"Comment, when used at the start of a line": "Považováno za komentář, pokud je použito na začátku řádku",
|
||||
"Compression": "Komprese",
|
||||
"Configuration Directory": "Konfigurační složka",
|
||||
"Configuration Directory": "Konfigurační adresář",
|
||||
"Configuration File": "Konfigurační soubor",
|
||||
"Configured": "Nastaveno",
|
||||
"Connected (Unused)": "Připojeno (nepoužité)",
|
||||
"Connected (Unused)": "Připojeno (nepoužito)",
|
||||
"Connection Error": "Chyba připojení",
|
||||
"Connection Management": "Správa připojení",
|
||||
"Connection Type": "Typ připojení",
|
||||
"Connections": "Spojení",
|
||||
"Connections via relays might be rate limited by the relay": "Připojení přes přenašeč může být přenašečem omezena rychlost",
|
||||
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Syncthing nyní umožňuje nepřetržité sledování změn. To zachytí změny na úložišti a spustí sken pouze pro umístění, ve kterých se něco změnilo. Výhodami jsou rychlejší propagace změn a méně plných skenů.",
|
||||
"Connections": "Připojení",
|
||||
"Connections via relays might be rate limited by the relay": "Připojení přes relé může být omezeno rychlostí relé",
|
||||
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Syncthing nyní umožňuje průběžné sledování změn. To zachytí změny na disku a provede skenování pouze změněných cest. Výhodou je rychlejší šíření změn a menší počet úplných skenování.",
|
||||
"Copied from elsewhere": "Zkopírováno odjinud",
|
||||
"Copied from original": "Zkopírováno z originálu",
|
||||
"Copied!": "Zkopírováno!",
|
||||
"Copy": "Kopírovat",
|
||||
"Copy failed! Try to select and copy manually.": "Kopírování selhalo! Zkuste vybrat a zkopírovat manuálně.",
|
||||
"Copy failed! Try to select and copy manually.": "Kopírování selhalo! Zkuste vybrat a zkopírovat ručně.",
|
||||
"Currently Shared With Devices": "Aktuálně sdíleno se zařízeními",
|
||||
"Custom Range": "Přesný rozsah",
|
||||
"Custom Range": "Vlastní rozsah",
|
||||
"Danger!": "Nebezpečí!",
|
||||
"Database Location": "Umístění databáze",
|
||||
"Debugging Facilities": "Nástroje pro ladění",
|
||||
"Default": "Výchozí",
|
||||
"Default Configuration": "Výchozí nastavení",
|
||||
"Default Configuration": "Výchozí konfigurace",
|
||||
"Default Device": "Výchozí zařízení",
|
||||
"Default Folder": "Výchozí složka",
|
||||
"Default Ignore Patterns": "Výchozí vzory ignorovaného",
|
||||
"Default Ignore Patterns": "Výchozí vzory ignorování",
|
||||
"Defaults": "Výchozí hodnoty",
|
||||
"Delete": "Smazat",
|
||||
"Delete Unexpected Items": "Smazat neočekávané položky",
|
||||
"Deleted {%file%}": "Smazáno {{file}}",
|
||||
"Delete": "Odstranit",
|
||||
"Delete Unexpected Items": "Odstranit neočekávané položky",
|
||||
"Deleted {%file%}": "Odstraněn {{file}}",
|
||||
"Deselect All": "Zrušit výběr všeho",
|
||||
"Deselect devices to stop sharing this folder with.": "Zrušte výběr zařízení, se kterými již nemá být tato složka sdílena.",
|
||||
"Deselect folders to stop sharing with this device.": "Zrušte výběr složek, které se mají přestat sdílet s tímto zařízením.",
|
||||
"Deselect devices to stop sharing this folder with.": "Zrušením výběru zařízení s ním přestanete tuto složku sdílet.",
|
||||
"Deselect folders to stop sharing with this device.": "Zrušením výběru složek zastavíte sdílení s tímto zařízením.",
|
||||
"Device": "Zařízení",
|
||||
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Zařízení „{{name}}“ ({{device}} na {{address}}) se chce připojit. Přidat nové zařízení?",
|
||||
"Device Certificate": "Certifikát zařízení",
|
||||
"Device ID": "Identifikátor zařízení",
|
||||
"Device Identification": "Identifikace zařízení",
|
||||
"Device Name": "Název zařízení",
|
||||
"Device Status": "Stav zařízení",
|
||||
"Device is untrusted, enter encryption password": "Zařízení nemá důvěru, zadejte šifrovací heslo.",
|
||||
"Device rate limits": "Omezení přenosové rychlosti pro zařízení",
|
||||
"Device that last modified the item": "Zařízení, které položku změnilo naposledy",
|
||||
@@ -153,7 +155,7 @@
|
||||
"Failed to load file versions.": "Nepodařilo se nahrát verze souboru.",
|
||||
"Failed to load ignore patterns.": "Načtení vzorů ignorovaného se nezdařilo.",
|
||||
"Failed to setup, retrying": "Nastavování se nezdařilo, zkouší se znovu",
|
||||
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Je v pořádku, když připojení k IPv6 serverům nezdaří, pokud není k dispozici IPv6 konektivita.",
|
||||
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Je v pořádku, když se připojení k IPv6 serverům nezdaří, pokud není k dispozici IPv6 konektivita.",
|
||||
"File Pull Order": "Pořadí stahování souborů",
|
||||
"File Versioning": "Správa verzí souborů",
|
||||
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Při nahrazování nebo mazání aplikací Syncthing jsou původní soubory přesunuty do složky .stversions.",
|
||||
@@ -494,7 +496,9 @@
|
||||
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "Ve složce typu „{{receiveEncrypted}}“ byste neměli lokálně nic měnit ani vytvářet.",
|
||||
"days": "dní",
|
||||
"directories": "složky",
|
||||
"file": "soubor",
|
||||
"files": "souborů",
|
||||
"folder": "složka",
|
||||
"full documentation": "úplná dokumentace",
|
||||
"items": "položky",
|
||||
"seconds": "sekund",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"A device with that ID is already added.": "Ya se ha agregado un dispositivo con ese ID.",
|
||||
"A negative number of days doesn't make sense.": "Un número negativo de días no tiene sentido.",
|
||||
"A new major version may not be compatible with previous versions.": "Una nueva versión principal puede no ser compatible con las versiones anteriores.",
|
||||
"A new major version may not be compatible with previous versions.": "Una nueva versión principal podría no ser compatible con las versiones anteriores.",
|
||||
"API Key": "Clave del API",
|
||||
"About": "Acerca de",
|
||||
"Action": "Acción",
|
||||
@@ -10,7 +10,7 @@
|
||||
"Add": "Agregar",
|
||||
"Add Device": "Agregar el dispositivo",
|
||||
"Add Folder": "Agregar Carpeta",
|
||||
"Add Remote Device": "Añadir un dispositivo",
|
||||
"Add Remote Device": "Añadir un dispositivo remoto",
|
||||
"Add devices from the introducer to our device list, for mutually shared folders.": "Añadir dispositivos desde el introductor a nuestra lista de dispositivos, para las carpetas compartidas mutuamente.",
|
||||
"Add filter entry": "Añadir una entrada al filtro",
|
||||
"Add ignore patterns": "Agregar patrones a ignorar",
|
||||
@@ -26,14 +26,14 @@
|
||||
"Allow Anonymous Usage Reporting?": "¿Deseas permitir el envío anónimo de informes de uso?",
|
||||
"Allowed Networks": "Redes permitidas",
|
||||
"Alphabetic": "Alfabético",
|
||||
"Altered by ignoring deletes.": "Alterado al ignorar eliminaciones.",
|
||||
"Altered by ignoring deletes.": "Alterado ignorando eliminaciones.",
|
||||
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Un comando externo maneja las versiones. Tienes que eliminar el archivo de la carpeta compartida. Si la ruta a la aplicación contiene espacios, ésta debe estar entre comillas.",
|
||||
"Anonymous Usage Reporting": "Informe anónimo de uso",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "El formato del informe de uso anónimo a cambiado. ¿Desearía usar el nuevo formato?",
|
||||
"Applied to LAN": "Aplicado a la LAN",
|
||||
"Apply": "Solicitar",
|
||||
"Are you sure you want to override all remote changes?": "¿Está seguro(a) de que desea sobreescribir todos los cambios remotos?",
|
||||
"Are you sure you want to permanently delete all these files?": "¿Está seguro de que desea eliminar permanente todos estos archivos?",
|
||||
"Are you sure you want to permanently delete all these files?": "¿Está seguro de que desea eliminar permanentemente todos estos archivos?",
|
||||
"Are you sure you want to remove device {%name%}?": "¿Está seguro que desea eliminar el dispositivo {{name}}?",
|
||||
"Are you sure you want to remove folder {%label%}?": "¿Está seguro que desea eliminar la carpeta {{label}}?",
|
||||
"Are you sure you want to restore {%count%} files?": "¿Está seguro que desea restaurar {{count}} archivos?",
|
||||
@@ -271,7 +271,7 @@
|
||||
"Notice": "Aviso",
|
||||
"Number of Connections": "Número de las conexiones",
|
||||
"OK": "De acuerdo",
|
||||
"Off": "Desconectar",
|
||||
"Off": "Desactivado",
|
||||
"Oldest First": "El más antiguo primero",
|
||||
"Optional descriptive label for the folder. Can be different on each device.": "Etiqueta descriptiva opcional para la carpeta. Puede ser diferente en cada dispositivo.",
|
||||
"Options": "Opciones",
|
||||
|
||||
192
gui/default/assets/lang/lang-fil.json
Normal file
192
gui/default/assets/lang/lang-fil.json
Normal file
@@ -0,0 +1,192 @@
|
||||
{
|
||||
"A device with that ID is already added.": "Nadagdag na ang device na may ganitong ID.",
|
||||
"API Key": "API Key",
|
||||
"About": "Tungkol sa",
|
||||
"Action": "Aksyon",
|
||||
"Actions": "Mga Aksyon",
|
||||
"Active filter rules": "Mga aktibong tuntunin sa pag-filter",
|
||||
"Add": "Magdagdag",
|
||||
"Add Device": "Magdagdag ng Device",
|
||||
"Add Folder": "Magdagdag ng Folder",
|
||||
"Add Remote Device": "Magdagdag ng Remote Device",
|
||||
"Add devices from the introducer to our device list, for mutually shared folders.": "Magdagdag ng mga device mula sa introducer sa aming listahan ng device, para sa mga folder na pinagsasaluhan.",
|
||||
"Add filter entry": "Magdagdag ng filter entry",
|
||||
"Add ignore patterns": "Magdagdag ng mga pattern na huwag pansinin",
|
||||
"Add new folder?": "Magdagdag ng bagong folder?",
|
||||
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "Dagdag pa rito, ang buong agwat ng muling pag-scan ay tataas (mga beses na 60, ibig sabihin, bagong default na 1h). Maaari mo ring i-configure ito nang manu-mano para sa bawat folder sa ibang pagkakataon pagkatapos piliin ang Hindi.",
|
||||
"Address": "Address",
|
||||
"Addresses": "Mga Address",
|
||||
"Advanced": "Advanced",
|
||||
"Advanced Configuration": "Advanced na Pagsasaayos",
|
||||
"All Data": "Lahat ng Data",
|
||||
"All Time": "Lahat ng Oras",
|
||||
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Dapat protektahan ang lahat ng mga folder sa device na ito sa pamamagitan ng password, upang hindi mabasa ang lahat ng mga data na ipinapadala nang wala ang ibinigay na password.",
|
||||
"Allow Anonymous Usage Reporting?": "Payagan ang Anonymous na Pag-uulat ng Paggamit?",
|
||||
"Allowed Networks": "Mga Pinapayagang Network",
|
||||
"Alphabetic": "Alpabetiko",
|
||||
"Altered by ignoring deletes.": "Binago sa pamamagitan ng hindi pagpansin sa mga pagtanggal.",
|
||||
"Anonymous Usage Reporting": "Anonymous na Pag-uulat ng Paggamit",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "Nagbago ang pormat ng anonymous na ulat ng paggamit. Gusto mo bang lumipat sa bagong pormat?",
|
||||
"Applied to LAN": "Naka-apply sa LAN",
|
||||
"Apply": "I-apply",
|
||||
"Are you sure you want to override all remote changes?": "Sigurado ka ba gusto mong i-override ang lahat ng mga remote na pagbabago?",
|
||||
"Are you sure you want to permanently delete all these files?": "Sigurado ka bang gusto mong permanenteng burahin ang lahat ng mga file na ito?",
|
||||
"Are you sure you want to remove device {%name%}?": "Sigurado ka bang gusto mong tanggalin ang device na {{name}}?",
|
||||
"Are you sure you want to remove folder {%label%}?": "Sigurado ka bang gusto mong tanggalin ang folder na {{label}}?",
|
||||
"Are you sure you want to restore {%count%} files?": "Sigurado ka bang gusto mong ibalik ang {{count}} mga file?",
|
||||
"Are you sure you want to revert all local changes?": "Sigurado ka bang gusto mong i-revert ang lahat ng mga lokal na pagbabago?",
|
||||
"Are you sure you want to upgrade?": "Sigurado ka bang gusto mong mag-upgrade?",
|
||||
"Authentication Required": "Nangangailangan ng Authentikasyon",
|
||||
"Authors": "Mga Awtor",
|
||||
"Auto Accept": "Awto na Pagtanggap",
|
||||
"Automatic Crash Reporting": "Awtomatikong Pag-ulat ng Crash",
|
||||
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Nag-aalok na ngayon ang awtomatikong pag-upgrade ng pagpipilian sa pagitan ng mga stable na release at release na mga kandidato.",
|
||||
"Automatic upgrades": "Awtomatikong pag-upgrade",
|
||||
"Automatic upgrades are always enabled for candidate releases.": "Palaging naka-enable ang awtomatikong pag-upgrade sa mga kandidato na release.",
|
||||
"Automatically create or share folders that this device advertises at the default path.": "Awtomatikong gumawa o ibahagi ang mga folder na ang device na ito na inaaanunsyo sa default path.",
|
||||
"Available debug logging facilities:": "Mga available na facility ng debug logging:",
|
||||
"Be careful!": "Mag-ingat ka!",
|
||||
"Body:": "Body:",
|
||||
"Bugs": "Mga Bug",
|
||||
"Cancel": "Kanselahin",
|
||||
"Changelog": "Mga Pagbabago",
|
||||
"Clean out after": "Linisin pagkatapos",
|
||||
"Cleaning Versions": "Mga Bersyon ng Paglinis",
|
||||
"Cleanup Interval": "Pagitan ng Paglinis",
|
||||
"Click to see full identification string and QR code.": "I-click upang makita ang buong string ng pagkakakilanlan at QR code.",
|
||||
"Close": "Isara",
|
||||
"Command": "Command",
|
||||
"Comment, when used at the start of a line": "Komento, kapag ginamit sa simula ng linya",
|
||||
"Compression": "Compression",
|
||||
"Configuration Directory": "Direktoryo ng Configuration",
|
||||
"Configuration File": "File ng Configuration",
|
||||
"Configured": "Naka-configure",
|
||||
"Connected (Unused)": "Konektado (Hindi Ginamit)",
|
||||
"Connection Error": "Error sa Pagkonekta",
|
||||
"Connection Management": "Pamahalaan ng Koneksyon",
|
||||
"Connection Type": "Uri ng Koneksyon",
|
||||
"Connections": "Mga Koneksyon",
|
||||
"Connections via relays might be rate limited by the relay": "Ang mga koneksyon sa pamamagitan ng mga relay ay maaaring ma-rate limit ng relay",
|
||||
"Copied from elsewhere": "Kinopya mula sa ibang lugar",
|
||||
"Copied from original": "Kinopya mula sa orihinal",
|
||||
"Copied!": "Kinopya!",
|
||||
"Copy": "Kopyahin",
|
||||
"Copy failed! Try to select and copy manually.": "Nabigo ang pagkopya! Subukang manwal na piliin at kopyahin.",
|
||||
"Currently Shared With Devices": "Kasalukuyang Binabahagi Sa Mga Device",
|
||||
"Custom Range": "Custom na Saklaw",
|
||||
"Danger!": "Panganib!",
|
||||
"Database Location": "Lokasyon ng Database",
|
||||
"Debugging Facilities": "Mga Facility ng Pag-debug",
|
||||
"Default": "Default",
|
||||
"Default Configuration": "Default na Configuration",
|
||||
"Default Device": "Default na Device",
|
||||
"Default Folder": "Default na Folder",
|
||||
"Default Ignore Patterns": "Default na mga Ignore Pattern",
|
||||
"Defaults": "Mga Default",
|
||||
"Delete": "Burahin",
|
||||
"Delete Unexpected Items": "Burahin ang mga Hindi Inaasahang Item",
|
||||
"Deleted {%file%}": "Binura ang {{file}}",
|
||||
"Deselect All": "I-deselect Lahat",
|
||||
"Deselect devices to stop sharing this folder with.": "I-deselect ang mga device para itigil ang pagbahagi ng folder na ito sa.",
|
||||
"Deselect folders to stop sharing with this device.": "I-deselect ang mga folder para itigil ang pagbahagi sa device na ito.",
|
||||
"Device": "Device",
|
||||
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Gustong kumonekta ang device na \"{{name}}\" ({{device}} sa {{address}}). Idagdag ang bagong device?",
|
||||
"Device Certificate": "Sertipiko ng Device",
|
||||
"Device ID": "ID ng Device",
|
||||
"Device Identification": "Pagkakilanlan ng Device",
|
||||
"Device Name": "Pangalan ng Device",
|
||||
"Device Status": "Status ng Device",
|
||||
"Device is untrusted, enter encryption password": "Hindi pinagkakatiwalaan ang device, ilagay ang password ng pag-encrypt",
|
||||
"Device rate limits": "Mga rate limit ng device",
|
||||
"Device that last modified the item": "Device na huling binago ang item",
|
||||
"Devices": "Mga Device",
|
||||
"Disable Crash Reporting": "I-disable ang Pag-uulat ng Crash",
|
||||
"Disabled": "Naka-disable",
|
||||
"Disabled periodic scanning and disabled watching for changes": "Na-disable ang pana-panahon na pag-scan at na-disable ang panonood sa mga pagbabago",
|
||||
"Disabled periodic scanning and enabled watching for changes": "Na-disable ang pana-panahon na pag-scan at na-enable ang panonood sa mga pagbabago",
|
||||
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "Dini-disable ang pagkumpara at pag-sync ng mga pahintulot ng file. Kapaki-pakinabang sa mga sistema na walang custom na pahintulot (hal. FAT, exFAT, Synology, Android).",
|
||||
"Discard": "I-discard",
|
||||
"Disconnected": "Nadiskonekta",
|
||||
"Disconnected (Inactive)": "Nadiskonekta (Hindi Aktibo)",
|
||||
"Disconnected (Unused)": "Nadiskonekta (Hindi Ginamit)",
|
||||
"Discovered": "Natuklasan",
|
||||
"Discovery": "Pagtuklas",
|
||||
"Discovery Failures": "Mga Pagkabigo sa Pagtuklas",
|
||||
"Discovery Status": "Status ng Pagtuklas",
|
||||
"Dismiss": "I-dismiss",
|
||||
"Do not add it to the ignore list, so this notification may recur.": "Huwag ito i-add sa listahan ng hindi papansinin, kaya baka lumabas muli ang notification na ito.",
|
||||
"Do not restore": "Huwag ibalik",
|
||||
"Do not restore all": "Huwag ibalik lahat",
|
||||
"Do you want to enable watching for changes for all your folders?": "Gusto mo bang i-enable ang panonood sa pagbabago para sa lahat ng iyong mga folder?",
|
||||
"Documentation": "Dokumentasyon",
|
||||
"Download Rate": "Rate ng Pag-download",
|
||||
"Downloaded": "Na-download",
|
||||
"Downloading": "Dina-download",
|
||||
"Edit": "I-edit",
|
||||
"Edit Device": "I-edit ang Device",
|
||||
"Edit Device Defaults": "I-edit ang mga Device Default",
|
||||
"Edit Folder": "I-edit ang Folder",
|
||||
"Edit Folder Defaults": "I-edit ang mga Folder Default",
|
||||
"Editing {%path%}.": "Ine-edit ang {{path}}.",
|
||||
"Enable Crash Reporting": "I-enable ang Pag-uulat ng Crash",
|
||||
"Enable NAT traversal": "I-enable ang NAT traversal",
|
||||
"Enable Relaying": "I-enable ang pag-relay",
|
||||
"Enabled": "Naka-enable",
|
||||
"Enables sending extended attributes to other devices, and applying incoming extended attributes. May require running with elevated privileges.": "Ine-enable ang pagpadala ng napalawak na attribute sa mga ibang device, at pag-apply ng papasok na napalawak na attribute. Maaring nangangailangan ng pagtakbo na may naka-elevate na pribilehiyo.",
|
||||
"Enables sending extended attributes to other devices, but not applying incoming extended attributes. This can have a significant performance impact. Always enabled when \"Sync Extended Attributes\" is enabled.": "Ine-enable ang pagpadala ng mga napalawak na attribute sa mga ibang device, pero hindi ang pag-apply ng papasok na napalawak na attribute. Maaari itong magkaroon ng makabuluhang epekto sa pagganap. Palaging naka-enable kapag naka-enable ang \"I-sync ang mga Napalawak na Attribute\".",
|
||||
"Enables sending ownership information to other devices, and applying incoming ownership information. Typically requires running with elevated privileges.": "Ine-enable ang pagpapadala ng impormasyon ng pagmamay-ari sa iba pang mga device, at paglalapat ng papasok na impormasyon ng pagmamay-ari. Karaniwang nangangailangan ng pagtakbo na may mataas na mga pribilehiyo.",
|
||||
"Enables sending ownership information to other devices, but not applying incoming ownership information. This can have a significant performance impact. Always enabled when \"Sync Ownership\" is enabled.": "Ine-enable ang pagpapadala ng impormasyon ng pagmamay-ari sa iba pang mga device, pero hindi ang paglapat ng papasok na impormasyon ng pagmamay-ari. Maari itong magkaroon ng makabuluhang epekto sa pagganap. Palaging naka-enable kapag naka-enable ang \"I-sync ang Pagmamay-ari\".",
|
||||
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Maglagay ng hindi negatibong numero (hal, \"2.35\") at pumili ng unit. Ang mga percentage ay bahagi ng kabuuan ng laki ng disk.",
|
||||
"Enter a non-privileged port number (1024 - 65535).": "Maglagay ng hindi pribilehiyong port number (1024 - 65535).",
|
||||
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Maglagay ng mga address na hinihiwalay ng kuwit (\"tcp://ip:port\", \"tcp://host:port\") o \"dinamiko\" upang gumawa ng awtomatikong pagtuklas ng address.",
|
||||
"Enter ignore patterns, one per line.": "Maglagay ng mga ignore pattern, isa kada-linya.",
|
||||
"Enter up to three octal digits.": "Maglagay ng hanggang tatlong octal digit.",
|
||||
"Error": "Error",
|
||||
"Extended Attributes": "Mga Napalawak na Attribute",
|
||||
"Extended Attributes Filter": "Filter ng Mga Napalawak na Attribute",
|
||||
"External": "Panlabas",
|
||||
"External File Versioning": "Panlabas na File Versioning",
|
||||
"Failed Items": "Mga Nabigong Item",
|
||||
"Failed to load file versions.": "Nabigong i-load ang mga bersyon ng file.",
|
||||
"Failed to load ignore patterns.": "Nabigong i-load ang mga ignore pattern.",
|
||||
"Failed to setup, retrying": "Nabigong i-set up, sinusubukan muli",
|
||||
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Inaasahan ang pagbigo sa pagkonekta sa mga IPv6 na server kapag walang konektibidad sa IPv6.",
|
||||
"File Pull Order": "Order ng Pagkuha ng File",
|
||||
"File Versioning": "File Versioning",
|
||||
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Nilipat ang mga file sa .stversions na direktoryo kapag pinalitan o binura ng Syncthing.",
|
||||
"Filter by date": "I-filter ayon sa petsa",
|
||||
"Filter by name": "I-filter ayon sa pangalan",
|
||||
"Folder": "Folder",
|
||||
"Folder ID": "ID ng Folder",
|
||||
"Folder Label": "Label ng Folder",
|
||||
"Folder Path": "Path ng Folder",
|
||||
"Folder Status": "Status ng Folder",
|
||||
"Folder Type": "Uri ng Folder",
|
||||
"Folders": "Mga Folder",
|
||||
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Para sa mga sumusunod na folder, may naganap na error habang nagsisimulang manood ng mga pagbabago. Susubukan itong muli bawat minuto, kaya maaaring mawala ang mga error sa lalong madaling panahon. Kung magpapatuloy sila, subukang ayusin ang pinagbabatayan na isyu at humingi ng tulong kung hindi mo kaya.",
|
||||
"Forever": "Magpakailanman",
|
||||
"Full Rescan Interval (s)": "Pagitan ng Punong Rescan (s)",
|
||||
"GUI": "GUI",
|
||||
"GUI / API HTTPS Certificate": "Sertipiko ng HTTPS ng GUI / API",
|
||||
"GUI Authentication Password": "Password ng Authentikasyon sa GUI",
|
||||
"GUI Authentication User": "User ng Authentikasyon sa GUI",
|
||||
"GUI Authentication: Set User and Password": "Authentikasyon sa GUI: Magtakda ng User at Password",
|
||||
"GUI Listen Address": "Listen Address ng GUI",
|
||||
"GUI Override Directory": "Override Directory ng GUI",
|
||||
"GUI Theme": "Tema ng GUI",
|
||||
"General": "General",
|
||||
"Generate": "I-generate",
|
||||
"Global Discovery": "Global na Pagtuklas",
|
||||
"Global Discovery Servers": "Mga Server ng Global na Pagtuklas",
|
||||
"Global State": "State ng Global",
|
||||
"Help": "Tulong",
|
||||
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "Hint: deny-rules lang ang nakita habang ang default ay deny. Isaalang-alang ang pagdaragdag ng \"pahintulutan ang alinman\" bilang huling panuntunan.",
|
||||
"Home page": "Pahina ng panimula",
|
||||
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Gayunpaman, ang iyong kasalukuyang mga setting ay nagpapahiwatig na maaaring hindi mo ito gustong paganahin. Hindi namin pinagana ang awtomatikong pag-uulat ng pag-crash para sa iyo.",
|
||||
"Identification": "Pagkakakilanlan",
|
||||
"If untrusted, enter encryption password": "Kapag hindi pinagkakatiwalaan, ilagay ang password ng pag-encrypt",
|
||||
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Kung gusto mong iwasan ang ibang mga user sa computer na ito na i-access ang Syncthing at sa iyong mga file, isaalang-alang na mag-set up ng authentikasyon.",
|
||||
"Ignore": "Huwag Pansinin",
|
||||
"Ignore Patterns": "Mga Ignore Pattern",
|
||||
"Ignore Permissions": "Huwag Pansinin ang mga Pahintulot"
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
"Allow Anonymous Usage Reporting?": "Autoriser l'envoi de statistiques d'utilisation anonymisées ?",
|
||||
"Allowed Networks": "Réseaux autorisés",
|
||||
"Alphabetic": "Alphabétique",
|
||||
"Altered by ignoring deletes.": "Altéré par \"Ignore Delete\".",
|
||||
"Altered by ignoring deletes.": "Protégé par \"Ignore Delete\".",
|
||||
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Une commande externe gère les versions de fichiers. Il lui incombe de supprimer les fichiers du répertoire partagé. Si le chemin contient des espaces, il doit être spécifié entre guillemets.",
|
||||
"Anonymous Usage Reporting": "Rapport anonyme de statistiques d'utilisation",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "Le format du rapport anonyme d'utilisation a changé. Voulez-vous passer au nouveau format ?",
|
||||
@@ -190,7 +190,7 @@
|
||||
"Global Discovery": "Découverte globale",
|
||||
"Global Discovery Servers": "Serveurs de découverte globale",
|
||||
"Global State": "État global",
|
||||
"Help": "Aide (en anglais)",
|
||||
"Help": "Aide (anglais)",
|
||||
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "Remarque : vous n'avez indiqué que des filtres de refus alors que le comportement par défaut est déjà le refus. Envisagez d'ajouter * (Partager tout les autres attributs non spécifiés) comme dernier filtre (coché) pour inverser le comportement par défaut.",
|
||||
"Home page": "Page d'accueil",
|
||||
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Cependant, vos réglages indiquent que vous pourriez souhaiter ne pas l'activer. Nous avons désactivé pour vous l'envoi automatique des rapports.",
|
||||
|
||||
@@ -11,16 +11,149 @@
|
||||
"Add Folder": "Engadir cartafol",
|
||||
"Add Remote Device": "Engadir dispositivo remoto",
|
||||
"Add devices from the introducer to our device list, for mutually shared folders.": "Engadir dispositivos desde o enviador ao noso dispositivo, para cartafoles mutuamente compartidos.",
|
||||
"Add filter entry": "Engadir unha entrada ao filtro",
|
||||
"Add ignore patterns": "Engadir patróns a ignorar",
|
||||
"Add new folder?": "Engadir novo cartafol?",
|
||||
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "Ademais, aumentarase o lapso de reescaneo completo (60 veces, é dicir, novo por defecto dunha hora). Tamén pode configuralo de xeito manual para cada cartafol logo de escoller No.",
|
||||
"Address": "Enderezo",
|
||||
"Addresses": "Enderezos",
|
||||
"Advanced": "Avanzado",
|
||||
"Advanced Configuration": "Configuración avanzada",
|
||||
"All Data": "Todos os datos",
|
||||
"All Time": "Todo o tempo",
|
||||
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Todos os cartafoles compartidos con este dispositivo teñen que estar protexidos por un contrasinal, de modo que os datos enviados sexan ilexibles sen o constrasinal indicado.",
|
||||
"Allow Anonymous Usage Reporting?": "Permitir o informe de uso anónimo?",
|
||||
"Allowed Networks": "Redes permitidas",
|
||||
"Alphabetic": "Alfabética",
|
||||
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Un comando externo xestiona as versións. Ten que eliminar o ficheiro do cartafol compartido. Si a ruta ao aplicativo contén espazos, deberían ir acotados.",
|
||||
"Anonymous Usage Reporting": "Informe anónimo de uso",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "O formato do informe de uso anónimo cambiou. Quere usar o novo formato?",
|
||||
"Applied to LAN": "Aplicado a LAN",
|
||||
"Apply": "Aplicar",
|
||||
"Are you sure you want to override all remote changes?": "Está seguro de que desexa sobrecribir todos os cambios remotos?",
|
||||
"Are you sure you want to permanently delete all these files?": "Está seguro de que desexa eliminar permanentemente todos estes ficheiros?",
|
||||
"Are you sure you want to remove device {%name%}?": "Está seguro de que desexa eliminar o dispositivo {{name}}?",
|
||||
"Are you sure you want to remove folder {%label%}?": "Está seguro de que desexa eliminar o cartafol {{label}}?",
|
||||
"Are you sure you want to restore {%count%} files?": "Está seguro de que desexa restaurar {{count}} ficheiros?",
|
||||
"Are you sure you want to revert all local changes?": "Está seguro de que quere reverter todos os cambios locais?",
|
||||
"Are you sure you want to upgrade?": "Está seguro de que desexa actualizar?",
|
||||
"Authors": "Autores",
|
||||
"Auto Accept": "Aceptar automaticamente",
|
||||
"Automatic Crash Reporting": "Informe Automático de Erros",
|
||||
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Agora a actualización automática permite escoller entre versións estables e versións candidatas.",
|
||||
"Automatic upgrades": "Actualizacións automáticas",
|
||||
"Automatic upgrades are always enabled for candidate releases.": "As actualizacións automáticas sempre están activadas para versións candidatas.",
|
||||
"Be careful!": "Teña coidado!",
|
||||
"Body:": "Corpo:",
|
||||
"Bugs": "Erros",
|
||||
"Cancel": "Cancelar",
|
||||
"Changelog": "Rexistro de cambios",
|
||||
"Cleaning Versions": "Limpando Versións",
|
||||
"Cleanup Interval": "Intervalo de Limpeza",
|
||||
"Click to see full identification string and QR code.": "Faga clic para ver a cadea de identificación completa e o código QR.",
|
||||
"Close": "Pechar",
|
||||
"Comment, when used at the start of a line": "Comentar, cando se usa ao inicio dunha liña",
|
||||
"Compression": "Compresión",
|
||||
"Configuration Directory": "Directorio de Configuración",
|
||||
"Configuration File": "Ficheiro de Configuración",
|
||||
"Configured": "Configurado",
|
||||
"Connected (Unused)": "Conectado (Sen uso)",
|
||||
"Connection Error": "Erro de Conexión",
|
||||
"Connection Management": "Xestión de Conexións",
|
||||
"Connection Type": "Tipo de Conexión",
|
||||
"Connections": "Conexións",
|
||||
"Connections via relays might be rate limited by the relay": "As conexións a través de relevos poden estar limitados polo relevo",
|
||||
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Agora está dispoñible o control de cambios continuo en Syncthing. Esto detectará cambios no disco e fará un escaneo só nas rutas modificadas. Os beneficios son que os cambios propaganse máis rapido e fan falta menos escaneos completos.",
|
||||
"Copied from elsewhere": "Copiado doutro sitio",
|
||||
"Copied from original": "Copiado do orixinal",
|
||||
"Copied!": "Copiado!",
|
||||
"Copy": "Copiar",
|
||||
"Copy failed! Try to select and copy manually.": "Fallou a copia! Probe a seleccionar e copiar manualmente.",
|
||||
"Danger!": "Perigo!",
|
||||
"Database Location": "Localización da Base de Datos",
|
||||
"Default": "Predeterminado",
|
||||
"Default Configuration": "Configuración Predeterminada",
|
||||
"Default Device": "Dispositivo Predeterminado",
|
||||
"Default Folder": "Cartafol Predeterminado",
|
||||
"Default Ignore Patterns": "Patróns de Ignorado Predeterminados",
|
||||
"Delete": "Eliminar",
|
||||
"Delete Unexpected Items": "Eliminar os Ítems Inesperados",
|
||||
"Deleted {%file%}": "Eliminado {{file}}",
|
||||
"Deselect All": "Deseleccionar Todo",
|
||||
"Deselect devices to stop sharing this folder with.": "Deleccionar os dispositivos cos que deixar de compartir este cartafol.",
|
||||
"Deselect folders to stop sharing with this device.": "Deseleccionar os cartafois que deixar de compartir con este dispositivo.",
|
||||
"Device": "Dispositivo",
|
||||
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "O dispositivo \"{{name}}\" ({{device}} en {{address}}) quere conectarse. Engadir o dispositivo?",
|
||||
"Device Certificate": "Certificado do Dispositivo",
|
||||
"Device ID": "ID do dispositivo",
|
||||
"Device Identification": "Identificación do dispositivo",
|
||||
"Device Name": "Nome do dispositivo",
|
||||
"Device Status": "Estado do dispositivo",
|
||||
"Device that last modified the item": "Dispositivo que modificou o elemento por última vez",
|
||||
"Devices": "Dispositivos",
|
||||
"Disable Crash Reporting": "Desactivar o Informe de Erros",
|
||||
"Disabled": "Deshabilitado",
|
||||
"Discard": "Descartar",
|
||||
"Disconnected": "Desconectado",
|
||||
"Disconnected (Inactive)": "Desconectado (Inactivo)",
|
||||
"Disconnected (Unused)": "Desconectado (Sen uso)",
|
||||
"Discovered": "Descuberto",
|
||||
"Discovery": "Descubrimento",
|
||||
"Discovery Failures": "Erros de Descubrimento",
|
||||
"Discovery Status": "Estado do Descubrimento",
|
||||
"Dismiss": "Descartar",
|
||||
"Do not restore": "Non restaurar",
|
||||
"Do you want to enable watching for changes for all your folders?": "Quere habilitar o control de cambios para todos os seus cartafois?",
|
||||
"Documentation": "Documentación",
|
||||
"Download Rate": "Velocidade de Descarga",
|
||||
"Downloaded": "Descargado",
|
||||
"Downloading": "Descargando",
|
||||
"Edit": "Editar",
|
||||
"Edit Device": "Editar o Dispositivo",
|
||||
"Edit Folder": "Editar o Cartafol",
|
||||
"Editing {%path%}.": "Editando {{path}}.",
|
||||
"Enable NAT traversal": "Habilitar o NAT traversal",
|
||||
"Enable Relaying": "Habilitar Relevos",
|
||||
"Enabled": "Habilitado",
|
||||
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Introduza un número non negativo (por exemplo, \"2.35\") e seleccione unha unidade. As porcentaxes son como partes totais do tamaño do disco.",
|
||||
"Enter a non-privileged port number (1024 - 65535).": "Introduza un número de porto non privilexiado (1024-65535).",
|
||||
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduza direccións separadas por comas (\"tcp://ip:porto\", \"tcp://host:porto\") ou \"dynamic\" para realizar o descubrimento automático da dirección.",
|
||||
"Enter ignore patterns, one per line.": "Introduza patróns a ignorar, un por liña.",
|
||||
"Enter up to three octal digits.": "Introduza ata tres díxitos octais.",
|
||||
"Error": "Erro",
|
||||
"Extended Attributes": "Atributos Estendidos",
|
||||
"Extended Attributes Filter": "Filtro de Atributos Estendidos",
|
||||
"External": "Externo",
|
||||
"External File Versioning": "Versionado de Fichiro Externo",
|
||||
"File Pull Order": "Orde de Obtención de Arquivos",
|
||||
"File Versioning": "Versionado de Ficheiros",
|
||||
"Filter by date": "FIltrar por data",
|
||||
"Filter by name": "Filtrar por nome",
|
||||
"Folder": "Cartafol",
|
||||
"Folder ID": "ID do Cartafol",
|
||||
"Folder Label": "Etiqueta do Cartafol",
|
||||
"Folder Path": "Ruta do Cartafol",
|
||||
"Folder Status": "Estado do Cartafol",
|
||||
"Folder Type": "Tipo do Cartafol",
|
||||
"Folder type \"{%receiveEncrypted%}\" can only be set when adding a new folder.": "O tipo de cartafol \"{{receiveEncrypted}}\" so pode ser establecido ao engadir un cartafol novo.",
|
||||
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "O tipo de cartafol \"{{receiveEncrypted}}\" non se pode cambiar despois de engadir o cartafol. Ten que eliminar o cartafol, eliminar ou desencriptar os datos do disco e volver a engadirlo.",
|
||||
"Folders": "Cartafois",
|
||||
"Forever": "Para sempre",
|
||||
"Full Rescan Interval (s)": "Intervalo de Escaneamento Completo (s)",
|
||||
"GUI": "GUI",
|
||||
"GUI / API HTTPS Certificate": "Certificado HTTPS GUI/API",
|
||||
"GUI Authentication Password": "Contrasinal de Autenticación da GUI",
|
||||
"GUI Authentication User": "Usuario de Autenticación da GUI",
|
||||
"GUI Authentication: Set User and Password": "Autenticación da GUI: Establecer o Usuario e o Contrasinal",
|
||||
"GUI Listen Address": "Dirección de Escoita da GUI",
|
||||
"GUI Theme": "Tema da GUI",
|
||||
"General": "Xeral",
|
||||
"Generate": "Xerar",
|
||||
"Global Discovery": "Descubrimento Global",
|
||||
"Global Discovery Servers": "Servidores de Descubrimento Global",
|
||||
"Global State": "Estado Global",
|
||||
"Help": "Axuda",
|
||||
"Home page": "Páxina de inicio",
|
||||
"Identification": "Identificación",
|
||||
"LDAP": "LDAP"
|
||||
}
|
||||
|
||||
555
gui/default/assets/lang/lang-hi.json
Normal file
555
gui/default/assets/lang/lang-hi.json
Normal file
@@ -0,0 +1,555 @@
|
||||
{
|
||||
"A device with that ID is already added.": "उस ID वाला उपकरण पहले से ही जुड़ा है।",
|
||||
"A negative number of days doesn't make sense.": "दिनों की नकारात्मक संख्या का कोई मतलब नहीं है।",
|
||||
"A new major version may not be compatible with previous versions.": "नया प्रमुख संस्करण पिछले संस्करणों के साथ संगत नहीं हो सकता है।",
|
||||
"API Key": "API कुंजी",
|
||||
"About": "हमारे बारे में",
|
||||
"Action": "कार्रवाई",
|
||||
"Actions": "कार्रवाइयां",
|
||||
"Active filter rules": "सक्रिय फिल्टर नियम",
|
||||
"Add": "जोड़ें",
|
||||
"Add Device": "उपकरण जोड़ें",
|
||||
"Add Folder": "फोल्डर जोड़ें",
|
||||
"Add Remote Device": "रिमोट उपकरण जोड़ें",
|
||||
"Add devices from the introducer to our device list, for mutually shared folders.": "पारस्परिक रूप से साझा किए गए फोल्डरों के लिए, परिचयकर्ता से हमारी उपकरण सूची में उपकरण जोड़ें।",
|
||||
"Add filter entry": "फिल्टर प्रविष्टि जोड़ें",
|
||||
"Add ignore patterns": "नजरअंदाज प्रतिमान जोड़ें",
|
||||
"Add new folder?": "नया फोल्डर जोड़ें?",
|
||||
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "इसके अतिरिक्त पूर्ण पुन: स्कैन अंतराल बढ़ाया जाएगा (60 गुना, यानी 1घं का नया तयशुदा अंतराल)। आप नंबर चुनने के बाद में इसे प्रत्येक फोल्डर के लिए मैन्युअल रूप से विन्यस्त भी कर सकते हैं।",
|
||||
"Address": "पता",
|
||||
"Addresses": "पते",
|
||||
"Advanced": "उन्नत",
|
||||
"Advanced Configuration": "उन्नत विन्यास",
|
||||
"All Data": "सभी डेटा",
|
||||
"All Time": "हर समय",
|
||||
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "इस उपकरण के साथ साझा किए गए सभी फोल्डरों को पासवर्ड द्वारा संरक्षित किया जाना चाहिए, जैसे कि दिए गए पासवर्ड के बिना भेजा गया सभी डेटा अपठनीय हो।",
|
||||
"Allow Anonymous Usage Reporting?": "अज्ञात उपयोग रिपोर्टिंग की अनुमति दें?",
|
||||
"Allowed Networks": "अनुमत नेटवर्क",
|
||||
"Alphabetic": "वर्णानुक्रमक",
|
||||
"Altered by ignoring deletes.": "मिटाए गए को अनदेखा करके बदला गया।",
|
||||
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "एक बाहरी कमांड संस्करणीकरण को संभालता है। इसे साझा फोल्डर से फाइल को हटाना होगा। यदि अनुप्रयोग के पथ में रिक्त स्थान हैं, तो उसे उद्धृत किया जाना चाहिए।",
|
||||
"Anonymous Usage Reporting": "अनाम उपयोग रिपोर्टिंग",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "अनाम उपयोग रिपोर्ट प्रारूप बदल गया है। क्या आप नए प्रारूप में जाना चाहेंगे?",
|
||||
"Applied to LAN": "LAN पर लागू किया गया",
|
||||
"Apply": "लागू करें",
|
||||
"Are you sure you want to override all remote changes?": "क्या आप वाकई सभी रिमोट परिवर्तनों का अध्यारोहण करना चाहते हैं?",
|
||||
"Are you sure you want to permanently delete all these files?": "क्या आप वाकई इन सभी फाइलों को स्थायी रूप से मिटाना चाहते हैं?",
|
||||
"Are you sure you want to remove device {%name%}?": "क्या आप वाकई उपकरण {{name}} को हटाना चाहते हैं?",
|
||||
"Are you sure you want to remove folder {%label%}?": "क्या आप वाकई फोल्डर {{label}} हटाना चाहते हैं?",
|
||||
"Are you sure you want to restore {%count%} files?": "क्या आप वाकई {{count}} फाइलें पुनर्स्थापित करना चाहते हैं?",
|
||||
"Are you sure you want to revert all local changes?": "क्या आप वाकई सभी स्थानीय परिवर्तन पूर्ववत करना चाहते हैं?",
|
||||
"Are you sure you want to upgrade?": "क्या आप वाकई उन्नयन करना चाहते हैं?",
|
||||
"Authentication Required": "प्रमाणीकरण आवश्यक",
|
||||
"Authors": "रचयिता",
|
||||
"Auto Accept": "स्वतः स्वीकारें",
|
||||
"Automatic Crash Reporting": "स्वचालित क्रैश रिपोर्टिंग",
|
||||
"Automatic upgrade now offers the choice between stable releases and release candidates.": "स्वचालित उन्नयन अब स्थिर रिलीज़ और रिलीज़ उम्मीदवारों के बीच विकल्प प्रदान करता है।",
|
||||
"Automatic upgrades": "स्वचालित उन्नयन",
|
||||
"Automatic upgrades are always enabled for candidate releases.": "उम्मीदवार रिलीज़ के लिए स्वचालित उन्नयन हमेशा सक्षम होते हैं।",
|
||||
"Automatically create or share folders that this device advertises at the default path.": "स्वचालित रूप से वे फोल्डर बनाएं या साझा करें जिन्हें यह उपकरण तयशुदा पथ पर विज्ञापित करता है।",
|
||||
"Available debug logging facilities:": "उपलब्ध डिबग लॉगिंग सुविधाएं:",
|
||||
"Be careful!": "ध्यान से!",
|
||||
"Body:": "ढांचा:",
|
||||
"Bugs": "बग",
|
||||
"Cancel": "रद्द करें",
|
||||
"Changelog": "चेंजलॉग",
|
||||
"Clean out after": "इतने समय के बाद साफ़ करें",
|
||||
"Cleaning Versions": "सफाई संस्करण",
|
||||
"Cleanup Interval": "सफाई अंतराल",
|
||||
"Click to see full identification string and QR code.": "पूर्ण पहचान स्ट्रिंग और QR कोड देखने के लिए क्लिक करें।",
|
||||
"Close": "बंद करें",
|
||||
"Command": "कमांड",
|
||||
"Comment, when used at the start of a line": "टिप्पणी, जब किसी पंक्ति के आरंभ में उपयोग किया जाता है",
|
||||
"Compression": "संपीड़न",
|
||||
"Configuration Directory": "विन्यास निर्देशिका",
|
||||
"Configuration File": "विन्यास फाइल",
|
||||
"Configured": "विन्यस्त",
|
||||
"Connected (Unused)": "जुड़े हुए (अप्रयुक्त)",
|
||||
"Connection Error": "कनेक्शन त्रुटि",
|
||||
"Connection Management": "कनेक्शन प्रबंधन",
|
||||
"Connection Type": "कनेक्शन प्रकार",
|
||||
"Connections": "कनेक्शन",
|
||||
"Connections via relays might be rate limited by the relay": "रिले के माध्यम से कनेक्शन की दर रिले द्वारा सीमित हो सकती है",
|
||||
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "परिवर्तनों पर लगातार नजर रखना अब Syncthing के भीतर उपलब्ध है। यह डिस्क पर परिवर्तनों का पता लगाएगा और केवल संशोधित पथों पर स्कैन जारी करेगा। लाभ यह है कि परिवर्तन तेजी से प्रसारित होते हैं और कम पूर्ण स्कैन की आवश्यकता होती है।",
|
||||
"Copied from elsewhere": "अन्यत्र से कॉपी किया गया",
|
||||
"Copied from original": "मूल से कॉपी किया गया",
|
||||
"Copied!": "कॉपी किया गया!",
|
||||
"Copy": "कॉपी करें",
|
||||
"Copy failed! Try to select and copy manually.": "कॉपी विफल! मैन्युअल रूप से चयन करने और कॉपी करने का प्रयास करें।",
|
||||
"Currently Shared With Devices": "वर्तमान में उपकरणों के साथ साझा किया गया",
|
||||
"Custom Range": "तदनुकूल दायरा",
|
||||
"Danger!": "खतरा!",
|
||||
"Database Location": "डेटाबेस स्थान",
|
||||
"Debugging Facilities": "डिबगिंग सुविधाएं",
|
||||
"Default": "तयशुदा",
|
||||
"Default Configuration": "तयशुदा विन्यास",
|
||||
"Default Device": "तयशुदा उपकरण",
|
||||
"Default Folder": "तयशुदा फोल्डर",
|
||||
"Default Ignore Patterns": "तयशुदा नजरअंदाज प्रतिमान",
|
||||
"Defaults": "तयशुदा मान",
|
||||
"Delete": "मिटाएं",
|
||||
"Delete Unexpected Items": "अप्रत्याशित वस्तुएं मिटाएं",
|
||||
"Deleted {%file%}": "{{file}} मिटाई गई",
|
||||
"Deselect All": "सभी अचयनित करें",
|
||||
"Deselect devices to stop sharing this folder with.": "इस फोल्डर को साझा करना बंद करने के लिए उपकरण का चयन रद्द करें।",
|
||||
"Deselect folders to stop sharing with this device.": "इस उपकरण के साथ साझा करना बंद करने के लिए फोल्डरों का चयन रद्द करें।",
|
||||
"Device": "उपकरण",
|
||||
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "उपकरण \"{{name}}\" ({{device}} {{address}} पर) जुड़ना चाहता है। नया उपकरण जोड़ें?",
|
||||
"Device Certificate": "उपकरण प्रमाणपत्र",
|
||||
"Device ID": "उपकरण ID",
|
||||
"Device Identification": "उपकरण पहचान",
|
||||
"Device Name": "उपकरण का नाम",
|
||||
"Device Status": "उपकरण की स्थिति",
|
||||
"Device is untrusted, enter encryption password": "उपकरण अविश्वसनीय है, कूटलेखन पासवर्ड दर्ज करें",
|
||||
"Device rate limits": "उपकरण दर सीमा",
|
||||
"Device that last modified the item": "वह उपकरण जिसने अंतिम बार वस्तु को संशोधित किया था",
|
||||
"Devices": "उपकरण",
|
||||
"Disable Crash Reporting": "क्रैश रिपोर्टिंग अक्षम करें",
|
||||
"Disabled": "अक्षम",
|
||||
"Disabled periodic scanning and disabled watching for changes": "आवधिक स्कैनिंग और परिवर्तनों को देखना अक्षम किया गया",
|
||||
"Disabled periodic scanning and enabled watching for changes": "आवधिक स्कैनिंग अक्षम की गई और परिवर्तनों को देखना सक्षम किया गया",
|
||||
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "आवधिक स्कैनिंग अक्षम और परिवर्तनों को देखने के लिए स्थापना विफल, हर 1मि में पुन: प्रयास:",
|
||||
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "फाइल अनुमतियों की तुलना और समन्वयन अक्षम करता है। अस्तित्वहीन या तदनुकूल अनुमतियों (जैसे FAT, exFAT, Synology, Android) वाले सिस्टम पर उपयोगी।",
|
||||
"Discard": "त्यागें",
|
||||
"Disconnected": "वियोजीत",
|
||||
"Disconnected (Inactive)": "वियोजीत (निष्क्रिय)",
|
||||
"Disconnected (Unused)": "वियोजीत (अप्रयुक्त)",
|
||||
"Discovered": "खोजे गए",
|
||||
"Discovery": "खोज",
|
||||
"Discovery Failures": "खोज विफलताएं",
|
||||
"Discovery Status": "खोज स्थिति",
|
||||
"Dismiss": "खारिज करें",
|
||||
"Do not add it to the ignore list, so this notification may recur.": "इसे अनदेखा सूची में न जोड़ें, ताकि यह अधिसूचना दोबारा आ सके।",
|
||||
"Do not restore": "पुनर्स्थापित न करें",
|
||||
"Do not restore all": "सभी को पुनर्स्थापित न करें",
|
||||
"Do you want to enable watching for changes for all your folders?": "क्या आप अपने सभी फोल्डरों के लिए परिवर्तनों को देखना सक्षम करना चाहते हैं?",
|
||||
"Documentation": "दस्तावेज़ीकरण",
|
||||
"Download Rate": "डाउनलोड दर",
|
||||
"Downloaded": "डाउनलोड किए गए",
|
||||
"Downloading": "डाउनलोड किया जा रहा है",
|
||||
"Edit": "संपादित करें",
|
||||
"Edit Device": "उपकरण संपादित करें",
|
||||
"Edit Device Defaults": "उपकरण तयशुदा संपादित करें",
|
||||
"Edit Folder": "फोल्डर संपादित करें",
|
||||
"Edit Folder Defaults": "फोल्डर तयशुदा संपादित करें",
|
||||
"Editing {%path%}.": "{{path}} का संपादन।",
|
||||
"Enable Crash Reporting": "क्रैश रिपोर्टिंग सक्षम करें",
|
||||
"Enable NAT traversal": "NAT ट्रैवर्सल सक्षम करें",
|
||||
"Enable Relaying": "रिले करना सक्षम करें",
|
||||
"Enabled": "सक्षम",
|
||||
"Enables sending extended attributes to other devices, and applying incoming extended attributes. May require running with elevated privileges.": "अन्य उपकरणों पर विस्तारित विशेषताएं भेजने और आने वाली विस्तारित विशेषताएं लागू करने में सक्षम बनाता है। उन्नत विशेषाधिकारों के साथ चलने की आवश्यकता हो सकती है।",
|
||||
"Enables sending extended attributes to other devices, but not applying incoming extended attributes. This can have a significant performance impact. Always enabled when \"Sync Extended Attributes\" is enabled.": "अन्य उपकरणों पर विस्तारित विशेषताएं भेजने में सक्षम बनाता है, लेकिन आने वाली विस्तारित विशेषताओं को लागू नहीं करता है। इससे प्रदर्शन पर महत्वपूर्ण प्रभाव पड़ सकता है। \"विस्तारित विशेषताएं समन्वयित करें\" सक्षम होने पर हमेशा सक्षम होता है।",
|
||||
"Enables sending ownership information to other devices, and applying incoming ownership information. Typically requires running with elevated privileges.": "अन्य उपकरणों पर स्वामित्व जानकारी भेजने और आने वाली स्वामित्व जानकारी लागू करने में सक्षम बनाता है। आमतौर पर उन्नत विशेषाधिकारों के साथ चलने की आवश्यकता होती है।",
|
||||
"Enables sending ownership information to other devices, but not applying incoming ownership information. This can have a significant performance impact. Always enabled when \"Sync Ownership\" is enabled.": "अन्य उपकरणों पर स्वामित्व जानकारी भेजने में सक्षम बनाता है, लेकिन आने वाली स्वामित्व जानकारी को लागू नहीं करता है। इससे प्रदर्शन पर महत्वपूर्ण प्रभाव पड़ सकता है। \"स्वामित्व समन्वयित करें\" सक्षम होने पर हमेशा सक्षम रहें।",
|
||||
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "एक गैर-नकारात्मक संख्या दर्ज करें (उदाहरण के लिए, \"2.35\") और एक इकाई का चयन करें। प्रतिशत कुल डिस्क आकार के भाग के रूप में हैं।",
|
||||
"Enter a non-privileged port number (1024 - 65535).": "एक गैर-विशेषाधिकार प्राप्त पोर्ट नंबर (1024 - 65535) दर्ज करें।",
|
||||
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "पते की स्वचालित खोज करने के लिए अल्पविराम से अलग किए गए पते (\"tcp://ip:port\", \"tcp://host:port\") या \"dynamic\" दर्ज करें।",
|
||||
"Enter ignore patterns, one per line.": "नजरअंदाज प्रतिमान दर्ज करें, प्रति पंक्ति एक।",
|
||||
"Enter up to three octal digits.": "तीन अष्टक अंक तक दर्ज करें।",
|
||||
"Error": "त्रुटि",
|
||||
"Extended Attributes": "विस्तारित विशेषताएं",
|
||||
"Extended Attributes Filter": "विस्तारित विशेषताएं फिल्टर",
|
||||
"External": "बाहरी",
|
||||
"External File Versioning": "बाहरी फाइल संस्करणीकरण",
|
||||
"Failed Items": "विफल वस्तुएं",
|
||||
"Failed to load file versions.": "फाइल संस्करण लोड करने में विफल।",
|
||||
"Failed to load ignore patterns.": "नजरअंदाज प्रतिमान लोड करने में विफल।",
|
||||
"Failed to setup, retrying": "स्थापना करने में विफल, पुनः प्रयास किया जा रहा है",
|
||||
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "यदि IPv6 संयोजकता नहीं है तो IPv6 सर्वर से जुड़ने में विफलता अपेक्षित है।",
|
||||
"File Pull Order": "फाइल खींचने का क्रम",
|
||||
"File Versioning": "फाइल संस्करणीकरण",
|
||||
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Syncthing द्वारा प्रतिस्थापित या हटाए जाने पर फाइलों को .stversions निर्देशिका में ले जाया जाता है।",
|
||||
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Syncthing द्वारा प्रतिस्थापित या हटाए जाने पर फाइलों को .stversions निर्देशिका में दिनांक अंकित संस्करणों में ले जाया जाता है।",
|
||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "फाइलें अन्य उपकरण पर किए गए परिवर्तनों से सुरक्षित रहती हैं, लेकिन इस उपकरण पर किए गए परिवर्तन शेष समूह में भेजे जाएंगे।",
|
||||
"Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.": "फाइलें समूह से समन्वयित की जाती हैं, लेकिन स्थानीय रूप से किया गया कोई भी परिवर्तन अन्य उपकरणों पर नहीं भेजा जाएगा।",
|
||||
"Filesystem Watcher Errors": "फाइलसिस्टम वॉचर त्रुटियां",
|
||||
"Filter by date": "दिनांक अनुसार फिल्टर करें",
|
||||
"Filter by name": "नाम अनुसार फिल्टर करें",
|
||||
"Folder": "फोल्डर",
|
||||
"Folder ID": "फोल्डर ID",
|
||||
"Folder Label": "फोल्डर लेबल",
|
||||
"Folder Path": "फोल्डर पथ",
|
||||
"Folder Status": "फोल्डर स्थिति",
|
||||
"Folder Type": "फोल्डर प्रकार",
|
||||
"Folder type \"{%receiveEncrypted%}\" can only be set when adding a new folder.": "फोल्डर प्रकार \"{{receiveEncrypted}}\" केवल नया फोल्डर जोड़ते समय ही निर्धारित किया जा सकता है।",
|
||||
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "फोल्डर जोड़ने के बाद फोल्डर प्रकार \"{{receiveEncrypted}}\" को बदला नहीं जा सकता। आपको फोल्डर को हटाना होगा, डिस्क पर डेटा को मिटाना या विकोड करना होगा और फोल्डर को फिर से जोड़ना होगा।",
|
||||
"Folders": "फोल्डर",
|
||||
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "निम्नलिखित फोल्डरों के लिए परिवर्तनों को देखना प्रारंभ करते समय एक त्रुटि उत्पन्न हुई। इसे हर मिनट पुनः प्रयास किया जाएगा, इसलिए त्रुटियां जल्द ही दूर हो सकती हैं। यदि वे बने रहते हैं, तो अंतर्निहित समस्या को ठीक करने का प्रयास करें और यदि आप नहीं कर सकते तो मदद मांगें।",
|
||||
"Forever": "सदैव",
|
||||
"Full Rescan Interval (s)": "पूर्ण पुनःस्कैन अंतराल (से)",
|
||||
"GUI": "GUI",
|
||||
"GUI / API HTTPS Certificate": "GUI / API HTTPS प्रमाणपत्र",
|
||||
"GUI Authentication Password": "GUI प्रमाणीकरण पासवर्ड",
|
||||
"GUI Authentication User": "GUI प्रमाणीकरण उपयोक्ता",
|
||||
"GUI Authentication: Set User and Password": "जीयूआई प्रमाणीकरण: उपयोक्ता और पासवर्ड निर्धारित करें",
|
||||
"GUI Listen Address": "GUI सुनने का पता",
|
||||
"GUI Override Directory": "GUI अध्यारोहण निर्देशिका",
|
||||
"GUI Theme": "GUI थीम",
|
||||
"General": "सामान्य",
|
||||
"Generate": "उत्पन्न करें",
|
||||
"Global Discovery": "वैश्विक खोज",
|
||||
"Global Discovery Servers": "वैश्विक खोज सर्वर",
|
||||
"Global State": "वैश्विक स्थिति",
|
||||
"Help": "सहायता",
|
||||
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "संकेत: केवल deny-rules का पता चला है जबकि तयशुदा deny है। अंतिम नियम के रूप में \"permit any\" जोड़ने पर विचार करें।",
|
||||
"Home page": "घर पृष्ठ",
|
||||
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "हालांकि, आपकी वर्तमान सेटिंग्स इंगित करती हैं कि आप शायद इसे सक्षम नहीं करना चाहेंगे। हमने आपके लिए स्वचालित क्रैश रिपोर्टिंग अक्षम कर दी है।",
|
||||
"Identification": "पहचान",
|
||||
"If untrusted, enter encryption password": "यदि अविश्वसनीय है, तो कूटलेखन पासवर्ड दर्ज करें",
|
||||
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "यदि आप इस कंप्यूटर पर अन्य उपयोक्ताओं को Syncthing और इसके माध्यम से अपनी फाइलों तक पहुँचने से रोकना चाहते हैं, तो प्रमाणीकरण स्थापित करने पर विचार करें।",
|
||||
"Ignore": "नजरअंदाज करें",
|
||||
"Ignore Patterns": "नजरअंदाज प्रतिमान",
|
||||
"Ignore Permissions": "अनुमतियां नजरअंदाज करें",
|
||||
"Ignore patterns can only be added after the folder is created. If checked, an input field to enter ignore patterns will be presented after saving.": "फोल्डर बनने के बाद ही नजरअंदाज प्रतिमान जोड़े जा सकते हैं। यदि जांच की जाती है, तो सहेजने के बाद नजरअंदाज प्रतिमान दर्ज करने के लिए एक आगत क्षेत्र प्रस्तुत किया जाएगा।",
|
||||
"Ignored Devices": "नजरअंदाज उपकरण",
|
||||
"Ignored Folders": "नजरअंदाज किये फोल्डर",
|
||||
"Ignored at": "यहां पर नजरअंदाज",
|
||||
"Included Software": "सम्मिलित सॉफ्टवेयर",
|
||||
"Incoming Rate Limit (KiB/s)": "आवक दर सीमा (KiB/s)",
|
||||
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "गलत विन्यास आपके फोल्डर की सामग्री को नुकसान पहुंचा सकता है और Syncthing को निष्क्रिय कर सकता है।",
|
||||
"Incorrect user name or password.": "गलत उपयोक्ता नाम या पासवर्ड।",
|
||||
"Internally used paths:": "आंतरिक प्रयुक्त पथ:",
|
||||
"Introduced By": "इनके द्वारा परिचय",
|
||||
"Introducer": "परिचयकर्ता",
|
||||
"Introduction": "परिचय",
|
||||
"Inversion of the given condition (i.e. do not exclude)": "दी गई शर्त का व्युत्क्रमण (अर्थात् बहिष्कृत न करें)",
|
||||
"Keep Versions": "संस्करण रखें",
|
||||
"LDAP": "LDAP",
|
||||
"Largest First": "सबसे बड़ा प्रथम",
|
||||
"Last 30 Days": "पिछले 30 दिन",
|
||||
"Last 7 Days": "पिछले 7 दिन",
|
||||
"Last Month": "पिछला महीना",
|
||||
"Last Scan": "अंतिम स्कैन",
|
||||
"Last seen": "अंतिम बार देखा गया",
|
||||
"Latest Change": "नवीनतम परिवर्तन",
|
||||
"Learn more": "अधिक जानें",
|
||||
"Learn more at {%url%}": "{{url}} पर और जानें",
|
||||
"Limit": "सीमा",
|
||||
"Listener Failures": "श्रोता की विफलता",
|
||||
"Listener Status": "श्रोता स्थिति",
|
||||
"Listeners": "श्रोता",
|
||||
"Loading data...": "डेटा लोड हो रहा है..।",
|
||||
"Loading...": "लोड हो रहा है..।",
|
||||
"Local Additions": "स्थानीय परिवर्धन",
|
||||
"Local Discovery": "स्थानीय खोज",
|
||||
"Local State": "स्थानिक स्थिति",
|
||||
"Local State (Total)": "स्थानिक स्थिति (कुल)",
|
||||
"Locally Changed Items": "स्थानीय रूप से परिवर्तित वस्तुएं",
|
||||
"Log": "लॉग",
|
||||
"Log File": "लॉग फाइल",
|
||||
"Log In": "लॉगिन",
|
||||
"Log Out": "लॉग आउट",
|
||||
"Log in to see paths information.": "पथ जानकारी देखने के लिए लॉगिन करें।",
|
||||
"Log in to see version information.": "संस्करण जानकारी देखने के लिए लॉगिन करें।",
|
||||
"Log tailing paused. Scroll to the bottom to continue.": "लॉग ट्रैकिंग रोक दी गई है। जारी रखने के लिए नीचे स्क्रॉल करें।",
|
||||
"Login failed, see Syncthing logs for details.": "लॉगिन विफल, विवरण के लिए Syncthing लॉग देखें।",
|
||||
"Logs": "लॉग",
|
||||
"Major Upgrade": "प्रमुख उन्नयन",
|
||||
"Mass actions": "सामूहिक कार्रवाई",
|
||||
"Maximum Age": "अधिकतम आयु",
|
||||
"Maximum single entry size": "अधिकतम एकल प्रविष्टि आकार",
|
||||
"Maximum total size": "अधिकतम कुल आकार",
|
||||
"Metadata Only": "केवल मेटाडेटा",
|
||||
"Minimum Free Disk Space": "न्यूनतम मुक्त डिस्क स्थान",
|
||||
"Mod. Device": "संशोधित उपकरण",
|
||||
"Mod. Time": "संशोधन समय",
|
||||
"More than a month ago": "एक महीने से भी पहले",
|
||||
"More than a week ago": "एक सप्ताह से भी पहले",
|
||||
"More than a year ago": "एक साल से भी पहले",
|
||||
"Move to top of queue": "कतार के शीर्ष पर जाएं",
|
||||
"Multi level wildcard (matches multiple directory levels)": "बहुस्तरीय वाइल्डकार्ड (एकाधिक निर्देशिका स्तरों से मेल खाता है)",
|
||||
"Never": "कभी नहीं",
|
||||
"New Device": "नया उपकरण",
|
||||
"New Folder": "नया फोल्डर",
|
||||
"Newest First": "नवीनतम पहले",
|
||||
"No": "नहीं",
|
||||
"No File Versioning": "कोई फाइल संस्करण नहीं",
|
||||
"No files will be deleted as a result of this operation.": "इस अभियान के परिणामस्वरूप कोई भी फाइल मिटाई नहीं जाएगी।",
|
||||
"No rules set": "कोई नियम निर्धारित नहीं",
|
||||
"No upgrades": "कोई उन्नयन नहीं",
|
||||
"Not shared": "साझा नहीं किया गया",
|
||||
"Notice": "सूचना",
|
||||
"Number of Connections": "कनेक्शनों की संख्या",
|
||||
"OK": "ठीक है",
|
||||
"Off": "बंद",
|
||||
"Oldest First": "पुराना पहले",
|
||||
"Optional descriptive label for the folder. Can be different on each device.": "फोल्डर के लिए वैकल्पिक वर्णनात्मक लेबल। प्रत्येक उपकरण पर भिन्न हो सकता है।",
|
||||
"Options": "विकल्प",
|
||||
"Out of Sync": "समन्वयन से बाहर",
|
||||
"Out of Sync Items": "समन्वयन से बाहर वस्तुएं",
|
||||
"Outgoing Rate Limit (KiB/s)": "जावक दर सीमा (KiB/s)",
|
||||
"Override": "अध्यारोहण",
|
||||
"Override Changes": "परिवर्तनों का अध्यारोहण",
|
||||
"Ownership": "स्वामित्व",
|
||||
"Password": "पासवर्ड",
|
||||
"Path": "पथ",
|
||||
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "स्थानीय कंप्यूटर पर फोल्डर का पथ। अगर यह मौजूद नहीं है तो इसे बनाया जाएगा। टिल्ड वर्ण (~) का उपयोग शॉर्टकट के रूप में किया जा सकता है",
|
||||
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "पथ जहां संस्करण संग्रहीत किए जाने चाहिए (साझा फोल्डर में तयशुदा .stversions निर्देशिका के लिए खाली छोड़ दें)।",
|
||||
"Paths": "पथ",
|
||||
"Pause": "विराम",
|
||||
"Pause All": "सभी विराम करें",
|
||||
"Paused": "विरामित",
|
||||
"Paused (Unused)": "विरामित (अप्रयुक्त)",
|
||||
"Pending changes": "लंबित परिवर्तन",
|
||||
"Periodic scanning at given interval and disabled watching for changes": "दिए गए अंतराल पर आवधिक स्कैनिंग और परिवर्तनों पर नजर रखने में अक्षम",
|
||||
"Periodic scanning at given interval and enabled watching for changes": "दिए गए अंतराल पर आवधिक स्कैनिंग और परिवर्तनों को देखने में सक्षम",
|
||||
"Periodic scanning at given interval and failed setting up watching for changes, retrying every 1m:": "दिए गए अंतराल पर आवधिक स्कैनिंग और परिवर्तनों को देखने के लिए स्थापना विफल, हर 1मि में पुन: प्रयास:",
|
||||
"Permanently add it to the ignore list, suppressing further notifications.": "आगे की सूचनाओं को दबाते हुए, इसे स्थायी रूप से अनदेखा सूची में जोड़ें।",
|
||||
"Please consult the release notes before performing a major upgrade.": "कृपया कोई बड़ा उन्नयन करने से पहले रिलीज़ नोट्स से परामर्श लें।",
|
||||
"Please set a GUI Authentication User and Password in the Settings dialog.": "कृपया सेटिंग्स संवाद में एक GUI प्रमाणीकरण उपयोक्ता और पासवर्ड निर्धारित करें।",
|
||||
"Please wait": "कृपया प्रतीक्षा करें",
|
||||
"Prefix indicating that the file can be deleted if preventing directory removal": "उपसर्ग यह दर्शाता है कि निर्देशिका हटाने से रोकने पर फाइल को मिटाया जा सकता है",
|
||||
"Prefix indicating that the pattern should be matched without case sensitivity": "उपसर्ग यह दर्शाता है कि प्रतिमान को केस संवेदनशीलता के बिना मिलान किया जाना चाहिए",
|
||||
"Preparing to Sync": "समन्वयन की तैयारी",
|
||||
"Preview": "पूर्वावलोकन",
|
||||
"Preview Usage Report": "उपयोग रिपोर्ट का पूर्वावलोकन करें",
|
||||
"QR code": "QR कोड",
|
||||
"QUIC LAN": "QUIC LAN",
|
||||
"QUIC WAN": "QUIC WAN",
|
||||
"Quick guide to supported patterns": "समर्थित प्रतिमान के लिए त्वरित मार्गदर्शिका",
|
||||
"Random": "यादृच्छिक",
|
||||
"Receive Encrypted": "कूटलेखित प्राप्त करें",
|
||||
"Receive Only": "केवल प्राप्त करें",
|
||||
"Received data is already encrypted": "प्राप्त डेटा पहले से ही कूटलेखित है",
|
||||
"Recent Changes": "हालिया परिवर्तन",
|
||||
"Reduced by ignore patterns": "नजरअंदाज प्रतिमान से कम किया गया",
|
||||
"Relay LAN": "रिले LAN",
|
||||
"Relay WAN": "रिले WAN",
|
||||
"Release Notes": "रिलीज नोट्स",
|
||||
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "रिलीज़ उम्मीदवारों में नवीनतम सुविधाएं और सुधार शामिल हैं। वे पारंपरिक द्वि-साप्ताहिक Syncthing रिलीज़ के समान हैं।",
|
||||
"Remote Devices": "रिमोट उपकरण",
|
||||
"Remote GUI": "रिमोट GUI",
|
||||
"Remove": "हटाएं",
|
||||
"Remove Device": "उपकरण हटाएं",
|
||||
"Remove Folder": "फोल्डर हटाएं",
|
||||
"Required identifier for the folder. Must be the same on all cluster devices.": "फोल्डर के लिए आवश्यक पहचानकर्ता। समूह के सभी उपकरणों पर समान होना चाहिए।",
|
||||
"Rescan": "पुनः स्कैन करें",
|
||||
"Rescan All": "सभी पुनः स्कैन करें",
|
||||
"Rescans": "पुनः स्कैन करता है",
|
||||
"Restart": "पुनः प्रारंभ करें",
|
||||
"Restart Needed": "पुनरारंभ की आवश्यकता है",
|
||||
"Restarting": "पुनः प्रारंभ हो रहा है",
|
||||
"Restore": "पुनर्स्थापित करें",
|
||||
"Restore Versions": "संस्करण पुनर्स्थापित करें",
|
||||
"Resume": "पुनः आरम्भ करें",
|
||||
"Resume All": "सभी पुनः आरंभ करें",
|
||||
"Reused": "पुन:प्रयुक्त",
|
||||
"Revert": "पूर्ववत करें",
|
||||
"Revert Local Changes": "स्थानीय परिवर्तन पूर्ववत करें",
|
||||
"Save": "सहेजें",
|
||||
"Saving changes": "परिवर्तन सहेजे जा रहे हैं",
|
||||
"Scan Time Remaining": "स्कैन समय शेष",
|
||||
"Scanning": "स्कैनिंग",
|
||||
"See external versioning help for supported templated command line parameters.": "समर्थित खाका कमांड लाइन पैरामीटर के लिए बाहरी संस्करण सहायता देखें।",
|
||||
"Select All": "सभी चुनें",
|
||||
"Select a version": "एक संस्करण चुनें",
|
||||
"Select additional devices to share this folder with.": "इस फोल्डर को साझा करने के लिए अतिरिक्त उपकरणों का चयन करें।",
|
||||
"Select additional folders to share with this device.": "इस उपकरण के साथ साझा करने के लिए अतिरिक्त फोल्डर चुनें।",
|
||||
"Select latest version": "नवीनतम संस्करण चुनें",
|
||||
"Select oldest version": "सबसे पुराना संस्करण चुनें",
|
||||
"Send & Receive": "भेजें एवं प्राप्त करें",
|
||||
"Send Extended Attributes": "विस्तारित विशेषताएं भेजें",
|
||||
"Send Only": "केवल भेजें",
|
||||
"Send Ownership": "स्वामित्व भेजें",
|
||||
"Set Ignores on Added Folder": "नए फोल्डर के लिए नजरअंदाज प्रतिमान निर्धारित करें",
|
||||
"Settings": "सेटिंग्स",
|
||||
"Share": "साझा करें",
|
||||
"Share Folder": "फोल्डर साझा करें",
|
||||
"Share by Email": "ईमेल द्वारा साझा करें",
|
||||
"Share by SMS": "SMS द्वारा साझा करें",
|
||||
"Share this folder?": "यह फोल्डर साझा करें?",
|
||||
"Shared Folders": "सांझे फोल्डर",
|
||||
"Shared With": "इसके साथ साझा",
|
||||
"Sharing": "साझाकरण",
|
||||
"Show ID": "ID दिखाएं",
|
||||
"Show QR": "QR दिखाएं",
|
||||
"Show detailed discovery status": "विस्तृत खोज स्थिति दिखाएं",
|
||||
"Show detailed listener status": "विस्तृत श्रोता स्थिति दिखाएं",
|
||||
"Show diff with previous version": "पिछले संस्करण के साथ अंतर दिखाएं",
|
||||
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "समूह स्थिति में उपकरण ID के बजाय दिखाया गया। वैकल्पिक तयशुदा नाम के रूप में अन्य उपकरणों पर विज्ञापित किया जाएगा।",
|
||||
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "समूह स्थिति में उपकरण ID के बजाय दिखाया गया। खाली छोड़े जाने पर उपकरण द्वारा विज्ञापित नाम में अद्यतित कर दिया जाएगा।",
|
||||
"Shutdown": "शटडाउन",
|
||||
"Shutdown Complete": "शटडाउन पूर्ण",
|
||||
"Simple": "सरल",
|
||||
"Simple File Versioning": "सरल फाइल संस्करण",
|
||||
"Single level wildcard (matches within a directory only)": "एकल स्तरीय वाइल्डकार्ड (केवल एक निर्देशिका के भीतर मेल खाता है)",
|
||||
"Size": "आकार",
|
||||
"Smallest First": "सबसे छोटा पहले",
|
||||
"Some discovery methods could not be established for finding other devices or announcing this device:": "अन्य उपकरणों को खोजने या इस उपकरण की घोषणा करने के लिए कुछ खोज विधियां स्थापित नहीं की जा सकीं:",
|
||||
"Some items could not be restored:": "कुछ वस्तुएं पुनर्स्थापित नहीं किए जा सके:",
|
||||
"Some listening addresses could not be enabled to accept connections:": "कुछ श्रवण पते कनेक्शन स्वीकार करने के लिए सक्षम नहीं किए जा सके:",
|
||||
"Source Code": "स्रोत कोड",
|
||||
"Stable releases and release candidates": "स्थिर रिलीज़ और रिलीज़ उम्मीदवार",
|
||||
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "स्थिर रिलीज़ में लगभग दो सप्ताह की देरी हो रही है। इस दौरान वे रिलीज़ उम्मीदवारों के रूप में परीक्षण से गुजरते हैं।",
|
||||
"Stable releases only": "केवल स्थिर रिलीज़",
|
||||
"Staggered": "विचलता",
|
||||
"Staggered File Versioning": "विचलता फाइल संस्करण",
|
||||
"Start Browser": "ब्राउज़र प्रारंभ करें",
|
||||
"Statistics": "आंकडे",
|
||||
"Stay logged in": "लॉगिन रहें",
|
||||
"Stopped": "रुका हुआ",
|
||||
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "केवल कूटलेखित डेटा को स्टोर और समन्वयित करें। सभी जुड़ें उपकरणों पर फोल्डरों को एक ही पासवर्ड के साथ स्थापित किया जाना चाहिए या \"{{receiveEncrypted}}\" प्रकार का भी होना चाहिए।",
|
||||
"Subject:": "विषय:",
|
||||
"Support": "समर्थन",
|
||||
"Support Bundle": "समर्थन बंडल",
|
||||
"Sync Extended Attributes": "विस्तारित विशेषताएं समन्वयित करें",
|
||||
"Sync Ownership": "स्वामित्व समन्वयित करें",
|
||||
"Sync Protocol Listen Addresses": "समन्वयन प्रोटोकॉल का श्रवण पता",
|
||||
"Sync Status": "समन्वयन स्थिति",
|
||||
"Syncing": "समन्वयित हो रहा है",
|
||||
"Syncthing device ID for \"{%devicename%}\"": "\"{{devicename}}\" के लिए Syncthing उपकरण ID",
|
||||
"Syncthing has been shut down.": "Syncthing बंद कर दिया गया है।",
|
||||
"Syncthing includes the following software or portions thereof:": "Syncthing में निम्नलिखित सॉफ़्टवेयर या उसके भाग शामिल हैं:",
|
||||
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing मुक्त और खुले-स्त्रोत सॉफ़्टवेयर है जिसे MPL v2.0 के रूप में लाइसेंस प्राप्त है।",
|
||||
"Syncthing is a continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it's transmitted over the internet.": "Syncthing एक सतत फाइल समन्वयन प्रोग्राम है। यह वास्तविक समय में दो या दो से अधिक कंप्यूटरों के बीच फाइलों को समन्वयित करता है, जो कि लोगों की नज़रों से सुरक्षित रूप से सुरक्षित रहता है। आपका डेटा केवल आपका डेटा है और आप यह चुनने के हकदार हैं कि इसे कहाँ संग्रहीत किया जाता है, क्या इसे किसी तीसरे पक्ष के साथ साझा किया जाता है, और इसे इंटरनेट पर कैसे प्रसारित किया जाता है।",
|
||||
"Syncthing is listening on the following network addresses for connection attempts from other devices:": "अन्य उपकरणों से कनेक्शन प्रयासों के लिए Syncthing निम्नलिखित नेटवर्क पतों पर सुन रहा है:",
|
||||
"Syncthing is not listening for connection attempts from other devices on any address. Only outgoing connections from this device may work.": "Syncthing किसी भी पते पर अन्य उपकरणों से कनेक्शन प्रयासों को नहीं सुन रहा है। इस उपकरण से केवल जावक कनेक्शन ही काम कर सकते हैं।",
|
||||
"Syncthing is restarting.": "Syncthing पुनः प्रारंभ हो रहा है।",
|
||||
"Syncthing is saving changes.": "Syncthing परिवर्तनों को सहेज रहा है।",
|
||||
"Syncthing is upgrading.": "Syncthing उन्नयन हो रहा है।",
|
||||
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing अब विकासकर्ता को क्रैश की स्वचालित रूप से रिपोर्ट करने का समर्थन करता है। यह सुविधा तयशुदा रूप से सक्षम है।",
|
||||
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "ऐसा लगता है कि Syncthing बंद है, या आपके इंटरनेट कनेक्शन में कोई समस्या है। पुनः प्रयास किया जा रहा है…",
|
||||
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "ऐसा लगता है कि Syncthing को आपके अनुरोध को संसाधित करने में समस्या आ रही है। यदि समस्या बनी रहती है तो कृपया पृष्ठ को ताज़ा करें या Syncthing को पुनरारंभ करें।",
|
||||
"TCP LAN": "TCP LAN",
|
||||
"TCP WAN": "TCP WAN",
|
||||
"Take me back": "मुझे वापस ले जाएं",
|
||||
"The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.": "GUI पता स्टार्टअप विकल्पों द्वारा अध्यारोहण किया गया है। अध्यारोहण लागू होने तक यहां परिवर्तन प्रभावी नहीं होंगे।",
|
||||
"The Syncthing Authors": "Syncthing के रचयिता",
|
||||
"The Syncthing admin interface is configured to allow remote access without a password.": "Syncthing व्यवस्थापक इंटरफ़ेस को पासवर्ड के बिना रिमोट पहुंच की अनुमति देने के लिए विन्यस्त किया गया है।",
|
||||
"The aggregated statistics are publicly available at the URL below.": "एकत्रित आंकड़े नीचे दिए गए URL पर सार्वजनिक रूप से उपलब्ध हैं।",
|
||||
"The cleanup interval cannot be blank.": "सफाई अंतराल रिक्त नहीं हो सकता।",
|
||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "विन्यास सहेजा गया है लेकिन सक्रिय नहीं किया गया है। नए विन्यास को सक्रिय करने के लिए Syncthing को पुनरारंभ करना होगा।",
|
||||
"The device ID cannot be blank.": "उपकरण ID रिक्त नहीं हो सकती।",
|
||||
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "यहां दर्ज की जाने वाली उपकरण ID अन्य उपकरण पर \"कार्रवाइयां > ID3 दिखाएं\" संवाद में पाई जा सकती है। रिक्त स्थान और डैश वैकल्पिक हैं (अनदेखा)।",
|
||||
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes, and app versions. If the reported data set is changed you will be prompted with this dialog again.": "कूटलेखित उपयोग रिपोर्ट प्रतिदिन भेजी जाती है। इसका उपयोग सामान्य प्लेटफ़ॉर्म, फोल्डर आकार और ऐप संस्करणों को ट्रैक करने के लिए किया जाता है। यदि रिपोर्ट किया गया डेटा सेट बदल दिया गया है तो आपको इस संवाद के साथ फिर से संकेत दिया जाएगा।",
|
||||
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "दर्ज की गई उपकरण ID वैध नहीं लगती। यह 52 या 56 वर्णमाला होनी चाहिए जिसमें अक्षर और संख्याएं हों, रिक्त स्थान और डैश वैकल्पिक हों।",
|
||||
"The folder ID cannot be blank.": "फोल्डर ID रिक्त नहीं हो सकती।",
|
||||
"The folder ID must be unique.": "फोल्डर ID अद्वितीय होनी चाहिए।",
|
||||
"The folder content on other devices will be overwritten to become identical with this device. Files not present here will be deleted on other devices.": "इस उपकरण के समान बनने के लिए अन्य उपकरण पर फोल्डर सामग्री को अधिलेखित कर दिया जाएगा। यहां मौजूद नहीं होने वाली फाइलें अन्य उपकरण पर मिटा दी जाएंगी।",
|
||||
"The folder content on this device will be overwritten to become identical with other devices. Files newly added here will be deleted.": "इस उपकरण पर फोल्डर सामग्री को अन्य उपकरण के समान बनाने के लिए अधिलेखित कर दिया जाएगा। यहां नई जोड़ी गई फाइलें मिटा दी जाएंगी।",
|
||||
"The folder path cannot be blank.": "फोल्डर पथ रिक्त नहीं हो सकता।",
|
||||
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "निम्नलिखित अंतरालों का उपयोग किया जाता है: पहले घंटे के लिए हर 30 सेकंड में एक संस्करण रखा जाता है, पहले दिन के लिए हर घंटे एक संस्करण रखा जाता है, पहले 30 दिनों के लिए हर दिन एक संस्करण रखा जाता है, अधिकतम आयु तक हर एक संस्करण रखा जाता है सप्ताह।",
|
||||
"The following items could not be synchronized.": "निम्नलिखित वस्तुएं समन्वयित नहीं किए जा सके।",
|
||||
"The following items were changed locally.": "निम्नलिखित वस्तुएं स्थानीय रूप से बदले गए थे।",
|
||||
"The following methods are used to discover other devices on the network and announce this device to be found by others:": "नेटवर्क पर अन्य उपकरणों को खोजने और इस उपकरण को दूसरों द्वारा पाए जाने की घोषणा करने के लिए निम्नलिखित विधियों का उपयोग किया जाता है:",
|
||||
"The following text will automatically be inserted into a new message.": "निम्नलिखित पाठ स्वचालित रूप से एक नए संदेश में डाला जाएगा।",
|
||||
"The following unexpected items were found.": "निम्नलिखित अप्रत्याशित वस्तुएं मिलीं।",
|
||||
"The interval must be a positive number of seconds.": "अंतराल सेकंड की सकारात्मक संख्या होनी चाहिए।",
|
||||
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "संस्करण निर्देशिका में सफाई करने की अंतराल, सेकंड में। आवधिक सफाई को अक्षम करने के लिए शून्य।",
|
||||
"The maximum age must be a number and cannot be blank.": "अधिकतम आयु एक संख्या होनी चाहिए और रिक्त नहीं हो सकती।",
|
||||
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "किसी संस्करण को रखने का अधिकतम समय (दिनों में, संस्करणों को हमेशा के लिए रखने के लिए 0 पर निर्धारित करें)।",
|
||||
"The number of connections must be a non-negative number.": "कनेक्शन की संख्या एक गैर-नकारात्मक संख्या होनी चाहिए।",
|
||||
"The number of days must be a number and cannot be blank.": "दिनों की संख्या एक संख्या होनी चाहिए और रिक्त नहीं हो सकती।",
|
||||
"The number of days to keep files in the trash can. Zero means forever.": "फाइलों को रद्दी में रखने के दिनों की संख्या। शून्य का अर्थ है सदैव।",
|
||||
"The number of old versions to keep, per file.": "प्रति फाइल रखने के लिए पुराने संस्करणों की संख्या।",
|
||||
"The number of versions must be a number and cannot be blank.": "संस्करणों की संख्या एक संख्या होनी चाहिए और रिक्त नहीं हो सकती।",
|
||||
"The path cannot be blank.": "पथ रिक्त नहीं हो सकता।",
|
||||
"The rate limit is applied to the accumulated traffic of all connections to this device.": "दर सीमा इस उपकरण के सभी कनेक्शनों के संचित ट्रैफिक पर लागू होती है।",
|
||||
"The rate limit must be a non-negative number (0: no limit)": "दर सीमा एक गैर-ऋणात्मक संख्या होनी चाहिए (0: कोई सीमा नहीं)",
|
||||
"The remote device has not accepted sharing this folder.": "रिमोट उपकरण ने इस फोल्डर को साझा करना स्वीकार नहीं किया है।",
|
||||
"The remote device has paused this folder.": "रिमोट उपकरण ने इस फोल्डर को रोक दिया है।",
|
||||
"The rescan interval must be a non-negative number of seconds.": "पुन: स्कैन अंतराल सेकंड की गैर-नकारात्मक संख्या होनी चाहिए।",
|
||||
"There are no devices to share this folder with.": "इस फोल्डर को साझा करने के लिए कोई उपकरण नहीं है।",
|
||||
"There are no file versions to restore.": "पुनर्स्थापित करने के लिए कोई फाइल संस्करण नहीं हैं।",
|
||||
"There are no folders to share with this device.": "इस उपकरण के साथ साझा करने के लिए कोई फोल्डर नहीं हैं।",
|
||||
"They are retried automatically and will be synced when the error is resolved.": "वे स्वचालित रूप से पुनः प्रयास किए जाते हैं और त्रुटि हल होने पर समन्वयित हो जाएंगे।",
|
||||
"This Device": "यह उपकरण",
|
||||
"This Month": "इस महीने",
|
||||
"This can easily give hackers access to read and change any files on your computer.": "इससे हैकर्स को आसानी से आपके कंप्यूटर पर किसी भी फाइल को पढ़ने और बदलने की सुविधा मिल सकती है।",
|
||||
"This device cannot automatically discover other devices or announce its own address to be found by others. Only devices with statically configured addresses can connect.": "यह उपकरण स्वचालित रूप से अन्य उपकरणों की खोज नहीं कर सकता है या दूसरों द्वारा ढूंढे जाने के लिए अपने स्वयं के पते की घोषणा नहीं कर सकता है। केवल स्थिर रूप से विन्यस्त पते वाले उपकरण ही जुड़ सकते हैं।",
|
||||
"This is a major version upgrade.": "यह प्रमुख संस्करण उन्नयन है।",
|
||||
"This setting controls the free space required on the home (i.e., index database) disk.": "यह सेटिंग होम (यानी, अनुक्रमणिका डेटाबेस) डिस्क पर आवश्यक खाली स्थान को नियंत्रित करती है।",
|
||||
"Time": "समय",
|
||||
"Time the item was last modified": "वस्तु को अंतिम बार संशोधित करने का समय",
|
||||
"To connect with the Syncthing device named \"{%devicename%}\", add a new remote device on your end with this ID:": "\"{{devicename}}\" नामक Syncthing उपकरण से जुड़ने के लिए, इस ID के साथ अपनी ओर से एक नया रिमोट उपकरण जोड़ें:",
|
||||
"To permit a rule, have the checkbox checked. To deny a rule, leave it unchecked.": "किसी नियम की अनुमति देने के लिए, चेकबॉक्स चेक करें। किसी नियम को अस्वीकार करने के लिए उसे अनियंत्रित छोड़ दें।",
|
||||
"Today": "आज",
|
||||
"Trash Can": "रद्दी",
|
||||
"Trash Can File Versioning": "रद्दी फाइल संस्करण",
|
||||
"Type": "प्रकार",
|
||||
"UNIX Permissions": "UNIX अनुमतियां",
|
||||
"Unavailable": "अनुपलब्ध",
|
||||
"Unavailable/Disabled by administrator or maintainer": "व्यवस्थापक या अनुरक्षक द्वारा अनुपलब्ध/अक्षम",
|
||||
"Undecided (will prompt)": "अनिर्णीत (संकेत देगा)",
|
||||
"Unexpected Items": "अप्रत्याशित वस्तुएं",
|
||||
"Unexpected items have been found in this folder.": "इस फोल्डर में अप्रत्याशित वस्तुएं मिली हैं।",
|
||||
"Unignore": "अनदेखा न करें",
|
||||
"Unknown": "अज्ञात",
|
||||
"Unshared": "अनसाझा",
|
||||
"Unshared Devices": "अनसाझा उपकरण",
|
||||
"Unshared Folders": "अनसाझा फोल्डर",
|
||||
"Untrusted": "अविश्वस्त",
|
||||
"Up to Date": "अद्यतित है",
|
||||
"Updated {%file%}": "{{file}} अद्यतित",
|
||||
"Upgrade": "उन्नयन",
|
||||
"Upgrade To {%version%}": "{{version}} पर उन्नयन करें",
|
||||
"Upgrading": "उन्नयन किया जा रहा है",
|
||||
"Upload Rate": "अपलोड दर",
|
||||
"Uptime": "सक्रिय-अवधि",
|
||||
"Usage reporting is always enabled for candidate releases.": "उम्मीदवार की रिलीज़ के लिए उपयोग रिपोर्टिंग हमेशा सक्षम होती है।",
|
||||
"Use HTTPS for GUI": "GUI के लिए HTTPS का उपयोग करें",
|
||||
"Use notifications from the filesystem to detect changed items.": "परिवर्तित वस्तुओं का पता लगाने के लिए फाइल सिस्टम से सूचनाओं का उपयोग करें।",
|
||||
"User": "उपयोक्ता",
|
||||
"User Home": "उपयोक्ता होम",
|
||||
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "GUI प्रमाणीकरण के लिए उपयोक्तानाम/पासवर्ड निर्धारित नहीं किया गया है। कृपया इसे स्थापित करने पर विचार करें।",
|
||||
"Using a QUIC connection over LAN": "LAN पर QUIC कनेक्शन का उपयोग किया जा रहा है",
|
||||
"Using a QUIC connection over WAN": "WAN पर QUIC कनेक्शन का उपयोग किया जा रहा है",
|
||||
"Using a direct TCP connection over LAN": "LAN पर सीधे TCP कनेक्शन का उपयोग किया जा रहा है",
|
||||
"Using a direct TCP connection over WAN": "WAN पर सीधे TCP कनेक्शन का उपयोग किया जा रहा है",
|
||||
"Version": "संस्करण",
|
||||
"Versions": "संस्करण",
|
||||
"Versions Path": "संस्करण पथ",
|
||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "यदि संस्करण अधिकतम आयु से अधिक पुराने हैं या किसी अंतराल में अनुमत फाइलों की संख्या से अधिक हैं तो वे स्वचालित रूप से मिटा दिए जाते हैं।",
|
||||
"Waiting to Clean": "सफाई की प्रतीक्षा में",
|
||||
"Waiting to Scan": "स्कैन की प्रतीक्षा में",
|
||||
"Waiting to Sync": "समन्वयन की प्रतीक्षा में",
|
||||
"Warning": "चेतावनी",
|
||||
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "चेतावनी, यह पथ मौजूदा फोल्डर \"{{otherFolder}}\" की मूल निर्देशिका है।",
|
||||
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "चेतावनी, यह पथ मौजूदा फोल्डर \"{{otherFolderLabel}}\" ({{otherFolder}}) की मूल निर्देशिका है।",
|
||||
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "चेतावनी, यह पथ मौजूदा फोल्डर \"{{otherFolder}}\" की एक उपनिर्देशिका है।",
|
||||
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "चेतावनी, यह पथ मौजूदा फोल्डर \"{{otherFolderLabel}}\" ({{otherFolder}}) की एक उपनिर्देशिका है।",
|
||||
"Warning: If you are using an external watcher like {%syncthingInotify%}, you should make sure it is deactivated.": "चेतावनी: यदि आप {{syncthingInotify}} जैसे बाहरी वॉचर का उपयोग कर रहे हैं, तो आपको यह सुनिश्चित करना चाहिए कि यह निष्क्रिय है।",
|
||||
"Watch for Changes": "परिवर्तनों पर नजर रखें",
|
||||
"Watching for Changes": "परिवर्तनों पर नजर रख रहे हैं",
|
||||
"Watching for changes discovers most changes without periodic scanning.": "परिवर्तनों पर नज़र रखने से समय-समय पर स्कैनिंग के बिना अधिकांश परिवर्तनों का पता चलता है।",
|
||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "नया उपकरण जोड़ते समय इस बात का ध्यान रखें कि यह उपकरण दूसरी तरफ भी जुड़ा होना चाहिए।",
|
||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "नया फोल्डर जोड़ते समय, ध्यान रखें कि फोल्डर ID का उपयोग उपकरणों के बीच फोल्डरों को एक साथ जोड़ने के लिए किया जाता है। वे केस संवेदनशील हैं और सभी उपकरणों के बीच बिल्कुल मेल खाना चाहिए।",
|
||||
"When set to more than one on both devices, Syncthing will attempt to establish multiple concurrent connections. If the values differ, the highest will be used. Set to zero to let Syncthing decide.": "जब दोनों उपकरणों पर एक से अधिक पर तय किया जाता है, तो Syncthing एकाधिक समवर्ती कनेक्शन स्थापित करने का प्रयास करेगा। यदि मान भिन्न हैं, तो उच्चतम का उपयोग किया जाएगा। Syncthing को निर्णय लेने देने के लिए शून्य पर निर्धारित करें।",
|
||||
"Yes": "हां",
|
||||
"Yesterday": "बिता कल",
|
||||
"You can also copy and paste the text into a new message manually.": "आप पाठ को मैन्युअल रूप से नए संदेश में कॉपी और पेस्ट भी कर सकते हैं।",
|
||||
"You can also select one of these nearby devices:": "आप इन निकटवर्ती उपकरणों में से एक का चयन भी कर सकते हैं:",
|
||||
"You can change your choice at any time in the Settings dialog.": "आप सेटिंग संवाद में किसी भी समय अपनी पसंद बदल सकते हैं।",
|
||||
"You can read more about the two release channels at the link below.": "आप नीचे दिए गए लिंक पर दो रिलीज़ चैनलों के बारे में अधिक पढ़ सकते हैं।",
|
||||
"You have no ignored devices.": "आपके पास कोई उपेक्षित उपकरण नहीं है।",
|
||||
"You have no ignored folders.": "आपके पास कोई उपेक्षित फोल्डर नहीं है।",
|
||||
"You have unsaved changes. Do you really want to discard them?": "आपके पास सहेजे नहीं गए परिवर्तन हैं। क्या आप सचमुच उन्हें त्यागना चाहते हैं?",
|
||||
"You must keep at least one version.": "आपको कम से कम एक संस्करण रखना होगा।",
|
||||
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "आपको \"{{receiveEncrypted}}\" फोल्डर में कभी भी स्थानीय रूप से कुछ भी जोड़ना या बदलना नहीं चाहिए।",
|
||||
"Your SMS app should open to let you choose the recipient and send it from your own number.": "आपका SMS ऐप खुल जाना चाहिए ताकि आप प्राप्तकर्ता का चयन कर सकें और इसे अपने नंबर से भेज सकें।",
|
||||
"Your email app should open to let you choose the recipient and send it from your own address.": "आपका ईमेल ऐप खुल जाना चाहिए ताकि आप प्राप्तकर्ता का चयन कर सकें और इसे अपने पते से भेज सकें।",
|
||||
"days": "दिन",
|
||||
"deleted": "मिटाया गया",
|
||||
"deny": "अस्वीकारें",
|
||||
"directories": "निर्देशिकाएं",
|
||||
"file": "फाइल",
|
||||
"files": "फाइलें",
|
||||
"folder": "फोल्डर",
|
||||
"full documentation": "पूर्ण दस्तावेज़ीकरण",
|
||||
"items": "वस्तुएं",
|
||||
"modified": "संशोधित",
|
||||
"permit": "अनुमति",
|
||||
"seconds": "सेकंड",
|
||||
"theme": {
|
||||
"name": {
|
||||
"black": "काली",
|
||||
"dark": "गहरी",
|
||||
"default": "तयशुदा",
|
||||
"light": "हल्की"
|
||||
}
|
||||
},
|
||||
"unknown device": "अज्ञात उपकरण",
|
||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} फोल्डर \"{{folder}}\" साझा करना चाहता है।",
|
||||
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} फोल्डर \"{{folderlabel}}\" ({{folder}}) साझा करना चाहता है।",
|
||||
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} इस उपकरण को दोबारा पेश कर सकता है।"
|
||||
}
|
||||
@@ -158,7 +158,7 @@
|
||||
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "La connessione a server IPv6 fallisce se non c'è connettività IPv6.",
|
||||
"File Pull Order": "Ordine Prelievo File",
|
||||
"File Versioning": "Controllo Versione File",
|
||||
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "I file sono spostati nella certella .stversions quando vengono sostituiti o cancellati da Syncthing.",
|
||||
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "I file sono spostati nella cartella .stversions quando vengono sostituiti o cancellati da Syncthing.",
|
||||
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "I file sostituiti o eliminati da Syncthing vengono datati e spostati in una cartella .stversions.",
|
||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "I file sono protetti dalle modifiche effettuate negli altri dispositivi, ma le modifiche effettuate in questo dispositivo verranno inviate anche al resto del cluster.",
|
||||
"Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.": "I file sono sincronizzati dal cluster, ma eventuali modifiche apportate localmente non verranno inviate ad altri dispositivi.",
|
||||
@@ -386,6 +386,7 @@
|
||||
"Staggered File Versioning": "Controllo Versione Cadenzato",
|
||||
"Start Browser": "Avvia Browser",
|
||||
"Statistics": "Statistiche",
|
||||
"Stay logged in": "Resta connesso",
|
||||
"Stopped": "Fermato",
|
||||
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Memorizza e sincronizza solo i dati crittografati. Le cartelle su tutti i dispositivi collegati devono essere configurate con la stessa password o essere del tipo \"{{receiveEncrypted}}\".",
|
||||
"Subject:": "Oggetto:",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"A device with that ID is already added.": "이 식별자를 가진 기기가 이미 추가되어 있습니다.",
|
||||
"A negative number of days doesn't make sense.": "일수를 음수로 입력하는 것은 말이 되지 않습니다.",
|
||||
"A negative number of days doesn't make sense.": "일수를 음수로 입력하는 것은 올바르지 않습니다.",
|
||||
"A new major version may not be compatible with previous versions.": "새로운 주요 버전이 이전 버전들과 호환되지 않을 수 있습니다.",
|
||||
"API Key": "API 키",
|
||||
"About": "정보",
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Išorinė komanda apdoroja versijų valdymą. Ji turi pašalinti failą iš bendrinamo aplanko. Jei kelyje į programą yra tarpų, jie turėtų būti imami į kabutes.",
|
||||
"Anonymous Usage Reporting": "Anoniminė naudojimo ataskaita",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "Anoniminės naudojimo ataskaitos formatas pasikeitė. Ar norėtumėte pereiti prie naujojo formato?",
|
||||
"Applied to LAN": "Pritaikyta vietiniam tinklui (LAN)",
|
||||
"Apply": "Taikyti",
|
||||
"Are you sure you want to override all remote changes?": "Ar tikrai norite nustelbti visus nuotolinius pakeitimus?",
|
||||
"Are you sure you want to permanently delete all these files?": "Ar tikrai norite visam laikui ištrinti visus šiuos failus?",
|
||||
@@ -34,30 +35,32 @@
|
||||
"Are you sure you want to restore {%count%} files?": "Ar tikrai norite atkurti {{count}} failų(-us)?",
|
||||
"Are you sure you want to revert all local changes?": "Ar tikrai norite sugrąžinti visus vietinius pakeitimus?",
|
||||
"Are you sure you want to upgrade?": "Ar tikrai norite naujinti?",
|
||||
"Authentication Required": "Reikia nustatyti tapatybę",
|
||||
"Authors": "Autoriai",
|
||||
"Auto Accept": "Automatiškai priimti",
|
||||
"Automatic Crash Reporting": "Automatinės ataskaitos apie strigtis",
|
||||
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Automatiniai atnaujinimai dabar siūlo pasirinkimą tarp stabilių versijų ir kandidatinių versijų.",
|
||||
"Automatic upgrades": "Automatiniai atnaujinimai",
|
||||
"Automatic upgrades are always enabled for candidate releases.": "Automatiniai naujinimai kandidatinėms versijoms visada yra įjungti.",
|
||||
"Automatically create or share folders that this device advertises at the default path.": "Automatiškai sukurti ar dalintis aplankais, kuriuos šis įrenginys skelbia numatytajame kelyje.",
|
||||
"Automatically create or share folders that this device advertises at the default path.": "Automatiškai sukurti ar bendrinti aplankus, kuriuos šis įrenginys skelbia numatytajame kelyje.",
|
||||
"Available debug logging facilities:": "Prieinamos derinimo registravimo priemonės:",
|
||||
"Be careful!": "Būkite atsargūs!",
|
||||
"Bugs": "Klaidos",
|
||||
"Cancel": "Atsisakyti",
|
||||
"Changelog": "Pasikeitimai",
|
||||
"Changelog": "Keitinių žurnalas",
|
||||
"Clean out after": "Išvalyti po",
|
||||
"Cleanup Interval": "Išvalymo intervalas",
|
||||
"Click to see full identification string and QR code.": "Spustelėkite norint pamatyti visą identifikavimo eilutę ir QR kodą.",
|
||||
"Click to see full identification string and QR code.": "Spustelėkite, kad pamatytumėte visą identifikavimo eilutę ir QR kodą.",
|
||||
"Close": "Užverti",
|
||||
"Command": "Komanda",
|
||||
"Comment, when used at the start of a line": "Komentaras naudojamas naujoje eilutėje",
|
||||
"Compression": "Kompresija",
|
||||
"Compression": "Glaudinimas",
|
||||
"Configuration Directory": "Konfigūracijos katalogas",
|
||||
"Configuration File": "Konfigūracijos failas",
|
||||
"Configured": "Sukonfigūruotas",
|
||||
"Connected (Unused)": "Prisijungęs (Nenaudojamas)",
|
||||
"Connection Error": "Susijungimo klaida",
|
||||
"Connection Error": "Ryšio klaida",
|
||||
"Connection Management": "Ryšių valdymas",
|
||||
"Connection Type": "Ryšio tipas",
|
||||
"Connections": "Ryšiai",
|
||||
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Pastoviai stebėti pakeitimus dabar galima Syncthing viduje. Tai aptiks pakeitimus jūsų diske ir paleis nuskaitymą tik modifikuotuose keliuose. Pranašumas yra tas, kad pakeitimai sklis greičiau ir reikės mažiau pilnų nuskaitymų.",
|
||||
@@ -67,6 +70,7 @@
|
||||
"Copy": "Kopijuoti",
|
||||
"Copy failed! Try to select and copy manually.": "Nepavyko nukopijuoti! Pabandykite pažymėti ir nukopijuoti rankiniu būdu.",
|
||||
"Currently Shared With Devices": "Šiuo metu bendrinama su įrenginiais",
|
||||
"Custom Range": "Tinkintas rėžis",
|
||||
"Danger!": "Pavojus!",
|
||||
"Database Location": "Duomenų bazės vieta",
|
||||
"Debugging Facilities": "Derinimo priemonės",
|
||||
@@ -78,12 +82,13 @@
|
||||
"Delete Unexpected Items": "Ištrinti netikėtus elementus",
|
||||
"Deleted {%file%}": "Ištrintas {{file}}",
|
||||
"Deselect All": "Nuimti žymėjimą nuo visų",
|
||||
"Deselect devices to stop sharing this folder with.": "Panaikinti įrenginių pasirinkimą, kad su jais būtų nustota bendrinti šį aplanką. ",
|
||||
"Deselect devices to stop sharing this folder with.": "Nuimkite žymėjimą nuo įrenginių norėdami nustoti su jais bendrinti šį aplanką.",
|
||||
"Deselect folders to stop sharing with this device.": "Nuimkite žymėjimą nuo aplankų norėdami nustoti juos bendinti su šiuo įrenginiu.",
|
||||
"Device": "Įrenginys",
|
||||
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Įrenginys \"{{name}}\" ({{device}} {{address}}) nori prisijungti. Pridėti naują įrenginį?",
|
||||
"Device Certificate": "Įrenginio liudijimas",
|
||||
"Device ID": "Įrenginio ID",
|
||||
"Device Identification": "Įrenginio identifikacija",
|
||||
"Device Identification": "Įrenginio identifikavimas",
|
||||
"Device Name": "Įrenginio pavadinimas",
|
||||
"Device Status": "Įrenginio būsena",
|
||||
"Device is untrusted, enter encryption password": "Įrenginys yra nepatikimas, įveskite šifravimo slaptažodį",
|
||||
@@ -101,17 +106,18 @@
|
||||
"Disconnected (Inactive)": "Atsijungęs (Pasyvus)",
|
||||
"Disconnected (Unused)": "Atsijungęs (Nenaudojamas)",
|
||||
"Discovered": "Atrastas",
|
||||
"Discovery": "Lokacija",
|
||||
"Discovery Failures": "Matomumo nesėkmės",
|
||||
"Discovery": "Atradimas",
|
||||
"Discovery Failures": "Atradimo nesėkmės",
|
||||
"Discovery Status": "Atradimo būsena",
|
||||
"Dismiss": "Atmesti",
|
||||
"Do not restore": "Neatkurti",
|
||||
"Do not restore all": "Neatkurti visus",
|
||||
"Do you want to enable watching for changes for all your folders?": "Ar norite įjungti pakeitimų stebėjimą visiems savo aplankams?",
|
||||
"Documentation": "Aprašymas",
|
||||
"Download Rate": "Parsisiuntimo greitis",
|
||||
"Downloaded": "Parsisiųstas",
|
||||
"Downloading": "Siunčiama",
|
||||
"Edit": "Redaguoti",
|
||||
"Download Rate": "Atsiuntimo greitis",
|
||||
"Downloaded": "Atsiųsta",
|
||||
"Downloading": "Atsiunčiama",
|
||||
"Edit": "Taisyti",
|
||||
"Edit Device": "Taisyti įrenginį",
|
||||
"Edit Device Defaults": "Taisyti įrenginio numatytąsias reikšmes",
|
||||
"Edit Folder": "Taisyti aplanką",
|
||||
@@ -123,13 +129,16 @@
|
||||
"Enabled": "Įjungta",
|
||||
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Įveskite neneigiamąjį skaičių (pvz., \"2.35\") ir pasirinkite įtaisą. Procentai yra skaičiuojami kaip viso disko dydžio dalis.",
|
||||
"Enter a non-privileged port number (1024 - 65535).": "Įveskite neprivilegijuoto prievado numerį (1024 - 65535).",
|
||||
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Įveskite kableliais atskirtus (\"tcp://ip:prievadas\", \"tcp://serveris:prievadas\") adresus arba \"dynamic\", kad atliktumėte automatinį adresų atlikimą.",
|
||||
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Įveskite kableliais atskirtus („tcp://ip:prievadas“, „tcp://serveris:prievadas“) adresus arba „dynamic“, kad atliktumėte automatinį adresų atradimą.",
|
||||
"Enter ignore patterns, one per line.": "Suveskite nepaisomus šablonus, kiekvieną naujoje eilutėje.",
|
||||
"Enter up to three octal digits.": "Įveskite iki trijų aštuntainių skaitmenų.",
|
||||
"Error": "Klaida",
|
||||
"Extended Attributes": "Išplėstiniai požymiai",
|
||||
"Extended Attributes Filter": "Išplėstinių požymių filtras",
|
||||
"External File Versioning": "Išorinis versijų valdymas",
|
||||
"Failed Items": "Nepavykę siuntimai",
|
||||
"Failed to load file versions.": "Nepavyko įkelti failo versijų.",
|
||||
"Failed to load ignore patterns.": "Nepavyko įkelti nepaisymo šablonų.",
|
||||
"Failed to setup, retrying": "Nepavyko nustatyti, bandoma iš naujo",
|
||||
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Nesėkmė prisijungti prie IPv6 serverių yra tikėtina, jei nėra IPv6 ryšio.",
|
||||
"File Pull Order": "Failų siuntimo tvarka",
|
||||
@@ -147,25 +156,30 @@
|
||||
"Folder Path": "Kelias iki aplanko",
|
||||
"Folder Status": "Aplanko būsena",
|
||||
"Folder Type": "Aplanko tipas",
|
||||
"Folder type \"{%receiveEncrypted%}\" can only be set when adding a new folder.": "Aplanko tipas „{{receiveEncrypted}}“ gali būti nustatytas tik pridedant naują aplanką.",
|
||||
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Aplanko tipas „{{receiveEncrypted}}“ negali būti pakeistas po to, kai aplankas pridėtas. Turite pašalinti aplanką, ištrinti arba iššifruoti diske esančius duomenis ir vėl pridėti aplanką.",
|
||||
"Folders": "Aplankai",
|
||||
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Pradėjus stebėti pakeitimus, šiuose aplankuose atsirado klaidų. Kiekvieną minutę bus bandoma iš naujo, taigi, klaidos gali išnykti. Jeigu jos neišnyks, pabandykite išspręsti slypinčią problemą, o jeigu neįstengiate, paprašykite pagalbos.",
|
||||
"Forever": "Amžinai",
|
||||
"Full Rescan Interval (s)": "Pilno nuskaitymo iš naujo intervalas (s)",
|
||||
"GUI": "Valdymo skydelis",
|
||||
"GUI / API HTTPS Certificate": "",
|
||||
"GUI Authentication Password": "Valdymo skydelio slaptažodis",
|
||||
"GUI Authentication User": "Valdymo skydelio vartotojo vardas",
|
||||
"GUI Authentication: Set User and Password": "Valdymo skydelio tapatybės nustatymas: Nustatyti vartotoją ir slaptažodį",
|
||||
"GUI Authentication User": "Valdymo skydelio naudotojo vardas",
|
||||
"GUI Authentication: Set User and Password": "Valdymo skydelio tapatybės nustatymas: Nustatyti naudotoją ir slaptažodį",
|
||||
"GUI Listen Address": "Valdymo skydelio adresas",
|
||||
"GUI Theme": "Valdymo skydelio apipavidalinimas",
|
||||
"General": "Bendra",
|
||||
"Generate": "Sukurti",
|
||||
"Global Discovery": "Visuotinis matomumas",
|
||||
"Global Discovery Servers": "Visuotinio matomumo serveriai",
|
||||
"Global Discovery": "Visuotinis atradimas",
|
||||
"Global Discovery Servers": "Visuotinio atradimo serveriai",
|
||||
"Global State": "Visuotinė būsena",
|
||||
"Help": "Pagalba",
|
||||
"Home page": "Pagrindinis puslapis",
|
||||
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Vis dėlto, jūsų esami nustatymai nurodo, kad jūs, greičiausiai, nenorite turėti jas įjungtas. Mes jums išjungėme automatines ataskaitas apie strigtis.",
|
||||
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Jei norite neleisti kitiems šio kompiuterio vartotojams gauti prieigą prie Syncthing, o per ją, prieigą prie jūsų failų, tuomet apsvarstykite galimybę nusistatyti tapatybės nustatymą.",
|
||||
"Identification": "Identifikavimas",
|
||||
"If untrusted, enter encryption password": "Jei nepatikimas, įveskite šifravimo slaptažodį",
|
||||
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Jei norite neleisti kitiems šio kompiuterio naudotojams gauti prieigą prie Syncthing, o per ją, prieigą prie jūsų failų, tuomet apsvarstykite galimybę nusistatyti tapatybės nustatymą.",
|
||||
"Ignore": "Nepaisyti",
|
||||
"Ignore Patterns": "Nepaisyti šablonų",
|
||||
"Ignore Permissions": "Nepaisyti failų prieigos leidimų",
|
||||
@@ -175,12 +189,13 @@
|
||||
"Included Software": "Įtraukta programinė įranga",
|
||||
"Incoming Rate Limit (KiB/s)": "Atsiunčiamo srauto maksimalus greitis (KiB/s)",
|
||||
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Neteisinga konfigūracija gali pažeisti jūsų aplankų turinį ir padaryti Syncthing neoperuotina.",
|
||||
"Incorrect user name or password.": "Neteisingas naudotojo vardas ar slaptažodis.",
|
||||
"Introduced By": "Supažindė",
|
||||
"Introducer": "Supažindintojas",
|
||||
"Inversion of the given condition (i.e. do not exclude)": "Apversti sąlygas (pvz.: nenustoti naudoti)",
|
||||
"Keep Versions": "Saugojamų versijų kiekis",
|
||||
"LDAP": "LDAP",
|
||||
"Largest First": "Didžiausi pirmiau",
|
||||
"Largest First": "Pirma didžiausi",
|
||||
"Last Scan": "Paskutinis nuskaitymas",
|
||||
"Last seen": "Paskutinį kartą matytas",
|
||||
"Latest Change": "Paskutinis pakeitimas",
|
||||
@@ -191,17 +206,23 @@
|
||||
"Loading data...": "Įkeliami duomenys...",
|
||||
"Loading...": "Įkeliama...",
|
||||
"Local Additions": "Vietiniai pridėjimai",
|
||||
"Local Discovery": "Vietinis matomumas",
|
||||
"Local Discovery": "Vietinis atradimas",
|
||||
"Local State": "Vietinė būsena",
|
||||
"Local State (Total)": "Vietinė būsena (Bendrai)",
|
||||
"Locally Changed Items": "Vietoje pakeisti elementai",
|
||||
"Log": "Žurnalas",
|
||||
"Log File": "Žurnalo failas",
|
||||
"Log In": "Prisijungti",
|
||||
"Log Out": "Atsijungti",
|
||||
"Log in to see paths information.": "Prisijunkite norėdami matyti informaciją apie kelius.",
|
||||
"Log in to see version information.": "Prisijunkite norėdami matyti informaciją apie versijas.",
|
||||
"Log tailing paused. Scroll to the bottom to continue.": "Žurnalo galas pristabdytas. Slinkite į apačią, norėdami tęsti.",
|
||||
"Login failed, see Syncthing logs for details.": "Nepavyko prisijungti, išsamesnei informacijai žiūrėkite Syncthing žurnalus.",
|
||||
"Logs": "Žurnalai",
|
||||
"Major Upgrade": "Stambus atnaujinimas",
|
||||
"Mass actions": "Masiniai veiksmai",
|
||||
"Maximum Age": "Maksimalus amžius",
|
||||
"Metadata Only": "Metaduomenims",
|
||||
"Metadata Only": "Tik metaduomenys",
|
||||
"Minimum Free Disk Space": "Minimum laisvos vietos diske",
|
||||
"Mod. Device": "Mod. įrenginys",
|
||||
"Mod. Time": "Mod. laikas",
|
||||
@@ -213,15 +234,17 @@
|
||||
"Never": "Niekada",
|
||||
"New Device": "Naujas įrenginys",
|
||||
"New Folder": "Naujas aplankas",
|
||||
"Newest First": "Naujausi pirmiau",
|
||||
"Newest First": "Pirma naujausi",
|
||||
"No": "Ne",
|
||||
"No File Versioning": "Nėra versijų valdymo",
|
||||
"No files will be deleted as a result of this operation.": "Šios operacijos rezultate nebus pašalinti jokie failai.",
|
||||
"No upgrades": "Be atnaujinimų",
|
||||
"Not shared": "Nebendrinama",
|
||||
"Notice": "Įspėjimas",
|
||||
"Number of Connections": "Ryšių skaičius",
|
||||
"OK": "Gerai",
|
||||
"Off": "Netaikoma",
|
||||
"Oldest First": "Seniausi pirmiau",
|
||||
"Oldest First": "Pirma seniausi",
|
||||
"Optional descriptive label for the folder. Can be different on each device.": "Nebūtina aprašomoji aplanko etiketė. Kiekviename įrenginyje gali būti skirtinga.",
|
||||
"Options": "Parametrai",
|
||||
"Out of Sync": "Išsisinchronizavę",
|
||||
@@ -229,9 +252,10 @@
|
||||
"Outgoing Rate Limit (KiB/s)": "Išsiunčiamo srauto maksimalus greitis (KiB/s)",
|
||||
"Override": "Nustelbti",
|
||||
"Override Changes": "Perrašyti pakeitimus",
|
||||
"Password": "Slaptažodis",
|
||||
"Path": "Kelias",
|
||||
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Kelias iki aplanko šiame kompiuteryje. Bus sukurtas, jei neegzistuoja. Tildės simbolis (~) gali būti naudojamas kaip trumpinys",
|
||||
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Kelias, kur bus saugomos versijos (palikite tuščią numatytajam .stversions katalogui bendrinamame aplanke).",
|
||||
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Kelias, kuriame bus saugomos versijos (palikite tuščią numatytajam .stversions katalogui bendrinamame aplanke).",
|
||||
"Paths": "Keliai",
|
||||
"Pause": "Pristabdyti",
|
||||
"Pause All": "Pristabdyti visus",
|
||||
@@ -242,7 +266,7 @@
|
||||
"Periodic scanning at given interval and enabled watching for changes": "Periodinis nuskaitymas nurodytu intervalu ir įjungtas pakeitimų stebėjimas",
|
||||
"Periodic scanning at given interval and failed setting up watching for changes, retrying every 1m:": "Periodinis nuskaitymas nurodytu intervalu ir nepavykęs nustatyti pakeitimų stebėjimas, bandoma iš naujo kas 1 min.:",
|
||||
"Please consult the release notes before performing a major upgrade.": "Peržvelkite laidos informaciją prieš atlikdami stambų atnaujinimą.",
|
||||
"Please set a GUI Authentication User and Password in the Settings dialog.": "Prašome nustatymų dialoge nustatyti valdymo skydelio vartotojo vardą ir slaptažodį.",
|
||||
"Please set a GUI Authentication User and Password in the Settings dialog.": "Prašome nustatymų dialoge nustatyti valdymo skydelio naudotojo vardą ir slaptažodį.",
|
||||
"Please wait": "Prašome palaukti",
|
||||
"Prefix indicating that the file can be deleted if preventing directory removal": "Priešdelis, nurodantis, kad failas gali būti ištrintas tuo atveju, jei neleidžia šalinti katalogo",
|
||||
"Prefix indicating that the pattern should be matched without case sensitivity": "Priešdelis, nurodantis, kad šablonas turėtų būti atitiktas neskiriant raidžių dydžio",
|
||||
@@ -254,6 +278,7 @@
|
||||
"QUIC WAN": "QUIC WAN (platusis tinklas)",
|
||||
"Quick guide to supported patterns": "Trumpas leistinų šablonų vadovas",
|
||||
"Random": "Atsitiktinė",
|
||||
"Receive Encrypted": "Gauti šifruotą",
|
||||
"Receive Only": "Tik gauti",
|
||||
"Received data is already encrypted": "Gauti duomenys jau yra šifruoti",
|
||||
"Recent Changes": "Paskiausi keitimai",
|
||||
@@ -268,9 +293,9 @@
|
||||
"Rescan": "Nuskaityti iš naujo",
|
||||
"Rescan All": "Nuskaityti visus aplankus",
|
||||
"Rescans": "Nuskaitymai",
|
||||
"Restart": "Perleisti",
|
||||
"Restart Needed": "Reikalingas perleidimas",
|
||||
"Restarting": "Persileidžia",
|
||||
"Restart": "Paleisti iš naujo",
|
||||
"Restart Needed": "Reikia paleisti iš naujo",
|
||||
"Restarting": "Paleidžiama iš naujo",
|
||||
"Restore": "Atkurti",
|
||||
"Restore Versions": "Atkurti versijas",
|
||||
"Resume": "Pratęsti",
|
||||
@@ -279,15 +304,18 @@
|
||||
"Revert": "Sugrąžinti",
|
||||
"Revert Local Changes": "Sugrąžinti vietinius pakeitimus",
|
||||
"Save": "Išsaugoti",
|
||||
"Saving changes": "Įrašomi pakeitimai",
|
||||
"Scan Time Remaining": "Likęs nuskaitymo laikas",
|
||||
"Scanning": "Skenuojama",
|
||||
"See external versioning help for supported templated command line parameters.": "Palaikomiems šabloniniams komandų eilutės parametrams, žiūrėkite išorinį versijų valdymo žinyną.",
|
||||
"Select All": "Žymėti visus",
|
||||
"Select a version": "Pasirinkti versiją",
|
||||
"Select additional devices to share this folder with.": "Pasirinkti papildomus įrenginius, su kuriais bendrinti šį aplanką.",
|
||||
"Select additional devices to share this folder with.": "Pažymėkite papildomus įrenginius, su kuriais bendrinti šį aplanką.",
|
||||
"Select additional folders to share with this device.": "Pažymėkite papildomus aplankus, kuriuos bendrinti su šiuo įrenginiu.",
|
||||
"Select latest version": "Pasirinkti paskiausią versiją",
|
||||
"Select oldest version": "Pasirinkti seniausią versiją",
|
||||
"Send & Receive": "Siųsti ir gauti",
|
||||
"Send Extended Attributes": "Siųsti išplėstinius požymius",
|
||||
"Send Only": "Tik siųsti",
|
||||
"Settings": "Nustatymai",
|
||||
"Share": "Bendrinti",
|
||||
@@ -297,9 +325,10 @@
|
||||
"Share this folder?": "Bendrinti šį aplanką?",
|
||||
"Shared Folders": "Bendrinami aplankai",
|
||||
"Shared With": "Bendrinama su",
|
||||
"Sharing": "Dalinamasis",
|
||||
"Sharing": "Bendrinimas",
|
||||
"Show ID": "Rodyti ID",
|
||||
"Show QR": "Rodyti QR",
|
||||
"Show detailed discovery status": "Rodyti išsamią atradimo būseną",
|
||||
"Show diff with previous version": "Rodyti skirtumus su ankstesne versija",
|
||||
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Grupės būsenoje rodomas vietoje įrenginio vardo. Kiti įrenginiai matys kaip pasirinktinį vardą.",
|
||||
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Grupės būsenoje rodomas vietoje įrenginio vardo. Bus atnaujintas į įrenginio vardą jei nieko neįrašysite.",
|
||||
@@ -308,30 +337,35 @@
|
||||
"Simple File Versioning": "Supaprastintas versijų valdymas",
|
||||
"Single level wildcard (matches within a directory only)": "Vieno lygio pakaitos simbolis (atitinka tik vieną katalogo lygį)",
|
||||
"Size": "Dydis",
|
||||
"Smallest First": "Mažiausi pirmiau",
|
||||
"Smallest First": "Pirma mažiausi",
|
||||
"Some items could not be restored:": "Kai kurių elementų atkurti nepavyko:",
|
||||
"Source Code": "Išeities kodas",
|
||||
"Stable releases and release candidates": "Stabilios versijos ir kandidatinės versijos",
|
||||
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stabilios versijos pasirodo maždaug dvi savaites vėliau. Per tą laiką, jos pereina testavimą kaip kandidatinės versijos.",
|
||||
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stabilios versijos pasirodo maždaug dvi savaites vėliau. Per tą laiką jos yra testuojamos kaip kandidatinės versijos.",
|
||||
"Stable releases only": "Tik stabilios versijos",
|
||||
"Staggered File Versioning": "Pakopinis versijų valdymas",
|
||||
"Start Browser": "Paleisti naršyklę",
|
||||
"Statistics": "Statistika",
|
||||
"Stay logged in": "Išlikti prisijungus",
|
||||
"Stopped": "Sustabdyta",
|
||||
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Saugo ir sinchronizuoja tik šifruotus duomenis. Aplankui visuose prijungtuose įrenginiuose turi būti nustatytas tas pats slaptažodis arba aplankas irgi turi būti „{{receiveEncrypted}}“ tipo.",
|
||||
"Support": "Pagalba",
|
||||
"Support Bundle": "Palaikymo paketas",
|
||||
"Sync Extended Attributes": "Sinchronizuoti išplėstinius požymius",
|
||||
"Sync Protocol Listen Addresses": "Sutapatinimo taisyklių adresas",
|
||||
"Sync Status": "Sinchronizavimo būsena",
|
||||
"Syncing": "Sutapatinama",
|
||||
"Syncthing device ID for \"{%devicename%}\"": "Syncthing įrenginio ID, skirtas „{{devicename}}“",
|
||||
"Syncthing has been shut down.": "Syncthing išjungtas",
|
||||
"Syncthing includes the following software or portions thereof:": "Syncthing naudoja šias programas ar jų dalis:",
|
||||
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing yra laisva ir atvirojo kodo programinė įranga, licencijuota pagal MPL v2.0.",
|
||||
"Syncthing is a continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it's transmitted over the internet.": "Syncthing yra pastovaus failų sinchronizavimo programa. Ji realiu laiku sinchronizuoja failus tarp dviejų ar daugiau kompiuterių, saugiai apsaugodama juos nuo smalsių akių. Jūsų duomenys yra tik jūsų duomenys ir jūs turite teisę rinktis, kur juos laikyti, su kuo juos bendrinti ir kaip juos persiuntinėti.",
|
||||
"Syncthing is restarting.": "Syncthing perleidžiamas",
|
||||
"Syncthing is restarting.": "Syncthing paleidžiama iš naujo.",
|
||||
"Syncthing is saving changes.": "Syncthing įrašo pakeitimus.",
|
||||
"Syncthing is upgrading.": "Syncthing atsinaujina.",
|
||||
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Dabar, Syncthing palaiko ir automatiškai plėtotojams siunčia ataskaitas apie strigtis. Pagal numatymą, ši ypatybė yra įjungta.",
|
||||
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing išjungta arba problemos su Interneto ryšių. Bandoma iš naujo…",
|
||||
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Atrodo, kad Syncthing, vykdydamas jūsų užklausą, susidūrė su problemomis. Prašome iš naujo įkelti puslapį, arba jei problema išlieka, iš naujo paleisti Syncthing.",
|
||||
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Atrodo, kad Syncthing išjungta arba yra problemų su interneto ryšiu. Bandoma iš naujo…",
|
||||
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Atrodo, kad Syncthing, vykdydama jūsų užklausą, susidūrė su problemomis. Prašome įkelti puslapį iš naujo arba, jei problema išlieka, iš naujo paleisti Syncthing.",
|
||||
"TCP LAN": "TCP LAN (vietinis tinklas)",
|
||||
"TCP WAN": "TCP WAN (platusis tinklas)",
|
||||
"Take me back": "Sugrąžinkite mane",
|
||||
@@ -340,15 +374,15 @@
|
||||
"The Syncthing admin interface is configured to allow remote access without a password.": "Syncthing administratoriaus sąsaja yra sukonfigūruota taip, kad be slaptažodžio leistų nuotolinę prieigą.",
|
||||
"The aggregated statistics are publicly available at the URL below.": "Naudojimosi ataskaitą galite peržiūrėti žemiau nurodytu URL adresu.",
|
||||
"The cleanup interval cannot be blank.": "Išvalymo intervalas negali būti tuščias.",
|
||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Nauji nustatymai išsaugoti, bet neaktyvuoti. Perleiskite Syncthing programą iš naujo norėdami įgalinti naujus nustatymus.",
|
||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Konfigūracija įrašyta, bet neaktyvuota. Syncthing privalo būti paleista iš naujo, kad aktyvuotų naują konfigūraciją.",
|
||||
"The device ID cannot be blank.": "Įrenginio ID negali būti tuščias.",
|
||||
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Įrenginio ID, kurį čia reikia įvesti, galite rasti „Veiksmai > Rodyti ID“ dialoge kitame įrenginyje. Tarpai ir brūkšneliai nebūtini (ignoruojami).",
|
||||
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes, and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Kas dieną siunčiama šifruota naudojimo ataskaita. Ji naudojama sekti, kokios platformos naudojamos, aplankų dydžius ir programų versijas. Jei siunčiamų duomenų turinys pasikeis, šis dialogas bus parodytas iš naujo.",
|
||||
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "Įvestas neteisingas įrenginio ID. Turi būti 52 ar 56 simbolių eilutė su raidėmis ir skaičiais kuriuos galima atskirti tarpu arba brūkšneliu.",
|
||||
"The folder ID cannot be blank.": "Aplanko ID negali būti tuščias.",
|
||||
"The folder ID must be unique.": "Aplanko ID turi būti unikalus.",
|
||||
"The folder content on other devices will be overwritten to become identical with this device. Files not present here will be deleted on other devices.": "Aplanko turinys kituose įrenginiuose bus perrašytas taip, kad būtų toks pats, kaip šiame įrenginyje. Failai, kurių nėra šiame aplanke, bus ištrinti kituose įrenginiuose.",
|
||||
"The folder content on this device will be overwritten to become identical with other devices. Files newly added here will be deleted.": "Aplanko turinys šiame įrenginyje bus perrašytas taip, kad būtų toks pats, kaip kituose įrenginiuose. Į šią vietą naujai pridėti failai, bus ištrinti.",
|
||||
"The folder content on other devices will be overwritten to become identical with this device. Files not present here will be deleted on other devices.": "Aplanko turinys kituose įrenginiuose bus perrašytas taip, kad būtų toks pats, kaip šiame įrenginyje. Failai, kurių nėra šiame aplanke, kituose įrenginiuose bus ištrinti.",
|
||||
"The folder content on this device will be overwritten to become identical with other devices. Files newly added here will be deleted.": "Aplanko turinys šiame įrenginyje bus perrašytas taip, kad būtų toks pats, kaip kituose įrenginiuose. Į šią vietą naujai pridėti failai bus ištrinti.",
|
||||
"The folder path cannot be blank.": "Kelias iki aplanko negali būti tuščias.",
|
||||
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "Šie pertraukų nustatymai naudojami: pirmą valandą versijos laikomos 30 sekundžių, pirmą dieną versijos laikomos valandą, pirmas 30 dienų versijos laikomos parą, kol nebus viršytas nustatytas maksimalus amžius.",
|
||||
"The following items could not be synchronized.": "Nepavyko parsiųsti šių failų.",
|
||||
@@ -359,11 +393,12 @@
|
||||
"The maximum age must be a number and cannot be blank.": "Maksimalus amžius turi būti skaitmuo ir negali būti tuščias laukelis.",
|
||||
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Maksimalus laikas kurį bus saugojama versija (dienomis, nustatykite 0 norėdami saugoti amžinai).",
|
||||
"The number of days must be a number and cannot be blank.": "Dienų skaičius turi būti teigiamas skaičius.",
|
||||
"The number of days to keep files in the trash can. Zero means forever.": "Kiek dienų laikyti failus šiukšliadėžėje. Nulis reiškia amžinai.",
|
||||
"The number of days to keep files in the trash can. Zero means forever.": "Kiek dienų laikyti failus šiukšlinėje. Nulis reiškia amžinai.",
|
||||
"The number of old versions to keep, per file.": "Kiek failo versijų saugoti.",
|
||||
"The number of versions must be a number and cannot be blank.": "Versijų skaičius turi būti skaitmuo ir negali būti tuščias laukelis.",
|
||||
"The path cannot be blank.": "Kelias negali būti tuščias.",
|
||||
"The rate limit must be a non-negative number (0: no limit)": "Srauto maksimalus greitis privalo būti ne neigiamas skaičius (0: nėra apribojimo)",
|
||||
"The remote device has not accepted sharing this folder.": "Nuotolinis įrenginys nepriėmė šio aplanko bendrinimo.",
|
||||
"The remote device has paused this folder.": "Nuotolinis įrenginys pristabdė šį aplanką.",
|
||||
"The rescan interval must be a non-negative number of seconds.": "Nuskaitymo dažnis negali būti neigiamas skaičius.",
|
||||
"There are no devices to share this folder with.": "Nėra įrenginių su kuriais bendrinti šį aplanką.",
|
||||
@@ -378,7 +413,7 @@
|
||||
"Time the item was last modified": "Laikas, kai elementas buvo paskutinį kartą modifikuotas",
|
||||
"Today": "Šiandien",
|
||||
"Trash Can": "Šiukšlinė",
|
||||
"Trash Can File Versioning": "Šiukšliadėžės versijų valdymas",
|
||||
"Trash Can File Versioning": "Šiukšlinės versijų valdymas",
|
||||
"Type": "Tipas",
|
||||
"UNIX Permissions": "UNIX leidimai",
|
||||
"Unavailable": "Neprieinama",
|
||||
@@ -389,8 +424,9 @@
|
||||
"Unignore": "Nustoti nepaisyti",
|
||||
"Unknown": "Nežinoma",
|
||||
"Unshared": "Nebendrinama",
|
||||
"Unshared Devices": "Nebedrinami įrenginiai",
|
||||
"Unshared Devices": "Įrenginiai, su kuriais nebendrinama",
|
||||
"Unshared Folders": "Nebendrinami aplankai",
|
||||
"Untrusted": "Nepatikimas",
|
||||
"Up to Date": "Atnaujinta",
|
||||
"Updated {%file%}": "Atnaujintas {{file}}",
|
||||
"Upgrade": "Atnaujinimas",
|
||||
@@ -401,7 +437,12 @@
|
||||
"Usage reporting is always enabled for candidate releases.": "Naudojimo ataskaita kandidatinėms versijoms visada yra įjungta.",
|
||||
"Use HTTPS for GUI": "Valdymo skydeliui naudoti saugų ryšį ",
|
||||
"Use notifications from the filesystem to detect changed items.": "Naudoti pranešimus iš failų sistemos, norint aptikti pakeistus elementus.",
|
||||
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "Valdymo skydelio tapatybės nustatymui nebuvo nustatytas vartotojo vardas/slaptažodis. Apsvarstykite galimybę jį nusistatyti.",
|
||||
"User": "Naudotojas",
|
||||
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "Valdymo skydelio tapatybės nustatymui nebuvo nustatytas naudotojo vardas/slaptažodis. Apsvarstykite galimybę jį nusistatyti.",
|
||||
"Using a QUIC connection over LAN": "Naudoja QUIC ryšį per vietinį tinklą (LAN)",
|
||||
"Using a QUIC connection over WAN": "Naudoja QUIC ryšį per platųjį tinklą (WAN)",
|
||||
"Using a direct TCP connection over LAN": "Naudoja tiesioginį TCP ryšį per vietinį tinklą (LAN)",
|
||||
"Using a direct TCP connection over WAN": "Naudoja tiesioginį TCP ryšį per platųjį tinklą (WAN)",
|
||||
"Version": "Versija",
|
||||
"Versions": "Versijos",
|
||||
"Versions Path": "Kelias iki versijos",
|
||||
@@ -430,6 +471,8 @@
|
||||
"You have no ignored folders.": "Jūs neturite jokių nepaisomų aplankų.",
|
||||
"You have unsaved changes. Do you really want to discard them?": "Turite neįrašytų pakeitimų. Ar tikrai norite juos atmesti?",
|
||||
"You must keep at least one version.": "Būtina saugoti bent vieną versiją.",
|
||||
"Your SMS app should open to let you choose the recipient and send it from your own number.": "Turi atsiverti SMS programėlė ir leisti jums pasirinkti gavėją bei išsiųsti žinutę iš nuosavo numerio.",
|
||||
"Your email app should open to let you choose the recipient and send it from your own address.": "Turi atsiverti el. pašto programėlė ir leisti jums pasirinkti gavėją bei išsiųsti el. laišką iš nuosavo adreso.",
|
||||
"days": "dienos",
|
||||
"deleted": "ištrintas",
|
||||
"directories": "katalogai",
|
||||
@@ -440,6 +483,15 @@
|
||||
"items": "įrašai",
|
||||
"modified": "modifikuotas",
|
||||
"seconds": "sek.",
|
||||
"theme": {
|
||||
"name": {
|
||||
"black": "Juodas",
|
||||
"dark": "Tamsus",
|
||||
"default": "Numatytasis",
|
||||
"light": "Šviesus"
|
||||
}
|
||||
},
|
||||
"unknown device": "nežinomas įrenginys",
|
||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} nori bendrinti aplanką „{{folder}}“.",
|
||||
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} nori bendrinti aplanką „{{folderlabel}}“ ({{folder}})."
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"Are you sure you want to override all remote changes?": "Tem a certeza que quer sobrepor todas as alterações remotas?",
|
||||
"Are you sure you want to permanently delete all these files?": "Deseja realmente excluir todos estes arquivos permanentemente?",
|
||||
"Are you sure you want to remove device {%name%}?": "Deseja mesmo remover o dispositivo {{name}}?",
|
||||
"Are you sure you want to remove folder {%label%}?": "Deseja mesmo remover a pasta {{name}}?",
|
||||
"Are you sure you want to remove folder {%label%}?": "Deseja mesmo remover a pasta {{label}}?",
|
||||
"Are you sure you want to restore {%count%} files?": "Deseja mesmo restaurar {{count}} arquivo(s)?",
|
||||
"Are you sure you want to revert all local changes?": "Tem a certeza que quer reverter todas as alterações locais?",
|
||||
"Are you sure you want to upgrade?": "Deseja mesmo fazer a atualização?",
|
||||
@@ -69,7 +69,7 @@
|
||||
"Connection Management": "Gerenciamento de Conexões",
|
||||
"Connection Type": "Tipo da conexão",
|
||||
"Connections": "Conexões",
|
||||
"Connections via relays might be rate limited by the relay": "Conexões que usam retransmissão podem podem ter velocidade limitada pelo retransmissor",
|
||||
"Connections via relays might be rate limited by the relay": "Conexões que usam retransmissão podem ter a velocidade limitada pelo retransmissor",
|
||||
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Observar continuamente as alterações agora está disponível no Syncthing. Isso detectará mudanças no disco e fará uma varredura apenas nos caminhos modificados. Os benefícios são que as alterações são propagadas mais rapidamente e menos verificações completas são necessárias.",
|
||||
"Copied from elsewhere": "Copiado de outro lugar",
|
||||
"Copied from original": "Copiado do original",
|
||||
@@ -99,6 +99,7 @@
|
||||
"Device ID": "ID do dispositivo",
|
||||
"Device Identification": "Identificação do dispositivo",
|
||||
"Device Name": "Nome do dispositivo",
|
||||
"Device Status": "Status do Dispositivo",
|
||||
"Device is untrusted, enter encryption password": "O dispositivo não é confiável, digite a senha de criptografia",
|
||||
"Device rate limits": "Limites de velocidade do dispositivo",
|
||||
"Device that last modified the item": "Dispositivo que modificou o item pela última vez",
|
||||
@@ -168,6 +169,7 @@
|
||||
"Folder ID": "ID da pasta",
|
||||
"Folder Label": "Rótulo da pasta",
|
||||
"Folder Path": "Caminho da pasta",
|
||||
"Folder Status": "Status da Pasta",
|
||||
"Folder Type": "Tipo da pasta",
|
||||
"Folder type \"{%receiveEncrypted%}\" can only be set when adding a new folder.": "O tipo de pasta \"{{receiveEncrypted}}\" só pode ser definido ao adicionar uma nova pasta.",
|
||||
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "O tipo de pasta \"{{receiveEncrypted}}\" não pode ser alterado após adicionar a pasta. Você precisa remover a pasta, excluir ou descriptografar os dados do disco e adicionar a pasta novamente.",
|
||||
@@ -237,6 +239,8 @@
|
||||
"Log File": "Arquivo de registro",
|
||||
"Log In": "Entrar",
|
||||
"Log Out": "Sair",
|
||||
"Log in to see paths information.": "Faça Log In para ver informações de caminhos.",
|
||||
"Log in to see version information.": "Faça Log In para ver informações de versão.",
|
||||
"Log tailing paused. Scroll to the bottom to continue.": "Log tailing pausado. Role até o final para continuar.",
|
||||
"Login failed, see Syncthing logs for details.": "Falha no login. Veja os logs do Syncthing para mais detalhes.",
|
||||
"Logs": "Registros",
|
||||
@@ -382,6 +386,7 @@
|
||||
"Staggered File Versioning": "Escalonado",
|
||||
"Start Browser": "Iniciar navegador",
|
||||
"Statistics": "Estatísticas",
|
||||
"Stay logged in": "Ficar conectado",
|
||||
"Stopped": "Parado",
|
||||
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Armazena e sincroniza apenas dados criptografados. As pastas em todos os dispositivos conectados precisam ser configuradas com a mesma senha ou ser do tipo \"{{receiveEncrypted}}\" também.",
|
||||
"Subject:": "Assunto:",
|
||||
@@ -543,6 +548,7 @@
|
||||
"light": "Claro"
|
||||
}
|
||||
},
|
||||
"unknown device": "dispositivo desconhecido",
|
||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quer compartilhar a pasta \"{{folder}}\".",
|
||||
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} quer compartilhar a pasta \"{{folderlabel}}\" ({{folder}}).",
|
||||
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} pode reintroduzir este dispositivo."
|
||||
|
||||
@@ -38,14 +38,14 @@
|
||||
"Are you sure you want to remove folder {%label%}?": "Tem a certeza que quer remover a pasta {{label}}?",
|
||||
"Are you sure you want to restore {%count%} files?": "Tem a certeza que quer restaurar {{count}} ficheiros?",
|
||||
"Are you sure you want to revert all local changes?": "Tem a certeza que quer reverter todas as alterações locais?",
|
||||
"Are you sure you want to upgrade?": "Tem a certeza que quer actualizar?",
|
||||
"Are you sure you want to upgrade?": "Tem a certeza que quer atualizar?",
|
||||
"Authentication Required": "É necessária autenticação",
|
||||
"Authors": "Autores",
|
||||
"Auto Accept": "Aceitar automaticamente",
|
||||
"Automatic Crash Reporting": "Relatório Automático de Estouro",
|
||||
"Automatic upgrade now offers the choice between stable releases and release candidates.": "A actualização automática agora oferece a escolha entre versões estáveis e candidatas a lançamento.",
|
||||
"Automatic upgrades": "Actualizações automáticas",
|
||||
"Automatic upgrades are always enabled for candidate releases.": "As actualizações automáticas estão sempre activadas nas versões candidatas a lançamento.",
|
||||
"Automatic Crash Reporting": "Relatório Automático de Falhas",
|
||||
"Automatic upgrade now offers the choice between stable releases and release candidates.": "A atualização automática agora oferece a escolha entre versões estáveis e candidatas a lançamento.",
|
||||
"Automatic upgrades": "Atualizações automáticas",
|
||||
"Automatic upgrades are always enabled for candidate releases.": "As atualizações automáticas estão sempre ativadas nas versões candidatas a lançamento.",
|
||||
"Automatically create or share folders that this device advertises at the default path.": "Criar ou partilhar, de forma automática e no caminho predefinido, pastas que este dispositivo publicita.",
|
||||
"Available debug logging facilities:": "Recursos de registo de depuração disponíveis:",
|
||||
"Be careful!": "Tenha cuidado!",
|
||||
@@ -70,12 +70,12 @@
|
||||
"Connection Type": "Tipo de ligação",
|
||||
"Connections": "Ligações",
|
||||
"Connections via relays might be rate limited by the relay": "Ligações via retransmissores podem ter a velocidade limitada pelo retransmissor",
|
||||
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "A vigilância de alterações contínua está agora disponível dentro do Syncthing. Este sistema irá detectar alterações no disco e efectuar uma verificação apenas nas pastas modificadas. Os benefícios são que as alterações são propagadas mais depressa e são necessárias menos verificações completas.",
|
||||
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "A vigilância de alterações contínua está agora disponível dentro do Syncthing. Este sistema irá detetar alterações no disco e efetuar uma verificação apenas nas pastas modificadas. Os benefícios são que as alterações são propagadas mais depressa e são necessárias menos verificações completas.",
|
||||
"Copied from elsewhere": "Copiado doutro sítio",
|
||||
"Copied from original": "Copiado do original",
|
||||
"Copied!": "Copiado!",
|
||||
"Copy": "Copiar",
|
||||
"Copy failed! Try to select and copy manually.": "A cópia falhou! Tente seleccionar e copiar manualmente.",
|
||||
"Copy failed! Try to select and copy manually.": "A cópia falhou! Tente selecionar e copiar manualmente.",
|
||||
"Currently Shared With Devices": "Dispositivos com os quais está partilhada",
|
||||
"Custom Range": "Intervalo personalizado",
|
||||
"Danger!": "Perigo!",
|
||||
@@ -90,9 +90,9 @@
|
||||
"Delete": "Eliminar",
|
||||
"Delete Unexpected Items": "Eliminar itens inesperados",
|
||||
"Deleted {%file%}": "{{file}} eliminado",
|
||||
"Deselect All": "Retirar todas as selecções",
|
||||
"Deselect devices to stop sharing this folder with.": "Retire a selecção para deixar de partilhar a pasta com esses dispositivos.",
|
||||
"Deselect folders to stop sharing with this device.": "Retire a selecção das pastas para deixar de as partilhar com este dispositivo.",
|
||||
"Deselect All": "Retirar todas as seleções",
|
||||
"Deselect devices to stop sharing this folder with.": "Retire a seleção para deixar de partilhar a pasta com esses dispositivos.",
|
||||
"Deselect folders to stop sharing with this device.": "Retire a seleção das pastas para deixar de as partilhar com este dispositivo.",
|
||||
"Device": "Dispositivo",
|
||||
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "O dispositivo \"{{name}}\" ({{device}} em {{address}}) quer conectar-se. Adiciono este novo dispositivo?",
|
||||
"Device Certificate": "Certificado do dispositivo",
|
||||
@@ -104,12 +104,12 @@
|
||||
"Device rate limits": "Limites de velocidade do dispositivo",
|
||||
"Device that last modified the item": "Último dispositivo a modificar o item",
|
||||
"Devices": "Dispositivos",
|
||||
"Disable Crash Reporting": "Desactivar Relatório de Estouro",
|
||||
"Disabled": "Desactivada",
|
||||
"Disabled periodic scanning and disabled watching for changes": "Desactivada a verificação periódica e desactivada a vigilância de alterações",
|
||||
"Disabled periodic scanning and enabled watching for changes": "Desactivada a verificação periódica e desactivada a vigilância de alterações",
|
||||
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "Desactivada a verificação periódica e falha ao preparar a vigilância de alterações, tentando novamente a cada minuto:",
|
||||
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "Desactiva a comparação e a sincronização das permissões dos ficheiros. É útil em sistemas onde as permissões não existem ou são personalizadas (ex.: FAT, exFAT, Synology, Android).",
|
||||
"Disable Crash Reporting": "Desativar Relatório de Falhas",
|
||||
"Disabled": "Desativada",
|
||||
"Disabled periodic scanning and disabled watching for changes": "Desativada a verificação periódica e desativada a vigilância de alterações",
|
||||
"Disabled periodic scanning and enabled watching for changes": "Desativada a verificação periódica e ativada a vigilância de alterações",
|
||||
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "Desativada a verificação periódica e falha ao preparar a vigilância de alterações, tentando novamente a cada minuto:",
|
||||
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "Desativa a comparação e a sincronização das permissões dos ficheiros. É útil em sistemas onde as permissões não existem ou são personalizadas (ex.: FAT, exFAT, Synology, Android).",
|
||||
"Discard": "Descartar",
|
||||
"Disconnected": "Desconectado",
|
||||
"Disconnected (Inactive)": "Desconectado (inactivo)",
|
||||
@@ -122,39 +122,39 @@
|
||||
"Do not add it to the ignore list, so this notification may recur.": "Não adicionar à lista dos ignorados, para que esta notificação volte a aparecer.",
|
||||
"Do not restore": "Não restaurar",
|
||||
"Do not restore all": "Não restaurar nenhum",
|
||||
"Do you want to enable watching for changes for all your folders?": "Quer activar a vigilância de alterações para todas as suas pastas?",
|
||||
"Do you want to enable watching for changes for all your folders?": "Quer ativar a vigilância de alterações para todas as suas pastas?",
|
||||
"Documentation": "Documentação",
|
||||
"Download Rate": "Velocidade de recepção",
|
||||
"Downloaded": "Recebido",
|
||||
"Downloading": "Recebendo",
|
||||
"Downloading": "A Receber",
|
||||
"Edit": "Editar",
|
||||
"Edit Device": "Editar dispositivo",
|
||||
"Edit Device Defaults": "Editar as predefinições do dispositivo",
|
||||
"Edit Folder": "Editar pasta",
|
||||
"Edit Folder Defaults": "Editar as predefinições da pasta",
|
||||
"Editing {%path%}.": "Editando {{path}}.",
|
||||
"Enable Crash Reporting": "Activar Relatório de Estouro",
|
||||
"Enable NAT traversal": "Activar travessia de NAT",
|
||||
"Editing {%path%}.": "A editar {{path}}.",
|
||||
"Enable Crash Reporting": "Ativar Relatório de Falhas",
|
||||
"Enable NAT traversal": "Ativar travessia de NAT",
|
||||
"Enable Relaying": "Permitir retransmissão",
|
||||
"Enabled": "Activada",
|
||||
"Enables sending extended attributes to other devices, and applying incoming extended attributes. May require running with elevated privileges.": "Habilita o envio de atributos estendidos para os outros dispositivos e a aplicação dos atributos estendidos recebidos. Pode exigir que se corra com privilégios elevados.",
|
||||
"Enables sending extended attributes to other devices, but not applying incoming extended attributes. This can have a significant performance impact. Always enabled when \"Sync Extended Attributes\" is enabled.": "Habilita o envio de atributos estendidos para outros dispositivos, mas não a aplicação dos atributos estendidos recebidos. Isto pode ter um impacto de desempenho significativo. Fica sempre habilitado quando \"Sincronizar atributos estendidos\" é habilitado.",
|
||||
"Enables sending ownership information to other devices, and applying incoming ownership information. Typically requires running with elevated privileges.": "Habilita o envio de informação sobre propriedade para os outros dispositivos e a aplicação da informação recebida sobre propriedade. Requer, tipicamente, que se execute com privilégios elevados.",
|
||||
"Enables sending ownership information to other devices, but not applying incoming ownership information. This can have a significant performance impact. Always enabled when \"Sync Ownership\" is enabled.": "Habilita o envio da informação de propriedade para outros dispositivos, mas não a aplicação da informação de propriedade recebida. Pode ter um impacto significativo no desempenho. Fica sempre habilitado quando \"Sincronizar a propriedade\" é habilitada.",
|
||||
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Escreva um número positivo (ex.: \"2.35\") e seleccione uma unidade. Percentagens são relativas ao tamanho total do disco.",
|
||||
"Enter a non-privileged port number (1024 - 65535).": "Escreva um número de porto não-privilegiado (1024-65535).",
|
||||
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduza endereços separados por vírgulas (\"tcp://ip:porto\", \"tcp://máquina:porto\") ou \"dynamic\" para descobrir automaticamente os endereços.",
|
||||
"Enabled": "Ativada",
|
||||
"Enables sending extended attributes to other devices, and applying incoming extended attributes. May require running with elevated privileges.": "Permite o envio de atributos estendidos para outros dispositivos, e a aplicação de atributos estendidos recebidos. Pode ser necessário executar com privilégios elevados.",
|
||||
"Enables sending extended attributes to other devices, but not applying incoming extended attributes. This can have a significant performance impact. Always enabled when \"Sync Extended Attributes\" is enabled.": "Permite o envio de atributos estendidos para outros dispositivos, mas não a aplicação dos atributos estendidos recebidos. Isto pode ter um impacto de desempenho significativo. Sempre ativo quando \"Sincronizar atributos estendidos\" está ativado.",
|
||||
"Enables sending ownership information to other devices, and applying incoming ownership information. Typically requires running with elevated privileges.": "Permite o envio de informação sobre propriedade para outros dispositivos, e a aplicação da informação recebida sobre propriedade. Requer, tipicamente, que se execute com privilégios elevados.",
|
||||
"Enables sending ownership information to other devices, but not applying incoming ownership information. This can have a significant performance impact. Always enabled when \"Sync Ownership\" is enabled.": "Permite o envio da informação de propriedade para outros dispositivos, mas não a aplicação da informação de propriedade recebida. Pode ter um impacto significativo no desempenho. Sempre ativo quando \"Sincronizar a propriedade\" está ativado.",
|
||||
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Escreva um número positivo (ex.: \"2.35\") e selecione uma unidade. Percentagens são relativas ao tamanho total do disco.",
|
||||
"Enter a non-privileged port number (1024 - 65535).": "Escreva um número de porta não privilegiado (1024-65535).",
|
||||
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduza endereços separados por vírgulas (\"tcp://ip:porta\", \"tcp://máquina:porta\") ou \"dynamic\" para descobrir automaticamente os endereços.",
|
||||
"Enter ignore patterns, one per line.": "Escreva os padrões de exclusão, um por linha.",
|
||||
"Enter up to three octal digits.": "Insira de um a três dígitos em octal.",
|
||||
"Error": "Erro",
|
||||
"Extended Attributes": "Atributos estendidos",
|
||||
"Extended Attributes Filter": "Filtro de atributos extendidos",
|
||||
"External": "Externa",
|
||||
"External File Versioning": "Externa",
|
||||
"External File Versioning": "Gestão de Versões de Ficheiros Externa",
|
||||
"Failed Items": "Itens que falharam",
|
||||
"Failed to load file versions.": "Falhou ao carregar as versões do ficheiro.",
|
||||
"Failed to load ignore patterns.": "Falhou o carregamento dos padrões de exclusão.",
|
||||
"Failed to setup, retrying": "A preparação falhou, tentando novamente",
|
||||
"Failed to load file versions.": "Falha ao carregar as versões do ficheiro.",
|
||||
"Failed to load ignore patterns.": "Falha ao carregar os padrões de exclusão.",
|
||||
"Failed to setup, retrying": "A preparação falhou, a tentar novamente",
|
||||
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "São esperadas falhas na ligação a servidores IPv6 se não existir conectividade IPv6.",
|
||||
"File Pull Order": "Ordem de obtenção de ficheiros",
|
||||
"File Versioning": "Gestão de versões de ficheiros",
|
||||
@@ -192,8 +192,8 @@
|
||||
"Global State": "Estado global",
|
||||
"Help": "Ajuda",
|
||||
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "Dica: quando a predefinição é \"negar\", apenas as regras de negação são encontradas. Considere adicionar \"permitir tudo\" como última regra.",
|
||||
"Home page": "Página do projecto",
|
||||
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Contudo, a sua configuração actual indica que pode não a querer activada. Nós desactivámos automaticamente o relatório de estouro para si.",
|
||||
"Home page": "Inicio",
|
||||
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Contudo, a sua configuração atual indica que pode não a querer ativada. Nós desativámos automaticamente o relatório de falhas para si.",
|
||||
"Identification": "Identificação",
|
||||
"If untrusted, enter encryption password": "Se não for fiável, insira uma senha de encriptação",
|
||||
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Se quiser evitar que outros utilizadores neste computador acedam ao Syncthing e, através dele, aos seus ficheiros, considere configurar a autenticação.",
|
||||
@@ -206,7 +206,7 @@
|
||||
"Ignored at": "Ignorado em",
|
||||
"Included Software": "Software incluído",
|
||||
"Incoming Rate Limit (KiB/s)": "Limite de velocidade de recepção (KiB/s)",
|
||||
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Uma configuração incorrecta pode danificar o conteúdo da pasta e tornar o Syncthing inoperacional.",
|
||||
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Uma configuração incorreta pode danificar o conteúdo da pasta e tornar o Syncthing inoperacional.",
|
||||
"Incorrect user name or password.": "Nome de utilizador ou senha errados.",
|
||||
"Internally used paths:": "Caminhos usados internamente:",
|
||||
"Introduced By": "Introduzido por",
|
||||
@@ -244,7 +244,7 @@
|
||||
"Log tailing paused. Scroll to the bottom to continue.": "O acompanhamento do final do registo está em pausa. Desloque para o final para continuar.",
|
||||
"Login failed, see Syncthing logs for details.": "O início da sessão falhou. Veja os registos do Syncthing para mais detalhes.",
|
||||
"Logs": "Registos",
|
||||
"Major Upgrade": "Actualização importante",
|
||||
"Major Upgrade": "Atualização importante",
|
||||
"Mass actions": "Operações em massa",
|
||||
"Maximum Age": "Idade máxima",
|
||||
"Maximum single entry size": "Tamanho máximo das entradas únicas",
|
||||
@@ -291,8 +291,8 @@
|
||||
"Paused": "Em pausa",
|
||||
"Paused (Unused)": "Em pausa (não usado)",
|
||||
"Pending changes": "Alterações pendentes",
|
||||
"Periodic scanning at given interval and disabled watching for changes": "Verificação periódica no intervalo dado e desactivada a vigilância de alterações",
|
||||
"Periodic scanning at given interval and enabled watching for changes": "Verificação periódica no intervalo dado e activada a vigilância de alterações",
|
||||
"Periodic scanning at given interval and disabled watching for changes": "Verificação periódica no intervalo dado e desativada a vigilância de alterações",
|
||||
"Periodic scanning at given interval and enabled watching for changes": "Verificação periódica no intervalo dado e ativada a vigilância de alterações",
|
||||
"Periodic scanning at given interval and failed setting up watching for changes, retrying every 1m:": "Verificação periódica no intervalo dado e falha ao preparar a vigilância de alterações, tentando novamente a cada minuto:",
|
||||
"Permanently add it to the ignore list, suppressing further notifications.": "Adicionar permanentemente à lista de ignorados, inibindo novas notificações.",
|
||||
"Please consult the release notes before performing a major upgrade.": "Consulte as notas de lançamento antes de fazer uma actualização importante.",
|
||||
@@ -337,16 +337,16 @@
|
||||
"Revert": "Reverter",
|
||||
"Revert Local Changes": "Reverter alterações locais",
|
||||
"Save": "Gravar",
|
||||
"Saving changes": "Guardando modificações",
|
||||
"Saving changes": "A guardar modificações",
|
||||
"Scan Time Remaining": "Tempo restante da verificação",
|
||||
"Scanning": "Verificação de alterações",
|
||||
"See external versioning help for supported templated command line parameters.": "Veja a ajuda sobre a gestão de versões externa para ver os modelos suportados de parâmetros para a linha de comandos.",
|
||||
"Select All": "Seleccionar tudo",
|
||||
"Select a version": "Seleccione uma versão",
|
||||
"Select additional devices to share this folder with.": "Seleccione outros dispositivos com os quais também pretende partilhar a pasta.",
|
||||
"Select additional folders to share with this device.": "Seleccione pastas adicionais para partilhar com este dispositivo.",
|
||||
"Select latest version": "Seleccionar a última versão",
|
||||
"Select oldest version": "Seleccionar a versão mais antiga",
|
||||
"Select additional devices to share this folder with.": "Selecione outros dispositivos com os quais também pretende partilhar a pasta.",
|
||||
"Select additional folders to share with this device.": "Selecione pastas adicionais para partilhar com este dispositivo.",
|
||||
"Select latest version": "Selecionar a última versão",
|
||||
"Select oldest version": "Selecionar a versão mais antiga",
|
||||
"Send & Receive": "envia e recebe",
|
||||
"Send Extended Attributes": "Enviar atributos estendidos",
|
||||
"Send Only": "envia apenas",
|
||||
@@ -377,7 +377,7 @@
|
||||
"Smallest First": "Primeiro os menores",
|
||||
"Some discovery methods could not be established for finding other devices or announcing this device:": "Não foi possível estabelecer alguns dos métodos de descoberta para encontrar outros dispositivos ou anunciar este dispositivo:",
|
||||
"Some items could not be restored:": "Não foi possível restaurar alguns dos itens:",
|
||||
"Some listening addresses could not be enabled to accept connections:": "Alguns endereços de escuta não puderam ser activados para aceitar ligações:",
|
||||
"Some listening addresses could not be enabled to accept connections:": "Alguns endereços de escuta não puderam ser ativados para aceitar ligações:",
|
||||
"Source Code": "Código fonte",
|
||||
"Stable releases and release candidates": "Versões estáveis e versões candidatas a lançamento",
|
||||
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Versões estáveis são adiadas por cerca de duas semanas. Durante esse período são submetidas a testes sob a forma de versões candidatas a lançamento.",
|
||||
@@ -386,6 +386,7 @@
|
||||
"Staggered File Versioning": "Escalonada",
|
||||
"Start Browser": "Iniciar navegador",
|
||||
"Statistics": "Estatísticas",
|
||||
"Stay logged in": "Continuar conectado",
|
||||
"Stopped": "Parado",
|
||||
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Armazena e sincroniza apenas dados encriptados. As pastas em todos os dispositivos conectados têm de ser configuradas com a mesma senha ou ser também do tipo \"{{receiveEncrypted}}\".",
|
||||
"Subject:": "Assunto:",
|
||||
@@ -412,12 +413,12 @@
|
||||
"TCP LAN": "TCP LAN",
|
||||
"TCP WAN": "TCP WAN",
|
||||
"Take me back": "Voltar atrás",
|
||||
"The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.": "O endereço da interface gráfica é substituído pelas opções de arranque. Alterações feitas aqui não terão efeito enquanto a substituição estiver activa.",
|
||||
"The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.": "O endereço da interface gráfica é substituído pelas opções de arranque. Alterações feitas aqui não terão efeito enquanto a substituição estiver ativa.",
|
||||
"The Syncthing Authors": "Os autores do Syncthing",
|
||||
"The Syncthing admin interface is configured to allow remote access without a password.": "A interface de administração do Syncthing está configurada para permitir o acesso remoto sem pedir senha.",
|
||||
"The aggregated statistics are publicly available at the URL below.": "As estatísticas agregadas estão publicamente disponíveis no URL abaixo.",
|
||||
"The cleanup interval cannot be blank.": "O intervalo entre limpezas não pode estar vazio.",
|
||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "A configuração foi gravada mas não activada. O Syncthing tem que reiniciar para activar a nova configuração.",
|
||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "A configuração foi gravada mas não ativada. O Syncthing tem que reiniciar para ativar a nova configuração.",
|
||||
"The device ID cannot be blank.": "O ID do dispositivo não pode estar vazio.",
|
||||
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "O ID do dispositivo a colocar aqui pode ser obtido no menu \"Operações > Mostrar ID\" do outro dispositivo. Espaços e hífenes são opcionais (ignorados).",
|
||||
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes, and app versions. If the reported data set is changed you will be prompted with this dialog again.": "O relatório de utilização cifrado é enviado diariamente. É utilizado para rastrear plataformas comuns, tamanhos de pastas e versões da aplicação. Se o tipo de dados do relatório for alterado, será notificado novamente através desta janela.",
|
||||
@@ -434,7 +435,7 @@
|
||||
"The following text will automatically be inserted into a new message.": "O texto seguinte será inserido automaticamente numa nova mensagem.",
|
||||
"The following unexpected items were found.": "Foram encontrados os seguinte itens inesperados.",
|
||||
"The interval must be a positive number of seconds.": "O intervalo tem que ser um número positivo de segundos.",
|
||||
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "O intervalo, em segundos, para executar limpezas na pasta das versões. Coloque zero para desactivar a limpeza periódica.",
|
||||
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "O intervalo, em segundos, para executar limpezas na pasta das versões. Coloque zero para desativar a limpeza periódica.",
|
||||
"The maximum age must be a number and cannot be blank.": "A idade máxima tem que ser um número e não pode estar vazia.",
|
||||
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Tempo máximo, em dias, para manter uma versão (use 0 para manter a versão para sempre).",
|
||||
"The number of connections must be a non-negative number.": "O número de ligações tem que ser um número não negativo.",
|
||||
@@ -456,7 +457,7 @@
|
||||
"This Month": "Este mês",
|
||||
"This can easily give hackers access to read and change any files on your computer.": "Isso facilmente dará acesso aos piratas informáticos para lerem e modificarem quaisquer ficheiros no seu computador.",
|
||||
"This device cannot automatically discover other devices or announce its own address to be found by others. Only devices with statically configured addresses can connect.": "Este dispositivo não pode descobrir automaticamente outros dispositivos ou anunciar o seu próprio endereço para que seja encontrado pelos outros. Apenas dispositivos com endereços configurados estaticamente podem estabelecer ligação.",
|
||||
"This is a major version upgrade.": "Esta é uma actualização para uma versão importante.",
|
||||
"This is a major version upgrade.": "Esta é uma atualização para uma versão importante.",
|
||||
"This setting controls the free space required on the home (i.e., index database) disk.": "Este parâmetro controla o espaço livre necessário no disco base (ou seja, o disco da base de dados do índice).",
|
||||
"Time": "Quando",
|
||||
"Time the item was last modified": "Quando o item foi modificado pela última vez",
|
||||
@@ -499,17 +500,17 @@
|
||||
"Versions": "Versões",
|
||||
"Versions Path": "Caminho das versões",
|
||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "As versões são eliminadas automaticamente se forem mais antigas do que a idade máxima ou excederem o número máximo de ficheiros permitido num intervalo.",
|
||||
"Waiting to Clean": "Aguardando a limpeza",
|
||||
"Waiting to Scan": "Aguardando a verificação",
|
||||
"Waiting to Sync": "Aguardando a sincronização",
|
||||
"Waiting to Clean": "A aguardar a Limpeza",
|
||||
"Waiting to Scan": "A aguardar a Verificação",
|
||||
"Waiting to Sync": "A aguardar a Sincronização",
|
||||
"Warning": "Aviso",
|
||||
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Aviso: Este caminho é uma pasta mãe duma pasta \"{{otherFolder}}\" já existente.",
|
||||
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Aviso: Este caminho é uma pasta mãe duma pasta \"{{otherFolderLabel}}\" ({{otherFolder}}) já existente.",
|
||||
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Aviso: Este caminho é uma subpasta da pasta \"{{otherFolder}}\" já existente.",
|
||||
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Aviso: Este caminho é uma subpasta da pasta \"{{otherFolderLabel}}\" ({{otherFolder}}) já existente.",
|
||||
"Warning: If you are using an external watcher like {%syncthingInotify%}, you should make sure it is deactivated.": "Aviso: Se estiver a usar um verificador externo, tal como o {{syncthingInotify}}, deve certificar-se que está desactivado.",
|
||||
"Warning: If you are using an external watcher like {%syncthingInotify%}, you should make sure it is deactivated.": "Aviso: Se estiver a usar um verificador externo, tal como o {{syncthingInotify}}, deve certificar-se que está desativado.",
|
||||
"Watch for Changes": "Vigiar alterações",
|
||||
"Watching for Changes": "Vigilância de alterações",
|
||||
"Watching for Changes": "A vigiar Alterações",
|
||||
"Watching for changes discovers most changes without periodic scanning.": "A vigilância de alterações descobre a maior parte das alterações sem a necessidade de fazer uma verificação periódica.",
|
||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quando adicionar um novo dispositivo, lembre-se que este dispositivo tem que ser adicionado do outro lado também.",
|
||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quando adicionar uma nova pasta, lembre-se que o ID da pasta é utilizado para ligar as pastas entre dispositivos. É sensível às diferenças entre maiúsculas e minúsculas e tem que ter uma correspondência perfeita entre todos os dispositivos.",
|
||||
|
||||
@@ -386,7 +386,7 @@
|
||||
"Staggered File Versioning": "Aşamalı Dosya Sürümlendirme",
|
||||
"Start Browser": "Tarayıcıyı başlat",
|
||||
"Statistics": "İstatistikler",
|
||||
"Stay logged in": "Oturum açık kal",
|
||||
"Stay logged in": "Oturum açık kalsın",
|
||||
"Stopped": "Durduruldu",
|
||||
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Yalnızca şifrelenmiş verileri depolar ve eşitler. Tüm bağlı cihazlardaki klasörlerin de aynı parola ile ayarlanması veya \"{{receiveEncrypted}}\" türünde olması gerekir.",
|
||||
"Subject:": "Konu:",
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
{
|
||||
"A device with that ID is already added.": "Пристрій з таким ID вже додано раніше.",
|
||||
"A device with that ID is already added.": "Пристрій з таким ID вже додано.",
|
||||
"A negative number of days doesn't make sense.": "Від'ємна кількість днів немає сенсу.",
|
||||
"A new major version may not be compatible with previous versions.": "Нова мажорна версія може бути несумісною із попередніми версіями.",
|
||||
"A new major version may not be compatible with previous versions.": "Нова версія з великими змінвми може бути несумісною із попередніми версіями.",
|
||||
"API Key": "API ключ",
|
||||
"About": "Про програму",
|
||||
"Action": "Дія",
|
||||
"Actions": "Дії",
|
||||
"Active filter rules": "Діючі правила фільтрування",
|
||||
"Add": "Додати",
|
||||
"Add Device": "Додати пристрій",
|
||||
"Add Folder": "Додати директорію",
|
||||
"Add Folder": "Додати папку",
|
||||
"Add Remote Device": "Додати віддалений пристрій",
|
||||
"Add devices from the introducer to our device list, for mutually shared folders.": "Додати пристрої від того, що рекомендує, до нашого списку пристроїв для спільних папок.",
|
||||
"Add devices from the introducer to our device list, for mutually shared folders.": "Додавати пристрої з пристрою що рекомендує, до списку пристроїв для налаштування спільних папок.",
|
||||
"Add filter entry": "Додати правило фільтру",
|
||||
"Add ignore patterns": "Додати шаблони ігнорування",
|
||||
"Add new folder?": "Додати нову директорію?",
|
||||
"Add new folder?": "Додати нову папку?",
|
||||
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "Крім того, буде збільшений інтервал повного сканування (у 60 разів, тобто нове значення за замовчанням - 1 година). Ви також можете налаштувати його вручну для кожної папки пізніше після вибору \"Ні\".",
|
||||
"Address": "Адреса",
|
||||
"Addresses": "Адреси",
|
||||
@@ -23,11 +25,12 @@
|
||||
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Ті папки, якими поділилися з цим пристроєм, мають бути захищені паролем, щоб усі надіслані дані неможливо було прочитати без вказаного пароля.",
|
||||
"Allow Anonymous Usage Reporting?": "Дозволити програмі збирати анонімну статистику використання?",
|
||||
"Allowed Networks": "Дозволені мережі",
|
||||
"Alphabetic": "За алфавітом",
|
||||
"Alphabetic": "За абеткою",
|
||||
"Altered by ignoring deletes.": "Змінено шляхом ігнорування видалень.",
|
||||
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Зовнішня команда для керування версіями. Вона має видалити файл зі спільної папки. Якщо шлях до програми містить пробіли, його слід взяти в лапки.",
|
||||
"Anonymous Usage Reporting": "Анонімна статистика використання",
|
||||
"Anonymous Usage Reporting": "Анонімізована статистика використання",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "Змінився формат анонімного звіту про користування. Бажаєте перейти на новий формат?",
|
||||
"Applied to LAN": "Застосовано до LAN",
|
||||
"Apply": "Застосувати",
|
||||
"Are you sure you want to override all remote changes?": "Ви впевнені, що бажаєте відхилити всі зміни у віддалених папках?",
|
||||
"Are you sure you want to permanently delete all these files?": "Ви впевнені, що бажаєте остаточно видалити всі ці файли?",
|
||||
@@ -35,12 +38,13 @@
|
||||
"Are you sure you want to remove folder {%label%}?": "Ви впевнені, що хочете видалити папку {{label}}?",
|
||||
"Are you sure you want to restore {%count%} files?": "Чи ви впевнені в необхідності відновити наступну к-сть файлів: {{count}} ?",
|
||||
"Are you sure you want to revert all local changes?": "Ви впевнені, що бажаєте відкинути всі локальні зміни?",
|
||||
"Are you sure you want to upgrade?": "Впевнені, що хочете оновитися?",
|
||||
"Are you sure you want to upgrade?": "Напевно хочете оновити?",
|
||||
"Authentication Required": "Потрібна авторизація",
|
||||
"Authors": "Автори",
|
||||
"Auto Accept": "Автоприймання",
|
||||
"Automatic Crash Reporting": "Автоматичне звітування про збої",
|
||||
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Автоматиче оновлення зараз дозволяє обирати між стабільними випусками та реліз-кандидатами.",
|
||||
"Automatic upgrades": "Автоматичні оновлення",
|
||||
"Automatic upgrades": "Автоматичне оновлення",
|
||||
"Automatic upgrades are always enabled for candidate releases.": "Автоматичні оновлення завжди увімкнені для реліз-кандидатів.",
|
||||
"Automatically create or share folders that this device advertises at the default path.": "Автоматично створювати або поширювати каталоги, які цей пристрій декларує як створені по замовчанню.",
|
||||
"Available debug logging facilities:": "Доступні засоби журналу для відладки:",
|
||||
@@ -62,6 +66,7 @@
|
||||
"Configured": "Налаштовано",
|
||||
"Connected (Unused)": "Під'єднано (не використовується)",
|
||||
"Connection Error": "Помилка з’єднання",
|
||||
"Connection Management": "Керування з'єднанням",
|
||||
"Connection Type": "Тип з'єднання",
|
||||
"Connections": "З'єднання",
|
||||
"Connections via relays might be rate limited by the relay": "Швидкість з’єднання через реле може бути обмежена ним",
|
||||
@@ -73,9 +78,10 @@
|
||||
"Copy failed! Try to select and copy manually.": "Помилка копіювання! Спробуйте вибрати та скопіювати вручну.",
|
||||
"Currently Shared With Devices": "На даний момент є спільний доступ пристроїв",
|
||||
"Custom Range": "Вибрати діапазон",
|
||||
"Danger!": "Небезпечно!",
|
||||
"Danger!": "Небезпека!",
|
||||
"Database Location": "Місцезнаходження бази даних",
|
||||
"Debugging Facilities": "Засоби відладки",
|
||||
"Default": "За замовчанням",
|
||||
"Default Configuration": "Конфігурація за замовчуванням",
|
||||
"Default Device": "Пристрій за замовчуванням",
|
||||
"Default Folder": "Папка за замовчуванням",
|
||||
@@ -93,6 +99,7 @@
|
||||
"Device ID": "ID пристрою",
|
||||
"Device Identification": "Ідентифікатор пристрою",
|
||||
"Device Name": "Назва пристрою",
|
||||
"Device Status": "Статус пристрою",
|
||||
"Device is untrusted, enter encryption password": "Пристрій ненадійний, введіть пароль для шифрування",
|
||||
"Device rate limits": "Обмеження пристрою",
|
||||
"Device that last modified the item": "Пристрій, що останнім змінив елемент",
|
||||
@@ -103,7 +110,7 @@
|
||||
"Disabled periodic scanning and enabled watching for changes": "Відключено періодичне сканування та увімкнене стеження за змінами",
|
||||
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "Відключено періодичне сканування та не вдається налаштувати перегляд змін, повторення кожну 1 хв:",
|
||||
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "Вимикає порівняння та синхронізацію дозволів на файли. Корисно для систем з відсутніми або особливими дозволами (наприклад: FAT, exFAT, Synology, Android).",
|
||||
"Discard": "Відхилити",
|
||||
"Discard": "Відхили",
|
||||
"Disconnected": "З’єднання відсутнє",
|
||||
"Disconnected (Inactive)": "Від'єднаний (неактивний)",
|
||||
"Disconnected (Unused)": "Від'єднано (не використовується)",
|
||||
@@ -119,8 +126,8 @@
|
||||
"Documentation": "Документація",
|
||||
"Download Rate": "Швидкість завантаження",
|
||||
"Downloaded": "Завантажено",
|
||||
"Downloading": "Завантаження",
|
||||
"Edit": "Редагувати",
|
||||
"Downloading": "Завантажується",
|
||||
"Edit": "Редагуй",
|
||||
"Edit Device": "Налаштування пристрою",
|
||||
"Edit Device Defaults": "Редагувати параметри пристрою за замовчуванням",
|
||||
"Edit Folder": "Налаштування папки",
|
||||
@@ -141,6 +148,7 @@
|
||||
"Enter up to three octal digits.": "Введіть до трьох вісімкових цифр.",
|
||||
"Error": "Помилка",
|
||||
"Extended Attributes": "Розширені атрибути",
|
||||
"Extended Attributes Filter": "Фільтр за розширеними атрибутами",
|
||||
"External": "Зовнішній",
|
||||
"External File Versioning": "Зовнішне керування версіями",
|
||||
"Failed Items": "Невдалі",
|
||||
@@ -161,6 +169,7 @@
|
||||
"Folder ID": "ID папки",
|
||||
"Folder Label": "Назва папки",
|
||||
"Folder Path": "Шлях до папки",
|
||||
"Folder Status": "Статус папки",
|
||||
"Folder Type": "Тип папки",
|
||||
"Folder type \"{%receiveEncrypted%}\" can only be set when adding a new folder.": "Тип папки \"{{receiveEncrypted}}\" можна встановити лише під час додавання нової папки.",
|
||||
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Тип папки \"{{receiveEncrypted}}\" не можна змінити після її додавання. Потрібно видалити її спочатку, далі видалити або розшифрувати дані на диску, а потім додати папку знову.",
|
||||
@@ -182,6 +191,7 @@
|
||||
"Global Discovery Servers": "Сервери глобального виявлення",
|
||||
"Global State": "Глобальний статус",
|
||||
"Help": "Допомога",
|
||||
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "Підказка: додано лише забороняючі правила при тому, що \"заборонити\" дія за замовченням. Розважте додавання \"дозволити будь-яке\" як останнє правило.",
|
||||
"Home page": "Домашня сторінка",
|
||||
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Однак ваші поточні налаштування вказують, що ви, можливо, не хочете, щоб це було ввімкнено. Ми вимкнули автоматичне повідомлення про аварійне завершення роботи.",
|
||||
"Identification": "Ідентифікатор",
|
||||
@@ -197,9 +207,11 @@
|
||||
"Included Software": "Включене ПЗ",
|
||||
"Incoming Rate Limit (KiB/s)": "Ліміт швидкості завантаження (КіБ/с)",
|
||||
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Невірна конфігурація може пошкодити вміст вашої папки та зробити Syncthing недієздатним.",
|
||||
"Incorrect user name or password.": "Невірний логін або пароль.",
|
||||
"Internally used paths:": "Шляхи, що використовуються внутрішньо:",
|
||||
"Introduced By": "Рекомендовано",
|
||||
"Introducer": "Рекомендувач",
|
||||
"Introduction": "Введення",
|
||||
"Inversion of the given condition (i.e. do not exclude)": "Інверсія поточної умови (тобто не виключає)",
|
||||
"Keep Versions": "Зберігати версії",
|
||||
"LDAP": "LDAP",
|
||||
@@ -225,11 +237,18 @@
|
||||
"Locally Changed Items": "Локально змінені об'єкти",
|
||||
"Log": "Журнал",
|
||||
"Log File": "Файл журналу",
|
||||
"Log In": "Увійти",
|
||||
"Log Out": "Вийти",
|
||||
"Log in to see paths information.": "Увійдіть щоб отримати інформацію о шляхах.",
|
||||
"Log in to see version information.": "Увійдіть щоб отримати інформацію про версії.",
|
||||
"Log tailing paused. Scroll to the bottom to continue.": "Промотування журналу призупинене. Прокрутіть нижче, щоби продовжити.",
|
||||
"Login failed, see Syncthing logs for details.": "Вхід не завершено, перевірьте деталі у логах Syncthing.",
|
||||
"Logs": "Журнали",
|
||||
"Major Upgrade": "Мажорне оновлення",
|
||||
"Mass actions": "Масові операції",
|
||||
"Maximum Age": "Максимальний вік",
|
||||
"Maximum single entry size": "Максимальний розмір одного запису",
|
||||
"Maximum total size": "Максимальний загальний розмір",
|
||||
"Metadata Only": "Тільки метадані",
|
||||
"Minimum Free Disk Space": "Мінімальний вільний простір на диску",
|
||||
"Mod. Device": "Модифікований пристрій:",
|
||||
@@ -241,14 +260,16 @@
|
||||
"Multi level wildcard (matches multiple directory levels)": "Багаторівнева маска (пошук збігів в усіх піддиректоріях) ",
|
||||
"Never": "Ніколи",
|
||||
"New Device": "Новий пристрій",
|
||||
"New Folder": "Нова директорія",
|
||||
"New Folder": "Нова папка",
|
||||
"Newest First": "Спершу новіші",
|
||||
"No": "Ні",
|
||||
"No File Versioning": "Версіювання вимкнено",
|
||||
"No files will be deleted as a result of this operation.": "В результаті цієї операції не було видалено жодного файлу.",
|
||||
"No rules set": "Не вказано правила",
|
||||
"No upgrades": "Немає оновлень",
|
||||
"Not shared": "Не розповсюджується",
|
||||
"Notice": "Зауваження",
|
||||
"Number of Connections": "Кількість З'єднань",
|
||||
"OK": "Гаразд",
|
||||
"Off": "Вимкнути",
|
||||
"Oldest First": "Спершу старіші",
|
||||
@@ -260,6 +281,7 @@
|
||||
"Override": "Перевизначити",
|
||||
"Override Changes": "Розіслати мою версію",
|
||||
"Ownership": "Права власності",
|
||||
"Password": "Пароль",
|
||||
"Path": "Шлях",
|
||||
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Шлях до папки на локальному комп’ютері. Буде створений, якщо не існує. Символ тильди (~) може бути використаний як ярлик для",
|
||||
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Шлях, де повинні зберігатися версії (залиште порожнім для зберігання в .stversions усередині директорії)",
|
||||
@@ -293,11 +315,11 @@
|
||||
"Reduced by ignore patterns": "Зменшено шаблонами ігнорування",
|
||||
"Relay LAN": "LAN реле",
|
||||
"Relay WAN": "WAN реле",
|
||||
"Release Notes": "Примітки до випуску",
|
||||
"Release Notes": "Перелік Змін",
|
||||
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Реліз-кандидати містять найостанніші функції та виправлення. Вони схожі на традиційні щодвотижневі випуски Syncthing.",
|
||||
"Remote Devices": "Віддалені пристрої",
|
||||
"Remote GUI": "Віддалена панель керування",
|
||||
"Remove": "Видалити",
|
||||
"Remove": "Видали",
|
||||
"Remove Device": "Видалити пристрій",
|
||||
"Remove Folder": "Видалити папку",
|
||||
"Required identifier for the folder. Must be the same on all cluster devices.": "Обов'язковий унікальний ідентифікатор папки. Має бути однаковим на усіх пристроях кластеру.",
|
||||
@@ -314,7 +336,8 @@
|
||||
"Reused": "Використано вдруге",
|
||||
"Revert": "Повернути",
|
||||
"Revert Local Changes": "Інвертувати локальні зміни",
|
||||
"Save": "Зберегти",
|
||||
"Save": "Збережи",
|
||||
"Saving changes": "Збереження змін",
|
||||
"Scan Time Remaining": "Час до кінця сканування",
|
||||
"Scanning": "Сканування",
|
||||
"See external versioning help for supported templated command line parameters.": "Дивіться допомогу по зовнішньому версіюванню, щоб дізнатися підтримувані шаблони для параметрів командного рядка.",
|
||||
@@ -363,6 +386,7 @@
|
||||
"Staggered File Versioning": "Поступове версіювання",
|
||||
"Start Browser": "Запустити браузер",
|
||||
"Statistics": "Статистика",
|
||||
"Stay logged in": "Не виходити",
|
||||
"Stopped": "Зупинено",
|
||||
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Зберігає та синхронізує лише зашифровані дані. Папки на всіх під’єднаних пристроях мають бути налаштовані з однаковим паролем або ще мати тип \"{{receiveEncrypted}}\".",
|
||||
"Subject:": "Тема:",
|
||||
@@ -381,6 +405,7 @@
|
||||
"Syncthing is listening on the following network addresses for connection attempts from other devices:": "Syncthing прослуховує такі мережеві адреси на предмет спроб підключення з інших пристроїв:",
|
||||
"Syncthing is not listening for connection attempts from other devices on any address. Only outgoing connections from this device may work.": "Syncthing не прослуховує спроби підключення від інших пристроїв із жодних адрес. Можуть працювати лише вихідні з’єднання з цього пристрою.",
|
||||
"Syncthing is restarting.": "Syncthing перезавантажується.",
|
||||
"Syncthing is saving changes.": "Syncthing записує зміни.",
|
||||
"Syncthing is upgrading.": "Syncthing оновлюється.",
|
||||
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing тепер підтримує автоматичне звітування розобникам про збої. Ця функція увімкнена за умовчанням.",
|
||||
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Схоже на те, що Syncthing закритий, або виникла проблема із Інтернет-з’єднанням. Проводиться повторна спроба з’єднання…",
|
||||
@@ -413,11 +438,13 @@
|
||||
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "Інтервал в секундах, для запуску очищення в директорії версій. Нуль вимикає періодичну очистку.",
|
||||
"The maximum age must be a number and cannot be blank.": "Максимальний термін повинен бути числом та не може бути пустим.",
|
||||
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Максимальний термін зберігання версії (у днях; впишіть 0, щоб зберігати версії без обмежень).",
|
||||
"The number of connections must be a non-negative number.": "Кількість з'єднань має бути додатнім числом.",
|
||||
"The number of days must be a number and cannot be blank.": "Кількість днів має бути числом і не може бути порожнім.",
|
||||
"The number of days to keep files in the trash can. Zero means forever.": "Кількість днів зберігання файлів у кошику. Нуль означає назавжди.",
|
||||
"The number of old versions to keep, per file.": "Кількість старих версій, яку необхідно зберігати для кожного файлу.",
|
||||
"The number of versions must be a number and cannot be blank.": "Кількість версій повинна бути цифрою та не може бути порожньою.",
|
||||
"The path cannot be blank.": "Шлях не може бути порожнім.",
|
||||
"The rate limit is applied to the accumulated traffic of all connections to this device.": "Обмеження швидкості накладається на сумарний трафік всіх під'єднань до цього пристрою.",
|
||||
"The rate limit must be a non-negative number (0: no limit)": "Швидкість має бути додатнім числом.",
|
||||
"The remote device has not accepted sharing this folder.": "Віддалений пристрій не прийняв спільний доступ до цієї папки.",
|
||||
"The remote device has paused this folder.": "Віддалений пристрій призупинив синхронізацію цієї папки.",
|
||||
@@ -435,6 +462,7 @@
|
||||
"Time": "Час",
|
||||
"Time the item was last modified": "Час останньої зміни елемента:",
|
||||
"To connect with the Syncthing device named \"{%devicename%}\", add a new remote device on your end with this ID:": "Щоб підключитися до пристрою Syncthing з назвою \"{{devicename}}\", додайте новий віддалений пристрій із свого боку за цим ID:",
|
||||
"To permit a rule, have the checkbox checked. To deny a rule, leave it unchecked.": "Аби застосувати правило, зазначте поле. Аби відмінити правило, залишить поле порожнім.",
|
||||
"Today": "Сьогодні",
|
||||
"Trash Can": "Смітник",
|
||||
"Trash Can File Versioning": "Версіювання файлів у кошику",
|
||||
@@ -461,8 +489,11 @@
|
||||
"Usage reporting is always enabled for candidate releases.": "Звіти про користування завжди увімкнені для реліз-кандидатів.",
|
||||
"Use HTTPS for GUI": "Використовувати HTTPS для доступу до панелі керування",
|
||||
"Use notifications from the filesystem to detect changed items.": "Використовувати сповіщення від файлової системи для виявлення змінених об'єктів.",
|
||||
"User": "Користувач",
|
||||
"User Home": "Домашня директорія користувача",
|
||||
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "Логін/пароль не встановлені для автентифікації в панелі керування. Будь ласка, налаштуйте їх.",
|
||||
"Using a QUIC connection over LAN": "З використанням QUICK з'єднання у LAN",
|
||||
"Using a QUIC connection over WAN": "З використанням QUICK з'єднання у WAN",
|
||||
"Using a direct TCP connection over LAN": "Використовується пряме TCP-з'єднання через локальну мережу",
|
||||
"Using a direct TCP connection over WAN": "Використовується пряме TCP-з'єднання через глобальну мережу",
|
||||
"Version": "Версія",
|
||||
@@ -483,6 +514,7 @@
|
||||
"Watching for changes discovers most changes without periodic scanning.": "Моніторинг виявляє більшість змін без періодичного сканування.",
|
||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Коли додаєте новий вузол, пам’ятайте, що цей вузол повинен бути доданий і на іншій стороні.",
|
||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Коли додаєте нову папку, пам’ятайте, що її ID дозволяє зв’язувати папки разом на різних пристроях. Назви повинні точно збігатися між усіма пристроями, а регістр символів має значення.",
|
||||
"When set to more than one on both devices, Syncthing will attempt to establish multiple concurrent connections. If the values differ, the highest will be used. Set to zero to let Syncthing decide.": "Коли вказано більше ніш одне на обох пристроях, Syncthing спробує встановити паралельні з'єднання. Якщо значення різняться, буде використано найбільше. Вкажіть 0 аби Syncthing обрав .",
|
||||
"Yes": "Так",
|
||||
"Yesterday": "Вчора",
|
||||
"You can also copy and paste the text into a new message manually.": "Ви також можете скопіювати та вставити текст у нове повідомлення вручну.",
|
||||
@@ -498,6 +530,7 @@
|
||||
"Your email app should open to let you choose the recipient and send it from your own address.": "Ваш додаток електронної пошти має відкритися, щоб ви могли вибрати одержувача та надіслати його зі своєї власної адреси.",
|
||||
"days": "днів",
|
||||
"deleted": "видалено",
|
||||
"deny": "заборонити",
|
||||
"directories": "директорії",
|
||||
"file": "файл",
|
||||
"files": "файли",
|
||||
@@ -505,6 +538,7 @@
|
||||
"full documentation": "повна документація",
|
||||
"items": "елементи",
|
||||
"modified": "змінено",
|
||||
"permit": "дозволь",
|
||||
"seconds": "секунд",
|
||||
"theme": {
|
||||
"name": {
|
||||
@@ -514,6 +548,7 @@
|
||||
"light": "Світла"
|
||||
}
|
||||
},
|
||||
"unknown device": "невідомий пристрій",
|
||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} хоче поділитися папкою \"{{folder}}\".",
|
||||
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} хоче поділитися папкою \"{{folderLabel}}\" ({{folder}}).",
|
||||
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} може повторно порекомендувати цей пристрій."
|
||||
|
||||
@@ -26,14 +26,20 @@
|
||||
"Allow Anonymous Usage Reporting?": "允許回報匿名數據?",
|
||||
"Allowed Networks": "允許的網路",
|
||||
"Alphabetic": "字母順序",
|
||||
"Altered by ignoring deletes.": "透過忽略刪除動作進行變更。",
|
||||
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "外部指令接管了版本控制。它必須將檔案自分享資料夾中移除。如果應用程式的路徑包含了空格,則必須使用雙引號刮起。",
|
||||
"Anonymous Usage Reporting": "匿名數據回報",
|
||||
"Anonymous usage report format has changed. Would you like to move to the new format?": "匿名數據回報格式已經變更,想要移至新格式嗎?",
|
||||
"Applied to LAN": "套用至區域網路",
|
||||
"Apply": "套用",
|
||||
"Are you sure you want to override all remote changes?": "您確定要覆蓋所有遠端的變更嗎?",
|
||||
"Are you sure you want to permanently delete all these files?": "確認永久刪除檔案?",
|
||||
"Are you sure you want to remove device {%name%}?": "確定要移除 {{name}} 裝置?",
|
||||
"Are you sure you want to remove folder {%label%}?": "確定要移除 {{label}} 資料夾?",
|
||||
"Are you sure you want to restore {%count%} files?": "確定想要還原 {{count}} 個檔案?",
|
||||
"Are you sure you want to revert all local changes?": "您確定要還原所有本地的變更嗎?",
|
||||
"Are you sure you want to upgrade?": "確定想要更新?",
|
||||
"Authentication Required": "需要驗證",
|
||||
"Authors": "作者群",
|
||||
"Auto Accept": "自動接受",
|
||||
"Automatic Crash Reporting": "自動回傳當機報告",
|
||||
@@ -43,6 +49,7 @@
|
||||
"Automatically create or share folders that this device advertises at the default path.": "自動在預設資料夾路徑建立或分享該裝置推薦的資料夾。",
|
||||
"Available debug logging facilities:": "可用的除錯日誌工具:",
|
||||
"Be careful!": "請小心!",
|
||||
"Body:": "內文:",
|
||||
"Bugs": "程式錯誤",
|
||||
"Cancel": "取消",
|
||||
"Changelog": "更新日誌",
|
||||
@@ -54,6 +61,8 @@
|
||||
"Command": "指令",
|
||||
"Comment, when used at the start of a line": "註解,當輸入在一行的開頭時",
|
||||
"Compression": "壓縮",
|
||||
"Configuration Directory": "設定檔目錄",
|
||||
"Configuration File": "設定檔",
|
||||
"Configured": "已設定",
|
||||
"Connected (Unused)": "已連線(未使用)",
|
||||
"Connection Error": "連線錯誤",
|
||||
@@ -68,8 +77,11 @@
|
||||
"Copy": "複製",
|
||||
"Copy failed! Try to select and copy manually.": "複製失敗!嘗試手動選擇並複製。",
|
||||
"Currently Shared With Devices": "目前與裝置共享",
|
||||
"Custom Range": "自訂範圍",
|
||||
"Danger!": "危險!",
|
||||
"Database Location": "資料庫位置",
|
||||
"Debugging Facilities": "除錯工具",
|
||||
"Default": "預設",
|
||||
"Default Configuration": "預設配置",
|
||||
"Default Device": "預設裝置",
|
||||
"Default Folder": "預設資料夾",
|
||||
@@ -83,9 +95,11 @@
|
||||
"Deselect folders to stop sharing with this device.": "取消選擇資料夾以停用與此裝置共享。",
|
||||
"Device": "裝置",
|
||||
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "裝置 \"{{name}}\" ({{device}} 位於 {{address}}) 想要連線。要添加新裝置嗎?",
|
||||
"Device Certificate": "裝置憑證",
|
||||
"Device ID": "裝置識別碼",
|
||||
"Device Identification": "裝置識別",
|
||||
"Device Name": "裝置名稱",
|
||||
"Device Status": "裝置狀態",
|
||||
"Device is untrusted, enter encryption password": "裝置不受信任,輸入加密密碼",
|
||||
"Device rate limits": "裝置速率限制",
|
||||
"Device that last modified the item": "前次修改裝置",
|
||||
@@ -134,8 +148,12 @@
|
||||
"Enter up to three octal digits.": "輸入最多三位八進位數字。",
|
||||
"Error": "錯誤",
|
||||
"Extended Attributes": "延伸屬性",
|
||||
"Extended Attributes Filter": "擴充屬性篩選器",
|
||||
"External": "外部",
|
||||
"External File Versioning": "外部的檔案版本控制",
|
||||
"Failed Items": "失敗的項目",
|
||||
"Failed to load file versions.": "無法載入檔案版本。",
|
||||
"Failed to load ignore patterns.": "無法載入忽略模式。",
|
||||
"Failed to setup, retrying": "無法設定,正在重試",
|
||||
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "若沒有 IPv6 連線能力,則無法連接 IPv6 伺服器為正常現象。",
|
||||
"File Pull Order": "提取檔案的順序",
|
||||
@@ -151,17 +169,21 @@
|
||||
"Folder ID": "資料夾識別碼",
|
||||
"Folder Label": "資料夾標籤",
|
||||
"Folder Path": "資料夾路徑",
|
||||
"Folder Status": "資料夾狀態",
|
||||
"Folder Type": "資料夾類型",
|
||||
"Folder type \"{%receiveEncrypted%}\" can only be set when adding a new folder.": "資料夾類型「{{receiveEncrypted}}」只能在新增資料夾時設定。",
|
||||
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "資料夾類型 \"{{receiveEncrypted}}\" 無法在新增後變更。您需要移除資料夾、刪除或解密磁碟上的資料,並再次新增資料夾。",
|
||||
"Folders": "資料夾",
|
||||
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "啟動監視下列資料夾時發生錯誤。由於每分鐘將進行重試,錯誤可能很快就消失。若錯誤仍存在,請嘗試修復潛在問題,或請求協助。",
|
||||
"Forever": "永遠",
|
||||
"Full Rescan Interval (s)": "完全重新掃描間隔 (秒)",
|
||||
"GUI": "GUI",
|
||||
"GUI / API HTTPS Certificate": "GUI / API HTTPS 憑證",
|
||||
"GUI Authentication Password": "GUI 驗證密碼",
|
||||
"GUI Authentication User": "GUI 驗證使用者名稱",
|
||||
"GUI Authentication: Set User and Password": "GUI 驗證:設定使用者名稱與密碼",
|
||||
"GUI Listen Address": "GUI 監聽位址",
|
||||
"GUI Override Directory": "GUI 覆蓋目錄",
|
||||
"GUI Theme": "主題",
|
||||
"General": "一般",
|
||||
"Generate": "產生",
|
||||
@@ -169,6 +191,7 @@
|
||||
"Global Discovery Servers": "全域探索伺服器",
|
||||
"Global State": "全域狀態",
|
||||
"Help": "說明",
|
||||
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "提示:只偵測到拒絕規則,而預設為拒絕。請考慮在最後新增「允許所有」規則。",
|
||||
"Home page": "首頁",
|
||||
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "但是,當前設定表明您可能不希望啟用它。我們為您停用了當機自動回報。",
|
||||
"Identification": "識別碼",
|
||||
@@ -184,18 +207,25 @@
|
||||
"Included Software": "包含的軟體",
|
||||
"Incoming Rate Limit (KiB/s)": "傳入速率限制 (KiB/s)",
|
||||
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "不正確的設定可能會損壞您的資料夾內容,並導致 Syncthing 不正常運作。",
|
||||
"Incorrect user name or password.": "使用者名稱或密碼不正確。",
|
||||
"Internally used paths:": "內部使用的路徑:",
|
||||
"Introduced By": "引入自",
|
||||
"Introducer": "引入者",
|
||||
"Introduction": "介紹",
|
||||
"Inversion of the given condition (i.e. do not exclude)": "反轉給定條件 (即:不要排除)",
|
||||
"Keep Versions": "保留歷史版本數",
|
||||
"LDAP": "LDAP",
|
||||
"Largest First": "最大的優先",
|
||||
"Last 30 Days": "過去 30 天",
|
||||
"Last 7 Days": "過去 7 天",
|
||||
"Last Month": "上個月",
|
||||
"Last Scan": "最後掃描",
|
||||
"Last seen": "最後發現時間",
|
||||
"Latest Change": "最近變動",
|
||||
"Learn more": "瞭解更多",
|
||||
"Learn more at {%url%}": "在 {{url}} 了解更多",
|
||||
"Limit": "限制",
|
||||
"Listener Failures": "監聽器失敗",
|
||||
"Listener Status": "監聽狀態",
|
||||
"Listeners": "監聽者",
|
||||
"Loading data...": "正在載入資料...",
|
||||
@@ -206,11 +236,19 @@
|
||||
"Local State (Total)": "本機狀態 (總結)",
|
||||
"Locally Changed Items": "本地變動項目",
|
||||
"Log": "日誌",
|
||||
"Log File": "日誌檔案",
|
||||
"Log In": "登入",
|
||||
"Log Out": "登出",
|
||||
"Log in to see paths information.": "登入以檢視路徑資訊。",
|
||||
"Log in to see version information.": "登入以檢視版本資訊。",
|
||||
"Log tailing paused. Scroll to the bottom to continue.": "日誌自動滾動已暫停。滾動到底部以繼續。",
|
||||
"Login failed, see Syncthing logs for details.": "登入失敗,請檢視 Syncthing 日誌以取得詳細資訊。",
|
||||
"Logs": "日誌",
|
||||
"Major Upgrade": "重大更新",
|
||||
"Mass actions": "大量操作",
|
||||
"Maximum Age": "最長保留時間",
|
||||
"Maximum single entry size": "單一檔案大小上限",
|
||||
"Maximum total size": "總空間上限",
|
||||
"Metadata Only": "僅中繼資料",
|
||||
"Minimum Free Disk Space": "最少閒置磁碟空間",
|
||||
"Mod. Device": "修改裝置",
|
||||
@@ -227,6 +265,7 @@
|
||||
"No": "否",
|
||||
"No File Versioning": "無檔案版本控制",
|
||||
"No files will be deleted as a result of this operation.": "此操作將不會移除您的檔案。",
|
||||
"No rules set": "未設定規則",
|
||||
"No upgrades": "不更新",
|
||||
"Not shared": "未共享",
|
||||
"Notice": "注意",
|
||||
@@ -239,8 +278,10 @@
|
||||
"Out of Sync": "未同步",
|
||||
"Out of Sync Items": "未同步項目",
|
||||
"Outgoing Rate Limit (KiB/s)": "連出速率限制 (KiB/s)",
|
||||
"Override": "覆蓋",
|
||||
"Override Changes": "覆蓋變動",
|
||||
"Ownership": "所有權",
|
||||
"Password": "密碼",
|
||||
"Path": "路徑",
|
||||
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "資料夾在本機的路徑。若資料夾不存在則會建立。波浪符號 (~) 可用作下列資料夾的捷徑:",
|
||||
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "儲存歷史版本的路徑(共享資料夾中的預設 .stversions 目錄則留白)。",
|
||||
@@ -262,6 +303,7 @@
|
||||
"Preparing to Sync": "正在準備同步",
|
||||
"Preview": "預覽",
|
||||
"Preview Usage Report": "預覽數據報告",
|
||||
"QR code": "QR 碼",
|
||||
"QUIC LAN": "QUIC 區域網路",
|
||||
"QUIC WAN": "QUIC 廣域網路",
|
||||
"Quick guide to supported patterns": "可支援樣式的快速指南",
|
||||
@@ -292,8 +334,10 @@
|
||||
"Resume": "繼續",
|
||||
"Resume All": "全部繼續",
|
||||
"Reused": "重用",
|
||||
"Revert": "還原",
|
||||
"Revert Local Changes": "撤銷本機變更",
|
||||
"Save": "儲存",
|
||||
"Saving changes": "正在儲存變更",
|
||||
"Scan Time Remaining": "剩餘掃描時間",
|
||||
"Scanning": "正在掃描",
|
||||
"See external versioning help for supported templated command line parameters.": "查看關於命令列模板參數請參閱外部版本管理說明。",
|
||||
@@ -307,6 +351,7 @@
|
||||
"Send Extended Attributes": "傳送延伸屬性",
|
||||
"Send Only": "僅傳送",
|
||||
"Send Ownership": "傳送所有權",
|
||||
"Set Ignores on Added Folder": "在新增的資料夾上設定忽略",
|
||||
"Settings": "設定",
|
||||
"Share": "共享",
|
||||
"Share Folder": "共享資料夾",
|
||||
@@ -325,21 +370,26 @@
|
||||
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "代替裝置識別碼顯示在叢集狀態中。本欄若未填寫則將被更新為此裝置所廣播的名稱。",
|
||||
"Shutdown": "關閉",
|
||||
"Shutdown Complete": "關閉完成",
|
||||
"Simple": "簡單",
|
||||
"Simple File Versioning": "簡單檔案版本控制",
|
||||
"Single level wildcard (matches within a directory only)": "單階層萬用字元 (只在單個資料夾階層內比對)",
|
||||
"Size": "大小",
|
||||
"Smallest First": "最小的優先",
|
||||
"Some discovery methods could not be established for finding other devices or announcing this device:": "無法建立一些探索方式來尋找其他裝置或宣佈此裝置:",
|
||||
"Some items could not be restored:": "有些項目無法被還原:",
|
||||
"Some listening addresses could not be enabled to accept connections:": "某些監聽地址無法啟用以接受連線:",
|
||||
"Source Code": "原始碼",
|
||||
"Stable releases and release candidates": "穩定版及候選發行版",
|
||||
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "穩定版大約延遲兩週發佈。這段期間將作為候選發行版來測試。",
|
||||
"Stable releases only": "僅穩定發行版",
|
||||
"Staggered": "分階段",
|
||||
"Staggered File Versioning": "變動式檔案版本控制",
|
||||
"Start Browser": "啟動瀏覽器",
|
||||
"Statistics": "統計",
|
||||
"Stay logged in": "保持登入",
|
||||
"Stopped": "已停止",
|
||||
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "僅儲存並同步已加密的資料。所有位於已連接裝置上的資料夾,必須設定相同的密碼,或屬於 \"{{receiveEncrypted}}\" 類型。",
|
||||
"Subject:": "主旨:",
|
||||
"Support": "支援",
|
||||
"Support Bundle": "支援包",
|
||||
"Sync Extended Attributes": "同步延伸屬性",
|
||||
@@ -347,14 +397,18 @@
|
||||
"Sync Protocol Listen Addresses": "同步通訊協定監聽位址",
|
||||
"Sync Status": "同步狀態",
|
||||
"Syncing": "正在同步",
|
||||
"Syncthing device ID for \"{%devicename%}\"": "「{{devicename}}」的 Syncthing 裝置 ID",
|
||||
"Syncthing has been shut down.": "Syncthing 已經關閉。",
|
||||
"Syncthing includes the following software or portions thereof:": "Syncthing 包括以下軟體或其中的一部分:",
|
||||
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing 為自由且開源授權條款為 MPL v2.0。",
|
||||
"Syncthing is a continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it's transmitted over the internet.": "Syncthing 是一個連續檔案同步程式。它能安全、即時地同步多台裝置之間的檔案,保護檔案免於窺視。您的資料只屬於您自己,您有權選擇將其儲存在何處,決定是否與第三方共享,以及該如何透過網路傳輸。",
|
||||
"Syncthing is listening on the following network addresses for connection attempts from other devices:": "Syncthing 正在以下的網路位址上監聽來自其他設備的連接嘗試:",
|
||||
"Syncthing is not listening for connection attempts from other devices on any address. Only outgoing connections from this device may work.": "Syncthing 不會主動接受其他裝置的發起的連線,只會從此裝置對外發起連線。",
|
||||
"Syncthing is restarting.": "Syncthing 正在重新啟動。",
|
||||
"Syncthing is saving changes.": "Syncthing 正在儲存變更。",
|
||||
"Syncthing is upgrading.": "Syncthing 正在進行升級。",
|
||||
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing 已支援將當機報告回傳至開發者。此功能預設為啟用。",
|
||||
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing 似乎離線了,或者您的網際網路連線出現問題。正在重試...",
|
||||
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing 似乎離線了,或者您的網際網路連線出現問題。正在重試…",
|
||||
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing 在處理您的請求時似乎遇到了問題。請重新整理本頁面,若問題持續發生,請重新啟動 Syncthing。",
|
||||
"TCP LAN": "TCP 區域網路",
|
||||
"TCP WAN": "TCP 廣域網路",
|
||||
@@ -371,16 +425,20 @@
|
||||
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "輸入的裝置識別碼似乎無效。它應該為一串長度為 52 或 56 個字元長的半形英文字母及數字,並可能會含有額外的空白或連接符號。",
|
||||
"The folder ID cannot be blank.": "資料夾識別碼不能為空白。",
|
||||
"The folder ID must be unique.": "資料夾識別碼必須為獨一無二的。",
|
||||
"The folder content on other devices will be overwritten to become identical with this device. Files not present here will be deleted on other devices.": "其他裝置上的資料夾內容將被覆蓋以與此裝置相同。這裡不存在的檔案將在其他裝置上被刪除。",
|
||||
"The folder content on this device will be overwritten to become identical with other devices. Files newly added here will be deleted.": "此裝置上的資料夾內容將被覆蓋以與其他裝置相同。這裡新增的檔案將被刪除。",
|
||||
"The folder path cannot be blank.": "資料夾路徑不能空白。",
|
||||
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "使用下列的間隔:在第一個小時內每 30 秒保留一個版本,在第一天內每小時保留一個版本,在第 30 天內每一天保留一個版本,在達到最長保留時間前每一星期保留一個版本。",
|
||||
"The following items could not be synchronized.": "無法同步以下項目。",
|
||||
"The following items were changed locally.": "以下項目在本機進行了變更。",
|
||||
"The following methods are used to discover other devices on the network and announce this device to be found by others:": "以下方式被用來探索網路上的其他裝置以及宣佈此裝置,被其他裝置探索",
|
||||
"The following methods are used to discover other devices on the network and announce this device to be found by others:": "以下方式被用來探索網路上的其他裝置以及宣告此裝置以被其他裝置探索:",
|
||||
"The following text will automatically be inserted into a new message.": "以下文字將自動插入到新訊息中。",
|
||||
"The following unexpected items were found.": "找到以下不預期項目。",
|
||||
"The interval must be a positive number of seconds.": "間隔秒數必須為正數。",
|
||||
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "間隔,以秒為單位,執行清除歷史版本目錄。如欲停用週期清除,設 0 。",
|
||||
"The maximum age must be a number and cannot be blank.": "最長保留時間必須為一個數字且不得為空。",
|
||||
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "一個版本被保留的最長時間 (單位為天,若設定為 0 則表示永遠保留)。",
|
||||
"The number of connections must be a non-negative number.": "連線數量必須為正整數。",
|
||||
"The number of days must be a number and cannot be blank.": "天數必須必須為一個數字且不得為空。",
|
||||
"The number of days to keep files in the trash can. Zero means forever.": "檔案在垃圾筒中保留的天數。零表示永遠地保留。",
|
||||
"The number of old versions to keep, per file.": "每個檔案要保留的舊版本數量。",
|
||||
@@ -392,14 +450,21 @@
|
||||
"The remote device has paused this folder.": "遠端裝置已暫停同步此資料夾。",
|
||||
"The rescan interval must be a non-negative number of seconds.": "重新掃描間隔必須為一個非負數的秒數。",
|
||||
"There are no devices to share this folder with.": "沒有裝置可以共享此資料夾。",
|
||||
"There are no file versions to restore.": "沒有檔案版本可以還原。",
|
||||
"There are no folders to share with this device.": "沒有資料夾分享給此裝置。",
|
||||
"They are retried automatically and will be synced when the error is resolved.": "解決問題後,將會自動重試和同步。",
|
||||
"This Device": "本機",
|
||||
"This Month": "本月",
|
||||
"This can easily give hackers access to read and change any files on your computer.": "這能給駭客輕易的來讀取、變更電腦中的任何檔案。",
|
||||
"This device cannot automatically discover other devices or announce its own address to be found by others. Only devices with statically configured addresses can connect.": "此裝置無法自動尋找其他裝置,或公開自身地址讓其他裝置找到。只有設定了固定位址的裝置才能進行連線。",
|
||||
"This is a major version upgrade.": "這是一個重大版本更新。",
|
||||
"This setting controls the free space required on the home (i.e., index database) disk.": "此設定控制家目錄(即:索引資料庫)的必須可用空間。",
|
||||
"Time": "時間",
|
||||
"Time the item was last modified": "前次修改時間",
|
||||
"To connect with the Syncthing device named \"{%devicename%}\", add a new remote device on your end with this ID:": "要連線名稱為「{{devicename}}」的 Syncthing 裝置,請在您的端點新增一個具有此 ID 的新遠端裝置:",
|
||||
"To permit a rule, have the checkbox checked. To deny a rule, leave it unchecked.": "若要允許某項規則,請勾選該規則旁的選取匡。若要拒絕某項規則,則不要勾選其旁邊的選取匡。",
|
||||
"Today": "今天",
|
||||
"Trash Can": "垃圾桶",
|
||||
"Trash Can File Versioning": "垃圾筒式檔案版本控制",
|
||||
"Type": "類型",
|
||||
"UNIX Permissions": "UNIX 權限",
|
||||
@@ -424,6 +489,8 @@
|
||||
"Usage reporting is always enabled for candidate releases.": "候選發行版永遠啟用使用數據回報。",
|
||||
"Use HTTPS for GUI": "為 GUI 使用 HTTPS",
|
||||
"Use notifications from the filesystem to detect changed items.": "使用來自檔案系統的通知以檢測變動的項目。",
|
||||
"User": "使用者",
|
||||
"User Home": "使用者主目錄",
|
||||
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "尚未設定GUI 驗證的使用者名稱/密碼。請考慮進行設定。",
|
||||
"Using a QUIC connection over LAN": "通過區域網路使用 QUIC 連線",
|
||||
"Using a QUIC connection over WAN": "通過廣域網路使用 QUIC 連線",
|
||||
@@ -449,19 +516,29 @@
|
||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "當新增一個資料夾時,請記住,資料夾識別碼是用來將裝置之間的資料夾綁定在一起的。它們有區分大小寫,且必須在所有裝置之間完全相同。",
|
||||
"When set to more than one on both devices, Syncthing will attempt to establish multiple concurrent connections. If the values differ, the highest will be used. Set to zero to let Syncthing decide.": "當兩台裝置都設定為大於 1 時,Syncthing 會嘗試建立多個並行的連線。如果兩台裝置數值不同,最高的數值會被使用。設定為 0 以便讓 Syncthing 自行決定。",
|
||||
"Yes": "是",
|
||||
"Yesterday": "昨天",
|
||||
"You can also copy and paste the text into a new message manually.": "您也可以手動複製並貼上文字到新訊息中。",
|
||||
"You can also select one of these nearby devices:": "您亦可從這些附近裝置中擇一:",
|
||||
"You can change your choice at any time in the Settings dialog.": "您可以在設定對話框中隨時更改您的選擇。",
|
||||
"You can read more about the two release channels at the link below.": "您可於下方連結閱讀更多關於發行頻道的說明。",
|
||||
"You have no ignored devices.": "您沒有已忽略的裝置。\n",
|
||||
"You have no ignored folders.": "您沒有已忽略的資料夾。\n",
|
||||
"You have no ignored devices.": "您沒有已忽略的裝置。",
|
||||
"You have no ignored folders.": "您沒有已忽略的資料夾。",
|
||||
"You have unsaved changes. Do you really want to discard them?": "您有未儲存的變更。確認棄用嗎?",
|
||||
"You must keep at least one version.": "您必須保留至少一個版本。",
|
||||
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "您不應該在 \"{{receiveEncrypted}}\" 資料夾中新增或變更任何內容。",
|
||||
"Your SMS app should open to let you choose the recipient and send it from your own number.": "您的簡訊應用程式應該開啟,讓您選擇收件人並從您自己的號碼傳送。",
|
||||
"Your email app should open to let you choose the recipient and send it from your own address.": "您的電子郵件應用程式應該開啟,讓您選擇收件人並從您自己的地址傳送。",
|
||||
"days": "日",
|
||||
"deleted": "已刪除",
|
||||
"deny": "拒絕",
|
||||
"directories": "目錄",
|
||||
"file": "檔案",
|
||||
"files": "個檔案",
|
||||
"folder": "資料夾",
|
||||
"full documentation": "完整說明文件",
|
||||
"items": "個項目",
|
||||
"modified": "已修改",
|
||||
"permit": "允許",
|
||||
"seconds": "秒",
|
||||
"theme": {
|
||||
"name": {
|
||||
@@ -471,6 +548,7 @@
|
||||
"light": "淺色"
|
||||
}
|
||||
},
|
||||
"unknown device": "未知裝置",
|
||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 想要共享資料夾 \"{{folder}}\"。",
|
||||
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} 想要共享資料夾 \"{{folderlabel}}\" ({{folder}})。",
|
||||
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} 可能會重新引入此裝置。"
|
||||
|
||||
@@ -1 +1 @@
|
||||
var langPrettyprint = {"ar":"Arabic","bg":"Bulgarian","ca":"Catalan","ca@valencia":"Valencian","cs":"Czech","da":"Danish","de":"German","el":"Greek","en":"English","en-GB":"English (United Kingdom)","es":"Spanish","eu":"Basque","fr":"French","fy":"Frisian","hu":"Hungarian","id":"Indonesian","it":"Italian","ja":"Japanese","ko-KR":"Korean","lt":"Lithuanian","nl":"Dutch","pl":"Polish","pt-BR":"Portuguese (Brazil)","pt-PT":"Portuguese (Portugal)","ro-RO":"Romanian","ru":"Russian","sk":"Slovak","sl":"Slovenian","sv":"Swedish","tr":"Turkish","uk":"Ukrainian","zh-CN":"Chinese (Simplified)","zh-HK":"Chinese (Traditional, Hong Kong)","zh-TW":"Chinese (Traditional)"}
|
||||
var langPrettyprint = {"ar":"Arabic","bg":"Bulgarian","ca":"Catalan","ca@valencia":"Valencian","cs":"Czech","da":"Danish","de":"German","el":"Greek","en":"English","en-GB":"English (United Kingdom)","es":"Spanish","eu":"Basque","fr":"French","fy":"Frisian","hi":"Hindi","hu":"Hungarian","id":"Indonesian","it":"Italian","ja":"Japanese","ko-KR":"Korean","lt":"Lithuanian","nl":"Dutch","pl":"Polish","pt-BR":"Portuguese (Brazil)","pt-PT":"Portuguese (Portugal)","ro-RO":"Romanian","ru":"Russian","sk":"Slovak","sl":"Slovenian","sv":"Swedish","tr":"Turkish","uk":"Ukrainian","zh-CN":"Chinese (Simplified)","zh-HK":"Chinese (Traditional, Hong Kong)","zh-TW":"Chinese (Traditional)"}
|
||||
|
||||
@@ -1 +1 @@
|
||||
var validLangs = ["ar","bg","ca","ca@valencia","cs","da","de","el","en","en-GB","es","eu","fr","fy","hu","id","it","ja","ko-KR","lt","nl","pl","pt-BR","pt-PT","ro-RO","ru","sk","sl","sv","tr","uk","zh-CN","zh-HK","zh-TW"]
|
||||
var validLangs = ["ar","bg","ca","ca@valencia","cs","da","de","el","en","en-GB","es","eu","fr","fy","hi","hu","id","it","ja","ko-KR","lt","nl","pl","pt-BR","pt-PT","ro-RO","ru","sk","sl","sv","tr","uk","zh-CN","zh-HK","zh-TW"]
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="shortcut icon" href="assets/img/favicon-default.png" type="image/x-icon"/>
|
||||
<link rel="shortcut icon" href="assets/img/favicon-{{syncthingStatus()}}.png" type="image/x-icon"/>
|
||||
<link rel="shortcut icon" href="assets/img/favicon-default.png" ng-href="assets/img/favicon-{{syncthingStatus()}}.png" type="image/x-icon"/>
|
||||
<link rel="mask-icon" href="assets/img/safari-pinned-tab.svg" color="#0882c8"/>
|
||||
|
||||
<title ng-bind="thisDeviceName() + ' | Syncthing'"></title>
|
||||
@@ -404,9 +403,9 @@
|
||||
<span class="hidden-xs">{{folderStatusText(folder)}}</span>
|
||||
<span ng-switch-when="scanning" ng-if="scanPercentage(folder.id) != undefined">({{scanPercentage(folder.id) | percent}})</span>
|
||||
<span ng-switch-when="syncing">({{syncPercentage(folder.id) | percent}}, {{model[folder.id].needBytes | binary}}B)</span>
|
||||
<span class="inline-icon">
|
||||
<span class="inline-icon">
|
||||
<span class="visible-xs fa fa-fw {{folderStatusIcon(folder)}}" aria-label="{{folderStatusText(folder)}}"></span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="panel-title-text">
|
||||
<span tooltip data-original-title="{{folder.label.length != 0 ? folder.id : ''}}">{{folder.label.length != 0 ? folder.label : folder.id}}</span>
|
||||
@@ -585,12 +584,16 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><span class="fas fa-fw fa-share-alt"></span> <span translate>Shared With</span></th>
|
||||
<td class="text-right no-overflow-ellipse word-break-all">
|
||||
<td class="text-right no-overflow-ellipse overflow-break-word">
|
||||
<span ng-repeat="device in otherDevices(folder.devices)">
|
||||
<span ng-switch="completion[device.deviceID][folder.id].remoteState">
|
||||
<span ng-switch-when="notSharing" data-original-title="{{'The remote device has not accepted sharing this folder.' | translate}}" tooltip>{{deviceName(devices[device.deviceID])}}<sup>1</sup><span ng-if="!$last">,</span></span>
|
||||
<span ng-switch-when="paused" data-original-title="{{'The remote device has paused this folder.' | translate}}" tooltip>{{deviceName(devices[device.deviceID])}}<sup>2</sup><span ng-if="!$last">,</span></span>
|
||||
<span ng-switch-default>{{deviceName(devices[device.deviceID])}}<span ng-if="!$last">,</span></span>
|
||||
<span ng-if="folder.type !== 'receiveencrypted' && device.encryptionPassword" class="text-nowrap">
|
||||
<span class="fa fa-lock"></span> <!-- Avoid stray space...
|
||||
--></span><!-- Avoid stray space...
|
||||
--><span ng-switch="completion[device.deviceID][folder.id].remoteState"><!-- Avoid stray space...
|
||||
--><a ng-switch-when="notSharing" href="" ng-click="editDeviceExisting(devices[device.deviceID])" data-original-title="{{'The remote device has not accepted sharing this folder.' | translate}}" tooltip>{{deviceName(devices[device.deviceID])}}<sup>1</sup></a><!-- Avoid stray space...
|
||||
--><a ng-switch-when="paused" href="" ng-click="editDeviceExisting(devices[device.deviceID])" data-original-title="{{'The remote device has paused this folder.' | translate}}" tooltip>{{deviceName(devices[device.deviceID])}}<sup>2</sup></a><!-- Avoid stray space...
|
||||
--><a ng-switch-default href="" ng-click="editDeviceExisting(devices[device.deviceID])">{{deviceName(devices[device.deviceID])}}</a><!-- Avoid stray space...
|
||||
--><span ng-if="!$last">,</span>
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
@@ -940,12 +943,16 @@
|
||||
</tr>
|
||||
<tr ng-if="deviceFolders(deviceCfg).length > 0">
|
||||
<th><span class="fas fa-fw fa-folder"></span> <span translate>Folders</span></th>
|
||||
<td class="text-right no-overflow-ellipse word-break-all">
|
||||
<td class="text-right no-overflow-ellipse overflow-break-word">
|
||||
<span ng-repeat="folderID in deviceFolders(deviceCfg)">
|
||||
<span ng-switch="completion[deviceCfg.deviceID][folderID].remoteState">
|
||||
<span ng-switch-when="notSharing" data-original-title="{{'The remote device has not accepted sharing this folder.' | translate}}" tooltip>{{folderLabel(folderID)}}<sup>1</sup><span ng-if="!$last">,</span></span>
|
||||
<span ng-switch-when="paused" data-original-title="{{'The remote device has paused this folder.' | translate}}" tooltip>{{folderLabel(folderID)}}<sup>2</sup><span ng-if="!$last">,</span></span>
|
||||
<span ng-switch-default>{{folderLabel(folderID)}}<span ng-if="!$last">,</span></span>
|
||||
<span ng-if="folderIsSharedEncrypted(folderID, deviceCfg.deviceID)" class="text-nowrap">
|
||||
<span class="fa fa-lock"></span> <!-- Avoid stray space...
|
||||
--></span><!-- Avoid stray space...
|
||||
--><span ng-switch="completion[deviceCfg.deviceID][folderID].remoteState"><!-- Avoid stray space...
|
||||
--><span ng-switch-when="notSharing" data-original-title="{{'The remote device has not accepted sharing this folder.' | translate}}" tooltip>{{folderLabel(folderID)}}<sup>1</sup></span><!-- Avoid stray space...
|
||||
--><span ng-switch-when="paused" data-original-title="{{'The remote device has paused this folder.' | translate}}" tooltip>{{folderLabel(folderID)}}<sup>2</sup></span><!-- Avoid stray space...
|
||||
--><span ng-switch-default>{{folderLabel(folderID)}}</span><!-- Avoid stray space...
|
||||
--><span ng-if="!$last">,</span>
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
@@ -1043,6 +1050,7 @@
|
||||
<script type="text/javascript" src="vendor/bootstrap/js/bootstrap.js"></script>
|
||||
<script type="text/javascript" src="vendor/daterangepicker/daterangepicker.js"></script>
|
||||
<script type="text/javascript" src="vendor/fancytree/jquery.fancytree-all-deps.js"></script>
|
||||
<script type="text/javascript" src="vendor/HumanizeDuration.js/humanize-duration.js"></script>
|
||||
<!-- / vendor scripts -->
|
||||
|
||||
<!-- gui application code -->
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<h4 class="text-center" translate>The Syncthing Authors</h4>
|
||||
<div class="row">
|
||||
<div class="col-md-12" id="contributor-list">
|
||||
Jakob Borg, Audrius Butkevicius, Jesse Lucas, Simon Frei, Tomasz Wilczyński, Alexander Graf, Alexandre Viau, Anderson Mesquita, André Colomb, Antony Male, Ben Schulz, Caleb Callaway, Daniel Harte, Eric P, Evgeny Kuznetsov, Lars K.W. Gohlke, Lode Hoste, Michael Ploujnikov, Nate Morrison, Philippe Schommers, Ryan Sullivan, Sergey Mishin, Stefan Tatschner, Wulf Weich, bt90, greatroar, Aaron Bieber, Adam Piggott, Adel Qalieh, Alan Pope, Alberto Donato, Aleksey Vasenev, Alessandro G., Alex Lindeman, Alex Xu, Alexander Seiler, Alexandre Alves, Aman Gupta, Anatoli Babenia, Andreas Sommer, Andrew Dunham, Andrew Meyer, Andrew Rabert, Andrey D, Anjan Momi, Anthony Goeckner, Antoine Lamielle, Anur, Aranjedeath, Arkadiusz Tymiński, Aroun, Arthur Axel fREW Schmidt, Artur Zubilewicz, Aurélien Rainone, BAHADIR YILMAZ, Bart De Vries, Beat Reichenbach, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benedikt Morbach, Benjamin Nater, Benno Fünfstück, Benny Ng, Boqin Qin, Boris Rybalkin, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Catfriend1, Cathryne Linenweaver, Cedric Staniewski, Chih-Hsuan Yen, Choongkyu, Chris Howie, Chris Joel, Chris Tonkinson, Christian Kujau, Christian Prescott, Colin Kennedy, Cromefire_, Cyprien Devillez, Dale Visser, Dan, Daniel Barczyk, Daniel Bergmann, Daniel Martí, Daniel Padrta, Darshil Chanpura, David Rimmer, DeflateAwning, Denis A., Dennis Wilson, DerRockWolf, Devon G. Redekopp, Dimitri Papadopoulos Orfanos, Dmitry Saveliev, Domenic Horner, Dominik Heidler, Elias Jarlebring, Elliot Huffman, Emil Hessman, Emil Lundberg, Eng Zer Jun, Eric Lesiuta, Erik Meitner, Evan Spensley, Federico Castagnini, Felix, Felix Ableitner, Felix Lampe, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gahl Saraf, Gilli Sigurdsson, Gleb Sinyavskiy, Graham Miln, Greg, Han Boetes, HansK-p, Harrison Jones, Heiko Zuerker, Hugo Locurcio, Iain Barnett, Ian Johnson, Ikko Ashimine, Ilya Brin, Iskander Sharipov, Jaakko Hannikainen, Jacek Szafarkiewicz, Jack Croft, Jacob, Jake Peterson, James O'Beirne, James Patterson, Jaroslav Lichtblau, Jaroslav Malec, Jauder Ho, Jaya Chithra, Jaya Kumar, Jeffery To, Jens Diemer, Jerry Jacobs, Jochen Voss, Johan Andersson, Johan Vromans, John Rinehart, Jonas Thelemann, Jonathan, Jonathan Cross, Jonta, Jose Manuel Delicado, Julian Lehrhuber, Jörg Thalheim, Jędrzej Kula, K.B.Dharun Krishna, Kalle Laine, Karol Różycki, Kebin Liu, Keith Harrison, Keith Turner, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin Bushiri, Kevin White, Jr., Kurt Fitzner, LSmithx2, Lars Lehtonen, Laurent Arnoud, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, Lukas Lihotzki, Majed Abdulaziz, Marc Laporte, Marc Pujol, Marcin Dziadus, Marcus Legendre, Mario Majila, Mark Pulford, Martchus, Martin Polehla, Mateusz Naściszewski, Mateusz Ż, Matic Potočnik, Matt Burke, Matt Robenolt, Matteo Ruina, Maurizio Tomasi, Max, Max Schulze, MaximAL, Maxime Thirouin, Maximilian, MichaIng, Michael Jephcote, Michael Rienstra, Michael Tilli, Migelo, Mike Boone, MikeLund, MikolajTwarog, Mingxuan Lin, Naveen, Nicholas Rishel, Nick Busey, Nico Stapelbroek, Nicolas Braud-Santoni, Nicolas Perraut, Niels Peter Roest, Nils Jakobi, NinoM4ster, Nitroretro, NoLooseEnds, Oliver Freyermuth, Otiel, Oyebanji Jacob Mayowa, Pablo, Pascal Jungblut, Paul Brit, Pawel Palenica, Paweł Rozlach, Peter Badida, Peter Dave Hello, Peter Hoeg, Peter Marquardt, Phani Rithvij, Phil Davis, Phill Luby, Pier Paolo Ramon, Piotr Bejda, Pramodh KP, Quentin Hibon, Rahmi Pruitt, Richard Hartmann, Robert Carosi, Roberto Santalla, Robin Schoonover, Roman Zaynetdinov, Ross Smith II, Ruslan Yevdokymov, Ryan Qian, Sacheendra Talluri, Scott Klupfel, Sertonix, Shaarad Dalvi, Simon Mwepu, Sly_tom_cat, Stefan Kuntz, Steven Eckhoff, Suhas Gundimeda, Sven Bachmann, Taylor Khan, Thomas Hipp, Tim Abell, Tim Howes, Tobias Klauser, Tobias Nygren, Tobias Tom, Tom Jakubowski, Tommy Thorn, Tully Robinson, Tyler Brazier, Tyler Kropp, Unrud, Veeti Paananen, Victor Buinsky, Vik, Vil Brekin, Vladimir Rusinov, Will Rouesnel, William A. Kennington III, Xavier O., Yannic A., andresvia, andyleap, boomsquared, chenrui, chucic, cjc7373, cui fliter, d-volution, derekriemer, desbma, diemade, digital, entity0xfe, georgespatton, ghjklw, guangwu, gudvinr, ignacy123, janost, jaseg, jelle van der Waa, jtagcat, klemens, kylosus, luzpaz, marco-m, mclang, mv1005, nf, orangekame3, otbutz, overkill, perewa, red_led, rubenbe, sec65, vapatel2, villekalliomaki, wangguoliang, wouter bolsterlee, xarx00, xjtdy888, 佛跳墙, 落心
|
||||
Jakob Borg, Audrius Butkevicius, Jesse Lucas, Simon Frei, Tomasz Wilczyński, Alexander Graf, Alexandre Viau, Anderson Mesquita, André Colomb, Antony Male, Ben Schulz, Caleb Callaway, Daniel Harte, Eric P, Evgeny Kuznetsov, Lars K.W. Gohlke, Lode Hoste, Michael Ploujnikov, Nate Morrison, Philippe Schommers, Ryan Sullivan, Sergey Mishin, Stefan Tatschner, Wulf Weich, bt90, greatroar, Aaron Bieber, Adam Piggott, Adel Qalieh, Alan Pope, Alberto Donato, Aleksey Vasenev, Alessandro G., Alex Lindeman, Alex Xu, Alexander Seiler, Alexandre Alves, Aman Gupta, Anatoli Babenia, Andreas Sommer, Andrew Dunham, Andrew Meyer, Andrew Rabert, Andrey D, Anjan Momi, Anthony Goeckner, Antoine Lamielle, Anur, Aranjedeath, Arkadiusz Tymiński, Aroun, Arthur Axel fREW Schmidt, Artur Zubilewicz, Aurélien Rainone, BAHADIR YILMAZ, Bart De Vries, Beat Reichenbach, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benedikt Morbach, Benjamin Nater, Benno Fünfstück, Benny Ng, Boqin Qin, Boris Rybalkin, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Catfriend1, Cathryne Linenweaver, Cedric Staniewski, Chih-Hsuan Yen, Choongkyu, Chris Howie, Chris Joel, Chris Tonkinson, Christian Kujau, Christian Prescott, Colin Kennedy, Cromefire_, Cyprien Devillez, Dale Visser, Dan, Daniel Barczyk, Daniel Bergmann, Daniel Martí, Daniel Padrta, Darshil Chanpura, David Rimmer, DeflateAwning, Denis A., Dennis Wilson, DerRockWolf, Devon G. Redekopp, Dimitri Papadopoulos Orfanos, Dmitry Saveliev, Domenic Horner, Dominik Heidler, Elias Jarlebring, Elliot Huffman, Emil Hessman, Emil Lundberg, Eng Zer Jun, Eric Lesiuta, Erik Meitner, Evan Spensley, Federico Castagnini, Felix, Felix Ableitner, Felix Lampe, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gahl Saraf, Gilli Sigurdsson, Gleb Sinyavskiy, Graham Miln, Greg, Han Boetes, HansK-p, Harrison Jones, Heiko Zuerker, Hugo Locurcio, Iain Barnett, Ian Johnson, Ikko Ashimine, Ilya Brin, Iskander Sharipov, Jaakko Hannikainen, Jacek Szafarkiewicz, Jack Croft, Jacob, Jake Peterson, James O'Beirne, James Patterson, Jaroslav Lichtblau, Jaroslav Malec, Jaspitta, Jauder Ho, Jaya Chithra, Jaya Kumar, Jeffery To, Jens Diemer, Jerry Jacobs, Jochen Voss, Johan Andersson, Johan Vromans, John Rinehart, Jonas Thelemann, Jonathan, Jonathan Cross, Jonta, Jose Manuel Delicado, Julian Lehrhuber, Jörg Thalheim, Jędrzej Kula, K.B.Dharun Krishna, Kalle Laine, Karol Różycki, Kebin Liu, Keith Harrison, Keith Turner, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin Bushiri, Kevin White, Jr., Kurt Fitzner, LSmithx2, Lars Lehtonen, Laurent Arnoud, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, Lukas Lihotzki, Luke Hamburg, Majed Abdulaziz, Marc Laporte, Marc Pujol, Marcin Dziadus, Marcus Legendre, Mario Majila, Mark Pulford, Martchus, Martin Polehla, Mateusz Naściszewski, Mateusz Ż, Matic Potočnik, Matt Burke, Matt Robenolt, Matteo Ruina, Maurizio Tomasi, Max, Max Schulze, MaximAL, Maxime Thirouin, Maximilian, MichaIng, Michael Jephcote, Michael Rienstra, Michael Tilli, Migelo, Mike Boone, MikeLund, MikolajTwarog, Mingxuan Lin, Naveen, Nicholas Rishel, Nick Busey, Nico Stapelbroek, Nicolas Braud-Santoni, Nicolas Perraut, Niels Peter Roest, Nils Jakobi, NinoM4ster, Nitroretro, NoLooseEnds, Oliver Freyermuth, Otiel, Oyebanji Jacob Mayowa, Pablo, Pascal Jungblut, Paul Brit, Pawel Palenica, Paweł Rozlach, Peter Badida, Peter Dave Hello, Peter Hoeg, Peter Marquardt, Phani Rithvij, Phil Davis, Phill Luby, Pier Paolo Ramon, Piotr Bejda, Pramodh KP, Quentin Hibon, Rahmi Pruitt, Richard Hartmann, Robert Carosi, Roberto Santalla, Robin Schoonover, Roman Zaynetdinov, Ross Smith II, Ruslan Yevdokymov, Ryan Qian, Sacheendra Talluri, Scott Klupfel, Sertonix, Severin von Wnuck-Lipinski, Shaarad Dalvi, Simon Mwepu, Sly_tom_cat, Stefan Kuntz, Steven Eckhoff, Suhas Gundimeda, Sven Bachmann, Taylor Khan, Thomas, Thomas Hipp, Tim Abell, Tim Howes, Tim Nordenfur, Tobias Klauser, Tobias Nygren, Tobias Tom, Tom Jakubowski, Tommy Thorn, Tully Robinson, Tyler Brazier, Tyler Kropp, Unrud, Veeti Paananen, Victor Buinsky, Vik, Vil Brekin, Vladimir Rusinov, WangXi, Will Rouesnel, William A. Kennington III, Xavier O., Yannic A., andresvia, andyleap, boomsquared, chenrui, chucic, cjc7373, cui fliter, d-volution, derekriemer, desbma, diemade, digital, entity0xfe, georgespatton, ghjklw, guangwu, gudvinr, ignacy123, janost, jaseg, jelle van der Waa, jtagcat, klemens, kylosus, luchenhan, luzpaz, marco-m, mclang, mv1005, nf, orangekame3, otbutz, overkill, perewa, red_led, rubenbe, sec65, vapatel2, villekalliomaki, wangguoliang, wouter bolsterlee, xarx00, xjtdy888, 佛跳墙, 落心
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,16 +7,63 @@
|
||||
* {{1|duration:"h"}} --> <1h
|
||||
**/
|
||||
angular.module('syncthing.core')
|
||||
.filter('duration', function () {
|
||||
.filter('duration', function ($translate) {
|
||||
'use strict';
|
||||
|
||||
var SECONDS_IN = { "d": 86400, "h": 3600, "m": 60, "s": 1 };
|
||||
return function (input, precision) {
|
||||
var result = "";
|
||||
if (!precision) {
|
||||
precision = "s";
|
||||
}
|
||||
input = parseInt(input, 10);
|
||||
var language_cc = $translate.use();
|
||||
if (language_cc != null) {
|
||||
language_cc = language_cc.replace("-", "_");
|
||||
var fallbacks = [];
|
||||
var language = language_cc.substr(0, 2);
|
||||
switch (language) {
|
||||
case "zh":
|
||||
// Use zh_TW for zh_HK
|
||||
fallbacks.push("zh_TW");
|
||||
break
|
||||
}
|
||||
if (language != language_cc) {
|
||||
fallbacks.push(language);
|
||||
}
|
||||
// Fallback to english, if the language isn't found
|
||||
fallbacks.push("en");
|
||||
|
||||
var units = ["d", "h", "m", "s"];
|
||||
switch (precision) {
|
||||
case "d":
|
||||
units.pop();
|
||||
// fallthrough
|
||||
case "h":
|
||||
units.pop();
|
||||
// fallthrough
|
||||
case "m":
|
||||
units.pop();
|
||||
// fallthrough
|
||||
case "s":
|
||||
break
|
||||
default:
|
||||
return "[Error: precision must be d, h, m or s, it's " + precision + "]";
|
||||
}
|
||||
|
||||
try {
|
||||
// humanizeDuration accepts only milliseconds
|
||||
return humanizeDuration(input * 1000, {
|
||||
language: language_cc,
|
||||
maxDecimalPoints: 0,
|
||||
units: units,
|
||||
fallbacks: fallbacks
|
||||
});
|
||||
} catch(err) {
|
||||
console.log(err.message + ": language_cc=" + language_cc)
|
||||
// if we crash, fallthrough to english
|
||||
}
|
||||
}
|
||||
var result = "";
|
||||
for (var k in SECONDS_IN) {
|
||||
var t = (input / SECONDS_IN[k] | 0); // Math.floor
|
||||
|
||||
|
||||
@@ -2662,6 +2662,15 @@ angular.module('syncthing.core')
|
||||
+ '&device=' + encodeURIComponent(deviceID));
|
||||
};
|
||||
|
||||
$scope.folderIsSharedEncrypted = function (folderID, deviceID) {
|
||||
var folderCfg = $scope.folders[folderID];
|
||||
if (!folderCfg || folderCfg.type === 'receiveencrypted') return false;
|
||||
|
||||
return folderCfg.devices.some(function (device) {
|
||||
return device.deviceID === deviceID && device.encryptionPassword !== '';
|
||||
});
|
||||
};
|
||||
|
||||
$scope.folderHasUnacceptedDevices = function (folderCfg) {
|
||||
for (var deviceID in $scope.completion) {
|
||||
if (deviceID in $scope.devices
|
||||
|
||||
56
gui/default/vendor/HumanizeDuration.js/LICENSE.txt
vendored
Normal file
56
gui/default/vendor/HumanizeDuration.js/LICENSE.txt
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2024 Evan Hahn (@EvanHahn)
|
||||
Portions copyright (c) 2024 Ross Smith II (@rasa)
|
||||
Other portions copyright their respective authors, see
|
||||
https://github.com/EvanHahn/HumanizeDuration.js/graphs/contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
This project is also licensed under the Unlicense license, at your option:
|
||||
|
||||
The Unlicense
|
||||
-----------
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org/>
|
||||
|
||||
-----------
|
||||
SPDX-License-Identifier: MIT or UNLICENSE
|
||||
7
gui/default/vendor/HumanizeDuration.js/Makefile
vendored
Normal file
7
gui/default/vendor/HumanizeDuration.js/Makefile
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
help:
|
||||
@echo To update this package, type: make update
|
||||
|
||||
update:
|
||||
wget -O LICENSE.txt https://raw.githubusercontent.com/rasa/HumanizeDuration.js/main/LICENSE.txt
|
||||
wget -O humanize-duration.js https://raw.githubusercontent.com/rasa/HumanizeDuration.js/main/humanize-duration.js
|
||||
748
gui/default/vendor/HumanizeDuration.js/humanize-duration.js
vendored
Normal file
748
gui/default/vendor/HumanizeDuration.js/humanize-duration.js
vendored
Normal file
@@ -0,0 +1,748 @@
|
||||
// HumanizeDuration.js - https://git.io/j0HgmQ
|
||||
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* @typedef {string | ((unitCount: number) => string)} Unit
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {("y" | "mo" | "w" | "d" | "h" | "m" | "s" | "ms")} UnitName
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} UnitMeasures
|
||||
* @prop {number} y
|
||||
* @prop {number} mo
|
||||
* @prop {number} w
|
||||
* @prop {number} d
|
||||
* @prop {number} h
|
||||
* @prop {number} m
|
||||
* @prop {number} s
|
||||
* @prop {number} ms
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @typedef {[string, string, string, string, string, string, string, string, string, string]} DigitReplacements
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Language
|
||||
* @prop {Unit} y
|
||||
* @prop {Unit} mo
|
||||
* @prop {Unit} w
|
||||
* @prop {Unit} d
|
||||
* @prop {Unit} h
|
||||
* @prop {Unit} m
|
||||
* @prop {Unit} s
|
||||
* @prop {Unit} ms
|
||||
* @prop {string} [decimal]
|
||||
* @prop {string} [delimiter]
|
||||
* @prop {DigitReplacements} [_digitReplacements]
|
||||
* @prop {boolean} [_numberFirst]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @prop {string} [language]
|
||||
* @prop {Record<string, Language>} [languages]
|
||||
* @prop {string[]} [fallbacks]
|
||||
* @prop {string} [delimiter]
|
||||
* @prop {string} [spacer]
|
||||
* @prop {boolean} [round]
|
||||
* @prop {number} [largest]
|
||||
* @prop {UnitName[]} [units]
|
||||
* @prop {string} [decimal]
|
||||
* @prop {string} [conjunction]
|
||||
* @prop {number} [maxDecimalPoints]
|
||||
* @prop {UnitMeasures} [unitMeasures]
|
||||
* @prop {boolean} [serialComma]
|
||||
* @prop {DigitReplacements} [digitReplacements]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @typedef {Required<Options>} NormalizedOptions
|
||||
*/
|
||||
|
||||
(function () {
|
||||
// Fallback for `Object.assign` if relevant.
|
||||
var assign =
|
||||
Object.assign ||
|
||||
/** @param {...any} destination */
|
||||
function (destination) {
|
||||
var source;
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
source = arguments[i];
|
||||
for (var prop in source) {
|
||||
if (has(source, prop)) {
|
||||
destination[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
return destination;
|
||||
};
|
||||
|
||||
// Fallback for `Array.isArray` if relevant.
|
||||
var isArray =
|
||||
Array.isArray ||
|
||||
function (arg) {
|
||||
return Object.prototype.toString.call(arg) === "[object Array]";
|
||||
};
|
||||
|
||||
// This has to be defined separately because of a bug: we want to alias
|
||||
// `gr` and `el` for backwards-compatiblity. In a breaking change, we can
|
||||
// remove `gr` entirely.
|
||||
// See https://github.com/EvanHahn/HumanizeDuration.js/issues/143 for more.
|
||||
var GREEK = language("έ", "μ", "ε", "η", "ώ", "λ", "δ", "χδ", ","); //
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @type {Record<string, Language>}
|
||||
*/
|
||||
var LANGUAGES = {
|
||||
// Afrikaans (Afrikaans)
|
||||
af: language("j", "mnd", "w", "d", "u", "m", "s", "ms", ","),
|
||||
// አማርኛ (Amharic)
|
||||
am: language("ዓ", "ወ", "ሳ", "ቀ", "ሰ", "ደ", "ሰከ", "ሳ", "ሚሊ"),
|
||||
//العربية (Arabic) (RTL)
|
||||
// https://github.com/EvanHahn/HumanizeDuration.js/issues/221#issuecomment-2119762498
|
||||
// year -> ع stands for "عام" or س stands for "سنة"
|
||||
// month -> ش stands for "شهر"
|
||||
// week -> أ stands for "أسبوع"
|
||||
// day -> ي stands for "يوم"
|
||||
// hour -> س stands for "ساعة"
|
||||
// minute -> د stands for "دقيقة"
|
||||
// second -> ث stands for "ثانية"
|
||||
ar: assign(language("س", "ش", "أ", "ي", "س", "د", "ث", "م ث", ","), {
|
||||
_digitReplacements: ["۰", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"]
|
||||
}),
|
||||
// български (Bulgarian)
|
||||
bg: language("г", "мес", "с", "д", "ч", "м", "сек", "мс", ","),
|
||||
// বাংলা (Bengali)
|
||||
bn: language("ব", "ম", "সপ্তা", "দ", "ঘ", "মি", "স", "মি.স"),
|
||||
// català (Catalan)
|
||||
ca: language("a", "mes", "set", "d", "h", "m", "s", "ms", ","),
|
||||
//کوردیی ناوەڕاست (Central Kurdish) (RTL)
|
||||
ckb: language("م چ", "چ", "خ", "ک", "ڕ", "ه", "م", "س", "."),
|
||||
// čeština (Czech)
|
||||
cs: language("r", "měs", "t", "d", "h", "m", "s", "ms", ","),
|
||||
// Cymraeg (Welsh)
|
||||
cy: language("b", "mis", "wth", "d", "awr", "mun", "eil", "ms"),
|
||||
// dansk (Danish)
|
||||
da: language("å", "md", "u", "d", "t", "m", "s", "ms", ","),
|
||||
// Deutsch (German)
|
||||
de: language("J", "mo", "w", "t", "std", "m", "s", "ms", ","),
|
||||
// Ελληνικά (Greek)
|
||||
el: GREEK,
|
||||
// English (English)
|
||||
en: language("y", "mo", "w", "d", "h", "m", "s", "ms"),
|
||||
// Esperanto (Esperanto)
|
||||
eo: language("j", "mo", "se", "t", "h", "m", "s", "ms", ","),
|
||||
// español (Spanish)
|
||||
es: language("a", "me", "se", "d", "h", "m", "s", "ms", ","),
|
||||
// eesti keel (Estonian)
|
||||
et: language("a", "k", "n", "p", "t", "m", "s", "ms", ","),
|
||||
// euskara (Basque)
|
||||
eu: language("u", "h", "a", "e", "o", "m", "s", "ms", ","),
|
||||
//فارسی (Farsi/Persian) (RTL)
|
||||
fa: language("س", "ما", "ه", "ر", "سا", "دقی", "ثانی", "میلیثانیه"),
|
||||
// suomi (Finnish)
|
||||
fi: language("v", "kk", "vk", "pv", "t", "m", "s", "ms", ","),
|
||||
// føroyskt (Faroese)
|
||||
fo: language("á", "má", "v", "d", "t", "m", "s", "ms", ","),
|
||||
// français (French)
|
||||
fr: language("a", "m", "sem", "j", "h", "m", "s", "ms", ","),
|
||||
// Ελληνικά (Greek) (el)
|
||||
gr: GREEK,
|
||||
//עברית (Hebrew) (RTL)
|
||||
he: language("ש׳", "ח׳", "שב׳", "י׳", "שע׳", "ד׳", "שנ׳", "מל׳"),
|
||||
// hrvatski (Croatian)
|
||||
hr: language("g", "mj", "t", "d", "h", "m", "s", "ms", ","),
|
||||
// हिंदी (Hindi)
|
||||
hi: language("व", "म", "स", "द", "घ", "मि", "से", "मि.से"),
|
||||
// magyar (Hungarian)
|
||||
hu: language("é", "h", "hét", "n", "ó", "p", "mp", "ms", ","),
|
||||
// Indonesia (Indonesian)
|
||||
id: language("t", "b", "mgg", "h", "j", "m", "d", "md"),
|
||||
// íslenska (Icelandic)
|
||||
is: language("ár", "mán", "v", "d", "k", "m", "s", "ms"),
|
||||
// italiano (Italian)
|
||||
it: language("a", "me", "se", "g", "h", "m", "s", "ms", ","),
|
||||
// 日本語 (Japanese)
|
||||
ja: language("年", "月", "週", "日", "時", "分", "秒", "ミリ秒"),
|
||||
// ភាសាខ្មែរ (Khmer)
|
||||
km: language("ឆ", "ខ", "សប្តា", "ថ", "ម", "ន", "វ", "មវ"),
|
||||
// ಕನ್ನಡ (Kannada)
|
||||
kn: language("ವ", "ತ", "ವ", "ದ", "ಗಂ", "ನಿ", "ಸೆ", "ಮಿಸೆ"),
|
||||
// 한국어 (Korean)
|
||||
ko: language("년", "월", "주", "일", "시", "분", "초", "밀리초"),
|
||||
// Kurdî (Kurdish)
|
||||
ku: language("sal", "m", "h", "r", "s", "d", "ç", "ms", ","),
|
||||
// ລາວ (Lao)
|
||||
lo: language("ປ", "ເດ", "ອ", "ວ", "ຊ", "ນທ", "ວິນ", "ມິລິວິນາທີ", ","),
|
||||
// lietuvių (Lithuanian)
|
||||
lt: language("met", "mėn", "sav", "d", "v", "m", "s", "ms", ","),
|
||||
// latviešu (Latvian)
|
||||
lv: language("g", "mēn", "n", "d", "st", "m", "s", "ms", ","),
|
||||
// македонски (Macedonian)
|
||||
mk: language("г", "мес", "н", "д", "ч", "м", "с", "мс", ","),
|
||||
// монгол (Mongolian)
|
||||
mn: language("ж", "с", "дх", "ө", "ц", "м", "с", "мс"),
|
||||
// मराठी (Marathi)
|
||||
mr: language("व", "म", "आ", "दि", "त", "मि", "से", "मि.से"),
|
||||
// Melayu (Malay)
|
||||
ms: language("thn", "bln", "mgg", "hr", "j", "m", "s", "ms"),
|
||||
// Nederlands (Dutch)
|
||||
nl: language("j", "mnd", "w", "d", "u", "m", "s", "ms", ","),
|
||||
// norsk (Norwegian)
|
||||
no: language("år", "mnd", "u", "d", "t", "m", "s", "ms", ","),
|
||||
// polski (Polish)
|
||||
pl: language("r", "mi", "t", "d", "g", "m", "s", "ms", ","),
|
||||
// português (Portuguese)
|
||||
pt: language("a", "mês", "sem", "d", "h", "m", "s", "ms", ","),
|
||||
// română (Romanian) săpt?
|
||||
ro: language("a", "l", "să", "z", "h", "m", "s", "ms", ","),
|
||||
// русский (Russian)
|
||||
ru: language("г", "мес", "н", "д", "ч", "м", "с", "мс", ","),
|
||||
// shqip (Albanian) orë? muaj?
|
||||
sq: language("v", "mu", "j", "d", "o", "m", "s", "ms", ","),
|
||||
// српски (Serbian)
|
||||
sr: language("г", "мес", "н", "д", "ч", "м", "с", "мс", ","),
|
||||
// தமிழ் (Tamil)
|
||||
ta: language("ஆ", "மா", "வ", "நா", "ம", "நி", "வி", "மி.வி"),
|
||||
// తెలుగు (Telugu)
|
||||
te: language("సం", "నె", "వ", "రో", "గం", "ని", "సె", "మి.సె"), //
|
||||
// українська (Ukrainian)
|
||||
uk: language("р", "м", "т", "д", "г", "хв", "с", "мс", ","),
|
||||
//اردو (Urdu) (RTL)
|
||||
ur: language("س", "م", "ہ", "د", "گ", "م", "س", "م س"),
|
||||
// slovenčina (Slovak)
|
||||
sk: language("r", "mes", "t", "d", "h", "m", "s", "ms", ","),
|
||||
// slovenščina (Slovenian)
|
||||
sl: language("l", "mes", "t", "d", "ur", "m", "s", "ms", ","),
|
||||
// svenska (Swedish)
|
||||
sv: language("å", "mån", "v", "d", "h", "m", "s", "ms", ","),
|
||||
// Kiswahili (Swahili)
|
||||
sw: assign(language("mw", "m", "w", "s", "h", "dk", "s", "ms"), {
|
||||
_numberFirst: true
|
||||
}),
|
||||
// Türkçe (Turkish)
|
||||
tr: language("y", "a", "h", "g", "sa", "d", "s", "ms", ","),
|
||||
// ไทย (Thai)
|
||||
th: language("ปี", "ด", "ส", "ว", "ชม", "น", "วิ", "มิลลิวินาที"),
|
||||
// o'zbek (Uzbek)
|
||||
uz: language("y", "o", "h", "k", "soa", "m", "s", "ms"),
|
||||
// Ўзбек (Кирилл) (Uzbek (Cyrillic))
|
||||
uz_CYR: language("й", "о", "х", "к", "соа", "д", "с", "мс"),
|
||||
// Tiếng Việt (Vietnamese)
|
||||
vi: language("n", "th", "t", "ng", "gi", "p", "g", "ms", ","),
|
||||
// 中文 (简体) (Chinese, simplified)
|
||||
zh_CN: language("年", "月", "周", "天", "时", "分", "秒", "毫秒"),
|
||||
// 中文 (繁體) (Chinese, traditional)
|
||||
zh_TW: language("年", "月", "週", "天", "時", "分", "秒", "毫秒")
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function for creating language definitions.
|
||||
*
|
||||
* @internal
|
||||
* @param {Unit} y
|
||||
* @param {Unit} mo
|
||||
* @param {Unit} w
|
||||
* @param {Unit} d
|
||||
* @param {Unit} h
|
||||
* @param {Unit} m
|
||||
* @param {Unit} s
|
||||
* @param {Unit} ms
|
||||
* @param {string} [decimal]
|
||||
* @returns {Language}
|
||||
*/
|
||||
function language(y, mo, w, d, h, m, s, ms, decimal) {
|
||||
/** @type {Language} */
|
||||
var result = { y: y, mo: mo, w: w, d: d, h: h, m: m, s: s, ms: ms };
|
||||
if (typeof decimal !== "undefined") {
|
||||
result.decimal = decimal;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for Arabic.
|
||||
*
|
||||
* @internal
|
||||
* @param {number} c
|
||||
* @returns {0 | 1 | 2}
|
||||
*/
|
||||
// function getArabicForm(c) {
|
||||
// if (c === 2) {
|
||||
// return 1;
|
||||
// }
|
||||
// if (c > 2 && c < 11) {
|
||||
// return 2;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Helper function for Polish.
|
||||
*
|
||||
* @internal
|
||||
* @param {number} c
|
||||
* @returns {0 | 1 | 2 | 3}
|
||||
*/
|
||||
// function getPolishForm(c) {
|
||||
// if (c === 1) {
|
||||
// return 0;
|
||||
// }
|
||||
// if (Math.floor(c) !== c) {
|
||||
// return 1;
|
||||
// }
|
||||
// if (c % 10 >= 2 && c % 10 <= 4 && !(c % 100 > 10 && c % 100 < 20)) {
|
||||
// return 2;
|
||||
// }
|
||||
// return 3;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Helper function for Slavic languages.
|
||||
*
|
||||
* @internal
|
||||
* @param {number} c
|
||||
* @returns {0 | 1 | 2 | 3}
|
||||
*/
|
||||
// function getSlavicForm(c) {
|
||||
// if (Math.floor(c) !== c) {
|
||||
// return 2;
|
||||
// }
|
||||
// if (
|
||||
// (c % 100 >= 5 && c % 100 <= 20) ||
|
||||
// (c % 10 >= 5 && c % 10 <= 9) ||
|
||||
// c % 10 === 0
|
||||
// ) {
|
||||
// return 0;
|
||||
// }
|
||||
// if (c % 10 === 1) {
|
||||
// return 1;
|
||||
// }
|
||||
// if (c > 1) {
|
||||
// return 2;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Helper function for Czech or Slovak.
|
||||
*
|
||||
* @internal
|
||||
* @param {number} c
|
||||
* @returns {0 | 1 | 2 | 3}
|
||||
*/
|
||||
// function getCzechOrSlovakForm(c) {
|
||||
// if (c === 1) {
|
||||
// return 0;
|
||||
// }
|
||||
// if (Math.floor(c) !== c) {
|
||||
// return 1;
|
||||
// }
|
||||
// if (c % 10 >= 2 && c % 10 <= 4 && c % 100 < 10) {
|
||||
// return 2;
|
||||
// }
|
||||
// return 3;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Helper function for Lithuanian.
|
||||
*
|
||||
* @internal
|
||||
* @param {number} c
|
||||
* @returns {0 | 1 | 2}
|
||||
*/
|
||||
// function getLithuanianForm(c) {
|
||||
// if (c === 1 || (c % 10 === 1 && c % 100 > 20)) {
|
||||
// return 0;
|
||||
// }
|
||||
// if (
|
||||
// Math.floor(c) !== c ||
|
||||
// (c % 10 >= 2 && c % 100 > 20) ||
|
||||
// (c % 10 >= 2 && c % 100 < 10)
|
||||
// ) {
|
||||
// return 1;
|
||||
// }
|
||||
// return 2;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Helper function for Latvian.
|
||||
*
|
||||
* @internal
|
||||
* @param {number} c
|
||||
* @returns {boolean}
|
||||
*/
|
||||
// function getLatvianForm(c) {
|
||||
// return c % 10 === 1 && c % 100 !== 11;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @template T
|
||||
* @param {T} obj
|
||||
* @param {keyof T} key
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function has(obj, key) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param {Pick<Required<Options>, "language" | "fallbacks" | "languages">} options
|
||||
* @throws {Error} Throws an error if language is not found.
|
||||
* @returns {Language}
|
||||
*/
|
||||
function getLanguage(options) {
|
||||
var possibleLanguages = [options.language];
|
||||
|
||||
if (has(options, "fallbacks")) {
|
||||
if (isArray(options.fallbacks) && options.fallbacks.length) {
|
||||
possibleLanguages = possibleLanguages.concat(options.fallbacks);
|
||||
} else {
|
||||
throw new Error("fallbacks must be an array with at least one element");
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < possibleLanguages.length; i++) {
|
||||
var languageToTry = possibleLanguages[i];
|
||||
if (has(options.languages, languageToTry)) {
|
||||
return options.languages[languageToTry];
|
||||
}
|
||||
if (has(LANGUAGES, languageToTry)) {
|
||||
return LANGUAGES[languageToTry];
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error("No language found.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param {Piece} piece
|
||||
* @param {Language} language
|
||||
* @param {Pick<Required<Options>, "decimal" | "spacer" | "maxDecimalPoints" | "digitReplacements">} options
|
||||
*/
|
||||
function renderPiece(piece, language, options) {
|
||||
var unitName = piece.unitName;
|
||||
var unitCount = piece.unitCount;
|
||||
|
||||
var spacer = options.spacer;
|
||||
var maxDecimalPoints = options.maxDecimalPoints;
|
||||
|
||||
/** @type {string} */
|
||||
var decimal;
|
||||
if (has(options, "decimal")) {
|
||||
decimal = options.decimal;
|
||||
} else if (has(language, "decimal")) {
|
||||
decimal = language.decimal;
|
||||
} else {
|
||||
decimal = ".";
|
||||
}
|
||||
|
||||
/** @type {undefined | DigitReplacements} */
|
||||
var digitReplacements;
|
||||
if ("digitReplacements" in options) {
|
||||
digitReplacements = options.digitReplacements;
|
||||
} else if ("_digitReplacements" in language) {
|
||||
digitReplacements = language._digitReplacements;
|
||||
}
|
||||
|
||||
/** @type {string} */
|
||||
var formattedCount;
|
||||
var normalizedUnitCount =
|
||||
maxDecimalPoints === void 0
|
||||
? unitCount
|
||||
: Math.floor(unitCount * Math.pow(10, maxDecimalPoints)) /
|
||||
Math.pow(10, maxDecimalPoints);
|
||||
var countStr = normalizedUnitCount.toString();
|
||||
if (digitReplacements) {
|
||||
formattedCount = "";
|
||||
for (var i = 0; i < countStr.length; i++) {
|
||||
var char = countStr[i];
|
||||
if (char === ".") {
|
||||
formattedCount += decimal;
|
||||
} else {
|
||||
// @ts-ignore because `char` should always be 0-9 at this point.
|
||||
formattedCount += digitReplacements[char];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
formattedCount = countStr.replace(".", decimal);
|
||||
}
|
||||
|
||||
var languageWord = language[unitName];
|
||||
var word;
|
||||
if (typeof languageWord === "function") {
|
||||
word = languageWord(unitCount);
|
||||
} else {
|
||||
word = languageWord;
|
||||
}
|
||||
|
||||
if (language._numberFirst) {
|
||||
return word + spacer + formattedCount;
|
||||
}
|
||||
return formattedCount + spacer + word;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @typedef {Object} Piece
|
||||
* @prop {UnitName} unitName
|
||||
* @prop {number} unitCount
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param {number} ms
|
||||
* @param {Pick<Required<Options>, "units" | "unitMeasures" | "largest" | "round">} options
|
||||
* @returns {Piece[]}
|
||||
*/
|
||||
function getPieces(ms, options) {
|
||||
/** @type {UnitName} */
|
||||
var unitName;
|
||||
|
||||
/** @type {number} */
|
||||
var i;
|
||||
|
||||
/** @type {number} */
|
||||
var unitCount;
|
||||
|
||||
/** @type {number} */
|
||||
var msRemaining;
|
||||
|
||||
var units = options.units;
|
||||
var unitMeasures = options.unitMeasures;
|
||||
var largest = "largest" in options ? options.largest : Infinity;
|
||||
|
||||
if (!units.length) return [];
|
||||
|
||||
// Get the counts for each unit. Doesn't round or truncate anything.
|
||||
// For example, might create an object like `{ y: 7, m: 6, w: 0, d: 5, h: 23.99 }`.
|
||||
/** @type {Partial<Record<UnitName, number>>} */
|
||||
var unitCounts = {};
|
||||
msRemaining = ms;
|
||||
for (i = 0; i < units.length; i++) {
|
||||
unitName = units[i];
|
||||
var unitMs = unitMeasures[unitName];
|
||||
|
||||
var isLast = i === units.length - 1;
|
||||
unitCount = isLast
|
||||
? msRemaining / unitMs
|
||||
: Math.floor(msRemaining / unitMs);
|
||||
unitCounts[unitName] = unitCount;
|
||||
|
||||
msRemaining -= unitCount * unitMs;
|
||||
}
|
||||
|
||||
if (options.round) {
|
||||
// Update counts based on the `largest` option.
|
||||
// For example, if `largest === 2` and `unitCount` is `{ y: 7, m: 6, w: 0, d: 5, h: 23.99 }`,
|
||||
// updates to something like `{ y: 7, m: 6.2 }`.
|
||||
var unitsRemainingBeforeRound = largest;
|
||||
for (i = 0; i < units.length; i++) {
|
||||
unitName = units[i];
|
||||
unitCount = unitCounts[unitName];
|
||||
|
||||
if (unitCount === 0) continue;
|
||||
|
||||
unitsRemainingBeforeRound--;
|
||||
|
||||
// "Take" the rest of the units into this one.
|
||||
if (unitsRemainingBeforeRound === 0) {
|
||||
for (var j = i + 1; j < units.length; j++) {
|
||||
var smallerUnitName = units[j];
|
||||
var smallerUnitCount = unitCounts[smallerUnitName];
|
||||
unitCounts[unitName] +=
|
||||
(smallerUnitCount * unitMeasures[smallerUnitName]) /
|
||||
unitMeasures[unitName];
|
||||
unitCounts[smallerUnitName] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Round the last piece (which should be the only non-integer).
|
||||
//
|
||||
// This can be a little tricky if the last piece "bubbles up" to a larger
|
||||
// unit. For example, "3 days, 23.99 hours" should be rounded to "4 days".
|
||||
// It can also require multiple passes. For example, "6 days, 23.99 hours"
|
||||
// should become "1 week".
|
||||
for (i = units.length - 1; i >= 0; i--) {
|
||||
unitName = units[i];
|
||||
unitCount = unitCounts[unitName];
|
||||
|
||||
if (unitCount === 0) continue;
|
||||
|
||||
var rounded = Math.round(unitCount);
|
||||
unitCounts[unitName] = rounded;
|
||||
|
||||
if (i === 0) break;
|
||||
|
||||
var previousUnitName = units[i - 1];
|
||||
var previousUnitMs = unitMeasures[previousUnitName];
|
||||
var amountOfPreviousUnit = Math.floor(
|
||||
(rounded * unitMeasures[unitName]) / previousUnitMs
|
||||
);
|
||||
if (amountOfPreviousUnit) {
|
||||
unitCounts[previousUnitName] += amountOfPreviousUnit;
|
||||
unitCounts[unitName] = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {Piece[]} */
|
||||
var result = [];
|
||||
for (i = 0; i < units.length && result.length < largest; i++) {
|
||||
unitName = units[i];
|
||||
unitCount = unitCounts[unitName];
|
||||
if (unitCount) {
|
||||
result.push({ unitName: unitName, unitCount: unitCount });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param {Piece[]} pieces
|
||||
* @param {Pick<Required<Options>, "units" | "language" | "languages" | "fallbacks" | "delimiter" | "spacer" | "decimal" | "conjunction" | "maxDecimalPoints" | "serialComma" | "digitReplacements">} options
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatPieces(pieces, options) {
|
||||
var language = getLanguage(options);
|
||||
|
||||
if (!pieces.length) {
|
||||
var units = options.units;
|
||||
var smallestUnitName = units[units.length - 1];
|
||||
return renderPiece(
|
||||
{ unitName: smallestUnitName, unitCount: 0 },
|
||||
language,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
var conjunction = options.conjunction;
|
||||
var serialComma = options.serialComma;
|
||||
|
||||
var delimiter;
|
||||
if (has(options, "delimiter")) {
|
||||
delimiter = options.delimiter;
|
||||
} else if (has(language, "delimiter")) {
|
||||
delimiter = language.delimiter;
|
||||
} else {
|
||||
delimiter = " ";
|
||||
}
|
||||
|
||||
/** @type {string[]} */
|
||||
var renderedPieces = [];
|
||||
for (var i = 0; i < pieces.length; i++) {
|
||||
renderedPieces.push(renderPiece(pieces[i], language, options));
|
||||
}
|
||||
|
||||
if (!conjunction || pieces.length === 1) {
|
||||
return renderedPieces.join(delimiter);
|
||||
}
|
||||
|
||||
if (pieces.length === 2) {
|
||||
return renderedPieces.join(conjunction);
|
||||
}
|
||||
|
||||
return (
|
||||
renderedPieces.slice(0, -1).join(delimiter) +
|
||||
(serialComma ? "," : "") +
|
||||
conjunction +
|
||||
renderedPieces.slice(-1)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a humanizer, which lets you change the default options.
|
||||
*
|
||||
* @param {Options} [passedOptions]
|
||||
*/
|
||||
function humanizer(passedOptions) {
|
||||
/**
|
||||
* @param {number} ms
|
||||
* @param {Options} [humanizerOptions]
|
||||
* @returns {string}
|
||||
*/
|
||||
var result = function humanizer(ms, humanizerOptions) {
|
||||
// Make sure we have a positive number.
|
||||
//
|
||||
// Has the nice side-effect of converting things to numbers. For example,
|
||||
// converts `"123"` and `Number(123)` to `123`.
|
||||
ms = Math.abs(ms);
|
||||
|
||||
var options = assign({}, result, humanizerOptions || {});
|
||||
|
||||
var pieces = getPieces(ms, options);
|
||||
|
||||
return formatPieces(pieces, options);
|
||||
};
|
||||
|
||||
return assign(
|
||||
result,
|
||||
{
|
||||
language: "en",
|
||||
spacer: "",
|
||||
conjunction: "",
|
||||
serialComma: true,
|
||||
units: ["y", "mo", "w", "d", "h", "m", "s"],
|
||||
languages: {},
|
||||
round: false,
|
||||
unitMeasures: {
|
||||
y: 31557600000,
|
||||
mo: 2629800000,
|
||||
w: 604800000,
|
||||
d: 86400000,
|
||||
h: 3600000,
|
||||
m: 60000,
|
||||
s: 1000,
|
||||
ms: 1
|
||||
}
|
||||
},
|
||||
passedOptions
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Humanize a duration.
|
||||
*
|
||||
* This is a wrapper around the default humanizer.
|
||||
*/
|
||||
var humanizeDuration = assign(humanizer({}), {
|
||||
getSupportedLanguages: function getSupportedLanguages() {
|
||||
var result = [];
|
||||
for (var language in LANGUAGES) {
|
||||
if (has(LANGUAGES, language) && language !== "gr") {
|
||||
result.push(language);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
humanizer: humanizer
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
if (typeof define === "function" && define.amd) {
|
||||
// @ts-ignore
|
||||
define(function () {
|
||||
return humanizeDuration;
|
||||
});
|
||||
} else if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = humanizeDuration;
|
||||
} else {
|
||||
this.humanizeDuration = humanizeDuration;
|
||||
}
|
||||
})();
|
||||
@@ -368,8 +368,8 @@ func (s *service) Serve(ctx context.Context) error {
|
||||
|
||||
// Wrap everything in basic auth, if user/password is set.
|
||||
if guiCfg.IsAuthEnabled() {
|
||||
sessionCookieName := "sessionid-" + s.id.Short().String()
|
||||
authMW := newBasicAuthAndSessionMiddleware(sessionCookieName, s.id.Short().String(), guiCfg, s.cfg.LDAP(), handler, s.evLogger, s.miscDB)
|
||||
tokenCookieManager := newTokenCookieManager(s.id.Short().String(), guiCfg, s.evLogger, s.miscDB)
|
||||
authMW := newBasicAuthAndSessionMiddleware(tokenCookieManager, guiCfg, s.cfg.LDAP(), handler, s.evLogger)
|
||||
handler = authMW
|
||||
|
||||
restMux.Handler(http.MethodPost, "/rest/noauth/auth/password", http.HandlerFunc(authMW.passwordAuthHandler))
|
||||
@@ -977,6 +977,7 @@ func (s *service) getDBFile(w http.ResponseWriter, r *http.Request) {
|
||||
av, err := s.model.Availability(folder, gf, protocol.BlockInfo{})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
mtimeMapping, mtimeErr := s.model.GetMtimeMapping(folder, file)
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ import (
|
||||
|
||||
ldap "github.com/go-ldap/ldap/v3"
|
||||
"github.com/syncthing/syncthing/lib/config"
|
||||
"github.com/syncthing/syncthing/lib/db"
|
||||
"github.com/syncthing/syncthing/lib/events"
|
||||
"github.com/syncthing/syncthing/lib/rand"
|
||||
)
|
||||
@@ -80,24 +79,20 @@ func isNoAuthPath(path string) bool {
|
||||
}
|
||||
|
||||
type basicAuthAndSessionMiddleware struct {
|
||||
cookieName string
|
||||
shortID string
|
||||
guiCfg config.GUIConfiguration
|
||||
ldapCfg config.LDAPConfiguration
|
||||
next http.Handler
|
||||
evLogger events.Logger
|
||||
tokens *tokenManager
|
||||
tokenCookieManager *tokenCookieManager
|
||||
guiCfg config.GUIConfiguration
|
||||
ldapCfg config.LDAPConfiguration
|
||||
next http.Handler
|
||||
evLogger events.Logger
|
||||
}
|
||||
|
||||
func newBasicAuthAndSessionMiddleware(cookieName, shortID string, guiCfg config.GUIConfiguration, ldapCfg config.LDAPConfiguration, next http.Handler, evLogger events.Logger, miscDB *db.NamespacedKV) *basicAuthAndSessionMiddleware {
|
||||
func newBasicAuthAndSessionMiddleware(tokenCookieManager *tokenCookieManager, guiCfg config.GUIConfiguration, ldapCfg config.LDAPConfiguration, next http.Handler, evLogger events.Logger) *basicAuthAndSessionMiddleware {
|
||||
return &basicAuthAndSessionMiddleware{
|
||||
cookieName: cookieName,
|
||||
shortID: shortID,
|
||||
guiCfg: guiCfg,
|
||||
ldapCfg: ldapCfg,
|
||||
next: next,
|
||||
evLogger: evLogger,
|
||||
tokens: newTokenManager("sessions", miscDB, maxSessionLifetime, maxActiveSessions),
|
||||
tokenCookieManager: tokenCookieManager,
|
||||
guiCfg: guiCfg,
|
||||
ldapCfg: ldapCfg,
|
||||
next: next,
|
||||
evLogger: evLogger,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,22 +102,14 @@ func (m *basicAuthAndSessionMiddleware) ServeHTTP(w http.ResponseWriter, r *http
|
||||
return
|
||||
}
|
||||
|
||||
for _, cookie := range r.Cookies() {
|
||||
// We iterate here since there may, historically, be multiple
|
||||
// cookies with the same name but different path. Any "old" ones
|
||||
// won't match an existing session and will be ignored, then
|
||||
// later removed on logout or when timing out.
|
||||
if cookie.Name == m.cookieName {
|
||||
if m.tokens.Check(cookie.Value) {
|
||||
m.next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
if m.tokenCookieManager.hasValidSession(r) {
|
||||
m.next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Fall back to Basic auth if provided
|
||||
if username, ok := attemptBasicAuth(r, m.guiCfg, m.ldapCfg, m.evLogger); ok {
|
||||
m.createSession(username, false, w, r)
|
||||
m.tokenCookieManager.createSession(username, false, w, r)
|
||||
m.next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
@@ -136,7 +123,7 @@ func (m *basicAuthAndSessionMiddleware) ServeHTTP(w http.ResponseWriter, r *http
|
||||
// Some browsers don't send the Authorization request header unless prompted by a 401 response.
|
||||
// This enables https://user:pass@localhost style URLs to keep working.
|
||||
if m.guiCfg.SendBasicAuthPrompt {
|
||||
unauthorized(w, m.shortID)
|
||||
unauthorized(w, m.tokenCookieManager.shortID)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -156,7 +143,7 @@ func (m *basicAuthAndSessionMiddleware) passwordAuthHandler(w http.ResponseWrite
|
||||
}
|
||||
|
||||
if auth(req.Username, req.Password, m.guiCfg, m.ldapCfg) {
|
||||
m.createSession(req.Username, req.StayLoggedIn, w, r)
|
||||
m.tokenCookieManager.createSession(req.Username, req.StayLoggedIn, w, r)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
@@ -189,55 +176,8 @@ func attemptBasicAuth(r *http.Request, guiCfg config.GUIConfiguration, ldapCfg c
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (m *basicAuthAndSessionMiddleware) createSession(username string, persistent bool, w http.ResponseWriter, r *http.Request) {
|
||||
sessionid := m.tokens.New()
|
||||
|
||||
// Best effort detection of whether the connection is HTTPS --
|
||||
// either directly to us, or as used by the client towards a reverse
|
||||
// proxy who sends us headers.
|
||||
connectionIsHTTPS := r.TLS != nil ||
|
||||
strings.ToLower(r.Header.Get("x-forwarded-proto")) == "https" ||
|
||||
strings.Contains(strings.ToLower(r.Header.Get("forwarded")), "proto=https")
|
||||
// If the connection is HTTPS, or *should* be HTTPS, set the Secure
|
||||
// bit in cookies.
|
||||
useSecureCookie := connectionIsHTTPS || m.guiCfg.UseTLS()
|
||||
|
||||
maxAge := 0
|
||||
if persistent {
|
||||
maxAge = int(maxSessionLifetime.Seconds())
|
||||
}
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: m.cookieName,
|
||||
Value: sessionid,
|
||||
// In HTTP spec Max-Age <= 0 means delete immediately,
|
||||
// but in http.Cookie MaxAge = 0 means unspecified (session) and MaxAge < 0 means delete immediately
|
||||
MaxAge: maxAge,
|
||||
Secure: useSecureCookie,
|
||||
Path: "/",
|
||||
})
|
||||
|
||||
emitLoginAttempt(true, username, r.RemoteAddr, m.evLogger)
|
||||
}
|
||||
|
||||
func (m *basicAuthAndSessionMiddleware) handleLogout(w http.ResponseWriter, r *http.Request) {
|
||||
for _, cookie := range r.Cookies() {
|
||||
// We iterate here since there may, historically, be multiple
|
||||
// cookies with the same name but different path. We drop them
|
||||
// all.
|
||||
if cookie.Name == m.cookieName {
|
||||
m.tokens.Delete(cookie.Value)
|
||||
|
||||
// Delete the cookie
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: m.cookieName,
|
||||
Value: "",
|
||||
MaxAge: -1,
|
||||
Secure: cookie.Secure,
|
||||
Path: cookie.Path,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
m.tokenCookieManager.destroySession(w, r)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
|
||||
@@ -498,6 +498,15 @@ func hasSessionCookie(cookies []*http.Cookie) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func hasDeleteSessionCookie(cookies []*http.Cookie) bool {
|
||||
for _, cookie := range cookies {
|
||||
if cookie.MaxAge < 0 && strings.HasPrefix(cookie.Name, "sessionid") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func httpGet(url string, basicAuthUsername string, basicAuthPassword string, xapikeyHeader string, authorizationBearer string, cookies []*http.Cookie, t *testing.T) *http.Response {
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
for _, cookie := range cookies {
|
||||
@@ -527,7 +536,7 @@ func httpGet(url string, basicAuthUsername string, basicAuthPassword string, xap
|
||||
return resp
|
||||
}
|
||||
|
||||
func httpPost(url string, body map[string]string, t *testing.T) *http.Response {
|
||||
func httpPost(url string, body map[string]string, cookies []*http.Cookie, t *testing.T) *http.Response {
|
||||
bodyBytes, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -538,6 +547,10 @@ func httpPost(url string, body map[string]string, t *testing.T) *http.Response {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, cookie := range cookies {
|
||||
req.AddCookie(cookie)
|
||||
}
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -622,6 +635,43 @@ func TestHTTPLogin(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Logout removes the session cookie", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
resp := httpGetBasicAuth(url, "üser", "räksmörgås") // string literals in Go source code are in UTF-8
|
||||
if resp.StatusCode != expectedOkStatus {
|
||||
t.Errorf("Unexpected non-%d return code %d for authed request (UTF-8)", expectedOkStatus, resp.StatusCode)
|
||||
}
|
||||
if !hasSessionCookie(resp.Cookies()) {
|
||||
t.Errorf("Expected session cookie for authed request (UTF-8)")
|
||||
}
|
||||
logoutResp := httpPost(baseURL+"/rest/noauth/auth/logout", nil, resp.Cookies(), t)
|
||||
if !hasDeleteSessionCookie(logoutResp.Cookies()) {
|
||||
t.Errorf("Expected session cookie to be deleted for logout request")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Session cookie is invalid after logout", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
loginResp := httpGetBasicAuth(url, "üser", "räksmörgås") // string literals in Go source code are in UTF-8
|
||||
if loginResp.StatusCode != expectedOkStatus {
|
||||
t.Errorf("Unexpected non-%d return code %d for authed request (UTF-8)", expectedOkStatus, loginResp.StatusCode)
|
||||
}
|
||||
if !hasSessionCookie(loginResp.Cookies()) {
|
||||
t.Errorf("Expected session cookie for authed request (UTF-8)")
|
||||
}
|
||||
|
||||
resp := httpGet(url, "", "", "", "", loginResp.Cookies(), t)
|
||||
if resp.StatusCode != expectedOkStatus {
|
||||
t.Errorf("Unexpected non-%d return code %d for cookie-authed request (UTF-8)", expectedOkStatus, resp.StatusCode)
|
||||
}
|
||||
|
||||
httpPost(baseURL+"/rest/noauth/auth/logout", nil, loginResp.Cookies(), t)
|
||||
resp = httpGet(url, "", "", "", "", loginResp.Cookies(), t)
|
||||
if resp.StatusCode != expectedFailStatus {
|
||||
t.Errorf("Expected session to be invalid (status %d) after logout, got status: %d", expectedFailStatus, resp.StatusCode)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ISO-8859-1 auth works", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
resp := httpGetBasicAuth(url, "\xfcser", "r\xe4ksm\xf6rg\xe5s") // escaped ISO-8859-1
|
||||
@@ -708,7 +758,7 @@ func TestHtmlFormLogin(t *testing.T) {
|
||||
resourceUrl404 := baseURL + "/any-path/that/does/nooooooot/match-any/noauth-pattern"
|
||||
|
||||
performLogin := func(username string, password string) *http.Response {
|
||||
return httpPost(loginUrl, map[string]string{"username": username, "password": password}, t)
|
||||
return httpPost(loginUrl, map[string]string{"username": username, "password": password}, nil, t)
|
||||
}
|
||||
|
||||
performResourceRequest := func(url string, cookies []*http.Cookie) *http.Response {
|
||||
@@ -773,9 +823,40 @@ func TestHtmlFormLogin(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Logout removes the session cookie", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// JSON is always UTF-8, so ISO-8859-1 case is not applicable
|
||||
resp := performLogin("üser", "räksmörgås") // string literals in Go source code are in UTF-8
|
||||
if resp.StatusCode != http.StatusNoContent {
|
||||
t.Errorf("Unexpected non-204 return code %d for authed request (UTF-8)", resp.StatusCode)
|
||||
}
|
||||
logoutResp := httpPost(baseURL+"/rest/noauth/auth/logout", nil, resp.Cookies(), t)
|
||||
if !hasDeleteSessionCookie(logoutResp.Cookies()) {
|
||||
t.Errorf("Expected session cookie to be deleted for logout request")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Session cookie is invalid after logout", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// JSON is always UTF-8, so ISO-8859-1 case is not applicable
|
||||
loginResp := performLogin("üser", "räksmörgås") // string literals in Go source code are in UTF-8
|
||||
if loginResp.StatusCode != http.StatusNoContent {
|
||||
t.Errorf("Unexpected non-204 return code %d for authed request (UTF-8)", loginResp.StatusCode)
|
||||
}
|
||||
resp := performResourceRequest(resourceUrl, loginResp.Cookies())
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Errorf("Unexpected non-200 return code %d for authed request (UTF-8)", resp.StatusCode)
|
||||
}
|
||||
httpPost(baseURL+"/rest/noauth/auth/logout", nil, loginResp.Cookies(), t)
|
||||
resp = performResourceRequest(resourceUrl, loginResp.Cookies())
|
||||
if resp.StatusCode != http.StatusForbidden {
|
||||
t.Errorf("Expected session to be invalid (status 403) after logout, got status: %d", resp.StatusCode)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("form login is not applicable to other URLs", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
resp := httpPost(baseURL+"/meta.js", map[string]string{"username": "üser", "password": "räksmörgås"}, t)
|
||||
resp := httpPost(baseURL+"/meta.js", map[string]string{"username": "üser", "password": "räksmörgås"}, nil, t)
|
||||
if resp.StatusCode != http.StatusForbidden {
|
||||
t.Errorf("Unexpected non-403 return code %d for incorrect form login URL", resp.StatusCode)
|
||||
}
|
||||
|
||||
@@ -7,10 +7,14 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/config"
|
||||
"github.com/syncthing/syncthing/lib/db"
|
||||
"github.com/syncthing/syncthing/lib/events"
|
||||
"github.com/syncthing/syncthing/lib/rand"
|
||||
"github.com/syncthing/syncthing/lib/sync"
|
||||
)
|
||||
@@ -135,3 +139,86 @@ func (m *tokenManager) scheduledSave() {
|
||||
bs, _ := m.tokens.Marshal() // can't fail
|
||||
_ = m.miscDB.PutBytes(m.key, bs) // can fail, but what are we going to do?
|
||||
}
|
||||
|
||||
type tokenCookieManager struct {
|
||||
cookieName string
|
||||
shortID string
|
||||
guiCfg config.GUIConfiguration
|
||||
evLogger events.Logger
|
||||
tokens *tokenManager
|
||||
}
|
||||
|
||||
func newTokenCookieManager(shortID string, guiCfg config.GUIConfiguration, evLogger events.Logger, miscDB *db.NamespacedKV) *tokenCookieManager {
|
||||
return &tokenCookieManager{
|
||||
cookieName: "sessionid-" + shortID,
|
||||
shortID: shortID,
|
||||
guiCfg: guiCfg,
|
||||
evLogger: evLogger,
|
||||
tokens: newTokenManager("sessions", miscDB, maxSessionLifetime, maxActiveSessions),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *tokenCookieManager) createSession(username string, persistent bool, w http.ResponseWriter, r *http.Request) {
|
||||
sessionid := m.tokens.New()
|
||||
|
||||
// Best effort detection of whether the connection is HTTPS --
|
||||
// either directly to us, or as used by the client towards a reverse
|
||||
// proxy who sends us headers.
|
||||
connectionIsHTTPS := r.TLS != nil ||
|
||||
strings.ToLower(r.Header.Get("x-forwarded-proto")) == "https" ||
|
||||
strings.Contains(strings.ToLower(r.Header.Get("forwarded")), "proto=https")
|
||||
// If the connection is HTTPS, or *should* be HTTPS, set the Secure
|
||||
// bit in cookies.
|
||||
useSecureCookie := connectionIsHTTPS || m.guiCfg.UseTLS()
|
||||
|
||||
maxAge := 0
|
||||
if persistent {
|
||||
maxAge = int(maxSessionLifetime.Seconds())
|
||||
}
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: m.cookieName,
|
||||
Value: sessionid,
|
||||
// In HTTP spec Max-Age <= 0 means delete immediately,
|
||||
// but in http.Cookie MaxAge = 0 means unspecified (session) and MaxAge < 0 means delete immediately
|
||||
MaxAge: maxAge,
|
||||
Secure: useSecureCookie,
|
||||
Path: "/",
|
||||
})
|
||||
|
||||
emitLoginAttempt(true, username, r.RemoteAddr, m.evLogger)
|
||||
}
|
||||
|
||||
func (m *tokenCookieManager) hasValidSession(r *http.Request) bool {
|
||||
for _, cookie := range r.Cookies() {
|
||||
// We iterate here since there may, historically, be multiple
|
||||
// cookies with the same name but different path. Any "old" ones
|
||||
// won't match an existing session and will be ignored, then
|
||||
// later removed on logout or when timing out.
|
||||
if cookie.Name == m.cookieName {
|
||||
if m.tokens.Check(cookie.Value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *tokenCookieManager) destroySession(w http.ResponseWriter, r *http.Request) {
|
||||
for _, cookie := range r.Cookies() {
|
||||
// We iterate here since there may, historically, be multiple
|
||||
// cookies with the same name but different path. We drop them
|
||||
// all.
|
||||
if cookie.Name == m.cookieName {
|
||||
m.tokens.Delete(cookie.Value)
|
||||
|
||||
// Create a cookie deletion command
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: m.cookieName,
|
||||
Value: "",
|
||||
MaxAge: -1,
|
||||
Secure: cookie.Secure,
|
||||
Path: cookie.Path,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
93
lib/build/parse.go
Normal file
93
lib/build/parse.go
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright (C) 2019 The Syncthing Authors.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
package build
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// syncthing v1.1.4-rc.1+30-g6aaae618-dirty-crashrep "Erbium Earthworm" (go1.12.5 darwin-amd64) jb@kvin.kastelo.net 2019-05-23 16:08:14 UTC [foo, bar]
|
||||
// or, somewhere along the way the "+" in the version tag disappeared:
|
||||
// syncthing v1.23.7-dev.26.gdf7b56ae.dirty-stversionextra "Fermium Flea" (go1.20.5 darwin-arm64) jb@ok.kastelo.net 2023-07-12 06:55:26 UTC [Some Wrapper, purego, stnoupgrade]
|
||||
var (
|
||||
longVersionRE = regexp.MustCompile(`syncthing\s+(v[^\s]+)\s+"([^"]+)"\s\(([^\s]+)\s+([^-]+)-([^)]+)\)\s+([^\s]+)[^\[]*(?:\[(.+)\])?$`)
|
||||
gitExtraRE = regexp.MustCompile(`\.\d+\.g[0-9a-f]+`) // ".1.g6aaae618"
|
||||
gitExtraSepRE = regexp.MustCompile(`[.-]`) // dot or dash
|
||||
)
|
||||
|
||||
type VersionParts struct {
|
||||
Version string // "v1.1.4-rc.1+30-g6aaae618-dirty-crashrep"
|
||||
Tag string // "v1.1.4-rc.1"
|
||||
Commit string // "6aaae618", blank when absent
|
||||
Codename string // "Erbium Earthworm"
|
||||
Runtime string // "go1.12.5"
|
||||
GOOS string // "darwin"
|
||||
GOARCH string // "amd64"
|
||||
Builder string // "jb@kvin.kastelo.net"
|
||||
Extra []string // "foo", "bar"
|
||||
}
|
||||
|
||||
func (v VersionParts) Environment() string {
|
||||
if v.Commit != "" {
|
||||
return "Development"
|
||||
}
|
||||
if strings.Contains(v.Tag, "-rc.") {
|
||||
return "Candidate"
|
||||
}
|
||||
if strings.Contains(v.Tag, "-") {
|
||||
return "Beta"
|
||||
}
|
||||
return "Stable"
|
||||
}
|
||||
|
||||
func ParseVersion(line string) (VersionParts, error) {
|
||||
m := longVersionRE.FindStringSubmatch(line)
|
||||
if len(m) == 0 {
|
||||
return VersionParts{}, errors.New("unintelligeble version string")
|
||||
}
|
||||
|
||||
v := VersionParts{
|
||||
Version: m[1],
|
||||
Codename: m[2],
|
||||
Runtime: m[3],
|
||||
GOOS: m[4],
|
||||
GOARCH: m[5],
|
||||
Builder: m[6],
|
||||
}
|
||||
|
||||
// Split the version tag into tag and commit. This is old style
|
||||
// v1.2.3-something.4+11-g12345678 or newer with just dots
|
||||
// v1.2.3-something.4.11.g12345678 or v1.2.3-dev.11.g12345678.
|
||||
parts := []string{v.Version}
|
||||
if strings.Contains(v.Version, "+") {
|
||||
parts = strings.Split(v.Version, "+")
|
||||
} else {
|
||||
idxs := gitExtraRE.FindStringIndex(v.Version)
|
||||
if len(idxs) > 0 {
|
||||
parts = []string{v.Version[:idxs[0]], v.Version[idxs[0]+1:]}
|
||||
}
|
||||
}
|
||||
v.Tag = parts[0]
|
||||
if len(parts) > 1 {
|
||||
fields := gitExtraSepRE.Split(parts[1], -1)
|
||||
if len(fields) >= 2 && strings.HasPrefix(fields[1], "g") {
|
||||
v.Commit = fields[1][1:]
|
||||
}
|
||||
}
|
||||
|
||||
if len(m) >= 8 && m[7] != "" {
|
||||
tags := strings.Split(m[7], ",")
|
||||
for i := range tags {
|
||||
tags[i] = strings.TrimSpace(tags[i])
|
||||
}
|
||||
v.Extra = tags
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
72
lib/build/parse_test.go
Normal file
72
lib/build/parse_test.go
Normal file
@@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2019 The Syncthing Authors.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseVersion(t *testing.T) {
|
||||
cases := []struct {
|
||||
longVersion string
|
||||
parsed VersionParts
|
||||
}{
|
||||
{
|
||||
longVersion: `syncthing v1.1.4-rc.1+30-g6aaae618-dirty-crashrep "Erbium Earthworm" (go1.12.5 darwin-amd64) jb@kvin.kastelo.net 2019-05-23 16:08:14 UTC`,
|
||||
parsed: VersionParts{
|
||||
Version: "v1.1.4-rc.1+30-g6aaae618-dirty-crashrep",
|
||||
Tag: "v1.1.4-rc.1",
|
||||
Commit: "6aaae618",
|
||||
Codename: "Erbium Earthworm",
|
||||
Runtime: "go1.12.5",
|
||||
GOOS: "darwin",
|
||||
GOARCH: "amd64",
|
||||
Builder: "jb@kvin.kastelo.net",
|
||||
},
|
||||
},
|
||||
{
|
||||
longVersion: `syncthing v1.1.4-rc.1+30-g6aaae618-dirty-crashrep "Erbium Earthworm" (go1.12.5 darwin-amd64) jb@kvin.kastelo.net 2019-05-23 16:08:14 UTC [foo, bar]`,
|
||||
parsed: VersionParts{
|
||||
Version: "v1.1.4-rc.1+30-g6aaae618-dirty-crashrep",
|
||||
Tag: "v1.1.4-rc.1",
|
||||
Commit: "6aaae618",
|
||||
Codename: "Erbium Earthworm",
|
||||
Runtime: "go1.12.5",
|
||||
GOOS: "darwin",
|
||||
GOARCH: "amd64",
|
||||
Builder: "jb@kvin.kastelo.net",
|
||||
Extra: []string{"foo", "bar"},
|
||||
},
|
||||
},
|
||||
{
|
||||
longVersion: `syncthing v1.23.7-dev.26.gdf7b56ae-stversionextra "Fermium Flea" (go1.20.5 darwin-arm64) jb@ok.kastelo.net 2023-07-12 06:55:26 UTC [Some Wrapper, purego, stnoupgrade]`,
|
||||
parsed: VersionParts{
|
||||
Version: "v1.23.7-dev.26.gdf7b56ae-stversionextra",
|
||||
Tag: "v1.23.7-dev",
|
||||
Commit: "df7b56ae",
|
||||
Codename: "Fermium Flea",
|
||||
Runtime: "go1.20.5",
|
||||
GOOS: "darwin",
|
||||
GOARCH: "arm64",
|
||||
Builder: "jb@ok.kastelo.net",
|
||||
Extra: []string{"Some Wrapper", "purego", "stnoupgrade"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
v, err := ParseVersion(tc.longVersion)
|
||||
if err != nil {
|
||||
t.Errorf("%s\nerror: %v\n", tc.longVersion, err)
|
||||
continue
|
||||
}
|
||||
if fmt.Sprint(v) != fmt.Sprint(tc.parsed) {
|
||||
t.Errorf("%s\nA: %v\nE: %v\n", tc.longVersion, v, tc.parsed)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
@@ -90,27 +92,51 @@ func (f *FolderConfiguration) CreateMarker() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
permBits := fs.FileMode(0o777)
|
||||
if build.IsWindows {
|
||||
// Windows has no umask so we must chose a safer set of bits to
|
||||
// begin with.
|
||||
permBits = 0o700
|
||||
}
|
||||
fs := f.Filesystem(nil)
|
||||
err := fs.Mkdir(DefaultMarkerName, permBits)
|
||||
ffs := f.Filesystem(nil)
|
||||
|
||||
// Create the marker as a directory
|
||||
err := ffs.Mkdir(DefaultMarkerName, 0o755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dir, err := fs.Open("."); err != nil {
|
||||
|
||||
// Create a file inside it, reducing the risk of the marker directory
|
||||
// being removed by automated cleanup tools.
|
||||
markerFile := filepath.Join(DefaultMarkerName, f.markerFilename())
|
||||
if err := fs.WriteFile(ffs, markerFile, f.markerContents(), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Sync & hide the containing directory
|
||||
if dir, err := ffs.Open("."); err != nil {
|
||||
l.Debugln("folder marker: open . failed:", err)
|
||||
} else if err := dir.Sync(); err != nil {
|
||||
l.Debugln("folder marker: fsync . failed:", err)
|
||||
}
|
||||
fs.Hide(DefaultMarkerName)
|
||||
ffs.Hide(DefaultMarkerName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FolderConfiguration) RemoveMarker() error {
|
||||
ffs := f.Filesystem(nil)
|
||||
_ = ffs.Remove(filepath.Join(DefaultMarkerName, f.markerFilename()))
|
||||
return ffs.Remove(DefaultMarkerName)
|
||||
}
|
||||
|
||||
func (f *FolderConfiguration) markerFilename() string {
|
||||
h := sha256.Sum256([]byte(f.ID))
|
||||
return fmt.Sprintf("syncthing-folder-%x.txt", h[:3])
|
||||
}
|
||||
|
||||
func (f *FolderConfiguration) markerContents() []byte {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString("# This directory is a Syncthing folder marker.\n# Do not delete.\n\n")
|
||||
fmt.Fprintf(&buf, "folderID: %s\n", f.ID)
|
||||
fmt.Fprintf(&buf, "created: %s\n", time.Now().Format(time.RFC3339))
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// CheckPath returns nil if the folder root exists and contains the marker file
|
||||
func (f *FolderConfiguration) CheckPath() error {
|
||||
return f.checkFilesystemPath(f.Filesystem(nil), ".")
|
||||
|
||||
@@ -75,6 +75,7 @@ type FolderConfiguration struct {
|
||||
RescanIntervalS int `protobuf:"varint,7,opt,name=rescan_interval_s,json=rescanIntervalS,proto3,casttype=int" json:"rescanIntervalS" xml:"rescanIntervalS,attr" default:"3600"`
|
||||
FSWatcherEnabled bool `protobuf:"varint,8,opt,name=fs_watcher_enabled,json=fsWatcherEnabled,proto3" json:"fsWatcherEnabled" xml:"fsWatcherEnabled,attr" default:"true"`
|
||||
FSWatcherDelayS float64 `protobuf:"fixed64,9,opt,name=fs_watcher_delay_s,json=fsWatcherDelayS,proto3" json:"fsWatcherDelayS" xml:"fsWatcherDelayS,attr" default:"10"`
|
||||
FSWatcherTimeoutS float64 `protobuf:"fixed64,40,opt,name=fs_watcher_timeout_s,json=fsWatcherTimeoutS,proto3" json:"fsWatcherTimeoutS" xml:"fsWatcherTimeoutS,attr"`
|
||||
IgnorePerms bool `protobuf:"varint,10,opt,name=ignore_perms,json=ignorePerms,proto3" json:"ignorePerms" xml:"ignorePerms,attr"`
|
||||
AutoNormalize bool `protobuf:"varint,11,opt,name=auto_normalize,json=autoNormalize,proto3" json:"autoNormalize" xml:"autoNormalize,attr" default:"true"`
|
||||
MinDiskFree Size `protobuf:"bytes,12,opt,name=min_disk_free,json=minDiskFree,proto3" json:"minDiskFree" xml:"minDiskFree" default:"1 %"`
|
||||
@@ -240,158 +241,161 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptor_44a9785876ed3afa = []byte{
|
||||
// 2413 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xcf, 0x6f, 0x24, 0x47,
|
||||
0xf5, 0x77, 0xdb, 0xbb, 0x6b, 0xbb, 0xfc, 0xbb, 0x6c, 0xef, 0x76, 0x9c, 0xc4, 0x35, 0xe9, 0xcc,
|
||||
0x26, 0x4e, 0xbe, 0x89, 0x77, 0xe3, 0x44, 0x91, 0x12, 0x7d, 0x03, 0x64, 0xec, 0x8c, 0x58, 0x16,
|
||||
0x67, 0xad, 0x1e, 0x43, 0x20, 0x41, 0x6a, 0xda, 0xdd, 0x35, 0x33, 0x1d, 0xf7, 0x8f, 0xa1, 0xab,
|
||||
0xbd, 0xf6, 0xec, 0x21, 0x0a, 0x39, 0x20, 0x24, 0x72, 0x40, 0xe6, 0x80, 0x38, 0x20, 0x45, 0x02,
|
||||
0x21, 0x08, 0x17, 0xce, 0xfc, 0x05, 0xb9, 0x20, 0xfb, 0x84, 0x10, 0x87, 0x92, 0xe2, 0xbd, 0xcd,
|
||||
0x71, 0x8e, 0x7b, 0x42, 0xef, 0xf5, 0x8f, 0xa9, 0x9e, 0x99, 0x48, 0x48, 0xdc, 0xa6, 0x3e, 0x9f,
|
||||
0x57, 0xef, 0x7d, 0xfa, 0x55, 0xd5, 0xab, 0x57, 0x43, 0xaa, 0xbe, 0x77, 0x74, 0xc7, 0x89, 0xc2,
|
||||
0xa6, 0xd7, 0xba, 0xd3, 0x8c, 0x7c, 0x97, 0xc7, 0xe9, 0xe0, 0x24, 0xb6, 0x13, 0x2f, 0x0a, 0xb7,
|
||||
0x3b, 0x71, 0x94, 0x44, 0xf4, 0x46, 0x0a, 0x6e, 0x3c, 0x3d, 0x62, 0x9d, 0x74, 0x3b, 0x3c, 0x35,
|
||||
0xda, 0x58, 0x57, 0x48, 0xe1, 0x3d, 0xca, 0xe1, 0x0d, 0x05, 0xee, 0x9c, 0xf8, 0x7e, 0x14, 0xbb,
|
||||
0x3c, 0xce, 0xb8, 0x2d, 0x85, 0x7b, 0xc8, 0x63, 0xe1, 0x45, 0xa1, 0x17, 0xb6, 0xc6, 0x28, 0xd8,
|
||||
0x60, 0x8a, 0xe5, 0x91, 0x1f, 0x39, 0xc7, 0xc3, 0xae, 0x28, 0x18, 0x34, 0xc5, 0x1d, 0x10, 0x24,
|
||||
0x32, 0xec, 0x99, 0x0c, 0x73, 0xa2, 0x4e, 0x37, 0xb6, 0xc3, 0x16, 0x0f, 0x78, 0xd2, 0x8e, 0xdc,
|
||||
0x8c, 0x9d, 0xe5, 0x67, 0x49, 0xfa, 0xd3, 0xf8, 0xe7, 0x14, 0x79, 0xaa, 0x8e, 0xdf, 0xb3, 0xc7,
|
||||
0x1f, 0x7a, 0x0e, 0xdf, 0x55, 0x15, 0xd0, 0x2f, 0x35, 0x32, 0xeb, 0x22, 0x6e, 0x79, 0xae, 0xae,
|
||||
0x55, 0xb4, 0xad, 0xf9, 0xda, 0xe7, 0xda, 0x57, 0x92, 0x4d, 0xfc, 0x5b, 0xb2, 0x37, 0x5a, 0x5e,
|
||||
0xd2, 0x3e, 0x39, 0xda, 0x76, 0xa2, 0xe0, 0x8e, 0xe8, 0x86, 0x4e, 0xd2, 0xf6, 0xc2, 0x96, 0xf2,
|
||||
0x0b, 0x24, 0x60, 0x10, 0x27, 0xf2, 0xb7, 0x53, 0xef, 0xf7, 0xf6, 0xae, 0x24, 0x9b, 0xc9, 0x7f,
|
||||
0xf7, 0x24, 0x9b, 0x71, 0xb3, 0xdf, 0x7d, 0xc9, 0x16, 0xce, 0x02, 0xff, 0x6d, 0xc3, 0x73, 0x5f,
|
||||
0xb1, 0x93, 0x24, 0x36, 0x7a, 0x17, 0xd5, 0xe9, 0xec, 0x77, 0xff, 0xa2, 0x5a, 0xd8, 0xfd, 0xf2,
|
||||
0xb2, 0xaa, 0x9d, 0x5f, 0x56, 0x0b, 0x1f, 0x66, 0xce, 0xb8, 0xf4, 0x4f, 0x1a, 0x59, 0xf0, 0xc2,
|
||||
0x24, 0x8e, 0xdc, 0x13, 0x87, 0xbb, 0xd6, 0x51, 0x57, 0x9f, 0x44, 0xc1, 0x9f, 0xfe, 0x4f, 0x82,
|
||||
0x7b, 0x92, 0xcd, 0x0f, 0xbc, 0xd6, 0xba, 0x7d, 0xc9, 0x6e, 0xa5, 0x42, 0x15, 0xb0, 0x90, 0xbc,
|
||||
0x32, 0x82, 0x82, 0x60, 0xb3, 0xe4, 0x81, 0x3a, 0x64, 0x95, 0x87, 0x4e, 0xdc, 0xed, 0x40, 0x8e,
|
||||
0xad, 0x8e, 0x2d, 0xc4, 0x69, 0x14, 0xbb, 0xfa, 0x54, 0x45, 0xdb, 0x9a, 0xad, 0xed, 0xf4, 0x24,
|
||||
0xa3, 0x03, 0xfa, 0x20, 0x63, 0xfb, 0x92, 0xe9, 0x18, 0x76, 0x94, 0x32, 0xcc, 0x31, 0xf6, 0xc6,
|
||||
0x79, 0x95, 0xac, 0xa6, 0x0b, 0x5b, 0x5e, 0xd2, 0x06, 0x99, 0xcc, 0x96, 0x72, 0xb6, 0xb6, 0x7b,
|
||||
0x25, 0xd9, 0x24, 0x7e, 0xe2, 0xa4, 0x07, 0x11, 0x36, 0x4b, 0x2b, 0x50, 0x09, 0x23, 0x97, 0x37,
|
||||
0xed, 0x13, 0x3f, 0x79, 0xdb, 0x48, 0xe2, 0x13, 0xae, 0x2e, 0xc9, 0xf9, 0x65, 0x75, 0xf2, 0xde,
|
||||
0xde, 0x17, 0xf0, 0x6d, 0x93, 0x9e, 0x4b, 0x7f, 0x40, 0xae, 0xfb, 0xf6, 0x11, 0xf7, 0x31, 0xe3,
|
||||
0xb3, 0xb5, 0x6f, 0xf7, 0x24, 0x4b, 0x81, 0xbe, 0x64, 0x15, 0x74, 0x8a, 0xa3, 0xcc, 0x6f, 0xcc,
|
||||
0x45, 0x62, 0xc7, 0xc9, 0xdb, 0x46, 0xd3, 0xf6, 0x05, 0xba, 0x25, 0x03, 0xfa, 0xd3, 0xcb, 0xea,
|
||||
0x84, 0x99, 0x4e, 0xa6, 0x2d, 0xb2, 0xd4, 0xf4, 0x7c, 0x2e, 0xba, 0x22, 0xe1, 0x81, 0x05, 0xfb,
|
||||
0x1b, 0x93, 0xb4, 0xb8, 0x43, 0xb7, 0x9b, 0x62, 0xbb, 0x5e, 0x50, 0x87, 0xdd, 0x0e, 0xaf, 0xbd,
|
||||
0xdc, 0x93, 0x6c, 0xb1, 0x59, 0xc2, 0xfa, 0x92, 0xad, 0x61, 0xf4, 0x32, 0x6c, 0x98, 0x43, 0x76,
|
||||
0x74, 0x9f, 0x5c, 0xeb, 0xd8, 0x49, 0x5b, 0xbf, 0x86, 0xf2, 0xdf, 0xea, 0x49, 0x86, 0xe3, 0xbe,
|
||||
0x64, 0x4f, 0xe3, 0x7c, 0x18, 0x64, 0xe2, 0x8b, 0x94, 0x7c, 0x02, 0xc2, 0x67, 0x0b, 0xe6, 0xc9,
|
||||
0x45, 0x55, 0xfb, 0xc4, 0xc4, 0x69, 0xf4, 0x80, 0x5c, 0x43, 0xb1, 0xd7, 0x33, 0xb1, 0xe9, 0xe9,
|
||||
0xdd, 0x4e, 0x97, 0x03, 0xc5, 0x6e, 0x41, 0x88, 0x24, 0x95, 0xb8, 0x84, 0x21, 0x60, 0x50, 0x6c,
|
||||
0xa3, 0xd9, 0x62, 0x64, 0xa2, 0x15, 0xfd, 0x09, 0x99, 0x4e, 0xf7, 0xb9, 0xd0, 0x6f, 0x54, 0xa6,
|
||||
0xb6, 0xe6, 0x76, 0x9e, 0x2b, 0x3b, 0x1d, 0x73, 0x78, 0x6b, 0x0c, 0xb6, 0x7d, 0x4f, 0xb2, 0x7c,
|
||||
0x66, 0x5f, 0xb2, 0x79, 0x0c, 0x95, 0x8e, 0x0d, 0x33, 0x27, 0xe8, 0x6f, 0x34, 0xb2, 0x12, 0x73,
|
||||
0xe1, 0xd8, 0xa1, 0xe5, 0x85, 0x09, 0x8f, 0x1f, 0xda, 0xbe, 0x25, 0xf4, 0xe9, 0x8a, 0xb6, 0x75,
|
||||
0xbd, 0xd6, 0xea, 0x49, 0xb6, 0x94, 0x92, 0xf7, 0x32, 0xae, 0xd1, 0x97, 0xec, 0x25, 0xf4, 0x34,
|
||||
0x84, 0x0f, 0xa7, 0xe8, 0xf5, 0x37, 0xef, 0xde, 0x35, 0x9e, 0x48, 0x36, 0xe5, 0x85, 0x49, 0xef,
|
||||
0xa2, 0xba, 0x36, 0xce, 0xfc, 0xc9, 0x45, 0xf5, 0x1a, 0xd8, 0x99, 0xc3, 0x41, 0xe8, 0xdf, 0x35,
|
||||
0x42, 0x9b, 0xc2, 0x3a, 0xb5, 0x13, 0xa7, 0xcd, 0x63, 0x8b, 0x87, 0xf6, 0x91, 0xcf, 0x5d, 0x7d,
|
||||
0xa6, 0xa2, 0x6d, 0xcd, 0xd4, 0x7e, 0xa5, 0x5d, 0x49, 0xb6, 0x5c, 0x6f, 0x7c, 0x90, 0xb2, 0xef,
|
||||
0xa5, 0x64, 0x4f, 0xb2, 0xe5, 0xa6, 0x28, 0x63, 0x7d, 0xc9, 0x5e, 0x4e, 0x37, 0xc1, 0x10, 0x31,
|
||||
0xac, 0x36, 0xdf, 0xe3, 0xeb, 0x63, 0x0d, 0x41, 0x27, 0x58, 0x9c, 0x5f, 0x56, 0x47, 0xc2, 0x9a,
|
||||
0x23, 0x41, 0xe9, 0xdf, 0xca, 0xe2, 0x5d, 0xee, 0xdb, 0x5d, 0x4b, 0xe8, 0xb3, 0x15, 0x6d, 0x4b,
|
||||
0xab, 0x7d, 0x06, 0xe2, 0x97, 0x0a, 0x2f, 0x7b, 0x40, 0x36, 0x20, 0xcf, 0x85, 0x9b, 0x14, 0xea,
|
||||
0x4b, 0xf6, 0x62, 0x59, 0x7a, 0x8a, 0x0f, 0x2b, 0x7f, 0xed, 0x2e, 0xe8, 0x5e, 0x1b, 0x67, 0xf5,
|
||||
0xe4, 0xa2, 0x3a, 0xf9, 0xda, 0xdd, 0xf3, 0xcb, 0xea, 0x70, 0x38, 0x73, 0x38, 0x18, 0xfd, 0x29,
|
||||
0x99, 0xf7, 0x5a, 0x61, 0x14, 0x73, 0xab, 0xc3, 0xe3, 0x40, 0xe8, 0x04, 0x13, 0xfd, 0x4e, 0x4f,
|
||||
0xb2, 0xb9, 0x14, 0x3f, 0x00, 0xb8, 0x2f, 0xd9, 0xcd, 0xb4, 0x4c, 0x0c, 0xb0, 0x62, 0xdf, 0x2e,
|
||||
0x0f, 0x83, 0xa6, 0x3a, 0x95, 0xfe, 0x5c, 0x23, 0x8b, 0xf6, 0x49, 0x12, 0x59, 0x61, 0x14, 0x07,
|
||||
0xb6, 0xef, 0x3d, 0xe2, 0xfa, 0x1c, 0x06, 0xf9, 0xb0, 0x27, 0xd9, 0x02, 0x30, 0xef, 0xe7, 0x44,
|
||||
0xf1, 0xe9, 0x25, 0xf4, 0x9b, 0x96, 0x8c, 0x8e, 0x5a, 0xe5, 0xeb, 0x65, 0x96, 0xfd, 0xd2, 0x88,
|
||||
0x2c, 0x04, 0x5e, 0x68, 0xb9, 0x9e, 0x38, 0xb6, 0x9a, 0x31, 0xe7, 0xfa, 0x7c, 0x45, 0xdb, 0x9a,
|
||||
0xdb, 0x99, 0xcf, 0xcf, 0x53, 0xc3, 0x7b, 0xc4, 0x6b, 0xef, 0x64, 0x47, 0x67, 0x2e, 0xf0, 0xc2,
|
||||
0x3d, 0x4f, 0x1c, 0xd7, 0x63, 0x0e, 0x8a, 0x18, 0x2a, 0x52, 0x30, 0x75, 0x0d, 0x2a, 0xb7, 0x8d,
|
||||
0x27, 0x17, 0xd5, 0xa9, 0xd7, 0x2a, 0xb7, 0x4d, 0x75, 0x1a, 0x6d, 0x11, 0x32, 0xb8, 0xe0, 0xf5,
|
||||
0x05, 0x8c, 0xc6, 0xf2, 0x68, 0x3f, 0x2c, 0x98, 0xf2, 0xd9, 0x7d, 0x21, 0x13, 0xa0, 0x4c, 0xed,
|
||||
0x4b, 0xb6, 0x8c, 0xf1, 0x07, 0x90, 0x61, 0x2a, 0x3c, 0x7d, 0x87, 0x4c, 0x3b, 0x51, 0xc7, 0xe3,
|
||||
0xb1, 0xd0, 0x17, 0xf1, 0xe8, 0x3e, 0x0f, 0x87, 0x3f, 0x83, 0x8a, 0xfb, 0x35, 0x1b, 0xe7, 0xc7,
|
||||
0xd2, 0xcc, 0x0d, 0xe8, 0x3f, 0x34, 0x72, 0x13, 0x5a, 0x0b, 0x1e, 0x5b, 0x81, 0x7d, 0x66, 0x75,
|
||||
0x78, 0xe8, 0x7a, 0x61, 0xcb, 0x3a, 0xf6, 0x8e, 0xf4, 0x25, 0x74, 0xf7, 0x5b, 0xd8, 0xb5, 0xab,
|
||||
0x07, 0x68, 0xb2, 0x6f, 0x9f, 0x1d, 0xa4, 0x06, 0xf7, 0xbd, 0x5a, 0x4f, 0xb2, 0xd5, 0xce, 0x28,
|
||||
0xdc, 0x97, 0xec, 0xa9, 0xb4, 0x7a, 0x8e, 0x72, 0x4a, 0x55, 0x18, 0x3b, 0x75, 0x3c, 0x7c, 0x7e,
|
||||
0x59, 0x1d, 0x17, 0xdf, 0x1c, 0x63, 0x7b, 0x04, 0xe9, 0x68, 0xdb, 0xa2, 0x0d, 0xe9, 0x58, 0x1e,
|
||||
0xa4, 0x23, 0x83, 0x8a, 0x74, 0x64, 0xe3, 0x41, 0x3a, 0x32, 0x80, 0xbe, 0x4b, 0xae, 0x63, 0x93,
|
||||
0xa5, 0xaf, 0x60, 0x11, 0x5f, 0xc9, 0x57, 0x0c, 0xe2, 0x3f, 0x00, 0xa2, 0xa6, 0xc3, 0x2d, 0x87,
|
||||
0x36, 0x7d, 0xc9, 0xe6, 0xd0, 0x1b, 0x8e, 0x0c, 0x33, 0x45, 0xe9, 0x7d, 0xb2, 0x90, 0x1d, 0x28,
|
||||
0x97, 0xfb, 0x3c, 0xe1, 0x3a, 0xc5, 0xcd, 0xfe, 0x02, 0xb6, 0x14, 0x48, 0xec, 0x21, 0xde, 0x97,
|
||||
0x8c, 0x2a, 0x47, 0x2a, 0x05, 0x0d, 0xb3, 0x64, 0x43, 0xcf, 0x88, 0x8e, 0x05, 0xba, 0x13, 0x47,
|
||||
0xad, 0x98, 0x0b, 0xa1, 0x56, 0xea, 0x55, 0xfc, 0x3e, 0xb8, 0x75, 0xd7, 0xc1, 0xe6, 0x20, 0x33,
|
||||
0x51, 0xeb, 0x75, 0x7a, 0x8f, 0x8d, 0x65, 0x8b, 0x6f, 0x1f, 0x3f, 0x99, 0x36, 0xc8, 0x62, 0xb6,
|
||||
0x2f, 0x3a, 0xf6, 0x89, 0xe0, 0x96, 0xd0, 0xd7, 0x30, 0xde, 0xab, 0xf0, 0x1d, 0x29, 0x73, 0x00,
|
||||
0x44, 0xa3, 0xf8, 0x0e, 0x15, 0x2c, 0xbc, 0x97, 0x4c, 0x29, 0x27, 0x0b, 0xb0, 0xcb, 0x20, 0xa9,
|
||||
0xbe, 0xe7, 0x24, 0x42, 0x5f, 0x47, 0x9f, 0xdf, 0x01, 0x9f, 0x81, 0x7d, 0xb6, 0x9b, 0xe3, 0x83,
|
||||
0x53, 0xa7, 0x80, 0xe5, 0xd2, 0x97, 0x05, 0x48, 0x2b, 0x9d, 0x59, 0x9a, 0x4d, 0x5d, 0xb2, 0xe6,
|
||||
0x7a, 0x02, 0x4a, 0xb2, 0x25, 0x3a, 0x76, 0x2c, 0xb8, 0x85, 0x37, 0xbf, 0x7e, 0x13, 0x57, 0x02,
|
||||
0x7b, 0xad, 0x8c, 0x6f, 0x20, 0x8d, 0x3d, 0x45, 0xd1, 0x6b, 0x8d, 0x52, 0x86, 0x39, 0xc6, 0x5e,
|
||||
0x8d, 0x92, 0xf0, 0xa0, 0x63, 0x79, 0xa1, 0xcb, 0xcf, 0xb8, 0xd0, 0x6f, 0x8d, 0x44, 0x39, 0xe4,
|
||||
0x41, 0xe7, 0x5e, 0xca, 0x0e, 0x47, 0x51, 0xa8, 0x41, 0x14, 0x05, 0xa4, 0x3b, 0xe4, 0x06, 0x2e,
|
||||
0x80, 0xab, 0xeb, 0xe8, 0x77, 0xa3, 0x27, 0x59, 0x86, 0x14, 0x57, 0x7b, 0x3a, 0x34, 0xcc, 0x0c,
|
||||
0xa7, 0x09, 0xb9, 0x75, 0xca, 0xed, 0x63, 0x0b, 0x76, 0xb5, 0x95, 0xb4, 0x63, 0x2e, 0xda, 0x91,
|
||||
0xef, 0x5a, 0x1d, 0x27, 0xd1, 0x9f, 0xc2, 0x84, 0x43, 0x79, 0x5f, 0x03, 0x93, 0xef, 0xda, 0xa2,
|
||||
0x7d, 0x98, 0x1b, 0x1c, 0x38, 0x49, 0x5f, 0xb2, 0x0d, 0x74, 0x39, 0x8e, 0x2c, 0x16, 0x75, 0xec,
|
||||
0x54, 0xba, 0x4b, 0xe6, 0x02, 0x3b, 0x3e, 0xe6, 0xb1, 0x15, 0xda, 0x01, 0xd7, 0x37, 0xb0, 0xab,
|
||||
0x32, 0xa0, 0x9c, 0xa5, 0xf0, 0xfb, 0x76, 0xc0, 0x8b, 0x72, 0x36, 0x80, 0x0c, 0x53, 0xe1, 0x69,
|
||||
0x97, 0x6c, 0xc0, 0xeb, 0xc5, 0x8a, 0x4e, 0x43, 0x1e, 0x8b, 0xb6, 0xd7, 0xb1, 0x9a, 0x71, 0x14,
|
||||
0x58, 0x1d, 0x3b, 0xe6, 0x61, 0xa2, 0x3f, 0x8d, 0x29, 0xf8, 0xff, 0x9e, 0x64, 0xb7, 0xc0, 0xea,
|
||||
0x41, 0x6e, 0x54, 0x8f, 0xa3, 0xe0, 0x00, 0x4d, 0xfa, 0x92, 0x3d, 0x9b, 0x57, 0xbc, 0x71, 0xbc,
|
||||
0x61, 0x7e, 0xd3, 0x4c, 0xfa, 0x0b, 0x8d, 0xac, 0x04, 0x91, 0x6b, 0x25, 0x5e, 0xc0, 0xad, 0x53,
|
||||
0x2f, 0x74, 0xa3, 0x53, 0x4b, 0xe8, 0xcf, 0x60, 0xc2, 0x3e, 0xba, 0x92, 0x6c, 0xc5, 0xb4, 0x4f,
|
||||
0xf7, 0x23, 0xf7, 0xd0, 0x0b, 0xf8, 0x07, 0xc8, 0xc2, 0xe5, 0xbd, 0x18, 0x94, 0x90, 0xa2, 0xf7,
|
||||
0x2c, 0xc3, 0x79, 0xe6, 0xce, 0x2f, 0xab, 0xa3, 0x5e, 0xcc, 0x21, 0x1f, 0xf4, 0x53, 0x8d, 0xac,
|
||||
0x67, 0xc7, 0xc4, 0x39, 0x89, 0x41, 0x9b, 0x75, 0x1a, 0x7b, 0x09, 0x17, 0xfa, 0xb3, 0x28, 0xe6,
|
||||
0xfb, 0x50, 0x7a, 0xd3, 0x0d, 0x9f, 0xf1, 0x1f, 0x20, 0xdd, 0x97, 0xec, 0xb6, 0x72, 0x6a, 0x4a,
|
||||
0x9c, 0x72, 0x78, 0x76, 0x94, 0xb3, 0xa3, 0xed, 0x98, 0xe3, 0x3c, 0x41, 0x11, 0xcb, 0xf7, 0x76,
|
||||
0x13, 0x9e, 0x4a, 0xfa, 0xe6, 0xa0, 0x88, 0x65, 0x44, 0x1d, 0xf0, 0xe2, 0xf0, 0xab, 0xa0, 0x61,
|
||||
0x96, 0x6c, 0xa8, 0x4f, 0x96, 0xf1, 0x09, 0x6b, 0x41, 0x2d, 0xb0, 0xd2, 0xfa, 0xca, 0xb0, 0xbe,
|
||||
0xde, 0xcc, 0xeb, 0x6b, 0x0d, 0xf8, 0x41, 0x91, 0xc5, 0xae, 0xfe, 0xa8, 0x84, 0x15, 0x99, 0x2d,
|
||||
0xc3, 0x86, 0x39, 0x64, 0x47, 0x3f, 0xd7, 0xc8, 0x0a, 0x6e, 0x21, 0x7c, 0x01, 0x5b, 0xe9, 0x13,
|
||||
0x58, 0xaf, 0x60, 0xbc, 0x55, 0x78, 0x41, 0xec, 0x46, 0x9d, 0xae, 0x09, 0xdc, 0x3e, 0x52, 0xb5,
|
||||
0xfb, 0xd0, 0x83, 0x39, 0x65, 0xb0, 0x2f, 0xd9, 0x56, 0xb1, 0x8d, 0x14, 0x5c, 0x49, 0xa3, 0x48,
|
||||
0xec, 0xd0, 0xb5, 0x63, 0x17, 0xee, 0xff, 0x99, 0x7c, 0x60, 0x0e, 0x3b, 0xa2, 0x7f, 0x04, 0x39,
|
||||
0x36, 0x14, 0x50, 0x1e, 0x0a, 0x2f, 0xf1, 0x1e, 0x42, 0x46, 0xf5, 0xe7, 0x30, 0x9d, 0x67, 0xd0,
|
||||
0x10, 0xee, 0xda, 0x82, 0x37, 0x72, 0xae, 0x8e, 0x0d, 0xa1, 0x53, 0x86, 0xfa, 0x92, 0xad, 0xa7,
|
||||
0x62, 0xca, 0x38, 0xf4, 0x40, 0x23, 0xb6, 0xa3, 0x10, 0xb4, 0x81, 0x43, 0x41, 0xcc, 0x21, 0x1b,
|
||||
0x41, 0xff, 0xa0, 0x91, 0xe5, 0x66, 0xe4, 0xfb, 0xd1, 0xa9, 0xf5, 0xf1, 0x49, 0xe8, 0x40, 0x3b,
|
||||
0x22, 0x74, 0x63, 0xa0, 0xf2, 0x7b, 0x39, 0xf8, 0xae, 0xd8, 0xf3, 0x62, 0x01, 0x2a, 0x3f, 0x2e,
|
||||
0x43, 0x85, 0xca, 0x21, 0x1c, 0x55, 0x0e, 0xdb, 0x8e, 0x42, 0xa0, 0x72, 0x28, 0x88, 0xb9, 0x94,
|
||||
0x2a, 0x2a, 0x60, 0xfa, 0x80, 0x2c, 0xc2, 0x8e, 0x1a, 0x54, 0x07, 0xfd, 0x79, 0x94, 0x08, 0x0f,
|
||||
0xab, 0x05, 0x60, 0x8a, 0x73, 0xdd, 0x97, 0x6c, 0x35, 0xbd, 0xfc, 0x54, 0xd4, 0x30, 0xcb, 0x56,
|
||||
0xe8, 0x90, 0x87, 0xae, 0xe2, 0xb0, 0xaa, 0x38, 0xe4, 0xa1, 0x3b, 0xc6, 0xa1, 0x8a, 0x82, 0x43,
|
||||
0x75, 0x0c, 0x45, 0x10, 0x15, 0x9e, 0x41, 0x37, 0x2a, 0xf4, 0xdb, 0xe8, 0x0d, 0x8b, 0x20, 0xc0,
|
||||
0x3f, 0x42, 0xb4, 0x28, 0x82, 0x03, 0xc8, 0x30, 0x15, 0x1e, 0x9d, 0x80, 0xaa, 0xcc, 0xc9, 0x0b,
|
||||
0x8a, 0x13, 0x1e, 0xba, 0xc3, 0x4e, 0x0a, 0x08, 0x9c, 0x14, 0x03, 0x68, 0xec, 0x71, 0x3e, 0xdc,
|
||||
0x7d, 0x09, 0x8f, 0xf5, 0x17, 0xb1, 0x07, 0x5d, 0xcd, 0x4f, 0x1c, 0x5a, 0xd5, 0x91, 0xaa, 0x6d,
|
||||
0xe5, 0x8d, 0xef, 0xd9, 0x00, 0xec, 0x4b, 0xb6, 0x82, 0xfe, 0x15, 0xcc, 0x30, 0x55, 0x0b, 0x7a,
|
||||
0x4c, 0x66, 0x63, 0x6e, 0xbb, 0x56, 0x14, 0xfa, 0x5d, 0xfd, 0xcf, 0x75, 0x54, 0xb9, 0x7f, 0x25,
|
||||
0x19, 0xdd, 0xe3, 0x9d, 0x98, 0x3b, 0x76, 0xc2, 0x5d, 0x93, 0xdb, 0xee, 0x83, 0xd0, 0xef, 0xf6,
|
||||
0x24, 0xd3, 0x5e, 0x2d, 0xfe, 0x44, 0x89, 0x23, 0x6c, 0xd6, 0x5f, 0x89, 0x02, 0x0f, 0x6e, 0xce,
|
||||
0xa4, 0x8b, 0x7f, 0xa2, 0x8c, 0xa0, 0xba, 0x66, 0xce, 0xc4, 0x99, 0x03, 0xfa, 0x33, 0xb2, 0x52,
|
||||
0xea, 0xe0, 0xf1, 0x36, 0xfb, 0x4b, 0x1d, 0x5f, 0x56, 0xef, 0x5d, 0x49, 0xa6, 0x0f, 0x82, 0xee,
|
||||
0x0f, 0xfa, 0xf0, 0x03, 0x27, 0xc9, 0x43, 0x6f, 0x0e, 0xb7, 0xf1, 0x07, 0x4e, 0xa2, 0x28, 0xd0,
|
||||
0x35, 0x73, 0xb1, 0x4c, 0xd2, 0x1f, 0x93, 0xe9, 0xb4, 0x7b, 0x11, 0xfa, 0x97, 0x75, 0xac, 0xbc,
|
||||
0xdf, 0x82, 0x6b, 0x60, 0x10, 0x28, 0xed, 0x4a, 0x45, 0xf9, 0xe3, 0xb2, 0x29, 0x8a, 0xeb, 0xac,
|
||||
0xdc, 0xea, 0x9a, 0x99, 0xfb, 0xa3, 0xc7, 0x64, 0x11, 0xfb, 0xba, 0xc1, 0xbe, 0xfb, 0x6b, 0x9a,
|
||||
0xbf, 0xdd, 0x2b, 0xc9, 0x6e, 0x0d, 0x22, 0x34, 0x1c, 0x3b, 0x2c, 0x36, 0x57, 0x1e, 0xe7, 0xd9,
|
||||
0xa2, 0xab, 0x2b, 0xa8, 0xf2, 0x87, 0x2c, 0x94, 0x38, 0xe3, 0xb3, 0x29, 0x32, 0xa7, 0x2c, 0x37,
|
||||
0xfd, 0x88, 0x4c, 0xf3, 0x30, 0x89, 0x3d, 0x2e, 0x74, 0x0d, 0xff, 0x56, 0xd0, 0xc7, 0x6c, 0x8a,
|
||||
0xf7, 0xc2, 0x24, 0xee, 0xd6, 0x5e, 0xcc, 0xff, 0x4d, 0xc8, 0x26, 0x14, 0x3d, 0x2f, 0x8c, 0x71,
|
||||
0xd9, 0xae, 0xe3, 0x2f, 0x33, 0x37, 0xa0, 0xbf, 0xcb, 0x2e, 0x2f, 0xe1, 0x85, 0x2d, 0x9f, 0x5b,
|
||||
0xc8, 0x5a, 0x02, 0x1e, 0x7d, 0x93, 0x98, 0xc2, 0x26, 0xf4, 0x45, 0x81, 0x7d, 0xd6, 0x40, 0x1e,
|
||||
0xa3, 0x34, 0xd4, 0x97, 0xdf, 0x28, 0x55, 0xea, 0xfb, 0x76, 0xde, 0x50, 0x1e, 0x11, 0x63, 0xfc,
|
||||
0xc0, 0x03, 0x10, 0xac, 0xcc, 0x31, 0x1c, 0x7d, 0x44, 0x16, 0x41, 0x5a, 0x12, 0x25, 0xd0, 0x40,
|
||||
0x83, 0xa6, 0x29, 0xd4, 0x74, 0x98, 0xf5, 0x9f, 0x87, 0x40, 0x64, 0x6a, 0x9e, 0xcb, 0xd5, 0x14,
|
||||
0xa0, 0xa2, 0xe3, 0x8d, 0xbb, 0x6f, 0xbd, 0xa9, 0xe8, 0x28, 0xcd, 0x05, 0x05, 0xc0, 0x9b, 0x25,
|
||||
0xd4, 0xf8, 0xbd, 0x46, 0x96, 0x87, 0xd3, 0x0b, 0xcf, 0x8d, 0x00, 0x5e, 0xe3, 0xd9, 0x3f, 0x73,
|
||||
0xff, 0x07, 0x6f, 0x0b, 0x04, 0x94, 0x3e, 0x29, 0x71, 0xda, 0xc5, 0x4b, 0x9b, 0x0c, 0x86, 0x66,
|
||||
0x6a, 0x48, 0xeb, 0xe4, 0x06, 0x3c, 0xdc, 0xbd, 0x04, 0xf3, 0x3b, 0x53, 0xdb, 0xc6, 0xfe, 0x10,
|
||||
0x91, 0xe2, 0x08, 0xa7, 0xc3, 0xc2, 0xcb, 0x9c, 0x32, 0x36, 0x33, 0xdb, 0xda, 0xfd, 0xaf, 0xbe,
|
||||
0xde, 0x9c, 0xb8, 0xfc, 0x7a, 0x73, 0xe2, 0xab, 0xab, 0x4d, 0xed, 0xf2, 0x6a, 0x53, 0xfb, 0xf5,
|
||||
0xe3, 0xcd, 0x89, 0x2f, 0x1e, 0x6f, 0x6a, 0x97, 0x8f, 0x37, 0x27, 0xfe, 0xf5, 0x78, 0x73, 0xe2,
|
||||
0xc3, 0x97, 0xfe, 0x8b, 0x3f, 0x52, 0xd3, 0x7d, 0x74, 0x74, 0x03, 0xff, 0x50, 0x7d, 0xfd, 0x3f,
|
||||
0x01, 0x00, 0x00, 0xff, 0xff, 0xe3, 0x79, 0xd7, 0x43, 0x6e, 0x17, 0x00, 0x00,
|
||||
// 2460 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0x4d, 0x6c, 0x24, 0x47,
|
||||
0x15, 0x76, 0xdb, 0xfb, 0x63, 0x97, 0xd7, 0x5e, 0xbb, 0x6c, 0xef, 0x76, 0x9c, 0xc4, 0x35, 0xe9,
|
||||
0xcc, 0x26, 0x93, 0x90, 0x78, 0x37, 0x4e, 0x14, 0x29, 0x11, 0x01, 0x32, 0x76, 0x46, 0x2c, 0x8b,
|
||||
0xb3, 0x56, 0x8f, 0x21, 0x90, 0x20, 0x35, 0xed, 0xee, 0x9a, 0x99, 0x8e, 0x7b, 0xba, 0x87, 0xae,
|
||||
0xf6, 0xda, 0xb3, 0x87, 0x28, 0xe4, 0x80, 0x90, 0xc8, 0x01, 0x99, 0x03, 0xe2, 0x80, 0x14, 0x09,
|
||||
0x84, 0x20, 0x5c, 0x38, 0x73, 0xe1, 0xba, 0x17, 0x64, 0x9f, 0x10, 0xe2, 0x50, 0x52, 0xbc, 0xb7,
|
||||
0x39, 0xf6, 0x71, 0x4f, 0xe8, 0xbd, 0xfe, 0x99, 0xea, 0x99, 0x89, 0x84, 0xc4, 0x6d, 0xea, 0xfb,
|
||||
0x5e, 0xbd, 0xf7, 0x75, 0xd5, 0xab, 0x57, 0xaf, 0x86, 0x54, 0x7d, 0xef, 0xe0, 0xb6, 0x13, 0x06,
|
||||
0x2d, 0xaf, 0x7d, 0xbb, 0x15, 0xfa, 0x2e, 0x8f, 0xd2, 0xc1, 0x51, 0x64, 0xc7, 0x5e, 0x18, 0x6c,
|
||||
0xf6, 0xa2, 0x30, 0x0e, 0xe9, 0x95, 0x14, 0x5c, 0x7f, 0x7a, 0xcc, 0x3a, 0xee, 0xf7, 0x78, 0x6a,
|
||||
0xb4, 0xbe, 0xa6, 0x90, 0xc2, 0x7b, 0x98, 0xc3, 0xeb, 0x0a, 0xdc, 0x3b, 0xf2, 0xfd, 0x30, 0x72,
|
||||
0x79, 0x94, 0x71, 0x35, 0x85, 0x7b, 0xc0, 0x23, 0xe1, 0x85, 0x81, 0x17, 0xb4, 0x27, 0x28, 0x58,
|
||||
0x67, 0x8a, 0xe5, 0x81, 0x1f, 0x3a, 0x87, 0xa3, 0xae, 0x28, 0x18, 0xb4, 0xc4, 0x6d, 0x10, 0x24,
|
||||
0x32, 0xec, 0x99, 0x0c, 0x73, 0xc2, 0x5e, 0x3f, 0xb2, 0x83, 0x36, 0xef, 0xf2, 0xb8, 0x13, 0xba,
|
||||
0x19, 0x3b, 0xc7, 0x4f, 0xe2, 0xf4, 0xa7, 0xf1, 0xaf, 0x19, 0xf2, 0x54, 0x03, 0xbf, 0x67, 0x87,
|
||||
0x3f, 0xf0, 0x1c, 0xbe, 0xad, 0x2a, 0xa0, 0x5f, 0x6a, 0x64, 0xce, 0x45, 0xdc, 0xf2, 0x5c, 0x5d,
|
||||
0xab, 0x68, 0xb5, 0x6b, 0xf5, 0xcf, 0xb5, 0x47, 0x92, 0x4d, 0xfd, 0x47, 0xb2, 0x37, 0xda, 0x5e,
|
||||
0xdc, 0x39, 0x3a, 0xd8, 0x74, 0xc2, 0xee, 0x6d, 0xd1, 0x0f, 0x9c, 0xb8, 0xe3, 0x05, 0x6d, 0xe5,
|
||||
0x17, 0x48, 0xc0, 0x20, 0x4e, 0xe8, 0x6f, 0xa6, 0xde, 0xef, 0xee, 0x5c, 0x48, 0x36, 0x9b, 0xff,
|
||||
0x1e, 0x48, 0x36, 0xeb, 0x66, 0xbf, 0x13, 0xc9, 0x16, 0x4e, 0xba, 0xfe, 0xdb, 0x86, 0xe7, 0xbe,
|
||||
0x62, 0xc7, 0x71, 0x64, 0x0c, 0xce, 0xaa, 0x57, 0xb3, 0xdf, 0xc9, 0x59, 0xb5, 0xb0, 0xfb, 0xe5,
|
||||
0x79, 0x55, 0x3b, 0x3d, 0xaf, 0x16, 0x3e, 0xcc, 0x9c, 0x71, 0xe9, 0x9f, 0x34, 0xb2, 0xe0, 0x05,
|
||||
0x71, 0x14, 0xba, 0x47, 0x0e, 0x77, 0xad, 0x83, 0xbe, 0x3e, 0x8d, 0x82, 0x3f, 0xfd, 0xbf, 0x04,
|
||||
0x0f, 0x24, 0xbb, 0x36, 0xf4, 0x5a, 0xef, 0x27, 0x92, 0xdd, 0x4c, 0x85, 0x2a, 0x60, 0x21, 0x79,
|
||||
0x79, 0x0c, 0x05, 0xc1, 0x66, 0xc9, 0x03, 0x75, 0xc8, 0x0a, 0x0f, 0x9c, 0xa8, 0xdf, 0x83, 0x35,
|
||||
0xb6, 0x7a, 0xb6, 0x10, 0xc7, 0x61, 0xe4, 0xea, 0x33, 0x15, 0xad, 0x36, 0x57, 0xdf, 0x1a, 0x48,
|
||||
0x46, 0x87, 0xf4, 0x5e, 0xc6, 0x26, 0x92, 0xe9, 0x18, 0x76, 0x9c, 0x32, 0xcc, 0x09, 0xf6, 0xc6,
|
||||
0x3f, 0x6e, 0x91, 0x95, 0x74, 0x63, 0xcb, 0x5b, 0xda, 0x24, 0xd3, 0xd9, 0x56, 0xce, 0xd5, 0xb7,
|
||||
0x2f, 0x24, 0x9b, 0xc6, 0x4f, 0x9c, 0xf6, 0x20, 0xc2, 0x46, 0x69, 0x07, 0x2a, 0x41, 0xe8, 0xf2,
|
||||
0x96, 0x7d, 0xe4, 0xc7, 0x6f, 0x1b, 0x71, 0x74, 0xc4, 0xd5, 0x2d, 0x39, 0x3d, 0xaf, 0x4e, 0xdf,
|
||||
0xdd, 0xf9, 0x02, 0xbe, 0x6d, 0xda, 0x73, 0xe9, 0x0f, 0xc8, 0x65, 0xdf, 0x3e, 0xe0, 0x3e, 0xae,
|
||||
0xf8, 0x5c, 0xfd, 0xdb, 0x03, 0xc9, 0x52, 0x20, 0x91, 0xac, 0x82, 0x4e, 0x71, 0x94, 0xf9, 0x8d,
|
||||
0xb8, 0x88, 0xed, 0x28, 0x7e, 0xdb, 0x68, 0xd9, 0xbe, 0x40, 0xb7, 0x64, 0x48, 0x7f, 0x7a, 0x5e,
|
||||
0x9d, 0x32, 0xd3, 0xc9, 0xb4, 0x4d, 0xae, 0xb7, 0x3c, 0x9f, 0x8b, 0xbe, 0x88, 0x79, 0xd7, 0x82,
|
||||
0xfc, 0xc6, 0x45, 0x5a, 0xdc, 0xa2, 0x9b, 0x2d, 0xb1, 0xd9, 0x28, 0xa8, 0xfd, 0x7e, 0x8f, 0xd7,
|
||||
0x5f, 0x1e, 0x48, 0xb6, 0xd8, 0x2a, 0x61, 0x89, 0x64, 0xab, 0x18, 0xbd, 0x0c, 0x1b, 0xe6, 0x88,
|
||||
0x1d, 0xdd, 0x25, 0x97, 0x7a, 0x76, 0xdc, 0xd1, 0x2f, 0xa1, 0xfc, 0xb7, 0x06, 0x92, 0xe1, 0x38,
|
||||
0x91, 0xec, 0x69, 0x9c, 0x0f, 0x83, 0x4c, 0x7c, 0xb1, 0x24, 0x9f, 0x80, 0xf0, 0xb9, 0x82, 0x79,
|
||||
0x72, 0x56, 0xd5, 0x3e, 0x31, 0x71, 0x1a, 0xdd, 0x23, 0x97, 0x50, 0xec, 0xe5, 0x4c, 0x6c, 0x7a,
|
||||
0x7a, 0x37, 0xd3, 0xed, 0x40, 0xb1, 0x35, 0x08, 0x11, 0xa7, 0x12, 0xaf, 0x63, 0x08, 0x18, 0x14,
|
||||
0x69, 0x34, 0x57, 0x8c, 0x4c, 0xb4, 0xa2, 0x3f, 0x21, 0x57, 0xd3, 0x3c, 0x17, 0xfa, 0x95, 0xca,
|
||||
0x4c, 0x6d, 0x7e, 0xeb, 0xb9, 0xb2, 0xd3, 0x09, 0x87, 0xb7, 0xce, 0x20, 0xed, 0x07, 0x92, 0xe5,
|
||||
0x33, 0x13, 0xc9, 0xae, 0x61, 0xa8, 0x74, 0x6c, 0x98, 0x39, 0x41, 0x7f, 0xa3, 0x91, 0xe5, 0x88,
|
||||
0x0b, 0xc7, 0x0e, 0x2c, 0x2f, 0x88, 0x79, 0xf4, 0xc0, 0xf6, 0x2d, 0xa1, 0x5f, 0xad, 0x68, 0xb5,
|
||||
0xcb, 0xf5, 0xf6, 0x40, 0xb2, 0xeb, 0x29, 0x79, 0x37, 0xe3, 0x9a, 0x89, 0x64, 0x2f, 0xa1, 0xa7,
|
||||
0x11, 0x7c, 0x74, 0x89, 0x5e, 0x7f, 0xf3, 0xce, 0x1d, 0xe3, 0x89, 0x64, 0x33, 0x5e, 0x10, 0x0f,
|
||||
0xce, 0xaa, 0xab, 0x93, 0xcc, 0x9f, 0x9c, 0x55, 0x2f, 0x81, 0x9d, 0x39, 0x1a, 0x84, 0xfe, 0x5d,
|
||||
0x23, 0xb4, 0x25, 0xac, 0x63, 0x3b, 0x76, 0x3a, 0x3c, 0xb2, 0x78, 0x60, 0x1f, 0xf8, 0xdc, 0xd5,
|
||||
0x67, 0x2b, 0x5a, 0x6d, 0xb6, 0xfe, 0x2b, 0xed, 0x42, 0xb2, 0xa5, 0x46, 0xf3, 0x83, 0x94, 0x7d,
|
||||
0x2f, 0x25, 0x07, 0x92, 0x2d, 0xb5, 0x44, 0x19, 0x4b, 0x24, 0x7b, 0x39, 0x4d, 0x82, 0x11, 0x62,
|
||||
0x54, 0x6d, 0x9e, 0xe3, 0x6b, 0x13, 0x0d, 0x41, 0x27, 0x58, 0x9c, 0x9e, 0x57, 0xc7, 0xc2, 0x9a,
|
||||
0x63, 0x41, 0xe9, 0xdf, 0xca, 0xe2, 0x5d, 0xee, 0xdb, 0x7d, 0x4b, 0xe8, 0x73, 0x15, 0xad, 0xa6,
|
||||
0xd5, 0x3f, 0x03, 0xf1, 0xd7, 0x0b, 0x2f, 0x3b, 0x40, 0x36, 0x61, 0x9d, 0x0b, 0x37, 0x29, 0x94,
|
||||
0x48, 0xf6, 0x62, 0x59, 0x7a, 0x8a, 0x8f, 0x2a, 0x7f, 0xed, 0x0e, 0xe8, 0x5e, 0x9d, 0x64, 0xf5,
|
||||
0xe4, 0xac, 0x3a, 0xfd, 0xda, 0x9d, 0xd3, 0xf3, 0xea, 0x68, 0x38, 0x73, 0x34, 0x18, 0x14, 0xfb,
|
||||
0x55, 0x45, 0x72, 0xec, 0x75, 0x79, 0x78, 0x14, 0x5b, 0x42, 0xaf, 0xa1, 0xe8, 0xfe, 0x85, 0x64,
|
||||
0xcb, 0x85, 0x93, 0xfd, 0x94, 0x05, 0xd5, 0xcb, 0x85, 0xa3, 0x1c, 0x4c, 0x24, 0x7b, 0xa6, 0xac,
|
||||
0x3b, 0x67, 0x8a, 0x0c, 0xbf, 0x31, 0x99, 0x3a, 0x3d, 0xaf, 0x8e, 0xc7, 0x30, 0xc7, 0x23, 0xd0,
|
||||
0x9f, 0x92, 0x6b, 0x5e, 0x3b, 0x08, 0x23, 0x6e, 0xf5, 0x78, 0xd4, 0x15, 0x3a, 0xc1, 0xac, 0x78,
|
||||
0x67, 0x20, 0xd9, 0x7c, 0x8a, 0xef, 0x01, 0x9c, 0x48, 0x76, 0x23, 0xad, 0x69, 0x43, 0xac, 0x90,
|
||||
0xb0, 0x34, 0x0a, 0x9a, 0xea, 0x54, 0xfa, 0x73, 0x8d, 0x2c, 0xda, 0x47, 0x71, 0x68, 0x05, 0x61,
|
||||
0xd4, 0xb5, 0x7d, 0xef, 0x21, 0xd7, 0xe7, 0x31, 0xc8, 0x87, 0x03, 0xc9, 0x16, 0x80, 0x79, 0x3f,
|
||||
0x27, 0x8a, 0x7d, 0x2a, 0xa1, 0x5f, 0x97, 0x5f, 0x74, 0xdc, 0x2a, 0x4f, 0x2e, 0xb3, 0xec, 0x97,
|
||||
0x86, 0x64, 0xa1, 0xeb, 0x05, 0x96, 0xeb, 0x89, 0x43, 0xab, 0x15, 0x71, 0xae, 0x5f, 0xab, 0x68,
|
||||
0xb5, 0xf9, 0xad, 0x6b, 0xf9, 0xe1, 0x6f, 0x7a, 0x0f, 0x79, 0xfd, 0x9d, 0xec, 0x9c, 0xcf, 0x77,
|
||||
0xbd, 0x60, 0xc7, 0x13, 0x87, 0x8d, 0x88, 0x83, 0x22, 0x86, 0x8a, 0x14, 0x4c, 0x4d, 0x98, 0xca,
|
||||
0x2d, 0xe3, 0xc9, 0x59, 0x75, 0xe6, 0xb5, 0xca, 0x2d, 0x53, 0x9d, 0x46, 0xdb, 0x84, 0x0c, 0xbb,
|
||||
0x11, 0x7d, 0x01, 0xa3, 0xb1, 0x3c, 0xda, 0x0f, 0x0b, 0xa6, 0x5c, 0x68, 0x5e, 0xc8, 0x04, 0x28,
|
||||
0x53, 0x13, 0xc9, 0x96, 0x30, 0xfe, 0x10, 0x32, 0x4c, 0x85, 0xa7, 0xef, 0x90, 0xab, 0x4e, 0xd8,
|
||||
0xf3, 0x78, 0x24, 0xf4, 0x45, 0xac, 0x33, 0xcf, 0x43, 0xa5, 0xca, 0xa0, 0xa2, 0x19, 0xc8, 0xc6,
|
||||
0x79, 0x0d, 0x31, 0x73, 0x03, 0xfa, 0x4f, 0x8d, 0xdc, 0x80, 0x3e, 0x88, 0x47, 0x56, 0xd7, 0x3e,
|
||||
0xb1, 0x7a, 0x3c, 0x70, 0xbd, 0xa0, 0x6d, 0x1d, 0x7a, 0x07, 0xfa, 0x75, 0x74, 0xf7, 0x5b, 0x38,
|
||||
0x62, 0x2b, 0x7b, 0x68, 0xb2, 0x6b, 0x9f, 0xec, 0xa5, 0x06, 0xf7, 0xbc, 0xfa, 0x40, 0xb2, 0x95,
|
||||
0xde, 0x38, 0x9c, 0x48, 0xf6, 0x54, 0x5a, 0xea, 0xc7, 0x39, 0xa5, 0x84, 0x4d, 0x9c, 0x3a, 0x19,
|
||||
0x3e, 0x3d, 0xaf, 0x4e, 0x8a, 0x6f, 0x4e, 0xb0, 0x3d, 0x80, 0xe5, 0xe8, 0xd8, 0xa2, 0x03, 0xcb,
|
||||
0xb1, 0x34, 0x5c, 0x8e, 0x0c, 0x2a, 0x96, 0x23, 0x1b, 0x0f, 0x97, 0x23, 0x03, 0xe8, 0xbb, 0xe4,
|
||||
0x32, 0x76, 0x84, 0xfa, 0x32, 0xde, 0x38, 0xcb, 0xf9, 0x8e, 0x41, 0xfc, 0xfb, 0x40, 0xd4, 0x75,
|
||||
0xb8, 0x92, 0xd1, 0x26, 0x91, 0x6c, 0x1e, 0xbd, 0xe1, 0xc8, 0x30, 0x53, 0x94, 0xde, 0x23, 0x0b,
|
||||
0xd9, 0x81, 0x72, 0xb9, 0xcf, 0x63, 0xae, 0x53, 0x4c, 0xf6, 0x17, 0xb0, 0xff, 0x41, 0x62, 0x07,
|
||||
0xf1, 0x44, 0x32, 0xaa, 0x1c, 0xa9, 0x14, 0x34, 0xcc, 0x92, 0x0d, 0x3d, 0x21, 0x3a, 0xde, 0x26,
|
||||
0xbd, 0x28, 0x6c, 0x47, 0x5c, 0x08, 0xf5, 0x5a, 0x59, 0xc1, 0xef, 0x83, 0x16, 0x61, 0x0d, 0x6c,
|
||||
0xf6, 0x32, 0x13, 0xf5, 0x72, 0x49, 0x2f, 0xdd, 0x89, 0x6c, 0xf1, 0xed, 0x93, 0x27, 0xd3, 0x26,
|
||||
0x59, 0xcc, 0xf2, 0xa2, 0x67, 0x1f, 0x09, 0x6e, 0x09, 0x7d, 0x15, 0xe3, 0xbd, 0x0a, 0xdf, 0x91,
|
||||
0x32, 0x7b, 0x40, 0x34, 0x8b, 0xef, 0x50, 0xc1, 0xc2, 0x7b, 0xc9, 0x94, 0x72, 0xb2, 0x00, 0x59,
|
||||
0x06, 0x8b, 0xea, 0x7b, 0x4e, 0x2c, 0xf4, 0x35, 0xf4, 0xf9, 0x1d, 0xf0, 0xd9, 0xb5, 0x4f, 0xb6,
|
||||
0x73, 0x7c, 0x78, 0xea, 0x14, 0xb0, 0x5c, 0xa7, 0xb3, 0x00, 0x69, 0x59, 0x36, 0x4b, 0xb3, 0xa9,
|
||||
0x4b, 0x56, 0x5d, 0x4f, 0xc0, 0xfd, 0x61, 0x89, 0x9e, 0x1d, 0x09, 0x6e, 0x61, 0x9b, 0xa2, 0xdf,
|
||||
0xc0, 0x9d, 0xc0, 0xc6, 0x30, 0xe3, 0x9b, 0x48, 0x63, 0x03, 0x54, 0x34, 0x86, 0xe3, 0x94, 0x61,
|
||||
0x4e, 0xb0, 0x57, 0xa3, 0xc4, 0xbc, 0xdb, 0xb3, 0xbc, 0xc0, 0xe5, 0x27, 0x5c, 0xe8, 0x37, 0xc7,
|
||||
0xa2, 0xec, 0xf3, 0x6e, 0xef, 0x6e, 0xca, 0x8e, 0x46, 0x51, 0xa8, 0x61, 0x14, 0x05, 0xa4, 0x5b,
|
||||
0xe4, 0x0a, 0x6e, 0x80, 0xab, 0xeb, 0xe8, 0x77, 0x7d, 0x20, 0x59, 0x86, 0x14, 0x7d, 0x48, 0x3a,
|
||||
0x34, 0xcc, 0x0c, 0xa7, 0x31, 0xb9, 0x79, 0xcc, 0xed, 0x43, 0x0b, 0xb2, 0xda, 0x8a, 0x3b, 0x11,
|
||||
0x17, 0x9d, 0xd0, 0x77, 0xad, 0x9e, 0x13, 0xeb, 0x4f, 0xe1, 0x82, 0x43, 0x79, 0x5f, 0x05, 0x93,
|
||||
0xef, 0xda, 0xa2, 0xb3, 0x9f, 0x1b, 0xec, 0x39, 0x71, 0x22, 0xd9, 0x3a, 0xba, 0x9c, 0x44, 0x16,
|
||||
0x9b, 0x3a, 0x71, 0x2a, 0xdd, 0x26, 0xf3, 0x5d, 0x3b, 0x3a, 0xe4, 0x91, 0x15, 0xd8, 0x5d, 0xae,
|
||||
0xaf, 0x63, 0x0b, 0x68, 0x40, 0x39, 0x4b, 0xe1, 0xf7, 0xed, 0x2e, 0x2f, 0xca, 0xd9, 0x10, 0x32,
|
||||
0x4c, 0x85, 0xa7, 0x7d, 0xb2, 0x0e, 0x4f, 0x2d, 0x2b, 0x3c, 0x0e, 0x78, 0x24, 0x3a, 0x5e, 0xcf,
|
||||
0x6a, 0x45, 0x61, 0xd7, 0xea, 0xd9, 0x11, 0x0f, 0x62, 0xfd, 0x69, 0x5c, 0x82, 0x6f, 0x0e, 0x24,
|
||||
0xbb, 0x09, 0x56, 0xf7, 0x73, 0xa3, 0x46, 0x14, 0x76, 0xf7, 0xd0, 0x24, 0x91, 0xec, 0xd9, 0xbc,
|
||||
0xe2, 0x4d, 0xe2, 0x0d, 0xf3, 0xeb, 0x66, 0xd2, 0x5f, 0x68, 0x64, 0xb9, 0x1b, 0xba, 0x78, 0x5f,
|
||||
0x5b, 0xc7, 0x5e, 0xe0, 0x86, 0xc7, 0x96, 0xd0, 0x9f, 0xc1, 0x05, 0xfb, 0x08, 0xee, 0x6c, 0xd3,
|
||||
0x3e, 0xde, 0x0d, 0x5d, 0xb8, 0x39, 0x3f, 0x40, 0x16, 0xee, 0xec, 0xc5, 0x6e, 0x09, 0x29, 0x1a,
|
||||
0xe5, 0x32, 0x9c, 0xaf, 0x1c, 0xdc, 0xca, 0x63, 0x5e, 0xcc, 0x11, 0x1f, 0xf4, 0x53, 0x8d, 0xac,
|
||||
0x65, 0xc7, 0xc4, 0x39, 0x8a, 0x40, 0x9b, 0x75, 0x1c, 0x79, 0x31, 0x17, 0xfa, 0xb3, 0x28, 0xe6,
|
||||
0xfb, 0x50, 0x7a, 0xd3, 0x84, 0xcf, 0xf8, 0x0f, 0x90, 0x4e, 0x24, 0xbb, 0xa5, 0x9c, 0x9a, 0x12,
|
||||
0xa7, 0x1c, 0x9e, 0x2d, 0xe5, 0xec, 0x68, 0x5b, 0xe6, 0x24, 0x4f, 0x50, 0xc4, 0xf2, 0xdc, 0x6e,
|
||||
0xc1, 0xbb, 0x4e, 0xdf, 0x18, 0x16, 0xb1, 0x8c, 0x68, 0x00, 0x5e, 0x1c, 0x7e, 0x15, 0x34, 0xcc,
|
||||
0x92, 0x0d, 0xf5, 0xc9, 0x12, 0xbe, 0xb7, 0x2d, 0xa8, 0x05, 0x56, 0x5a, 0x5f, 0x19, 0xd6, 0xd7,
|
||||
0x1b, 0x79, 0x7d, 0xad, 0x03, 0x3f, 0x2c, 0xb2, 0xf8, 0x04, 0x39, 0x28, 0x61, 0xc5, 0xca, 0x96,
|
||||
0x61, 0xc3, 0x1c, 0xb1, 0xa3, 0x9f, 0x6b, 0x64, 0x19, 0x53, 0x08, 0x9f, 0xeb, 0x56, 0xfa, 0x5e,
|
||||
0xd7, 0x2b, 0x18, 0x6f, 0x05, 0x9e, 0x3b, 0xdb, 0x61, 0xaf, 0x6f, 0x02, 0xb7, 0x8b, 0x54, 0xfd,
|
||||
0x1e, 0x34, 0x8c, 0x4e, 0x19, 0x4c, 0x24, 0xab, 0x15, 0x69, 0xa4, 0xe0, 0xca, 0x32, 0x8a, 0xd8,
|
||||
0x0e, 0x5c, 0x3b, 0x72, 0xe1, 0xfe, 0x9f, 0xcd, 0x07, 0xe6, 0xa8, 0x23, 0xfa, 0x47, 0x90, 0x63,
|
||||
0x43, 0x01, 0xe5, 0x81, 0xf0, 0x62, 0xef, 0x01, 0xac, 0xa8, 0xfe, 0x1c, 0x2e, 0xe7, 0x09, 0x74,
|
||||
0xaf, 0xdb, 0xb6, 0xe0, 0xcd, 0x9c, 0x6b, 0x60, 0xf7, 0xea, 0x94, 0xa1, 0x44, 0xb2, 0xb5, 0x54,
|
||||
0x4c, 0x19, 0x87, 0x1e, 0x68, 0xcc, 0x76, 0x1c, 0x82, 0x9e, 0x75, 0x24, 0x88, 0x39, 0x62, 0x23,
|
||||
0xe8, 0x1f, 0x34, 0xb2, 0xd4, 0x0a, 0x7d, 0x3f, 0x3c, 0xb6, 0x3e, 0x3e, 0x0a, 0x1c, 0x68, 0x47,
|
||||
0x84, 0x6e, 0x0c, 0x55, 0x7e, 0x2f, 0x07, 0xdf, 0x15, 0x3b, 0x5e, 0x24, 0x40, 0xe5, 0xc7, 0x65,
|
||||
0xa8, 0x50, 0x39, 0x82, 0xa3, 0xca, 0x51, 0xdb, 0x71, 0x08, 0x54, 0x8e, 0x04, 0x31, 0xaf, 0xa7,
|
||||
0x8a, 0x0a, 0x98, 0xde, 0x27, 0x8b, 0x90, 0x51, 0xc3, 0xea, 0xa0, 0x3f, 0x8f, 0x12, 0xe1, 0x15,
|
||||
0xb8, 0x00, 0x4c, 0x71, 0xae, 0x13, 0xc9, 0x56, 0xd2, 0xcb, 0x4f, 0x45, 0x0d, 0xb3, 0x6c, 0x85,
|
||||
0x0e, 0x79, 0xe0, 0x2a, 0x0e, 0xab, 0x8a, 0x43, 0x1e, 0xb8, 0x13, 0x1c, 0xaa, 0x28, 0x38, 0x54,
|
||||
0xc7, 0x50, 0x04, 0x51, 0xe1, 0x09, 0x74, 0xa3, 0x42, 0xbf, 0x85, 0xde, 0xb0, 0x08, 0x02, 0xfc,
|
||||
0x23, 0x44, 0x8b, 0x22, 0x38, 0x84, 0x0c, 0x53, 0xe1, 0xd1, 0x09, 0xa8, 0xca, 0x9c, 0xbc, 0xa0,
|
||||
0x38, 0xe1, 0x81, 0x3b, 0xea, 0xa4, 0x80, 0xc0, 0x49, 0x31, 0x80, 0xc6, 0x1e, 0xe7, 0xc3, 0xdd,
|
||||
0x17, 0xf3, 0x48, 0x7f, 0x11, 0x7b, 0xd0, 0x95, 0xfc, 0xc4, 0xa1, 0x55, 0x03, 0xa9, 0x7a, 0x2d,
|
||||
0x6f, 0x7c, 0x4f, 0x86, 0x60, 0x22, 0xd9, 0x32, 0xfa, 0x57, 0x30, 0xc3, 0x54, 0x2d, 0xe8, 0x21,
|
||||
0x99, 0x8b, 0xb8, 0xed, 0x5a, 0x61, 0xe0, 0xf7, 0xf5, 0x3f, 0x37, 0x50, 0xe5, 0xee, 0x85, 0x64,
|
||||
0x74, 0x87, 0xf7, 0x22, 0xee, 0xd8, 0x31, 0x77, 0x4d, 0x6e, 0xbb, 0xf7, 0x03, 0xbf, 0x3f, 0x90,
|
||||
0x4c, 0x7b, 0xb5, 0xf8, 0xc7, 0x27, 0x0a, 0xb1, 0x59, 0x7f, 0x25, 0xec, 0x7a, 0x70, 0x73, 0xc6,
|
||||
0x7d, 0xfc, 0xc7, 0x67, 0x0c, 0xd5, 0x35, 0x73, 0x36, 0xca, 0x1c, 0xd0, 0x9f, 0x91, 0xe5, 0x52,
|
||||
0x07, 0x8f, 0xb7, 0xd9, 0x5f, 0x1a, 0xf8, 0xa2, 0x7a, 0xef, 0x42, 0x32, 0x7d, 0x18, 0x74, 0x77,
|
||||
0xd8, 0x87, 0xef, 0x39, 0x71, 0x1e, 0x7a, 0x63, 0xb4, 0x8d, 0xdf, 0x73, 0x62, 0x45, 0x81, 0xae,
|
||||
0x99, 0x8b, 0x65, 0x92, 0xfe, 0x98, 0x5c, 0x4d, 0xbb, 0x17, 0xa1, 0x7f, 0xd9, 0xc0, 0xca, 0xfb,
|
||||
0x2d, 0xb8, 0x06, 0x86, 0x81, 0xd2, 0xae, 0x54, 0x94, 0x3f, 0x2e, 0x9b, 0xa2, 0xb8, 0xce, 0xca,
|
||||
0xad, 0xae, 0x99, 0xb9, 0x3f, 0x7a, 0x48, 0x16, 0xb1, 0xaf, 0x1b, 0xe6, 0xdd, 0x5f, 0xd3, 0xf5,
|
||||
0xdb, 0xbe, 0x90, 0xec, 0xe6, 0x30, 0x42, 0xd3, 0xb1, 0x83, 0x22, 0xb9, 0xf2, 0x38, 0xcf, 0x16,
|
||||
0x5d, 0x5d, 0x41, 0x95, 0x3f, 0x64, 0xa1, 0xc4, 0x19, 0x9f, 0xcd, 0x90, 0x79, 0x65, 0xbb, 0xe9,
|
||||
0x47, 0xe4, 0x2a, 0x0f, 0xe2, 0xc8, 0xe3, 0x42, 0xd7, 0xf0, 0x3f, 0x10, 0x7d, 0x42, 0x52, 0xbc,
|
||||
0x17, 0xc4, 0x51, 0xbf, 0xfe, 0x62, 0xfe, 0xd7, 0x47, 0x36, 0xa1, 0xe8, 0x79, 0x61, 0x8c, 0xdb,
|
||||
0x76, 0x19, 0x7f, 0x99, 0xb9, 0x01, 0xfd, 0x5d, 0x76, 0x79, 0x09, 0x2f, 0x68, 0xfb, 0xdc, 0x42,
|
||||
0xd6, 0x12, 0xf0, 0xe8, 0x9b, 0xc6, 0x25, 0x6c, 0x41, 0x5f, 0xd4, 0xb5, 0x4f, 0x9a, 0xc8, 0x63,
|
||||
0x94, 0xa6, 0xfa, 0xf2, 0x1b, 0xa7, 0x4a, 0x7d, 0xdf, 0xd6, 0x1b, 0xca, 0x23, 0x62, 0x82, 0x1f,
|
||||
0x78, 0x00, 0x82, 0x95, 0x39, 0x81, 0xa3, 0x0f, 0xc9, 0x22, 0x48, 0x8b, 0xc3, 0x18, 0x1a, 0x68,
|
||||
0xd0, 0x34, 0x83, 0x9a, 0xf6, 0xb3, 0xfe, 0x73, 0x1f, 0x88, 0x4c, 0xcd, 0x73, 0xb9, 0x9a, 0x02,
|
||||
0x54, 0x74, 0xbc, 0x71, 0xe7, 0xad, 0x37, 0x15, 0x1d, 0xa5, 0xb9, 0xa0, 0x00, 0x78, 0xb3, 0x84,
|
||||
0x1a, 0xbf, 0xd7, 0xc8, 0xd2, 0xe8, 0xf2, 0xc2, 0x73, 0xa3, 0x0b, 0xef, 0xf1, 0xec, 0x6f, 0xc4,
|
||||
0x6f, 0xc0, 0xdb, 0x02, 0x01, 0xa5, 0x4f, 0x8a, 0x9d, 0x4e, 0xf1, 0xd2, 0x26, 0xc3, 0xa1, 0x99,
|
||||
0x1a, 0xd2, 0x06, 0xb9, 0x02, 0x0f, 0x77, 0x2f, 0xc6, 0xf5, 0x9d, 0xad, 0x6f, 0x62, 0x7f, 0x88,
|
||||
0x48, 0x71, 0x84, 0xd3, 0x61, 0xe1, 0x65, 0x5e, 0x19, 0x9b, 0x99, 0x6d, 0xfd, 0xde, 0xa3, 0xaf,
|
||||
0x36, 0xa6, 0xce, 0xbf, 0xda, 0x98, 0x7a, 0x74, 0xb1, 0xa1, 0x9d, 0x5f, 0x6c, 0x68, 0xbf, 0x7e,
|
||||
0xbc, 0x31, 0xf5, 0xc5, 0xe3, 0x0d, 0xed, 0xfc, 0xf1, 0xc6, 0xd4, 0xbf, 0x1f, 0x6f, 0x4c, 0x7d,
|
||||
0xf8, 0xd2, 0xff, 0xf0, 0xaf, 0x6f, 0x9a, 0x47, 0x07, 0x57, 0xf0, 0xdf, 0xdf, 0xd7, 0xff, 0x1b,
|
||||
0x00, 0x00, 0xff, 0xff, 0x68, 0x19, 0x36, 0x63, 0x1b, 0x18, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *FolderDeviceConfiguration) Marshal() (dAtA []byte, err error) {
|
||||
@@ -511,6 +515,14 @@ func (m *FolderConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i--
|
||||
dAtA[i] = 0xc0
|
||||
}
|
||||
if m.FSWatcherTimeoutS != 0 {
|
||||
i -= 8
|
||||
encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.FSWatcherTimeoutS))))
|
||||
i--
|
||||
dAtA[i] = 0x2
|
||||
i--
|
||||
dAtA[i] = 0xc1
|
||||
}
|
||||
{
|
||||
size, err := m.XattrFilter.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
@@ -1107,6 +1119,9 @@ func (m *FolderConfiguration) ProtoSize() (n int) {
|
||||
}
|
||||
l = m.XattrFilter.ProtoSize()
|
||||
n += 2 + l + sovFolderconfiguration(uint64(l))
|
||||
if m.FSWatcherTimeoutS != 0 {
|
||||
n += 10
|
||||
}
|
||||
if m.DeprecatedReadOnly {
|
||||
n += 4
|
||||
}
|
||||
@@ -2199,6 +2214,17 @@ func (m *FolderConfiguration) Unmarshal(dAtA []byte) error {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 40:
|
||||
if wireType != 1 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field FSWatcherTimeoutS", wireType)
|
||||
}
|
||||
var v uint64
|
||||
if (iNdEx + 8) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
|
||||
iNdEx += 8
|
||||
m.FSWatcherTimeoutS = float64(math.Float64frombits(v))
|
||||
case 9000:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field DeprecatedReadOnly", wireType)
|
||||
|
||||
27
lib/connections/metrics.go
Normal file
27
lib/connections/metrics.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2024 The Syncthing Authors.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
package connections
|
||||
|
||||
import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
)
|
||||
|
||||
var (
|
||||
metricDeviceActiveConnections = promauto.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: "syncthing",
|
||||
Subsystem: "connections",
|
||||
Name: "active",
|
||||
Help: "Number of currently active connections, per device. If value is 0, the device is disconnected.",
|
||||
}, []string{"device"})
|
||||
)
|
||||
|
||||
func registerDeviceMetrics(deviceID string) {
|
||||
// Register metrics for this device, so that counters & gauges are present even
|
||||
// when zero.
|
||||
metricDeviceActiveConnections.WithLabelValues(deviceID)
|
||||
}
|
||||
@@ -12,6 +12,7 @@ package connections
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"net"
|
||||
"net/url"
|
||||
"sync"
|
||||
@@ -145,7 +146,7 @@ func (t *quicListener) serve(ctx context.Context) error {
|
||||
}
|
||||
|
||||
session, err := listener.Accept(ctx)
|
||||
if err == context.Canceled {
|
||||
if errors.Is(err, context.Canceled) {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
l.Infoln("Listen (BEP/quic): Accepting connection:", err)
|
||||
|
||||
@@ -846,6 +846,7 @@ func (s *service) CommitConfiguration(from, to config.Configuration) bool {
|
||||
newDevices := make(map[protocol.DeviceID]bool, len(to.Devices))
|
||||
for _, dev := range to.Devices {
|
||||
newDevices[dev.DeviceID] = true
|
||||
registerDeviceMetrics(dev.DeviceID.String())
|
||||
}
|
||||
|
||||
for _, dev := range from.Devices {
|
||||
@@ -853,6 +854,7 @@ func (s *service) CommitConfiguration(from, to config.Configuration) bool {
|
||||
warningLimitersMut.Lock()
|
||||
delete(warningLimiters, dev.DeviceID)
|
||||
warningLimitersMut.Unlock()
|
||||
metricDeviceActiveConnections.DeleteLabelValues(dev.DeviceID.String())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1378,6 +1380,9 @@ func (c *deviceConnectionTracker) accountAddedConnection(conn protocol.Connectio
|
||||
c.wantConnections[d] = int(h.NumConnections)
|
||||
l.Debugf("Added connection for %s (now %d), they want %d connections", d.Short(), len(c.connections[d]), h.NumConnections)
|
||||
|
||||
// Update active connections metric
|
||||
metricDeviceActiveConnections.WithLabelValues(d.String()).Inc()
|
||||
|
||||
// Close any connections we no longer want to retain.
|
||||
c.closeWorsePriorityConnectionsLocked(d, conn.Priority()-upgradeThreshold)
|
||||
}
|
||||
@@ -1399,6 +1404,10 @@ func (c *deviceConnectionTracker) accountRemovedConnection(conn protocol.Connect
|
||||
delete(c.connections, d)
|
||||
delete(c.wantConnections, d)
|
||||
}
|
||||
|
||||
// Update active connections metric
|
||||
metricDeviceActiveConnections.WithLabelValues(d.String()).Dec()
|
||||
|
||||
l.Debugf("Removed connection for %s (now %d)", d.Short(), c.connections[d])
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ func OpenLevelDBRO(location string) (Backend, error) {
|
||||
return newLeveldbBackend(ldb, location), nil
|
||||
}
|
||||
|
||||
// OpenMemory returns a new Backend referencing an in-memory database.
|
||||
// OpenLevelDBMemory returns a new Backend referencing an in-memory database.
|
||||
func OpenLevelDBMemory() Backend {
|
||||
ldb, _ := leveldb.Open(storage.NewMemStorage(), nil)
|
||||
return newLeveldbBackend(ldb, "")
|
||||
|
||||
@@ -103,6 +103,7 @@ type keyer interface {
|
||||
// index IDs
|
||||
GenerateIndexIDKey(key, device, folder []byte) (indexIDKey, error)
|
||||
FolderFromIndexIDKey(key []byte) ([]byte, bool)
|
||||
DeviceFromIndexIDKey(key []byte) ([]byte, bool)
|
||||
|
||||
// Mtimes
|
||||
GenerateMtimesKey(key, folder []byte) (mtimesKey, error)
|
||||
@@ -308,6 +309,10 @@ func (k defaultKeyer) FolderFromIndexIDKey(key []byte) ([]byte, bool) {
|
||||
return k.folderIdx.Val(binary.BigEndian.Uint32(key[keyPrefixLen+keyDeviceLen:]))
|
||||
}
|
||||
|
||||
func (k defaultKeyer) DeviceFromIndexIDKey(key []byte) ([]byte, bool) {
|
||||
return k.folderIdx.Val(binary.BigEndian.Uint32(key[keyPrefixLen : keyPrefixLen+keyDeviceLen]))
|
||||
}
|
||||
|
||||
type mtimesKey []byte
|
||||
|
||||
func (k defaultKeyer) GenerateMtimesKey(key, folder []byte) (mtimesKey, error) {
|
||||
|
||||
@@ -665,6 +665,24 @@ func (db *Lowlevel) dropIndexIDs() error {
|
||||
return t.Commit()
|
||||
}
|
||||
|
||||
// dropOtherDeviceIndexIDs drops all index IDs for devices other than the
|
||||
// local device. This means we will resend our indexes to all other devices,
|
||||
// but they don't have to resend to us.
|
||||
func (db *Lowlevel) dropOtherDeviceIndexIDs() error {
|
||||
t, err := db.newReadWriteTransaction()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer t.close()
|
||||
if err := t.deleteKeyPrefixMatching([]byte{KeyTypeIndexID}, func(key []byte) bool {
|
||||
dev, _ := t.keyer.DeviceFromIndexIDKey(key)
|
||||
return !bytes.Equal(dev, protocol.LocalDeviceID[:])
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return t.Commit()
|
||||
}
|
||||
|
||||
func (db *Lowlevel) dropMtimes(folder []byte) error {
|
||||
key, err := db.keyer.GenerateMtimesKey(nil, folder)
|
||||
if err != nil {
|
||||
|
||||
@@ -143,7 +143,7 @@ func NewFolderStatisticsNamespace(db backend.Backend, folder string) *Namespaced
|
||||
return NewNamespacedKV(db, string(KeyTypeFolderStatistic)+folder)
|
||||
}
|
||||
|
||||
// NewMiscDateNamespace creates a KV namespace for miscellaneous metadata.
|
||||
// NewMiscDataNamespace creates a KV namespace for miscellaneous metadata.
|
||||
func NewMiscDataNamespace(db backend.Backend) *NamespacedKV {
|
||||
return NewNamespacedKV(db, string(KeyTypeMiscData))
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
// do not put restrictions on downgrades (e.g. for repairs after a bugfix).
|
||||
const (
|
||||
dbVersion = 14
|
||||
dbMigrationVersion = 19
|
||||
dbMigrationVersion = 20
|
||||
dbMinSyncthingVersion = "v1.9.0"
|
||||
)
|
||||
|
||||
@@ -102,7 +102,8 @@ func (db *schemaUpdater) updateSchema() error {
|
||||
{14, 14, "v1.9.0", db.updateSchemaTo14},
|
||||
{14, 16, "v1.9.0", db.checkRepairMigration},
|
||||
{14, 17, "v1.9.0", db.migration17},
|
||||
{14, 19, "v1.9.0", db.dropIndexIDsMigration},
|
||||
{14, 19, "v1.9.0", db.dropAllIndexIDsMigration},
|
||||
{14, 20, "v1.9.0", db.dropOutgoingIndexIDsMigration},
|
||||
}
|
||||
|
||||
for _, m := range migrations {
|
||||
@@ -130,13 +131,13 @@ func (db *schemaUpdater) updateSchema() error {
|
||||
}
|
||||
|
||||
func (*schemaUpdater) writeVersions(m migration, miscDB *NamespacedKV) error {
|
||||
if err := miscDB.PutInt64("dbVersion", m.schemaVersion); err != nil && err == nil {
|
||||
if err := miscDB.PutInt64("dbVersion", m.schemaVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := miscDB.PutString("dbMinSyncthingVersion", m.minSyncthingVersion); err != nil && err == nil {
|
||||
if err := miscDB.PutString("dbMinSyncthingVersion", m.minSyncthingVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := miscDB.PutInt64("dbMigrationVersion", m.migrationVersion); err != nil && err == nil {
|
||||
if err := miscDB.PutInt64("dbMigrationVersion", m.migrationVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -831,10 +832,14 @@ func (db *schemaUpdater) migration17(prev int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *schemaUpdater) dropIndexIDsMigration(_ int) error {
|
||||
func (db *schemaUpdater) dropAllIndexIDsMigration(_ int) error {
|
||||
return db.dropIndexIDs()
|
||||
}
|
||||
|
||||
func (db *schemaUpdater) dropOutgoingIndexIDsMigration(_ int) error {
|
||||
return db.dropOtherDeviceIndexIDs()
|
||||
}
|
||||
|
||||
func rewriteGlobals(t readWriteTransaction) error {
|
||||
it, err := t.NewPrefixIterator([]byte{KeyTypeGlobal})
|
||||
if err != nil {
|
||||
|
||||
@@ -168,6 +168,10 @@ type Snapshot struct {
|
||||
func (s *FileSet) Snapshot() (*Snapshot, error) {
|
||||
opStr := fmt.Sprintf("%s Snapshot()", s.folder)
|
||||
l.Debugf(opStr)
|
||||
|
||||
s.updateMutex.Lock()
|
||||
defer s.updateMutex.Unlock()
|
||||
|
||||
t, err := s.db.newReadOnlyTransaction()
|
||||
if err != nil {
|
||||
s.db.handleFailure(err)
|
||||
|
||||
@@ -388,7 +388,7 @@ func (vl *VersionList) findGlobal() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// findDevices returns whether the device is in InvalidVersions or Versions and
|
||||
// findDevice returns whether the device is in InvalidVersions or Versions and
|
||||
// in InvalidDevices or Devices (true for invalid), the positions in the version
|
||||
// and device slices and whether it has been found at all.
|
||||
func (vl *VersionList) findDevice(device []byte) (bool, int, int, bool) {
|
||||
|
||||
@@ -12,7 +12,7 @@ package fs
|
||||
import "github.com/syncthing/notify"
|
||||
|
||||
const (
|
||||
subEventMask = notify.Create | notify.Remove | notify.Write | notify.Rename | notify.FSEventsInodeMetaMod
|
||||
subEventMask = notify.Create | notify.Remove | notify.Write | notify.Rename | notify.FSEventsInodeMetaMod | notify.FSEventsXattrMod
|
||||
// FSEventsChangeOwner fires on permission change
|
||||
permEventMask = notify.FSEventsChangeOwner
|
||||
rmEventMask = notify.Remove | notify.Rename
|
||||
|
||||
124
lib/geoip/geoip.go
Normal file
124
lib/geoip/geoip.go
Normal file
@@ -0,0 +1,124 @@
|
||||
// Copyright (C) 2024 The Syncthing Authors.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
// Package geoip provides an automatically updating MaxMind GeoIP2 database
|
||||
// provider.
|
||||
package geoip
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/maxmind/geoipupdate/v6/pkg/geoipupdate"
|
||||
"github.com/oschwald/geoip2-golang"
|
||||
)
|
||||
|
||||
type Provider struct {
|
||||
edition string
|
||||
accountID int
|
||||
licenseKey string
|
||||
refreshInterval time.Duration
|
||||
directory string
|
||||
|
||||
mut sync.Mutex
|
||||
currentDBDir string
|
||||
db *geoip2.Reader
|
||||
}
|
||||
|
||||
// NewGeoLite2CityProvider returns a new GeoIP2 database provider for the
|
||||
// GeoLite2-City database. The database will be stored in the given
|
||||
// directory (which should exist) and refreshed every 7 days.
|
||||
func NewGeoLite2CityProvider(ctx context.Context, accountID int, licenseKey string, directory string) (*Provider, error) {
|
||||
p := &Provider{
|
||||
edition: "GeoLite2-City",
|
||||
accountID: accountID,
|
||||
licenseKey: licenseKey,
|
||||
refreshInterval: 7 * 24 * time.Hour,
|
||||
directory: directory,
|
||||
}
|
||||
|
||||
if err := p.download(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p *Provider) City(ip net.IP) (*geoip2.City, error) {
|
||||
p.mut.Lock()
|
||||
defer p.mut.Unlock()
|
||||
|
||||
if p.db == nil {
|
||||
return nil, errors.New("database not open")
|
||||
}
|
||||
|
||||
return p.db.City(ip)
|
||||
}
|
||||
|
||||
// Serve downloads the GeoIP2 database and keeps it up to date. It will return
|
||||
// when the context is canceled.
|
||||
func (p *Provider) Serve(ctx context.Context) error {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
|
||||
case <-time.After(p.refreshInterval):
|
||||
if err := p.download(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Provider) download(ctx context.Context) error {
|
||||
newSubdir, err := os.MkdirTemp(p.directory, "geoipupdate")
|
||||
if err != nil {
|
||||
return fmt.Errorf("download: %w", err)
|
||||
}
|
||||
|
||||
cfg := &geoipupdate.Config{
|
||||
URL: "https://updates.maxmind.com",
|
||||
DatabaseDirectory: newSubdir,
|
||||
LockFile: filepath.Join(newSubdir, "geoipupdate.lock"),
|
||||
RetryFor: 5 * time.Minute,
|
||||
Parallelism: 1,
|
||||
AccountID: p.accountID,
|
||||
LicenseKey: p.licenseKey,
|
||||
EditionIDs: []string{p.edition},
|
||||
}
|
||||
|
||||
if err := geoipupdate.NewClient(cfg).Run(ctx); err != nil {
|
||||
return fmt.Errorf("download: %w", err)
|
||||
}
|
||||
|
||||
dbPath := filepath.Join(newSubdir, p.edition+".mmdb")
|
||||
db, err := geoip2.Open(dbPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("open downloaded db: %w", err)
|
||||
}
|
||||
|
||||
p.mut.Lock()
|
||||
prevDBDir := p.currentDBDir
|
||||
if p.db != nil {
|
||||
p.db.Close()
|
||||
}
|
||||
p.currentDBDir = newSubdir
|
||||
p.db = db
|
||||
p.mut.Unlock()
|
||||
|
||||
if prevDBDir != "" {
|
||||
_ = os.RemoveAll(p.currentDBDir)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
36
lib/geoip/geoip_test.go
Normal file
36
lib/geoip/geoip_test.go
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2024 The Syncthing Authors.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
package geoip
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDownloadAndOpen(t *testing.T) {
|
||||
acctID, _ := strconv.Atoi(os.Getenv("GEOIP_ACCOUNT_ID"))
|
||||
if acctID == 0 {
|
||||
t.Skip("No account ID set")
|
||||
}
|
||||
license := os.Getenv("GEOIP_LICENSE_KEY")
|
||||
if license == "" {
|
||||
t.Skip("No license key set")
|
||||
}
|
||||
|
||||
p, err := NewGeoLite2CityProvider(context.Background(), acctID, license, t.TempDir())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = p.City(net.ParseIP("8.8.8.8"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -596,7 +596,7 @@ func (f *sendReceiveFolder) handleDir(file protocol.FileInfo, snap *db.Snapshot,
|
||||
case err == nil && !info.IsDir():
|
||||
// Check that it is what we have in the database.
|
||||
curFile, hasCurFile := snap.Get(protocol.LocalDeviceID, file.Name)
|
||||
if err := f.scanIfItemChanged(file.Name, info, curFile, hasCurFile, scanChan); err != nil {
|
||||
if err := f.scanIfItemChanged(file.Name, info, curFile, hasCurFile, false, scanChan); err != nil {
|
||||
f.newPullError(file.Name, fmt.Errorf("handling dir: %w", err))
|
||||
return
|
||||
}
|
||||
@@ -787,7 +787,7 @@ func (f *sendReceiveFolder) handleSymlinkCheckExisting(file protocol.FileInfo, s
|
||||
}
|
||||
// Check that it is what we have in the database.
|
||||
curFile, hasCurFile := snap.Get(protocol.LocalDeviceID, file.Name)
|
||||
if err := f.scanIfItemChanged(file.Name, info, curFile, hasCurFile, scanChan); err != nil {
|
||||
if err := f.scanIfItemChanged(file.Name, info, curFile, hasCurFile, false, scanChan); err != nil {
|
||||
return err
|
||||
}
|
||||
// Remove it to replace with the symlink. This also handles the
|
||||
@@ -1629,7 +1629,7 @@ func (f *sendReceiveFolder) performFinish(file, curFile protocol.FileInfo, hasCu
|
||||
// There is an old file or directory already in place. We need to
|
||||
// handle that.
|
||||
|
||||
if err := f.scanIfItemChanged(file.Name, stat, curFile, hasCurFile, scanChan); err != nil {
|
||||
if err := f.scanIfItemChanged(file.Name, stat, curFile, hasCurFile, false, scanChan); err != nil {
|
||||
return fmt.Errorf("checking existing file: %w", err)
|
||||
}
|
||||
|
||||
@@ -1967,7 +1967,6 @@ func (f *sendReceiveFolder) deleteDirOnDiskHandleChildren(dir string, snap *db.S
|
||||
var dirsToDelete []string
|
||||
var hasIgnored, hasKnown, hasToBeScanned, hasReceiveOnlyChanged bool
|
||||
var delErr error
|
||||
|
||||
err := f.mtimefs.Walk(dir, func(path string, info fs.FileInfo, err error) error {
|
||||
if path == dir {
|
||||
return nil
|
||||
@@ -2066,7 +2065,7 @@ func (f *sendReceiveFolder) deleteDirOnDiskHandleChildren(dir string, snap *db.S
|
||||
// scanIfItemChanged schedules the given file for scanning and returns errModified
|
||||
// if it differs from the information in the database. Returns nil if the file has
|
||||
// not changed.
|
||||
func (f *sendReceiveFolder) scanIfItemChanged(name string, stat fs.FileInfo, item protocol.FileInfo, hasItem bool, scanChan chan<- string) (err error) {
|
||||
func (f *sendReceiveFolder) scanIfItemChanged(name string, stat fs.FileInfo, item protocol.FileInfo, hasItem bool, fromDelete bool, scanChan chan<- string) (err error) {
|
||||
defer func() {
|
||||
if err == errModified {
|
||||
scanChan <- name
|
||||
@@ -2086,14 +2085,13 @@ func (f *sendReceiveFolder) scanIfItemChanged(name string, stat fs.FileInfo, ite
|
||||
if err != nil {
|
||||
return fmt.Errorf("comparing item on disk to db: %w", err)
|
||||
}
|
||||
|
||||
if !statItem.IsEquivalentOptional(item, protocol.FileInfoComparison{
|
||||
ModTimeWindow: f.modTimeWindow,
|
||||
IgnorePerms: f.IgnorePerms,
|
||||
IgnoreBlocks: true,
|
||||
IgnoreFlags: protocol.LocalAllFlags,
|
||||
IgnoreOwnership: !f.SyncOwnership,
|
||||
IgnoreXattrs: !f.SyncXattrs,
|
||||
IgnoreOwnership: fromDelete || !f.SyncOwnership,
|
||||
IgnoreXattrs: fromDelete || !f.SyncXattrs,
|
||||
}) {
|
||||
return errModified
|
||||
}
|
||||
@@ -2124,7 +2122,7 @@ func (f *sendReceiveFolder) checkToBeDeleted(file, cur protocol.FileInfo, hasCur
|
||||
return err
|
||||
}
|
||||
|
||||
return f.scanIfItemChanged(file.Name, stat, cur, hasCur, scanChan)
|
||||
return f.scanIfItemChanged(file.Name, stat, cur, hasCur, true, scanChan)
|
||||
}
|
||||
|
||||
// setPlatformData makes adjustments to the metadata that should happen for
|
||||
|
||||
@@ -293,15 +293,18 @@ func (s *indexHandler) sendIndexTo(ctx context.Context, fset *db.FileSet) error
|
||||
return err
|
||||
}
|
||||
|
||||
err = batch.Flush()
|
||||
|
||||
// True if there was nothing to be sent
|
||||
if f.Sequence == 0 {
|
||||
if err := batch.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.prevSequence = f.Sequence
|
||||
return err
|
||||
// Use the sequence of the snapshot we iterated as a starting point for the
|
||||
// next run. Previously we used the sequence of the last file we sent,
|
||||
// however it's possible that a higher sequence exists, just doesn't need to
|
||||
// be sent (e.g. in a receive-only folder, when a local change was
|
||||
// reverted). No point trying to send nothing again.
|
||||
s.prevSequence = snap.Sequence(protocol.LocalDeviceID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *indexHandler) receive(fs []protocol.FileInfo, update bool, op string) error {
|
||||
|
||||
@@ -464,9 +464,9 @@ func (m *model) removeFolder(cfg config.FolderConfiguration) {
|
||||
if isPathUnique {
|
||||
// Remove (if empty and removable) or move away (if non-empty or
|
||||
// otherwise not removable) Syncthing-specific marker files.
|
||||
fs := cfg.Filesystem(nil)
|
||||
if err := fs.Remove(config.DefaultMarkerName); err != nil {
|
||||
if err := cfg.RemoveMarker(); err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
moved := config.DefaultMarkerName + time.Now().Format(".removed-20060102-150405")
|
||||
fs := cfg.Filesystem(nil)
|
||||
_ = fs.Rename(config.DefaultMarkerName, moved)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,9 +233,8 @@ func (s *Service) verifyExistingLocked(ctx context.Context, mapping *Mapping, na
|
||||
default:
|
||||
}
|
||||
|
||||
// Delete addresses for NATDevice's that do not exist anymore
|
||||
nat, ok := nats[id]
|
||||
if !ok {
|
||||
if nat, ok := nats[id]; !ok || len(extAddrs) == 0 {
|
||||
// Delete addresses for NATDevice's that do not exist anymore
|
||||
mapping.removeAddressLocked(id)
|
||||
change = true
|
||||
continue
|
||||
|
||||
@@ -58,5 +58,6 @@ func registerDeviceMetrics(deviceID string) {
|
||||
metricDeviceSentUncompressedBytes.WithLabelValues(deviceID)
|
||||
metricDeviceSentMessages.WithLabelValues(deviceID)
|
||||
metricDeviceRecvBytes.WithLabelValues(deviceID)
|
||||
metricDeviceRecvDecompressedBytes.WithLabelValues(deviceID)
|
||||
metricDeviceRecvMessages.WithLabelValues(deviceID)
|
||||
}
|
||||
|
||||
@@ -142,8 +142,6 @@ func (w *walker) walk(ctx context.Context) chan ScanResult {
|
||||
w.ProgressTickIntervalS = 2
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(time.Duration(w.ProgressTickIntervalS) * time.Second)
|
||||
|
||||
// We need to emit progress events, hence we create a routine which buffers
|
||||
// the list of files to be hashed, counts the total number of
|
||||
// bytes to hash, and once no more files need to be hashed (chan gets closed),
|
||||
@@ -188,17 +186,17 @@ func (w *walker) walk(ctx context.Context) chan ScanResult {
|
||||
})
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(time.Duration(w.ProgressTickIntervalS) * time.Second)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
emitProgressEvent()
|
||||
l.Debugln(w, "Walk progress done", w.Folder, w.Subs, w.Matcher)
|
||||
ticker.Stop()
|
||||
return
|
||||
case <-ticker.C:
|
||||
emitProgressEvent()
|
||||
case <-ctx.Done():
|
||||
ticker.Stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,7 +437,14 @@ func (a *aggregator) CommitConfiguration(_, to config.Configuration) bool {
|
||||
|
||||
func (a *aggregator) updateConfig(folderCfg config.FolderConfiguration) {
|
||||
a.notifyDelay = time.Duration(folderCfg.FSWatcherDelayS) * time.Second
|
||||
a.notifyTimeout = notifyTimeout(folderCfg.FSWatcherDelayS)
|
||||
if maxDelay := folderCfg.FSWatcherTimeoutS; maxDelay > 0 {
|
||||
// FSWatcherTimeoutS is set explicitly so use that, but it also
|
||||
// can't be lower than FSWatcherDelayS
|
||||
a.notifyTimeout = time.Duration(max(maxDelay, folderCfg.FSWatcherDelayS)) * time.Second
|
||||
} else {
|
||||
// Use the default FSWatcherTimeoutS calculation
|
||||
a.notifyTimeout = notifyTimeout(folderCfg.FSWatcherDelayS)
|
||||
}
|
||||
a.folderCfg = folderCfg
|
||||
}
|
||||
|
||||
@@ -461,8 +468,8 @@ func notifyTimeout(eventDelayS float64) time.Duration {
|
||||
shortDelayS = 10
|
||||
shortDelayMultiplicator = 6
|
||||
longDelayS = 60
|
||||
longDelayTimeout = time.Minute
|
||||
)
|
||||
longDelayTimeout := time.Duration(1) * time.Minute
|
||||
if eventDelayS < shortDelayS {
|
||||
return time.Duration(eventDelayS*shortDelayMultiplicator) * time.Second
|
||||
}
|
||||
|
||||
100
man/stdiscosrv.1
100
man/stdiscosrv.1
@@ -27,20 +27,18 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "STDISCOSRV" "1" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "STDISCOSRV" "1" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
stdiscosrv \- Syncthing Discovery Server
|
||||
.SH SYNOPSIS
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
stdiscosrv [\-cert=<file>] [\-db\-dir=<string>] [\-debug] [\-http] [\-key=<string>]
|
||||
[\-listen=<address>] [\-metrics\-listen=<address>]
|
||||
[\-replicate=<peers>] [\-replication\-listen=<address>]
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH DESCRIPTION
|
||||
@@ -87,7 +85,7 @@ Prometheus compatible metrics endpoint listen address (default disabled).
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-replicate=<peers>
|
||||
Replication peers, \fI\%id@address\fP <\fBid@address\fP>, comma separated
|
||||
Replication peers, \X'tty: link mailto:id@address'\fI\%id@address\fP <\fBid@address\fP>\X'tty: link', comma separated
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -114,10 +112,10 @@ entry from the list.
|
||||
.SS Description
|
||||
.sp
|
||||
This guide assumes that you have already set up Syncthing. If you
|
||||
haven’t yet, head over to \fI\%Getting Started\fP first.
|
||||
haven’t yet, head over to \X'tty: link #getting-started'\fI\%Getting Started\fP\X'tty: link' first.
|
||||
.SS Installing
|
||||
.sp
|
||||
Go to \fI\%releases\fP <\fBhttps://github.com/syncthing/discosrv/releases\fP> and
|
||||
Go to \X'tty: link https://github.com/syncthing/discosrv/releases'\fI\%releases\fP <\fBhttps://github.com/syncthing/discosrv/releases\fP>\X'tty: link' and
|
||||
download the file appropriate for your operating system. Unpacking it will
|
||||
yield a binary called \fBstdiscosrv\fP (or \fBstdiscosrv.exe\fP on Windows).
|
||||
Start this in whatever way you are most comfortable with; double clicking
|
||||
@@ -127,7 +125,7 @@ given flags to the contrary.
|
||||
.sp
|
||||
The discovery server can also be obtained through apt, the Debian/Ubuntu package
|
||||
manager. Recent releases can be found at syncthing’s
|
||||
\fI\%apt repository\fP <\fBhttps://apt.syncthing.net/\fP>\&. The name of the package is
|
||||
\X'tty: link https://apt.syncthing.net/'\fI\%apt repository\fP <\fBhttps://apt.syncthing.net/\fP>\X'tty: link'\&. The name of the package is
|
||||
syncthing\-discosrv.
|
||||
.SS Configuring
|
||||
.sp
|
||||
@@ -164,12 +162,10 @@ the certificate and key at startup. This isn’t necessary with the \fBhttp\fP f
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
$ stdiscosrv \-cert=/path/to/cert.pem \-key=/path/to/key.pem
|
||||
Server device ID is 7DDRT7J\-UICR4PM\-PBIZYL3\-MZOJ7X7\-EX56JP6\-IK6HHMW\-S7EK32W\-G3EUPQA
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -179,11 +175,9 @@ the clients in the discovery server URL:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
https://disco.example.com:8443/?id=7DDRT7J\-UICR4PM\-PBIZYL3\-MZOJ7X7\-EX56JP6\-IK6HHMW\-S7EK32W\-G3EUPQA
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -191,11 +185,9 @@ Otherwise, the URL will be:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
https://disco.example.com:8443/
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Replication
|
||||
@@ -210,8 +202,8 @@ shared with the main discovery API. If the \fB\-http\fP mode is used the
|
||||
certificate is not used for client requests but only for replication
|
||||
connections.
|
||||
.sp
|
||||
Authentication of replication connections is done using \fI\%Syncthing\-style
|
||||
device IDs\fP <\fBhttps://docs.syncthing.net/dev/device-ids.html#id1\fP> only \- CA
|
||||
Authentication of replication connections is done using \X'tty: link https://docs.syncthing.net/dev/device-ids.html#id1'\fI\%Syncthing\-style
|
||||
device IDs\fP <\fBhttps://docs.syncthing.net/dev/device-ids.html#id1\fP>\X'tty: link' only \- CA
|
||||
verification is not available. The device IDs in question are those printed
|
||||
by the discovery server on startup.
|
||||
.sp
|
||||
@@ -235,11 +227,9 @@ On server one:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
$ stdiscosrv \-replicate=MRI...7OK@192.0.2.55:19200 <other options>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -247,11 +237,9 @@ On server two:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
$ stdiscosrv \-replicate=I6K...H76@192.0.2.20:19200 <other options>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -266,11 +254,9 @@ device ID without “@ip:port” address:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
$ stdiscosrv \-replicate=I6K...H76 <other options>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -283,7 +269,7 @@ Syncthing towards this name. The same certificate must be used on both
|
||||
discovery servers.
|
||||
.SS Reverse Proxy Setup
|
||||
.sp
|
||||
New in version 1.8.0: A new “X\-Client\-Port” HTTP header was added.
|
||||
Added in version 1.8.0: A new “X\-Client\-Port” HTTP header was added.
|
||||
|
||||
.sp
|
||||
The discovery server can be run behind an SSL\-secured reverse proxy. This
|
||||
@@ -331,25 +317,22 @@ listed above:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
proxy_set_header X\-Forwarded\-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X\-Client\-Port $remote_port;
|
||||
proxy_set_header X\-SSL\-Cert $ssl_client_cert;
|
||||
ssl_verify_client optional_no_ca;
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
The following is a complete example Nginx configuration file. With this setup,
|
||||
clients can use \fI\%https://discovery.example.com\fP as the discovery server URL in
|
||||
clients can use \X'tty: link https://discovery.example.com'\fI\%https://discovery.example.com\fP\X'tty: link' as the discovery server URL in
|
||||
the Syncthing settings.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
# HTTP 1.1 support
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
@@ -404,26 +387,23 @@ server {
|
||||
proxy_pass http://discovery.example.com;
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
An example of automating the SSL certificates and reverse\-proxying the Discovery
|
||||
Server and Syncthing using Nginx, \fI\%Let’s Encrypt\fP <\fBhttps://letsencrypt.org/\fP> and Docker can be found \fI\%here\fP <\fBhttps://forum.syncthing.net/t/docker-syncthing-and-syncthing-discovery-behind-nginx-reverse-proxy-with-lets-encrypt/6880\fP>\&.
|
||||
Server and Syncthing using Nginx, \X'tty: link https://letsencrypt.org/'\fI\%Let’s Encrypt\fP <\fBhttps://letsencrypt.org/\fP>\X'tty: link' and Docker can be found \X'tty: link https://forum.syncthing.net/t/docker-syncthing-and-syncthing-discovery-behind-nginx-reverse-proxy-with-lets-encrypt/6880'\fI\%here\fP <\fBhttps://forum.syncthing.net/t/docker-syncthing-and-syncthing-discovery-behind-nginx-reverse-proxy-with-lets-encrypt/6880\fP>\X'tty: link'\&.
|
||||
.SS Apache
|
||||
.sp
|
||||
The following lines must be added to the configuration:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
SSLProxyEngine On
|
||||
SSLVerifyClient optional_no_ca
|
||||
RequestHeader set X\-SSL\-Cert \(dq%{SSL_CLIENT_CERT}s\(dq
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -435,11 +415,9 @@ configuration:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
RemoteIPHeader X\-Forwarded\-For
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Caddy
|
||||
@@ -448,8 +426,7 @@ The following lines must be added to the Caddyfile:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
discovery.example.com {
|
||||
reverse_proxy 192.0.2.1:8443 {
|
||||
header_up X\-Forwarded\-For {http.request.remote.host}
|
||||
@@ -463,23 +440,20 @@ The following lines must be added to the Caddyfile:
|
||||
}
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
For more details, see also the recommendations in the
|
||||
\fI\%Reverse Proxy Setup\fP <\fBhttps://docs.syncthing.net/users/reverseproxy.html\fP>
|
||||
\X'tty: link https://docs.syncthing.net/users/reverseproxy.html'\fI\%Reverse Proxy Setup\fP <\fBhttps://docs.syncthing.net/users/reverseproxy.html\fP>\X'tty: link'
|
||||
page. Note that that page is directed at setting up a proxy for the
|
||||
Syncthing web UI. You should do the proper path and port adjustments to proxying
|
||||
the discovery server and your particular setup.
|
||||
|
||||
@@ -27,22 +27,20 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "STRELAYSRV" "1" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "STRELAYSRV" "1" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
strelaysrv \- Syncthing Relay Server
|
||||
.SH SYNOPSIS
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
strelaysrv [\-debug] [\-ext\-address=<address>] [\-global\-rate=<bytes/s>] [\-keys=<dir>] [\-listen=<listen addr>]
|
||||
[\-message\-timeout=<duration>] [\-nat] [\-nat\-lease=<duration>] [\-nat\-renewal=<duration>]
|
||||
[\-nat\-timeout=<duration>] [\-network\-timeout=<duration>] [\-per\-session\-rate=<bytes/s>]
|
||||
[\-ping\-interval=<duration>] [\-pools=<pool addresses>] [\-pprof] [\-protocol=<string>]
|
||||
[\-provided\-by=<string>] [\-status\-srv=<listen addr>] [\-token=<string>] [\-version]
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH DESCRIPTION
|
||||
@@ -50,7 +48,7 @@ strelaysrv [\-debug] [\-ext\-address=<address>] [\-global\-rate=<bytes/s>] [\-ke
|
||||
Syncthing relies on a network of community\-contributed relay servers. Anyone
|
||||
can run a relay server, and it will automatically join the relay pool and be
|
||||
available to Syncthing users. The current list of relays can be found at
|
||||
\fI\%https://relays.syncthing.net/\fP\&.
|
||||
\X'tty: link https://relays.syncthing.net/'\fI\%https://relays.syncthing.net/\fP\X'tty: link'\&.
|
||||
.SH OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -127,7 +125,7 @@ How often pings are sent (default 1m0s).
|
||||
.TP
|
||||
.B \-pools=<pool addresses>
|
||||
Comma separated list of relay pool addresses to join (default
|
||||
“\fI\%https://relays.syncthing.net/endpoint\fP”). Blank to disable announcement to
|
||||
“\X'tty: link https://relays.syncthing.net/endpoint'\fI\%https://relays.syncthing.net/endpoint\fP\X'tty: link'”). Blank to disable announcement to
|
||||
a pool, thereby remaining a private relay.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
@@ -163,7 +161,7 @@ Show version
|
||||
.UNINDENT
|
||||
.SS Installing
|
||||
.sp
|
||||
Go to \fI\%releases\fP <\fBhttps://github.com/syncthing/relaysrv/releases\fP> and
|
||||
Go to \X'tty: link https://github.com/syncthing/relaysrv/releases'\fI\%releases\fP <\fBhttps://github.com/syncthing/relaysrv/releases\fP>\X'tty: link' and
|
||||
download the file appropriate for your operating system. Unpacking it will
|
||||
yield a binary called \fBstrelaysrv\fP (or \fBstrelaysrv.exe\fP on Windows).
|
||||
Start this in whatever way you are most comfortable with; double clicking
|
||||
@@ -175,7 +173,7 @@ The startup message prints instructions on how to change this.
|
||||
.sp
|
||||
The relay server can also be obtained through apt, the Debian/Ubuntu package
|
||||
manager. Recent releases can be found at syncthing’s
|
||||
\fI\%apt repository\fP <\fBhttps://apt.syncthing.net/\fP>\&. The name of the package is
|
||||
\X'tty: link https://apt.syncthing.net/'\fI\%apt repository\fP <\fBhttps://apt.syncthing.net/\fP>\X'tty: link'\&. The name of the package is
|
||||
syncthing\-relaysrv.
|
||||
.SH SETTING UP
|
||||
.sp
|
||||
@@ -189,14 +187,12 @@ system:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
$ sudo useradd strelaysrv
|
||||
$ sudo mkdir /etc/strelaysrv
|
||||
$ sudo chown strelaysrv /etc/strelaysrv
|
||||
$ sudo \-u strelaysrv /usr/local/bin/strelaysrv \-keys /etc/strelaysrv
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -212,11 +208,9 @@ Syncthing can be configured to use specific relay servers (exclusively of the pu
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
relay://<host name|IP>[:port]/?id=<relay device ID>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -224,11 +218,9 @@ For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
relay://private\-relay\-1.example.com:443/?id=ITZRNXE\-YNROGBZ\-HXTH5P7\-VK5NYE5\-QHRQGE2\-7JQ6VNJ\-KZUEDIU\-5PPR5AM
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -246,11 +238,9 @@ to forward traffic from port 443 to port 22067, for example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
iptables \-t nat \-A PREROUTING \-p tcp \-\-dport 443 \-j REDIRECT \-\-to\-port 22067
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -258,8 +248,7 @@ Or, if you’re using \fBufw\fP, add the following to \fB/etc/ufw/before.rules\f
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
*nat
|
||||
:PREROUTING ACCEPT [0:0]
|
||||
:POSTROUTING ACCEPT [0:0]
|
||||
@@ -267,8 +256,7 @@ Or, if you’re using \fBufw\fP, add the following to \fB/etc/ufw/before.rules\f
|
||||
\-A PREROUTING \-p tcp \-\-dport 443 \-j REDIRECT \-\-to\-port 22067
|
||||
|
||||
COMMIT
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -277,12 +265,12 @@ You will need to start \fBstrelaysrv\fP with \fB\-ext\-address \(dq:443\(dq\fP\&
|
||||
on port 22067. You will also need to let both port 443 and 22067 through your
|
||||
firewall.
|
||||
.sp
|
||||
Another option is \fI\%described here\fP <\fBhttps://wiki.apache.org/httpd/NonRootPortBinding\fP>,
|
||||
Another option is \X'tty: link https://wiki.apache.org/httpd/NonRootPortBinding'\fI\%described here\fP <\fBhttps://wiki.apache.org/httpd/NonRootPortBinding\fP>\X'tty: link',
|
||||
although your mileage may vary.
|
||||
.SH FIREWALL CONSIDERATIONS
|
||||
.sp
|
||||
The relay server listens on two ports by default. One for data connections and the other
|
||||
for providing public statistics at \fI\%https://relays.syncthing.net/\fP\&. The firewall, such as
|
||||
for providing public statistics at \X'tty: link https://relays.syncthing.net/'\fI\%https://relays.syncthing.net/\fP\X'tty: link'\&. The firewall, such as
|
||||
\fBiptables\fP, must permit incoming TCP connections to the following ports:
|
||||
.INDENT 0.0
|
||||
.IP \(bu 2
|
||||
@@ -295,19 +283,17 @@ Runtime \fBiptables\fP rules to allow access to the default ports:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
iptables \-I INPUT \-p tcp \-\-dport 22067 \-j ACCEPT
|
||||
iptables \-I INPUT \-p tcp \-\-dport 22070 \-j ACCEPT
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
Please consult Linux distribution documentation to persist firewall rules.
|
||||
.SH ACCESS CONTROL FOR PRIVATE RELAYS
|
||||
.sp
|
||||
New in version 1.22.1.
|
||||
Added in version 1.22.1.
|
||||
|
||||
.sp
|
||||
Private relays can be configured to only accept connections from peers in possession of a shared secret.
|
||||
@@ -319,11 +305,9 @@ Then configure your Syncthing devices to send the token when joining the relay:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
relay://<host name|IP>[:port]/?id=<relay device ID>&token=mySecretToken
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
'\" t
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.
|
||||
@@ -27,7 +28,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING-BEP" "7" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING-BEP" "7" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing-bep \- Block Exchange Protocol v1
|
||||
.SH INTRODUCTION AND DEFINITIONS
|
||||
@@ -48,7 +49,7 @@ for the last block which may be smaller.
|
||||
.sp
|
||||
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”,
|
||||
“SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this
|
||||
document are to be interpreted as described in \fI\%RFC 2119\fP <\fBhttps://datatracker.ietf.org/doc/html/rfc2119.html\fP>\&.
|
||||
document are to be interpreted as described in \X'tty: link https://datatracker.ietf.org/doc/html/rfc2119.html'\fI\%RFC 2119\fP <\fBhttps://datatracker.ietf.org/doc/html/rfc2119.html\fP>\X'tty: link'\&.
|
||||
.SH TRANSPORT AND AUTHENTICATION
|
||||
.sp
|
||||
BEP is deployed as the highest level in a protocol stack, with the lower
|
||||
@@ -56,8 +57,7 @@ level protocols providing encryption and authentication.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
|
||||
| Block Exchange Protocol |
|
||||
|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-|
|
||||
@@ -66,8 +66,7 @@ level protocols providing encryption and authentication.
|
||||
| Reliable Transport |
|
||||
|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-|
|
||||
v ... v
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -129,8 +128,7 @@ followed by the contents of the Hello message itself.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
0 1
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
@@ -143,8 +141,7 @@ followed by the contents of the Hello message itself.
|
||||
\e Hello \e
|
||||
/ /
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -152,15 +149,13 @@ The Hello message itself is in protocol buffer format with the following schema:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
message Hello {
|
||||
string device_name = 1;
|
||||
string client_name = 2;
|
||||
string client_version = 3;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Fields (Hello message)
|
||||
@@ -172,8 +167,8 @@ The \fBclient_name\fP and \fBclient_version\fP identifies the implementation. Th
|
||||
values SHOULD be simple strings identifying the implementation name, as a
|
||||
user would expect to see it, and the version string in the same manner. An
|
||||
example client name is “syncthing” and an example client version is “v0.7.2”.
|
||||
The client version field SHOULD follow the patterns laid out in the \fI\%Semantic
|
||||
Versioning\fP <\fBhttps://semver.org/\fP> standard.
|
||||
The client version field SHOULD follow the patterns laid out in the \X'tty: link https://semver.org/'\fI\%Semantic
|
||||
Versioning\fP <\fBhttps://semver.org/\fP>\X'tty: link' standard.
|
||||
.sp
|
||||
Immediately after exchanging Hello messages, the connection MUST be dropped
|
||||
if the remote device does not pass authentication.
|
||||
@@ -193,8 +188,7 @@ A \fBMessage\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
0 1
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
@@ -211,8 +205,7 @@ A \fBMessage\fP
|
||||
\e Message \e
|
||||
/ /
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -228,8 +221,7 @@ As always, the length words are in network byte order (big endian).
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
message Header {
|
||||
MessageType type = 1;
|
||||
MessageCompression compression = 2;
|
||||
@@ -250,8 +242,7 @@ enum MessageCompression {
|
||||
NONE = 0;
|
||||
LZ4 = 1;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -274,8 +265,7 @@ initial exchange.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
message ClusterConfig {
|
||||
repeated Folder folders = 1;
|
||||
}
|
||||
@@ -310,8 +300,7 @@ enum Compression {
|
||||
NEVER = 1;
|
||||
ALWAYS = 2;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Fields (Cluster Config Message)
|
||||
@@ -389,7 +378,7 @@ The \fBencryption_password_token\fP field contains a token derived from the pass
|
||||
used to encrypt data sent to this device. If the device is the same as the
|
||||
device sending the message, it signifies that the device itself has encrypted
|
||||
data that was encrypted with the given token. It is empty or missing if there is
|
||||
no encryption. See \fI\%Untrusted Device Encryption\fP for details on the encryption scheme.
|
||||
no encryption. See \X'tty: link #untrusted'\fI\%Untrusted Device Encryption\fP\X'tty: link' for details on the encryption scheme.
|
||||
.SS Index and Index Update
|
||||
.sp
|
||||
The Index and Index Update messages define the contents of the senders
|
||||
@@ -406,8 +395,7 @@ although this is not guaranteed to be the case in the future.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
message Index {
|
||||
string folder = 1;
|
||||
repeated FileInfo files = 2;
|
||||
@@ -460,8 +448,7 @@ message Counter {
|
||||
uint64 id = 1;
|
||||
uint64 value = 2;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Fields (Index Message)
|
||||
@@ -544,8 +531,7 @@ corresponding to a part of a certain file in the peer’s folder.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
message Request {
|
||||
int32 id = 1;
|
||||
string folder = 2;
|
||||
@@ -555,8 +541,7 @@ message Request {
|
||||
bytes hash = 6;
|
||||
bool from_temporary = 7;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Fields
|
||||
@@ -586,8 +571,7 @@ The Response message is sent in response to a Request message.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
message Response {
|
||||
int32 id = 1;
|
||||
bytes data = 2;
|
||||
@@ -600,8 +584,7 @@ enum ErrorCode {
|
||||
NO_SUCH_FILE = 2;
|
||||
INVALID_FILE = 3;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Fields
|
||||
@@ -642,8 +625,7 @@ contain zero or more FileDownloadProgressUpdate messages.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
message DownloadProgress {
|
||||
string folder = 1;
|
||||
repeated FileDownloadProgressUpdate updates = 2;
|
||||
@@ -660,8 +642,7 @@ enum FileDownloadProgressUpdateType {
|
||||
APPEND = 0;
|
||||
FORGET = 1;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Fields (DownloadProgress Message)
|
||||
@@ -721,12 +702,10 @@ other message has been sent in the preceding 90 seconds.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
message Ping {
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Close
|
||||
@@ -738,13 +717,11 @@ further messages.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
message Close {
|
||||
string reason = 1;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Fields
|
||||
@@ -759,15 +736,13 @@ directions.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
+\-\-\-\-\-\-\-\-\-\-\-\-+ Updates /\-\-\-\-\-\-\-\-\-\e
|
||||
| | \-\-\-\-\-\-\-\-\-\-\-> / \e
|
||||
| Device | | Cluster |
|
||||
| | <\-\-\-\-\-\-\-\-\-\-\- \e /
|
||||
+\-\-\-\-\-\-\-\-\-\-\-\-+ Updates \e\-\-\-\-\-\-\-\-\-/
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Send Only
|
||||
@@ -777,15 +752,13 @@ publishes changes of its local folder to the cluster as usual.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
+\-\-\-\-\-\-\-\-\-\-\-\-+ Updates /\-\-\-\-\-\-\-\-\-\e
|
||||
| | \-\-\-\-\-\-\-\-\-\-\-> / \e
|
||||
| Device | | Cluster |
|
||||
| | \e /
|
||||
+\-\-\-\-\-\-\-\-\-\-\-\-+ \e\-\-\-\-\-\-\-\-\-/
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Receive Only
|
||||
@@ -795,15 +768,13 @@ accepts changes to its local folder from the cluster as usual.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
+\-\-\-\-\-\-\-\-\-\-\-\-+ Updates /\-\-\-\-\-\-\-\-\-\e
|
||||
| | <\-\-\-\-\-\-\-\-\-\-\- / \e
|
||||
| Device | | Cluster |
|
||||
| | \e /
|
||||
+\-\-\-\-\-\-\-\-\-\-\-\-+ \e\-\-\-\-\-\-\-\-\-/
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH DELTA INDEX EXCHANGE
|
||||
@@ -878,9 +849,8 @@ results in fewer than 2000 blocks, or the maximum block size for larger
|
||||
files. This rule results in the following table of block sizes per file
|
||||
size:
|
||||
.TS
|
||||
center;
|
||||
|l|l|.
|
||||
_
|
||||
box center;
|
||||
l|l.
|
||||
T{
|
||||
File Size
|
||||
T} T{
|
||||
@@ -934,7 +904,6 @@ T{
|
||||
T} T{
|
||||
16 MiB
|
||||
T}
|
||||
_
|
||||
.TE
|
||||
.sp
|
||||
An implementation MAY deviate from the block size rule when there is good
|
||||
@@ -950,9 +919,8 @@ allowed. The block size used MUST be exactly one of the power\-of\-two block
|
||||
sizes listed in the table above.
|
||||
.SH EXAMPLE EXCHANGE
|
||||
.TS
|
||||
center;
|
||||
|l|l|l|.
|
||||
_
|
||||
box center;
|
||||
l|l|l.
|
||||
T{
|
||||
#
|
||||
T} T{
|
||||
@@ -1074,7 +1042,6 @@ T} T{
|
||||
Ping\->
|
||||
T} T{
|
||||
T}
|
||||
_
|
||||
.TE
|
||||
.sp
|
||||
The connection is established and at 1. both peers send ClusterConfiguration
|
||||
@@ -1089,9 +1056,8 @@ the ping timer on device B expires and a Ping message is sent. The same
|
||||
process occurs for device A at 15.
|
||||
.SH EXAMPLES OF STRONG CIPHER SUITES
|
||||
.TS
|
||||
center;
|
||||
|l|l|l|.
|
||||
_
|
||||
box center;
|
||||
l|l|l.
|
||||
T{
|
||||
ID
|
||||
T} T{
|
||||
@@ -1163,7 +1129,6 @@ ECDHE\-RSA\-AES128\-SHA256
|
||||
T} T{
|
||||
TLSv1.2 ECDH RSA AES(128) SHA256
|
||||
T}
|
||||
_
|
||||
.TE
|
||||
.SH AUTHOR
|
||||
The Syncthing Authors
|
||||
|
||||
@@ -27,21 +27,19 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING-CONFIG" "5" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING-CONFIG" "5" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing-config \- Syncthing Configuration
|
||||
.SH SYNOPSIS
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
$XDG_STATE_HOME/syncthing
|
||||
$HOME/.local/state/syncthing
|
||||
$HOME/Library/Application Support/Syncthing
|
||||
%LOCALAPPDATA%\eSyncthing
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH DESCRIPTION
|
||||
@@ -56,7 +54,7 @@ installations may still use these directories instead of the newer
|
||||
defaults.
|
||||
|
||||
.sp
|
||||
New in version 1.5.0: Database and config can now be set separately. Previously the database was
|
||||
Added in version 1.5.0: Database and config can now be set separately. Previously the database was
|
||||
always located in the same directory as the config.
|
||||
|
||||
.sp
|
||||
@@ -119,10 +117,9 @@ may no longer correspond to the defaults.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
<configuration version=\(dq37\(dq>
|
||||
<folder id=\(dqdefault\(dq label=\(dqDefault Folder\(dq path=\(dq/Users/jb/Sync/\(dq type=\(dqsendreceive\(dq rescanIntervalS=\(dq3600\(dq fsWatcherEnabled=\(dqtrue\(dq fsWatcherDelayS=\(dq10\(dq ignorePerms=\(dqfalse\(dq autoNormalize=\(dqtrue\(dq>
|
||||
<folder id=\(dqdefault\(dq label=\(dqDefault Folder\(dq path=\(dq/Users/jb/Sync/\(dq type=\(dqsendreceive\(dq rescanIntervalS=\(dq3600\(dq fsWatcherEnabled=\(dqtrue\(dq fsWatcherDelayS=\(dq10\(dq fsWatcherTimeoutS=\(dq0\(dq ignorePerms=\(dqfalse\(dq autoNormalize=\(dqtrue\(dq>
|
||||
<filesystemType>basic</filesystemType>
|
||||
<device id=\(dqS7UKX27\-GI7ZTXS\-GC6RKUA\-7AJGZ44\-C6NAYEB\-HSKTJQK\-KJHU2NO\-CWV7EQW\(dq introducedBy=\(dq\(dq>
|
||||
<encryptionPassword></encryptionPassword>
|
||||
@@ -228,7 +225,7 @@ may no longer correspond to the defaults.
|
||||
</options>
|
||||
<remoteIgnoredDevice time=\(dq2022\-01\-09T20:02:01Z\(dq id=\(dq5SYI2FS\-LW6YAXI\-JJDYETS\-NDBBPIO\-256MWBO\-XDPXWVG\-24QPUM4\-PDW4UQU\(dq name=\(dqbugger\(dq address=\(dq192.168.0.20:22000\(dq></remoteIgnoredDevice>
|
||||
<defaults>
|
||||
<folder id=\(dq\(dq label=\(dq\(dq path=\(dq~\(dq type=\(dqsendreceive\(dq rescanIntervalS=\(dq3600\(dq fsWatcherEnabled=\(dqtrue\(dq fsWatcherDelayS=\(dq10\(dq ignorePerms=\(dqfalse\(dq autoNormalize=\(dqtrue\(dq>
|
||||
<folder id=\(dq\(dq label=\(dq\(dq path=\(dq~\(dq type=\(dqsendreceive\(dq rescanIntervalS=\(dq3600\(dq fsWatcherEnabled=\(dqtrue\(dq fsWatcherDelayS=\(dq10\(dq fsWatcherTimeoutS=\(dq0\(dq ignorePerms=\(dqfalse\(dq autoNormalize=\(dqtrue\(dq>
|
||||
<filesystemType>basic</filesystemType>
|
||||
<device id=\(dqS7UKX27\-GI7ZTXS\-GC6RKUA\-7AJGZ44\-C6NAYEB\-HSKTJQK\-KJHU2NO\-CWV7EQW\(dq introducedBy=\(dq\(dq>
|
||||
<encryptionPassword></encryptionPassword>
|
||||
@@ -277,16 +274,14 @@ may no longer correspond to the defaults.
|
||||
</device>
|
||||
</defaults>
|
||||
</configuration>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH CONFIGURATION ELEMENT
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
<configuration version=\(dq37\(dq>
|
||||
<folder></folder>
|
||||
<device></device>
|
||||
@@ -296,8 +291,7 @@ may no longer correspond to the defaults.
|
||||
<remoteIgnoredDevice></remoteIgnoredDevice>
|
||||
<defaults></defaults>
|
||||
</configuration>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -322,9 +316,8 @@ GUI.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
<folder id=\(dqdefault\(dq label=\(dqDefault Folder\(dq path=\(dq/Users/jb/Sync/\(dq type=\(dqsendreceive\(dq rescanIntervalS=\(dq3600\(dq fsWatcherEnabled=\(dqtrue\(dq fsWatcherDelayS=\(dq10\(dq ignorePerms=\(dqfalse\(dq autoNormalize=\(dqtrue\(dq>
|
||||
.EX
|
||||
<folder id=\(dqdefault\(dq label=\(dqDefault Folder\(dq path=\(dq/Users/jb/Sync/\(dq type=\(dqsendreceive\(dq rescanIntervalS=\(dq3600\(dq fsWatcherEnabled=\(dqtrue\(dq fsWatcherDelayS=\(dq10\(dq fsWatcherTimeoutS=\(dq0\(dq ignorePerms=\(dqfalse\(dq autoNormalize=\(dqtrue\(dq>
|
||||
<filesystemType>basic</filesystemType>
|
||||
<device id=\(dqS7UKX27\-GI7ZTXS\-GC6RKUA\-7AJGZ44\-C6NAYEB\-HSKTJQK\-KJHU2NO\-CWV7EQW\(dq introducedBy=\(dq\(dq>
|
||||
<encryptionPassword></encryptionPassword>
|
||||
@@ -361,8 +354,7 @@ GUI.
|
||||
<syncXattrs>false</syncXattrs>
|
||||
<sendXattrs>false</sendXattrs>
|
||||
</folder>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -438,6 +430,13 @@ scheduled (only takes effect if \fI\%fsWatcherEnabled\fP is set to \fBtrue\fP).
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B fsWatcherTimeoutS
|
||||
The maximum delay before a scan is triggered when a file is continuously
|
||||
changing. If unset or zero a default value is calculated based on
|
||||
\fI\%fsWatcherDelayS\fP\&.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ignorePerms
|
||||
If \fBtrue\fP, files originating from this folder will be announced to remote
|
||||
devices with the “no permission bits” flag. The remote devices will use
|
||||
@@ -603,7 +602,7 @@ to \fB\-1\fP to always use weak hash. Default is \fB25\fP\&.
|
||||
.TP
|
||||
.B markerName
|
||||
Name of a directory or file in the folder root to be used as
|
||||
\fI\%How do I serve a folder from a read only filesystem?\fP\&. Default is \fB\&.stfolder\fP\&.
|
||||
\X'tty: link #marker-faq'\fI\%How do I serve a folder from a read only filesystem?\fP\X'tty: link'\&. Default is \fB\&.stfolder\fP\&.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -715,8 +714,7 @@ devices when this is set to \fBtrue\fP\&. See
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
<device id=\(dqS7UKX27\-GI7ZTXS\-GC6RKUA\-7AJGZ44\-C6NAYEB\-HSKTJQK\-KJHU2NO\-CWV7EQW\(dq name=\(dqsyno\(dq compression=\(dqmetadata\(dq introducer=\(dqfalse\(dq skipIntroductionRemovals=\(dqfalse\(dq introducedBy=\(dq2CYF2WQ\-AKZO2QZ\-JAKWLYD\-AGHMQUM\-BGXUOIS\-GYILW34\-HJG3DUK\-LRRYQAR\(dq>
|
||||
<address>dynamic</address>
|
||||
<paused>false</paused>
|
||||
@@ -741,8 +739,7 @@ devices when this is set to \fBtrue\fP\&. See
|
||||
<remoteGUIPort>8384</remoteGUIPort>
|
||||
<numConnections>0</numConnections>
|
||||
</device>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -754,7 +751,7 @@ element:
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B id (mandatory)
|
||||
The \fI\%device ID\fP\&.
|
||||
The \X'tty: link #device-ids'\fI\%device ID\fP\X'tty: link'\&.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -855,15 +852,13 @@ for example:
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
<device id=\(dq...\(dq>
|
||||
<address>tcp://192.0.2.1:22001</address>
|
||||
<address>quic://192.0.1.254:22000</address>
|
||||
<address>dynamic</address>
|
||||
</device>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
@@ -942,15 +937,13 @@ The number of connections to this device. See
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
<gui enabled=\(dqtrue\(dq tls=\(dqfalse\(dq debugging=\(dqfalse\(dq>
|
||||
<address>127.0.0.1:8384</address>
|
||||
<apikey>k1dnz1Dd0rzTBjjFFh7CXPnrF12C49B1</apikey>
|
||||
<theme>default</theme>
|
||||
</gui>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -1060,7 +1053,7 @@ LDAP authentication. Requires ldap top level config section to be present.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B sendBasicAuthPrompt
|
||||
New in version 1.26.0.
|
||||
Added in version 1.26.0.
|
||||
|
||||
.sp
|
||||
Prior to version 1.26.0 the GUI used HTTP Basic Authorization for login, but
|
||||
@@ -1082,16 +1075,14 @@ won’t see browser popups prompting for username and password.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
<ldap>
|
||||
<address>localhost:389</address>
|
||||
<bindDN>cn=%s,ou=users,dc=syncthing,dc=net</bindDN>
|
||||
<transport>nontls</transport>
|
||||
<insecureSkipVerify>false</insecureSkipVerify>
|
||||
</ldap>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -1150,8 +1141,7 @@ Search filter for user searches.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
<options>
|
||||
<listenAddress>default</listenAddress>
|
||||
<globalAnnounceServer>default</globalAnnounceServer>
|
||||
@@ -1202,8 +1192,7 @@ Search filter for user searches.
|
||||
<connectionLimitMax>0</connectionLimitMax>
|
||||
<insecureAllowOldTLSVersions>false</insecureAllowOldTLSVersions>
|
||||
</options>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -1345,7 +1334,7 @@ automatic upgrades.
|
||||
.TP
|
||||
.B upgradeToPreReleases
|
||||
If \fBtrue\fP, automatic upgrades include release candidates (see
|
||||
\fI\%Versions & Releases\fP).
|
||||
\X'tty: link #releases'\fI\%Versions & Releases\fP\X'tty: link').
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -1415,7 +1404,10 @@ the user acknowledged it (e.g. an transition notice on an upgrade).
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B trafficClass
|
||||
Specify a type of service (TOS)/traffic class of outgoing packets.
|
||||
Specify an IPv4 type of service (TOS)/IPv6 traffic class for outgoing
|
||||
packets. To specify a differentiated services code point (DSCP) the value
|
||||
must be bit shifted to the left by two to take the two least significant
|
||||
ECN bits into account.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -1497,7 +1489,7 @@ addresses to global discovery.
|
||||
.TP
|
||||
.B sendFullIndexOnUpgrade
|
||||
Controls whether all index data is resent when an upgrade has happened,
|
||||
equivalent to starting Syncthing with \fI\%\-\-reset\-deltas\fP\&. This used
|
||||
equivalent to starting Syncthing with \X'tty: link #cmdoption-reset-deltas'\fI\%\-\-reset\-deltas\fP\X'tty: link'\&. This used
|
||||
to be the default behavior in older versions, but is mainly useful as a
|
||||
troubleshooting step and causes high database churn. The default is now
|
||||
\fBfalse\fP\&.
|
||||
@@ -1535,10 +1527,9 @@ detailed in \fI\%insecureAllowOldTLSVersions\fP\&.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
<defaults>
|
||||
<folder id=\(dq\(dq label=\(dq\(dq path=\(dq~\(dq type=\(dqsendreceive\(dq rescanIntervalS=\(dq3600\(dq fsWatcherEnabled=\(dqtrue\(dq fsWatcherDelayS=\(dq10\(dq ignorePerms=\(dqfalse\(dq autoNormalize=\(dqtrue\(dq>
|
||||
<folder id=\(dq\(dq label=\(dq\(dq path=\(dq~\(dq type=\(dqsendreceive\(dq rescanIntervalS=\(dq3600\(dq fsWatcherEnabled=\(dqtrue\(dq fsWatcherDelayS=\(dq10\(dq fsWatcherTimeoutS=\(dq0\(dq ignorePerms=\(dqfalse\(dq autoNormalize=\(dqtrue\(dq>
|
||||
<filesystemType>basic</filesystemType>
|
||||
<device id=\(dqS7UKX27\-GI7ZTXS\-GC6RKUA\-7AJGZ44\-C6NAYEB\-HSKTJQK\-KJHU2NO\-CWV7EQW\(dq introducedBy=\(dq\(dq>
|
||||
<encryptionPassword></encryptionPassword>
|
||||
@@ -1590,8 +1581,7 @@ detailed in \fI\%insecureAllowOldTLSVersions\fP\&.
|
||||
<line>qu*</line>
|
||||
</ignores>
|
||||
</defaults>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -1623,10 +1613,10 @@ including the appropriate \fI\%folder.device\fP element underneath.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ignores
|
||||
New in version 1.19.0.
|
||||
Added in version 1.19.0.
|
||||
|
||||
.sp
|
||||
Template for the \fI\%ignore patterns\fP applied to new
|
||||
Template for the \X'tty: link #ignoring-files'\fI\%ignore patterns\fP\X'tty: link' applied to new
|
||||
folders. These are copied to the \fB\&.stignore\fP file when a folder is
|
||||
automatically accepted from a remote device. The GUI uses them to pre\-fill
|
||||
the respective field when adding a new folder as well. In XML, each pattern
|
||||
@@ -1698,12 +1688,12 @@ accidentally if you sync your home folder between devices. A common symptom
|
||||
of syncing configuration files is two devices ending up with the same Device ID.
|
||||
.sp
|
||||
If you want to use Syncthing to backup your configuration files, it is recommended
|
||||
that the files you are backing up are in a \fI\%Send Only Folder\fP to prevent other
|
||||
that the files you are backing up are in a \X'tty: link #folder-sendonly'\fI\%Send Only Folder\fP\X'tty: link' to prevent other
|
||||
devices from overwriting the per device configuration. The folder on the remote
|
||||
device(s) should not be used as configuration for the remote devices.
|
||||
.sp
|
||||
If you’d like to sync your home folder in non\-send only mode, you may add the
|
||||
folder that stores the configuration files to the \fI\%ignore list\fP\&.
|
||||
folder that stores the configuration files to the \X'tty: link #ignoring-files'\fI\%ignore list\fP\X'tty: link'\&.
|
||||
If you’d also like to backup your configuration files, add another folder in
|
||||
send only mode for just the configuration folder.
|
||||
.SH AUTHOR
|
||||
|
||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING-DEVICE-IDS" "7" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING-DEVICE-IDS" "7" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing-device-ids \- Understanding Device IDs
|
||||
.sp
|
||||
@@ -52,8 +52,7 @@ The typical certificate will look something like this, inspected with
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
@@ -87,8 +86,7 @@ Certificate:
|
||||
...
|
||||
88:7e:e2:61:aa:4c:02:e3:64:b0:da:70:3a:cd:1c:3d:86:db:
|
||||
df:54:b9:4e:be:1b
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -113,27 +111,23 @@ bits) so the resulting ID looks something like:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
MFZWI3DBONSGYYLTMRWGC43ENRQXGZDMMFZWI3DBONSGYYLTMRWA====
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
The padding (\fB====\fP) is stripped away, the device ID split into four
|
||||
groups, and \fI\%check
|
||||
digits\fP <\fBhttps://forum.syncthing.net/t/v0-9-0-new-node-id-format/478\fP>
|
||||
groups, and \X'tty: link https://forum.syncthing.net/t/v0-9-0-new-node-id-format/478'\fI\%check
|
||||
digits\fP <\fBhttps://forum.syncthing.net/t/v0-9-0-new-node-id-format/478\fP>\X'tty: link'
|
||||
are added for each group. For presentation purposes the device ID is
|
||||
grouped with dashes, resulting in the final value:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
MFZWI3D\-BONSGYC\-YLTMRWG\-C43ENR5\-QXGZDMM\-FZWI3DP\-BONSGYY\-LTMRWAD
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Connection Establishment
|
||||
@@ -192,8 +186,8 @@ You can argue that of course there are collisions \- there’s an infinite
|
||||
amount of inputs and a finite amount of outputs \- so by definition there
|
||||
are infinitely many messages that result in the same hash.
|
||||
.sp
|
||||
I’m going to quote \fI\%stack
|
||||
overflow\fP <\fBhttps://stackoverflow.com/questions/4014090/is-it-safe-to-ignore-the-possibility-of-sha-collisions-in-practice\fP>
|
||||
I’m going to quote \X'tty: link https://stackoverflow.com/questions/4014090/is-it-safe-to-ignore-the-possibility-of-sha-collisions-in-practice'\fI\%stack
|
||||
overflow\fP <\fBhttps://stackoverflow.com/questions/4014090/is-it-safe-to-ignore-the-possibility-of-sha-collisions-in-practice\fP>\X'tty: link'
|
||||
here:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
|
||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING-EVENT-API" "7" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING-EVENT-API" "7" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing-event-api \- Event API
|
||||
.SH DESCRIPTION
|
||||
@@ -40,8 +40,7 @@ Each event is represented by an object similar to the following:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 2,
|
||||
\(dqglobalID\(dq: 3,
|
||||
@@ -52,8 +51,7 @@ Each event is represented by an object similar to the following:
|
||||
\(dqid\(dq: \(dqNFGKEKE\-7Z6RTH7\-I3PRZXS\-DEJF3UJ\-FRWJBFO\-VBBTDND\-4SGNGVZ\-QUQHJAG\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -85,7 +83,7 @@ determined by the event type.
|
||||
.SH EVENT TYPES
|
||||
.SS ClusterConfigReceived
|
||||
.sp
|
||||
New in version 1.20.0.
|
||||
Added in version 1.20.0.
|
||||
|
||||
.sp
|
||||
The \fBClusterConfigReceived\fP event is emitted after processing such a protocol
|
||||
@@ -93,8 +91,7 @@ message received from a remote device. It is mainly used for internal purposes.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 84,
|
||||
\(dqglobalID\(dq: 84,
|
||||
@@ -104,8 +101,7 @@ message received from a remote device. It is mainly used for internal purposes.
|
||||
\(dqdevice\(dq: \(dqI6KAH76\-66SLLLB\-5PFXSOA\-UFJCDZC\-YAOMLEK\-CP2GB32\-BV5RQST\-3PSROAU\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS ConfigSaved
|
||||
@@ -115,8 +111,7 @@ itself.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 50,
|
||||
\(dqglobalID\(dq: 50,
|
||||
@@ -133,8 +128,7 @@ itself.
|
||||
\(dqdefaults\(dq: {\(dq...\(dq}
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS DeviceConnected
|
||||
@@ -143,8 +137,7 @@ Generated each time a connection to a device has been established.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 2,
|
||||
\(dqglobalID\(dq: 2,
|
||||
@@ -159,8 +152,7 @@ Generated each time a connection to a device has been established.
|
||||
\(dqtype\(dq: \(dqTCP (Client)\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS DeviceDisconnected
|
||||
@@ -169,8 +161,7 @@ Generated each time a connection to a device has been terminated.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 48,
|
||||
\(dqglobalID\(dq: 48,
|
||||
@@ -181,8 +172,7 @@ Generated each time a connection to a device has been terminated.
|
||||
\(dqid\(dq: \(dqNFGKEKE\-7Z6RTH7\-I3PRZXS\-DEJF3UJ\-FRWJBFO\-VBBTDND\-4SGNGVZ\-QUQHJAG\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -201,8 +191,7 @@ Emitted when a new device is discovered using local discovery.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 13,
|
||||
\(dqglobalID\(dq: 13,
|
||||
@@ -215,8 +204,7 @@ Emitted when a new device is discovered using local discovery.
|
||||
\(dqdevice\(dq: \(dqNFGKEKE\-7Z6RTH7\-I3PRZXS\-DEJF3UJ\-FRWJBFO\-VBBTDND\-4SGNGVZ\-QUQHJAG\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS DevicePaused
|
||||
@@ -225,8 +213,7 @@ Emitted when a device was paused.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 13,
|
||||
\(dqglobalID\(dq: 13,
|
||||
@@ -236,8 +223,7 @@ Emitted when a device was paused.
|
||||
\(dqdevice\(dq: \(dqNFGKEKE\-7Z6RTH7\-I3PRZXS\-DEJF3UJ\-FRWJBFO\-VBBTDND\-4SGNGVZ\-QUQHJAG\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS DeviceRejected (DEPRECATED)
|
||||
@@ -251,8 +237,7 @@ to talk to.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 24,
|
||||
\(dqglobalID\(dq: 24,
|
||||
@@ -264,8 +249,7 @@ to talk to.
|
||||
\(dqdevice\(dq: \(dqEJHMPAQ\-OGCVORE\-ISB4IS3\-SYYVJXF\-TKJGLTU\-66DIQPF\-GJ5D2GX\-GQ3OWQK\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS DeviceResumed
|
||||
@@ -274,8 +258,7 @@ Generated each time a device was resumed.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 2,
|
||||
\(dqglobalID\(dq: 2,
|
||||
@@ -285,8 +268,7 @@ Generated each time a device was resumed.
|
||||
\(dqdevice\(dq: \(dqNFGKEKE\-7Z6RTH7\-I3PRZXS\-DEJF3UJ\-FRWJBFO\-VBBTDND\-4SGNGVZ\-QUQHJAG\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS DownloadProgress
|
||||
@@ -297,8 +279,7 @@ configuration can cause multiple files to be shown.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 221,
|
||||
\(dqglobalID\(dq: 221,
|
||||
@@ -351,8 +332,7 @@ configuration can cause multiple files to be shown.
|
||||
}
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
@@ -393,8 +373,7 @@ The \fBdata\fP field contains a textual error message.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 93,
|
||||
\(dqglobalID\(dq: 93,
|
||||
@@ -402,8 +381,7 @@ The \fBdata\fP field contains a textual error message.
|
||||
\(dqtime\(dq: \(dq2021\-06\-07T21:22:03.414609034+02:00\(dq,
|
||||
\(dqdata\(dq: \(dqindex handler got paused while already paused\(dq
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FolderCompletion
|
||||
@@ -413,7 +391,7 @@ contents for a folder changes. It contains the completion percentage for
|
||||
a given remote device and is emitted once per currently connected remote
|
||||
device.
|
||||
.sp
|
||||
New in version 1.20.0: Indication whether the remote device has accepted the folder (shares it with
|
||||
Added in version 1.20.0: Indication whether the remote device has accepted the folder (shares it with
|
||||
us) as well, and whether it is paused. The \fBremoteState\fP field is
|
||||
\fBunknown\fP when the remote device is not connected. Otherwise it can be
|
||||
either \fBpaused\fP, \fBnotSharing\fP, or \fBvalid\fP if the remote is sharing back.
|
||||
@@ -421,8 +399,7 @@ either \fBpaused\fP, \fBnotSharing\fP, or \fBvalid\fP if the remote is sharing b
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 84,
|
||||
\(dqglobalID\(dq: 84,
|
||||
@@ -441,8 +418,7 @@ either \fBpaused\fP, \fBnotSharing\fP, or \fBvalid\fP if the remote is sharing b
|
||||
\(dqsequence\(dq: 12
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FolderErrors
|
||||
@@ -455,8 +431,7 @@ synchronization attempt, a new \fBFolderErrors\fP event is emitted.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 132,
|
||||
\(dqtype\(dq: \(dqFolderErrors\(dq,
|
||||
@@ -471,18 +446,17 @@ synchronization attempt, a new \fBFolderErrors\fP event is emitted.
|
||||
\(dqfolder\(dq: \(dqdefault\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
New in version 0.11.12.
|
||||
Added in version 0.11.12.
|
||||
|
||||
.sp
|
||||
\fBSEE ALSO:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
The \fI\%StateChanged\fP event.
|
||||
The \X'tty: link #statechanged'\fI\%StateChanged\fP\X'tty: link' event.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FolderPaused
|
||||
@@ -492,8 +466,7 @@ of a folder. Sent repeatedly for each changed folder.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 93,
|
||||
\(dqglobalID\(dq: 93,
|
||||
@@ -504,8 +477,7 @@ of a folder. Sent repeatedly for each changed folder.
|
||||
\(dqlabel\(dq: \(dqMy folder\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FolderRejected (DEPRECATED)
|
||||
@@ -519,8 +491,7 @@ have, or have but do not share with the device in question.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 27,
|
||||
\(dqglobalID\(dq: 27,
|
||||
@@ -532,8 +503,7 @@ have, or have but do not share with the device in question.
|
||||
\(dqfolderLabel\(dq: \(dqMy Pictures\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FolderResumed
|
||||
@@ -543,8 +513,7 @@ of a folder. Sent repeatedly for each changed folder.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 93,
|
||||
\(dqglobalID\(dq: 93,
|
||||
@@ -555,8 +524,7 @@ of a folder. Sent repeatedly for each changed folder.
|
||||
\(dqlabel\(dq: \(dqMy folder\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FolderScanProgress
|
||||
@@ -567,8 +535,7 @@ total , as well as the current scanning rates in bytes per second.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqdata\(dq : {
|
||||
\(dqtotal\(dq : 1,
|
||||
@@ -581,8 +548,7 @@ total , as well as the current scanning rates in bytes per second.
|
||||
\(dqtime\(dq : \(dq2017\-03\-06T15:00:58.072004209+01:00\(dq,
|
||||
\(dqid\(dq : 29
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FolderSummary
|
||||
@@ -593,8 +559,7 @@ state.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 16,
|
||||
\(dqtype\(dq: \(dqFolderSummary\(dq,
|
||||
@@ -644,8 +609,7 @@ state.
|
||||
}
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FolderWatchStateChanged
|
||||
@@ -658,8 +622,7 @@ If there was no error in either of these, the respective field is omitted.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 123,
|
||||
\(dqtype\(dq: \(dqFolderWatchStateChanged\(dq,
|
||||
@@ -670,8 +633,7 @@ If there was no error in either of these, the respective field is omitted.
|
||||
\(dqto\(dq: \(dqSomething worse happened.\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS ItemFinished
|
||||
@@ -681,8 +643,7 @@ successful operation:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 93,
|
||||
\(dqglobalID\(dq: 93,
|
||||
@@ -696,8 +657,7 @@ successful operation:
|
||||
\(dqaction\(dq: \(dqupdate\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -705,8 +665,7 @@ An unsuccessful operation:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 44,
|
||||
\(dqglobalID\(dq: 44,
|
||||
@@ -720,14 +679,13 @@ An unsuccessful operation:
|
||||
\(dqtype\(dq: \(dqfile\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
The \fBaction\fP field is either \fBupdate\fP (contents changed), \fBmetadata\fP (file metadata changed but not contents), or \fBdelete\fP\&.
|
||||
.sp
|
||||
New in version 0.11.10: The \fBmetadata\fP action.
|
||||
Added in version 0.11.10: The \fBmetadata\fP action.
|
||||
|
||||
.SS ItemStarted
|
||||
.sp
|
||||
@@ -735,8 +693,7 @@ Generated when Syncthing begins synchronizing a file to a newer version.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 93,
|
||||
\(dqglobalID\(dq: 93,
|
||||
@@ -749,23 +706,21 @@ Generated when Syncthing begins synchronizing a file to a newer version.
|
||||
\(dqaction\(dq: \(dqupdate\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
The \fBaction\fP field is either \fBupdate\fP (contents changed), \fBmetadata\fP (file metadata changed but not contents), or \fBdelete\fP\&.
|
||||
.sp
|
||||
New in version 0.11.10: The \fBmetadata\fP action.
|
||||
Added in version 0.11.10: The \fBmetadata\fP action.
|
||||
|
||||
.SS ListenAddressesChanged
|
||||
.sp
|
||||
This event is emitted when a \fI\%listen address\fP changes.
|
||||
This event is emitted when a \X'tty: link #listen-addresses'\fI\%listen address\fP\X'tty: link' changes.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqtype\(dq : \(dqListenAddressesChanged\(dq,
|
||||
\(dqid\(dq : 70,
|
||||
@@ -811,8 +766,7 @@ This event is emitted when a \fI\%listen address\fP changes.
|
||||
]
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS LocalChangeDetected
|
||||
@@ -832,8 +786,7 @@ a mask specified, but needs to be selected explicitly.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 7,
|
||||
\(dqglobalID\(dq: 59,
|
||||
@@ -848,8 +801,7 @@ a mask specified, but needs to be selected explicitly.
|
||||
\(dqtype\(dq: \(dqfile\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -864,8 +816,7 @@ changes during a scan.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 59,
|
||||
\(dqglobalID\(dq: 59,
|
||||
@@ -883,8 +834,7 @@ changes during a scan.
|
||||
\(dqversion\(dq: 12345
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -901,8 +851,7 @@ origin of the request, but e.g. a reverse proxy.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq : 187,
|
||||
\(dqtime\(dq : \(dq2017\-03\-07T00:19:24.420386143+01:00\(dq,
|
||||
@@ -914,13 +863,12 @@ origin of the request, but e.g. a reverse proxy.
|
||||
\(dqtype\(dq : \(dqLoginAttempt\(dq,
|
||||
\(dqglobalID\(dq : 195
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS PendingDevicesChanged
|
||||
.sp
|
||||
New in version 1.14.0.
|
||||
Added in version 1.14.0.
|
||||
|
||||
.sp
|
||||
Emitted when pending devices were added / updated (connection from
|
||||
@@ -928,8 +876,7 @@ unknown ID) or removed (device is ignored, dismissed or added).
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 87,
|
||||
\(dqtype\(dq: \(dqPendingDevicesChanged\(dq,
|
||||
@@ -949,13 +896,12 @@ unknown ID) or removed (device is ignored, dismissed or added).
|
||||
]
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS PendingFoldersChanged
|
||||
.sp
|
||||
New in version 1.14.0.
|
||||
Added in version 1.14.0.
|
||||
|
||||
.sp
|
||||
Emitted when pending folders were added / updated (offered by some
|
||||
@@ -966,8 +912,7 @@ longer pending for any device.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 101,
|
||||
\(dqtype\(dq: \(dqPendingFoldersChanged\(dq,
|
||||
@@ -993,8 +938,7 @@ longer pending for any device.
|
||||
]
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS RemoteChangeDetected
|
||||
@@ -1012,8 +956,7 @@ a mask specified, but needs to be selected explicitly.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqtime\(dq : \(dq2017\-03\-06T23:58:21.844739891+01:00\(dq,
|
||||
\(dqglobalID\(dq : 123,
|
||||
@@ -1029,8 +972,7 @@ a mask specified, but needs to be selected explicitly.
|
||||
\(dqtype\(dq : \(dqRemoteChangeDetected\(dq,
|
||||
\(dqid\(dq : 2
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -1039,15 +981,14 @@ Deprecated since version v1.1.2: The \fBfolderID\fP field is a legacy name kept
|
||||
|
||||
.SS RemoteDownloadProgress
|
||||
.sp
|
||||
This event is emitted when a \fI\%DownloadProgress\fP message is
|
||||
This event is emitted when a \X'tty: link #download-progress'\fI\%DownloadProgress\fP\X'tty: link' message is
|
||||
received. It returns a map \fBdata\fP of filenames with a count of
|
||||
downloaded blocks. The files in questions are currently being
|
||||
downloaded on the remote \fBdevice\fP and belong to \fBfolder\fP\&.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqtime\(dq : \(dq2017\-03\-07T00:11:37.65838955+01:00\(dq,
|
||||
\(dqglobalID\(dq : 170,
|
||||
@@ -1061,8 +1002,7 @@ downloaded on the remote \fBdevice\fP and belong to \fBfolder\fP\&.
|
||||
\(dqtype\(dq : \(dqRemoteDownloadProgress\(dq,
|
||||
\(dqid\(dq : 163
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS RemoteIndexUpdated
|
||||
@@ -1071,8 +1011,7 @@ Generated each time new index information is received from a device.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 44,
|
||||
\(dqglobalID\(dq: 44,
|
||||
@@ -1084,8 +1023,7 @@ Generated each time new index information is received from a device.
|
||||
\(dqitems\(dq: 1000
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Starting
|
||||
@@ -1095,8 +1033,7 @@ configuration etc.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 1,
|
||||
\(dqglobalID\(dq: 1,
|
||||
@@ -1106,8 +1043,7 @@ configuration etc.
|
||||
\(dqhome\(dq: \(dq/home/jb/.config/syncthing\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS StartupComplete
|
||||
@@ -1117,8 +1053,7 @@ ready to start exchanging data with other devices.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 1,
|
||||
\(dqglobalID\(dq: 1,
|
||||
@@ -1126,8 +1061,7 @@ ready to start exchanging data with other devices.
|
||||
\(dqtime\(dq: \(dq2014\-07\-13T21:03:18.383239179+02:00\(dq,
|
||||
\(dqdata\(dq: null
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS StateChanged
|
||||
@@ -1140,8 +1074,7 @@ seconds and is now in state \fBidle\fP\&.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
\(dqid\(dq: 8,
|
||||
\(dqglobalID\(dq: 8,
|
||||
@@ -1154,8 +1087,7 @@ seconds and is now in state \fBidle\fP\&.
|
||||
\(dqto\(dq: \(dqidle\(dq
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH AUTHOR
|
||||
|
||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING-FAQ" "7" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING-FAQ" "7" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing-faq \- Frequently Asked Questions
|
||||
.INDENT 0.0
|
||||
@@ -164,7 +164,7 @@ Directory modification times (not preserved)
|
||||
Hard links (followed, not preserved)
|
||||
.IP \(bu 2
|
||||
Windows junctions (synced as ordinary directories; require enabling in
|
||||
\fI\%the configuration\fP on a per\-folder
|
||||
\X'tty: link #config-option-folder.junctionsasdirs'\fI\%the configuration\fP\X'tty: link' on a per\-folder
|
||||
basis)
|
||||
.IP \(bu 2
|
||||
Resource forks (not preserved)
|
||||
@@ -176,7 +176,7 @@ Devices, FIFOs, and other specials (ignored)
|
||||
Sparse file sparseness (will become sparse, when supported by the OS & filesystem)
|
||||
.IP \(bu 2
|
||||
Syncthing internal files and folders (e.g. \fB\&.stfolder\fP, \fB\&.stignore\fP,
|
||||
\fB\&.stversions\fP, \fI\%temporary files\fP, etc.)
|
||||
\fB\&.stversions\fP, \X'tty: link #temporary-files'\fI\%temporary files\fP\X'tty: link', etc.)
|
||||
.UNINDENT
|
||||
.SS Is synchronization fast?
|
||||
.sp
|
||||
@@ -191,7 +191,7 @@ manner. This means that renaming a file will not cause a retransmission of
|
||||
that file. Additionally, appending data to existing files should be handled
|
||||
efficiently as well.
|
||||
.sp
|
||||
\fI\%Temporary files\fP are used to store partial data
|
||||
\X'tty: link #temporary-files'\fI\%Temporary files\fP\X'tty: link' are used to store partial data
|
||||
downloaded from other devices. They are automatically removed whenever a file
|
||||
transfer has been completed or after the configured amount of time which is set
|
||||
in the configuration file (24 hours by default).
|
||||
@@ -209,7 +209,7 @@ Syncthing uses an open and documented protocol, and likewise the security
|
||||
mechanisms in use are well defined and visible in the source code. Resilio
|
||||
Sync uses an undocumented, closed protocol with unknown security properties.
|
||||
.IP [1] 5
|
||||
\fI\%https://en.wikipedia.org/wiki/Resilio_Sync\fP
|
||||
\X'tty: link https://en.wikipedia.org/wiki/Resilio_Sync'\fI\%https://en.wikipedia.org/wiki/Resilio_Sync\fP\X'tty: link'
|
||||
.SS Is there an iOS client?
|
||||
.sp
|
||||
There are no plans by the current Syncthing team to officially support iOS in the foreseeable future.
|
||||
@@ -219,7 +219,7 @@ run Syncthing reliably and integrate it into the system.
|
||||
.sp
|
||||
However, there is a commercial packaging of Syncthing for iOS that attempts to work within these limitations. [2]
|
||||
.IP [2] 5
|
||||
\fI\%https://www.mobiussync.com\fP
|
||||
\X'tty: link https://www.mobiussync.com'\fI\%https://www.mobiussync.com\fP\X'tty: link'
|
||||
.SS Should I keep my device IDs secret?
|
||||
.sp
|
||||
No. The IDs are not sensitive. Given a device ID it’s possible to find the IP
|
||||
@@ -236,7 +236,7 @@ oyster!)
|
||||
\fBSEE ALSO:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
\fI\%Understanding Device IDs\fP
|
||||
\X'tty: link #device-ids'\fI\%Understanding Device IDs\fP\X'tty: link'
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH TROUBLESHOOTING
|
||||
@@ -262,7 +262,7 @@ Devices” list on the right side of the GUI, double check that you see
|
||||
.sp
|
||||
If you are connected via a relay, this is because a direct connection could
|
||||
not be established. Double check and follow the suggestions in
|
||||
\fI\%Firewall Setup\fP to enable direct connections.
|
||||
\X'tty: link #firewall-setup'\fI\%Firewall Setup\fP\X'tty: link' to enable direct connections.
|
||||
.sp
|
||||
Second, if one of the devices is a very low powered machine (a Raspberry Pi,
|
||||
or a phone, or a NAS, or similar) you are likely constrained by the CPU on
|
||||
@@ -295,8 +295,8 @@ causes a certain amount of extra CPU usage to calculate the summary data it
|
||||
presents. Note however that once things are \fIin sync\fP CPU usage should be
|
||||
negligible.
|
||||
.sp
|
||||
To minimize the impact of this, Syncthing attempts to \fI\%lower the
|
||||
process priority\fP when starting up.
|
||||
To minimize the impact of this, Syncthing attempts to \X'tty: link #config-option-options.setlowpriority'\fI\%lower the
|
||||
process priority\fP\X'tty: link' when starting up.
|
||||
.sp
|
||||
To further limit the amount of CPU used when syncing and scanning, set the
|
||||
environment variable \fBGOMAXPROCS\fP to the maximum number of CPU cores
|
||||
@@ -315,7 +315,7 @@ This is an area that we are working to improve in the long term.
|
||||
.sp
|
||||
Since version 0.14.6 Syncthing does an extra security check when the GUI/API
|
||||
is bound to localhost \- namely that the browser is talking to localhost.
|
||||
This protects against most forms of \fI\%DNS rebinding attack\fP <\fBhttps://en.wikipedia.org/wiki/DNS_rebinding\fP> against the GUI.
|
||||
This protects against most forms of \X'tty: link https://en.wikipedia.org/wiki/DNS_rebinding'\fI\%DNS rebinding attack\fP <\fBhttps://en.wikipedia.org/wiki/DNS_rebinding\fP>\X'tty: link' against the GUI.
|
||||
.sp
|
||||
To pass this test, ensure that you are accessing the GUI using an URL that
|
||||
begins with \fBhttp://localhost\fP, \fBhttp://127.0.0.1\fP or \fBhttp://[::1]\fP\&. HTTPS
|
||||
@@ -328,7 +328,7 @@ protect against unauthorized access. Either:
|
||||
.IP \(bu 2
|
||||
Make sure the proxy sets a \fBHost\fP header containing \fBlocalhost\fP, or
|
||||
.IP \(bu 2
|
||||
Set \fI\%gui.insecureSkipHostcheck\fP in the advanced settings, or
|
||||
Set \X'tty: link #config-option-gui.insecureskiphostcheck'\fI\%gui.insecureSkipHostcheck\fP\X'tty: link' in the advanced settings, or
|
||||
.IP \(bu 2
|
||||
Bind the GUI/API to a non\-localhost listen port.
|
||||
.UNINDENT
|
||||
@@ -338,8 +338,8 @@ In all cases, username/password authentication and HTTPS should be used.
|
||||
.sp
|
||||
This is almost always a result of bad RAM, storage device or other hardware.
|
||||
When the index database is found to be corrupt Syncthing cannot operate and will
|
||||
note this in the logs and exit. To overcome this delete the \fI\%database
|
||||
folder\fP inside Syncthing’s data directory and re\-start
|
||||
note this in the logs and exit. To overcome this delete the \X'tty: link #config-locations'\fI\%database
|
||||
folder\fP\X'tty: link' inside Syncthing’s data directory and re\-start
|
||||
Syncthing. It will then need to perform a full re\-hashing of all shared
|
||||
folders. You should check your system in case the underlying cause is indeed
|
||||
faulty hardware which may put the system at risk of further data loss.
|
||||
@@ -374,10 +374,10 @@ up\-to\-date state with all the neighbours.
|
||||
.SS Why does Syncthing connect to this unknown/suspicious address?
|
||||
.sp
|
||||
If you see outgoing connections to odd and unexpected addresses these are
|
||||
most likely connections to \fI\%relay servers\fP\&. Relay servers
|
||||
most likely connections to \X'tty: link #relaying'\fI\%relay servers\fP\X'tty: link'\&. Relay servers
|
||||
are run by volunteers all over the world. They usually listen on ports 443 or
|
||||
22067, though this is controlled by the user running it. You can compare the
|
||||
address you are concerned about with \fI\%the current list of active relays\fP <\fBhttps://relays.syncthing.net\fP>\&. Relays do not and can not see the data
|
||||
address you are concerned about with \X'tty: link https://relays.syncthing.net'\fI\%the current list of active relays\fP <\fBhttps://relays.syncthing.net\fP>\X'tty: link'\&. Relays do not and can not see the data
|
||||
transmitted via them.
|
||||
.SS I am seeing the error message “folder marker missing”. What do I do?
|
||||
.sp
|
||||
@@ -420,7 +420,7 @@ Also see the \fI\%marker FAQ\fP for more information about the folder marker.
|
||||
\fBSEE ALSO:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
\fI\%Conflicting Changes\fP
|
||||
\X'tty: link #conflict-handling'\fI\%Conflicting Changes\fP\X'tty: link'
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS How do I serve a folder from a read only filesystem?
|
||||
@@ -468,8 +468,8 @@ to configure listening ports such that they do not overlap (see \fI\%Syncthing C
|
||||
.sp
|
||||
No. Syncthing is not designed to sync locally and the overhead involved in
|
||||
doing so using Syncthing’s method would be wasteful. There are better
|
||||
programs to achieve this such as \fI\%rsync\fP <\fBhttps://rsync.samba.org/\fP> or
|
||||
\fI\%Unison\fP <\fBhttps://www.cis.upenn.edu/~bcpierce/unison\fP>\&.
|
||||
programs to achieve this such as \X'tty: link https://rsync.samba.org/'\fI\%rsync\fP <\fBhttps://rsync.samba.org/\fP>\X'tty: link' or
|
||||
\X'tty: link https://www.cis.upenn.edu/~bcpierce/unison'\fI\%Unison\fP <\fBhttps://www.cis.upenn.edu/~bcpierce/unison\fP>\X'tty: link'\&.
|
||||
.SS When I do have two distinct Syncthing\-managed folders on two hosts, how does Syncthing handle moving files between them?
|
||||
.sp
|
||||
Syncthing does not specially handle this case, and most files will most likely get
|
||||
@@ -526,12 +526,10 @@ computer, change the \fBGUI listen address\fP option in the web GUI from
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
<gui enabled=\(dqtrue\(dq tls=\(dqfalse\(dq>
|
||||
<address>127.0.0.1:8384</address>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -539,12 +537,10 @@ to
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
<gui enabled=\(dqtrue\(dq tls=\(dqtrue\(dq>
|
||||
<address>0.0.0.0:8384</address>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -557,33 +553,29 @@ GUI settings at default and use an SSH port forward to access it. For example,
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
$ ssh \-L 9090:127.0.0.1:8384 user@othercomputer.example.com
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
will log you into \fBothercomputer.example.com\fP, and present the \fIremote\fP
|
||||
Syncthing GUI on \fI\%http://localhost:9090\fP on your \fIlocal\fP computer.
|
||||
Syncthing GUI on \X'tty: link http://localhost:9090'\fI\%http://localhost:9090\fP\X'tty: link' on your \fIlocal\fP computer.
|
||||
.sp
|
||||
If you only want to access the remote GUI and don’t want the terminal session,
|
||||
use this example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
$ ssh \-N \-L 9090:127.0.0.1:8384 user@othercomputer.example.com
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
If only your remote computer is Unix\-like, you can still access it with SSH from
|
||||
Windows. Under Windows 10 or later you can use the same \fBssh\fP command if you
|
||||
\fI\%install the OpenSSH Client\fP <\fBhttps://learn.microsoft.com/windows-server/administration/openssh/openssh_install_firstuse\fP>\&.
|
||||
\X'tty: link https://learn.microsoft.com/windows-server/administration/openssh/openssh_install_firstuse'\fI\%install the OpenSSH Client\fP <\fBhttps://learn.microsoft.com/windows-server/administration/openssh/openssh_install_firstuse\fP>\X'tty: link'\&.
|
||||
.SS I don’t like the GUI or the theme. Can it be changed?
|
||||
.sp
|
||||
You can change the theme in the settings. Syncthing ships with other themes
|
||||
@@ -601,7 +593,7 @@ To add e.g. a red theme, you can create the file \fBred/assets/css/theme.css\fP
|
||||
inside the GUI override directory to override the default CSS styles.
|
||||
.sp
|
||||
To create a whole new GUI, you should checkout the files at
|
||||
\fI\%https://github.com/syncthing/syncthing/tree/main/gui/default\fP
|
||||
\X'tty: link https://github.com/syncthing/syncthing/tree/main/gui/default'\fI\%https://github.com/syncthing/syncthing/tree/main/gui/default\fP\X'tty: link'
|
||||
to get an idea how to do that.
|
||||
.SS How do I upgrade Syncthing?
|
||||
.sp
|
||||
@@ -626,13 +618,13 @@ so should Syncthing.
|
||||
.SS Where do I find the latest release?
|
||||
.sp
|
||||
We release new versions through GitHub. The latest release is always found
|
||||
\fI\%on the release page\fP <\fBhttps://github.com/syncthing/syncthing/releases/latest\fP>\&. Unfortunately
|
||||
\X'tty: link https://github.com/syncthing/syncthing/releases/latest'\fI\%on the release page\fP <\fBhttps://github.com/syncthing/syncthing/releases/latest\fP>\X'tty: link'\&. Unfortunately
|
||||
GitHub does not provide a single URL to automatically download the latest
|
||||
version. We suggest to use the \fI\%GitHub API\fP <\fBhttps://api.github.com/repos/syncthing/syncthing/releases/latest\fP> and parsing
|
||||
version. We suggest to use the \X'tty: link https://api.github.com/repos/syncthing/syncthing/releases/latest'\fI\%GitHub API\fP <\fBhttps://api.github.com/repos/syncthing/syncthing/releases/latest\fP>\X'tty: link' and parsing
|
||||
the JSON response.
|
||||
.SS How do I run Syncthing as a daemon process on Linux?
|
||||
.sp
|
||||
If you’re using systemd, runit, or upstart, we ship \fI\%example configurations\fP <\fBhttps://github.com/syncthing/syncthing/tree/main/etc\fP>\&.
|
||||
If you’re using systemd, runit, or upstart, we ship \X'tty: link https://github.com/syncthing/syncthing/tree/main/etc'\fI\%example configurations\fP <\fBhttps://github.com/syncthing/syncthing/tree/main/etc\fP>\X'tty: link'\&.
|
||||
.sp
|
||||
If however you’re not using one of these tools, you have a couple of options.
|
||||
If your system has a tool called \fBstart\-stop\-daemon\fP installed (that’s the name
|
||||
@@ -650,7 +642,7 @@ the filesystem watcher on linux:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Failed to start filesystem watcher for folder yourLabel (yourID): failed to
|
||||
setup inotify handler. Please increase inotify limits, see \fI\%https://docs.syncthing.net/users/faq.html#inotify\-limits\fP
|
||||
setup inotify handler. Please increase inotify limits, see \X'tty: link https://docs.syncthing.net/users/faq.html#inotify-limits'\fI\%https://docs.syncthing.net/users/faq.html#inotify\-limits\fP\X'tty: link'
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -661,11 +653,9 @@ On many Linux distributions you can run the following to fix it:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
echo \(dqfs.inotify.max_user_watches=204800\(dq | sudo tee \-a /etc/sysctl.conf
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -674,11 +664,9 @@ separate file, i.e. you should run:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
echo \(dqfs.inotify.max_user_watches=204800\(dq | sudo tee \-a /etc/sysctl.d/90\-override.conf
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -686,17 +674,15 @@ This only takes effect after a reboot. To adjust the limit immediately, run:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
echo 204800 | sudo tee /proc/sys/fs/inotify/max_user_watches
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS How do I reset the GUI password?
|
||||
.sp
|
||||
If you’ve forgotten / lost the GUI password, you can reset it using the
|
||||
\fI\%\-\-gui\-password\fP (and possibly \fI\%\-\-gui\-user\fP) options to the
|
||||
\X'tty: link #cmdoption-gui-password'\fI\%\-\-gui\-password\fP\X'tty: link' (and possibly \X'tty: link #cmdoption-gui-user'\fI\%\-\-gui\-user\fP\X'tty: link') options to the
|
||||
\fBsyncthing generate\fP subcommand. This should be done while Syncthing is not
|
||||
running.
|
||||
.INDENT 0.0
|
||||
@@ -708,7 +694,7 @@ Stop Syncthing: \fBsyncthing cli operations shutdown\fP
|
||||
Restart Syncthing as usual.
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fIAlternatively, in step 2\fP, you can manually delete the \fI\%<user>\fP and \fI\%<password>\fP XML tags from the
|
||||
\fIAlternatively, in step 2\fP, you can manually delete the \X'tty: link #config-option-gui.user'\fI\%<user>\fP\X'tty: link' and \X'tty: link #config-option-gui.password'\fI\%<password>\fP\X'tty: link' XML tags from the
|
||||
\fB<gui>\fP block in file \fBconfig.xml\fP\&. The location of the file depends on the
|
||||
OS and is described in the \fI\%configuration documentation\fP\&.
|
||||
.sp
|
||||
@@ -716,8 +702,7 @@ For example, the two emphasized lines below would be removed from the file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
<gui enabled=\(dqtrue\(dq tls=\(dqfalse\(dq debugging=\(dqfalse\(dq>
|
||||
<address>127.0.0.1:8384</address>
|
||||
<user>syncguy</user>
|
||||
@@ -725,8 +710,7 @@ For example, the two emphasized lines below would be removed from the file.
|
||||
<apikey>9RCKohqCAyrj5RjpyZdR2wXmQ9PyQFeN</apikey>
|
||||
<theme>default</theme>
|
||||
</gui>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH AUTHOR
|
||||
|
||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING-GLOBALDISCO" "7" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING-GLOBALDISCO" "7" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing-globaldisco \- Global Discovery Protocol v3
|
||||
.SH ANNOUNCEMENTS
|
||||
@@ -39,13 +39,11 @@ listing connection addresses (if any):
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
{
|
||||
addresses: [\(dqtcp://192.0.2.45:22000\(dq, \(dqtcp://:22202\(dq, \(dqrelay://192.0.2.99:22028\(dq],
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
|
||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING-LOCALDISCO" "7" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING-LOCALDISCO" "7" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing-localdisco \- Local Discovery Protocol v4
|
||||
.SH MODE OF OPERATION
|
||||
@@ -55,15 +55,14 @@ previously unknown device is discovered or a device has restarted (see the
|
||||
.SH DEVICE ID
|
||||
.sp
|
||||
The device ID is the SHA\-256 (32 bytes) of the device X.509 certificate. See
|
||||
\fI\%Understanding Device IDs\fP in the Syncthing documentation.
|
||||
\X'tty: link #device-ids'\fI\%Understanding Device IDs\fP\X'tty: link' in the Syncthing documentation.
|
||||
.SH ANNOUNCEMENT PACKET
|
||||
.sp
|
||||
The Announcement packet has the following structure:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
@@ -73,8 +72,7 @@ The Announcement packet has the following structure:
|
||||
\e Announce Message \e
|
||||
/ /
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -90,15 +88,13 @@ following schema:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
message Announce {
|
||||
bytes id = 1;
|
||||
repeated string addresses = 2;
|
||||
int64 instance_id = 3;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
|
||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING-NETWORKING" "7" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING-NETWORKING" "7" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing-networking \- Firewall Setup
|
||||
.SH ROUTER SETUP
|
||||
@@ -40,11 +40,9 @@ message in the console saying:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
Created UPnP port mapping for external port XXXXX on UPnP device YYYYY.
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -57,7 +55,7 @@ Communication in Syncthing works both ways. Therefore if you set up port
|
||||
forwards for one device, other devices will be able to connect to it even when
|
||||
they are behind a NAT network or firewall.
|
||||
.sp
|
||||
In the absence of port forwarding, \fI\%Relaying\fP may work well enough to get
|
||||
In the absence of port forwarding, \X'tty: link #relaying'\fI\%Relaying\fP\X'tty: link' may work well enough to get
|
||||
devices connected and synced, but will perform poorly in comparison to a
|
||||
direct connection.
|
||||
.SS Local Discovery
|
||||
@@ -87,15 +85,13 @@ If you configured a custom port in the \fISync Protocol Listen Address\fP settin
|
||||
you have to adapt the firewall rules accordingly.
|
||||
.SS Uncomplicated Firewall (ufw)
|
||||
.sp
|
||||
If you’re using \fBufw\fP on Linux and have installed the \fI\%Syncthing package\fP <\fBhttps://apt.syncthing.net/\fP>, you can allow the necessary ports by running:
|
||||
If you’re using \fBufw\fP on Linux and have installed the \X'tty: link https://apt.syncthing.net/'\fI\%Syncthing package\fP <\fBhttps://apt.syncthing.net/\fP>\X'tty: link', you can allow the necessary ports by running:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
sudo ufw allow syncthing
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -103,11 +99,9 @@ If you also want to allow external access to the Syncthing web GUI, run:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
sudo ufw allow syncthing\-gui
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -117,29 +111,25 @@ You can then verify that the ports mentioned above are allowed:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
sudo ufw status verbose
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
In case you installed Syncthing manually you can follow the \fI\%instructions to manually add the syncthing preset\fP <\fBhttps://github.com/syncthing/syncthing/tree/main/etc/firewall-ufw\fP> to ufw.
|
||||
In case you installed Syncthing manually you can follow the \X'tty: link https://github.com/syncthing/syncthing/tree/main/etc/firewall-ufw'\fI\%instructions to manually add the syncthing preset\fP <\fBhttps://github.com/syncthing/syncthing/tree/main/etc/firewall-ufw\fP>\X'tty: link' to ufw.
|
||||
.SS Firewalld
|
||||
.sp
|
||||
If you are using \fI\%Firewalld\fP <\fBhttps://firewalld.org/\fP> it has included
|
||||
If you are using \X'tty: link https://firewalld.org/'\fI\%Firewalld\fP <\fBhttps://firewalld.org/\fP>\X'tty: link' it has included
|
||||
support for syncthing (since version 0.5.0, January 2018), and you can enable
|
||||
it with:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
sudo firewall\-cmd \-\-zone=public \-\-add\-service=syncthing \-\-permanent
|
||||
sudo firewall\-cmd \-\-reload
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -158,11 +148,9 @@ tunnel instead. You can start a tunnel with a command like the following:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
ssh \-L 9999:localhost:8384 machine
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -171,7 +159,7 @@ port 8384 on the target machine. This still works even if Syncthing is bound to
|
||||
listen on localhost only.
|
||||
.SH VIA A PROXY
|
||||
.sp
|
||||
Syncthing can use a SOCKS5 proxy for outbound connections. Please see \fI\%Using Proxies\fP\&.
|
||||
Syncthing can use a SOCKS5 proxy for outbound connections. Please see \X'tty: link #proxying'\fI\%Using Proxies\fP\X'tty: link'\&.
|
||||
.SH AUTHOR
|
||||
The Syncthing Authors
|
||||
.SH COPYRIGHT
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
'\" t
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.
|
||||
@@ -27,7 +28,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING-RELAY" "7" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING-RELAY" "7" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing-relay \- Relay Protocol v1
|
||||
.SH WHAT IS A RELAY?
|
||||
@@ -114,9 +115,8 @@ The connection is terminated immediately after that.
|
||||
Client A \- Permanent protocol submode
|
||||
Client B \- Temporary protocol submode
|
||||
.TS
|
||||
center;
|
||||
|l|l|l|l|.
|
||||
_
|
||||
box center;
|
||||
l|l|l|l.
|
||||
T{
|
||||
#
|
||||
T} T{
|
||||
@@ -222,7 +222,6 @@ T} T{
|
||||
<\-Pong
|
||||
T} T{
|
||||
T}
|
||||
_
|
||||
.TE
|
||||
.SH SESSION MODE
|
||||
.sp
|
||||
@@ -246,9 +245,8 @@ relayed between the two devices in the session directly.
|
||||
Client A \- Permanent protocol mode
|
||||
Client B \- Temporary protocol mode
|
||||
.TS
|
||||
center;
|
||||
|l|l|l|l|.
|
||||
_
|
||||
box center;
|
||||
l|l|l|l.
|
||||
T{
|
||||
#
|
||||
T} T{
|
||||
@@ -333,7 +331,6 @@ T} T{
|
||||
T} T{
|
||||
<\-Data
|
||||
T}
|
||||
_
|
||||
.TE
|
||||
.SH MESSAGES
|
||||
.sp
|
||||
@@ -351,8 +348,7 @@ us to identify what type of message it is.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
@@ -369,16 +365,14 @@ struct Header {
|
||||
int MessageType;
|
||||
int MessageLength;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Ping message (Type = 0)
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
@@ -386,16 +380,14 @@ struct Header {
|
||||
|
||||
struct Ping {
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Pong message (Type = 1)
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
@@ -403,16 +395,14 @@ struct Ping {
|
||||
|
||||
struct Pong {
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS JoinRelayRequest message (Type = 2)
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
@@ -420,16 +410,14 @@ struct Pong {
|
||||
|
||||
struct JoinRelayRequest {
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS JoinSessionRequest message (Type = 3)
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
@@ -444,8 +432,7 @@ struct JoinRelayRequest {
|
||||
struct JoinSessionRequest {
|
||||
opaque Key<32>;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
@@ -458,8 +445,7 @@ used to identify which session you are trying to connect to.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
@@ -477,8 +463,7 @@ struct Response {
|
||||
int Code;
|
||||
string Message<>;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
@@ -493,8 +478,7 @@ Message associated with the code.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
@@ -509,8 +493,7 @@ Message associated with the code.
|
||||
struct ConnectRequest {
|
||||
opaque ID<32>;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
@@ -522,8 +505,7 @@ Device ID to which the client would like to connect.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+\-+
|
||||
@@ -558,8 +540,7 @@ struct SessionInvitation {
|
||||
unsigned int Port;
|
||||
bool ServerSocket;
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
@@ -615,9 +596,8 @@ performing device ID validation, and full TLS encryption, and provides the same
|
||||
security properties as it would provide when connecting over the internet.
|
||||
.SH EXAMPLES OF STRONG CIPHER SUITES
|
||||
.TS
|
||||
center;
|
||||
|l|l|l|.
|
||||
_
|
||||
box center;
|
||||
l|l|l.
|
||||
T{
|
||||
ID
|
||||
T} T{
|
||||
@@ -689,7 +669,6 @@ ECDHE\-RSA\-AES128\-SHA256
|
||||
T} T{
|
||||
TLSv1.2 ECDH RSA AES(128) SHA256
|
||||
T}
|
||||
_
|
||||
.TE
|
||||
.SH AUTHOR
|
||||
The Syncthing Authors
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING-SECURITY" "7" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING-SECURITY" "7" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing-security \- Security Principles
|
||||
.sp
|
||||
@@ -46,7 +46,7 @@ Incoming requests for file data are verified to the extent that the requested
|
||||
file name must exist in the local index and the global model.
|
||||
.sp
|
||||
For information about ensuring you are running the code you think you are and
|
||||
for reporting security vulnerabilities, please see the official \fI\%security page\fP <\fBhttps://syncthing.net/security\fP>\&.
|
||||
for reporting security vulnerabilities, please see the official \X'tty: link https://syncthing.net/security'\fI\%security page\fP <\fBhttps://syncthing.net/security\fP>\X'tty: link'\&.
|
||||
.SH INFORMATION LEAKAGE
|
||||
.SS Global Discovery
|
||||
.sp
|
||||
@@ -59,7 +59,7 @@ servers containing the device ID of the requested device. The connection to
|
||||
the discovery server is encrypted using TLS and the discovery server
|
||||
certificate is verified, so the contents of the query should be considered
|
||||
private between the device and the discovery server. The discovery servers
|
||||
are currently hosted by \fI\%@calmh\fP <\fBhttps://github.com/calmh\fP>\&. Global discovery defaults to \fBon\fP\&.
|
||||
are currently hosted by \X'tty: link https://github.com/calmh'\fI\%@calmh\fP <\fBhttps://github.com/calmh\fP>\X'tty: link'\&. Global discovery defaults to \fBon\fP\&.
|
||||
.sp
|
||||
When turned off, devices with dynamic addresses not on the local network cannot
|
||||
be found and connected to.
|
||||
@@ -87,7 +87,7 @@ found and connected to.
|
||||
.sp
|
||||
When automatic upgrades are enabled, Syncthing checks for a new version at
|
||||
startup and then once every twelve hours. This is by an HTTPS request to the
|
||||
download site for releases, currently hosted by \fI\%@calmh\fP <\fBhttps://github.com/calmh\fP>\&.
|
||||
download site for releases, currently hosted by \X'tty: link https://github.com/calmh'\fI\%@calmh\fP <\fBhttps://github.com/calmh\fP>\X'tty: link'\&.
|
||||
Automatic upgrades default to \fBon\fP (unless Syncthing was compiled with
|
||||
upgrades disabled).
|
||||
.sp
|
||||
@@ -105,7 +105,7 @@ information about the user or device.
|
||||
.sp
|
||||
When usage reporting is enabled, Syncthing reports usage data at startup and
|
||||
then every 24 hours. The report is sent as an HTTPS POST to the usage reporting
|
||||
server, currently hosted by \fI\%@calmh\fP <\fBhttps://github.com/calmh\fP>\&. The contents of the usage report can
|
||||
server, currently hosted by \X'tty: link https://github.com/calmh'\fI\%@calmh\fP <\fBhttps://github.com/calmh\fP>\X'tty: link'\&. The contents of the usage report can
|
||||
be seen behind the “Preview” link in settings. Usage reporting defaults to
|
||||
\fBoff\fP but the GUI will ask once about enabling it, shortly after the first
|
||||
install.
|
||||
@@ -147,7 +147,7 @@ web GUI defaults to being reachable from the \fBlocal host only\fP\&.
|
||||
.sp
|
||||
Parties doing surveillance on your network (whether that be corporate IT, the
|
||||
NSA or someone else) will be able to see that you use Syncthing, and your device
|
||||
IDs \fI\%are OK to share anyway\fP <\fBhttps://docs.syncthing.net/users/faq.html#should-i-keep-my-device-ids-secret\fP>,
|
||||
IDs \X'tty: link https://docs.syncthing.net/users/faq.html#should-i-keep-my-device-ids-secret'\fI\%are OK to share anyway\fP <\fBhttps://docs.syncthing.net/users/faq.html#should-i-keep-my-device-ids-secret\fP>\X'tty: link',
|
||||
but the actual transmitted data is protected as well as we can. Knowing your
|
||||
device ID can expose your IP address, using global discovery.
|
||||
.SH PROTECTING YOUR SYNCTHING KEYS AND IDENTITY
|
||||
|
||||
@@ -27,18 +27,16 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING-STIGNORE" "5" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING-STIGNORE" "5" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing-stignore \- Prevent files from being synchronized to other nodes
|
||||
.SH SYNOPSIS
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
\&.stignore
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH DESCRIPTION
|
||||
@@ -126,21 +124,19 @@ more general patterns that follow.
|
||||
.INDENT 3.5
|
||||
Negated patterns that can match items below the folder root will cause
|
||||
Syncthing to traverse otherwise ignored directories. If the
|
||||
\fI\%watcher\fP is enabled, those directories will also be
|
||||
\X'tty: link #scanning'\fI\%watcher\fP\X'tty: link' is enabled, those directories will also be
|
||||
watched. Directories ignored before the first negated pattern can
|
||||
however be safely skipped, since the first matching pattern wins. For
|
||||
example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
/foo
|
||||
/bar
|
||||
!baz
|
||||
*
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -152,12 +148,10 @@ not cause this behaviour:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
!/baz
|
||||
*
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -194,8 +188,7 @@ Given a directory layout starting at the synced folder’s root:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
\&.DS_Store
|
||||
\&.stignore
|
||||
foo
|
||||
@@ -209,8 +202,7 @@ bar2/
|
||||
frobble
|
||||
My Pictures/
|
||||
Img15.PNG
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -218,8 +210,7 @@ and an \fB\&.stignore\fP file with the contents:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
(?d).DS_Store
|
||||
!frobble
|
||||
!quuz
|
||||
@@ -227,8 +218,7 @@ foo
|
||||
*2
|
||||
qu*
|
||||
(?i)my pictures
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -237,8 +227,7 @@ all files and directories called “foo”, ending in a “2” or starting with
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
\&.DS_Store # ignored, will be deleted if gets in the way of parent directory removal
|
||||
foo # ignored, matches \(dqfoo\(dq
|
||||
foofoo # synced, does not match \(dqfoo\(dq but would match \(dqfoo*\(dq or \(dq*foo\(dq
|
||||
@@ -251,8 +240,7 @@ bar2/ # synced, despite matching \(dq*2\(dq due to child frobble
|
||||
frobble # synced, due to \(dq!frobble\(dq
|
||||
My Pictures/ # ignored, matched case insensitive \(dq(?i)my pictures\(dq pattern
|
||||
Img15.PNG # ignored, due to parent being ignored
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -266,7 +254,7 @@ content, make sure it does not have a \fB/\fP at the end of the pattern.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
New in version 1.19.0: Default patterns can be configured which will take effect when automatically
|
||||
Added in version 1.19.0: Default patterns can be configured which will take effect when automatically
|
||||
accepting a folder from a remote device. The GUI suggests same the patterns
|
||||
when adding a folder manually. In either case, the \fB\&.stignore\fP file is
|
||||
created with these defaults if none is present yet.
|
||||
|
||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING-VERSIONING" "7" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING-VERSIONING" "7" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing-versioning \- Keep automatic backups of deleted files by other nodes
|
||||
.sp
|
||||
@@ -113,7 +113,7 @@ will be deleted unless when the interval they are entering is empty. By keeping
|
||||
the oldest versions this versioning scheme preserves the file if it is
|
||||
overwritten.
|
||||
.sp
|
||||
For more info, check the \fI\%unit test file\fP <\fBhttps://github.com/syncthing/syncthing/blob/main/lib/versioner/staggered_test.go#L32\fP>
|
||||
For more info, check the \X'tty: link https://github.com/syncthing/syncthing/blob/main/lib/versioner/staggered_test.go#L32'\fI\%unit test file\fP <\fBhttps://github.com/syncthing/syncthing/blob/main/lib/versioner/staggered_test.go#L32\fP>\X'tty: link'
|
||||
that shows which versions are deleted for a specific run.
|
||||
.SH EXTERNAL FILE VERSIONING
|
||||
.sp
|
||||
@@ -147,8 +147,7 @@ the following script and store it as \fB/Users/jb/bin/onlylatest.sh\fP (i.e. the
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
#!/bin/sh
|
||||
set \-eu
|
||||
|
||||
@@ -164,8 +163,7 @@ outpath=$(dirname \(dq$versionspath/$filepath\(dq)
|
||||
mkdir \-p \(dq$outpath\(dq
|
||||
# Then move the file there
|
||||
mv \-f \(dq$folderpath/$filepath\(dq \(dq$versionspath/$filepath\(dq
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -178,11 +176,9 @@ script will be called as if I ran this from the command line:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
$ /Users/jb/bin/onlylatest.sh /Users/jb/Sync docs/letter.txt
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -198,8 +194,7 @@ behavior as mentioned above. I created the following script and saved it as
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
@echo off
|
||||
|
||||
rem Enable UTF\-8 encoding to deal with multilingual folder and file names
|
||||
@@ -221,8 +216,7 @@ if not exist \(dq%output_path%\(dq md \(dq%output_path%\(dq || exit /b
|
||||
|
||||
rem Finally move the file, overwrite existing file if any
|
||||
move /y \(dq%folder_path%\e%file_path%\(dq \(dq%versions_path%\e%file_path%\(dq
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -237,8 +231,7 @@ location, e.g. \fBC:\eUsers\eUser\eScripts\eSendToRecycleBin.ps1\fP\&.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
# PowerShell has no native method to recycle files, so we use Visual
|
||||
# Basic to perform the operation. If succeeded, we also include the
|
||||
# recycled file in the Syncthing\(aqs DEBUG output.
|
||||
@@ -247,8 +240,7 @@ Add\-Type \-AssemblyName Microsoft.VisualBasic
|
||||
if ($?) {
|
||||
Write\-Output (\(dqRecycled \(dq + $args + \(dq.\(dq)
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -258,8 +250,7 @@ more consistent with how the Explorer works.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
# PowerShell has no native method to recycle files, so we use Visual
|
||||
# Basic to perform the operation.
|
||||
Add\-Type \-AssemblyName Microsoft.VisualBasic
|
||||
@@ -279,8 +270,7 @@ if (Test\-Path \-LiteralPath ((Split\-Path \-Path $args) + \(dq\e~syncthing~\(dq
|
||||
Write\-Output (\(dqRecycled \(dq + $args + \(dq.\(dq)
|
||||
}
|
||||
}
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -295,13 +285,12 @@ files permanently.
|
||||
.SH CONFIGURATION PARAMETER REFERENCE
|
||||
.sp
|
||||
The versioning settings are grouped into their own section of each folder in the
|
||||
\fI\%configuration file\fP\&. The following shows an
|
||||
\X'tty: link #config-option-folder.versioning'\fI\%configuration file\fP\X'tty: link'\&. The following shows an
|
||||
example of such a section in the XML:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
<folder id=\(dq...\(dq>
|
||||
<versioning type=\(dqsimple\(dq>
|
||||
<cleanupIntervalS>3600</cleanupIntervalS>
|
||||
@@ -311,8 +300,7 @@ example of such a section in the XML:
|
||||
<param key=\(dqkeep\(dq val=\(dq5\(dq></param>
|
||||
</versioning>
|
||||
</folder>
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
@@ -338,7 +326,7 @@ in the \fI\%params\fP element.
|
||||
.B versioning.fsType
|
||||
The internal file system implementation used to access this versions folder.
|
||||
Only applies if \fI\%fsPath\fP is also set non\-empty,
|
||||
otherwise the \fI\%filesystemType\fP from the folder element is used
|
||||
otherwise the \X'tty: link #config-option-folder.filesystemtype'\fI\%filesystemType\fP\X'tty: link' from the folder element is used
|
||||
instead. Refer to that option description for possible values. Ignored for
|
||||
the \fBexternal\fP versioning strategy.
|
||||
.sp
|
||||
|
||||
@@ -27,15 +27,14 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "SYNCTHING" "1" "Feb 25, 2024" "v1.27.3" "Syncthing"
|
||||
.TH "SYNCTHING" "1" "Jun 29, 2024" "v1.27.7" "Syncthing"
|
||||
.SH NAME
|
||||
syncthing \- Syncthing
|
||||
.SH SYNOPSIS
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
syncthing [serve]
|
||||
[\-\-audit] [\-\-auditfile=<file|\-|\-\->] [\-\-browser\-only] [\-\-device\-id]
|
||||
[\-\-generate=<dir>] [\-\-gui\-address=<address>] [\-\-gui\-apikey=<key>]
|
||||
@@ -64,8 +63,7 @@ syncthing cli
|
||||
[\-\-gui\-address=<address>] [\-\-gui\-apikey=<key>]
|
||||
[\-\-help]
|
||||
<command> [command options...] [arguments...]
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH DESCRIPTION
|
||||
@@ -369,7 +367,7 @@ it is validated and updated to the latest configuration schema, including adding
|
||||
default values for any new options.
|
||||
.sp
|
||||
The \fBdecrypt\fP subcommand is used in conjunction with untrusted (encrypted)
|
||||
devices, see the relevant section on \fI\%decryption\fP for
|
||||
devices, see the relevant section on \X'tty: link #untrusted-decrypt'\fI\%decryption\fP\X'tty: link' for
|
||||
details. It does not depend on Syncthing to be running, but works on offline
|
||||
data.
|
||||
.sp
|
||||
@@ -423,11 +421,9 @@ example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
.EX
|
||||
$ export all_proxy=socks://192.0.2.42:8081
|
||||
.ft P
|
||||
.fi
|
||||
.EE
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH DEVELOPMENT SETTINGS
|
||||
@@ -582,7 +578,7 @@ Disable automatic upgrades. Equivalent to the \fI\%\-\-no\-upgrade\fP flag.
|
||||
.B STPROFILER
|
||||
Set to a listen address such as “127.0.0.1:9090” to start the profiler with
|
||||
HTTP access, which then can be reached at
|
||||
\fI\%http://localhost:9090/debug/pprof\fP\&. See \fBgo tool pprof\fP for more
|
||||
\X'tty: link http://localhost:9090/debug/pprof'\fI\%http://localhost:9090/debug/pprof\fP\X'tty: link'\&. See \fBgo tool pprof\fP for more
|
||||
information.
|
||||
.TP
|
||||
.B STPERFSTATS
|
||||
|
||||
@@ -29,6 +29,7 @@ message FolderConfiguration {
|
||||
int32 rescan_interval_s = 7 [(ext.xml) = "rescanIntervalS,attr", (ext.default) = "3600"];
|
||||
bool fs_watcher_enabled = 8 [(ext.goname) = "FSWatcherEnabled", (ext.xml) = "fsWatcherEnabled,attr", (ext.default) = "true"];
|
||||
double fs_watcher_delay_s = 9 [(ext.goname) = "FSWatcherDelayS", (ext.xml) = "fsWatcherDelayS,attr", (ext.default) = "10"];
|
||||
double fs_watcher_timeout_s = 40 [(ext.goname) = "FSWatcherTimeoutS", (ext.xml) = "fsWatcherTimeoutS,attr"];
|
||||
bool ignore_perms = 10 [(ext.xml) = "ignorePerms,attr"];
|
||||
bool auto_normalize = 11 [(ext.xml) = "autoNormalize,attr", (ext.default) = "true"];
|
||||
Size min_disk_free = 12 [(ext.default) = "1 %"];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user