{
  "time": {
    "current_time_label": "Current time:",
    "input_label": "Input (Unix ms/s or date)",
    "input_placeholder": "1690000000 / 1690000000000 / 2026-04-22T00:00:00Z",
    "convert": "Convert",
    "copy_output": "Copy output",
    "output": "Output",
    "err_parse_timestamp": "Could not parse timestamp.",
    "err_parse_date": "Could not parse date string.",
    "copied": "Copied."
  },
  "json_diff": {
    "intro": "Object-level diff powered by jsondiffpatch (not plain line diff). Arrays support move detection; delta is a patch structure for add/remove/update fields.",
    "left_json": "Left JSON",
    "right_json": "Right JSON",
    "compute": "Compute diff",
    "delta_title": "Delta (jsondiffpatch format)",
    "no_diff_comment": "// No difference (same JSON structure)",
    "parse_failed": "Parse failed"
  },
  "ascii": {
    "th_dec": "Dec",
    "th_hex": "Hex",
    "th_char": "Char",
    "th_note": "Note",
    "note_control": "Control",
    "note_printable": "Printable"
  },
  "uuid": {
    "count_label": "Count (1–200)",
    "generate_uuid_v4": "Generate UUID v4",
    "copy_all": "Copy all",
    "please_generate_first": "Please generate first.",
    "copied_all": "Copied all.",
    "output": "Output",
    "output_placeholder": "Click generate."
  },
  "ulid": {
    "count_label": "Count (1–100)",
    "generate": "Generate ULID",
    "copy": "Copy",
    "placeholder": "26-character time-sortable IDs"
  },
  "nanoid": {
    "length_label": "Length (4–64)",
    "alphabet_hint": "Custom alphabet (empty = nanoid URL-safe default)",
    "generate": "Generate",
    "copy": "Copy"
  },
  "units": {
    "css_title": "CSS: px ↔ rem",
    "root_px": "Root font size (px)",
    "check_line": "Check: {px}px ÷ {root} = {rem} rem",
    "storage_title": "Data size",
    "iec_toggle": "IEC steps (1024): KiB / MiB / GiB",
    "bytes_label": "Byte count (integer)"
  },
  "color": {
    "picker": "Color picker",
    "css": "CSS",
    "hex": "HEX",
    "rgb_title": "RGB (0–255)",
    "hsl_title": "HSL",
    "h_label": "H (°)",
    "s_label": "S (%)",
    "l_label": "L (%)",
    "copy_all_formats": "Copy all formats",
    "copied_line": "Copied HEX / RGB / HSL line."
  },
  "contrast": {
    "fg": "Foreground (text)",
    "bg": "Background",
    "large_text_toggle": "Use large-text threshold (≥18pt bold or ≥24pt regular)",
    "sample_text": "Sample Aa 中文 123",
    "invalid_hex": "Use #RRGGBB or #RGB.",
    "ratio_label": "Contrast",
    "wcag_prefix": "WCAG 2.1:"
  },
  "url_parse": {
    "parse": "Parse",
    "err_invalid": "Invalid URL",
    "url_object_fields": "URL object fields",
    "search_params": "Query (searchParams)",
    "key": "Key",
    "value": "Value",
    "port_default": "(default)",
    "page_intro": "Uses native <api>URL</api> and <usp>URLSearchParams</usp>; no network requests."
  },
  "punycode": {
    "unicode_label": "Unicode domain / labels (lines or dot-separated)",
    "to_punycode": "→ Punycode / ASCII",
    "puny_label": "Punycode (xn--…)",
    "to_unicode": "→ Unicode",
    "fail": "Failed"
  },
  "data_url": {
    "drop_label": "File → Data URL",
    "drop_title": "Choose or drop a file",
    "drop_desc": "Uses FileReader.readAsDataURL; not uploaded.",
    "data_url": "Data URL",
    "copy": "Copy",
    "decode_download": "Decode & download",
    "err_format": "Expected data:[mime][;base64],payload",
    "decode_failed": "Decode failed"
  },
  "mime_sniff": {
    "drop_label": "Read file header",
    "drop_title": "Choose or drop a file",
    "drop_desc": "Reads first 64 bytes for magic sniff; not uploaded.",
    "guess_type": "Guessed type",
    "first_64_hex": "First 64 bytes (hex)"
  },
  "mime_types": {
    "search_ph": "Search extension or MIME…",
    "col_ext": "Extension",
    "col_mime": "MIME",
    "col_note": "Note"
  },
  "html_format": {
    "format": "Format",
    "minify_simple": "Simple minify (strip comment whitespace)",
    "output": "Output",
    "copy": "Copy",
    "fail": "Failed"
  },
  "svg_format": {
    "source": "SVG source",
    "validate_indent": "Validate & indent",
    "xml_parse_err": "XML parse error; check tags.",
    "fail": "Failed"
  },
  "markdown": {
    "render_failed": "Render failed",
    "label": "Markdown source",
    "export_html": "Export HTML",
    "copy_md": "Copy Markdown",
    "preview": "Live preview"
  },
  "http_codes": {
    "search_ph": "Search code, name, or description…",
    "col_code": "Code",
    "col_name": "Name",
    "col_desc": "Description"
  },
  "ua_parse": {
    "fill_ua": "Fill this device UA",
    "hint": "Light regex parse, not a full device database; crawlers/WebViews may show as Other.",
    "browser": "Browser",
    "engine": "Engine (coarse)",
    "os": "OS",
    "mobile": "Mobile",
    "yes": "Yes",
    "no": "No"
  },
  "keycode": {
    "instructions": "Click the area below, then press keys (some shortcuts are blocked by the browser).",
    "capture_aria": "Key capture area",
    "focus_hint": "Focus here, then press keys…",
    "which_keycode": "which / keyCode (legacy)",
    "modifiers": "Modifiers"
  },
  "yaml_json": {
    "warning": "js-yaml runs tag parsing; do not paste untrusted large YAML. Local only.",
    "yaml_to_json": "YAML → JSON",
    "json_to_yaml": "JSON → YAML",
    "parse_failed": "Parse failed"
  },
  "toml_json": {
    "warning": "TOML date types map to JSON-friendly forms; do not paste untrusted large configs.",
    "toml_to_json": "TOML → JSON",
    "json_to_toml": "JSON → TOML",
    "parse_failed": "Parse failed"
  },
  "json_csv": {
    "json_label": "JSON (array of objects)",
    "csv_label": "CSV (header row)",
    "json_to_csv": "JSON → CSV",
    "csv_to_json": "CSV → JSON",
    "need_object_array": "JSON must be an array of objects.",
    "parse_failed": "Parse failed"
  },
  "jsonpath": {
    "expr_label": "JSONPath expression",
    "hint": "Powered by jsonpath-plus (jq-like in parts).",
    "query": "Query",
    "result_array": "Result (array)",
    "fail": "Failed"
  },
  "json_to_ts": {
    "root_name": "Root interface name",
    "generate": "Generate types",
    "typescript": "TypeScript",
    "fail": "Failed"
  },
  "jmespath": {
    "expr_label": "JMESPath expression",
    "hint": "Same JMESPath as AWS CLI / some SDKs; wrap JSON literals in backticks, e.g.",
    "query": "Query",
    "result": "Result",
    "fail": "Failed"
  },
  "sql_format": {
    "dialect": "Dialect",
    "dialect_sql": "Standard SQL",
    "beautify": "Beautify",
    "compress": "Compress",
    "output": "Output",
    "format_failed": "Format failed"
  },
  "gitignore": {
    "templates": "Templates",
    "merge": "Merge",
    "placeholder": "Merged .gitignore",
    "copy": "Copy"
  },
  "compress": {
    "warn": "Uses CompressionStream; Brotli depends on browser. Output is Base64 bytes.",
    "algo": "Algorithm",
    "mode_compress": "Compress",
    "mode_decompress": "Decompress",
    "utf8_text": "UTF-8 text",
    "run_text_compress": "Compress text",
    "run_text_decompress": "Decompress (expects UTF-8 text)",
    "file_label": "Or file (raw bytes)",
    "file_title": "Choose file",
    "file_desc": "Binary compress / decompress.",
    "b64_label": "Base64 result / input",
    "copy_b64": "Copy Base64",
    "from_b64_compress": "From Base64 → compress",
    "from_b64_decompress": "From Base64 → decompress",
    "unsupported_algo": "This algorithm is not supported; try Chrome/Edge or gzip/deflate.",
    "done_bytes": "Done ({n} bytes)",
    "fail": "Failed",
    "b64_invalid": "Invalid Base64"
  },
  "cron": {
    "label": "Cron (min hour day month dow)",
    "hint": "Human text via cronstrue; complex expr follows library.",
    "natural_language": "Natural language",
    "cannot_parse": "Could not parse this expression."
  },
  "chmod": {
    "oct_label": "Octal (e.g. 644, 755)",
    "to_rwx": "→ rwx",
    "rwx_label": "rwxrwxrwx",
    "to_octal": "→ octal",
    "err_oct_range": "Octal must be 0–777.",
    "err_rwx": "rwx must be 9 chars of r w x - (setuid simplified)."
  },
  "cidr": {
    "label": "IPv4 / CIDR",
    "calc": "Calculate",
    "err": "Error",
    "network": "Network",
    "broadcast": "Broadcast",
    "mask": "Subnet mask",
    "first_host": "First host",
    "last_host": "Last host",
    "total_addrs": "Total addresses",
    "usable_hosts": "Usable hosts (/31,/32 simplified)"
  },
  "ipv6": {
    "label": "IPv6 address or CIDR",
    "parse": "Parse",
    "err": "Error",
    "correct_form": "Normalized (correctForm)",
    "canonical_form": "Full expand (canonicalForm)",
    "prefix_len": "Prefix length",
    "subnet_start": "Subnet start",
    "subnet_end": "Subnet end",
    "addr_count": "Address count"
  },
  "ieee754": {
    "label": "Number (decimal)",
    "need_finite": "Enter a finite number.",
    "float64": "Float64",
    "float32": "Float32",
    "hex_be": "Hex (big-endian)",
    "detail_64": "sign {sign} · exp {exp} (bias 1023) · frac {frac}",
    "detail_32": "sign {sign} · exp {exp} (bias 127) · frac {frac}"
  },
  "num_base": {
    "from_radix": "Source radix (2–36)",
    "digits": "Digits",
    "convert": "Convert",
    "common_bases": "Common bases",
    "parse_err": "Could not parse integer for this radix."
  },
  "iban": {
    "label": "IBAN (spaces ok)",
    "check": "Check mod 97",
    "ok": "Checksum OK (mod 97 = 1). Normalized: {n}",
    "bad": "Checksum failed (remainder {r}). Normalized: {n}"
  },
  "luhn": {
    "label": "Digits (spaces ok)",
    "check": "Luhn check",
    "pass": "Passes Luhn (mod 10)",
    "fail": "Failed"
  },
  "phone": {
    "default_country": "Default country (ISO 3166-1 alpha-2; used without +)",
    "number": "Phone number",
    "parse": "Parse",
    "unparsed": "Could not parse (try changing default country).",
    "err": "Error",
    "line_e164": "E.164: {v}",
    "line_intl": "International: {v}",
    "line_nat": "National: {v}",
    "line_country": "Country: {c} (default {d})",
    "line_type": "Type: {v}",
    "line_valid": "Valid: {v}",
    "yes": "Yes",
    "no": "No",
    "dash": "—"
  },
  "letter_codes": {
    "input": "Input (A–Z, 0–9; use / for space in Morse)",
    "nato": "NATO alphabet",
    "morse": "Morse code",
    "braille": "Braille (A–Z, digits)"
  },
  "barcode": {
    "format": "Format",
    "content": "Content (valid length/charset per symbology)",
    "download_png": "Download PNG",
    "cannot_generate": "Could not generate"
  },
  "media_convert": {
    "intro": "Experimental: loads ffmpeg wasm from CDN (large). Works best for small/medium files.",
    "load_btn_loading": "Loading…",
    "load_btn_ready": "Ready",
    "load_btn_idle": "Load ffmpeg core",
    "media_file": "Media file",
    "no_file": "No media file selected.",
    "out_ext": "Output extension",
    "convert_go": "Convert",
    "converting": "Converting…",
    "download": "Download {name}",
    "log": "Log",
    "load_failed": "Load failed",
    "ffmpeg_loaded_log": "ffmpeg core loaded (unpkg CDN, this session only)",
    "ffmpeg_exit": "ffmpeg exited with code {c}; see log.",
    "convert_failed": "Conversion failed",
    "moved_notice": "Media conversion has moved to Video Tools. Please use the new format converter.",
    "moved_link": "Go to Video Format Converter →"
  },
  "video_common": {
    "intro": "The ffmpeg core (~30MB) loads automatically when you open this page. Files are processed locally in your browser; nothing is uploaded. Recommended max {mb}MB per file.",
    "core_loading": "Loading video processor…",
    "core_reload": "Reload component",
    "load_btn_loading": "Loading…",
    "load_btn_ready": "Core ready",
    "load_btn_idle": "Load ffmpeg core",
    "media_file": "Video or audio file",
    "no_file": "No file selected.",
    "converting": "Processing…",
    "download": "Download {name}",
    "log": "Log",
    "load_failed": "Failed to load ffmpeg core. Check your network and try again.",
    "load_failed_wasm": "ffmpeg-core.wasm (~32MB) did not load. Try disabling proxy/VPN or switching networks.",
    "ffmpeg_exit": "ffmpeg exited with code {c}. Try another output format or Video Compress first.",
    "convert_failed": "Processing failed",
    "progress": "About {n}%",
    "err_file_too_large": "File exceeds the {mb}MB limit. Trim or compress first."
  },
  "video_convert": {
    "page_intro": "Convert between MP4, WebM, MKV, GIF, M4A, WAV, and more. Some codecs are limited in wasm; try another output or use Video Compress first.",
    "out_ext": "Output format",
    "convert_go": "Start conversion"
  },
  "video_to_mp4": {
    "page_intro": "Export to MP4 (H.264/AAC chosen by ffmpeg). Best for sharing and mobile playback. If it fails, try Video Compress to re-encode first."
  },
  "video_mov_to_mp4": {
    "page_intro": "Convert QuickTime / iPhone MOV to MP4. Other video inputs are also accepted; output is always MP4."
  },
  "video_mkv_to_mp4": {
    "page_intro": "Convert Matroska (.mkv) to MP4 for players that do not support MKV. Output is always MP4."
  },
  "video_webm_to_mp4": {
    "page_intro": "Convert WebM screen recordings or downloads to MP4. Output is always MP4."
  },
  "video_avi_to_mp4": {
    "page_intro": "Convert legacy AVI to MP4. Output is always MP4; very old codecs may need compress/re-encode first."
  },
  "video_to_webm": {
    "page_intro": "Export WebM (VP8/VP9 + Opus/Vorbis). Good for web embeds; playback support varies by device."
  },
  "video_to_mkv": {
    "page_intro": "Export MKV container. Useful for archiving; MP4 is usually better for sharing."
  },
  "video_trim": {
    "page_intro": "Cut by start/end time in seconds. Fast = stream copy (quick, keyframe-aligned); Precise = re-encode (slower, tighter cuts).",
    "duration_label": "Duration ≈ {sec} s",
    "start_sec": "Start (s)",
    "end_sec": "End (s)",
    "mode_label": "Mode",
    "mode_copy": "Fast (stream copy)",
    "mode_encode": "Precise (re-encode)",
    "trim_go": "Trim & download"
  },
  "video_compress": {
    "page_intro": "Shrink file size by lowering resolution and increasing CRF (higher = smaller, lower quality; typical 23–32).",
    "height_label": "Max height",
    "height_option": "{h}p",
    "crf_label": "CRF (now {crf})",
    "crf_hint": "Higher CRF = stronger compression.",
    "compress_go": "Compress & download"
  },
  "video_to_gif": {
    "page_intro": "Convert video to GIF. Higher FPS/width = larger files and slower runs.",
    "fps_label": "FPS",
    "width_label": "Width (px)",
    "convert_go": "Create GIF"
  },
  "video_extract_audio": {
    "page_intro": "Strip the audio track from video. M4A is smaller; WAV is uncompressed.",
    "format_label": "Output format",
    "format_m4a": "M4A (AAC)",
    "format_wav": "WAV (PCM)",
    "format_hint": "MP3 encoding may be unavailable in wasm; prefer M4A.",
    "extract_go": "Extract audio"
  },
  "x509_view": {
    "intro": "Paste PEM (with BEGIN/END) or DER Base64; SHA-256 fingerprint via Web Crypto, local only.",
    "cert": "Certificate",
    "parse": "Parse",
    "parsing": "Parsing…",
    "fingerprint": "SHA-256 fingerprint (hex)",
    "structured": "Structured info",
    "parse_failed": "Parse failed"
  },
  "jwt": {
    "warning": "Decodes Base64URL and formats JSON only. <strong>Signature is not verified</strong> — not for auth decisions. Do not paste sensitive tokens into untrusted environments.",
    "input_label": "JWT string",
    "decode": "Decode",
    "err_empty": "Enter a JWT.",
    "err_parts": "Need at least header.payload.",
    "err_header_json": "Header is not valid JSON.",
    "err_payload_json": "Payload is not valid JSON."
  },
  "base64": {
    "text_label": "Text",
    "text_to_base64": "Text → Base64",
    "base64_to_text": "Base64 → Text",
    "base64_field": "Base64",
    "base64_from_file": "Base64 from file",
    "select_or_drop_file": "Select or drop file",
    "base64_from_file_desc": "Raw bytes encoded; not uploaded.",
    "encoded_file": "Encoded: {name}",
    "copy": "Copy",
    "copied": "Copied.",
    "base64_to_download": "Decode to download",
    "decode_failed": "Decode failed"
  },
  "base32": {
    "original_utf8": "Original (UTF-8)",
    "text_to_base32": "Text → Base32",
    "base32_to_text": "Base32 → Text",
    "base32_rfc4648": "Base32 (RFC 4648, no padding)",
    "copy": "Copy",
    "copied_base32": "Copied Base32.",
    "decode_failed": "Decode failed"
  },
  "base58": {
    "text_utf8": "Text (UTF-8)",
    "text_to_base58": "Text → Base58",
    "base58_to_text": "Base58 → Text",
    "base58_field": "Base58",
    "decode_failed": "Decode failed"
  },
  "url_encode": {
    "input": "Input",
    "output": "Output",
    "encode": "Encode",
    "decode": "Decode",
    "copy_output": "Copy output",
    "copied": "Copied.",
    "decode_failed": "Decode failed"
  },
  "hex": {
    "text_utf8": "Text (UTF-8)",
    "text_to_hex": "Text → Hex",
    "hex_to_text": "Hex → Text",
    "hex_field": "Hex (spaces, newlines, and 0x are stripped when decoding)",
    "copy": "Copy",
    "copied_hex": "Copied hex.",
    "err_hex_odd_length": "Hex length must be even (whitespace and 0x ignored).",
    "err_utf8_decode": "Could not decode as UTF-8"
  },
  "escape": {
    "mode": "Mode",
    "html_entity_mode": "HTML entities",
    "json_string_mode": "JSON string escape",
    "input": "Input",
    "encode_or_escape": "Encode / escape",
    "decode_or_restore": "Decode / restore",
    "json_decode_not_string": "JSON value is not a string.",
    "decode_failed": "Decode failed",
    "output": "Output",
    "copied_output": "Copied output.",
    "copy_output": "Copy output",
    "failed": "Failed",
    "page_intro": "Like common Escape / entity tools: HTML uses core character entities; JSON mode escapes strings parseable by <jp>JSON.parse</jp>."
  },
  "hash": {
    "select_file": "Select file",
    "select_or_drop_file": "Select or drop file",
    "hash_local_desc": "Digest computed locally; not uploaded.",
    "please_select_file": "Please select a file first.",
    "computing": "Computing…",
    "compute_digest": "Compute digest",
    "copy": "Copy",
    "computed_file": "Computed: {name} ({size} bytes)",
    "compute_failed": "Compute failed",
    "md5_label": "MD5",
    "sha256_label": "SHA-256",
    "dash": "—"
  },
  "hmac": {
    "hash_algorithm": "Hash algorithm",
    "secret_key": "Secret key",
    "message": "Message",
    "compute_hmac_hex": "Compute HMAC (hex)",
    "output": "Output",
    "copy": "Copy",
    "failed": "Failed",
    "dash": "—"
  },
  "aes": {
    "aes_pbkdf2_note": "AES-256-GCM: random salt + PBKDF2 ({iter} iterations, SHA-256) derives the key in your browser only.",
    "passphrase": "Passphrase",
    "plaintext": "Plaintext",
    "encrypt": "Encrypt",
    "decrypt": "Decrypt",
    "processing": "Processing…",
    "please_input_passphrase": "Please enter a passphrase.",
    "encrypt_success": "Encrypted.",
    "encrypt_failed": "Encrypt failed",
    "cipher_base64": "Ciphertext (Base64: salt ∥ IV ∥ data)",
    "cipher_too_short": "Ciphertext is too short or corrupted.",
    "decrypt_success": "Decrypted.",
    "decrypt_failed_bad_key": "Decrypt failed (wrong passphrase or bad data).",
    "copied_cipher": "Copied ciphertext.",
    "copy_cipher": "Copy ciphertext"
  },
  "password": {
    "select_charset": "Select at least one character set.",
    "length_4_to_256": "Length (4–256)",
    "upper_az": "Uppercase A–Z",
    "lower_az": "Lowercase a–z",
    "digits": "Digits",
    "symbols": "Symbols",
    "generate": "Generate",
    "copy": "Copy",
    "copied": "Copied.",
    "result": "Result",
    "placeholder_click_generate": "Click Generate",
    "footnote": "Uses crypto.getRandomValues; symbol set is a small keyboard-friendly subset—adjust checkboxes as needed."
  },
  "crc32": {
    "text_utf8": "Text (UTF-8)",
    "compute_crc32": "Compute CRC32",
    "label_from_file": "Or from file",
    "title_drop": "Select or drop file",
    "desc_local": "IEEE CRC-32 over raw bytes; not uploaded.",
    "crc32_title": "CRC32",
    "label_current_text": "current text",
    "copy_hex": "Copy hex",
    "copied_hex_value": "Copied hex value.",
    "msg_computed": "Computed: {label} ({bytes} bytes)",
    "read_failed": "Read failed",
    "decode_failed": "Failed",
    "dash": "—"
  },
  "xor": {
    "warning": "XOR is symmetric and offers no authentication—do not use for real secrecy; fine for CTFs, demos, or light obfuscation.",
    "encrypt_section": "Encrypt",
    "decrypt_section": "Decrypt",
    "plaintext_utf8": "Plaintext (UTF-8)",
    "key_utf8_cyclic": "Key (UTF-8, repeated)",
    "output_format": "Output format",
    "opt_hex": "Hex",
    "opt_b64": "Base64",
    "xor_to_cipher": "XOR → ciphertext",
    "cipher_label": "Ciphertext",
    "cipher_input_label": "Ciphertext ({mode})",
    "xor_to_plain": "XOR → plaintext",
    "plaintext_result": "Plaintext",
    "err_key_empty": "Key cannot be empty",
    "err_hex_odd": "Hex length must be even",
    "failed": "Failed"
  },
  "vigenere": {
    "intro": "Vigenère: only A–Z / a–z are transformed; other characters are kept. Non-letters in the key are ignored.",
    "text": "Text",
    "key_english": "Key (letters)",
    "encrypt": "Encrypt",
    "decrypt": "Decrypt",
    "result": "Result",
    "err_key_letters": "Key must contain at least one A–Z letter",
    "error_generic": "Error"
  },
  "rsa": {
    "intro": "Uses the browser <link>Web Crypto</link> RSA-OAEP; only for short messages or wrapping symmetric keys. Requires a secure context (HTTPS or localhost).",
    "generate_keypair": "Generate key pair",
    "pub_pem": "Public key (SPKI PEM)",
    "priv_pem": "Private key (PKCS#8 PEM)",
    "encrypt_section": "Encrypt",
    "plaintext_utf8": "Plaintext (UTF-8)",
    "encrypt_public": "Encrypt with public key",
    "cipher_section": "Ciphertext & decrypt",
    "cipher_b64": "Ciphertext (Base64)",
    "decrypt_private": "Decrypt with private key",
    "decrypted": "Decrypted",
    "msg_generated": "Generated 2048-bit RSA-OAEP (SHA-256); private key stays in memory only—do not share.",
    "msg_generate_fail": "Generate failed (some environments need a secure context: HTTPS or localhost).",
    "err_need_public_pem": "Generate or paste public key PEM first.",
    "err_plain_too_long": "Plaintext too long: RSA-OAEP (2048 / SHA-256) is usually under about {max} bytes; current {current}. Use symmetric crypto (e.g. AES-256-GCM) to wrap keys.",
    "encrypt_failed": "Encrypt failed",
    "err_need_private_pem": "Generate or paste private key PEM first.",
    "decrypt_failed": "Decrypt failed",
    "err_pem_parse": "Could not parse PEM; check BEGIN/END blocks."
  },
  "qr_generate": {
    "content_label": "Content (text / URL / Wi‑Fi)",
    "size_px": "Size (px)",
    "margin": "Margin",
    "foreground": "Foreground",
    "background": "Background",
    "generate_preview": "Generate preview",
    "busy": "Generating…",
    "download_png": "Download PNG",
    "preview": "Preview",
    "qr_alt": "QR code",
    "err_empty": "Content cannot be empty",
    "err_generate": "Generate failed"
  },
  "qr_decode": {
    "drop_label": "Image with QR code",
    "drop_title": "Select or drop PNG / JPG …",
    "drop_desc": "Decoded locally with jsQR; not uploaded.",
    "empty_hint": "No image selected yet.",
    "parse_result": "Result",
    "copy": "Copy",
    "err_canvas": "Canvas unavailable",
    "err_not_found": "No QR found (try a clearer, higher-contrast image).",
    "err_decode": "Decode failed",
    "err_load_image": "Could not load image",
    "dash": "—"
  },
  "text_case": {
    "mode_label": "Transform",
    "mode_upper": "UPPERCASE",
    "mode_lower": "lowercase",
    "mode_title": "Title Case (words)",
    "mode_sentence": "Sentence case (heuristic)",
    "mode_camel": "camelCase",
    "mode_constant": "CONSTANT_CASE",
    "mode_kebab": "kebab-case",
    "mode_snake": "snake_case",
    "source": "Source",
    "result": "Result",
    "copy_result": "Copy result",
    "placeholder_source": "Paste or type…"
  },
  "text_lines": {
    "sort_asc": "Sort lines (↑)",
    "sort_desc": "Sort lines (↓)",
    "dedupe": "Dedupe lines",
    "remove_empty": "Remove empty lines",
    "trim_lines": "Trim each line",
    "reverse": "Reverse line order",
    "input": "Input",
    "result": "Result",
    "copy_result": "Copy result",
    "placeholder_input": "One item per line, or paste a list…",
    "placeholder_result": "Use the buttons above…"
  },
  "text_stats": {
    "label": "Text",
    "placeholder": "Paste content; stats update live…",
    "lines": "Lines",
    "chars_code_units": "Characters (code units)",
    "chars_no_ws": "Characters (no whitespace)",
    "words_ws": "Words (whitespace split)",
    "graphemes": "Grapheme clusters (Intl, approx. “characters”)",
    "bytes_utf8": "UTF-8 bytes",
    "footnote": "“Words” split on spaces; for CJK etc. prefer graphemes. All stats run locally."
  },
  "text_replace": {
    "find": "Find",
    "replace_with": "Replace with",
    "use_regex": "Use regular expression",
    "flags": "Flags",
    "source": "Source",
    "result": "Result",
    "copy": "Copy",
    "footnote": "Literal mode replaces all matches globally; regex mode follows String.replace—mind escaping and flags (common: g, i, m)."
  },
  "text_split_join": {
    "delimiter": "Delimiter",
    "placeholder_delimiter": "e.g. , or | or custom",
    "split_lines": "Split → one item per line",
    "join_lines": "Join ← lines with delimiter",
    "copy_result": "Copy result",
    "help": "Split: cut the text by delimiter into lines. Join: read input line-by-line and insert the delimiter between lines.",
    "placeholder_input": "Split: paste one comma-separated line; Join: one item per line…",
    "placeholder_output": "Click split or join…",
    "input": "Input",
    "output": "Output"
  },
  "text_regex": {
    "warn_truncated": "Only the first {max} characters are matched and highlighted.",
    "pattern": "Pattern",
    "flags": "Flags",
    "flags_ph": "gimsuy",
    "invalid": "Invalid regular expression",
    "text": "Text",
    "match_count": "{count} match(es)",
    "list_omitted": "… further matches omitted"
  },
  "text_diff": {
    "text_a": "Text A",
    "text_b": "Text B",
    "line_diff": "Line diff"
  },
  "text_lorem": {
    "paragraphs": "Paragraphs (1–50)",
    "generate": "Generate",
    "copy": "Copy",
    "placeholder": "Click Generate"
  },
  "text_rot13": {
    "label": "Text (A–Z rotates 13; run again to undo)",
    "action": "ROT13"
  },
  "text_strip_html": {
    "warning": "Uses DOMParser for text nodes; scripts are not executed—still avoid pasting huge untrusted HTML.",
    "html": "HTML",
    "plain": "Plain text",
    "extract": "Extract plain text",
    "placeholder_out": "Use the button on the left"
  },
  "text_slug": {
    "input": "Input",
    "generate": "Generate slug",
    "hint": "Strip diacritics, keep a–z and 0–9, turn spaces/symbols into hyphens (URL slug helper, not full SEO).",
    "result": "Result",
    "copy": "Copy",
    "dash": "—"
  },
  "text_indent": {
    "text": "Text",
    "use_tab": "Indent with Tab",
    "spaces_per_level": "Spaces per level",
    "dedent_times": "Dedent passes",
    "indent_once": "Indent whole block",
    "dedent_tab": "Remove up to {n} leading tab(s) per line",
    "dedent_space": "Remove up to {n} leading space(s) per line"
  },
  "text_sort_lines": {
    "label": "Sort lines",
    "desc": "Descending",
    "natural": "Natural sort (numeric)",
    "trim_end": "Trim end of line before sort",
    "sort": "Sort",
    "page_intro": "Complements sorting in line cleanup: toggle ascending/descending and enable <lc>localeCompare</lc>-friendly numeric mode—great for version numbers and file lists."
  },
  "text_line_numbers": {
    "text": "Text",
    "start": "Start number",
    "pad_width": "Min width",
    "separator": "Separator",
    "add": "Add line numbers",
    "strip": "Strip simple “number | ” prefix",
    "footnote": "Strip uses a simple regex for leading digits and “|”; edit manually for complex cases."
  },
  "text_wrap": {
    "note": "Width counts UTF-16 code units—not terminal columns or full-width CJK; toggle hard-break for long unbroken lines.",
    "text": "Text",
    "max_width": "Max characters per line",
    "break_long": "Hard-break long lines without spaces",
    "rewrap": "Rewrap in place"
  },
  "csv_markdown": {
    "csv_to_md": "CSV → Markdown",
    "to_markdown": "To Markdown table",
    "md_to_csv": "Markdown table → CSV",
    "to_csv": "To CSV",
    "failed": "Failed"
  },
  "fullwidth": {
    "source": "Text",
    "to_full": "To fullwidth",
    "to_half": "To halfwidth",
    "footnote": "Covers printable ASCII and space; CJK etc. unchanged."
  },
  "rmb_daxie": {
    "convert": "Convert",
    "placeholder": "1234.56",
    "error": "Error"
  },
  "ics": {
    "raw_label": "iCalendar text",
    "parse": "Parse",
    "no_events": "No VEVENT parsed",
    "parse_failed": "Parse failed",
    "no_title": "(No title)",
    "start": "Start",
    "end": "End",
    "location": "Location",
    "dash": "—"
  },
  "vcard": {
    "raw_label": "vCard text",
    "th_field": "Field",
    "th_value": "Value",
    "empty": "No valid rows"
  },
  "email_headers": {
    "raw_label": "Raw headers (up to first blank line)",
    "th_name": "Name",
    "th_value": "Value",
    "empty": "Nothing parsed"
  },
  "docmind": {
    "privacy_title": "Cloud conversion notice",
    "privacy_body": "Files are sent through this site's converter to Alibaba Cloud Document Mind (China mainland). Do not upload sensitive personal data. Download links from Alibaba are typically valid for about 24 hours.",
    "err_no_file": "Choose a PDF file first.",
    "err_file_too_large": "File must not exceed {max}MB.",
    "err_too_many_files": "Only one PDF file per conversion.",
    "err_failed": "Conversion failed",
    "err_no_download_url": "Conversion finished but no download URL was returned. Try again.",
    "err_proxy_unreachable": "Cannot reach the converter service ({base}). Start the docmind proxy and set NEXT_PUBLIC_DOCMIND_API_URL.",
    "msg_submitting": "Submitting conversion job…",
    "msg_processing": "Processing in the cloud; this may take tens of seconds to a few minutes…",
    "msg_done": "Conversion complete. Download from the list below.",
    "result_title": "Conversion results",
    "download_hint": "Links are provided by Alibaba Cloud and are typically valid for about 24 hours. If save fails, open the link in a new tab.",
    "selected_file": "Selected: {name} (~{size} MB)",
    "poll_hint": "Polled {count} time(s), checking about every 10 seconds",
    "limits_note": "Limits: one PDF per job, max 10MB, max 1000 pages (per Alibaba Document Mind)."
  },
  "pdf_to_word": {
    "drop_label": "Choose PDF",
    "drop_desc": "One PDF per job, max 10MB; converts to Word (.docx) via Alibaba Document Mind.",
    "empty_hint": "No file selected yet.",
    "btn_convert": "Convert"
  },
  "pdf_to_excel": {
    "drop_label": "Choose PDF",
    "drop_desc": "One PDF per job, max 10MB; converts to Excel (.xlsx) via Alibaba Document Mind.",
    "empty_hint": "No file selected yet.",
    "btn_convert": "Convert"
  },
  "pdf_roadmap": {
    "page_intro": "Product commitments must match technical limits: the capabilities below involve layout engines, font subsetting, and legal compliance, and cannot reach professional grade on a pure-browser pdf-lib path alone—evaluate server-side, WASM, or commercial SDKs separately.",
    "section_office_title": "Office interchange (Word / Excel / PPT)",
    "section_office_li1": "Typical approaches: self-hosted converters (LibreOffice / OnlyOffice / commercial APIs) or in-browser WASM (evaluate bundle size, licensing, and output quality).",
    "section_office_li2": "Suggested product stance: clearly label when high-fidelity conversion requires upload to a conversion service, plus privacy terms.",
    "section_edit_title": "Bulk text edits / watermark removal",
    "section_edit_li1": "PDF text is usually drawing operators, not an editable document tree; \"Word-like\" edits typically need a professional PDF engine or manual cleanup.",
    "section_edit_li2": "Watermark removal cannot be guaranteed for arbitrary files; compliant scope is removing layers added via this site's tools, with clear restrictions in terms."
  },
  "pdf_merge": {
    "drop_label": "Choose PDFs (merged in list order; add multiple times)",
    "drop_desc": "Multi-select supported; order follows the list below; drag in again to append.",
    "err_need_two": "Select at least 2 PDF files.",
    "msg_done": "Download finished.",
    "err_failed": "Merge failed",
    "empty_hint": "No files selected yet.",
    "btn_merge_download": "Merge and download",
    "download_name": "merged.pdf"
  },
  "pdf_batch": {
    "phase2_title": "Phase 2: batch queue + Worker rendering (when supported)",
    "phase2_body": "If OffscreenCanvas is supported, rasterization runs in a Worker to reduce UI jank; otherwise it falls back to the main thread with chunking.",
    "drop_label": "Add PDFs to queue (multi-select, drag multiple times)",
    "drop_desc": "Non-PDF files are filtered. Tasks appear in the list below.",
    "err_no_pdf": "No PDF files detected.",
    "err_no_pending": "No pending tasks (completed items are not re-exported).",
    "log_started": "Starting batch export…",
    "err_cancelled": "Cancelled",
    "err_failed_msg": "Batch failed",
    "log_done_zip": "Packed ZIP download finished.",
    "scale_label": "Export scale (batch suggests 1.4 – 2.2)",
    "fmt_label": "Export format",
    "quality_label": "Quality (0.1 – 1.0)",
    "status_prefix": "Status:",
    "status_pending": "pending",
    "status_running": "running",
    "status_done": "done",
    "status_error": "error",
    "btn_remove": "Remove",
    "queue_empty": "Queue is empty.",
    "btn_export_all": "Export all ({n} pending)",
    "btn_processing": "Working…",
    "btn_cancel": "Cancel",
    "btn_clear_queue": "Clear queue",
    "log_page_progress": "{file}: {current}/{total}"
  },
  "pdf_compress": {
    "notice_title": "Compression strategy (transparent)",
    "notice_body": "Raster compression: each page is rendered to JPG and rebuilt into a PDF. Works best on scans; text PDFs may grow or look softer.",
    "drop_label": "Choose PDF",
    "drop_desc": "Re-pack locally in the browser to shrink size; nothing is uploaded.",
    "compress_desc": "Local streaming repack to reduce size; not uploaded.",
    "empty_pdf": "No PDF selected yet.",
    "download_name": "compressed.pdf",
    "scale_label": "Render scale (higher = sharper but larger)",
    "quality_label": "JPG quality (0.1 – 1.0)",
    "btn_compress": "Compress and download",
    "msg_select_first": "Choose a PDF first.",
    "msg_done_hint": "Download finished (note: scans shrink more than text PDFs).",
    "err_failed": "Compression failed"
  },
  "pdf_crop": {
    "intro": "Adjust CropBox/MediaBox margins (pt). This changes the visible region and page bounds without deleting vector content.",
    "drop_label": "Choose PDF",
    "drop_desc": "Cropping runs locally. Pages are configured below.",
    "empty_pdf": "No PDF selected yet.",
    "left": "Left margin (pt)",
    "right": "Right margin (pt)",
    "top": "Top margin (pt)",
    "bottom": "Bottom margin (pt)",
    "mode_label": "Crop mode",
    "mode_crop_media": "CropBox + MediaBox (more general)",
    "mode_crop_only": "CropBox only (conservative)",
    "btn_crop": "Crop and download",
    "msg_select_pdf": "Choose a PDF first.",
    "msg_pick_pages": "Select pages to crop.",
    "msg_done": "Download finished.",
    "err_failed": "Crop failed",
    "download_name": "cropped.pdf"
  },
  "pdf_decrypt": {
    "notice_title": "Compliance notice",
    "notice_body": "Only for PDFs whose password you know. Pages are rasterized and rebuilt, so selectable text and links are lost.",
    "drop_encrypt_label": "Choose encrypted PDF",
    "drop_desc": "Decrypt locally with your password; files are not uploaded.",
    "empty_pdf": "No PDF selected yet.",
    "password_label": "Open password",
    "scale_label": "Render scale",
    "quality_label": "JPG quality (0.1 – 1.0)",
    "btn_decrypt": "Decrypt and download",
    "msg_select_first": "Choose a PDF first.",
    "msg_done": "Download finished.",
    "err_failed": "Decrypt failed",
    "download_name": "decrypted.pdf"
  },
  "pdf_delete_pages": {
    "drop_label": "Choose PDF",
    "drop_desc": "Click thumbnails to delete; unselected pages stay and export to a new file.",
    "hint_short": "Click pages to delete; unselected pages remain in the exported PDF.",
    "btn_delete": "Delete selected pages and download",
    "empty_pdf": "No PDF selected yet.",
    "msg_select_pdf": "Choose a PDF first.",
    "msg_pick_delete": "Select pages to delete.",
    "msg_done": "Download finished.",
    "err_failed": "Delete failed",
    "thumb_title": "Pages to delete",
    "download_name": "deleted-pages.pdf"
  },
  "pdf_extract_text": {
    "drop_label": "Choose PDF",
    "drop_desc": "Extract text per page locally; scans may have no text layer.",
    "empty_pdf": "No PDF selected yet.",
    "btn_extract": "Extract text (txt)",
    "msg_select_pdf": "Choose a PDF first.",
    "progress_page": "Extracting page {current} / {total}…",
    "msg_done_hint": "Exported txt. Note: scanned/image PDFs may yield no text.",
    "err_failed": "Extract failed"
  },
  "pdf_header_footer": {
    "intro": "Phase 2: left/center/right header and footer templates; placeholders '{'n'}' and '{'total'}' are replaced on export. Chinese text uses Source Han Sans subset from OSS; fetch failures fall back gracefully.",
    "presets_heading": "Quick presets",
    "drop_label": "Choose PDF",
    "drop_desc": "Apply header/footer text per page locally; supports '{'n'}' / '{'total'}', etc.",
    "empty_pdf": "No PDF selected yet.",
    "header_left": "Header left",
    "header_center": "Header center",
    "header_right": "Header right",
    "footer_left": "Footer left",
    "footer_center": "Footer center",
    "footer_right": "Footer right",
    "ph_company": "e.g. company name",
    "ph_title": "e.g. document title",
    "ph_version": "e.g. version",
    "footer_center_ph": "Suggested: '{'n'}' / '{'total'}'",
    "font_size": "Font size",
    "margin_pt": "Margin (pt)",
    "btn_apply": "Apply and download",
    "msg_select_pdf": "Choose a PDF first.",
    "msg_need_field": "Fill at least one header or footer slot.",
    "msg_pick_pages": "Select pages for the template.",
    "msg_done": "Download finished.",
    "err_failed": "Failed",
    "preset_minimal_name": "Minimal footer (n / total)",
    "preset_internal_name": "Internal use + footer",
    "preset_dual_name": "Dual header + centered footer",
    "preset_internal_header": "Internal · Do not distribute",
    "preset_internal_footer": "Page '{'n'}' / '{'total'}' pages",
    "preset_dual_footer": "Confidential",
    "download_name": "header-footer.pdf"
  },
  "images_to_pdf": {
    "intro": "PNG / JPEG supported. One image per PDF page; page size matches pixel dimensions.",
    "drop_label": "Choose images (page order follows list; add multiple times)",
    "drop_desc": "PNG and JPEG only; list order is page order.",
    "empty_hint": "No files selected yet.",
    "btn_generate": "Build PDF",
    "msg_need_image": "Choose at least one image.",
    "msg_done": "Download finished.",
    "err_failed": "Failed to generate",
    "download_name": "images-merged.pdf"
  },
  "pdf_metadata": {
    "drop_label": "Choose PDF",
    "drop_desc": "Read common document properties; edit and export as a new file.",
    "empty_pdf": "No PDF selected yet.",
    "label_title": "Title",
    "label_author": "Author",
    "label_subject": "Subject",
    "label_keywords": "Keywords",
    "keywords_ph": "Separate with commas",
    "label_creator": "Creator",
    "label_producer": "Producer (optional)",
    "producer_ph": "Leave empty to keep existing Producer",
    "label_language": "Language (optional)",
    "language_ph": "e.g. zh-CN, en-US; leave empty to skip Lang in outline",
    "checkbox_viewer_prefs": "Prefer document title in viewer window title (pdf-lib ViewerPreferences)",
    "btn_apply": "Apply and download",
    "msg_loaded": "Metadata loaded; edit and export.",
    "msg_read_failed": "Read failed",
    "msg_select_pdf": "Choose a PDF first.",
    "msg_done_verify": "Metadata written and downloaded (some viewers cache old metadata—rename to verify).",
    "err_export_failed": "Export failed",
    "download_suffix": "-metadata",
    "page_intro": "Covers common fields shown under reader \"document properties\". Changes write a new file locally—nothing uploads to our servers. Powered by <pdflib>Hopding/pdf-lib</pdflib>."
  },
  "pdf_page_numbers": {
    "intro": "Placeholders: '{'n'}' current page, '{'total'}' total pages. Chinese strings are OK (e.g. “Page '{'n'}'”); font loads from OSS subset with fallback.",
    "drop_label": "Choose PDF",
    "drop_desc": "Add footer/page-edge numbering locally.",
    "empty_pdf": "No PDF selected yet.",
    "start_number": "Start number",
    "align_label": "Alignment",
    "align_left": "Left",
    "align_center": "Center",
    "align_right": "Right",
    "format_string": "Format string",
    "font_size": "Font size",
    "margin_x": "Horizontal margin (pt)",
    "margin_y_footer": "Footer lift (pt, larger = higher on page)",
    "btn_add": "Add page numbers and download",
    "msg_select_pdf": "Choose a PDF first.",
    "msg_pick_pages": "Select pages for numbering.",
    "msg_done": "Download finished.",
    "err_failed": "Failed",
    "download_name": "page-numbers.pdf"
  },
  "pdf_reverse": {
    "drop_label": "Choose PDF",
    "drop_desc": "Reverse the entire page order; content unchanged.",
    "empty_pdf": "No PDF selected yet.",
    "btn_reverse": "Reverse order and download",
    "msg_select_pdf": "Choose a PDF first.",
    "msg_done": "Download ready.",
    "err_failed": "Processing failed",
    "download_suffix": "-reversed",
    "page_intro": "Useful when binding or reading order needs the entire PDF flipped end-to-end; implemented via <pdflib>pdf-lib</pdflib> page copying without re-rendering vector contents."
  },
  "pdf_rotate": {
    "drop_label": "Choose PDF",
    "drop_desc": "Pick thumbnails, then add relative rotation per selected page; processed locally.",
    "empty_pdf": "No PDF selected yet.",
    "angle_label": "Rotation to apply (relative)",
    "btn_rotate": "Apply rotation",
    "msg_select_pdf": "Choose a PDF first.",
    "msg_pick_page": "Select at least one page.",
    "msg_rotate_done": "Rotation complete. You can download now.",
    "msg_download_done": "Download started.",
    "err_failed": "Rotate failed",
    "thumb_title": "Pages to rotate",
    "thumb_preview_hint": "Previews are thumbnails only; export quality is unaffected.",
    "download_name": "rotated.pdf"
  },
  "pdf_split": {
    "drop_label": "Choose PDF",
    "drop_desc": "Split into multiple PDFs by every page or fixed chunk size (ZIP download).",
    "empty_pdf": "No PDF selected yet.",
    "legend_mode": "Split mode",
    "mode_each": "One file per page",
    "mode_chunk": "Fixed page groups",
    "chunk_size_label": "Pages per group",
    "hint_each": "Each page exports as its own PDF.",
    "hint_chunk": "Group export every {chunk} pages.",
    "btn_split": "Split and download ZIP",
    "msg_select_pdf": "Choose a PDF first.",
    "msg_done_zip": "ZIP generation started.",
    "err_failed": "Split failed",
    "thumb_preview_title": "Preview (browse only; split follows options above)"
  },
  "pdf_stamp": {
    "drop_pdf_label": "Choose PDF",
    "drop_pdf_desc": "Base document; pick pages to stamp.",
    "drop_stamp_label": "Stamp image (PNG recommended)",
    "drop_stamp_desc": "PNG or JPEG; transparent PNG usually looks best.",
    "empty_pdf": "No PDF selected yet.",
    "empty_stamp": "No stamp image yet.",
    "position_label": "Position",
    "scale_label": "Scale (relative to image width)",
    "margin_label": "Margin (pt)",
    "pos_center": "Center",
    "pos_br": "Bottom-right",
    "pos_bl": "Bottom-left",
    "pos_tr": "Top-right",
    "pos_tl": "Top-left",
    "btn_apply": "Stamp and download",
    "msg_need_both": "Select both a PDF and stamp image (PNG/JPG).",
    "msg_pick_pages": "Select pages to stamp.",
    "msg_done": "Download finished.",
    "err_failed": "Failed",
    "download_name": "stamped.pdf"
  },
  "pdf_to_images": {
    "hint_base": "Export as images. Sharpness follows scale: higher is clearer but slower and heavier on memory.",
    "hint_fallback": " Offscreen rendering not supported; some formats fall back to PNG.",
    "drop_label": "Choose PDF",
    "drop_desc": "Each page becomes an image; packaged as ZIP; local only.",
    "empty_pdf": "No PDF selected yet.",
    "scale_label": "Render scale (suggest 1.5 – 3)",
    "fmt_label": "Export format",
    "opt_png": "PNG (lossless)",
    "opt_jpeg": "JPG (smaller)",
    "opt_webp": "WebP (smaller)",
    "quality_label": "Quality (0.1 – 1.0)",
    "btn_export": "Export (ZIP)",
    "msg_select_pdf": "Choose a PDF first.",
    "progress_export": "Exporting page {current} / {total}…",
    "msg_zip_done": "ZIP packed; download started.",
    "err_failed": "Export failed",
    "err_cancelled": "Cancelled"
  },
  "pdf_watermark": {
    "intro": "Chinese text watermarks via OSS Source Han Sans subset. If font fetch fails, embedded fonts are used and Chinese may appear as boxes.",
    "drop_label": "Choose PDF",
    "drop_desc": "Add text watermark to chosen pages locally.",
    "empty_pdf": "No PDF selected yet.",
    "page_range_hint": "Tip: all / odd / even / 1,3-5",
    "label_text": "Watermark text",
    "label_color": "Color (#RRGGBB)",
    "label_font_size": "Font size",
    "label_opacity": "Opacity (0–1)",
    "label_angle": "Rotation (degrees)",
    "btn_generate": "Generate and download",
    "msg_select_pdf": "Choose a PDF first.",
    "msg_pick_pages": "Select pages to watermark.",
    "msg_done": "Download finished.",
    "err_failed": "Failed",
    "download_name": "watermarked.pdf"
  },
  "json_format": {
    "indent_label": "Indent",
    "indent_2": "2 spaces",
    "indent_4": "4 spaces",
    "indent_tab": "Tab",
    "font_size_label": "Font size",
    "valid_ok": "✓ Valid",
    "valid_bad": "✗ Invalid",
    "btn_escape": "Escape / Unescape",
    "btn_json_xml": "JSON ↔ XML",
    "btn_fold": "Fold / Unfold",
    "hdr_src": "Source",
    "hdr_result": "Result (editable)",
    "ph_src": "Paste or enter JSON here…",
    "ph_result": "Formatted JSON appears here…",
    "flash_unescape_fmt_ok": "Unescaped and formatted successfully",
    "flash_unescape_ok_maybe": "Unescaped (may not be valid JSON)",
    "flash_unescape_fail": "Unescape failed",
    "flash_escape_ok": "Escaped successfully",
    "flash_escape_ok_maybe": "Escaped successfully (source may not be valid JSON)",
    "flash_escape_fail": "Escape failed",
    "flash_please_data": "Please enter data first",
    "flash_xml_bad": "Conversion failed: invalid XML",
    "flash_json_bad": "Conversion failed: invalid JSON",
    "hint_xml_done": "Converted to XML",
    "hint_json_done": "Converted to JSON",
    "flash_need_json_src": "Please enter JSON in source panel first",
    "flash_need_valid_json": "Please format or enter valid JSON first",
    "hint_all_fold": "All folded",
    "hint_all_unfold": "All unfolded",
    "flash_result_empty": "Result is empty",
    "flash_clipboard_ok": "Copied to clipboard",
    "flash_no_download": "Nothing to download",
    "confirm_plain_download": "Content is not valid JSON. Download anyway?",
    "suffix_json_invalid": "Invalid JSON",
    "btn_copy_result": "Copy result"
  },
  "og_preview": {
    "mock_card_title": "Simulated card (not a real crawler preview)",
    "tag_snippet_title": "Meta snippet",
    "demo_title": "Tools Ku | Example",
    "demo_desc": "Example description for a locally simulated share card."
  },
  "robots": {
    "chk_allow_site": "Allow: / (allow entire site crawls)",
    "lbl_disallow_paths": "Disallow paths (one per line)",
    "lbl_sitemap_urls": "Sitemap URLs (one per line)",
    "hdr_preview": "robots.txt"
  },
  "sitemap": {
    "lbl_site_root": "Site root URL",
    "lbl_paths": "Paths or full URLs (one per line)",
    "hdr_preview": "sitemap.xml"
  },
  "csp": {
    "opt_default": "default-src 'self'",
    "opt_script": "script-src 'self'",
    "opt_unsafe_inline": "Allow inline scripts (weaker)",
    "opt_style": "style-src 'self' 'unsafe-inline'",
    "opt_img": "img-src * data:",
    "opt_font": "font-src 'self'",
    "opt_connect": "connect-src 'self'",
    "opt_frame": "frame-ancestors 'none'",
    "opt_base": "base-uri 'self'",
    "opt_form": "form-action 'self'",
    "opt_upgrade": "upgrade-insecure-requests",
    "lbl_extra_directives": "Extra directives (one per line; joined with semicolons)",
    "hdr_preview": "Content-Security-Policy",
    "placeholder_extra": "report-uri https://..."
  },
  "permissions_policy": {
    "lbl_extra": "Extra entries (comma-separated)",
    "hdr_preview": "Permissions-Policy",
    "placeholder_extra": "interest-cohort=()"
  },
  "env_parse": {
    "chk_mask": "Mask values (display only; source text unchanged)",
    "lbl_raw": ".env content",
    "th_key": "Key",
    "th_value": "Value",
    "empty_rows": "No key=value rows"
  },
  "http_headers": {
    "intro": "Common security response header examples; configure one stack (Nginx / CDN / framework).",
    "hsts_title": "HSTS",
    "hsts_desc": "Force HTTPS (one-year max-age)",
    "xcto_title": "X-Content-Type-Options",
    "xcto_desc": "Disable MIME sniffing",
    "xfo_title": "X-Frame-Options",
    "xfo_desc": "Deny embedding (same as DENY)",
    "ref_title": "Referrer-Policy",
    "ref_desc": "Tighten Referer",
    "pp_title": "Permissions-Policy (sample)",
    "pp_desc": "Disable some sensitive APIs"
  },
  "graphql_format": {
    "lbl_input": "GraphQL",
    "syntax_error": "Syntax error"
  },
  "openapi_view": {
    "lbl_input": "OpenAPI (JSON)",
    "err_invalid_json": "Could not parse JSON",
    "root_label": "root"
  },
  "properties_json": {
    "lbl_properties": ".properties",
    "lbl_json": "JSON (string values → properties)",
    "btn_to_json": "→ JSON",
    "btn_to_properties": "→ Properties",
    "footnote_flat": "Nested objects are not flattened; only flat string maps.",
    "err_failed": "Failed"
  },
  "xml_format": {
    "lbl_xml": "XML",
    "btn_validate_indent": "Validate & indent",
    "err_parse_failed": "XML parse failed",
    "err_failed": "Failed"
  },
  "semver": {
    "lbl_a": "Version A",
    "lbl_b": "Version B",
    "btn_compare": "Compare",
    "invalid": "invalid",
    "err_parse_line": "Parse failed: A={a}  B={b}",
    "cmp_before": "A is before B",
    "cmp_after": "A is after B",
    "cmp_equal": "Equal",
    "line_norm": "Normalized: A={a}  B={b}",
    "line_cmp": "Compare: {rel}",
    "line_diff": "semver.diff: {diff}",
    "diff_same": "diff: (same version)"
  },
  "mermaid": {
    "lbl_source": "Mermaid source",
    "btn_render": "Render",
    "btn_rendering": "Rendering…",
    "err_render": "Render failed"
  },
  "editorconfig": {
    "preset_web": "Web default (2 spaces)",
    "preset_py": "Python (4 spaces)",
    "preset_go": "Go (Tab)"
  },
  "image_compress": {
    "intro_note": "Image compression runs locally in your browser; nothing is uploaded. Dimensions match the source: PNG lossless repack via Oxipng (WASM) when unchanged size/no scaling—often smaller than re-encoding on canvas; JPG/WebP still re-encoded by quality. If output is not smaller for the same format, the original is kept. Default follows each source format, or pick a unified format below.",
    "drop_desc": "Choose format and quality, then click Start compress to batch export (same width/height as source).",
    "fmt_auto": "Same as source",
    "fmt_jpeg": "Unify as JPG",
    "fmt_webp": "Unify as WebP",
    "fmt_png": "Unify as PNG"
  },
  "image_exif": {
    "intro_note": "Viewing/stripping happens locally. Stripping re-exports the image (more universal) and may change size/format.",
    "drop_desc": "Parse EXIF locally; files are not uploaded.",
    "empty_hint": "No image selected.",
    "lbl_export_after_strip": "Format after strip",
    "opt_jpeg_rec": "JPG (recommended)",
    "opt_png": "PNG",
    "opt_webp": "WebP",
    "btn_strip": "Strip EXIF & download",
    "details_raw": "Raw EXIF JSON",
    "msg_no_exif": "No EXIF detected (or format has none).",
    "msg_read_fail": "Read failed",
    "msg_exported_clean": "Exported metadata-free version.",
    "msg_strip_fail": "Processing failed"
  },
  "image_crop": {
    "intro_note": "Drag on the preview to select the crop box, or enter pixels below. Processing is local.",
    "drop_desc": "Single image crop; export PNG / JPG / WebP.",
    "empty_hint": "No image selected.",
    "hint_canvas": "Source {w}×{h} px — drag on the image to select",
    "lbl_left_x": "Left X",
    "lbl_top_y": "Top Y",
    "lbl_width": "Width",
    "lbl_height": "Height",
    "btn_reset_full": "Reset to full image",
    "lbl_quality_short": "Quality",
    "btn_export": "Export crop",
    "msg_pick_area": "Please select an image and a crop area.",
    "msg_exported": "Crop exported.",
    "msg_export_fail": "Export failed"
  },
  "image_resize": {
    "intro_note": "Resize runs locally. contain = fit inside with padding; cover = fill and crop.",
    "drop_desc": "Set size and format below, then click Start processing to batch export."
  },
  "image_scale": {
    "intro_note": "Proportional scaling by long edge, fixed width, or fixed height; aspect ratio preserved. Long-edge mode keeps originals smaller than the target; width/height modes may upscale. Local processing.",
    "drop_desc": "Set scale mode and target pixels, then batch export.",
    "lbl_scale_by": "Scale by",
    "mode_long_edge": "Long edge (shrink only to limit)",
    "mode_width": "Width (fixed width, proportional height)",
    "mode_height": "Height (fixed height, proportional width)",
    "dim_long_edge": "Long edge limit (px)",
    "dim_width": "Target width (px)",
    "dim_height": "Target height (px)",
    "lbl_quality_01": "Quality (0.1–1)"
  },
  "image_transform": {
    "intro_note": "Canvas + CSS filters (grayscale/invert) locally; JPEG export composites transparency onto white.",
    "drop_desc": "Common raster formats; set transforms then batch export.",
    "lbl_rotate": "Rotate",
    "rot_0": "None",
    "rot_90": "90° clockwise",
    "rot_180": "180°",
    "rot_270": "270° clockwise",
    "lbl_export_fmt": "Export format",
    "lbl_quality_short": "Quality",
    "flip_h": "Flip horizontal",
    "flip_v": "Flip vertical",
    "filter_gray": "Grayscale",
    "filter_invert": "Invert",
    "msg_need_transform": "Pick at least one transform (rotate, flip, or filter).",
    "msg_summary": "Done: {ok}/{total} succeeded.",
    "btn_zip": "Download ZIP bundle"
  },
  "image_watermark": {
    "intro_note": "Watermarks are rendered locally; nothing is uploaded.",
    "drop_desc": "Set text watermark, then batch export.",
    "lbl_text": "Watermark text",
    "lbl_position": "Position",
    "pos_tl": "Top-left",
    "pos_tr": "Top-right",
    "pos_bl": "Bottom-left",
    "pos_br": "Bottom-right",
    "pos_center": "Center",
    "lbl_color": "Color",
    "lbl_font_size": "Font size",
    "lbl_opacity": "Opacity (0–1)",
    "lbl_padding": "Padding (px)",
    "msg_empty_text": "Watermark text cannot be empty."
  },
  "image_collage": {
    "intro_note": "Stitching runs locally; avoid too many images (very tall/wide output).",
    "drop_label": "Select images (order = stitch order)",
    "drop_desc": "Multi-select supported; list order is stitch order—remove items to adjust.",
    "empty_hint": "No images yet. Order here defines stitch order.",
    "lbl_direction": "Direction",
    "dir_vertical": "Vertical (long strip)",
    "dir_horizontal": "Horizontal",
    "lbl_gap": "Gap (px)",
    "msg_started": "Download started."
  },
  "image_convert": {
    "page_intro": "Common raster formats (including <fmt>PNG, JPEG, WebP, GIF, BMP, ICO, AVIF</fmt>, depending on browser decoding) and <svg>SVG</svg> convert locally. Animated GIF exports first frame only; transparent areas fill white when exporting JPEG; HEIC and similar formats often cannot be decoded in-browser.",
    "common_uses_title": "Common uses",
    "common_use_li1": "Unify web assets to WebP or PNG; print/archive workflows to JPEG.",
    "common_use_li2": "Rasterize SVG to bitmap for raster-only downstream tools."
  },
  "image_convert_to_png": {
    "page_intro": "Export common image formats to PNG locally on your device—nothing leaves your machine. Useful when you need a PNG-only workflow or downstream accepts PNG only. Animated images export the first frame.",
    "common_notes_title": "Notes",
    "common_notes_li1": "HEIC and some vendor formats may not decode in the browser—convert to JPG in your OS first.",
    "common_notes_li2": "Very large images use more memory; if conversion fails, resize or split.",
    "drop_subline": "Multi-format input; output is always PNG."
  },
  "image_gif_to_png": {
    "drop_subline": "GIF-focused; exports single-frame PNG."
  },
  "image_jpg_to_png": {
    "page_intro": "<jpeg>JPEG</jpeg> is lossy; converting to PNG cannot recover discarded detail, but it stops further lossy compression—handy when your editing pipeline or batch jobs standardize on PNG. Multi-select and drag-and-drop supported.",
    "notes_title": "Notes",
    "notes_body": "Typical JPEG photos are opaque; after PNG conversion they usually stay fully opaque unless the source already had transparency (uncommon).",
    "drop_subline": "JPG/JPEG-focused; other rasters allowed. Output is PNG."
  },
  "image_jpg_to_webp": {
    "drop_subline": "JPG/JPEG-focused; other rasters to WebP also supported."
  },
  "image_png_to_jpg": {
    "drop_subline": "PNG-focused; other rasters to JPG also supported."
  },
  "image_png_to_webp": {
    "drop_subline": "PNG-focused; other rasters to WebP also supported."
  },
  "image_svg_to_png": {
    "drop_subline": "Pick .svg files; output is PNG."
  },
  "image_webp_to_jpg": {
    "drop_subline": "WebP-focused; other rasters to JPG also supported."
  },
  "image_webp_to_png": {
    "page_intro": "Many sites ship smaller <webp>WebP</webp> assets; when your target toolchain only accepts PNG, batch-convert locally here before importing elsewhere. Multi-file selection supported.",
    "tips_title": "Tip",
    "tips_body": "Lossy, lossless, and transparent WebP all rasterize in the browser before saving as PNG—similar to exporting from desktop graphics apps in most cases.",
    "drop_subline": "WebP-focused; other rasters OK; output is always PNG."
  },
  "image_ico": {
    "intro_note": "Build favicon.ico from one image locally: pick a square size and download (PNG inside ICO for modern browsers & Windows).",
    "drop_desc": "Pick size, then download favicon.ico.",
    "pick_label": "Select image (512×512 or larger recommended)",
    "empty_hint": "No image selected.",
    "lbl_side": "Output side (square)",
    "hint_one_size": "ICO contains only the selected size.",
    "err_pick_first": "Please select an image first.",
    "err_canvas": "Could not create canvas context",
    "msg_download_started": "Started downloading favicon.ico.",
    "msg_generate_fail": "Generation failed",
    "page_intro": "Pick one large image (512×512 or larger recommended), choose output edge length, then download <favicon>favicon.ico</favicon>."
  },
  "image_ocr": {
    "intro_note": "Tesseract worker, core, and language packs load from CDN (first run slower). Images stay in your browser.",
    "lbl_langs": "Languages (Tesseract codes, e.g. eng, chi_sim, eng+chi_sim)",
    "lbl_image": "Image",
    "hdr_result": "Recognized text",
    "prog_initializing": "Initializing…",
    "prog_recognizing": "Recognizing {pct}%",
    "empty_result": "(No text recognized)",
    "err_failed": "Recognition failed"
  },
  "bcrypt": {
    "text_label": "Text",
    "rounds_label": "Rounds (4-31)",
    "generate": "Generate Hash",
    "copy": "Copy",
    "verify_hash_label": "Hash to Verify",
    "verify": "Verify",
    "match": "Match",
    "not_match": "Not Match"
  },
  "sm3": {
    "text_label": "Input Text",
    "compute": "Compute",
    "copy": "Copy"
  },
  "sm4": {
    "key_label": "Key (32 hex chars)",
    "text_label": "Input Text",
    "encrypt": "Encrypt",
    "decrypt": "Decrypt",
    "process": "Process",
    "copy": "Copy",
    "error": "Error"
  },
  "sm2": {
    "generate_keypair": "Generate Key Pair",
    "public_key": "Public Key",
    "private_key": "Private Key",
    "text_label": "Input Text",
    "encrypt": "Encrypt",
    "decrypt": "Decrypt",
    "copy": "Copy",
    "error": "Error"
  },
  "password_strength": {
    "password_label": "Password",
    "level_0": "Weak",
    "level_1": "Fair",
    "level_2": "Strong",
    "level_3": "Very Strong",
    "length": "Length",
    "crack_time": "Crack Time",
    "lower": "Lower",
    "upper": "Upper",
    "digit": "Digit",
    "special": "Special"
  },
  "wifi_qr": {
    "ssid": "SSID",
    "password": "Password",
    "encryption": "Encryption",
    "none": "None",
    "generate": "Generate QR"
  },
  "json_to_go": {
    "struct_name": "Struct Name",
    "json_label": "Input JSON",
    "convert": "Convert",
    "copy": "Copy",
    "parse_error": "JSON parse error"
  },
  "json_to_java": {
    "class_name": "Class Name",
    "json_label": "Input JSON",
    "convert": "Convert",
    "copy": "Copy",
    "parse_error": "JSON parse error"
  },
  "json_to_sql": {
    "table_name": "Table Name",
    "json_label": "Input JSON Array",
    "convert": "Convert",
    "copy": "Copy",
    "parse_error": "JSON parse error",
    "not_array": "Input is not a JSON array"
  },
  "json_merge": {
    "json_a": "JSON A",
    "json_b": "JSON B",
    "merge": "Merge",
    "copy": "Copy",
    "parse_error": "JSON parse error"
  },
  "nginx_format": {
    "input_label": "Input Nginx Config",
    "format": "Format",
    "copy": "Copy"
  },
  "docker_to_compose": {
    "cmd_label": "Input docker run Command",
    "convert": "Convert",
    "copy": "Copy"
  },
  "regex_cheatsheet": {
    "copy": "Copy",
    "copied": "Copied"
  },
  "faker": {
    "generate": "Generate Fake Data"
  },
  "deobfuscate": {
    "input_label": "Input JS Code",
    "format": "Format",
    "copy": "Copy"
  },
  "text_pinyin": {
    "input_label": "Input Chinese",
    "copy": "Copy"
  },
  "text_zh_convert": {
    "s2t": "Simp→Trad",
    "t2s": "Trad→Simp",
    "input_label": "Input Text",
    "copy": "Copy"
  },
  "text_mask": {
    "input_label": "Input Text",
    "keep_first": "Keep First N",
    "keep_last": "Keep Last N",
    "mask_char": "Mask Char",
    "copy": "Copy"
  },
  "text_emoji": {
    "search_placeholder": "Search Emoji…",
    "copied": "Copied"
  },
  "text_synonym": {
    "input_label": "Input Word",
    "synonyms": "Synonyms",
    "antonyms": "Antonyms",
    "not_found": "Not found in dictionary"
  },
  "totp": {
    "secret_label": "Secret (Base32)",
    "remaining": "{sec}s remaining"
  },
  "basic_auth": {
    "username": "Username",
    "password": "Password",
    "copy": "Copy"
  },
  "cookie_parse": {
    "input_label": "Input Cookie String",
    "key": "Key",
    "value": "Value"
  },
  "jwt_generate": {
    "header": "Header (JSON)",
    "payload": "Payload (JSON)",
    "secret": "Secret",
    "generate": "Generate JWT",
    "copy": "Copy",
    "error": "Generation failed"
  },
  "svg_placeholder": {
    "width": "Width",
    "height": "Height",
    "text": "Text",
    "fg": "Foreground",
    "bg": "Background",
    "copy_svg": "Copy SVG",
    "copy_data_url": "Copy Data URL"
  },
  "stopwatch": {
    "start": "Start",
    "pause": "Pause",
    "resume": "Resume",
    "lap": "Lap",
    "reset": "Reset",
    "lap_n": "Lap {n}"
  },
  "date_calc": {
    "add_days": "Add/Subtract Days",
    "date_diff": "Date Difference",
    "date1": "Date",
    "date2": "Date 2",
    "days": "Days",
    "calc": "Calculate"
  },
  "percentage": {
    "mode_of": "X% of Y",
    "mode_is": "X is what % of Y",
    "mode_change": "Change Rate",
    "percent": "Percent",
    "of_value": "Value",
    "value": "Value",
    "total": "Total",
    "from": "From",
    "to": "To"
  },
  "temperature": {
    "value": "Temperature"
  },
  "roman_numeral": {
    "to_roman": "→ Roman",
    "from_roman": "→ Arabic",
    "arabic": "Arabic",
    "roman": "Roman"
  },
  "image_greyscale": {
    "process": "To Greyscale",
    "download": "Download"
  },
  "image_nine_grid": {
    "process": "Nine Grid Crop"
  },
  "mac_lookup": {
    "input_label": "Input MAC Address",
    "not_found": "Vendor not found"
  },
  "ipv4_range": {
    "start": "Start IP",
    "end": "End IP"
  },
  "port_reference": {
    "port": "Port",
    "proto": "Protocol",
    "name": "Name"
  },
  "math_eval": {
    "placeholder": "Enter expression, e.g. 2^10 + sqrt(16)",
    "calc": "Calculate",
    "preview": "Preview",
    "supported": "Supported operations",
    "history": "History",
    "clear": "Clear"
  },
  "eta_calc": {
    "total": "Total",
    "done": "Done",
    "elapsed": "Elapsed",
    "elapsed_unit": "seconds",
    "speed": "Speed",
    "speed_unit": "/s",
    "remaining": "ETA",
    "total_time": "Total Est."
  },
  "mac_gen": {
    "count": "Count",
    "separator": "Separator",
    "prefix": "Prefix (optional)",
    "uppercase": "Uppercase",
    "generate": "Generate",
    "results": "Results",
    "copy_all": "Copy All"
  },
  "device_info": {
    "note": "Detect current browser environment information.",
    "property": "Property",
    "value": "Value"
  },
  "bip39": {
    "strength": "Entropy Bits",
    "generate": "Generate",
    "loading": "Loading…",
    "mnemonic": "Mnemonic",
    "copy": "Copy",
    "error": "Generation failed"
  },
  "rsa_keygen": {
    "key_size": "Key Size",
    "generate": "Generate Key Pair",
    "generating": "Generating…",
    "public_key": "Public Key (PEM)",
    "private_key": "Private Key (PEM)",
    "copy": "Copy"
  },
  "xml_json": {
    "input": "Input",
    "output": "Output",
    "convert": "Convert",
    "copy": "Copy"
  },
  "json_minify": {
    "input": "Input JSON",
    "minify": "Minify",
    "output": "Output",
    "copy": "Copy",
    "original": "Original",
    "minified_size": "Minified",
    "saved": "Saved"
  },
  "numeronym": {
    "encode": "Encode",
    "decode": "Decode",
    "examples": "Common Examples"
  },
  "ascii_art": {
    "text": "Text",
    "char_set": "Fill Character",
    "result": "Result",
    "copy": "Copy",
    "hint": "Supports English letters, digits, and some punctuation, up to 30 characters."
  },
  "idcard": {
    "input_label": "Input ID Card Number",
    "valid": "Valid",
    "invalid": "Invalid",
    "province": "Province",
    "birthday": "Birthday",
    "gender": "Gender",
    "male": "Male",
    "female": "Female",
    "unknown": "Unknown"
  },
  "chinese_colors": {
    "copied": "Copied"
  },
  "relationship": {
    "input_label": "Input relationship chain (e.g., father,mother)",
    "placeholder": "father,mother",
    "unknown": "Unknown"
  },
  "curl_to_code": {
    "input_label": "cURL Command",
    "lang_label": "Target Language",
    "convert": "Convert",
    "output": "Output Code",
    "copy": "Copy",
    "copied": "Copied",
    "err_parse": "Could not parse cURL command"
  },
  "box_shadow": {
    "layer": "Layer",
    "remove": "Remove",
    "offsetX": "Offset X",
    "offsetY": "Offset Y",
    "blur": "Blur",
    "spread": "Spread",
    "color": "Color",
    "add_layer": "Add Layer",
    "preview": "Preview",
    "copy": "Copy",
    "copied": "Copied"
  },
  "border_radius": {
    "top_left": "Top Left",
    "top_right": "Top Right",
    "bottom_right": "Bottom Right",
    "bottom_left": "Bottom Left",
    "preview": "Preview",
    "copy": "Copy",
    "copied": "Copied"
  },
  "flexbox": {
    "direction": "flex-direction",
    "justify_content": "justify-content",
    "align_items": "align-items",
    "flex_wrap": "flex-wrap",
    "gap": "gap",
    "add_child": "Add Child",
    "remove_child": "Remove Child",
    "preview": "Preview",
    "copy": "Copy",
    "copied": "Copied"
  },
  "gradient": {
    "type": "Type",
    "angle": "Angle",
    "color_stops": "Color Stops",
    "remove": "Remove",
    "add_stop": "Add Stop",
    "preview": "Preview",
    "copy": "Copy",
    "copied": "Copied"
  },
  "css_animation": {
    "preset": "Preset",
    "duration": "Duration(s)",
    "timing": "Timing",
    "iteration": "Iteration",
    "keyframes": "Keyframes",
    "preview": "Preview",
    "copy": "Copy",
    "copied": "Copied"
  },
  "color_blindness": {
    "input_color": "Input Color",
    "original": "Original",
    "palette": "Palette Preview"
  },
  "token_count": {
    "input_label": "Input Text",
    "placeholder": "Enter text to estimate token count…",
    "chars": "chars",
    "words": "words",
    "lines": "lines",
    "estimate": "Token Estimate",
    "tokens": "tokens",
    "of_context": "of context",
    "disclaimer": "※ Approximate estimate. Actual count depends on the specific tokenizer. CJK ~1.5 token/char, English ~1.0-1.3 token/word."
  },
  "screenshot_beautify": {
    "upload": "Upload Screenshot",
    "bg_color": "Background",
    "padding": "Padding",
    "border_radius": "Border Radius",
    "shadow_blur": "Shadow Blur",
    "shadow_color": "Shadow Color",
    "preview": "Preview",
    "no_image": "Please upload a screenshot first",
    "export_png": "Export PNG"
  },
  "pangu_spacing": {
    "input_label": "Input Text",
    "placeholder": "Hello世界，这是123test文本",
    "output": "Result",
    "copy": "Copy",
    "copied": "Copied"
  },
  "aspect_ratio": {
    "width": "Width",
    "height": "Height",
    "calc_ratio": "Calculate Ratio",
    "common_ratios": "Common Ratios",
    "reverse_calc": "Reverse Calculate",
    "ratio_w": "Ratio W",
    "ratio_h": "Ratio H",
    "known_side": "Known Side",
    "known_value": "Known Value",
    "result": "Result"
  },
  "loan_calc": {
    "principal": "Principal Amount",
    "annual_rate": "Annual Rate (%)",
    "term": "Loan term (years)",
    "term_half_year": "6 months ({months} periods)",
    "term_years": "{years, plural, one {1 year} other {# years}} ({months} periods)",
    "method": "Method",
    "equal_installment": "Equal Installment",
    "equal_principal": "Equal Principal",
    "monthly_payment": "Monthly Payment",
    "total_interest": "Total Interest",
    "total_payment": "Total Payment",
    "schedule": "Payment Schedule",
    "month": "Month",
    "payment": "Payment",
    "principal_part": "Principal",
    "interest_part": "Interest",
    "remaining": "Remaining"
  },
  "bmi": {
    "height": "Height",
    "weight": "Weight",
    "underweight": "Underweight",
    "normal": "Normal",
    "overweight": "Overweight",
    "obese": "Obese",
    "range_chart": "BMI Range Chart"
  },
  "work_hours": {
    "start_time": "Start Time",
    "end_time": "End Time",
    "lunch_break": "Lunch Break",
    "minutes": "minutes",
    "standard_hours": "Standard Hours",
    "total_time": "Total Time",
    "work_time": "Work Time",
    "overtime": "Overtime",
    "salary_estimate": "Salary Estimate",
    "hourly_rate": "Hourly Rate",
    "regular_pay": "Regular Pay",
    "overtime_pay": "Overtime Pay",
    "total_pay": "Total Pay",
    "hour": "h",
    "minute": "min"
  },
  "template_filler": {
    "template_label": "Template Text",
    "template_placeholder": "Enter template, e.g.: Hello, '{' '{' 'name' '}' '}'!",
    "variables": "Variables",
    "fill_data": "Fill Data",
    "add_row": "Add Row",
    "row": "Row",
    "remove_row": "Remove",
    "result": "Result",
    "copy": "Copy",
    "copied": "Copied"
  },
  "url_defang": {
    "defang": "Defang",
    "refang": "Refang",
    "input_label": "Input URL",
    "output": "Output",
    "copy": "Copy",
    "copied": "Copied",
    "rules": "Rules",
    "rule1": ":// → [://]",
    "rule2": ". → [.]",
    "rule3": "Refang is the reverse operation"
  },
  "protobuf_decode": {
    "decode": "Decode",
    "invalid_hex": "Invalid hex input",
    "result": "Result",
    "field": "Field",
    "wire_type": "Wire Type",
    "value": "Value",
    "unknown_wire": "Unknown wire type"
  },
  "pdf_signature": {
    "upload": "Upload PDF",
    "checking": "Checking…",
    "signed": "Signed",
    "not_signed": "Not Signed",
    "file": "File",
    "pages": "Pages",
    "parse_error": "PDF parse error"
  },
  "dev_string_obfuscator": {
    "input_label": "Input Code",
    "input_placeholder": "Paste JavaScript code with string literals…",
    "method_label": "Obfuscation Method",
    "method_base64": "Base64",
    "method_hex": "Hex",
    "method_unicode": "Unicode",
    "method_charcode": "CharCode",
    "method_reverse": "Reverse",
    "obfuscate": "Obfuscate",
    "output": "Obfuscated Result",
    "copy": "Copy",
    "copied": "Copied"
  },
  "web_safelink_decode": {
    "input_label": "Input SafeLink URL",
    "input_placeholder": "Paste Outlook SafeLink URL…",
    "decode": "Decode",
    "original_url": "Original URL",
    "copy": "Copy",
    "copied": "Copied",
    "err_not_safelink": "Not a valid Outlook SafeLink",
    "err_no_url_param": "Missing `url` query parameter in SafeLink",
    "err_invalid_url": "Could not parse the URL"
  },
  "dev_git_cheatsheet": {
    "category_basic": "Basic Operations",
    "category_branch": "Branch Management",
    "category_remote": "Remote Repository",
    "category_undo": "Undo & Rollback",
    "category_stash": "Stash",
    "category_log": "Log & History",
    "copy": "Copy",
    "copied": "Copied",
    "click_copy": "Click to copy"
  },
  "email_normalizer": {
    "input_label": "Input Email Addresses",
    "input_placeholder": "One email address per line…",
    "normalize": "Normalize",
    "output": "Normalized Result",
    "copy": "Copy",
    "copied": "Copied",
    "col_original": "Original",
    "col_normalized": "Normalized",
    "remove_dots": "Remove Gmail dots",
    "remove_plus": "Remove +aliases",
    "lowercase": "Convert to lowercase"
  },
  "html_wysiwyg": {
    "bold": "Bold",
    "italic": "Italic",
    "underline": "Underline",
    "strikethrough": "Strikethrough",
    "ordered_list": "Ordered List",
    "unordered_list": "Unordered List",
    "mode_edit": "Visual",
    "source_view": "Source View",
    "preview": "Preview",
    "copy_html": "Copy HTML",
    "copied": "Copied",
    "prompt_url": "Link URL",
    "prompt_img_url": "Image URL"
  },
  "dev_benchmark": {
    "add_snippet": "Add Code Snippet",
    "snippet_label": "Snippet {n}",
    "iterations_label": "Iterations",
    "run": "Run Benchmark",
    "running": "Running…",
    "result": "Result",
    "avg_time": "Avg Time",
    "rank": "Rank",
    "copy": "Copy",
    "placeholder_name": "Snippet name",
    "placeholder_code": "JavaScript code to benchmark…",
    "err_run": "Benchmark run failed",
    "col_snippet": "Snippet",
    "col_bar": "Relative"
  },
  "dev_css_unit_converter": {
    "context_title": "Px reference",
    "input_title": "Input",
    "value_label": "Value",
    "from_unit": "From Unit",
    "results_title": "Conversions",
    "col_unit": "Unit",
    "col_value": "Value",
    "base_size_label": "Base Font Size (px)",
    "viewport_width": "Viewport Width (px)",
    "viewport_height": "Viewport Height (px)",
    "result": "Conversion Result",
    "copy": "Copy",
    "copied": "Copied"
  },
  "random_port": {
    "count_label": "Count",
    "min_label": "Min Port",
    "max_label": "Max Port",
    "exclude_system": "Exclude system ports (0–1023)",
    "generate": "Generate",
    "copy": "Copy",
    "copied": "Copied",
    "output": "Result",
    "click_copy": "Click to copy"
  },
  "ipv6_ula": {
    "mac_label": "MAC Address (optional)",
    "mac_placeholder": "e.g. aa:bb:cc:dd:ee:ff",
    "generate": "Generate ULA",
    "prefix": "ULA Prefix",
    "copy": "Copy",
    "copied": "Copied"
  },
  "ipv4_converter": {
    "input_label": "Input IPv4 Address",
    "input_placeholder": "e.g. 192.168.1.1",
    "dotted_decimal": "Dotted Decimal",
    "decimal": "Decimal Integer",
    "hexadecimal": "Hexadecimal",
    "binary": "Binary",
    "octal": "Octal",
    "copy": "Copy",
    "copied": "Copied",
    "err_invalid": "Invalid IPv4 address"
  },
  "web_meta_tag_generator": {
    "general": "Basic meta",
    "title_label": "Title",
    "description_label": "Description",
    "viewport_label": "Viewport",
    "charset_label": "Charset",
    "author_label": "Author",
    "keywords_label": "Keywords",
    "robots_label": "Robots",
    "og_title": "OG Title",
    "og_description": "OG Description",
    "og_image": "OG Image URL",
    "og_url": "OG URL",
    "twitter_card": "Twitter Card Type",
    "generate": "Generate",
    "output": "Meta Tag Code",
    "preview": "Preview",
    "copy": "Copy",
    "copied": "Copied"
  },
  "encode_unicode": {
    "input_label": "Input Text",
    "output_label": "Output",
    "encode": "Encode",
    "decode": "Decode",
    "format_label": "Format",
    "format_backslash_u": "\\uXXXX",
    "format_html_entity": "&#xXXXX;",
    "copy": "Copy",
    "copied": "Copied",
    "decode_failed": "Decode failed"
  },
  "encode_quoted_printable": {
    "input_label": "Input",
    "output_label": "Output",
    "line_len": "Max line length",
    "encode": "Encode",
    "decode": "Decode",
    "copy": "Copy",
    "copied": "Copied",
    "encode_failed": "Encode failed",
    "decode_failed": "Decode failed",
    "err_decode": "Quoted-Printable decode failed"
  },
  "encode_uuencode": {
    "input_label": "Input",
    "output_label": "Output",
    "encode": "UUEncode",
    "decode": "UUDecode",
    "filename_label": "Filename",
    "mode": "File mode (e.g. 644)",
    "copy": "Copy",
    "copied": "Copied",
    "encode_failed": "Encode failed",
    "decode_failed": "Decode failed",
    "err_decode": "UUDecode failed"
  },
  "encode_base85": {
    "input_label": "Input",
    "input_mode": "Input mode",
    "mode_text": "Text (UTF-8)",
    "mode_hex": "Hex bytes",
    "delimiters": "wrap with <~ ~>",
    "output_label": "Output",
    "encode": "Encode",
    "decode": "Decode",
    "copy": "Copy",
    "copied": "Copied",
    "invalid_hex": "Invalid hex input",
    "encode_failed": "Encode failed",
    "decode_failed": "Decode failed",
    "err_decode": "Base85 decode failed"
  },
  "camera_recorder": {
    "select_device": "Camera device",
    "default": "Default",
    "start_camera": "Start Camera",
    "stop_camera": "Stop Camera",
    "take_photo": "Take Photo",
    "start_record": "Start Recording",
    "stop_record": "Stop Recording",
    "pause": "Pause",
    "resume": "Resume",
    "recording": "Recording…",
    "paused": "Paused",
    "photo_result": "Photo",
    "video_result": "Video",
    "export_photo": "Export PNG",
    "export_video": "Export WebM",
    "no_camera": "Cannot access camera"
  },
  "docs_cheatsheet": {
    "title_label": "Cheatsheet Title",
    "add_category": "Add Category",
    "category_label": "Category Name",
    "content_label": "Content (Markdown)",
    "preview": "Preview",
    "export": "Export",
    "export_md": "Export Markdown",
    "export_html": "Export HTML",
    "remove": "Remove",
    "entry_title": "Entry title",
    "add_entry": "Add entry",
    "copy": "Copy",
    "copied": "Copied"
  },
  "text_regex_memo": {
    "category_chars": "Character Classes",
    "category_quantifiers": "Quantifiers",
    "category_anchors": "Anchors",
    "category_groups": "Groups & References",
    "category_lookaround": "Lookaround (lookahead / lookbehind)",
    "category_flags": "Flags",
    "copy": "Copy",
    "click_copy": "Click to copy",
    "copied": "Copied"
  },
  "dev_git_diff_viewer": {
    "input_label": "Paste Diff Output",
    "input_placeholder": "Paste git diff output text…",
    "parse": "Parse",
    "files_changed": "Files Changed",
    "additions": "Additions",
    "deletions": "Deletions",
    "changes": "Changes",
    "err_parse": "Could not parse diff output"
  },
  "web_url_query_editor": {
    "url_label": "Input URL",
    "url_placeholder": "https://example.com?key=value&foo=bar",
    "parse": "Parse",
    "url_encode": "URL-encode when building",
    "params": "Query parameters",
    "result": "Built URL",
    "key": "Key",
    "value": "Value",
    "add_param": "Add Parameter",
    "remove_param": "Remove",
    "preview": "Preview URL",
    "copy": "Copy",
    "copied": "Copied",
    "err_invalid_url": "Invalid URL"
  },
  "tax_calc": {
    "income_label": "Monthly Salary (CNY)",
    "social_label": "Social Insurance (monthly, CNY)",
    "special_label": "Special Deductions (monthly, CNY)",
    "calc": "Calculate",
    "taxable": "Monthly Taxable Income: ",
    "annual_taxable": "Annual Taxable Income: ",
    "rate": "Tax Rate: ",
    "monthly_tax": "Monthly Tax: ",
    "annual_tax": "Annual Tax: ",
    "after_tax": "After-Tax Salary: "
  },
  "coord_convert": {
    "lng_label": "Longitude (lng)",
    "lat_label": "Latitude (lat)",
    "from_label": "From",
    "to_label": "To",
    "convert": "Convert",
    "result_label": "Result",
    "copy": "Copy"
  },
  "sensitive_words": {
    "placeholder": "Paste official documents, press releases, notices, etc.",
    "check": "Strict check",
    "found_prefix": "Sensitive terms found ({count} types): ",
    "col_word": "Term",
    "col_count": "Count",
    "no_found": "No dictionary hits, but manual review is still required before publishing.",
    "bank_count": "Government strict dictionary: {count} terms",
    "mode_hint": "Evasion detection enabled: whitespace and zero-width characters removed; full-width normalized.",
    "disclaimer": "This tool does not replace confidentiality review or final human approval. No hits does not mean publishable.",
    "custom_dict_title": "Custom word list",
    "custom_dict_hint": "UTF-8 text, one term per line; lines starting with # are comments. Stored locally in your browser.",
    "upload_dict": "Upload dictionary (.txt)",
    "upload_txt": "Upload text to check (.txt)",
    "clear_custom": "Clear custom list",
    "custom_bank_count": "Custom {count}",
    "active_bank_count": "Active {count}",
    "source_file": "Source file",
    "highlight_title": "Highlighted preview",
    "col_position": "Positions",
    "dict_imported": "Imported {count} custom terms",
    "dict_cleared": "Custom list cleared",
    "err_dict_empty": "Dictionary file is empty or invalid",
    "err_dict_parse": "Failed to read dictionary file",
    "err_txt_read": "Failed to read text file"
  },
  "signature": {
    "color_label": "Stroke Color",
    "width_label": "Stroke Width",
    "export": "Export PNG",
    "clear": "Clear"
  },
  "subtitle_convert": {
    "from_fmt": "From Format",
    "to_fmt": "To Format",
    "input_placeholder": "Paste subtitle content…",
    "convert": "Convert",
    "output": "Output",
    "copy": "Copy"
  },
  "htpasswd": {
    "username_label": "Username",
    "password_label": "Password",
    "algorithm_label": "Algorithm",
    "add": "Add",
    "copy": "Copy All"
  },
  "gcd_lcm": {
    "input_label": "Numbers (comma separated)",
    "input_placeholder": "e.g. 12, 18, 24",
    "calc": "Calculate"
  },
  "periodic_table": {
    "atomic_number": "Atomic Number: ",
    "atomic_mass": "Atomic Mass: ",
    "category": "Category: "
  },
  "danmaku": {
    "text_label": "Danmaku Text",
    "color_label": "Color",
    "speed_label": "Speed",
    "send": "Send"
  },
  "teleprompter": {
    "placeholder": "Enter script content…",
    "speed_label": "Speed",
    "font_size_label": "Font Size",
    "mirror_label": "Mirror",
    "play": "Play",
    "stop": "Stop",
    "pause": "Pause"
  },
  "batch_rename": {
    "add_files": "Add Files",
    "prefix_label": "Prefix",
    "start_num_label": "Start Number",
    "pad_len_label": "Zero Padding",
    "ext_label": "Extension",
    "col_original": "Original",
    "col_renamed": "Renamed",
    "copy": "Copy List"
  },
  "bankcard_bin": {
    "card_label": "Card Number",
    "placeholder": "Enter at least 6 digits",
    "query": "Query",
    "bank_label": "Bank: ",
    "type_label": "Type: ",
    "not_found": "Bank info not found."
  },
  "gif_frames": {
    "hint": "Upload a GIF file to extract frames",
    "frame_count": "Frames: "
  },
  "code_screenshot": {
    "lang_label": "Language",
    "bg_label": "Background",
    "export": "Export PNG"
  },
  "grid_paper": {
    "type_label": "Grid Type",
    "type_tian": "Tian",
    "type_mi": "Mi",
    "type_fang": "Square",
    "type_dot": "Dot",
    "cell_size_label": "Cell Size (px)",
    "rows_label": "Rows",
    "cols_label": "Columns",
    "generate": "Generate",
    "export": "Export PNG"
  },
  "exchange_rate": {
    "amount_label": "Amount",
    "from_label": "From",
    "to_label": "To",
    "convert": "Convert",
    "disclaimer": "Rates are offline reference values only."
  },
  "hanzi_decompose": {
    "placeholder": "Enter Chinese characters…",
    "decompose": "Decompose",
    "unknown": "N/A"
  },
  "audio_editor": {
    "start_label": "Start (sec)",
    "end_label": "End (sec)",
    "duration": "Duration: ",
    "clip": "Clip & Export WAV"
  },
  "csr_generate": {
    "key_size": "Key Size",
    "generate": "Generate",
    "private_key": "Private Key"
  },
  "torrent_analyze": {
    "parse_error": "Parse failed. Please confirm it is a valid .torrent file.",
    "name_label": "Name: ",
    "total_size": "Total Size: ",
    "piece_length": "Piece Length: ",
    "info_hash": "Info Hash: ",
    "files_label": "Files: ",
    "trackers": "Trackers: ",
    "magnet_link": "Magnet Link: ",
    "copy": "Copy"
  },
  "pdf_encrypt": {
    "drop_label": "Choose PDF",
    "drop_desc": "Add an open password to an unencrypted PDF",
    "empty_pdf": "No PDF selected",
    "password_label": "Open password",
    "confirm_label": "Confirm password",
    "btn_encrypt": "Encrypt & download",
    "msg_select_first": "Please select a PDF file first.",
    "msg_password_required": "Please enter a password.",
    "msg_password_mismatch": "Passwords do not match.",
    "msg_done": "Encrypted PDF generated; download started.",
    "err_encrypted_or_invalid": "Cannot read this PDF (encrypted, corrupt, or unsupported). If it has a password, use PDF Decrypt first.",
    "err_failed": "Encryption failed. Try Chrome or Edge."
  },
  "heic_to_jpg": {
    "hint": "HEIC/HEIF is decoded to JPG in your browser; files are not uploaded.",
    "drop_label": "HEIC / HEIF images",
    "drop_desc": ".heic, .heif — multiple files OK",
    "empty": "No HEIC files selected",
    "quality_label": "JPG quality (0.5–1)",
    "btn_convert": "Convert to JPG",
    "msg_select": "Please select HEIC/HEIF images first.",
    "msg_done": "Done. Download started.",
    "err_convert": "Could not decode this HEIC file.",
    "err_failed": "Conversion failed. Try Chrome or Edge."
  },
  "word_count": {
    "hint": "Type or paste text to count locally—nothing is sent to a server."
  },
  "age_calc": {
    "birth_label": "Date of birth",
    "ref_label": "As of date (optional)",
    "ref_hint": "Leave empty to use today",
    "years": "Years",
    "months": "Months",
    "days": "Days",
    "total_days": "Total days",
    "err_invalid_birth": "Invalid birth date",
    "err_ref_before_birth": "Reference date cannot be before birth date"
  },
  "random_number": {
    "min": "Minimum",
    "max": "Maximum",
    "count": "Count (1–500)",
    "integer": "Integers only",
    "generate": "Generate",
    "copy": "Copy all",
    "output": "Results",
    "err_range": "For integers, min cannot be greater than max",
    "copied": "Copied to clipboard."
  },
  "caesar": {
    "input_text": "Input text",
    "shift": "Shift (1-25)",
    "mode": "Mode",
    "encrypt": "Encrypt",
    "decrypt": "Decrypt",
    "run": "Run",
    "result": "Result"
  },
  "des": {
    "input_text": "Input text / hex",
    "key": "Key (≥8 bytes)",
    "mode": "Mode",
    "action": "Action",
    "encrypt": "Encrypt",
    "decrypt": "Decrypt",
    "run": "Run",
    "result": "Result",
    "key_too_short": "Key must be at least 8 bytes",
    "invalid_hex": "Hex length not multiple of 16"
  },
  "ripemd": {
    "input_text": "Input text",
    "compute": "Compute",
    "result": "RIPEMD-160 Hash"
  },
  "bcc_lrc": {
    "input_hex": "Hex data (space-separated)",
    "mode": "Check mode",
    "compute": "Compute",
    "result": "Result",
    "invalid_hex": "Invalid hex byte",
    "no_data": "Please enter data"
  },
  "iso_garble": {
    "input": "Garbled text",
    "fix": "Fix",
    "result": "Fixed text",
    "not_iso": "Contains non-ISO-8859-1 characters",
    "decode_failed": "UTF-8 decode failed"
  },
  "emoji_encode": {
    "input": "Input text",
    "mode": "Encoding mode",
    "core_values": "Core Values",
    "action": "Action",
    "encode": "Encode",
    "decode": "Decode",
    "run": "Run",
    "result": "Result",
    "decode_failed": "Decode failed"
  },
  "code_playground": {
    "preview": "Preview"
  },
  "dir_tree": {
    "input": "Directory paths (one per line)",
    "generate": "Generate",
    "result": "Directory tree"
  },
  "kv_to_code": {
    "input": "Key-value pairs (key=value, one per line)",
    "language": "Target language",
    "convert": "Convert",
    "result": "Code"
  },
  "file_hash": {
    "algorithm": "Hash algorithm",
    "drop_here": "Drop file here",
    "browse": "Browse file"
  },
  "endianness": {
    "input_hex": "Input hex bytes",
    "from": "From endianness",
    "to": "To endianness",
    "convert": "Convert",
    "result": "Result"
  },
  "ones_complement": {
    "decimal": "Decimal integer",
    "bits": "Bit width",
    "compute": "Compute",
    "original": "Original",
    "ones": "Ones complement",
    "twos": "Twos complement"
  },
  "ssl_generate": {
    "key_type": "Key type",
    "generate": "Generate",
    "public_key": "Public Key",
    "private_key": "Private Key",
    "fingerprint": "SHA-256 Fingerprint"
  },
  "url_batch": {
    "template": "URL template ({id} or {param} placeholder)",
    "params": "Parameters (one per line)",
    "generate": "Generate",
    "result": "Result"
  },
  "line_filter": {
    "input": "Input text",
    "min_len": "Min length",
    "max_len": "Max length",
    "action": "Action",
    "filter": "Filter",
    "truncate": "Truncate",
    "pad": "Pad",
    "run": "Run",
    "result": "Result"
  },
  "tts": {
    "input": "Input text",
    "voice": "Voice",
    "rate": "Rate",
    "volume": "Volume",
    "play": "Play",
    "pause": "Pause",
    "stop": "Stop",
    "speaking": "Speaking..."
  },
  "whois": {
    "domain": "Domain",
    "query": "Query",
    "querying": "Querying...",
    "result": "Result"
  },
  "dns_query": {
    "domain": "Domain",
    "record_type": "Record type",
    "query": "Query",
    "querying": "Querying...",
    "result": "Result"
  },
  "icp_query": {
    "domain": "Domain",
    "query": "Query",
    "querying": "Querying...",
    "result": "Result",
    "api_error": "API request failed"
  },
  "my_ip": {
    "query": "Query My IP",
    "querying": "Querying..."
  },
  "browser_fingerprint": {
    "ua": "User-Agent",
    "language": "Language",
    "languages": "Languages",
    "platform": "Platform",
    "cookies": "Cookies",
    "do_not_track": "Do Not Track",
    "screen_res": "Screen Resolution",
    "avail_res": "Available Resolution",
    "color_depth": "Color Depth",
    "pixel_depth": "Pixel Depth",
    "device_pixel_ratio": "Device Pixel Ratio",
    "timezone": "Timezone",
    "timezone_offset": "Timezone Offset",
    "max_touch": "Max Touch",
    "hardware_concurrency": "CPU Cores",
    "memory": "Memory",
    "canvas": "Canvas Fingerprint"
  },
  "doh": {
    "domain": "Domain",
    "server": "DoH Server",
    "query": "Query",
    "querying": "Querying...",
    "result": "Result"
  },
  "placeholder_img": {
    "width": "Width",
    "height": "Height",
    "bg": "Background",
    "fg": "Foreground",
    "text": "Text",
    "generate": "Generate",
    "download": "Download"
  },
  "privacy_policy": {
    "app_name": "App Name",
    "developer": "Developer",
    "collect_types": "Data Types Collected",
    "generate": "Generate",
    "result": "Privacy Policy",
    "title": "Privacy Policy",
    "default_types": "Device info, location, usage logs",
    "section1_title": "1. Information Collection",
    "section1_body": "{appName} is developed by {developer}. We collect the following information to provide and improve services.",
    "section2_title": "2. Information Usage",
    "section2_body": "{appName} collects {types} solely for app operation and experience improvement, and will not sell to third parties.",
    "section3_title": "3. Information Security",
    "section3_body": "We take reasonable measures to protect your personal information.",
    "section4_title": "4. Your Rights",
    "section4_body": "You have the right to access, correct, and delete your personal information.",
    "section5_title": "5. Contact",
    "section5_body": "For questions, please contact {developer}."
  },
  "pomodoro": {
    "work": "Working",
    "break": "Break",
    "start": "Start",
    "pause": "Pause",
    "reset": "Reset",
    "work_min": "Work(min)",
    "break_min": "Break(min)",
    "completed": "Completed"
  },
  "art_qr": {
    "text": "Text/URL",
    "fg": "Foreground",
    "bg": "Background",
    "style": "Dot style",
    "square": "Square",
    "circle": "Circle",
    "generate": "Generate",
    "download": "Download"
  },
  "ppi_calc": {
    "diagonal": "Diagonal(inches)",
    "horizontal": "Horizontal px",
    "vertical": "Vertical px",
    "compute": "Compute",
    "result": "PPI"
  },
  "mortgage_calc": {
    "principal": "Principal",
    "rate": "Annual Rate(%)",
    "years": "Years",
    "method": "Method",
    "equal_payment": "Equal Payment",
    "equal_principal": "Equal Principal",
    "compute": "Compute",
    "monthly": "Monthly",
    "total": "Total",
    "interest": "Total Interest",
    "first_month": "First Month"
  },
  "gb_code": {
    "search": "Search character or code"
  },
  "solar_lunar": {
    "year": "Year",
    "month": "Month",
    "day": "Day",
    "convert": "Convert"
  },
  "world_clock": {},
  "chem_balance": {
    "input": "Chemical equation (e.g. H2+O2=H2O)",
    "balance": "Balance"
  },
  "mic_test": {
    "enumerate": "Enumerate Devices",
    "default": "Default Device",
    "device": "Device",
    "status_label": "Status",
    "status_idle": "Idle",
    "status_granted": "Granted",
    "status_denied": "Denied",
    "status_recording": "Recording",
    "status_playing": "Playing",
    "record": "Start Recording",
    "stop": "Stop Recording",
    "play": "Play Recording",
    "download": "Download Recording",
    "duration": "Duration",
    "volume": "Volume"
  },
  "keyboard_test": {
    "hint": "Press any key on your keyboard to test",
    "current": "Current Key",
    "history": "Key History"
  },
  "screen_test": {
    "color_red": "Red",
    "color_green": "Green",
    "color_blue": "Blue",
    "color_white": "White",
    "color_black": "Black",
    "click_exit": "Click or press ESC to exit fullscreen",
    "screen_info": "Screen Info",
    "resolution": "Resolution",
    "available": "Available",
    "pixel_ratio": "Pixel Ratio",
    "esc_hint": "Press ESC to exit fullscreen mode"
  },
  "pfx_to_pem": {
    "select_file": "Select PFX/P12 File",
    "password": "Password",
    "parse": "Parse",
    "parsing": "Parsing...",
    "cert_pem": "Certificate PEM",
    "key_pem": "Private Key PEM",
    "download": "Download",
    "parse_error": "Parse failed",
    "no_content": "No certificate or private key found",
    "forge_required": "node-forge library is required"
  },
  "http_request": {
    "headers": "Headers",
    "add_header": "Add Header",
    "body": "Body",
    "send": "Send",
    "sending": "Sending...",
    "cors_warning": "Note: Browser CORS policy may limit some requests; only CORS-enabled endpoints are supported",
    "status": "Status",
    "status_text": "Status Text",
    "time": "Time",
    "response_headers": "Response Headers",
    "response_body": "Response Body"
  },
  "doodle": {
    "color": "Color",
    "size": "Brush Size",
    "eraser": "Eraser",
    "undo": "Undo",
    "clear": "Clear",
    "download": "Download PNG",
    "reset": "Reset Canvas"
  },
  "modpow": {
    "base": "Base",
    "exponent": "Exponent",
    "modulus": "Modulus",
    "calc": "Calculate",
    "result": "Result:",
    "err_modulus_zero": "Modulus cannot be 0",
    "err_negative_exp": "Exponent cannot be negative",
    "err_invalid": "Invalid input, please enter integers",
    "note": "Modular exponentiation is widely used in RSA encryption, Diffie-Hellman key exchange, elliptic curve cryptography, etc. This tool uses BigInt with the square-and-multiply algorithm, supporting arbitrarily large integers."
  },
  "bit_reverse": {
    "input_label": "Input positive integer",
    "width_label": "Bit width",
    "calc": "Calculate",
    "step_original": "Original binary:",
    "step_reversed": "Reversed binary:",
    "result_dec": "Result (decimal):",
    "result_hex": "Result (hex):",
    "err_negative": "Please enter a non-negative integer",
    "err_invalid": "Invalid input"
  },
  "punctuation": {
    "cn2en": "CN → EN",
    "en2cn": "EN → CN",
    "input_label": "Input text",
    "convert": "Convert",
    "output_label": "Output",
    "copy": "Copy",
    "copied": "Copied"
  },
  "leap_year": {
    "mode_single": "Single Year",
    "mode_range": "Range",
    "year_label": "Year",
    "start_label": "Start Year",
    "end_label": "End Year",
    "check": "Check",
    "is_leap": "Year {year} is a leap year",
    "not_leap": "Year {year} is not a leap year",
    "range_result": "{count} leap years between {start} and {end}:",
    "err_invalid": "Please enter a valid year",
    "err_range": "Please enter valid start and end years",
    "rule": "Leap year rule: A year divisible by 4 is a leap year, unless it is divisible by 100 but not by 400. For example: 2000 is a leap year, 1900 is not, 2024 is."
  },
  "reverse": {
    "mode_char": "Character Reverse",
    "mode_line": "Line Reverse",
    "input_label": "Input text",
    "action": "Reverse",
    "output_label": "Output",
    "copy": "Copy",
    "copied": "Copied"
  },
  "reaction_test": {
    "click_start": "Click to start",
    "wait_green": "Wait for green…",
    "click_now": "Click now!",
    "your_time": "Your reaction time: {ms} ms",
    "too_early": "Too early! Wait for the green signal.",
    "try_again": "Try again",
    "stats_title": "Statistics",
    "avg": "Average",
    "best": "Best",
    "worst": "Worst",
    "history_title": "History (last 10)"
  },
  "ipv4_ipv6": {
    "input_label": "Enter address",
    "mode_auto": "Auto",
    "mode_ipv4": "IPv4",
    "mode_ipv6": "IPv6",
    "invalid_ipv4": "Invalid IPv4 address",
    "invalid_ipv6": "Invalid IPv6 address",
    "invalid_input": "Invalid address input",
    "mapped": "IPv6 Mapped",
    "mapped_hex": "IPv6 Mapped (Hex)",
    "compatible": "IPv4 Compatible",
    "compatible_hex": "IPv4 Compatible (Hex)",
    "six_to_four": "6to4 Address",
    "expanded": "Full Expanded",
    "compressed": "Compressed",
    "extracted_ipv4": "Extracted IPv4",
    "no_ipv4_mapping": "This IPv6 address does not contain an IPv4 mapping"
  },
  "code_formatter": {
    "language": "Language",
    "indent_size": "Indent Size",
    "wrap_length": "Wrap Length",
    "input_label": "Input Code",
    "input_placeholder": "Paste code…",
    "format": "Format",
    "output_label": "Formatted Output",
    "copy": "Copy",
    "copied": "Copied"
  },
  "port_check": {
    "host_label": "Hostname / IP",
    "port_label": "Port",
    "check": "Check",
    "check_common": "Check Common Ports",
    "th_port": "Port",
    "th_service": "Service",
    "th_status": "Status",
    "status_checking": "Checking…",
    "status_open": "Open",
    "status_closed": "Closed",
    "status_timeout": "Timeout",
    "status_error": "Error",
    "limitation_note": "Note: Due to browser CORS security restrictions, port check results are for reference only. This uses fetch with no-cors mode; an opaque response suggests the service may be responding, but cannot be confirmed. More accurate detection requires server-side tools."
  },
  "auto_refresh": {
    "url_label": "Target URL",
    "interval_label": "Refresh Interval",
    "seconds": "seconds (min 5s)",
    "start": "Start",
    "stop": "Stop",
    "countdown": "Countdown",
    "total_refreshes": "Refreshes",
    "last_refresh": "Last Refresh",
    "preview": "Page Preview",
    "bookmarklet_title": "Bookmarklet",
    "bookmarklet_desc": "Drag the button below to your bookmarks bar to use auto-refresh on any page.",
    "bookmarklet_btn": "Auto Refresh Bookmarklet"
  },
  "text_to_html_table": {
    "inputLabel": "Input text (CSV/TSV)",
    "placeholder": "Name,Age,City\nAlice,25,Beijing\nBob,30,Shanghai",
    "delimiter": "Delimiter",
    "hasHeader": "Header row",
    "border": "Border",
    "padding": "Cell padding",
    "className": "CSS class name",
    "htmlCode": "HTML Code",
    "copy": "Copy Code",
    "copied": "Copied",
    "preview": "Preview"
  },
  "font_preview": {
    "textLabel": "Preview text",
    "fontSize": "Font size",
    "customFont": "Custom font"
  },
  "symbols": {
    "search": "Search",
    "searchPlaceholder": "Search symbol or name…"
  },
  "rc4": {
    "key": "Key",
    "mode": "Mode",
    "encrypt": "Encrypt",
    "decrypt": "Decrypt",
    "plaintext": "Plaintext",
    "ciphertext": "Ciphertext",
    "inputEnc": "Input encoding",
    "outputEnc": "Output encoding",
    "result": "Result",
    "keyRequired": "Key is required",
    "inputRequired": "Input is required"
  },
  "clipboard_viewer": {
    "read": "Read Clipboard",
    "hint": "Requires browser permission. If denied, use the paste area below.",
    "pasteArea": "Paste area (Ctrl+V)",
    "pasteItems": "Pasted content"
  },
  "svg_editor": {
    "tool": "Tool",
    "add": "Add Shape",
    "properties": "Properties",
    "delete": "Delete Selected",
    "svgCode": "SVG Code",
    "copy": "Copy",
    "copied": "Copied"
  }
}
