Compare commits

..

2 Commits

Author SHA1 Message Date
henrygd
5f74438bd7 update 2025-12-21 16:44:20 -05:00
henrygd
ea354ec030 initial nvml collector 2025-12-21 14:33:04 -05:00
68 changed files with 1525 additions and 2868 deletions

View File

@@ -15,6 +15,9 @@ import (
"github.com/henrygd/beszel"
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/entities/smart"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/henrygd/beszel/internal/entities/systemd"
"github.com/fxamacker/cbor/v2"
"github.com/lxzan/gws"
@@ -256,16 +259,40 @@ func (client *WebSocketClient) sendMessage(data any) error {
return err
}
// sendResponse sends a response with optional request ID.
// For ID-based requests, we must populate legacy typed fields for backward
// compatibility with older hubs (<= 0.17) that don't read the generic Data field.
// sendResponse sends a response with optional request ID for the new protocol
func (client *WebSocketClient) sendResponse(data any, requestID *uint32) error {
if requestID != nil {
response := newAgentResponse(data, requestID)
// New format with ID - use typed fields
response := common.AgentResponse{
Id: requestID,
}
// Set the appropriate typed field based on data type
switch v := data.(type) {
case *system.CombinedData:
response.SystemData = v
case *common.FingerprintResponse:
response.Fingerprint = v
case string:
response.String = &v
case map[string]smart.SmartData:
response.SmartData = v
case systemd.ServiceDetails:
response.ServiceInfo = v
// case []byte:
// response.RawBytes = v
// case string:
// response.RawBytes = []byte(v)
default:
// For any other type, convert to error
response.Error = fmt.Sprintf("unsupported response type: %T", data)
}
return client.sendMessage(response)
} else {
// Legacy format - send data directly
return client.sendMessage(data)
}
// Legacy format - send data directly
return client.sendMessage(data)
}
// getUserAgent returns one of two User-Agent strings based on current time.

View File

@@ -694,8 +694,7 @@ func (dm *dockerManager) getLogs(ctx context.Context, containerID string) (strin
}
var builder strings.Builder
multiplexed := resp.Header.Get("Content-Type") == "application/vnd.docker.multiplexed-stream"
if err := decodeDockerLogStream(resp.Body, &builder, multiplexed); err != nil {
if err := decodeDockerLogStream(resp.Body, &builder); err != nil {
return "", err
}
@@ -707,11 +706,7 @@ func (dm *dockerManager) getLogs(ctx context.Context, containerID string) (strin
return logs, nil
}
func decodeDockerLogStream(reader io.Reader, builder *strings.Builder, multiplexed bool) error {
if !multiplexed {
_, err := io.Copy(builder, io.LimitReader(reader, maxTotalLogSize))
return err
}
func decodeDockerLogStream(reader io.Reader, builder *strings.Builder) error {
const headerSize = 8
var header [headerSize]byte
totalBytesRead := 0

View File

@@ -950,7 +950,6 @@ func TestDecodeDockerLogStream(t *testing.T) {
input []byte
expected string
expectError bool
multiplexed bool
}{
{
name: "simple log entry",
@@ -961,7 +960,6 @@ func TestDecodeDockerLogStream(t *testing.T) {
},
expected: "Hello World",
expectError: false,
multiplexed: true,
},
{
name: "multiple frames",
@@ -975,7 +973,6 @@ func TestDecodeDockerLogStream(t *testing.T) {
},
expected: "HelloWorld",
expectError: false,
multiplexed: true,
},
{
name: "zero length frame",
@@ -988,20 +985,12 @@ func TestDecodeDockerLogStream(t *testing.T) {
},
expected: "Hello",
expectError: false,
multiplexed: true,
},
{
name: "empty input",
input: []byte{},
expected: "",
expectError: false,
multiplexed: true,
},
{
name: "raw stream (not multiplexed)",
input: []byte("raw log content"),
expected: "raw log content",
multiplexed: false,
},
}
@@ -1009,7 +998,7 @@ func TestDecodeDockerLogStream(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
reader := bytes.NewReader(tt.input)
var builder strings.Builder
err := decodeDockerLogStream(reader, &builder, tt.multiplexed)
err := decodeDockerLogStream(reader, &builder)
if tt.expectError {
assert.Error(t, err)
@@ -1033,7 +1022,7 @@ func TestDecodeDockerLogStreamMemoryProtection(t *testing.T) {
reader := bytes.NewReader(input)
var builder strings.Builder
err := decodeDockerLogStream(reader, &builder, true)
err := decodeDockerLogStream(reader, &builder)
assert.Error(t, err)
assert.Contains(t, err.Error(), "log frame size")
@@ -1067,7 +1056,7 @@ func TestDecodeDockerLogStreamMemoryProtection(t *testing.T) {
reader := bytes.NewReader(input)
var builder strings.Builder
err := decodeDockerLogStream(reader, &builder, true)
err := decodeDockerLogStream(reader, &builder)
// Should complete without error (graceful truncation)
assert.NoError(t, err)

View File

@@ -15,7 +15,7 @@ import (
"github.com/henrygd/beszel/internal/entities/system"
"log/slog"
"golang.org/x/exp/slog"
)
const (

View File

@@ -2,13 +2,13 @@ package agent
import (
"fmt"
"log/slog"
"strings"
"time"
"unsafe"
"github.com/ebitengine/purego"
"github.com/henrygd/beszel/internal/entities/system"
"golang.org/x/exp/slog"
)
// NVML constants and types
@@ -72,7 +72,7 @@ type nvmlCollector struct {
}
func (c *nvmlCollector) init() error {
slog.Debug("NVML: Initializing")
slog.Info("NVML: Initializing")
libPath := getNVMLPath()
lib, err := openLibrary(libPath)
@@ -159,7 +159,7 @@ func (c *nvmlCollector) collect() {
gpu := c.gm.GpuDataMap[id]
if bdf != "" && !c.isGPUActive(bdf) {
slog.Debug("NVML: GPU is suspended, skipping", "bdf", bdf)
slog.Info("NVML: GPU is suspended, skipping", "bdf", bdf)
gpu.Temperature = 0
gpu.MemoryUsed = 0
continue
@@ -168,45 +168,31 @@ func (c *nvmlCollector) collect() {
// Utilization
var utilization nvmlUtilization
if ret := nvmlDeviceGetUtilizationRates(device, &utilization); ret != nvmlReturn(nvmlSuccess) {
slog.Debug("NVML: Utilization failed (GPU likely suspended)", "bdf", bdf, "ret", ret)
slog.Info("NVML: Utilization failed (GPU likely suspended)", "bdf", bdf, "ret", ret)
gpu.Temperature = 0
gpu.MemoryUsed = 0
continue
}
slog.Debug("NVML: Collecting data for GPU", "bdf", bdf)
slog.Info("NVML: Collecting data for GPU", "bdf", bdf)
// Temperature
var temp uint32
nvmlDeviceGetTemperature(device, 0, &temp) // 0 is NVML_TEMPERATURE_GPU
// Memory: only poll if GPU is active to avoid leaving D3cold state (#1522)
if utilization.Gpu > 0 {
var usedMem, totalMem uint64
if c.isV2 {
var memory nvmlMemoryV2
memory.Version = 0x02000028 // (2 << 24) | 40 bytes
if ret := nvmlDeviceGetMemoryInfo(device, uintptr(unsafe.Pointer(&memory))); ret != nvmlReturn(nvmlSuccess) {
slog.Debug("NVML: MemoryInfo_v2 failed", "bdf", bdf, "ret", ret)
} else {
usedMem = memory.Used
totalMem = memory.Total
}
} else {
var memory nvmlMemoryV1
if ret := nvmlDeviceGetMemoryInfo(device, uintptr(unsafe.Pointer(&memory))); ret != nvmlReturn(nvmlSuccess) {
slog.Debug("NVML: MemoryInfo failed", "bdf", bdf, "ret", ret)
} else {
usedMem = memory.Used
totalMem = memory.Total
}
}
if totalMem > 0 {
gpu.MemoryUsed = float64(usedMem) / 1024 / 1024 / mebibytesInAMegabyte
gpu.MemoryTotal = float64(totalMem) / 1024 / 1024 / mebibytesInAMegabyte
}
// Memory
var usedMem, totalMem uint64
if c.isV2 {
var memory nvmlMemoryV2
memory.Version = 0x02000028 // (2 << 24) | 40 bytes
nvmlDeviceGetMemoryInfo(device, uintptr(unsafe.Pointer(&memory)))
usedMem = memory.Used
totalMem = memory.Total
} else {
slog.Debug("NVML: Skipping memory info (utilization=0)", "bdf", bdf)
var memory nvmlMemoryV1
nvmlDeviceGetMemoryInfo(device, uintptr(unsafe.Pointer(&memory)))
usedMem = memory.Used
totalMem = memory.Total
}
// Power
@@ -214,9 +200,11 @@ func (c *nvmlCollector) collect() {
nvmlDeviceGetPowerUsage(device, &power)
gpu.Temperature = float64(temp)
gpu.MemoryUsed = float64(usedMem) / 1024 / 1024 / mebibytesInAMegabyte
gpu.MemoryTotal = float64(totalMem) / 1024 / 1024 / mebibytesInAMegabyte
gpu.Usage += float64(utilization.Gpu)
gpu.Power += float64(power) / 1000.0
gpu.Count++
slog.Debug("NVML: Collected data", "gpu", gpu)
slog.Info("NVML: Collected data", "gpu", gpu)
}
}

View File

@@ -8,7 +8,7 @@ import (
"strings"
"github.com/ebitengine/purego"
"log/slog"
"golang.org/x/exp/slog"
)
func openLibrary(name string) (uintptr, error) {
@@ -29,12 +29,12 @@ func (c *nvmlCollector) isGPUActive(bdf string) bool {
statusPath := filepath.Join("/sys/bus/pci/devices", bdf, "power/runtime_status")
status, err := os.ReadFile(statusPath)
if err != nil {
slog.Debug("NVML: Can't read runtime_status", "bdf", bdf, "err", err)
slog.Info("NVML: Can't read runtime_status", "bdf", bdf, "err", err)
return true // Assume active if we can't read status
}
statusStr := strings.TrimSpace(string(status))
if statusStr != "active" && statusStr != "resuming" {
slog.Debug("NVML: GPU not active", "bdf", bdf, "status", statusStr)
slog.Info("NVML: GPU is not active", "bdf", bdf, "status", statusStr)
return false
}
@@ -47,7 +47,6 @@ func (c *nvmlCollector) isGPUActive(bdf string) bool {
if err == nil {
pstateStr := strings.TrimSpace(string(pstate))
if pstateStr != "D0" {
slog.Debug("NVML: GPU not in D0 state", "bdf", bdf, "pstate", pstateStr)
return false
}
}

View File

@@ -825,7 +825,7 @@ func TestInitializeSnapshots(t *testing.T) {
}
func TestCalculateGPUAverage(t *testing.T) {
t.Run("returns cached average when deltaCount is zero", func(t *testing.T) {
t.Run("returns zero value when deltaCount is zero", func(t *testing.T) {
gm := &GPUManager{
lastSnapshots: map[uint16]map[string]*gpuSnapshot{
5000: {
@@ -838,10 +838,9 @@ func TestCalculateGPUAverage(t *testing.T) {
}
gpu := &system.GPUData{
Count: 10.0, // Same as snapshot, so delta = 0
Usage: 100.0,
Power: 200.0,
Temperature: 50.0, // Non-zero to avoid "suspended" check
Count: 10.0, // Same as snapshot, so delta = 0
Usage: 100.0,
Power: 200.0,
}
result := gm.calculateGPUAverage("0", gpu, 5000)
@@ -850,31 +849,6 @@ func TestCalculateGPUAverage(t *testing.T) {
assert.Equal(t, 100.0, result.Power, "Should return cached average")
})
t.Run("returns zero value when GPU is suspended", func(t *testing.T) {
gm := &GPUManager{
lastSnapshots: map[uint16]map[string]*gpuSnapshot{
5000: {
"0": {count: 10, usage: 100, power: 200},
},
},
lastAvgData: map[string]system.GPUData{
"0": {Usage: 50.0, Power: 100.0},
},
}
gpu := &system.GPUData{
Name: "Test GPU",
Count: 10.0,
Temperature: 0,
MemoryUsed: 0,
}
result := gm.calculateGPUAverage("0", gpu, 5000)
assert.Equal(t, 0.0, result.Usage, "Should return zero usage")
assert.Equal(t, 0.0, result.Power, "Should return zero power")
})
t.Run("calculates average for standard GPU", func(t *testing.T) {
gm := &GPUManager{
lastSnapshots: map[uint16]map[string]*gpuSnapshot{

View File

@@ -9,7 +9,7 @@ import (
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/entities/smart"
"log/slog"
"golang.org/x/exp/slog"
)
// HandlerContext provides context for request handlers

View File

@@ -1,31 +0,0 @@
package agent
import (
"github.com/fxamacker/cbor/v2"
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/entities/smart"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/henrygd/beszel/internal/entities/systemd"
)
// newAgentResponse creates an AgentResponse using legacy typed fields.
// This maintains backward compatibility with <= 0.17 hubs that expect specific fields.
func newAgentResponse(data any, requestID *uint32) common.AgentResponse {
response := common.AgentResponse{Id: requestID}
switch v := data.(type) {
case *system.CombinedData:
response.SystemData = v
case *common.FingerprintResponse:
response.Fingerprint = v
case string:
response.String = &v
case map[string]smart.SmartData:
response.SmartData = v
case systemd.ServiceDetails:
response.ServiceInfo = v
default:
// For unknown types, use the generic Data field
response.Data, _ = cbor.Marshal(data)
}
return response
}

View File

@@ -13,7 +13,9 @@ import (
"github.com/henrygd/beszel"
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/entities/smart"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/henrygd/beszel/internal/entities/systemd"
"github.com/blang/semver"
"github.com/fxamacker/cbor/v2"
@@ -163,9 +165,20 @@ func (a *Agent) handleSSHRequest(w io.Writer, req *common.HubRequest[cbor.RawMes
}
// responder that writes AgentResponse to stdout
// Uses legacy typed fields for backward compatibility with <= 0.17
sshResponder := func(data any, requestID *uint32) error {
response := newAgentResponse(data, requestID)
response := common.AgentResponse{Id: requestID}
switch v := data.(type) {
case *system.CombinedData:
response.SystemData = v
case string:
response.String = &v
case map[string]smart.SmartData:
response.SmartData = v
case systemd.ServiceDetails:
response.ServiceInfo = v
default:
response.Error = fmt.Sprintf("unsupported response type: %T", data)
}
return cbor.NewEncoder(w).Encode(response)
}

View File

@@ -19,7 +19,7 @@ import (
"github.com/henrygd/beszel/internal/entities/smart"
"log/slog"
"golang.org/x/exp/slog"
)
// SmartManager manages data collection for SMART devices

View File

@@ -8,7 +8,6 @@ import (
"log/slog"
"maps"
"math"
"os"
"strconv"
"strings"
"sync"
@@ -29,29 +28,11 @@ type systemdManager struct {
patterns []string
}
// isSystemdAvailable checks if systemd is used on the system to avoid unnecessary connection attempts.
func isSystemdAvailable() bool {
if _, err := os.Stat("/run/systemd/system"); err == nil {
return true
}
if data, err := os.ReadFile("/proc/1/comm"); err == nil {
return strings.TrimSpace(string(data)) == "systemd"
}
return false
}
// newSystemdManager creates a new systemdManager.
func newSystemdManager() (*systemdManager, error) {
if skipSystemd, _ := GetEnv("SKIP_SYSTEMD"); skipSystemd == "true" {
return nil, nil
}
// Check if systemd is available on the system before attempting connection
if !isSystemdAvailable() {
slog.Debug("Systemd not available on this system")
return nil, nil
}
conn, err := dbus.NewSystemConnectionContext(context.Background())
if err != nil {
slog.Debug("Error connecting to systemd", "err", err, "ref", "https://beszel.dev/guide/systemd")

View File

@@ -4,7 +4,6 @@ package agent
import (
"os"
"strings"
"testing"
"github.com/stretchr/testify/assert"
@@ -49,35 +48,6 @@ func TestUnescapeServiceNameInvalid(t *testing.T) {
}
}
func TestIsSystemdAvailable(t *testing.T) {
// Note: This test's result will vary based on the actual system running the tests
// On systems with systemd, it should return true
// On systems without systemd, it should return false
result := isSystemdAvailable()
// Check if either the /run/systemd/system directory exists or PID 1 is systemd
runSystemdExists := false
if _, err := os.Stat("/run/systemd/system"); err == nil {
runSystemdExists = true
}
pid1IsSystemd := false
if data, err := os.ReadFile("/proc/1/comm"); err == nil {
pid1IsSystemd = strings.TrimSpace(string(data)) == "systemd"
}
expected := runSystemdExists || pid1IsSystemd
assert.Equal(t, expected, result, "isSystemdAvailable should correctly detect systemd presence")
// Log the result for informational purposes
if result {
t.Log("Systemd is available on this system")
} else {
t.Log("Systemd is not available on this system")
}
}
func TestGetServicePatterns(t *testing.T) {
tests := []struct {
name string

View File

@@ -6,7 +6,7 @@ import "github.com/blang/semver"
const (
// Version is the current version of the application.
Version = "0.18.0-beta.2"
Version = "0.18.0-beta.1"
// AppName is the name of the application.
AppName = "beszel"
)

34
go.mod
View File

@@ -11,17 +11,17 @@ require (
github.com/gliderlabs/ssh v0.3.8
github.com/google/uuid v1.6.0
github.com/lxzan/gws v1.8.9
github.com/nicholas-fedor/shoutrrr v0.13.1
github.com/nicholas-fedor/shoutrrr v0.12.1
github.com/pocketbase/dbx v1.11.0
github.com/pocketbase/pocketbase v0.35.0
github.com/shirou/gopsutil/v4 v4.25.12
github.com/pocketbase/pocketbase v0.34.0
github.com/shirou/gopsutil/v4 v4.25.10
github.com/spf13/cast v1.10.0
github.com/spf13/cobra v1.10.2
github.com/spf13/cobra v1.10.1
github.com/spf13/pflag v1.0.10
github.com/stretchr/testify v1.11.1
golang.org/x/crypto v0.46.0
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93
golang.org/x/sys v0.40.0
golang.org/x/crypto v0.45.0
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39
golang.org/x/sys v0.38.0
gopkg.in/yaml.v3 v3.0.1
)
@@ -34,15 +34,15 @@ require (
github.com/domodwyer/mailyak/v3 v3.6.2 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.12 // indirect
github.com/gabriel-vasile/mimetype v1.4.11 // indirect
github.com/ganigeorgiev/fexpr v0.5.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
github.com/go-sql-driver/mysql v1.9.1 // indirect
github.com/godbus/dbus/v5 v5.2.2 // indirect
github.com/godbus/dbus/v5 v5.2.0 // indirect
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.18.2 // indirect
github.com/klauspost/compress v1.18.1 // indirect
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
@@ -54,15 +54,15 @@ require (
github.com/tklauser/numcpus v0.11.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/image v0.34.0 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/term v0.38.0 // indirect
golang.org/x/text v0.32.0 // indirect
golang.org/x/image v0.33.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/oauth2 v0.33.0 // indirect
golang.org/x/sync v0.18.0 // indirect
golang.org/x/term v0.37.0 // indirect
golang.org/x/text v0.31.0 // indirect
howett.net/plist v1.0.1 // indirect
modernc.org/libc v1.66.10 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
modernc.org/sqlite v1.41.0 // indirect
modernc.org/sqlite v1.40.1 // indirect
)

100
go.sum
View File

@@ -33,8 +33,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gabriel-vasile/mimetype v1.4.11 h1:AQvxbp830wPhHTqc1u7nzoLT+ZFxGY7emj5DR5DYFik=
github.com/gabriel-vasile/mimetype v1.4.11/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/ganigeorgiev/fexpr v0.5.0 h1:XA9JxtTE/Xm+g/JFI6RfZEHSiQlk+1glLvRK1Lpv/Tk=
github.com/ganigeorgiev/fexpr v0.5.0/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE=
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
@@ -51,8 +51,8 @@ github.com/go-sql-driver/mysql v1.9.1 h1:FrjNGn/BsJQjVRuSa8CBrM5BWA9BWoXXat3KrtS
github.com/go-sql-driver/mysql v1.9.1/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ=
github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
github.com/godbus/dbus/v5 v5.2.0 h1:3WexO+U+yg9T70v9FdHr9kCxYlazaAXUhx2VMkbfax8=
github.com/godbus/dbus/v5 v5.2.0/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -62,15 +62,13 @@ github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8 h1:3DsUAV+VNEQa2CUVLx
github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jarcoal/httpmock v1.4.1 h1:0Ju+VCFuARfFlhVXFc2HxlcQkfB+Xq12/EotHko+x2A=
github.com/jarcoal/httpmock v1.4.1/go.mod h1:ftW1xULwo+j0R0JJkJIIi7UKigZUXCLLanykgjwBXL0=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=
github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -85,19 +83,19 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/nicholas-fedor/shoutrrr v0.13.1 h1:llEoHNbnMM4GfQ9+2Ns3n6ssvNfi3NPWluM0AQiicoY=
github.com/nicholas-fedor/shoutrrr v0.13.1/go.mod h1:kU4cFJpEAtTzl3iV0l+XUXmM90OlC5T01b7roM4/pYM=
github.com/onsi/ginkgo/v2 v2.27.3 h1:ICsZJ8JoYafeXFFlFAG75a7CxMsJHwgKwtO+82SE9L8=
github.com/onsi/ginkgo/v2 v2.27.3/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
github.com/onsi/gomega v1.38.3 h1:eTX+W6dobAYfFeGC2PV6RwXRu/MyT+cQguijutvkpSM=
github.com/onsi/gomega v1.38.3/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
github.com/nicholas-fedor/shoutrrr v0.12.1 h1:8NjY+I3K7cGHy89ncnaPGUA0ex44XbYK3SAFJX9YMI8=
github.com/nicholas-fedor/shoutrrr v0.12.1/go.mod h1:64qWuPpvTUv9ZppEoR6OdroiFmgf9w11YSaR0h9KZGg=
github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pocketbase/dbx v1.11.0 h1:LpZezioMfT3K4tLrqA55wWFw1EtH1pM4tzSVa7kgszU=
github.com/pocketbase/dbx v1.11.0/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs=
github.com/pocketbase/pocketbase v0.35.0 h1:MW905RYJnpwl8bvFDPCn+/5Y/TGKbf+kpdKiZmqx/1s=
github.com/pocketbase/pocketbase v0.35.0/go.mod h1:eA9IKEvGYhdVbngBzgXPDZ2aNAGfDBkB6kcuLnHLTag=
github.com/pocketbase/pocketbase v0.34.0 h1:5W80PrGvkRYIMAIK90F7w031/hXgZVz1KSuCJqSpgJo=
github.com/pocketbase/pocketbase v0.34.0/go.mod h1:K/9z/Zb9PR9yW2Qyoc73jHV/EKT8cMTk9bQWyrzYlvI=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
@@ -105,12 +103,12 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shirou/gopsutil/v4 v4.25.12 h1:e7PvW/0RmJ8p8vPGJH4jvNkOyLmbkXgXW4m6ZPic6CY=
github.com/shirou/gopsutil/v4 v4.25.12/go.mod h1:EivAfP5x2EhLp2ovdpKSozecVXn1TmuG7SMzs/Wh4PU=
github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA=
github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM=
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
@@ -129,38 +127,38 @@ github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 h1:DHNhtq3sNNzrvduZZIiFyXWOL9IWaDPHqTnLJp+rCBY=
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.34.0 h1:33gCkyw9hmwbZJeZkct8XyR11yH889EQt/QH4VmXMn8=
golang.org/x/image v0.34.0/go.mod h1:2RNFBZRB+vnwwFil8GkMdRvrJOFd1AzdZI6vOY+eJVU=
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
golang.org/x/image v0.33.0 h1:LXRZRnv1+zGd5XBUVRFmYEphyyKJjQjCRiOuAP3sZfQ=
golang.org/x/image v0.33.0/go.mod h1:DD3OsTYT9chzuzTQt+zMcOlBHgfoKQb1gry8p76Y1sc=
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo=
golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
@@ -173,22 +171,18 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.30.1 h1:4r4U1J6Fhj98NKfSjnPUN7Ze2c6MnAdL0hWw6+LrJpc=
modernc.org/ccgo/v4 v4.30.1/go.mod h1:bIOeI1JL54Utlxn+LwrFyjCx2n2RDiYEaJVSrgdrRfM=
modernc.org/cc/v4 v4.26.5 h1:xM3bX7Mve6G8K8b+T11ReenJOT+BmVqQj0FY5T4+5Y4=
modernc.org/cc/v4 v4.26.5/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A=
modernc.org/ccgo/v4 v4.28.1/go.mod h1:uD+4RnfrVgE6ec9NGguUNdhqzNIeeomeXf6CL0GTE5Q=
modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA=
modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/gc/v3 v3.1.1 h1:k8T3gkXWY9sEiytKhcgyiZ2L0DTyCQ/nvX+LoCljoRE=
modernc.org/gc/v3 v3.1.1/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.66.10 h1:yZkb3YeLx4oynyR+iUsXsybsX4Ubx7MQlSYEw4yj59A=
modernc.org/libc v1.66.10/go.mod h1:8vGSEwvoUoltr4dlywvHqjtAqHBaw0j1jI7iFBTAr2I=
modernc.org/libc v1.67.4 h1:zZGmCMUVPORtKv95c2ReQN5VDjvkoRm9GWPTEPuvlWg=
modernc.org/libc v1.67.4/go.mod h1:QvvnnJ5P7aitu0ReNpVIEyesuhmDLQ8kaEoyMjIFZJA=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
@@ -197,10 +191,8 @@ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.41.0 h1:bJXddp4ZpsqMsNN1vS0jWo4IJTZzb8nWpcgvyCFG9Ck=
modernc.org/sqlite v1.41.0/go.mod h1:9fjQZ0mB1LLP0GYrp39oOJXx/I2sxEnZtzCmEQIKvGE=
modernc.org/sqlite v1.43.0 h1:8YqiFx3G1VhHTXO2Q00bl1Wz9KhS9Q5okwfp9Y97VnA=
modernc.org/sqlite v1.43.0/go.mod h1:+VkC6v3pLOAE0A0uVucQEcbVW0I5nHCeDaBf+DpsQT8=
modernc.org/sqlite v1.40.1 h1:VfuXcxcUWWKRBuP8+BR9L7VnmusMgBNNnBYGEe9w/iY=
modernc.org/sqlite v1.40.1/go.mod h1:9fjQZ0mB1LLP0GYrp39oOJXx/I2sxEnZtzCmEQIKvGE=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=

View File

@@ -1,7 +1,6 @@
package common
import (
"github.com/fxamacker/cbor/v2"
"github.com/henrygd/beszel/internal/entities/smart"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/henrygd/beszel/internal/entities/systemd"
@@ -35,14 +34,14 @@ type HubRequest[T any] struct {
// AgentResponse defines the structure for responses sent from agent to hub.
type AgentResponse struct {
Id *uint32 `cbor:"0,keyasint,omitempty"`
SystemData *system.CombinedData `cbor:"1,keyasint,omitempty,omitzero"` // Legacy (<= 0.17)
Fingerprint *FingerprintResponse `cbor:"2,keyasint,omitempty,omitzero"` // Legacy (<= 0.17)
SystemData *system.CombinedData `cbor:"1,keyasint,omitempty,omitzero"`
Fingerprint *FingerprintResponse `cbor:"2,keyasint,omitempty,omitzero"`
Error string `cbor:"3,keyasint,omitempty,omitzero"`
String *string `cbor:"4,keyasint,omitempty,omitzero"` // Legacy (<= 0.17)
SmartData map[string]smart.SmartData `cbor:"5,keyasint,omitempty,omitzero"` // Legacy (<= 0.17)
ServiceInfo systemd.ServiceDetails `cbor:"6,keyasint,omitempty,omitzero"` // Legacy (<= 0.17)
// Data is the generic response payload for new endpoints (0.18+)
Data cbor.RawMessage `cbor:"7,keyasint,omitempty,omitzero"`
String *string `cbor:"4,keyasint,omitempty,omitzero"`
SmartData map[string]smart.SmartData `cbor:"5,keyasint,omitempty,omitzero"`
ServiceInfo systemd.ServiceDetails `cbor:"6,keyasint,omitempty,omitzero"`
// Logs *LogsPayload `cbor:"4,keyasint,omitempty,omitzero"`
// RawBytes []byte `cbor:"4,keyasint,omitempty,omitzero"`
}
type FingerprintRequest struct {

View File

@@ -13,11 +13,9 @@ import (
"time"
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/hub/transport"
"github.com/henrygd/beszel/internal/hub/ws"
"github.com/henrygd/beszel/internal/entities/container"
"github.com/henrygd/beszel/internal/entities/smart"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/henrygd/beszel/internal/entities/systemd"
@@ -25,30 +23,28 @@ import (
"github.com/blang/semver"
"github.com/fxamacker/cbor/v2"
"github.com/lxzan/gws"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/core"
"golang.org/x/crypto/ssh"
)
type System struct {
Id string `db:"id"`
Host string `db:"host"`
Port string `db:"port"`
Status string `db:"status"`
manager *SystemManager // Manager that this system belongs to
client *ssh.Client // SSH client for fetching data
sshTransport *transport.SSHTransport // SSH transport for requests
data *system.CombinedData // system data from agent
ctx context.Context // Context for stopping the updater
cancel context.CancelFunc // Stops and removes system from updater
WsConn *ws.WsConn // Handler for agent WebSocket connection
agentVersion semver.Version // Agent version
updateTicker *time.Ticker // Ticker for updating the system
detailsFetched atomic.Bool // True if static system details have been fetched and saved
smartFetching atomic.Bool // True if SMART devices are currently being fetched
smartInterval time.Duration // Interval for periodic SMART data updates
lastSmartFetch atomic.Int64 // Unix milliseconds of last SMART data fetch
Id string `db:"id"`
Host string `db:"host"`
Port string `db:"port"`
Status string `db:"status"`
manager *SystemManager // Manager that this system belongs to
client *ssh.Client // SSH client for fetching data
data *system.CombinedData // system data from agent
ctx context.Context // Context for stopping the updater
cancel context.CancelFunc // Stops and removes system from updater
WsConn *ws.WsConn // Handler for agent WebSocket connection
agentVersion semver.Version // Agent version
updateTicker *time.Ticker // Ticker for updating the system
detailsFetched atomic.Bool // True if static system details have been fetched and saved
smartFetching atomic.Bool // True if SMART devices are currently being fetched
smartInterval time.Duration // Interval for periodic SMART data updates
lastSmartFetch atomic.Int64 // Unix milliseconds of last SMART data fetch
}
func (sm *SystemManager) NewSystem(systemId string) *System {
@@ -363,78 +359,8 @@ func (sys *System) getContext() (context.Context, context.CancelFunc) {
return sys.ctx, sys.cancel
}
// request sends a request to the agent, trying WebSocket first, then SSH.
// This is the unified request method that uses the transport abstraction.
func (sys *System) request(ctx context.Context, action common.WebSocketAction, req any, dest any) error {
// Try WebSocket first
if sys.WsConn != nil && sys.WsConn.IsConnected() {
wsTransport := transport.NewWebSocketTransport(sys.WsConn)
if err := wsTransport.Request(ctx, action, req, dest); err == nil {
return nil
} else if !shouldFallbackToSSH(err) {
return err
} else if shouldCloseWebSocket(err) {
sys.closeWebSocketConnection()
}
}
// Fall back to SSH if WebSocket fails
if err := sys.ensureSSHTransport(); err != nil {
return err
}
err := sys.sshTransport.RequestWithRetry(ctx, action, req, dest, 1)
// Keep legacy SSH client/version fields in sync for other code paths.
if sys.sshTransport != nil {
sys.client = sys.sshTransport.GetClient()
sys.agentVersion = sys.sshTransport.GetAgentVersion()
}
return err
}
func shouldFallbackToSSH(err error) bool {
if err == nil {
return false
}
if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
return true
}
if errors.Is(err, gws.ErrConnClosed) {
return true
}
return errors.Is(err, transport.ErrWebSocketNotConnected)
}
func shouldCloseWebSocket(err error) bool {
if err == nil {
return false
}
return errors.Is(err, gws.ErrConnClosed) || errors.Is(err, transport.ErrWebSocketNotConnected)
}
// ensureSSHTransport ensures the SSH transport is initialized and connected.
func (sys *System) ensureSSHTransport() error {
if sys.sshTransport == nil {
if sys.manager.sshConfig == nil {
if err := sys.manager.createSSHClientConfig(); err != nil {
return err
}
}
sys.sshTransport = transport.NewSSHTransport(transport.SSHTransportConfig{
Host: sys.Host,
Port: sys.Port,
Config: sys.manager.sshConfig,
Timeout: 4 * time.Second,
})
}
// Sync client state with transport
if sys.client != nil {
sys.sshTransport.SetClient(sys.client)
sys.sshTransport.SetAgentVersion(sys.agentVersion)
}
return nil
}
// fetchDataFromAgent attempts to fetch data from the agent, prioritizing WebSocket if available.
// fetchDataFromAgent attempts to fetch data from the agent,
// prioritizing WebSocket if available.
func (sys *System) fetchDataFromAgent(options common.DataRequestOptions) (*system.CombinedData, error) {
if sys.data == nil {
sys.data = &system.CombinedData{}
@@ -460,47 +386,112 @@ func (sys *System) fetchDataViaWebSocket(options common.DataRequestOptions) (*sy
if sys.WsConn == nil || !sys.WsConn.IsConnected() {
return nil, errors.New("no websocket connection")
}
wsTransport := transport.NewWebSocketTransport(sys.WsConn)
err := wsTransport.Request(context.Background(), common.GetData, options, sys.data)
err := sys.WsConn.RequestSystemData(context.Background(), sys.data, options)
if err != nil {
return nil, err
}
return sys.data, nil
}
// fetchStringFromAgentViaSSH is a generic function to fetch strings via SSH
func (sys *System) fetchStringFromAgentViaSSH(action common.WebSocketAction, requestData any, errorMsg string) (string, error) {
var result string
err := sys.runSSHOperation(4*time.Second, 1, func(session *ssh.Session) (bool, error) {
stdout, err := session.StdoutPipe()
if err != nil {
return false, err
}
stdin, stdinErr := session.StdinPipe()
if stdinErr != nil {
return false, stdinErr
}
if err := session.Shell(); err != nil {
return false, err
}
req := common.HubRequest[any]{Action: action, Data: requestData}
_ = cbor.NewEncoder(stdin).Encode(req)
_ = stdin.Close()
var resp common.AgentResponse
err = cbor.NewDecoder(stdout).Decode(&resp)
if err != nil {
return false, err
}
if resp.String == nil {
return false, errors.New(errorMsg)
}
result = *resp.String
return false, nil
})
return result, err
}
// FetchContainerInfoFromAgent fetches container info from the agent
func (sys *System) FetchContainerInfoFromAgent(containerID string) (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
var result string
err := sys.request(ctx, common.GetContainerInfo, common.ContainerInfoRequest{ContainerID: containerID}, &result)
return result, err
// fetch via websocket
if sys.WsConn != nil && sys.WsConn.IsConnected() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
return sys.WsConn.RequestContainerInfo(ctx, containerID)
}
// fetch via SSH
return sys.fetchStringFromAgentViaSSH(common.GetContainerInfo, common.ContainerInfoRequest{ContainerID: containerID}, "no info in response")
}
// FetchContainerLogsFromAgent fetches container logs from the agent
func (sys *System) FetchContainerLogsFromAgent(containerID string) (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
var result string
err := sys.request(ctx, common.GetContainerLogs, common.ContainerLogsRequest{ContainerID: containerID}, &result)
return result, err
// fetch via websocket
if sys.WsConn != nil && sys.WsConn.IsConnected() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
return sys.WsConn.RequestContainerLogs(ctx, containerID)
}
// fetch via SSH
return sys.fetchStringFromAgentViaSSH(common.GetContainerLogs, common.ContainerLogsRequest{ContainerID: containerID}, "no logs in response")
}
// FetchSystemdInfoFromAgent fetches detailed systemd service information from the agent
func (sys *System) FetchSystemdInfoFromAgent(serviceName string) (systemd.ServiceDetails, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
var result systemd.ServiceDetails
err := sys.request(ctx, common.GetSystemdInfo, common.SystemdInfoRequest{ServiceName: serviceName}, &result)
return result, err
}
// fetch via websocket
if sys.WsConn != nil && sys.WsConn.IsConnected() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
return sys.WsConn.RequestSystemdInfo(ctx, serviceName)
}
var result systemd.ServiceDetails
err := sys.runSSHOperation(5*time.Second, 1, func(session *ssh.Session) (bool, error) {
stdout, err := session.StdoutPipe()
if err != nil {
return false, err
}
stdin, stdinErr := session.StdinPipe()
if stdinErr != nil {
return false, stdinErr
}
if err := session.Shell(); err != nil {
return false, err
}
req := common.HubRequest[any]{Action: common.GetSystemdInfo, Data: common.SystemdInfoRequest{ServiceName: serviceName}}
if err := cbor.NewEncoder(stdin).Encode(req); err != nil {
return false, err
}
_ = stdin.Close()
var resp common.AgentResponse
if err := cbor.NewDecoder(stdout).Decode(&resp); err != nil {
return false, err
}
if resp.ServiceInfo == nil {
if resp.Error != "" {
return false, errors.New(resp.Error)
}
return false, errors.New("no systemd info in response")
}
result = resp.ServiceInfo
return false, nil
})
// FetchSmartDataFromAgent fetches SMART data from the agent
func (sys *System) FetchSmartDataFromAgent() (map[string]smart.SmartData, error) {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
var result map[string]smart.SmartData
err := sys.request(ctx, common.GetSmartData, nil, &result)
return result, err
}
@@ -665,9 +656,6 @@ func (sys *System) createSessionWithTimeout(timeout time.Duration) (*ssh.Session
// closeSSHConnection closes the SSH connection but keeps the system in the manager
func (sys *System) closeSSHConnection() {
if sys.sshTransport != nil {
sys.sshTransport.Close()
}
if sys.client != nil {
sys.client.Close()
sys.client = nil

View File

@@ -1,14 +1,54 @@
package systems
import (
"context"
"database/sql"
"errors"
"strings"
"time"
"github.com/fxamacker/cbor/v2"
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/entities/smart"
"github.com/pocketbase/pocketbase/core"
"golang.org/x/crypto/ssh"
)
// FetchSmartDataFromAgent fetches SMART data from the agent
func (sys *System) FetchSmartDataFromAgent() (map[string]smart.SmartData, error) {
// fetch via websocket
if sys.WsConn != nil && sys.WsConn.IsConnected() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
return sys.WsConn.RequestSmartData(ctx)
}
// fetch via SSH
var result map[string]smart.SmartData
err := sys.runSSHOperation(5*time.Second, 1, func(session *ssh.Session) (bool, error) {
stdout, err := session.StdoutPipe()
if err != nil {
return false, err
}
stdin, stdinErr := session.StdinPipe()
if stdinErr != nil {
return false, stdinErr
}
if err := session.Shell(); err != nil {
return false, err
}
req := common.HubRequest[any]{Action: common.GetSmartData}
_ = cbor.NewEncoder(stdin).Encode(req)
_ = stdin.Close()
var resp common.AgentResponse
if err := cbor.NewDecoder(stdout).Decode(&resp); err != nil {
return false, err
}
result = resp.SmartData
return false, nil
})
return result, err
}
// FetchAndSaveSmartDevices fetches SMART data from the agent and saves it to the database
func (sys *System) FetchAndSaveSmartDevices() error {
smartData, err := sys.FetchSmartDataFromAgent()

View File

@@ -1,227 +0,0 @@
package transport
import (
"context"
"errors"
"fmt"
"io"
"net"
"strings"
"time"
"github.com/blang/semver"
"github.com/fxamacker/cbor/v2"
"github.com/henrygd/beszel/internal/common"
"golang.org/x/crypto/ssh"
)
// SSHTransport implements Transport over SSH connections.
type SSHTransport struct {
client *ssh.Client
config *ssh.ClientConfig
host string
port string
agentVersion semver.Version
timeout time.Duration
}
// SSHTransportConfig holds configuration for creating an SSH transport.
type SSHTransportConfig struct {
Host string
Port string
Config *ssh.ClientConfig
AgentVersion semver.Version
Timeout time.Duration
}
// NewSSHTransport creates a new SSH transport with the given configuration.
func NewSSHTransport(cfg SSHTransportConfig) *SSHTransport {
timeout := cfg.Timeout
if timeout == 0 {
timeout = 4 * time.Second
}
return &SSHTransport{
config: cfg.Config,
host: cfg.Host,
port: cfg.Port,
agentVersion: cfg.AgentVersion,
timeout: timeout,
}
}
// SetClient sets the SSH client for reuse across requests.
func (t *SSHTransport) SetClient(client *ssh.Client) {
t.client = client
}
// SetAgentVersion sets the agent version (extracted from SSH handshake).
func (t *SSHTransport) SetAgentVersion(version semver.Version) {
t.agentVersion = version
}
// GetClient returns the current SSH client (for connection management).
func (t *SSHTransport) GetClient() *ssh.Client {
return t.client
}
// GetAgentVersion returns the agent version.
func (t *SSHTransport) GetAgentVersion() semver.Version {
return t.agentVersion
}
// Request sends a request to the agent via SSH and unmarshals the response.
func (t *SSHTransport) Request(ctx context.Context, action common.WebSocketAction, req any, dest any) error {
if t.client == nil {
if err := t.connect(); err != nil {
return err
}
}
session, err := t.createSessionWithTimeout(ctx)
if err != nil {
return err
}
defer session.Close()
stdout, err := session.StdoutPipe()
if err != nil {
return err
}
stdin, err := session.StdinPipe()
if err != nil {
return err
}
if err := session.Shell(); err != nil {
return err
}
// Send request
hubReq := common.HubRequest[any]{Action: action, Data: req}
if err := cbor.NewEncoder(stdin).Encode(hubReq); err != nil {
return fmt.Errorf("failed to encode request: %w", err)
}
stdin.Close()
// Read response
var resp common.AgentResponse
if err := cbor.NewDecoder(stdout).Decode(&resp); err != nil {
return fmt.Errorf("failed to decode response: %w", err)
}
if resp.Error != "" {
return errors.New(resp.Error)
}
if err := session.Wait(); err != nil {
return err
}
return UnmarshalResponse(resp, action, dest)
}
// IsConnected returns true if the SSH connection is active.
func (t *SSHTransport) IsConnected() bool {
return t.client != nil
}
// Close terminates the SSH connection.
func (t *SSHTransport) Close() {
if t.client != nil {
t.client.Close()
t.client = nil
}
}
// connect establishes a new SSH connection.
func (t *SSHTransport) connect() error {
if t.config == nil {
return errors.New("SSH config not set")
}
network := "tcp"
host := t.host
if strings.HasPrefix(host, "/") {
network = "unix"
} else {
host = net.JoinHostPort(host, t.port)
}
client, err := ssh.Dial(network, host, t.config)
if err != nil {
return err
}
t.client = client
// Extract agent version from server version string
t.agentVersion, _ = extractAgentVersion(string(client.Conn.ServerVersion()))
return nil
}
// createSessionWithTimeout creates a new SSH session with a timeout.
func (t *SSHTransport) createSessionWithTimeout(ctx context.Context) (*ssh.Session, error) {
if t.client == nil {
return nil, errors.New("client not initialized")
}
ctx, cancel := context.WithTimeout(ctx, t.timeout)
defer cancel()
sessionChan := make(chan *ssh.Session, 1)
errChan := make(chan error, 1)
go func() {
session, err := t.client.NewSession()
if err != nil {
errChan <- err
} else {
sessionChan <- session
}
}()
select {
case session := <-sessionChan:
return session, nil
case err := <-errChan:
return nil, err
case <-ctx.Done():
return nil, errors.New("timeout creating session")
}
}
// extractAgentVersion extracts the beszel version from SSH server version string.
func extractAgentVersion(versionString string) (semver.Version, error) {
_, after, _ := strings.Cut(versionString, "_")
return semver.Parse(after)
}
// RequestWithRetry sends a request with automatic retry on connection failures.
func (t *SSHTransport) RequestWithRetry(ctx context.Context, action common.WebSocketAction, req any, dest any, retries int) error {
var lastErr error
for attempt := 0; attempt <= retries; attempt++ {
err := t.Request(ctx, action, req, dest)
if err == nil {
return nil
}
lastErr = err
// Check if it's a connection error that warrants a retry
if isConnectionError(err) && attempt < retries {
t.Close()
continue
}
return err
}
return lastErr
}
// isConnectionError checks if an error indicates a connection problem.
func isConnectionError(err error) bool {
if err == nil {
return false
}
errStr := err.Error()
return strings.Contains(errStr, "connection") ||
strings.Contains(errStr, "EOF") ||
strings.Contains(errStr, "closed") ||
errors.Is(err, io.EOF)
}

View File

@@ -1,112 +0,0 @@
// Package transport provides a unified abstraction for hub-agent communication
// over different transports (WebSocket, SSH).
package transport
import (
"context"
"errors"
"fmt"
"github.com/fxamacker/cbor/v2"
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/entities/smart"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/henrygd/beszel/internal/entities/systemd"
)
// Transport defines the interface for hub-agent communication.
// Both WebSocket and SSH transports implement this interface.
type Transport interface {
// Request sends a request to the agent and unmarshals the response into dest.
// The dest parameter should be a pointer to the expected response type.
Request(ctx context.Context, action common.WebSocketAction, req any, dest any) error
// IsConnected returns true if the transport connection is active.
IsConnected() bool
// Close terminates the transport connection.
Close()
}
// UnmarshalResponse unmarshals an AgentResponse into the destination type.
// It first checks the generic Data field (0.19+ agents), then falls back
// to legacy typed fields for backward compatibility with 0.18.0 agents.
func UnmarshalResponse(resp common.AgentResponse, action common.WebSocketAction, dest any) error {
if dest == nil {
return errors.New("nil destination")
}
// Try generic Data field first (0.19+)
if len(resp.Data) > 0 {
if err := cbor.Unmarshal(resp.Data, dest); err != nil {
return fmt.Errorf("failed to unmarshal generic response data: %w", err)
}
return nil
}
// Fall back to legacy typed fields for older agents/hubs.
return unmarshalLegacyResponse(resp, action, dest)
}
// unmarshalLegacyResponse handles legacy responses that use typed fields.
func unmarshalLegacyResponse(resp common.AgentResponse, action common.WebSocketAction, dest any) error {
switch action {
case common.GetData:
d, ok := dest.(*system.CombinedData)
if !ok {
return fmt.Errorf("unexpected dest type for GetData: %T", dest)
}
if resp.SystemData == nil {
return errors.New("no system data in response")
}
*d = *resp.SystemData
return nil
case common.CheckFingerprint:
d, ok := dest.(*common.FingerprintResponse)
if !ok {
return fmt.Errorf("unexpected dest type for CheckFingerprint: %T", dest)
}
if resp.Fingerprint == nil {
return errors.New("no fingerprint in response")
}
*d = *resp.Fingerprint
return nil
case common.GetContainerLogs:
d, ok := dest.(*string)
if !ok {
return fmt.Errorf("unexpected dest type for GetContainerLogs: %T", dest)
}
if resp.String == nil {
return errors.New("no logs in response")
}
*d = *resp.String
return nil
case common.GetContainerInfo:
d, ok := dest.(*string)
if !ok {
return fmt.Errorf("unexpected dest type for GetContainerInfo: %T", dest)
}
if resp.String == nil {
return errors.New("no info in response")
}
*d = *resp.String
return nil
case common.GetSmartData:
d, ok := dest.(*map[string]smart.SmartData)
if !ok {
return fmt.Errorf("unexpected dest type for GetSmartData: %T", dest)
}
if resp.SmartData == nil {
return errors.New("no SMART data in response")
}
*d = resp.SmartData
return nil
case common.GetSystemdInfo:
d, ok := dest.(*systemd.ServiceDetails)
if !ok {
return fmt.Errorf("unexpected dest type for GetSystemdInfo: %T", dest)
}
if resp.ServiceInfo == nil {
return errors.New("no systemd info in response")
}
*d = resp.ServiceInfo
return nil
}
return fmt.Errorf("unsupported action: %d", action)
}

View File

@@ -1,74 +0,0 @@
package transport
import (
"context"
"errors"
"github.com/fxamacker/cbor/v2"
"github.com/henrygd/beszel"
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/hub/ws"
)
// ErrWebSocketNotConnected indicates a WebSocket transport is not currently connected.
var ErrWebSocketNotConnected = errors.New("websocket not connected")
// WebSocketTransport implements Transport over WebSocket connections.
type WebSocketTransport struct {
wsConn *ws.WsConn
}
// NewWebSocketTransport creates a new WebSocket transport wrapper.
func NewWebSocketTransport(wsConn *ws.WsConn) *WebSocketTransport {
return &WebSocketTransport{wsConn: wsConn}
}
// Request sends a request to the agent via WebSocket and unmarshals the response.
func (t *WebSocketTransport) Request(ctx context.Context, action common.WebSocketAction, req any, dest any) error {
if !t.IsConnected() {
return ErrWebSocketNotConnected
}
pendingReq, err := t.wsConn.SendRequest(ctx, action, req)
if err != nil {
return err
}
// Wait for response
select {
case message := <-pendingReq.ResponseCh:
defer message.Close()
defer pendingReq.Cancel()
// Legacy agents (< MinVersionAgentResponse) respond with a raw payload instead of an AgentResponse wrapper.
if t.wsConn.AgentVersion().LT(beszel.MinVersionAgentResponse) {
return cbor.Unmarshal(message.Data.Bytes(), dest)
}
var agentResponse common.AgentResponse
if err := cbor.Unmarshal(message.Data.Bytes(), &agentResponse); err != nil {
return err
}
if agentResponse.Error != "" {
return errors.New(agentResponse.Error)
}
return UnmarshalResponse(agentResponse, action, dest)
case <-pendingReq.Context.Done():
return pendingReq.Context.Err()
}
}
// IsConnected returns true if the WebSocket connection is active.
func (t *WebSocketTransport) IsConnected() bool {
return t.wsConn != nil && t.wsConn.IsConnected()
}
// Close terminates the WebSocket connection.
func (t *WebSocketTransport) Close() {
if t.wsConn != nil {
t.wsConn.Close(nil)
}
}

View File

@@ -6,12 +6,14 @@ import (
"github.com/fxamacker/cbor/v2"
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/entities/smart"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/henrygd/beszel/internal/entities/systemd"
"github.com/lxzan/gws"
"golang.org/x/crypto/ssh"
)
// ResponseHandler defines interface for handling agent responses.
// This is used by handleAgentRequest for legacy response handling.
// ResponseHandler defines interface for handling agent responses
type ResponseHandler interface {
Handle(agentResponse common.AgentResponse) error
HandleLegacy(rawData []byte) error
@@ -25,7 +27,167 @@ func (h *BaseHandler) HandleLegacy(rawData []byte) error {
}
////////////////////////////////////////////////////////////////////////////
// Fingerprint handling (used for WebSocket authentication)
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// systemDataHandler implements ResponseHandler for system data requests
type systemDataHandler struct {
data *system.CombinedData
}
func (h *systemDataHandler) HandleLegacy(rawData []byte) error {
return cbor.Unmarshal(rawData, h.data)
}
func (h *systemDataHandler) Handle(agentResponse common.AgentResponse) error {
if agentResponse.SystemData != nil {
*h.data = *agentResponse.SystemData
}
return nil
}
// RequestSystemData requests system metrics from the agent and unmarshals the response.
func (ws *WsConn) RequestSystemData(ctx context.Context, data *system.CombinedData, options common.DataRequestOptions) error {
if !ws.IsConnected() {
return gws.ErrConnClosed
}
req, err := ws.requestManager.SendRequest(ctx, common.GetData, options)
if err != nil {
return err
}
handler := &systemDataHandler{data: data}
return ws.handleAgentRequest(req, handler)
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// stringResponseHandler is a generic handler for string responses from agents
type stringResponseHandler struct {
BaseHandler
value string
errorMsg string
}
func (h *stringResponseHandler) Handle(agentResponse common.AgentResponse) error {
if agentResponse.String == nil {
return errors.New(h.errorMsg)
}
h.value = *agentResponse.String
return nil
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// requestContainerStringViaWS is a generic function to request container-related strings via WebSocket
func (ws *WsConn) requestContainerStringViaWS(ctx context.Context, action common.WebSocketAction, requestData any, errorMsg string) (string, error) {
if !ws.IsConnected() {
return "", gws.ErrConnClosed
}
req, err := ws.requestManager.SendRequest(ctx, action, requestData)
if err != nil {
return "", err
}
handler := &stringResponseHandler{errorMsg: errorMsg}
if err := ws.handleAgentRequest(req, handler); err != nil {
return "", err
}
return handler.value, nil
}
// RequestContainerLogs requests logs for a specific container via WebSocket.
func (ws *WsConn) RequestContainerLogs(ctx context.Context, containerID string) (string, error) {
return ws.requestContainerStringViaWS(ctx, common.GetContainerLogs, common.ContainerLogsRequest{ContainerID: containerID}, "no logs in response")
}
// RequestContainerInfo requests information about a specific container via WebSocket.
func (ws *WsConn) RequestContainerInfo(ctx context.Context, containerID string) (string, error) {
return ws.requestContainerStringViaWS(ctx, common.GetContainerInfo, common.ContainerInfoRequest{ContainerID: containerID}, "no info in response")
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// RequestSystemdInfo requests detailed information about a systemd service via WebSocket.
func (ws *WsConn) RequestSystemdInfo(ctx context.Context, serviceName string) (systemd.ServiceDetails, error) {
if !ws.IsConnected() {
return nil, gws.ErrConnClosed
}
req, err := ws.requestManager.SendRequest(ctx, common.GetSystemdInfo, common.SystemdInfoRequest{ServiceName: serviceName})
if err != nil {
return nil, err
}
var result systemd.ServiceDetails
handler := &systemdInfoHandler{result: &result}
if err := ws.handleAgentRequest(req, handler); err != nil {
return nil, err
}
return result, nil
}
// systemdInfoHandler parses ServiceDetails from AgentResponse
type systemdInfoHandler struct {
BaseHandler
result *systemd.ServiceDetails
}
func (h *systemdInfoHandler) Handle(agentResponse common.AgentResponse) error {
if agentResponse.ServiceInfo == nil {
return errors.New("no systemd info in response")
}
*h.result = agentResponse.ServiceInfo
return nil
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// RequestSmartData requests SMART data via WebSocket.
func (ws *WsConn) RequestSmartData(ctx context.Context) (map[string]smart.SmartData, error) {
if !ws.IsConnected() {
return nil, gws.ErrConnClosed
}
req, err := ws.requestManager.SendRequest(ctx, common.GetSmartData, nil)
if err != nil {
return nil, err
}
var result map[string]smart.SmartData
handler := ResponseHandler(&smartDataHandler{result: &result})
if err := ws.handleAgentRequest(req, handler); err != nil {
return nil, err
}
return result, nil
}
// smartDataHandler parses SMART data map from AgentResponse
type smartDataHandler struct {
BaseHandler
result *map[string]smart.SmartData
}
func (h *smartDataHandler) Handle(agentResponse common.AgentResponse) error {
if agentResponse.SmartData == nil {
return errors.New("no SMART data in response")
}
*h.result = agentResponse.SmartData
return nil
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// fingerprintHandler implements ResponseHandler for fingerprint requests

View File

@@ -0,0 +1,75 @@
//go:build testing
package ws
import (
"testing"
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/entities/systemd"
"github.com/stretchr/testify/assert"
)
func TestSystemdInfoHandlerSuccess(t *testing.T) {
handler := &systemdInfoHandler{
result: &systemd.ServiceDetails{},
}
// Test successful handling with valid ServiceInfo
testDetails := systemd.ServiceDetails{
"Id": "nginx.service",
"ActiveState": "active",
"SubState": "running",
"Description": "A high performance web server",
"ExecMainPID": 1234,
"MemoryCurrent": 1024000,
}
response := common.AgentResponse{
ServiceInfo: testDetails,
}
err := handler.Handle(response)
assert.NoError(t, err)
assert.Equal(t, testDetails, *handler.result)
}
func TestSystemdInfoHandlerError(t *testing.T) {
handler := &systemdInfoHandler{
result: &systemd.ServiceDetails{},
}
// Test error handling when ServiceInfo is nil
response := common.AgentResponse{
ServiceInfo: nil,
Error: "service not found",
}
err := handler.Handle(response)
assert.Error(t, err)
assert.Equal(t, "no systemd info in response", err.Error())
}
func TestSystemdInfoHandlerEmptyResponse(t *testing.T) {
handler := &systemdInfoHandler{
result: &systemd.ServiceDetails{},
}
// Test with completely empty response
response := common.AgentResponse{}
err := handler.Handle(response)
assert.Error(t, err)
assert.Equal(t, "no systemd info in response", err.Error())
}
func TestSystemdInfoHandlerLegacyNotSupported(t *testing.T) {
handler := &systemdInfoHandler{
result: &systemd.ServiceDetails{},
}
// Test that legacy format is not supported
err := handler.HandleLegacy([]byte("some data"))
assert.Error(t, err)
assert.Equal(t, "legacy format not supported", err.Error())
}

View File

@@ -45,15 +45,7 @@ func NewRequestManager(conn *gws.Conn) *RequestManager {
func (rm *RequestManager) SendRequest(ctx context.Context, action common.WebSocketAction, data any) (*PendingRequest, error) {
reqID := RequestID(rm.nextID.Add(1))
// Respect any caller-provided deadline. If none is set, apply a reasonable default
// so pending requests don't live forever if the agent never responds.
reqCtx := ctx
var cancel context.CancelFunc
if _, hasDeadline := ctx.Deadline(); hasDeadline {
reqCtx, cancel = context.WithCancel(ctx)
} else {
reqCtx, cancel = context.WithTimeout(ctx, 5*time.Second)
}
reqCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
req := &PendingRequest{
ID: reqID,
@@ -108,11 +100,6 @@ func (rm *RequestManager) handleResponse(message *gws.Message) {
return
}
if response.Id == nil {
rm.routeLegacyResponse(message)
return
}
reqID := RequestID(*response.Id)
rm.RLock()

View File

@@ -1,7 +1,6 @@
package ws
import (
"context"
"errors"
"time"
"weak"
@@ -162,14 +161,3 @@ func (ws *WsConn) handleAgentRequest(req *PendingRequest, handler ResponseHandle
func (ws *WsConn) IsConnected() bool {
return ws.conn != nil
}
// AgentVersion returns the connected agent's version (as reported during handshake).
func (ws *WsConn) AgentVersion() semver.Version {
return ws.agentVersion
}
// SendRequest sends a request to the agent and returns a pending request handle.
// This is used by the transport layer to send requests.
func (ws *WsConn) SendRequest(ctx context.Context, action common.WebSocketAction, data any) (*PendingRequest, error) {
return ws.requestManager.SendRequest(ctx, action, data)
}

View File

@@ -184,18 +184,14 @@ func TestCommonActions(t *testing.T) {
assert.Equal(t, common.WebSocketAction(2), common.GetContainerLogs, "GetLogs should be action 2")
}
func TestFingerprintHandler(t *testing.T) {
var result common.FingerprintResponse
h := &fingerprintHandler{result: &result}
func TestLogsHandler(t *testing.T) {
h := &stringResponseHandler{errorMsg: "no logs in response"}
resp := common.AgentResponse{Fingerprint: &common.FingerprintResponse{
Fingerprint: "test-fingerprint",
Hostname: "test-host",
}}
logValue := "test logs"
resp := common.AgentResponse{String: &logValue}
err := h.Handle(resp)
assert.NoError(t, err)
assert.Equal(t, "test-fingerprint", result.Fingerprint)
assert.Equal(t, "test-host", result.Hostname)
assert.Equal(t, logValue, h.value)
}
// TestHandler tests that we can create a Handler

View File

@@ -14,7 +14,6 @@ export default defineConfig({
"he",
"hr",
"hu",
"id",
"it",
"ja",
"ko",

View File

@@ -1,7 +1,7 @@
{
"name": "beszel",
"private": true,
"version": "0.18.0-beta.2",
"version": "0.18.0-beta.1",
"type": "module",
"scripts": {
"dev": "vite --host",

View File

@@ -18,7 +18,7 @@ export function LangToggle() {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="grid grid-cols-3">
{languages.map(([lang, label, e]) => (
{languages.map(({ lang, label, e }) => (
<DropdownMenuItem
key={lang}
className={cn("px-2.5 flex gap-2.5 cursor-pointer", lang === i18n.locale && "bg-accent/70 font-medium")}

View File

@@ -25,13 +25,13 @@ const passwordSchema = v.pipe(
)
const LoginSchema = v.looseObject({
company_website: honeypot,
name: honeypot,
email: emailSchema,
password: passwordSchema,
})
const RegisterSchema = v.looseObject({
company_website: honeypot,
name: honeypot,
email: emailSchema,
password: passwordSchema,
passwordConfirm: passwordSchema,
@@ -248,8 +248,8 @@ export function UserAuthForm({
)}
<div className="sr-only">
{/* honeypot */}
<label htmlFor="company_website"></label>
<input id="company_website" type="text" name="company_website" tabIndex={-1} autoComplete="off" />
<label htmlFor="name"></label>
<input id="name" type="text" name="name" tabIndex={-1} autoComplete="off" />
</div>
<button className={cn(buttonVariants())} disabled={isLoading}>
{isLoading ? (
@@ -305,9 +305,9 @@ export function UserAuthForm({
className="me-2 h-4 w-4 dark:brightness-0 dark:invert"
src={getAuthProviderIcon(provider)}
alt=""
// onError={(e) => {
// e.currentTarget.src = "/static/lock.svg"
// }}
// onError={(e) => {
// e.currentTarget.src = "/static/lock.svg"
// }}
/>
)}
<span className="translate-y-px">{provider.displayName}</span>

View File

@@ -68,10 +68,10 @@ export default function SettingsProfilePage({ userSettings }: { userSettings: Us
<SelectValue />
</SelectTrigger>
<SelectContent>
{languages.map(([lang, label, e]) => (
<SelectItem key={lang} value={lang}>
<span className="me-2.5">{e}</span>
{label}
{languages.map((lang) => (
<SelectItem key={lang.lang} value={lang.lang}>
<span className="me-2.5">{lang.e}</span>
{lang.label}
</SelectItem>
))}
</SelectContent>

View File

@@ -16,7 +16,7 @@ import MemChart from "@/components/charts/mem-chart"
import SwapChart from "@/components/charts/swap-chart"
import TemperatureChart from "@/components/charts/temperature-chart"
import { getPbTimestamp, pb } from "@/lib/api"
import { ChartType, SystemStatus, Unit } from "@/lib/enums"
import { ChartType, Os, SystemStatus, Unit } from "@/lib/enums"
import { batteryStateTranslations } from "@/lib/i18n"
import {
$allSystemsById,
@@ -222,6 +222,7 @@ export default memo(function SystemDetail({ id }: { id: string }) {
}, [system.id])
// subscribe to realtime metrics if chart time is 1m
// biome-ignore lint/correctness/useExhaustiveDependencies: not necessary
useEffect(() => {
let unsub = () => {}
if (!system.id || chartTime !== "1m") {
@@ -259,6 +260,7 @@ export default memo(function SystemDetail({ id }: { id: string }) {
}
}, [chartTime, system.id])
// biome-ignore lint/correctness/useExhaustiveDependencies: not necessary
const chartData: ChartData = useMemo(() => {
const lastCreated = Math.max(
(systemStats.at(-1)?.created as number) ?? 0,
@@ -298,6 +300,7 @@ export default memo(function SystemDetail({ id }: { id: string }) {
}, [])
// get stats
// biome-ignore lint/correctness/useExhaustiveDependencies: not necessary
useEffect(() => {
if (!system.id || !chartTime || chartTime === "1m") {
return
@@ -400,35 +403,11 @@ export default memo(function SystemDetail({ id }: { id: string }) {
const containerFilterBar = containerData.length ? <FilterBar /> : null
const dataEmpty = !chartLoading && chartData.systemStats.length === 0
const lastGpus = systemStats.at(-1)?.stats?.g
let hasGpuData = false
let hasGpuEnginesData = false
let hasGpuPowerData = false
if (lastGpus) {
// check if there are any GPUs with engines
for (const id in lastGpus) {
hasGpuData = true
if (lastGpus[id].e !== undefined) {
hasGpuEnginesData = true
break
}
}
// check if there are any GPUs with power data
for (let i = 0; i < systemStats.length && !hasGpuPowerData; i++) {
const gpus = systemStats[i].stats?.g
if (!gpus) continue
for (const id in gpus) {
if (gpus[id].p !== undefined || gpus[id].pp !== undefined) {
hasGpuPowerData = true
break
}
}
}
}
const isLinux = !(details?.os ?? system.info?.os)
const lastGpuVals = Object.values(systemStats.at(-1)?.stats.g ?? {})
const hasGpuData = lastGpuVals.length > 0
const hasGpuPowerData = lastGpuVals.some((gpu) => gpu.p !== undefined || gpu.pp !== undefined)
const hasGpuEnginesData = lastGpuVals.some((gpu) => gpu.e !== undefined)
const isLinux = (details?.os ?? system.info?.os) === Os.Linux
const isPodman = details?.podman ?? system.info?.p ?? false
return (
@@ -739,65 +718,64 @@ export default memo(function SystemDetail({ id }: { id: string }) {
<GpuEnginesChart chartData={chartData} />
</ChartCard>
)}
{lastGpus &&
Object.keys(lastGpus).map((id) => {
const gpu = lastGpus[id] as GPUData
return (
<div key={id} className="contents">
{Object.keys(systemStats.at(-1)?.stats.g ?? {}).map((id) => {
const gpu = systemStats.at(-1)?.stats.g?.[id] as GPUData
return (
<div key={id} className="contents">
<ChartCard
className={cn(grid && "!col-span-1")}
empty={dataEmpty}
grid={grid}
title={`${gpu.n} ${t`Usage`}`}
description={t`Average utilization of ${gpu.n}`}
>
<AreaChartDefault
chartData={chartData}
dataPoints={[
{
label: t`Usage`,
dataKey: ({ stats }) => stats?.g?.[id]?.u ?? 0,
color: 1,
opacity: 0.35,
},
]}
tickFormatter={(val) => `${toFixedFloat(val, 2)}%`}
contentFormatter={({ value }) => `${decimalString(value)}%`}
/>
</ChartCard>
{(gpu.mt ?? 0) > 0 && (
<ChartCard
className={cn(grid && "!col-span-1")}
empty={dataEmpty}
grid={grid}
title={`${gpu.n} ${t`Usage`}`}
description={t`Average utilization of ${gpu.n}`}
title={`${gpu.n} VRAM`}
description={t`Precise utilization at the recorded time`}
>
<AreaChartDefault
chartData={chartData}
dataPoints={[
{
label: t`Usage`,
dataKey: ({ stats }) => stats?.g?.[id]?.u ?? 0,
color: 1,
opacity: 0.35,
dataKey: ({ stats }) => stats?.g?.[id]?.mu ?? 0,
color: 2,
opacity: 0.25,
},
]}
tickFormatter={(val) => `${toFixedFloat(val, 2)}%`}
contentFormatter={({ value }) => `${decimalString(value)}%`}
max={gpu.mt}
tickFormatter={(val) => {
const { value, unit } = formatBytes(val, false, Unit.Bytes, true)
return `${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`
}}
contentFormatter={({ value }) => {
const { value: convertedValue, unit } = formatBytes(value, false, Unit.Bytes, true)
return `${decimalString(convertedValue)} ${unit}`
}}
/>
</ChartCard>
{(gpu.mt ?? 0) > 0 && (
<ChartCard
empty={dataEmpty}
grid={grid}
title={`${gpu.n} VRAM`}
description={t`Precise utilization at the recorded time`}
>
<AreaChartDefault
chartData={chartData}
dataPoints={[
{
label: t`Usage`,
dataKey: ({ stats }) => stats?.g?.[id]?.mu ?? 0,
color: 2,
opacity: 0.25,
},
]}
max={gpu.mt}
tickFormatter={(val) => {
const { value, unit } = formatBytes(val, false, Unit.Bytes, true)
return `${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`
}}
contentFormatter={({ value }) => {
const { value: convertedValue, unit } = formatBytes(value, false, Unit.Bytes, true)
return `${decimalString(convertedValue)} ${unit}`
}}
/>
</ChartCard>
)}
</div>
)
})}
)}
</div>
)
})}
</div>
)}

View File

@@ -287,12 +287,12 @@ export function SystemsTableColumns(viewMode: "table" | "grid"): ColumnDef<Syste
return null
}
const iconColor = pct < 10 ? "text-red-500" : pct < 25 ? "text-yellow-500" : "text-muted-foreground"
let Icon = PlugChargingIcon
let iconColor = "text-muted-foreground"
if (state !== BatteryState.Charging) {
if (pct < 25) {
iconColor = pct < 11 ? "text-red-500" : "text-yellow-500"
Icon = BatteryLowIcon
} else if (pct < 75) {
Icon = BatteryMediumIcon

View File

@@ -154,7 +154,7 @@ export function BatteryMediumIcon(props: SVGProps<SVGSVGElement>) {
export function BatteryLowIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg viewBox="0 0 24 24" {...props} fill="currentColor">
<path d="M16 17H8V6h8m.7-2H15V2H9v2H7.3A1.3 1.3 0 0 0 6 5.3v15.4q.1 1.2 1.3 1.3h9.4a1.3 1.3 0 0 0 1.3-1.3V5.3q-.1-1.2-1.3-1.3" />
<path d="M16 20H8V6h8m.67-2H15V2H9v2H7.33C6.6 4 6 4.6 6 5.33v15.34C6 21.4 6.6 22 7.33 22h9.34c.74 0 1.33-.59 1.33-1.33V5.33C18 4.6 17.4 4 16.67 4M15 16H9v3h6zm0-4.5H9v3h6z" />
</svg>
)
}

View File

@@ -53,7 +53,7 @@ export function getLocale() {
}
locale = (locale || "en").split("-")[0]
// use en if locale is not in languages
if (!languages.some((l) => l[0] === locale)) {
if (!languages.some((l) => l.lang === locale)) {
locale = "en"
}
return locale

View File

@@ -1,32 +1,147 @@
export default [
["ar", "العربية", "🇵🇸"],
["bg", "Български", "🇧🇬"],
["cs", "Čeština", "🇨🇿"],
["da", "Dansk", "🇩🇰"],
["de", "Deutsch", "🇩🇪"],
["en", "English", "🇬🇧"],
["es", "Español", "🇪🇸"],
["fa", "فارسی", "🇮🇷"],
["fr", "Français", "🇫🇷"],
["he", "עברית", "🕎"],
["hr", "Hrvatski", "🇭🇷"],
["hu", "Magyar", "🇭🇺"],
["id", "Indonesia", "🇮🇩"],
["it", "Italiano", "🇮🇹"],
["ja", "日本語", "🇯🇵"],
["ko", "한국어", "🇰🇷"],
["nl", "Nederlands", "🇳🇱"],
["no", "Norsk", "🇳🇴"],
["pl", "Polski", "🇵🇱"],
["pt", "Português", "🇵🇹"],
["ru", "Русский", "🇷🇺"],
["sl", "Slovenščina", "🇸🇮"],
["sr", "Српски", "🇷🇸"],
["sv", "Svenska", "🇸🇪"],
["tr", "Türkçe", "🇹🇷"],
["uk", "Українська", "🇺🇦"],
["vi", "Tiếng Việt", "🇻🇳"],
["zh-CN", "简体中文", "🇨🇳"],
["zh-HK", "繁體中文", "🇭🇰"],
["zh", "繁體中文", "🇹🇼"],
{
lang: "ar",
label: "العربية",
e: "🇵🇸",
},
{
lang: "bg",
label: "Български",
e: "🇧🇬",
},
{
lang: "cs",
label: "Čeština",
e: "🇨🇿",
},
{
lang: "da",
label: "Dansk",
e: "🇩🇰",
},
{
lang: "de",
label: "Deutsch",
e: "🇩🇪",
},
{
lang: "en",
label: "English",
e: "🇺🇸",
},
{
lang: "es",
label: "Español",
e: "🇲🇽",
},
{
lang: "fa",
label: "فارسی",
e: "🇮🇷",
},
{
lang: "fr",
label: "Français",
e: "🇫🇷",
},
{
lang: "he",
label: "עברית",
e: "🕎",
},
{
lang: "hr",
label: "Hrvatski",
e: "🇭🇷",
},
{
lang: "hu",
label: "Magyar",
e: "🇭🇺",
},
{
lang: "it",
label: "Italiano",
e: "🇮🇹",
},
{
lang: "ja",
label: "日本語",
e: "🇯🇵",
},
{
lang: "ko",
label: "한국어",
e: "🇰🇷",
},
{
lang: "nl",
label: "Nederlands",
e: "🇳🇱",
},
{
lang: "no",
label: "Norsk",
e: "🇳🇴",
},
{
lang: "pl",
label: "Polski",
e: "🇵🇱",
},
{
lang: "pt",
label: "Português",
e: "🇧🇷",
},
{
lang: "ru",
label: "Русский",
e: "🇷🇺",
},
{
lang: "sl",
label: "Slovenščina",
e: "🇸🇮",
},
{
lang: "sr",
label: "Српски",
e: "🇷🇸",
},
{
lang: "sv",
label: "Svenska",
e: "🇸🇪",
},
{
lang: "tr",
label: "Türkçe",
e: "🇹🇷",
},
{
lang: "uk",
label: "Українська",
e: "🇺🇦",
},
{
lang: "vi",
label: "Tiếng Việt",
e: "🇻🇳",
},
{
lang: "zh-CN",
label: "简体中文",
e: "🇨🇳",
},
{
lang: "zh-HK",
label: "繁體中文",
e: "🇭🇰",
},
{
lang: "zh",
label: "繁體中文",
e: "🇹🇼",
},
] as const

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: ar\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-25 19:15\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Arabic\n"
"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "تم تحديد {0} من {1} صف"
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# نواة} other {# نواة}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} يوم} other {{countString} أيام}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} ساعة} other {{countString} ساع
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} دقيقة} few {{countString} دقائق} many {{countString} دقيقة} other {{countString} دقيقة}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# خيط} other {# خيط}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 ساعة"
@@ -190,11 +182,6 @@ msgstr "متوسط"
msgid "Average CPU utilization of containers"
msgstr "متوسط استخدام وحدة المعالجة المركزية للحاويات"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "المتوسط ينخفض أقل من <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "النسخ الاحتياطية"
msgid "Bandwidth"
msgstr "عرض النطاق الترددي"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "بطارية"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "البطارية"
@@ -249,13 +230,6 @@ msgstr "أصبح غير نشط"
msgid "Before"
msgstr "قبل"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "أقل من {0}{1} في آخر {2, plural, one {# دقيقة} other {# دقائق}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "يدعم بيزيل بروتوكول OpenID Connect والعديد من مزوّدي المصادقة عبر بروتوكول OAuth2."
@@ -594,7 +568,7 @@ msgstr "التوثيق"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -620,7 +594,7 @@ msgstr "تعديل"
#: src/components/add-system.tsx
#: src/components/routes/settings/quiet-hours.tsx
msgid "Edit {foo}"
msgstr "إضافة {foo}"
msgstr ""
#: src/components/login/auth-form.tsx
#: src/components/login/forgot-pass-form.tsx
@@ -829,6 +803,11 @@ msgstr "غير نشط"
msgid "Invalid email address."
msgstr "عنوان البريد الإشباكي غير صالح."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "النواة"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "اللغة"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "الحد الأقصى دقيقة"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "تنسيق الوقت"
msgid "To email(s)"
msgstr "إلى البريد الإشباكي"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "تبديل الشبكة"
@@ -1531,10 +1509,6 @@ msgstr "يتم التفعيل عندما يتجاوز متوسط التحميل
msgid "Triggers when any sensor exceeds a threshold"
msgstr "يتم التفعيل عندما يتجاوز أي مستشعر عتبة معينة"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "يتم التفعيل عندما تنخفض شحنة البطارية أقل من عتبة معينة"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "يتم التفعيل عندما يتجاوز الجمع بين الصعود/الهبوط عتبة معينة"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "غير محدود"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "قيد التشغيل"
@@ -1617,7 +1591,7 @@ msgstr "يتم التحديث كل 10 دقائق."
msgid "Upload"
msgstr "رفع"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "مدة التشغيل"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: bg\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:17\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Bulgarian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} от {1} селектирани."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# ядро} other {# ядра}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} ден} other {{countString} дни}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} час} other {{countString} часа
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} минута} few {{countString} минути} many {{countString} минути} other {{countString} минути}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# нишка} other {# нишки}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 час"
@@ -190,11 +182,6 @@ msgstr "Средно"
msgid "Average CPU utilization of containers"
msgstr "Средно използване на процесора на контейнерите"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Средната стойност пада под <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Архиви"
msgid "Bandwidth"
msgstr "Bandwidth на мрежата"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Батерия"
@@ -249,13 +230,6 @@ msgstr "Стана неактивен"
msgid "Before"
msgstr "Преди"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Под {0}{1} в последните {2, plural, one {# минута} other {# минути}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel поддържа OpenID Connect и много други OAuth2 доставчици за удостоверяване."
@@ -594,7 +568,7 @@ msgstr "Документация"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "Неактивен"
msgid "Invalid email address."
msgstr "Невалиден имейл адрес."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Linux Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Език"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Максимум 1 минута"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Формат на времето"
msgid "To email(s)"
msgstr "До имейл(ите)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Превключване на мрежа"
@@ -1531,10 +1509,6 @@ msgstr "Задейства се, когато употребата на паме
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Задейства се, когато някой даден сензор надвиши зададен праг"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Задейства се, когато зарядът на батерията падне под зададен праг"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Задейства се, когато комбинираното качване/сваляне надвиши зададен праг"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Неограничено"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Нагоре"
@@ -1617,7 +1591,7 @@ msgstr "Актуализира се на всеки 10 минути."
msgid "Upload"
msgstr "Качване"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Време на работа"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: cs\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-05 20:24\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Czech\n"
"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 3;\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} z {1} vybraných řádků."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# jádro} few {# jádra} many {# jader} other {# jader}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} den} few {{countString} dny} other {{countString} dní}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} Hodina} few {{countString} Hodiny} ma
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuty} many {{countString} minut} other {{countString} minut}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# vlákno} few {# vlákna} many {# vláken} other {# vláken}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 hodina"
@@ -190,11 +182,6 @@ msgstr "Průměr"
msgid "Average CPU utilization of containers"
msgstr "Průměrné využití CPU kontejnerů"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Průměr klesne pod <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Zálohy"
msgid "Bandwidth"
msgstr "Přenos"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Baterie"
@@ -249,13 +230,6 @@ msgstr "Stal se neaktivním"
msgid "Before"
msgstr "Před"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Pod {0}{1} za {2, plural, one {poslední # minutu} few {poslední # minuty} other {posledních # minut}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel podporuje OpenID Connect a mnoho poskytovatelů OAuth2 ověřování."
@@ -594,7 +568,7 @@ msgstr "Dokumentace"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "Neaktivní"
msgid "Invalid email address."
msgstr "Neplatná e-mailová adresa."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Jádro"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Jazyk"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Max. 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Formát času"
msgid "To email(s)"
msgstr "Na email(y)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Přepnout mřížku"
@@ -1531,10 +1509,6 @@ msgstr "Spustí se, když využití paměti během 5 minut překročí prahovou
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Spustí se, když některý senzor překročí prahovou hodnotu"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Spustí se, když úroveň nabití baterie klesne pod prahovou hodnotu"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Spustí se, když kombinace up/down překročí prahovou hodnotu"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Neomezeno"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Funkční"
@@ -1617,7 +1591,7 @@ msgstr "Aktualizováno každých 10 minut."
msgid "Upload"
msgstr "Odeslání"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Doba provozu"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: da\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-19 10:55\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Danish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} af {1} række(r) valgt."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# kerne} other {# kerner}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} dag} other {{countString} dage}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} time} other {{countString} timer}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minut} other {{countString} minutter}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# tråd} other {# tråde}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 time"
@@ -190,11 +182,6 @@ msgstr "Gennemsnitlig"
msgid "Average CPU utilization of containers"
msgstr "Gennemsnitlig CPU udnyttelse af containere"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Gennemsnit falder under <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Sikkerhedskopier"
msgid "Bandwidth"
msgstr "Båndbredde"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Batteri"
@@ -249,13 +230,6 @@ msgstr "Blev inaktiv"
msgid "Before"
msgstr "Før"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Under {0}{1} i sidste {2, plural, one {# minut} other {# minutter}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel understøtter OpenID Connect og mange OAuth2 godkendelsesudbydere."
@@ -468,7 +442,7 @@ msgstr "CPU Peak"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "CPU tid"
msgstr ""
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
@@ -594,7 +568,7 @@ msgstr "Dokumentation"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -674,7 +648,7 @@ msgstr "Overskrider {0}{1} i sidste {2, plural, one {# minut} other {# minutter}
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr "Exec vigtigste PID"
msgstr ""
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
@@ -746,7 +720,7 @@ msgstr "Fingeraftryk"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "Firmware"
msgstr ""
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
@@ -829,6 +803,11 @@ msgstr "Inaktiv"
msgid "Invalid email address."
msgstr "Ugyldig email adresse."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kerne"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Sprog"
@@ -848,7 +827,7 @@ msgstr "Livscyklus"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr "grænse"
msgstr ""
#: src/components/routes/system.tsx
msgid "Load Average"
@@ -904,7 +883,7 @@ msgstr "Leder du i stedet for efter hvor du kan oprette alarmer? Klik på klokke
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr "Primær PID"
msgstr ""
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Maks. 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -935,7 +913,7 @@ msgstr "Hukommelsesgrænse"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "Hukommelsesspids"
msgstr ""
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
@@ -961,7 +939,7 @@ msgstr "Navn"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "Net"
msgstr ""
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
@@ -1230,7 +1208,7 @@ msgstr "Genoptag"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr "Root"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
@@ -1388,7 +1366,7 @@ msgstr "Gennemsnitlig system belastning over tid"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr "Systemd Services"
msgstr ""
#: src/components/navbar.tsx
msgid "Systems"
@@ -1461,8 +1439,8 @@ msgstr "Tidsformat"
msgid "To email(s)"
msgstr "Til email(s)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Slå gitter til/fra"
@@ -1531,10 +1509,6 @@ msgstr "Udløser når 5 minut belastning gennemsnit overstiger en tærskel"
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Udløser når en sensor overstiger en tærskel"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Udløses når batteriniveauet falder under en tærskel"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Udløses når de kombinerede op/ned overstiger en tærskel"
@@ -1567,7 +1541,7 @@ msgstr "Type"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr "Enhed fil"
msgstr ""
#. Temperature / network units
#: src/components/routes/settings/general.tsx
@@ -1587,10 +1561,10 @@ msgstr "Ukendt"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "Ubegrænset"
msgstr ""
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Oppe"
@@ -1617,7 +1591,7 @@ msgstr "Opdateret hver 10. minut."
msgid "Upload"
msgstr "Overfør"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Oppetid"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: de\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-05 20:24\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: German\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} von {1} Zeile(n) ausgewählt."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# Kern} other {# Kerne}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} Tag} other {{countString} Tage}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} Stunde} other {{countString} Stunden}
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} Minute} other {{countString} Minuten}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# Thread} other {# Threads}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 Stunde"
@@ -190,11 +182,6 @@ msgstr "Durchschnitt"
msgid "Average CPU utilization of containers"
msgstr "Durchschnittliche CPU-Auslastung der Container"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Durchschnitt unterschreitet <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Backups"
msgid "Bandwidth"
msgstr "Bandbreite"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Batterie"
@@ -249,13 +230,6 @@ msgstr "Wurde inaktiv"
msgid "Before"
msgstr "Vor"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Unterschreitet {0}{1} in den letzten {2, plural, one {# Minute} other {# Minuten}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel unterstützt OpenID Connect und viele OAuth2-Authentifizierungsanbieter."
@@ -594,7 +568,7 @@ msgstr "Dokumentation"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "Inaktiv"
msgid "Invalid email address."
msgstr "Ungültige E-Mail-Adresse."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Sprache"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Max 1 Min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Zeitformat"
msgid "To email(s)"
msgstr "An E-Mail(s)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Raster umschalten"
@@ -1531,10 +1509,6 @@ msgstr "Löst aus, wenn der Lastdurchschnitt der letzten 5 Minuten einen Schwell
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Löst aus, wenn ein Sensor einen Schwellenwert überschreitet"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Löst aus, wenn der Batterieladestand unter einen Schwellenwert fällt"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Löst aus, wenn die kombinierte Up- und Downloadrate einen Schwellenwert überschreitet"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Unbegrenzt"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "aktiv"
@@ -1617,7 +1591,7 @@ msgstr "Alle 10 Minuten aktualisiert."
msgid "Upload"
msgstr "Hochladen"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Betriebszeit"

View File

@@ -19,10 +19,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} of {1} row(s) selected."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# core} other {# cores}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} day} other {{countString} days}}"
@@ -35,10 +31,6 @@ msgstr "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# thread} other {# threads}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 hour"
@@ -185,11 +177,6 @@ msgstr "Average"
msgid "Average CPU utilization of containers"
msgstr "Average CPU utilization of containers"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Average drops below <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -222,13 +209,7 @@ msgstr "Backups"
msgid "Bandwidth"
msgstr "Bandwidth"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Battery"
@@ -244,13 +225,6 @@ msgstr "Became inactive"
msgid "Before"
msgstr "Before"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel supports OpenID Connect and many OAuth2 authentication providers."
@@ -589,7 +563,7 @@ msgstr "Documentation"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -824,6 +798,11 @@ msgstr "Inactive"
msgid "Invalid email address."
msgstr "Invalid email address."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Language"
@@ -916,7 +895,6 @@ msgid "Max 1 min"
msgstr "Max 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1456,8 +1434,8 @@ msgstr "Time format"
msgid "To email(s)"
msgstr "To email(s)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Toggle grid"
@@ -1526,10 +1504,6 @@ msgstr "Triggers when 5 minute load average exceeds a threshold"
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Triggers when any sensor exceeds a threshold"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Triggers when battery charge drops below a threshold"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Triggers when combined up/down exceeds a threshold"
@@ -1585,7 +1559,7 @@ msgid "Unlimited"
msgstr "Unlimited"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Up"
@@ -1612,7 +1586,7 @@ msgstr "Updated every 10 minutes."
msgid "Upload"
msgstr "Upload"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Uptime"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: es\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-14 09:39\n"
"PO-Revision-Date: 2025-12-01 23:32\n"
"Last-Translator: \n"
"Language-Team: Spanish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} de {1} fila(s) seleccionada(s)."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# núcleo} other {# núcleos}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} día} other {{countString} días}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} hora} other {{countString} horas}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuto} other {{countString} minutos}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# hilo} other {# hilos}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 hora"
@@ -190,11 +182,6 @@ msgstr "Promedio"
msgid "Average CPU utilization of containers"
msgstr "Utilización promedio de CPU de los contenedores"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "El promedio cae por debajo de <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Copias de seguridad"
msgid "Bandwidth"
msgstr "Ancho de banda"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Batería"
@@ -249,13 +230,6 @@ msgstr "Se desactivó"
msgid "Before"
msgstr "Antes"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Por debajo de {0}{1} en el último {2, plural, one {# minuto} other {# minutos}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel admite OpenID Connect y muchos proveedores de autenticación OAuth2."
@@ -357,7 +331,7 @@ msgstr "Verifica tu servicio de notificaciones"
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Limpiar"
msgstr ""
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
@@ -594,7 +568,7 @@ msgstr "Documentación"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "Inactivo"
msgid "Invalid email address."
msgstr "Dirección de correo electrónico no válida."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Idioma"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Máx. 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Formato de hora"
msgid "To email(s)"
msgstr "A correo(s)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Alternar cuadrícula"
@@ -1531,10 +1509,6 @@ msgstr "Se activa cuando la carga media de 5 minutos supera un umbral"
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Se activa cuando cualquier sensor supera un umbral"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Se activa cuando la carga de la batería baja de un umbral"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Se activa cuando la suma de subida/bajada supera un umbral"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Ilimitado"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Activo"
@@ -1617,7 +1591,7 @@ msgstr "Actualizado cada 10 minutos."
msgid "Upload"
msgstr "Cargar"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Tiempo de actividad"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: fa\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:18\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Persian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} از {1} ردیف انتخاب شده است."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# هسته} other {# هسته}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} روز} other {{countString} روز}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} ساعت} other {{countString} ساع
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} دقیقه} few {{countString} دقیقه} many {{countString} دقیقه} other {{countString} دقیقه}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# رشته} other {# رشته}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "۱ ساعت"
@@ -190,11 +182,6 @@ msgstr "میانگین"
msgid "Average CPU utilization of containers"
msgstr "میانگین استفاده از CPU کانتینرها"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "میانگین به زیر <0>{value}{0}</0> می‌افتد"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "پشتیبان‌گیری‌ها"
msgid "Bandwidth"
msgstr "پهنای باند"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "باتری"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "باتری"
@@ -249,13 +230,6 @@ msgstr "غیرفعال شد"
msgid "Before"
msgstr "قبل از"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "زیر {0}{1} در آخرین {2, plural, one {# دقیقه} other {# دقیقه}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "بِزل از OpenID Connect و بسیاری از ارائه‌دهندگان احراز هویت OAuth2 پشتیبانی می‌کند."
@@ -357,7 +331,7 @@ msgstr "سرویس اطلاع‌رسانی خود را بررسی کنید"
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "پاک کردن"
msgstr ""
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
@@ -594,7 +568,7 @@ msgstr "مستندات"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -674,7 +648,7 @@ msgstr "در {2, plural, one {# دقیقه} other {# دقیقه}} گذشته ا
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr "PID اصلی اجرایی"
msgstr ""
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
@@ -829,6 +803,11 @@ msgstr "غیرفعال"
msgid "Invalid email address."
msgstr "آدرس ایمیل نامعتبر است."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "هسته"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "زبان"
@@ -848,7 +827,7 @@ msgstr "چرخه حیات"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr "محدودیت"
msgstr ""
#: src/components/routes/system.tsx
msgid "Load Average"
@@ -904,7 +883,7 @@ msgstr "به دنبال جایی برای ایجاد هشدار هستید؟ ر
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr "PID اصلی"
msgstr ""
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "حداکثر ۱ دقیقه"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1230,7 +1208,7 @@ msgstr "ادامه"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr "ریشه"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
@@ -1461,8 +1439,8 @@ msgstr "فرمت زمان"
msgid "To email(s)"
msgstr "به ایمیل(ها)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "تغییر نمایش جدول"
@@ -1531,10 +1509,6 @@ msgstr "هنگامی که میانگین بار ۵ دقیقه‌ای از یک
msgid "Triggers when any sensor exceeds a threshold"
msgstr "هنگامی که هر حسگری از یک آستانه فراتر رود، فعال می‌شود"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "زمانی که شارژ باتری زیر آستانه قرار می‌گیرد، فعال می‌شود"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "هنگامی که مجموع بالا/پایین از یک آستانه فراتر رود، فعال می‌شود"
@@ -1567,7 +1541,7 @@ msgstr "نوع"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr "فایل واحد"
msgstr ""
#. Temperature / network units
#: src/components/routes/settings/general.tsx
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "نامحدود"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "فعال"
@@ -1617,7 +1591,7 @@ msgstr "هر ۱۰ دقیقه به‌روزرسانی می‌شود."
msgid "Upload"
msgstr "آپلود"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "آپتایم"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: fr\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-01-09 21:08\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: French\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} sur {1} ligne(s) sélectionnée(s)."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# cœur} other {# cœurs}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} jour} other {{countString} jours}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} heure} other {{countString} heures}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minute} other {{countString} minutes}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# fil} other {# fils}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 heure"
@@ -190,11 +182,6 @@ msgstr "Moyenne"
msgid "Average CPU utilization of containers"
msgstr "Utilisation moyenne du CPU des conteneurs"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "La moyenne descend en dessous de <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Sauvegardes"
msgid "Bandwidth"
msgstr "Bande passante"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Batterie"
@@ -249,13 +230,6 @@ msgstr "Devenu inactif"
msgid "Before"
msgstr "Avant"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Inférieur à {0}{1} dans {2, plural, one {la dernière # minute} other {les dernières # minutes}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel prend en charge OpenID Connect et de nombreux fournisseurs d'authentification OAuth2."
@@ -538,7 +512,7 @@ msgstr "Supprimer l'empreinte"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr "Description"
msgstr ""
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
@@ -594,11 +568,11 @@ msgstr "Documentation"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
msgstr "Hors ligne"
msgstr "Injoignable"
#: src/components/systems-table/systems-table.tsx
msgid "Down ({downSystemsLength})"
@@ -750,7 +724,7 @@ msgstr "Micrologiciel"
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Pendant <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Pour <0>{min}</0> {min, plural, one {minute} other {minutes}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
@@ -829,6 +803,11 @@ msgstr "Inactif"
msgid "Invalid email address."
msgstr "Adresse email invalide."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Noyau"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Langue"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Max 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -961,7 +939,7 @@ msgstr "Nom"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "Rés"
msgstr "Net"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
@@ -1461,8 +1439,8 @@ msgstr "Format d'heure"
msgid "To email(s)"
msgstr "Aux email(s)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Basculer la grille"
@@ -1521,20 +1499,16 @@ msgstr "Se déclenche lorsque la charge moyenne sur 1 minute dépasse un seuil"
#: src/lib/alerts.ts
msgid "Triggers when 15 minute load average exceeds a threshold"
msgstr "Se déclenche lorsque la charge moyenne sur 15 minutes dépasse un seuil"
msgstr "Se déclenche lorsque la charge moyenne sur 15 minute dépasse un seuil"
#: src/lib/alerts.ts
msgid "Triggers when 5 minute load average exceeds a threshold"
msgstr "Se déclenche lorsque la charge moyenne sur 5 minutes dépasse un seuil"
msgstr "Se déclenche lorsque la charge moyenne sur 5 minute dépasse un seuil"
#: src/lib/alerts.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Déclenchement lorsque tout capteur dépasse un seuil"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Déclenchement lorsque la charge de la batterie descend en dessous d'un seuil"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Déclenchement lorsque le montant/descendant combinée dépasse un seuil"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Illimité"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Joignable"
@@ -1617,7 +1591,7 @@ msgstr "Mis à jour toutes les 10 minutes."
msgid "Upload"
msgstr "Téléverser"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Temps de fonctionnement"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: he\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:18\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Hebrew\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} מתוך {1} שורה(ות) נבחרו."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# ליבה} other {# ליבות}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} יום} two {{countString} ימים} other {{countString} ימים}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} שעה} two {{countString} שעות}
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} דקה} two {{countString} דקות} other {{countString} דקות}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# תהליכון} other {# תהליכונים}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "שעה"
@@ -190,11 +182,6 @@ msgstr "ממוצע"
msgid "Average CPU utilization of containers"
msgstr "ניצול ממוצע של CPU בקונטיינרים"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "הממוצע יורד מתחת ל-<0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "גיבויים"
msgid "Bandwidth"
msgstr "רוחב פס"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "סוללה"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "סוללה"
@@ -249,13 +230,6 @@ msgstr "הפך ללא פעיל"
msgid "Before"
msgstr "לפני"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "מתחת ל-{0}{1} ב-{2, plural, one {דקה האחרונה} other {-# הדקות האחרונות}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel תומך ב-OpenID Connect ובספקי אימות רבים של OAuth2."
@@ -594,7 +568,7 @@ msgstr "תיעוד"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "לא פעיל"
msgid "Invalid email address."
msgstr "כתובת אימייל לא תקינה."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "קרנל"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "שפה"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "מקס 1 דק'"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1230,7 +1208,7 @@ msgstr "המשך"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr "שורש"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
@@ -1461,8 +1439,8 @@ msgstr "פורמט זמן"
msgid "To email(s)"
msgstr "לאימייל(ים)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "החלף רשת"
@@ -1531,10 +1509,6 @@ msgstr "מופעל כאשר ממוצע העומס ל-5 דקות עולה על ס
msgid "Triggers when any sensor exceeds a threshold"
msgstr "מופעל כאשר כל חיישן עולה על סף"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "מופעל כאשר טעינת הסוללה יורדת מתחת לסף"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "מופעל כאשר השילוב של למעלה/למטה עולה על סף"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "ללא הגבלה"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "למעלה"
@@ -1617,7 +1591,7 @@ msgstr "מתעדכן כל 10 דקות."
msgid "Upload"
msgstr "העלאה"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "זמן פעילות"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: hr\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:18\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Croatian\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} od {1} redaka izabrano."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# jezgra} few {# jezgre} other {# jezgri}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} dan} other {{countString} dani}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} sat} other {{countString} sati}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuta} many {{countString} minuta} other {{countString} minute}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# nit} few {# niti} other {# niti}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 sat"
@@ -109,7 +101,7 @@ msgstr "Aktivno stanje"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/quiet-hours.tsx
msgid "Add {foo}"
msgstr "Dodaj {foo}"
msgstr ""
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
@@ -190,11 +182,6 @@ msgstr "Prosjek"
msgid "Average CPU utilization of containers"
msgstr "Prosječna iskorištenost procesora u spremnicima"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Prosjek pada ispod <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Sigurnosne kopije"
msgid "Bandwidth"
msgstr "Propusnost"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Baterija"
@@ -249,13 +230,6 @@ msgstr "Postalo neaktivno"
msgid "Before"
msgstr "Prije"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Ispod {0}{1} u posljednjih {2, plural, one {# minuti} few {# minute} other {# minuta}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel podržava OpenID Connect i mnoge druge OAuth2 davatalje autentifikacije."
@@ -306,7 +280,7 @@ msgstr "Otkaži"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "Mogućnosti"
msgstr ""
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
@@ -594,7 +568,7 @@ msgstr "Dokumentacija"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -620,7 +594,7 @@ msgstr "Uredi"
#: src/components/add-system.tsx
#: src/components/routes/settings/quiet-hours.tsx
msgid "Edit {foo}"
msgstr "Uredi {foo}"
msgstr ""
#: src/components/login/auth-form.tsx
#: src/components/login/forgot-pass-form.tsx
@@ -746,7 +720,7 @@ msgstr "Otisak prsta"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "Firmver"
msgstr ""
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
@@ -829,6 +803,11 @@ msgstr "Neaktivno"
msgid "Invalid email address."
msgstr "Nevažeća adresa e-pošte."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Jezgra"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Jezik"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Maksimalno 1 minuta"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -948,7 +926,7 @@ msgstr "Upotreba memorije Docker spremnika"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "Model"
msgstr ""
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1230,7 +1208,7 @@ msgstr "Nastavi"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr "Korijen"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
@@ -1291,7 +1269,7 @@ msgstr "Pogledajte <0>postavke obavijesti</0> da biste konfigurirali način prim
#: src/components/routes/settings/quiet-hours.tsx
msgid "Select {foo}"
msgstr "Odaberi {foo}"
msgstr ""
#: src/components/routes/system.tsx
msgid "Sent"
@@ -1388,7 +1366,7 @@ msgstr "Prosječno opterećenje sustava kroz vrijeme"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr "Systemd servisi"
msgstr ""
#: src/components/navbar.tsx
msgid "Systems"
@@ -1461,8 +1439,8 @@ msgstr "Format vremena"
msgid "To email(s)"
msgstr "Primaoci e-pošte"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Uključi/isključi rešetku"
@@ -1531,10 +1509,6 @@ msgstr "Pokreće se kada prosječna opterećenost sustava unutar 5 minuta prije
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Pokreće se kada bilo koji senzor prijeđe prag"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Pokreće se kada razina baterije padne ispod praga"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Pokreće se kada kombinacija gore/dolje premaši prag"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Neograničeno"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Sustav je podignut"
@@ -1617,7 +1591,7 @@ msgstr "Ažurirano svakih 10 minuta."
msgid "Upload"
msgstr "Otpremi"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Vrijeme rada"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: hu\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:18\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Hungarian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} a(z) {1} sorból kiválasztva."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# mag} other {# mag}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} nap} other {{countString} nap}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} óra} other {{countString} óra}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} perc} few {{countString} perc} many {{countString} perc} other {{countString} perc}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# szál} other {# szál}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 óra"
@@ -109,7 +101,7 @@ msgstr "Aktív állapot"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/quiet-hours.tsx
msgid "Add {foo}"
msgstr "Hozzáadás {foo}"
msgstr ""
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
@@ -190,11 +182,6 @@ msgstr "Átlag"
msgid "Average CPU utilization of containers"
msgstr "Konténerek átlagos CPU kihasználtsága"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Az átlag esik <0>{value}{0}</0> alá"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Biztonsági mentések"
msgid "Bandwidth"
msgstr "Sávszélesség"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Akk"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Akkumulátor"
@@ -249,13 +230,6 @@ msgstr "Inaktívvá vált"
msgid "Before"
msgstr "Előtte"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "{0}{1} alatt az elmúlt {2, plural, one {# percben} other {# percben}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "A Beszel támogatja az OpenID Connect-et és számos OAuth2 hitelesítési szolgáltatót."
@@ -594,7 +568,7 @@ msgstr "Dokumentáció"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -620,7 +594,7 @@ msgstr "Szerkesztés"
#: src/components/add-system.tsx
#: src/components/routes/settings/quiet-hours.tsx
msgid "Edit {foo}"
msgstr "Szerkesztés {foo}"
msgstr ""
#: src/components/login/auth-form.tsx
#: src/components/login/forgot-pass-form.tsx
@@ -674,7 +648,7 @@ msgstr "Túllépi a {0}{1} értéket az elmúlt {2, plural, one {# percben} othe
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr "Fő folyamat PID"
msgstr ""
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
@@ -746,7 +720,7 @@ msgstr "Ujjlenyomat"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "Firmware"
msgstr ""
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
@@ -829,6 +803,11 @@ msgstr "Inaktív"
msgid "Invalid email address."
msgstr "Érvénytelen e-mail cím."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Nyelv"
@@ -904,7 +883,7 @@ msgstr "Inkább azt keresi, hogy hol hozhat létre riasztásokat? Kattintson a c
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr "Fő PID"
msgstr ""
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Maximum 1 perc"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Időformátum"
msgid "To email(s)"
msgstr "E-mailben"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Rács ki- és bekapcsolása"
@@ -1531,10 +1509,6 @@ msgstr "Riaszt, ha az 5 perces terhelési átlag túllép egy küszöbértéket"
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Bekapcsol, ha bármelyik érzékelő túllép egy küszöbértéket"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr ""
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Bekapcsol, ha bármelyik érzékelő túllép egy küszöbértéket"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Korlátlan"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Online"
@@ -1617,7 +1591,7 @@ msgstr "10 percenként frissítve."
msgid "Upload"
msgstr "Feltöltés"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Üzemidő"

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: it\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:17\n"
"PO-Revision-Date: 2025-11-20 16:58\n"
"Last-Translator: \n"
"Language-Team: Italian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} di {1} righe selezionate."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# core} other {# core}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} giorno} other {{countString} giorni}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} ora} other {{countString} ore}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuto} other {{countString} minuti}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# thread} other {# thread}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 ora"
@@ -190,11 +182,6 @@ msgstr "Media"
msgid "Average CPU utilization of containers"
msgstr "Utilizzo medio della CPU dei container"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "La media scende sotto <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Backup"
msgid "Bandwidth"
msgstr "Larghezza di banda"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Batteria"
@@ -249,13 +230,6 @@ msgstr "Diventato inattivo"
msgid "Before"
msgstr "Prima"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Sotto {0}{1} negli ultimi {2, plural, one {# minuto} other {# minuti}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel supporta OpenID Connect e molti provider di autenticazione OAuth2."
@@ -594,7 +568,7 @@ msgstr "Documentazione"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "Inattivo"
msgid "Invalid email address."
msgstr "Indirizzo email non valido."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Lingua"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Max 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Formato orario"
msgid "To email(s)"
msgstr "A email(s)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Attiva/disattiva griglia"
@@ -1531,10 +1509,6 @@ msgstr "Si attiva quando la media di carico di 5 minuti supera una soglia"
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Attiva quando un sensore supera una soglia"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Attiva quando la carica della batteria scende sotto una soglia"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Attiva quando il combinato up/down supera una soglia"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Illimitato"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Attivo"
@@ -1617,7 +1591,7 @@ msgstr "Aggiornato ogni 10 minuti."
msgid "Upload"
msgstr "Carica"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Tempo di attività"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: ja\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:18\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Japanese\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{1}行のうち{0}行が選択されました。"
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# コア} other {# コア}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} 日} other {{countString} 日}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} 時間} other {{countString} 時間}}
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} 分} few {{countString} 分} many {{countString} 分} other {{countString} 分}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# スレッド} other {# スレッド}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1時間"
@@ -190,11 +182,6 @@ msgstr "平均"
msgid "Average CPU utilization of containers"
msgstr "コンテナの平均CPU使用率"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "平均が<0>{value}{0}</0>を下回っています"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "バックアップ"
msgid "Bandwidth"
msgstr "帯域幅"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "バッテリー"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "バッテリー"
@@ -249,13 +230,6 @@ msgstr "非アクティブになった"
msgid "Before"
msgstr "前"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "過去{2, plural, one {# 分} other {# 分}}で{0}{1}を下回っています"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "BeszelはOpenID Connectと多くのOAuth2認証プロバイダーをサポートしています。"
@@ -594,7 +568,7 @@ msgstr "ドキュメント"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "非アクティブ"
msgid "Invalid email address."
msgstr "無効なメールアドレスです。"
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "カーネル"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "言語"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "最大1分"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "時間形式"
msgid "To email(s)"
msgstr "宛先メールアドレス"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "グリッドを切り替え"
@@ -1531,10 +1509,6 @@ msgstr "5分間の負荷平均がしきい値を超えたときにトリガー
msgid "Triggers when any sensor exceeds a threshold"
msgstr "センサーがしきい値を超えたときにトリガーされます"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "バッテリーの充電量がしきい値を下回ったときにトリガーされます"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "上り/下りの合計がしきい値を超えたときにトリガーされます"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "無制限"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "正常"
@@ -1617,7 +1591,7 @@ msgstr "10分ごとに更新されます。"
msgid "Upload"
msgstr "アップロード"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "稼働時間"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: ko\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:18\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Korean\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{1}개의 행 중 {0}개가 선택되었습니다."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# 코어} other {# 코어}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} 일} other {{countString} 일}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} 시간} other {{countString} 시간}}
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} 분} few {{countString} 분} many {{countString} 분} other {{countString} 분}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# 스레드} other {# 스레드}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1시간"
@@ -190,11 +182,6 @@ msgstr "평균"
msgid "Average CPU utilization of containers"
msgstr "Docker 컨테이너의 평균 CPU 사용량"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "평균이 <0>{value}{0}</0> 아래로 떨어집니다"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "백업"
msgid "Bandwidth"
msgstr "대역폭"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "배터리"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "배터리"
@@ -249,13 +230,6 @@ msgstr "비활성화됨"
msgid "Before"
msgstr "이전"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "마지막 {2, plural, one {# 분} other {# 분}} 동안 {0}{1} 미만"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel은 OpenID Connect 및 많은 OAuth2 인증 제공자를 지원합니다."
@@ -594,7 +568,7 @@ msgstr "문서"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "비활성"
msgid "Invalid email address."
msgstr "잘못된 이메일 주소입니다."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "커널"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "언어"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "1분간 최댓값"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "시간 형식"
msgid "To email(s)"
msgstr "받는사람(들)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "그리드 전환"
@@ -1531,10 +1509,6 @@ msgstr "5분 부하 평균이 임계값을 초과하면 트리거됩니다."
msgid "Triggers when any sensor exceeds a threshold"
msgstr "센서가 임계값을 초과할 때 트리거됩니다."
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "배터리 충전량이 임계값 아래로 떨어질 때 트리거됩니다."
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "업로드와 다운로드 대역폭의 합이 임계값을 초과할 때 트리거됩니다."
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "무제한"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "온라인"
@@ -1617,7 +1591,7 @@ msgstr "10분마다 업데이트됩니다."
msgid "Upload"
msgstr "업로드"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "가동 시간"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: nl\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-17 12:02\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Dutch\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} van de {1} rij(en) geselecteerd."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# kern} other {# kernen}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} dag} other {{countString} dagen}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} uur} other {{countString} uren}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuut} other {{countString} minuten}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# thread} other {# threads}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 uur"
@@ -190,11 +182,6 @@ msgstr "Gemiddelde"
msgid "Average CPU utilization of containers"
msgstr "Gemiddeld CPU-gebruik van containers"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Gemiddelde daalt onder <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Back-ups"
msgid "Bandwidth"
msgstr "Bandbreedte"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Batterij"
@@ -249,13 +230,6 @@ msgstr "Inactief geworden"
msgid "Before"
msgstr "Voor"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Onder {0}{1} in de laatste {2, plural, one {# minuut} other {# minuten}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel ondersteunt OpenID Connect en vele OAuth2 authenticatieaanbieders."
@@ -542,7 +516,7 @@ msgstr "Beschrijving"
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr "Details"
msgstr ""
#: src/components/routes/system/smart-table.tsx
msgid "Device"
@@ -594,7 +568,7 @@ msgstr "Documentatie"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -746,7 +720,7 @@ msgstr "Vingerafdruk"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "Firmware"
msgstr ""
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
@@ -819,7 +793,7 @@ msgstr "Als je het wachtwoord voor je beheerdersaccount bent kwijtgeraakt, kan j
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "Afbeelding"
msgstr ""
#: src/components/routes/settings/quiet-hours.tsx
msgid "Inactive"
@@ -829,6 +803,11 @@ msgstr "Inactief"
msgid "Invalid email address."
msgstr "Ongeldig e-mailadres."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Taal"
@@ -843,12 +822,12 @@ msgstr "Layoutbreedte"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr "Levenscyclus"
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr "limiet"
msgstr ""
#: src/components/routes/system.tsx
msgid "Load Average"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr ""
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -948,7 +926,7 @@ msgstr "Geheugengebruik van docker containers"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "Model"
msgstr ""
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1086,7 +1064,7 @@ msgstr "Wachtwoord reset aanvraag ontvangen"
#: src/components/routes/settings/quiet-hours.tsx
msgid "Past"
msgstr "Verleden"
msgstr ""
#: src/components/systems-table/systems-table-columns.tsx
msgid "Pause"
@@ -1230,7 +1208,7 @@ msgstr "Hervatten"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr "Root"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
@@ -1307,7 +1285,7 @@ msgstr "Servicedetails"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr "Services"
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
@@ -1339,7 +1317,7 @@ msgstr "Sorteren op"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/quiet-hours.tsx
msgid "Start Time"
msgstr "Starttijd"
msgstr ""
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Tijdnotatie"
msgid "To email(s)"
msgstr "Naar e-mail(s)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Schakel raster"
@@ -1513,7 +1491,7 @@ msgstr "Geactiveerd door"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr "Triggers"
msgstr ""
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
@@ -1531,10 +1509,6 @@ msgstr "Triggert wanneer de 5 minuten gemiddelde belasting een drempelwaarde ove
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Triggert wanneer een sensor een drempelwaarde overschrijdt"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Triggert wanneer de batterijlading onder een drempelwaarde daalt"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Triggert wanneer de gecombineerde up/down een drempelwaarde overschrijdt"
@@ -1563,7 +1537,7 @@ msgstr "Triggert wanneer het gebruik van een schijf een drempelwaarde overschrij
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "Type"
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Onbeperkt"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Online"
@@ -1617,7 +1591,7 @@ msgstr "Elke 10 minuten bijgewerkt."
msgid "Upload"
msgstr "Uploaden"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Actief"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: no\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-05 20:24\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Norwegian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} av {1} rad(er) valgt."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# kjerne} other {# kjerner}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} dag} other {{countString} dager}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} time} other {{countString} timer}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minutt} other {{countString} minutter}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# tråd} other {# tråder}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 time"
@@ -190,11 +182,6 @@ msgstr "Gjennomsnitt"
msgid "Average CPU utilization of containers"
msgstr "Gjennomsnittlig CPU-utnyttelse av konteinere"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Gjennomsnittet faller under <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Sikkerhetskopier"
msgid "Bandwidth"
msgstr "Båndbredde"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr ""
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Batteri"
@@ -249,13 +230,6 @@ msgstr "Ble inaktiv"
msgid "Before"
msgstr "Før"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Under {0}{1} i siste {2, plural, one {# minutt} other {# minutter}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel støtter OpenID Connect og mange OAuth2 autentiserings-tilbydere."
@@ -594,7 +568,7 @@ msgstr "Dokumentasjon"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "Inaktiv"
msgid "Invalid email address."
msgstr "Ugyldig e-postadresse."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kjerne"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Språk"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Maks 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1086,7 +1064,7 @@ msgstr "Mottatt forespørsel om å nullstille passord"
#: src/components/routes/settings/quiet-hours.tsx
msgid "Past"
msgstr "Fortid"
msgstr ""
#: src/components/systems-table/systems-table-columns.tsx
msgid "Pause"
@@ -1339,7 +1317,7 @@ msgstr "Sorter Etter"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/quiet-hours.tsx
msgid "Start Time"
msgstr "Starttid"
msgstr ""
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Tidsformat"
msgid "To email(s)"
msgstr "Til e-postadresse(r)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Rutenett av/på"
@@ -1531,10 +1509,6 @@ msgstr "Slår inn når gjennomsnittsbelastningen over 5 minutter overstiger en g
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Slår inn når enhver sensor overstiger en grenseverdi"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Utløses når batterilading faller under en terskel"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Slår inn når kombinert opp/ned overskrider en grenseverdi"
@@ -1563,7 +1537,7 @@ msgstr "Slår inn når forbruk av hvilken som helst disk overstiger en grensever
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "Type"
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Ubegrenset"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Oppe"
@@ -1617,7 +1591,7 @@ msgstr "Oppdatert hvert 10. minutt."
msgid "Upload"
msgstr "Last opp"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Oppetid"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: pl\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-18 19:21\n"
"PO-Revision-Date: 2025-11-17 16:53\n"
"Last-Translator: \n"
"Language-Team: Polish\n"
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} z {1} wybranych wierszy."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# rdzeń} few {# rdzenie} many {# rdzeni} other {# rdzeni}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} dzień} few {{countString} dni} many {{countString} dni} other {{countString} dni}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {godzinę} few {{countString} godziny} many {{countS
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuty} many {{countString} minut} other {{countString} minut}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# wątek} few {# wątki} many {# wątków} other {# wątków}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 godzina"
@@ -190,11 +182,6 @@ msgstr "Średnia"
msgid "Average CPU utilization of containers"
msgstr "Średnie wykorzystanie procesora przez kontenery"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr ""
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Kopie"
msgid "Bandwidth"
msgstr "Przepustowość"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr ""
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Bateria"
@@ -249,13 +230,6 @@ msgstr "Stało się nieaktywnym"
msgid "Before"
msgstr "Przed"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr ""
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel obsługuje OpenID Connect i wielu dostawców uwierzytelniania OAuth2."
@@ -594,7 +568,7 @@ msgstr "Dokumentacja"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "Nieaktywny"
msgid "Invalid email address."
msgstr "Nieprawidłowy adres e-mail."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Jądro"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Język"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Maks. 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1086,7 +1064,7 @@ msgstr "Otrzymane żądanie resetowania hasła"
#: src/components/routes/settings/quiet-hours.tsx
msgid "Past"
msgstr "Przeszłe"
msgstr ""
#: src/components/systems-table/systems-table-columns.tsx
msgid "Pause"
@@ -1339,7 +1317,7 @@ msgstr "Sortuj według"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/quiet-hours.tsx
msgid "Start Time"
msgstr "Czas rozpoczęcia"
msgstr ""
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Format czasu"
msgid "To email(s)"
msgstr "Do e-mail(ów)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Przełącz siatkę"
@@ -1531,10 +1509,6 @@ msgstr "Uruchamia się, gdy 5-minutowe średnie obciążenie systemu przekroczy
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Wyzwalane, gdy jakikolwiek czujnik przekroczy ustalony próg."
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr ""
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Wyzwalane, gdy łączna wartość w górę/w dół przekroczy próg"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Bez limitu"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Działa"
@@ -1617,7 +1591,7 @@ msgstr "Aktualizowane co 10 minut."
msgid "Upload"
msgstr "Wysyłanie"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Czas pracy"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: pt\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-05 20:24\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Portuguese\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} de {1} linha(s) selecionada(s)."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# núcleo} other {# núcleos}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} dia} other {{countString} dias}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} hora} other {{countString} horas}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuto} other {{countString} minutos}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# thread} other {# threads}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 hora"
@@ -190,11 +182,6 @@ msgstr "Média"
msgid "Average CPU utilization of containers"
msgstr "Utilização média de CPU dos contêineres"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "A média cai abaixo de <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Cópias de segurança"
msgid "Bandwidth"
msgstr "Largura de Banda"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Bateria"
@@ -249,13 +230,6 @@ msgstr "Tornou-se inativo"
msgid "Before"
msgstr "Antes"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Abaixo de {0}{1} no último {2, plural, one {# minuto} other {# minutos}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel suporta OpenID Connect e muitos provedores de autenticação OAuth2."
@@ -594,7 +568,7 @@ msgstr "Documentação"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "Inativo"
msgid "Invalid email address."
msgstr "Endereço de email inválido."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Idioma"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Máx 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Formato de hora"
msgid "To email(s)"
msgstr "Para email(s)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Alternar grade"
@@ -1531,10 +1509,6 @@ msgstr "Dispara quando a média de carga de 5 minutos excede um limite"
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Dispara quando qualquer sensor excede um limite"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Dispara quando a carga da bateria cai abaixo de um limite"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Dispara quando a soma de subida/descida excede um limite"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Ilimitado"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Ligado"
@@ -1617,7 +1591,7 @@ msgstr "Atualizado a cada 10 minutos."
msgid "Upload"
msgstr "Carregar"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Tempo de Atividade"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: ru\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:17\n"
"PO-Revision-Date: 2025-12-01 23:32\n"
"Last-Translator: \n"
"Language-Team: Russian\n"
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "Выбрано {0} из {1} строк."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# ядро} few {# ядра} many {# ядер} other {# ядер}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} день} other {{countString} дней}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} час} other {{countString} часо
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} минута} few {{countString} минут} many {{countString} минут} other {{countString} минуты}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# поток} few {# потока} many {# потоков} other {# потоков}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 час"
@@ -190,11 +182,6 @@ msgstr "Среднее"
msgid "Average CPU utilization of containers"
msgstr "Среднее использование CPU контейнерами"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Среднее опускается ниже <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Резервные копии"
msgid "Bandwidth"
msgstr "Пропускная способность"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Батарея"
@@ -249,13 +230,6 @@ msgstr "Стал неактивным"
msgid "Before"
msgstr "До"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Ниже {0}{1} за последние {2, plural, one {# минуту} other {# минут}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel поддерживает OpenID Connect и множество поставщиков аутентификации OAuth2."
@@ -594,7 +568,7 @@ msgstr "Документация"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "Неактивно"
msgid "Invalid email address."
msgstr "Неверный адрес электронной почты."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Ядро"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Язык"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Макс 1 мин"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Формат времени"
msgid "To email(s)"
msgstr "На электронную почту"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Переключить сетку"
@@ -1531,10 +1509,6 @@ msgstr "Срабатывает, когда средняя загрузка за
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Срабатывает, когда любой датчик превышает порог"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Срабатывает, когда заряд батареи опускается ниже порога"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Срабатывает, когда комбинированный вход/выход превышает порог"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Неограниченно"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "В сети"
@@ -1617,7 +1591,7 @@ msgstr "Обновляется каждые 10 минут."
msgid "Upload"
msgstr "Отдача"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Время работы"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: sl\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-05 20:24\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Slovenian\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} od {1} vrstic izbranih."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# jedro} two {# jedri} few {# jedra} other {# jeder}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} dan} two {{countString} dneva} few {{countString} dni} other {{countString} dni}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} ura} two {{countString} uri} few {{co
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuti} many {{countString} minut} other {{countString} minut}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# nit} two {# niti} few {# niti} other {# niti}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 ura"
@@ -142,7 +134,7 @@ msgstr "Po"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "Agent"
msgstr ""
#: src/components/command-palette.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
@@ -190,11 +182,6 @@ msgstr "Povprečno"
msgid "Average CPU utilization of containers"
msgstr "Povprečna izkoriščenost procesorja kontejnerjev"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr ""
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Varnostne kopije"
msgid "Bandwidth"
msgstr "Pasovna širina"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Baterija"
@@ -249,13 +230,6 @@ msgstr "Postalo neaktivno"
msgid "Before"
msgstr "Pred"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr ""
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel podpira OpenID Connect in številne ponudnike preverjanja pristnosti OAuth2."
@@ -318,7 +292,7 @@ msgstr "Pozor - možna izguba podatkov"
#: src/components/routes/settings/general.tsx
msgid "Celsius (°C)"
msgstr "Celzija (°C)"
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Change display units for metrics."
@@ -456,7 +430,7 @@ msgstr "Kopiraj YAML"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "CPU"
msgstr ""
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
@@ -594,7 +568,7 @@ msgstr "Dokumentacija"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -698,7 +672,7 @@ msgstr "Izvozi trenutne nastavitve sistema."
#: src/components/routes/settings/general.tsx
msgid "Fahrenheit (°F)"
msgstr "Fahrenheit (°F)"
msgstr ""
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
@@ -829,6 +803,11 @@ msgstr "Neaktivno"
msgid "Invalid email address."
msgstr "Napačen e-poštni naslov."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Jedro"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Jezik"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Največ 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Oblika časa"
msgid "To email(s)"
msgstr "E-pošta za"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Preklopi način mreže"
@@ -1531,10 +1509,6 @@ msgstr "Sproži se, ko 5-minutna povprečna obremenitev preseže prag"
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Sproži se, ko kateri koli senzor preseže prag"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr ""
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Sproži, ko kombinacija gor/dol preseže prag"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Neomejeno"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Delujoč"
@@ -1617,7 +1591,7 @@ msgstr "Posodobljeno vsakih 10 minut."
msgid "Upload"
msgstr "Naloži"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Čas delovanja"

View File

@@ -1,22 +1,17 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"POT-Creation-Date: 2025-12-04 14:50-0500\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: sr\n"
"Project-Id-Version: beszel\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-08 18:22\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: Serbian (Cyrillic)\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: sr\n"
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
"Language-Team: \n"
"Plural-Forms: \n"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
@@ -24,10 +19,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} од {1} редова изабрано."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# jezgro} few {# jezgra} other {# jezgara}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} дан} few {{countString} дана} other {{countString} дана}}"
@@ -40,10 +31,6 @@ msgstr "{count, plural, one {{countString} сат} few {{countString} сата}
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} минут} few {{countString} минута} many {{countString} минута} other {{countString} минута}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# nit} few {# niti} other {# niti}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 сат"
@@ -188,12 +175,7 @@ msgstr "Просек"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Просечна искоришћеност процесора контејнера"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Prosek pada ispod <0>{value}{0}</0>"
msgstr "Просечна CPU употреба контејнера"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
@@ -202,11 +184,11 @@ msgstr "Просек премашује <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Просечна потрошња енергије графичких картица"
msgstr "Просечна потрошња енергије GPU-ова"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Просечна системска искоришћеност процесор"
msgstr "Просечна системска CPU употреба"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
@@ -215,7 +197,7 @@ msgstr "Просечна употреба {0}"
#: src/components/routes/system.tsx
msgid "Average utilization of GPU engines"
msgstr "Просечна искоришћеност мотора графичких картица"
msgstr "Просечна употреба GPU енгине-а"
#: src/components/command-palette.tsx
#: src/components/navbar.tsx
@@ -227,13 +209,7 @@ msgstr "Резервне копије"
msgid "Bandwidth"
msgstr "Пропусни опсег"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Батерија"
@@ -249,13 +225,6 @@ msgstr "Постао неактиван"
msgid "Before"
msgstr "Пре"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Ispod {0}{1} u poslednjih {2, plural, one {# minuti} few {# minuta} other {# minuta}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel подржава OpenID Connect и многе OAuth2 провајдере аутентификације."
@@ -404,7 +373,7 @@ msgstr "Настави"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Копирано у међуспремник"
msgstr "Копирано у клипборд"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
@@ -425,7 +394,7 @@ msgstr "Копирај env"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Copy host"
msgstr "Копирај хоста"
msgstr "Копирај хост"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
@@ -456,7 +425,7 @@ msgstr "Копирај YAML"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "Процесор"
msgstr ""
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
@@ -464,7 +433,7 @@ msgstr "CPU језгра"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "CPU врхунац"
msgstr "CPU пик"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
@@ -472,14 +441,14 @@ msgstr "CPU време"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "Расподела времена процесора"
msgstr "Растављање CPU времена"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "Искоришћеност процесора"
msgstr "CPU употреба"
#: src/components/routes/settings/quiet-hours.tsx
msgid "Create"
@@ -563,7 +532,7 @@ msgstr "Диск I/O"
#: src/components/routes/settings/general.tsx
msgid "Disk unit"
msgstr "Диск јединица"
msgstr "Јединица диска"
#: src/components/charts/disk-chart.tsx
#: src/components/routes/system.tsx
@@ -594,7 +563,7 @@ msgstr "Документација"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -626,16 +595,16 @@ msgstr "Измени {foo}"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/otp-forms.tsx
msgid "Email"
msgstr "Е-пошта"
msgstr "Имејл"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Обавештењe е-поштом"
msgstr "Имејл обавештења"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Empty"
msgstr "Празнo"
msgstr "Празна"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/quiet-hours.tsx
@@ -644,11 +613,11 @@ msgstr "Време завршетка"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Унесите адресу е-поште за ресетовање лозинке"
msgstr "Унесите имејл адресу за ресетовање лозинке"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Унесите адресу е-поште..."
msgstr "Унесите имејл адресу..."
#: src/components/login/otp-forms.tsx
msgid "Enter your one-time password."
@@ -678,7 +647,7 @@ msgstr "Главни PID извршавања"
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "Системи који нису дефинисани у <0>config.yml</0> биће обрисани. Молимо вас да редовно правите резервне копије."
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
@@ -690,11 +659,11 @@ msgstr "Извези"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Извези конфигурацију"
msgstr ""
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Извезите тренутну конфигурацију система."
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Fahrenheit (°F)"
@@ -819,7 +788,7 @@ msgstr "Ако сте изгубили лозинку за ваш админис
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "Слика"
msgstr ""
#: src/components/routes/settings/quiet-hours.tsx
msgid "Inactive"
@@ -829,6 +798,11 @@ msgstr "Неактивно"
msgid "Invalid email address."
msgstr "Неважећа имејл адреса."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Кернел"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Језик"
@@ -900,7 +874,7 @@ msgstr "Логови"
#: src/components/routes/settings/notifications.tsx
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Тражите где да креирате упозорења? Кликните на звоно <0/> у табели система."
msgstr "Тражите где да креирате упозорења? Кликните на звона <0/> иконе у табели система."
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
@@ -921,7 +895,6 @@ msgid "Max 1 min"
msgstr "Макс 1 мин"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -935,7 +908,7 @@ msgstr "Ограничење меморије"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "Врхунац меморије"
msgstr "Пик меморије"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
@@ -983,7 +956,7 @@ msgstr "Мрежна јединица"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr "Не"
msgstr ""
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
@@ -1086,7 +1059,7 @@ msgstr "Захтев за ресетовање лозинке примљен"
#: src/components/routes/settings/quiet-hours.tsx
msgid "Past"
msgstr "Прошлост"
msgstr "Прошло"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Pause"
@@ -1120,7 +1093,7 @@ msgstr "Молимо вас проверите логове за више дет
#: src/components/login/auth-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Please check your credentials and try again"
msgstr "Молимо вас проверите своје податке за пријаву и покушајте поново"
msgstr "Молимо вас проверите ваше акредитиве и покушајте поново"
#: src/components/login/login.tsx
msgid "Please create an admin account"
@@ -1128,11 +1101,11 @@ msgstr "Молимо вас креирајте администраторски
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Молимо вас омогућите искачуће прозоре за овај сајт"
msgstr "Молимо вас омогућите поп-упе за овај сајт"
#: src/lib/api.ts
msgid "Please log in again"
msgstr "Молимо вас да се пријавите поново"
msgstr "Молимо вас пријавите се поново"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
@@ -1140,7 +1113,7 @@ msgstr "Молимо вас погледајте <0>документацију</
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Молимо вас да се пријавите на ваш налог"
msgstr "Молимо вас пријавите се на ваш налог"
#: src/components/add-system.tsx
msgid "Port"
@@ -1149,7 +1122,7 @@ msgstr "Порт"
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "Укључи"
msgstr "Укључен"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
@@ -1250,11 +1223,11 @@ msgstr "S.M.A.R.T. детаљи"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "S.M.A.R.T. самопровера"
msgstr "S.M.A.R.T. само-тест"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Сачувајте адресу користећи enter тастер или зарез. Оставите празно да онемогућите обавештења путем е -поште."
msgstr "Сачувајте адресу користећи enter тастер или зарез. Оставите празно да онемогућите имејл обавештења."
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/notifications.tsx
@@ -1459,10 +1432,10 @@ msgstr "Формат времена"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "На е-пошту(е)"
msgstr "На имејл(ове)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Укључи/искључи мрежу"
@@ -1473,7 +1446,7 @@ msgstr "Промени тему"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Token"
msgstr "Токен"
msgstr ""
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
@@ -1531,10 +1504,6 @@ msgstr "Окида се када просечно оптерећење од 5 м
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Окида се када било који сензор премаши праг"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Pokreće se kada nivo baterije padne ispod praga"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Окида се када комбиновано горе/доле премаши праг"
@@ -1577,7 +1546,7 @@ msgstr "Преференце јединица"
#: src/components/command-palette.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Universal token"
msgstr "Универзални токен"
msgstr ""
#. Context: Battery state
#: src/lib/i18n.ts
@@ -1590,7 +1559,7 @@ msgid "Unlimited"
msgstr "Неограничено"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Укључен"
@@ -1607,7 +1576,7 @@ msgstr "Ажурирај"
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Ажурирано"
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
@@ -1615,9 +1584,9 @@ msgstr "Ажурира се сваких 10 минута."
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "Отпреми"
msgstr ""
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Време рада"
@@ -1627,7 +1596,7 @@ msgstr "Време рада"
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Употреба"
msgstr ""
#: src/components/routes/system.tsx
msgid "Usage of root partition"
@@ -1636,7 +1605,7 @@ msgstr "Употреба root партиције"
#: src/components/charts/mem-chart.tsx
#: src/components/charts/swap-chart.tsx
msgid "Used"
msgstr "Коришћено"
msgstr ""
#: src/components/command-palette.tsx
#: src/components/navbar.tsx
@@ -1678,7 +1647,7 @@ msgstr "Жели"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "Упозорење (%)"
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Warning thresholds"
@@ -1686,7 +1655,7 @@ msgstr "Прагове упозорења"
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Push обавештења"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
@@ -1696,17 +1665,17 @@ msgstr "Када је омогућено, овај токен омогућава
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows команда"
msgstr ""
#. Disk write
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Write"
msgstr "Писање"
msgstr ""
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML конфигурација"
msgstr ""
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
@@ -1716,7 +1685,7 @@ msgstr "YAML конфигурација"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "Да"
msgstr ""
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: sv\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-05 20:24\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Swedish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{0} av {1} rad(er) valda."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# kärna} other {# kärnor}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} dag} other {{countString} dagar}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} timme} other {{countString} timmar}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minut} few {{countString} minuter} many {{countString} minuter} other {{countString} minuter}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# tråd} other {# trådar}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 timme"
@@ -190,11 +182,6 @@ msgstr "Genomsnitt"
msgid "Average CPU utilization of containers"
msgstr "Genomsnittlig CPU-användning för containrar"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Genomsnittet sjunker under <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Säkerhetskopior"
msgid "Bandwidth"
msgstr "Bandbredd"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Batteri"
@@ -249,13 +230,6 @@ msgstr "Blev inaktiv"
msgid "Before"
msgstr "Före"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Under {0}{1} under de senaste {2, plural, one {# minuten} other {# minuterna}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel stöder OpenID Connect och många OAuth2-autentiseringsleverantörer."
@@ -594,7 +568,7 @@ msgstr "Dokumentation"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "Inaktiv"
msgid "Invalid email address."
msgstr "Ogiltig e-postadress."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kärna"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Språk"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Max 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Tidsformat"
msgid "To email(s)"
msgstr "Till e-postadress(er)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Växla rutnät"
@@ -1531,10 +1509,6 @@ msgstr "Utlöses när 5-minuters genomsnittlig belastning överskrider ett trös
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Utlöses när någon sensor överskrider ett tröskelvärde"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Utlöses när batteriladdningen sjunker under ett tröskelvärde"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Utlöses när kombinerad upp/ner överskrider ett tröskelvärde"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr ""
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Upp"
@@ -1617,7 +1591,7 @@ msgstr "Uppdateras var 10:e minut."
msgid "Upload"
msgstr "Ladda upp"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Drifttid"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: tr\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:18\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Turkish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "{1} satırdan {0} tanesi seçildi."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# çekirdek} other {# çekirdek}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} gün} other {{countString} gün}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} saat} other {{countString} saat}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} dakika} few {{countString} dakika} many {{countString} dakika} other {{countString} dakika}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# iş parçacığı} other {# iş parçacığı}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 saat"
@@ -190,11 +182,6 @@ msgstr "Ortalama"
msgid "Average CPU utilization of containers"
msgstr "Konteynerlerin ortalama CPU kullanımı"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Ortalama <0>{value}{0}</0> altına düşüyor"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Yedekler"
msgid "Bandwidth"
msgstr "Bant Genişliği"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Pil"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Pil"
@@ -249,13 +230,6 @@ msgstr "Pasif oldu"
msgid "Before"
msgstr "Önce"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Son {2, plural, one {# dakika} other {# dakika}} içinde {0}{1} altında"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel, OpenID Connect ve birçok OAuth2 kimlik doğrulama sağlayıcısını destekler."
@@ -594,7 +568,7 @@ msgstr "Dokümantasyon"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "Pasif"
msgid "Invalid email address."
msgstr "Geçersiz e-posta adresi."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Çekirdek"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Dil"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Maks 1 dk"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Zaman formatı"
msgid "To email(s)"
msgstr "E-posta(lar)a"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Izgarayı değiştir"
@@ -1531,10 +1509,6 @@ msgstr "5 dakikalık yük ortalaması bir eşiği aştığında tetiklenir"
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Herhangi bir sensör bir eşiği aştığında tetiklenir"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Pil şarjı bir eşiğin altına düştüğünde tetiklenir"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Birleştirilmiş yukarı/aşağı bir eşiği aştığında tetiklenir"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Sınırsız"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Açık"
@@ -1617,7 +1591,7 @@ msgstr "Her 10 dakikada bir güncellenir."
msgid "Upload"
msgstr "Yükle"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Çalışma Süresi"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: uk\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:18\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Ukrainian\n"
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "Вибрано {0} з {1} рядків."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# ядро} few {# ядра} many {# ядер} other {# ядер}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} день} few {{countString} дні} many {{countString} днів} other {{countString} дня}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} година} few {{countString} го
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} хвилина} few {{countString} хвилини} many {{countString} хвилин} other {{countString} хвилини}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# потік} few {# потоки} many {# потоків} other {# потоків}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 година"
@@ -190,11 +182,6 @@ msgstr "Середнє"
msgid "Average CPU utilization of containers"
msgstr "Середнє використання CPU контейнерами"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Середнє опускається нижче <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Резервні копії"
msgid "Bandwidth"
msgstr "Пропускна здатність"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Bat"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Батарея"
@@ -249,13 +230,6 @@ msgstr "Стало неактивним"
msgid "Before"
msgstr "До"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Нижче {0}{1} протягом {2, plural, one {останньої # хвилини} other {останніх # хвилин}}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel підтримує OpenID Connect та багато постачальників автентифікації OAuth2."
@@ -594,7 +568,7 @@ msgstr "Документація"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "Неактивне"
msgid "Invalid email address."
msgstr "Неправильна адреса електронної пошти."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Ядро"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Мова"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Макс 1 хв"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "Формат часу"
msgid "To email(s)"
msgstr "На електронну пошту"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Перемкнути сітку"
@@ -1531,10 +1509,6 @@ msgstr "Спрацьовує, коли середнє навантаження
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Спрацьовує, коли будь-який датчик перевищує поріг"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Спрацьовує, коли заряд батареї опускається нижче порогу"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Спрацьовує, коли відправлення/отримання сумарно перевищує поріг"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Необмежено"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Працює"
@@ -1617,7 +1591,7 @@ msgstr "Оновлюється кожні 10 хвилин."
msgid "Upload"
msgstr "Відвантажити"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Час роботи"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: vi\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:18\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Vietnamese\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "Đã chọn {0} trên {1} hàng."
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# nhân} other {# nhân}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} ngày} other {{countString} ngày}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} giờ} other {{countString} giờ}}"
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} phút} few {{countString} phút} many {{countString} phút} other {{countString} phút}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# luồng} other {# luồng}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 giờ"
@@ -109,7 +101,7 @@ msgstr "Trạng thái hoạt động"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/quiet-hours.tsx
msgid "Add {foo}"
msgstr "Thêm {foo}"
msgstr ""
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
@@ -190,11 +182,6 @@ msgstr "Trung bình"
msgid "Average CPU utilization of containers"
msgstr "Sử dụng CPU trung bình của các container"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "Trung bình giảm xuống dưới <0>{value}{0}</0>"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "Sao lưu"
msgid "Bandwidth"
msgstr "Băng thông"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "Pin"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "Pin"
@@ -249,13 +230,6 @@ msgstr "Đã trở thành không hoạt động"
msgid "Before"
msgstr "Trước"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Dưới {0}{1} trong {2, plural, one {# phút} other {# phút}} qua"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel hỗ trợ OpenID Connect và nhiều nhà cung cấp xác thực OAuth2."
@@ -456,7 +430,7 @@ msgstr "Sao chép YAML"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "CPU"
msgstr ""
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
@@ -594,7 +568,7 @@ msgstr "Tài liệu"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -620,13 +594,13 @@ msgstr "Chỉnh sửa"
#: src/components/add-system.tsx
#: src/components/routes/settings/quiet-hours.tsx
msgid "Edit {foo}"
msgstr "Chỉnh sửa {foo}"
msgstr ""
#: src/components/login/auth-form.tsx
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/otp-forms.tsx
msgid "Email"
msgstr "Email"
msgstr ""
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
@@ -829,6 +803,11 @@ msgstr "Không hoạt động"
msgid "Invalid email address."
msgstr "Địa chỉ email không hợp lệ."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Nhân"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Ngôn ngữ"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "Tối đa 1 phút"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1291,7 +1269,7 @@ msgstr "Xem <0>cài đặt thông báo</0> để cấu hình cách bạn nhận
#: src/components/routes/settings/quiet-hours.tsx
msgid "Select {foo}"
msgstr "Chọn {foo}"
msgstr ""
#: src/components/routes/system.tsx
msgid "Sent"
@@ -1461,8 +1439,8 @@ msgstr "Định dạng thời gian"
msgid "To email(s)"
msgstr "Đến email(s)"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Chuyển đổi lưới"
@@ -1473,7 +1451,7 @@ msgstr "Chuyển đổi chủ đề"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Token"
msgstr "Token"
msgstr ""
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
@@ -1531,10 +1509,6 @@ msgstr "Kích hoạt khi tải trung bình 5 phút vượt quá ngưỡng"
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Kích hoạt khi bất kỳ cảm biến nào vượt quá ngưỡng"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "Kích hoạt khi mức pin giảm xuống dưới ngưỡng"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Kích hoạt khi kết hợp lên/xuống vượt quá ngưỡng"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "Không giới hạn"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Hoạt động"
@@ -1617,7 +1591,7 @@ msgstr "Cập nhật mỗi 10 phút."
msgid "Upload"
msgstr "Tải lên"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Thời gian hoạt động"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: zh\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:18\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Chinese Simplified\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "已选择 {0} / {1} 行"
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# 核心} other {# 核心}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} 天} other {{countString} 天}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} 小时} other {{countString} 小时}}
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} 分钟} few {{countString} 分钟} many {{countString} 分钟} other {{countString} 分钟}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# 线程} other {# 线程}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 小时"
@@ -190,11 +182,6 @@ msgstr "平均"
msgid "Average CPU utilization of containers"
msgstr "容器的平均 CPU 使用率"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "平均值降至<0>{value}{0}</0>以下"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "备份"
msgid "Bandwidth"
msgstr "带宽"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "电池"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "电池"
@@ -249,13 +230,6 @@ msgstr "变为非活动"
msgid "Before"
msgstr "之前"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "在过去的{2, plural, one {# 分钟} other {# 分钟}}中低于{0}{1}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel 支持 OpenID Connect 和其他 OAuth2 认证方式。"
@@ -594,7 +568,7 @@ msgstr "文档"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "非活跃"
msgid "Invalid email address."
msgstr "无效的电子邮件地址。"
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "内核"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "语言"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "1分钟内最大值"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "时间格式"
msgid "To email(s)"
msgstr "发送到电子邮件"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "切换网格"
@@ -1531,10 +1509,6 @@ msgstr "当 5 分钟内的平均负载超过阈值时触发"
msgid "Triggers when any sensor exceeds a threshold"
msgstr "当任何传感器超过阈值时触发"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "当电池电量降至阈值以下时触发"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "当网络的上/下行速度超过阈值时触发"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "无限制"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "在线"
@@ -1617,7 +1591,7 @@ msgstr "每 10 分钟更新一次。"
msgid "Upload"
msgstr "上传"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "正常运行时间"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: zh\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-12-02 23:18\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Chinese Traditional, Hong Kong\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "已選擇 {1} 個項目中的 {0} 個"
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# 核心} other {# 核心}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} 天} other {{countString} 天}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} 小時} other {{countString} 小時}}
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} 分鐘} few {{countString} 分鐘} many {{countString} 分鐘} other {{countString} 分鐘}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# 執行緒} other {# 執行緒}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1小時"
@@ -190,11 +182,6 @@ msgstr "平均"
msgid "Average CPU utilization of containers"
msgstr "容器的平均 CPU 使用率"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "平均值降至<0>{value}{0}</0>以下"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "備份"
msgid "Bandwidth"
msgstr "帶寬"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "電池"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "電池"
@@ -249,13 +230,6 @@ msgstr "變為非活動"
msgid "Before"
msgstr "之前"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "在過去的{2, plural, one {# 分鐘} other {# 分鐘}}中低於{0}{1}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel支持OpenID Connect和許多OAuth2認證提供者。"
@@ -594,7 +568,7 @@ msgstr "文件"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -829,6 +803,11 @@ msgstr "未啟用"
msgid "Invalid email address."
msgstr "無效的電子郵件地址。"
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "核心"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "語言"
@@ -921,7 +900,6 @@ msgid "Max 1 min"
msgstr "一分鐘內最大值"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "時間格式"
msgid "To email(s)"
msgstr "發送到電子郵件"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "切換網格"
@@ -1531,10 +1509,6 @@ msgstr "當 5 分鐘平均負載超過閾值時觸發"
msgid "Triggers when any sensor exceeds a threshold"
msgstr "當任何傳感器超過閾值時觸發"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "當電池電量降至閾值以下時觸發"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "當組合的上/下超過閾值時觸發"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "無限制"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "上線"
@@ -1617,7 +1591,7 @@ msgstr "每 10 分鐘更新一次。"
msgid "Upload"
msgstr "上傳"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "正常運行時間"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: zh\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-01-10 17:34\n"
"PO-Revision-Date: 2025-12-01 23:32\n"
"Last-Translator: \n"
"Language-Team: Chinese Traditional\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -24,10 +24,6 @@ msgstr ""
msgid "{0} of {1} row(s) selected."
msgstr "已選取 {1} 個項目中的 {0} 個"
#: src/components/routes/system/info-bar.tsx
msgid "{cores, plural, one {# core} other {# cores}}"
msgstr "{cores, plural, one {# 核心} other {# 核心}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} 天} other {{countString} 天}}"
@@ -40,10 +36,6 @@ msgstr "{count, plural, one {{countString} 小時} other {{countString} 小時}}
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} 分鐘} few {{countString} 分鐘} many {{countString} 分鐘} other {{countString} 分鐘}}"
#: src/components/routes/system/info-bar.tsx
msgid "{threads, plural, one {# thread} other {# threads}}"
msgstr "{threads, plural, one {# 執行緒} other {# 執行緒}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1小時"
@@ -109,7 +101,7 @@ msgstr "活動狀態"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/quiet-hours.tsx
msgid "Add {foo}"
msgstr "新增{foo}"
msgstr ""
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
@@ -180,7 +172,7 @@ msgstr "您確定嗎?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "只有在受保護的環境HTTPS才能自動複製。"
msgstr "只有在受保護的環境才能自動複製。"
#: src/components/routes/system.tsx
msgid "Average"
@@ -190,11 +182,6 @@ msgstr "平均"
msgid "Average CPU utilization of containers"
msgstr "容器的平均 CPU 使用率"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average drops below <0>{value}{0}</0>"
msgstr "平均值降至<0>{value}{0}</0>以下"
#. placeholder {0}: alertData.unit
#: src/components/alerts/alerts-sheet.tsx
msgid "Average exceeds <0>{value}{0}</0>"
@@ -227,13 +214,7 @@ msgstr "備份"
msgid "Bandwidth"
msgstr "網路流量"
#. Battery label in systems table header
#: src/components/systems-table/systems-table-columns.tsx
msgid "Bat"
msgstr "電池"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Battery"
msgstr "電池"
@@ -249,16 +230,9 @@ msgstr "停用"
msgid "Before"
msgstr "之前"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/active-alerts.tsx
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "在過去的{2, plural, one {# 分鐘} other {# 分鐘}}中低於{0}{1}"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel 支援 OpenID Connect 和許多 OAuth2 認證提供者。"
msgstr "Beszel支援OpenID Connect和許多OAuth2認證提供者。"
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
@@ -343,7 +317,7 @@ msgstr "圖表選項"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "檢查 {email} 以取得重設連結。"
msgstr "檢查{email}以取得重設連結。"
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
@@ -357,7 +331,7 @@ msgstr "檢查您的通知服務"
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "清除"
msgstr ""
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
@@ -450,7 +424,7 @@ msgstr "複製下面的代理程式<0>docker-compose.yml</0>內容,或使用<1
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy YAML"
msgstr "複製 YAML"
msgstr "複製YAML"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
@@ -594,7 +568,7 @@ msgstr "文件"
#. Context: System is down
#: src/components/alerts-history-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
@@ -620,7 +594,7 @@ msgstr "編輯"
#: src/components/add-system.tsx
#: src/components/routes/settings/quiet-hours.tsx
msgid "Edit {foo}"
msgstr "編輯{foo}"
msgstr ""
#: src/components/login/auth-form.tsx
#: src/components/login/forgot-pass-form.tsx
@@ -829,6 +803,11 @@ msgstr "未啟用"
msgid "Invalid email address."
msgstr "無效的電子郵件地址。"
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "語言"
@@ -918,10 +897,9 @@ msgstr "手動設定說明"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "最多 1 分鐘"
msgstr "最多1分鐘"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1074,7 +1052,7 @@ msgstr "密碼"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "密碼需要至少 8 個字元"
msgstr "密碼需要至少8個字元"
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
@@ -1086,7 +1064,7 @@ msgstr "已收到密碼重設請求"
#: src/components/routes/settings/quiet-hours.tsx
msgid "Past"
msgstr "已過期"
msgstr ""
#: src/components/systems-table/systems-table-columns.tsx
msgid "Pause"
@@ -1111,7 +1089,7 @@ msgstr "狀態時間佔比"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "請<0>設定一個 SMTP 伺服器</0>以確保能傳送警報。"
msgstr "請<0>設定一個SMTP 伺服器</0>以確保能傳送警報。"
#: src/components/alerts/alerts-sheet.tsx
msgid "Please check logs for more details."
@@ -1267,7 +1245,7 @@ msgstr "儲存系統"
#: src/components/routes/settings/quiet-hours.tsx
msgid "Schedule"
msgstr "排程"
msgstr ""
#: src/components/routes/settings/quiet-hours.tsx
msgid "Schedule quiet hours where notifications will not be sent, such as during maintenance periods."
@@ -1291,7 +1269,7 @@ msgstr "查看<0>通知設定</0>以設定您如何接收警報。"
#: src/components/routes/settings/quiet-hours.tsx
msgid "Select {foo}"
msgstr "選取{foo}"
msgstr ""
#: src/components/routes/system.tsx
msgid "Sent"
@@ -1366,7 +1344,7 @@ msgstr "系統的虛擬記憶體使用量"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "交換空間使用量"
msgstr "虛擬記憶體使用量"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1461,8 +1439,8 @@ msgstr "時間格式"
msgid "To email(s)"
msgstr "發送到電子郵件"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "切換網格"
@@ -1531,17 +1509,13 @@ msgstr "當 5 分鐘平均負載超過閾值時觸發"
msgid "Triggers when any sensor exceeds a threshold"
msgstr "當任何感應器超過閾值時觸發"
#: src/lib/alerts.ts
msgid "Triggers when battery charge drops below a threshold"
msgstr "當電池電量降至閾值以下時觸發"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "當總流量超過閾值時觸發"
#: src/lib/alerts.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "當 CPU 使用率超過閾值時觸發"
msgstr "當CPU使用率超過閾值時觸發"
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
@@ -1590,7 +1564,7 @@ msgid "Unlimited"
msgstr "無限制"
#. Context: System is up
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "上線"
@@ -1617,7 +1591,7 @@ msgstr "每 10 分鐘更新一次。"
msgid "Upload"
msgstr "上傳"
#: src/components/routes/system/info-bar.tsx
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "運行時間"

View File

@@ -1,13 +1,5 @@
## 0.18.0
- Add experimental NVML GPU collector. (#1522, #1587)
- Add low battery alerts. (#1507)
- Add battery charge to systems table.
- Add `--url` and `--token` command line arguments to the agent. (#1524)
- Collect S.M.A.R.T. data in the background every hour.
- Add `SMART_INTERVAL` environment variable to customize S.M.A.R.T. data collection interval.
@@ -16,25 +8,8 @@
- Add `system_details` collection to store infrequently updated system information.
- Improve S.M.A.R.T. device path lookup for NVMe devices. (#1504)
- Use origin country flags for Spanish, Portuguese, English languages. (#1571)
- Raise `smartctl` timeout to 15 seconds. (#1465)
- Skip known non-unique product UUID when generating fingerprints. (#1556)
- Fix container logs decoding for raw streams. (#1535)
- Fix capacity sorting in S.M.A.R.T. table. (#1551)
- Fix loader visibility when no systems are present. (#1511)
- Add Serbian translations.
- Update Go dependencies.
## 0.17.0
- Add quiet hours to silence alerts during specific time periods. (#265)