Files
OpenFlare/frontend/messages/fragments/security.en.json
T
ryan f5c9da03f4 前端测试套件 44 失败→全绿:10 个测试文件补 NextIntlClientProvider 包装(含 React19 createElement 类型修复、.ts→.tsx 重命名);修复真实 i18n ICU bug(githubUrlInvalid 的 {owner}/{repo} 未转义导致生产渲染成 key,zh/en + fragment 4 文件同步转义);更新 2 处过期测试期望。vitest 116/116 + tsc + eslint 全绿,checks.sh 增加前端测试门禁。
Result: {"status":"keep","total_issues":8,"golint_canonicalheader":0,"golint_errname":0,"golint_errorlint":1,"golint_exhaustive":0,"golint_forcetypeassert":0,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":0,"golint_recvcheck":1,"golint_usestdlibvars":0,"golint_wastedassign":0,"golint_total":8,"golint_test_testifylint":0,"golint_test_thelper":0,"golint_test_usetesting":0,"golint_test_total":0,"golint_vetx_total":0,"eslint_problems":0,"eslint_errors":0,"eslint_warnings":0,"tsc_errors":0,"measure_s":39}
2026-08-16 19:08:21 +08:00

1081 lines
44 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"waf": {
"title": "WAF",
"createRule": "New rule",
"ruleGroups": "Rule groups",
"ruleGroupsDesc": "Build WAF protection rules with a visual flow. Global rules always apply to every site.",
"refresh": "Refresh",
"loading": "Loading WAF rule groups...",
"empty": "No rule groups yet. The system usually creates a global group automatically.",
"created": "Rule created",
"groupDeleted": "Rule group deleted",
"deleteTitle": "Delete rule group",
"deleteDesc": "Delete rule group “{name}”? This cannot be undone.",
"deleting": "Deleting...",
"confirmDelete": "Delete",
"operationFailed": "Operation failed",
"autoConfigMustBeObject": "Automatic configuration must be a JSON object.",
"autoConfigInvalid": "Invalid automatic configuration format",
"saveFailed": "Save failed",
"enabled": "Enabled",
"disabled": "Disabled",
"enable": "Enabled",
"disable": "Disabled",
"global": "Global",
"custom": "Custom",
"allSites": "All sites",
"siteCount": "{count} sites",
"columns": {
"name": "Name",
"type": "Type",
"status": "Status",
"nodeCount": "Nodes",
"scope": "Scope",
"updatedAt": "Updated",
"actions": "Actions"
},
"actions": {
"compose": "Edit",
"delete": "Delete"
},
"createDialog": {
"title": "New WAF rule",
"description": "After creation you will open the editor and configure the processing flow.",
"name": "Rule name",
"namePlaceholder": "e.g. Edge protection",
"submit": "Create and edit"
},
"editor": {
"missingId": "A valid rule ID is required.",
"loadFailed": "Failed to load the rule. Please try again.",
"reload": "Reload",
"back": "Back",
"graphValid": "Graph is valid",
"issueCount": "{count} issues",
"unsaved": "Unsaved",
"enableRule": "Enable rule",
"format": "Format",
"formatTitle": "Auto-arrange nodes and edges",
"saving": "Saving...",
"save": "Save",
"saved": "Rule graph saved",
"conflict": "This rule was updated elsewhere. Please reload.",
"saveCheckNodes": "Save failed. Check the highlighted nodes and edges.",
"ruleEnabled": "Rule enabled",
"ruleDisabled": "Rule disabled",
"leaveTitle": "Unsaved changes",
"leaveDesc": "You have unsaved changes. Leave anyway?",
"leaveConfirm": "Leave",
"deleteNode": "Delete node",
"systemNodeLocked": "System nodes cannot be deleted",
"deleteEdge": "Delete edge",
"propsTitle": "Node properties",
"propsDesc": "Configure this processing unit",
"systemNodeNoConfig": "System nodes do not need configuration.",
"displayName": "Display name",
"ips": "IP addresses",
"cidrs": "CIDR ranges",
"ipGroups": "IP groups",
"countries": "Country codes",
"countriesDesc": "{count} countries/regions, showing names and ISO codes",
"regions": "Region codes",
"regionsDesc": "{count} first-level regions. Search by name or code.",
"uaCheck": "UA check",
"enableUaCheck": "Enable UA check",
"enableUaCheckTip": "When enabled, requests without a User-Agent return False",
"block": "Block",
"blockTip": "A match returns false and takes priority over match rules",
"blockBots": "Block common crawler UAs",
"blockBotsTip": "Browser or OS classified as Bot (bot / spider / crawler / slurp, e.g. Googlebot)",
"blockAbnormal": "Block abnormal UAs",
"blockAbnormalTip": "Browser classified as Other or Unknown (excludes search-engine bots; use the switch above for crawlers)",
"blockCustom": "Block custom UAs",
"blockCustomTip": "Returns false if the raw User-Agent matches any regex (Lua pattern syntax)",
"customUaPatterns": "Custom UA regex",
"customUaPatternsTip": "One Lua-pattern regex per line. Any match returns false. Max 32.",
"uaMatch": "UA match",
"matchMode": "Match mode",
"matchModeTip": "Used when both browser and OS selections are set",
"matchOr": "OR",
"matchAnd": "AND",
"browsers": "Browsers",
"os": "Operating systems",
"security": "Security checks",
"securityTip": "Any enabled rule match returns False",
"basicProtection": "Basic protection",
"help": "Help",
"oneValuePerLine": "One value per line",
"selectedCount": "{count} selected",
"pleaseSelect": "Select",
"createLabel": "New {label}",
"searchNameOrCode": "Search name or code",
"addCode": "Add code",
"searchOptions": "Search {count} options by name or code",
"noMatchingOptions": "No matching options",
"algorithm": "Algorithm",
"algorithmFast": "Fast",
"algorithmSlow": "Robust",
"difficulty": "Difficulty",
"sessionTtl": "Session TTL (seconds)",
"challengeTtl": "Challenge TTL (seconds)",
"statusCode": "HTTP status code",
"responseBody": "HTML response body",
"bytes": "bytes",
"securityRules": {
"path_traversal": {
"label": "Path traversal",
"tip": "Detect ../ and encoded variants in Path / Query / Body"
},
"file_inclusion": {
"label": "File inclusion (LFI/RFI)",
"tip": "Detect php://, file://, /etc/passwd, and similar in Path / Query / Body"
},
"sql_injection": {
"label": "SQL injection",
"tip": "Detect SQL injection patterns in Query / Body / Header / Cookie"
},
"command_injection": {
"label": "Command injection",
"tip": "Detect OS command injection patterns in Query / Body / Header"
},
"xss": {
"label": "XSS",
"tip": "Detect reflected XSS patterns in Query / Body / Header"
},
"ssrf": {
"label": "SSRF",
"tip": "Detect private addresses and dangerous protocols in Query / Body"
},
"malicious_upload": {
"label": "Malicious upload",
"tip": "Detect dangerous multipart filenames and extensions"
},
"xxe": {
"label": "XXE",
"tip": "Detect external-entity patterns in XML bodies"
},
"crlf_injection": {
"label": "CRLF injection",
"tip": "Detect newline injection in Header / Query / Body"
}
}
}
},
"ipGroups": {
"title": "IP groups",
"create": "New IP group",
"listTitle": "IP groups",
"listDesc": "Maintain manual, automatic, and subscription IP sets that WAF allow/deny lists can reference.",
"refresh": "Refresh",
"loading": "Loading IP groups...",
"empty": "No IP groups yet. Create one first.",
"updated": "IP group updated",
"created": "IP group created",
"deleted": "IP group deleted",
"synced": "Sync completed",
"ipRemoved": "IP removed",
"testHit": "Rule test finished. {count} IPs matched.",
"testMiss": "Rule test finished. No IPs matched.",
"deleteTitle": "Delete IP group",
"deleteDesc": "Delete IP group “{name}”? This cannot be undone.",
"deleting": "Deleting...",
"confirmDelete": "Delete",
"operationFailed": "Operation failed",
"autoConfigMustBeObject": "Automatic configuration must be a JSON object.",
"types": {
"manual": "Manual",
"automatic": "Automatic",
"subscription": "Subscription"
},
"enabled": "Enabled",
"disabled": "Disabled",
"noSyncRecord": "No sync history",
"columns": {
"name": "Name",
"type": "Type",
"status": "Status",
"ipCount": "IPs",
"refCount": "References",
"syncStatus": "Sync status",
"updatedAt": "Updated",
"actions": "Actions"
},
"actions": {
"view": "View",
"edit": "Edit",
"test": "Test rule",
"runNow": "Run now",
"syncNow": "Sync now",
"delete": "Delete"
},
"ban": {
"permanent": "Permanent",
"expired": "Expired",
"minutesLater": "in {count} min",
"hoursLater": "in {count} hr"
},
"presets": {
"scan404": "High-frequency 404 scan from one IP",
"directAccess": "Abnormal direct access from one IP"
},
"dialog": {
"editTitle": "Edit {name}",
"createTitle": "New IP group",
"description": "Maintain manual, automatic, and subscription IP sets that WAF allow/deny lists can reference.",
"name": "IP group name",
"nameRequired": "Enter an IP group name",
"type": "Type",
"enable": "Enable IP group",
"enableDesc": "When disabled, the configuration is kept but not expanded into the WAF runtime list on publish.",
"subscriptionUrl": "Subscription URL",
"subscriptionUrlRequired": "Subscription type requires a URL",
"subscriptionFormat": "Subscription format",
"formatText": "Text list",
"syncInterval": "Sync interval (minutes)",
"syncIntervalDesc": "Minimum 1 minute. Default 1440 minutes.",
"mappingRule": "JSON mapping rule",
"mappingPlaceholder": "Leave empty for the root array",
"autoIntervalDesc": "How often to mine malicious IPs from request logs. Minimum 1 minute, default 1440 minutes.",
"presetRules": "Preset rules",
"autoConfigJson": "Automatic configuration JSON",
"ipList": "IPs / CIDRs",
"ipListSubscriptionHint": "The next subscription sync overwrites this list. You can still save the current contents first.",
"ipListManualHint": "One IP or CIDR per line.",
"saving": "Saving...",
"save": "Save IP group"
},
"testDialog": {
"title": "Automatic rule test result",
"description": "Replay request logs against the current automatic configuration JSON.",
"testing": "Testing...",
"summary": "Lookback {lookback} · {rules} rules · {matched} IPs matched",
"testedAt": "Tested at: {time}",
"noMatch": "No IPs matched.",
"empty": "No test result yet.",
"close": "Close"
},
"viewDialog": {
"titleNamed": "View {name}",
"title": "View IP group",
"summary": "{type} · {count} IPs",
"fallbackDesc": "View IPs in this group and remove entries you no longer need.",
"loading": "Loading IP list...",
"noGroup": "No IP group selected.",
"emptyAuto": "This automatic rule has not captured any IPs yet. Click “Run now” to trigger a capture.",
"empty": "This IP group has no IPs.",
"subscriptionHint": "Subscription groups may restore deleted IPs on the next sync.",
"ipAddress": "IP address",
"capturedAt": "Captured at",
"banRemaining": "Ban remaining",
"actions": "Actions",
"deleteIp": "Delete {ip}",
"close": "Close",
"deleteTitle": "Delete IP",
"deleteDesc": "Remove {ip} from IP group “{name}”?",
"deleting": "Deleting...",
"confirmDelete": "Delete"
}
},
"rateLimits": {
"title": "Rate limits",
"subtitle": "Inspect edge request pressure and configure default concurrency and bandwidth limits.",
"loadingAuth": "Loading permissions...",
"forbiddenTitle": "Insufficient permissions",
"forbiddenDesc": "Only administrators can access rate-limit settings.",
"tabAnalysis": "Analysis",
"tabConfig": "Configuration",
"loadingPage": "Loading rate limits...",
"loadingPressure": "Loading request pressure...",
"loadFailed": "Load failed",
"emptyTitle": "No data",
"emptyDesc": "There are no access logs in the current time range.",
"topHost": "Highest average RPS host",
"topIp": "Highest average RPS IP",
"avgRate": "Average request rate for {range}",
"range": {
"h24": "24 hours",
"h72": "3 days"
},
"chart": {
"title": "Request pressure",
"empty": "No request-pressure data",
"requestRate": "Request rate",
"uniqueVisitors": "Unique visitors",
"visitorsPerBucket": "Visitors / bucket"
},
"config": {
"saved": "Rate-limit settings saved",
"saveFailed": "Save failed",
"loading": "Loading rate-limit settings...",
"preview": "View config preview",
"title": "Global default rate limits",
"description": "0 or empty means disabled by default. Sites without their own settings inherit these values. Publish a release to apply changes.",
"save": "Save",
"connPerServer": "Default concurrency (per site)",
"connPerServerHint": "Default maximum concurrent connections per site",
"connPerIp": "Default concurrency per IP",
"connPerIpHint": "Default maximum concurrent connections per IP",
"limitRate": "Default bandwidth limit",
"limitRateHint": "Default per-request bandwidth, e.g. 512k or 1m",
"reqPerIp": "Default request-rate limit per IP",
"reqPerIpHint": "Default request rate per IP, e.g. 10r/s or 100r/m. Leave empty to disable.",
"invalidConn": "Enter a non-negative integer for concurrency, or leave empty to disable",
"invalidRate": "Invalid rate format. Use 512k, 1m, a number, or leave empty to disable",
"invalidReq": "Invalid request-rate format. Use values like 10r/s or 100r/m, or leave empty to disable"
}
},
"pages": {
"title": "Pages",
"subtitle": "Host static sites at the edge. Upload a static package and select Pages as the upstream in proxy rules.",
"refresh": "Refresh",
"create": "New project",
"loadFailed": "Load failed",
"emptyTitle": "No Pages projects yet",
"emptyDesc": "Create a project, then upload a static deployment package.",
"enabled": "Enabled",
"disabled": "Disabled",
"spaFallback": "SPA fallback",
"strict404": "Strict 404",
"currentActive": "Currently active",
"none": "None",
"activatedAt": "Activated: ",
"notActivated": "Not activated",
"viewDetail": "View details",
"saveFailed": "Save failed",
"updated": "Project updated",
"created": "Project created",
"deleted": "Project deleted",
"deleteFailed": "Delete failed",
"editTitle": "Edit Pages project",
"createTitle": "New Pages project",
"editorDesc": "Configure static hosting settings. After uploading a package, select Pages as the upstream in proxy rules.",
"settingsDesc": "Configure static hosting settings. Saving syncs the project details and proxy references.",
"reset": "Reset",
"saving": "Saving...",
"saveChanges": "Save changes",
"createProject": "Create project",
"form": {
"name": "Project name",
"nameRequired": "Enter a project name",
"slug": "Project slug",
"slugPlaceholder": "Leave empty to auto-generate",
"entryFile": "Entry file",
"entryRequired": "Enter an entry file",
"rootDir": "Root directory",
"optional": "Optional",
"spaFallback": "SPA fallback",
"spaFallbackDesc": "Fall back to the specified path when no static file matches",
"fallbackPath": "Fallback path",
"fallbackPathPrefix": "Fallback path must start with /",
"apiProxy": "API reverse proxy",
"apiProxyDesc": "Attach API proxy rules to the static site",
"matchPath": "Match path",
"matchPathPrefix": "Match path must start with /",
"backend": "Backend URL",
"backendPrefix": "Backend URL must start with http:// or https://",
"rewrite": "Rewrite rule"
},
"detail": {
"invalidId": "A valid Pages project ID is required.",
"loading": "Loading project details...",
"loadFailed": "Failed to load project details",
"back": "Back to list",
"notFound": "This Pages project does not exist or has been deleted.",
"deploymentCount": "{count} deployments",
"tabDeployments": "Deployments",
"tabSettings": "Settings"
},
"danger": {
"title": "Danger zone",
"deleteProject": "Delete project",
"deleteHint": "Permanently delete {name} ({slug}) and all of its deployments.",
"confirmTitle": "Delete Pages project",
"confirmDesc": "Delete project {name}? This cannot be undone.",
"confirm": "Delete"
},
"upload": {
"selectFile": "Select a deployment package",
"success": "Deployment package uploaded",
"failed": "Upload failed",
"unsupported": "Only zip, tar.gz, tar.xz, tar.bz2, tar, and 7z packages are supported",
"title": "Upload deployment package",
"description": "Upload an immutable static archive. You can activate it from deployment history afterward.",
"localPackage": "Local package",
"dropHint": "Drop a package here, or click to choose a file",
"selected": "Selected {name} ({size})",
"chooseArchive": "Choose a supported archive.",
"entry": "Deployment entry",
"entryHint": "The entry comes from project settings. Uploading a package does not overwrite it.",
"processing": "Processing on server",
"progress": "Upload progress",
"pleaseWait": "Please wait",
"uploading": "Uploading...",
"submit": "Upload and create deployment"
},
"files": {
"loadFailed": "Failed to load file list",
"empty": "No file records",
"path": "Path",
"size": "Size"
},
"history": {
"source": {
"manual_upload": "Local upload",
"manual_url": "URL import"
},
"trigger": {
"manual_upload": "Manual upload",
"manual_url": "Manual import",
"manual_sync": "Manual sync",
"scheduled_auto_update": "Scheduled update"
},
"fileMeta": "{checksum} · {count} files · ",
"createdAt": "Created {time}",
"activatedAt": " · Activated {time}",
"collapseFiles": "Collapse file list",
"expandFiles": "Expand file list",
"deploymentNumber": "Deployment #{number}",
"activate": "Activate",
"delete": "Delete",
"activated": "Historical deployment activated. Auto-update (if enabled) has been turned off.",
"activateFailed": "Activation failed",
"deleted": "Deployment deleted",
"deleteFailed": "Delete failed",
"activateTitle": "Activate historical deployment",
"deleteTitle": "Delete deployment",
"activateDesc": "Activating another historical deployment stops the current source task. If auto-update is enabled, it will be turned off.",
"deleteDesc": "Delete deployment #{number}? This cannot be undone.",
"confirm": "Confirm",
"loading": "Loading deployment history...",
"loadFailed": "Failed to load deployment history",
"productionHint": "This is the live production deployment. Changing the active deployment takes effect immediately.",
"manualUpload": "Manual upload",
"emptyProductionTitle": "No production deployment",
"emptyProductionDesc": "Upload a local package, or configure a Remote URL / GitHub Release source and sync.",
"historyHint": "Deployments are immutable. Source info is a snapshot from creation time. You can activate or delete historical deployments.",
"emptyTitle": "No deployments",
"emptyDesc": "Upload a local package, or configure a Remote URL / GitHub Release source and sync."
},
"source": {
"status": {
"idle": "Idle",
"checking": "Checking",
"update_available": "Update available",
"syncing": "Syncing",
"failed": "Last sync failed",
"attention": "Needs confirmation"
},
"check": "Check",
"syncPublish": "Sync and publish",
"missingExecutionId": "Missing task execution ID",
"actionDone": "Source {action} completed",
"actionFailed": "Source {action} failed",
"checkQueued": "Check task queued",
"checkQueueFailed": "Failed to queue check task",
"syncQueued": "Sync task queued",
"syncQueueFailed": "Failed to queue sync task",
"title": "Deployment source",
"loadingDesc": "Loading source configuration...",
"independentDesc": "Source configuration is independent of deployment history.",
"loadFailed": "Failed to load deployment source",
"configDesc": "Configure a remote source and sync to publish. Results appear in deployment history.",
"manualBadge": "Manual deploy",
"localPackage": "Local package",
"noRemote": "No persistent remote source. Upload a package, then activate it from deployment history.",
"submitFailed": "Failed to queue source task",
"statusFailed": "Failed to read task status",
"waitStopped": "Automatic waiting stopped. The task may still be running in the background.",
"refreshStatus": "Refresh task status",
"configure": "Configure",
"checkUpdate": "Check for updates",
"refresh": "Refresh",
"confirmTitle": "Publish the current GitHub revision",
"confirmLead": "This publishes the exact revision currently shown on the card:",
"revisionUnavailable": "The current revision is no longer available. Refresh and try again.",
"confirmPublish": "Confirm and publish",
"updated": "Deployment source updated",
"updateFailed": "Failed to update deployment source",
"switchedManual": "Switched back to manual deploy",
"switchFailed": "Switch failed",
"urlRequired": "Enter a Remote URL",
"urlInvalid": "Enter a valid HTTP(S) URL",
"githubUrlInvalid": "Enter a public repository URL in https://github.com/'{owner}'/'{repo}' format",
"tagInvalid": "Release tag must be a valid Git ref (1–255 bytes; / # & = are allowed)",
"assetInvalid": "Asset name must be 1–255 bytes and cannot be a path or contain control, newline, or bidi characters",
"intervalInvalid": "Check interval must be an integer between 5 and 1440 minutes",
"useManual": "Use manual deploy",
"saveRemote": "Save Remote source",
"saveGithub": "Save GitHub source",
"settingsTitle": "Deployment source",
"settingsDesc": "Choose a deployment source.",
"mode": "Source type",
"manual": "Manual deploy",
"manualHint": "Keep existing deployments and the current production version. Create new deployments with “Upload package”.",
"urlHint": "Enter an HTTP(S) URL that downloads a deployment package directly.",
"allowInsecure": "Allow insecure connections",
"allowInsecureDesc": "Public and private addresses are allowed by default. Enabling this skips TLS certificate verification for self-signed or private CAs.",
"switchManualTitle": "Switch back to manual deploy",
"switchManualDesc": "The current source configuration will be deleted. Existing deployments and the current production version are kept.",
"githubUrl": "GitHub repository URL",
"githubUrlHint": "Only public github.com repositories are supported.",
"releaseSelect": "Release selection",
"latestRelease": "Latest release",
"pinnedTag": "Pinned tag",
"pinnedTagHint": "Check and sync this exact tag.",
"autoUpdate": "Auto-update",
"autoUpdateHint": "Automatically sync and publish when a new release is found.",
"checkInterval": "Check interval (minutes)",
"checkIntervalHint": "Can be set to 5–1440 minutes.",
"assetName": "Release asset filename",
"noRecord": "No record yet",
"address": "URL",
"verifyCert": "Verify certificate",
"lastSync": "Last sync",
"neverSynced": "Not synced yet",
"applied": "Applied",
"latestReleaseLabel": "Latest release",
"pinnedTagLabel": "Pinned tag · {tag}",
"tagMissing": "Not provided",
"assetChangedTitle": "Release asset changed and needs confirmation",
"assetChangedDesc": "The remote revision does not match the published content. Verify the version and assets, then confirm publishing this exact revision.",
"autoUpdateOn": "On",
"autoUpdateOff": "Off",
"intervalMinutes": "{count} minutes",
"nextCheck": "Next check",
"waitingSchedule": "Waiting for schedule",
"lastCheck": "Last check",
"neverChecked": "Not checked yet",
"remote": "Remote"
}
},
"accessLogs": {
"title": "Access logs",
"subtitle": "View traffic overview, IP details, and request logs.",
"refresh": "Refresh",
"cleanup": "Clean up logs",
"tabOverview": "Overview",
"tabIps": "IPs",
"tabList": "Logs",
"cleaned": "Cleaned up {count} logs",
"cleanupFailed": "Cleanup failed",
"loadingTitle": "Loading access logs",
"loadingDesc": "Preparing the page...",
"loadFailed": "Load failed",
"range": {
"h24": "24 hours",
"h168": "7 days",
"h360": "15 days",
"h720": "30 days"
},
"rangeHint": {
"hours24": "Last 24 hours",
"days": "Last {count} days",
"hours": "Last {count} hours"
},
"sort": {
"logged_at:desc": "Newest first",
"logged_at:asc": "Oldest first",
"status_code:desc": "Status high to low",
"status_code:asc": "Status low to high",
"remote_addr:asc": "IP A–Z",
"remote_addr:desc": "IP Z–A",
"total_requests:desc": "Requests high to low",
"total_requests:asc": "Requests low to high",
"request_length:desc": "Inbound high to low",
"request_length:asc": "Inbound low to high",
"bytes_sent:desc": "Outbound high to low",
"bytes_sent:asc": "Outbound low to high",
"success_ratio:desc": "2xx ratio high to low",
"success_ratio:asc": "2xx ratio low to high",
"last_seen_at:desc": "Last seen newest first",
"last_seen_at:asc": "Last seen oldest first"
},
"cache": {
"hit": "Hit",
"origin": "Origin",
"uncached": "Uncached"
},
"filters": {
"pickTime": "Pick a time",
"remoteAddr": "Source IP",
"remoteAddrPlaceholder": "Search by IP",
"host": "Host",
"hostPlaceholder": "Search by host",
"statusCode": "Status code",
"statusCodePlaceholder": "Enter a status code, e.g. 404",
"more": "More filters",
"nodeId": "Node ID",
"nodeIdPlaceholder": "Search by node_id",
"path": "Path",
"pathPlaceholder": "Search by path",
"timeRange": "Time range",
"pageSize": "Per page",
"pageSizeItem": "{count} items",
"apply": "Filter",
"clear": "Clear"
},
"cleanupDialog": {
"invalidDays": "Retention days must be greater than 0",
"title": "Clean up access logs",
"description": "Delete access logs older than the retention period. This cannot be undone.",
"policy": "Retention policy",
"keepDays": "Keep last {days} days",
"custom": "Custom days",
"customDays": "Custom retention days",
"cleaning": "Cleaning...",
"confirm": "Clean up"
},
"detail": {
"title": "Access log details",
"description": "All fields for this request. Use the IPs tab for IP analysis.",
"logId": "Log ID",
"requestTime": "Request time",
"storedAt": "Stored at",
"node": "Node",
"nodeId": "Node ID",
"clientIp": "Client IP",
"region": "Region",
"host": "Host",
"status": "Status",
"cache": "Cache",
"bytesSent": "Outbound",
"requestLength": "Inbound",
"duration": "Duration",
"path": "Path",
"page": "Page {page}",
"prev": "Previous",
"next": "Next",
"listTitle": "Logs",
"empty": "No access logs",
"time": "Time",
"view": "View details"
},
"ip": {
"needRange": "Enter a start and end time",
"invalidTime": "Invalid time format",
"endAfterStart": "End time must be after start time",
"maxRange": "Time range cannot exceed 30 days",
"page": "Page {page}",
"total": " · {count} IPs",
"prev": "Previous",
"next": "Next",
"customRange": "Custom range",
"customPending": "Custom (not applied)",
"timeRange": "Time range",
"current": "Current: {range}",
"custom": "Custom",
"start": "Start",
"end": "End",
"apply": "Apply",
"applyHint": "Click Apply after changing the time. The detail window matches the list range.",
"sort": "Sort",
"pageSize": "Per page",
"title": "IPs",
"empty": "No IP data",
"region": "Region",
"requests": "Requests",
"successRatio": "2xx ratio",
"inbound": "Inbound",
"outbound": "Outbound",
"lastSeen": "Last seen",
"view": "View IP details",
"dialogTitle": "IP details",
"dialogDesc": ". View this IP’s traffic trend, distribution, and WAF IP-group actions."
},
"analysis": {
"emptySeries": "No {title} data",
"selectGroup": "Select an IP group to join",
"added": "Added {ip} to IP group “{name}”",
"addFailed": "Failed to add to IP group",
"removed": "Removed {ip} from IP group “{name}”",
"removeFailed": "Remove failed",
"joinTitle": "Add IP to IP group",
"targetIp": "Target IP:",
"loadingGroups": "Loading IP groups",
"loadGroupsFailed": "Failed to load IP groups",
"alreadyIn": "This IP is already in these IP groups",
"alreadyInHint": "You can remove it, or add it to another IP group.",
"entryCount": "{type} · {count} entries",
"delete": "Delete",
"cannotDelete": "Cannot delete manually",
"notInAny": "This IP is not in any IP group yet.",
"addToOther": "Add to another IP group",
"noWritable": "No writable manual IP groups (or they already contain this IP).",
"selectManual": "Select a manual IP group",
"close": "Close",
"processing": "Working...",
"joinSelected": "Add to selected IP group",
"recentHours": "Last {hours} hours",
"invalidIp": "No valid IP.",
"addToGroup": "Add IP to IP group",
"loading": "Loading IP analysis",
"loadFailed": "Failed to load IP analysis",
"totalRequests": "Total requests",
"errors": "Errors",
"bandwidth": "Bandwidth served",
"received": "Data received",
"uniqueHosts": "Unique hosts",
"uniquePaths": "Unique paths",
"trend": "IP request trend",
"trendMeta": "{ip} · {range} · {minutes}-minute buckets",
"refresh": "Refresh",
"trendFailed": "Failed to load trend",
"trendEmpty": "This IP has no requests in {range}."
},
"overview": {
"loadingTitle": "Loading traffic overview",
"loadingDesc": "Aggregating requests, visits, and bandwidth trends...",
"loadFailed": "Failed to load traffic overview",
"emptyTitle": "No overview data",
"emptyDesc": "There are no traffic stats in the current time range.",
"uniqueVisitors": "{hint} · unique visitors",
"served": "{hint} · data served",
"requestsHint": "Watch for unusual spikes or drops in request volume.",
"requests": "Requests",
"deviceDesc": "Request share by device type.",
"deviceEmpty": "No device-type data",
"statusDesc": "Request share by HTTP status code.",
"statusEmpty": "No status-code data",
"topPathsDesc": "Most requested paths.",
"topHostsDesc": "Hosts with the most traffic.",
"topIpsDesc": "Source IPs with the most requests.",
"browsersDesc": "Requests aggregated by browser.",
"osDesc": "Requests aggregated by operating system.",
"uaDesc": "Requests ranked by raw User-Agent."
},
"toolbar": {
"hostsFiltered": "{count} hosts filtered",
"filterByHost": "Filter by host",
"filterHosts": "Filter hosts",
"clear": "Clear",
"searchPlaceholder": "Search zone or host",
"loadingHosts": "Loading hosts…",
"loadHostsFailed": "Failed to load hosts",
"retry": "Retry",
"noRegistered": "No registered hosts",
"noMatch": "No matching hosts",
"selectZone": "Select zone {name}",
"selectHost": "Select host {name}",
"selectedCount": "{count} hosts selected"
}
},
"cloudflare": {
"title": "Cloudflare",
"connectionSettings": "Connection settings",
"addGroup": "New group",
"loadingOverview": "Loading Cloudflare overview...",
"notReadyTitle": "Cloudflare connection is not ready",
"notReadyDesc": "Import an existing Cloudflare DNS account, or enter a standalone API token and test the connection.",
"configure": "Configure connection",
"groupsTitle": "Pointing groups",
"groupsDesc": "Manage the nodes and domain members behind Cloudflare A records.",
"loadingGroups": "Loading pointing groups...",
"emptyTitle": "No pointing groups",
"emptyDesc": "After creating a group, you can sync domain members to selected edge nodes.",
"enabled": "Enabled",
"disabled": "Disabled",
"memberSummary": "{count} members · new members default orange-cloud {proxy}",
"proxyOn": "on",
"proxyOff": "off",
"manage": "Manage",
"sync": "Sync",
"delete": "Delete",
"created": "Pointing group created",
"syncQueued": "Group sync queued",
"deleted": "Pointing group and remote records deleted",
"deleteTitle": "Delete pointing group",
"deleteDesc": "This deletes all members of {name} and the remote A records managed by this module. This cannot be undone.",
"confirmDelete": "Delete",
"loadingDetail": "Loading group details...",
"groupUpdated": "Group settings updated",
"memberAddedOne": "Domain added and queued for sync",
"memberAddedMany": "Added {count} domains and queued them for sync",
"memberAddFailed": "Failed to add {count} domains",
"memberPartial": "Partial success: {succeeded} added, {failed} failed",
"proxyUpdated": "Orange-cloud setting updated and queued for sync",
"memberSyncQueued": "Member sync queued",
"memberDeleted": "Member and remote A record deleted",
"back": "Back to list",
"refresh": "Refresh",
"edit": "Edit",
"addDomain": "Add domain",
"currentPoint": "Current target",
"activeNode": "Active node {name} · {ip}",
"syncEnabled": "Sync enabled",
"syncDisabled": "Sync disabled",
"primaryNode": "Primary {name}",
"backupNode": "Backup {name}",
"backupUnset": "Not set",
"members": "Domain members",
"membersDesc": "Per-member orange-cloud is the only source of truth during sync.",
"noMembers": "No domain members yet.",
"columns": {
"domain": "Domain",
"desiredIp": "Desired IP",
"status": "Status",
"proxied": "Orange cloud",
"actions": "Actions"
},
"pendingSync": "Pending sync",
"remove": "Remove",
"groupDialog": {
"editTitle": "Edit pointing group",
"createTitle": "New pointing group",
"description": "Phase 1 uses the primary node as the active node. Backup nodes are saved only and do not fail over automatically.",
"name": "Group name",
"primary": "Primary node",
"primaryPlaceholder": "Select an edge node with IPv4",
"noIp": "No IP configured",
"backup": "Backup node",
"none": "None",
"defaultProxied": "Enable orange cloud for new members by default",
"enableSync": "Enable sync",
"save": "Save"
},
"memberDialog": {
"title": "Add domain members",
"description": "Search and select in bulk. Joining creates or takes over the unique same-name A record. Multiple same-name A records are rejected.",
"zoneDomain": "Zone domain",
"searchPlaceholder": "Search domains or zones…",
"selected": "{count} selected",
"visible": "{count} visible",
"unselectAll": "Clear visible",
"selectVisible": "Select visible",
"clear": "Clear",
"noAvailable": "No available domains (already in a group, or not added in website management).",
"noMatch": "No matching domains",
"groupByZone": "Group by zone",
"selectZone": "Select zone {name}",
"zone": "Zone",
"proxied": "Enable orange-cloud proxy",
"submitCount": "Add and sync ({count})",
"submit": "Add and sync"
},
"tasks": {
"pending": "Pending",
"running": "Running",
"succeeded": "Succeeded",
"failed": "Failed",
"system": "System",
"manual": "Manual",
"retry": "Retry",
"schedule": "Scheduled",
"retried": "Sync task re-queued",
"newTaskId": "New task ID: {id}",
"retryFailed": "Failed to retry task",
"unknownError": "Unknown error",
"title": "Sync tasks",
"description": "Shows Cloudflare domain sync (sync_member) and group sync (sync_group) executions only.",
"statusPlaceholder": "Status",
"allStatus": "All statuses",
"refresh": "Refresh",
"loadFailed": "Failed to load sync tasks",
"loading": "Loading sync tasks...",
"emptyTitle": "No sync tasks",
"emptyDesc": "After adding domains or syncing a group, Cloudflare domain/group sync executions appear here.",
"columns": {
"task": "Task",
"status": "Status",
"trigger": "Trigger",
"duration": "Duration",
"result": "Result / error",
"createdAt": "Created"
},
"pageSummary": "{total} total, page {page}/{pages}",
"prev": "Previous",
"next": "Next",
"detailTitle": "Sync task details",
"defaultName": "Cloudflare sync",
"loadingDetail": "Loading task details...",
"status": "Status",
"trigger": "Trigger",
"retries": "Retries",
"duration": "Duration",
"taskId": "Task ID",
"createdAt": "Created",
"finishedAt": "Finished",
"result": "Result",
"error": "Error",
"logs": "Logs",
"close": "Close"
},
"settings": {
"saved": "Cloudflare connection saved",
"verified": "Cloudflare connection verified",
"cleared": "Cloudflare connection cleared",
"back": "Back to list",
"title": "Cloudflare connection",
"sourceTitle": "Credential source",
"sourceDesc": "The token should have Zone:Read and DNS:Edit. Tokens are never echoed in the API or UI.",
"source": "Connection source",
"importDns": "Import existing DNS account",
"standalone": "Standalone API token",
"dnsAccount": "Cloudflare DNS account",
"selectAccount": "Select a DNS account",
"dnsHint": "Only cloudflare-type DNS accounts are shown. Add one in",
"dnsLink": "DNS accounts",
"dnsHintAfter": ".",
"tokenKeep": "Leave empty to keep the existing token; saving replaces it",
"tokenEnter": "Enter a Cloudflare API token",
"save": "Save settings",
"test": "Test connection",
"clear": "Clear connection",
"statusTitle": "Current status",
"ready": "Token verified. Cloudflare pointing sync can run.",
"notReady": "After saving, you still need to test the connection. Sync is rejected until it is verified."
}
},
"openflareOps": {
"saved": "OpenFlare operations settings saved",
"saveFailed": "Save failed",
"tokenRotated": "Discovery token regenerated",
"tokenRotateFailed": "Failed to rotate token",
"kumaSynced": "Uptime Kuma sync ran",
"syncFailed": "Sync failed",
"invalidParams": "Validation failed",
"loading": "Loading OpenFlare operations settings...",
"loadFailed": "Load failed",
"save": "Save",
"agent": {
"title": "Agent runtime",
"description": "Heartbeat interval and offline threshold sync to nodes on the next heartbeat.",
"heartbeat": "Heartbeat interval ({duration})",
"offline": "Offline threshold ({duration})",
"wsUpgrade": "Enable WebSocket upgrade",
"wsUpgradeDesc": "After a successful HTTP heartbeat, try upgrading to WebSocket so config publishes can notify immediately.",
"updateRepo": "Agent update repository"
},
"geo": {
"title": "IP geolocation",
"description": "Controls the GeoIP source for node maps and similar views. Visitor access-log geolocation always uses MaxMind mmdb.",
"mode": "Lookup method",
"disabled": "Off",
"testIp": "Test IP",
"querying": "Looking up...",
"query": "Look up",
"country": "Country / region"
},
"pages": {
"title": "Pages static hosting",
"description": "Configure the upload size limit and how many historical deployments each project keeps.",
"maxSize": "Package size limit (MiB)",
"history": "Historical deployments to keep (0 = unlimited)",
"historyHint": "Each project keeps at most N deployments: the active one is always kept, then the rest fill newest-first. Extra inactive deployments are cleaned up after a successful upload. zip, tar.gz, tar.xz, tar.bz2, tar, and 7z are supported."
},
"discovery": {
"title": "Discovery token and deploy",
"description": "New nodes use the discovery token on first join. Rotate it from node management or the action below.",
"manageNodes": "Node management",
"rotate": "Rotate token",
"tokenReadonly": "Discovery token (read-only)",
"loading": "Loading...",
"notGenerated": "Not generated",
"command": "One-line deploy command",
"commandHint": "Enter a reachable Server URL and fetch a token first.",
"copied": "Command copied",
"copy": "Copy command"
},
"kuma": {
"title": "Uptime Kuma integration",
"description": "Diff-sync reverse-proxy sites to an Uptime Kuma instance.",
"syncNow": "Sync now",
"enable": "Enable Uptime Kuma",
"url": "Uptime Kuma URL",
"username": "Username",
"password": "Password",
"passwordKeep": "Leave empty to keep the current password",
"syncInterval": "Sync interval (minutes)",
"scope": "Monitor scope",
"allSites": "All sites",
"selectedSites": "Selected sites",
"selectedLabel": "Selected sites",
"pickSites": "Choose monitored sites",
"noneSelected": "No sites selected",
"interval": "Check interval (seconds)",
"retry": "Retries",
"retryInterval": "Retry interval (seconds)",
"timeout": "Request timeout (seconds)"
},
"duration": {
"minutes": "{count} min",
"seconds": "{count} sec"
},
"errors": {
"heartbeatMin": "Heartbeat interval cannot be less than 1000 milliseconds.",
"offlineMin": "Offline threshold cannot be less than 10000 milliseconds.",
"offlineRatio": "Offline threshold should be at least 3× the heartbeat interval.",
"kumaUrl": "Enter an Uptime Kuma URL.",
"kumaUser": "Enter an Uptime Kuma username.",
"syncInterval": "Sync interval must be a positive integer.",
"interval": "Heartbeat interval must be a positive integer.",
"retry": "Retry count must be a non-negative integer.",
"retryInterval": "Heartbeat retry interval must be a positive integer.",
"timeout": "Request timeout must be a positive integer.",
"pagesSize": "Pages package size limit must be between 1 and 2048 MiB.",
"pagesHistory": "Pages history count must be an integer ≥ 0 (0 means unlimited)."
},
"status": {
"title": "System status",
"loadFailed": "Failed to load system status",
"unknownError": "An unknown error occurred",
"autoRefresh": "Auto-refresh",
"refresh": "Refresh",
"overview": "Service overview",
"overviewDesc": "Basic service health metrics",
"uptime": "Uptime",
"goroutines": "Goroutines",
"heapObjects": "Heap objects",
"memory": "Memory",
"memoryDesc": "Primary memory usage",
"alloc": "Current allocation",
"totalAlloc": "Total allocated",
"sys": "System memory",
"nextGc": "Next GC target",
"usageRatio": "Current usage (Alloc / Sys)",
"heapStack": "Heap / stack",
"heapStackDesc": "Runtime heap and stack details",
"heapAlloc": "Heap allocated",
"heapSys": "Heap system",
"heapIdle": "Heap idle",
"heapInuse": "Heap in use",
"heapReleased": "Heap released",
"stackInuse": "Stack in use",
"stackSys": "Stack system",
"structs": "Internal structures",
"structsDesc": "Runtime management structure overhead",
"mspanInuse": "MSpan in use",
"mspanSys": "MSpan system",
"mcacheInuse": "MCache in use",
"mcacheSys": "MCache system",
"buckHashSys": "Profiling hash table",
"gcSys": "GC metadata",
"otherSys": "Other system memory",
"gc": "GC and allocations",
"gcDesc": "GC history and allocation counts",
"numGc": "GC runs",
"lastGc": "Time since last GC",
"pauseTotal": "Total GC pause",
"lastPause": "Last GC pause",
"mallocs": "Allocations",
"frees": "Frees",
"lookups": "Pointer lookups"
},
"siteModal": {
"title": "Choose monitored sites",
"description": "Select reverse-proxy sites to sync to Uptime Kuma. Search by site name or domain.",
"search": "Search sites",
"searchPlaceholder": "Search by name or domain...",
"selectFiltered": "Select filtered",
"clearFiltered": "Clear filtered",
"loading": "Loading sites...",
"loadFailed": "Failed to load sites",
"noMatch": "No matching sites",
"select": "Select",
"siteName": "Site name",
"primaryDomain": "Primary domain",
"selectedCount": "{count} monitored sites selected",
"save": "Save selection"
}
}
}