Compare commits

..
Author SHA1 Message Date
Jakob Borg 24e691925c Add Debian build stuff 2015-05-11 22:09:38 +02:00
200 changed files with 3803 additions and 19592 deletions
-1
View File
@@ -13,4 +13,3 @@ coverage.xml
syncthing.md5 syncthing.md5
syncthing.exe.md5 syncthing.exe.md5
RELEASE RELEASE
deb
+2 -8
View File
@@ -3,10 +3,8 @@
Aaron Bieber <qbit@deftly.net> Aaron Bieber <qbit@deftly.net>
Alexander Graf <register-github@alex-graf.de> Alexander Graf <register-github@alex-graf.de>
Andrew Dunham <andrew@du.nham.ca> Andrew Dunham <andrew@du.nham.ca>
Antony Male <antony.male@gmail.com>
Arthur Axel fREW Schmidt <frew@afoolishmanifesto.com> <frioux@gmail.com>
Audrius Butkevicius <audrius.butkevicius@gmail.com> Audrius Butkevicius <audrius.butkevicius@gmail.com>
Bart De Vries <devriesb@gmail.com> Arthur Axel fREW Schmidt <frew@afoolishmanifesto.com> <frioux@gmail.com>
Ben Curthoys <ben@bencurthoys.com> Ben Curthoys <ben@bencurthoys.com>
Ben Schulz <ueomkail@gmail.com> <uok@users.noreply.github.com> Ben Schulz <ueomkail@gmail.com> <uok@users.noreply.github.com>
Ben Sidhom <bsidhom@gmail.com> Ben Sidhom <bsidhom@gmail.com>
@@ -15,21 +13,17 @@ Brendan Long <self@brendanlong.com>
Caleb Callaway <enlightened.despot@gmail.com> Caleb Callaway <enlightened.despot@gmail.com>
Carsten Hagemann <moter8@gmail.com> Carsten Hagemann <moter8@gmail.com>
Cathryne Linenweaver <cathryne.linenweaver@gmail.com> <Cathryne@users.noreply.github.com> Cathryne Linenweaver <cathryne.linenweaver@gmail.com> <Cathryne@users.noreply.github.com>
Chris Howie <me@chrishowie.com>
Chris Joel <chris@scriptolo.gy> Chris Joel <chris@scriptolo.gy>
Colin Kennedy <moshen.colin@gmail.com> Colin Kennedy <moshen.colin@gmail.com>
Daniel Bergmann <dan.arne.bergmann@gmail.com> <brgmnn@users.noreply.github.com>
Daniel Martí <mvdan@mvdan.cc> Daniel Martí <mvdan@mvdan.cc>
Dennis Wilson <dw@risu.io> Dennis Wilson <dw@risu.io>
Dominik Heidler <dominik@heidler.eu> Dominik Heidler <dominik@heidler.eu>
Elias Jarlebring <jarlebring@gmail.com> Elias Jarlebring <jarlebring@gmail.com>
Emil Hessman <emil@hessman.se> Emil Hessman <emil@hessman.se>
Erik Meitner <e.meitner@willystreet.coop>
Federico Castagnini <federico.castagnini@gmail.com> Federico Castagnini <federico.castagnini@gmail.com>
Felix Ableitner <me@nutomic.com> Felix Ableitner <me@nutomic.com>
Felix Unterpaintner <bigbear2nd@gmail.com> Felix Unterpaintner <bigbear2nd@gmail.com>
Francois-Xavier Gsell <fxgsell@gmail.com> Francois-Xavier Gsell <fxgsell@gmail.com>
Frank Isemann <frank@isemann.name>
Gilli Sigurdsson <gilli@vx.is> Gilli Sigurdsson <gilli@vx.is>
Jakob Borg <jakob@nym.se> Jakob Borg <jakob@nym.se>
James Patterson <jamespatterson@operamail.com> <jpjp@users.noreply.github.com> James Patterson <jamespatterson@operamail.com> <jpjp@users.noreply.github.com>
@@ -41,9 +35,9 @@ Karol Różycki <rozycki.karol@gmail.com>
Ken'ichi Kamada <kamada@nanohz.org> Ken'ichi Kamada <kamada@nanohz.org>
Lode Hoste <zillode@zillode.be> Lode Hoste <zillode@zillode.be>
Lord Landon Agahnim <lordlandon@gmail.com> Lord Landon Agahnim <lordlandon@gmail.com>
Marcin Dziadus <dziadus.marcin@gmail.com>
Marc Laporte <marc@marclaporte.com> <marc@laporte.name> Marc Laporte <marc@marclaporte.com> <marc@laporte.name>
Marc Pujol <kilburn@la3.org> Marc Pujol <kilburn@la3.org>
Marcin Dziadus <dziadus.marcin@gmail.com>
Michael Jephcote <rewt0r@gmx.com> <Rewt0r@users.noreply.github.com> Michael Jephcote <rewt0r@gmx.com> <Rewt0r@users.noreply.github.com>
Michael Tilli <pyfisch@gmail.com> Michael Tilli <pyfisch@gmail.com>
Pascal Jungblut <github@pascalj.com> <mail@pascal-jungblut.com> Pascal Jungblut <github@pascalj.com> <mail@pascal-jungblut.com>
+95 -7
View File
@@ -32,15 +32,64 @@ latest info on Transifex.
## Contributing Code ## Contributing Code
Every contribution is welcome. If you want to contribute but are unsure Every contribution is welcome. If you want to contribute but are unsure
where to start, any open issues are fair game! See the [Contribution where to start, any open issues are fair game! Be prepared for a
Guidelines](http://docs.syncthing.net/dev/contributing.html) for the full [certain amount of review](https://github.com/syncthing/syncthing/wiki/FAQ#why-are-you-being-so-hard-on-my-pull-request);
story on committing code. it's all in the name of quality. :) Following the points below will make this
a smoother process.
## Contributing Documentation Individuals making significant and valuable contributions are given
commit-access to the project. If you make a significant contribution and
are not considered for commit-access, please contact any of the
Syncthing core team members.
Updates to the [documentation site](http://docs.syncthing.net/) can be All nontrivial contributions should go through the pull request
made as pull requests on the [documentation mechanism for internal review. Determining what is "nontrivial" is left
repository](https://github.com/syncthing/docs). at the discretion of the contributor.
### Authorship
All code authors are listed in the AUTHORS file. Commits must be made
with the same name and email as listed in the AUTHORS file. To
accomplish this, ensure that your git configuration is set correctly
prior to making your first commit;
$ git config --global user.name "Jane Doe"
$ git config --global user.email janedoe@example.com
You must be reachable on the given email address. If you do not wish to
use your real name for whatever reason, using a nickname or pseudonym is
perfectly acceptable.
### Core Team
The Syncthing core team currently consists of the following members;
- Jakob Borg (@calmh)
- Audrius Butkevicius (@AudriusButkevicius)
## Coding Style
- Follow the conventions laid out in [Effective Go](https://golang.org/doc/effective_go.html)
as much as makes sense.
- All text files use Unix line endings.
- Each commit should be `go fmt` clean.
- The commit message subject should be a single short sentence
describing the change, starting with a capital letter.
- Commits that resolve an existing issue must include the issue number
as `(fixes #123)` at the end of the commit message subject.
- Imports are grouped per `goimports` standard; that is, standard
library first, then third party libraries after a blank line.
- A contribution solving a single issue or introducing a single new
feature should probably be a single commit based on the current
`master` branch. You may be asked to "rebase" or "squash" your pull
request to make sure this is the case, especially if there have been
amendments during review.
## Licensing ## Licensing
@@ -50,3 +99,42 @@ strings which are licensed under the Creative Commons Attribution 4.0
International License. You retain the copyright to code you have International License. You retain the copyright to code you have
written. written.
When accepting your first contribution, the maintainer of the project
will ensure that you are added to the AUTHORS file. You are welcome to
add yourself as a separate commit in your first pull request.
## Building
[See the documentation](https://github.com/syncthing/syncthing/wiki/Building)
on how to get started with a build environment.
## Branches
- `master` is the main branch containing good code that will end up in
the next release. You should base your work on it. It won't ever be
rebased or force-pushed to.
- `vx.y` branches exist to make patch releases on otherwise obsolete
minor releases. Should only contain fixes cherry picked from master.
Don't base any work on them.
- Other branches are probably topic branches and may be subject to
rebasing. Don't base any work on them unless you specifically know
otherwise.
## Tags
All releases are tagged semver style as `vx.y.z`. Release tags are
signed by GPG key BCE524C7.
## Tests
Yes please!
## Documentation
[Over here!](https://github.com/syncthing/syncthing/wiki)
## License
MPLv2
+14 -14
View File
@@ -7,11 +7,11 @@
"Deps": [ "Deps": [
{ {
"ImportPath": "github.com/bkaradzic/go-lz4", "ImportPath": "github.com/bkaradzic/go-lz4",
"Rev": "4f7c2045dbd17b802370e2e6022200468abf02ba" "Rev": "93a831dcee242be64a9cc9803dda84af25932de7"
}, },
{ {
"ImportPath": "github.com/calmh/logger", "ImportPath": "github.com/calmh/logger",
"Rev": "c96f6a1a8c7b6bf2f4860c667867d90174799eb2" "Rev": "4d4e2801954c5581e4c2a80a3d3beb3b3645fd04"
}, },
{ {
"ImportPath": "github.com/calmh/luhn", "ImportPath": "github.com/calmh/luhn",
@@ -21,25 +21,25 @@
"ImportPath": "github.com/calmh/xdr", "ImportPath": "github.com/calmh/xdr",
"Rev": "5f7208e86762911861c94f1849eddbfc0a60cbf0" "Rev": "5f7208e86762911861c94f1849eddbfc0a60cbf0"
}, },
{
"ImportPath": "github.com/google/go-snappy/snappy",
"Rev": "eaa750b9bf4dcb7cb20454be850613b66cda3273"
},
{ {
"ImportPath": "github.com/juju/ratelimit", "ImportPath": "github.com/juju/ratelimit",
"Rev": "faa59ce93750e747b2997635e8b7daf30024b1ac" "Rev": "c5abe513796336ee2869745bff0638508450e9c5"
}, },
{ {
"ImportPath": "github.com/kardianos/osext", "ImportPath": "github.com/kardianos/osext",
"Rev": "6e7f843663477789fac7c02def0d0909e969b4e5" "Rev": "efacde03154693404c65e7aa7d461ac9014acd0c"
}, },
{ {
"ImportPath": "github.com/syncthing/protocol", "ImportPath": "github.com/syncthing/protocol",
"Rev": "95e15c95f21b81b09772f07de5c142a3e68f78db" "Rev": "e7db2648034fb71b051902a02bc25d4468ed492e"
}, },
{ {
"ImportPath": "github.com/syndtr/goleveldb/leveldb", "ImportPath": "github.com/syndtr/goleveldb/leveldb",
"Rev": "a06509502ca32565bdf74afc1e573050023f261c" "Rev": "87e4e645d80ae9c537e8f2dee52b28036a5dd75e"
},
{
"ImportPath": "github.com/syndtr/gosnappy/snappy",
"Rev": "156a073208e131d7d2e212cb749feae7c339e846"
}, },
{ {
"ImportPath": "github.com/thejerf/suture", "ImportPath": "github.com/thejerf/suture",
@@ -59,19 +59,19 @@
}, },
{ {
"ImportPath": "golang.org/x/crypto/bcrypt", "ImportPath": "golang.org/x/crypto/bcrypt",
"Rev": "1e856cbfdf9bc25eefca75f83f25d55e35ae72e0" "Rev": "c57d4a71915a248dbad846d60825145062b4c18e"
}, },
{ {
"ImportPath": "golang.org/x/crypto/blowfish", "ImportPath": "golang.org/x/crypto/blowfish",
"Rev": "1e856cbfdf9bc25eefca75f83f25d55e35ae72e0" "Rev": "c57d4a71915a248dbad846d60825145062b4c18e"
}, },
{ {
"ImportPath": "golang.org/x/text/transform", "ImportPath": "golang.org/x/text/transform",
"Rev": "df923bbb63f8ea3a26bb743e2a497abd0ab585f7" "Rev": "2076e9cab4147459c82bc81169e46c139d358547"
}, },
{ {
"ImportPath": "golang.org/x/text/unicode/norm", "ImportPath": "golang.org/x/text/unicode/norm",
"Rev": "df923bbb63f8ea3a26bb743e2a497abd0ab585f7" "Rev": "2076e9cab4147459c82bc81169e46c139d358547"
} }
] ]
} }
-23
View File
@@ -1,23 +0,0 @@
// +build gofuzz
package lz4
import "encoding/binary"
func Fuzz(data []byte) int {
if len(data) < 4 {
return 0
}
ln := binary.LittleEndian.Uint32(data)
if ln > (1 << 21) {
return 0
}
if _, err := Decode(nil, data); err != nil {
return 0
}
return 1
}
+1 -6
View File
@@ -141,7 +141,7 @@ func Decode(dst, src []byte) ([]byte, error) {
length += ln length += ln
} }
if int(d.spos+length) > len(d.src) || int(d.dpos+length) > len(d.dst) { if int(d.spos+length) > len(d.src) {
return nil, ErrCorrupt return nil, ErrCorrupt
} }
@@ -179,12 +179,7 @@ func Decode(dst, src []byte) ([]byte, error) {
} }
literal := d.dpos - d.ref literal := d.dpos - d.ref
if literal < 4 { if literal < 4 {
if int(d.dpos+4) > len(d.dst) {
return nil, ErrCorrupt
}
d.cp(4, decr[literal]) d.cp(4, decr[literal])
} else { } else {
length += 4 length += 4
+2 -4
View File
@@ -25,10 +25,8 @@
package lz4 package lz4
import ( import "encoding/binary"
"encoding/binary" import "errors"
"errors"
)
const ( const (
minMatch = 4 minMatch = 4
-8
View File
@@ -6,7 +6,6 @@ package logger
import ( import (
"fmt" "fmt"
"io/ioutil"
"log" "log"
"os" "os"
"strings" "strings"
@@ -38,13 +37,6 @@ type Logger struct {
var DefaultLogger = New() var DefaultLogger = New()
func New() *Logger { func New() *Logger {
if os.Getenv("LOGGER_DISCARD") != "" {
// Hack to completely disable logging, for example when running benchmarks.
return &Logger{
logger: log.New(ioutil.Discard, "", 0),
}
}
return &Logger{ return &Logger{
logger: log.New(os.Stdout, "", log.Ltime), logger: log.New(os.Stdout, "", log.Ltime),
} }
+2 -5
View File
@@ -1,8 +1,5 @@
All files in this repository are licensed as follows. If you contribute This package contains an efficient token-bucket-based rate limiter.
to this repository, it is assumed that you license your contribution Copyright (C) 2015 Canonical Ltd.
under the same license unless you state otherwise.
All files Copyright (C) 2015 Canonical Ltd. unless otherwise specified in the file.
This software is licensed under the LGPLv3, included below. This software is licensed under the LGPLv3, included below.
+8 -2
View File
@@ -7,7 +7,6 @@
package ratelimit package ratelimit
import ( import (
"math"
"strconv" "strconv"
"sync" "sync"
"time" "time"
@@ -56,7 +55,7 @@ func NewBucketWithRate(rate float64, capacity int64) *Bucket {
continue continue
} }
tb := NewBucketWithQuantum(fillInterval, capacity, quantum) tb := NewBucketWithQuantum(fillInterval, capacity, quantum)
if diff := math.Abs(tb.Rate() - rate); diff/rate <= rateMargin { if diff := abs(tb.Rate() - rate); diff/rate <= rateMargin {
return tb return tb
} }
} }
@@ -218,3 +217,10 @@ func (tb *Bucket) adjust(now time.Time) (currentTick int64) {
tb.availTick = currentTick tb.availTick = currentTick
return return
} }
func abs(f float64) float64 {
if f < 0 {
return -f
}
return f
}
+1 -3
View File
@@ -4,9 +4,7 @@
There is sometimes utility in finding the current executable file There is sometimes utility in finding the current executable file
that is running. This can be used for upgrading the current executable that is running. This can be used for upgrading the current executable
or finding resources located relative to the executable file. Both or finding resources located relative to the executable file.
working directory and the os.Args[0] value are arbitrary and cannot
be relied on; os.Args[0] can be "faked".
Multi-platform and supports: Multi-platform and supports:
* Linux * Linux
+3 -3
View File
@@ -16,12 +16,12 @@ func Executable() (string, error) {
} }
// Returns same path as Executable, returns just the folder // Returns same path as Executable, returns just the folder
// path. Excludes the executable name and any trailing slash. // path. Excludes the executable name.
func ExecutableFolder() (string, error) { func ExecutableFolder() (string, error) {
p, err := Executable() p, err := Executable()
if err != nil { if err != nil {
return "", err return "", err
} }
folder, _ := filepath.Split(p)
return filepath.Dir(p), nil return folder, nil
} }
+2 -4
View File
@@ -17,14 +17,12 @@ import (
func executable() (string, error) { func executable() (string, error) {
switch runtime.GOOS { switch runtime.GOOS {
case "linux": case "linux":
const deletedTag = " (deleted)" const deletedSuffix = " (deleted)"
execpath, err := os.Readlink("/proc/self/exe") execpath, err := os.Readlink("/proc/self/exe")
if err != nil { if err != nil {
return execpath, err return execpath, err
} }
execpath = strings.TrimSuffix(execpath, deletedTag) return strings.TrimSuffix(execpath, deletedSuffix), nil
execpath = strings.TrimPrefix(execpath, deletedTag)
return execpath, nil
case "netbsd": case "netbsd":
return os.Readlink("/proc/curproc/exe") return os.Readlink("/proc/curproc/exe")
case "openbsd", "dragonfly": case "openbsd", "dragonfly":
-23
View File
@@ -24,29 +24,6 @@ const (
executableEnvValueDelete = "delete" executableEnvValueDelete = "delete"
) )
func TestPrintExecutable(t *testing.T) {
ef, err := Executable()
if err != nil {
t.Fatalf("Executable failed: %v", err)
}
t.Log("Executable:", ef)
}
func TestPrintExecutableFolder(t *testing.T) {
ef, err := ExecutableFolder()
if err != nil {
t.Fatalf("ExecutableFolder failed: %v", err)
}
t.Log("Executable Folder:", ef)
}
func TestExecutableFolder(t *testing.T) {
ef, err := ExecutableFolder()
if err != nil {
t.Fatalf("ExecutableFolder failed: %v", err)
}
if ef[len(ef)-1] == filepath.Separator {
t.Fatal("ExecutableFolder ends with a trailing slash.")
}
}
func TestExecutableMatch(t *testing.T) { func TestExecutableMatch(t *testing.T) {
ep, err := Executable() ep, err := Executable()
if err != nil { if err != nil {
+27 -32
View File
@@ -31,7 +31,8 @@ const (
const ( const (
stateInitial = iota stateInitial = iota
stateReady stateCCRcvd
stateIdxRcvd
) )
// FileInfo flags // FileInfo flags
@@ -102,6 +103,7 @@ type rawConnection struct {
id DeviceID id DeviceID
name string name string
receiver Model receiver Model
state int
cr *countingReader cr *countingReader
cw *countingWriter cw *countingWriter
@@ -140,9 +142,9 @@ type isEofer interface {
IsEOF() bool IsEOF() bool
} }
var ( const (
PingTimeout = 30 * time.Second pingTimeout = 30 * time.Second
PingIdleTime = 60 * time.Second pingIdleTime = 60 * time.Second
) )
func NewConnection(deviceID DeviceID, reader io.Reader, writer io.Writer, receiver Model, name string, compress Compression) Connection { func NewConnection(deviceID DeviceID, reader io.Reader, writer io.Writer, receiver Model, name string, compress Compression) Connection {
@@ -153,6 +155,7 @@ func NewConnection(deviceID DeviceID, reader io.Reader, writer io.Writer, receiv
id: deviceID, id: deviceID,
name: name, name: name,
receiver: nativeModel{receiver}, receiver: nativeModel{receiver},
state: stateInitial,
cr: cr, cr: cr,
cw: cw, cw: cw,
outbox: make(chan hdrMsg), outbox: make(chan hdrMsg),
@@ -282,7 +285,6 @@ func (c *rawConnection) readerLoop() (err error) {
c.close(err) c.close(err)
}() }()
state := stateInitial
for { for {
select { select {
case <-c.closed: case <-c.closed:
@@ -296,55 +298,48 @@ func (c *rawConnection) readerLoop() (err error) {
} }
switch msg := msg.(type) { switch msg := msg.(type) {
case ClusterConfigMessage:
if state != stateInitial {
return fmt.Errorf("protocol error: cluster config message in state %d", state)
}
go c.receiver.ClusterConfig(c.id, msg)
state = stateReady
case IndexMessage: case IndexMessage:
switch hdr.msgType { switch hdr.msgType {
case messageTypeIndex: case messageTypeIndex:
if state != stateReady { if c.state < stateCCRcvd {
return fmt.Errorf("protocol error: index message in state %d", state) return fmt.Errorf("protocol error: index message in state %d", c.state)
} }
c.handleIndex(msg) c.handleIndex(msg)
state = stateReady c.state = stateIdxRcvd
case messageTypeIndexUpdate: case messageTypeIndexUpdate:
if state != stateReady { if c.state < stateIdxRcvd {
return fmt.Errorf("protocol error: index update message in state %d", state) return fmt.Errorf("protocol error: index update message in state %d", c.state)
} }
c.handleIndexUpdate(msg) c.handleIndexUpdate(msg)
state = stateReady
} }
case RequestMessage: case RequestMessage:
if state != stateReady { if c.state < stateIdxRcvd {
return fmt.Errorf("protocol error: request message in state %d", state) return fmt.Errorf("protocol error: request message in state %d", c.state)
} }
// Requests are handled asynchronously // Requests are handled asynchronously
go c.handleRequest(hdr.msgID, msg) go c.handleRequest(hdr.msgID, msg)
case ResponseMessage: case ResponseMessage:
if state != stateReady { if c.state < stateIdxRcvd {
return fmt.Errorf("protocol error: response message in state %d", state) return fmt.Errorf("protocol error: response message in state %d", c.state)
} }
c.handleResponse(hdr.msgID, msg) c.handleResponse(hdr.msgID, msg)
case pingMessage: case pingMessage:
if state != stateReady {
return fmt.Errorf("protocol error: ping message in state %d", state)
}
c.send(hdr.msgID, messageTypePong, pongMessage{}) c.send(hdr.msgID, messageTypePong, pongMessage{})
case pongMessage: case pongMessage:
if state != stateReady {
return fmt.Errorf("protocol error: pong message in state %d", state)
}
c.handlePong(hdr.msgID) c.handlePong(hdr.msgID)
case ClusterConfigMessage:
if c.state != stateInitial {
return fmt.Errorf("protocol error: cluster config message in state %d", c.state)
}
go c.receiver.ClusterConfig(c.id, msg)
c.state = stateCCRcvd
case CloseMessage: case CloseMessage:
return errors.New(msg.Reason) return errors.New(msg.Reason)
@@ -684,17 +679,17 @@ func (c *rawConnection) idGenerator() {
func (c *rawConnection) pingerLoop() { func (c *rawConnection) pingerLoop() {
var rc = make(chan bool, 1) var rc = make(chan bool, 1)
ticker := time.Tick(PingIdleTime / 2) ticker := time.Tick(pingIdleTime / 2)
for { for {
select { select {
case <-ticker: case <-ticker:
if d := time.Since(c.cr.Last()); d < PingIdleTime { if d := time.Since(c.cr.Last()); d < pingIdleTime {
if debug { if debug {
l.Debugln(c.id, "ping skipped after rd", d) l.Debugln(c.id, "ping skipped after rd", d)
} }
continue continue
} }
if d := time.Since(c.cw.Last()); d < PingIdleTime { if d := time.Since(c.cw.Last()); d < pingIdleTime {
if debug { if debug {
l.Debugln(c.id, "ping skipped after wr", d) l.Debugln(c.id, "ping skipped after wr", d)
} }
@@ -714,7 +709,7 @@ func (c *rawConnection) pingerLoop() {
if !ok { if !ok {
c.close(fmt.Errorf("ping failure")) c.close(fmt.Errorf("ping failure"))
} }
case <-time.After(PingTimeout): case <-time.After(pingTimeout):
c.close(fmt.Errorf("ping timeout")) c.close(fmt.Errorf("ping timeout"))
case <-c.closed: case <-c.closed:
return return
+9 -21
View File
@@ -67,10 +67,8 @@ func TestPing(t *testing.T) {
ar, aw := io.Pipe() ar, aw := io.Pipe()
br, bw := io.Pipe() br, bw := io.Pipe()
c0 := NewConnection(c0ID, ar, bw, newTestModel(), "name", CompressAlways).(wireFormatConnection).next.(*rawConnection) c0 := NewConnection(c0ID, ar, bw, nil, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection)
c1 := NewConnection(c1ID, br, aw, newTestModel(), "name", CompressAlways).(wireFormatConnection).next.(*rawConnection) c1 := NewConnection(c1ID, br, aw, nil, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection)
c0.ClusterConfig(ClusterConfigMessage{})
c1.ClusterConfig(ClusterConfigMessage{})
if ok := c0.ping(); !ok { if ok := c0.ping(); !ok {
t.Error("c0 ping failed") t.Error("c0 ping failed")
@@ -83,8 +81,8 @@ func TestPing(t *testing.T) {
func TestPingErr(t *testing.T) { func TestPingErr(t *testing.T) {
e := errors.New("something broke") e := errors.New("something broke")
for i := 0; i < 32; i++ { for i := 0; i < 16; i++ {
for j := 0; j < 32; j++ { for j := 0; j < 16; j++ {
m0 := newTestModel() m0 := newTestModel()
m1 := newTestModel() m1 := newTestModel()
@@ -94,16 +92,12 @@ func TestPingErr(t *testing.T) {
ebw := &ErrPipe{PipeWriter: *bw, max: j, err: e} ebw := &ErrPipe{PipeWriter: *bw, max: j, err: e}
c0 := NewConnection(c0ID, ar, ebw, m0, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection) c0 := NewConnection(c0ID, ar, ebw, m0, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection)
c1 := NewConnection(c1ID, br, eaw, m1, "name", CompressAlways) NewConnection(c1ID, br, eaw, m1, "name", CompressAlways)
c0.ClusterConfig(ClusterConfigMessage{})
c1.ClusterConfig(ClusterConfigMessage{})
res := c0.ping() res := c0.ping()
if (i < 8 || j < 8) && res { if (i < 8 || j < 8) && res {
// This should have resulted in failure, as there is no way an empty ClusterConfig plus a Ping message fits in eight bytes.
t.Errorf("Unexpected ping success; i=%d, j=%d", i, j) t.Errorf("Unexpected ping success; i=%d, j=%d", i, j)
} else if (i >= 28 && j >= 28) && !res { } else if (i >= 12 && j >= 12) && !res {
// This should have worked though, as 28 bytes is plenty for both.
t.Errorf("Unexpected ping fail; i=%d, j=%d", i, j) t.Errorf("Unexpected ping fail; i=%d, j=%d", i, j)
} }
} }
@@ -174,9 +168,7 @@ func TestVersionErr(t *testing.T) {
br, bw := io.Pipe() br, bw := io.Pipe()
c0 := NewConnection(c0ID, ar, bw, m0, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection) c0 := NewConnection(c0ID, ar, bw, m0, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection)
c1 := NewConnection(c1ID, br, aw, m1, "name", CompressAlways) NewConnection(c1ID, br, aw, m1, "name", CompressAlways)
c0.ClusterConfig(ClusterConfigMessage{})
c1.ClusterConfig(ClusterConfigMessage{})
w := xdr.NewWriter(c0.cw) w := xdr.NewWriter(c0.cw)
w.WriteUint32(encodeHeader(header{ w.WriteUint32(encodeHeader(header{
@@ -199,9 +191,7 @@ func TestTypeErr(t *testing.T) {
br, bw := io.Pipe() br, bw := io.Pipe()
c0 := NewConnection(c0ID, ar, bw, m0, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection) c0 := NewConnection(c0ID, ar, bw, m0, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection)
c1 := NewConnection(c1ID, br, aw, m1, "name", CompressAlways) NewConnection(c1ID, br, aw, m1, "name", CompressAlways)
c0.ClusterConfig(ClusterConfigMessage{})
c1.ClusterConfig(ClusterConfigMessage{})
w := xdr.NewWriter(c0.cw) w := xdr.NewWriter(c0.cw)
w.WriteUint32(encodeHeader(header{ w.WriteUint32(encodeHeader(header{
@@ -224,9 +214,7 @@ func TestClose(t *testing.T) {
br, bw := io.Pipe() br, bw := io.Pipe()
c0 := NewConnection(c0ID, ar, bw, m0, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection) c0 := NewConnection(c0ID, ar, bw, m0, "name", CompressAlways).(wireFormatConnection).next.(*rawConnection)
c1 := NewConnection(c1ID, br, aw, m1, "name", CompressAlways) NewConnection(c1ID, br, aw, m1, "name", CompressAlways)
c0.ClusterConfig(ClusterConfigMessage{})
c1.ClusterConfig(ClusterConfigMessage{})
c0.close(nil) c0.close(nil)
+145 -268
View File
@@ -63,14 +63,13 @@ type DB struct {
journalAckC chan error journalAckC chan error
// Compaction. // Compaction.
tcompCmdC chan cCmd tcompCmdC chan cCmd
tcompPauseC chan chan<- struct{} tcompPauseC chan chan<- struct{}
mcompCmdC chan cCmd mcompCmdC chan cCmd
compErrC chan error compErrC chan error
compPerErrC chan error compPerErrC chan error
compErrSetC chan error compErrSetC chan error
compWriteLocking bool compStats []cStats
compStats []cStats
// Close. // Close.
closeW sync.WaitGroup closeW sync.WaitGroup
@@ -109,44 +108,28 @@ func openDB(s *session) (*DB, error) {
closeC: make(chan struct{}), closeC: make(chan struct{}),
} }
// Read-only mode. if err := db.recoverJournal(); err != nil {
readOnly := s.o.GetReadOnly() return nil, err
}
if readOnly { // Remove any obsolete files.
// Recover journals (read-only mode). if err := db.checkAndCleanFiles(); err != nil {
if err := db.recoverJournalRO(); err != nil { // Close journal.
return nil, err if db.journal != nil {
db.journal.Close()
db.journalWriter.Close()
} }
} else { return nil, err
// Recover journals.
if err := db.recoverJournal(); err != nil {
return nil, err
}
// Remove any obsolete files.
if err := db.checkAndCleanFiles(); err != nil {
// Close journal.
if db.journal != nil {
db.journal.Close()
db.journalWriter.Close()
}
return nil, err
}
} }
// Doesn't need to be included in the wait group. // Doesn't need to be included in the wait group.
go db.compactionError() go db.compactionError()
go db.mpoolDrain() go db.mpoolDrain()
if readOnly { db.closeW.Add(3)
db.SetReadOnly() go db.tCompaction()
} else { go db.mCompaction()
db.closeW.Add(3) go db.jWriter()
go db.tCompaction()
go db.mCompaction()
go db.jWriter()
}
s.logf("db@open done T·%v", time.Since(start)) s.logf("db@open done T·%v", time.Since(start))
@@ -292,7 +275,7 @@ func recoverTable(s *session, o *opt.Options) error {
// We will drop corrupted table. // We will drop corrupted table.
strict = o.GetStrict(opt.StrictRecovery) strict = o.GetStrict(opt.StrictRecovery)
rec = &sessionRecord{} rec = &sessionRecord{numLevel: o.GetNumLevel()}
bpool = util.NewBufferPool(o.GetBlockSize() + 5) bpool = util.NewBufferPool(o.GetBlockSize() + 5)
) )
buildTable := func(iter iterator.Iterator) (tmp storage.File, size int64, err error) { buildTable := func(iter iterator.Iterator) (tmp storage.File, size int64, err error) {
@@ -467,136 +450,132 @@ func recoverTable(s *session, o *opt.Options) error {
} }
func (db *DB) recoverJournal() error { func (db *DB) recoverJournal() error {
// Get all journals and sort it by file number. // Get all tables and sort it by file number.
allJournalFiles, err := db.s.getFiles(storage.TypeJournal) journalFiles_, err := db.s.getFiles(storage.TypeJournal)
if err != nil { if err != nil {
return err return err
} }
files(allJournalFiles).sort() journalFiles := files(journalFiles_)
journalFiles.sort()
// Journals that will be recovered. // Discard older journal.
var recJournalFiles []storage.File prev := -1
for _, jf := range allJournalFiles { for i, file := range journalFiles {
if jf.Num() >= db.s.stJournalNum || jf.Num() == db.s.stPrevJournalNum { if file.Num() >= db.s.stJournalNum {
recJournalFiles = append(recJournalFiles, jf) if prev >= 0 {
i--
journalFiles[i] = journalFiles[prev]
}
journalFiles = journalFiles[i:]
break
} else if file.Num() == db.s.stPrevJournalNum {
prev = i
} }
} }
var ( var jr *journal.Reader
of storage.File // Obsolete file. var of storage.File
rec = &sessionRecord{} var mem *memdb.DB
) batch := new(Batch)
cm := newCMem(db.s)
buf := new(util.Buffer)
// Options.
strict := db.s.o.GetStrict(opt.StrictJournal)
checksum := db.s.o.GetStrict(opt.StrictJournalChecksum)
writeBuffer := db.s.o.GetWriteBuffer()
recoverJournal := func(file storage.File) error {
db.logf("journal@recovery recovering @%d", file.Num())
reader, err := file.Open()
if err != nil {
return err
}
defer reader.Close()
// Recover journals. // Create/reset journal reader instance.
if len(recJournalFiles) > 0 { if jr == nil {
db.logf("journal@recovery F·%d", len(recJournalFiles)) jr = journal.NewReader(reader, dropper{db.s, file}, strict, checksum)
} else {
// Mark file number as used. jr.Reset(reader, dropper{db.s, file}, strict, checksum)
db.s.markFileNum(recJournalFiles[len(recJournalFiles)-1].Num())
var (
// Options.
strict = db.s.o.GetStrict(opt.StrictJournal)
checksum = db.s.o.GetStrict(opt.StrictJournalChecksum)
writeBuffer = db.s.o.GetWriteBuffer()
jr *journal.Reader
mdb = memdb.New(db.s.icmp, writeBuffer)
buf = &util.Buffer{}
batch = &Batch{}
)
for _, jf := range recJournalFiles {
db.logf("journal@recovery recovering @%d", jf.Num())
fr, err := jf.Open()
if err != nil {
return err
}
// Create or reset journal reader instance.
if jr == nil {
jr = journal.NewReader(fr, dropper{db.s, jf}, strict, checksum)
} else {
jr.Reset(fr, dropper{db.s, jf}, strict, checksum)
}
// Flush memdb and remove obsolete journal file.
if of != nil {
if mdb.Len() > 0 {
if _, err := db.s.flushMemdb(rec, mdb, -1); err != nil {
fr.Close()
return err
}
}
rec.setJournalNum(jf.Num())
rec.setSeqNum(db.seq)
if err := db.s.commit(rec); err != nil {
fr.Close()
return err
}
rec.resetAddedTables()
of.Remove()
of = nil
}
// Replay journal to memdb.
mdb.Reset()
for {
r, err := jr.Next()
if err != nil {
if err == io.EOF {
break
}
fr.Close()
return errors.SetFile(err, jf)
}
buf.Reset()
if _, err := buf.ReadFrom(r); err != nil {
if err == io.ErrUnexpectedEOF {
// This is error returned due to corruption, with strict == false.
continue
}
fr.Close()
return errors.SetFile(err, jf)
}
if err := batch.memDecodeAndReplay(db.seq, buf.Bytes(), mdb); err != nil {
if !strict && errors.IsCorrupted(err) {
db.s.logf("journal error: %v (skipped)", err)
// We won't apply sequence number as it might be corrupted.
continue
}
fr.Close()
return errors.SetFile(err, jf)
}
// Save sequence number.
db.seq = batch.seq + uint64(batch.Len())
// Flush it if large enough.
if mdb.Size() >= writeBuffer {
if _, err := db.s.flushMemdb(rec, mdb, 0); err != nil {
fr.Close()
return err
}
mdb.Reset()
}
}
fr.Close()
of = jf
} }
// Flush the last memdb. // Flush memdb and remove obsolete journal file.
if mdb.Len() > 0 { if of != nil {
if _, err := db.s.flushMemdb(rec, mdb, 0); err != nil { if mem.Len() > 0 {
if err := cm.flush(mem, 0); err != nil {
return err
}
}
if err := cm.commit(file.Num(), db.seq); err != nil {
return err
}
cm.reset()
of.Remove()
of = nil
}
// Replay journal to memdb.
mem.Reset()
for {
r, err := jr.Next()
if err != nil {
if err == io.EOF {
break
}
return errors.SetFile(err, file)
}
buf.Reset()
if _, err := buf.ReadFrom(r); err != nil {
if err == io.ErrUnexpectedEOF {
// This is error returned due to corruption, with strict == false.
continue
} else {
return errors.SetFile(err, file)
}
}
if err := batch.memDecodeAndReplay(db.seq, buf.Bytes(), mem); err != nil {
if strict || !errors.IsCorrupted(err) {
return errors.SetFile(err, file)
} else {
db.s.logf("journal error: %v (skipped)", err)
// We won't apply sequence number as it might be corrupted.
continue
}
}
// Save sequence number.
db.seq = batch.seq + uint64(batch.Len())
// Flush it if large enough.
if mem.Size() >= writeBuffer {
if err := cm.flush(mem, 0); err != nil {
return err
}
mem.Reset()
}
}
of = file
return nil
}
// Recover all journals.
if len(journalFiles) > 0 {
db.logf("journal@recovery F·%d", len(journalFiles))
// Mark file number as used.
db.s.markFileNum(journalFiles[len(journalFiles)-1].Num())
mem = memdb.New(db.s.icmp, writeBuffer)
for _, file := range journalFiles {
if err := recoverJournal(file); err != nil {
return err
}
}
// Flush the last journal.
if mem.Len() > 0 {
if err := cm.flush(mem, 0); err != nil {
return err return err
} }
} }
@@ -608,10 +587,8 @@ func (db *DB) recoverJournal() error {
} }
// Commit. // Commit.
rec.setJournalNum(db.journalFile.Num()) if err := cm.commit(db.journalFile.Num(), db.seq); err != nil {
rec.setSeqNum(db.seq) // Close journal.
if err := db.s.commit(rec); err != nil {
// Close journal on error.
if db.journal != nil { if db.journal != nil {
db.journal.Close() db.journal.Close()
db.journalWriter.Close() db.journalWriter.Close()
@@ -627,103 +604,6 @@ func (db *DB) recoverJournal() error {
return nil return nil
} }
func (db *DB) recoverJournalRO() error {
// Get all journals and sort it by file number.
allJournalFiles, err := db.s.getFiles(storage.TypeJournal)
if err != nil {
return err
}
files(allJournalFiles).sort()
// Journals that will be recovered.
var recJournalFiles []storage.File
for _, jf := range allJournalFiles {
if jf.Num() >= db.s.stJournalNum || jf.Num() == db.s.stPrevJournalNum {
recJournalFiles = append(recJournalFiles, jf)
}
}
var (
// Options.
strict = db.s.o.GetStrict(opt.StrictJournal)
checksum = db.s.o.GetStrict(opt.StrictJournalChecksum)
writeBuffer = db.s.o.GetWriteBuffer()
mdb = memdb.New(db.s.icmp, writeBuffer)
)
// Recover journals.
if len(recJournalFiles) > 0 {
db.logf("journal@recovery RO·Mode F·%d", len(recJournalFiles))
var (
jr *journal.Reader
buf = &util.Buffer{}
batch = &Batch{}
)
for _, jf := range recJournalFiles {
db.logf("journal@recovery recovering @%d", jf.Num())
fr, err := jf.Open()
if err != nil {
return err
}
// Create or reset journal reader instance.
if jr == nil {
jr = journal.NewReader(fr, dropper{db.s, jf}, strict, checksum)
} else {
jr.Reset(fr, dropper{db.s, jf}, strict, checksum)
}
// Replay journal to memdb.
for {
r, err := jr.Next()
if err != nil {
if err == io.EOF {
break
}
fr.Close()
return errors.SetFile(err, jf)
}
buf.Reset()
if _, err := buf.ReadFrom(r); err != nil {
if err == io.ErrUnexpectedEOF {
// This is error returned due to corruption, with strict == false.
continue
}
fr.Close()
return errors.SetFile(err, jf)
}
if err := batch.memDecodeAndReplay(db.seq, buf.Bytes(), mdb); err != nil {
if !strict && errors.IsCorrupted(err) {
db.s.logf("journal error: %v (skipped)", err)
// We won't apply sequence number as it might be corrupted.
continue
}
fr.Close()
return errors.SetFile(err, jf)
}
// Save sequence number.
db.seq = batch.seq + uint64(batch.Len())
}
fr.Close()
}
}
// Set memDB.
db.mem = &memDB{db: db, DB: mdb, ref: 1}
return nil
}
func (db *DB) get(key []byte, seq uint64, ro *opt.ReadOptions) (value []byte, err error) { func (db *DB) get(key []byte, seq uint64, ro *opt.ReadOptions) (value []byte, err error) {
ikey := newIkey(key, seq, ktSeek) ikey := newIkey(key, seq, ktSeek)
@@ -734,7 +614,7 @@ func (db *DB) get(key []byte, seq uint64, ro *opt.ReadOptions) (value []byte, er
} }
defer m.decref() defer m.decref()
mk, mv, me := m.Find(ikey) mk, mv, me := m.mdb.Find(ikey)
if me == nil { if me == nil {
ukey, _, kt, kerr := parseIkey(mk) ukey, _, kt, kerr := parseIkey(mk)
if kerr != nil { if kerr != nil {
@@ -772,7 +652,7 @@ func (db *DB) has(key []byte, seq uint64, ro *opt.ReadOptions) (ret bool, err er
} }
defer m.decref() defer m.decref()
mk, _, me := m.Find(ikey) mk, _, me := m.mdb.Find(ikey)
if me == nil { if me == nil {
ukey, _, kt, kerr := parseIkey(mk) ukey, _, kt, kerr := parseIkey(mk)
if kerr != nil { if kerr != nil {
@@ -904,7 +784,7 @@ func (db *DB) GetProperty(name string) (value string, err error) {
const prefix = "leveldb." const prefix = "leveldb."
if !strings.HasPrefix(name, prefix) { if !strings.HasPrefix(name, prefix) {
return "", ErrNotFound return "", errors.New("leveldb: GetProperty: unknown property: " + name)
} }
p := name[len(prefix):] p := name[len(prefix):]
@@ -918,7 +798,7 @@ func (db *DB) GetProperty(name string) (value string, err error) {
var rest string var rest string
n, _ := fmt.Sscanf(p[len(numFilesPrefix):], "%d%s", &level, &rest) n, _ := fmt.Sscanf(p[len(numFilesPrefix):], "%d%s", &level, &rest)
if n != 1 || int(level) >= db.s.o.GetNumLevel() { if n != 1 || int(level) >= db.s.o.GetNumLevel() {
err = ErrNotFound err = errors.New("leveldb: GetProperty: invalid property: " + name)
} else { } else {
value = fmt.Sprint(v.tLen(int(level))) value = fmt.Sprint(v.tLen(int(level)))
} }
@@ -957,7 +837,7 @@ func (db *DB) GetProperty(name string) (value string, err error) {
case p == "aliveiters": case p == "aliveiters":
value = fmt.Sprintf("%d", atomic.LoadInt32(&db.aliveIters)) value = fmt.Sprintf("%d", atomic.LoadInt32(&db.aliveIters))
default: default:
err = ErrNotFound err = errors.New("leveldb: GetProperty: unknown property: " + name)
} }
return return
@@ -1020,9 +900,6 @@ func (db *DB) Close() error {
var err error var err error
select { select {
case err = <-db.compErrC: case err = <-db.compErrC:
if err == ErrReadOnly {
err = nil
}
default: default:
} }
+79 -35
View File
@@ -11,6 +11,7 @@ import (
"time" "time"
"github.com/syndtr/goleveldb/leveldb/errors" "github.com/syndtr/goleveldb/leveldb/errors"
"github.com/syndtr/goleveldb/leveldb/memdb"
"github.com/syndtr/goleveldb/leveldb/opt" "github.com/syndtr/goleveldb/leveldb/opt"
) )
@@ -61,8 +62,58 @@ func (p *cStatsStaging) stopTimer() {
} }
} }
type cMem struct {
s *session
level int
rec *sessionRecord
}
func newCMem(s *session) *cMem {
return &cMem{s: s, rec: &sessionRecord{numLevel: s.o.GetNumLevel()}}
}
func (c *cMem) flush(mem *memdb.DB, level int) error {
s := c.s
// Write memdb to table.
iter := mem.NewIterator(nil)
defer iter.Release()
t, n, err := s.tops.createFrom(iter)
if err != nil {
return err
}
// Pick level.
if level < 0 {
v := s.version()
level = v.pickLevel(t.imin.ukey(), t.imax.ukey())
v.release()
}
c.rec.addTableFile(level, t)
s.logf("mem@flush created L%d@%d N·%d S·%s %q:%q", level, t.file.Num(), n, shortenb(int(t.size)), t.imin, t.imax)
c.level = level
return nil
}
func (c *cMem) reset() {
c.rec = &sessionRecord{numLevel: c.s.o.GetNumLevel()}
}
func (c *cMem) commit(journal, seq uint64) error {
c.rec.setJournalNum(journal)
c.rec.setSeqNum(seq)
// Commit changes.
return c.s.commit(c.rec)
}
func (db *DB) compactionError() { func (db *DB) compactionError() {
var err error var (
err error
wlocked bool
)
noerr: noerr:
// No error. // No error.
for { for {
@@ -70,7 +121,7 @@ noerr:
case err = <-db.compErrSetC: case err = <-db.compErrSetC:
switch { switch {
case err == nil: case err == nil:
case err == ErrReadOnly, errors.IsCorrupted(err): case errors.IsCorrupted(err):
goto hasperr goto hasperr
default: default:
goto haserr goto haserr
@@ -88,7 +139,7 @@ haserr:
switch { switch {
case err == nil: case err == nil:
goto noerr goto noerr
case err == ErrReadOnly, errors.IsCorrupted(err): case errors.IsCorrupted(err):
goto hasperr goto hasperr
default: default:
} }
@@ -104,9 +155,9 @@ hasperr:
case db.compPerErrC <- err: case db.compPerErrC <- err:
case db.writeLockC <- struct{}{}: case db.writeLockC <- struct{}{}:
// Hold write lock, so that write won't pass-through. // Hold write lock, so that write won't pass-through.
db.compWriteLocking = true wlocked = true
case _, _ = <-db.closeC: case _, _ = <-db.closeC:
if db.compWriteLocking { if wlocked {
// We should release the lock or Close will hang. // We should release the lock or Close will hang.
<-db.writeLockC <-db.writeLockC
} }
@@ -236,18 +287,21 @@ func (db *DB) compactionExitTransact() {
} }
func (db *DB) memCompaction() { func (db *DB) memCompaction() {
mdb := db.getFrozenMem() mem := db.getFrozenMem()
if mdb == nil { if mem == nil {
return return
} }
defer mdb.decref() defer mem.decref()
db.logf("memdb@flush N·%d S·%s", mdb.Len(), shortenb(mdb.Size())) c := newCMem(db.s)
stats := new(cStatsStaging)
db.logf("mem@flush N·%d S·%s", mem.mdb.Len(), shortenb(mem.mdb.Size()))
// Don't compact empty memdb. // Don't compact empty memdb.
if mdb.Len() == 0 { if mem.mdb.Len() == 0 {
db.logf("memdb@flush skipping") db.logf("mem@flush skipping")
// drop frozen memdb // drop frozen mem
db.dropFrozenMem() db.dropFrozenMem()
return return
} }
@@ -263,20 +317,13 @@ func (db *DB) memCompaction() {
return return
} }
var ( db.compactionTransactFunc("mem@flush", func(cnt *compactionTransactCounter) (err error) {
rec = &sessionRecord{}
stats = &cStatsStaging{}
flushLevel int
)
db.compactionTransactFunc("memdb@flush", func(cnt *compactionTransactCounter) (err error) {
stats.startTimer() stats.startTimer()
flushLevel, err = db.s.flushMemdb(rec, mdb.DB, -1) defer stats.stopTimer()
stats.stopTimer() return c.flush(mem.mdb, -1)
return
}, func() error { }, func() error {
for _, r := range rec.addedTables { for _, r := range c.rec.addedTables {
db.logf("memdb@flush revert @%d", r.num) db.logf("mem@flush revert @%d", r.num)
f := db.s.getTableFile(r.num) f := db.s.getTableFile(r.num)
if err := f.Remove(); err != nil { if err := f.Remove(); err != nil {
return err return err
@@ -285,23 +332,20 @@ func (db *DB) memCompaction() {
return nil return nil
}) })
db.compactionTransactFunc("memdb@commit", func(cnt *compactionTransactCounter) (err error) { db.compactionTransactFunc("mem@commit", func(cnt *compactionTransactCounter) (err error) {
stats.startTimer() stats.startTimer()
rec.setJournalNum(db.journalFile.Num()) defer stats.stopTimer()
rec.setSeqNum(db.frozenSeq) return c.commit(db.journalFile.Num(), db.frozenSeq)
err = db.s.commit(rec)
stats.stopTimer()
return
}, nil) }, nil)
db.logf("memdb@flush committed F·%d T·%v", len(rec.addedTables), stats.duration) db.logf("mem@flush committed F·%d T·%v", len(c.rec.addedTables), stats.duration)
for _, r := range rec.addedTables { for _, r := range c.rec.addedTables {
stats.write += r.size stats.write += r.size
} }
db.compStats[flushLevel].add(stats) db.compStats[c.level].add(stats)
// Drop frozen memdb. // Drop frozen mem.
db.dropFrozenMem() db.dropFrozenMem()
// Resume table compaction. // Resume table compaction.
@@ -513,7 +557,7 @@ func (b *tableCompactionBuilder) revert() error {
func (db *DB) tableCompaction(c *compaction, noTrivial bool) { func (db *DB) tableCompaction(c *compaction, noTrivial bool) {
defer c.release() defer c.release()
rec := &sessionRecord{} rec := &sessionRecord{numLevel: db.s.o.GetNumLevel()}
rec.addCompPtr(c.level, c.imax) rec.addCompPtr(c.level, c.imax)
if !noTrivial && c.trivial() { if !noTrivial && c.trivial() {
+7 -25
View File
@@ -8,7 +8,6 @@ package leveldb
import ( import (
"errors" "errors"
"math/rand"
"runtime" "runtime"
"sync" "sync"
"sync/atomic" "sync/atomic"
@@ -40,11 +39,11 @@ func (db *DB) newRawIterator(slice *util.Range, ro *opt.ReadOptions) iterator.It
ti := v.getIterators(slice, ro) ti := v.getIterators(slice, ro)
n := len(ti) + 2 n := len(ti) + 2
i := make([]iterator.Iterator, 0, n) i := make([]iterator.Iterator, 0, n)
emi := em.NewIterator(slice) emi := em.mdb.NewIterator(slice)
emi.SetReleaser(&memdbReleaser{m: em}) emi.SetReleaser(&memdbReleaser{m: em})
i = append(i, emi) i = append(i, emi)
if fm != nil { if fm != nil {
fmi := fm.NewIterator(slice) fmi := fm.mdb.NewIterator(slice)
fmi.SetReleaser(&memdbReleaser{m: fm}) fmi.SetReleaser(&memdbReleaser{m: fm})
i = append(i, fmi) i = append(i, fmi)
} }
@@ -81,10 +80,6 @@ func (db *DB) newIterator(seq uint64, slice *util.Range, ro *opt.ReadOptions) *d
return iter return iter
} }
func (db *DB) iterSamplingRate() int {
return rand.Intn(2 * db.s.o.GetIteratorSamplingRate())
}
type dir int type dir int
const ( const (
@@ -103,21 +98,11 @@ type dbIter struct {
seq uint64 seq uint64
strict bool strict bool
smaplingGap int dir dir
dir dir key []byte
key []byte value []byte
value []byte err error
err error releaser util.Releaser
releaser util.Releaser
}
func (i *dbIter) sampleSeek() {
ikey := i.iter.Key()
i.smaplingGap -= len(ikey) + len(i.iter.Value())
for i.smaplingGap < 0 {
i.smaplingGap += i.db.iterSamplingRate()
i.db.sampleSeek(ikey)
}
} }
func (i *dbIter) setErr(err error) { func (i *dbIter) setErr(err error) {
@@ -190,7 +175,6 @@ func (i *dbIter) Seek(key []byte) bool {
func (i *dbIter) next() bool { func (i *dbIter) next() bool {
for { for {
if ukey, seq, kt, kerr := parseIkey(i.iter.Key()); kerr == nil { if ukey, seq, kt, kerr := parseIkey(i.iter.Key()); kerr == nil {
i.sampleSeek()
if seq <= i.seq { if seq <= i.seq {
switch kt { switch kt {
case ktDel: case ktDel:
@@ -241,7 +225,6 @@ func (i *dbIter) prev() bool {
if i.iter.Valid() { if i.iter.Valid() {
for { for {
if ukey, seq, kt, kerr := parseIkey(i.iter.Key()); kerr == nil { if ukey, seq, kt, kerr := parseIkey(i.iter.Key()); kerr == nil {
i.sampleSeek()
if seq <= i.seq { if seq <= i.seq {
if !del && i.icmp.uCompare(ukey, i.key) < 0 { if !del && i.icmp.uCompare(ukey, i.key) < 0 {
return true return true
@@ -283,7 +266,6 @@ func (i *dbIter) Prev() bool {
case dirForward: case dirForward:
for i.iter.Prev() { for i.iter.Prev() {
if ukey, _, _, kerr := parseIkey(i.iter.Key()); kerr == nil { if ukey, _, _, kerr := parseIkey(i.iter.Key()); kerr == nil {
i.sampleSeek()
if i.icmp.uCompare(ukey, i.key) < 0 { if i.icmp.uCompare(ukey, i.key) < 0 {
goto cont goto cont
} }
+7 -16
View File
@@ -15,8 +15,8 @@ import (
) )
type memDB struct { type memDB struct {
db *DB db *DB
*memdb.DB mdb *memdb.DB
ref int32 ref int32
} }
@@ -27,12 +27,12 @@ func (m *memDB) incref() {
func (m *memDB) decref() { func (m *memDB) decref() {
if ref := atomic.AddInt32(&m.ref, -1); ref == 0 { if ref := atomic.AddInt32(&m.ref, -1); ref == 0 {
// Only put back memdb with std capacity. // Only put back memdb with std capacity.
if m.Capacity() == m.db.s.o.GetWriteBuffer() { if m.mdb.Capacity() == m.db.s.o.GetWriteBuffer() {
m.Reset() m.mdb.Reset()
m.db.mpoolPut(m.DB) m.db.mpoolPut(m.mdb)
} }
m.db = nil m.db = nil
m.DB = nil m.mdb = nil
} else if ref < 0 { } else if ref < 0 {
panic("negative memdb ref") panic("negative memdb ref")
} }
@@ -48,15 +48,6 @@ func (db *DB) addSeq(delta uint64) {
atomic.AddUint64(&db.seq, delta) atomic.AddUint64(&db.seq, delta)
} }
func (db *DB) sampleSeek(ikey iKey) {
v := db.s.version()
if v.sampleSeek(ikey) {
// Trigger table compaction.
db.compSendTrigger(db.tcompCmdC)
}
v.release()
}
func (db *DB) mpoolPut(mem *memdb.DB) { func (db *DB) mpoolPut(mem *memdb.DB) {
defer func() { defer func() {
recover() recover()
@@ -126,7 +117,7 @@ func (db *DB) newMem(n int) (mem *memDB, err error) {
} }
mem = &memDB{ mem = &memDB{
db: db, db: db,
DB: mdb, mdb: mdb,
ref: 2, ref: 2,
} }
db.mem = mem db.mem = mem
+13 -135
View File
@@ -405,21 +405,19 @@ func (h *dbHarness) compactRange(min, max string) {
t.Log("DB range compaction done") t.Log("DB range compaction done")
} }
func (h *dbHarness) sizeOf(start, limit string) uint64 { func (h *dbHarness) sizeAssert(start, limit string, low, hi uint64) {
sz, err := h.db.SizeOf([]util.Range{ t := h.t
db := h.db
s, err := db.SizeOf([]util.Range{
{[]byte(start), []byte(limit)}, {[]byte(start), []byte(limit)},
}) })
if err != nil { if err != nil {
h.t.Error("SizeOf: got error: ", err) t.Error("SizeOf: got error: ", err)
} }
return sz.Sum() if s.Sum() < low || s.Sum() > hi {
} t.Errorf("sizeof %q to %q not in range, want %d - %d, got %d",
shorten(start), shorten(limit), low, hi, s.Sum())
func (h *dbHarness) sizeAssert(start, limit string, low, hi uint64) {
sz := h.sizeOf(start, limit)
if sz < low || sz > hi {
h.t.Errorf("sizeOf %q to %q not in range, want %d - %d, got %d",
shorten(start), shorten(limit), low, hi, sz)
} }
} }
@@ -2445,7 +2443,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
rec := &sessionRecord{} rec := &sessionRecord{numLevel: s.o.GetNumLevel()}
rec.addTableFile(i, tf) rec.addTableFile(i, tf)
if err := s.commit(rec); err != nil { if err := s.commit(rec); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -2455,7 +2453,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) {
// Build grandparent. // Build grandparent.
v := s.version() v := s.version()
c := newCompaction(s, v, 1, append(tFiles{}, v.tables[1]...)) c := newCompaction(s, v, 1, append(tFiles{}, v.tables[1]...))
rec := &sessionRecord{} rec := &sessionRecord{numLevel: s.o.GetNumLevel()}
b := &tableCompactionBuilder{ b := &tableCompactionBuilder{
s: s, s: s,
c: c, c: c,
@@ -2479,7 +2477,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) {
// Build level-1. // Build level-1.
v = s.version() v = s.version()
c = newCompaction(s, v, 0, append(tFiles{}, v.tables[0]...)) c = newCompaction(s, v, 0, append(tFiles{}, v.tables[0]...))
rec = &sessionRecord{} rec = &sessionRecord{numLevel: s.o.GetNumLevel()}
b = &tableCompactionBuilder{ b = &tableCompactionBuilder{
s: s, s: s,
c: c, c: c,
@@ -2523,7 +2521,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) {
// Compaction with transient error. // Compaction with transient error.
v = s.version() v = s.version()
c = newCompaction(s, v, 1, append(tFiles{}, v.tables[1]...)) c = newCompaction(s, v, 1, append(tFiles{}, v.tables[1]...))
rec = &sessionRecord{} rec = &sessionRecord{numLevel: s.o.GetNumLevel()}
b = &tableCompactionBuilder{ b = &tableCompactionBuilder{
s: s, s: s,
c: c, c: c,
@@ -2579,123 +2577,3 @@ func TestDB_TableCompactionBuilder(t *testing.T) {
} }
v.release() v.release()
} }
func testDB_IterTriggeredCompaction(t *testing.T, limitDiv int) {
const (
vSize = 200 * opt.KiB
tSize = 100 * opt.MiB
mIter = 100
n = tSize / vSize
)
h := newDbHarnessWopt(t, &opt.Options{
Compression: opt.NoCompression,
DisableBlockCache: true,
})
defer h.close()
key := func(x int) string {
return fmt.Sprintf("v%06d", x)
}
// Fill.
value := strings.Repeat("x", vSize)
for i := 0; i < n; i++ {
h.put(key(i), value)
}
h.compactMem()
// Delete all.
for i := 0; i < n; i++ {
h.delete(key(i))
}
h.compactMem()
var (
limit = n / limitDiv
startKey = key(0)
limitKey = key(limit)
maxKey = key(n)
slice = &util.Range{Limit: []byte(limitKey)}
initialSize0 = h.sizeOf(startKey, limitKey)
initialSize1 = h.sizeOf(limitKey, maxKey)
)
t.Logf("inital size %s [rest %s]", shortenb(int(initialSize0)), shortenb(int(initialSize1)))
for r := 0; true; r++ {
if r >= mIter {
t.Fatal("taking too long to compact")
}
// Iterates.
iter := h.db.NewIterator(slice, h.ro)
for iter.Next() {
}
if err := iter.Error(); err != nil {
t.Fatalf("Iter err: %v", err)
}
iter.Release()
// Wait compaction.
h.waitCompaction()
// Check size.
size0 := h.sizeOf(startKey, limitKey)
size1 := h.sizeOf(limitKey, maxKey)
t.Logf("#%03d size %s [rest %s]", r, shortenb(int(size0)), shortenb(int(size1)))
if size0 < initialSize0/10 {
break
}
}
if initialSize1 > 0 {
h.sizeAssert(limitKey, maxKey, initialSize1/4-opt.MiB, initialSize1+opt.MiB)
}
}
func TestDB_IterTriggeredCompaction(t *testing.T) {
testDB_IterTriggeredCompaction(t, 1)
}
func TestDB_IterTriggeredCompactionHalf(t *testing.T) {
testDB_IterTriggeredCompaction(t, 2)
}
func TestDB_ReadOnly(t *testing.T) {
h := newDbHarness(t)
defer h.close()
h.put("foo", "v1")
h.put("bar", "v2")
h.compactMem()
h.put("xfoo", "v1")
h.put("xbar", "v2")
t.Log("Trigger read-only")
if err := h.db.SetReadOnly(); err != nil {
h.close()
t.Fatalf("SetReadOnly error: %v", err)
}
h.stor.SetEmuErr(storage.TypeAll, tsOpCreate, tsOpReplace, tsOpRemove, tsOpWrite, tsOpWrite, tsOpSync)
ro := func(key, value, wantValue string) {
if err := h.db.Put([]byte(key), []byte(value), h.wo); err != ErrReadOnly {
t.Fatalf("unexpected error: %v", err)
}
h.getVal(key, wantValue)
}
ro("foo", "vx", "v1")
h.o.ReadOnly = true
h.reopenDB()
ro("foo", "vx", "v1")
ro("bar", "vx", "v2")
h.assertNumKeys(4)
}
+24 -51
View File
@@ -63,24 +63,24 @@ func (db *DB) rotateMem(n int) (mem *memDB, err error) {
return return
} }
func (db *DB) flush(n int) (mdb *memDB, mdbFree int, err error) { func (db *DB) flush(n int) (mem *memDB, nn int, err error) {
delayed := false delayed := false
flush := func() (retry bool) { flush := func() (retry bool) {
v := db.s.version() v := db.s.version()
defer v.release() defer v.release()
mdb = db.getEffectiveMem() mem = db.getEffectiveMem()
defer func() { defer func() {
if retry { if retry {
mdb.decref() mem.decref()
mdb = nil mem = nil
} }
}() }()
mdbFree = mdb.Free() nn = mem.mdb.Free()
switch { switch {
case v.tLen(0) >= db.s.o.GetWriteL0SlowdownTrigger() && !delayed: case v.tLen(0) >= db.s.o.GetWriteL0SlowdownTrigger() && !delayed:
delayed = true delayed = true
time.Sleep(time.Millisecond) time.Sleep(time.Millisecond)
case mdbFree >= n: case nn >= n:
return false return false
case v.tLen(0) >= db.s.o.GetWriteL0PauseTrigger(): case v.tLen(0) >= db.s.o.GetWriteL0PauseTrigger():
delayed = true delayed = true
@@ -90,15 +90,15 @@ func (db *DB) flush(n int) (mdb *memDB, mdbFree int, err error) {
} }
default: default:
// Allow memdb to grow if it has no entry. // Allow memdb to grow if it has no entry.
if mdb.Len() == 0 { if mem.mdb.Len() == 0 {
mdbFree = n nn = n
} else { } else {
mdb.decref() mem.decref()
mdb, err = db.rotateMem(n) mem, err = db.rotateMem(n)
if err == nil { if err == nil {
mdbFree = mdb.Free() nn = mem.mdb.Free()
} else { } else {
mdbFree = 0 nn = 0
} }
} }
return false return false
@@ -157,18 +157,18 @@ func (db *DB) Write(b *Batch, wo *opt.WriteOptions) (err error) {
} }
}() }()
mdb, mdbFree, err := db.flush(b.size()) mem, memFree, err := db.flush(b.size())
if err != nil { if err != nil {
return return
} }
defer mdb.decref() defer mem.decref()
// Calculate maximum size of the batch. // Calculate maximum size of the batch.
m := 1 << 20 m := 1 << 20
if x := b.size(); x <= 128<<10 { if x := b.size(); x <= 128<<10 {
m = x + (128 << 10) m = x + (128 << 10)
} }
m = minInt(m, mdbFree) m = minInt(m, memFree)
// Merge with other batch. // Merge with other batch.
drain: drain:
@@ -197,7 +197,7 @@ drain:
select { select {
case db.journalC <- b: case db.journalC <- b:
// Write into memdb // Write into memdb
if berr := b.memReplay(mdb.DB); berr != nil { if berr := b.memReplay(mem.mdb); berr != nil {
panic(berr) panic(berr)
} }
case err = <-db.compPerErrC: case err = <-db.compPerErrC:
@@ -211,7 +211,7 @@ drain:
case err = <-db.journalAckC: case err = <-db.journalAckC:
if err != nil { if err != nil {
// Revert memdb if error detected // Revert memdb if error detected
if berr := b.revertMemReplay(mdb.DB); berr != nil { if berr := b.revertMemReplay(mem.mdb); berr != nil {
panic(berr) panic(berr)
} }
return return
@@ -225,7 +225,7 @@ drain:
if err != nil { if err != nil {
return return
} }
if berr := b.memReplay(mdb.DB); berr != nil { if berr := b.memReplay(mem.mdb); berr != nil {
panic(berr) panic(berr)
} }
} }
@@ -233,7 +233,7 @@ drain:
// Set last seq number. // Set last seq number.
db.addSeq(uint64(b.Len())) db.addSeq(uint64(b.Len()))
if b.size() >= mdbFree { if b.size() >= memFree {
db.rotateMem(0) db.rotateMem(0)
} }
return return
@@ -249,7 +249,8 @@ func (db *DB) Put(key, value []byte, wo *opt.WriteOptions) error {
return db.Write(b, wo) return db.Write(b, wo)
} }
// Delete deletes the value for the given key. // Delete deletes the value for the given key. It returns ErrNotFound if
// the DB does not contain the key.
// //
// It is safe to modify the contents of the arguments after Delete returns. // It is safe to modify the contents of the arguments after Delete returns.
func (db *DB) Delete(key []byte, wo *opt.WriteOptions) error { func (db *DB) Delete(key []byte, wo *opt.WriteOptions) error {
@@ -289,9 +290,9 @@ func (db *DB) CompactRange(r util.Range) error {
} }
// Check for overlaps in memdb. // Check for overlaps in memdb.
mdb := db.getEffectiveMem() mem := db.getEffectiveMem()
defer mdb.decref() defer mem.decref()
if isMemOverlaps(db.s.icmp, mdb.DB, r.Start, r.Limit) { if isMemOverlaps(db.s.icmp, mem.mdb, r.Start, r.Limit) {
// Memdb compaction. // Memdb compaction.
if _, err := db.rotateMem(0); err != nil { if _, err := db.rotateMem(0); err != nil {
<-db.writeLockC <-db.writeLockC
@@ -308,31 +309,3 @@ func (db *DB) CompactRange(r util.Range) error {
// Table compaction. // Table compaction.
return db.compSendRange(db.tcompCmdC, -1, r.Start, r.Limit) return db.compSendRange(db.tcompCmdC, -1, r.Start, r.Limit)
} }
// SetReadOnly makes DB read-only. It will stay read-only until reopened.
func (db *DB) SetReadOnly() error {
if err := db.ok(); err != nil {
return err
}
// Lock writer.
select {
case db.writeLockC <- struct{}{}:
db.compWriteLocking = true
case err := <-db.compPerErrC:
return err
case _, _ = <-db.closeC:
return ErrClosed
}
// Set compaction read-only.
select {
case db.compErrSetC <- ErrReadOnly:
case perr := <-db.compPerErrC:
return perr
case _, _ = <-db.closeC:
return ErrClosed
}
return nil
}
-1
View File
@@ -12,7 +12,6 @@ import (
var ( var (
ErrNotFound = errors.ErrNotFound ErrNotFound = errors.ErrNotFound
ErrReadOnly = errors.New("leveldb: read-only mode")
ErrSnapshotReleased = errors.New("leveldb: snapshot released") ErrSnapshotReleased = errors.New("leveldb: snapshot released")
ErrIterReleased = errors.New("leveldb: iterator released") ErrIterReleased = errors.New("leveldb: iterator released")
ErrClosed = errors.New("leveldb: closed") ErrClosed = errors.New("leveldb: closed")
+3 -6
View File
@@ -206,7 +206,6 @@ func (p *DB) randHeight() (h int) {
return return
} }
// Must hold RW-lock if prev == true, as it use shared prevNode slice.
func (p *DB) findGE(key []byte, prev bool) (int, bool) { func (p *DB) findGE(key []byte, prev bool) (int, bool) {
node := 0 node := 0
h := p.maxHeight - 1 h := p.maxHeight - 1
@@ -303,7 +302,7 @@ func (p *DB) Put(key []byte, value []byte) error {
node := len(p.nodeData) node := len(p.nodeData)
p.nodeData = append(p.nodeData, kvOffset, len(key), len(value), h) p.nodeData = append(p.nodeData, kvOffset, len(key), len(value), h)
for i, n := range p.prevNode[:h] { for i, n := range p.prevNode[:h] {
m := n + nNext + i m := n + 4 + i
p.nodeData = append(p.nodeData, p.nodeData[m]) p.nodeData = append(p.nodeData, p.nodeData[m])
p.nodeData[m] = node p.nodeData[m] = node
} }
@@ -435,22 +434,20 @@ func (p *DB) Len() int {
// Reset resets the DB to initial empty state. Allows reuse the buffer. // Reset resets the DB to initial empty state. Allows reuse the buffer.
func (p *DB) Reset() { func (p *DB) Reset() {
p.mu.Lock()
p.rnd = rand.New(rand.NewSource(0xdeadbeef)) p.rnd = rand.New(rand.NewSource(0xdeadbeef))
p.maxHeight = 1 p.maxHeight = 1
p.n = 0 p.n = 0
p.kvSize = 0 p.kvSize = 0
p.kvData = p.kvData[:0] p.kvData = p.kvData[:0]
p.nodeData = p.nodeData[:nNext+tMaxHeight] p.nodeData = p.nodeData[:4+tMaxHeight]
p.nodeData[nKV] = 0 p.nodeData[nKV] = 0
p.nodeData[nKey] = 0 p.nodeData[nKey] = 0
p.nodeData[nVal] = 0 p.nodeData[nVal] = 0
p.nodeData[nHeight] = tMaxHeight p.nodeData[nHeight] = tMaxHeight
for n := 0; n < tMaxHeight; n++ { for n := 0; n < tMaxHeight; n++ {
p.nodeData[nNext+n] = 0 p.nodeData[4+n] = 0
p.prevNode[n] = 0 p.prevNode[n] = 0
} }
p.mu.Unlock()
} }
// New creates a new initalized in-memory key/value DB. The capacity // New creates a new initalized in-memory key/value DB. The capacity
+2 -48
View File
@@ -34,11 +34,10 @@ var (
DefaultCompactionTotalSize = 10 * MiB DefaultCompactionTotalSize = 10 * MiB
DefaultCompactionTotalSizeMultiplier = 10.0 DefaultCompactionTotalSizeMultiplier = 10.0
DefaultCompressionType = SnappyCompression DefaultCompressionType = SnappyCompression
DefaultIteratorSamplingRate = 1 * MiB
DefaultMaxMemCompationLevel = 2
DefaultNumLevel = 7
DefaultOpenFilesCacher = LRUCacher DefaultOpenFilesCacher = LRUCacher
DefaultOpenFilesCacheCapacity = 500 DefaultOpenFilesCacheCapacity = 500
DefaultMaxMemCompationLevel = 2
DefaultNumLevel = 7
DefaultWriteBuffer = 4 * MiB DefaultWriteBuffer = 4 * MiB
DefaultWriteL0PauseTrigger = 12 DefaultWriteL0PauseTrigger = 12
DefaultWriteL0SlowdownTrigger = 8 DefaultWriteL0SlowdownTrigger = 8
@@ -250,11 +249,6 @@ type Options struct {
// The default value (DefaultCompression) uses snappy compression. // The default value (DefaultCompression) uses snappy compression.
Compression Compression Compression Compression
// DisableBufferPool allows disable use of util.BufferPool functionality.
//
// The default value is false.
DisableBufferPool bool
// DisableBlockCache allows disable use of cache.Cache functionality on // DisableBlockCache allows disable use of cache.Cache functionality on
// 'sorted table' block. // 'sorted table' block.
// //
@@ -294,13 +288,6 @@ type Options struct {
// The default value is nil. // The default value is nil.
Filter filter.Filter Filter filter.Filter
// IteratorSamplingRate defines approximate gap (in bytes) between read
// sampling of an iterator. The samples will be used to determine when
// compaction should be triggered.
//
// The default is 1MiB.
IteratorSamplingRate int
// MaxMemCompationLevel defines maximum level a newly compacted 'memdb' // MaxMemCompationLevel defines maximum level a newly compacted 'memdb'
// will be pushed into if doesn't creates overlap. This should less than // will be pushed into if doesn't creates overlap. This should less than
// NumLevel. Use -1 for level-0. // NumLevel. Use -1 for level-0.
@@ -326,11 +313,6 @@ type Options struct {
// The default value is 500. // The default value is 500.
OpenFilesCacheCapacity int OpenFilesCacheCapacity int
// If true then opens DB in read-only mode.
//
// The default value is false.
ReadOnly bool
// Strict defines the DB strict level. // Strict defines the DB strict level.
Strict Strict Strict Strict
@@ -482,20 +464,6 @@ func (o *Options) GetCompression() Compression {
return o.Compression return o.Compression
} }
func (o *Options) GetDisableBufferPool() bool {
if o == nil {
return false
}
return o.DisableBufferPool
}
func (o *Options) GetDisableBlockCache() bool {
if o == nil {
return false
}
return o.DisableBlockCache
}
func (o *Options) GetDisableCompactionBackoff() bool { func (o *Options) GetDisableCompactionBackoff() bool {
if o == nil { if o == nil {
return false return false
@@ -524,13 +492,6 @@ func (o *Options) GetFilter() filter.Filter {
return o.Filter return o.Filter
} }
func (o *Options) GetIteratorSamplingRate() int {
if o == nil || o.IteratorSamplingRate <= 0 {
return DefaultIteratorSamplingRate
}
return o.IteratorSamplingRate
}
func (o *Options) GetMaxMemCompationLevel() int { func (o *Options) GetMaxMemCompationLevel() int {
level := DefaultMaxMemCompationLevel level := DefaultMaxMemCompationLevel
if o != nil { if o != nil {
@@ -572,13 +533,6 @@ func (o *Options) GetOpenFilesCacheCapacity() int {
return o.OpenFilesCacheCapacity return o.OpenFilesCacheCapacity
} }
func (o *Options) GetReadOnly() bool {
if o == nil {
return false
}
return o.ReadOnly
}
func (o *Options) GetStrict(strict Strict) bool { func (o *Options) GetStrict(strict Strict) bool {
if o == nil || o.Strict == 0 { if o == nil || o.Strict == 0 {
return DefaultStrict&strict != 0 return DefaultStrict&strict != 0
+254 -10
View File
@@ -11,8 +11,10 @@ import (
"io" "io"
"os" "os"
"sync" "sync"
"sync/atomic"
"github.com/syndtr/goleveldb/leveldb/errors" "github.com/syndtr/goleveldb/leveldb/errors"
"github.com/syndtr/goleveldb/leveldb/iterator"
"github.com/syndtr/goleveldb/leveldb/journal" "github.com/syndtr/goleveldb/leveldb/journal"
"github.com/syndtr/goleveldb/leveldb/opt" "github.com/syndtr/goleveldb/leveldb/opt"
"github.com/syndtr/goleveldb/leveldb/storage" "github.com/syndtr/goleveldb/leveldb/storage"
@@ -125,16 +127,11 @@ func (s *session) recover() (err error) {
return return
} }
defer reader.Close() defer reader.Close()
strict := s.o.GetStrict(opt.StrictManifest)
jr := journal.NewReader(reader, dropper{s, m}, strict, true)
var ( staging := s.stVersion.newStaging()
// Options. rec := &sessionRecord{numLevel: s.o.GetNumLevel()}
numLevel = s.o.GetNumLevel()
strict = s.o.GetStrict(opt.StrictManifest)
jr = journal.NewReader(reader, dropper{s, m}, strict, true)
rec = &sessionRecord{}
staging = s.stVersion.newStaging()
)
for { for {
var r io.Reader var r io.Reader
r, err = jr.Next() r, err = jr.Next()
@@ -146,7 +143,7 @@ func (s *session) recover() (err error) {
return errors.SetFile(err, m) return errors.SetFile(err, m)
} }
err = rec.decode(r, numLevel) err = rec.decode(r)
if err == nil { if err == nil {
// save compact pointers // save compact pointers
for _, r := range rec.compPtrs { for _, r := range rec.compPtrs {
@@ -209,3 +206,250 @@ func (s *session) commit(r *sessionRecord) (err error) {
return return
} }
// Pick a compaction based on current state; need external synchronization.
func (s *session) pickCompaction() *compaction {
v := s.version()
var level int
var t0 tFiles
if v.cScore >= 1 {
level = v.cLevel
cptr := s.stCompPtrs[level]
tables := v.tables[level]
for _, t := range tables {
if cptr == nil || s.icmp.Compare(t.imax, cptr) > 0 {
t0 = append(t0, t)
break
}
}
if len(t0) == 0 {
t0 = append(t0, tables[0])
}
} else {
if p := atomic.LoadPointer(&v.cSeek); p != nil {
ts := (*tSet)(p)
level = ts.level
t0 = append(t0, ts.table)
} else {
v.release()
return nil
}
}
return newCompaction(s, v, level, t0)
}
// Create compaction from given level and range; need external synchronization.
func (s *session) getCompactionRange(level int, umin, umax []byte) *compaction {
v := s.version()
t0 := v.tables[level].getOverlaps(nil, s.icmp, umin, umax, level == 0)
if len(t0) == 0 {
v.release()
return nil
}
// Avoid compacting too much in one shot in case the range is large.
// But we cannot do this for level-0 since level-0 files can overlap
// and we must not pick one file and drop another older file if the
// two files overlap.
if level > 0 {
limit := uint64(v.s.o.GetCompactionSourceLimit(level))
total := uint64(0)
for i, t := range t0 {
total += t.size
if total >= limit {
s.logf("table@compaction limiting F·%d -> F·%d", len(t0), i+1)
t0 = t0[:i+1]
break
}
}
}
return newCompaction(s, v, level, t0)
}
func newCompaction(s *session, v *version, level int, t0 tFiles) *compaction {
c := &compaction{
s: s,
v: v,
level: level,
tables: [2]tFiles{t0, nil},
maxGPOverlaps: uint64(s.o.GetCompactionGPOverlaps(level)),
tPtrs: make([]int, s.o.GetNumLevel()),
}
c.expand()
c.save()
return c
}
// compaction represent a compaction state.
type compaction struct {
s *session
v *version
level int
tables [2]tFiles
maxGPOverlaps uint64
gp tFiles
gpi int
seenKey bool
gpOverlappedBytes uint64
imin, imax iKey
tPtrs []int
released bool
snapGPI int
snapSeenKey bool
snapGPOverlappedBytes uint64
snapTPtrs []int
}
func (c *compaction) save() {
c.snapGPI = c.gpi
c.snapSeenKey = c.seenKey
c.snapGPOverlappedBytes = c.gpOverlappedBytes
c.snapTPtrs = append(c.snapTPtrs[:0], c.tPtrs...)
}
func (c *compaction) restore() {
c.gpi = c.snapGPI
c.seenKey = c.snapSeenKey
c.gpOverlappedBytes = c.snapGPOverlappedBytes
c.tPtrs = append(c.tPtrs[:0], c.snapTPtrs...)
}
func (c *compaction) release() {
if !c.released {
c.released = true
c.v.release()
}
}
// Expand compacted tables; need external synchronization.
func (c *compaction) expand() {
limit := uint64(c.s.o.GetCompactionExpandLimit(c.level))
vt0, vt1 := c.v.tables[c.level], c.v.tables[c.level+1]
t0, t1 := c.tables[0], c.tables[1]
imin, imax := t0.getRange(c.s.icmp)
// We expand t0 here just incase ukey hop across tables.
t0 = vt0.getOverlaps(t0, c.s.icmp, imin.ukey(), imax.ukey(), c.level == 0)
if len(t0) != len(c.tables[0]) {
imin, imax = t0.getRange(c.s.icmp)
}
t1 = vt1.getOverlaps(t1, c.s.icmp, imin.ukey(), imax.ukey(), false)
// Get entire range covered by compaction.
amin, amax := append(t0, t1...).getRange(c.s.icmp)
// See if we can grow the number of inputs in "level" without
// changing the number of "level+1" files we pick up.
if len(t1) > 0 {
exp0 := vt0.getOverlaps(nil, c.s.icmp, amin.ukey(), amax.ukey(), c.level == 0)
if len(exp0) > len(t0) && t1.size()+exp0.size() < limit {
xmin, xmax := exp0.getRange(c.s.icmp)
exp1 := vt1.getOverlaps(nil, c.s.icmp, xmin.ukey(), xmax.ukey(), false)
if len(exp1) == len(t1) {
c.s.logf("table@compaction expanding L%d+L%d (F·%d S·%s)+(F·%d S·%s) -> (F·%d S·%s)+(F·%d S·%s)",
c.level, c.level+1, len(t0), shortenb(int(t0.size())), len(t1), shortenb(int(t1.size())),
len(exp0), shortenb(int(exp0.size())), len(exp1), shortenb(int(exp1.size())))
imin, imax = xmin, xmax
t0, t1 = exp0, exp1
amin, amax = append(t0, t1...).getRange(c.s.icmp)
}
}
}
// Compute the set of grandparent files that overlap this compaction
// (parent == level+1; grandparent == level+2)
if c.level+2 < c.s.o.GetNumLevel() {
c.gp = c.v.tables[c.level+2].getOverlaps(c.gp, c.s.icmp, amin.ukey(), amax.ukey(), false)
}
c.tables[0], c.tables[1] = t0, t1
c.imin, c.imax = imin, imax
}
// Check whether compaction is trivial.
func (c *compaction) trivial() bool {
return len(c.tables[0]) == 1 && len(c.tables[1]) == 0 && c.gp.size() <= c.maxGPOverlaps
}
func (c *compaction) baseLevelForKey(ukey []byte) bool {
for level, tables := range c.v.tables[c.level+2:] {
for c.tPtrs[level] < len(tables) {
t := tables[c.tPtrs[level]]
if c.s.icmp.uCompare(ukey, t.imax.ukey()) <= 0 {
// We've advanced far enough.
if c.s.icmp.uCompare(ukey, t.imin.ukey()) >= 0 {
// Key falls in this file's range, so definitely not base level.
return false
}
break
}
c.tPtrs[level]++
}
}
return true
}
func (c *compaction) shouldStopBefore(ikey iKey) bool {
for ; c.gpi < len(c.gp); c.gpi++ {
gp := c.gp[c.gpi]
if c.s.icmp.Compare(ikey, gp.imax) <= 0 {
break
}
if c.seenKey {
c.gpOverlappedBytes += gp.size
}
}
c.seenKey = true
if c.gpOverlappedBytes > c.maxGPOverlaps {
// Too much overlap for current output; start new output.
c.gpOverlappedBytes = 0
return true
}
return false
}
// Creates an iterator.
func (c *compaction) newIterator() iterator.Iterator {
// Creates iterator slice.
icap := len(c.tables)
if c.level == 0 {
// Special case for level-0
icap = len(c.tables[0]) + 1
}
its := make([]iterator.Iterator, 0, icap)
// Options.
ro := &opt.ReadOptions{
DontFillCache: true,
Strict: opt.StrictOverride,
}
strict := c.s.o.GetStrict(opt.StrictCompaction)
if strict {
ro.Strict |= opt.StrictReader
}
for i, tables := range c.tables {
if len(tables) == 0 {
continue
}
// Level-0 is not sorted and may overlaps each other.
if c.level+i == 0 {
for _, t := range tables {
its = append(its, c.s.tops.newIterator(t, nil, ro))
}
} else {
it := iterator.NewIndexedIterator(tables.newIndexIterator(c.s.tops, c.s.icmp, nil, ro), strict)
its = append(its, it)
}
}
return iterator.NewMergedIterator(its, c.s.icmp, strict)
}
@@ -1,287 +0,0 @@
// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package leveldb
import (
"sync/atomic"
"github.com/syndtr/goleveldb/leveldb/iterator"
"github.com/syndtr/goleveldb/leveldb/memdb"
"github.com/syndtr/goleveldb/leveldb/opt"
)
func (s *session) pickMemdbLevel(umin, umax []byte) int {
v := s.version()
defer v.release()
return v.pickMemdbLevel(umin, umax)
}
func (s *session) flushMemdb(rec *sessionRecord, mdb *memdb.DB, level int) (level_ int, err error) {
// Create sorted table.
iter := mdb.NewIterator(nil)
defer iter.Release()
t, n, err := s.tops.createFrom(iter)
if err != nil {
return level, err
}
// Pick level and add to record.
if level < 0 {
level = s.pickMemdbLevel(t.imin.ukey(), t.imax.ukey())
}
rec.addTableFile(level, t)
s.logf("memdb@flush created L%d@%d N·%d S·%s %q:%q", level, t.file.Num(), n, shortenb(int(t.size)), t.imin, t.imax)
return level, nil
}
// Pick a compaction based on current state; need external synchronization.
func (s *session) pickCompaction() *compaction {
v := s.version()
var level int
var t0 tFiles
if v.cScore >= 1 {
level = v.cLevel
cptr := s.stCompPtrs[level]
tables := v.tables[level]
for _, t := range tables {
if cptr == nil || s.icmp.Compare(t.imax, cptr) > 0 {
t0 = append(t0, t)
break
}
}
if len(t0) == 0 {
t0 = append(t0, tables[0])
}
} else {
if p := atomic.LoadPointer(&v.cSeek); p != nil {
ts := (*tSet)(p)
level = ts.level
t0 = append(t0, ts.table)
} else {
v.release()
return nil
}
}
return newCompaction(s, v, level, t0)
}
// Create compaction from given level and range; need external synchronization.
func (s *session) getCompactionRange(level int, umin, umax []byte) *compaction {
v := s.version()
t0 := v.tables[level].getOverlaps(nil, s.icmp, umin, umax, level == 0)
if len(t0) == 0 {
v.release()
return nil
}
// Avoid compacting too much in one shot in case the range is large.
// But we cannot do this for level-0 since level-0 files can overlap
// and we must not pick one file and drop another older file if the
// two files overlap.
if level > 0 {
limit := uint64(v.s.o.GetCompactionSourceLimit(level))
total := uint64(0)
for i, t := range t0 {
total += t.size
if total >= limit {
s.logf("table@compaction limiting F·%d -> F·%d", len(t0), i+1)
t0 = t0[:i+1]
break
}
}
}
return newCompaction(s, v, level, t0)
}
func newCompaction(s *session, v *version, level int, t0 tFiles) *compaction {
c := &compaction{
s: s,
v: v,
level: level,
tables: [2]tFiles{t0, nil},
maxGPOverlaps: uint64(s.o.GetCompactionGPOverlaps(level)),
tPtrs: make([]int, s.o.GetNumLevel()),
}
c.expand()
c.save()
return c
}
// compaction represent a compaction state.
type compaction struct {
s *session
v *version
level int
tables [2]tFiles
maxGPOverlaps uint64
gp tFiles
gpi int
seenKey bool
gpOverlappedBytes uint64
imin, imax iKey
tPtrs []int
released bool
snapGPI int
snapSeenKey bool
snapGPOverlappedBytes uint64
snapTPtrs []int
}
func (c *compaction) save() {
c.snapGPI = c.gpi
c.snapSeenKey = c.seenKey
c.snapGPOverlappedBytes = c.gpOverlappedBytes
c.snapTPtrs = append(c.snapTPtrs[:0], c.tPtrs...)
}
func (c *compaction) restore() {
c.gpi = c.snapGPI
c.seenKey = c.snapSeenKey
c.gpOverlappedBytes = c.snapGPOverlappedBytes
c.tPtrs = append(c.tPtrs[:0], c.snapTPtrs...)
}
func (c *compaction) release() {
if !c.released {
c.released = true
c.v.release()
}
}
// Expand compacted tables; need external synchronization.
func (c *compaction) expand() {
limit := uint64(c.s.o.GetCompactionExpandLimit(c.level))
vt0, vt1 := c.v.tables[c.level], c.v.tables[c.level+1]
t0, t1 := c.tables[0], c.tables[1]
imin, imax := t0.getRange(c.s.icmp)
// We expand t0 here just incase ukey hop across tables.
t0 = vt0.getOverlaps(t0, c.s.icmp, imin.ukey(), imax.ukey(), c.level == 0)
if len(t0) != len(c.tables[0]) {
imin, imax = t0.getRange(c.s.icmp)
}
t1 = vt1.getOverlaps(t1, c.s.icmp, imin.ukey(), imax.ukey(), false)
// Get entire range covered by compaction.
amin, amax := append(t0, t1...).getRange(c.s.icmp)
// See if we can grow the number of inputs in "level" without
// changing the number of "level+1" files we pick up.
if len(t1) > 0 {
exp0 := vt0.getOverlaps(nil, c.s.icmp, amin.ukey(), amax.ukey(), c.level == 0)
if len(exp0) > len(t0) && t1.size()+exp0.size() < limit {
xmin, xmax := exp0.getRange(c.s.icmp)
exp1 := vt1.getOverlaps(nil, c.s.icmp, xmin.ukey(), xmax.ukey(), false)
if len(exp1) == len(t1) {
c.s.logf("table@compaction expanding L%d+L%d (F·%d S·%s)+(F·%d S·%s) -> (F·%d S·%s)+(F·%d S·%s)",
c.level, c.level+1, len(t0), shortenb(int(t0.size())), len(t1), shortenb(int(t1.size())),
len(exp0), shortenb(int(exp0.size())), len(exp1), shortenb(int(exp1.size())))
imin, imax = xmin, xmax
t0, t1 = exp0, exp1
amin, amax = append(t0, t1...).getRange(c.s.icmp)
}
}
}
// Compute the set of grandparent files that overlap this compaction
// (parent == level+1; grandparent == level+2)
if c.level+2 < c.s.o.GetNumLevel() {
c.gp = c.v.tables[c.level+2].getOverlaps(c.gp, c.s.icmp, amin.ukey(), amax.ukey(), false)
}
c.tables[0], c.tables[1] = t0, t1
c.imin, c.imax = imin, imax
}
// Check whether compaction is trivial.
func (c *compaction) trivial() bool {
return len(c.tables[0]) == 1 && len(c.tables[1]) == 0 && c.gp.size() <= c.maxGPOverlaps
}
func (c *compaction) baseLevelForKey(ukey []byte) bool {
for level, tables := range c.v.tables[c.level+2:] {
for c.tPtrs[level] < len(tables) {
t := tables[c.tPtrs[level]]
if c.s.icmp.uCompare(ukey, t.imax.ukey()) <= 0 {
// We've advanced far enough.
if c.s.icmp.uCompare(ukey, t.imin.ukey()) >= 0 {
// Key falls in this file's range, so definitely not base level.
return false
}
break
}
c.tPtrs[level]++
}
}
return true
}
func (c *compaction) shouldStopBefore(ikey iKey) bool {
for ; c.gpi < len(c.gp); c.gpi++ {
gp := c.gp[c.gpi]
if c.s.icmp.Compare(ikey, gp.imax) <= 0 {
break
}
if c.seenKey {
c.gpOverlappedBytes += gp.size
}
}
c.seenKey = true
if c.gpOverlappedBytes > c.maxGPOverlaps {
// Too much overlap for current output; start new output.
c.gpOverlappedBytes = 0
return true
}
return false
}
// Creates an iterator.
func (c *compaction) newIterator() iterator.Iterator {
// Creates iterator slice.
icap := len(c.tables)
if c.level == 0 {
// Special case for level-0.
icap = len(c.tables[0]) + 1
}
its := make([]iterator.Iterator, 0, icap)
// Options.
ro := &opt.ReadOptions{
DontFillCache: true,
Strict: opt.StrictOverride,
}
strict := c.s.o.GetStrict(opt.StrictCompaction)
if strict {
ro.Strict |= opt.StrictReader
}
for i, tables := range c.tables {
if len(tables) == 0 {
continue
}
// Level-0 is not sorted and may overlaps each other.
if c.level+i == 0 {
for _, t := range tables {
its = append(its, c.s.tops.newIterator(t, nil, ro))
}
} else {
it := iterator.NewIndexedIterator(tables.newIndexIterator(c.s.tops, c.s.icmp, nil, ro), strict)
its = append(its, it)
}
}
return iterator.NewMergedIterator(its, c.s.icmp, strict)
}
@@ -52,6 +52,8 @@ type dtRecord struct {
} }
type sessionRecord struct { type sessionRecord struct {
numLevel int
hasRec int hasRec int
comparer string comparer string
journalNum uint64 journalNum uint64
@@ -228,7 +230,7 @@ func (p *sessionRecord) readBytes(field string, r byteReader) []byte {
return x return x
} }
func (p *sessionRecord) readLevel(field string, r io.ByteReader, numLevel int) int { func (p *sessionRecord) readLevel(field string, r io.ByteReader) int {
if p.err != nil { if p.err != nil {
return 0 return 0
} }
@@ -236,14 +238,14 @@ func (p *sessionRecord) readLevel(field string, r io.ByteReader, numLevel int) i
if p.err != nil { if p.err != nil {
return 0 return 0
} }
if x >= uint64(numLevel) { if x >= uint64(p.numLevel) {
p.err = errors.NewErrCorrupted(nil, &ErrManifestCorrupted{field, "invalid level number"}) p.err = errors.NewErrCorrupted(nil, &ErrManifestCorrupted{field, "invalid level number"})
return 0 return 0
} }
return int(x) return int(x)
} }
func (p *sessionRecord) decode(r io.Reader, numLevel int) error { func (p *sessionRecord) decode(r io.Reader) error {
br, ok := r.(byteReader) br, ok := r.(byteReader)
if !ok { if !ok {
br = bufio.NewReader(r) br = bufio.NewReader(r)
@@ -284,13 +286,13 @@ func (p *sessionRecord) decode(r io.Reader, numLevel int) error {
p.setSeqNum(x) p.setSeqNum(x)
} }
case recCompPtr: case recCompPtr:
level := p.readLevel("comp-ptr.level", br, numLevel) level := p.readLevel("comp-ptr.level", br)
ikey := p.readBytes("comp-ptr.ikey", br) ikey := p.readBytes("comp-ptr.ikey", br)
if p.err == nil { if p.err == nil {
p.addCompPtr(level, iKey(ikey)) p.addCompPtr(level, iKey(ikey))
} }
case recAddTable: case recAddTable:
level := p.readLevel("add-table.level", br, numLevel) level := p.readLevel("add-table.level", br)
num := p.readUvarint("add-table.num", br) num := p.readUvarint("add-table.num", br)
size := p.readUvarint("add-table.size", br) size := p.readUvarint("add-table.size", br)
imin := p.readBytes("add-table.imin", br) imin := p.readBytes("add-table.imin", br)
@@ -299,7 +301,7 @@ func (p *sessionRecord) decode(r io.Reader, numLevel int) error {
p.addTable(level, num, size, imin, imax) p.addTable(level, num, size, imin, imax)
} }
case recDelTable: case recDelTable:
level := p.readLevel("del-table.level", br, numLevel) level := p.readLevel("del-table.level", br)
num := p.readUvarint("del-table.num", br) num := p.readUvarint("del-table.num", br)
if p.err == nil { if p.err == nil {
p.delTable(level, num) p.delTable(level, num)
@@ -19,8 +19,8 @@ func decodeEncode(v *sessionRecord) (res bool, err error) {
if err != nil { if err != nil {
return return
} }
v2 := &sessionRecord{} v2 := &sessionRecord{numLevel: opt.DefaultNumLevel}
err = v.decode(b, opt.DefaultNumLevel) err = v.decode(b)
if err != nil { if err != nil {
return return
} }
@@ -34,7 +34,7 @@ func decodeEncode(v *sessionRecord) (res bool, err error) {
func TestSessionRecord_EncodeDecode(t *testing.T) { func TestSessionRecord_EncodeDecode(t *testing.T) {
big := uint64(1) << 50 big := uint64(1) << 50
v := &sessionRecord{} v := &sessionRecord{numLevel: opt.DefaultNumLevel}
i := uint64(0) i := uint64(0)
test := func() { test := func() {
res, err := decodeEncode(v) res, err := decodeEncode(v)
+1 -1
View File
@@ -182,7 +182,7 @@ func (s *session) newManifest(rec *sessionRecord, v *version) (err error) {
defer v.release() defer v.release()
} }
if rec == nil { if rec == nil {
rec = &sessionRecord{} rec = &sessionRecord{numLevel: s.o.GetNumLevel()}
} }
s.fillRecord(rec, true) s.fillRecord(rec, true)
v.fillRecord(rec) v.fillRecord(rec)
@@ -42,8 +42,6 @@ type tsOp uint
const ( const (
tsOpOpen tsOp = iota tsOpOpen tsOp = iota
tsOpCreate tsOpCreate
tsOpReplace
tsOpRemove
tsOpRead tsOpRead
tsOpReadAt tsOpReadAt
tsOpWrite tsOpWrite
@@ -243,10 +241,6 @@ func (tf tsFile) Replace(newfile storage.File) (err error) {
if err != nil { if err != nil {
return return
} }
if tf.shouldErr(tsOpReplace) {
err = errors.New("leveldb.testStorage: emulated create error")
return
}
err = tf.File.Replace(newfile.(tsFile).File) err = tf.File.Replace(newfile.(tsFile).File)
if err != nil { if err != nil {
ts.t.Errorf("E: cannot replace file, num=%d type=%v: %v", tf.Num(), tf.Type(), err) ts.t.Errorf("E: cannot replace file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
@@ -264,10 +258,6 @@ func (tf tsFile) Remove() (err error) {
if err != nil { if err != nil {
return return
} }
if tf.shouldErr(tsOpRemove) {
err = errors.New("leveldb.testStorage: emulated create error")
return
}
err = tf.File.Remove() err = tf.File.Remove()
if err != nil { if err != nil {
ts.t.Errorf("E: cannot remove file, num=%d type=%v: %v", tf.Num(), tf.Type(), err) ts.t.Errorf("E: cannot remove file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
+2 -6
View File
@@ -441,26 +441,22 @@ func newTableOps(s *session) *tOps {
var ( var (
cacher cache.Cacher cacher cache.Cacher
bcache *cache.Cache bcache *cache.Cache
bpool *util.BufferPool
) )
if s.o.GetOpenFilesCacheCapacity() > 0 { if s.o.GetOpenFilesCacheCapacity() > 0 {
cacher = cache.NewLRU(s.o.GetOpenFilesCacheCapacity()) cacher = cache.NewLRU(s.o.GetOpenFilesCacheCapacity())
} }
if !s.o.GetDisableBlockCache() { if !s.o.DisableBlockCache {
var bcacher cache.Cacher var bcacher cache.Cacher
if s.o.GetBlockCacheCapacity() > 0 { if s.o.GetBlockCacheCapacity() > 0 {
bcacher = cache.NewLRU(s.o.GetBlockCacheCapacity()) bcacher = cache.NewLRU(s.o.GetBlockCacheCapacity())
} }
bcache = cache.NewCache(bcacher) bcache = cache.NewCache(bcacher)
} }
if !s.o.GetDisableBufferPool() {
bpool = util.NewBufferPool(s.o.GetBlockSize() + 5)
}
return &tOps{ return &tOps{
s: s, s: s,
cache: cache.NewCache(cacher), cache: cache.NewCache(cacher),
bcache: bcache, bcache: bcache,
bpool: bpool, bpool: util.NewBufferPool(s.o.GetBlockSize() + 5),
} }
} }
+1 -1
View File
@@ -14,7 +14,7 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/google/go-snappy/snappy" "github.com/syndtr/gosnappy/snappy"
"github.com/syndtr/goleveldb/leveldb/cache" "github.com/syndtr/goleveldb/leveldb/cache"
"github.com/syndtr/goleveldb/leveldb/comparer" "github.com/syndtr/goleveldb/leveldb/comparer"
+1 -1
View File
@@ -12,7 +12,7 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/google/go-snappy/snappy" "github.com/syndtr/gosnappy/snappy"
"github.com/syndtr/goleveldb/leveldb/comparer" "github.com/syndtr/goleveldb/leveldb/comparer"
"github.com/syndtr/goleveldb/leveldb/filter" "github.com/syndtr/goleveldb/leveldb/filter"
+3 -24
View File
@@ -136,8 +136,9 @@ func (v *version) get(ikey iKey, ro *opt.ReadOptions, noValue bool) (value []byt
if !tseek { if !tseek {
if tset == nil { if tset == nil {
tset = &tSet{level, t} tset = &tSet{level, t}
} else { } else if tset.table.consumeSeek() <= 0 {
tseek = true tseek = true
tcomp = atomic.CompareAndSwapPointer(&v.cSeek, nil, unsafe.Pointer(tset))
} }
} }
@@ -202,28 +203,6 @@ func (v *version) get(ikey iKey, ro *opt.ReadOptions, noValue bool) (value []byt
return true return true
}) })
if tseek && tset.table.consumeSeek() <= 0 {
tcomp = atomic.CompareAndSwapPointer(&v.cSeek, nil, unsafe.Pointer(tset))
}
return
}
func (v *version) sampleSeek(ikey iKey) (tcomp bool) {
var tset *tSet
v.walkOverlapping(ikey, func(level int, t *tFile) bool {
if tset == nil {
tset = &tSet{level, t}
return true
} else {
if tset.table.consumeSeek() <= 0 {
tcomp = atomic.CompareAndSwapPointer(&v.cSeek, nil, unsafe.Pointer(tset))
}
return false
}
}, nil)
return return
} }
@@ -300,7 +279,7 @@ func (v *version) offsetOf(ikey iKey) (n uint64, err error) {
return return
} }
func (v *version) pickMemdbLevel(umin, umax []byte) (level int) { func (v *version) pickLevel(umin, umax []byte) (level int) {
if !v.tables[0].overlaps(v.s.icmp, umin, umax, true) { if !v.tables[0].overlaps(v.s.icmp, umin, umax, true) {
var overlaps tFiles var overlaps tFiles
maxLevel := v.s.o.GetMaxMemCompationLevel() maxLevel := v.s.o.GetMaxMemCompationLevel()
+1 -7
View File
@@ -15,19 +15,15 @@ asdil12 <dominik@heidler.eu>
bencurthoys <ben@bencurthoys.com> bencurthoys <ben@bencurthoys.com>
bigbear2nd <bigbear2nd@gmail.com> bigbear2nd <bigbear2nd@gmail.com>
brendanlong <self@brendanlong.com> brendanlong <self@brendanlong.com>
brgmnn <dan.arne.bergmann@gmail.com> <brgmnn@users.noreply.github.com>
bsidhom <bsidhom@gmail.com> bsidhom <bsidhom@gmail.com>
calmh <jakob@nym.se> calmh <jakob@nym.se>
canton7 <antony.male@gmail.com>
cdata <chris@scriptolo.gy> cdata <chris@scriptolo.gy>
cdhowie <me@chrishowie.com>
ceh <emil@hessman.se> ceh <emil@hessman.se>
cqcallaw <enlightened.despot@gmail.com> cqcallaw <enlightened.despot@gmail.com>
dzarda <dzardacz@gmail.com> dzarda <dzardacz@gmail.com>
facastagnini <federico.castagnini@gmail.com> facastagnini <federico.castagnini@gmail.com>
filoozoom <philippe@schommers.be> filoozoom <philippe@schommers.be>
frioux <frew@afoolishmanifesto.com> <frioux@gmail.com> frioux <frew@afoolishmanifesto.com> <frioux@gmail.com>
fti7 <frank@isemann.name>
gillisig <gilli@vx.is> gillisig <gilli@vx.is>
jarlebring <jarlebring@gmail.com> jarlebring <jarlebring@gmail.com>
jedie <github.com@jensdiemer.de> <git@jensdiemer.de> jedie <github.com@jensdiemer.de> <git@jensdiemer.de>
@@ -38,7 +34,6 @@ kozec <kozec@kozec.com>
krozycki <rozycki.karol@gmail.com> krozycki <rozycki.karol@gmail.com>
marcindziadus <dziadus.marcin@gmail.com> marcindziadus <dziadus.marcin@gmail.com>
marclaporte <marc@marclaporte.com> marclaporte <marc@marclaporte.com>
mogwa1 <devriesb@gmail.com>
moshen <moshen.colin@gmail.com> moshen <moshen.colin@gmail.com>
mvdan <mvdan@mvdan.cc> mvdan <mvdan@mvdan.cc>
pascalj <github@pascalj.com> <mail@pascal-jungblut.com> pascalj <github@pascalj.com> <mail@pascal-jungblut.com>
@@ -47,9 +42,9 @@ philips <brandon@ifup.org>
piobpl <piotrb10@gmail.com> piobpl <piotrb10@gmail.com>
pluby <phill.luby@newredo.com> pluby <phill.luby@newredo.com>
pyfisch <pyfisch@gmail.com> pyfisch <pyfisch@gmail.com>
qbit <qbit@deftly.net>
ralder <ralder@yandex.ru> ralder <ralder@yandex.ru>
rumpelsepp <stefan@sevenbyte.org> rumpelsepp <stefan@sevenbyte.org>
qbit <qbit@deftly.net>
sciurius <jvromans@squirrel.nl> sciurius <jvromans@squirrel.nl>
seehuhn <voss@seehuhn.de> seehuhn <voss@seehuhn.de>
snnd <dw@risu.io> snnd <dw@risu.io>
@@ -58,5 +53,4 @@ tnn2 <tnn@nygren.pp.se>
tojrobinson <tully@tojr.org> tojrobinson <tully@tojr.org>
uok <ueomkail@gmail.com> <uok@users.noreply.github.com> uok <ueomkail@gmail.com> <uok@users.noreply.github.com>
veeti <veeti.paananen@rojekti.fi> veeti <veeti.paananen@rojekti.fi>
wsgcsysadmin <e.meitner@willystreet.coo>
zukoo <fxgsell@gmail.com> zukoo <fxgsell@gmail.com>
+9 -8
View File
@@ -1,11 +1,11 @@
Syncthing syncthing
========= =========
[![Latest Build](http://img.shields.io/jenkins/s/http/build.syncthing.net/syncthing.svg?style=flat-square)](http://build.syncthing.net/job/syncthing/lastBuild/) [![Latest Build](http://img.shields.io/jenkins/s/http/build.syncthing.net/syncthing.svg?style=flat-square)](http://build.syncthing.net/job/syncthing/lastBuild/)
[![API Documentation](http://img.shields.io/badge/api-Godoc-blue.svg?style=flat-square)](http://godoc.org/github.com/syncthing/syncthing) [![API Documentation](http://img.shields.io/badge/api-Godoc-blue.svg?style=flat-square)](http://godoc.org/github.com/syncthing/syncthing)
[![MPLv2 License](http://img.shields.io/badge/license-MPLv2-blue.svg?style=flat-square)](https://www.mozilla.org/MPL/2.0/) [![MPLv2 License](http://img.shields.io/badge/license-MPLv2-blue.svg?style=flat-square)](https://www.mozilla.org/MPL/2.0/)
This is the Syncthing project which pursues the following goals: This is the `syncthing` project which pursues the following goals:
1. Define a protocol for synchronization of a folder between a number of 1. Define a protocol for synchronization of a folder between a number of
collaborating devices. This protocol should be well defined, unambiguous, collaborating devices. This protocol should be well defined, unambiguous,
@@ -18,16 +18,16 @@ This is the Syncthing project which pursues the following goals:
alternative, compatible implementations of the protocol will arise. alternative, compatible implementations of the protocol will arise.
The two are evolving together; the protocol is not to be considered The two are evolving together; the protocol is not to be considered
stable until Syncthing 1.0 is released, at which point it is locked down stable until syncthing 1.0 is released, at which point it is locked down
for incompatible changes. for incompatible changes.
Getting Started Getting Started
--------------- ---------------
Take a look at the [getting started Take a look at the [getting started
guide](http://docs.syncthing.net/intro/getting-started.html). guide](https://github.com/syncthing/syncthing/wiki/Getting-Started).
There are a few examples for keeping Syncthing running in the background There are a few examples for keeping syncthing running in the background
on your system in [the etc directory](https://github.com/syncthing/syncthing/blob/master/etc). on your system in [the etc directory](https://github.com/syncthing/syncthing/blob/master/etc).
There is an IRC channel, `#syncthing` on Freenode, for talking directly There is an IRC channel, `#syncthing` on Freenode, for talking directly
@@ -37,7 +37,7 @@ Building
-------- --------
Building Syncthing from source is easy, and there's a Building Syncthing from source is easy, and there's a
[guide](http://docs.syncthing.net/dev/building.html). [guide](https://github.com/syncthing/syncthing/wiki/Building).
that describes it for both Unix and Windows systems. that describes it for both Unix and Windows systems.
Signed Releases Signed Releases
@@ -51,8 +51,9 @@ available in the md5sum.txt.asc and sha1sum.txt.asc files.
Documentation Documentation
============= =============
Please see the [Syncthing The [syncthing
documentation site](http://docs.syncthing.net/). documentation](https://github.com/syncthing/syncthing/wiki/) is on the
Github wiki.
All code is licensed under the All code is licensed under the
[MPLv2 License](https://github.com/syncthing/syncthing/blob/master/LICENSE). [MPLv2 License](https://github.com/syncthing/syncthing/blob/master/LICENSE).
-50
View File
@@ -1,50 +0,0 @@
// Copyright (C) 2015 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 http://mozilla.org/MPL/2.0/.
// +build ignore
// Neatly format benchmarking output which otherwise looks like crap.
package main
import (
"bufio"
"bytes"
"fmt"
"os"
"regexp"
"text/tabwriter"
)
var (
benchRe = regexp.MustCompile(`^Bench`)
spacesRe = regexp.MustCompile(`\s+`)
numbersRe = regexp.MustCompile(`\b[\d\.]+\b`)
)
func main() {
tw := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0)
br := bufio.NewScanner(os.Stdin)
n := 0
for br.Scan() {
line := br.Bytes()
if benchRe.Match(line) {
n++
line = spacesRe.ReplaceAllLiteral(line, []byte("\t"))
line = numbersRe.ReplaceAllFunc(line, func(n []byte) []byte {
return []byte(fmt.Sprintf("%12s", n))
})
tw.Write(line)
tw.Write([]byte("\n"))
} else if n > 0 && bytes.HasPrefix(line, []byte("ok")) {
n = 0
tw.Flush()
fmt.Printf("%s\n\n", line)
}
}
tw.Flush()
}
+5 -29
View File
@@ -110,9 +110,6 @@ func main() {
case "test": case "test":
test("./...") test("./...")
case "bench":
bench("./...")
case "assets": case "assets":
assets() assets()
@@ -185,11 +182,6 @@ func test(pkg string) {
runPrint("go", "test", "-short", "-timeout", "60s", pkg) runPrint("go", "test", "-short", "-timeout", "60s", pkg)
} }
func bench(pkg string) {
setBuildEnv()
runPrint("go", "test", "-run", "NONE", "-bench", ".", pkg)
}
func install(pkg string, tags []string) { func install(pkg string, tags []string) {
os.Setenv("GOBIN", "./bin") os.Setenv("GOBIN", "./bin")
args := []string{"install", "-v", "-ldflags", ldflags()} args := []string{"install", "-v", "-ldflags", ldflags()}
@@ -286,17 +278,6 @@ func buildZip() {
func buildDeb() { func buildDeb() {
os.RemoveAll("deb") os.RemoveAll("deb")
// "goarch" here is set to whatever the Debian packages expect. We correct
// "it to what we actually know how to build and keep the Debian variant
// "name in "debarch".
debarch := goarch
switch goarch {
case "i386":
goarch = "386"
case "armel", "armhf":
goarch = "arm"
}
build("./cmd/syncthing", []string{"noupgrade"}) build("./cmd/syncthing", []string{"noupgrade"})
files := []archiveFile{ files := []archiveFile{
@@ -304,16 +285,6 @@ func buildDeb() {
{src: "LICENSE", dst: "deb/usr/share/doc/syncthing/LICENSE.txt", perm: 0644}, {src: "LICENSE", dst: "deb/usr/share/doc/syncthing/LICENSE.txt", perm: 0644},
{src: "AUTHORS", dst: "deb/usr/share/doc/syncthing/AUTHORS.txt", perm: 0644}, {src: "AUTHORS", dst: "deb/usr/share/doc/syncthing/AUTHORS.txt", perm: 0644},
{src: "syncthing", dst: "deb/usr/bin/syncthing", perm: 0755}, {src: "syncthing", dst: "deb/usr/bin/syncthing", perm: 0755},
{src: "man/syncthing.1", dst: "deb/usr/share/man/man1/syncthing.1", perm: 0644},
{src: "man/syncthing-config.5", dst: "deb/usr/share/man/man5/syncthing-config.5", perm: 0644},
{src: "man/syncthing-stignore.5", dst: "deb/usr/share/man/man5/syncthing-stignore.5", perm: 0644},
{src: "man/syncthing-device-ids.7", dst: "deb/usr/share/man/man7/syncthing-device-ids.7", perm: 0644},
{src: "man/syncthing-event-api.7", dst: "deb/usr/share/man/man7/syncthing-event-api.7", perm: 0644},
{src: "man/syncthing-faq.7", dst: "deb/usr/share/man/man7/syncthing-faq.7", perm: 0644},
{src: "man/syncthing-networking.7", dst: "deb/usr/share/man/man7/syncthing-networking.7", perm: 0644},
{src: "man/syncthing-rest-api.7", dst: "deb/usr/share/man/man7/syncthing-rest-api.7", perm: 0644},
{src: "man/syncthing-security.7", dst: "deb/usr/share/man/man7/syncthing-security.7", perm: 0644},
{src: "man/syncthing-versioning.7", dst: "deb/usr/share/man/man7/syncthing-versioning.7", perm: 0644},
} }
for _, file := range listFiles("extra") { for _, file := range listFiles("extra") {
@@ -326,6 +297,11 @@ func buildDeb() {
} }
} }
debarch := goarch
if debarch == "386" {
debarch = "i386"
}
control := `Package: syncthing control := `Package: syncthing
Architecture: {{arch}} Architecture: {{arch}}
Depends: libc6 Depends: libc6
+5 -15
View File
@@ -17,11 +17,8 @@ case "${1:-default}" in
ulimit -t 60 &>/dev/null || true ulimit -t 60 &>/dev/null || true
ulimit -d 512000 &>/dev/null || true ulimit -d 512000 &>/dev/null || true
ulimit -m 512000 &>/dev/null || true ulimit -m 512000 &>/dev/null || true
go run build.go test
;;
bench) go run build.go "$1"
LOGGER_DISCARD=1 go run build.go bench | go run benchfilter.go
;; ;;
tar) tar)
@@ -44,14 +41,8 @@ case "${1:-default}" in
go run build.go "$1" go run build.go "$1"
;; ;;
prerelease) transifex)
go run build.go transifex go run build.go "$1"
git add -A gui/assets/ internal/auto/
pushd man ; ./refresh.sh ; popd
git add -A man
echo
echo Changelog:
go run changelog.go
;; ;;
noupgrade) noupgrade)
@@ -127,9 +118,8 @@ case "${1:-default}" in
-e "STTRACE=$STTRACE" \ -e "STTRACE=$STTRACE" \
syncthing/build:latest \ syncthing/build:latest \
sh -c './build.sh clean \ sh -c './build.sh clean \
&& ./build.sh test-cov \ && ./build.sh all \
&& ./build.sh bench \ && STTRACE=all ./build.sh test-cov'
&& ./build.sh all'
;; ;;
docker-test) docker-test)
+2 -3
View File
@@ -19,8 +19,7 @@ no-docs-typos() {
grep -v 4b76ec40c07078beaa2c5e250ed7d9bd6276a718 |\ grep -v 4b76ec40c07078beaa2c5e250ed7d9bd6276a718 |\
grep -v ffc39dfbcb34eacc3ea12327a02b6e7741a2c207 |\ grep -v ffc39dfbcb34eacc3ea12327a02b6e7741a2c207 |\
grep -v 32a76901a91ff0f663db6f0830e0aedec946e4d0 |\ grep -v 32a76901a91ff0f663db6f0830e0aedec946e4d0 |\
grep -v af3288043a49bcc28f8ae3060852a09de552fe5f |\ grep -v af3288043a49bcc28f8ae3060852a09de552fe5f
grep -v 3626003f680bad3e63677982576d3a05421e88e9
} }
print-missing-authors() { print-missing-authors() {
@@ -30,7 +29,7 @@ print-missing-authors() {
} }
print-missing-copyright() { print-missing-copyright() {
find . -name \*.go | xargs egrep -L 'Copyright|automatically generated' | grep -v Godeps | grep -v internal/auto/ find . -name \*.go | xargs egrep -L 'Copyright \(C\)|automatically generated' | grep -v Godeps | grep -v internal/auto/
} }
authors=$(print-missing-authors) authors=$(print-missing-authors)
+2 -1
View File
@@ -36,7 +36,8 @@ const (
func Assets() map[string][]byte { func Assets() map[string][]byte {
var assets = make(map[string][]byte, {{.Assets | len}}) var assets = make(map[string][]byte, {{.Assets | len}})
{{range $asset := .Assets}} {{range $asset := .Assets}}
assets["{{$asset.Name}}"], _ = base64.StdEncoding.DecodeString("{{$asset.Data}}"){{end}} assets["{{$asset.Name}}"], _ = base64.StdEncoding.DecodeString("{{$asset.Data}}")
{{end}}
return assets return assets
} }
+3 -3
View File
@@ -65,13 +65,13 @@ func main() {
fmt.Printf("[block] F:%q H:%x N:%q I:%d\n", folder, hash, name, binary.BigEndian.Uint32(it.Value())) fmt.Printf("[block] F:%q H:%x N:%q I:%d\n", folder, hash, name, binary.BigEndian.Uint32(it.Value()))
case db.KeyTypeDeviceStatistic: case db.KeyTypeDeviceStatistic:
fmt.Printf("[dstat]\n %x\n %x\n", it.Key(), it.Value()) fmt.Printf("[dstat]\n %x\n %x", it.Key(), it.Value())
case db.KeyTypeFolderStatistic: case db.KeyTypeFolderStatistic:
fmt.Printf("[fstat]\n %x\n %x\n", it.Key(), it.Value()) fmt.Printf("[fstat]\n %x\n %x", it.Key(), it.Value())
default: default:
fmt.Printf("[???]\n %x\n %x\n", it.Key(), it.Value()) fmt.Printf("[???]\n %x\n %x", it.Key(), it.Value())
} }
} }
} }
-21
View File
@@ -353,24 +353,3 @@ func (s *connectionSvc) shouldLimit(addr net.Addr) bool {
} }
return !tcpaddr.IP.IsLoopback() return !tcpaddr.IP.IsLoopback()
} }
func (s *connectionSvc) VerifyConfiguration(from, to config.Configuration) error {
return nil
}
func (s *connectionSvc) CommitConfiguration(from, to config.Configuration) bool {
// We require a restart if a device as been removed.
newDevices := make(map[protocol.DeviceID]bool, len(to.Devices))
for _, dev := range to.Devices {
newDevices[dev.DeviceID] = true
}
for _, dev := range from.Devices {
if !newDevices[dev.DeviceID] {
return false
}
}
return true
}
+2 -3
View File
@@ -12,7 +12,6 @@ import (
) )
var ( var (
debugNet = strings.Contains(os.Getenv("STTRACE"), "net") || os.Getenv("STTRACE") == "all" debugNet = strings.Contains(os.Getenv("STTRACE"), "net") || os.Getenv("STTRACE") == "all"
debugHTTP = strings.Contains(os.Getenv("STTRACE"), "http") || os.Getenv("STTRACE") == "all" debugHTTP = strings.Contains(os.Getenv("STTRACE"), "http") || os.Getenv("STTRACE") == "all"
debugSuture = strings.Contains(os.Getenv("STTRACE"), "suture") || os.Getenv("STTRACE") == "all"
) )
+57 -115
View File
@@ -49,36 +49,31 @@ var (
guiErrors = []guiError{} guiErrors = []guiError{}
guiErrorsMut = sync.NewMutex() guiErrorsMut = sync.NewMutex()
startTime = time.Now() startTime = time.Now()
eventSub *events.BufferedSubscription
) )
type apiSvc struct { type apiSvc struct {
id protocol.DeviceID cfg config.GUIConfiguration
cfg config.GUIConfiguration assetDir string
assetDir string model *model.Model
model *model.Model fss *folderSummarySvc
listener net.Listener listener net.Listener
fss *folderSummarySvc
stop chan struct{}
systemConfigMut sync.Mutex
eventSub *events.BufferedSubscription
} }
func newAPISvc(id protocol.DeviceID, cfg config.GUIConfiguration, assetDir string, m *model.Model, eventSub *events.BufferedSubscription) (*apiSvc, error) { func newAPISvc(cfg config.GUIConfiguration, assetDir string, m *model.Model) (*apiSvc, error) {
svc := &apiSvc{ svc := &apiSvc{
id: id, cfg: cfg,
cfg: cfg, assetDir: assetDir,
assetDir: assetDir, model: m,
model: m, fss: newFolderSummarySvc(m),
systemConfigMut: sync.NewMutex(),
eventSub: eventSub,
} }
var err error var err error
svc.listener, err = svc.getListener(cfg) svc.listener, err = svc.getListener()
return svc, err return svc, err
} }
func (s *apiSvc) getListener(cfg config.GUIConfiguration) (net.Listener, error) { func (s *apiSvc) getListener() (net.Listener, error) {
cert, err := tls.LoadX509KeyPair(locations[locHTTPSCertFile], locations[locHTTPSKeyFile]) cert, err := tls.LoadX509KeyPair(locations[locHTTPSCertFile], locations[locHTTPSKeyFile])
if err != nil { if err != nil {
l.Infoln("Loading HTTPS certificate:", err) l.Infoln("Loading HTTPS certificate:", err)
@@ -115,7 +110,7 @@ func (s *apiSvc) getListener(cfg config.GUIConfiguration) (net.Listener, error)
}, },
} }
rawListener, err := net.Listen("tcp", cfg.Address) rawListener, err := net.Listen("tcp", s.cfg.Address)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -125,9 +120,10 @@ func (s *apiSvc) getListener(cfg config.GUIConfiguration) (net.Listener, error)
} }
func (s *apiSvc) Serve() { func (s *apiSvc) Serve() {
s.stop = make(chan struct{})
l.AddHandler(logger.LevelWarn, s.showGuiError) l.AddHandler(logger.LevelWarn, s.showGuiError)
sub := events.Default.Subscribe(events.AllEvents)
eventSub = events.NewBufferedSubscription(sub, 1000)
defer events.Default.Unsubscribe(sub)
// The GET handlers // The GET handlers
getRestMux := http.NewServeMux() getRestMux := http.NewServeMux()
@@ -190,14 +186,14 @@ func (s *apiSvc) Serve() {
// Wrap everything in CSRF protection. The /rest prefix should be // Wrap everything in CSRF protection. The /rest prefix should be
// protected, other requests will grant cookies. // protected, other requests will grant cookies.
handler := csrfMiddleware(s.id.String()[:5], "/rest", s.cfg.APIKey, mux) handler := csrfMiddleware("/rest", s.cfg.APIKey, mux)
// Add our version and ID as a header to responses // Add our version as a header to responses
handler = withDetailsMiddleware(s.id, handler) handler = withVersionMiddleware(handler)
// Wrap everything in basic auth, if user/password is set. // Wrap everything in basic auth, if user/password is set.
if len(s.cfg.User) > 0 && len(s.cfg.Password) > 0 { if len(s.cfg.User) > 0 && len(s.cfg.Password) > 0 {
handler = basicAuthAndSessionMiddleware("sessionid-"+s.id.String()[:5], s.cfg, handler) handler = basicAuthAndSessionMiddleware(s.cfg, handler)
} }
// Redirect to HTTPS if we are supposed to // Redirect to HTTPS if we are supposed to
@@ -214,63 +210,15 @@ func (s *apiSvc) Serve() {
ReadTimeout: 10 * time.Second, ReadTimeout: 10 * time.Second,
} }
s.fss = newFolderSummarySvc(s.model)
defer s.fss.Stop()
s.fss.ServeBackground() s.fss.ServeBackground()
l.Infoln("API listening on", s.listener.Addr())
err := srv.Serve(s.listener) err := srv.Serve(s.listener)
l.Warnln("API:", err)
// The return could be due to an intentional close. Wait for the stop
// signal before returning. IF there is no stop signal within a second, we
// assume it was unintentional and log the error before retrying.
select {
case <-s.stop:
case <-time.After(time.Second):
l.Warnln("API:", err)
}
} }
func (s *apiSvc) Stop() { func (s *apiSvc) Stop() {
close(s.stop)
s.listener.Close() s.listener.Close()
} s.fss.Stop()
func (s *apiSvc) String() string {
return fmt.Sprintf("apiSvc@%p", s)
}
func (s *apiSvc) VerifyConfiguration(from, to config.Configuration) error {
return nil
}
func (s *apiSvc) CommitConfiguration(from, to config.Configuration) bool {
if to.GUI == from.GUI {
return true
}
// Order here is important. We must close the listener to stop Serve(). We
// must create a new listener before Serve() starts again. We can't create
// a new listener on the same port before the previous listener is closed.
// To assist in this little dance the Serve() method will wait for a
// signal on the stop channel after the listener has closed.
s.listener.Close()
var err error
s.listener, err = s.getListener(to.GUI)
if err != nil {
// Ideally this should be a verification error, but we check it by
// creating a new listener which requires shutting down the previous
// one first, which is too destructive for the VerifyConfiguration
// method.
return false
}
s.cfg = to.GUI
close(s.stop)
return true
} }
func getPostHandler(get, post http.Handler) http.Handler { func getPostHandler(get, post http.Handler) http.Handler {
@@ -336,10 +284,9 @@ func noCacheMiddleware(h http.Handler) http.Handler {
}) })
} }
func withDetailsMiddleware(id protocol.DeviceID, h http.Handler) http.Handler { func withVersionMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Syncthing-Version", Version) w.Header().Set("X-Syncthing-Version", Version)
w.Header().Set("X-Syncthing-ID", id.String())
h.ServeHTTP(w, r) h.ServeHTTP(w, r)
}) })
} }
@@ -428,10 +375,7 @@ func folderSummary(m *model.Model, folder string) map[string]interface{} {
res["error"] = err.Error() res["error"] = err.Error()
} }
lv, _ := m.CurrentLocalVersion(folder) res["version"] = m.CurrentLocalVersion(folder) + m.RemoteLocalVersion(folder)
rv, _ := m.RemoteLocalVersion(folder)
res["version"] = lv + rv
ignorePatterns, _, _ := m.GetIgnores(folder) ignorePatterns, _, _ := m.GetIgnores(folder)
res["ignorePatterns"] = false res["ignorePatterns"] = false
@@ -520,46 +464,49 @@ func (s *apiSvc) getSystemConfig(w http.ResponseWriter, r *http.Request) {
} }
func (s *apiSvc) postSystemConfig(w http.ResponseWriter, r *http.Request) { func (s *apiSvc) postSystemConfig(w http.ResponseWriter, r *http.Request) {
s.systemConfigMut.Lock() var newCfg config.Configuration
defer s.systemConfigMut.Unlock() err := json.NewDecoder(r.Body).Decode(&newCfg)
var to config.Configuration
err := json.NewDecoder(r.Body).Decode(&to)
if err != nil { if err != nil {
l.Warnln("decoding posted config:", err) l.Warnln("decoding posted config:", err)
http.Error(w, err.Error(), 500) http.Error(w, err.Error(), 500)
return return
} }
if to.GUI.Password != cfg.GUI().Password { if newCfg.GUI.Password != cfg.GUI().Password {
if to.GUI.Password != "" { if newCfg.GUI.Password != "" {
hash, err := bcrypt.GenerateFromPassword([]byte(to.GUI.Password), 0) hash, err := bcrypt.GenerateFromPassword([]byte(newCfg.GUI.Password), 0)
if err != nil { if err != nil {
l.Warnln("bcrypting password:", err) l.Warnln("bcrypting password:", err)
http.Error(w, err.Error(), 500) http.Error(w, err.Error(), 500)
return return
} }
to.GUI.Password = string(hash) newCfg.GUI.Password = string(hash)
} }
} }
// Fixup usage reporting settings // Start or stop usage reporting as appropriate
if curAcc := cfg.Options().URAccepted; to.Options.URAccepted > curAcc { if curAcc := cfg.Options().URAccepted; newCfg.Options.URAccepted > curAcc {
// UR was enabled // UR was enabled
to.Options.URAccepted = usageReportVersion newCfg.Options.URAccepted = usageReportVersion
to.Options.URUniqueID = randomString(8) newCfg.Options.URUniqueID = randomString(8)
} else if to.Options.URAccepted < curAcc { err := sendUsageReport(s.model)
if err != nil {
l.Infoln("Usage report:", err)
}
go usageReportingLoop(s.model)
} else if newCfg.Options.URAccepted < curAcc {
// UR was disabled // UR was disabled
to.Options.URAccepted = -1 newCfg.Options.URAccepted = -1
to.Options.URUniqueID = "" newCfg.Options.URUniqueID = ""
stopUsageReporting()
} }
// Activate and save // Activate and save
resp := cfg.Replace(to) configInSync = !config.ChangeRequiresRestart(cfg.Raw(), newCfg)
configInSync = !resp.RequiresRestart cfg.Replace(newCfg)
cfg.Save() cfg.Save()
} }
@@ -576,26 +523,21 @@ func (s *apiSvc) postSystemRestart(w http.ResponseWriter, r *http.Request) {
func (s *apiSvc) postSystemReset(w http.ResponseWriter, r *http.Request) { func (s *apiSvc) postSystemReset(w http.ResponseWriter, r *http.Request) {
var qs = r.URL.Query() var qs = r.URL.Query()
folder := qs.Get("folder") folder := qs.Get("folder")
var err error
if len(folder) > 0 { if len(folder) == 0 {
if _, ok := cfg.Folders()[folder]; !ok { err = resetDB()
http.Error(w, "Invalid folder ID", 500) } else {
return err = s.model.ResetFolder(folder)
}
} }
if err != nil {
http.Error(w, err.Error(), 500)
return
}
if len(folder) == 0 { if len(folder) == 0 {
// Reset all folders.
for folder := range cfg.Folders() {
s.model.ResetFolder(folder)
}
s.flushResponse(`{"ok": "resetting database"}`, w) s.flushResponse(`{"ok": "resetting database"}`, w)
} else { } else {
// Reset a specific folder, assuming it's supposed to exist. s.flushResponse(`{"ok": "resetting folder " + folder}`, w)
s.model.ResetFolder(folder)
s.flushResponse(`{"ok": "resetting folder `+folder+`"}`, w)
} }
go restart() go restart()
} }
@@ -752,7 +694,7 @@ func (s *apiSvc) getEvents(w http.ResponseWriter, r *http.Request) {
f := w.(http.Flusher) f := w.(http.Flusher)
f.Flush() f.Flush()
evs := s.eventSub.Since(since, nil) evs := eventSub.Since(since, nil)
if 0 < limit && limit < len(evs) { if 0 < limit && limit < len(evs) {
evs = evs[len(evs)-limit:] evs = evs[len(evs)-limit:]
} }
+3 -4
View File
@@ -24,15 +24,14 @@ var (
sessionsMut = sync.NewMutex() sessionsMut = sync.NewMutex()
) )
func basicAuthAndSessionMiddleware(cookieName string, cfg config.GUIConfiguration, next http.Handler) http.Handler { func basicAuthAndSessionMiddleware(cfg config.GUIConfiguration, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if cfg.APIKey != "" && r.Header.Get("X-API-Key") == cfg.APIKey { if cfg.APIKey != "" && r.Header.Get("X-API-Key") == cfg.APIKey {
next.ServeHTTP(w, r) next.ServeHTTP(w, r)
return return
} }
cookie, err := r.Cookie(cookieName) cookie, err := r.Cookie("sessionid")
if err == nil && cookie != nil { if err == nil && cookie != nil {
sessionsMut.Lock() sessionsMut.Lock()
_, ok := sessions[cookie.Value] _, ok := sessions[cookie.Value]
@@ -87,7 +86,7 @@ func basicAuthAndSessionMiddleware(cookieName string, cfg config.GUIConfiguratio
sessions[sessionid] = true sessions[sessionid] = true
sessionsMut.Unlock() sessionsMut.Unlock()
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{
Name: cookieName, Name: "sessionid",
Value: sessionid, Value: sessionid,
MaxAge: 0, MaxAge: 0,
}) })
+4 -4
View File
@@ -24,7 +24,7 @@ var csrfMut = sync.NewMutex()
// Check for CSRF token on /rest/ URLs. If a correct one is not given, reject // Check for CSRF token on /rest/ URLs. If a correct one is not given, reject
// the request with 403. For / and /index.html, set a new CSRF cookie if none // the request with 403. For / and /index.html, set a new CSRF cookie if none
// is currently set. // is currently set.
func csrfMiddleware(unique, prefix, apiKey string, next http.Handler) http.Handler { func csrfMiddleware(prefix, apiKey string, next http.Handler) http.Handler {
loadCsrfTokens() loadCsrfTokens()
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Allow requests carrying a valid API key // Allow requests carrying a valid API key
@@ -35,10 +35,10 @@ func csrfMiddleware(unique, prefix, apiKey string, next http.Handler) http.Handl
// Allow requests for the front page, and set a CSRF cookie if there isn't already a valid one. // Allow requests for the front page, and set a CSRF cookie if there isn't already a valid one.
if !strings.HasPrefix(r.URL.Path, prefix) { if !strings.HasPrefix(r.URL.Path, prefix) {
cookie, err := r.Cookie("CSRF-Token-" + unique) cookie, err := r.Cookie("CSRF-Token")
if err != nil || !validCsrfToken(cookie.Value) { if err != nil || !validCsrfToken(cookie.Value) {
cookie = &http.Cookie{ cookie = &http.Cookie{
Name: "CSRF-Token-" + unique, Name: "CSRF-Token",
Value: newCsrfToken(), Value: newCsrfToken(),
} }
http.SetCookie(w, cookie) http.SetCookie(w, cookie)
@@ -54,7 +54,7 @@ func csrfMiddleware(unique, prefix, apiKey string, next http.Handler) http.Handl
} }
// Verify the CSRF token // Verify the CSRF token
token := r.Header.Get("X-CSRF-Token-" + unique) token := r.Header.Get("X-CSRF-Token")
if !validCsrfToken(token) { if !validCsrfToken(token) {
http.Error(w, "CSRF Error", 403) http.Error(w, "CSRF Error", 403)
return return
-2
View File
@@ -31,7 +31,6 @@ const (
locCsrfTokens = "csrfTokens" locCsrfTokens = "csrfTokens"
locPanicLog = "panicLog" locPanicLog = "panicLog"
locAuditLog = "auditLog" locAuditLog = "auditLog"
locGUIAssets = "GUIAssets"
locDefFolder = "defFolder" locDefFolder = "defFolder"
) )
@@ -53,7 +52,6 @@ var locations = map[locationEnum]string{
locCsrfTokens: "${config}/csrftokens.txt", locCsrfTokens: "${config}/csrftokens.txt",
locPanicLog: "${config}/panic-${timestamp}.log", locPanicLog: "${config}/panic-${timestamp}.log",
locAuditLog: "${config}/audit-${timestamp}.log", locAuditLog: "${config}/audit-${timestamp}.log",
locGUIAssets: "${config}/gui",
locDefFolder: "${home}/Sync", locDefFolder: "${home}/Sync",
} }
+52 -73
View File
@@ -155,7 +155,6 @@ are mostly useful for developers. Use with care.
- "model" (the model package) - "model" (the model package)
- "scanner" (the scanner package) - "scanner" (the scanner package)
- "stats" (the stats package) - "stats" (the stats package)
- "suture" (the suture package; service management)
- "upnp" (the upnp package) - "upnp" (the upnp package)
- "xdr" (the xdr package) - "xdr" (the xdr package)
- "all" (all of the above) - "all" (all of the above)
@@ -252,10 +251,6 @@ func main() {
l.Fatalln(err) l.Fatalln(err)
} }
if guiAssets == "" {
guiAssets = locations[locGUIAssets]
}
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
if logFile == "" { if logFile == "" {
// Use the default log file location // Use the default log file location
@@ -284,7 +279,7 @@ func main() {
l.Fatalln(dir, "is not a directory") l.Fatalln(dir, "is not a directory")
} }
if err != nil && os.IsNotExist(err) { if err != nil && os.IsNotExist(err) {
err = osutil.MkdirAll(dir, 0700) err = os.MkdirAll(dir, 0700)
if err != nil { if err != nil {
l.Fatalln("generate:", err) l.Fatalln("generate:", err)
} }
@@ -425,12 +420,11 @@ func upgradeViaRest() error {
func syncthingMain() { func syncthingMain() {
// Create a main service manager. We'll add things to this as we go along. // Create a main service manager. We'll add things to this as we go along.
// We want any logging it does to go through our log system. // We want any logging it does to go through our log system, with INFO
// severity.
mainSvc := suture.New("main", suture.Spec{ mainSvc := suture.New("main", suture.Spec{
Log: func(line string) { Log: func(line string) {
if debugSuture { l.Infoln(line)
l.Debugln(line)
}
}, },
}) })
mainSvc.ServeBackground() mainSvc.ServeBackground()
@@ -447,13 +441,12 @@ func syncthingMain() {
mainSvc.Add(newVerboseSvc()) mainSvc.Add(newVerboseSvc())
} }
// Event subscription for the API; must start early to catch the early events.
apiSub := events.NewBufferedSubscription(events.Default.Subscribe(events.AllEvents), 1000)
if len(os.Getenv("GOMAXPROCS")) == 0 { if len(os.Getenv("GOMAXPROCS")) == 0 {
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())
} }
events.Default.Log(events.Starting, map[string]string{"home": baseDirs["config"]})
// Ensure that that we have a certificate and key. // Ensure that that we have a certificate and key.
cert, err := tls.LoadX509KeyPair(locations[locCertFile], locations[locKeyFile]) cert, err := tls.LoadX509KeyPair(locations[locCertFile], locations[locKeyFile])
if err != nil { if err != nil {
@@ -473,13 +466,6 @@ func syncthingMain() {
l.Infoln(LongVersion) l.Infoln(LongVersion)
l.Infoln("My ID:", myID) l.Infoln("My ID:", myID)
// Emit the Starting event, now that we know who we are.
events.Default.Log(events.Starting, map[string]string{
"home": baseDirs["config"],
"myID": myID.String(),
})
// Prepare to be able to save configuration // Prepare to be able to save configuration
cfgFile := locations[locConfigFile] cfgFile := locations[locConfigFile]
@@ -565,9 +551,6 @@ func syncthingMain() {
symlinks.Supported = false symlinks.Supported = false
} }
protocol.PingTimeout = time.Duration(opts.PingTimeoutS) * time.Second
protocol.PingIdleTime = time.Duration(opts.PingIdleTimeS) * time.Second
if opts.MaxSendKbps > 0 { if opts.MaxSendKbps > 0 {
writeRateLimit = ratelimit.NewBucketWithRate(float64(1000*opts.MaxSendKbps), int64(5*1000*opts.MaxSendKbps)) writeRateLimit = ratelimit.NewBucketWithRate(float64(1000*opts.MaxSendKbps), int64(5*1000*opts.MaxSendKbps))
} }
@@ -603,7 +586,6 @@ func syncthingMain() {
} }
m := model.NewModel(cfg, myID, myName, "syncthing", Version, ldb) m := model.NewModel(cfg, myID, myName, "syncthing", Version, ldb)
cfg.Subscribe(m)
if t := os.Getenv("STDEADLOCKTIMEOUT"); len(t) > 0 { if t := os.Getenv("STDEADLOCKTIMEOUT"); len(t) > 0 {
it, err := strconv.Atoi(t) it, err := strconv.Atoi(t)
@@ -614,6 +596,10 @@ func syncthingMain() {
m.StartDeadlockDetector(20 * 60 * time.Second) m.StartDeadlockDetector(20 * 60 * time.Second)
} }
// GUI
setupGUI(mainSvc, cfg, m)
// Clear out old indexes for other devices. Otherwise we'll start up and // Clear out old indexes for other devices. Otherwise we'll start up and
// start needing a bunch of files which are nowhere to be found. This // start needing a bunch of files which are nowhere to be found. This
// needs to be changed when we correctly do persistent indexes. // needs to be changed when we correctly do persistent indexes.
@@ -625,23 +611,8 @@ func syncthingMain() {
} }
m.Index(device, folderCfg.ID, nil, 0, nil) m.Index(device, folderCfg.ID, nil, 0, nil)
} }
// Routine to pull blocks from other devices to synchronize the local
// folder. Does not run when we are in read only (publish only) mode.
if folderCfg.ReadOnly {
l.Okf("Ready to synchronize %s (read only; no external updates accepted)", folderCfg.ID)
m.StartFolderRO(folderCfg.ID)
} else {
l.Okf("Ready to synchronize %s (read-write)", folderCfg.ID)
m.StartFolderRW(folderCfg.ID)
}
} }
mainSvc.Add(m)
// GUI
setupGUI(mainSvc, cfg, m, apiSub)
// The default port we announce, possibly modified by setupUPnP next. // The default port we announce, possibly modified by setupUPnP next.
addr, err := net.ResolveTCPAddr("tcp", opts.ListenAddress[0]) addr, err := net.ResolveTCPAddr("tcp", opts.ListenAddress[0])
@@ -663,9 +634,20 @@ func syncthingMain() {
} }
connectionSvc := newConnectionSvc(cfg, myID, m, tlsCfg) connectionSvc := newConnectionSvc(cfg, myID, m, tlsCfg)
cfg.Subscribe(connectionSvc)
mainSvc.Add(connectionSvc) mainSvc.Add(connectionSvc)
for _, folder := range cfg.Folders() {
// Routine to pull blocks from other devices to synchronize the local
// folder. Does not run when we are in read only (publish only) mode.
if folder.ReadOnly {
l.Okf("Ready to synchronize %s (read only; no external updates accepted)", folder.ID)
m.StartFolderRO(folder.ID)
} else {
l.Okf("Ready to synchronize %s (read-write)", folder.ID)
m.StartFolderRW(folder.ID)
}
}
if cpuProfile { if cpuProfile {
f, err := os.Create(fmt.Sprintf("cpu-%d.pprof", os.Getpid())) f, err := os.Create(fmt.Sprintf("cpu-%d.pprof", os.Getpid()))
if err != nil { if err != nil {
@@ -695,13 +677,16 @@ func syncthingMain() {
cfg.SetOptions(opts) cfg.SetOptions(opts)
cfg.Save() cfg.Save()
} }
go usageReportingLoop(m)
go func() {
time.Sleep(10 * time.Minute)
err := sendUsageReport(m)
if err != nil {
l.Infoln("Usage report:", err)
}
}()
} }
// The usageReportingManager registers itself to listen to configuration
// changes, and there's nothing more we need to tell it from the outside.
// Hence we don't keep the returned pointer.
newUsageReportingManager(m, cfg)
if opts.RestartOnWakeup { if opts.RestartOnWakeup {
go standbyMonitor() go standbyMonitor()
} }
@@ -716,9 +701,7 @@ func syncthingMain() {
} }
} }
events.Default.Log(events.StartupComplete, map[string]string{ events.Default.Log(events.StartupComplete, nil)
"myID": myID.String(),
})
go generatePingEvents() go generatePingEvents()
cleanConfigDirectory() cleanConfigDirectory()
@@ -732,28 +715,25 @@ func syncthingMain() {
} }
func dbOpts() *opt.Options { func dbOpts() *opt.Options {
// Calculate a suitable database block cache capacity. // Calculate a sutiable database block cache capacity. We start at the
// default of 8 MiB and use larger values for machines with more memory.
// In reality, the database will use twice the amount we calculate here,
// as it also has two write buffers each sized at half the block cache.
// Default is 8 MiB.
blockCacheCapacity := 8 << 20 blockCacheCapacity := 8 << 20
// Increase block cache up to this maximum: if bytes, err := memorySize(); err == nil {
const maxCapacity = 64 << 20 if bytes > 74<<30 {
// ... which we reach when the box has this much RAM: // At 74 GiB of RAM, we hit a 256 MiB block cache (per the
const maxAtRAM = 8 << 30 // calculations below). There's probably no point in growing the
// cache beyond this point.
if v := cfg.Options().DatabaseBlockCacheMiB; v != 0 { blockCacheCapacity = 256 << 20
// Use the value from the config, if it's set. } else if bytes > 8<<30 {
blockCacheCapacity = v << 20 // Slowly grow from 128 MiB at 8 GiB of RAM up to 256 MiB for a
} else if bytes, err := memorySize(); err == nil { // ~74 GiB RAM machine
// We start at the default of 8 MiB and use larger values for machines blockCacheCapacity = int(bytes/512) + 128 - 16
// with more memory. } else if bytes > 512<<20 {
// Grow from 8 MiB at start to 128 MiB of cache at 8 GiB of RAM.
if bytes > maxAtRAM { blockCacheCapacity = int(bytes / 64)
// Cap the cache at maxCapacity when we reach maxAtRam amount of memory
blockCacheCapacity = maxCapacity
} else if bytes > maxAtRAM/maxCapacity*int64(blockCacheCapacity) {
// Grow from the default to maxCapacity at maxAtRam amount of memory
blockCacheCapacity = int(bytes * maxCapacity / maxAtRAM)
} }
l.Infoln("Database block cache capacity", blockCacheCapacity/1024, "KiB") l.Infoln("Database block cache capacity", blockCacheCapacity/1024, "KiB")
} }
@@ -761,7 +741,7 @@ func dbOpts() *opt.Options {
return &opt.Options{ return &opt.Options{
OpenFilesCacheCapacity: 100, OpenFilesCacheCapacity: 100,
BlockCacheCapacity: blockCacheCapacity, BlockCacheCapacity: blockCacheCapacity,
WriteBuffer: 4 << 20, WriteBuffer: blockCacheCapacity / 2,
} }
} }
@@ -782,7 +762,7 @@ func startAuditing(mainSvc *suture.Supervisor) {
l.Infoln("Audit log in", auditFile) l.Infoln("Audit log in", auditFile)
} }
func setupGUI(mainSvc *suture.Supervisor, cfg *config.Wrapper, m *model.Model, apiSub *events.BufferedSubscription) { func setupGUI(mainSvc *suture.Supervisor, cfg *config.Wrapper, m *model.Model) {
opts := cfg.Options() opts := cfg.Options()
guiCfg := overrideGUIConfig(cfg.GUI(), guiAddress, guiAuthentication, guiAPIKey) guiCfg := overrideGUIConfig(cfg.GUI(), guiAddress, guiAuthentication, guiAPIKey)
@@ -811,11 +791,10 @@ func setupGUI(mainSvc *suture.Supervisor, cfg *config.Wrapper, m *model.Model, a
urlShow := fmt.Sprintf("%s://%s/", proto, net.JoinHostPort(hostShow, strconv.Itoa(addr.Port))) urlShow := fmt.Sprintf("%s://%s/", proto, net.JoinHostPort(hostShow, strconv.Itoa(addr.Port)))
l.Infoln("Starting web GUI on", urlShow) l.Infoln("Starting web GUI on", urlShow)
api, err := newAPISvc(myID, guiCfg, guiAssets, m, apiSub) api, err := newAPISvc(guiCfg, guiAssets, m)
if err != nil { if err != nil {
l.Fatalln("Cannot start GUI:", err) l.Fatalln("Cannot start GUI:", err)
} }
cfg.Subscribe(api)
mainSvc.Add(api) mainSvc.Add(api)
if opts.StartBrowser && !noBrowser && !stRestarting { if opts.StartBrowser && !noBrowser && !stRestarting {
@@ -901,7 +880,7 @@ func discovery(extPort int) *discover.Discoverer {
func ensureDir(dir string, mode int) { func ensureDir(dir string, mode int) {
fi, err := os.Stat(dir) fi, err := os.Stat(dir)
if os.IsNotExist(err) { if os.IsNotExist(err) {
err := osutil.MkdirAll(dir, 0700) err := os.MkdirAll(dir, 0700)
if err != nil { if err != nil {
l.Fatalln(err) l.Fatalln(err)
} }
+2 -6
View File
@@ -7,7 +7,6 @@
package main package main
import ( import (
"runtime"
"sync" "sync"
"testing" "testing"
) )
@@ -15,13 +14,10 @@ import (
var predictableRandomTest sync.Once var predictableRandomTest sync.Once
func TestPredictableRandom(t *testing.T) { func TestPredictableRandom(t *testing.T) {
if runtime.GOARCH != "amd64" {
t.Skip("Test only for 64 bit platforms; but if it works there, it should work on 32 bit")
}
predictableRandomTest.Do(func() { predictableRandomTest.Do(func() {
// predictable random sequence is predictable // predictable random sequence is predictable
e := int64(3440579354231278675) e := 3440579354231278675
if v := int64(predictableRandom.Int()); v != e { if v := predictableRandom.Int(); v != e {
t.Errorf("Unexpected random value %d != %d", v, e) t.Errorf("Unexpected random value %d != %d", v, e)
} }
}) })
+2 -4
View File
@@ -79,10 +79,8 @@ func (s *upnpSvc) tryIGDs(igds []upnp.IGD, prevExtPort int) int {
// External port changed; refresh the discovery announcement. // External port changed; refresh the discovery announcement.
// TODO: Don't reach out to some magic global here? // TODO: Don't reach out to some magic global here?
l.Infof("New UPnP port mapping: external port %d to local port %d.", extPort, s.localPort) l.Infof("New UPnP port mapping: external port %d to local port %d.", extPort, s.localPort)
if s.cfg.Options().GlobalAnnEnabled { discoverer.StopGlobal()
discoverer.StopGlobal() discoverer.StartGlobal(s.cfg.Options().GlobalAnnServers, uint16(extPort))
discoverer.StartGlobal(s.cfg.Options().GlobalAnnServers, uint16(extPort))
}
} }
if debugNet { if debugNet {
l.Debugf("Created/updated UPnP port mapping for external port %d on device %s.", extPort, igd.FriendlyIdentifier()) l.Debugf("Created/updated UPnP port mapping for external port %d on device %s.", extPort, igd.FriendlyIdentifier())
+18 -72
View File
@@ -11,15 +11,12 @@ import (
"crypto/rand" "crypto/rand"
"crypto/sha256" "crypto/sha256"
"encoding/json" "encoding/json"
"fmt"
"net" "net"
"net/http" "net/http"
"runtime" "runtime"
"time" "time"
"github.com/syncthing/syncthing/internal/config"
"github.com/syncthing/syncthing/internal/model" "github.com/syncthing/syncthing/internal/model"
"github.com/thejerf/suture"
) )
// Current version number of the usage report, for acceptance purposes. If // Current version number of the usage report, for acceptance purposes. If
@@ -27,54 +24,8 @@ import (
// are prompted for acceptance of the new report. // are prompted for acceptance of the new report.
const usageReportVersion = 1 const usageReportVersion = 1
type usageReportingManager struct { var stopUsageReportingCh = make(chan struct{})
model *model.Model
sup *suture.Supervisor
}
func newUsageReportingManager(m *model.Model, cfg *config.Wrapper) *usageReportingManager {
mgr := &usageReportingManager{
model: m,
}
// Start UR if it's enabled.
mgr.CommitConfiguration(config.Configuration{}, cfg.Raw())
// Listen to future config changes so that we can start and stop as
// appropriate.
cfg.Subscribe(mgr)
return mgr
}
func (m *usageReportingManager) VerifyConfiguration(from, to config.Configuration) error {
return nil
}
func (m *usageReportingManager) CommitConfiguration(from, to config.Configuration) bool {
if to.Options.URAccepted >= usageReportVersion && m.sup == nil {
// Usage reporting was turned on; lets start it.
svc := &usageReportingService{
model: m.model,
}
m.sup = suture.NewSimple("usageReporting")
m.sup.Add(svc)
m.sup.ServeBackground()
} else if to.Options.URAccepted < usageReportVersion && m.sup != nil {
// Usage reporting was turned off
m.sup.Stop()
m.sup = nil
}
return true
}
func (m *usageReportingManager) String() string {
return fmt.Sprintf("usageReportingManager@%p", m)
}
// reportData returns the data to be sent in a usage report. It's used in
// various places, so not part of the usageReportingSvc object.
func reportData(m *model.Model) map[string]interface{} { func reportData(m *model.Model) map[string]interface{} {
res := make(map[string]interface{}) res := make(map[string]interface{})
res["uniqueID"] = cfg.Options().URUniqueID res["uniqueID"] = cfg.Options().URUniqueID
@@ -124,13 +75,8 @@ func reportData(m *model.Model) map[string]interface{} {
return res return res
} }
type usageReportingService struct { func sendUsageReport(m *model.Model) error {
model *model.Model d := reportData(m)
stop chan struct{}
}
func (s *usageReportingService) sendUsageReport() error {
d := reportData(s.model)
var b bytes.Buffer var b bytes.Buffer
json.NewEncoder(&b).Encode(d) json.NewEncoder(&b).Encode(d)
@@ -148,32 +94,32 @@ func (s *usageReportingService) sendUsageReport() error {
return err return err
} }
func (s *usageReportingService) Serve() { func usageReportingLoop(m *model.Model) {
s.stop = make(chan struct{})
l.Infoln("Starting usage reporting") l.Infoln("Starting usage reporting")
defer l.Infoln("Stopping usage reporting") t := time.NewTicker(86400 * time.Second)
loop:
t := time.NewTimer(10 * time.Minute) // time to initial report at start
for { for {
select { select {
case <-s.stop: case <-stopUsageReportingCh:
return break loop
case <-t.C: case <-t.C:
err := s.sendUsageReport() err := sendUsageReport(m)
if err != nil { if err != nil {
l.Infoln("Usage report:", err) l.Infoln("Usage report:", err)
} }
t.Reset(24 * time.Hour) // next report tomorrow
} }
} }
l.Infoln("Stopping usage reporting")
}
func stopUsageReporting() {
select {
case stopUsageReportingCh <- struct{}{}:
default:
}
} }
func (s *usageReportingService) Stop() { // Returns CPU performance as a measure of single threaded SHA-256 MiB/s
close(s.stop)
}
// cpuBench returns CPU performance as a measure of single threaded SHA-256 MiB/s
func cpuBench() float64 { func cpuBench() float64 {
chunkSize := 100 * 1 << 10 chunkSize := 100 * 1 << 10
h := sha256.New() h := sha256.New()
+2 -5
View File
@@ -102,11 +102,8 @@ func (s *verboseSvc) formatEvent(ev events.Event) string {
return fmt.Sprintf("Started syncing %q / %q (%v %v)", data["folder"], data["item"], data["action"], data["type"]) return fmt.Sprintf("Started syncing %q / %q (%v %v)", data["folder"], data["item"], data["action"], data["type"])
case events.ItemFinished: case events.ItemFinished:
data := ev.Data.(map[string]interface{}) data := ev.Data.(map[string]interface{})
if err, ok := data["error"].(*string); ok && err != nil { if err := data["err"]; err != nil {
// If the err interface{} is not nil, it is a string pointer. return fmt.Sprintf("Finished syncing %q / %q (%v %v): %v", data["folder"], data["item"], data["action"], data["type"], err)
// Dereference it to get the actual error or Sprintf will print
// the pointer value....
return fmt.Sprintf("Finished syncing %q / %q (%v %v): %v", data["folder"], data["item"], data["action"], data["type"], *err)
} }
return fmt.Sprintf("Finished syncing %q / %q (%v %v): Success", data["folder"], data["item"], data["action"], data["type"]) return fmt.Sprintf("Finished syncing %q / %q (%v %v): Success", data["folder"], data["item"], data["action"], data["type"])
+1 -31
View File
@@ -51,8 +51,6 @@ func main() {
} }
resp.Body.Close() resp.Body.Close()
names := make(map[string]string)
var langs []string var langs []string
for code, stat := range stats { for code, stat := range stats {
code = strings.Replace(code, "_", "-", 1) code = strings.Replace(code, "_", "-", 1)
@@ -64,7 +62,6 @@ func main() {
} }
langs = append(langs, code) langs = append(langs, code)
names[code] = languageName(code)
if code == "en" { if code == "en" {
continue continue
} }
@@ -88,7 +85,6 @@ func main() {
} }
saveValidLangs(langs) saveValidLangs(langs)
saveLanguageNames(names)
} }
func saveValidLangs(langs []string) { func saveValidLangs(langs []string) {
@@ -102,16 +98,6 @@ func saveValidLangs(langs []string) {
fd.Close() fd.Close()
} }
func saveLanguageNames(names map[string]string) {
fd, err := os.Create("prettyprint.js")
if err != nil {
log.Fatal(err)
}
fmt.Fprint(fd, "var langPrettyprint = ")
json.NewEncoder(fd).Encode(names)
fd.Close()
}
func userPass() (string, string) { func userPass() (string, string) {
user := os.Getenv("TRANSIFEX_USER") user := os.Getenv("TRANSIFEX_USER")
pass := os.Getenv("TRANSIFEX_PASS") pass := os.Getenv("TRANSIFEX_PASS")
@@ -145,7 +131,7 @@ func loadValidLangs() []string {
} }
var langs []string var langs []string
exp := regexp.MustCompile(`\[([a-zA-Z@",-]+)\]`) exp := regexp.MustCompile(`\[([a-zA-Z",-]+)\]`)
if matches := exp.FindSubmatch(bs); len(matches) == 2 { if matches := exp.FindSubmatch(bs); len(matches) == 2 {
langs = strings.Split(string(matches[1]), ",") langs = strings.Split(string(matches[1]), ",")
for i := range langs { for i := range langs {
@@ -156,19 +142,3 @@ func loadValidLangs() []string {
return langs return langs
} }
type languageResponse struct {
Code string
Name string
}
func languageName(code string) string {
var lang languageResponse
resp := req("https://www.transifex.com/api/2/language/" + code)
defer resp.Body.Close()
json.NewDecoder(resp.Body).Decode(&lang)
if lang.Name == "" {
return code
}
return lang.Name
}
+1 -1
View File
@@ -5,4 +5,4 @@ This directory contains configuration files for running syncthing under the
systemd user service. For further documentation take a look at the [systemd systemd user service. For further documentation take a look at the [systemd
section][1] on the Github Wiki. section][1] on the Github Wiki.
[1]: http://docs.syncthing.net/users/autostart.html?highlight=systemd [1]: https://github.com/syncthing/syncthing/wiki/Autostart-syncthing#systemd
+1 -1
View File
@@ -1,6 +1,6 @@
[Unit] [Unit]
Description=Syncthing - Open Source Continuous File Synchronization for %I Description=Syncthing - Open Source Continuous File Synchronization for %I
Documentation=http://docs.syncthing.net/ Documentation=https://github.com/syncthing/syncthing/wiki
After=network.target After=network.target
[Service] [Service]
+1 -1
View File
@@ -1,6 +1,6 @@
[Unit] [Unit]
Description=Syncthing - Open Source Continuous File Synchronization Description=Syncthing - Open Source Continuous File Synchronization
Documentation=http://docs.syncthing.net/ Documentation=https://github.com/syncthing/syncthing/wiki
After=network.target After=network.target
[Service] [Service]
+6 -12
View File
@@ -68,7 +68,7 @@ identicon {
} }
.panel-heading .glyphicon { .panel-heading .glyphicon {
margin-right: 10px; margin-right: 15px;
} }
.panel-heading { .panel-heading {
@@ -153,33 +153,27 @@ table.table-condensed td {
padding-right: 15px; padding-right: 15px;
} }
/** /**
* Menu for select language * Menu for select language
*/ */
@media (min-width:480px) and (max-width:649px) { @media (min-width:480px) {
*[language-select] > .dropdown-menu {
width: 230px;
}
}
@media (min-width:650px) {
*[language-select] > .dropdown-menu > li { *[language-select] > .dropdown-menu > li {
width: 50%; width: 50%;
float: left; float: left;
} }
*[language-select] > .dropdown-menu { *[language-select] > .dropdown-menu {
width: 440px; width: 400px;
} }
} }
@media (max-width:479px) { @media (max-width:479px) {
.dropdown-menu { .dropdown-menu {
padding-top: 55px; padding-top: 55px;
} }
nav .dropdown-toggle { *[language-select] > .dropdown-toggle {
font-size: 14px; font-size: 14px;
} }
@@ -245,7 +239,7 @@ ul.three-columns li, ul.two-columns li {
/** Footer nav on small devices **/ /** Footer nav on small devices **/
@media (max-width: 991px) { @media (max-width: 767px) {
body { body {
padding-bottom: 0; padding-bottom: 0;
} }
+186
View File
@@ -0,0 +1,186 @@
{
"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": "Аб праграме",
"Add": "Дадаць",
"Add Device": "Дадаць прыладу",
"Add Folder": "Дадаць каталёг",
"Add new folder?": "Дадаць новы каталёг ?",
"Address": "Адрас",
"Addresses": "Адрасы",
"All Data": "All Data",
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
"Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the synced folder.": "An external command handles the versioning. It has to remove the file from the synced folder.",
"Anonymous Usage Reporting": "Anonymous Usage Reporting",
"Any devices configured on an introducer device will be added to this device as well.": "Any devices configured on an introducer device will be added to this device as well.",
"Automatic upgrades": "Automatic upgrades",
"Bugs": "Памылкі",
"CPU Utilization": "Выкарыстаньне працэсара",
"Changelog": "Сьпіс зьменаў",
"Close": "Зачыніць",
"Command": "Command",
"Comment, when used at the start of a line": "Comment, when used at the start of a line",
"Compression": "Compression",
"Connection Error": "Connection Error",
"Copied from elsewhere": "Copied from elsewhere",
"Copied from original": "Copied from original",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
"Delete": "Выдаліць",
"Device ID": "ID прылады",
"Device Identification": "Ідэнтыфікацыя прылады",
"Device Name": "Назва прылады",
"Device {%device%} ({%address%}) wants to connect. Add new device?": "Device {{device}} ({{address}}) wants to connect. Add new device?",
"Devices": "Прылады",
"Disconnected": "Адлучана",
"Documentation": "Дакумэнтацыя",
"Download Rate": "Хуткасьць спампоўваньня",
"Downloaded": "Downloaded",
"Downloading": "Downloading",
"Edit": "Зьмяніць",
"Edit Device": "Зьмяніць прыладу",
"Edit Folder": "Зьмяніць каталёг",
"Editing": "Editing",
"Enable UPnP": "Enable UPnP",
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.",
"Enter ignore patterns, one per line.": "Enter ignore patterns, one per line.",
"Error": "Error",
"External File Versioning": "External File Versioning",
"File Pull Order": "File Pull Order",
"File Versioning": "Вэрсіі файлаў",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by 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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.",
"Folder ID": "ID каталёгу",
"Folder Master": "Folder Master",
"Folder Path": "Шлях каталёгу",
"Folders": "Каталёгі",
"GUI Authentication Password": "GUI Authentication Password",
"GUI Authentication User": "GUI Authentication User",
"GUI Listen Addresses": "GUI Listen Addresses",
"Generate": "Сгенераваць",
"Global Discovery": "Глябальнае вызначэньне",
"Global Discovery Server": "Сэрвер глябальнага вызначэньня",
"Global State": "Глябальны стан",
"Ignore": "Ignore",
"Ignore Patterns": "Ігнараваць шаблёны",
"Ignore Permissions": "Ігнараваць правы",
"Incoming Rate Limit (KiB/s)": "Incoming Rate Limit (KiB/s)",
"Introducer": "Introducer",
"Inversion of the given condition (i.e. do not exclude)": "Inversion of the given condition (i.e. do not exclude)",
"Keep Versions": "Трымаць вэрсій",
"Largest First": "Largest First",
"Last File Received": "Апошні атрыманы файл",
"Last seen": "Апошні раз бачылі",
"Later": "Later",
"Local Discovery": "Лякальнае вызначэньне",
"Local State": "Лякальны стан",
"Major Upgrade": "Major Upgrade",
"Maximum Age": "Maximum Age",
"Metadata Only": "Metadata Only",
"Move to top of queue": "Move to top of queue",
"Multi level wildcard (matches multiple directory levels)": "Multi level wildcard (matches multiple directory levels)",
"Never": "Ніколі",
"New Device": "New Device",
"New Folder": "New Folder",
"Newest First": "Newest First",
"No": "Не",
"No File Versioning": "Не захоўваць вэрсіі",
"Notice": "Notice",
"OK": "Добра",
"Off": "Off",
"Oldest First": "Oldest First",
"Out Of Sync": "Несынхранізавана",
"Out of Sync Items": "Несынхранізаваныя складнікі",
"Outgoing Rate Limit (KiB/s)": "Outgoing Rate Limit (KiB/s)",
"Override Changes": "Override Changes",
"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 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 folder in the folder).": "Path where versions should be stored (leave empty for the default .stversions folder in the folder).",
"Please consult the release notes before performing a major upgrade.": "Please consult the release notes before performing a major upgrade.",
"Please wait": "Please wait",
"Preview": "Preview",
"Preview Usage Report": "Preview Usage Report",
"Quick guide to supported patterns": "Quick guide to supported patterns",
"RAM Utilization": "Выкарыстаньне памяці",
"Random": "Random",
"Release Notes": "Release Notes",
"Rescan": "Перачытаць",
"Rescan All": "Rescan All",
"Rescan Interval": "Інтэрвал перачытваньня",
"Restart": "Перастартаваць",
"Restart Needed": "Патрэбна перастартоўваньне",
"Restarting": "Перастартоўваньне",
"Reused": "Reused",
"Save": "Захаваць",
"Scanning": "Скануецца",
"Select the devices to share this folder with.": "Пазначце прылады зь якімі трэба абагуліць гэты каталёг.",
"Select the folders to share with this device.": "Пазначце каталёгі якія трэба абагуліць з гэтай прыладай.",
"Settings": "Налады",
"Share": "Абагуліць",
"Share Folder": "Share Folder",
"Share Folders With Device": "Share Folders With Device",
"Share With Devices": "Абагуліць з прыладамі",
"Share this folder?": "Абагуліць гэты каталёг ?",
"Shared With": "Абагулены з",
"Short identifier for the folder. Must be the same on all cluster devices.": "Short identifier for the folder. Must be the same on all cluster devices.",
"Show ID": "Паказаць ID",
"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 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.": "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 File Versioning": "Простае захоўваньне вэрсій",
"Single level wildcard (matches within a directory only)": "Single level wildcard (matches within a directory only)",
"Smallest First": "Smallest First",
"Source Code": "Зыходнікі",
"Staggered File Versioning": "Адаптыўнае захоўваньне вэрсій",
"Start Browser": "Start Browser",
"Stopped": "Спынена",
"Support": "Падтрымка",
"Sync Protocol Listen Addresses": "Sync Protocol Listen Addresses",
"Syncing": "Сынхранізуецца",
"Syncthing has been shut down.": "Syncthing has been shut down.",
"Syncthing includes the following software or portions thereof:": "Syncthing includes the following software or portions thereof:",
"Syncthing is restarting.": "Syncthing перастартоўвае.",
"Syncthing is upgrading.": "Syncthing is upgrading.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.",
"The aggregated statistics are publicly available at {%url%}.": "The aggregated statistics are publicly available at {{url}}.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.",
"The device ID cannot be blank.": "The device ID cannot be blank.",
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "The device ID to enter here can be found in the \"Edit > 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.": "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.": "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.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "The first command line parameter is the folder path and the second parameter is the relative path in the folder.",
"The folder ID cannot be blank.": "The folder ID cannot be blank.",
"The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.",
"The folder ID must be unique.": "The folder ID must be unique.",
"The folder path cannot be blank.": "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.": "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.",
"The maximum age must be a number and cannot be blank.": "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).": "The maximum time to keep a version (in days, set to 0 to keep versions forever).",
"The number of old versions to keep, per file.": "Колькі старых вэрсій трымаць, для кожнага файлу.",
"The number of versions must be a number and cannot be blank.": "The number of versions must be a number and cannot be blank.",
"The path cannot be blank.": "The path cannot be blank.",
"The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.",
"This is a major version upgrade.": "This is a major version upgrade.",
"Unknown": "Невядома",
"Unshared": "Unshared",
"Unused": "Unused",
"Up to Date": "Найноўшае",
"Upgrade": "Upgrade",
"Upgrade To {%version%}": "Upgrade To {{version}}",
"Upgrading": "Абнаўленьне",
"Upload Rate": "Хуткасьць запампоўваньня",
"Uptime": "Uptime",
"Use HTTPS for GUI": "Use HTTPS for GUI",
"Version": "Вэрсія",
"Versions Path": "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.",
"When adding a new device, keep in mind that this device must be added on the other side too.": "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.": "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.",
"Yes": "Так",
"You must keep at least one version.": "You must keep at least one version.",
"full documentation": "full documentation",
"items": "складнікаў",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wants to share folder \"{{folder}}\"."
}
-11
View File
@@ -1,9 +1,7 @@
{ {
"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 Ключ", "API Key": "API Ключ",
"About": "За Програмата", "About": "За Програмата",
"Actions": "Действия",
"Add": "Добави", "Add": "Добави",
"Add Device": "Добави устройство", "Add Device": "Добави устройство",
"Add Folder": "Добави папка", "Add Folder": "Добави папка",
@@ -20,7 +18,6 @@
"Bugs": "Бъгове", "Bugs": "Бъгове",
"CPU Utilization": "Натоварване на Процесора", "CPU Utilization": "Натоварване на Процесора",
"Changelog": "Сипъск с промени", "Changelog": "Сипъск с промени",
"Clean out after": "Изчисти след",
"Close": "Затвори", "Close": "Затвори",
"Command": "Команда", "Command": "Команда",
"Comment, when used at the start of a line": "Коментар, използван в началото на реда", "Comment, when used at the start of a line": "Коментар, използван в началото на реда",
@@ -30,7 +27,6 @@
"Copied from original": "Копиран от оригинала", "Copied from original": "Копиран от оригинала",
"Copyright © 2015 the following Contributors:": "Правата запазени © 2015 Сътрудници:", "Copyright © 2015 the following Contributors:": "Правата запазени © 2015 Сътрудници:",
"Delete": "Изтрий", "Delete": "Изтрий",
"Deleted": "Изтрито",
"Device ID": "Идентификатор на устройство", "Device ID": "Идентификатор на устройство",
"Device Identification": "Идентификация на устройство", "Device Identification": "Идентификация на устройство",
"Device Name": "Име на устройство", "Device Name": "Име на устройство",
@@ -53,7 +49,6 @@
"File Pull Order": "По ред на дърпане", "File Pull Order": "По ред на дърпане",
"File Versioning": "Файлови Версии", "File Versioning": "Файлови Версии",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Битовете за права за достъп са игнорирани, когато се проверява за промени. Използвай с файлови системи тип FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Битовете за права за достъп са игнорирани, когато се проверява за промени. Използвай с файлови системи тип FAT.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Файловете биват преместени в .stversions папка, когато са заменен или изтрити от Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Когато syncthing замени или изтрие файл той се премества в .stversions и преименува с дабавени дата и час.", "Files are moved to date stamped versions in a .stversions folder 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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Файловете са защитени от промени направени на други устройства, но промени направени на това устройство ще бъдат синхронизирани с другите устройства.",
"Folder ID": "Идентификатор на папка", "Folder ID": "Идентификатор на папка",
@@ -67,7 +62,6 @@
"Global Discovery": "Глобавно Откриване", "Global Discovery": "Глобавно Откриване",
"Global Discovery Server": "Сървър за Глобално Откриване", "Global Discovery Server": "Сървър за Глобално Откриване",
"Global State": "Глобално състояние", "Global State": "Глобално състояние",
"Help": "Помощ",
"Ignore": "Игнорирай", "Ignore": "Игнорирай",
"Ignore Patterns": "Шаблони за Игнориране", "Ignore Patterns": "Шаблони за Игнориране",
"Ignore Permissions": "Игнорирай Права за Достъп", "Ignore Permissions": "Игнорирай Права за Достъп",
@@ -81,7 +75,6 @@
"Later": "По-късно", "Later": "По-късно",
"Local Discovery": "Локално Откриване", "Local Discovery": "Локално Откриване",
"Local State": "Локално състояние", "Local State": "Локално състояние",
"Local State (Total)": "Локално Състояние (Общо)",
"Major Upgrade": "Основно Обновяване", "Major Upgrade": "Основно Обновяване",
"Maximum Age": "Максимална Възраст", "Maximum Age": "Максимална Възраст",
"Metadata Only": "Само мета информация", "Metadata Only": "Само мета информация",
@@ -165,19 +158,15 @@
"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 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 maximum age must be a number and cannot be blank.": "Максималната възраст трябва да е число и не може д ае празна.", "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 maximum time to keep a version (in days, set to 0 to keep versions forever).": "Максималното време да се пазят весрсии (в дни, сложи 0, за да пазиш версии завинаги).",
"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 old versions to keep, per file.": "Броят стари версии, които да бъдат пазени за всеки файл.",
"The number of versions must be a number and cannot be blank.": "Броят версии трябва да бъде число и не може да бъде празно.", "The number of versions must be a number and cannot be blank.": "Броят версии трябва да бъде число и не може да бъде празно.",
"The path cannot be blank.": "Пътят неможе да бъде празен.", "The path cannot be blank.": "Пътят неможе да бъде празен.",
"The rescan interval must be a non-negative number of seconds.": "Интервала на сканиране трябва да бъде не отрицателно число в секунди.", "The rescan interval must be a non-negative number of seconds.": "Интервала на сканиране трябва да бъде не отрицателно число в секунди.",
"This is a major version upgrade.": "Това е нова основна версия.", "This is a major version upgrade.": "Това е нова основна версия.",
"Trash Can File Versioning": "Версии на файлове в кошчето",
"Unknown": "Неясен", "Unknown": "Неясен",
"Unshared": "Споделянето прекратено", "Unshared": "Споделянето прекратено",
"Unused": "Неизползван", "Unused": "Неизползван",
"Up to Date": "Актуален", "Up to Date": "Актуален",
"Updated": "Обновено",
"Upgrade": "Обнови", "Upgrade": "Обнови",
"Upgrade To {%version%}": "Обновен До {{version}}", "Upgrade To {%version%}": "Обновен До {{version}}",
"Upgrading": "Обновяване", "Upgrading": "Обновяване",
+31 -42
View File
@@ -1,36 +1,32 @@
{ {
"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.": "A new major version may not be compatible with previous versions.",
"A new major version may not be compatible with previous versions.": "Una nova versió major pot ser incompatible amb versions anteriors.",
"API Key": "Clau API", "API Key": "Clau API",
"About": "Sobre", "About": "Sobre",
"Actions": "Accions",
"Add": "Afegir", "Add": "Afegir",
"Add Device": "Afegir dispositiu", "Add Device": "Afegir dispositiu",
"Add Folder": "Afegir carpeta", "Add Folder": "Afegir carpeta",
"Add new folder?": "Afegir nova carpeta?", "Add new folder?": "Afegir nova carpeta?",
"Address": "Adreça", "Address": "Adreça",
"Addresses": "Adreces", "Addresses": "Adreces",
"All Data": "Totes les dades", "All Data": "All Data",
"Allow Anonymous Usage Reporting?": "Permetre l'enviament anònim d'informes d'ús?", "Allow Anonymous Usage Reporting?": "Permetre l'enviament anònim d'informes d'ús?",
"Alphabetic": "Alfabètic", "Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Un comando extern s'encarrega del control de versions. Ha d'eliminar l'arxiu de la carpeta sincronitzada.", "An external command handles the versioning. It has to remove the file from the synced folder.": "An external command handles the versioning. It has to remove the file from the synced folder.",
"Anonymous Usage Reporting": "Informe anònim d'ús", "Anonymous Usage Reporting": "Informe anònim d'ús",
"Any devices configured on an introducer device will be added to this device as well.": "Qualsevol dispositiu configurat en un dispositiu introductor també s'afegirà a aquest dispositiu.", "Any devices configured on an introducer device will be added to this device as well.": "Qualsevol dispositiu configurat com a dispositiu introductor s'afegirà a aquest dispositiu tambè.",
"Automatic upgrades": "Actualitzacions automàtiques", "Automatic upgrades": "Actualitzacions automàtiques",
"Bugs": "Bugs", "Bugs": "Bugs",
"CPU Utilization": "Utilització del CPU", "CPU Utilization": "Utilització del CPU",
"Changelog": "Historial de canvis", "Changelog": "Historial de canvis",
"Clean out after": "Clean out after",
"Close": "Tancar", "Close": "Tancar",
"Command": "Comando", "Command": "Command",
"Comment, when used at the start of a line": "Comentari quan és usat al principi d'una línia", "Comment, when used at the start of a line": "Comentari quan és usat al principi d'una línia",
"Compression": "Compressió", "Compression": "Compression",
"Connection Error": "Error de connexió", "Connection Error": "Error de connexió",
"Copied from elsewhere": "Copiat d'un altre lloc", "Copied from elsewhere": "Copiat d'un altre lloc",
"Copied from original": "Copiat de l'original", "Copied from original": "Copiat de l'original",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 els següents col·laboradors:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
"Delete": "Esborrar", "Delete": "Esborrar",
"Deleted": "Deleted",
"Device ID": "ID del dispositiu", "Device ID": "ID del dispositiu",
"Device Identification": "Identificació del dispositiu", "Device Identification": "Identificació del dispositiu",
"Device Name": "Nom del dispositiu", "Device Name": "Nom del dispositiu",
@@ -47,14 +43,13 @@
"Editing": "Modificant", "Editing": "Modificant",
"Enable UPnP": "Habilitat UPnP", "Enable UPnP": "Habilitat UPnP",
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduir, separat per comes, adreces \"ip:port\" o \"dynamic\" per descobrir automàticament les adreces.", "Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduir, separat per comes, adreces \"ip:port\" o \"dynamic\" per descobrir automàticament les adreces.",
"Enter ignore patterns, one per line.": "Introduex patrons a ignorar, un per línia.", "Enter ignore patterns, one per line.": "Introduïx els patrons d'ignoració, un per línia.",
"Error": "Error", "Error": "Error",
"External File Versioning": "Versionat de fitxers extern", "External File Versioning": "External File Versioning",
"File Pull Order": "Ordre d'agafar fitxers", "File Pull Order": "File Pull Order",
"File Versioning": "Versionat de Fitxers", "File Versioning": "Versionat de Fitxers",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Els bits de permisos dels fitxers son ignorats quan es cerquen canvis. Utilitzar en sistemes de fitxers FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Els fitxers es mouen amb l'estampat de la data a la carpeta .stversions quan son substituïts o esborrats per 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.": "Els fitxers estan protegits de canvis fets per altres dispositius, però els canvis fets en aquest dispositiu seran enviats a la resta del cluster.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Els fitxers estan protegits de canvis fets per altres dispositius, però els canvis fets en aquest dispositiu seran enviats a la resta del cluster.",
"Folder ID": "ID de carpeta", "Folder ID": "ID de carpeta",
"Folder Master": "Carpeta mestre", "Folder Master": "Carpeta mestre",
@@ -67,7 +62,6 @@
"Global Discovery": "Descobriment Global", "Global Discovery": "Descobriment Global",
"Global Discovery Server": "Servidor de Descobriment Global", "Global Discovery Server": "Servidor de Descobriment Global",
"Global State": "Estat global", "Global State": "Estat global",
"Help": "Ajuda",
"Ignore": "Ignorar", "Ignore": "Ignorar",
"Ignore Patterns": "Patrons d'ignoració", "Ignore Patterns": "Patrons d'ignoració",
"Ignore Permissions": "Ignora Permisos", "Ignore Permissions": "Ignora Permisos",
@@ -75,44 +69,43 @@
"Introducer": "Introductor", "Introducer": "Introductor",
"Inversion of the given condition (i.e. do not exclude)": "Inversió del patrò introduït", "Inversion of the given condition (i.e. do not exclude)": "Inversió del patrò introduït",
"Keep Versions": "Mantenir Versions", "Keep Versions": "Mantenir Versions",
"Largest First": "Més gran primer", "Largest First": "Largest First",
"Last File Received": "Últim fitxer rebut", "Last File Received": "Últim fitxer rebut",
"Last seen": "Vist per última vegada", "Last seen": "Vist per última vegada",
"Later": "Després", "Later": "Després",
"Local Discovery": "Descobriment Local", "Local Discovery": "Descobriment Local",
"Local State": "Estat local", "Local State": "Estat local",
"Local State (Total)": "Local State (Total)", "Major Upgrade": "Major Upgrade",
"Major Upgrade": "Actualització major",
"Maximum Age": "Antiguitat Màxima", "Maximum Age": "Antiguitat Màxima",
"Metadata Only": "Només metadades", "Metadata Only": "Metadata Only",
"Move to top of queue": "Moure al primer de la cua", "Move to top of queue": "Move to top of queue",
"Multi level wildcard (matches multiple directory levels)": "Caràcter comodí de nivell múltiple (aparella en carpetes de nivells múltiples)", "Multi level wildcard (matches multiple directory levels)": "Caràcter comodí de nivell múltiple (aparella en carpetes de nivells múltiples)",
"Never": "Mai", "Never": "Mai",
"New Device": "Nou dispositiu", "New Device": "Nou dispositiu",
"New Folder": "Nova carpeta", "New Folder": "Nova carpeta",
"Newest First": "Més nou primer", "Newest First": "Newest First",
"No": "No", "No": "No",
"No File Versioning": "Sense Versionat de Fitxer", "No File Versioning": "Sense Versionat de Fitxer",
"Notice": "Avís", "Notice": "Avís",
"OK": "OK", "OK": "OK",
"Off": "Desactivar", "Off": "Off",
"Oldest First": "Més antic primer", "Oldest First": "Oldest First",
"Out Of Sync": "Fora de la Sincronització", "Out Of Sync": "Fora de la Sincronització",
"Out of Sync Items": "Arxius encara no sincronitzats", "Out of Sync Items": "Arxius encara no sincronitzats",
"Outgoing Rate Limit (KiB/s)": "Tasca Límit de Sortida (KiB/s)", "Outgoing Rate Limit (KiB/s)": "Tasca Límit de Sortida (KiB/s)",
"Override Changes": "Sobreescriure Canvis", "Override Changes": "Sobreescriure Canvis",
"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 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 folder in the folder).": "Ruta on les versions s'haurien de guardar (deixa-ho buit per fer servir el directori .stversions per defecte a la carpeta)", "Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Ruta on les versions s'haurien de guardar (deixa-ho buit per fer servir el directori .stversions per defecte a la carpeta)",
"Please consult the release notes before performing a major upgrade.": "Si us plau consulta les notes de llançament abans de realitzar una actualització major.", "Please consult the release notes before performing a major upgrade.": "Please consult the release notes before performing a major upgrade.",
"Please wait": "Si-us-plau espera", "Please wait": "Si-us-plau espera",
"Preview": "Vista prèvia", "Preview": "Vista prèvia",
"Preview Usage Report": "Vista Prèvia de l'Informe d'Ús", "Preview Usage Report": "Vista Prèvia de l'Informe d'Ús",
"Quick guide to supported patterns": "Guia ràpida per als possibles patrons", "Quick guide to supported patterns": "Guia ràpida per als possibles patrons",
"RAM Utilization": "Utilització de la RAM", "RAM Utilization": "Utilització de la RAM",
"Random": "Aleatori", "Random": "Random",
"Release Notes": "Notes de llançament", "Release Notes": "Release Notes",
"Rescan": "Re-escanejar", "Rescan": "Re-escanejar",
"Rescan All": "Re-escanejar tot", "Rescan All": "Rescan All",
"Rescan Interval": "Interval de re-escaneig", "Rescan Interval": "Interval de re-escaneig",
"Restart": "Reiniciar", "Restart": "Reiniciar",
"Restart Needed": "És Necessari Reiniciar", "Restart Needed": "És Necessari Reiniciar",
@@ -137,7 +130,7 @@
"Shutdown Complete": "Apagat complet", "Shutdown Complete": "Apagat complet",
"Simple File Versioning": "Versionat de Fitxers Senzill", "Simple File Versioning": "Versionat de Fitxers Senzill",
"Single level wildcard (matches within a directory only)": "Caràcter comodí de nivell singular (aparella sóls en una carpeta)", "Single level wildcard (matches within a directory only)": "Caràcter comodí de nivell singular (aparella sóls en una carpeta)",
"Smallest First": "Més petit primer", "Smallest First": "Smallest First",
"Source Code": "Codi Font", "Source Code": "Codi Font",
"Staggered File Versioning": "Versionat de Fitxers Esglaonat", "Staggered File Versioning": "Versionat de Fitxers Esglaonat",
"Start Browser": "Arrancar Navegador", "Start Browser": "Arrancar Navegador",
@@ -150,14 +143,14 @@
"Syncthing is restarting.": "Reiniciant syncthing.", "Syncthing is restarting.": "Reiniciant syncthing.",
"Syncthing is upgrading.": "Actualitzant syncthing.", "Syncthing is upgrading.": "Actualitzant syncthing.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Synthing sembla parat, o hi ha algun problema amb la connexió a Internet. Reintentant...", "Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Synthing sembla parat, o hi ha algun problema amb la connexió a Internet. Reintentant...",
"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.": "Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.",
"The aggregated statistics are publicly available at {%url%}.": "Les estadístiques agregades estan públicament disponibles a {{url}}.", "The aggregated statistics are publicly available at {%url%}.": "Les estadístiques agregades estan públicament disponibles a {{url}}.",
"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 guardar però no s'ha activat. S'ha de reiniciar el synthing per activar la nova configuració.",
"The device ID cannot be blank.": "El ID del dispositiu no pot estar en blanc.", "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 \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "El ID del dispositiu per introduir ací es pot trobar al diàleg \"Editar > Mostrar ID\" en l'altre dispositiu. Els espais i les barres son opcionals (s'ignoren).", "The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "El ID del dispositiu per introduir ací es pot trobar al diàleg \"Editar > Mostrar ID\" en l'altre dispositiu. Els espais i les barres son opcionals (s'ignoren).",
"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.", "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.",
"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.": "El ID del dispositiu introduït no sembla vàlid. Hauria de tenir 52 o 56 caràcters amb lletres i números, els espais i les barres son opcionals.", "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.": "El ID del dispositiu introduït no sembla vàlid. Hauria de tenir 52 o 56 caràcters amb lletres i números, els espais i les barres son opcionals.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "El primer paràmetre de la línia de comandes és el camí a la carpeta i el segon paràmetre és el camí relatiu a la carpeta.", "The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "The first command line parameter is the folder path and the second parameter is the relative path in the folder.",
"The folder ID cannot be blank.": "El ID del dispositiu no pot estar en blanc.", "The folder ID cannot be blank.": "El ID del dispositiu no pot estar en blanc.",
"The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "El ID de la carpeta ha de ser un identificador curt (64 caràcters o menys) format només per lletres, nombres i el punt (.), barra (-) i barra baixa (_).", "The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "El ID de la carpeta ha de ser un identificador curt (64 caràcters o menys) format només per lletres, nombres i el punt (.), barra (-) i barra baixa (_).",
"The folder ID must be unique.": "El ID de la carpeta ha de ser únic.", "The folder ID must be unique.": "El ID de la carpeta ha de ser únic.",
@@ -165,24 +158,20 @@
"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.": "Es fan servir els següents intervals: per la primera hora es manté una versió cada 30 segons, pel primer dia es manté una versió cada hora, pel primer cada 30 dies es manté una versió cada dia, fins el màxim d'antiguitat es manté una versió cada setmana.", "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.": "Es fan servir els següents intervals: per la primera hora es manté una versió cada 30 segons, pel primer dia es manté una versió cada hora, pel primer cada 30 dies es manté una versió cada dia, fins el màxim d'antiguitat es manté una versió cada setmana.",
"The maximum age must be a number and cannot be blank.": "La màxima antiguitat ha de ser un número i no pot estar en blanc.", "The maximum age must be a number and cannot be blank.": "La màxima antiguitat ha de ser un número i no pot estar en blanc.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Temps màxim en mantenir una versió (en dies, si es deixa en 0 es mantenen les versions per sempre).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Temps màxim en mantenir una versió (en dies, si es deixa en 0 es mantenen les versions per sempre).",
"The number of days must be a number and cannot be blank.": "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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "El nombre de versions antigues que es mantenen per fitxer.", "The number of old versions to keep, per file.": "El nombre de versions antigues que es mantenen per fitxer.",
"The number of versions must be a number and cannot be blank.": "El nombre de versions ha de ser un número i no es pot deixar en blanc.", "The number of versions must be a number and cannot be blank.": "El nombre de versions ha de ser un número i no es pot deixar en blanc.",
"The path cannot be blank.": "El camí no pot estar en blanc.", "The path cannot be blank.": "The path cannot be blank.",
"The rescan interval must be a non-negative number of seconds.": "El interval de re-escaneig ha der ser un nombre positiu de segons.", "The rescan interval must be a non-negative number of seconds.": "El interval de re-escaneig ha der ser un nombre positiu de segons.",
"This is a major version upgrade.": "Aquesta és una actualització de versió major.", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Trash Can File Versioning",
"Unknown": "Desconegut", "Unknown": "Desconegut",
"Unshared": "No compartit", "Unshared": "No compartit",
"Unused": "No usat", "Unused": "No usat",
"Up to Date": "Actualitzat", "Up to Date": "Actualitzat",
"Updated": "Updated", "Upgrade": "Upgrade",
"Upgrade": "Actualització",
"Upgrade To {%version%}": "Actualitzar a {{version}}", "Upgrade To {%version%}": "Actualitzar a {{version}}",
"Upgrading": "Actualitzant", "Upgrading": "Actualitzant",
"Upload Rate": "Tasca de Pujada", "Upload Rate": "Tasca de Pujada",
"Uptime": "Temps funcionant", "Uptime": "Uptime",
"Use HTTPS for GUI": "Utilitzar HTTPS pel GUI", "Use HTTPS for GUI": "Utilitzar HTTPS pel GUI",
"Version": "Versió", "Version": "Versió",
"Versions Path": "Carpeta de les Versions", "Versions Path": "Carpeta de les Versions",
-197
View File
@@ -1,197 +0,0 @@
{
"A negative number of days doesn't make sense.": "Un nombre negatiu de dies no té sentit.",
"A new major version may not be compatible with previous versions.": "Una nova versión amb canvis importants pot no ser compatible amb versions prèvies.",
"API Key": "Clau API",
"About": "Sobre",
"Actions": "Accions",
"Add": "Afegir",
"Add Device": "Afegir dispositiu",
"Add Folder": "Afegir carpeta",
"Add new folder?": "Afegir nova carpeta?",
"Address": "Direcció",
"Addresses": "Direccions",
"All Data": "Totes les dades",
"Allow Anonymous Usage Reporting?": "Permetre informes d'ús anònim?",
"Alphabetic": "Alfabètic",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Un comando extern controla el versionat. És necessari eliminar el fitxer de la carpeta sincronitzada.",
"Anonymous Usage Reporting": "Informe d'ús anònim",
"Any devices configured on an introducer device will be added to this device as well.": "Tots els dispositius configurats en un dispositiu presentador seràn afegits també a aquest dispositiu.",
"Automatic upgrades": "Actualitzacions automàtiques",
"Bugs": "Errors (Bugs)",
"CPU Utilization": "Utilització de la CPU",
"Changelog": "Registre de canvis",
"Clean out after": "Netejar després de",
"Close": "Tancar",
"Command": "Comando",
"Comment, when used at the start of a line": "Comentar, quant s'utilitza al principi d'una línia",
"Compression": "Compresió",
"Connection Error": "Error de connexió",
"Copied from elsewhere": "Copiat de qualsevol lloc",
"Copied from original": "Copiat de l'original",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 els següents Col·laboradors:",
"Delete": "Esborrar",
"Deleted": "Esborrat",
"Device ID": "ID del dispositiu",
"Device Identification": "Identificació del dispositiu",
"Device Name": "Nom del dispositiu",
"Device {%device%} ({%address%}) wants to connect. Add new device?": "El dispositiu {{device}} ({{address}}) vol connectar-se. Afegir nou dispositiu?",
"Devices": "Dispositius",
"Disconnected": "Desconnectat",
"Documentation": "Documentació",
"Download Rate": "Velocitat de descàrrega",
"Downloaded": "Descarregat",
"Downloading": "Descarregant",
"Edit": "Editar",
"Edit Device": "Editar dispositiu",
"Edit Folder": "Editar carpeta",
"Editing": "Editant",
"Enable UPnP": "Activar UPnp",
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduïr direccions separades per coma com \"ip:port\" o \"dynamic\" per a fer un descobriment automàtic de la direcció.",
"Enter ignore patterns, one per line.": "Introduïr patrons a ignorar, un per línia.",
"Error": "Error",
"External File Versioning": "Versionat extern de fitxers",
"File Pull Order": "Ordre de fitxers del pull",
"File Versioning": "Versionat de fitxer",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Els bits de permís del fitxer són ignorats quant es busquen els canvis. Utilitzar en sistemes de fitxers FAT.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Els arxius es menejen a la carpeta .stversions quant són substituïts o esborrats per Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Els fitxers són canviats a versions amb indicació de data en una carpeta \".stversions\" quant són reemplaçats o esborrats per 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.": "Els fitxers són protegits dels canvis fets en altres dispositius, però els canvis fets en aquest dispositiu seràn enviats a la resta del grup (cluster).",
"Folder ID": "ID de carpeta",
"Folder Master": "Carpeta principal",
"Folder Path": "Ruta de la carpeta",
"Folders": "Carpetes",
"GUI Authentication Password": "Password d'autenticació de l'Interfície Gràfica d'Usuari (GUI)",
"GUI Authentication User": "Autenticació de l'usuari de l'Interfície Gràfica d'Usuari (GUI)",
"GUI Listen Addresses": "Direcció d'escolta de l'Interfície Gràfica d'Usuari (GUI)",
"Generate": "Generar",
"Global Discovery": "Descobriment global",
"Global Discovery Server": "Servidor de descobriment global",
"Global State": "Estat global",
"Help": "Ajuda",
"Ignore": "Ignorar",
"Ignore Patterns": "Patrons a ignorar",
"Ignore Permissions": "Permisos a ignorar",
"Incoming Rate Limit (KiB/s)": "Límit de descàrrega (KiB/s)",
"Introducer": "Presentador",
"Inversion of the given condition (i.e. do not exclude)": "Inversió de la condició donada (per exemple no excloure)",
"Keep Versions": "Mantindre versions",
"Largest First": "El més gran primer",
"Last File Received": "Darrer fitxer rebut",
"Last seen": "Vist per última vegada",
"Later": "Més tard",
"Local Discovery": "Descobriment local",
"Local State": "Estat local",
"Local State (Total)": "Estat Local (Total)",
"Major Upgrade": "Actualització important",
"Maximum Age": "Edat màxima",
"Metadata Only": "Sols metadades",
"Move to top of queue": "Moure al principi de la cua",
"Multi level wildcard (matches multiple directory levels)": "Comodí multinivell (coincideix amb múltiples nivells de directoris)",
"Never": "Mai",
"New Device": "Nou dispositiu",
"New Folder": "Nova carpeta",
"Newest First": "El més nou primer",
"No": "No",
"No File Versioning": "Sense versionat de fitxer",
"Notice": "Avís",
"OK": "OK",
"Off": "Off",
"Oldest First": "El més vell primer",
"Out Of Sync": "Sense sincronitzar",
"Out of Sync Items": "Dispositius sense sincronitzar",
"Outgoing Rate Limit (KiB/s)": "Límit de pujada (KiB/s)",
"Override Changes": "Sobreescriure els canvis",
"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 a la carpeta local en l'ordinador. Es crearà si no existeix. El caràcter tilde (~) es pot utilitzar com a drecera",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Ruta on les versions deurien estar emmagatzemades (deixar buit per a la carpeta .stversions en la carpeta).",
"Please consult the release notes before performing a major upgrade.": "Per favor, consultar les notes de la versió abans de fer una actualització important.",
"Please wait": "Per favor, espere",
"Preview": "Vista prèvia",
"Preview Usage Report": "Informe d'ús de vista prèvia",
"Quick guide to supported patterns": "Guía ràpida de patrons suportats",
"RAM Utilization": "Utilització de la RAM",
"Random": "Aleatori",
"Release Notes": "Notes de la versió",
"Rescan": "Tornar a buscar",
"Rescan All": "Tornar a buscar tot",
"Rescan Interval": "Interval de nova busca",
"Restart": "Reiniciar",
"Restart Needed": "Reinici necesari",
"Restarting": "Reiniciant",
"Reused": "Reutilitzat",
"Save": "Gravar",
"Scanning": "Rastrejant",
"Select the devices to share this folder with.": "Selecciona els dispositius amb els que compartir aquesta carpeta.",
"Select the folders to share with this device.": "Selecciona les carpetes per a compartir amb aquest dispositiu.",
"Settings": "Ajustos",
"Share": "Compartir",
"Share Folder": "Compartir carpeta",
"Share Folders With Device": "Compartir carpetes amb el dispositiu",
"Share With Devices": "Compartir amb els dispositius",
"Share this folder?": "Compartir aquesta carpeta?",
"Shared With": "Compartit amb",
"Short identifier for the folder. Must be the same on all cluster devices.": "Identificador curt per a la carpeta. Deu ser el mateix en tots els dispositius del grup (cluster).",
"Show ID": "Mostrar ID",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Mostrat en lloc de l'ID del dispositiu en l'estat del grup (cluster). S'anunciarà als altres dispositius com el 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 lloc de l'ID del dispositiu en l'estat del grup (cluster). S'actualitzarà al nom que el dispositiu anuncia si es deixa buit.",
"Shutdown": "Apagar",
"Shutdown Complete": "Apagar completament",
"Simple File Versioning": "Versionat de fitxers senzill",
"Single level wildcard (matches within a directory only)": "Comodí de nivell únic (coincideix sols dins d'un directori)",
"Smallest First": "El més xicotet primer",
"Source Code": "Codi font",
"Staggered File Versioning": "Versionat de fitxers escalonat",
"Start Browser": "Iniciar navegador",
"Stopped": "Parat",
"Support": "Suport",
"Sync Protocol Listen Addresses": "Direccions d'escolta del protocol de sincronització",
"Syncing": "Sincronitzant",
"Syncthing has been shut down.": "Syncthing s'ha apagat",
"Syncthing includes the following software or portions thereof:": "Syncthing inclou el següent software o parts d'ell:",
"Syncthing is restarting.": "Syncthing està reiniciant.",
"Syncthing is upgrading.": "Syncthing està actualitzant-se.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing pareix apagat o hi ha un problema amb la connexió a Internet. Tornant a intentar...",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing pareix que té un problema processant la seua sol·licitud. Per favor, refresque la pàgina o reinicie Syncthing si el problema persistix.",
"The aggregated statistics are publicly available at {%url%}.": "Les estadístiques agregades estan disponibles públicament en {{url}}.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "La configuració ha sigut gravada però no activada. Syncthing deu reiniciar per tal d'activar la nova configuració.",
"The device ID cannot be blank.": "L'ID del dispositiu no pot estar buida.",
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "L'ID del dispositiu que hi ha que introduïr ací es pot trobar en el menú \"Editar > Mostrar ID\" en l'altre dispositiu. Els espais i les barres son 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 encriptat d'ús s'envia diariament. S'utilitza per a rastrejar plataformes comuns, tamanys de carpetes i versions de l'aplicació. Si el conjunt de dades enviat a l'informe es canvia, se li demanarà a vosté l'autorització altra vegada.\n",
"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.": "L'ID del dispositiu introduïda no pareix vàlida. Deuria ser una cadena de 52 o 56 caracters consistents en lletres i nombre, amb espais i barres opcionals.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "El primer paràmetre de la línia de comandos és la ruta de la carpeta i el segon és la ruta relativa en la carpeta.",
"The folder ID cannot be blank.": "L'ID de la carpeta no pot estar buit.",
"The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "L'ID de la carpeta deu ser un identificador curt (64 caracters o menys) consistint en lletres, nombres i únicament els caracters del punt (.), guió (-) i guió baix (_).",
"The folder ID must be unique.": "L'ID de la carpeta deu ser única.",
"The folder path cannot be blank.": "La ruta de la carpeta no pot estar buida.",
"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.": "S'utilitzen els següents intervals: per a la primera hora es guarda una versió cada 30 segons, per al primer dia es guarda una versió cada hora, per als primers 30 dies es guarda una versió diaria, fins l'edat màxima es guarda una versió cada setmana.",
"The maximum age must be a number and cannot be blank.": "L'edat màxima deu ser un nombre i no pot estar buida.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "El temps màxim per a guardar una versió (en dies, ficar 0 per a guardar les versions per a sempre).",
"The number of days must be a number and cannot be blank.": "El nombre de dies deu ser un nombre i no pot estar en blanc.",
"The number of days to keep files in the trash can. Zero means forever.": "El nombre de dies per a mantindre els arxius a la paperera. Cero vol dir \"per a sempre\".",
"The number of old versions to keep, per file.": "El nombre de versions antigues per a guardar, per cada fitxer.",
"The number of versions must be a number and cannot be blank.": "El nombre de versions deu ser un nombre i no pot estar buit.",
"The path cannot be blank.": "La ruta no pot estar buida.",
"The rescan interval must be a non-negative number of seconds.": "L'interval de reescaneig deu ser un nombre positiu de segons.",
"This is a major version upgrade.": "Aquesta és una actualització important de la versió.",
"Trash Can File Versioning": "Versionat d'arxius de la paperera",
"Unknown": "Desconegut",
"Unshared": "No compartit",
"Unused": "No utilitzat",
"Up to Date": "Actualitzat",
"Updated": "Actualitzat",
"Upgrade": "Actualitzar",
"Upgrade To {%version%}": "Actualitzar a {{version}}",
"Upgrading": "Actualitzant",
"Upload Rate": "Velocitat d'actualització",
"Uptime": "Temps de funcionament",
"Use HTTPS for GUI": "Utilitzar HTTP per a l'Interfície Gràfica d'Usuari (GUI)",
"Version": "Versió",
"Versions Path": "Ruta de les versions",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Les versions s'esborren automàticament si són més antigues que l'edat màxima o excedixen el nombre de fitxer permesos en un interval.",
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quant s'afig un nou dispositiu, hi ha que tindre en compte que aquest dispositiu deu ser afegit també en l'altre costat.",
"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.": "Quant s'afig una nova carpeta, hi ha que tindre en compte que l'ID de la carpeta s'utilitza per a juntar les carpetes entre dispositius. Són sensibles a les majúscules i deuen coincidir exactament entre tots els dispositius.",
"Yes": "Sí",
"You must keep at least one version.": "Es deu mantindre al menys una versió.",
"full documentation": "Documentació completa",
"items": "Elements",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vol compartit la carpeta \"{{folder}}\"."
}
-11
View File
@@ -1,9 +1,7 @@
{ {
"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á důležitá verze nemusí být kompatibilní s předchozími verzemi.", "A new major version may not be compatible with previous versions.": "Nová důležitá verze nemusí být kompatibilní s předchozími verzemi.",
"API Key": "API klíč", "API Key": "API klíč",
"About": "O aplikaci", "About": "O aplikaci",
"Actions": "Akce",
"Add": "Přidat", "Add": "Přidat",
"Add Device": "Přidat přístroj", "Add Device": "Přidat přístroj",
"Add Folder": "Přidat adresář", "Add Folder": "Přidat adresář",
@@ -20,7 +18,6 @@
"Bugs": "Chyby", "Bugs": "Chyby",
"CPU Utilization": "Využití CPU", "CPU Utilization": "Využití CPU",
"Changelog": "Changelog", "Changelog": "Changelog",
"Clean out after": "Vyčistit po",
"Close": "Zavřít", "Close": "Zavřít",
"Command": "Příkaz", "Command": "Příkaz",
"Comment, when used at the start of a line": "Komentář, pokud použito na začátku řádku", "Comment, when used at the start of a line": "Komentář, pokud použito na začátku řádku",
@@ -30,7 +27,6 @@
"Copied from original": "Zkopírováno z originálu", "Copied from original": "Zkopírováno z originálu",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 následující přispěvatelé:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 následující přispěvatelé:",
"Delete": "Smazat", "Delete": "Smazat",
"Deleted": "Smazáno",
"Device ID": "ID přístroje", "Device ID": "ID přístroje",
"Device Identification": "Identifikace přístroje", "Device Identification": "Identifikace přístroje",
"Device Name": "Jméno přístroje", "Device Name": "Jméno přístroje",
@@ -53,7 +49,6 @@
"File Pull Order": "Pořadí stahování souborů", "File Pull Order": "Pořadí stahování souborů",
"File Versioning": "Verzování souborů", "File Versioning": "Verzování souborů",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Bity označující práva souborů jsou při hledání změn ignorovány. Použít pro souborové systémy FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Bity označující práva souborů jsou při hledání změn ignorovány. Použít pro souborové systémy FAT.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Po nahrazení nebo smazání aplikací Syncthing jsou soubory přesunuty do adresáře .stversions.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Po nahrazení nebo smazání aplikací Syncthing jsou soubory přesunuty do verzí označených daty v adresáři .stversions.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Po nahrazení nebo smazání aplikací Syncthing jsou soubory přesunuty do verzí označených daty v adresáři .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.": "Soubory jsou chráněny před změnami na ostatních přístrojích, ale změny provedené z tohoto přístroje budou rozeslány na zbytek clusteru.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Soubory jsou chráněny před změnami na ostatních přístrojích, ale změny provedené z tohoto přístroje budou rozeslány na zbytek clusteru.",
"Folder ID": "ID adresáře", "Folder ID": "ID adresáře",
@@ -67,7 +62,6 @@
"Global Discovery": "Globální oznamování", "Global Discovery": "Globální oznamování",
"Global Discovery Server": "Server globálního oznamování", "Global Discovery Server": "Server globálního oznamování",
"Global State": "Všeobecný status", "Global State": "Všeobecný status",
"Help": "Pomoc",
"Ignore": "Ignorovat", "Ignore": "Ignorovat",
"Ignore Patterns": "Ignorované vzory", "Ignore Patterns": "Ignorované vzory",
"Ignore Permissions": "Ignorovat oprávnění", "Ignore Permissions": "Ignorovat oprávnění",
@@ -81,7 +75,6 @@
"Later": "Později", "Later": "Později",
"Local Discovery": "Místní oznamování", "Local Discovery": "Místní oznamování",
"Local State": "Místní status", "Local State": "Místní status",
"Local State (Total)": "Místní status (Celkem)",
"Major Upgrade": "Důležitá aktualizace", "Major Upgrade": "Důležitá aktualizace",
"Maximum Age": "Maximální časový limit", "Maximum Age": "Maximální časový limit",
"Metadata Only": "Pouze metadata", "Metadata Only": "Pouze metadata",
@@ -165,19 +158,15 @@
"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.": "Jsou použity následující intervaly: za první hodinu jsou ponechány verze pro každých 30 sekund, za první den jsou ponechány verze pro každou hodinu, za prvních 30 dní jsou ponechány verze pro každý den a do nejvyššího nastaveného stáří jsou ponechány verze pro každý týden.", "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.": "Jsou použity následující intervaly: za první hodinu jsou ponechány verze pro každých 30 sekund, za první den jsou ponechány verze pro každou hodinu, za prvních 30 dní jsou ponechány verze pro každý den a do nejvyššího nastaveného stáří jsou ponechány verze pro každý týden.",
"The maximum age must be a number and cannot be blank.": "Nejvyšší stáří je třeba zadat v podobě čísla a nemůže být prázdné.", "The maximum age must be a number and cannot be blank.": "Nejvyšší stáří je třeba zadat v podobě čísla a nemůže být prázdné.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Maximální doba pro zachování verze (dny, zapsáním hodnoty 0 bude ponecháno navždy).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Maximální doba pro zachování verze (dny, zapsáním hodnoty 0 bude ponecháno navždy).",
"The number of days must be a number and cannot be blank.": "Počet dní musí být číslo a nesmí být prázdný.",
"The number of days to keep files in the trash can. Zero means forever.": "Počet dní, po který budou soubory uchovány v koši. Nula znamená navždy.",
"The number of old versions to keep, per file.": "Počet starších verzí k zachování pro každý soubor.", "The number of old versions to keep, per file.": "Počet starších verzí k zachování pro každý soubor.",
"The number of versions must be a number and cannot be blank.": "Počet verzí musí být číslo a nemůže být prázdné.", "The number of versions must be a number and cannot be blank.": "Počet verzí musí být číslo a nemůže být prázdné.",
"The path cannot be blank.": "Cesta nesmí být prázdná.", "The path cannot be blank.": "Cesta nesmí být prázdná.",
"The rescan interval must be a non-negative number of seconds.": "Interval opakování skenování musí být pozitivní číslo.", "The rescan interval must be a non-negative number of seconds.": "Interval opakování skenování musí být pozitivní číslo.",
"This is a major version upgrade.": "Toto je důležitá aktualizace.", "This is a major version upgrade.": "Toto je důležitá aktualizace.",
"Trash Can File Versioning": "Verzování souborů v koši",
"Unknown": "Neznámý", "Unknown": "Neznámý",
"Unshared": "Nesdílený", "Unshared": "Nesdílený",
"Unused": "Nepoužitý", "Unused": "Nepoužitý",
"Up to Date": "Aktuální", "Up to Date": "Aktuální",
"Updated": "Aktualizováno",
"Upgrade": "Aktualizace", "Upgrade": "Aktualizace",
"Upgrade To {%version%}": "Aktualizovat na {{version}}", "Upgrade To {%version%}": "Aktualizovat na {{version}}",
"Upgrading": "Aktualizuji", "Upgrading": "Aktualizuji",
+31 -42
View File
@@ -1,9 +1,7 @@
{ {
"A negative number of days doesn't make sense.": "Eine negative Anzahl von Tagen ergibt keinen Sinn.", "A new major version may not be compatible with previous versions.": "Eine neue Hauptversion ist evtl. nicht mit vorherigen Versionen kompatibel.",
"A new major version may not be compatible with previous versions.": "Die neue Hauptversion ist evtl. nicht mit vorherigen Versionen kompatibel.",
"API Key": "API-Schlüssel", "API Key": "API-Schlüssel",
"About": "Über Syncthing", "About": "Über Syncthing",
"Actions": "Aktionen",
"Add": "Hinzufügen", "Add": "Hinzufügen",
"Add Device": "Gerät hinzufügen", "Add Device": "Gerät hinzufügen",
"Add Folder": "Verzeichnis hinzufügen", "Add Folder": "Verzeichnis hinzufügen",
@@ -20,17 +18,15 @@
"Bugs": "Fehler", "Bugs": "Fehler",
"CPU Utilization": "Prozessorauslastung", "CPU Utilization": "Prozessorauslastung",
"Changelog": "Änderungsprotokoll", "Changelog": "Änderungsprotokoll",
"Clean out after": "Aufräumen nach",
"Close": "Schließen", "Close": "Schließen",
"Command": "Kommando", "Command": "Kommando",
"Comment, when used at the start of a line": "Kommentar, wenn am Anfang der Zeile benutzt.", "Comment, when used at the start of a line": "Kommentar, wenn am Anfang der Zeile benutzt.",
"Compression": "Komprimierung", "Compression": "Komprimierung",
"Connection Error": "Verbindungsfehler", "Connection Error": "Verbindungsfehler",
"Copied from elsewhere": "Von anderer Quelle kopiert", "Copied from elsewhere": "Von woanders kopiert",
"Copied from original": "Vom Original kopiert", "Copied from original": "Vom Original kopiert",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 die folgenden Unterstützer:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 die folgenden Unterstützer:",
"Delete": "Löschen", "Delete": "Löschen",
"Deleted": "gelöscht",
"Device ID": "Geräte ID", "Device ID": "Geräte ID",
"Device Identification": "Gerät Identifikation", "Device Identification": "Gerät Identifikation",
"Device Name": "Gerätename", "Device Name": "Gerätename",
@@ -44,44 +40,41 @@
"Edit": "Bearbeiten", "Edit": "Bearbeiten",
"Edit Device": "Gerät bearbeiten", "Edit Device": "Gerät bearbeiten",
"Edit Folder": "Verzeichnis bearbeiten", "Edit Folder": "Verzeichnis bearbeiten",
"Editing": "Bearbeiten", "Editing": "Bearbeitung",
"Enable UPnP": "UPnP aktivieren", "Enable UPnP": "UPnP aktivieren",
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Trage durch ein Komma getrennte \"IP:Port\" Adressen oder \"dynamic\" ein, um die automatische Adresserkennung zu nutzen.", "Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Trage durch ein Komma getrennte \"IP:Port\" Adressen oder \"dynamic\" ein um automatische Adresserkennung durchzuführen.",
"Enter ignore patterns, one per line.": "Geben Sie Ignoriermuster ein, eines pro Zeile.", "Enter ignore patterns, one per line.": "Geben Sie Ignoriermuster ein, eines pro Zeile.",
"Error": "Fehler", "Error": "Fehler",
"External File Versioning": "Externe Dateiversionierung", "External File Versioning": "Externe Dateiversionierung",
"File Pull Order": "Dateiübertragungsreihenfolge", "File Pull Order": "Dateianforderungsreihenfolge",
"File Versioning": "Dateiversionierung", "File Versioning": "Dateiversionierung",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Dateizugriffsrechte beim Suchen nach Veränderungen ignorieren. Bei FAT-Dateisystemen zu verwenden.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Dateizugriffsrechte beim Suchen nach Veränderungen ignorieren. Bei FAT-Dateisystemen zu verwenden.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Dateien werden, bevor Syncthing sie löscht oder ersetzt, als datierte Versionen in einen Ordner namens .stversions verschoben.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Dateien werden, bevor Syncthing sie löscht oder ersetzt, als datierte Versionen in einen Ordner namens .stversions verschoben.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Dateien werden, bevor Syncthing sie löscht oder ersetzt, als datierte Versionen in einen Ordner namens .stversions verschoben.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Dateien sind vor Veränderung durch andere Geräte geschützt. Auf diesem Gerät durchgeführte Veränderungen werden aber auf den Rest des Verbunds übertragen.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Dateien sind vor Veränderung durch andere Geräte geschützt, auf diesem Gerät durchgeführte Veränderungen werden aber auf den Rest des Verbunds übertragen.",
"Folder ID": "Verzeichnis ID", "Folder ID": "Verzeichnis ID",
"Folder Master": "Master Ordner - schreibgeschützt", "Folder Master": "Keine Veränderungen zulassen",
"Folder Path": "Verzeichnispfad", "Folder Path": "Verzeichnispfad",
"Folders": "Verzeichnisse", "Folders": "Verzeichnisse",
"GUI Authentication Password": "Passwort für Zugang zur Benutzeroberfläche", "GUI Authentication Password": "Passwort für Zugang zur Benutzeroberfläche",
"GUI Authentication User": "Nutzername für Zugang zur Benutzeroberfläche", "GUI Authentication User": "Nutzername für Zugang zur Benutzeroberfläche",
"GUI Listen Addresses": "Adresse(n) für die Benutzeroberfläche", "GUI Listen Addresses": "Adresse(n) für die Benutzeroberfläche",
"Generate": "Generieren", "Generate": "Generieren",
"Global Discovery": "Globale Gerätesuche", "Global Discovery": "Globale Auffindung",
"Global Discovery Server": "Globale(r) Indexserver", "Global Discovery Server": "Globaler Auffindungsserver",
"Global State": "Globaler Status", "Global State": "Globaler Status",
"Help": "Hilfe",
"Ignore": "Ignorieren", "Ignore": "Ignorieren",
"Ignore Patterns": "Ignoriermuster", "Ignore Patterns": "Ignoriermuster",
"Ignore Permissions": "Berechtigungen ignorieren", "Ignore Permissions": "Berechtigungen ignorieren",
"Incoming Rate Limit (KiB/s)": "Limit Datenrate (eingehend) (KB/s)", "Incoming Rate Limit (KiB/s)": "Eingehendes Datenratelimit (KiB/s)",
"Introducer": "Verteilergerät", "Introducer": "Verteilergerät",
"Inversion of the given condition (i.e. do not exclude)": "Umkehrung der angegebenen Bedingung (z.B. schließe nicht aus)", "Inversion of the given condition (i.e. do not exclude)": "Umkehrung der angegebenen Bedingung (z.B. schließe nicht aus)",
"Keep Versions": "Versionen erhalten", "Keep Versions": "Versionen erhalten",
"Largest First": "Größte zuerst", "Largest First": "Größtes zuerst",
"Last File Received": "Letzte empfangene Datei ", "Last File Received": "Letzte Datei",
"Last seen": "Zuletzt online", "Last seen": "Zuletzt online",
"Later": "Später", "Later": "Später",
"Local Discovery": "Lokale Gerätesuche", "Local Discovery": "Lokale Auffindung",
"Local State": "Lokaler Status", "Local State": "Lokaler Status",
"Local State (Total)": "Lokaler Status (total)",
"Major Upgrade": "Hauptversionsupgrade", "Major Upgrade": "Hauptversionsupgrade",
"Maximum Age": "Höchstalter", "Maximum Age": "Höchstalter",
"Metadata Only": "Nur Metadaten", "Metadata Only": "Nur Metadaten",
@@ -90,16 +83,16 @@
"Never": "Nie", "Never": "Nie",
"New Device": "Neues Gerät", "New Device": "Neues Gerät",
"New Folder": "Neues Verzeichnis", "New Folder": "Neues Verzeichnis",
"Newest First": "Neueste zuerst", "Newest First": "Neuestes zuerst",
"No": "Nein", "No": "Nein",
"No File Versioning": "Keine Dateiversionierung", "No File Versioning": "Keine Dateiversionierung",
"Notice": "Hinweis", "Notice": "Hinweis",
"OK": "OK", "OK": "OK",
"Off": "Aus", "Off": "Aus",
"Oldest First": "Älteste zuerst", "Oldest First": "Ältestes zuerst",
"Out Of Sync": "Nicht synchronisiert", "Out Of Sync": "Nicht synchronisiert",
"Out of Sync Items": "Nicht synchronisierte Objekte", "Out of Sync Items": "Nicht synchronisierte Objekte",
"Outgoing Rate Limit (KiB/s)": "Limit Datenrate (ausgehend) (KB/s)", "Outgoing Rate Limit (KiB/s)": "Ausgehendes Datenratelimit (KiB/s)",
"Override Changes": "Änderungen überschreiben", "Override Changes": "Änderungen überschreiben",
"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": "Pfad zum Verzeichnis auf dem lokalen Rechner. Wird erzeugt, wenn es nicht existiert. Das Tilden-Zeichen (~) kann als Abkürzung benutzt werden für", "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": "Pfad zum Verzeichnis auf dem lokalen Rechner. Wird erzeugt, wenn es nicht existiert. Das Tilden-Zeichen (~) kann als Abkürzung benutzt werden für",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Pfad in dem die Versionen gespeichert werden sollen (ohne Angabe wird das Verzeichnis .stversions im Verzeichnis verwendet).", "Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Pfad in dem die Versionen gespeichert werden sollen (ohne Angabe wird das Verzeichnis .stversions im Verzeichnis verwendet).",
@@ -111,15 +104,15 @@
"RAM Utilization": "RAM Auslastung", "RAM Utilization": "RAM Auslastung",
"Random": "Zufall", "Random": "Zufall",
"Release Notes": "Veröffentlichungsnotizen", "Release Notes": "Veröffentlichungsnotizen",
"Rescan": "Neu scannen", "Rescan": "Überprüfen",
"Rescan All": "Alle neu scannen", "Rescan All": "Alle überprüfen",
"Rescan Interval": "Scanintervall", "Rescan Interval": "Suchintervall",
"Restart": "Neustart", "Restart": "Neustart",
"Restart Needed": "Neustart benötigt", "Restart Needed": "Neustart benötigt",
"Restarting": "Wird neu gestartet", "Restarting": "Wird neu gestartet",
"Reused": "Erneut benutzt", "Reused": "Erneut benutzt",
"Save": "Speichern", "Save": "Speichern",
"Scanning": "Scanning", "Scanning": "Suche",
"Select the devices to share this folder with.": "Wähle die Geräte aus, mit denen Du dieses Verzeichnis teilen willst.", "Select the devices to share this folder with.": "Wähle die Geräte aus, mit denen Du dieses Verzeichnis teilen willst.",
"Select the folders to share with this device.": "Wähle die Verzeichnisse aus, die du mit diesem Gerät teilen möchtest", "Select the folders to share with this device.": "Wähle die Verzeichnisse aus, die du mit diesem Gerät teilen möchtest",
"Settings": "Einstellungen", "Settings": "Einstellungen",
@@ -131,7 +124,7 @@
"Shared With": "Geteilt mit", "Shared With": "Geteilt mit",
"Short identifier for the folder. Must be the same on all cluster devices.": "Kurze ID für das Verzeichnis. Muss auf allen Verbunds-Geräten gleich sein.", "Short identifier for the folder. Must be the same on all cluster devices.": "Kurze ID für das Verzeichnis. Muss auf allen Verbunds-Geräten gleich sein.",
"Show ID": "ID anzeigen", "Show ID": "ID anzeigen",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Wird anstatt der Geräte ID angezeigt. Wird als optionaler Gerätename an die anderen Clients weitergegeben.", "Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Wird anstatt der Geräte ID im Verbunds-Status angezeigt. Wird als optionaler Standardname an andere Geräte bekannt gegeben.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Wird anstatt der Geräte ID im Verbunds-Status angezeigt. Wird auf den Namen aktualisiert, den das Gerät angibt.", "Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Wird anstatt der Geräte ID im Verbunds-Status angezeigt. Wird auf den Namen aktualisiert, den das Gerät angibt.",
"Shutdown": "Herunterfahren", "Shutdown": "Herunterfahren",
"Shutdown Complete": "Vollständig Heruntergefahren", "Shutdown Complete": "Vollständig Heruntergefahren",
@@ -152,32 +145,28 @@
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing scheint nicht erreichbar zu sein oder es gibt ein Problem mit Deiner Internetverbindung. Versuche erneut...", "Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing scheint nicht erreichbar zu sein oder es gibt ein Problem mit Deiner Internetverbindung. Versuche erneut...",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Es scheint als ob Syncthing ein Problem mit der Verarbeitung ihrer Eingabe hat. Bitte laden sie die Seite neu oder führen sie einen Neustart von Syncthing durch, falls das Problem weiterhin besteht.", "Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Es scheint als ob Syncthing ein Problem mit der Verarbeitung ihrer Eingabe hat. Bitte laden sie die Seite neu oder führen sie einen Neustart von Syncthing durch, falls das Problem weiterhin besteht.",
"The aggregated statistics are publicly available at {%url%}.": "Die gesammelten Statistiken sind öffentlich verfügbar unter {{url}}.", "The aggregated statistics are publicly available at {%url%}.": "Die gesammelten Statistiken sind öffentlich verfügbar unter {{url}}.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Die Konfiguration wurde gespeichert, aber nicht aktiviert. Syncthing muss neugestartet werden um die neue Konfiguration zu übernehmen.", "The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Die Konfiguration wurde gespeichert, aber nicht aktiviert. Syncthing muss neugestartet werden um die neue Konfiguration zu aktivieren.",
"The device ID cannot be blank.": "Die Geräte ID darf nicht leer sein.", "The device ID cannot be blank.": "Die Geräte ID darf nicht leer sein.",
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Die hier einzutragende Geräte ID kann im \"Bearbeiten > Zeige ID\"-Dialog auf dem anderen Gerät gefunden werden. Leerzeichen und Bindestriche sind optional (werden ignoriert).", "The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Die hier einzutragende Geräte ID kann im \"Bearbeiten > Zeige ID\"-Dialog auf dem anderen Gerät gefunden werden. Leerzeichen und Bindestriche sind optional (werden ignoriert).",
"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.": "Der verschlüsselte Nutzungsbericht wird täglich gesendet. Er wird verwendet, um Statistiken über verwendete Betriebssysteme, Verzeichnis-Größen und Programm-Versionen zu erstellen. Sollte der Bericht in Zukunft weitere Daten erfassen, wird dieses Fenster erneut angezeigt.", "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.": "Der verschlüsselte Nutzungsbericht wird täglich gesendet. Er wird benutzt um Statistiken über verwendete Betriebssysteme, Verzeichnis-Größen und Programm-Versionen zu erstellen. Sollte der Bericht in Zukunft weitere Daten erfassen, wird dieses Fenster erneut angezeigt.",
"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.": "Die eingegebene Geräte ID scheint nicht gültig zu sein. Es sollte eine 52 oder 56 stellige Zeichenkette aus Buchstaben und Nummern sein. Leerzeichen und Bindestriche sind optional.", "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.": "Die eingegebene Geräte ID scheint nicht gültig zu sein. Es sollte eine 52 oder 56 stellige Zeichenkette aus Buchstaben und Nummern sein. Leerzeichen und Bindestriche sind optional.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "Der erste Kommandozeilenparameter ist der Verzeichnis-Pfad und der zweite Parameter ist der relative Pfad in diesem Ordner.", "The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "Der erste Kommandozeilenparameter ist der Verzeichnis-Pfad und der zweite Parameter ist der relative Pfad in diesem Ordner.",
"The folder ID cannot be blank.": "Die Verzeichnis ID darf nicht leer sein.", "The folder ID cannot be blank.": "Die Verzeichnis ID darf nicht leer sein.",
"The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "Die Verzeichnis ID muss eine kurze Bezeichnung haben (64 Zeichen oder weniger). Sie darf nur aus Buchstaben, Zahlen und dem Punkt- (.), Bindestrich- (-), und Unterstrich- (_) Zeichen bestehen.", "The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "Die Verzeichnis ID muss eine kurze Kennung (64 Zeichen oder weniger) sein. Sie kann nur aus Buchstaben, Zahlen und dem Punkt- (.), Bindestrich- (-), und Unterstrich- (_) Zeichen bestehen.",
"The folder ID must be unique.": "Die Verzeichnis ID darf nur einmal existieren.", "The folder ID must be unique.": "Die Verzeichnis ID muss eindeutig sein.",
"The folder path cannot be blank.": "Der Verzeichnispfad darf nicht leer sein", "The folder path cannot be blank.": "Der Verzeichnispfad kann nicht leer sein",
"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.": "Es wird in folgenden Abständen versioniert: in der ersten Stunde wird alle 30 Sekunden eine Version behalten, am ersten Tag eine jede Stunde, in den ersten 30 Tagen eine jeden Tag, danach wird bis zum Höchstalter eine Version pro Woche beibehalten.", "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.": "Es wird in folgenden Abständen versioniert: in der ersten Stunde wird alle 30 Sekunden eine Version behalten, am ersten Tag eine jede Stunde, in den ersten 30 Tagen eine jeden Tag, danach wird bis zum Höchstalter eine Version pro Woche beibehalten.",
"The maximum age must be a number and cannot be blank.": "Das Höchstalter muss angegeben werden und eine Zahl sein.", "The maximum age must be a number and cannot be blank.": "Das Höchstalter muss angegeben werden und eine Zahl sein.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Die längste Zeit, die alte Versionen vorgehalten werden (in Tagen, 0 bedeutet, alte Versionen für immer zu behalten).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Die längste Zeit, die alte Versionen vorgehalten werden (in Tagen, 0 bedeutet, alte Versionen für immer zu behalten).",
"The number of days must be a number and cannot be blank.": "Die Anzahl von Versionen muss eine Zahl und darf nicht leer sein.",
"The number of days to keep files in the trash can. Zero means forever.": "Dauer in Tagen für welche die Dateien aufgehoben werden sollen. 0 bedeutet für immer.",
"The number of old versions to keep, per file.": "Anzahl der alten Versionen, die von jeder Datei gespeichert werden sollen.", "The number of old versions to keep, per file.": "Anzahl der alten Versionen, die von jeder Datei gespeichert werden sollen.",
"The number of versions must be a number and cannot be blank.": "Die Anzahl von Versionen muss eine Zahl und darf nicht leer sein.", "The number of versions must be a number and cannot be blank.": "Die Anzahl von Versionen muss eine Zahl und darf nicht leer sein.",
"The path cannot be blank.": "Der Pfad darf nicht leer sein.", "The path cannot be blank.": "Der Pfad darf nicht leer sein",
"The rescan interval must be a non-negative number of seconds.": "Das Scanintervall muss eine nicht negative Anzahl von Sekunden sein.", "The rescan interval must be a non-negative number of seconds.": "Das Suchintervall muss eine nicht negative Anzahl von Sekunden sein.",
"This is a major version upgrade.": "Dies ist eine neue Hauptversion.", "This is a major version upgrade.": "Dies ist eine neue Hauptversion",
"Trash Can File Versioning": "Papierkorb Dateiversionierung",
"Unknown": "Unbekannt", "Unknown": "Unbekannt",
"Unshared": "Ungeteilt", "Unshared": "Ungeteilt",
"Unused": "Ungenutzt", "Unused": "Ungenutzt",
"Up to Date": "Aktuell", "Up to Date": "Aktuell",
"Updated": "aktualisiert",
"Upgrade": "Upgrade", "Upgrade": "Upgrade",
"Upgrade To {%version%}": "Update auf {{version}}", "Upgrade To {%version%}": "Update auf {{version}}",
"Upgrading": "Wird aktualisiert", "Upgrading": "Wird aktualisiert",
@@ -186,9 +175,9 @@
"Use HTTPS for GUI": "HTTPS für Benutzeroberfläche benutzen", "Use HTTPS for GUI": "HTTPS für Benutzeroberfläche benutzen",
"Version": "Version", "Version": "Version",
"Versions Path": "Versionierungspfad", "Versions Path": "Versionierungspfad",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Alte Versionen werden automatisch gelöscht, wenn sie älter als das angegebene Höchstalter sind oder die Höchstzahl der Dateien je Zeitabschnitt überschritten wird.", "Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Alte Versionen werden automatisch gelöscht wenn sie älter als das angegebene Höchstalter sind oder die Höchstzahl der Dateien pro Zeitabschnitt überschritten wird.",
"When adding a new device, keep in mind that this device must be added on the other side too.": "Beachte beim Hinzufügen eines neuen Gerätes, dass dieses Gerät auch auf der Gegenseite hinzugefügt werden muss.", "When adding a new device, keep in mind that this device must be added on the other side too.": "Beachte beim Hinzufügen eines neuen Gerätes, dass dieses Gerät auch auf der Gegenseite hinzugefügt werden muss.",
"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.": "Beim Hinzufügen eines neuen Verzeichnisses beachte, dass die Verzeichnis ID dazu verwendet wird, Verzeichnisse zwischen Geräten zu verbinden. Die ID muss also auf allen Geräten gleich sein, die Groß- und Kleinschreibung muss dabei beachtet werden.", "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.": "Beim Hinzufügen eines neuen Verzeichnisses, beachte dass die Verzeichnis ID dazu verwendet wird, Verzeichnisse zwischen Geräten zu verbinden. Die ID muss also auf allen Geräten gleich sein, die Groß- und Kleinschreibung muss dabei beachtet werden.",
"Yes": "Ja", "Yes": "Ja",
"You must keep at least one version.": "Du musst mindestens eine Version behalten.", "You must keep at least one version.": "Du musst mindestens eine Version behalten.",
"full documentation": "Komplette Dokumentation", "full documentation": "Komplette Dokumentation",
+22 -33
View File
@@ -1,9 +1,7 @@
{ {
"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.",
"A new major version may not be compatible with previous versions.": "Μια νέα σημαντική έκδοση μπορεί να μην είναι συμβατή με τις προηγούμενες εκδόσεις.",
"API Key": "Κλειδί API", "API Key": "Κλειδί API",
"About": "Σχετικά με το Syncthing", "About": "Σχετικά με το Syncthing",
"Actions": "Ενέργειες",
"Add": "Προσθήκη", "Add": "Προσθήκη",
"Add Device": "Προσθήκη συσκευής", "Add Device": "Προσθήκη συσκευής",
"Add Folder": "Προσθήκη φακέλου", "Add Folder": "Προσθήκη φακέλου",
@@ -12,15 +10,14 @@
"Addresses": "Διευθύνσεις", "Addresses": "Διευθύνσεις",
"All Data": "Όλα τα δεδομένα", "All Data": "Όλα τα δεδομένα",
"Allow Anonymous Usage Reporting?": "Να επιτρέπεται η αποστολή ανώνυμων στοιχείων χρήσης;", "Allow Anonymous Usage Reporting?": "Να επιτρέπεται η αποστολή ανώνυμων στοιχείων χρήσης;",
"Alphabetic": "Αλφαβητικά", "Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Μια εξωτερική εντολή χειρίζεται την διαχείριση εκδόσεων. Χρειάζεται να αφαιρέσει το αρχείο από το φάκελο συγχρονισμένων.", "An external command handles the versioning. It has to remove the file from the synced folder.": "Μια εξωτερική εντολή χειρίζεται την διαχείριση εκδόσεων. Πρέπει να καταργήσετε το αρχείο από το φάκελο συγχρονισμένων.",
"Anonymous Usage Reporting": "Ανώνυμα στοιχεία χρήσης", "Anonymous Usage Reporting": "Ανώνυμα στοιχεία χρήσης",
"Any devices configured on an introducer device will be added to this device as well.": "Αν δηλωθεί σαν «βασικός κόμβος», τότε όλες οι συσκευές που είναι δηλωμένες εκεί θα υπάρχουν και στον τοπικό κόμβο.", "Any devices configured on an introducer device will be added to this device as well.": "Αν δηλωθεί σαν «βασικός κόμβος», τότε όλες οι συσκευές που είναι δηλωμένες εκεί θα υπάρχουν και στον τοπικό κόμβο.",
"Automatic upgrades": "Αυτόματη αναβάθμιση", "Automatic upgrades": "Αυτόματη αναβάθμιση",
"Bugs": "Bugs", "Bugs": "Bugs",
"CPU Utilization": "Επιβάρυνση του επεξεργαστή", "CPU Utilization": "Επιβάρυνση του επεξεργαστή",
"Changelog": "Πληροφορίες εκδόσεων", "Changelog": "Πληροφορίες εκδόσεων",
"Clean out after": "Μετά από αυτό, εκκαθάρισε",
"Close": "Τέλος", "Close": "Τέλος",
"Command": "Εντολή", "Command": "Εντολή",
"Comment, when used at the start of a line": "Σχόλιο, όταν χρησιμοποιείται στην αρχή μιας γραμμής", "Comment, when used at the start of a line": "Σχόλιο, όταν χρησιμοποιείται στην αρχή μιας γραμμής",
@@ -30,7 +27,6 @@
"Copied from original": "Έχει αντιγραφεί από το πρωτότυπο", "Copied from original": "Έχει αντιγραφεί από το πρωτότυπο",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 από τους παρακάτω συνεισφορείς:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 από τους παρακάτω συνεισφορείς:",
"Delete": "Διαγραφή", "Delete": "Διαγραφή",
"Deleted": "Διαγραμμένα",
"Device ID": "Ταυτότητα συσκευής", "Device ID": "Ταυτότητα συσκευής",
"Device Identification": "Ταυτότητα συσκευής", "Device Identification": "Ταυτότητα συσκευής",
"Device Name": "Όνομα συσκευής", "Device Name": "Όνομα συσκευής",
@@ -49,12 +45,11 @@
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Γράψε τις διευθύνσεις IP με τη μορφή «ip:θύρα», διαχωρισμένες με κόμμα. Αλλιώς γράψε «dynamic» για να πραγματοποιηθεί η αυτόματη εύρεση διευθύνσεων.", "Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Γράψε τις διευθύνσεις IP με τη μορφή «ip:θύρα», διαχωρισμένες με κόμμα. Αλλιώς γράψε «dynamic» για να πραγματοποιηθεί η αυτόματη εύρεση διευθύνσεων.",
"Enter ignore patterns, one per line.": "Δώσε τα πρότυπα που θα αγνοηθούν, ένα σε κάθε γραμμή.", "Enter ignore patterns, one per line.": "Δώσε τα πρότυπα που θα αγνοηθούν, ένα σε κάθε γραμμή.",
"Error": "Σφάλμα", "Error": "Σφάλμα",
"External File Versioning": "Εξωτερική τήρηση εκδόσεων", "External File Versioning": "Εξωτερική διαχείριση εκδόσεων Αρχείου",
"File Pull Order": "Σειρά με την οποία θα κατεβαίνουν τα αρχεία", "File Pull Order": "File Pull Order",
"File Versioning": "Τήρηση εκδόσεων", "File Versioning": "Τήρηση εκδόσεων",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Τα δικαιώματα των αρχείων θα αγνοούνται όταν κοιτάζω για αλλαγές. Αφορά συστήματα αρχείων FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Τα bit αδεια αρχεία αγνοούνται όταν ψάχνουν για αλλαγές. Χρήση σε συστήματα αρχείων FAT.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Τα αρχεία μετακινούνται στον φάκελο .stversions, όταν αντικαθίστανται ή διαγράφονται από το Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Τα αρχεία που μετακινηθηκαν στην ημερομηνία που αναγράφεται τις εκδόσεις σε ένα φάκελο .stversions όταν αντικατασταθούν ή να διαγραφθούν από το Syncthing.",
"Files are moved to date stamped versions in a .stversions folder 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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Τα αρχεία προστατεύονται από αλλαγές που γίνονται σε άλλες συσκευές, αλλά όποιες αλλαγές γίνουν σε αυτή τη συσκευή θα αποσταλούν σε όλη τη συστάδα συσκευών.",
"Folder ID": "Ταυτότητα φακέλου", "Folder ID": "Ταυτότητα φακέλου",
"Folder Master": "Να μην επιτρέπονται αλλαγές", "Folder Master": "Να μην επιτρέπονται αλλαγές",
@@ -64,10 +59,9 @@
"GUI Authentication User": "Χρηστώνυμο για την πρόσβαση στη διεπαφή", "GUI Authentication User": "Χρηστώνυμο για την πρόσβαση στη διεπαφή",
"GUI Listen Addresses": "Διευθύνσεις από τις οποίες θα είναι προσβάσιμη η διεπαφή", "GUI Listen Addresses": "Διευθύνσεις από τις οποίες θα είναι προσβάσιμη η διεπαφή",
"Generate": "Δημιουργία", "Generate": "Δημιουργία",
"Global Discovery": "Καθολική ανεύρεση", "Global Discovery": "Να μπορεί να ανευρεθεί καθολικά (από παντού)",
"Global Discovery Server": "Διακομιστής καθολικής ανεύρεσης κόμβου", "Global Discovery Server": "Διακομιστής καθολικής ανεύρεσης κόμβου",
"Global State": "Καθολική κατάσταση", "Global State": "Καθολική κατάσταση",
"Help": "Βοήθεια",
"Ignore": "Αγνόησε", "Ignore": "Αγνόησε",
"Ignore Patterns": "Πρότυπο για αγνόηση", "Ignore Patterns": "Πρότυπο για αγνόηση",
"Ignore Permissions": "Αγνόησε τα δικαιώματα", "Ignore Permissions": "Αγνόησε τα δικαιώματα",
@@ -75,14 +69,13 @@
"Introducer": "Βασικός κόμβος", "Introducer": "Βασικός κόμβος",
"Inversion of the given condition (i.e. do not exclude)": "Αντιστροφή της δοσμένης συνθήκης (π.χ. να μην εξαιρείς) ", "Inversion of the given condition (i.e. do not exclude)": "Αντιστροφή της δοσμένης συνθήκης (π.χ. να μην εξαιρείς) ",
"Keep Versions": "Διατήρηση εκδόσεων", "Keep Versions": "Διατήρηση εκδόσεων",
"Largest First": "Το μεγαλύτερο πρώτα", "Largest First": "Largest First",
"Last File Received": "Πιο πρόσφατο αρχείο", "Last File Received": "Πιο πρόσφατο αρχείο",
"Last seen": "Τελευταία φορά συνδεδεμένος", "Last seen": "Τελευταία φορά συνδεδεμένος",
"Later": "Αργότερα", "Later": "Αργότερα",
"Local Discovery": "Τοπική ανεύρεση", "Local Discovery": "Τοπική ανεύρεση",
"Local State": "Τοπική κατάσταση", "Local State": "Τοπική κατάσταση",
"Local State (Total)": "Τοπική κατάσταση (συνολικά)", "Major Upgrade": "Major Upgrade",
"Major Upgrade": "Σημαντική αναβάθμιση",
"Maximum Age": "Μέγιστη ηλικία", "Maximum Age": "Μέγιστη ηλικία",
"Metadata Only": "Μόνο μεταδεδομένα", "Metadata Only": "Μόνο μεταδεδομένα",
"Move to top of queue": "Μεταφορά στην αρχή της λίστας", "Move to top of queue": "Μεταφορά στην αρχή της λίστας",
@@ -90,27 +83,27 @@
"Never": "Ποτέ", "Never": "Ποτέ",
"New Device": "Νέα συσκευή", "New Device": "Νέα συσκευή",
"New Folder": "Νέος φάκελος", "New Folder": "Νέος φάκελος",
"Newest First": "Το νεότερο πρώτα", "Newest First": "Newest First",
"No": "Όχι", "No": "Όχι",
"No File Versioning": "Να μην τηρούνται εκδόσεις", "No File Versioning": "Να μην τηρούνται εκδόσεις",
"Notice": "Σημείωση", "Notice": "Σημείωση",
"OK": "OK", "OK": "OK",
"Off": "Απενεργοποιημένο", "Off": "Απενεργοποιημένο",
"Oldest First": "Το παλιότερο πρώτα", "Oldest First": "Oldest First",
"Out Of Sync": "Μη συγχρονισμένα", "Out Of Sync": "Μη συγχρονισμένα",
"Out of Sync Items": "Μη συγχρονισμένα αντικείμενα", "Out of Sync Items": "Μη συγχρονισμένα αντικείμενα",
"Outgoing Rate Limit (KiB/s)": "Ρυθμός αποστολής (KiB/s)", "Outgoing Rate Limit (KiB/s)": "Ρυθμός αποστολής (KiB/s)",
"Override Changes": "Να αντικατασταθούν οι αλλαγές", "Override Changes": "Να αντικατασταθούν οι αλλαγές",
"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 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 folder in the folder).": "Ο φάκελος στον οποίο θα αποθηκεύονται οι εκδόσεις των αρχείων (αν δεν οριστεί θα αποθηκεύονται στον υποφάκελο .stversions)", "Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Ο φάκελος στον οποίο θα αποθηκεύονται οι εκδόσεις των αρχείων (αν δεν οριστεί θα αποθηκεύονται στον υποφάκελο .stversions)",
"Please consult the release notes before performing a major upgrade.": "Παρακαλούμε, πριν από την εκτέλεση μιας σημαντικής αναβάθμισης, να συμβουλευτείς το σημείωμα που τη συνοδεύει. ", "Please consult the release notes before performing a major upgrade.": "Please consult the release notes before performing a major upgrade.",
"Please wait": "Παρακαλώ περιμένετε", "Please wait": "Παρακαλώ περιμένετε",
"Preview": "Προεπισκόπηση", "Preview": "Προεπισκόπηση",
"Preview Usage Report": "Προεπισκόπηση αναφοράς χρήσης", "Preview Usage Report": "Προεπισκόπηση αναφοράς χρήσης",
"Quick guide to supported patterns": "Σύντομη βοήθεια σχετικά με τα πρότυπα αναζήτησης που υποστηρίζονται", "Quick guide to supported patterns": "Σύντομη βοήθεια σχετικά με τα πρότυπα αναζήτησης που υποστηρίζονται",
"RAM Utilization": "Επιβάρυνση RAM", "RAM Utilization": "Επιβάρυνση RAM",
"Random": "Τυχαία", "Random": "Random",
"Release Notes": "Σημείωμα έκδοσης", "Release Notes": "Release Notes",
"Rescan": "Έλεγξε για αλλαγές", "Rescan": "Έλεγξε για αλλαγές",
"Rescan All": "Έλεγξέ τα όλα για αλλαγές", "Rescan All": "Έλεγξέ τα όλα για αλλαγές",
"Rescan Interval": "Κάθε πότε θα ελέγχεται για αλλαγές ", "Rescan Interval": "Κάθε πότε θα ελέγχεται για αλλαγές ",
@@ -129,7 +122,7 @@
"Share With Devices": "Διαμοίρασε με αυτές τις συσκευές", "Share With Devices": "Διαμοίρασε με αυτές τις συσκευές",
"Share this folder?": "Να διαμοιραστεί αυτός ο φάκελος;", "Share this folder?": "Να διαμοιραστεί αυτός ο φάκελος;",
"Shared With": "Διαμοιράζεται με", "Shared With": "Διαμοιράζεται με",
"Short identifier for the folder. Must be the same on all cluster devices.": "Σύντομη ταυτότητα για το φάκελο. Θα πρέπει να είναι η ίδια σε όλη τη συστάδα συσκευών με τις οποίες διαμοιράζεται ο φάκελος αυτός.", "Short identifier for the folder. Must be the same on all cluster devices.": "Σύντομη ταυτότητα για το φάκελο. Θα πρέπει να είναι η ίδια σε όλες τις συσκευές με τις οποίες διαμοιράζεται ο φάκελος αυτός.",
"Show ID": "Εμφάνιση ταυτότητας", "Show ID": "Εμφάνιση ταυτότητας",
"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 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.": "Θα φαίνεται αντί για την ταυτότητα της συσκευής στην προβολή της κατάστασης ολόκληρης της συστάδας. Θα ενημερώνεται αυτόματα αν αλλάξει το όνομα της συσκευής.", "Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Θα φαίνεται αντί για την ταυτότητα της συσκευής στην προβολή της κατάστασης ολόκληρης της συστάδας. Θα ενημερώνεται αυτόματα αν αλλάξει το όνομα της συσκευής.",
@@ -137,7 +130,7 @@
"Shutdown Complete": "Πλήρης απενεργοποίηση", "Shutdown Complete": "Πλήρης απενεργοποίηση",
"Simple File Versioning": "Απλή τήρηση εκδόσεων", "Simple File Versioning": "Απλή τήρηση εκδόσεων",
"Single level wildcard (matches within a directory only)": "Τελεστής μπαλαντέρ (*) για ένα επίπεδο (χρησιμοποιείται για έναν φάκελο μόνο)", "Single level wildcard (matches within a directory only)": "Τελεστής μπαλαντέρ (*) για ένα επίπεδο (χρησιμοποιείται για έναν φάκελο μόνο)",
"Smallest First": "Το μικρότερο πρώτα", "Smallest First": "Smallest First",
"Source Code": "Πηγαίος κώδικας", "Source Code": "Πηγαίος κώδικας",
"Staggered File Versioning": "Να τηρούνται κλιμακούμενες εκδόσεις", "Staggered File Versioning": "Να τηρούνται κλιμακούμενες εκδόσεις",
"Start Browser": "Εκκίνηση προγράμματος περιήγησης", "Start Browser": "Εκκίνηση προγράμματος περιήγησης",
@@ -150,14 +143,14 @@
"Syncthing is restarting.": "Το Syncthing επανεκκινείται.", "Syncthing is restarting.": "Το Syncthing επανεκκινείται.",
"Syncthing is upgrading.": "Το Syncthing αναβαθμίζεται.", "Syncthing is upgrading.": "Το 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.", "Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Το Syncthing φαίνεται να αντιμετωπίζει ένα πρόβλημα κατά την επεξεργασία του αιτήματός σας. Παρακαλούμε ανανεώστε την σελίδα ή επανεκκινήστε το Syncthing εάν το πρόβλημα παραμένει.",
"The aggregated statistics are publicly available at {%url%}.": "Τα στατιστικά που έχουν συλλεγεί είναι δημόσια διαθέσιμα στο {{url}}.", "The aggregated statistics are publicly available at {%url%}.": "Τα στατιστικά που έχουν συλλεγεί είναι δημόσια διαθέσιμα στο {{url}}.",
"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 cannot be blank.": "Η ταυτότητα της συσκευής δεν μπορεί να είναι κενή",
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Η ταυτότητα της συσκευής που θα μπει εδώ βρίσκεται στο μενού «Επεξεργασία > Εμφάνιση ταυτότητας» στην άλλη συσκευή. Κενοί χαρακτήρες και παύλες είναι προαιρετικοί (απλά θα αγνοηθούν).", "The device ID to enter here can be found in the \"Edit > 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.": "Η κρυπτογραφημένη αναφορά χρήσης στέλνεται καθημερινά. Χρησιμοποιείται για να παραχθούν στατιστικές για τα λειτουργικά συστήματα που χρησιμοποιούνται, τα μεγέθη των φακέλων και τις εκδόσεις των προγραμμάτων. Αν στο μέλλον συμπεριληφθούν και άλλα δεδομένα στην αναφορά χρήσης, τότε αυτό το παράθυρο θα εμφανιστεί ξανά.", "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.": "Η ταυτότητα συσκευής που έδωσες δε φαίνεται έγκυρη. Θα πρέπει να είναι μια σειρά από 52 ή 56 χαρακτήρες (γράμματα και αριθμοί). Τα κενά και οι παύλες είναι προαιρετικά (αδιάφορα).", "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 first command line parameter is the folder path and the second parameter is the relative path in the folder.": "Η πρώτη παράμετρος στη γραμμή εντολών είναι το μονοπάτι του φακέλου και η δεύτερη παράμετρος είναι το σχετικό μονοπάτι στο φάκελο.", "The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "Η πρώτη παράμετρος γραμμής εντολών είναι η διαδρομή του φακέλου και η δεύτερη παράμετρος είναι η σχετική διαδρομή στο φάκελο.",
"The folder ID cannot be blank.": "Η ταυτότητα του φακέλου δεν μπορεί να είναι κενή.", "The folder ID cannot be blank.": "Η ταυτότητα του φακέλου δεν μπορεί να είναι κενή.",
"The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "Η ταυτότητα του φακέλου πρέπει να είναι ένα σύντομο αναγνωριστικό (το πολύ 64 χαρακτήρες). Μπορεί να αποτελείται από γράμματα, αριθμούς, την τελεία (.), την παύλα (-) και την κάτω παύλα (_).", "The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "Η ταυτότητα του φακέλου πρέπει να είναι ένα σύντομο αναγνωριστικό (το πολύ 64 χαρακτήρες). Μπορεί να αποτελείται από γράμματα, αριθμούς, την τελεία (.), την παύλα (-) και την κάτω παύλα (_).",
"The folder ID must be unique.": "Η ταυτότητα του φακέλου πρέπει να είναι μοναδική.", "The folder ID must be unique.": "Η ταυτότητα του φακέλου πρέπει να είναι μοναδική.",
@@ -165,24 +158,20 @@
"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 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 maximum age must be a number and cannot be blank.": "Η μέγιστη ηλικία πρέπει να είναι αριθμός και σίγουρα όχι κενό.", "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 maximum time to keep a version (in days, set to 0 to keep versions forever).": "Η μέγιστη ηλικία παλιότερων εκδόσεων (σε ημέρες, αν δώσεις 0 οι παλιότερες εκδόσεις θα διατηρούνται για πάντα).",
"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 old versions to keep, per file.": "Πόσες παλιότερες εκδόσεις θα διατηρούνται, ανά αρχείο.",
"The number of versions must be a number and cannot be blank.": "Ο αριθμός εκδόσεων πρέπει να είναι αριθμός και σίγουρα όχι κενό.", "The number of versions must be a number and cannot be blank.": "Ο αριθμός εκδόσεων πρέπει να είναι αριθμός και σίγουρα όχι κενό.",
"The path cannot be blank.": "Το μονοπάτι δεν μπορεί να είναι κενό.", "The path cannot be blank.": "Το μονοπάτι δεν μπορεί να είναι κενό.",
"The rescan interval must be a non-negative number of seconds.": "Ο χρόνος επανελέγχου για αλλαγές είναι σε δευτερόλεπτα (δηλ. θετικός αριθμός).", "The rescan interval must be a non-negative number of seconds.": "Ο χρόνος επανελέγχου για αλλαγές είναι σε δευτερόλεπτα (δηλ. θετικός αριθμός).",
"This is a major version upgrade.": "Αυτή είναι μιας σημαντική αναβάθμιση.", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Ο Κάδος μπορεί να τηρεί εκδόσεις",
"Unknown": "Άγνωστο", "Unknown": "Άγνωστο",
"Unshared": "Δε μοιράζεται", "Unshared": "Δε μοιράζεται",
"Unused": "Δε χρησιμοποιείται", "Unused": "Δε χρησιμοποιείται",
"Up to Date": "Ενημερωμένος", "Up to Date": "Ενημερωμένος",
"Updated": "Ενημερωμένο", "Upgrade": "Upgrade",
"Upgrade": "Αναβάθμιση",
"Upgrade To {%version%}": "Αναβάθμιση στην έκδοση {{version}}", "Upgrade To {%version%}": "Αναβάθμιση στην έκδοση {{version}}",
"Upgrading": "Αναβάθμιση", "Upgrading": "Αναβάθμιση",
"Upload Rate": "Ταχύτητα ανεβάσματος", "Upload Rate": "Ταχύτητα ανεβάσματος",
"Uptime": "Χρόνος απρόσκοπτης λειτουργίας", "Uptime": "Uptime",
"Use HTTPS for GUI": "Χρήση HTTPS για τη διεπαφή", "Use HTTPS for GUI": "Χρήση HTTPS για τη διεπαφή",
"Version": "Έκδοση", "Version": "Έκδοση",
"Versions Path": "Φάκελος τήρησης εκδόσεων", "Versions Path": "Φάκελος τήρησης εκδόσεων",
-11
View File
@@ -1,9 +1,7 @@
{ {
"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.": "A new major version may not be compatible with previous versions.", "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 Key", "API Key": "API Key",
"About": "About", "About": "About",
"Actions": "Actions",
"Add": "Add", "Add": "Add",
"Add Device": "Add Device", "Add Device": "Add Device",
"Add Folder": "Add Folder", "Add Folder": "Add Folder",
@@ -20,7 +18,6 @@
"Bugs": "Bugs", "Bugs": "Bugs",
"CPU Utilization": "CPU Utilisation", "CPU Utilization": "CPU Utilisation",
"Changelog": "Changelog", "Changelog": "Changelog",
"Clean out after": "Clean out after",
"Close": "Close", "Close": "Close",
"Command": "Command", "Command": "Command",
"Comment, when used at the start of a line": "Comment, when used at the start of a line", "Comment, when used at the start of a line": "Comment, when used at the start of a line",
@@ -30,7 +27,6 @@
"Copied from original": "Copied from original", "Copied from original": "Copied from original",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
"Delete": "Delete", "Delete": "Delete",
"Deleted": "Deleted",
"Device ID": "Device ID", "Device ID": "Device ID",
"Device Identification": "Device Identification", "Device Identification": "Device Identification",
"Device Name": "Device Name", "Device Name": "Device Name",
@@ -53,7 +49,6 @@
"File Pull Order": "File Pull Order", "File Pull Order": "File Pull Order",
"File Versioning": "File Versioning", "File Versioning": "File Versioning",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by 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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.", "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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.",
"Folder ID": "Folder ID", "Folder ID": "Folder ID",
@@ -67,7 +62,6 @@
"Global Discovery": "Global Discovery", "Global Discovery": "Global Discovery",
"Global Discovery Server": "Global Discovery Server", "Global Discovery Server": "Global Discovery Server",
"Global State": "Global State", "Global State": "Global State",
"Help": "Help",
"Ignore": "Ignore", "Ignore": "Ignore",
"Ignore Patterns": "Ignore Patterns", "Ignore Patterns": "Ignore Patterns",
"Ignore Permissions": "Ignore Permissions", "Ignore Permissions": "Ignore Permissions",
@@ -81,7 +75,6 @@
"Later": "Later", "Later": "Later",
"Local Discovery": "Local Discovery", "Local Discovery": "Local Discovery",
"Local State": "Local State", "Local State": "Local State",
"Local State (Total)": "Local State (Total)",
"Major Upgrade": "Major Upgrade", "Major Upgrade": "Major Upgrade",
"Maximum Age": "Maximum Age", "Maximum Age": "Maximum Age",
"Metadata Only": "Metadata Only", "Metadata Only": "Metadata Only",
@@ -165,19 +158,15 @@
"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.": "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.", "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.": "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.",
"The maximum age must be a number and cannot be blank.": "The maximum age must be a number and cannot be blank.", "The maximum age must be a number and cannot be blank.": "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).": "The maximum time to keep a version (in days, set to 0 to keep versions forever).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "The maximum time to keep a version (in days, set to 0 to keep versions forever).",
"The number of days must be a number and cannot be blank.": "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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "The number of old versions to keep, per file.", "The number of old versions to keep, per file.": "The number of old versions to keep, per file.",
"The number of versions must be a number and cannot be blank.": "The number of versions must be a number and cannot be blank.", "The number of versions must be a number and cannot be blank.": "The number of versions must be a number and cannot be blank.",
"The path cannot be blank.": "The path cannot be blank.", "The path cannot be blank.": "The path cannot be blank.",
"The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.", "The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.",
"This is a major version upgrade.": "This is a major version upgrade.", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Rubbish Bin File Versioning",
"Unknown": "Unknown", "Unknown": "Unknown",
"Unshared": "Unshared", "Unshared": "Unshared",
"Unused": "Unused", "Unused": "Unused",
"Up to Date": "Up to Date", "Up to Date": "Up to Date",
"Updated": "Updated",
"Upgrade": "Upgrade", "Upgrade": "Upgrade",
"Upgrade To {%version%}": "Upgrade to {{version}}", "Upgrade To {%version%}": "Upgrade to {{version}}",
"Upgrading": "Upgrading", "Upgrading": "Upgrading",
+1 -22
View File
@@ -1,17 +1,13 @@
{ {
"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.": "A new major version may not be compatible with previous versions.", "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 Key", "API Key": "API Key",
"About": "About", "About": "About",
"Actions": "Actions",
"Add": "Add", "Add": "Add",
"Add Device": "Add Device", "Add Device": "Add Device",
"Add Folder": "Add Folder", "Add Folder": "Add Folder",
"Add new folder?": "Add new folder?", "Add new folder?": "Add new folder?",
"Address": "Address", "Address": "Address",
"Addresses": "Addresses", "Addresses": "Addresses",
"Advanced": "Advanced",
"Advanced Configuration": "Advanced Configuration",
"All Data": "All Data", "All Data": "All Data",
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?", "Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
"Alphabetic": "Alphabetic", "Alphabetic": "Alphabetic",
@@ -19,11 +15,9 @@
"Anonymous Usage Reporting": "Anonymous Usage Reporting", "Anonymous Usage Reporting": "Anonymous Usage Reporting",
"Any devices configured on an introducer device will be added to this device as well.": "Any devices configured on an introducer device will be added to this device as well.", "Any devices configured on an introducer device will be added to this device as well.": "Any devices configured on an introducer device will be added to this device as well.",
"Automatic upgrades": "Automatic upgrades", "Automatic upgrades": "Automatic upgrades",
"Be careful!": "Be careful!",
"Bugs": "Bugs", "Bugs": "Bugs",
"CPU Utilization": "CPU Utilization", "CPU Utilization": "CPU Utilization",
"Changelog": "Changelog", "Changelog": "Changelog",
"Clean out after": "Clean out after",
"Close": "Close", "Close": "Close",
"Command": "Command", "Command": "Command",
"Comment, when used at the start of a line": "Comment, when used at the start of a line", "Comment, when used at the start of a line": "Comment, when used at the start of a line",
@@ -33,7 +27,6 @@
"Copied from original": "Copied from original", "Copied from original": "Copied from original",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
"Delete": "Delete", "Delete": "Delete",
"Deleted": "Deleted",
"Device ID": "Device ID", "Device ID": "Device ID",
"Device Identification": "Device Identification", "Device Identification": "Device Identification",
"Device Name": "Device Name", "Device Name": "Device Name",
@@ -53,19 +46,15 @@
"Enter ignore patterns, one per line.": "Enter ignore patterns, one per line.", "Enter ignore patterns, one per line.": "Enter ignore patterns, one per line.",
"Error": "Error", "Error": "Error",
"External File Versioning": "External File Versioning", "External File Versioning": "External File Versioning",
"Failed Items": "Failed Items",
"File Pull Order": "File Pull Order", "File Pull Order": "File Pull Order",
"File Versioning": "File Versioning", "File Versioning": "File Versioning",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by 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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.", "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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.",
"Folder": "Folder",
"Folder ID": "Folder ID", "Folder ID": "Folder ID",
"Folder Master": "Folder Master", "Folder Master": "Folder Master",
"Folder Path": "Folder Path", "Folder Path": "Folder Path",
"Folders": "Folders", "Folders": "Folders",
"GUI": "GUI",
"GUI Authentication Password": "GUI Authentication Password", "GUI Authentication Password": "GUI Authentication Password",
"GUI Authentication User": "GUI Authentication User", "GUI Authentication User": "GUI Authentication User",
"GUI Listen Addresses": "GUI Listen Addresses", "GUI Listen Addresses": "GUI Listen Addresses",
@@ -73,12 +62,10 @@
"Global Discovery": "Global Discovery", "Global Discovery": "Global Discovery",
"Global Discovery Server": "Global Discovery Server", "Global Discovery Server": "Global Discovery Server",
"Global State": "Global State", "Global State": "Global State",
"Help": "Help",
"Ignore": "Ignore", "Ignore": "Ignore",
"Ignore Patterns": "Ignore Patterns", "Ignore Patterns": "Ignore Patterns",
"Ignore Permissions": "Ignore Permissions", "Ignore Permissions": "Ignore Permissions",
"Incoming Rate Limit (KiB/s)": "Incoming Rate Limit (KiB/s)", "Incoming Rate Limit (KiB/s)": "Incoming Rate Limit (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Incorrect configuration may damage your folder contents and render Syncthing inoperable.",
"Introducer": "Introducer", "Introducer": "Introducer",
"Inversion of the given condition (i.e. do not exclude)": "Inversion of the given condition (i.e. do not exclude)", "Inversion of the given condition (i.e. do not exclude)": "Inversion of the given condition (i.e. do not exclude)",
"Keep Versions": "Keep Versions", "Keep Versions": "Keep Versions",
@@ -88,7 +75,6 @@
"Later": "Later", "Later": "Later",
"Local Discovery": "Local Discovery", "Local Discovery": "Local Discovery",
"Local State": "Local State", "Local State": "Local State",
"Local State (Total)": "Local State (Total)",
"Major Upgrade": "Major Upgrade", "Major Upgrade": "Major Upgrade",
"Maximum Age": "Maximum Age", "Maximum Age": "Maximum Age",
"Metadata Only": "Metadata Only", "Metadata Only": "Metadata Only",
@@ -104,8 +90,7 @@
"OK": "OK", "OK": "OK",
"Off": "Off", "Off": "Off",
"Oldest First": "Oldest First", "Oldest First": "Oldest First",
"Options": "Options", "Out Of Sync": "Out Of Sync",
"Out of Sync": "Out of Sync",
"Out of Sync Items": "Out of Sync Items", "Out of Sync Items": "Out of Sync Items",
"Outgoing Rate Limit (KiB/s)": "Outgoing Rate Limit (KiB/s)", "Outgoing Rate Limit (KiB/s)": "Outgoing Rate Limit (KiB/s)",
"Override Changes": "Override Changes", "Override Changes": "Override Changes",
@@ -171,23 +156,17 @@
"The folder ID must be unique.": "The folder ID must be unique.", "The folder ID must be unique.": "The folder ID must be unique.",
"The folder path cannot be blank.": "The folder path cannot be blank.", "The folder path cannot be blank.": "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.": "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.", "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.": "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.",
"The following items could not be synchronized.": "The following items could not be synchronized.",
"The maximum age must be a number and cannot be blank.": "The maximum age must be a number and cannot be blank.", "The maximum age must be a number and cannot be blank.": "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).": "The maximum time to keep a version (in days, set to 0 to keep versions forever).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "The maximum time to keep a version (in days, set to 0 to keep versions forever).",
"The number of days must be a number and cannot be blank.": "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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "The number of old versions to keep, per file.", "The number of old versions to keep, per file.": "The number of old versions to keep, per file.",
"The number of versions must be a number and cannot be blank.": "The number of versions must be a number and cannot be blank.", "The number of versions must be a number and cannot be blank.": "The number of versions must be a number and cannot be blank.",
"The path cannot be blank.": "The path cannot be blank.", "The path cannot be blank.": "The path cannot be blank.",
"The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.", "The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.",
"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 is a major version upgrade.": "This is a major version upgrade.", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Trash Can File Versioning",
"Unknown": "Unknown", "Unknown": "Unknown",
"Unshared": "Unshared", "Unshared": "Unshared",
"Unused": "Unused", "Unused": "Unused",
"Up to Date": "Up to Date", "Up to Date": "Up to Date",
"Updated": "Updated",
"Upgrade": "Upgrade", "Upgrade": "Upgrade",
"Upgrade To {%version%}": "Upgrade To {{version}}", "Upgrade To {%version%}": "Upgrade To {{version}}",
"Upgrading": "Upgrading", "Upgrading": "Upgrading",
+3 -14
View File
@@ -1,9 +1,7 @@
{ {
"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 con cambios importantes puede no ser compatible con versiones anteriores.", "A new major version may not be compatible with previous versions.": "Una nueva versión con cambios importantes puede no ser compatible con versiones anteriores.",
"API Key": "Clave del API", "API Key": "Clave del API",
"About": "Acerca de", "About": "Acerca de",
"Actions": "Acciones",
"Add": "Añadir", "Add": "Añadir",
"Add Device": "Añadir dispositivo", "Add Device": "Añadir dispositivo",
"Add Folder": "Añadir repositorio", "Add Folder": "Añadir repositorio",
@@ -20,7 +18,6 @@
"Bugs": "Errores (bugs)", "Bugs": "Errores (bugs)",
"CPU Utilization": "Uso de CPU", "CPU Utilization": "Uso de CPU",
"Changelog": "Informe de cambios", "Changelog": "Informe de cambios",
"Clean out after": "Limpiar tras",
"Close": "Cerrar", "Close": "Cerrar",
"Command": "Comando", "Command": "Comando",
"Comment, when used at the start of a line": "Comentar, cuando se usa al comienzo de una línea", "Comment, when used at the start of a line": "Comentar, cuando se usa al comienzo de una línea",
@@ -30,7 +27,6 @@
"Copied from original": "Copiado del original", "Copied from original": "Copiado del original",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 los siguientes Colaboradores:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 los siguientes Colaboradores:",
"Delete": "Borrar", "Delete": "Borrar",
"Deleted": "Borrado",
"Device ID": "ID del dispositivo", "Device ID": "ID del dispositivo",
"Device Identification": "Identificación del dispositivo", "Device Identification": "Identificación del dispositivo",
"Device Name": "Nombre del dispositivo", "Device Name": "Nombre del dispositivo",
@@ -46,14 +42,13 @@
"Edit Folder": "Editar repositorio", "Edit Folder": "Editar repositorio",
"Editing": "Editando", "Editing": "Editando",
"Enable UPnP": "Habilitar UPnP", "Enable UPnP": "Habilitar UPnP",
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduce las direcciones separadas por comas como \"ip:puerto\" o \"dynamic\" para el descubrimiento automático de la dirección.", "Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Introducir las direcciones separadas por comas como \"ip:puerto\" o \"dynamic\" para el descubrimiento automático de la dirección.",
"Enter ignore patterns, one per line.": "Introducir patrones a ignorar, uno por línea.", "Enter ignore patterns, one per line.": "Introducir patrones a ignorar, uno por línea.",
"Error": "Error", "Error": "Error",
"External File Versioning": "Versionado externo de fichero", "External File Versioning": "Versionado externo de fichero",
"File Pull Order": "Orden de ficheros del pull", "File Pull Order": "Orden de ficheros del pull",
"File Versioning": "Versionado de ficheros", "File Versioning": "Versionado de ficheros",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Los bits de permiso de ficheros son ignorados cuando se buscan cambios. Utilizar en sistemas de ficheros FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Los bits de permiso de ficheros son ignorados cuando se buscan cambios. Utilizar en sistemas de ficheros FAT.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Los archivos serán movidos a la carpeta .stversions cuando sean reemplazados o borrados por Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Los ficheros son cambiados a versiones con indicación de fecha en una carpeta \".stversions\" cuando son reemplazados o borrados por Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Los ficheros son cambiados a versiones con indicación de fecha en una carpeta \".stversions\" cuando son reemplazados o borrados por 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.": "Los ficheros son protegidos por los cambios hechos en otros dispositivos, pero los cambios hechos en este dispositivo serán enviados al resto del grupo (cluster).", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Los ficheros son protegidos por los cambios hechos en otros dispositivos, pero los cambios hechos en este dispositivo serán enviados al resto del grupo (cluster).",
"Folder ID": "ID de carpeta", "Folder ID": "ID de carpeta",
@@ -67,7 +62,6 @@
"Global Discovery": "Descubrimiento global", "Global Discovery": "Descubrimiento global",
"Global Discovery Server": "Servidor de descubrimiento global", "Global Discovery Server": "Servidor de descubrimiento global",
"Global State": "Estado global", "Global State": "Estado global",
"Help": "Ayuda",
"Ignore": "Ignorar", "Ignore": "Ignorar",
"Ignore Patterns": "Patrones a ignorar", "Ignore Patterns": "Patrones a ignorar",
"Ignore Permissions": "Permisos a ignorar", "Ignore Permissions": "Permisos a ignorar",
@@ -77,11 +71,10 @@
"Keep Versions": "Mantener versiones", "Keep Versions": "Mantener versiones",
"Largest First": "Más grande primero", "Largest First": "Más grande primero",
"Last File Received": "Último fichero recibido", "Last File Received": "Último fichero recibido",
"Last seen": "Visto por última vez", "Last seen": "La última vez que se vio",
"Later": "Más tarde", "Later": "Más tarde",
"Local Discovery": "Descubrimiento local", "Local Discovery": "Descubrimiento local",
"Local State": "Estado local", "Local State": "Estado local",
"Local State (Total)": "Estado Local (Total)",
"Major Upgrade": "Actualización importante", "Major Upgrade": "Actualización importante",
"Maximum Age": "Edad máxima", "Maximum Age": "Edad máxima",
"Metadata Only": "Sólo metadatos", "Metadata Only": "Sólo metadatos",
@@ -149,7 +142,7 @@
"Syncthing includes the following software or portions thereof:": "Syncthing incluye el siguiente software o partes de él:", "Syncthing includes the following software or portions thereof:": "Syncthing incluye el siguiente software o partes de él:",
"Syncthing is restarting.": "Syncthing se está reiniciando.", "Syncthing is restarting.": "Syncthing se está reiniciando.",
"Syncthing is upgrading.": "Syncthing se está actualizando.", "Syncthing is upgrading.": "Syncthing se está actualizando.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing parece no estar activo o hay un problema con tu conexión de internet. Reintentando...", "Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Sincthing parece no estar activo o hay un problema con tu conexión de internet. Reintentando...",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing tiene problemas para procesar tu solicitud. Por favor, actualiza la página o reinicia Syncthing si el problema persiste.", "Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing tiene problemas para procesar tu solicitud. Por favor, actualiza la página o reinicia Syncthing si el problema persiste.",
"The aggregated statistics are publicly available at {%url%}.": "Las estadísticas agregadas están disponibles públicamente en {{url}}.", "The aggregated statistics are publicly available at {%url%}.": "Las estadísticas agregadas están disponibles públicamente en {{url}}.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "La configuración ha sido grabada pero no activada. Syncthing debe reiniciarse para activar la nueva configuración.", "The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "La configuración ha sido grabada pero no activada. Syncthing debe reiniciarse para activar la nueva configuración.",
@@ -165,19 +158,15 @@
"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.": "Se utilizan los siguientes intervalos: para la primera hora se mantiene una versión cada 30 segundos, para el primer día se mantiene una versión cada hora, para los primeros 30 días se mantiene una versión diaria hasta la edad máxima de una semana.", "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.": "Se utilizan los siguientes intervalos: para la primera hora se mantiene una versión cada 30 segundos, para el primer día se mantiene una versión cada hora, para los primeros 30 días se mantiene una versión diaria hasta la edad máxima de una semana.",
"The maximum age must be a number and cannot be blank.": "La edad máxima debe ser un número y no puede estar vacía.", "The maximum age must be a number and cannot be blank.": "La edad máxima debe ser un número y no puede estar vacía.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "El tiempo máximo para mantener una versión en días (introducir 0 para mantener las versiones indefinidamente).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "El tiempo máximo para mantener una versión en días (introducir 0 para mantener las versiones indefinidamente).",
"The number of days must be a number and cannot be blank.": "El número de días debe ser un número y no puede estar en blanco.",
"The number of days to keep files in the trash can. Zero means forever.": "El número de días para mantener los archivos en la papelera. Cero significa \"para siempre\".",
"The number of old versions to keep, per file.": "El número de versiones a antiguas a mantener para cada fichero.", "The number of old versions to keep, per file.": "El número de versiones a antiguas a mantener para cada fichero.",
"The number of versions must be a number and cannot be blank.": "El número de versiones debe ser un número y no puede estar vacío.", "The number of versions must be a number and cannot be blank.": "El número de versiones debe ser un número y no puede estar vacío.",
"The path cannot be blank.": "La ruta no puede estar vacía.", "The path cannot be blank.": "La ruta no puede estar vacía.",
"The rescan interval must be a non-negative number of seconds.": "El intervalo de actualización debe ser un número positivo de segundos.", "The rescan interval must be a non-negative number of seconds.": "El intervalo de actualización debe ser un número positivo de segundos.",
"This is a major version upgrade.": "Hay una actualización importante.", "This is a major version upgrade.": "Hay una actualización importante.",
"Trash Can File Versioning": "Versionado de archivos de la papelera",
"Unknown": "Desconocido", "Unknown": "Desconocido",
"Unshared": "No compartido", "Unshared": "No compartido",
"Unused": "No usado", "Unused": "No usado",
"Up to Date": "Actualizado", "Up to Date": "Actualizado",
"Updated": "Actualizado",
"Upgrade": "Actualizar", "Upgrade": "Actualizar",
"Upgrade To {%version%}": "Actualizar a {{version}}", "Upgrade To {%version%}": "Actualizar a {{version}}",
"Upgrading": "Actualizando", "Upgrading": "Actualizando",
+14 -25
View File
@@ -1,9 +1,7 @@
{ {
"A negative number of days doesn't make sense.": "Un número negativo no tiene sentido", "A new major version may not be compatible with previous versions.": "A new major version may not be compatible with previous versions.",
"A new major version may not be compatible with previous versions.": "Una versión mayor nueva puede ser incompatible con versiones anteriores.",
"API Key": "Clave API", "API Key": "Clave API",
"About": "Acerca de", "About": "Acerca de",
"Actions": "Acciones",
"Add": "Agregar", "Add": "Agregar",
"Add Device": "Agregar Dispositivo", "Add Device": "Agregar Dispositivo",
"Add Folder": "Agregar Repositorio", "Add Folder": "Agregar Repositorio",
@@ -12,7 +10,7 @@
"Addresses": "Direcciones", "Addresses": "Direcciones",
"All Data": "Todos los datos", "All Data": "Todos los datos",
"Allow Anonymous Usage Reporting?": "Permitir reporte anónimo de uso?", "Allow Anonymous Usage Reporting?": "Permitir reporte anónimo de uso?",
"Alphabetic": "Alfabético", "Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Un comando exterior maneja el control de versiones. Éste tiene que eliminar el archivo de la carpeta sincronizada.", "An external command handles the versioning. It has to remove the file from the synced folder.": "Un comando exterior maneja el control de versiones. Éste tiene que eliminar el archivo de la carpeta sincronizada.",
"Anonymous Usage Reporting": "Reporte anónimo de uso", "Anonymous Usage Reporting": "Reporte anónimo de uso",
"Any devices configured on an introducer device will be added to this device as well.": "Cualquier dispositivo configurado en un dispositivo introductor será también agregado a este dispositivo.", "Any devices configured on an introducer device will be added to this device as well.": "Cualquier dispositivo configurado en un dispositivo introductor será también agregado a este dispositivo.",
@@ -20,7 +18,6 @@
"Bugs": "Errores", "Bugs": "Errores",
"CPU Utilization": "Uso de CPU", "CPU Utilization": "Uso de CPU",
"Changelog": "Registro de cambios", "Changelog": "Registro de cambios",
"Clean out after": "Limpiar después",
"Close": "Cerrar", "Close": "Cerrar",
"Command": "Comando", "Command": "Comando",
"Comment, when used at the start of a line": "Comentario, cuando es utilizado al inicio de una línea.", "Comment, when used at the start of a line": "Comentario, cuando es utilizado al inicio de una línea.",
@@ -30,7 +27,6 @@
"Copied from original": "Copiado del original", "Copied from original": "Copiado del original",
"Copyright © 2015 the following Contributors:": "Derechos de autor © 2015 los siguientes colaboradores:", "Copyright © 2015 the following Contributors:": "Derechos de autor © 2015 los siguientes colaboradores:",
"Delete": "Suprimir", "Delete": "Suprimir",
"Deleted": "Suprimido",
"Device ID": "ID del dispositivo", "Device ID": "ID del dispositivo",
"Device Identification": "Identificación del dispositivo", "Device Identification": "Identificación del dispositivo",
"Device Name": "Nombre del dispositivo", "Device Name": "Nombre del dispositivo",
@@ -50,10 +46,9 @@
"Enter ignore patterns, one per line.": "Añadir patrones de exclusión, uno por línea.", "Enter ignore patterns, one per line.": "Añadir patrones de exclusión, uno por línea.",
"Error": "Error", "Error": "Error",
"External File Versioning": "Control de versiones externo", "External File Versioning": "Control de versiones externo",
"File Pull Order": "Orden para coger ficheros", "File Pull Order": "File Pull Order",
"File Versioning": "Control de versiones", "File Versioning": "Control de versiones",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Los permisos de archivo son ignorados al buscar cambios. Usar el sistemas de archivos FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Los permisos de archivo son ignorados al buscar cambios. Usar el sistemas de archivos FAT.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Los archivos son movidos al directorio .stversions cuando son reemplazados o eliminados por Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Lo archivos son movidos al directorio .stversions y renombrados a versiones marcadas por fecha cuando son reemplazados o eliminados por Syncthing,", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Lo archivos son movidos al directorio .stversions y renombrados a versiones marcadas por fecha cuando son reemplazados o eliminados por 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.": "Los archivos están protegidos frente a los cambios realizados en otros dispositivos, peros los cambios realizados en este dispositivo serán envíados al resto del grupo", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Los archivos están protegidos frente a los cambios realizados en otros dispositivos, peros los cambios realizados en este dispositivo serán envíados al resto del grupo",
"Folder ID": "ID del repositorio", "Folder ID": "ID del repositorio",
@@ -67,7 +62,6 @@
"Global Discovery": "Búsqueda en internet", "Global Discovery": "Búsqueda en internet",
"Global Discovery Server": "Servidor global de identificación", "Global Discovery Server": "Servidor global de identificación",
"Global State": "Estado global", "Global State": "Estado global",
"Help": "Ayuda",
"Ignore": "Ignorar", "Ignore": "Ignorar",
"Ignore Patterns": "Patrones de exclusión", "Ignore Patterns": "Patrones de exclusión",
"Ignore Permissions": "Ignorar permisos", "Ignore Permissions": "Ignorar permisos",
@@ -75,14 +69,13 @@
"Introducer": "Introductor", "Introducer": "Introductor",
"Inversion of the given condition (i.e. do not exclude)": "Inversión de la condición dada (es decir, no excluir)", "Inversion of the given condition (i.e. do not exclude)": "Inversión de la condición dada (es decir, no excluir)",
"Keep Versions": "Conservar versiones", "Keep Versions": "Conservar versiones",
"Largest First": "Más grande primero", "Largest First": "Largest First",
"Last File Received": "Último archivo recibido", "Last File Received": "Último archivo recibido",
"Last seen": "Visto por ultima vez", "Last seen": "Visto por ultima vez",
"Later": "Más tarde", "Later": "Más tarde",
"Local Discovery": "Búsqueda en red local", "Local Discovery": "Búsqueda en red local",
"Local State": "Estado local", "Local State": "Estado local",
"Local State (Total)": "Estado local (total)", "Major Upgrade": "Major Upgrade",
"Major Upgrade": "Actualización mayor",
"Maximum Age": "Edad máxima", "Maximum Age": "Edad máxima",
"Metadata Only": "Sólo metadatos", "Metadata Only": "Sólo metadatos",
"Move to top of queue": "Mover al principio de la cola.", "Move to top of queue": "Mover al principio de la cola.",
@@ -90,27 +83,27 @@
"Never": "Nunca", "Never": "Nunca",
"New Device": "Nuevo dispositivo", "New Device": "Nuevo dispositivo",
"New Folder": "Nuevo repositorio", "New Folder": "Nuevo repositorio",
"Newest First": "Nuevo primero", "Newest First": "Newest First",
"No": "No", "No": "No",
"No File Versioning": "Sin control de versiones de archivos", "No File Versioning": "Sin control de versiones de archivos",
"Notice": "Aviso", "Notice": "Aviso",
"OK": "OK", "OK": "OK",
"Off": "Apagado", "Off": "Apagado",
"Oldest First": "Antiguo primero", "Oldest First": "Oldest First",
"Out Of Sync": "Fuera de sincronización", "Out Of Sync": "Fuera de sincronización",
"Out of Sync Items": "Ítems no sincronizados", "Out of Sync Items": "Ítems no sincronizados",
"Outgoing Rate Limit (KiB/s)": "Tasa máxima de envío (KiB/s)", "Outgoing Rate Limit (KiB/s)": "Tasa máxima de envío (KiB/s)",
"Override Changes": "Reemplazar los cambios", "Override Changes": "Reemplazar los cambios",
"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 del repositorio en el equipo local. Será creado si no existe. El carácter tilde (~) puede ser utilizado como atajo de ", "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 del repositorio en el equipo local. Será creado si no existe. El carácter tilde (~) puede ser utilizado como atajo de ",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Ruta donde serán guardas las versiones (dejar vacío para usar el directorio predifinido \".stversions\" en el repositorio)", "Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Ruta donde serán guardas las versiones (dejar vacío para usar el directorio predifinido \".stversions\" en el repositorio)",
"Please consult the release notes before performing a major upgrade.": "Por favor consulta las notas de lanzamiento antes de realizar una actualizacón mayor.", "Please consult the release notes before performing a major upgrade.": "Please consult the release notes before performing a major upgrade.",
"Please wait": "Aguarde por favor", "Please wait": "Aguarde por favor",
"Preview": "Vista previa", "Preview": "Vista previa",
"Preview Usage Report": "Ver reporte de uso", "Preview Usage Report": "Ver reporte de uso",
"Quick guide to supported patterns": "Guía rápida sobre los patrones soportados", "Quick guide to supported patterns": "Guía rápida sobre los patrones soportados",
"RAM Utilization": "Utilización de RAM", "RAM Utilization": "Utilización de RAM",
"Random": "Aleatorio", "Random": "Random",
"Release Notes": "Notas de lanzamiento", "Release Notes": "Release Notes",
"Rescan": "Reescanear", "Rescan": "Reescanear",
"Rescan All": "Reescanear todo", "Rescan All": "Reescanear todo",
"Rescan Interval": "Intervalo de reescaneo", "Rescan Interval": "Intervalo de reescaneo",
@@ -137,7 +130,7 @@
"Shutdown Complete": "Apagado completado", "Shutdown Complete": "Apagado completado",
"Simple File Versioning": "Versiones simple de archivos", "Simple File Versioning": "Versiones simple de archivos",
"Single level wildcard (matches within a directory only)": "Carácter comodín de un solo nivel (coincide sólo dentro de un directorio)", "Single level wildcard (matches within a directory only)": "Carácter comodín de un solo nivel (coincide sólo dentro de un directorio)",
"Smallest First": "Más pequeño primero", "Smallest First": "Smallest First",
"Source Code": "Código fuente", "Source Code": "Código fuente",
"Staggered File Versioning": "Versiones del archivo escalonado", "Staggered File Versioning": "Versiones del archivo escalonado",
"Start Browser": "Iniciar navegador", "Start Browser": "Iniciar navegador",
@@ -165,24 +158,20 @@
"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.": "Los siguientes intervalos se utilizan: para la primera hora una versión se mantiene cada 30 segundos, para el primer día de una versión se mantiene cada hora, durante los primeros 30 días de la versión se mantiene todos los días, hasta que la edad máxima de una versión se mantiene cada semana.", "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.": "Los siguientes intervalos se utilizan: para la primera hora una versión se mantiene cada 30 segundos, para el primer día de una versión se mantiene cada hora, durante los primeros 30 días de la versión se mantiene todos los días, hasta que la edad máxima de una versión se mantiene cada semana.",
"The maximum age must be a number and cannot be blank.": "La edad máxima debe ser un número y no puede estar en blanco.", "The maximum age must be a number and cannot be blank.": "La edad máxima debe ser un número y no puede estar en blanco.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "El tiempo máximo para mantener una versión (en días, establece en 0 para mantener versiones para siempre).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "El tiempo máximo para mantener una versión (en días, establece en 0 para mantener versiones para siempre).",
"The number of days must be a number and cannot be blank.": "El número de días debe ser un número y no puede estar vacío.",
"The number of days to keep files in the trash can. Zero means forever.": "El tiempo máximo para mantener un archivo en el cubo de basura (en días, establece en 0 para mantener versiones para siempre).",
"The number of old versions to keep, per file.": "El numero de versiones anteriores a conservar, por archivo.", "The number of old versions to keep, per file.": "El numero de versiones anteriores a conservar, por archivo.",
"The number of versions must be a number and cannot be blank.": "El número de versiones debe ser un número y no puede estar vacío.", "The number of versions must be a number and cannot be blank.": "El número de versiones debe ser un número y no puede estar vacío.",
"The path cannot be blank.": "La ruta no puede estar vacía.", "The path cannot be blank.": "La ruta no puede estar vacía.",
"The rescan interval must be a non-negative number of seconds.": "El intervalo de reescaneo debe ser un número no negativo de segundos.", "The rescan interval must be a non-negative number of seconds.": "El intervalo de reescaneo debe ser un número no negativo de segundos.",
"This is a major version upgrade.": "Esta es una actualización de version mayor.", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Versiones como cubo de basura",
"Unknown": "Desconocido", "Unknown": "Desconocido",
"Unshared": "No compartido", "Unshared": "No compartido",
"Unused": "No utilizado", "Unused": "No utilizado",
"Up to Date": "Actualizado", "Up to Date": "Actualizado",
"Updated": "Actualizado", "Upgrade": "Upgrade",
"Upgrade": "Actualizar",
"Upgrade To {%version%}": "Actualizar a {{version}}", "Upgrade To {%version%}": "Actualizar a {{version}}",
"Upgrading": "Actualizando", "Upgrading": "Actualizando",
"Upload Rate": "Tasa de subida", "Upload Rate": "Tasa de subida",
"Uptime": "Tiempo en funcionamiento", "Uptime": "Uptime",
"Use HTTPS for GUI": "Usar HTTPS para la GUI", "Use HTTPS for GUI": "Usar HTTPS para la GUI",
"Version": "Versión", "Version": "Versión",
"Versions Path": "Ruta de versiones", "Versions Path": "Ruta de versiones",
-11
View File
@@ -1,9 +1,7 @@
{ {
"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.": "A new major version may not be compatible with previous versions.", "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-avain", "API Key": "API-avain",
"About": "Tietoja", "About": "Tietoja",
"Actions": "Actions",
"Add": "Lisää", "Add": "Lisää",
"Add Device": "Lisää laite", "Add Device": "Lisää laite",
"Add Folder": "Lisää kansio", "Add Folder": "Lisää kansio",
@@ -20,7 +18,6 @@
"Bugs": "Bugit", "Bugs": "Bugit",
"CPU Utilization": "CPU:n käyttö", "CPU Utilization": "CPU:n käyttö",
"Changelog": "Muutoshistoria", "Changelog": "Muutoshistoria",
"Clean out after": "Clean out after",
"Close": "Sulje", "Close": "Sulje",
"Command": "Komento", "Command": "Komento",
"Comment, when used at the start of a line": "Kommentti, käytettäessä rivin alussa", "Comment, when used at the start of a line": "Kommentti, käytettäessä rivin alussa",
@@ -30,7 +27,6 @@
"Copied from original": "Kopioitu alkuperäisestä lähteestä", "Copied from original": "Kopioitu alkuperäisestä lähteestä",
"Copyright © 2015 the following Contributors:": "Tekijänoikeus © 2015 seuraavat avustajat:", "Copyright © 2015 the following Contributors:": "Tekijänoikeus © 2015 seuraavat avustajat:",
"Delete": "Poista", "Delete": "Poista",
"Deleted": "Deleted",
"Device ID": "Laitteen ID", "Device ID": "Laitteen ID",
"Device Identification": "Laitteen tunniste", "Device Identification": "Laitteen tunniste",
"Device Name": "Laitteen nimi", "Device Name": "Laitteen nimi",
@@ -53,7 +49,6 @@
"File Pull Order": "File Pull Order", "File Pull Order": "File Pull Order",
"File Versioning": "Tiedostoversiointi", "File Versioning": "Tiedostoversiointi",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Tiedostojen oikeusbitit jätetään huomiotta etsittäessä muutoksia. Käytä FAT-tiedostojärjestelmissä.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Tiedostojen oikeusbitit jätetään huomiotta etsittäessä muutoksia. Käytä FAT-tiedostojärjestelmissä.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Tiedostot siirretään päivämäärällä merkityiksi versioiksi .stversions-kansioon, kun Syncthing korvaa tai poistaa ne.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Tiedostot siirretään päivämäärällä merkityiksi versioiksi .stversions-kansioon, kun Syncthing korvaa tai poistaa ne.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Tiedostot on suojattu muilla laitteilla tehdyiltä muutoksilta, mutta tällä laitteella tehdyt muutokset lähetetään muuhun ryhmään.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Tiedostot on suojattu muilla laitteilla tehdyiltä muutoksilta, mutta tällä laitteella tehdyt muutokset lähetetään muuhun ryhmään.",
"Folder ID": "Kansion ID", "Folder ID": "Kansion ID",
@@ -67,7 +62,6 @@
"Global Discovery": "Globaali etsintä", "Global Discovery": "Globaali etsintä",
"Global Discovery Server": "Globaali etsintäpalvelin", "Global Discovery Server": "Globaali etsintäpalvelin",
"Global State": "Globaali tila", "Global State": "Globaali tila",
"Help": "Help",
"Ignore": "Ohita", "Ignore": "Ohita",
"Ignore Patterns": "Ohituslausekkeet", "Ignore Patterns": "Ohituslausekkeet",
"Ignore Permissions": "Jätä oikeudet huomiotta", "Ignore Permissions": "Jätä oikeudet huomiotta",
@@ -81,7 +75,6 @@
"Later": "Myöhemmin", "Later": "Myöhemmin",
"Local Discovery": "Paikallinen etsintä", "Local Discovery": "Paikallinen etsintä",
"Local State": "Paikallinen tila", "Local State": "Paikallinen tila",
"Local State (Total)": "Local State (Total)",
"Major Upgrade": "Major Upgrade", "Major Upgrade": "Major Upgrade",
"Maximum Age": "Maksimi-ikä", "Maximum Age": "Maksimi-ikä",
"Metadata Only": "Vain metadata", "Metadata Only": "Vain metadata",
@@ -165,19 +158,15 @@
"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.": "Seuraavat aikavälit ovat käytössä: ensimmäisen tunnin ajalta uusi versio säilytetään joka 30 sekunti, ensimmäisen päivän ajalta uusi versio säilytetään tunneittain ja ensimmäisen 30 päivän aikana uusi versio säilytetään päivittäin. Lopulta uusi versio säilytetään viikoittain, kunnes maksimi-ikä saavutetaan.", "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.": "Seuraavat aikavälit ovat käytössä: ensimmäisen tunnin ajalta uusi versio säilytetään joka 30 sekunti, ensimmäisen päivän ajalta uusi versio säilytetään tunneittain ja ensimmäisen 30 päivän aikana uusi versio säilytetään päivittäin. Lopulta uusi versio säilytetään viikoittain, kunnes maksimi-ikä saavutetaan.",
"The maximum age must be a number and cannot be blank.": "Maksimi-iän tulee olla numero, eikä se voi olla tyhjä.", "The maximum age must be a number and cannot be blank.": "Maksimi-iän tulee olla numero, eikä se voi olla tyhjä.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Maksimiaika versioiden säilytykseen (päivissä, aseta 0 säilyttääksesi versiot ikuisesti).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Maksimiaika versioiden säilytykseen (päivissä, aseta 0 säilyttääksesi versiot ikuisesti).",
"The number of days must be a number and cannot be blank.": "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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "Säilytettävien vanhojen versioiden määrä tiedostoa kohden.", "The number of old versions to keep, per file.": "Säilytettävien vanhojen versioiden määrä tiedostoa kohden.",
"The number of versions must be a number and cannot be blank.": "Versioiden määrän rulee olla numero, eikä se voi olla tyhjä.", "The number of versions must be a number and cannot be blank.": "Versioiden määrän rulee olla numero, eikä se voi olla tyhjä.",
"The path cannot be blank.": "Polku ei voi olla tyhjä.", "The path cannot be blank.": "Polku ei voi olla tyhjä.",
"The rescan interval must be a non-negative number of seconds.": "Uudelleenskannauksen aikavälin tulee olla ei-negatiivinen numero sekunteja.", "The rescan interval must be a non-negative number of seconds.": "Uudelleenskannauksen aikavälin tulee olla ei-negatiivinen numero sekunteja.",
"This is a major version upgrade.": "This is a major version upgrade.", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Trash Can File Versioning",
"Unknown": "Tuntematon", "Unknown": "Tuntematon",
"Unshared": "Jakamaton", "Unshared": "Jakamaton",
"Unused": "Käyttämätön", "Unused": "Käyttämätön",
"Up to Date": "Ajan tasalla", "Up to Date": "Ajan tasalla",
"Updated": "Updated",
"Upgrade": "Upgrade", "Upgrade": "Upgrade",
"Upgrade To {%version%}": "Päivitä versioon {{version}}", "Upgrade To {%version%}": "Päivitä versioon {{version}}",
"Upgrading": "Päivitetään", "Upgrading": "Päivitetään",
+3 -14
View File
@@ -1,9 +1,7 @@
{ {
"A negative number of days doesn't make sense.": "Un nombre négatif de jours n'a pas de sens.",
"A new major version may not be compatible with previous versions.": "Une nouvelle version majeure peut présenter des incompatibilités avec les versions antérieures.", "A new major version may not be compatible with previous versions.": "Une nouvelle version majeure peut présenter des incompatibilités avec les versions antérieures.",
"API Key": "Clé API", "API Key": "Clé API",
"About": "À propos", "About": "À propos",
"Actions": "Actions",
"Add": "Ajouter", "Add": "Ajouter",
"Add Device": "Ajouter un périphérique", "Add Device": "Ajouter un périphérique",
"Add Folder": "Ajouter un répertoire", "Add Folder": "Ajouter un répertoire",
@@ -19,8 +17,7 @@
"Automatic upgrades": "Mises à jour automatiques", "Automatic upgrades": "Mises à jour automatiques",
"Bugs": "Bugs", "Bugs": "Bugs",
"CPU Utilization": "Utilisation du CPU", "CPU Utilization": "Utilisation du CPU",
"Changelog": "Historique des changements", "Changelog": "Nouveautés",
"Clean out after": "Nettoyer après",
"Close": "Fermer", "Close": "Fermer",
"Command": "Commande", "Command": "Commande",
"Comment, when used at the start of a line": "Commentaire, lorsque utilisé en début de ligne", "Comment, when used at the start of a line": "Commentaire, lorsque utilisé en début de ligne",
@@ -30,7 +27,6 @@
"Copied from original": "Copié de l'original", "Copied from original": "Copié de l'original",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 Les contributeurs suivants:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 Les contributeurs suivants:",
"Delete": "Supprimer", "Delete": "Supprimer",
"Deleted": "Supprimé",
"Device ID": "ID du périphérique", "Device ID": "ID du périphérique",
"Device Identification": "Identification de l'appareil", "Device Identification": "Identification de l'appareil",
"Device Name": "Nom du périphérique", "Device Name": "Nom du périphérique",
@@ -53,7 +49,6 @@
"File Pull Order": "Ordre d'envoi de fichier", "File Pull Order": "Ordre d'envoi de fichier",
"File Versioning": "Versions de fichier", "File Versioning": "Versions de fichier",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Les bits de permission de fichier sont ignorés lors de la recherche de changements. Utilisé sur les systèmes de fichiers FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Les bits de permission de fichier sont ignorés lors de la recherche de changements. Utilisé sur les systèmes de fichiers FAT.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Les fichiers sont déplacés vers le dossier .stversions quand ils sont remplacés ou effacés par Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Les fichiers sont déplacés, avec horodatage, dans un dossier .stversions quand ils sont remplacés ou supprimés par Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Les fichiers sont déplacés, avec horodatage, dans un dossier .stversions quand ils sont remplacés ou supprimés par 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.": "Les fichiers sont protégés des changements réalisés sur les autres appareils, mais les changements réalisés sur cet appareil seront transférés au reste du groupe.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Les fichiers sont protégés des changements réalisés sur les autres appareils, mais les changements réalisés sur cet appareil seront transférés au reste du groupe.",
"Folder ID": "ID du répertoire", "Folder ID": "ID du répertoire",
@@ -67,7 +62,6 @@
"Global Discovery": "Recherche globale", "Global Discovery": "Recherche globale",
"Global Discovery Server": "Serveur global de recherche", "Global Discovery Server": "Serveur global de recherche",
"Global State": "État global", "Global State": "État global",
"Help": "Aide",
"Ignore": "Ignorer", "Ignore": "Ignorer",
"Ignore Patterns": "Modèles à éviter", "Ignore Patterns": "Modèles à éviter",
"Ignore Permissions": "Ignorer les permissions", "Ignore Permissions": "Ignorer les permissions",
@@ -81,7 +75,6 @@
"Later": "Plus tard", "Later": "Plus tard",
"Local Discovery": "Recherche locale", "Local Discovery": "Recherche locale",
"Local State": "État local", "Local State": "État local",
"Local State (Total)": "Etat local (Total)",
"Major Upgrade": "Mise à jour majeure", "Major Upgrade": "Mise à jour majeure",
"Maximum Age": "Ancienneté maximum", "Maximum Age": "Ancienneté maximum",
"Metadata Only": "Métadonnées uniquement", "Metadata Only": "Métadonnées uniquement",
@@ -165,24 +158,20 @@
"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.": "Les intervalles suivant sont utilisés: la première heure une version est conservée chaque 30 secondes, le premier jour une version est conservée chaque heure, les premiers 30 jours une version est conservée chaque jour, jusqu'à la limite d'âge maximum une version est conservée chaque semaine.", "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.": "Les intervalles suivant sont utilisés: la première heure une version est conservée chaque 30 secondes, le premier jour une version est conservée chaque heure, les premiers 30 jours une version est conservée chaque jour, jusqu'à la limite d'âge maximum une version est conservée chaque semaine.",
"The maximum age must be a number and cannot be blank.": "L'ancienneté maximum doit être un nombre et ne peut être vide.", "The maximum age must be a number and cannot be blank.": "L'ancienneté maximum doit être un nombre et ne peut être vide.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Le temps maximum de conservation d'une version (en jours, mettre à 0 pour conserver les versions pour toujours)", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Le temps maximum de conservation d'une version (en jours, mettre à 0 pour conserver les versions pour toujours)",
"The number of days must be a number and cannot be blank.": "Le nombre de jours doit être numérique et ne peut pas être vide.",
"The number of days to keep files in the trash can. Zero means forever.": "Le nombre de jours de conservation des fichiers dans la poubelle. Zéro signifie toujours.",
"The number of old versions to keep, per file.": "Le nombre d'anciennes versions à garder, par fichier.", "The number of old versions to keep, per file.": "Le nombre d'anciennes versions à garder, par fichier.",
"The number of versions must be a number and cannot be blank.": "Le nombre de versions doit être numérique, et ne peut pas être vide.", "The number of versions must be a number and cannot be blank.": "Le nombre de versions doit être numérique, et ne peut pas être vide.",
"The path cannot be blank.": "Le chemin ne peut pas être vide.", "The path cannot be blank.": "Le chemin ne peut pas être vide.",
"The rescan interval must be a non-negative number of seconds.": "L'intervalle d'analyse ne doit pas être un nombre négatif de secondes.", "The rescan interval must be a non-negative number of seconds.": "L'intervalle d'analyse ne doit pas être un nombre négatif de secondes.",
"This is a major version upgrade.": "Ceci est une mise à jour majeure", "This is a major version upgrade.": "Ceci est une mise à jour majeure",
"Trash Can File Versioning": "Gestion des versions de fichier de la poubelle.",
"Unknown": "Inconnu", "Unknown": "Inconnu",
"Unshared": "Non partagé", "Unshared": "Non partagé",
"Unused": "Non utilisé", "Unused": "Non utilisé",
"Up to Date": "Synchronisé", "Up to Date": "Synchronisation à jour",
"Updated": "Mis à jour",
"Upgrade": "Mise à jour", "Upgrade": "Mise à jour",
"Upgrade To {%version%}": "Mettre à jour vers {{version}}", "Upgrade To {%version%}": "Mettre à jour vers {{version}}",
"Upgrading": "Mise à jour de Syncthing", "Upgrading": "Mise à jour de Syncthing",
"Upload Rate": "Débit d'envoi", "Upload Rate": "Débit d'envoi",
"Uptime": "Durée de fonctionnement", "Uptime": "Uptime",
"Use HTTPS for GUI": "Utiliser l'HTTPS pour le GUI", "Use HTTPS for GUI": "Utiliser l'HTTPS pour le GUI",
"Version": "Version", "Version": "Version",
"Versions Path": "Emplacement des versions", "Versions Path": "Emplacement des versions",
+1 -12
View File
@@ -1,9 +1,7 @@
{ {
"A negative number of days doesn't make sense.": "Negatív számú nap nincs értelmezve.",
"A new major version may not be compatible with previous versions.": "Az új főverzió nem kompatibilis az előző főverzióval.", "A new major version may not be compatible with previous versions.": "Az új főverzió nem kompatibilis az előző főverzióval.",
"API Key": "API kulcs", "API Key": "API kulcs",
"About": "Névjegy", "About": "Névjegy",
"Actions": "Tevékenységek",
"Add": "Hozzáadás", "Add": "Hozzáadás",
"Add Device": "Eszköz hozzáadása", "Add Device": "Eszköz hozzáadása",
"Add Folder": "Mappa hozzáadása", "Add Folder": "Mappa hozzáadása",
@@ -20,7 +18,6 @@
"Bugs": "Hibák", "Bugs": "Hibák",
"CPU Utilization": "Processzor használat", "CPU Utilization": "Processzor használat",
"Changelog": "Változások", "Changelog": "Változások",
"Clean out after": "Clean out after",
"Close": "Bezárás", "Close": "Bezárás",
"Command": "Parancs", "Command": "Parancs",
"Comment, when used at the start of a line": "Megjegyzés, a sor elején használva", "Comment, when used at the start of a line": "Megjegyzés, a sor elején használva",
@@ -30,7 +27,6 @@
"Copied from original": "Másolva az eredetiről", "Copied from original": "Másolva az eredetiről",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 az alábbi Közreműködők", "Copyright © 2015 the following Contributors:": "Copyright © 2015 az alábbi Közreműködők",
"Delete": "Törlés", "Delete": "Törlés",
"Deleted": "Törölve",
"Device ID": "Eszköz azonosító", "Device ID": "Eszköz azonosító",
"Device Identification": "Eszköz azonosító", "Device Identification": "Eszköz azonosító",
"Device Name": "Eszköz neve", "Device Name": "Eszköz neve",
@@ -53,8 +49,7 @@
"File Pull Order": "Fájl küldési sorrend", "File Pull Order": "Fájl küldési sorrend",
"File Versioning": "Fájl verziózás", "File Versioning": "Fájl verziózás",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Fájl jogosultságok figyelmen kívül hagyása változások keresésekor. FAT fájlrendszereken használatakor.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Fájl jogosultságok figyelmen kívül hagyása változások keresésekor. FAT fájlrendszereken használatakor.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Ha a Syncthing áthelyezi vagy törli a fájlokat, akkor azok a .stversions mappába lesznek áthelyezve.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Ha a Syncthing áthelyezi vagy törli a fájlokat, akkor azok a .stversions mappába lesznek áthelyezve, időbélyegzővel ellátva.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "A fájlok védve vannak a más eszközökön történt változásokkal szemben, de az ezen az eszközön történt változások érvényesek lesznek a többire.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "A fájlok védve vannak a más eszközökön történt változásokkal szemben, de az ezen az eszközön történt változások érvényesek lesznek a többire.",
"Folder ID": "Mappa azonosító", "Folder ID": "Mappa azonosító",
"Folder Master": "Központi mappa", "Folder Master": "Központi mappa",
@@ -67,7 +62,6 @@
"Global Discovery": "Globális felfedezés", "Global Discovery": "Globális felfedezés",
"Global Discovery Server": "Globális felfedező szerver", "Global Discovery Server": "Globális felfedező szerver",
"Global State": "Globális állapot", "Global State": "Globális állapot",
"Help": "Segítség",
"Ignore": "Visszautasítás", "Ignore": "Visszautasítás",
"Ignore Patterns": "Figyelmen kívül hagyás", "Ignore Patterns": "Figyelmen kívül hagyás",
"Ignore Permissions": "Jogosultságok figyelmen kívül hagyása", "Ignore Permissions": "Jogosultságok figyelmen kívül hagyása",
@@ -81,7 +75,6 @@
"Later": "Később", "Later": "Később",
"Local Discovery": "Helyi felfedezés", "Local Discovery": "Helyi felfedezés",
"Local State": "Helyi állapot", "Local State": "Helyi állapot",
"Local State (Total)": "Helyi állapot (Teljes)",
"Major Upgrade": "Főverzió frissítés", "Major Upgrade": "Főverzió frissítés",
"Maximum Age": "Maximális kor", "Maximum Age": "Maximális kor",
"Metadata Only": "Csak metaadatok", "Metadata Only": "Csak metaadatok",
@@ -165,19 +158,15 @@
"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.": "A következő intervallumokat használjuk: egy régi verziót őrzünk meg az első órában minden 30 másodpercben, az első nap minden órában, az első 30 napban minden nap, egészen addig amíg el nem érjük a maximálisan megtartható verziók számát minden héten.", "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.": "A következő intervallumokat használjuk: egy régi verziót őrzünk meg az első órában minden 30 másodpercben, az első nap minden órában, az első 30 napban minden nap, egészen addig amíg el nem érjük a maximálisan megtartható verziók számát minden héten.",
"The maximum age must be a number and cannot be blank.": "A maximális kornak számnak kell lenni és nem lehet üres", "The maximum age must be a number and cannot be blank.": "A maximális kornak számnak kell lenni és nem lehet üres",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "A verziók megtartásának maximális ideje (napokban, ha 0-t adsz meg örökre megmaradnak).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "A verziók megtartásának maximális ideje (napokban, ha 0-t adsz meg örökre megmaradnak).",
"The number of days must be a number and cannot be blank.": "A napok száma szám kell legyen és nem lehet üres.",
"The number of days to keep files in the trash can. Zero means forever.": "A napok száma ameddig a fájlok meg lesznek tartva a lomtárban. A 0 azt jelenti örökre.",
"The number of old versions to keep, per file.": "A megtartott régi verziók száma, fájlonként.", "The number of old versions to keep, per file.": "A megtartott régi verziók száma, fájlonként.",
"The number of versions must be a number and cannot be blank.": "A megtartott verziók száma nem lehet üres", "The number of versions must be a number and cannot be blank.": "A megtartott verziók száma nem lehet üres",
"The path cannot be blank.": "Elérési út nem lehet üres.", "The path cannot be blank.": "Elérési út nem lehet üres.",
"The rescan interval must be a non-negative number of seconds.": "Az átnézési intervallum nullánál nagyobb másodperc érték kell legyen", "The rescan interval must be a non-negative number of seconds.": "Az átnézési intervallum nullánál nagyobb másodperc érték kell legyen",
"This is a major version upgrade.": "Ez egy főverzió frissítés.", "This is a major version upgrade.": "Ez egy főverzió frissítés.",
"Trash Can File Versioning": "Lomtár fájl verziózás",
"Unknown": "Ismeretlen", "Unknown": "Ismeretlen",
"Unshared": "Nincs megosztva", "Unshared": "Nincs megosztva",
"Unused": "Nincs használatban", "Unused": "Nincs használatban",
"Up to Date": "Friss", "Up to Date": "Friss",
"Updated": "Frissítve",
"Upgrade": "Frissítés", "Upgrade": "Frissítés",
"Upgrade To {%version%}": "Frissítés a {{version}} verzióra", "Upgrade To {%version%}": "Frissítés a {{version}} verzióra",
"Upgrading": "Frissítés", "Upgrading": "Frissítés",
+2 -13
View File
@@ -1,9 +1,7 @@
{ {
"A negative number of days doesn't make sense.": "Un numero di giorni negativo non ha alcun senso.",
"A new major version may not be compatible with previous versions.": "Una nuova versione principale potrebbe non essere compatibile con le versioni precedenti.", "A new major version may not be compatible with previous versions.": "Una nuova versione principale potrebbe non essere compatibile con le versioni precedenti.",
"API Key": "Chiave API", "API Key": "Chiave API",
"About": "Informazioni", "About": "Informazioni",
"Actions": "Azioni",
"Add": "Aggiungi", "Add": "Aggiungi",
"Add Device": "Aggiungi Dispositivo", "Add Device": "Aggiungi Dispositivo",
"Add Folder": "Aggiungi Cartella", "Add Folder": "Aggiungi Cartella",
@@ -20,7 +18,6 @@
"Bugs": "Bug", "Bugs": "Bug",
"CPU Utilization": "Utilizzo CPU", "CPU Utilization": "Utilizzo CPU",
"Changelog": "Changelog", "Changelog": "Changelog",
"Clean out after": "Svuota dopo",
"Close": "Chiudi", "Close": "Chiudi",
"Command": "Comando", "Command": "Comando",
"Comment, when used at the start of a line": "Per commentare, va inserito all'inizio di una riga", "Comment, when used at the start of a line": "Per commentare, va inserito all'inizio di una riga",
@@ -30,7 +27,6 @@
"Copied from original": "Copiato dall'originale", "Copied from original": "Copiato dall'originale",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 i seguenti Collaboratori:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 i seguenti Collaboratori:",
"Delete": "Elimina", "Delete": "Elimina",
"Deleted": "Cancellato",
"Device ID": "ID Dispositivo", "Device ID": "ID Dispositivo",
"Device Identification": "Identificazione Dispositivo", "Device Identification": "Identificazione Dispositivo",
"Device Name": "Nome Dispositivo", "Device Name": "Nome Dispositivo",
@@ -53,7 +49,6 @@
"File Pull Order": "Ordine di prelievo dei file", "File Pull Order": "Ordine di prelievo dei file",
"File Versioning": "Controllo Versione dei File", "File Versioning": "Controllo Versione dei File",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Il software evita i bit dei permessi dei file durante il controllo delle modifiche. Utilizzato nei filesystem FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Il software evita i bit dei permessi dei file durante il controllo delle modifiche. Utilizzato nei filesystem FAT.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "I file sono spostati nella certella .stversions quando vengono sostituiti o cancellati da Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "I file sostituiti o eliminati da Syncthing vengono datati e spostati in una cartella .stversions.", "Files are moved to date stamped versions in a .stversions folder 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 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.",
"Folder ID": "ID Cartella", "Folder ID": "ID Cartella",
@@ -67,7 +62,6 @@
"Global Discovery": "Individuazione Globale", "Global Discovery": "Individuazione Globale",
"Global Discovery Server": "Server di Ricerca Globale", "Global Discovery Server": "Server di Ricerca Globale",
"Global State": "Stato Globale", "Global State": "Stato Globale",
"Help": "Aiuto",
"Ignore": "Ignora", "Ignore": "Ignora",
"Ignore Patterns": "Schemi Esclusione File", "Ignore Patterns": "Schemi Esclusione File",
"Ignore Permissions": "Ignora Permessi", "Ignore Permissions": "Ignora Permessi",
@@ -81,7 +75,6 @@
"Later": "Più Tardi", "Later": "Più Tardi",
"Local Discovery": "Individuazione Locale", "Local Discovery": "Individuazione Locale",
"Local State": "Stato Locale", "Local State": "Stato Locale",
"Local State (Total)": "Stato Locale (Totale)",
"Major Upgrade": "Aggiornamento principale", "Major Upgrade": "Aggiornamento principale",
"Maximum Age": "Durata Massima", "Maximum Age": "Durata Massima",
"Metadata Only": "Solo i Metadati", "Metadata Only": "Solo i Metadati",
@@ -95,7 +88,7 @@
"No File Versioning": "Nessun Controllo Versione", "No File Versioning": "Nessun Controllo Versione",
"Notice": "Avviso", "Notice": "Avviso",
"OK": "OK", "OK": "OK",
"Off": "Disattiva", "Off": "Off",
"Oldest First": "Prima il meno recente", "Oldest First": "Prima il meno recente",
"Out Of Sync": "Non Sincronizzati", "Out Of Sync": "Non Sincronizzati",
"Out of Sync Items": "Elementi Non Sincronizzati", "Out of Sync Items": "Elementi Non Sincronizzati",
@@ -103,7 +96,7 @@
"Override Changes": "Ignora Modifiche", "Override Changes": "Ignora Modifiche",
"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": "Percorso della cartella nel computer locale. Verrà creata se non esiste già. Il carattere tilde (~) può essere utilizzato come scorciatoia per", "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": "Percorso della cartella nel computer locale. Verrà creata se non esiste già. Il carattere tilde (~) può essere utilizzato come scorciatoia per",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Percorso di salvataggio delle versioni (lasciare vuoto per utilizzare la cartella predefinita .stversions in questa cartella).", "Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Percorso di salvataggio delle versioni (lasciare vuoto per utilizzare la cartella predefinita .stversions in questa cartella).",
"Please consult the release notes before performing a major upgrade.": "Si prega di consultare le note di rilascio prima di eseguire un aggiornamento principale.", "Please consult the release notes before performing a major upgrade.": "Si prega di consultare le note di rilascio prima di eseguire un aggiornamento principale",
"Please wait": "Attendere prego", "Please wait": "Attendere prego",
"Preview": "Anteprima", "Preview": "Anteprima",
"Preview Usage Report": "Anteprima Statistiche di Utilizzo", "Preview Usage Report": "Anteprima Statistiche di Utilizzo",
@@ -165,19 +158,15 @@
"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.": "Vengono utilizzati i seguenti intervalli temporali: per la prima ora viene mantenuta una versione ogni 30 secondi, per il primo giorno viene mantenuta una versione ogni ora, per i primi 30 giorni viene mantenuta una versione al giorno, successivamente viene mantenuta una versione ogni settimana fino al periodo massimo impostato.", "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.": "Vengono utilizzati i seguenti intervalli temporali: per la prima ora viene mantenuta una versione ogni 30 secondi, per il primo giorno viene mantenuta una versione ogni ora, per i primi 30 giorni viene mantenuta una versione al giorno, successivamente viene mantenuta una versione ogni settimana fino al periodo massimo impostato.",
"The maximum age must be a number and cannot be blank.": "La durata massima dev'essere un numero e non può essere vuoto.", "The maximum age must be a number and cannot be blank.": "La durata massima dev'essere un numero e non può essere vuoto.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "La durata massima di una versione (in giorni, imposta a 0 per mantenere le versioni per sempre).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "La durata massima di una versione (in giorni, imposta a 0 per mantenere le versioni per sempre).",
"The number of days must be a number and cannot be blank.": "Il numero di giorni deve essere un numero e non può essere vuoto.",
"The number of days to keep files in the trash can. Zero means forever.": "Il numero di giorni per conservare i file nel cestino. Zero significa per sempre.",
"The number of old versions to keep, per file.": "Il numero di vecchie versioni da mantenere, per file.", "The number of old versions to keep, per file.": "Il numero di vecchie versioni da mantenere, per file.",
"The number of versions must be a number and cannot be blank.": "Il numero di versioni dev'essere un numero e non può essere vuoto.", "The number of versions must be a number and cannot be blank.": "Il numero di versioni dev'essere un numero e non può essere vuoto.",
"The path cannot be blank.": "Il percorso non può essere vuoto.", "The path cannot be blank.": "Il percorso non può essere vuoto.",
"The rescan interval must be a non-negative number of seconds.": "L'intervallo di scansione deve essere un numero superiore a zero secondi.", "The rescan interval must be a non-negative number of seconds.": "L'intervallo di scansione deve essere un numero superiore a zero secondi.",
"This is a major version upgrade.": "Questo è un aggiornamento di versione principale", "This is a major version upgrade.": "Questo è un aggiornamento di versione principale",
"Trash Can File Versioning": "Controllo Versione con Cestino",
"Unknown": "Sconosciuto", "Unknown": "Sconosciuto",
"Unshared": "Non Condiviso", "Unshared": "Non Condiviso",
"Unused": "Non Utilizzato", "Unused": "Non Utilizzato",
"Up to Date": "Sincronizzato", "Up to Date": "Sincronizzato",
"Updated": "Aggiornato",
"Upgrade": "Aggiornamento", "Upgrade": "Aggiornamento",
"Upgrade To {%version%}": "Aggiorna alla {{version}}", "Upgrade To {%version%}": "Aggiorna alla {{version}}",
"Upgrading": "Aggiornamento", "Upgrading": "Aggiornamento",
-197
View File
@@ -1,197 +0,0 @@
{
"A negative number of days doesn't make sense.": "負の日数は無理です。",
"A new major version may not be compatible with previous versions.": "新しいメジャーバージョンは以前のバージョンと互換性がないかもしれません",
"API Key": "APIキー",
"About": "Syncthingについて",
"Actions": "メニュー",
"Add": "追加",
"Add Device": "デバイスの追加",
"Add Folder": "フォルダの追加",
"Add new folder?": "フォルダを新規作成しますか?",
"Address": "アドレス",
"Addresses": "アドレス",
"All Data": "全てのデータ",
"Allow Anonymous Usage Reporting?": "匿名での利用者状況のレポートを許可しますか?",
"Alphabetic": "ABC順",
"An external command handles the versioning. It has to remove the file from the synced folder.": "バージョニングを行う外部コマンド。同期フォルダからファイルを削除する必要があります。",
"Anonymous Usage Reporting": "匿名での利用者状況レポート",
"Any devices configured on an introducer device will be added to this device as well.": "紹介デバイスで設定されたデバイスはここにも追加されます。",
"Automatic upgrades": "自動アップデート",
"Bugs": "バグ",
"CPU Utilization": "CPU使用率",
"Changelog": "更新履歴",
"Clean out after": "後で掃除",
"Close": "閉じる",
"Command": "コマンド",
"Comment, when used at the start of a line": "行頭で使用されるコメント",
"Compression": "圧縮",
"Connection Error": "接続エラー",
"Copied from elsewhere": "他の所からコピーしました",
"Copied from original": "オリジナルからコピーしました",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 以下の協力者たちの皆さん:",
"Delete": "削除",
"Deleted": "削除した",
"Device ID": "デバイスID",
"Device Identification": "デバイスの身分証明書",
"Device Name": "デバイスの名前",
"Device {%device%} ({%address%}) wants to connect. Add new device?": "デバイス{{device}} ({{address}})が接続しますか? ",
"Devices": "デバイス",
"Disconnected": "切断されました",
"Documentation": "マニュアル",
"Download Rate": "ダウンロード率",
"Downloaded": "ダウンロード済",
"Downloading": "ダウンロード中",
"Edit": "編集",
"Edit Device": "デバイスの変更",
"Edit Folder": "フォルダーの変更",
"Editing": "編集中",
"Enable UPnP": "UPnPを許可する",
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "自動接続の場合は「dynamic」またはカンマ区切り「IPアドレス:ポート」を入力をしてください",
"Enter ignore patterns, one per line.": "無視パターンを入力してください。一列一条件。",
"Error": "エラー",
"External File Versioning": "外部ファイルバージョニング",
"File Pull Order": "ファイルの引き順番",
"File Versioning": "ファイルバージョニング",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "更新時、ファイルパーミッションの設定が無視されます。FATファイルシステムでご利用ください。",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Syncthingによって移動や削除が行われるとファイルは.stversionsフォルダに移されます。",
"Files are moved to date stamped versions in a .stversions folder 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.": "ファイルは他デバイスによる変更から保護されます。しかしこのデバイス上での変更は他のクラスタに送信されます。",
"Folder ID": "フォルダID",
"Folder Master": "フォルダのマスター",
"Folder Path": "フォルダパス",
"Folders": "フォルダ",
"GUI Authentication Password": "GUI 認証パスワード",
"GUI Authentication User": "GUI 認証ユーザー",
"GUI Listen Addresses": "GUIリスンアドレス",
"Generate": "生成",
"Global Discovery": "グローバルディスカバリー",
"Global Discovery Server": "グローバルディスカバリーサーバー",
"Global State": "グローバル状態",
"Help": "ヘルプ",
"Ignore": "無視",
"Ignore Patterns": "パターンを無視する",
"Ignore Permissions": "アクセス許可を無視する",
"Incoming Rate Limit (KiB/s)": "着信率制限(KiB/s)",
"Introducer": "紹介デバイス",
"Inversion of the given condition (i.e. do not exclude)": "条件の裏(と言うのは省かないで)",
"Keep Versions": "バージョン保持",
"Largest First": "大きい順",
"Last File Received": "最後に受けとったファイル",
"Last seen": "最後に見た",
"Later": "後",
"Local Discovery": "ローカルディスカバリー",
"Local State": "ローカル状態",
"Local State (Total)": "ローカル状態(総和)",
"Major Upgrade": "メジャーアップグレード",
"Maximum Age": "再",
"Metadata Only": "メータデータだけ",
"Move to top of queue": "最優先にする",
"Multi level wildcard (matches multiple directory levels)": "広範なワイルドカード(複数のディレクトリに適用されます)",
"Never": "決して",
"New Device": "新規デバイス",
"New Folder": "新規フォルダ",
"Newest First": "新しい順",
"No": "いいえ",
"No File Versioning": "ファイルバージョニング不利用",
"Notice": "通知",
"OK": "OK",
"Off": "オフ",
"Oldest First": "古い順",
"Out Of Sync": "シンク外",
"Out of Sync Items": "シンクアイテム外",
"Outgoing Rate Limit (KiB/s)": "発信率制限(KiB/s)",
"Override Changes": "変更をオーバーライドする",
"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 folder in the folder).": "バージョンが保持されるパス(空欄の場合、デフォルトで.stversionsになります)",
"Please consult the release notes before performing a major upgrade.": "メジャーアップグレードをする前にリリースノートを参考してください。",
"Please wait": "お待ちください",
"Preview": "プレビュー",
"Preview Usage Report": "利用状況レポートのプレビュー",
"Quick guide to supported patterns": "サポートされているパターンの簡易ガイド",
"RAM Utilization": "メモリ利用率",
"Random": "ランダム",
"Release Notes": "リリースノート",
"Rescan": "再スキャン",
"Rescan All": "すべて再スキャン",
"Rescan Interval": "再スキャンの間隔",
"Restart": "再起動",
"Restart Needed": "再起動が必要です",
"Restarting": "再起動中",
"Reused": "再使用されている",
"Save": "保存",
"Scanning": "スキャン中",
"Select the devices to share this folder with.": "このフォルダをシェアするデバイスを選んでください。",
"Select the folders to share with this device.": "このデバイスでシェアしたいフォルダを選んでください",
"Settings": "設定",
"Share": "共有",
"Share Folder": "フォルダを共有する",
"Share Folders With Device": "デバイスでフォルダをシェアする",
"Share With Devices": "デバイスでシェアする",
"Share this folder?": "このフォルダを共有しますか?",
"Shared With": "シェアされている",
"Short identifier for the folder. Must be the same on all cluster devices.": "このフォルダの短いID。全てのデバイス上で同じである必要があります。",
"Show ID": "IDを表示",
"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 File Versioning": "簡易ファイルバージョニング",
"Single level wildcard (matches within a directory only)": "ワイルドカード(一つのディレクトリだけに適用されます)",
"Smallest First": "小さい順",
"Source Code": "ソースコード",
"Staggered File Versioning": "簡易ファイルバージョニング",
"Start Browser": "ブラウザーを起動する",
"Stopped": "止り",
"Support": "サポート",
"Sync Protocol Listen Addresses": "同期プロトコル待ち受けるアドレス",
"Syncing": "同期中",
"Syncthing has been shut down.": "Syncthingがシャットダウンしました。",
"Syncthing includes the following software or portions thereof:": "Syncthingは以下のソフトウェアかその一部を内包しています:",
"Syncthing is restarting.": "Syncthingが再起動しています",
"Syncthing is upgrading.": "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を再起動してください。",
"The aggregated statistics are publicly available at {%url%}.": "全体の統計は{{url}}でご覧いただけます。",
"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 \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "ここで入力したデバイスIDは他デバイス上の\"編集 > IDを表示\"で見ることができます。スペースとハイフンは無視されます。",
"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.": "暗号化された使用状況レポートが\b日ごとに送られます。これはプラットフォーム、フォルダの大きさ、アプリのバージョンを追跡するために利用されます。レポートのデータが変更された場合、このダイアログがまた表示されます。",
"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 first command line parameter is the folder path and the second parameter is the relative path in the folder.": "第一コマンドパラメータはフォルダパス、第二パラメータはフォルダ内の相対パスです。",
"The folder ID cannot be blank.": "フォルダIDは空欄にできません",
"The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "フォルダID(64文字以内)は数字、ドット(.)、ハイフン(-)、アンダースコア(_)で構成されている必要があります。",
"The folder ID must be unique.": "フォルダIDは固有である必要があります。",
"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 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 days must be a number and cannot be blank.": "日数は番号である必要があり、空欄ではいけません。",
"The number of days to keep files in the trash can. Zero means forever.": "ゴミ箱にファイルを保持する日数。0だと永続的に保持します。",
"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 rescan interval must be a non-negative number of seconds.": "リスキャン間隔はマイナス秒ではいけません。",
"This is a major version upgrade.": "メージャーアップグレードです。",
"Trash Can File Versioning": "ゴミ箱のファイルバージョニング",
"Unknown": "不明",
"Unshared": "シェアされていない",
"Unused": "使われていない",
"Up to Date": "最新",
"Updated": "更新済み",
"Upgrade": "アップグレード",
"Upgrade To {%version%}": "{{version}}にアップグレードする",
"Upgrading": "アップグレード中",
"Upload Rate": "アップロード率",
"Uptime": "稼働時間",
"Use HTTPS for GUI": "GUIにHTTPSを使う",
"Version": "バージョン",
"Versions Path": "バージョンパス",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "バージョンは、最大寿命もしくは最大同時数を超えた場合、自動的に削除されます。",
"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はケースセンシティブで全てのデバイス上で完全に同じである必要があります。",
"Yes": "はい",
"You must keep at least one version.": "バージョン一つ少なくとも保持してください",
"full documentation": "完全マニュアル",
"items": "アイテム",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}}がフォルダ\"{{folder}}\"をシェアしがたっています。"
}
-11
View File
@@ -1,9 +1,7 @@
{ {
"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.": "새로운 메이저 버전은 이전 버전과 호환되지 않을 수 있습니다.", "A new major version may not be compatible with previous versions.": "새로운 메이저 버전은 이전 버전과 호환되지 않을 수 있습니다.",
"API Key": "API 키", "API Key": "API 키",
"About": " 정보", "About": " 정보",
"Actions": "동작",
"Add": "추가", "Add": "추가",
"Add Device": "기기 추가", "Add Device": "기기 추가",
"Add Folder": "폴더 추가", "Add Folder": "폴더 추가",
@@ -20,7 +18,6 @@
"Bugs": "버그", "Bugs": "버그",
"CPU Utilization": "CPU 사용률", "CPU Utilization": "CPU 사용률",
"Changelog": "바뀐 점", "Changelog": "바뀐 점",
"Clean out after": "Clean out after",
"Close": "닫기", "Close": "닫기",
"Command": "커맨드", "Command": "커맨드",
"Comment, when used at the start of a line": "명령행에서 시작을 할수 있어요.", "Comment, when used at the start of a line": "명령행에서 시작을 할수 있어요.",
@@ -30,7 +27,6 @@
"Copied from original": "원본에서 복사됨", "Copied from original": "원본에서 복사됨",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
"Delete": "삭제", "Delete": "삭제",
"Deleted": "Deleted",
"Device ID": "기기 ID", "Device ID": "기기 ID",
"Device Identification": "기기 식별자", "Device Identification": "기기 식별자",
"Device Name": "기기 이름", "Device Name": "기기 이름",
@@ -53,7 +49,6 @@
"File Pull Order": "파일 동기화 순서", "File Pull Order": "파일 동기화 순서",
"File Versioning": "파일 버전 관리", "File Versioning": "파일 버전 관리",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "파일을 동기화할 때 파일 권한이 무시됩니다. FAT 파일 시스템에서 사용하세요.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "파일을 동기화할 때 파일 권한이 무시됩니다. FAT 파일 시스템에서 사용하세요.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "파일이 Syncthing에 의해서 교체되거나 삭제되면 .stversions 폴더에 있는 날짜가 바뀐 버전으로 이동됩니다.", "Files are moved to date stamped versions in a .stversions folder 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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "다른 장치가 파일을 편집할 수 없으며 반드시 이 장치의 내용을 기준으로 동기화합니다.",
"Folder ID": "폴더 ID", "Folder ID": "폴더 ID",
@@ -67,7 +62,6 @@
"Global Discovery": "글로벌 탐색", "Global Discovery": "글로벌 탐색",
"Global Discovery Server": "글로벌 탐색 서버", "Global Discovery Server": "글로벌 탐색 서버",
"Global State": "글로벌 서버 상태", "Global State": "글로벌 서버 상태",
"Help": "도움말",
"Ignore": "무시", "Ignore": "무시",
"Ignore Patterns": "패턴 무시", "Ignore Patterns": "패턴 무시",
"Ignore Permissions": "권한 무시", "Ignore Permissions": "권한 무시",
@@ -81,7 +75,6 @@
"Later": "나중에", "Later": "나중에",
"Local Discovery": "로컬 노드 검색", "Local Discovery": "로컬 노드 검색",
"Local State": "로컬 상태", "Local State": "로컬 상태",
"Local State (Total)": "Local State (Total)",
"Major Upgrade": "메이저 업데이트", "Major Upgrade": "메이저 업데이트",
"Maximum Age": "최대 보존 기간", "Maximum Age": "최대 보존 기간",
"Metadata Only": "메타데이터만", "Metadata Only": "메타데이터만",
@@ -165,19 +158,15 @@
"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초마다 유지되며, 첫 하루 동안은 매 시간, 첫 한 달 동안은 매 일마다 유지됩니다. 그리고 최대 날짜까지는 버전이 매 주마다 유지됩니다.", "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초마다 유지되며, 첫 하루 동안은 매 시간, 첫 한 달 동안은 매 일마다 유지됩니다. 그리고 최대 날짜까지는 버전이 매 주마다 유지됩니다.",
"The maximum age must be a number and cannot be blank.": "최대 보존 기간은 숫자여야 하며 비워 둘 수 없습니다.", "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 maximum time to keep a version (in days, set to 0 to keep versions forever).": "버전을 유지할 최대 시간을 지정합니다. 일단위이며 버전을 계속 유지하려면 0을 입력하세요,",
"The number of days must be a number and cannot be blank.": "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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "각 파일별로 유지할 이전 버전의 개수를 지정합니다.", "The number of old versions to keep, per file.": "각 파일별로 유지할 이전 버전의 개수를 지정합니다.",
"The number of versions must be a number and cannot be blank.": "버전 개수는 숫자여야 하며 비워 둘 수 없습니다.", "The number of versions must be a number and cannot be blank.": "버전 개수는 숫자여야 하며 비워 둘 수 없습니다.",
"The path cannot be blank.": "경로는 비워 둘 수 없습니다.", "The path cannot be blank.": "경로는 비워 둘 수 없습니다.",
"The rescan interval must be a non-negative number of seconds.": "재검색 간격은 초단위이며 양수로 입력해야 합니다.", "The rescan interval must be a non-negative number of seconds.": "재검색 간격은 초단위이며 양수로 입력해야 합니다.",
"This is a major version upgrade.": "이 업데이트는 메이저 버전입니다.", "This is a major version upgrade.": "이 업데이트는 메이저 버전입니다.",
"Trash Can File Versioning": "Trash Can File Versioning",
"Unknown": "알 수 없음", "Unknown": "알 수 없음",
"Unshared": "공유되지 않음", "Unshared": "공유되지 않음",
"Unused": "사용되지 않음", "Unused": "사용되지 않음",
"Up to Date": "최신 데이터", "Up to Date": "최신 데이터",
"Updated": "Updated",
"Upgrade": "업데이트", "Upgrade": "업데이트",
"Upgrade To {%version%}": "{{version}} 으로 업데이트", "Upgrade To {%version%}": "{{version}} 으로 업데이트",
"Upgrading": "업데이트 중", "Upgrading": "업데이트 중",
+6 -17
View File
@@ -1,9 +1,7 @@
{ {
"A negative number of days doesn't make sense.": "Privalo būti teigiamas skaičius.",
"A new major version may not be compatible with previous versions.": "Nauja versija gali būti nesuderinama su senomis versijomis.", "A new major version may not be compatible with previous versions.": "Nauja versija gali būti nesuderinama su senomis versijomis.",
"API Key": "API raktas", "API Key": "API raktas",
"About": "Apie programą", "About": "Apie programą",
"Actions": "Veiksmai",
"Add": "Pridėti", "Add": "Pridėti",
"Add Device": "Pridėti įrenginį", "Add Device": "Pridėti įrenginį",
"Add Folder": "Pridėti aplanką", "Add Folder": "Pridėti aplanką",
@@ -13,14 +11,13 @@
"All Data": "Visiems duomenims", "All Data": "Visiems duomenims",
"Allow Anonymous Usage Reporting?": "Siųsti anonimišką vartojimo ataskaitą?", "Allow Anonymous Usage Reporting?": "Siųsti anonimišką vartojimo ataskaitą?",
"Alphabetic": "Abėcėlės tvarka", "Alphabetic": "Abėcėlės tvarka",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Išorinė komanda apdoroja versijų valdymą. Ji turi pašalinti failą iš sinchronizuoto aplanko.", "An external command handles the versioning. It has to remove the file from the synced folder.": "An external command handles the versioning. It has to remove the file from the synced folder.",
"Anonymous Usage Reporting": "Anoniminė vartojimo ataskaita", "Anonymous Usage Reporting": "Anoniminė vartojimo ataskaita",
"Any devices configured on an introducer device will be added to this device as well.": "Visi supažindintojo įrenginiai bus pridėti prie jūsų įrenginių sąrašo.", "Any devices configured on an introducer device will be added to this device as well.": "Visi supažindintojo įrenginiai bus pridėti prie jūsų įrenginių sąrašo.",
"Automatic upgrades": "Automatiniai atnaujinimai", "Automatic upgrades": "Automatiniai atnaujinimai",
"Bugs": "Klaidos", "Bugs": "Klaidos",
"CPU Utilization": "Procesoriaus panaudojimas", "CPU Utilization": "Procesoriaus panaudojimas",
"Changelog": "Pasikeitimai", "Changelog": "Pasikeitimai",
"Clean out after": "Išvalyto po",
"Close": "Uždaryti", "Close": "Uždaryti",
"Command": "Komanda", "Command": "Komanda",
"Comment, when used at the start of a line": "Komentaras naudojamas naujoje eilutėje", "Comment, when used at the start of a line": "Komentaras naudojamas naujoje eilutėje",
@@ -30,7 +27,6 @@
"Copied from original": "Nukopijuota iš originalo", "Copied from original": "Nukopijuota iš originalo",
"Copyright © 2015 the following Contributors:": "Visos teisės saugomos © 2015 šių bendraautorių:", "Copyright © 2015 the following Contributors:": "Visos teisės saugomos © 2015 šių bendraautorių:",
"Delete": "Trinti", "Delete": "Trinti",
"Deleted": "Ištrinta",
"Device ID": "Įrenginio ID", "Device ID": "Įrenginio ID",
"Device Identification": "Įrenginio identifikacija", "Device Identification": "Įrenginio identifikacija",
"Device Name": "Įrenginio pavadinimas", "Device Name": "Įrenginio pavadinimas",
@@ -49,12 +45,11 @@
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Įveskite dvitaškiu atskirtą \"ip:port\" adresą arba žodį \"dynamic\" norėdami gauti adresą automatiškai", "Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Įveskite dvitaškiu atskirtą \"ip:port\" adresą arba žodį \"dynamic\" norėdami gauti adresą automatiškai",
"Enter ignore patterns, one per line.": "Suveskite nepaisomus šablonus, kiekvieną naujoje eilutėje.", "Enter ignore patterns, one per line.": "Suveskite nepaisomus šablonus, kiekvieną naujoje eilutėje.",
"Error": "Klaida", "Error": "Klaida",
"External File Versioning": "Išorinis versijų valdymas", "External File Versioning": "External File Versioning",
"File Pull Order": "Failų siuntimo tvarka", "File Pull Order": "Failų siuntimo tvarka",
"File Versioning": "Versijų valdymas", "File Versioning": "Versijų valdymas",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Ieškant pakeitimų, į failų leidimų bitus yra nekreipiama dėmesio. Naudoti FAT failų sistemose.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Failai perkeliami į .stversions aplanką kai tampa pakeisti arba ištrinti.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Programai Syncthing pakeičiant ar ištrinant failus, jie yra perkeliami į datomis pažymėtas versijas, aplanke .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.": "Failai apsaugoti nuo pakeitimų atliktų kituose įrenginiuose, bet pakeitimai šiame įrenginyje bus nusiųsti kitiems.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Failai apsaugoti nuo pakeitimų atliktų kituose įrenginiuose, bet pakeitimai šiame įrenginyje bus nusiųsti kitiems.",
"Folder ID": "Aplanko ID", "Folder ID": "Aplanko ID",
"Folder Master": "Aplanko vadovas", "Folder Master": "Aplanko vadovas",
@@ -67,7 +62,6 @@
"Global Discovery": "Visuotinis matomumas", "Global Discovery": "Visuotinis matomumas",
"Global Discovery Server": "Visuotinio matomumo serveris", "Global Discovery Server": "Visuotinio matomumo serveris",
"Global State": "Visuotinė būsena", "Global State": "Visuotinė būsena",
"Help": "Pagalba",
"Ignore": "Ignoruoti", "Ignore": "Ignoruoti",
"Ignore Patterns": "Nepaisyti šablonų", "Ignore Patterns": "Nepaisyti šablonų",
"Ignore Permissions": "Nepaisyti failų prieigos leidimų", "Ignore Permissions": "Nepaisyti failų prieigos leidimų",
@@ -81,7 +75,6 @@
"Later": "Vėliau", "Later": "Vėliau",
"Local Discovery": "Vietinis matomumas", "Local Discovery": "Vietinis matomumas",
"Local State": "Vietinė būsena", "Local State": "Vietinė būsena",
"Local State (Total)": "Vietinė būsena (Bendrai)",
"Major Upgrade": "Stambus atnaujinimas", "Major Upgrade": "Stambus atnaujinimas",
"Maximum Age": "Maksimalus amžius", "Maximum Age": "Maksimalus amžius",
"Metadata Only": "Metaduomenims", "Metadata Only": "Metaduomenims",
@@ -150,14 +143,14 @@
"Syncthing is restarting.": "Syncthing perleidžiamas", "Syncthing is restarting.": "Syncthing perleidžiamas",
"Syncthing is upgrading.": "Syncthing atsinaujina.", "Syncthing is upgrading.": "Syncthing atsinaujina.",
"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 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 experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.",
"The aggregated statistics are publicly available at {%url%}.": "Naudojimosi ataskaitą galite peržiūrėti adresu: {{url}}.", "The aggregated statistics are publicly available at {%url%}.": "Naudojimosi ataskaitą galite peržiūrėti adresu: {{url}}.",
"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.": "Nauji nustatymai išsaugoti, bet neaktyvuoti. Perleiskite Syncthing programą iš naujo norėdami įgalinti naujus nustatymus.",
"The device ID cannot be blank.": "Įrenginio ID negali būti tuščias.", "The device ID cannot be blank.": "Įrenginio ID negali būti tuščias.",
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Įrenginio ID, kurį čia reikia įvesti, gali būti rastas „Redaguoti > Rodyti ID“ dialoge kitame įrenginyje. Tarpai ir brūkšneliai nebūtini (ignoruojami).", "The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Įrenginio ID, kurį čia reikia įvesti, gali būti rastas „Redaguoti > 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 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 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 first command line parameter is the folder path and the second parameter is the relative path in the folder.": "Pirmasis komandų eilutės parametras yra aplanko kelias, o antrasis parametras yra santykinis kelias aplanke.", "The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "The first command line parameter is the folder path and the second parameter is the relative path in the folder.",
"The folder ID cannot be blank.": "Aplanko ID negali būti tuščias.", "The folder ID cannot be blank.": "Aplanko ID negali būti tuščias.",
"The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "Aplanko vardas negali būti ilgesnis nei 64 simboliai. Galima naudoti tik raides ir skaičius bet tašką (.), brūkšnelį (-) ir pabraukimą (_).", "The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "Aplanko vardas negali būti ilgesnis nei 64 simboliai. Galima naudoti tik raides ir skaičius bet tašką (.), brūkšnelį (-) ir pabraukimą (_).",
"The folder ID must be unique.": "Aplanko ID turi būti unikalus.", "The folder ID must be unique.": "Aplanko ID turi būti unikalus.",
@@ -165,19 +158,15 @@
"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 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 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 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 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 old versions to keep, per file.": "Kiek failo versijų saugoti.", "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 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 path cannot be blank.": "Kelias negali būti tuščias.",
"The rescan interval must be a non-negative number of seconds.": "Nuskaitymo dažnis negali būti neigiamas skaičius.", "The rescan interval must be a non-negative number of seconds.": "Nuskaitymo dažnis negali būti neigiamas skaičius.",
"This is a major version upgrade.": "Tai yra stambus atnaujinimas.", "This is a major version upgrade.": "Tai yra stambus atnaujinimas.",
"Trash Can File Versioning": "Šiukšliadėžės versijų valdymas",
"Unknown": "Nežinoma", "Unknown": "Nežinoma",
"Unshared": "Nesidalinama", "Unshared": "Nesidalinama",
"Unused": "Nenaudojamas", "Unused": "Nenaudojamas",
"Up to Date": "Atnaujinta", "Up to Date": "Atnaujinta",
"Updated": "Atnaujinta",
"Upgrade": "Atnaujinimas", "Upgrade": "Atnaujinimas",
"Upgrade To {%version%}": "Atnaujinti į {{version}}", "Upgrade To {%version%}": "Atnaujinti į {{version}}",
"Upgrading": "Atnaujinama", "Upgrading": "Atnaujinama",
+20 -31
View File
@@ -1,9 +1,7 @@
{ {
"A negative number of days doesn't make sense.": "Et negativt antall dager gir ikke mening.", "A new major version may not be compatible with previous versions.": "A new major version may not be compatible with previous versions.",
"A new major version may not be compatible with previous versions.": "En ny hovedversjon kan bli ikke-kompatibel med en eldre versjon.",
"API Key": "API-nøkkel", "API Key": "API-nøkkel",
"About": "Om", "About": "Om",
"Actions": "Handlinger",
"Add": "Legg til", "Add": "Legg til",
"Add Device": "Legg Til Enhet", "Add Device": "Legg Til Enhet",
"Add Folder": "Legg Til Mappe", "Add Folder": "Legg Til Mappe",
@@ -12,15 +10,14 @@
"Addresses": "Adresser", "Addresses": "Adresser",
"All Data": "Alle data", "All Data": "Alle data",
"Allow Anonymous Usage Reporting?": "Tillat Anonym Innsamling Av Brukerdata?", "Allow Anonymous Usage Reporting?": "Tillat Anonym Innsamling Av Brukerdata?",
"Alphabetic": "Alfabetisk", "Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the synced folder.": "En ekstern kommando håndterer versjonkontrollen. Den må fjerne filen fra den synkroniserte katalogen.", "An external command handles the versioning. It has to remove the file from the synced folder.": "An external command handles the versioning. It has to remove the file from the synced folder.",
"Anonymous Usage Reporting": "Anonym Innsamling Av Brukerdata", "Anonymous Usage Reporting": "Anonym Innsamling Av Brukerdata",
"Any devices configured on an introducer device will be added to this device as well.": "Enheter konfigurert på en introduksjonsenhet vil også bli lagt til denne enheten.", "Any devices configured on an introducer device will be added to this device as well.": "Enheter konfigurert på en introduksjonsenhet vil også bli lagt til denne enheten.",
"Automatic upgrades": "Automatiske oppdateringer", "Automatic upgrades": "Automatiske oppdateringer",
"Bugs": "Programfeil", "Bugs": "Programfeil",
"CPU Utilization": "CPU-utnyttelse", "CPU Utilization": "CPU-utnyttelse",
"Changelog": "Endringslog", "Changelog": "Endringslog",
"Clean out after": "Tøm etter",
"Close": "Lukk", "Close": "Lukk",
"Command": "Kommando", "Command": "Kommando",
"Comment, when used at the start of a line": "Kommentar, når det blir brukt i starten av en linje.", "Comment, when used at the start of a line": "Kommentar, når det blir brukt i starten av en linje.",
@@ -30,8 +27,7 @@
"Copied from original": "Kopiert fra original", "Copied from original": "Kopiert fra original",
"Copyright © 2015 the following Contributors:": "Kopirett © 2015 de følgende bidragsytere:", "Copyright © 2015 the following Contributors:": "Kopirett © 2015 de følgende bidragsytere:",
"Delete": "Slett", "Delete": "Slett",
"Deleted": "Slettet", "Device ID": "Enhet ID",
"Device ID": "Enhets ID",
"Device Identification": "Enhetskjennemerke", "Device Identification": "Enhetskjennemerke",
"Device Name": "Navn På Enhet", "Device Name": "Navn På Enhet",
"Device {%device%} ({%address%}) wants to connect. Add new device?": "Enhet {{device}} ({{address}}) ønsker å koble seg til. Legg til ny enhet?", "Device {%device%} ({%address%}) wants to connect. Add new device?": "Enhet {{device}} ({{address}}) ønsker å koble seg til. Legg til ny enhet?",
@@ -50,11 +46,10 @@
"Enter ignore patterns, one per line.": "Skriv inn mønster som skal utelates, ett per linje.", "Enter ignore patterns, one per line.": "Skriv inn mønster som skal utelates, ett per linje.",
"Error": "Feilmelding", "Error": "Feilmelding",
"External File Versioning": "Ekstern versjonskontroll", "External File Versioning": "Ekstern versjonskontroll",
"File Pull Order": "Filenes Henterekkefølge", "File Pull Order": "File Pull Order",
"File Versioning": "Versjonskontroll", "File Versioning": "Versjonskontroll",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Fil bit-rettigheter ignoreres når forandringer oppdages. Bruk FAT filsystem. ", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Filer som slettes eller erstattes av Syncthing flyttes til katalogen .stversions", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Filer flyttes til en datostemplet versjon i .stversions-katalogen når den oppdateres eller slettes av 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.": "Filer er beskyttet mot endringer som er gjort på andre enheter, men endringer som er gjort på denne enheten blir sendt til resten av gruppen.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Filer er beskyttet mot endringer som er gjort på andre enheter, men endringer som er gjort på denne enheten blir sendt til resten av gruppen.",
"Folder ID": "Mappe ID", "Folder ID": "Mappe ID",
"Folder Master": "Styrende Mappe", "Folder Master": "Styrende Mappe",
@@ -67,7 +62,6 @@
"Global Discovery": "Global Søking", "Global Discovery": "Global Søking",
"Global Discovery Server": "Global Søkemotor", "Global Discovery Server": "Global Søkemotor",
"Global State": "Global Tilstand", "Global State": "Global Tilstand",
"Help": "Hjelp",
"Ignore": "Ignorer", "Ignore": "Ignorer",
"Ignore Patterns": "Utelatelsesmønster", "Ignore Patterns": "Utelatelsesmønster",
"Ignore Permissions": "Ignorer Tilgangsbit", "Ignore Permissions": "Ignorer Tilgangsbit",
@@ -75,14 +69,13 @@
"Introducer": "Introduktør", "Introducer": "Introduktør",
"Inversion of the given condition (i.e. do not exclude)": "Invers av den gitte tilstanden (t.d. ikke ekskluder)", "Inversion of the given condition (i.e. do not exclude)": "Invers av den gitte tilstanden (t.d. ikke ekskluder)",
"Keep Versions": "Behold Versjoner", "Keep Versions": "Behold Versjoner",
"Largest First": "Største fil", "Largest First": "Largest First",
"Last File Received": "Sist Mottatte Fil", "Last File Received": "Sist Mottatte Fil",
"Last seen": "Sist sett", "Last seen": "Sist sett",
"Later": "Senere", "Later": "Senere",
"Local Discovery": "Lokal Søking", "Local Discovery": "Lokal Søking",
"Local State": "Lokal Tilstand", "Local State": "Lokal Tilstand",
"Local State (Total)": "Lokal Tilstand (Total)", "Major Upgrade": "Major Upgrade",
"Major Upgrade": "Hovedoppgradering",
"Maximum Age": "Maksimal Levetid", "Maximum Age": "Maksimal Levetid",
"Metadata Only": "Kun metadata", "Metadata Only": "Kun metadata",
"Move to top of queue": "Flytt til topp av kø", "Move to top of queue": "Flytt til topp av kø",
@@ -90,27 +83,27 @@
"Never": "Aldri", "Never": "Aldri",
"New Device": "Ny Enhet", "New Device": "Ny Enhet",
"New Folder": "Ny Mappe", "New Folder": "Ny Mappe",
"Newest First": "Den nyeste først", "Newest First": "Newest First",
"No": "Nei", "No": "Nei",
"No File Versioning": "Ingen Versjonskontroll", "No File Versioning": "Ingen Versjonskontroll",
"Notice": "Merknad", "Notice": "Merknad",
"OK": "OK", "OK": "OK",
"Off": "Av", "Off": "Av",
"Oldest First": "Den eldste først", "Oldest First": "Oldest First",
"Out Of Sync": "Ikke Synkronisert", "Out Of Sync": "Ikke Synkronisert",
"Out of Sync Items": "Ikke Synkroniserte Element", "Out of Sync Items": "Ikke Synkroniserte Element",
"Outgoing Rate Limit (KiB/s)": "Utgående Hastighetsbegrensning (KiB/s)", "Outgoing Rate Limit (KiB/s)": "Utgående Hastighetsbegrensning (KiB/s)",
"Override Changes": "Overstyr Endringer", "Override Changes": "Overstyr Endringer",
"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": "Plasseringen av mappen på datamaskinen. Denne vil bli opprettet dersom den ikke finnes. Krøllstrektegnet (~) kan brukes som forkortelse for", "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": "Plasseringen av mappen på datamaskinen. Blir opprettet om den ikke finnes. Krøllstrektegnet (~) kan brukes som forkortelse for",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Plasseringen for lagrede versjoner (la denne være tom for å bruke standard .stversions-mappen i mappen).", "Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Plasseringen for lagrede versjoner (la denne være tom for å bruke standard .stversions-mappen i mappen).",
"Please consult the release notes before performing a major upgrade.": "Se \"release notes\" før en hovedoppgradering utføres.", "Please consult the release notes before performing a major upgrade.": "Please consult the release notes before performing a major upgrade.",
"Please wait": "Vennligst vent", "Please wait": "Vennligst vent",
"Preview": "Forhåndsvisning", "Preview": "Forhåndsvisning",
"Preview Usage Report": "Forhåndsvisning Av Datainnsamling", "Preview Usage Report": "Forhåndsvisning Av Datainnsamling",
"Quick guide to supported patterns": "Kjapp innføring i godkjente mønster", "Quick guide to supported patterns": "Kjapp innføring i godkjente mønster",
"RAM Utilization": "RAM-utnyttelse", "RAM Utilization": "RAM-utnyttelse",
"Random": "TIlfeldig", "Random": "Random",
"Release Notes": "Utgivelsesnotat", "Release Notes": "Release Notes",
"Rescan": "Skann på nytt", "Rescan": "Skann på nytt",
"Rescan All": "Skann alt på nytt", "Rescan All": "Skann alt på nytt",
"Rescan Interval": "Skanneintervall", "Rescan Interval": "Skanneintervall",
@@ -137,7 +130,7 @@
"Shutdown Complete": "Avslutning fullført", "Shutdown Complete": "Avslutning fullført",
"Simple File Versioning": "Enkel Versjonskontroll", "Simple File Versioning": "Enkel Versjonskontroll",
"Single level wildcard (matches within a directory only)": "Enkeltnivåsøk (søker kun i en mappe)", "Single level wildcard (matches within a directory only)": "Enkeltnivåsøk (søker kun i en mappe)",
"Smallest First": "Den minste først", "Smallest First": "Smallest First",
"Source Code": "Kildekode", "Source Code": "Kildekode",
"Staggered File Versioning": "Forskjøvet Versjonskontroll", "Staggered File Versioning": "Forskjøvet Versjonskontroll",
"Start Browser": "Start Nettleser", "Start Browser": "Start Nettleser",
@@ -157,7 +150,7 @@
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Enhet-IDen lagt til her kan hentes fram via \"Rediger > Vis ID\"-dialogboksen på den andre enheten. Mellomrom og bindestrek er valgfritt (blir ignorert).", "The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Enhet-IDen lagt til her kan hentes fram via \"Rediger > Vis ID\"-dialogboksen på den andre enheten. Mellomrom og bindestrek er valgfritt (blir ignorert).",
"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.": "Kryptert informasjon om bruken av programmet blir gjort daglig. Dette blir brukt til å følge med på vanlig brukte systemoppsett, størrelser på mapper, og versjoner av programmet. Om datasettet endrer seg vil denne dialogboksen dukke opp og du vil bli bedt om å godkjenne dette.", "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.": "Kryptert informasjon om bruken av programmet blir gjort daglig. Dette blir brukt til å følge med på vanlig brukte systemoppsett, størrelser på mapper, og versjoner av programmet. Om datasettet endrer seg vil denne dialogboksen dukke opp og du vil bli bedt om å godkjenne dette.",
"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.": "IDen for denne enheten er ikke godkjent. Det bør være 52 eller 56 tegn bestående av bokstaver og tall, valgfritt med mellomrom og bindestrek.", "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.": "IDen for denne enheten er ikke godkjent. Det bør være 52 eller 56 tegn bestående av bokstaver og tall, valgfritt med mellomrom og bindestrek.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "Den første kommandolinje-parameteren er katalog-filbanen, det andre parametere er den relative filbanen i katalogen.", "The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "The first command line parameter is the folder path and the second parameter is the relative path in the folder.",
"The folder ID cannot be blank.": "Mappe-ID kan ikke være tom.", "The folder ID cannot be blank.": "Mappe-ID kan ikke være tom.",
"The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "Mappe-IDen må være et kort kjennemerke (64 tegn eller mindre) bestående kun av bokstaver, tall og tegnene punktum (.), mellomrom (-) og strek (_).", "The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "Mappe-IDen må være et kort kjennemerke (64 tegn eller mindre) bestående kun av bokstaver, tall og tegnene punktum (.), mellomrom (-) og strek (_).",
"The folder ID must be unique.": "Mappe-ID må være unik.", "The folder ID must be unique.": "Mappe-ID må være unik.",
@@ -165,24 +158,20 @@
"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.": "Følgende intervall blir brukt: den første timen blir en versjon lagret hvert 30. sekund, den første dagen blir en versjon lagret hver time, de første 30 dagene blir en versjon lagret hver dag, og inntil maksimal levetid blir en versjon lagret hver uke.", "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.": "Følgende intervall blir brukt: den første timen blir en versjon lagret hvert 30. sekund, den første dagen blir en versjon lagret hver time, de første 30 dagene blir en versjon lagret hver dag, og inntil maksimal levetid blir en versjon lagret hver uke.",
"The maximum age must be a number and cannot be blank.": "Maksimal levetid må være et tall og kan ikke være tomt.", "The maximum age must be a number and cannot be blank.": "Maksimal levetid må være et tall og kan ikke være tomt.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Maksimal tid å beholde en versjon (i dager, sett til 0 for å beholde versjoner på ubegrenset tid).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Maksimal tid å beholde en versjon (i dager, sett til 0 for å beholde versjoner på ubegrenset tid).",
"The number of days must be a number and cannot be blank.": "Antall dager må være et tall og kan ikke være tomt.",
"The number of days to keep files in the trash can. Zero means forever.": "Antall dager man skal bevare filene i papirkurven. Null betyr for alltid.",
"The number of old versions to keep, per file.": "Antall gamle versjoner å beholde, per fil.", "The number of old versions to keep, per file.": "Antall gamle versjoner å beholde, per fil.",
"The number of versions must be a number and cannot be blank.": "Antall versjoner må være et tall og kan ikke være tomt.", "The number of versions must be a number and cannot be blank.": "Antall versjoner må være et tall og kan ikke være tomt.",
"The path cannot be blank.": "Plasseringen kan ikke være tom.", "The path cannot be blank.": "Plasseringen kan ikke være tom.",
"The rescan interval must be a non-negative number of seconds.": "Antall sekund i skanneintervallet kan ikke være negativt.", "The rescan interval must be a non-negative number of seconds.": "Antall sekund i skanneintervallet kan ikke være negativt.",
"This is a major version upgrade.": "Dette er en hovedoppgradering", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Fil versjonskontroll i papirkurven",
"Unknown": "Ukjent", "Unknown": "Ukjent",
"Unshared": "Ikke delt", "Unshared": "Ikke delt",
"Unused": "Ikke i bruk", "Unused": "Ikke i bruk",
"Up to Date": "Oppdatert", "Up to Date": "Oppdatert",
"Updated": "Oppdatert", "Upgrade": "Upgrade",
"Upgrade": "Oppgradere",
"Upgrade To {%version%}": "Oppgrader Til {{version}}", "Upgrade To {%version%}": "Oppgrader Til {{version}}",
"Upgrading": "Oppgraderer", "Upgrading": "Oppgraderer",
"Upload Rate": "Opplastingsrate", "Upload Rate": "Opplastingsrate",
"Uptime": "Oppetid", "Uptime": "Uptime",
"Use HTTPS for GUI": "Bruk HTTPS for GUI", "Use HTTPS for GUI": "Bruk HTTPS for GUI",
"Version": "Versjon", "Version": "Versjon",
"Versions Path": "Plassering Av Versjoner", "Versions Path": "Plassering Av Versjoner",
+19 -30
View File
@@ -1,9 +1,7 @@
{ {
"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.": "Het kan voorkomen dat een grote nieuwe update niet meer werkt met eerdere versies.", "A new major version may not be compatible with previous versions.": "Het kan voorkomen dat een grote nieuwe update niet meer werkt met eerdere versies.",
"API Key": "API-sleutel", "API Key": "API-sleutel",
"About": "Over", "About": "Over",
"Actions": "Acties",
"Add": "Toevoegen", "Add": "Toevoegen",
"Add Device": "Toestel toevoegen", "Add Device": "Toestel toevoegen",
"Add Folder": "Folder toevoegen", "Add Folder": "Folder toevoegen",
@@ -15,12 +13,11 @@
"Alphabetic": "Alfabetisch", "Alphabetic": "Alfabetisch",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Versiebeheer gebeurt door een extern commando. Het moet het bestand verwijderen van de gesynchroniseerde map.", "An external command handles the versioning. It has to remove the file from the synced folder.": "Versiebeheer gebeurt door een extern commando. Het moet het bestand verwijderen van de gesynchroniseerde map.",
"Anonymous Usage Reporting": "Bijhouden anonieme gebruikers statistieken", "Anonymous Usage Reporting": "Bijhouden anonieme gebruikers statistieken",
"Any devices configured on an introducer device will be added to this device as well.": "Toestellen die geconfigureerd worden op een introductietoestel zullen ook aan dit toestel worden toegevoegd.", "Any devices configured on an introducer device will be added to this device as well.": "Toestellen geconfigureerd op een introductie toestel zullen ook aan dit toestel worden toegevoegd.",
"Automatic upgrades": "Automatisch bijwerken", "Automatic upgrades": "Automatisch bijwerken",
"Bugs": "Fouten", "Bugs": "Fouten",
"CPU Utilization": "CPU Gebruik", "CPU Utilization": "CPU Gebruik",
"Changelog": "Logboek", "Changelog": "Logboek",
"Clean out after": "Clean out after",
"Close": "Sluiten", "Close": "Sluiten",
"Command": "Commando", "Command": "Commando",
"Comment, when used at the start of a line": "Commentaar, indien gebruikt aan het begin van de lijn", "Comment, when used at the start of a line": "Commentaar, indien gebruikt aan het begin van de lijn",
@@ -30,8 +27,7 @@
"Copied from original": "Gekopieerd van het origineel", "Copied from original": "Gekopieerd van het origineel",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 de volgende Bijdragers:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 de volgende Bijdragers:",
"Delete": "Verwijderen", "Delete": "Verwijderen",
"Deleted": "Deleted", "Device ID": "Apparaat ID",
"Device ID": "Apparaat-ID",
"Device Identification": "Apparaat identificatie", "Device Identification": "Apparaat identificatie",
"Device Name": "Naam apparaat", "Device Name": "Naam apparaat",
"Device {%device%} ({%address%}) wants to connect. Add new device?": "Het apparaat {{device}} ({{address}}) wenst te verbinden. Dit apparaat toevoegen?", "Device {%device%} ({%address%}) wants to connect. Add new device?": "Het apparaat {{device}} ({{address}}) wenst te verbinden. Dit apparaat toevoegen?",
@@ -49,14 +45,13 @@
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Geef, gescheiden door komma's, \"ip:port\" adressen of \"dynamic\" voor het automatische vinden van de addressen.", "Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Geef, gescheiden door komma's, \"ip:port\" adressen of \"dynamic\" voor het automatische vinden van de addressen.",
"Enter ignore patterns, one per line.": "Geef te negeren patronen, één per regel.", "Enter ignore patterns, one per line.": "Geef te negeren patronen, één per regel.",
"Error": "Fout", "Error": "Fout",
"External File Versioning": "Extern versiebeheer voor bestanden", "External File Versioning": "Extern Bestandsversiebeheer",
"File Pull Order": "Volgorde van bijwerken van bestanden", "File Pull Order": "Volgorde van updaten bestanden",
"File Versioning": "Versiebeheer", "File Versioning": "Versiebeheer",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Toegangsrechten voor bestanden worden genegeerd bij het zoeken naar wijzigingen. Gebruik voor FAT bestandssystemen.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Toegangsrechten voor bestanden worden genegeerd bij het zoeken naar wijzigingen. Gebruik voor FAT bestandssystemen.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Bestanden worden niet door Syncthing vervangen of verwijderd, maar verplaatst naar de .stversions-map.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Bestanden worden niet door Syncthing vervangen of verwijderd, maar verplaatst naar de map .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.": "Bestanden zijn beschermt tegen aanpassingen gemaakt door andere apparaten maar aanpassingen op dit apparaat worden doorgestuurd naar de rest van de cluster.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Bestanden zijn beschermt tegen aanpassingen gemaakt door andere apparaten maar aanpassingen op dit apparaat worden doorgestuurd naar de rest van het cluster.", "Folder ID": "Folder ID",
"Folder ID": "Folder-ID",
"Folder Master": "Hoofdfolder", "Folder Master": "Hoofdfolder",
"Folder Path": "Locatie folder", "Folder Path": "Locatie folder",
"Folders": "Folders", "Folders": "Folders",
@@ -67,7 +62,6 @@
"Global Discovery": "Globaal zoeken", "Global Discovery": "Globaal zoeken",
"Global Discovery Server": "Globale zoekserver", "Global Discovery Server": "Globale zoekserver",
"Global State": "Globale status", "Global State": "Globale status",
"Help": "Help",
"Ignore": "Negeren", "Ignore": "Negeren",
"Ignore Patterns": "Te negeren patronen", "Ignore Patterns": "Te negeren patronen",
"Ignore Permissions": "Rechten negeren", "Ignore Permissions": "Rechten negeren",
@@ -81,11 +75,10 @@
"Later": "Later", "Later": "Later",
"Local Discovery": "Lokaal zoeken", "Local Discovery": "Lokaal zoeken",
"Local State": "Lokale status", "Local State": "Lokale status",
"Local State (Total)": "Local State (Total)",
"Major Upgrade": "Grote update", "Major Upgrade": "Grote update",
"Maximum Age": "Maximum leeftijd", "Maximum Age": "Maximum leeftijd",
"Metadata Only": "Alleen Metadata", "Metadata Only": "Alleen Metadata",
"Move to top of queue": "Verplaats naar het begin van de wachtrij", "Move to top of queue": "Verplaats naar begin van wachtrij",
"Multi level wildcard (matches multiple directory levels)": "Wildcard op meerder niveaus (toepasbaar op meerdere niveaus van folders)", "Multi level wildcard (matches multiple directory levels)": "Wildcard op meerder niveaus (toepasbaar op meerdere niveaus van folders)",
"Never": "Nooit", "Never": "Nooit",
"New Device": "Nieuw Apparaat", "New Device": "Nieuw Apparaat",
@@ -129,10 +122,10 @@
"Share With Devices": "Delen met toestellen", "Share With Devices": "Delen met toestellen",
"Share this folder?": "Deze folder delen?", "Share this folder?": "Deze folder delen?",
"Shared With": "Gedeeld met", "Shared With": "Gedeeld met",
"Short identifier for the folder. Must be the same on all cluster devices.": "Korte aanduiding voor deze folder. Moet dezelfde zijn op alle toestellen in het cluster.", "Short identifier for the folder. Must be the same on all cluster devices.": "Korte aanduiding voor deze folder. Moet dezelfde zijn op alle toestellen in de cluster.",
"Show ID": "Toon ID", "Show ID": "Toon ID",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Wordt getoond in plaats van het toestel-ID in het cluster staat. Wordt doorgegeven aan andere toestellen as een bijkomende standaard toestelnaam.", "Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Wordt getoond in plaats van de toestel ID in de cluster staat. Wordt doorgegeven aan andere toestellen as een bijkomende standaard toestelnaam.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Wordt getoond in plaats van het toestel-ID in het cluster status. Indien leeggelaten, dan wordt het bijgewerkt met de naam zoals het toestel aangeeft.", "Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Wordt getoond in plaats van de toestel ID in de cluster staat. Wanneer leeg wordt deze aangepast met de naam aangekondigd door het toestel.",
"Shutdown": "Sluit af", "Shutdown": "Sluit af",
"Shutdown Complete": "Afsluiten voltooid", "Shutdown Complete": "Afsluiten voltooid",
"Simple File Versioning": "Eenvoudig versiebeheer", "Simple File Versioning": "Eenvoudig versiebeheer",
@@ -153,31 +146,27 @@
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing heeft een probleem met het verwerken van je verzoek. Gelieve de pagina te vernieuwen of Syncthing te herstarten als het probleem zich blijft voordoen.", "Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing heeft een probleem met het verwerken van je verzoek. Gelieve de pagina te vernieuwen of Syncthing te herstarten als het probleem zich blijft voordoen.",
"The aggregated statistics are publicly available at {%url%}.": "The verzamelde statistieken zijn publiek beschikbaar op {{url}}", "The aggregated statistics are publicly available at {%url%}.": "The verzamelde statistieken zijn publiek beschikbaar op {{url}}",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "De configuratie is opslagen maar nog niet actief. Syncthing moet opnieuw opgestart worden om de nieuwe configuratie te activeren.", "The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "De configuratie is opslagen maar nog niet actief. Syncthing moet opnieuw opgestart worden om de nieuwe configuratie te activeren.",
"The device ID cannot be blank.": "Het toestel-ID mag niet leeg zijn.", "The device ID cannot be blank.": "Het toestel ID mag niet leeg zijn.",
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Het verwachte toestel-ID kan teruggevonden worden in het \"Aanpassen > Toon ID\" scherm op het andere toestel. Spaties en streepjes zijn facultatief (worden genegeerd).", "The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Het verwachte toestel ID kan teruggevonden worden in het \"Aanpassen > Toon ID\" scherm op het andere toestel. Spaties en streepjes zijn facultatief (worden genegeerd).",
"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.": "Het versleutelde gebruiksrapport wordt dagelijks opgestuurd en wordt gebruikt om de verschillende platformen, folder groottes en versies op te volgen. Als de reeks gegevens wijzigt zal opnieuw toestemming gevraagd worden.", "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.": "Het versleutelde gebruiksrapport wordt dagelijks opgestuurd en wordt gebruikt om de verschillende platformen, folder groottes en versies op te volgen. Als de reeks gegevens wijzigt zal opnieuw toestemming gevraagd worden.",
"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.": "Dit toestel-ID lijkt ongeldig. Het toestel-ID bestaat uit 52 of 56 letters en nummers met facultatieve spaties en streepjes.", "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.": "Dit toestel ID lijkt ongeldig. Het toestel ID bestaat uit 52 of 56 letters en nummers met facultatieve spaties en streepjes.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "De eerste parameter is het pad naar de map en de tweede parameter is het relatieve pad binnenin de map.", "The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "De eerste parameter is het pad naar de map en de tweede parameter is het relatieve pad binnenin de map.",
"The folder ID cannot be blank.": "Het folder-ID mag niet leeg zijn.", "The folder ID cannot be blank.": "De folder ID mag niet leeg zijn.",
"The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "Het folder-ID is een korte aanduiding (maximaal 64 tekens lang) en bestaat enkel uit letters, nummers, punten (.), streepjes (-) en onderstrepingstekens (_).", "The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "De folder ID mag maximaal 64 tekens lang zijn en bestaat enkel uit letters, nummers, punten (.), streepjes (-) en onderstrepingstekens (_).",
"The folder ID must be unique.": "Het folder-ID moet uniek zijn.", "The folder ID must be unique.": "De folder ID moet uniek zijn.",
"The folder path cannot be blank.": "De folder locatie mag niet leeg zijn.", "The folder path cannot be blank.": "De folder locatie mag niet leeg zijn.",
"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.": "De volgende intervallen worden gebruikt: het eerste uur worden versies iedere 30 seconden bewaard, de eerste dag worden versies ieder uur bewaard, de eerste 30 dagen worden versies iedere dag bewaard, tot de maximale leeftijd worden versies iedere week bewaard.", "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.": "De volgende intervallen worden gebruikt: het eerste uur worden versies iedere 30 seconden bewaard, de eerste dag worden versies ieder uur bewaard, de eerste 30 dagen worden versies iedere dag bewaard, tot de maximale leeftijd worden versies iedere week bewaard.",
"The maximum age must be a number and cannot be blank.": "De maximum leeftijd moet uit cijfers bestaan en mag niet leeggelaten worden.", "The maximum age must be a number and cannot be blank.": "De maximum leeftijd moet uit cijfers bestaan en mag niet leeggelaten worden.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "De maximale tijdsduur om een versie te bewaren (in dagen, gebruik 0 om versies voor altijd te bewaren).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "De maximale tijdsduur om een versie te bewaren (in dagen, gebruik 0 om versies voor altijd te bewaren).",
"The number of days must be a number and cannot be blank.": "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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "Het aantal versies dat bewaard moet worden per file.", "The number of old versions to keep, per file.": "Het aantal versies dat bewaard moet worden per file.",
"The number of versions must be a number and cannot be blank.": "Het aantal nummers moet een getal zijn en mag niet leeg blijven.", "The number of versions must be a number and cannot be blank.": "Het aantal nummers moet een getal zijn en mag niet leeg blijven.",
"The path cannot be blank.": "U dient een locatie in te voeren.", "The path cannot be blank.": "U dient een locatie in te voeren.",
"The rescan interval must be a non-negative number of seconds.": "De scanfrequentie moet een positief getal in seconden zijn.", "The rescan interval must be a non-negative number of seconds.": "De scanfrequentie moet een positief getal in seconden zijn.",
"This is a major version upgrade.": "Dit is een grote update.", "This is a major version upgrade.": "Dit is een grote update.",
"Trash Can File Versioning": "Trash Can File Versioning",
"Unknown": "Onbekend", "Unknown": "Onbekend",
"Unshared": "Niet gedeeld", "Unshared": "Niet gedeeld",
"Unused": "Ongebruikt", "Unused": "Ongebruikt",
"Up to Date": "Gesynchroniseerd", "Up to Date": "Gesynchroniseerd",
"Updated": "Updated",
"Upgrade": "Update", "Upgrade": "Update",
"Upgrade To {%version%}": "Upgrade naar {{version}}", "Upgrade To {%version%}": "Upgrade naar {{version}}",
"Upgrading": "Bezig met upgrade", "Upgrading": "Bezig met upgrade",
@@ -187,8 +176,8 @@
"Version": "Versie", "Version": "Versie",
"Versions Path": "Locatie versies", "Versions Path": "Locatie versies",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versies worden automatisch verwijderd als deze ouder zijn dan de maximale leeftijd of als ze het maximaal aantal toegestane bestanden per interval overschrijden. ", "Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versies worden automatisch verwijderd als deze ouder zijn dan de maximale leeftijd of als ze het maximaal aantal toegestane bestanden per interval overschrijden. ",
"When adding a new device, keep in mind that this device must be added on the other side too.": "Wanneer een nieuw toestel wordt toegevoegd, houd er dan rekening mee dat dit toestel ook aan de andere kant moet worden toegevoegd.", "When adding a new device, keep in mind that this device must be added on the other side too.": "Onthoud dat een toegevoegd toestel ook aan de andere kant moet worden toegevoegd.",
"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.": "Houd er rekening mee dat -bij het toevoegen van een folder- het folder-ID gebruikt wordt om folders tussen toestellen te verbinden. Ze zijn hoofdletter gevoelig en moeten exact hetzelfde zijn op de andere toestellen.", "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.": "Onthoud, bij het toevoegen van een folder, dat de folder ID gebruikt wordt om folders tussen toestellen te verbinden. Ze zijn hoofdletter gevoelig en moeten exact hetzelfde zijn op de andere toestellen.",
"Yes": "Ja", "Yes": "Ja",
"You must keep at least one version.": "Minstens 1 versie moet bewaard blijven.", "You must keep at least one version.": "Minstens 1 versie moet bewaard blijven.",
"full documentation": "volledige documentatie", "full documentation": "volledige documentatie",
-11
View File
@@ -1,9 +1,7 @@
{ {
"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.": "A new major version may not be compatible with previous versions.", "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-nøkkel", "API Key": "API-nøkkel",
"About": "Om", "About": "Om",
"Actions": "Actions",
"Add": "Legg til", "Add": "Legg til",
"Add Device": "Legg Til Eining", "Add Device": "Legg Til Eining",
"Add Folder": "Legg Til Mappe", "Add Folder": "Legg Til Mappe",
@@ -20,7 +18,6 @@
"Bugs": "Programfeil", "Bugs": "Programfeil",
"CPU Utilization": "CPU-utnytting", "CPU Utilization": "CPU-utnytting",
"Changelog": "Endringslogg", "Changelog": "Endringslogg",
"Clean out after": "Clean out after",
"Close": "Lukk", "Close": "Lukk",
"Command": "Kommando", "Command": "Kommando",
"Comment, when used at the start of a line": "Kommentar, når brukt i starten av linja", "Comment, when used at the start of a line": "Kommentar, når brukt i starten av linja",
@@ -30,7 +27,6 @@
"Copied from original": "Kopiert frå originalen", "Copied from original": "Kopiert frå originalen",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
"Delete": "Slett", "Delete": "Slett",
"Deleted": "Deleted",
"Device ID": "Eining ID", "Device ID": "Eining ID",
"Device Identification": "Einingskjennemerke", "Device Identification": "Einingskjennemerke",
"Device Name": "Namn På Eining", "Device Name": "Namn På Eining",
@@ -53,7 +49,6 @@
"File Pull Order": "File Pull Order", "File Pull Order": "File Pull Order",
"File Versioning": "Filutgåvekontroll", "File Versioning": "Filutgåvekontroll",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by 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.": "Filer er beskytta mot endringar gjort på andre einingar, men endringar gjort på denne eininga vert sende til resten av klyngja.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Filer er beskytta mot endringar gjort på andre einingar, men endringar gjort på denne eininga vert sende til resten av klyngja.",
"Folder ID": "Mappe ID", "Folder ID": "Mappe ID",
@@ -67,7 +62,6 @@
"Global Discovery": "Global søking", "Global Discovery": "Global søking",
"Global Discovery Server": "Global søkjetenar", "Global Discovery Server": "Global søkjetenar",
"Global State": "Global Tilstand", "Global State": "Global Tilstand",
"Help": "Help",
"Ignore": "Ignorer", "Ignore": "Ignorer",
"Ignore Patterns": "Utelatingsmønster", "Ignore Patterns": "Utelatingsmønster",
"Ignore Permissions": "Ignorer tilgangar", "Ignore Permissions": "Ignorer tilgangar",
@@ -81,7 +75,6 @@
"Later": "Seinare", "Later": "Seinare",
"Local Discovery": "Lokal oppdaging", "Local Discovery": "Lokal oppdaging",
"Local State": "Lokal Tilstand", "Local State": "Lokal Tilstand",
"Local State (Total)": "Local State (Total)",
"Major Upgrade": "Major Upgrade", "Major Upgrade": "Major Upgrade",
"Maximum Age": "Maksimal Levetid", "Maximum Age": "Maksimal Levetid",
"Metadata Only": "Berre metadata", "Metadata Only": "Berre metadata",
@@ -165,19 +158,15 @@
"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.": "Desse intervalla vert nytta: den fyrste timen vert ei utgåve lagra kvart 30. sekund, den fyrste dagen vert ei utgåve lagra kvar time, dei fyrste 30 dagane vert ei utgåve lagra kvar dag, og inntil høgaste alderen vert ei utgåve lagra kvar veke.", "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.": "Desse intervalla vert nytta: den fyrste timen vert ei utgåve lagra kvart 30. sekund, den fyrste dagen vert ei utgåve lagra kvar time, dei fyrste 30 dagane vert ei utgåve lagra kvar dag, og inntil høgaste alderen vert ei utgåve lagra kvar veke.",
"The maximum age must be a number and cannot be blank.": "Maksimal levetid må vera eit tal og kan ikkje vera tomt.", "The maximum age must be a number and cannot be blank.": "Maksimal levetid må vera eit tal og kan ikkje vera tomt.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Høgaste tidsrom å behalda ei utgåve (i dagar, set til 0 for å behalda versjonane for alltid).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Høgaste tidsrom å behalda ei utgåve (i dagar, set til 0 for å behalda versjonane for alltid).",
"The number of days must be a number and cannot be blank.": "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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "Tal på gamle versjonar ein skal behalda, per fil.", "The number of old versions to keep, per file.": "Tal på gamle versjonar ein skal behalda, per fil.",
"The number of versions must be a number and cannot be blank.": "Tal på versjonar må vera eit tal og kan ikkje vera tomt.", "The number of versions must be a number and cannot be blank.": "Tal på versjonar må vera eit tal og kan ikkje vera tomt.",
"The path cannot be blank.": "Bana kan ikkje vera tom.", "The path cannot be blank.": "Bana kan ikkje vera tom.",
"The rescan interval must be a non-negative number of seconds.": "Talet på sekund i skanneintervallet kan ikkje vera negativt.", "The rescan interval must be a non-negative number of seconds.": "Talet på sekund i skanneintervallet kan ikkje vera negativt.",
"This is a major version upgrade.": "This is a major version upgrade.", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Trash Can File Versioning",
"Unknown": "Ukjent", "Unknown": "Ukjent",
"Unshared": "Ikkje delt", "Unshared": "Ikkje delt",
"Unused": "Ubrukt", "Unused": "Ubrukt",
"Up to Date": "Oppdatert", "Up to Date": "Oppdatert",
"Updated": "Updated",
"Upgrade": "Upgrade", "Upgrade": "Upgrade",
"Upgrade To {%version%}": "Oppgrader Til {{version}}", "Upgrade To {%version%}": "Oppgrader Til {{version}}",
"Upgrading": "Oppgraderer", "Upgrading": "Oppgraderer",
+1 -12
View File
@@ -1,9 +1,7 @@
{ {
"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.": "A new major version may not be compatible with previous versions.", "A new major version may not be compatible with previous versions.": "A new major version may not be compatible with previous versions.",
"API Key": "Klucz API", "API Key": "Klucz API",
"About": "O Syncthing", "About": "O Syncthing",
"Actions": "Actions",
"Add": "Dodaj", "Add": "Dodaj",
"Add Device": "Dodaj urządzenie", "Add Device": "Dodaj urządzenie",
"Add Folder": "Dodaj folder", "Add Folder": "Dodaj folder",
@@ -20,7 +18,6 @@
"Bugs": "Błędy", "Bugs": "Błędy",
"CPU Utilization": "Użycie CPU", "CPU Utilization": "Użycie CPU",
"Changelog": "Historia zmian", "Changelog": "Historia zmian",
"Clean out after": "Clean out after",
"Close": "Zamknij", "Close": "Zamknij",
"Command": "Polecenie", "Command": "Polecenie",
"Comment, when used at the start of a line": "Komentarz, jeżeli użyty na początku linii", "Comment, when used at the start of a line": "Komentarz, jeżeli użyty na początku linii",
@@ -30,7 +27,6 @@
"Copied from original": "Skopiowane z oryginału", "Copied from original": "Skopiowane z oryginału",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
"Delete": "Usuń", "Delete": "Usuń",
"Deleted": "Deleted",
"Device ID": "ID urządzenia", "Device ID": "ID urządzenia",
"Device Identification": "Identyfikator urządzenia", "Device Identification": "Identyfikator urządzenia",
"Device Name": "Nazwa urządzenia", "Device Name": "Nazwa urządzenia",
@@ -52,8 +48,7 @@
"External File Versioning": "Zewnętrzne wersjonowanie pliku", "External File Versioning": "Zewnętrzne wersjonowanie pliku",
"File Pull Order": "Kolejność pobierania plików", "File Pull Order": "Kolejność pobierania plików",
"File Versioning": "Wersjonowanie plików", "File Versioning": "Wersjonowanie plików",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Uprawnienia plików są ignorowane przy poszukiwaniu zmian. Używaj w systemie plików FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by 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.": "Pliki są zabezpieczone przed zmianami na innym urządzeniu, jednak zmiany w tym urządzeniu będą wysłane do reszty.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Pliki są zabezpieczone przed zmianami na innym urządzeniu, jednak zmiany w tym urządzeniu będą wysłane do reszty.",
"Folder ID": "ID folderu", "Folder ID": "ID folderu",
@@ -67,7 +62,6 @@
"Global Discovery": "Globalne odnajdywanie", "Global Discovery": "Globalne odnajdywanie",
"Global Discovery Server": "Globalny serwer rozgłoszeniowy", "Global Discovery Server": "Globalny serwer rozgłoszeniowy",
"Global State": "Status globalny", "Global State": "Status globalny",
"Help": "Help",
"Ignore": "Ignoruj", "Ignore": "Ignoruj",
"Ignore Patterns": "Wzorce ignorowania", "Ignore Patterns": "Wzorce ignorowania",
"Ignore Permissions": "Ignoruj uprawnienia", "Ignore Permissions": "Ignoruj uprawnienia",
@@ -81,7 +75,6 @@
"Later": "Później", "Later": "Później",
"Local Discovery": "Lokalne odnajdywanie", "Local Discovery": "Lokalne odnajdywanie",
"Local State": "Status lokalny", "Local State": "Status lokalny",
"Local State (Total)": "Local State (Total)",
"Major Upgrade": "Major Upgrade", "Major Upgrade": "Major Upgrade",
"Maximum Age": "Maksymalny wiek", "Maximum Age": "Maksymalny wiek",
"Metadata Only": "Tylko metadane", "Metadata Only": "Tylko metadane",
@@ -165,19 +158,15 @@
"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.": "Następujący interwał jest używany: dla pierwszej godziny wersja jest zachowywana co 30 sekund, dla pierwszego dnia wersja jest zachowywana co godzinę, dla pierwszego miesiąca wersja jest zachowywana codziennie, aż do maksymalnego odstępu zapisywania wersji co tydzień.", "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.": "Następujący interwał jest używany: dla pierwszej godziny wersja jest zachowywana co 30 sekund, dla pierwszego dnia wersja jest zachowywana co godzinę, dla pierwszego miesiąca wersja jest zachowywana codziennie, aż do maksymalnego odstępu zapisywania wersji co tydzień.",
"The maximum age must be a number and cannot be blank.": "Maksymalny wiek musi być liczbą i nie może być pusty.", "The maximum age must be a number and cannot be blank.": "Maksymalny wiek musi być liczbą i nie może być pusty.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Maksymalny czas zachowania wersji (w dniach, ustaw 0 aby zachować na zawsze)", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Maksymalny czas zachowania wersji (w dniach, ustaw 0 aby zachować na zawsze)",
"The number of days must be a number and cannot be blank.": "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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "Liczba wersji pliku do zachowania.", "The number of old versions to keep, per file.": "Liczba wersji pliku do zachowania.",
"The number of versions must be a number and cannot be blank.": "Liczba wersji musi być liczbą i nie może być pusta.", "The number of versions must be a number and cannot be blank.": "Liczba wersji musi być liczbą i nie może być pusta.",
"The path cannot be blank.": "Ścieżka nie może być pusta.", "The path cannot be blank.": "Ścieżka nie może być pusta.",
"The rescan interval must be a non-negative number of seconds.": "Interwał skanowania musi być niezerową liczbą sekund.", "The rescan interval must be a non-negative number of seconds.": "Interwał skanowania musi być niezerową liczbą sekund.",
"This is a major version upgrade.": "This is a major version upgrade.", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Trash Can File Versioning",
"Unknown": "Nieznany", "Unknown": "Nieznany",
"Unshared": "Nieudostępnione", "Unshared": "Nieudostępnione",
"Unused": "Nieużywane", "Unused": "Nieużywane",
"Up to Date": "Aktualny", "Up to Date": "Aktualny",
"Updated": "Updated",
"Upgrade": "Aktualizacja", "Upgrade": "Aktualizacja",
"Upgrade To {%version%}": "Aktualizuj do {{version}}", "Upgrade To {%version%}": "Aktualizuj do {{version}}",
"Upgrading": "Aktualizowanie", "Upgrading": "Aktualizowanie",
+6 -17
View File
@@ -1,9 +1,7 @@
{ {
"A negative number of days doesn't make sense.": "Um número negativo de dias não faz sentido.",
"A new major version may not be compatible with previous versions.": "Uma nova versão principal pode não ser compatível com versões anteriores.", "A new major version may not be compatible with previous versions.": "Uma nova versão principal pode não ser compatível com versões anteriores.",
"API Key": "Chave da API", "API Key": "Chave da API",
"About": "Sobre", "About": "Sobre",
"Actions": "Ações",
"Add": "Adicionar", "Add": "Adicionar",
"Add Device": "Adicionar dispositivo", "Add Device": "Adicionar dispositivo",
"Add Folder": "Adicionar pasta", "Add Folder": "Adicionar pasta",
@@ -20,7 +18,6 @@
"Bugs": "Erros", "Bugs": "Erros",
"CPU Utilization": "Uso de CPU", "CPU Utilization": "Uso de CPU",
"Changelog": "Registro de alterações", "Changelog": "Registro de alterações",
"Clean out after": "Limpar depois de",
"Close": "Fechar", "Close": "Fechar",
"Command": "Comando", "Command": "Comando",
"Comment, when used at the start of a line": "Comentário, se usado no início de uma linha", "Comment, when used at the start of a line": "Comentário, se usado no início de uma linha",
@@ -30,7 +27,6 @@
"Copied from original": "Copiado do original", "Copied from original": "Copiado do original",
"Copyright © 2015 the following Contributors:": "Copyright © 2015. Direitos reservados aos seguintes colaboradores:", "Copyright © 2015 the following Contributors:": "Copyright © 2015. Direitos reservados aos seguintes colaboradores:",
"Delete": "Apagar", "Delete": "Apagar",
"Deleted": "Apagado",
"Device ID": "ID do dispositivo", "Device ID": "ID do dispositivo",
"Device Identification": "Identificação do dispositivo", "Device Identification": "Identificação do dispositivo",
"Device Name": "Nome do dispositivo", "Device Name": "Nome do dispositivo",
@@ -49,11 +45,10 @@
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Insira endereços \"ip:porta\" separados por vírgulas ou \"dynamic\" para descobrir automaticamente o endereço.\n", "Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Insira endereços \"ip:porta\" separados por vírgulas ou \"dynamic\" para descobrir automaticamente o endereço.\n",
"Enter ignore patterns, one per line.": "Insira os padrões de exclusão, um por linha.", "Enter ignore patterns, one per line.": "Insira os padrões de exclusão, um por linha.",
"Error": "Erro", "Error": "Erro",
"External File Versioning": "Versionamento externo de arquivo", "External File Versioning": "Versionamento Externo de Arquivo",
"File Pull Order": "Ordem de retirada do arquivo", "File Pull Order": "Ordem de retirada do arquivo",
"File Versioning": "Versionamento de arquivos", "File Versioning": "Versionamento de arquivos",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Os bits de permissão de um arquivo são ignorados durante as verificações. Use em sistemas de arquivo FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Os bits de permissão de um arquivo são ignorados durante as verificações. Use em sistemas de arquivo FAT.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Os arquivos são motivos para a pasta .stversions quando substituídos ou apagados pelo Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Os arquivos são renomeados com suas datas na pasta .stversions quando são substituídos ou removidos pelo Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Os arquivos são renomeados com suas datas na pasta .stversions quando são substituídos ou removidos pelo 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.": "Os arquivos estão protegidos contra alterações feitas em outros dispositivos, mas alterações feitas neste dispositivo serão enviadas ao resto do grupo.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Os arquivos estão protegidos contra alterações feitas em outros dispositivos, mas alterações feitas neste dispositivo serão enviadas ao resto do grupo.",
"Folder ID": "ID da pasta", "Folder ID": "ID da pasta",
@@ -67,7 +62,6 @@
"Global Discovery": "Descoberta global", "Global Discovery": "Descoberta global",
"Global Discovery Server": "Servidor de descoberta global", "Global Discovery Server": "Servidor de descoberta global",
"Global State": "Estado global", "Global State": "Estado global",
"Help": "Ajuda",
"Ignore": "Ignorar", "Ignore": "Ignorar",
"Ignore Patterns": "Padrões de exclusão", "Ignore Patterns": "Padrões de exclusão",
"Ignore Permissions": "Ignorar permissões", "Ignore Permissions": "Ignorar permissões",
@@ -81,7 +75,6 @@
"Later": "Depois", "Later": "Depois",
"Local Discovery": "Descoberta local", "Local Discovery": "Descoberta local",
"Local State": "Estado local", "Local State": "Estado local",
"Local State (Total)": "Estado local (total)",
"Major Upgrade": "Atualização \"major\"", "Major Upgrade": "Atualização \"major\"",
"Maximum Age": "Idade máxima", "Maximum Age": "Idade máxima",
"Metadata Only": "Somente metadados", "Metadata Only": "Somente metadados",
@@ -97,8 +90,8 @@
"OK": "OK", "OK": "OK",
"Off": "Desligada", "Off": "Desligada",
"Oldest First": "Mais antigo primeiro", "Oldest First": "Mais antigo primeiro",
"Out Of Sync": "Fora de sincronia", "Out Of Sync": "Não sincronizado",
"Out of Sync Items": "Itens fora de sincronia", "Out of Sync Items": "Itens não sincronizados",
"Outgoing Rate Limit (KiB/s)": "Limite de velocidade de envio (KiB/s)", "Outgoing Rate Limit (KiB/s)": "Limite de velocidade de envio (KiB/s)",
"Override Changes": "Sobrescrever mudanças", "Override Changes": "Sobrescrever mudanças",
"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": "Caminho para a pasta na máquina local. Será criado caso não exista. O caractere til (~) pode ser usado como um atalho para", "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": "Caminho para a pasta na máquina local. Será criado caso não exista. O caractere til (~) pode ser usado como um atalho para",
@@ -155,7 +148,7 @@
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "A configuração foi salva mas ainda não foi ativada. O Syncthing precisa ser reiniciado para a ativação da nova configuração.", "The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "A configuração foi salva mas ainda não foi ativada. O Syncthing precisa ser reiniciado para a ativação da nova configuração.",
"The device ID cannot be blank.": "O ID de dispositivo não pode ficar vazio.", "The device ID cannot be blank.": "O ID de dispositivo não pode ficar vazio.",
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "O ID do dispositivo a ser inserido aqui pode ser encontrado no menu \"Editar > Mostrar ID\" do outro dispositivo. Espaços e hífens são opcionais (ignorados).", "The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "O ID do dispositivo a ser inserido aqui pode ser encontrado no menu \"Editar > Mostrar ID\" do outro dispositivo. Espaços e hífens 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 criptografado de uso é enviado diariamente. É utilizado para rastrear plataformas, tamanhos de pastas e versões da aplicação. Caso o formato dos dados seja alterado, esta janela te avisará.", "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 criptografado de uso é 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, esta janela te notificará novamente.",
"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.": "O ID de dispositivo inserido não parece ser válido. Ele deve ter entre 52 e 56 caracteres e ser composto de letras e números, com espaços e hífens opcionais.", "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.": "O ID de dispositivo inserido não parece ser válido. Ele deve ter entre 52 e 56 caracteres e ser composto de letras e números, com espaços e hífens opcionais.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "O primeiro argumento da linha de comando é o caminho da pasta e o segundo é o caminho relativo à pasta.", "The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "O primeiro argumento da linha de comando é o caminho da pasta e o segundo é o caminho relativo à pasta.",
"The folder ID cannot be blank.": "O ID da pasta não pode ficar vazio.", "The folder ID cannot be blank.": "O ID da pasta não pode ficar vazio.",
@@ -163,21 +156,17 @@
"The folder ID must be unique.": "O ID da pasta deve ser único.", "The folder ID must be unique.": "O ID da pasta deve ser único.",
"The folder path cannot be blank.": "O caminho da pasta não pode ficar vazio.", "The folder path cannot be blank.": "O caminho da pasta não pode ficar vazio.",
"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.": "São utilizados os seguintes intervalos: na primeira hora é guardada uma versão a cada 30 segundos, no primeiro dia é guardada uma versão a cada hora, nos primeiros 30 dias é guardada uma versão por dia e, até que atinja a idade máxima, é guardada uma versão por semana.", "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.": "São utilizados os seguintes intervalos: na primeira hora é guardada uma versão a cada 30 segundos, no primeiro dia é guardada uma versão a cada hora, nos primeiros 30 dias é guardada uma versão por dia e, até que atinja a idade máxima, é guardada uma versão por semana.",
"The maximum age must be a number and cannot be blank.": "A idade máxima deve ser um valor numérico. O campo não pode ficar vazio.", "The maximum age must be a number and cannot be blank.": "A idade máxima deve ser um valor numérico e não pode ficar vazio.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "O número máximo de dias em que uma versão é guardada. (Use 0 para manter para sempre).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "O número máximo de dias em que uma versão é guardada. (Use 0 para manter para sempre).",
"The number of days must be a number and cannot be blank.": "O número de dias deve ser um número valido e não pode ficar em branco.",
"The number of days to keep files in the trash can. Zero means forever.": "O número de dias em que são mantidos os arquivos da lixeira. Zero significa para sempre.",
"The number of old versions to keep, per file.": "O número de versões antigas a serem mantidas, por arquivo.", "The number of old versions to keep, per file.": "O número de versões antigas a serem mantidas, por arquivo.",
"The number of versions must be a number and cannot be blank.": "O número de versões deve ser um valor numérico. O campo não pode ficar vazio.", "The number of versions must be a number and cannot be blank.": "O número de versões deve ser um valor numério e não pode ficar vazio.",
"The path cannot be blank.": "O caminho não pode ficar vazio.", "The path cannot be blank.": "O caminho não pode ficar vazio.",
"The rescan interval must be a non-negative number of seconds.": "O intervalo entre verificações deve ser um número positivo de segundos.", "The rescan interval must be a non-negative number of seconds.": "O intervalo entre verificações deve ser um número positivo de segundos.",
"This is a major version upgrade.": "Esta é uma atualização para uma versão \"major\".", "This is a major version upgrade.": "Esta é uma atualização para uma versão \"major\".",
"Trash Can File Versioning": "Versionamento de arquivos da lixeira",
"Unknown": "Desconhecida", "Unknown": "Desconhecida",
"Unshared": "Não compartilhada", "Unshared": "Não compartilhada",
"Unused": "Não utilizado", "Unused": "Não utilizado",
"Up to Date": "Sincronizada", "Up to Date": "Sincronizada",
"Updated": "Atualizado",
"Upgrade": "Atualização", "Upgrade": "Atualização",
"Upgrade To {%version%}": "Atualizar para {{version}}", "Upgrade To {%version%}": "Atualizar para {{version}}",
"Upgrading": "Atualizando", "Upgrading": "Atualizando",
+17 -28
View File
@@ -1,9 +1,7 @@
{ {
"A negative number of days doesn't make sense.": "Um número negativo de dias não faz sentido.",
"A new major version may not be compatible with previous versions.": "Uma nova versão principal pode não ser compatível com versões anteriores.", "A new major version may not be compatible with previous versions.": "Uma nova versão principal pode não ser compatível com versões anteriores.",
"API Key": "Chave da API", "API Key": "Chave da API",
"About": "Acerca da aplicação", "About": "Acerca da aplicação",
"Actions": "Acções",
"Add": "Adicionar", "Add": "Adicionar",
"Add Device": "Adicionar dispositivo", "Add Device": "Adicionar dispositivo",
"Add Folder": "Adicionar pasta", "Add Folder": "Adicionar pasta",
@@ -20,7 +18,6 @@
"Bugs": "Erros", "Bugs": "Erros",
"CPU Utilization": "Utilização da CPU", "CPU Utilization": "Utilização da CPU",
"Changelog": "Registo de alterações", "Changelog": "Registo de alterações",
"Clean out after": "Esvaziar ao fim de",
"Close": "Fechar", "Close": "Fechar",
"Command": "Comando", "Command": "Comando",
"Comment, when used at the start of a line": "Comentário, quando usado no início de uma linha", "Comment, when used at the start of a line": "Comentário, quando usado no início de uma linha",
@@ -30,7 +27,6 @@
"Copied from original": "Copiado do original", "Copied from original": "Copiado do original",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 os seguintes contribuidores:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 os seguintes contribuidores:",
"Delete": "Eliminar", "Delete": "Eliminar",
"Deleted": "Eliminado",
"Device ID": "ID do dispositivo", "Device ID": "ID do dispositivo",
"Device Identification": "Identificação do dispositivo", "Device Identification": "Identificação do dispositivo",
"Device Name": "Nome do dispositivo", "Device Name": "Nome do dispositivo",
@@ -49,11 +45,10 @@
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduza endereços \"ip:porto\" separados por vírgulas ou \"dynamic\" para descobrir automaticamente o endereço.", "Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduza endereços \"ip:porto\" separados por vírgulas ou \"dynamic\" para descobrir automaticamente o endereço.",
"Enter ignore patterns, one per line.": "Escreva os padrões de exclusão, um por linha.", "Enter ignore patterns, one per line.": "Escreva os padrões de exclusão, um por linha.",
"Error": "Erro", "Error": "Erro",
"External File Versioning": "Externa", "External File Versioning": "Controle de versões de ficheiros externo",
"File Pull Order": "Ordem de obtenção de ficheiros", "File Pull Order": "Ordem de obtenção de ficheiros",
"File Versioning": "Gestão de versões de ficheiros", "File Versioning": "Gestão de versões",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "As permissões do ficheiro são ignoradas ao procurar alterações. Utilize nos sistemas de ficheiros FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "As permissões do ficheiro são ignoradas ao procurar alterações. Utilize nos sistemas de ficheiros FAT.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Os ficheiros são movidos para a pasta .stversions quando substituídos ou eliminados pelo Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Os ficheiros são movidos para versões carimbadas com o tempo numa pasta .stversions, ao serem substituídos ou apagados pelo Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Os ficheiros são movidos para versões carimbadas com o tempo numa pasta .stversions, ao serem substituídos ou apagados pelo 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.": "Os ficheiros estão protegidos contra alterações feitas noutros dispositivos, mas alterações feitas neste dispositivo serão enviadas ao resto do grupo.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Os ficheiros estão protegidos contra alterações feitas noutros dispositivos, mas alterações feitas neste dispositivo serão enviadas ao resto do grupo.",
"Folder ID": "ID da pasta", "Folder ID": "ID da pasta",
@@ -67,7 +62,6 @@
"Global Discovery": "Busca global", "Global Discovery": "Busca global",
"Global Discovery Server": "Servidor da busca global", "Global Discovery Server": "Servidor da busca global",
"Global State": "Estado global", "Global State": "Estado global",
"Help": "Ajuda",
"Ignore": "Ignorar", "Ignore": "Ignorar",
"Ignore Patterns": "Padrões de exclusão", "Ignore Patterns": "Padrões de exclusão",
"Ignore Permissions": "Ignorar permissões", "Ignore Permissions": "Ignorar permissões",
@@ -75,14 +69,13 @@
"Introducer": "Apresentador", "Introducer": "Apresentador",
"Inversion of the given condition (i.e. do not exclude)": "Inversão de uma dada condição (ou seja, não excluir)", "Inversion of the given condition (i.e. do not exclude)": "Inversão de uma dada condição (ou seja, não excluir)",
"Keep Versions": "Manter versões", "Keep Versions": "Manter versões",
"Largest First": "Primeiro os maiores", "Largest First": "Maior primeiro",
"Last File Received": "Último ficheiro recebido", "Last File Received": "Último ficheiro recebido",
"Last seen": "Última vez que foi verificado", "Last seen": "Última vez que foi verificado",
"Later": "Mais tarde", "Later": "Mais tarde",
"Local Discovery": "Busca local", "Local Discovery": "Busca local",
"Local State": "Estado local", "Local State": "Estado local",
"Local State (Total)": "Estado local (total)", "Major Upgrade": "Actualização principal",
"Major Upgrade": "Actualização importante",
"Maximum Age": "Idade máxima", "Maximum Age": "Idade máxima",
"Metadata Only": "Metadados apenas", "Metadata Only": "Metadados apenas",
"Move to top of queue": "Mover para o topo da fila", "Move to top of queue": "Mover para o topo da fila",
@@ -90,26 +83,26 @@
"Never": "Nunca", "Never": "Nunca",
"New Device": "Novo dispositivo", "New Device": "Novo dispositivo",
"New Folder": "Nova pasta", "New Folder": "Nova pasta",
"Newest First": "Primeiro os mais recentes", "Newest First": "Mais recente primeiro",
"No": "Não", "No": "Não",
"No File Versioning": "Nenhuma", "No File Versioning": "Sem gestão de versões de ficheiros",
"Notice": "Avisos", "Notice": "Avisos",
"OK": "OK", "OK": "OK",
"Off": "Desligada", "Off": "Desligado",
"Oldest First": "Primeiro os mais antigos", "Oldest First": "Mais antigo primeiro",
"Out Of Sync": "Não sincronizado", "Out Of Sync": "Não sincronizado",
"Out of Sync Items": "Itens por sincronizar", "Out of Sync Items": "Itens por sincronizar",
"Outgoing Rate Limit (KiB/s)": "Limite da velocidade de envio (KiB/s)", "Outgoing Rate Limit (KiB/s)": "Limite da velocidade de envio (KiB/s)",
"Override Changes": "Sobrepor alterações", "Override Changes": "Sobrepor alterações",
"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": "Caminho para a pasta no computador local. Será criada, caso não exista. O caractere (~) pode ser utilizado como atalho para", "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": "Caminho para a pasta no computador local. Será criada, caso não exista. O caractere (~) pode ser utilizado como atalho para",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Caminho onde as versões são guardadas (deixe vazio para usar a pasta pré-definida .stversions dentro da pasta a que se refere).", "Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Caminho onde as versões são guardadas (deixe vazio para usar a pasta pré-definida .stversions na pasta).",
"Please consult the release notes before performing a major upgrade.": "Consulte as notas de lançamento antes de fazer uma actualização importante.", "Please consult the release notes before performing a major upgrade.": "Consulte as notas de lançamento antes de fazer uma actualização principal.",
"Please wait": "Aguarde", "Please wait": "Aguarde",
"Preview": "Previsão", "Preview": "Previsão",
"Preview Usage Report": "Pré-visualizar relatório de utilização", "Preview Usage Report": "Pré-visualizar relatório de utilização",
"Quick guide to supported patterns": "Guia rápido dos padrões suportados", "Quick guide to supported patterns": "Guia rápido dos padrões suportados",
"RAM Utilization": "Utilização da RAM", "RAM Utilization": "Utilização da RAM",
"Random": "Aleatória", "Random": "Aleatório",
"Release Notes": "Notas de lançamento", "Release Notes": "Notas de lançamento",
"Rescan": "Verificar agora", "Rescan": "Verificar agora",
"Rescan All": "Verificar todas agora", "Rescan All": "Verificar todas agora",
@@ -135,11 +128,11 @@
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Apresentado ao invés do ID do dispositivo no indicador de estado do grupo. Será actualizado para o nome que o dispositivo divulga, se for deixado em branco.", "Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Apresentado ao invés do ID do dispositivo no indicador de estado do grupo. Será actualizado para o nome que o dispositivo divulga, se for deixado em branco.",
"Shutdown": "Desligar", "Shutdown": "Desligar",
"Shutdown Complete": "Encerramento completado", "Shutdown Complete": "Encerramento completado",
"Simple File Versioning": "Simples", "Simple File Versioning": "Gestão de versões de ficheiros simples",
"Single level wildcard (matches within a directory only)": "Caractere polivalente de um só nível (faz corresponder apenas dentro de uma pasta)", "Single level wildcard (matches within a directory only)": "Caractere polivalente de um só nível (faz corresponder apenas dentro de uma pasta)",
"Smallest First": "Primeiro os menores", "Smallest First": "Menor primeiro",
"Source Code": "Código fonte", "Source Code": "Código fonte",
"Staggered File Versioning": "Escalonada", "Staggered File Versioning": "Gestão de versões de ficheiros escalonada",
"Start Browser": "Iniciar navegador", "Start Browser": "Iniciar navegador",
"Stopped": "Parado", "Stopped": "Parado",
"Support": "Suporte", "Support": "Suporte",
@@ -164,25 +157,21 @@
"The folder path cannot be blank.": "O caminho da pasta não pode estar vazio.", "The folder path cannot be blank.": "O caminho da pasta não pode estar vazio.",
"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.": "São utilizados os seguintes intervalos: na primeira hora é guardada uma versão a cada 30 segundos, no primeiro dia é guardada uma versão a cada hora, nos primeiros 30 dias é guardada uma versão por dia e, até que atinja a idade máxima, é guardada uma versão por semana.", "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.": "São utilizados os seguintes intervalos: na primeira hora é guardada uma versão a cada 30 segundos, no primeiro dia é guardada uma versão a cada hora, nos primeiros 30 dias é guardada uma versão por dia e, até que atinja a idade máxima, é guardada uma versão por semana.",
"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 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 maximum time to keep a version (in days, set to 0 to keep versions forever).": "Tempo máximo para manter uma versão (em dias, use 0 para manter a versão para sempre).",
"The number of days must be a number and cannot be blank.": "O número de dias tem que ser um número e não pode estar em branco.",
"The number of days to keep files in the trash can. Zero means forever.": "O número de dias a manter os ficheiros na reciclagem. Zero significa para sempre.",
"The number of old versions to keep, per file.": "O número de versões antigas a manter, por ficheiro.", "The number of old versions to keep, per file.": "O número de versões antigas a manter, por ficheiro.",
"The number of versions must be a number and cannot be blank.": "O número de versões tem que ser um número e não pode estar vazio.", "The number of versions must be a number and cannot be blank.": "O número de versões tem que ser um número e não pode estar vazio.",
"The path cannot be blank.": "O caminho não pode estar vazio.", "The path cannot be blank.": "O caminho não pode estar vazio.",
"The rescan interval must be a non-negative number of seconds.": "O intervalo entre verificações tem que ser um valor não negativo de segundos.", "The rescan interval must be a non-negative number of seconds.": "O intervalo entre verificações tem que ser um valor não negativo de segundos.",
"This is a major version upgrade.": "Esta é uma actualização para uma versão importante.", "This is a major version upgrade.": "Esta é uma actualização de uma versão principal.",
"Trash Can File Versioning": "Reciclagem",
"Unknown": "Desconhecido", "Unknown": "Desconhecido",
"Unshared": "Não partilhada", "Unshared": "Não partilhada",
"Unused": "Não utilizado", "Unused": "Não utilizado",
"Up to Date": "Sincronizado", "Up to Date": "Sincronizado",
"Updated": "Actualizado",
"Upgrade": "Actualizar", "Upgrade": "Actualizar",
"Upgrade To {%version%}": "Actualizar para {{version}}", "Upgrade To {%version%}": "Actualizar para {{version}}",
"Upgrading": "Actualizando", "Upgrading": "Actualizando",
"Upload Rate": "Velocidade de envio", "Upload Rate": "Velocidade de envio",
"Uptime": "Tempo em actividade", "Uptime": "Tempo de funcionamento contínuo",
"Use HTTPS for GUI": "Utilizar HTTPS na interface gráfica", "Use HTTPS for GUI": "Utilizar HTTPS na interface gráfica",
"Version": "Versão", "Version": "Versão",
"Versions Path": "Caminho das versões", "Versions Path": "Caminho das versões",
-11
View File
@@ -1,9 +1,7 @@
{ {
"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.": "A new major version may not be compatible with previous versions.", "A new major version may not be compatible with previous versions.": "A new major version may not be compatible with previous versions.",
"API Key": "Cheie API", "API Key": "Cheie API",
"About": "Despre", "About": "Despre",
"Actions": "Actions",
"Add": "Adaugă", "Add": "Adaugă",
"Add Device": "Adaugă Dispozitiv", "Add Device": "Adaugă Dispozitiv",
"Add Folder": "Adaugă Mapă", "Add Folder": "Adaugă Mapă",
@@ -20,7 +18,6 @@
"Bugs": "Bug-uri", "Bugs": "Bug-uri",
"CPU Utilization": "CPU ", "CPU Utilization": "CPU ",
"Changelog": "Noutăți", "Changelog": "Noutăți",
"Clean out after": "Clean out after",
"Close": "Închide", "Close": "Închide",
"Command": "Comandă", "Command": "Comandă",
"Comment, when used at the start of a line": "Comentariu, când este folosit la începutul unei linii", "Comment, when used at the start of a line": "Comentariu, când este folosit la începutul unei linii",
@@ -30,7 +27,6 @@
"Copied from original": "Copiat din original", "Copied from original": "Copiat din original",
"Copyright © 2015 the following Contributors:": "Copyright ©2015 Următorii Contribuitori:", "Copyright © 2015 the following Contributors:": "Copyright ©2015 Următorii Contribuitori:",
"Delete": "Şterge", "Delete": "Şterge",
"Deleted": "Deleted",
"Device ID": "ID Dispozitiv", "Device ID": "ID Dispozitiv",
"Device Identification": "Identificare Dispozitiv", "Device Identification": "Identificare Dispozitiv",
"Device Name": "Nume Dispozitiv", "Device Name": "Nume Dispozitiv",
@@ -53,7 +49,6 @@
"File Pull Order": "File Pull Order", "File Pull Order": "File Pull Order",
"File Versioning": "Versiune Fișier", "File Versioning": "Versiune Fișier",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Biții de autorizare sînt excluși cînd se analizează modificările. A se utiliza pe sisteme FAT. ", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Biții de autorizare sînt excluși cînd se analizează modificările. A se utiliza pe sisteme FAT. ",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Documentele sînt mutate într-un fișier .stversions conținînd versiuni datate atunci cînd sînt șterse sau înlocuite de Syncthing. ", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Documentele sînt mutate într-un fișier .stversions conținînd versiuni datate atunci cînd sînt șterse sau înlocuite de 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.": "Fișierele sunt protejate de schimbările făcute pe alte dispozitive dar schimbările efectuate pe acest dispozitiv vor fi trimise catre restul grupului.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Fișierele sunt protejate de schimbările făcute pe alte dispozitive dar schimbările efectuate pe acest dispozitiv vor fi trimise catre restul grupului.",
"Folder ID": "ID Mapă", "Folder ID": "ID Mapă",
@@ -67,7 +62,6 @@
"Global Discovery": "Găsire Globală", "Global Discovery": "Găsire Globală",
"Global Discovery Server": "Server pentru Găsirea Globală", "Global Discovery Server": "Server pentru Găsirea Globală",
"Global State": "Status Global", "Global State": "Status Global",
"Help": "Help",
"Ignore": "Ignoră", "Ignore": "Ignoră",
"Ignore Patterns": "Reguli de excludere", "Ignore Patterns": "Reguli de excludere",
"Ignore Permissions": "Ignoră Permisiuni", "Ignore Permissions": "Ignoră Permisiuni",
@@ -81,7 +75,6 @@
"Later": "Mai tîrziu", "Later": "Mai tîrziu",
"Local Discovery": "Găsire Locală", "Local Discovery": "Găsire Locală",
"Local State": "Status Local", "Local State": "Status Local",
"Local State (Total)": "Local State (Total)",
"Major Upgrade": "Major Upgrade", "Major Upgrade": "Major Upgrade",
"Maximum Age": "Vârsta Maximă", "Maximum Age": "Vârsta Maximă",
"Metadata Only": "Doar Metadate", "Metadata Only": "Doar Metadate",
@@ -165,19 +158,15 @@
"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.": "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.", "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.": "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.",
"The maximum age must be a number and cannot be blank.": "Vârsta maximă trebuie să fie un număr şi nu poate fi goală.", "The maximum age must be a number and cannot be blank.": "Vârsta maximă trebuie să fie un număr şi nu poate fi goală.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Câte zile să se păstreze o versiune (setează 0 pentru nelimitat)", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Câte zile să se păstreze o versiune (setează 0 pentru nelimitat)",
"The number of days must be a number and cannot be blank.": "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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "Numărul de versiuni vechi de salvat per fişier.", "The number of old versions to keep, per file.": "Numărul de versiuni vechi de salvat per fişier.",
"The number of versions must be a number and cannot be blank.": "Numărul de versiuni trebuie să fie un număr şi nu poate fi gol.", "The number of versions must be a number and cannot be blank.": "Numărul de versiuni trebuie să fie un număr şi nu poate fi gol.",
"The path cannot be blank.": "Locația nu poate fi goală.", "The path cannot be blank.": "Locația nu poate fi goală.",
"The rescan interval must be a non-negative number of seconds.": "Intervalul de rescanare trebuie să nu fie un număr negativ de secunde. ", "The rescan interval must be a non-negative number of seconds.": "Intervalul de rescanare trebuie să nu fie un număr negativ de secunde. ",
"This is a major version upgrade.": "This is a major version upgrade.", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Trash Can File Versioning",
"Unknown": "Necunoscut", "Unknown": "Necunoscut",
"Unshared": "Neîmpărțit", "Unshared": "Neîmpărțit",
"Unused": "Nefolosit", "Unused": "Nefolosit",
"Up to Date": "La Zi", "Up to Date": "La Zi",
"Updated": "Updated",
"Upgrade": "Upgrade", "Upgrade": "Upgrade",
"Upgrade To {%version%}": "Actualizează La Versiunea {{version}}", "Upgrade To {%version%}": "Actualizează La Versiunea {{version}}",
"Upgrading": "Se Actualizează", "Upgrading": "Se Actualizează",
-11
View File
@@ -1,9 +1,7 @@
{ {
"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", "API Key": "Ключ API",
"About": "О программе", "About": "О программе",
"Actions": "Действия",
"Add": "Добавить", "Add": "Добавить",
"Add Device": "Добавить устройство", "Add Device": "Добавить устройство",
"Add Folder": "Добавить папку", "Add Folder": "Добавить папку",
@@ -20,7 +18,6 @@
"Bugs": "Ошибки", "Bugs": "Ошибки",
"CPU Utilization": "Загрузка ЦПУ", "CPU Utilization": "Загрузка ЦПУ",
"Changelog": "Журнал изменений", "Changelog": "Журнал изменений",
"Clean out after": "Очистить после",
"Close": "Закрыть", "Close": "Закрыть",
"Command": "Команда", "Command": "Команда",
"Comment, when used at the start of a line": "Комментарий, если используется в начале строки", "Comment, when used at the start of a line": "Комментарий, если используется в начале строки",
@@ -30,7 +27,6 @@
"Copied from original": "Скопировано с оригинала", "Copied from original": "Скопировано с оригинала",
"Copyright © 2015 the following Contributors:": "Все права защищены ©, 2015 участники:", "Copyright © 2015 the following Contributors:": "Все права защищены ©, 2015 участники:",
"Delete": "Удалить", "Delete": "Удалить",
"Deleted": "Удалено",
"Device ID": "ID устройства", "Device ID": "ID устройства",
"Device Identification": "Идентификация устройства", "Device Identification": "Идентификация устройства",
"Device Name": "Имя устройства", "Device Name": "Имя устройства",
@@ -53,7 +49,6 @@
"File Pull Order": "Порядок получения файлов", "File Pull Order": "Порядок получения файлов",
"File Versioning": "Управление версиями", "File Versioning": "Управление версиями",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Права на файлы игнорируются при поиске изменений. Используется на файловой системе FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Права на файлы игнорируются при поиске изменений. Используется на файловой системе FAT.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Файлы перемещаются в .stversions после замены или удаления Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Файлы с временнОй меткой версии помещаются в папку .stversions при их замене или удалении Syncthing.", "Files are moved to date stamped versions in a .stversions folder 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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Файлы защищены от изменений сделанных на других устройствах, но изменения сделанные на этом устройстве будут отправлены всему кластеру.",
"Folder ID": "ID папки", "Folder ID": "ID папки",
@@ -67,7 +62,6 @@
"Global Discovery": "Глобальное обнаружение", "Global Discovery": "Глобальное обнаружение",
"Global Discovery Server": "Сервер глобального обнаружения", "Global Discovery Server": "Сервер глобального обнаружения",
"Global State": "Глобальное состояние", "Global State": "Глобальное состояние",
"Help": "Помощь",
"Ignore": "Игнорировать", "Ignore": "Игнорировать",
"Ignore Patterns": "Шаблоны игнорирования", "Ignore Patterns": "Шаблоны игнорирования",
"Ignore Permissions": "Игнорировать файловые права доступа", "Ignore Permissions": "Игнорировать файловые права доступа",
@@ -81,7 +75,6 @@
"Later": "Потом", "Later": "Потом",
"Local Discovery": "Локальное обнаружение", "Local Discovery": "Локальное обнаружение",
"Local State": "Локальное состояние", "Local State": "Локальное состояние",
"Local State (Total)": "Локально (всего)",
"Major Upgrade": "Обновление основной версии", "Major Upgrade": "Обновление основной версии",
"Maximum Age": "Максимальный срок", "Maximum Age": "Максимальный срок",
"Metadata Only": "Только метаданные", "Metadata Only": "Только метаданные",
@@ -165,19 +158,15 @@
"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 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 maximum age must be a number and cannot be blank.": "Максимальный срок должен быть числом и не может быть пустым.", "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 maximum time to keep a version (in days, set to 0 to keep versions forever).": "Максимальный срок хранения версии (в днях, 0 значит вечное хранение).",
"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 old versions to keep, per file.": "Количество хранимых версий файла.",
"The number of versions must be a number and cannot be blank.": "Количество версий должно быть числом и не может быть пустым.", "The number of versions must be a number and cannot be blank.": "Количество версий должно быть числом и не может быть пустым.",
"The path cannot be blank.": "Путь не может быть пустым.", "The path cannot be blank.": "Путь не может быть пустым.",
"The rescan interval must be a non-negative number of seconds.": "Интервал пересканирования должен быть неотрицательным количеством секунд.", "The rescan interval must be a non-negative number of seconds.": "Интервал пересканирования должен быть неотрицательным количеством секунд.",
"This is a major version upgrade.": "Это обновление основной версии продукта.", "This is a major version upgrade.": "Это обновление основной версии продукта.",
"Trash Can File Versioning": "Использовать Корзину для версий файлов",
"Unknown": "Неизвестно", "Unknown": "Неизвестно",
"Unshared": "Необщедоступно", "Unshared": "Необщедоступно",
"Unused": "Не используется", "Unused": "Не используется",
"Up to Date": "Обновлено", "Up to Date": "Обновлено",
"Updated": "Обновлено",
"Upgrade": "Обновить", "Upgrade": "Обновить",
"Upgrade To {%version%}": "Обновить до {{version}}", "Upgrade To {%version%}": "Обновить до {{version}}",
"Upgrading": "Обновление", "Upgrading": "Обновление",
-11
View File
@@ -1,9 +1,7 @@
{ {
"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.": "En ny huvudversion kan eventuellt vara inkompatibel med tidigare versioner.", "A new major version may not be compatible with previous versions.": "En ny huvudversion kan eventuellt vara inkompatibel med tidigare versioner.",
"API Key": "API-nyckel", "API Key": "API-nyckel",
"About": "Om", "About": "Om",
"Actions": "Funktioner",
"Add": "Lägg till", "Add": "Lägg till",
"Add Device": "Lägg till enhet", "Add Device": "Lägg till enhet",
"Add Folder": "Lägg till katalog", "Add Folder": "Lägg till katalog",
@@ -20,7 +18,6 @@
"Bugs": "Buggar", "Bugs": "Buggar",
"CPU Utilization": "CPU-användning", "CPU Utilization": "CPU-användning",
"Changelog": "Changelog", "Changelog": "Changelog",
"Clean out after": "Clean out after",
"Close": "Stäng", "Close": "Stäng",
"Command": "Kommando", "Command": "Kommando",
"Comment, when used at the start of a line": "Kommentar, vid början av en rad.", "Comment, when used at the start of a line": "Kommentar, vid början av en rad.",
@@ -30,7 +27,6 @@
"Copied from original": "Oförändrat", "Copied from original": "Oförändrat",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 följande medverkande:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 följande medverkande:",
"Delete": "Radera", "Delete": "Radera",
"Deleted": "Deleted",
"Device ID": "Enhets-ID", "Device ID": "Enhets-ID",
"Device Identification": "Enhetsidentifikation", "Device Identification": "Enhetsidentifikation",
"Device Name": "Enhetsnamn", "Device Name": "Enhetsnamn",
@@ -53,7 +49,6 @@
"File Pull Order": "Hämtningsprioritering av filer", "File Pull Order": "Hämtningsprioritering av filer",
"File Versioning": "Versionshantering", "File Versioning": "Versionshantering",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Filrättigheter ignoreras vid sökning efter förändringar. Används på FAT-filsystem.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Filrättigheter ignoreras vid sökning efter förändringar. Används på FAT-filsystem.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Filer flyttas till datummärkta versioner i en .stversions-mapp när de ersatts eller raderats av Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Filer flyttas till datummärkta versioner i en .stversions-mapp när de ersatts eller raderats av 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.": "Filer skyddas från ändringar gjorda på andra enheter, men ändringar som görs på den här noden skickas till de andra klustermedlemmarna.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Filer skyddas från ändringar gjorda på andra enheter, men ändringar som görs på den här noden skickas till de andra klustermedlemmarna.",
"Folder ID": "Katalog-ID", "Folder ID": "Katalog-ID",
@@ -67,7 +62,6 @@
"Global Discovery": "Global uppslagning", "Global Discovery": "Global uppslagning",
"Global Discovery Server": "Global uppslagningsserver", "Global Discovery Server": "Global uppslagningsserver",
"Global State": "Global status", "Global State": "Global status",
"Help": "Hjälp",
"Ignore": "Ignorera", "Ignore": "Ignorera",
"Ignore Patterns": "Ignorerade filmönster", "Ignore Patterns": "Ignorerade filmönster",
"Ignore Permissions": "Ignorera filrättigheter", "Ignore Permissions": "Ignorera filrättigheter",
@@ -81,7 +75,6 @@
"Later": "Senare", "Later": "Senare",
"Local Discovery": "Lokal uppslagning", "Local Discovery": "Lokal uppslagning",
"Local State": "Lokal status", "Local State": "Lokal status",
"Local State (Total)": "Local State (Total)",
"Major Upgrade": "Stor uppgradering", "Major Upgrade": "Stor uppgradering",
"Maximum Age": "Högsta åldersgräns", "Maximum Age": "Högsta åldersgräns",
"Metadata Only": "Endast metadata", "Metadata Only": "Endast metadata",
@@ -165,19 +158,15 @@
"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.": "De följande intervallen används: varje 30 sekunder under den första timmen; varje timme under den första dagen; varje dag för de första 30 dagarna; varje vecka tills den maximala åldersgränsen uppnås.", "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.": "De följande intervallen används: varje 30 sekunder under den första timmen; varje timme under den första dagen; varje dag för de första 30 dagarna; varje vecka tills den maximala åldersgränsen uppnås.",
"The maximum age must be a number and cannot be blank.": "Åldersgränsen måste vara ett tal och kan inte lämnas tomt.", "The maximum age must be a number and cannot be blank.": "Åldersgränsen måste vara ett tal och kan inte lämnas tomt.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Den längsta tiden att behålla en version (i dagar, sätt till 0 för att behålla versioner för evigt).", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Den längsta tiden att behålla en version (i dagar, sätt till 0 för att behålla versioner för evigt).",
"The number of days must be a number and cannot be blank.": "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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "Antalet gamla versioner som ska behållas, per fil.", "The number of old versions to keep, per file.": "Antalet gamla versioner som ska behållas, per fil.",
"The number of versions must be a number and cannot be blank.": "Antalet versioner måste vara ett nummer och kan inte lämnas tomt.", "The number of versions must be a number and cannot be blank.": "Antalet versioner måste vara ett nummer och kan inte lämnas tomt.",
"The path cannot be blank.": "Ange en sökväg", "The path cannot be blank.": "Ange en sökväg",
"The rescan interval must be a non-negative number of seconds.": "Förnyelseintervallet måste vara ett positivt antal sekunder", "The rescan interval must be a non-negative number of seconds.": "Förnyelseintervallet måste vara ett positivt antal sekunder",
"This is a major version upgrade.": "Det här är en stor uppgradering.", "This is a major version upgrade.": "Det här är en stor uppgradering.",
"Trash Can File Versioning": "Trash Can File Versioning",
"Unknown": "Okänt", "Unknown": "Okänt",
"Unshared": "Inte delad", "Unshared": "Inte delad",
"Unused": "Oanvänd", "Unused": "Oanvänd",
"Up to Date": "Helt uppdaterad", "Up to Date": "Helt uppdaterad",
"Updated": "Updated",
"Upgrade": "Uppgradering", "Upgrade": "Uppgradering",
"Upgrade To {%version%}": "Uppgradera till {{version}}", "Upgrade To {%version%}": "Uppgradera till {{version}}",
"Upgrading": "Uppgraderar", "Upgrading": "Uppgraderar",
-11
View File
@@ -1,9 +1,7 @@
{ {
"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.": "A new major version may not be compatible with previous versions.", "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 Anahtarı", "API Key": "API Anahtarı",
"About": "Hakkında", "About": "Hakkında",
"Actions": "Actions",
"Add": "Ekle", "Add": "Ekle",
"Add Device": "Cihaz Ekle", "Add Device": "Cihaz Ekle",
"Add Folder": "Klasör Ekle", "Add Folder": "Klasör Ekle",
@@ -20,7 +18,6 @@
"Bugs": "Hatalar", "Bugs": "Hatalar",
"CPU Utilization": "İşlemci Kullanımı", "CPU Utilization": "İşlemci Kullanımı",
"Changelog": "Değişim Günlüğü", "Changelog": "Değişim Günlüğü",
"Clean out after": "Clean out after",
"Close": "Kapat", "Close": "Kapat",
"Command": "Command", "Command": "Command",
"Comment, when used at the start of a line": "Satır başında kullanıldığında açıklama özelliği taşır", "Comment, when used at the start of a line": "Satır başında kullanıldığında açıklama özelliği taşır",
@@ -30,7 +27,6 @@
"Copied from original": "Aslından kopyalanmış", "Copied from original": "Aslından kopyalanmış",
"Copyright © 2015 the following Contributors:": "Telif Hakkı © 2015 Katkıda bulunanlar:", "Copyright © 2015 the following Contributors:": "Telif Hakkı © 2015 Katkıda bulunanlar:",
"Delete": "Sil", "Delete": "Sil",
"Deleted": "Deleted",
"Device ID": "Cihaz ID", "Device ID": "Cihaz ID",
"Device Identification": "Cihaz Kimliği", "Device Identification": "Cihaz Kimliği",
"Device Name": "Cihaz Adı", "Device Name": "Cihaz Adı",
@@ -53,7 +49,6 @@
"File Pull Order": "File Pull Order", "File Pull Order": "File Pull Order",
"File Versioning": "Dosya Sürümlendirme", "File Versioning": "Dosya Sürümlendirme",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Değişimleri yoklarken dosya izin bilgilerini ihmal et. FAT dosya sistemlerinde kullanın.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Değişimleri yoklarken dosya izin bilgilerini ihmal et. FAT dosya sistemlerinde kullanın.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Dosyalar Syncthing tarafından değiştirildiğinde ya da silindiğinde, tarih damgalı sürümleri .stversions dizinine taşınır.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Dosyalar Syncthing tarafından değiştirildiğinde ya da silindiğinde, tarih damgalı sürümleri .stversions dizinine taşınır.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Dosyalar diğer cihazlarda yapılan değişikliklerden korunur, ancak bu cihazdaki değişiklikler kümedeki diğer cihazlara gönderilir.", "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Dosyalar diğer cihazlarda yapılan değişikliklerden korunur, ancak bu cihazdaki değişiklikler kümedeki diğer cihazlara gönderilir.",
"Folder ID": "Klasör ID", "Folder ID": "Klasör ID",
@@ -67,7 +62,6 @@
"Global Discovery": "Küresel Keşif", "Global Discovery": "Küresel Keşif",
"Global Discovery Server": "Küresel Keşif Sunucusu", "Global Discovery Server": "Küresel Keşif Sunucusu",
"Global State": "Küresel Durum", "Global State": "Küresel Durum",
"Help": "Help",
"Ignore": "Yoksay", "Ignore": "Yoksay",
"Ignore Patterns": "Kalıpları Yoksay", "Ignore Patterns": "Kalıpları Yoksay",
"Ignore Permissions": "İzinleri yoksay", "Ignore Permissions": "İzinleri yoksay",
@@ -81,7 +75,6 @@
"Later": "Sonra", "Later": "Sonra",
"Local Discovery": "Yerel bulma", "Local Discovery": "Yerel bulma",
"Local State": "Yerel Durum", "Local State": "Yerel Durum",
"Local State (Total)": "Local State (Total)",
"Major Upgrade": "Major Upgrade", "Major Upgrade": "Major Upgrade",
"Maximum Age": "Azami Süre", "Maximum Age": "Azami Süre",
"Metadata Only": "Metadata Only", "Metadata Only": "Metadata Only",
@@ -165,19 +158,15 @@
"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.": "Kullanılan zaman aralıkları : ilk bir saat içinde her 30 saniyede, ilk günde her saatte, ilk 30 günde her gün, azami süreye kadar geçen zamanda ise her hafta yeni sürüm değeri oluşturulur.", "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.": "Kullanılan zaman aralıkları : ilk bir saat içinde her 30 saniyede, ilk günde her saatte, ilk 30 günde her gün, azami süreye kadar geçen zamanda ise her hafta yeni sürüm değeri oluşturulur.",
"The maximum age must be a number and cannot be blank.": "Azami süre tanımı boş bırakılmamalı ve bir sayı olarak tanımlanmalıdır.", "The maximum age must be a number and cannot be blank.": "Azami süre tanımı boş bırakılmamalı ve bir sayı olarak tanımlanmalıdır.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Bir sürümün tutulması için belirlenen azami süre (sürümleri daimi olarak tutabilmek için 0 değeri atayın)", "The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Bir sürümün tutulması için belirlenen azami süre (sürümleri daimi olarak tutabilmek için 0 değeri atayın)",
"The number of days must be a number and cannot be blank.": "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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "Dosya başına saklanacak eski sürüm.", "The number of old versions to keep, per file.": "Dosya başına saklanacak eski sürüm.",
"The number of versions must be a number and cannot be blank.": "Sürümlerin sayısı sayı olmalı ve boş bırakılamaz.", "The number of versions must be a number and cannot be blank.": "Sürümlerin sayısı sayı olmalı ve boş bırakılamaz.",
"The path cannot be blank.": "Dizin yolu boş bırakılamaz.", "The path cannot be blank.": "Dizin yolu boş bırakılamaz.",
"The rescan interval must be a non-negative number of seconds.": "Tarama zaman aralığı, saniye cinsinden negatif olmayan bir sayı olmalıdır.", "The rescan interval must be a non-negative number of seconds.": "Tarama zaman aralığı, saniye cinsinden negatif olmayan bir sayı olmalıdır.",
"This is a major version upgrade.": "This is a major version upgrade.", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Trash Can File Versioning",
"Unknown": "Bilinmiyor", "Unknown": "Bilinmiyor",
"Unshared": "Paylaşılmayan", "Unshared": "Paylaşılmayan",
"Unused": "Kullanılmayan", "Unused": "Kullanılmayan",
"Up to Date": "Güncel", "Up to Date": "Güncel",
"Updated": "Updated",
"Upgrade": "Upgrade", "Upgrade": "Upgrade",
"Upgrade To {%version%}": "{{version}} sürümüne yükselt", "Upgrade To {%version%}": "{{version}} sürümüne yükselt",
"Upgrading": "Yükseltiliyor", "Upgrading": "Yükseltiliyor",
+14 -25
View File
@@ -1,9 +1,7 @@
{ {
"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.": "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 ключ", "API Key": "API ключ",
"About": "Про програму", "About": "Про програму",
"Actions": "Дії",
"Add": "Додати", "Add": "Додати",
"Add Device": "Додати пристрій", "Add Device": "Додати пристрій",
"Add Folder": "Додати директорію", "Add Folder": "Додати директорію",
@@ -12,7 +10,7 @@
"Addresses": "Адреси", "Addresses": "Адреси",
"All Data": "Усі дані", "All Data": "Усі дані",
"Allow Anonymous Usage Reporting?": "Дозволити програмі збирати анонімну статистику використання?", "Allow Anonymous Usage Reporting?": "Дозволити програмі збирати анонімну статистику використання?",
"Alphabetic": "За алфавітом", "Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Зовнішня команда керування версіями. Вона має видалити файл із директорії, що синхронізується.", "An external command handles the versioning. It has to remove the file from the synced folder.": "Зовнішня команда керування версіями. Вона має видалити файл із директорії, що синхронізується.",
"Anonymous Usage Reporting": "Анонімна статистика використання", "Anonymous Usage Reporting": "Анонімна статистика використання",
"Any devices configured on an introducer device will be added to this device as well.": "Усі пристрої, налаштовані на пристрої-рекомендувачі, будуть додані до поточного пристрою.", "Any devices configured on an introducer device will be added to this device as well.": "Усі пристрої, налаштовані на пристрої-рекомендувачі, будуть додані до поточного пристрою.",
@@ -20,7 +18,6 @@
"Bugs": "Помилки", "Bugs": "Помилки",
"CPU Utilization": "Навантаження CPU", "CPU Utilization": "Навантаження CPU",
"Changelog": "Перелік змін", "Changelog": "Перелік змін",
"Clean out after": "Clean out after",
"Close": "Закрити", "Close": "Закрити",
"Command": "Команда", "Command": "Команда",
"Comment, when used at the start of a line": "Коментар, якщо використовується на початку рядка", "Comment, when used at the start of a line": "Коментар, якщо використовується на початку рядка",
@@ -30,7 +27,6 @@
"Copied from original": "Скопійовано з оригіналу", "Copied from original": "Скопійовано з оригіналу",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 наступних контриб’юторів:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 наступних контриб’юторів:",
"Delete": "Видалити", "Delete": "Видалити",
"Deleted": "Deleted",
"Device ID": "ID пристрою", "Device ID": "ID пристрою",
"Device Identification": "Ідентифікатор пристрою", "Device Identification": "Ідентифікатор пристрою",
"Device Name": "Назва пристрою", "Device Name": "Назва пристрою",
@@ -50,10 +46,9 @@
"Enter ignore patterns, one per line.": "Введіть шаблони ігнорування, по одному на рядок.", "Enter ignore patterns, one per line.": "Введіть шаблони ігнорування, по одному на рядок.",
"Error": "Помилка", "Error": "Помилка",
"External File Versioning": "Зовнішне керування версіями", "External File Versioning": "Зовнішне керування версіями",
"File Pull Order": "Порядок витягнення файлів", "File Pull Order": "File Pull Order",
"File Versioning": "Керування версіями", "File Versioning": "Керування версіями",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Біти прав доступу до файлів будуть проігноровані під час пошуку змін. Використовуйте на файлових системах FAT.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "Біти прав доступу до файлів будуть проігноровані під час пошуку змін. Використовуйте на файлових системах FAT.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Файли будуть поміщатися у директорію .stversions із відповідною позначкою часу, коли вони будуть замінятися або видалятися програмою.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by 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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Файли захищено від змін зроблених на інших пристроях, але зміни зроблені на цьому пристрої будуть надіслані решті кластеру.",
"Folder ID": "ID директорії", "Folder ID": "ID директорії",
@@ -67,7 +62,6 @@
"Global Discovery": "Глобальне виявлення", "Global Discovery": "Глобальне виявлення",
"Global Discovery Server": "Сервер для глобального виявлення", "Global Discovery Server": "Сервер для глобального виявлення",
"Global State": "Глобальний статус", "Global State": "Глобальний статус",
"Help": "Допомога",
"Ignore": "Ігнорувати", "Ignore": "Ігнорувати",
"Ignore Patterns": "Ігнорувати шаблони", "Ignore Patterns": "Ігнорувати шаблони",
"Ignore Permissions": "Ігнорувати права доступу до файлів", "Ignore Permissions": "Ігнорувати права доступу до файлів",
@@ -75,14 +69,13 @@
"Introducer": "Рекомендувач", "Introducer": "Рекомендувач",
"Inversion of the given condition (i.e. do not exclude)": "Інверсія поточної умови (тобто не виключає)", "Inversion of the given condition (i.e. do not exclude)": "Інверсія поточної умови (тобто не виключає)",
"Keep Versions": "Зберігати версії", "Keep Versions": "Зберігати версії",
"Largest First": "Спершу найбільші", "Largest First": "Largest First",
"Last File Received": "Останній завантажений файл", "Last File Received": "Останній завантажений файл",
"Last seen": "З’являвся останній раз", "Last seen": "З’являвся останній раз",
"Later": "Пізніше", "Later": "Пізніше",
"Local Discovery": "Локальне виявлення", "Local Discovery": "Локальне виявлення",
"Local State": "Локальний статус", "Local State": "Локальний статус",
"Local State (Total)": "Local State (Total)", "Major Upgrade": "Major Upgrade",
"Major Upgrade": "Мажорне оновлення",
"Maximum Age": "Максимальний вік", "Maximum Age": "Максимальний вік",
"Metadata Only": "Тільки метадані", "Metadata Only": "Тільки метадані",
"Move to top of queue": "Пересунути у початок черги", "Move to top of queue": "Пересунути у початок черги",
@@ -90,27 +83,27 @@
"Never": "Ніколи", "Never": "Ніколи",
"New Device": "Новий пристрій", "New Device": "Новий пристрій",
"New Folder": "Нова директорія", "New Folder": "Нова директорія",
"Newest First": "Спершу новіші", "Newest First": "Newest First",
"No": "Ні", "No": "Ні",
"No File Versioning": "Версіонування вимкнено", "No File Versioning": "Версіонування вимкнено",
"Notice": "Повідомлення", "Notice": "Повідомлення",
"OK": "Гаразд", "OK": "Гаразд",
"Off": "Вимкнути", "Off": "Вимкнути",
"Oldest First": "Спершу старіші", "Oldest First": "Oldest First",
"Out Of Sync": "Не синхронізовано", "Out Of Sync": "Не синхронізовано",
"Out of Sync Items": "Не синхронізовані елементи", "Out of Sync Items": "Не синхронізовані елементи",
"Outgoing Rate Limit (KiB/s)": "Ліміт швидкості віддачі (КіБ/с)", "Outgoing Rate Limit (KiB/s)": "Ліміт швидкості віддачі (КіБ/с)",
"Override Changes": "Перезаписати зміни", "Override Changes": "Перезаписати зміни",
"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 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 folder in the folder).": "Шлях, де повинні зберігатися версії (залиште порожнім для зберігання в .stversions в середині директорії)", "Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Шлях, де повинні зберігатися версії (залиште порожнім для зберігання в .stversions в середині директорії)",
"Please consult the release notes before performing a major upgrade.": "Будь ласка перегляньте примітки до випуску перед мажорним оновленням. ", "Please consult the release notes before performing a major upgrade.": "Please consult the release notes before performing a major upgrade.",
"Please wait": "Будь ласка, зачекайте", "Please wait": "Будь ласка, зачекайте",
"Preview": "Попередній перегляд", "Preview": "Попередній перегляд",
"Preview Usage Report": "Попередній перегляд статистичного звіту", "Preview Usage Report": "Попередній перегляд статистичного звіту",
"Quick guide to supported patterns": "Швидкий посібник по шаблонам, що підтримуються", "Quick guide to supported patterns": "Швидкий посібник по шаблонам, що підтримуються",
"RAM Utilization": "Використання RAM", "RAM Utilization": "Використання RAM",
"Random": "Випадково", "Random": "Random",
"Release Notes": "Примітки до випуску", "Release Notes": "Release Notes",
"Rescan": "Пересканувати", "Rescan": "Пересканувати",
"Rescan All": "Пересканувати усе", "Rescan All": "Пересканувати усе",
"Rescan Interval": "Інтервал для повторного сканування", "Rescan Interval": "Інтервал для повторного сканування",
@@ -137,7 +130,7 @@
"Shutdown Complete": "Вимикання завершене", "Shutdown Complete": "Вимикання завершене",
"Simple File Versioning": "Просте версіонування", "Simple File Versioning": "Просте версіонування",
"Single level wildcard (matches within a directory only)": "Однорівнева маска (пошук збігів лише в середині директорії) ", "Single level wildcard (matches within a directory only)": "Однорівнева маска (пошук збігів лише в середині директорії) ",
"Smallest First": "Спершу найменші", "Smallest First": "Smallest First",
"Source Code": "Сирцевий код", "Source Code": "Сирцевий код",
"Staggered File Versioning": "Поступове версіонування", "Staggered File Versioning": "Поступове версіонування",
"Start Browser": "Запустити браузер", "Start Browser": "Запустити браузер",
@@ -165,24 +158,20 @@
"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 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 maximum age must be a number and cannot be blank.": "Максимальний термін повинен бути числом та не може бути пустим.", "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 maximum time to keep a version (in days, set to 0 to keep versions forever).": "Максимальний термін, щоб зберігати версію (у днях, вствновіть в 0, щоби зберігати версії назавжди).",
"The number of days must be a number and cannot be blank.": "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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "Кількість старих версій, яку необхідно зберігати для кожного файлу.", "The number of old versions to keep, per file.": "Кількість старих версій, яку необхідно зберігати для кожного файлу.",
"The number of versions must be a number and cannot be blank.": "Кількість версій повинна бути цифрою та не може бути порожньою.", "The number of versions must be a number and cannot be blank.": "Кількість версій повинна бути цифрою та не може бути порожньою.",
"The path cannot be blank.": "Шлях не може бути порожнім.", "The path cannot be blank.": "Шлях не може бути порожнім.",
"The rescan interval must be a non-negative number of seconds.": "Інтервал повторного сканування повинен бути неід’ємною величиною.", "The rescan interval must be a non-negative number of seconds.": "Інтервал повторного сканування повинен бути неід’ємною величиною.",
"This is a major version upgrade.": "Це оновлення мажорної версії", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Trash Can File Versioning",
"Unknown": "Невідомо", "Unknown": "Невідомо",
"Unshared": "Не розповсюджується", "Unshared": "Не розповсюджується",
"Unused": "Не використовується", "Unused": "Не використовується",
"Up to Date": "Актуальна версія", "Up to Date": "Актуальна версія",
"Updated": "Updated", "Upgrade": "Upgrade",
"Upgrade": "Оновлення",
"Upgrade To {%version%}": "Оновити до {{version}}", "Upgrade To {%version%}": "Оновити до {{version}}",
"Upgrading": "Оновлення", "Upgrading": "Оновлення",
"Upload Rate": "Швидкість віддачі", "Upload Rate": "Швидкість віддачі",
"Uptime": "Тривалість роботи", "Uptime": "Uptime",
"Use HTTPS for GUI": "Використовувати HTTPS для доступу до панелі управління", "Use HTTPS for GUI": "Використовувати HTTPS для доступу до панелі управління",
"Version": "Версія", "Version": "Версія",
"Versions Path": "Шлях до версій", "Versions Path": "Шлях до версій",
+36 -47
View File
@@ -1,9 +1,7 @@
{ {
"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.",
"A new major version may not be compatible with previous versions.": "重大更新可能与之前的版本之间无法兼容",
"API Key": "API Key", "API Key": "API Key",
"About": "关于", "About": "关于",
"Actions": "动作",
"Add": "添加", "Add": "添加",
"Add Device": "添加设备", "Add Device": "添加设备",
"Add Folder": "添加文件夹", "Add Folder": "添加文件夹",
@@ -12,25 +10,23 @@
"Addresses": "地址列表", "Addresses": "地址列表",
"All Data": "所有数据", "All Data": "所有数据",
"Allow Anonymous Usage Reporting?": "允许匿名使用报告?", "Allow Anonymous Usage Reporting?": "允许匿名使用报告?",
"Alphabetic": "字母顺序", "Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the synced folder.": "使用外部命令接管版本控制。当文件在其他设备被删除时,本机的 Syncthing 会调用该外部命令,并将文件路径以参数形式传递给该命令。该命令必须自行从同步文件夹中删除该文件。", "An external command handles the versioning. It has to remove the file from the synced folder.": "An external command handles the versioning. It has to remove the file from the synced folder.",
"Anonymous Usage Reporting": "匿名使用报告", "Anonymous Usage Reporting": "匿名使用报告",
"Any devices configured on an introducer device will be added to this device as well.": "在介绍人设备上被添加的其它设备,也将会被添加到本机。", "Any devices configured on an introducer device will be added to this device as well.": "在介绍人设备上被添加的其它设备,也将会被添加到本机。",
"Automatic upgrades": "自动升级", "Automatic upgrades": "自动升级",
"Bugs": "Bug汇报", "Bugs": "Bug汇报",
"CPU Utilization": "CPU使用率", "CPU Utilization": "CPU使用率",
"Changelog": "更新日志", "Changelog": "更新日志",
"Clean out after": "在该时间后清除:",
"Close": "关闭", "Close": "关闭",
"Command": "命令", "Command": "命令",
"Comment, when used at the start of a line": "注释,在行首使用", "Comment, when used at the start of a line": "注释,在行首使用",
"Compression": "压缩", "Compression": "压缩",
"Connection Error": "连接出错", "Connection Error": "连接出错",
"Copied from elsewhere": "从其他设备复制", "Copied from elsewhere": "从其他地点复制",
"Copied from original": "从源复制", "Copied from original": "从源复制",
"Copyright © 2015 the following Contributors:": "版权 ©2015 由下列贡献者所有:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
"Delete": "删除", "Delete": "删除",
"Deleted": "已删除",
"Device ID": "设备标识", "Device ID": "设备标识",
"Device Identification": "设备标识", "Device Identification": "设备标识",
"Device Name": "设备名", "Device Name": "设备名",
@@ -50,11 +46,10 @@
"Enter ignore patterns, one per line.": "请输入忽略表达式,每行一条", "Enter ignore patterns, one per line.": "请输入忽略表达式,每行一条",
"Error": "错误", "Error": "错误",
"External File Versioning": "外部版本控制", "External File Versioning": "外部版本控制",
"File Pull Order": "文件拉取顺序", "File Pull Order": "File Pull Order",
"File Versioning": "版本控制", "File Versioning": "版本控制",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "当寻找文件变更时,忽略文件权限。用于FAT文件系统。", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "当文件被 Syncthing 替换或删时,将会被移动到 .stversions 文件夹", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by 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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "在其它设备中对该文件夹内文件的修改并不会被同步到本机,但是在本机上对其的修改,则会被同步到其它设备中。",
"Folder ID": "文件夹标识", "Folder ID": "文件夹标识",
"Folder Master": "主文件夹", "Folder Master": "主文件夹",
@@ -64,25 +59,23 @@
"GUI Authentication User": "登陆web管理页面的用户名", "GUI Authentication User": "登陆web管理页面的用户名",
"GUI Listen Addresses": "web管理页面监听地址", "GUI Listen Addresses": "web管理页面监听地址",
"Generate": "生成", "Generate": "生成",
"Global Discovery": "在互联网上寻找设备\n", "Global Discovery": "在互联网上寻找节点",
"Global Discovery Server": "用以在互联网上寻找设备的Announce服务器地址", "Global Discovery Server": "用以在互联网上寻找节点的Announce服务器地址",
"Global State": "全局状态", "Global State": "全局状态",
"Help": "帮助",
"Ignore": "忽略", "Ignore": "忽略",
"Ignore Patterns": "忽略列表", "Ignore Patterns": "忽略列表",
"Ignore Permissions": "忽略文件权限", "Ignore Permissions": "忽略文件权限",
"Incoming Rate Limit (KiB/s)": "下载速率限制(KiB/s", "Incoming Rate Limit (KiB/s)": "下载速率限制(KiB/s",
"Introducer": "介绍人设备", "Introducer": "介绍人节点",
"Inversion of the given condition (i.e. do not exclude)": "对本条件取反(例如:不要排除某项)", "Inversion of the given condition (i.e. do not exclude)": "对本条件取反(例如:不要排除某项)",
"Keep Versions": "保留历史版本数量", "Keep Versions": "保留历史版本数量",
"Largest First": "大文件优先", "Largest First": "Largest First",
"Last File Received": "最后接收的文件", "Last File Received": "最后接收的文件",
"Last seen": "最后可见", "Last seen": "最后可见",
"Later": "稍后", "Later": "稍后",
"Local Discovery": "在局域网上寻找设备", "Local Discovery": "在局域网上寻找节点",
"Local State": "本地状态", "Local State": "本地状态",
"Local State (Total)": "本地状态汇总", "Major Upgrade": "Major Upgrade",
"Major Upgrade": "重大更新",
"Maximum Age": "历史版本最长保留时间", "Maximum Age": "历史版本最长保留时间",
"Metadata Only": "仅元数据", "Metadata Only": "仅元数据",
"Move to top of queue": "移动到队列顶端", "Move to top of queue": "移动到队列顶端",
@@ -90,32 +83,32 @@
"Never": "从未", "Never": "从未",
"New Device": "新设备", "New Device": "新设备",
"New Folder": "新文件夹", "New Folder": "新文件夹",
"Newest First": "新文件优先", "Newest First": "Newest First",
"No": "否", "No": "否",
"No File Versioning": "不启用版本控制", "No File Versioning": "不启用版本控制",
"Notice": "提示", "Notice": "提示",
"OK": "确定", "OK": "确定",
"Off": "关闭", "Off": "关闭",
"Oldest First": "旧文件优先", "Oldest First": "Oldest First",
"Out Of Sync": "未同步", "Out Of Sync": "未同步",
"Out of Sync Items": "未同步的项目", "Out of Sync Items": "未同步的项目",
"Outgoing Rate Limit (KiB/s)": "上传速度限制(千字节/秒)", "Outgoing Rate Limit (KiB/s)": "上传速度限制(千字节/秒)",
"Override Changes": "撤销改变", "Override Changes": "撤销改变",
"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 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 folder in the folder).": "用来存储历史版本的文件夹(留空则将默认会存储在.stversions文件夹中)", "Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "用来存储历史版本的文件夹(留空则将默认会存储在.stversions文件夹中)",
"Please consult the release notes before performing a major upgrade.": "请在进行重大更新前查看发布说明。", "Please consult the release notes before performing a major upgrade.": "Please consult the release notes before performing a major upgrade.",
"Please wait": "请稍候", "Please wait": "请稍候",
"Preview": "预览", "Preview": "预览",
"Preview Usage Report": "预览使用报告", "Preview Usage Report": "预览使用报告",
"Quick guide to supported patterns": "支持的通配符的简单教程:", "Quick guide to supported patterns": "支持的通配符的简单教程:",
"RAM Utilization": "内存使用量", "RAM Utilization": "内存使用量",
"Random": "随机顺序", "Random": "Random",
"Release Notes": "发布说明", "Release Notes": "Release Notes",
"Rescan": "重新扫描", "Rescan": "重新扫描",
"Rescan All": "全部重新扫描", "Rescan All": "全部重新扫描",
"Rescan Interval": "扫描间隔", "Rescan Interval": "扫描间隔",
"Restart": "重启 Syncthing", "Restart": "重启syncthing",
"Restart Needed": "需要重启 Syncthing", "Restart Needed": "需要重启Syncthing",
"Restarting": "重启中", "Restarting": "重启中",
"Reused": "复用", "Reused": "复用",
"Save": "保存", "Save": "保存",
@@ -130,14 +123,14 @@
"Share this folder?": "是否共享该文件夹?", "Share this folder?": "是否共享该文件夹?",
"Shared With": "共享给", "Shared With": "共享给",
"Short identifier for the folder. Must be the same on all cluster devices.": "文件夹的别名。必须在所有设备上保持一致。", "Short identifier for the folder. Must be the same on all cluster devices.": "文件夹的别名。必须在所有设备上保持一致。",
"Show ID": "显示设备标示", "Show ID": "显示设备ID",
"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 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.": "在设备丛中,将会显示本名称,而不是设备标识。如果设置为空,则会使用目标设备提供的默认名称。", "Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "在设备丛中,将会显示本名称,而不是设备标识。如果设置为空,则会使用目标设备提供的默认名称。",
"Shutdown": "关闭 Syncthing", "Shutdown": "关闭Syncthing",
"Shutdown Complete": "关闭完成", "Shutdown Complete": "关闭完成",
"Simple File Versioning": "简易版本控制", "Simple File Versioning": "简易版本控制",
"Single level wildcard (matches within a directory only)": "单级通配符(仅匹配单层文件夹)", "Single level wildcard (matches within a directory only)": "单级通配符(仅匹配单层文件夹)",
"Smallest First": "小文件优先", "Smallest First": "Smallest First",
"Source Code": "源代码", "Source Code": "源代码",
"Staggered File Versioning": "阶段版本控制", "Staggered File Versioning": "阶段版本控制",
"Start Browser": "启动浏览器", "Start Browser": "启动浏览器",
@@ -145,44 +138,40 @@
"Support": "支持", "Support": "支持",
"Sync Protocol Listen Addresses": "协议监听地址", "Sync Protocol Listen Addresses": "协议监听地址",
"Syncing": "同步中", "Syncing": "同步中",
"Syncthing has been shut down.": "Syncthing 已关闭", "Syncthing has been shut down.": "Syncthing已关闭",
"Syncthing includes the following software or portions thereof:": "Syncthing 使用了下列软件或其中的一部分", "Syncthing includes the following software or portions thereof:": "Syncthing使用了下列软件或其中的一部分",
"Syncthing is restarting.": "Syncthing 正在重启", "Syncthing is restarting.": "Syncthing正在重启",
"Syncthing is upgrading.": "Syncthing 正在升级", "Syncthing is upgrading.": "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。", "Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.",
"The aggregated statistics are publicly available at {%url%}.": "全局统计公布于 {{url}}", "The aggregated statistics are publicly available at {%url%}.": "全局统计公布于 {{url}}",
"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 cannot be blank.": "设备标识不能为空",
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "在这里所需要输入的设备标识,可以在目标设备的“选项->显示设备标识”中看到。空格和横线可选(将会被忽略)。", "The device ID to enter here can be found in the \"Edit > 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.": "经过加密的使用报告会每天发送。它用来跟踪统计使用本软件的平台,文件夹大小,以及本软件的版本。如果报告的内容有任何变化,本对话框会再次弹出提示您。", "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.": "输入的设备标识似乎无效。设备标识长度必须为52或56的字母和数字,空格和横线不算在内。", "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 first command line parameter is the folder path and the second parameter is the relative path in the folder.": "命令行的第一个参数是文件夹的路径,第二个参数是文件夹内的相对路径。", "The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "命令行的第一个参数是文件夹的路径,第二个参数是文件夹内的相对路径。",
"The folder ID cannot be blank.": "文件夹标识不能为空。", "The folder ID cannot be blank.": "文件夹标识不能为空。",
"The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "文件夹标识不长于 64 字符,且仅能包含字母、数字、半角句号(.)、横线(-)和下划线(_)。", "The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "文件夹标识必须由不长于 64 字符,且仅能包含字母、数字、半角句号(.)、横线(-)和下划线(_)。",
"The folder ID must be unique.": "文件夹标识不得重复", "The folder ID must be unique.": "文件夹标识不得重复",
"The folder path cannot be blank.": "文件夹路径不能为空", "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秒的仅保留一份。最近一天内的历史版本,更新间隔小于1小时的仅保留一份。最近一个月内的历史版本,更新间隔小于1天的仅保留一份。距离现在超过一个月且小于最长保留时间的,更新间隔小于1周的仅保留一份。", "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秒的仅保留一份。最近一天内的历史版本,更新间隔小于1小时的仅保留一份。最近一个月内的历史版本,更新间隔小于1天的仅保留一份。距离现在超过一个月且小于最长保留时间的,更新间隔小于1周的仅保留一份。",
"The maximum age must be a number and cannot be blank.": "最长保留时间必须为数字,且不能为空。", "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 maximum time to keep a version (in days, set to 0 to keep versions forever).": "历史版本保留的最长天数,0为永久保存",
"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 old versions to keep, per file.": "每个文件保留的版本数量上限。",
"The number of versions must be a number and cannot be blank.": "保留版本数量必须为数字,且不能为空。", "The number of versions must be a number and cannot be blank.": "保留版本数量必须为数字,且不能为空。",
"The path cannot be blank.": "路径不能为空", "The path cannot be blank.": "路径不能为空",
"The rescan interval must be a non-negative number of seconds.": "扫描间隔单位为秒,且不能为负数。", "The rescan interval must be a non-negative number of seconds.": "扫描间隔单位为秒,且不能为负数。",
"This is a major version upgrade.": "这是一个重大版本更新。", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "回收站式版本控制",
"Unknown": "未知", "Unknown": "未知",
"Unshared": "未共享", "Unshared": "未共享",
"Unused": "未使用", "Unused": "已共享",
"Up to Date": "同步完成", "Up to Date": "同步完成",
"Updated": "已更新", "Upgrade": "Upgrade",
"Upgrade": "更新",
"Upgrade To {%version%}": "升级至版本{{version}}", "Upgrade To {%version%}": "升级至版本{{version}}",
"Upgrading": "升级中", "Upgrading": "升级中",
"Upload Rate": "上传速度", "Upload Rate": "上传速度",
"Uptime": "已启动", "Uptime": "Uptime",
"Use HTTPS for GUI": "使用HTTPS连接web管理页面", "Use HTTPS for GUI": "使用HTTPS连接web管理页面",
"Version": "版本", "Version": "版本",
"Versions Path": "历史版本路径", "Versions Path": "历史版本路径",
+16 -27
View File
@@ -1,9 +1,7 @@
{ {
"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.", "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 金鑰", "API Key": "API 金鑰",
"About": "關於", "About": "關於",
"Actions": "操作",
"Add": "增加", "Add": "增加",
"Add Device": "增加裝置", "Add Device": "增加裝置",
"Add Folder": "增加資料夾", "Add Folder": "增加資料夾",
@@ -12,7 +10,7 @@
"Addresses": "位址", "Addresses": "位址",
"All Data": "全部資料", "All Data": "全部資料",
"Allow Anonymous Usage Reporting?": "允許匿名的使用資訊回報?", "Allow Anonymous Usage Reporting?": "允許匿名的使用資訊回報?",
"Alphabetic": "字母順序", "Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the synced folder.": "An external command handles the versioning. It has to remove the file from the synced folder.", "An external command handles the versioning. It has to remove the file from the synced folder.": "An external command handles the versioning. It has to remove the file from the synced folder.",
"Anonymous Usage Reporting": "匿名的使用資訊回報", "Anonymous Usage Reporting": "匿名的使用資訊回報",
"Any devices configured on an introducer device will be added to this device as well.": "任何在引入者裝置所設置的裝置將會一併新增至此裝置", "Any devices configured on an introducer device will be added to this device as well.": "任何在引入者裝置所設置的裝置將會一併新增至此裝置",
@@ -20,7 +18,6 @@
"Bugs": "程式錯誤", "Bugs": "程式錯誤",
"CPU Utilization": "CPU 使用", "CPU Utilization": "CPU 使用",
"Changelog": "更新日誌", "Changelog": "更新日誌",
"Clean out after": "Clean out after",
"Close": "關閉", "Close": "關閉",
"Command": "指令", "Command": "指令",
"Comment, when used at the start of a line": "註解,當輸入在一行的開頭時", "Comment, when used at the start of a line": "註解,當輸入在一行的開頭時",
@@ -28,9 +25,8 @@
"Connection Error": "連線錯誤", "Connection Error": "連線錯誤",
"Copied from elsewhere": "從別處複製", "Copied from elsewhere": "從別處複製",
"Copied from original": "Copied from original", "Copied from original": "Copied from original",
"Copyright © 2015 the following Contributors:": "Copyright © 2015 下列貢獻者:", "Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
"Delete": "刪除", "Delete": "刪除",
"Deleted": "Deleted",
"Device ID": "裝置識別碼", "Device ID": "裝置識別碼",
"Device Identification": "裝置識別", "Device Identification": "裝置識別",
"Device Name": "裝置名稱", "Device Name": "裝置名稱",
@@ -50,10 +46,9 @@
"Enter ignore patterns, one per line.": "輸入忽略樣式,每行一種。", "Enter ignore patterns, one per line.": "輸入忽略樣式,每行一種。",
"Error": "錯誤", "Error": "錯誤",
"External File Versioning": "外部檔案版本控制", "External File Versioning": "外部檔案版本控制",
"File Pull Order": "提取檔案的順序", "File Pull Order": "File Pull Order",
"File Versioning": "檔案版本控制", "File Versioning": "檔案版本控制",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.", "File permission bits are ignored when looking for changes. Use on FAT file systems.": "File permission bits are ignored when looking for changes. Use on FAT file systems.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.", "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by 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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "其他裝置做的改變不會影響到此裝置的檔案,但在此裝置上的變化將被發送到叢集中的其他部分。",
"Folder ID": "資料夾識別碼", "Folder ID": "資料夾識別碼",
@@ -67,7 +62,6 @@
"Global Discovery": "全域探索", "Global Discovery": "全域探索",
"Global Discovery Server": "全域探索伺服器", "Global Discovery Server": "全域探索伺服器",
"Global State": "全域狀態", "Global State": "全域狀態",
"Help": "說明",
"Ignore": "忽略", "Ignore": "忽略",
"Ignore Patterns": "忽略樣式", "Ignore Patterns": "忽略樣式",
"Ignore Permissions": "忽略權限", "Ignore Permissions": "忽略權限",
@@ -75,42 +69,41 @@
"Introducer": "引入者", "Introducer": "引入者",
"Inversion of the given condition (i.e. do not exclude)": "反轉給定條件 (即:不要排除)", "Inversion of the given condition (i.e. do not exclude)": "反轉給定條件 (即:不要排除)",
"Keep Versions": "保留歷史版本數", "Keep Versions": "保留歷史版本數",
"Largest First": "最大的優先", "Largest First": "Largest First",
"Last File Received": "最後接收的檔案", "Last File Received": "最後接收的檔案",
"Last seen": "最後發現時間", "Last seen": "最後發現時間",
"Later": "稍後", "Later": "稍後",
"Local Discovery": "本地探索", "Local Discovery": "本地探索",
"Local State": "本地狀態", "Local State": "本地狀態",
"Local State (Total)": "Local State (Total)", "Major Upgrade": "Major Upgrade",
"Major Upgrade": "重大更新",
"Maximum Age": "最長保留時間", "Maximum Age": "最長保留時間",
"Metadata Only": "僅中繼資料", "Metadata Only": "Metadata Only",
"Move to top of queue": "移到隊列頂端", "Move to top of queue": "移到隊列頂端",
"Multi level wildcard (matches multiple directory levels)": "多階層萬用字元 (可比對多層資料夾)", "Multi level wildcard (matches multiple directory levels)": "多階層萬用字元 (可比對多層資料夾)",
"Never": "從未", "Never": "從未",
"New Device": "新裝置", "New Device": "新裝置",
"New Folder": "新資料夾", "New Folder": "新資料夾",
"Newest First": "最新的優先", "Newest First": "Newest First",
"No": "否", "No": "否",
"No File Versioning": "無檔案版本控制", "No File Versioning": "無檔案版本控制",
"Notice": "注意", "Notice": "注意",
"OK": "確定", "OK": "確定",
"Off": "關閉", "Off": "關閉",
"Oldest First": "最舊的優先", "Oldest First": "Oldest First",
"Out Of Sync": "不同步", "Out Of Sync": "不同步",
"Out of Sync Items": "不同步物件", "Out of Sync Items": "不同步物件",
"Outgoing Rate Limit (KiB/s)": "連出速率限制 (KiB/s)", "Outgoing Rate Limit (KiB/s)": "連出速率限制 (KiB/s)",
"Override Changes": "置換改變", "Override Changes": "置換改變",
"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 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 folder in the folder).": "儲存歷史版本的路徑 (若為空,則預設使用資料夾中的 .stversions 資料夾)。", "Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "儲存歷史版本的路徑 (若為空,則預設使用資料夾中的 .stversions 資料夾)。",
"Please consult the release notes before performing a major upgrade.": "執行重大升級前請先參閱版本資訊。", "Please consult the release notes before performing a major upgrade.": "Please consult the release notes before performing a major upgrade.",
"Please wait": "請稍後", "Please wait": "請稍後",
"Preview": "預覽", "Preview": "預覽",
"Preview Usage Report": "預覽使用資訊報告", "Preview Usage Report": "預覽使用資訊報告",
"Quick guide to supported patterns": "可支援樣式的快速指南", "Quick guide to supported patterns": "可支援樣式的快速指南",
"RAM Utilization": "記憶體使用", "RAM Utilization": "記憶體使用",
"Random": "隨機", "Random": "Random",
"Release Notes": "版本資訊", "Release Notes": "Release Notes",
"Rescan": "重新掃描", "Rescan": "重新掃描",
"Rescan All": "全部重新掃描", "Rescan All": "全部重新掃描",
"Rescan Interval": "重新掃描間隔", "Rescan Interval": "重新掃描間隔",
@@ -137,7 +130,7 @@
"Shutdown Complete": "關閉完成", "Shutdown Complete": "關閉完成",
"Simple File Versioning": "簡單檔案版本控制", "Simple File Versioning": "簡單檔案版本控制",
"Single level wildcard (matches within a directory only)": "單階層萬用字元 (只在單個資料夾階層內比對)", "Single level wildcard (matches within a directory only)": "單階層萬用字元 (只在單個資料夾階層內比對)",
"Smallest First": "最小的優先", "Smallest First": "Smallest First",
"Source Code": "原始碼", "Source Code": "原始碼",
"Staggered File Versioning": "變動式檔案版本控制", "Staggered File Versioning": "變動式檔案版本控制",
"Start Browser": "啟動瀏覽器", "Start Browser": "啟動瀏覽器",
@@ -163,26 +156,22 @@
"The folder ID must be unique.": "資料夾識別碼必須為獨一無二的。", "The folder ID must be unique.": "資料夾識別碼必須為獨一無二的。",
"The folder path cannot be blank.": "資料夾路徑不能空白。", "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 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 maximum age must be a number and cannot be blank.": "最長保留時間必須為一個數字且不得為空。", "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 maximum time to keep a version (in days, set to 0 to keep versions forever).": "一個版本被保留的最長時間 (單位為天,若設定為 0 則表示永遠保留)。",
"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 days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "每個檔案要保留的舊版本數量。", "The number of old versions to keep, per file.": "每個檔案要保留的舊版本數量。",
"The number of versions must be a number and cannot be blank.": "每個檔案要保留的舊版本數量必須是數字且不能為空白。", "The number of versions must be a number and cannot be blank.": "每個檔案要保留的舊版本數量必須是數字且不能為空白。",
"The path cannot be blank.": "路徑不能空白。", "The path cannot be blank.": "路徑不能空白。",
"The rescan interval must be a non-negative number of seconds.": "重新掃描間隔必須為一個非負數的秒數。", "The rescan interval must be a non-negative number of seconds.": "重新掃描間隔必須為一個非負數的秒數。",
"This is a major version upgrade.": "這是一個主要版本更新。", "This is a major version upgrade.": "This is a major version upgrade.",
"Trash Can File Versioning": "Trash Can File Versioning",
"Unknown": "未知", "Unknown": "未知",
"Unshared": "未共享", "Unshared": "未共享",
"Unused": "未使用", "Unused": "未使用",
"Up to Date": "最新", "Up to Date": "最新",
"Updated": "Updated", "Upgrade": "Upgrade",
"Upgrade": "升級",
"Upgrade To {%version%}": "升級至 {{version}}", "Upgrade To {%version%}": "升級至 {{version}}",
"Upgrading": "正在升級", "Upgrading": "正在升級",
"Upload Rate": "上載速率", "Upload Rate": "上載速率",
"Uptime": "上線時間", "Uptime": "Uptime",
"Use HTTPS for GUI": "為 GUI 使用 HTTPS", "Use HTTPS for GUI": "為 GUI 使用 HTTPS",
"Version": "版本", "Version": "版本",
"Versions Path": "歷史版本路徑", "Versions Path": "歷史版本路徑",
-1
View File
@@ -1 +0,0 @@
var langPrettyprint = {"bg":"Bulgarian","ca":"Catalan","ca@valencia":"Catalan (Valencian)","cs":"Czech","de":"German","el":"Greek","en":"English","en-GB":"English (United Kingdom)","es":"Spanish","es-ES":"Spanish (Spain)","fi":"Finnish","fr":"French","hu":"Hungarian","it":"Italian","ja":"Japanese","ko-KR":"Korean (Korea)","lt":"Lithuanian","nb":"Norwegian Bokmål","nl":"Dutch","nn":"Norwegian Nynorsk","pl":"Polish","pt-BR":"Portuguese (Brazil)","pt-PT":"Portuguese (Portugal)","ro-RO":"Romanian (Romania)","ru":"Russian","sv":"Swedish","tr":"Turkish","uk":"Ukrainian","zh-CN":"Chinese (China)","zh-TW":"Chinese (Taiwan)"}
+1 -1
View File
@@ -1 +1 @@
var validLangs = ["bg","ca","ca@valencia","cs","de","el","en","en-GB","es","es-ES","fi","fr","hu","it","ja","ko-KR","lt","nb","nl","nn","pl","pt-BR","pt-PT","ro-RO","ru","sv","tr","uk","zh-CN","zh-TW"] var validLangs = ["be","bg","ca","cs","de","el","en","en-GB","es","es-ES","fi","fr","hu","it","ko-KR","lt","nb","nl","nn","pl","pt-BR","pt-PT","ro-RO","ru","sv","tr","uk","zh-CN","zh-TW"]
Executable → Regular
+124 -276
View File
@@ -16,13 +16,15 @@
<meta name="author" content=""> <meta name="author" content="">
<link rel="shortcut icon" href="assets/img/favicon.png"> <link rel="shortcut icon" href="assets/img/favicon.png">
<title>{{thisDeviceName()}} | Syncthing</title> <title>Syncthing | {{thisDeviceName()}}</title>
<link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="assets/font/raleway.css" rel="stylesheet"> <link href="assets/font/raleway.css" rel="stylesheet">
<link href="assets/css/overrides.css" rel="stylesheet"> <link href="assets/css/overrides.css" rel="stylesheet">
</head> </head>
<body> <body>
<div ng-controller="EventController"></div>
<!-- Top bar --> <!-- Top bar -->
<nav class="navbar navbar-top navbar-default" role="navigation"> <nav class="navbar navbar-top navbar-default" role="navigation">
@@ -32,39 +34,27 @@
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li ng-if="upgradeInfo && upgradeInfo.newer"> <li ng-if="upgradeInfo && upgradeInfo.newer">
<button type="button" class="btn navbar-btn btn-primary btn-sm" href="" ng-click="upgrade()"> <button type="button" class="btn navbar-btn btn-primary btn-sm" href="" ng-click="upgrade()">
<span class="glyphicon glyphicon-chevron-up"></span>&nbsp; <span class="glyphicon glyphicon-chevron-up"></span>&emsp;
<span translate translate-value-version="{{upgradeInfo.latest}}">Upgrade To {%version%}</span> <span translate translate-value-version="{{upgradeInfo.latest}}">Upgrade To {%version%}</span>
</button> </button>
</li> </li>
<li ng-if="upgradeInfo && upgradeInfo.majorNewer"> <li ng-if="upgradeInfo && upgradeInfo.majorNewer">
<button type="button" class="btn navbar-btn btn-danger btn-sm" href="" ng-click="upgradeMajor()"> <button type="button" class="btn navbar-btn btn-danger btn-sm" href="" ng-click="upgradeMajor()">
<span class="glyphicon glyphicon-chevron-up"></span>&nbsp; <span class="glyphicon glyphicon-chevron-up"></span>&emsp;
<span translate translate-value-version="{{upgradeInfo.latest}}">Upgrade To {%version%}</span> <span translate translate-value-version="{{upgradeInfo.latest}}">Upgrade To {%version%}</span>
</button> </button>
</li> </li>
<li class="dropdown" language-select></li> <li class="dropdown" language-select></li>
<li class="hidden-xs">
<a href="http://docs.syncthing.net/intro/gui.html" target="_blank">
<span class="glyphicon glyphicon-book"></span>&nbsp;<span translate>Help</span>
</a>
</li>
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-cog" aria-label="Edit"></span>&nbsp;<span translate>Actions</span><span class="caret"></span></a> <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-cog" aria-label="Edit"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="" ng-click="editSettings()"><span class="glyphicon glyphicon-cog"></span>&nbsp;<span translate>Settings</span></a></li> <li><a href="" ng-click="editSettings()"><span class="glyphicon glyphicon-cog"></span>&emsp;<span translate>Settings</span></a></li>
<li><a href="" ng-click="idDevice()"><span class="glyphicon glyphicon-qrcode"></span>&nbsp;<span translate>Show ID</span></a></li> <li><a href="" ng-click="idDevice()"><span class="glyphicon glyphicon-qrcode"></span>&emsp;<span translate>Show ID</span></a></li>
<li class="divider"></li> <li class="divider"></li>
<li><a href="" ng-click="shutdown()"><span class="glyphicon glyphicon-off"></span>&nbsp;<span translate>Shutdown</span></a></li> <li><a href="" ng-click="shutdown()"><span class="glyphicon glyphicon-off"></span>&emsp;<span translate>Shutdown</span></a></li>
<li><a href="" ng-click="restart()"><span class="glyphicon glyphicon-refresh"></span>&nbsp;<span translate>Restart</span></a></li> <li><a href="" ng-click="restart()"><span class="glyphicon glyphicon-refresh"></span>&emsp;<span translate>Restart</span></a></li>
<li class="divider"></li> <li class="divider"></li>
<li class="visible-xs"> <li><a href="" ng-click="about()"><span class="glyphicon glyphicon-heart-empty"></span>&emsp;<span translate>About</span></a></li>
<a href="http://docs.syncthing.net/intro/gui.html" target="_blank">
<span class="glyphicon glyphicon-book"></span>&nbsp;<span translate>Help</span>
</a>
</li>
<li><a href="" ng-click="about()"><span class="glyphicon glyphicon-heart-empty"></span>&nbsp;<span translate>About</span></a></li>
<li class="divider"></li>
<li><a href="" ng-click="advanced()"><span class="glyphicon glyphicon-cog"></span>&nbsp;<span translate>Advanced</span></a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
@@ -83,7 +73,7 @@
<p translate>The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.</p> <p translate>The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.</p>
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
<button type="button" class="btn btn-sm btn-default pull-right" ng-click="restart()"><span class="glyphicon glyphicon-refresh"></span>&nbsp;<span translate>Restart</span></button> <button type="button" class="btn btn-sm btn-default pull-right" ng-click="restart()"><span class="glyphicon glyphicon-refresh"></span>&emsp;<span translate>Restart</span></button>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
</div> </div>
@@ -97,12 +87,12 @@
<div class="panel panel-warning"> <div class="panel panel-warning">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="panel-title"> <h3 class="panel-title">
<identicon data-value="device"></identicon>&nbsp;<span translate>New Device</span> <identicon data-value="device"></identicon>&emsp;<span translate>New Device</span>
</h3> </h3>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<p> <p>
<small>{{ event.time | date:"yyyy-MM-dd HH:mm:ss" }}:</small> <small>{{ event.time | date:"H:mm:ss" }}:</small>
<span translate translate-value-device="{{ device }}" translate-value-address="{{ event.data.address }}"> <span translate translate-value-device="{{ device }}" translate-value-address="{{ event.data.address }}">
Device {%device%} ({%address%}) wants to connect. Add new device? Device {%device%} ({%address%}) wants to connect. Add new device?
<span> <span>
@@ -110,9 +100,9 @@
</div> </div>
<div class="panel-footer clearfix"> <div class="panel-footer clearfix">
<div class="pull-right"> <div class="pull-right">
<button class="btn btn-sm btn-success" ng-click="addNewDeviceID(device)"><span class="glyphicon glyphicon-ok"></span>&nbsp;<span translate>Add</span></button> <button class="btn btn-sm btn-success" ng-click="addNewDeviceID(device)"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Add</span></button>
<button class="btn btn-sm btn-danger" ng-click="ignoreRejectedDevice(device)"><span class="glyphicon glyphicon-remove"></span>&nbsp;<span translate>Ignore</span></button> <button class="btn btn-sm btn-danger" ng-click="ignoreRejectedDevice(device)"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>Ignore</span></button>
<button class="btn btn-sm btn-default" ng-click="dismissDeviceRejection(device)"><span class="glyphicon glyphicon-time"></span>&nbsp;<span translate>Later</span></button> <button class="btn btn-sm btn-default" ng-click="dismissDeviceRejection(device)"><span class="glyphicon glyphicon-time"></span>&emsp;<span translate>Later</span></button>
</div> </div>
</div> </div>
</div> </div>
@@ -132,7 +122,7 @@
</div> </div>
<div class="panel-body"> <div class="panel-body">
<p> <p>
<small>{{ event.time | date:"yyyy-MM-dd HH:mm:ss" }}:</small> <small>{{ event.time | date:"H:mm:ss" }}:</small>
<span translate translate-value-device="{{ deviceName(findDevice(event.data.device)) }}" translate-value-folder="{{ event.data.folder }}"> <span translate translate-value-device="{{ deviceName(findDevice(event.data.device)) }}" translate-value-folder="{{ event.data.folder }}">
{%device%} wants to share folder "{%folder%}". {%device%} wants to share folder "{%folder%}".
</span> </span>
@@ -143,13 +133,13 @@
<div class="panel-footer clearfix"> <div class="panel-footer clearfix">
<div class="pull-right"> <div class="pull-right">
<button class="btn btn-sm btn-success" ng-click="addFolderAndShare(event.data.folder, event.data.device)" ng-if="!folders[event.data.folder]"> <button class="btn btn-sm btn-success" ng-click="addFolderAndShare(event.data.folder, event.data.device)" ng-if="!folders[event.data.folder]">
<span class="glyphicon glyphicon-ok"></span>&nbsp;<span translate>Add</span> <span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Add</span>
</button> </button>
<button class="btn btn-sm btn-success" ng-click="shareFolderWithDevice(event.data.folder, event.data.device)" ng-if="folders[event.data.folder]"> <button class="btn btn-sm btn-success" ng-click="shareFolderWithDevice(event.data.folder, event.data.device)" ng-if="folders[event.data.folder]">
<span class="glyphicon glyphicon-ok"></span>&nbsp;<span translate>Share</span> <span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Share</span>
</button> </button>
<button class="btn btn-sm btn-default" ng-click="dismissFolderRejection(event.data.folder, event.data.device)"> <button class="btn btn-sm btn-default" ng-click="dismissFolderRejection(event.data.folder, event.data.device)">
<span class="glyphicon glyphicon-time"></span>&nbsp;<span translate>Later</span> <span class="glyphicon glyphicon-time"></span>&emsp;<span translate>Later</span>
</button> </button>
</div> </div>
</div> </div>
@@ -164,10 +154,10 @@
<div class="panel panel-warning"> <div class="panel panel-warning">
<div class="panel-heading"><h3 class="panel-title"><span class="glyphicon glyphicon-exclamation-sign"></span><span translate>Notice</span></h3></div> <div class="panel-heading"><h3 class="panel-title"><span class="glyphicon glyphicon-exclamation-sign"></span><span translate>Notice</span></h3></div>
<div class="panel-body"> <div class="panel-body">
<p ng-repeat="err in errorList()"><small>{{err.time | date:"yyyy-MM-dd HH:mm:ss"}}:</small> {{friendlyDevices(err.error)}}</p> <p ng-repeat="err in errorList()"><small>{{err.time | date:"H:mm:ss"}}:</small> {{friendlyDevices(err.error)}}</p>
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
<button type="button" class="pull-right btn btn-sm btn-default" ng-click="clearErrors()"><span class="glyphicon glyphicon-ok"></span>&nbsp;<span translate>OK</span></button> <button type="button" class="pull-right btn btn-sm btn-default" ng-click="clearErrors()"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>OK</span></button>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
</div> </div>
@@ -198,7 +188,6 @@
<span class="hidden-xs" translate>Syncing</span> <span class="hidden-xs" translate>Syncing</span>
({{syncPercentage(folder.id)}}%) ({{syncPercentage(folder.id)}}%)
</span> </span>
<span ng-switch-when="outofsync"><span class="hidden-xs" translate>Out of Sync</span><span class="visible-xs">&#9724;</span></span>
</span> </span>
</h3> </h3>
</div> </div>
@@ -207,62 +196,51 @@
<table class="table table-condensed table-striped"> <table class="table table-condensed table-striped">
<tbody> <tbody>
<tr> <tr>
<th><span class="glyphicon glyphicon-folder-open"></span>&nbsp;<span translate>Folder Path</span></th> <th><span class="glyphicon glyphicon-folder-open"></span>&emsp;<span translate>Folder Path</span></th>
<td class="text-right">{{folder.path}}</td> <td class="text-right">{{folder.path}}</td>
</tr> </tr>
<tr ng-if="model[folder.id].invalid || model[folder.id].error"> <tr ng-if="model[folder.id].invalid || model[folder.id].error">
<th><span class="glyphicon glyphicon-warning-sign"></span>&nbsp;<span translate>Error</span></th> <th><span class="glyphicon glyphicon-warning-sign"></span>&emsp;<span translate>Error</span></th>
<td class="text-right">{{model[folder.id].invalid || model[folder.id].error}}</td> <td class="text-right">{{model[folder.id].invalid || model[folder.id].error}}</td>
</tr> </tr>
<tr> <tr>
<th><span class="glyphicon glyphicon-globe"></span>&nbsp;<span translate>Global State</span></th> <th><span class="glyphicon glyphicon-globe"></span>&emsp;<span translate>Global State</span></th>
<td class="text-right">{{model[folder.id].globalFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.id].globalBytes | binary}}B</td> <td class="text-right">{{model[folder.id].globalFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.id].globalBytes | binary}}B</td>
</tr> </tr>
<tr> <tr>
<th><span class="glyphicon glyphicon-home"></span>&nbsp;<span translate>Local State</span></th> <th><span class="glyphicon glyphicon-home"></span>&emsp;<span translate>Local State</span></th>
<td class="text-right">{{model[folder.id].localFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.id].localBytes | binary}}B</td> <td class="text-right">{{model[folder.id].localFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.id].localBytes | binary}}B</td>
</tr> </tr>
<tr ng-if="model[folder.id].needFiles > 0"> <tr ng-if="model[folder.id].needFiles > 0">
<th><span class="glyphicon glyphicon-cloud-download"></span>&nbsp;<span translate>Out of Sync</span></th> <th><span class="glyphicon glyphicon-cloud-download"></span>&emsp;<span translate>Out Of Sync</span></th>
<td class="text-right"> <td class="text-right">
<a ng-click="showNeed(folder.id)" href="">{{model[folder.id].needFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.id].needBytes | binary}}B</a> <a ng-click="showNeed(folder.id)" href="">{{model[folder.id].needFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.id].needBytes | binary}}B</a>
</td> </td>
</tr> </tr>
<tr ng-if="!folder.readOnly && (folderStatus(folder) === 'outofsync' || hasFailedFiles(folder.id))">
<th><span class="glyphicon glyphicon-exclamation-sign"></span>&nbsp;<span translate>Failed Items</span></th>
<!-- Show the number of failed items as a link to bring up the list. -->
<td ng-if="hasFailedFiles(folder.id)" class="text-right">
<a ng-click="showFailed(folder.id)" href="">{{failed[folder.id].length | alwaysNumber}}&nbsp;<span translate>items</span></a>
</td>
<!-- The list of failed items hasn't loaded yet; show an ellipsis for the time being. -->
<td ng-if="!hasFailedFiles(folder.id)" class="text-right">
...
</td>
</tr>
<tr ng-if="folder.readOnly"> <tr ng-if="folder.readOnly">
<th><span class="glyphicon glyphicon-lock"></span>&nbsp;<span translate>Folder Master</span></th> <th><span class="glyphicon glyphicon-lock"></span>&emsp;<span translate>Folder Master</span></th>
<td class="text-right"> <td class="text-right">
<span translate>Yes</span> <span translate>Yes</span>
</td> </td>
</tr> </tr>
<tr ng-if="model[folder.id].ignorePatterns"> <tr ng-if="model[folder.id].ignorePatterns">
<th><span class="glyphicon glyphicon-eye-close"></span>&nbsp;<span translate>Ignore Patterns</span></th> <th><span class="glyphicon glyphicon-eye-close"></span>&emsp;<span translate>Ignore Patterns</span></th>
<td class="text-right"> <td class="text-right">
<span translate>Yes</span> <span translate>Yes</span>
</td> </td>
</tr> </tr>
<tr ng-if="folder.ignorePerms"> <tr ng-if="folder.ignorePerms">
<th><span class="glyphicon glyphicon-unchecked"></span>&nbsp;<span translate>Ignore Permissions</span></th> <th><span class="glyphicon glyphicon-unchecked"></span>&emsp;<span translate>Ignore Permissions</span></th>
<td class="text-right"> <td class="text-right">
<span translate>Yes</span> <span translate>Yes</span>
</td> </td>
</tr> </tr>
<tr ng-if="folder.rescanIntervalS != 60"> <tr ng-if="folder.rescanIntervalS != 60">
<th><span class="glyphicon glyphicon-refresh"></span>&nbsp;<span translate>Rescan Interval</span></th> <th><span class="glyphicon glyphicon-refresh"></span>&emsp;<span translate>Rescan Interval</span></th>
<td class="text-right">{{folder.rescanIntervalS}} s</td> <td class="text-right">{{folder.rescanIntervalS}} s</td>
</tr> </tr>
<tr ng-if="folder.order != 'random'"> <tr ng-if="folder.order != 'random'">
<th><span class="glyphicon glyphicon-sort"></span>&nbsp;<span translate>File Pull Order</span></th> <th><span class="glyphicon glyphicon-sort"></span>&emsp;<span translate>File Pull Order</span></th>
<td class="text-right" ng-switch="folder.order"> <td class="text-right" ng-switch="folder.order">
<span ng-switch-when="random" translate>Random</span> <span ng-switch-when="random" translate>Random</span>
<span ng-switch-when="alphabetic" translate>Alphabetic</span> <span ng-switch-when="alphabetic" translate>Alphabetic</span>
@@ -273,24 +251,21 @@
</td> </td>
</tr> </tr>
<tr ng-if="folder.versioning.type"> <tr ng-if="folder.versioning.type">
<th><span class="glyphicon glyphicon-tags"></span>&nbsp;<span translate>File Versioning</span></th> <th><span class="glyphicon glyphicon-tags"></span>&emsp;<span translate>File Versioning</span></th>
<td class="text-right" ng-switch="folder.versioning.type"> <td class="text-right" ng-switch="folder.versioning.type">
<span ng-switch-when="trashcan" translate>Trash Can File Versioning</span>
<span ng-switch-when="staggered" translate>Staggered File Versioning</span> <span ng-switch-when="staggered" translate>Staggered File Versioning</span>
<span ng-switch-when="simple" translate>Simple File Versioning</span> <span ng-switch-when="simple" translate>Simple File Versioning</span>
<span ng-switch-when="external" translate>External File Versioning</span> <span ng-switch-when="external" translate>External File Versioning</span>
</td> </td>
</tr> </tr>
<tr> <tr>
<th><span class="glyphicon glyphicon-share-alt"></span>&nbsp;<span translate>Shared With</span></th> <th><span class="glyphicon glyphicon-share-alt"></span>&emsp;<span translate>Shared With</span></th>
<td class="text-right">{{sharesFolder(folder)}}</td> <td class="text-right">{{sharesFolder(folder)}}</td>
</tr> </tr>
<tr ng-if="!folder.readOnly && folderStats[folder.id].lastFile && folderStats[folder.id].lastFile.filename"> <tr ng-if="!folder.readOnly && folderStats[folder.id].lastFile">
<th><span class="glyphicon glyphicon-transfer"></span>&nbsp;<span translate>Last File Received</span></th> <th><span class="glyphicon glyphicon-transfer"></span>&emsp;<span translate>Last File Received</span></th>
<td class="text-right"> <td class="text-right">
<span title="{{folderStats[folder.id].lastFile.filename}} @ {{folderStats[folder.id].lastFile.at | date:'yyyy-MM-dd HH:mm:ss'}}"> <span title="{{folderStats[folder.id].lastFile.filename}} @ {{folderStats[folder.id].lastFile.at | date:'yyyy-MM-dd HH:mm'}}">
<span translate ng-if="!folderStats[folder.id].lastFile.deleted">Updated</span>
<span translate ng-if="folderStats[folder.id].lastFile.deleted">Deleted</span>
{{folderStats[folder.id].lastFile.filename | basename}} {{folderStats[folder.id].lastFile.filename | basename}}
</span> </span>
</td> </td>
@@ -299,10 +274,10 @@
</table> </table>
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
<button class="btn btn-sm btn-danger pull-left" ng-if="folderStatus(folder) == 'outofsync' && folder.readOnly" ng-click="override(folder.id)" href=""><span class="glyphicon glyphicon-upload"></span>&nbsp;<span translate>Override Changes</span></button> <button class="btn btn-sm btn-danger pull-left" ng-if="folderStatus(folder) == 'idle' && folder.readOnly && model[folder.id].needFiles > 0" ng-click="override(folder.id)" href=""><span class="glyphicon glyphicon-upload"></span>&emsp;<span translate>Override Changes</span></button>
<span class="pull-right"> <span class="pull-right">
<button class="btn btn-sm btn-default" href="" ng-show="['idle', 'stopped'].indexOf(folderStatus(folder)) > -1" ng-click="rescanFolder(folder.id)"><span class="glyphicon glyphicon-refresh"></span>&nbsp;<span translate>Rescan</span></button> <button class="btn btn-sm btn-default" href="" ng-show="folderStatus(folder) == 'idle'" ng-click="rescanFolder(folder.id)"><span class="glyphicon glyphicon-refresh"></span>&emsp;<span translate>Rescan</span></button>
<button class="btn btn-sm btn-default" href="" ng-click="editFolder(folder)"><span class="glyphicon glyphicon-pencil"></span>&nbsp;<span translate>Edit</span></button> <button class="btn btn-sm btn-default" href="" ng-click="editFolder(folder)"><span class="glyphicon glyphicon-pencil"></span>&emsp;<span translate>Edit</span></button>
</span> </span>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
@@ -310,8 +285,8 @@
</div> </div>
</div> </div>
<span class="pull-right"> <span class="pull-right">
<button class="btn btn-sm btn-default" ng-click="rescanAllFolders()"><span class="glyphicon glyphicon-repeat"></span>&nbsp;<span translate>Rescan All</span></button> <button class="btn btn-sm btn-default" ng-click="rescanAllFolders()"><span class="glyphicon glyphicon-repeat"></span>&emsp;<span translate>Rescan All</span></button>
<button class="btn btn-sm btn-default" ng-click="addFolder()"><span class="glyphicon glyphicon-plus"></span>&nbsp;<span translate>Add Folder</span></button> <button class="btn btn-sm btn-default" ng-click="addFolder()"><span class="glyphicon glyphicon-plus"></span>&emsp;<span translate>Add Folder</span></button>
</span> </span>
<div class="clearfix"></div> <div class="clearfix"></div>
<hr class="visible-sm"/> <hr class="visible-sm"/>
@@ -334,27 +309,23 @@
<table class="table table-condensed table-striped"> <table class="table table-condensed table-striped">
<tbody> <tbody>
<tr> <tr>
<th><span class="glyphicon glyphicon-cloud-download"></span>&nbsp;<span translate>Download Rate</span></th> <th><span class="glyphicon glyphicon-cloud-download"></span>&emsp;<span translate>Download Rate</span></th>
<td class="text-right">{{connectionsTotal.inbps | binary}}B/s ({{connectionsTotal.inBytesTotal | binary}}B)</td> <td class="text-right">{{connectionsTotal.inbps | binary}}B/s ({{connectionsTotal.inBytesTotal | binary}}B)</td>
</tr> </tr>
<tr> <tr>
<th><span class="glyphicon glyphicon-cloud-upload"></span>&nbsp;<span translate>Upload Rate</span></th> <th><span class="glyphicon glyphicon-cloud-upload"></span>&emsp;<span translate>Upload Rate</span></th>
<td class="text-right">{{connectionsTotal.outbps | binary}}B/s ({{connectionsTotal.outBytesTotal | binary}}B)</td> <td class="text-right">{{connectionsTotal.outbps | binary}}B/s ({{connectionsTotal.outBytesTotal | binary}}B)</td>
</tr> </tr>
<tr> <tr>
<th><span class="glyphicon glyphicon-home"></span>&nbsp;<span translate>Local State (Total)</span> </th> <th><span class="glyphicon glyphicon-th"></span>&emsp;<span translate>RAM Utilization</span></th>
<td class="text-right">{{foldersTotalLocalFiles | alwaysNumber}} <span translate>items</span>, ~{{ foldersTotalLocalBytes | binary}}B</td>
</tr>
<tr>
<th><span class="glyphicon glyphicon-th"></span>&nbsp;<span translate>RAM Utilization</span></th>
<td class="text-right">{{system.sys | binary}}B</td> <td class="text-right">{{system.sys | binary}}B</td>
</tr> </tr>
<tr> <tr>
<th><span class="glyphicon glyphicon-dashboard"></span>&nbsp;<span translate>CPU Utilization</span></th> <th><span class="glyphicon glyphicon-dashboard"></span>&emsp;<span translate>CPU Utilization</span></th>
<td class="text-right">{{system.cpuPercent | alwaysNumber | natural:1}}%</td> <td class="text-right">{{system.cpuPercent | alwaysNumber | natural:1}}%</td>
</tr> </tr>
<tr ng-if="system.extAnnounceOK != undefined && announceServersTotal > 0"> <tr ng-if="system.extAnnounceOK != undefined && announceServersTotal > 0">
<th><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;<span translate>Global Discovery</span></th> <th><span class="glyphicon glyphicon-bullhorn"></span>&emsp;<span translate>Global Discovery</span></th>
<td class="text-right"> <td class="text-right">
<span ng-if="announceServersFailed.length == 0" class="data text-success"> <span ng-if="announceServersFailed.length == 0" class="data text-success">
<span>OK</span> <span>OK</span>
@@ -367,11 +338,11 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<th><span class="glyphicon glyphicon-time"></span>&nbsp;<span translate>Uptime</span></th> <th><span class="glyphicon glyphicon-time"></span>&emsp;<span translate>Uptime</span></th>
<td class="text-right">{{system.uptime | duration:"m"}}</td> <td class="text-right">{{system.uptime | duration:"m"}}</td>
</tr> </tr>
<tr> <tr>
<th><span class="glyphicon glyphicon-tag"></span>&nbsp;<span translate>Version</span></th> <th><span class="glyphicon glyphicon-tag"></span>&emsp;<span translate>Version</span></th>
<td class="text-right">{{versionString()}}</td> <td class="text-right">{{versionString()}}</td>
</tr> </tr>
</tbody> </tbody>
@@ -403,53 +374,53 @@
<table class="table table-condensed table-striped"> <table class="table table-condensed table-striped">
<tbody> <tbody>
<tr ng-if="connections[deviceCfg.deviceID]"> <tr ng-if="connections[deviceCfg.deviceID]">
<th><span class="glyphicon glyphicon-cloud-download"></span>&nbsp;<span translate>Download Rate</span></th> <th><span class="glyphicon glyphicon-cloud-download"></span>&emsp;<span translate>Download Rate</span></th>
<td class="text-right">{{connections[deviceCfg.deviceID].inbps | binary}}B/s ({{connections[deviceCfg.deviceID].inBytesTotal | binary}}B)</td> <td class="text-right">{{connections[deviceCfg.deviceID].inbps | binary}}B/s ({{connections[deviceCfg.deviceID].inBytesTotal | binary}}B)</td>
</tr> </tr>
<tr ng-if="connections[deviceCfg.deviceID]"> <tr ng-if="connections[deviceCfg.deviceID]">
<th><span class="glyphicon glyphicon-cloud-upload"></span>&nbsp;<span translate>Upload Rate</span></th> <th><span class="glyphicon glyphicon-cloud-upload"></span>&emsp;<span translate>Upload Rate</span></th>
<td class="text-right">{{connections[deviceCfg.deviceID].outbps | binary}}B/s ({{connections[deviceCfg.deviceID].outBytesTotal | binary}}B)</td> <td class="text-right">{{connections[deviceCfg.deviceID].outbps | binary}}B/s ({{connections[deviceCfg.deviceID].outBytesTotal | binary}}B)</td>
</tr> </tr>
<tr> <tr>
<th><span class="glyphicon glyphicon-link"></span>&nbsp;<span translate>Address</span></th> <th><span class="glyphicon glyphicon-link"></span>&emsp;<span translate>Address</span></th>
<td class="text-right">{{deviceAddr(deviceCfg)}}</td> <td class="text-right">{{deviceAddr(deviceCfg)}}</td>
</tr> </tr>
<tr ng-if="deviceCfg.compression != 'metadata'"> <tr ng-if="deviceCfg.compression != 'metadata'">
<th><span class="glyphicon glyphicon-compressed"></span>&nbsp;<span translate>Compression</span></th> <th><span class="glyphicon glyphicon-compressed"></span>&emsp;<span translate>Compression</span></th>
<td class="text-right"> <td class="text-right">
<span ng-if="deviceCfg.compression == 'always'" translate>All Data</span> <span ng-if="deviceCfg.compression == 'always'" translate>All Data</span>
<span ng-if="deviceCfg.compression == 'never'" translate>Off</span> <span ng-if="deviceCfg.compression == 'never'" translate>Off</span>
</td> </td>
</tr> </tr>
<tr ng-if="deviceCfg.introducer"> <tr ng-if="deviceCfg.introducer">
<th><span class="glyphicon glyphicon-thumbs-up"></span>&nbsp;<span translate>Introducer</span></th> <th><span class="glyphicon glyphicon-thumbs-up"></span>&emsp;<span translate>Introducer</span></th>
<td translate class="text-right">Yes</td> <td translate class="text-right">Yes</td>
</tr> </tr>
<tr ng-if="connections[deviceCfg.deviceID]"> <tr ng-if="connections[deviceCfg.deviceID]">
<th><span class="glyphicon glyphicon-tag"></span>&nbsp;<span translate>Version</span></th> <th><span class="glyphicon glyphicon-tag"></span>&emsp;<span translate>Version</span></th>
<td class="text-right">{{connections[deviceCfg.deviceID].clientVersion}}</td> <td class="text-right">{{connections[deviceCfg.deviceID].clientVersion}}</td>
</tr> </tr>
<tr ng-if="!connections[deviceCfg.deviceID]"> <tr ng-if="!connections[deviceCfg.deviceID]">
<th><span class="glyphicon glyphicon-eye-open"></span>&nbsp;<span translate>Last seen</span></th> <th><span class="glyphicon glyphicon-eye-open"></span>&emsp;<span translate>Last seen</span></th>
<td translate ng-if="!deviceStats[deviceCfg.deviceID].lastSeenDays || deviceStats[deviceCfg.deviceID].lastSeenDays >= 365" class="text-right">Never</td> <td translate ng-if="!deviceStats[deviceCfg.deviceID].lastSeenDays || deviceStats[deviceCfg.deviceID].lastSeenDays >= 365" class="text-right">Never</td>
<td ng-if="deviceStats[deviceCfg.deviceID].lastSeenDays < 365" class="text-right">{{deviceStats[deviceCfg.deviceID].lastSeen | date:"yyyy-MM-dd HH:mm:ss"}}</td> <td ng-if="deviceStats[deviceCfg.deviceID].lastSeenDays < 365" class="text-right">{{deviceStats[deviceCfg.deviceID].lastSeen | date:"yyyy-MM-dd HH:mm"}}</td>
</tr> </tr>
<tr ng-if="deviceFolders(deviceCfg).length > 0"> <tr ng-if="deviceFolders(deviceCfg).length > 0">
<th><span class="glyphicon glyphicon-hdd"></span>&nbsp;<span translate>Folders</span></th> <th><span class="glyphicon glyphicon-hdd"></span>&emsp;<span translate>Folders</span></th>
<td class="text-right">{{deviceFolders(deviceCfg).join(", ")}}</td> <td class="text-right">{{deviceFolders(deviceCfg).join(", ")}}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
<span class="pull-right"><a class="btn btn-sm btn-default" href="" ng-click="editDevice(deviceCfg)"><span class="glyphicon glyphicon-pencil"></span>&nbsp;<span translate>Edit</span></a></span> <span class="pull-right"><a class="btn btn-sm btn-default" href="" ng-click="editDevice(deviceCfg)"><span class="glyphicon glyphicon-pencil"></span>&emsp;<span translate>Edit</span></a></span>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<button class="btn btn-sm btn-default pull-right" ng-click="addDevice()"><span class="glyphicon glyphicon-plus"></span>&nbsp;<span translate>Add Device</span></button> <button class="btn btn-sm btn-default pull-right" ng-click="addDevice()"><span class="glyphicon glyphicon-plus"></span>&emsp;<span translate>Add Device</span></button>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
</div> </div>
@@ -462,13 +433,12 @@
<nav class="navbar navbar-default navbar-fixed-bottom"> <nav class="navbar navbar-default navbar-fixed-bottom">
<div class="container"> <div class="container">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a class="navbar-link" href="http://syncthing.net/" target="_blank"><span class="glyphicon glyphicon-home"></span>&nbsp;<span translate>Home page</span></a></li> <li><a class="navbar-link" href="https://github.com/syncthing/syncthing/wiki" target="_blank"><span class="glyphicon glyphicon-book"></span>&ensp;<span translate>Documentation</span></a></li>
<li><a class="navbar-link" href="http://docs.syncthing.net/" target="_blank"><span class="glyphicon glyphicon-book"></span>&nbsp;<span translate>Documentation</span></a></li> <li><a class="navbar-link" href="https://forum.syncthing.net" target="_blank"><span class="glyphicon glyphicon-question-sign"></span>&ensp;<span translate>Support</span></a></li>
<li><a class="navbar-link" href="https://forum.syncthing.net" target="_blank"><span class="glyphicon glyphicon-question-sign"></span>&nbsp;<span translate>Support</span></a></li> <li><a class="navbar-link" href="https://github.com/syncthing/syncthing/releases" target="_blank"><span class="glyphicon glyphicon-info-sign"></span>&ensp;<span translate>Changelog</span></a></li>
<li><a class="navbar-link" href="https://github.com/syncthing/syncthing/releases" target="_blank"><span class="glyphicon glyphicon-info-sign"></span>&nbsp;<span translate>Changelog</span></a></li> <li><a class="navbar-link" href="https://github.com/syncthing/syncthing/issues" target="_blank"><span class="glyphicon glyphicon-warning-sign"></span>&ensp;<span translate>Bugs</span></a></li>
<li><a class="navbar-link" href="https://github.com/syncthing/syncthing/issues" target="_blank"><span class="glyphicon glyphicon-warning-sign"></span>&nbsp;<span translate>Bugs</span></a></li> <li><a class="navbar-link" href="https://github.com/syncthing/syncthing" target="_blank"><span class="glyphicon glyphicon-wrench"></span>&ensp;<span translate>Source Code</span></a></li>
<li><a class="navbar-link" href="https://github.com/syncthing/syncthing" target="_blank"><span class="glyphicon glyphicon-wrench"></span>&nbsp;<span translate>Source Code</span></a></li> <li><a class="navbar-link" href="https://twitter.com/syncthing" target="_blank"><span class="glyphicon glyphicon-send"></span>&ensp;Twitter</a></li>
<li><a class="navbar-link" href="https://twitter.com/syncthing" target="_blank"><span class="glyphicon glyphicon-send"></span>&nbsp;Twitter</a></li>
</ul> </ul>
</div> </div>
</nav> </nav>
@@ -510,7 +480,7 @@
<!-- ID modal --> <!-- ID modal -->
<modal id="idqr" large="yes" status="info" close="yes" icon="qrcode" title="{{'Device Identification' | translate}} &mdash; {{deviceName(thisDevice())}}"> <modal id="idqr" large="yes" status="info" close="yes" icon="qrcode" title="{{'Device Identification' | translate}} &mdash; {{deviceName(thisDevice())}}">
<div select-on-click class="well well-sm text-monospace text-center">{{myID}}</div> <div class="well well-sm text-monospace text-center">{{myID}}</div>
<img ng-if="myID" class="center-block img-thumbnail" ng-src="qr/?text={{myID}}"/> <img ng-if="myID" class="center-block img-thumbnail" ng-src="qr/?text={{myID}}"/>
</modal> </modal>
@@ -536,8 +506,8 @@
</p> </p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="upgrade()"><span class="glyphicon glyphicon-ok"></span>&nbsp;<span translate>Upgrade</span></button> <button type="button" class="btn btn-primary btn-sm" ng-click="upgrade()"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Upgrade</span></button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&nbsp;<span translate>Close</span></button> <button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>Close</span></button>
</div> </div>
</div> </div>
</div> </div>
@@ -576,7 +546,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label translate for="addresses">Addresses</label> <label translate for="addresses">Addresses</label>
<input ng-disabled="currentDevice.deviceID == myID" id="addresses" class="form-control" type="text" ng-model="currentDevice._addressesStr"></input> <input ng-disabled="currentDevice.deviceID == myID" id="addresses" class="form-control" type="text" ng-model="currentDevice.addressesStr"></input>
<p translate class="help-block">Enter comma separated "ip:port" addresses or "dynamic" to perform automatic discovery of the address.</p> <p translate class="help-block">Enter comma separated "ip:port" addresses or "dynamic" to perform automatic discovery of the address.</p>
</div> </div>
<div ng-if="!editingSelf" class="form-group"> <div ng-if="!editingSelf" class="form-group">
@@ -601,13 +571,11 @@
<div class="form-group"> <div class="form-group">
<label translate for="folders">Share Folders With Device</label> <label translate for="folders">Share Folders With Device</label>
<p translate class="help-block">Select the folders to share with this device.</p> <p translate class="help-block">Select the folders to share with this device.</p>
<div class="container-fluid"> <div class="three-columns">
<div class="row" ng-repeat="folderGroup in folderList() | group:3"> <div class="checkbox" ng-repeat="folder in folderList()">
<div class="checkbox col-md-4" ng-repeat="folder in folderGroup"> <label>
<label> <input type="checkbox" ng-model="currentDevice.selectedFolders[folder.id]"> {{folder.id}}
<input type="checkbox" ng-model="currentDevice.selectedFolders[folder.id]"> {{folder.id}} </label>
</label>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -617,9 +585,9 @@
</form> </form>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="saveDevice()" ng-disabled="deviceEditor.$invalid"><span class="glyphicon glyphicon-ok"></span>&nbsp;<span translate>Save</span></button> <button type="button" class="btn btn-primary btn-sm" ng-click="saveDevice()" ng-disabled="deviceEditor.$invalid"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Save</span></button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&nbsp;<span translate>Close</span></button> <button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>Close</span></button>
<button ng-if="editingExisting && !editingSelf" type="button" class="btn btn-danger pull-left btn-sm" ng-click="deleteDevice()"><span class="glyphicon glyphicon-minus"></span>&nbsp;<span translate>Delete</span></button> <button ng-if="editingExisting && !editingSelf" type="button" class="btn btn-danger pull-left btn-sm" ng-click="deleteDevice()"><span class="glyphicon glyphicon-minus"></span>&emsp;<span translate>Delete</span></button>
</div> </div>
</div> </div>
</div> </div>
@@ -676,7 +644,6 @@
<label> <label>
<input type="checkbox" ng-model="currentFolder.readOnly"> <span translate>Folder Master</span> <input type="checkbox" ng-model="currentFolder.readOnly"> <span translate>Folder Master</span>
</label> </label>
&nbsp;<a href="http://docs.syncthing.net/users/foldermaster.html" target="_blank"><span class="glyphicon glyphicon-book"></span>&nbsp;<span translate>Help</span></a>
</div> </div>
<p translate class="help-block">Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.</p> <p translate class="help-block">Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.</p>
</div> </div>
@@ -704,27 +671,27 @@
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label translate>File Versioning</label>&emsp;<a href="http://docs.syncthing.net/users/versioning.html" target="_blank"><span class="glyphicon glyphicon-book"></span>&nbsp;<span translate>Help</span></a> <label translate>File Versioning</label>
<select class="form-control" ng-model="currentFolder.fileVersioningSelector"> <div class="radio">
<option value="none" translate>No File Versioning</option> <label>
<option value="trashcan" translate>Trash Can File Versioning</option> <input type="radio" ng-model="currentFolder.fileVersioningSelector" value="none"> <span translate>No File Versioning</span>
<option value="simple" translate>Simple File Versioning</option> </label>
<option value="staggered" translate>Staggered File Versioning</option> </div>
<option value="external" translate>External File Versioning</option> <div class="radio">
</select> <label>
</div> <input type="radio" ng-model="currentFolder.fileVersioningSelector" value="simple"> <span translate>Simple File Versioning</span>
<div class="form-group" ng-if="currentFolder.fileVersioningSelector=='trashcan'" ng-class="{'has-error': folderEditor.trashcanClean.$invalid && folderEditor.trashcanClean.$dirty}"> </label>
<p translate class="help-block">Files are moved to .stversions folder when replaced or deleted by Syncthing.</p> </div>
<label translate for="trashcanClean">Clean out after</label> <div class="radio">
<div class="input-group"> <label>
<input name="trashcanClean" id="trashcanClean" class="form-control text-right" type="number" ng-model="currentFolder.trashcanClean" required min="0"></input> <input type="radio" ng-model="currentFolder.fileVersioningSelector" value="staggered"> <span translate>Staggered File Versioning</span>
<div class="input-group-addon">days</div> </label>
</div>
<div class="radio">
<label>
<input type="radio" ng-model="currentFolder.fileVersioningSelector" value="external"> <span translate>External File Versioning</span>
</label>
</div> </div>
<p class="help-block">
<span translate ng-if="folderEditor.trashcanClean.$valid || folderEditor.trashcanClean.$pristine">The number of days to keep files in the trash can. Zero means forever.</span>
<span translate ng-if="folderEditor.trashcanClean.$error.required && folderEditor.trashcanClean.$dirty">The number of days must be a number and cannot be blank.</span>
<span translate ng-if="folderEditor.trashcanClean.$error.min && folderEditor.trashcanClean.$dirty">A negative number of days doesn't make sense.</span>
</p>
</div> </div>
<div class="form-group" ng-if="currentFolder.fileVersioningSelector=='simple'" ng-class="{'has-error': folderEditor.simpleKeep.$invalid && folderEditor.simpleKeep.$dirty}"> <div class="form-group" ng-if="currentFolder.fileVersioningSelector=='simple'" ng-class="{'has-error': folderEditor.simpleKeep.$invalid && folderEditor.simpleKeep.$dirty}">
<p translate class="help-block">Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.</p> <p translate class="help-block">Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.</p>
@@ -768,13 +735,11 @@
<div class="form-group"> <div class="form-group">
<label translate for="devices">Share With Devices</label> <label translate for="devices">Share With Devices</label>
<p translate class="help-block">Select the devices to share this folder with.</p> <p translate class="help-block">Select the devices to share this folder with.</p>
<div class="container-fluid"> <div class="three-columns">
<div class="row" ng-repeat="deviceGroup in otherDevices() | group:3"> <div class="checkbox" ng-repeat="device in otherDevices()">
<div class="checkbox col-md-4" ng-repeat="device in deviceGroup"> <label>
<label> <input type="checkbox" ng-model="currentFolder.selectedDevices[device.deviceID]"> {{deviceName(device)}}
<input type="checkbox" ng-model="currentFolder.selectedDevices[device.deviceID]"> {{deviceName(device)}} </label>
</label>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -785,10 +750,10 @@
<div translate ng-show="!editingExisting">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.</div> <div translate ng-show="!editingExisting">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.</div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="saveFolder()" ng-disabled="folderEditor.$invalid"><span class="glyphicon glyphicon-ok"></span>&nbsp;<span translate>Save</span></button> <button type="button" class="btn btn-primary btn-sm" ng-click="saveFolder()" ng-disabled="folderEditor.$invalid"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Save</span></button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&nbsp;<span translate>Close</span></button> <button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>Close</span></button>
<button ng-if="editingExisting" type="button" class="btn btn-danger pull-left btn-sm" ng-click="deleteFolder()"><span class="glyphicon glyphicon-minus"></span>&nbsp;<span translate>Delete</span></button> <button ng-if="editingExisting" type="button" class="btn btn-danger pull-left btn-sm" ng-click="deleteFolder()"><span class="glyphicon glyphicon-minus"></span>&emsp;<span translate>Delete</span></button>
<button id="editIgnoresButton" ng-if="editingExisting" type="button" class="btn btn-default pull-left btn-sm" ng-click="editIgnores()"><span class="glyphicon glyphicon-eye-close"></span>&nbsp;<span translate>Ignore Patterns</span></button> <button id="editIgnoresButton" ng-if="editingExisting" type="button" class="btn btn-default pull-left btn-sm" ng-click="editIgnores()"><span class="glyphicon glyphicon-eye-close"></span>&emsp;<span translate>Ignore Patterns</span></button>
</div> </div>
</div> </div>
</div> </div>
@@ -808,7 +773,7 @@
<hr/> <hr/>
<p class="small"><span translate>Quick guide to supported patterns</span> (<a href="http://docs.syncthing.net/users/ignoring.html" target="_blank" translate>full documentation</a>):</p> <p class="small"><span translate>Quick guide to supported patterns</span> (<a href="https://github.com/syncthing/syncthing/wiki/Ignoring-Files" target="_blank" translate>full documentation</a>):</p>
<dl class="dl-horizontal dl-narrow small"> <dl class="dl-horizontal dl-narrow small">
<dt><code>!</code></dt> <dd><span translate>Inversion of the given condition (i.e. do not exclude)</span></dd> <dt><code>!</code></dt> <dd><span translate>Inversion of the given condition (i.e. do not exclude)</span></dd>
<dt><code>*</code></dt> <dd><span translate>Single level wildcard (matches within a directory only)</span></dd> <dt><code>*</code></dt> <dd><span translate>Single level wildcard (matches within a directory only)</span></dd>
@@ -818,8 +783,8 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<div class="pull-left"><span translate>Editing</span> <code>{{currentFolder.path}}{{system.pathSeparator}}.stignore</code></div> <div class="pull-left"><span translate>Editing</span> <code>{{currentFolder.path}}{{system.pathSeparator}}.stignore</code></div>
<button type="button" class="btn btn-primary btn-sm" data-dismiss="modal" ng-click="saveIgnores()"><span class="glyphicon glyphicon-ok"></span>&nbsp;<span translate>Save</span></button> <button type="button" class="btn btn-primary btn-sm" data-dismiss="modal" ng-click="saveIgnores()"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Save</span></button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&nbsp;<span translate>Close</span></button> <button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>Close</span></button>
</div> </div>
</div> </div>
</div> </div>
@@ -844,7 +809,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label translate for="ListenAddressStr">Sync Protocol Listen Addresses</label> <label translate for="ListenAddressStr">Sync Protocol Listen Addresses</label>
<input id="ListenAddressStr" class="form-control" type="text" ng-model="tmpOptions._listenAddressStr"> <input id="ListenAddressStr" class="form-control" type="text" ng-model="tmpOptions.listenAddressStr">
</div> </div>
<div class="form-group"> <div class="form-group">
<label translate for="MaxRecvKbps">Incoming Rate Limit (KiB/s)</label> <label translate for="MaxRecvKbps">Incoming Rate Limit (KiB/s)</label>
@@ -888,7 +853,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label translate for="GlobalAnnServersStr">Global Discovery Server</label> <label translate for="GlobalAnnServersStr">Global Discovery Server</label>
<input ng-disabled="!tmpOptions.globalAnnounceEnabled" id="GlobalAnnServersStr" class="form-control" type="text" ng-model="tmpOptions._globalAnnounceServersStr"> <input ng-disabled="!tmpOptions.globalAnnounceEnabled" id="GlobalAnnServersStr" class="form-control" type="text" ng-model="tmpOptions.globalAnnounceServersStr">
</div> </div>
</div> </div>
@@ -940,8 +905,8 @@
</form> </form>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="saveSettings()"><span class="glyphicon glyphicon-ok"></span>&nbsp;<span translate>Save</span></button> <button type="button" class="btn btn-primary btn-sm" ng-click="saveSettings()"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Save</span></button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&nbsp;<span translate>Close</span></button> <button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>Close</span></button>
</div> </div>
</div> </div>
</div> </div>
@@ -962,8 +927,8 @@
<pre ng-if="reportPreview"><small>{{reportData | json}}</small></pre> <pre ng-if="reportPreview"><small>{{reportData | json}}</small></pre>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-success btn-sm" ng-click="acceptUR()"><span class="glyphicon glyphicon-ok"></span>&nbsp;<span translate>Yes</span></button> <button type="button" class="btn btn-success btn-sm" ng-click="acceptUR()"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Yes</span></button>
<button type="button" class="btn btn-danger btn-sm" ng-click="declineUR()"><span class="glyphicon glyphicon-remove"></span>&nbsp;<span translate>No</span></button> <button type="button" class="btn btn-danger btn-sm" ng-click="declineUR()"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>No</span></button>
</div> </div>
</div> </div>
</div> </div>
@@ -983,7 +948,7 @@
<pre><small>{{reportData | json}}</small></pre> <pre><small>{{reportData | json}}</small></pre>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-success btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-ok"></span>&nbsp;<span translate>OK</span></button> <button type="button" class="btn btn-success btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>OK</span></button>
</div> </div>
</div> </div>
</div> </div>
@@ -1004,7 +969,7 @@
<table class="table table-striped table-condensed"> <table class="table table-striped table-condensed">
<tr dir-paginate="f in needed | itemsPerPage: neededPageSize" current-page="neededCurrentPage" total-items="neededTotal" pagination-id="needed"> <tr dir-paginate="f in needed | itemsPerPage: neededPageSize" current-page="neededCurrentPage" total-items="neededTotal">
<!-- Icon --> <!-- Icon -->
<td class="small-data"><span class="glyphicon glyphicon-{{needIcons[f.action]}}"></span> {{needActions[f.action]}}</td> <td class="small-data"><span class="glyphicon glyphicon-{{needIcons[f.action]}}"></span> {{needActions[f.action]}}</td>
@@ -1014,7 +979,7 @@
<a href="" ng-click="bumpFile(neededFolder, f.name)" title="{{'Move to top of queue' | translate}}"> <a href="" ng-click="bumpFile(neededFolder, f.name)" title="{{'Move to top of queue' | translate}}">
<span class="glyphicon glyphicon-eject"></span> <span class="glyphicon glyphicon-eject"></span>
</a> </a>
<span title="{{f.name}}">&nbsp;{{f.name | basename}}</span> <span title="{{f.name}}">&ensp;{{f.name | basename}}</span>
</td> </td>
<!-- Size/Progress --> <!-- Size/Progress -->
@@ -1037,37 +1002,15 @@
</tr> </tr>
</table> </table>
<dir-pagination-controls on-page-change="neededPageChanged(newPageNumber)" pagination-id="needed"></dir-pagination-controls> <dir-pagination-controls on-page-change="neededPageChanged(newPageNumber)"></dir-pagination-controls>
<ul class="pagination pull-right"> <ul class="pagination pull-right">
<li ng-repeat="option in [10, 25, 50]" ng-class="{ active: neededPageSize == option }"> <li ng-repeat="option in [10, 20, 30, 50, 100]" ng-class="{ active: neededPageSize == option }">
<a href="#" ng-click="neededChangePageSize(option)">{{option}}</a> <a href="#" ng-click="neededChangePageSize(option)">{{option}}</a>
<li> <li>
</ul> </ul>
<div class="clearfix"></div> <div class="clearfix"></div>
</modal> </modal>
<!-- Failed Items modal -->
<modal id="failed" large="yes" status="warning" icon="exclamation-sign" close="yes" title="{{'Failed Items' | translate}}">
<p>
<span translate>The following items could not be synchronized.</span>
<span translate>They are retried automatically and will be synced when the error is resolved.</span>
</p>
<table class="table table-striped table-condensed">
<tr dir-paginate="e in failedCurrent | itemsPerPage: failedPageSize" current-page="failedCurrentPage" pagination-id="failed">
<td><abbr title="{{e.path}}">{{e.path | basename}}</abbr></td>
<td><abbr title="{{e.error}}">{{e.error | lastErrorComponent}}</abbr></td>
</tr>
</table>
<dir-pagination-controls on-page-change="failedPageChanged(newPageNumber)" pagination-id="failed"></dir-pagination-controls>
<ul class="pagination pull-right">
<li ng-repeat="option in [10, 25, 50]" ng-class="{ active: failedPageSize == option }">
<a href="#" ng-click="failedChangePageSize(option)">{{option}}</a>
<li>
</ul>
<div class="clearfix"></div>
</modal>
<!-- About modal --> <!-- About modal -->
<modal id="about" large="yes" close="yes" status="info" title="{{'About' | translate}}"> <modal id="about" large="yes" close="yes" status="info" title="{{'About' | translate}}">
@@ -1081,10 +1024,8 @@
<li class="auto-generated">Aaron Bieber</li> <li class="auto-generated">Aaron Bieber</li>
<li class="auto-generated">Alexander Graf</li> <li class="auto-generated">Alexander Graf</li>
<li class="auto-generated">Andrew Dunham</li> <li class="auto-generated">Andrew Dunham</li>
<li class="auto-generated">Antony Male</li>
<li class="auto-generated">Arthur Axel fREW Schmidt</li> <li class="auto-generated">Arthur Axel fREW Schmidt</li>
<li class="auto-generated">Audrius Butkevicius</li> <li class="auto-generated">Audrius Butkevicius</li>
<li class="auto-generated">Bart De Vries</li>
<li class="auto-generated">Ben Curthoys</li> <li class="auto-generated">Ben Curthoys</li>
<li class="auto-generated">Ben Schulz</li> <li class="auto-generated">Ben Schulz</li>
<li class="auto-generated">Ben Sidhom</li> <li class="auto-generated">Ben Sidhom</li>
@@ -1093,21 +1034,17 @@
<li class="auto-generated">Caleb Callaway</li> <li class="auto-generated">Caleb Callaway</li>
<li class="auto-generated">Carsten Hagemann</li> <li class="auto-generated">Carsten Hagemann</li>
<li class="auto-generated">Cathryne Linenweaver</li> <li class="auto-generated">Cathryne Linenweaver</li>
<li class="auto-generated">Chris Howie</li>
<li class="auto-generated">Chris Joel</li> <li class="auto-generated">Chris Joel</li>
<li class="auto-generated">Colin Kennedy</li> <li class="auto-generated">Colin Kennedy</li>
<li class="auto-generated">Daniel Bergmann</li>
<li class="auto-generated">Daniel Martí</li> <li class="auto-generated">Daniel Martí</li>
<li class="auto-generated">Dennis Wilson</li> <li class="auto-generated">Dennis Wilson</li>
<li class="auto-generated">Dominik Heidler</li> <li class="auto-generated">Dominik Heidler</li>
<li class="auto-generated">Elias Jarlebring</li> <li class="auto-generated">Elias Jarlebring</li>
<li class="auto-generated">Emil Hessman</li> <li class="auto-generated">Emil Hessman</li>
<li class="auto-generated">Erik Meitner</li>
<li class="auto-generated">Federico Castagnini</li> <li class="auto-generated">Federico Castagnini</li>
<li class="auto-generated">Felix Ableitner</li> <li class="auto-generated">Felix Ableitner</li>
<li class="auto-generated">Felix Unterpaintner</li> <li class="auto-generated">Felix Unterpaintner</li>
<li class="auto-generated">Francois-Xavier Gsell</li> <li class="auto-generated">Francois-Xavier Gsell</li>
<li class="auto-generated">Frank Isemann</li>
<li class="auto-generated">Gilli Sigurdsson</li> <li class="auto-generated">Gilli Sigurdsson</li>
<li class="auto-generated">Jakob Borg</li> <li class="auto-generated">Jakob Borg</li>
<li class="auto-generated">James Patterson</li> <li class="auto-generated">James Patterson</li>
@@ -1157,101 +1094,18 @@
</ul> </ul>
</modal> </modal>
<!-- Advanced modal -->
<div id="advanced" class="modal fade" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header alert alert-danger">
<h4 translate class="modal-title">Advanced Configuration</h4>
</div>
<div class="modal-body">
<p class="text-danger">
<b translate>Be careful!</b>
<span translate>Incorrect configuration may damage your folder contents and render Syncthing inoperable.</span>
</p>
<div class="panel-group" id="advancedAccordion" role="tablist" aria-multiselectable="true">
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="guiHeading" data-toggle="collapse" data-parent="#advancedAccordion" href="#guiConfig" aria-expanded="true" aria-controls="guiConfig" style="cursor: pointer">
<h4 class="panel-title" translate>GUI</h4>
</div>
<div id="guiConfig" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="guiHeading">
<div class="panel-body">
<form class="form-horizontal" role="form">
<div ng-repeat="(key, value) in config.gui" ng-init="type = inputTypeFor(key, value)" ng-if="type != 'skip'" class="form-group">
<label for="guiInput{{$index}}" class="col-sm-4 control-label">{{key}}</label>
<div class="col-sm-8">
<input id="guiInput{{$index}}" class="form-control" type="{{type}}" ng-model="config.gui[key]" />
</div>
</div>
</form>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="optionsHeading" data-toggle="collapse" data-parent="#advancedAccordion" href="#optionsConfig" aria-expanded="true" aria-controls="optionsConfig" style="cursor: pointer">
<h4 class="panel-title" translate>Options</h4>
</div>
<div id="optionsConfig" class="panel-collapse collapse" role="tabpanel" aria-labelledby="optionsHeading">
<div class="panel-body">
<form class="form-horizontal" role="form">
<div ng-repeat="(key, value) in config.options" ng-if="inputTypeFor(key, value) != 'skip'" class="form-group">
<label for="optionsInput{{$index}}" class="col-sm-4 control-label">{{key}}</label>
<div class="col-sm-8">
<input id="optionsInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="config.options[key]" />
</div>
</div>
</form>
</div>
</div>
</div>
<div class="panel panel-default" ng-repeat="(folder, _) in folders">
<div class="panel-heading" role="tab" id="folder{{folder}}Heading" data-toggle="collapse" data-parent="#advancedAccordion" href="#folder{{folder}}Config" aria-expanded="true" aria-controls="folder{{folder}}Config" style="cursor: pointer">
<h4 class="panel-title">
<span translate>Folder</span> "{{folder}}"
</h4>
</div>
<div id="folder{{folder}}Config" class="panel-collapse collapse" role="tabpanel" aria-labelledby="folder{{folder}}Heading">
<div class="panel-body">
<form class="form-horizontal" role="form">
<div ng-repeat="(key, value) in folders[folder]" ng-if="inputTypeFor(key, value) != 'skip'" class="form-group">
<label for="foldre{{folder}}Input{{$index}}" class="col-sm-4 control-label">{{key}}</label>
<div class="col-sm-8">
<input id="folder{{folder}}Input{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="folders[folder][key]" />
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="saveAdvanced()"><span class="glyphicon glyphicon-ok"></span>&nbsp;<span translate>Save</span></button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&nbsp;<span translate>Close</span></button>
</div>
</div>
</div>
</div>
</div>
<!-- vendor scripts --> <!-- vendor scripts -->
<script src="vendor/jquery/jquery-2.0.3.min.js"></script>
<script src="vendor/angular/angular.min.js"></script> <script src="vendor/angular/angular.min.js"></script>
<script src="vendor/angular/angular-translate.min.js"></script> <script src="vendor/angular/angular-translate.min.js"></script>
<script src="vendor/angular/angular-translate-loader.min.js"></script> <script src="vendor/angular/angular-translate-loader.min.js"></script>
<script src="vendor/angular/angular-dirPagination.js"></script> <script src="vendor/angular/angular-dirPagination.js"></script>
<script src="vendor/jquery/jquery-2.0.3.min.js"></script>
<script src="vendor/bootstrap/js/bootstrap.min.js"></script> <script src="vendor/bootstrap/js/bootstrap.min.js"></script>
<!-- / vendor scripts --> <!-- / vendor scripts -->
<!-- gui application code --> <!-- gui application code -->
<script src="scripts/syncthing/core/module.js"></script> <script src="scripts/syncthing/core/module.js"></script>
<script src="scripts/syncthing/core/services/events.js"></script> <script src="scripts/syncthing/core/controllers/eventController.js"></script>
<script src="scripts/syncthing/core/controllers/syncthingController.js"></script> <script src="scripts/syncthing/core/controllers/syncthingController.js"></script>
<script src="scripts/syncthing/core/directives/identiconDirective.js"></script> <script src="scripts/syncthing/core/directives/identiconDirective.js"></script>
<script src="scripts/syncthing/core/directives/languageSelectDirective.js"></script> <script src="scripts/syncthing/core/directives/languageSelectDirective.js"></script>
@@ -1259,20 +1113,14 @@
<script src="scripts/syncthing/core/directives/uniqueFolderDirective.js"></script> <script src="scripts/syncthing/core/directives/uniqueFolderDirective.js"></script>
<script src="scripts/syncthing/core/directives/validDeviceidDirective.js"></script> <script src="scripts/syncthing/core/directives/validDeviceidDirective.js"></script>
<script src="scripts/syncthing/core/directives/popoverDirective.js"></script> <script src="scripts/syncthing/core/directives/popoverDirective.js"></script>
<script src="scripts/syncthing/core/directives/selectOnClickDirective.js"></script>
<script src="scripts/syncthing/core/filters/alwaysNumberFilter.js"></script> <script src="scripts/syncthing/core/filters/alwaysNumberFilter.js"></script>
<script src="scripts/syncthing/core/filters/basenameFilter.js"></script> <script src="scripts/syncthing/core/filters/basenameFilter.js"></script>
<script src="scripts/syncthing/core/filters/binaryFilter.js"></script> <script src="scripts/syncthing/core/filters/binaryFilter.js"></script>
<script src="scripts/syncthing/core/filters/durationFilter.js"></script> <script src="scripts/syncthing/core/filters/durationFilter.js"></script>
<script src="scripts/syncthing/core/filters/groupFilter.js"></script>
<script src="scripts/syncthing/core/filters/naturalFilter.js"></script> <script src="scripts/syncthing/core/filters/naturalFilter.js"></script>
<script src="scripts/syncthing/core/filters/lastErrorComponentFilter.js"></script>
<script src="scripts/syncthing/core/services/filterStabilize.js"></script>
<script src="scripts/syncthing/core/services/localeService.js"></script> <script src="scripts/syncthing/core/services/localeService.js"></script>
<script src="scripts/syncthing/core/services/memoize.js"></script>
<script src="assets/lang/valid-langs.js"></script> <script src="assets/lang/valid-langs.js"></script>
<script src="assets/lang/prettyprint.js"></script>
<script src="scripts/syncthing/app.js"></script> <script src="scripts/syncthing/app.js"></script>
<!-- / gui application code --> <!-- / gui application code -->
+3 -9
View File
@@ -11,14 +11,16 @@
var syncthing = angular.module('syncthing', [ var syncthing = angular.module('syncthing', [
'angularUtils.directives.dirPagination', 'angularUtils.directives.dirPagination',
'pascalprecht.translate', 'pascalprecht.translate',
'syncthing.core' 'syncthing.core'
]); ]);
var urlbase = 'rest'; var urlbase = 'rest';
var guiVersion = null; var guiVersion = null;
var deviceId = null;
syncthing.config(function ($httpProvider, $translateProvider, LocaleServiceProvider) { syncthing.config(function ($httpProvider, $translateProvider, LocaleServiceProvider) {
$httpProvider.defaults.xsrfHeaderName = 'X-CSRF-Token';
$httpProvider.defaults.xsrfCookieName = 'CSRF-Token';
$httpProvider.interceptors.push(function () { $httpProvider.interceptors.push(function () {
return { return {
response: function (response) { response: function (response) {
@@ -28,14 +30,6 @@ syncthing.config(function ($httpProvider, $translateProvider, LocaleServiceProvi
} else if (guiVersion != responseVersion) { } else if (guiVersion != responseVersion) {
document.location.reload(true); document.location.reload(true);
} }
if (!deviceId) {
deviceId = response.headers()['x-syncthing-id'];
if (deviceId) {
var deviceIdShort = deviceId.substring(0, 5);
$httpProvider.defaults.xsrfHeaderName = 'X-CSRF-Token-' + deviceIdShort;
$httpProvider.defaults.xsrfCookieName = 'CSRF-Token-' + deviceIdShort;
}
}
return response; return response;
} }
}; };
@@ -0,0 +1,55 @@
var debugEvents = false;
angular.module('syncthing.core')
.controller('EventController', function ($scope, $http) {
'use strict';
$scope.lastEvent = null;
var lastID = 0;
var successFn = function (data) {
// When Syncthing restarts while the long polling connection is in
// progress the browser on some platforms returns a 200 (since the
// headers has been flushed with the return code 200), with no data.
// This basically means that the connection has been reset, and the call
// was not actually successful.
if (!data) {
errorFn(data);
return;
}
$scope.$emit('UIOnline');
if (lastID > 0) {
data.forEach(function (event) {
if (debugEvents) {
console.log("event", event.id, event.type, event.data);
}
$scope.$emit(event.type, event);
});
}
$scope.lastEvent = data[data.length - 1];
lastID = $scope.lastEvent.id;
setTimeout(function () {
$http.get(urlbase + '/events?since=' + lastID)
.success(successFn)
.error(errorFn);
}, 500);
};
var errorFn = function (data) {
$scope.$emit('UIOffline');
setTimeout(function () {
$http.get(urlbase + '/events?limit=1')
.success(successFn)
.error(errorFn);
}, 1000);
};
$http.get(urlbase + '/events?limit=1')
.success(successFn)
.error(errorFn);
});
+68 -157
View File
@@ -2,7 +2,7 @@ angular.module('syncthing.core')
.config(function($locationProvider) { .config(function($locationProvider) {
$locationProvider.html5Mode(true).hashPrefix('!'); $locationProvider.html5Mode(true).hashPrefix('!');
}) })
.controller('SyncthingController', function ($scope, $http, $location, LocaleService, Events) { .controller('SyncthingController', function ($scope, $http, $location, LocaleService) {
'use strict'; 'use strict';
// private/helper definitions // private/helper definitions
@@ -15,10 +15,10 @@ angular.module('syncthing.core')
function initController() { function initController() {
LocaleService.autoConfigLocale(); LocaleService.autoConfigLocale();
setInterval($scope.refresh, 10000); setInterval($scope.refresh, 10000);
Events.start();
} }
// public/scope definitions
// pubic/scope definitions
$scope.completion = {}; $scope.completion = {};
$scope.config = {}; $scope.config = {};
@@ -44,12 +44,6 @@ angular.module('syncthing.core')
$scope.neededTotal = 0; $scope.neededTotal = 0;
$scope.neededCurrentPage = 1; $scope.neededCurrentPage = 1;
$scope.neededPageSize = 10; $scope.neededPageSize = 10;
$scope.foldersTotalLocalBytes = 0;
$scope.foldersTotalLocalFiles = 0;
$scope.failed = {};
$scope.failedCurrentPage = 1;
$scope.failedCurrentFolder = undefined;
$scope.failedPageSize = 10;
$(window).bind('beforeunload', function () { $(window).bind('beforeunload', function () {
navigatingAway = true; navigatingAway = true;
@@ -72,7 +66,7 @@ angular.module('syncthing.core')
'touch': 'asterisk' 'touch': 'asterisk'
}; };
$scope.$on(Events.ONLINE, function () { $scope.$on('UIOnline', function (event, arg) {
if (online && !restarting) { if (online && !restarting) {
return; return;
} }
@@ -106,7 +100,7 @@ angular.module('syncthing.core')
$('#shutdown').modal('hide'); $('#shutdown').modal('hide');
}); });
$scope.$on(Events.OFFLINE, function () { $scope.$on('UIOffline', function (event, arg) {
if (navigatingAway || !online) { if (navigatingAway || !online) {
return; return;
} }
@@ -131,7 +125,7 @@ angular.module('syncthing.core')
if (!restarting) { if (!restarting) {
if (arg.status === 0) { if (arg.status === 0) {
// A network error, not an HTTP error // A network error, not an HTTP error
$scope.$emit(Events.OFFLINE); $scope.$emit('UIOffline');
} else if (arg.status >= 400 && arg.status <= 599) { } else if (arg.status >= 400 && arg.status <= 599) {
// A genuine HTTP error // A genuine HTTP error
$('#networkError').modal('hide'); $('#networkError').modal('hide');
@@ -142,31 +136,28 @@ angular.module('syncthing.core')
} }
}); });
$scope.$on(Events.STATE_CHANGED, function (event, arg) { $scope.$on('StateChanged', function (event, arg) {
var data = arg.data; var data = arg.data;
if ($scope.model[data.folder]) { if ($scope.model[data.folder]) {
$scope.model[data.folder].state = data.to; $scope.model[data.folder].state = data.to;
$scope.model[data.folder].error = data.error;
// If a folder has started syncing, then any old list of
// errors is obsolete. We may get a new list of errors very
// shortly though.
if (data.to === 'syncing') {
$scope.failed[data.folder] = [];
}
} }
}); });
$scope.$on(Events.LOCAL_INDEX_UPDATED, function (event, arg) { $scope.$on('LocalIndexUpdated', function (event, arg) {
var data = arg.data;
refreshFolderStats(); refreshFolderStats();
}); });
$scope.$on(Events.DEVICE_DISCONNECTED, function (event, arg) { $scope.$on('RemoteIndexUpdated', function (event, arg) {
// Nothing
});
$scope.$on('DeviceDisconnected', function (event, arg) {
delete $scope.connections[arg.data.id]; delete $scope.connections[arg.data.id];
refreshDeviceStats(); refreshDeviceStats();
}); });
$scope.$on(Events.DEVICE_CONNECTED, function (event, arg) { $scope.$on('DeviceConnected', function (event, arg) {
if (!$scope.connections[arg.data.id]) { if (!$scope.connections[arg.data.id]) {
$scope.connections[arg.data.id] = { $scope.connections[arg.data.id] = {
inbps: 0, inbps: 0,
@@ -181,7 +172,7 @@ angular.module('syncthing.core')
} }
}); });
$scope.$on('ConfigLoaded', function () { $scope.$on('ConfigLoaded', function (event) {
if ($scope.config.options.urAccepted === 0) { if ($scope.config.options.urAccepted === 0) {
// If usage reporting has been neither accepted nor declined, // If usage reporting has been neither accepted nor declined,
// we want to ask the user to make a choice. But we don't want // we want to ask the user to make a choice. But we don't want
@@ -201,15 +192,15 @@ angular.module('syncthing.core')
} }
}); });
$scope.$on(Events.DEVICE_REJECTED, function (event, arg) { $scope.$on('DeviceRejected', function (event, arg) {
$scope.deviceRejections[arg.data.device] = arg; $scope.deviceRejections[arg.data.device] = arg;
}); });
$scope.$on(Events.FOLDER_REJECTED, function (event, arg) { $scope.$on('FolderRejected', function (event, arg) {
$scope.folderRejections[arg.data.folder + "-" + arg.data.device] = arg; $scope.folderRejections[arg.data.folder + "-" + arg.data.device] = arg;
}); });
$scope.$on(Events.CONFIG_SAVED, function (event, arg) { $scope.$on('ConfigSaved', function (event, arg) {
updateLocalConfig(arg.data); updateLocalConfig(arg.data);
$http.get(urlbase + '/system/config/insync').success(function (data) { $http.get(urlbase + '/system/config/insync').success(function (data) {
@@ -217,7 +208,7 @@ angular.module('syncthing.core')
}).error($scope.emitHTTPError); }).error($scope.emitHTTPError);
}); });
$scope.$on(Events.DOWNLOAD_PROGRESS, function (event, arg) { $scope.$on('DownloadProgress', function (event, arg) {
var stats = arg.data; var stats = arg.data;
var progress = {}; var progress = {};
for (var folder in stats) { for (var folder in stats) {
@@ -262,12 +253,12 @@ angular.module('syncthing.core')
console.log("DownloadProgress", $scope.progress); console.log("DownloadProgress", $scope.progress);
}); });
$scope.$on(Events.FOLDER_SUMMARY, function (event, arg) { $scope.$on('FolderSummary', function (event, arg) {
var data = arg.data; var data = arg.data;
$scope.model[data.folder] = data.summary; $scope.model[data.folder] = data.summary;
}); });
$scope.$on(Events.FOLDER_COMPLETION, function (event, arg) { $scope.$on('FolderCompletion', function (event, arg) {
var data = arg.data; var data = arg.data;
if (!$scope.completion[data.device]) { if (!$scope.completion[data.device]) {
$scope.completion[data.device] = {}; $scope.completion[data.device] = {};
@@ -286,11 +277,6 @@ angular.module('syncthing.core')
$scope.completion[data.device]._total = tot / cnt; $scope.completion[data.device]._total = tot / cnt;
}); });
$scope.$on(Events.FOLDER_ERRORS, function (event, arg) {
var data = arg.data;
$scope.failed[data.folder] = data.errors;
});
$scope.emitHTTPError = function (data, status, headers, config) { $scope.emitHTTPError = function (data, status, headers, config) {
$scope.$emit('HTTPError', {data: data, status: status, headers: headers, config: config}); $scope.$emit('HTTPError', {data: data, status: status, headers: headers, config: config});
}; };
@@ -314,8 +300,8 @@ angular.module('syncthing.core')
var hasConfig = !isEmptyObject($scope.config); var hasConfig = !isEmptyObject($scope.config);
$scope.config = config; $scope.config = config;
$scope.config.options._listenAddressStr = $scope.config.options.listenAddress.join(', '); $scope.config.options.listenAddressStr = $scope.config.options.listenAddress.join(', ');
$scope.config.options._globalAnnounceServersStr = $scope.config.options.globalAnnounceServers.join(', '); $scope.config.options.globalAnnounceServersStr = $scope.config.options.globalAnnounceServers.join(', ');
$scope.devices = $scope.config.devices; $scope.devices = $scope.config.devices;
$scope.devices.forEach(function (deviceCfg) { $scope.devices.forEach(function (deviceCfg) {
@@ -349,15 +335,6 @@ angular.module('syncthing.core')
} }
} }
$scope.announceServersFailed = failed; $scope.announceServersFailed = failed;
$scope.foldersTotalLocalBytes = 0;
$scope.foldersTotalLocalFiles = 0;
for (var f in $scope.model) {
$scope.foldersTotalLocalBytes += $scope.model[f].localBytes;
$scope.foldersTotalLocalFiles += $scope.model[f].localFiles;
};
console.log("refreshSystem", data); console.log("refreshSystem", data);
}).error($scope.emitHTTPError); }).error($scope.emitHTTPError);
} }
@@ -466,7 +443,7 @@ angular.module('syncthing.core')
} else { } else {
return 'sync'; return 'sync';
} }
} };
function parseNeeded(data) { function parseNeeded(data) {
var merged = []; var merged = [];
@@ -497,15 +474,7 @@ angular.module('syncthing.core')
$scope.neededChangePageSize = function (perpage) { $scope.neededChangePageSize = function (perpage) {
$scope.neededPageSize = perpage; $scope.neededPageSize = perpage;
refreshNeed($scope.neededFolder); refreshNeed($scope.neededFolder);
}; }
$scope.failedPageChanged = function (page) {
$scope.failedCurrentPage = page;
};
$scope.failedChangePageSize = function (perpage) {
$scope.failedPageSize = perpage;
};
var refreshDeviceStats = debounce(function () { var refreshDeviceStats = debounce(function () {
$http.get(urlbase + "/stats/device").success(function (data) { $http.get(urlbase + "/stats/device").success(function (data) {
@@ -541,11 +510,6 @@ angular.module('syncthing.core')
return 'unknown'; return 'unknown';
} }
// after restart syncthing process state may be empty
if (!$scope.model[folderCfg.id].state) {
return 'unknown';
}
if (folderCfg.devices.length <= 1) { if (folderCfg.devices.length <= 1) {
return 'unshared'; return 'unshared';
} }
@@ -554,36 +518,42 @@ angular.module('syncthing.core')
return 'stopped'; return 'stopped';
} }
var state = '' + $scope.model[folderCfg.id].state; if ($scope.model[folderCfg.id].state == 'error') {
if (state === 'error') {
return 'stopped'; // legacy, the state is called "stopped" in the GUI return 'stopped'; // legacy, the state is called "stopped" in the GUI
} }
if (state === 'idle' && $scope.model[folderCfg.id].needFiles > 0) {
return 'outofsync';
}
return state; return '' + $scope.model[folderCfg.id].state;
}; };
$scope.folderClass = function (folderCfg) { $scope.folderClass = function (folderCfg) {
var status = $scope.folderStatus(folderCfg); if (typeof $scope.model[folderCfg.id] === 'undefined') {
// Unknown
if (status == 'idle') {
return 'success';
}
if (status == 'syncing' || status == 'scanning') {
return 'primary';
}
if (status === 'unknown') {
return 'info'; return 'info';
} }
if (status === 'unshared') {
if (folderCfg.devices.length <= 1) {
// Unshared
return 'warning'; return 'warning';
} }
if (status === 'stopped' || status === 'outofsync' || status === 'error') {
if ($scope.model[folderCfg.id].invalid !== '') {
// Errored
return 'danger'; return 'danger';
} }
var state = '' + $scope.model[folderCfg.id].state;
if (state == 'idle') {
return 'success';
}
if (state == 'syncing') {
return 'primary';
}
if (state == 'scanning') {
return 'primary';
}
if (state == 'error') {
return 'danger';
}
return 'info'; return 'info';
}; };
@@ -746,7 +716,7 @@ angular.module('syncthing.core')
$scope.config.gui = angular.copy($scope.tmpGUI); $scope.config.gui = angular.copy($scope.tmpGUI);
['listenAddress', 'globalAnnounceServers'].forEach(function (key) { ['listenAddress', 'globalAnnounceServers'].forEach(function (key) {
$scope.config.options[key] = $scope.config.options["_" + key + "Str"].split(/[ ,]+/).map(function (x) { $scope.config.options[key] = $scope.config.options[key + "Str"].split(/[ ,]+/).map(function (x) {
return x.trim(); return x.trim();
}); });
}); });
@@ -757,11 +727,6 @@ angular.module('syncthing.core')
$('#settings').modal("hide"); $('#settings').modal("hide");
}; };
$scope.saveAdvanced = function () {
$scope.saveConfig();
$('#advanced').modal("hide");
};
$scope.restart = function () { $scope.restart = function () {
restarting = true; restarting = true;
$('#restarting').modal(); $('#restarting').modal();
@@ -812,7 +777,7 @@ angular.module('syncthing.core')
$scope.currentDevice = $.extend({}, deviceCfg); $scope.currentDevice = $.extend({}, deviceCfg);
$scope.editingExisting = true; $scope.editingExisting = true;
$scope.editingSelf = (deviceCfg.deviceID == $scope.myID); $scope.editingSelf = (deviceCfg.deviceID == $scope.myID);
$scope.currentDevice._addressesStr = deviceCfg.addresses.join(', '); $scope.currentDevice.addressesStr = deviceCfg.addresses.join(', ');
if (!$scope.editingSelf) { if (!$scope.editingSelf) {
$scope.currentDevice.selectedFolders = {}; $scope.currentDevice.selectedFolders = {};
$scope.deviceFolders($scope.currentDevice).forEach(function (folder) { $scope.deviceFolders($scope.currentDevice).forEach(function (folder) {
@@ -834,7 +799,7 @@ angular.module('syncthing.core')
}) })
.then(function () { .then(function () {
$scope.currentDevice = { $scope.currentDevice = {
_addressesStr: 'dynamic', addressesStr: 'dynamic',
compression: 'metadata', compression: 'metadata',
introducer: false, introducer: false,
selectedFolders: {} selectedFolders: {}
@@ -879,7 +844,7 @@ angular.module('syncthing.core')
$scope.addNewDeviceID = function (device) { $scope.addNewDeviceID = function (device) {
var deviceCfg = { var deviceCfg = {
deviceID: device, deviceID: device,
_addressesStr: 'dynamic', addressesStr: 'dynamic',
compression: 'metadata', compression: 'metadata',
introducer: false, introducer: false,
selectedFolders: {} selectedFolders: {}
@@ -890,7 +855,7 @@ angular.module('syncthing.core')
$scope.saveDeviceConfig = function (deviceCfg) { $scope.saveDeviceConfig = function (deviceCfg) {
var done, i; var done, i;
deviceCfg.addresses = deviceCfg._addressesStr.split(',').map(function (x) { deviceCfg.addresses = deviceCfg.addressesStr.split(',').map(function (x) {
return x.trim(); return x.trim();
}); });
@@ -1002,7 +967,7 @@ angular.module('syncthing.core')
$scope.$watch('currentFolder.path', function (newvalue) { $scope.$watch('currentFolder.path', function (newvalue) {
if (newvalue && newvalue.trim().charAt(0) == '~') { if (newvalue && newvalue.trim().charAt(0) == '~') {
$scope.currentFolder.path = $scope.system.tilde + newvalue.trim().substring(1); $scope.currentFolder.path = $scope.system.tilde + newvalue.trim().substring(1)
} }
$http.get(urlbase + '/system/browse', { $http.get(urlbase + '/system/browse', {
params: { current: newvalue } params: { current: newvalue }
@@ -1020,11 +985,7 @@ angular.module('syncthing.core')
$scope.currentFolder.devices.forEach(function (n) { $scope.currentFolder.devices.forEach(function (n) {
$scope.currentFolder.selectedDevices[n.deviceID] = true; $scope.currentFolder.selectedDevices[n.deviceID] = true;
}); });
if ($scope.currentFolder.versioning && $scope.currentFolder.versioning.type === "trashcan") { if ($scope.currentFolder.versioning && $scope.currentFolder.versioning.type === "simple") {
$scope.currentFolder.trashcanFileVersioning = true;
$scope.currentFolder.fileVersioningSelector = "trashcan";
$scope.currentFolder.trashcanClean = +$scope.currentFolder.versioning.params.cleanoutDays;
} else if ($scope.currentFolder.versioning && $scope.currentFolder.versioning.type === "simple") {
$scope.currentFolder.simpleFileVersioning = true; $scope.currentFolder.simpleFileVersioning = true;
$scope.currentFolder.fileVersioningSelector = "simple"; $scope.currentFolder.fileVersioningSelector = "simple";
$scope.currentFolder.simpleKeep = +$scope.currentFolder.versioning.params.keep; $scope.currentFolder.simpleKeep = +$scope.currentFolder.versioning.params.keep;
@@ -1041,7 +1002,6 @@ angular.module('syncthing.core')
} else { } else {
$scope.currentFolder.fileVersioningSelector = "none"; $scope.currentFolder.fileVersioningSelector = "none";
} }
$scope.currentFolder.trashcanClean = $scope.currentFolder.trashcanClean || 0; // weeds out nulls and undefineds
$scope.currentFolder.simpleKeep = $scope.currentFolder.simpleKeep || 5; $scope.currentFolder.simpleKeep = $scope.currentFolder.simpleKeep || 5;
$scope.currentFolder.staggeredCleanInterval = $scope.currentFolder.staggeredCleanInterval || 3600; $scope.currentFolder.staggeredCleanInterval = $scope.currentFolder.staggeredCleanInterval || 3600;
$scope.currentFolder.staggeredVersionsPath = $scope.currentFolder.staggeredVersionsPath || ""; $scope.currentFolder.staggeredVersionsPath = $scope.currentFolder.staggeredVersionsPath || "";
@@ -1064,9 +1024,7 @@ angular.module('syncthing.core')
selectedDevices: {} selectedDevices: {}
}; };
$scope.currentFolder.rescanIntervalS = 60; $scope.currentFolder.rescanIntervalS = 60;
$scope.currentFolder.order = "random";
$scope.currentFolder.fileVersioningSelector = "none"; $scope.currentFolder.fileVersioningSelector = "none";
$scope.currentFolder.trashcanClean = 0;
$scope.currentFolder.simpleKeep = 5; $scope.currentFolder.simpleKeep = 5;
$scope.currentFolder.staggeredMaxAge = 365; $scope.currentFolder.staggeredMaxAge = 365;
$scope.currentFolder.staggeredCleanInterval = 3600; $scope.currentFolder.staggeredCleanInterval = 3600;
@@ -1082,19 +1040,18 @@ angular.module('syncthing.core')
$scope.dismissFolderRejection(folder, device); $scope.dismissFolderRejection(folder, device);
$scope.currentFolder = { $scope.currentFolder = {
id: folder, id: folder,
selectedDevices: {}, selectedDevices: {}
rescanIntervalS: 60,
fileVersioningSelector: "none",
trashcanClean: 0,
simpleKeep: 5,
staggeredMaxAge: 365,
staggeredCleanInterval: 3600,
staggeredVersionsPath: "",
externalCommand: "",
autoNormalize: true
}; };
$scope.currentFolder.selectedDevices[device] = true; $scope.currentFolder.selectedDevices[device] = true;
$scope.currentFolder.rescanIntervalS = 60;
$scope.currentFolder.fileVersioningSelector = "none";
$scope.currentFolder.simpleKeep = 5;
$scope.currentFolder.staggeredMaxAge = 365;
$scope.currentFolder.staggeredCleanInterval = 3600;
$scope.currentFolder.staggeredVersionsPath = "";
$scope.currentFolder.externalCommand = "";
$scope.currentFolder.autoNormalize = true;
$scope.editingExisting = false; $scope.editingExisting = false;
$scope.folderEditor.$setPristine(); $scope.folderEditor.$setPristine();
$('#editFolder').modal(); $('#editFolder').modal();
@@ -1125,16 +1082,7 @@ angular.module('syncthing.core')
} }
delete folderCfg.selectedDevices; delete folderCfg.selectedDevices;
if (folderCfg.fileVersioningSelector === "trashcan") { if (folderCfg.fileVersioningSelector === "simple") {
folderCfg.versioning = {
'Type': 'trashcan',
'Params': {
'cleanoutDays': '' + folderCfg.trashcanClean
}
};
delete folderCfg.trashcanFileVersioning;
delete folderCfg.trashcanClean;
} else if (folderCfg.fileVersioningSelector === "simple") {
folderCfg.versioning = { folderCfg.versioning = {
'Type': 'simple', 'Type': 'simple',
'Params': { 'Params': {
@@ -1189,12 +1137,12 @@ angular.module('syncthing.core')
}); });
names.sort(); names.sort();
return names.join(", "); return names.join(", ");
}; }
$scope.deviceFolders = function (deviceCfg) { $scope.deviceFolders = function (deviceCfg) {
var folders = []; var folders = [];
for (var folderID in $scope.folders) { for (var folderID in $scope.folders) {
var devices = $scope.folders[folderID].devices; var devices = $scope.folders[folderID].devices
for (var i = 0; i < devices.length; i++) { for (var i = 0; i < devices.length; i++) {
if (devices[i].deviceID == deviceCfg.deviceID) { if (devices[i].deviceID == deviceCfg.deviceID) {
folders.push(folderID); folders.push(folderID);
@@ -1291,23 +1239,6 @@ angular.module('syncthing.core')
}); });
}; };
$scope.showFailed = function (folder) {
$scope.failedCurrent = $scope.failed[folder]
$('#failed').modal().on('hidden.bs.modal', function () {
$scope.failedCurrent = undefined;
});
};
$scope.hasFailedFiles = function (folder) {
if (!$scope.failed[folder]) {
return false;
}
if ($scope.failed[folder].length == 0) {
return false;
}
return true
};
$scope.override = function (folder) { $scope.override = function (folder) {
$http.post(urlbase + "/db/override?folder=" + encodeURIComponent(folder)); $http.post(urlbase + "/db/override?folder=" + encodeURIComponent(folder));
}; };
@@ -1316,10 +1247,6 @@ angular.module('syncthing.core')
$('#about').modal('show'); $('#about').modal('show');
}; };
$scope.advanced = function () {
$('#advanced').modal('show');
};
$scope.showReportPreview = function () { $scope.showReportPreview = function () {
$scope.reportPreview = true; $scope.reportPreview = true;
}; };
@@ -1370,22 +1297,6 @@ angular.module('syncthing.core')
return $scope.version.version + ', ' + os + ' (' + arch + ')'; return $scope.version.version + ', ' + os + ' (' + arch + ')';
}; };
$scope.inputTypeFor = function (key, value) {
if (key.substr(0, 1) === '_') {
return 'skip';
}
if (typeof value === 'number') {
return 'number';
}
if (typeof value === 'boolean') {
return 'checkbox';
}
if (typeof value === 'object') {
return 'skip';
}
return 'text';
};
// pseudo main. called on all definitions assigned // pseudo main. called on all definitions assigned
initController(); initController();
}); });

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