tool.xpcool.com/src/i18n/locales/en-US.ts
夏犀麟 dd38aeaf38
All checks were successful
Build and Deploy (tool.xpcool.com) / build-and-deploy (push) Successful in 1m10s
feat(theme): 改版为清晰蓝卡片工作台并接管 UI 库尺度
主色青玉改宝石蓝,字号整体放大一档(正文 16px),
通过 --td-comp-* 与 --td-font-* 接管 TDesign 控件高度与文字,
修复 theme-mode 选择器权重不足导致深色变量被 UI 库覆盖的问题。
2026-09-14 23:54:53 +08:00

534 lines
18 KiB
TypeScript

/**
* English locale.
* Key structure must stay identical to zh-CN.ts (see that file for the convention).
*/
export default {
app: {
name: 'Online Toolbox',
short: 'Toolbox',
tagline: 'Runs in your browser. Nothing leaves your device.',
footer: {
local: 'Runs entirely in the browser',
privacy: 'No data uploaded',
free: 'Free to use',
icpTitle: 'Verify the ICP filing (Ministry of Industry and Information Technology)',
},
home: 'Home',
backHome: 'Back to home',
},
nav: {
home: 'Home',
browse: 'Browse tools',
searchPlaceholder: 'Search tools by name or purpose',
searchAria: 'Search tools',
commandHint: 'Shortcut',
toolsCount: '{count} tools',
noResult: 'No matching tools',
noResultHint: 'Try another keyword, or browse the categories below.',
clearSearch: 'Clear search',
menuAria: 'Open navigation',
skipToContent: 'Skip to main content',
},
palette: {
title: 'Quick jump',
placeholder: 'Type a tool name, category, or keyword…',
empty: 'No matching tools',
emptyHint: 'Try keywords like "image", "JSON", or "time".',
hintNavigate: 'Select',
hintClose: 'Close',
hintToggle: 'Toggle theme',
groupTool: 'Tools',
groupPage: 'Pages',
},
theme: {
label: 'Theme',
light: 'Light',
dark: 'Dark',
auto: 'System',
switchToLight: 'Switch to light mode',
switchToDark: 'Switch to dark mode',
switchToAuto: 'Follow system setting',
current: 'Current theme: {mode}',
},
locale: {
label: 'Language',
'zh-CN': '简体中文',
'en-US': 'English',
'ja-JP': '日本語',
'ko-KR': '한국어',
},
home: {
title: 'A toolbox that lives in your browser',
desc: '{count} everyday utilities. Every calculation and file operation happens on your own machine.',
statTools: 'Available tools',
statCategories: 'Categories',
statUpload: 'Data uploaded to a server',
statUploadValue: '0 bytes',
statLocal: 'Processed locally',
statLocalValue: 'Everything',
statLanguages: 'Languages',
statServer: 'Server endpoints',
statServerValue: '{count}',
searchPlaceholder: 'Search tools, or filter by purpose',
resultCount: '{count} tools',
filterAll: 'All',
emptyTitle: 'No matching tools',
emptyHint: 'Try a shorter keyword such as "image", "JSON", or "convert".',
resetFilter: 'Reset filters',
serverBadge: 'Online',
localBadge: 'Local',
},
category: {
work: {
label: 'Everyday work',
desc: 'Programming, office text, and file handling',
},
dev: {
label: 'Developer tools',
desc: 'Formatting, conversion, and diffing for developers',
},
design: {
label: 'Creative',
desc: 'Gradients, placeholder images, and ASCII art',
},
life: {
label: 'Daily life',
desc: 'Everyday calculators, lookups, and helpers',
},
fun: {
label: 'Just for fun',
desc: 'Morse code and other small toys',
},
online: {
label: 'Server tools',
desc: 'Powered by our own backend API, needs a network connection',
},
},
tool: {
'image-compress': {
name: 'Image compressor',
desc: 'Compress JPG/PNG/WebP locally with adjustable quality, then download',
},
'image-to-ico': {
name: 'Image to ICO',
desc: 'Turn PNG/JPG/WebP/SVG into icons with multi-size output and size control',
},
'json-format': {
name: 'JSON formatter',
desc: 'Format, minify, and validate JSON, then copy the result in one click',
},
timestamp: {
name: 'Timestamp converter',
desc: 'Convert between Unix timestamps and dates, in seconds or milliseconds',
},
base64: {
name: 'Base64 encoder',
desc: 'Encode and decode Base64 text, or convert image files to and from Base64',
},
'jwt-parse': {
name: 'JWT decoder',
desc: 'Read the header and payload of a JWT, including its expiry',
},
cron: {
name: 'Cron expression',
desc: 'Preview the next run times and build expressions visually',
},
'radix-convert': {
name: 'Number base converter',
desc: 'Convert between binary, octal, decimal, and hexadecimal',
},
hash: {
name: 'Hash calculator',
desc: 'MD5, SHA1, SHA256, and SHA512 for text or files',
},
'url-parse': {
name: 'URL parser',
desc: 'Break a URL into protocol, host, path, and query, or build one',
},
translate: {
name: 'Translation',
desc: 'Chinese, English, Japanese, and Korean translation',
},
ocr: {
name: 'Image OCR',
desc: 'Extract text from images locally, Chinese and English supported',
},
uuid: {
name: 'UUID generator',
desc: 'Batch UUID v4 generation, either in-browser or through the backend API',
},
'regex-test': {
name: 'Regex tester',
desc: 'Test matching, groups, and replacements live with highlighted hits',
},
'case-convert': {
name: 'Case converter',
desc: 'Switch between camelCase, snake_case, kebab-case, and more',
},
'color-convert': {
name: 'Color converter',
desc: 'Convert between HEX, RGB, HSL, and HSV with a picker and swatches',
},
'yaml-json': {
name: 'YAML ↔ JSON',
desc: 'Two-way conversion between YAML and JSON with clear error positions',
},
'word-count': {
name: 'Word counter',
desc: 'Count characters, CJK glyphs, words, and paragraphs, plus reading time',
},
'zh-convert': {
name: 'Chinese converter',
desc: 'Convert between Simplified and Traditional Chinese',
},
'image-cropper': {
name: 'Image cropper',
desc: 'Crop images to a fixed ratio with live preview, export as JPG or PNG',
},
qrcode: {
name: 'QR code reader',
desc: 'Generate QR codes from text or links, and decode them from an image',
},
idcard: {
name: 'ID card parser',
desc: 'Validate a Chinese ID number and read its birth date, gender, and region',
},
'address-parse': {
name: 'Address parser',
desc: 'Split a Chinese address into province, city, district, and street',
},
'unit-convert': {
name: 'Unit converter',
desc: 'Eight families of units including length, mass, temperature, and data',
},
'rmb-upper': {
name: 'RMB in words',
desc: 'Write an amount in formal Chinese capital numerals, including cents',
},
'date-calc': {
name: 'Date calculator',
desc: 'Date differences, offsets, plus age, zodiac, and constellation',
},
'password-gen': {
name: 'Password generator',
desc: 'Batch-generate strong random passwords with a strength estimate',
},
bmi: {
name: 'BMI calculator',
desc: 'Body mass index with the Chinese classification and healthy weight range',
},
mortgage: {
name: 'Mortgage calculator',
desc: 'Compare equal-installment and equal-principal loans: payment and total interest',
},
'bill-split': {
name: 'Bill splitter',
desc: 'Split a shared bill and get a minimal set of transfers to settle up',
},
'random-decision': {
name: 'Random decision',
desc: 'Draw lots, roll dice, or pick a number when you cannot decide',
},
pomodoro: {
name: 'Pomodoro timer',
desc: 'Focus and break countdowns with a record of completed rounds',
},
'sql-format': {
name: 'SQL formatter',
desc: 'Beautify SQL with keyword line breaks and clause indentation, live',
},
'text-diff': {
name: 'Text diff',
desc: 'Compare two texts line by line with added and removed lines highlighted',
},
'json-to-code': {
name: 'JSON to code',
desc: 'Generate TypeScript interfaces, Go structs, or Python classes from JSON',
},
'gradient-generator': {
name: 'Gradient generator',
desc: 'Design CSS gradients visually with curated presets, ready to copy',
},
'placeholder-image': {
name: 'Placeholder image',
desc: 'Custom size and color placeholders, download as PNG or copy SVG',
},
'ascii-art': {
name: 'Image to ASCII',
desc: 'Turn a photo into ASCII art with adjustable density and inversion',
},
'morse-code': {
name: 'Morse code',
desc: 'Translate text to and from Morse, and play it back as real beeps',
},
'regex-visual': {
name: 'Regex visualizer',
desc: 'Break a regular expression into a structure tree with match testing',
},
'markdown-table': {
name: 'Markdown table',
desc: 'Paste data and get a Markdown or HTML table in one step',
},
'api-builder': {
name: 'API request builder',
desc: 'Compose a request visually and get ready-to-run fetch or curl code',
},
'gitignore-gen': {
name: '.gitignore generator',
desc: 'Pick your stack and get the ignore rules you actually need',
},
'code-to-image': {
name: 'Code to image',
desc: 'Render code as a shareable card image with syntax highlighting',
},
'color-namer': {
name: 'Color namer',
desc: 'Match a color value to the closest CSS color name',
},
'indent-convert': {
name: 'Indent converter',
desc: 'Convert between spaces and tabs, with 2, 4, or 8 space widths',
},
'code-stats': {
name: 'Code statistics',
desc: 'Count total, code, comment, and blank lines',
},
'hello-world': {
name: 'Hello World collection',
desc: 'Starter code for over 30 programming languages',
},
'json-diff': {
name: 'JSON diff',
desc: 'Compare two JSON documents key by key: added, removed, changed',
},
'env-parse': {
name: 'Env file parser',
desc: 'Convert between .env, JSON, and plain key-value pairs',
},
'random-string': {
name: 'Random string',
desc: 'Generate random strings by length and character set, locally or server-side',
},
'api-status': {
name: 'API status',
desc: 'Probe the backend endpoints for availability and response time',
},
'exchange-rate': {
name: 'Currency converter',
desc: 'Live exchange rates for major currencies',
},
'express-query': {
name: 'Parcel tracking',
desc: 'Look up delivery progress by tracking number',
},
'phone-locate': {
name: 'Phone number lookup',
desc: 'Find the region and carrier of a mobile number',
},
'ip-info': {
name: 'IP information',
desc: 'See the IP the server sees, whether it is private, plus your browser details',
},
'network-test': {
name: 'Network test',
desc: 'Check reachability with HTTP, Ping, TCP, and DNS probes',
},
'speed-test': {
name: 'Speed test',
desc: 'Measure download and upload throughput and latency',
},
},
page: {
common: {
local: 'Local',
server: 'Server',
source: 'Compute on',
localHint: 'Done inside this browser, no network request',
serverHint: 'Calls the backend API, needs a network connection',
serverUnavailable: 'Server unavailable: {message}',
refresh: 'Refresh',
copyResult: 'Copy result',
},
'ip-info': {
title: 'IP information',
desc: 'Ask the backend which IP it sees, check whether it is a private address, and inspect your local browser environment.',
serverTitle: 'Source IP as seen by the server',
ipLabel: 'IP address',
internal: 'Private address',
external: 'Public address',
internalHint: 'A private address usually comes from a company or home network, so the server cannot resolve a public location from it.',
externalHint: 'This is the public egress IP the server sees. It can differ from your local network if a proxy or NAT is involved.',
browserTitle: 'Local environment',
timezone: 'Time zone',
language: 'Browser language',
platform: 'Operating system',
screen: 'Screen resolution',
viewport: 'Viewport',
userAgent: 'User agent',
geoTitle: 'Location lookup',
geoUnavailable: 'The current backend returns only the IP and the private-address flag, without geolocation data.',
},
uuid: {
title: 'UUID generator',
desc: 'Generate UUIDs in batches, either locally with the browser CSPRNG or through the backend API.',
count: 'Count',
uppercase: 'Uppercase',
noHyphen: 'No hyphens',
modeLabel: 'Generation mode',
modeLocal: 'Local (UUID v4)',
modeServer: 'Server (GoFrame guid)',
serverHint: 'The server returns a 32-character ID, or an 8-character short code when requested.',
short: 'Short code (8 chars)',
resultTitle: 'Results',
regenerate: 'Regenerate',
copyAll: 'Copy all',
},
hash: {
title: 'Hash calculator',
desc: 'Compute MD5, SHA1, SHA256, and SHA512 for text or files, locally by default.',
tabText: 'Text',
tabFile: 'File',
inputTitle: 'Input text',
inputPlaceholder: 'Enter the text to hash',
uppercase: 'Uppercase output',
compute: 'Compute',
clear: 'Clear',
uploadTitle: 'Upload a file',
uploadTip: 'Drop any file and the hashes are computed automatically',
resultTitle: 'Hash results',
serverMd5: 'Also compute MD5 on the server',
serverMd5Hint: 'Runs MD5 once more through the backend so you can check both implementations agree.',
compareTitle: 'Side-by-side comparison',
compareSame: 'Both sides match',
compareDiff: 'The two sides disagree, check the source',
compareServerFailed: 'Server-side MD5 failed: {message}',
errEmpty: 'Enter some text to hash first',
errCompute: 'Computation failed, please try again',
errFile: 'Could not read the file, please try again',
},
timestamp: {
title: 'Timestamp converter',
desc: 'Convert between timestamps and Beijing time (UTC+8), in seconds or milliseconds, and read the server clock.',
tabTs2Date: 'Timestamp → date',
tabDate2Ts: 'Date → timestamp',
tabBatch: 'Bulk convert',
convertTitle: 'Convert',
tsPlaceholder: 'Enter a timestamp, e.g. 1704067200',
unit: 'Unit',
unitSecond: 'Seconds',
unitMillisecond: 'Milliseconds',
now: 'Now',
convert: 'Convert',
batchConvert: 'Convert all',
resultTitle: 'Result',
pickTitle: 'Pick a Beijing time',
pickPlaceholder: 'Select date and time',
batchInputTitle: 'Bulk timestamps → Beijing time',
batchInputPlaceholder: 'One timestamp per line, e.g.:\n1704067200\n1704067200000',
batchResultTitle: 'Bulk results',
download: 'Download',
beijing: 'Beijing time',
localTime: 'Local time',
secondSuffix: ' (seconds)',
millisecondSuffix: ' (milliseconds)',
errInvalidTs: 'Enter a valid numeric timestamp',
errOutOfRange: 'Timestamp is outside the representable range',
errInvalidDate: 'Choose a valid date and time',
invalidTs: '[invalid timestamp]',
outOfRange: '[out of range]',
serverNow: 'Read server time',
serverTimeLabel: 'Server time',
serverOffset: 'Difference from local clock',
clockSkewOk: 'Local clock matches the server',
clockSkewWarn: 'Local clock may be off by {seconds} seconds',
serverFailed: 'Request failed: {message}',
},
'random-string': {
title: 'Random string',
desc: 'Generate random strings by length and character set, optionally from the server CSPRNG.',
length: 'Length',
type: 'Character set',
typeAlnum: 'Letters + digits',
typeDigits: 'Digits only',
typeLetters: 'Letters only',
count: 'How many',
modeLocal: 'Local (Web Crypto)',
modeServer: 'Server (crypto/rand)',
generate: 'Generate',
resultTitle: 'Results',
serverRangeHint: 'The server accepts lengths from 1 to 128; anything else falls back to local generation.',
strengthHint: 'Longer strings from a larger character set are harder to guess.',
},
'api-status': {
title: 'API status',
desc: 'Probe each backend endpoint for availability and response time to confirm the frontend and backend are talking.',
endpoint: 'Endpoint',
method: 'Method',
status: 'Status',
latency: 'Latency',
summary: '{ok} of {total} endpoints healthy',
allOk: 'All endpoints healthy',
partial: 'Some endpoints failed',
probe: 'Run probe',
probing: 'Probing…',
lastChecked: 'Last checked: {time}',
baseUrlLabel: 'API base URL',
sampleTitle: 'Sample response',
notConfigured: 'No API base URL configured, cannot probe.',
failed: 'Request failed',
endpointIp: 'Client IP',
endpointMd5: 'MD5 digest',
endpointRandom: 'Random string',
endpointTime: 'Server time',
endpointUuid: 'Unique ID',
ok: 'Healthy',
error: 'Failed',
},
},
pending: {
title: 'This endpoint is not live yet',
hint: 'The page is ready. Once the backend implements the endpoint it starts working automatically, with no frontend change.',
networkTest:
'The HTTP reachability check works today. Ping, TCP, and DNS probes turn on once the backend implements them.',
speedTest:
'Download testing can use a public source (subject to its CORS policy). Upload testing turns on once the backend implements the upload endpoint.',
contactHint: 'The endpoint contract lives in docs/api-contract.md inside the project.',
},
common: {
copy: 'Copy',
copied: 'Copied to clipboard',
copyAll: 'Copy all',
clear: 'Clear',
download: 'Download',
loading: 'Working…',
query: 'Search',
querying: 'Searching…',
convert: 'Convert',
generate: 'Generate',
compute: 'Compute',
history: 'History',
historyEmpty: 'No history yet',
empty: 'Nothing here yet',
error: 'Something went wrong',
retry: 'Retry',
close: 'Close',
confirm: 'Confirm',
cancel: 'Cancel',
unitSeconds: 'Seconds',
unitMilliseconds: 'Milliseconds',
yes: 'Yes',
no: 'No',
notProvided: 'Not provided',
},
}