diff --git a/components.d.ts b/components.d.ts
index e31119b36..c172b2bd0 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -81,6 +81,8 @@ declare module '@vue/runtime-core' {
FormatTransformer: typeof import('./src/components/FormatTransformer.vue')['default']
GitMemo: typeof import('./src/tools/git-memo/git-memo.vue')['default']
'GitMemo.content': typeof import('./src/tools/git-memo/git-memo.content.md')['default']
+ 'GitMemo.content.fr': typeof import('./src/tools/git-memo/git-memo.content.fr.md')['default']
+ 'GitMemo.content.zh': typeof import('./src/tools/git-memo/git-memo.content.zh.md')['default']
HashText: typeof import('./src/tools/hash-text/hash-text.vue')['default']
HmacGenerator: typeof import('./src/tools/hmac-generator/hmac-generator.vue')['default']
'Home.page': typeof import('./src/pages/Home.page.vue')['default']
@@ -90,16 +92,23 @@ declare module '@vue/runtime-core' {
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
+ IconMdiCamera: typeof import('~icons/mdi/camera')['default']
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
IconMdiClose: typeof import('~icons/mdi/close')['default']
IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
+ IconMdiDeleteOutline: typeof import('~icons/mdi/delete-outline')['default']
+ IconMdiDownload: typeof import('~icons/mdi/download')['default']
IconMdiEye: typeof import('~icons/mdi/eye')['default']
IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
IconMdiHeart: typeof import('~icons/mdi/heart')['default']
+ IconMdiPause: typeof import('~icons/mdi/pause')['default']
+ IconMdiPlay: typeof import('~icons/mdi/play')['default']
+ IconMdiRecord: typeof import('~icons/mdi/record')['default']
IconMdiSearch: typeof import('~icons/mdi/search')['default']
IconMdiTranslate: typeof import('~icons/mdi/translate')['default']
IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
+ IconMdiVideo: typeof import('~icons/mdi/video')['default']
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
@@ -136,6 +145,7 @@ declare module '@vue/runtime-core' {
NGi: typeof import('naive-ui')['NGi']
NGrid: typeof import('naive-ui')['NGrid']
NH1: typeof import('naive-ui')['NH1']
+ NH2: typeof import('naive-ui')['NH2']
NH3: typeof import('naive-ui')['NH3']
NIcon: typeof import('naive-ui')['NIcon']
NInputNumber: typeof import('naive-ui')['NInputNumber']
@@ -145,6 +155,8 @@ declare module '@vue/runtime-core' {
NMenu: typeof import('naive-ui')['NMenu']
NScrollbar: typeof import('naive-ui')['NScrollbar']
NSpin: typeof import('naive-ui')['NSpin']
+ NTable: typeof import('naive-ui')['NTable']
+ NTag: typeof import('naive-ui')['NTag']
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
@@ -159,6 +171,7 @@ declare module '@vue/runtime-core' {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
RsaKeyPairGenerator: typeof import('./src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue')['default']
+ SafelinkDecoder: typeof import('./src/tools/safelink-decoder/safelink-decoder.vue')['default']
SlugifyString: typeof import('./src/tools/slugify-string/slugify-string.vue')['default']
SpanCopyable: typeof import('./src/components/SpanCopyable.vue')['default']
SqlPrettify: typeof import('./src/tools/sql-prettify/sql-prettify.vue')['default']
diff --git a/locales/en.yml b/locales/en.yml
index 50d48af92..bc676dd3a 100644
--- a/locales/en.yml
+++ b/locales/en.yml
@@ -56,6 +56,41 @@ toolCard:
new: New
search:
label: Search
+ placeholder: Type to search a tool or a command...
+ui:
+ fileUpload:
+ tips: Drag and drop files here, or click to select files
+ or: or
+ browseFileBtn: Browse files
+ inputText:
+ placeholder: Input text
+ modalValue:
+ copied: Copied!
+ copy: Copy
+ select:
+ placeholder: Select an option
+ empty: No results found
+ table:
+ description: Data table
+ textCopyable:
+ copied: Copied!
+ copyToClipboard: Copy to clipboard
+ color:
+ invalidHexColor: Invalid hex color
+components:
+ formatTransformer:
+ inputLabel: Input
+ inputPlaceholder: Input...
+ outputLabel: Output
+ inputCopyable:
+ copied: Copied!
+ copyToClipboard: Copy to clipboard
+ spanCopyable:
+ copyToClipboard: Copy to clipboard
+ copied: Copied!
+ textareaCopyable:
+ copyToClipboard: Copy to clipboard
+ copied: Copied!
tools:
categories:
favorite-tools: 'Your favorite tools'
@@ -69,325 +104,3 @@ tools:
measurement: Measurement
text: Text
data: Data
-
- password-strength-analyser:
- title: Password strength analyser
- description: Discover the strength of your password with this client side only password strength analyser and crack time estimation tool.
-
- chronometer:
- title: Chronometer
- description: Monitor the duration of a thing. Basically a chronometer with simple chronometer features.
-
- token-generator:
- title: Token generator
- description: Generate random string with the chars you want, uppercase or lowercase letters, numbers and/or symbols.
-
- uppercase: Uppercase (ABC...)
- lowercase: Lowercase (abc...)
- numbers: Numbers (123...)
- symbols: Symbols (!-;...)
- length: Length
- tokenPlaceholder: 'The token...'
- copied: Token copied to the clipboard
- button:
- copy: Copy
- refresh: Refresh
- percentage-calculator:
- title: Percentage calculator
- description: Easily calculate percentages from a value to another value, or from a percentage to a value.
-
- svg-placeholder-generator:
- title: SVG placeholder generator
- description: Generate svg images to use as placeholder in your applications.
-
- json-to-csv:
- title: JSON to CSV
- description: Convert JSON to CSV with automatic header detection.
-
- camera-recorder:
- title: Camera recorder
- description: Take a picture or record a video from your webcam or camera.
-
- keycode-info:
- title: Keycode info
- description: Find the javascript keycode, code, location and modifiers of any pressed key.
-
- emoji-picker:
- title: Emoji picker
- description: Copy and paste emojis easily and get the unicode and code points value of each emoji.
-
- color-converter:
- title: Color converter
- description: Convert color between the different formats (hex, rgb, hsl and css name)
-
- bcrypt:
- title: Bcrypt
- description: Hash and compare text string using bcrypt. Bcrypt is a password-hashing function based on the Blowfish cipher.
-
- crontab-generator:
- title: Crontab generator
- description: Validate and generate crontab and get the human readable description of the cron schedule.
-
- http-status-codes:
- title: HTTP status codes
- description: The list of all HTTP status codes their name and their meaning.
-
- sql-prettify:
- title: SQL prettify and format
- description: Format and prettify your SQL queries online (it supports various SQL dialects).
-
- benchmark-builder:
- title: Benchmark builder
- description: Easily compare execution time of tasks with this very simple online benchmark builder.
-
- git-memo:
- title: Git cheatsheet
- description: Git is a decentralized version management software. With this cheatsheet you will have a quick access to the most common git commands.
-
- slugify-string:
- title: Slugify string
- description: Make a string url, filename and id safe.
-
- encryption:
- title: Encrypt / decrypt text
- description: Encrypt and decrypt text clear text using crypto algorithm like AES, TripleDES, Rabbit or RC4.
-
- random-port-generator:
- title: Random port generator
- description: Generate random port numbers outside of the range of "known" ports (0-1023).
-
- yaml-prettify:
- title: YAML prettify and format
- description: Prettify your YAML string to a human friendly readable format.
-
- eta-calculator:
- title: ETA calculator
- description: An ETA (Estimated Time of Arrival) calculator to know the approximate end time of a task, for example the moment of ending of a download.
-
- roman-numeral-converter:
- title: Roman numeral converter
- description: Convert Roman numerals to numbers and convert numbers to Roman numerals.
-
- hmac-generator:
- title: Hmac generator
- description: Computes a hash-based message authentication code (HMAC) using a secret key and your favorite hashing function.
-
- bip39-generator:
- title: BIP39 passphrase generator
- description: Generate BIP39 passphrase from existing or random mnemonic, or get the mnemonic from the passphrase.
-
- base64-file-converter:
- title: Base64 file converter
- description: Convert string, files or images into a it\'s base64 representation.
-
- list-converter:
- title: List converter
- description: This tool can process column-based data and apply various changes (transpose, add prefix and suffix, reverse list, sort list, lowercase values, truncate values) to each row.
-
- base64-string-converter:
- title: Base64 string encoder/decoder
- description: Simply encode and decode string into a their base64 representation.
-
- toml-to-yaml:
- title: TOML to YAML
- description: Parse and convert TOML to YAML.
-
- math-evaluator:
- title: Math evaluator
- description: A calculator for evaluating mathematical expressions. You can use functions like sqrt, cos, sin, abs, etc.
-
- json-to-yaml-converter:
- title: JSON to YAML converter
- description: Simply convert JSON to YAML with this live online converter.
-
- url-parser:
- title: Url parser
- description: Parse an url string to get all the different parts (protocol, origin, params, port, username-password, ...)
-
- iban-validator-and-parser:
- title: IBAN validator and parser
- description: Validate and parse IBAN numbers. Check if IBAN is valid and get the country, BBAN, if it is a QR-IBAN and the IBAN friendly format.
-
- user-agent-parser:
- title: User-agent parser
- description: Detect and parse Browser, Engine, OS, CPU, and Device type/model from an user-agent string.
-
- numeronym-generator:
- title: Numeronym generator
- description: A numeronym is a word where a number is used to form an abbreviation. For example, "i18n" is a numeronym of "internationalization" where 18 stands for the number of letters between the first i and the last n in the word.
-
- case-converter:
- title: Case converter
- description: Change the case of a string and chose between different formats
-
- html-entities:
- title: Escape html entities
- description: Escape or unescape html entities (replace <,>, &, " and \' to their html version)
-
- json-prettify:
- title: JSON prettify and format
- description: Prettify your JSON string to a human friendly readable format.
-
- docker-run-to-docker-compose-converter:
- title: Docker run to Docker compose converter
- description: Turns docker run commands into docker-compose files!
-
- mac-address-lookup:
- title: MAC address lookup
- description: Find the vendor and manufacturer of a device by its MAC address.
-
- mime-types:
- title: Mime types
- description: Convert mime types to extensions and vice-versa.
-
- toml-to-json:
- title: TOML to JSON
- description: Parse and convert TOML to JSON.
-
- lorem-ipsum-generator:
- title: Lorem ipsum generator
- description: Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content
-
- qrcode-generator:
- title: QR Code generator
- description: Generate and download QR-code for an url or just a text and customize the background and foreground colors.
-
- wifi-qrcode-generator:
- title: WiFi QR Code generator
- description: Generate and download QR-codes for quick connections to WiFi networks.
-
- xml-formatter:
- title: XML formatter
- description: Prettify your XML string to a human friendly readable format.
-
- temperature-converter:
- title: Temperature converter
- description: Temperature degrees conversions for Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Réaumur and Rømer.
-
- chmod-calculator:
- title: Chmod calculator
- description: Compute your chmod permissions and commands with this online chmod calculator.
-
- rsa-key-pair-generator:
- title: RSA key pair generator
- description: Generate new random RSA private and public key pem certificates.
-
- html-wysiwyg-editor:
- title: HTML WYSIWYG editor
- description: Online HTML editor with feature-rich WYSIWYG editor, get the source code of the content immediately.
-
- yaml-to-toml:
- title: YAML to TOML
- description: Parse and convert YAML to TOML.
-
- mac-address-generator:
- title: MAC address generator
- description: Enter the quantity and prefix. MAC addresses will be generated in your chosen case (uppercase or lowercase)
-
- json-diff:
- title: JSON diff
- description: Compare two JSON objects and get the differences between them.
-
- jwt-parser:
- title: JWT parser
- description: Parse and decode your JSON Web Token (jwt) and display its content.
-
- date-converter:
- title: Date-time converter
- description: Convert date and time into the various different formats
-
- phone-parser-and-formatter:
- title: Phone parser and formatter
- description: Parse, validate and format phone numbers. Get information about the phone number, like the country code, type, etc.
-
- ipv4-subnet-calculator:
- title: IPv4 subnet calculator
- description: Parse your IPv4 CIDR blocks and get all the info you need about your sub network.
-
- og-meta-generator:
- title: Open graph meta generator
- description: Generate open-graph and socials html meta tags for your website.
-
- ipv6-ula-generator:
- title: IPv6 ULA generator
- description: Generate your own local, non-routable IP addresses on your network according to RFC4193.
-
- hash-text:
- title: Hash text
- description: 'Hash a text string using the function you need : MD5, SHA1, SHA256, SHA224, SHA512, SHA384, SHA3 or RIPEMD160'
-
- json-to-toml:
- title: JSON to TOML
- description: Parse and convert JSON to TOML.
-
- device-information:
- title: Device information
- description: Get information about your current device (screen size, pixel-ratio, user agent, ...)
-
- pdf-signature-checker:
- title: PDF signature checker
- description: Verify the signatures of a PDF file. A signed PDF file contains one or more signatures that may be used to determine whether the contents of the file have been altered since the file was signed.
-
- json-minify:
- title: JSON minify
- description: Minify and compress your JSON by removing unnecessary white spaces.
-
- ulid-generator:
- title: ULID generator
- description: Generate random Universally Unique Lexicographically Sortable Identifier (ULID).
-
- string-obfuscator:
- title: String obfuscator
- description: Obfuscate a string (like a secret, an IBAN, or a token) to make it shareable and identifiable without revealing its content.
-
- base-converter:
- title: Integer base converter
- description: Convert number between different bases (decimal, hexadecimal, binary, octal, base64, ...)
-
- yaml-to-json-converter:
- title: YAML to JSON converter
- description: Simply convert YAML to JSON with this live online converter.
-
- uuid-generator:
- title: UUIDs generator
- description: A Universally Unique Identifier (UUID) is a 128-bit number used to identify information in computer systems. The number of possible UUIDs is 16^32, which is 2^128 or about 3.4x10^38 (which is a lot!).
-
- ipv4-address-converter:
- title: Ipv4 address converter
- description: Convert an ip address into decimal, binary, hexadecimal or event in ipv6
-
- text-statistics:
- title: Text statistics
- description: Get information about a text, the amount of characters, the amount of words, it\'s size, ...
-
- text-to-nato-alphabet:
- title: Text to NATO alphabet
- description: Transform text into NATO phonetic alphabet for oral transmission.
-
- basic-auth-generator:
- title: Basic auth generator
- description: Generate a base64 basic auth header from an username and a password.
-
- text-to-unicode:
- title: Text to Unicode
- description: Parse and convert text to unicode and vice-versa
-
- ipv4-range-expander:
- title: IPv4 range expander
- description: Given a start and an end IPv4 address this tool calculates a valid IPv4 network with its CIDR notation.
-
- text-diff:
- title: Text diff
- description: Compare two texts and see the differences between them.
-
- otp-generator:
- title: OTP code generator
- description: Generate and validate time-based OTP (one time password) for multi-factor authentication.
-
- url-encoder:
- title: Encode/decode url formatted strings
- description: Encode to url-encoded format (also known as "percent-encoded") or decode from it.
-
- text-to-binary:
- title: Text to ASCII binary
- description: Convert text to its ASCII binary representation and vice versa.
diff --git a/locales/fr.yml b/locales/fr.yml
index 35c7df2ef..c4f117a0d 100644
--- a/locales/fr.yml
+++ b/locales/fr.yml
@@ -50,6 +50,41 @@ toolCard:
new: Nouveau
search:
label: Rechercher
+ placeholder: 'Tapez pour rechercher un outil ou une commande...'
+ui:
+ fileUpload:
+ tips: 'Glissez-déposez des fichiers ici, ou cliquez pour sélectionner des fichiers'
+ or: ou
+ browseFileBtn: 'Parcourir les fichiers'
+ inputText:
+ placeholder: "Texte d'entrée"
+ modalValue:
+ copied: 'Copié !'
+ copy: Copier
+ select:
+ placeholder: 'Sélectionnez une option'
+ empty: Aucun résultat trouvé
+ table:
+ description: Table de données
+ textCopyable:
+ copied: 'Copié !'
+ copyToClipboard: Copier dans le presse-papiers
+ color:
+ invalidHexColor: Couleur hexadécimale invalide
+components:
+ formatTransformer:
+ inputLabel: Entrée
+ inputPlaceholder: Entrée...
+ outputLabel: Sortie
+ inputCopyable:
+ copied: 'Copié !'
+ copyToClipboard: Copier dans le presse-papiers
+ spanCopyable:
+ copyToClipboard: Copier dans le presse-papiers
+ copied: 'Copié !'
+ textareaCopyable:
+ copyToClipboard: Copier dans le presse-papiers
+ copied: 'Copié !'
tools:
categories:
favorite-tools: 'Vos outils favoris'
@@ -63,19 +98,3 @@ tools:
measurement: Mesure
text: Texte
data: Données
-
- token-generator:
- title: Générateur de token
- description: >-
- Génère une chaîne aléatoire avec les caractères que vous voulez, lettres
- majuscules ou minuscules, chiffres et/ou symboles.
- uppercase: Majuscules (ABC...)
- lowercase: Minuscules (abc...)
- numbers: Chiffres (123...)
- symbols: Symboles (!-;...)
- button:
- copy: Copier
- refresh: Rafraichir
- copied: Le token a été copié
- length: Longueur
- tokenPlaceholder: Le token...
diff --git a/locales/vi.yml b/locales/vi.yml
index 9eb16bf0f..efcaf8d42 100644
--- a/locales/vi.yml
+++ b/locales/vi.yml
@@ -69,314 +69,3 @@ tools:
measurement: Đo lường
text: Văn bản
data: Dữ liệu
-
- password-strength-analyser:
- title: Bộ phân tích độ mạnh mật khẩu
- description: Khám phá độ mạnh của mật khẩu của bạn với công cụ phân tích độ mạnh mật khẩu chỉ chạy trên phía máy khách và ước tính thời gian phá mật khẩu.
-
- chronometer:
- title: Đồng hồ bấm giờ
- description: Giám sát thời gian của một sự việc. Cơ bản là một đồng hồ bấm giờ với các tính năng đơn giản.
-
- token-generator:
- title: Trình tạo mã thông báo
- description: Tạo chuỗi ngẫu nhiên với các ký tự bạn muốn, chữ hoa hoặc chữ thường, số và/hoặc ký tự đặc biệt.
-
- uppercase: Chữ hoa (ABC...)
- lowercase: Chữ thường (abc...)
- numbers: Số (123...)
- symbols: Ký tự đặc biệt (!-;...)
- length: Độ dài
- tokenPlaceholder: 'Mã thông báo...'
- copied: Mã thông báo đã được sao chép vào clipboard
- button:
- copy: Sao chép
- refresh: Làm mới
-
- percentage-calculator:
- title: Máy tính phần trăm
- description: Dễ dàng tính toán phần trăm từ một giá trị đến giá trị khác, hoặc từ một phần trăm đến một giá trị.
-
- svg-placeholder-generator:
- title: Trình tạo hình ảnh SVG giả định
- description: Tạo hình ảnh svg để sử dụng làm giả định trong ứng dụng của bạn.
-
- json-to-csv:
- title: Chuyển đổi JSON thành CSV
- description: Chuyển đổi JSON thành CSV với việc tự động phát hiện tiêu đề.
-
- camera-recorder:
- title: Ghi lại camera
- description: Chụp ảnh hoặc quay video từ webcam hoặc máy ảnh của bạn.
- keycode-info:
- title: Thông tin Keycode
- description: Tìm mã keycode, mã, vị trí và các phím điều khiển của bất kỳ phím nào được nhấn.
-
- emoji-picker:
- title: Bộ chọn biểu tượng cảm xúc
- description: Sao chép và dán biểu tượng cảm xúc một cách dễ dàng và nhận giá trị unicode và mã điểm của mỗi biểu tượng cảm xúc.
-
- color-converter:
- title: Trình chuyển đổi màu
- description: Chuyển đổi màu giữa các định dạng khác nhau (hex, rgb, hsl và tên css)
-
- bcrypt:
- title: Bcrypt
- description: Mã hóa và so sánh chuỗi văn bản sử dụng bcrypt. Bcrypt là một hàm mã hóa mật khẩu dựa trên thuật toán Blowfish.
- crontab-generator:
- title: Trình tạo Crontab
- description: Xác thực và tạo crontab và lấy mô tả đọc được của lịch trình cron.
- http-status-codes:
- title: Mã trạng thái HTTP
- description: Danh sách tất cả các mã trạng thái HTTP, tên và ý nghĩa của chúng.
-
- sql-prettify:
- title: Định dạng và làm đẹp SQL
- description: Định dạng và làm đẹp các truy vấn SQL của bạn trực tuyến (hỗ trợ nhiều ngôn ngữ SQL khác nhau).
-
- benchmark-builder:
- title: Trình tạo bảng đánh giá
- description: Dễ dàng so sánh thời gian thực thi của các nhiệm vụ với trình tạo bảng đánh giá trực tuyến đơn giản này.
- git-memo:
- title: Lệnh Git
- description: Git là một phần mềm quản lý phiên bản phân tán. Với bảng ghi chú này, bạn sẽ có thể truy cập nhanh vào các lệnh Git phổ biến nhất.
-
- slugify-string:
- title: Chuyển đổi chuỗi thành slug
- description: Biến đổi chuỗi thành dạng an toàn để sử dụng trong URL, tên file và ID.
-
- encryption:
- title: Mã hóa / giải mã văn bản
- description: Mã hóa và giải mã văn bản rõ bằng cách sử dụng thuật toán mã hóa như AES, TripleDES, Rabbit hoặc RC4.
-
- random-port-generator:
- title: Trình tạo số cổng ngẫu nhiên
- description: Tạo số cổng ngẫu nhiên nằm ngoài phạm vi của các cổng "biết được" (0-1023).
-
- yaml-prettify:
- title: Định dạng và làm đẹp YAML
- description: Định dạng chuỗi YAML của bạn thành một định dạng dễ đọc và thân thiện với con người.
-
- eta-calculator:
- title: Máy tính ETA
- description: Một máy tính ETA (Thời gian dự kiến đến) để biết thời gian kết thúc xấp xỉ của một nhiệm vụ, ví dụ như thời điểm kết thúc của một quá trình tải xuống.
-
- roman-numeral-converter:
- title: Bộ chuyển đổi số La Mã
- description: Chuyển đổi số La Mã thành số và chuyển đổi số thành số La Mã.
-
- hmac-generator:
- title: Máy tạo HMAC
- description: Tính toán mã xác thực thông điệp dựa trên hash (HMAC) sử dụng một khóa bí mật và hàm băm yêu thích của bạn.
-
- bip39-generator:
- title: Trình tạo BIP39 passphrase
- description: Tạo BIP39 passphrase từ mnemonic hiện có hoặc ngẫu nhiên, hoặc lấy mnemonic từ passphrase.
- base64-file-converter:
- title: Trình chuyển đổi tệp Base64
- description: Chuyển đổi chuỗi, tệp hoặc hình ảnh thành mã Base64.
- list-converter:
- title: Trình chuyển đổi danh sách
- description: Công cụ này có thể xử lý dữ liệu dựa trên cột và áp dụng các thay đổi khác nhau (đảo ngược, thêm tiền tố và hậu tố, đảo danh sách, sắp xếp danh sách, giảm giá trị thành chữ thường, cắt giá trị) cho mỗi hàng.
-
- base64-string-converter:
- title: Trình mã hóa/giải mã chuỗi Base64
- description: Đơn giản mã hóa và giải mã chuỗi thành mã Base64.
- toml-to-yaml:
- title: Chuyển đổi TOML thành YAML
- description: Phân tích và chuyển đổi TOML thành YAML.
-
- math-evaluator:
- title: Trình đánh giá toán học
- description: Một máy tính để tính toán biểu thức toán học. Bạn có thể sử dụng các hàm như sqrt, cos, sin, abs, v.v.
-
- json-to-yaml-converter:
- title: Chuyển đổi JSON sang YAML
- description: Chuyển đổi đơn giản JSON sang YAML với công cụ chuyển đổi trực tuyến này.
-
- url-parser:
- title: Trình phân tích URL
- description: Phân tích một chuỗi URL để lấy tất cả các phần khác nhau (giao thức, nguồn gốc, tham số, cổng, tên người dùng-mật khẩu, ...)
-
- iban-validator-and-parser:
- title: Kiểm tra và phân tích số IBAN
- description: Xác thực và phân tích số IBAN. Kiểm tra tính hợp lệ của IBAN và lấy thông tin về quốc gia, BBAN, xem có phải là QR-IBAN và định dạng thân thiện của IBAN.
-
- user-agent-parser:
- title: Trình phân tích User-agent
- description: Phát hiện và phân tích trình duyệt, engine, hệ điều hành, CPU và kiểu/mô hình thiết bị từ chuỗi user-agent.
-
- numeronym-generator:
- title: Trình tạo Numeronym
- description: Numeronym là một từ mà một số được sử dụng để tạo thành một từ viết tắt. Ví dụ, "i18n" là một numeronym của "internationalization" trong đó số 18 đại diện cho số chữ cái giữa chữ i đầu tiên và chữ n cuối cùng trong từ.
-
- case-converter:
- title: Chuyển đổi chữ hoa/chữ thường
- description: Thay đổi kiểu chữ của một chuỗi và chọn giữa các định dạng khác nhau
- html-entities:
- title: Thay thế các ký tự HTML
- description: Thay thế hoặc bỏ thẻ các ký tự HTML (thay thế <,>, &, " và \' thành phiên bản HTML tương ứng)
-
- json-prettify:
- title: Định dạng và làm đẹp JSON
- description: Định dạng chuỗi JSON của bạn thành một định dạng dễ đọc và thân thiện với con người.
-
- docker-run-to-docker-compose-converter:
- title: Chuyển đổi lệnh docker run thành tệp docker-compose
- description: Chuyển đổi các lệnh docker run thành tệp docker-compose!
-
- mac-address-lookup:
- title: Tra cứu địa chỉ MAC
- description: Tìm nhà sản xuất và nhà cung cấp của thiết bị dựa trên địa chỉ MAC.
-
- mime-types:
- title: Loại Mime
- description: Chuyển đổi loại mime thành phần mở rộng và ngược lại.
-
- toml-to-json:
- title: Chuyển đổi TOML thành JSON
- description: Phân tích và chuyển đổi TOML thành JSON.
-
- lorem-ipsum-generator:
- title: Máy tạo văn bản Lorem ipsum
- description: Lorem ipsum là một đoạn văn bản giả được sử dụng phổ biến để thể hiện hình thức của một tài liệu hoặc một kiểu chữ mà không cần dựa vào nội dung có ý nghĩa
-
- qrcode-generator:
- title: Tạo mã QR
- description: Tạo và tải xuống mã QR cho một URL hoặc chỉ một đoạn văn bản và tùy chỉnh màu nền và màu chữ.
-
- wifi-qrcode-generator:
- title: Tạo mã QR WiFi
- description: Tạo và tải xuống mã QR để kết nối nhanh đến mạng WiFi.
-
- xml-formatter:
- title: Định dạng XML
- description: Định dạng chuỗi XML của bạn thành một định dạng dễ đọc và thân thiện với con người.
-
- temperature-converter:
- title: Bộ chuyển đổi nhiệt độ
- description: Chuyển đổi độ nhiệt độ cho Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Réaumur và Rømer.
-
- chmod-calculator:
- title: Máy tính Chmod
- description: Tính toán quyền và lệnh chmod của bạn với máy tính Chmod trực tuyến này.
- rsa-key-pair-generator:
- title: Trình tạo cặp khóa RSA
- description: Tạo các chứng chỉ pem khóa riêng tư và khóa công khai RSA ngẫu nhiên mới.
-
- html-wysiwyg-editor:
- title: Trình soạn thảo HTML WYSIWYG
- description: Trình soạn thảo HTML trực tuyến với trình soạn thảo WYSIWYG đa chức năng, lấy mã nguồn của nội dung ngay lập tức.
-
- yaml-to-toml:
- title: YAML sang TOML
- description: Phân tích và chuyển đổi YAML sang TOML.
-
- mac-address-generator:
- title: Trình tạo địa chỉ MAC
- description: Nhập số lượng và tiền tố. Địa chỉ MAC sẽ được tạo ra theo kiểu chữ hoa hoặc chữ thường theo lựa chọn của bạn
-
- json-diff:
- title: So sánh JSON
- description: So sánh hai đối tượng JSON và lấy ra sự khác biệt giữa chúng.
-
- jwt-parser:
- title: Giải mã JWT
- description: Giải mã và hiển thị nội dung của JSON Web Token (jwt).
-
- date-converter:
- title: Chuyển đổi ngày-tháng
- description: Chuyển đổi ngày và thời gian sang các định dạng khác nhau
-
- phone-parser-and-formatter:
- title: Trình phân tích và định dạng số điện thoại
- description: Phân tích, xác thực và định dạng số điện thoại. Lấy thông tin về số điện thoại, như mã quốc gia, loại, v.v.
-
- ipv4-subnet-calculator:
- title: Máy tính mạng con IPv4
- description: Phân tích các khối CIDR IPv4 của bạn và nhận thông tin về mạng con của bạn.
-
- og-meta-generator:
- title: Trình tạo meta Open Graph
- description: Tạo các thẻ meta HTML Open Graph và mạng xã hội cho trang web của bạn.
-
- ipv6-ula-generator:
- title: Trình tạo địa chỉ IPv6 ULA
- description: Tạo địa chỉ IP cục bộ, không thể định tuyến trên mạng của bạn theo RFC4193.
-
- hash-text:
- title: Mã hóa văn bản
- description: 'Mã hóa một chuỗi văn bản bằng cách sử dụng các hàm bạn cần: MD5, SHA1, SHA256, SHA224, SHA512, SHA384, SHA3 hoặc RIPEMD160'
- json-to-toml:
- title: Chuyển đổi JSON sang TOML
- description: Phân tích và chuyển đổi JSON sang TOML.
-
- device-information:
- title: Thông tin thiết bị
- description: Lấy thông tin về thiết bị hiện tại của bạn (kích thước màn hình, tỷ lệ pixel, user agent, ...)
-
- pdf-signature-checker:
- title: Kiểm tra chữ ký PDF
- description: Xác minh chữ ký của một tệp PDF. Một tệp PDF đã được ký có chứa một hoặc nhiều chữ ký có thể được sử dụng để xác định xem nội dung của tệp đã được thay đổi kể từ khi tệp được ký.
-
- json-minify:
- title: Giảm kích thước JSON
- description: Giảm kích thước và nén JSON của bạn bằng cách loại bỏ khoảng trắng không cần thiết.
-
- ulid-generator:
- title: Tạo ULID
- description: Tạo ngẫu nhiên mã định danh duy nhất có thể sắp xếp theo thứ tự từ điển (ULID).
- string-obfuscator:
- title: Mã hóa chuỗi
- description: Mã hóa một chuỗi (như một bí mật, một IBAN hoặc một mã thông báo) để có thể chia sẻ và nhận dạng mà không tiết lộ nội dung.
-
- base-converter:
- title: Chuyển đổi cơ số số nguyên
- description: Chuyển đổi số giữa các cơ số khác nhau (thập phân, thập lục phân, nhị phân, bát phân, base64, ...)
-
- yaml-to-json-converter:
- title: Trình chuyển đổi YAML sang JSON
- description: Chuyển đổi YAML sang JSON một cách đơn giản với công cụ chuyển đổi trực tuyến này.
-
- uuid-generator:
- title: Trình tạo UUID
- description: Một UUID (Universally Unique Identifier) là một số 128 bit được sử dụng để xác định thông tin trong hệ thống máy tính. Số lượng UUID có thể có là 16^32, tương đương với 2^128 hoặc khoảng 3.4x10^38 (rất lớn!).
-
- ipv4-address-converter:
- title: Chuyển đổi địa chỉ Ipv4
- description: Chuyển đổi địa chỉ ip thành số thập phân, nhị phân, thập lục phân hoặc thậm chí thành ipv6
-
- text-statistics:
- title: Thống kê văn bản
- description: Lấy thông tin về một văn bản, số ký tự, số từ, kích thước của nó, ...
-
- text-to-nato-alphabet:
- title: Chuyển đổi văn bản thành bảng chữ cái NATO
- description: Chuyển đổi văn bản thành bảng chữ cái phiên âm NATO để truyền tải bằng miệng.
-
- basic-auth-generator:
- title: Tạo mã xác thực cơ bản
- description: Tạo một tiêu đề xác thực cơ bản base64 từ tên người dùng và mật khẩu.
- text-to-unicode:
- title: Chuyển đổi văn bản thành Unicode
- description: Phân tích và chuyển đổi văn bản thành Unicode và ngược lại
-
- ipv4-range-expander:
- title: Mở rộng dải IPv4
- description: Cho một địa chỉ IPv4 bắt đầu và kết thúc, công cụ này tính toán một mạng IPv4 hợp lệ với ký hiệu CIDR của nó.
-
- text-diff:
- title: So sánh văn bản
- description: So sánh hai văn bản và xem sự khác biệt giữa chúng.
-
- otp-generator:
- title: Tạo mã OTP
- description: Tạo và xác thực mã OTP (mật khẩu một lần) dựa trên thời gian cho xác thực đa yếu tố.
-
- url-encoder:
- title: Mã hóa/giải mã chuỗi định dạng URL
- description: Mã hóa thành định dạng URL (còn được gọi là "percent-encoded") hoặc giải mã từ đó.
-
- text-to-binary:
- title: Chuyển đổi văn bản thành nhị phân ASCII
- description: Chuyển đổi văn bản thành biểu diễn nhị phân ASCII của nó và ngược lại.
diff --git a/locales/zh.yml b/locales/zh.yml
index 160fe1fad..1f37f94c6 100644
--- a/locales/zh.yml
+++ b/locales/zh.yml
@@ -56,6 +56,41 @@ toolCard:
new: '新'
search:
label: '搜索'
+ placeholder: '搜索工具或指令...'
+ui:
+ fileUpload:
+ tips: 拖放文件到此处,或点击选择文件
+ or: 或
+ browseFileBtn: 浏览文件
+ inputText:
+ placeholder: 输入文本
+ modalValue:
+ copied: 已复制!
+ copy: 复制
+ select:
+ placeholder: 选择一个选项
+ empty: 未找到结果
+ table:
+ description: 数据表格
+ textCopyable:
+ copied: 已复制!
+ copyToClipboard: 复制到剪贴板
+ color:
+ invalidHexColor: 无效的十六进制颜色
+components:
+ formatTransformer:
+ inputLabel: 输入
+ inputPlaceholder: 输入...
+ outputLabel: 输出
+ inputCopyable:
+ copied: 已复制!
+ copyToClipboard: 复制到剪贴板
+ spanCopyable:
+ copyToClipboard: 复制到剪贴板
+ copied: 已复制!
+ textareaCopyable:
+ copyToClipboard: 复制到剪贴板
+ copied: 已复制!
tools:
categories:
favorite-tools: '我的收藏'
@@ -69,321 +104,3 @@ tools:
measurement: '测量'
text: '文本'
data: '数据'
-
- password-strength-analyser:
- title: 密码强度分析仪
- description: 使用此密码强度分析器和破解时间估计工具来发现密码的强度。
-
- chronometer:
- title: 计时器
- description: 监控事物的持续时间。基本上是一种具有简单计时器功能的计时器。
- token-generator:
- title: Token 生成器
- description: 使用您想要的字符、大写或小写字母、数字和/或符号生成随机字符串。
-
- uppercase: '大写 (ABC...)'
- lowercase: '小写 (abc...)'
- numbers: '数字 (123...)'
- symbols: '符号 (!-;...)'
- length: '长度'
- tokenPlaceholder: '令牌...'
- copied: 复制到剪贴板
- button:
- copy: 复制
- refresh: 刷新
- percentage-calculator:
- title: 百分比计算器
- description: 轻松计算从一个值到另一个值的百分比,或从百分比到值的百分比。
-
- svg-placeholder-generator:
- title: SVG 占位符生成器
- description: 生成 svg 图像以用作应用程序中的占位符。
-
- json-to-csv:
- title: JSON 转 CSV
- description: 使用自动标头检测将JSON转换为CSV。
-
- camera-recorder:
- title: 摄像机记录器
- description: 从网络摄像头或照相机拍摄照片或录制视频。
-
- keycode-info:
- title: Keycode 信息
- description: 查找任何按下的键的javascript键代码、代码、位置和修饰符。
-
- emoji-picker:
- title: Emoji 选择器
- description: 轻松复制和粘贴Emoji表情符号,并获得每个表情符号的unicode和code points值.
-
- color-converter:
- title: Color 选择器
- description: 在不同格式(十六进制、rgb、hsl和css名称)之间转换颜色
- bcrypt:
- title: 加密
- description: 使用bcrypt对文本字符串进行哈希和比较。Bcrypt是一个基于Blowfish密码的密码哈希函数。
-
- crontab-generator:
- title: Crontab 表达式生成
- description: 验证并生成crontab,并获取cron调度的可读描述。
-
- http-status-codes:
- title: HTTP 状态码
- description: 所有HTTP状态的列表对其名称和含义解释。
-
- sql-prettify:
- title: SQL 美化和格式化
- description: 在线格式化和美化您的 SQL 查询(它支持各种 SQL 方言)。
-
- benchmark-builder:
- title: 基准生成器
- description: 简单的在线基准构建器可以轻松比较任务的执行时间。
-
- git-memo:
- title: Git 备忘录
- description: Git是一种去中心化的版本管理软件。使用此备忘单,您可以快速访问最常见的git命令.
-
- slugify-string:
- title: 打乱字符串
- description: 确保字符串 url、文件名和 id 安全。
-
- encryption:
- title: 加密/解密文本
- description: 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。
-
- random-port-generator:
- title: 随机端口生成
- description: 生成“已知”端口范围(0-1023)之外的随机端口号。
-
- yaml-prettify:
- title: YAML美化和格式化
- description: 将YAML字符串修饰为友好的可读格式。
-
- eta-calculator:
- title: ETA 计算器
- description: ETA(估计到达时间)计算器,用于知道任务的近似结束时间,例如下载的结束时刻。
-
- roman-numeral-converter:
- title: 罗马数字转换器
- description: 将罗马数字转换为数字,并将数字转换为罗马数字。
-
- hmac-generator:
- title: Hmac 生成器
- description: 使用密钥和您喜欢的哈希函数计算基于哈希的消息身份验证代码(HMAC)。
-
- bip39-generator:
- title: BIP39密码生成器
- description: 从现有或随机助记符生成BIP39密码短语,或从密码短语获取助记符。
-
- base64-file-converter:
- title: Base64 文件转换器
- description: 将字符串、文件或图像转换为其 Base64 表示形式。
- list-converter:
- title: List 转换器
- description: 该工具可以处理基于数组的数据,并将各种更改(转置、添加前缀和后缀、反向列表、排序列表、小写值、截断值)应用于每一行。
-
- base64-string-converter:
- title: Base64 字符串编码/解码
- description: 将字符串编码和解码为其 Base64 格式表示形式即可。
-
- toml-to-yaml:
- title: TOML 到 YAML
- description: Parse and convert TOML to YAML.
-
- math-evaluator:
- title: 数学计算器
- description: 计算数学表达式的计算器。您可以使用sqrt、cos、sin、abs等函数。
-
- json-to-yaml-converter:
- title: JSON到YAML转换器
- description: 在线转换将JSON转换为YAML。
-
- url-parser:
- title: Url分析器
- description: 解析url字符串以获取所有不同的部分(协议、来源、参数、端口、用户名密码…)
-
- iban-validator-and-parser:
- title: IBAN验证器和解析器
- description: 验证和分析IBAN编号。检查IBAN是否有效,并获取国家BBAN,如果它是QR-IBAN和IBAN友好格式。
-
- user-agent-parser:
- title: 用户代理分析器
- description: 从用户代理字符串中检测和分析浏览器、引擎、操作系统、CPU和设备类型/型号。
-
- numeronym-generator:
- title: 数字名称生成器
- description: 数字名是一个用数字构成缩写的词。例如,“i18n”是“国际化”的名词,其中18表示单词中第一个i和最后一个n之间的字母数。
-
- case-converter:
- title: 大小写转换
- description: 更改字符串的大小写并在不同格式之间进行选择
-
- html-entities:
- title: 转义html实体
- description: 转义或unescape html实体(将<、>、&、“和\'替换为其html版本)
-
- json-prettify:
- title: JSON美化和格式化
- description: 将JSON字符串修饰为友好的可读格式。
-
- docker-run-to-docker-compose-converter:
- title: Docker Run 到 docker-compose 转换器
- description: 将 docker run 命令行转换为 docker-compose 文件!
-
- mac-address-lookup:
- title: MAC地址查找
- description: 通过设备的MAC地址查找设备的供应商和制造商。
-
- mime-types:
- title: mime类型
- description: 将mime类型转换为扩展,反之亦然。
-
- toml-to-json:
- title: TOML 到 JSON
- description: 解析TOML并将其转换为JSON。
-
- lorem-ipsum-generator:
- title: Lorem ipsum生成器
- description: Lorem ipsum是一种占位符文本,通常用于演示文档或字体的视觉形式,而不依赖于有意义的内容
-
- qrcode-generator:
- title: 二维码生成器
- description: 生成并下载url或文本的QR代码,并自定义背景和前景颜色。
-
- wifi-qrcode-generator:
- title: WiFi 二维码生成器
- description: 生成和下载QR码以快速连接到WiFi网络。
-
- xml-formatter:
- title: XML 格式化
- description: 将XML字符串修饰为友好的可读格式。
-
- temperature-converter:
- title: 温度转换器
- description: 开尔文、摄氏度、华氏度、兰金、德莱尔、牛顿、雷奥穆尔和罗默温度度数转换。
-
- chmod-calculator:
- title: Chmod 计算器
- description: 使用此在线的chmod计算器计算chmod权限和命令。
-
- rsa-key-pair-generator:
- title: RSA密钥对生成器
- description: 生成新的随机RSA私钥和公钥pem证书。
-
- html-wysiwyg-editor:
- title: HTML所见即所得编辑器
- description: 在线HTML编辑器具有功能丰富的所见即所得编辑器,立即获得内容的源代码。
-
- yaml-to-toml:
- title: YAML 到 TOML
- description: 解析YAML并将其转换为TOML。
-
- mac-address-generator:
- title: MAC 地址生成器
- description: 输入数量和前缀。MAC地址将以您选择的大小写(大写或小写)生成
-
- json-diff:
- title: JSON 差异比较
- description: 比较两个JSON对象并获得它们之间的差异。
- jwt-parser:
- title: JWT 解析器
- description: 解析和解码JSON Web Token(jwt)并显示其内容。
-
- date-converter:
- title: 日期时间转换器
- description: 将日期和时间转换为各种不同的格式
-
- phone-parser-and-formatter:
- title: 电话分析器和格式化程序
- description: 解析、验证和格式化电话号码。获取有关电话号码的信息,如国家/地区代码、类型等。
-
- ipv4-subnet-calculator:
- title: IPv4子网计算器
- description: 解析IPv4 CIDR块,并获取有关子网络的所有所需信息。
-
- og-meta-generator:
- title: 开放式图形元生成器
- description: 为您的网站生成开放式图形和社交html元标记。
-
- ipv6-ula-generator:
- title: IPv6 ULA生成器
- description: 根据RFC4193在网络上生成您自己的本地不可路由IP地址。
-
- hash-text:
- title: Hash 文本
- description: '使用所需的函数哈希文本字符串:MD5、SHA1、SHA256、SHA224、SHA512、SHA384、SHA3或RIPEMD160'
-
- json-to-toml:
- title: JSON 转 TOML
- description: 解析JSON并将其转换为TOML。
-
- device-information:
- title: 设备信息
- description: 获取有关当前设备的信息(屏幕大小、像素比率、用户代理…)
-
- pdf-signature-checker:
- title: PDF签名检查器
- description: '验证PDF文件的签名。签名的PDF文件包含一个或多个签名,可用于确定文件的内容在签名后是否已被更改。'
-
- json-minify:
- title: JSON 压缩
- description: 通过删除不必要的空白来缩小和压缩JSON。
-
- ulid-generator:
- title: ULID 生成器
- description: 生成随机的通用唯一词典可排序标识符(ULID)。
-
- string-obfuscator:
- title: 字符串混淆器
- description: 混淆字符串(如秘密、IBAN 或令牌),使其可共享和可识别,而不泄露其内容。
-
- base-converter:
- title: 整数基转换器
- description: 在不同的基数(十进制、十六进制、二进制、八进制、base64…)之间转换数字
-
- yaml-to-json-converter:
- title: YAML到JSON转换器
- description: 使用此在线转换器将YAML转换为JSON。
-
- uuid-generator:
- title: UUIDs 生成器
- description: 通用唯一标识符(UUID)是一个128位数字,用于标识计算机系统中的信息。可能的UUID数量为16^32,即2^128或约3.4x10^38(这是一个很大的数字!)。
-
- ipv4-address-converter:
- title: Ipv4地址转换器
- description: 在ipv6中,将ip地址转换为十进制、二进制、十六进制或事件
-
- text-statistics:
- title: 文本统计
- description: 获取有关文本、字符数、字数、大小等的信息
-
- text-to-nato-alphabet:
- title: 文本转北约字母表
- description: 将文本转换为北约拼音字母以进行口头传播。
-
- basic-auth-generator:
- title: 基本身份验证生成器
- description: 从用户名和密码生成 base64 基本身份验证标头。
-
- text-to-unicode:
- title: 文本转 Unicode
- description: 解析文本并将其转换为 unicode,反之亦然
-
- ipv4-range-expander:
- title: IPv4范围扩展器
- description: 给定起始和结束IPv4地址,此工具使用其CIDR表示法计算有效的IPv4网络。
-
- text-diff:
- title: 文本比较
- description: 比较两个文本并查看它们之间的差异。
-
- otp-generator:
- title: OTP代码生成器
- description: 为多因素身份验证生成和验证基于时间的OTP(一次性密码)。
-
- url-encoder:
- title: 编码/解码url格式的字符串
- description: 编码为url编码格式(也称为“百分比编码”)或从中解码。
-
- text-to-binary:
- title: 文本到 ASCII 二进制
- description: 将文本转换为其 ASCII 二进制表示形式,反之亦然。
diff --git a/src/components/FormatTransformer.vue b/src/components/FormatTransformer.vue
index 677fc25aa..7a88fc7be 100644
--- a/src/components/FormatTransformer.vue
+++ b/src/components/FormatTransformer.vue
@@ -2,6 +2,7 @@
import _ from 'lodash';
import type { UseValidationRule } from '@/composable/validation';
import CInputText from '@/ui/c-input-text/c-input-text.vue';
+import { translate as t } from '@/plugins/i18n.plugin';
const props = withDefaults(
defineProps<{
@@ -16,10 +17,10 @@ const props = withDefaults(
{
transformer: _.identity,
inputValidationRules: () => [],
- inputLabel: 'Input',
+ inputLabel: t('components.formatTransformer.inputLabel'),
inputDefault: '',
- inputPlaceholder: 'Input...',
- outputLabel: 'Output',
+ inputPlaceholder: t('components.formatTransformer.inputPlaceholder'),
+ outputLabel: t('components.formatTransformer.outputLabel'),
outputLanguage: '',
},
);
diff --git a/src/components/InputCopyable.vue b/src/components/InputCopyable.vue
index a69a039a4..1c4f3dfe9 100644
--- a/src/components/InputCopyable.vue
+++ b/src/components/InputCopyable.vue
@@ -1,13 +1,14 @@
diff --git a/src/components/SpanCopyable.vue b/src/components/SpanCopyable.vue
index 5643cff9a..1c0a3f07b 100644
--- a/src/components/SpanCopyable.vue
+++ b/src/components/SpanCopyable.vue
@@ -1,13 +1,14 @@
diff --git a/src/components/TextareaCopyable.vue b/src/components/TextareaCopyable.vue
index 8b0aae617..dab5ca9b1 100644
--- a/src/components/TextareaCopyable.vue
+++ b/src/components/TextareaCopyable.vue
@@ -8,6 +8,7 @@ import xmlHljs from 'highlight.js/lib/languages/xml';
import yamlHljs from 'highlight.js/lib/languages/yaml';
import iniHljs from 'highlight.js/lib/languages/ini';
import { useCopy } from '@/composable/copy';
+import { translate as t } from '@/plugins/i18n.plugin';
const props = withDefaults(
defineProps<{
@@ -21,7 +22,7 @@ const props = withDefaults(
followHeightOf: null,
language: 'txt',
copyPlacement: 'top-right',
- copyMessage: 'Copy to clipboard',
+ copyMessage: t('components.textareaCopyable.copyToClipboard'),
},
);
hljs.registerLanguage('sql', sqlHljs);
@@ -35,7 +36,7 @@ const { value, language, followHeightOf, copyPlacement, copyMessage } = toRefs(p
const { height } = followHeightOf.value ? useElementSize(followHeightOf) : { height: ref(null) };
const { copy, isJustCopied } = useCopy({ source: value, createToast: false });
-const tooltipText = computed(() => isJustCopied.value ? 'Copied!' : copyMessage.value);
+const tooltipText = computed(() => isJustCopied.value ? t('components.textareaCopyable.copied') : copyMessage.value);
diff --git a/src/layouts/tool.layout.vue b/src/layouts/tool.layout.vue
index aa808f1cd..f3813fb2d 100644
--- a/src/layouts/tool.layout.vue
+++ b/src/layouts/tool.layout.vue
@@ -7,14 +7,17 @@ import BaseLayout from './base.layout.vue';
import FavoriteButton from '@/components/FavoriteButton.vue';
import type { Tool } from '@/tools/tools.types';
+const { t } = useI18n();
+
const route = useRoute();
+const i18nKey = computed(() => route.path.trim().replace('/', ''));
const head = computed(() => ({
- title: `${route.meta.name} - IT Tools`,
+ title: `${t(`tools.${i18nKey.value}.title`)} - IT Tools`,
meta: [
{
name: 'description',
- content: route.meta?.description as string,
+ content: t(`tools.${i18nKey.value}.description`),
},
{
name: 'keywords',
@@ -23,9 +26,7 @@ const head = computed(() => ({
],
}));
useHead(head);
-const { t } = useI18n();
-const i18nKey = computed(() => route.path.trim().replace('/', ''));
const toolTitle = computed(() => t(`tools.${i18nKey.value}.title`, String(route.meta.name)));
const toolDescription = computed(() => t(`tools.${i18nKey.value}.description`, String(route.meta.description)));
diff --git a/src/modules/command-palette/command-palette.vue b/src/modules/command-palette/command-palette.vue
index bceef5cdc..eafa2d685 100644
--- a/src/modules/command-palette/command-palette.vue
+++ b/src/modules/command-palette/command-palette.vue
@@ -125,7 +125,7 @@ function activateOption(option: PaletteOption) {
-
+
diff --git a/src/tools/benchmark-builder/index.ts b/src/tools/benchmark-builder/index.ts
index 426d287a2..788f0f1a2 100644
--- a/src/tools/benchmark-builder/index.ts
+++ b/src/tools/benchmark-builder/index.ts
@@ -1,11 +1,11 @@
import { SpeedFilled } from '@vicons/material';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.benchmark-builder.title'),
+ name: t('tools.benchmark-builder.title'),
path: '/benchmark-builder',
- description: translate('tools.benchmark-builder.description'),
+ description: t('tools.benchmark-builder.description'),
keywords: ['benchmark', 'builder', 'execution', 'duration', 'mean', 'variance'],
component: () => import('./benchmark-builder.vue'),
icon: SpeedFilled,
diff --git a/src/tools/benchmark-builder/locales/en.yml b/src/tools/benchmark-builder/locales/en.yml
new file mode 100644
index 000000000..650d52a69
--- /dev/null
+++ b/src/tools/benchmark-builder/locales/en.yml
@@ -0,0 +1,26 @@
+tools:
+ benchmark-builder:
+ title: Benchmark builder
+ description: Easily compare execution time of tasks with this very simple online benchmark builder.
+
+ header:
+ position: Position
+ title: Suite
+ size: Samples
+ mean: Mean
+ variance: Variance
+ suiteNameLabel: Suite name
+ suiteNamePlaceholder: Suite name...
+ suiteValues: Suite values
+ suiteTitle: Suite {index}
+ deleteSuite: Delete suite
+ addSuite: Add suite
+ resetSuites: Reset suites
+ unitLabel: Unit
+ unitPlaceholder: 'Unit (eg: ms)'
+ setYourMeasure: Set your measure...
+ deleteThisValue: Delete this value
+ addAMeasure: Add a measure
+
+ copyAsMarkdown: Copy as markdown table
+ copyAsBulletList: Copy as bullet list
diff --git a/src/tools/benchmark-builder/locales/fr.yml b/src/tools/benchmark-builder/locales/fr.yml
new file mode 100644
index 000000000..a4eac87bd
--- /dev/null
+++ b/src/tools/benchmark-builder/locales/fr.yml
@@ -0,0 +1,26 @@
+tools:
+ benchmark-builder:
+ title: Constructeur de benchmark
+ description: Comparez facilement le temps d'exécution des tâches avec ce constructeur de benchmark en ligne très simple.
+
+ header:
+ position: Position
+ title: Suite
+ size: Samples
+ mean: Moyenne
+ variance: Variance
+ suiteNameLabel: Nom de la suite
+ suiteNamePlaceholder: Nom de la suite...
+ suiteValues: Valeurs de la suite
+ suiteTitle: Suite {index}
+ deleteSuite: Supprimer la suite
+ addSuite: Ajouter une suite
+ resetSuites: Réinitialiser les suites
+ unitLabel: Unité
+ unitPlaceholder: 'Unité (par ex : ms)'
+ setYourMeasure: Définissez votre mesure...
+ deleteThisValue: Supprimer cette valeur
+ addAMeasure: Ajouter une mesure
+
+ copyAsMarkdown: Copier en tant que tableau markdown
+ copyAsBulletList: Copier en tant que liste à puces
\ No newline at end of file
diff --git a/src/tools/benchmark-builder/locales/zh.yml b/src/tools/benchmark-builder/locales/zh.yml
new file mode 100644
index 000000000..739cecf78
--- /dev/null
+++ b/src/tools/benchmark-builder/locales/zh.yml
@@ -0,0 +1,26 @@
+tools:
+ benchmark-builder:
+ title: 基准测试生成器
+ description: 使用这个非常简单的在线基准测试生成器轻松比较任务的执行时间。
+
+ header:
+ position: 位置
+ title: 套件
+ size: 样本数
+ mean: 平均值
+ variance: 方差
+ suiteNameLabel: 套件名称
+ suiteNamePlaceholder: 输入套件名称...
+ suiteValues: 套件数值
+ suiteTitle: 套件 {index}
+ deleteSuite: 删除套件
+ addSuite: 添加套件
+ resetSuites: 重置套件
+ unitLabel: 单位
+ unitPlaceholder: '单位(例如:毫秒)'
+ setYourMeasure: 设置您的度量...
+ deleteThisValue: 删除此数值
+ addAMeasure: 添加一个度量
+
+ copyAsMarkdown: 复制为 markdown 表格
+ copyAsBulletList: 复制为项目列表
diff --git a/src/tools/bip39-generator/bip39-generator.vue b/src/tools/bip39-generator/bip39-generator.vue
index a07941b2c..dba97aea7 100644
--- a/src/tools/bip39-generator/bip39-generator.vue
+++ b/src/tools/bip39-generator/bip39-generator.vue
@@ -36,6 +36,7 @@ const languages = {
const entropy = ref(generateEntropy());
const passphraseInput = ref('');
+const { t } = useI18n();
const language = ref('English');
const passphrase = computed({
@@ -53,11 +54,11 @@ const entropyValidation = useValidation({
rules: [
{
validator: value => value === '' || (value.length <= 32 && value.length >= 16 && value.length % 4 === 0),
- message: 'Entropy length should be >= 16, <= 32 and be a multiple of 4',
+ message: t('tools.bip39-generator.validation.lengthError'),
},
{
validator: value => /^[a-fA-F0-9]*$/.test(value),
- message: 'Entropy should be an hexadecimal string',
+ message: t('tools.bip39-generator.validation.stringTypeError'),
},
],
});
@@ -67,7 +68,7 @@ const mnemonicValidation = useValidation({
rules: [
{
validator: value => isNotThrowing(() => mnemonicToEntropy(value, languages[language.value])),
- message: 'Invalid mnemonic',
+ message: t('tools.bip39-generator.validation.mnemonicError'),
},
],
});
@@ -76,8 +77,8 @@ function refreshEntropy() {
entropy.value = generateEntropy();
}
-const { copy: copyEntropy } = useCopy({ source: entropy, text: 'Entropy copied to the clipboard' });
-const { copy: copyPassphrase } = useCopy({ source: passphrase, text: 'Passphrase copied to the clipboard' });
+const { copy: copyEntropy } = useCopy({ source: entropy, text: t('tools.bip39-generator.copied.entropy') });
+const { copy: copyPassphrase } = useCopy({ source: passphrase, text: t('tools.bip39-generator.copied.passphrase') });
@@ -87,18 +88,18 @@ const { copy: copyPassphrase } = useCopy({ source: passphrase, text: 'Passphrase
-
+
@@ -115,12 +116,12 @@ const { copy: copyPassphrase } = useCopy({ source: passphrase, text: 'Passphrase
-
+
diff --git a/src/tools/bip39-generator/index.ts b/src/tools/bip39-generator/index.ts
index 40582da48..c51cce934 100644
--- a/src/tools/bip39-generator/index.ts
+++ b/src/tools/bip39-generator/index.ts
@@ -1,11 +1,11 @@
import { AlignJustified } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.bip39-generator.title'),
+ name: t('tools.bip39-generator.title'),
path: '/bip39-generator',
- description: translate('tools.bip39-generator.description'),
+ description: t('tools.bip39-generator.description'),
keywords: ['BIP39', 'passphrase', 'generator', 'mnemonic', 'entropy'],
component: () => import('./bip39-generator.vue'),
icon: AlignJustified,
diff --git a/src/tools/bip39-generator/locales/en.yml b/src/tools/bip39-generator/locales/en.yml
new file mode 100644
index 000000000..341360de6
--- /dev/null
+++ b/src/tools/bip39-generator/locales/en.yml
@@ -0,0 +1,18 @@
+tools:
+ bip39-generator:
+ title: BIP39 passphrase generator
+ description: Generate BIP39 passphrase from existing or random mnemonic, or get the mnemonic from the passphrase.
+
+ languageLabel: 'Language:'
+ entropyLabel: 'Entropy (seed):'
+ entropyPlaceholder: Your string...
+ passphraseLabel: 'Passphrase (mnemonic):'
+ passphrasePlaceholder: Your mnemonic...
+
+ validation:
+ lengthError: 'Entropy length should be >= 16, <= 32 and be a multiple of 4'
+ stringTypeError: Entropy should be an hexadecimal string
+ mnemonicError: Invalid mnemonic
+ copied:
+ entropy: Entropy copied to the clipboard
+ passphrase: Passphrase copied to the clipboard
diff --git a/src/tools/bip39-generator/locales/fr.yml b/src/tools/bip39-generator/locales/fr.yml
new file mode 100644
index 000000000..4d82e9527
--- /dev/null
+++ b/src/tools/bip39-generator/locales/fr.yml
@@ -0,0 +1,18 @@
+tools:
+ bip39-generator:
+ title: Générateur de phrase secrète BIP39
+ description: Génère une phrase secrète BIP39 à partir d'une mnémonique existante ou aléatoire, ou obtenez la mnémonique à partir de la phrase secrète.
+
+ languageLabel: 'Langue :'
+ entropyLabel: 'Entropie (graine) :'
+ entropyPlaceholder: Votre chaîne...
+ passphraseLabel: 'Phrase secrète (mnémonique) :'
+ passphrasePlaceholder: Votre mnémonique...
+
+ validation:
+ lengthError: "La longueur de l'entropie doit être >= 16, <= 32 et être un multiple de 4"
+ stringTypeError: L'entropie doit être une chaîne hexadécimale
+ mnemonicError: Mnémonique invalide
+ copied:
+ entropy: Entropie copiée dans le presse-papiers
+ passphrase: Phrase secrète copiée dans le presse-papiers
\ No newline at end of file
diff --git a/src/tools/bip39-generator/locales/zh.yml b/src/tools/bip39-generator/locales/zh.yml
new file mode 100644
index 000000000..dfc1d34e7
--- /dev/null
+++ b/src/tools/bip39-generator/locales/zh.yml
@@ -0,0 +1,18 @@
+tools:
+ bip39-generator:
+ title: BIP39 助记词生成器
+ description: 从现有或随机助记词生成 BIP39 助记词,或从助记词获取助记词。
+
+ languageLabel: '语言:'
+ entropyLabel: '熵(种子):'
+ entropyPlaceholder: 您的字符串...
+ passphraseLabel: '助记词(口令):'
+ passphrasePlaceholder: 您的助记词...
+
+ validation:
+ lengthError: '熵的长度应为 >= 16,<= 32,并且是4的倍数'
+ stringTypeError: 熵应为十六进制字符串
+ mnemonicError: 无效的助记词
+ copied:
+ entropy: 熵已复制到剪贴板
+ passphrase: 助记词已复制到剪贴板
diff --git a/src/tools/camera-recorder/camera-recorder.vue b/src/tools/camera-recorder/camera-recorder.vue
index 23fedd8ca..d075cff36 100644
--- a/src/tools/camera-recorder/camera-recorder.vue
+++ b/src/tools/camera-recorder/camera-recorder.vue
@@ -19,6 +19,8 @@ const {
},
});
+const { t } = useI18n();
+
const video = ref();
const medias = ref([]);
const currentCamera = ref(cameras.value[0]?.deviceId);
@@ -106,20 +108,19 @@ function downloadMedia({ type, value, createdAt }: Media) {
- Your browser does not support recording video from camera
+ {{ t('tools.camera-recorder.unSupported') }}
- You need to grant permission to use your camera and microphone
+ {{ t('tools.camera-recorder.needPermissionGranted') }}
- Your browser has blocked permission request or does not support it. You need to grant permission manually in
- your browser settings (usually the lock icon in the address bar).
+ {{ t('tools.camera-recorder.permissionCannotBePrompted') }}
- Grant permission
+ {{ t('tools.camera-recorder.grantPermission') }}
-
+
{{ decryptError }}
diff --git a/src/tools/encryption/index.ts b/src/tools/encryption/index.ts
index c8dd85dbf..8951954ca 100644
--- a/src/tools/encryption/index.ts
+++ b/src/tools/encryption/index.ts
@@ -1,11 +1,11 @@
import { Lock } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.encryption.title'),
+ name: t('tools.encryption.title'),
path: '/encryption',
- description: translate('tools.encryption.description'),
+ description: t('tools.encryption.description'),
keywords: ['cypher', 'encipher', 'text', 'AES', 'TripleDES', 'Rabbit', 'RC4'],
component: () => import('./encryption.vue'),
icon: Lock,
diff --git a/src/tools/encryption/locales/en.yml b/src/tools/encryption/locales/en.yml
new file mode 100644
index 000000000..724ee5d49
--- /dev/null
+++ b/src/tools/encryption/locales/en.yml
@@ -0,0 +1,24 @@
+tools:
+ encryption:
+ title: Encrypt / decrypt text
+ description: Encrypt and decrypt text clear text using crypto algorithm like AES, TripleDES, Rabbit or RC4.
+
+ encrypt:
+ title: Encrypt
+ inputLabel: 'Your text:'
+ inputPlaceholder: The string to cypher
+ secretLabel: 'Your secret key:'
+ algoLabel: 'Encryption algorithm:'
+ outputLabel: 'Your text encrypted:'
+ outputPlaceholder: Your string hash
+ decrypt:
+ title: Decrypt
+ inputLabel: 'Your encrypted text:'
+ inputPlaceholder: The string to cypher
+ secretLabel: 'Your secret key:'
+ algoLabel: 'Encryption algorithm:'
+ outputLabel: 'Your decrypted text:'
+ outputPlaceholder: Your string hash
+ decryptError: Error while decrypting
+
+ errorMessage: Unable to decrypt your text
\ No newline at end of file
diff --git a/src/tools/encryption/locales/fr.yml b/src/tools/encryption/locales/fr.yml
new file mode 100644
index 000000000..b0d60dd75
--- /dev/null
+++ b/src/tools/encryption/locales/fr.yml
@@ -0,0 +1,24 @@
+tools:
+ encryption:
+ title: Chiffrer / déchiffrer du texte
+ description: Chiffrer et déchiffrer du texte en clair en utilisant des algorithmes de cryptage comme AES, TripleDES, Rabbit ou RC4.
+
+ encrypt:
+ title: Chiffrer
+ inputLabel: 'Votre texte :'
+ inputPlaceholder: La chaîne à chiffrer
+ secretLabel: 'Votre clé secrète :'
+ algoLabel: 'Algorithme de chiffrement :'
+ outputLabel: 'Votre texte chiffré :'
+ outputPlaceholder: Votre hachage de chaîne
+ decrypt:
+ title: Déchiffrer
+ inputLabel: 'Votre texte chiffré :'
+ inputPlaceholder: La chaîne à chiffrer
+ secretLabel: 'Votre clé secrète :'
+ algoLabel: 'Algorithme de chiffrement :'
+ outputLabel: 'Votre texte déchiffré :'
+ outputPlaceholder: Votre hachage de chaîne
+ decryptError: Erreur lors du déchiffrement
+
+ errorMessage: Impossible de déchiffrer votre texte
diff --git a/src/tools/encryption/locales/zh.yml b/src/tools/encryption/locales/zh.yml
new file mode 100644
index 000000000..b90ebd4a9
--- /dev/null
+++ b/src/tools/encryption/locales/zh.yml
@@ -0,0 +1,24 @@
+tools:
+ encryption:
+ title: 加密/解密文本
+ description: 使用 AES、TripleDES、Rabbit 或 RC4 等加密算法对文本进行加密和解密。
+
+ encrypt:
+ title: 加密
+ inputLabel: '您的文本:'
+ inputPlaceholder: 要加密的字符串
+ secretLabel: '您的密钥:'
+ algoLabel: '加密算法:'
+ outputLabel: '加密后的文本:'
+ outputPlaceholder: 您的字符串哈希值
+ decrypt:
+ title: 解密
+ inputLabel: '您的加密文本:'
+ inputPlaceholder: 要解密的字符串
+ secretLabel: '您的密钥:'
+ algoLabel: '加密算法:'
+ outputLabel: '解密后的文本:'
+ outputPlaceholder: 您的字符串哈希值
+ decryptError: 解密时出错
+
+ errorMessage: 无法解密您的文本
diff --git a/src/tools/eta-calculator/eta-calculator.service.ts b/src/tools/eta-calculator/eta-calculator.service.ts
index 6c061a9da..f5f63c88f 100644
--- a/src/tools/eta-calculator/eta-calculator.service.ts
+++ b/src/tools/eta-calculator/eta-calculator.service.ts
@@ -1,6 +1,7 @@
import { formatDuration } from 'date-fns';
+import type { Locale } from 'date-fns';
-export function formatMsDuration(duration: number) {
+export function formatMsDuration(duration: number, locale: Locale) {
const ms = Math.floor(duration % 1000);
const secs = Math.floor(((duration - ms) / 1000) % 60);
const mins = Math.floor((((duration - ms) / 1000 - secs) / 60) % 60);
@@ -11,6 +12,6 @@ export function formatMsDuration(duration: number) {
hours: hrs,
minutes: mins,
seconds: secs,
- }) + (ms > 0 ? ` ${ms} ms` : '')
+ }, { locale }) + (ms > 0 ? ` ${ms} ms` : '')
);
}
diff --git a/src/tools/eta-calculator/eta-calculator.vue b/src/tools/eta-calculator/eta-calculator.vue
index e1c36a62b..f8071f457 100644
--- a/src/tools/eta-calculator/eta-calculator.vue
+++ b/src/tools/eta-calculator/eta-calculator.vue
@@ -3,57 +3,58 @@
import { addMilliseconds, formatRelative } from 'date-fns';
-import { enGB } from 'date-fns/locale';
+import { enGB, zhCN } from 'date-fns/locale';
import { formatMsDuration } from './eta-calculator.service';
+const { t, locale } = useI18n();
const unitCount = ref(3 * 62);
const unitPerTimeSpan = ref(3);
const timeSpan = ref(5);
const timeSpanUnitMultiplier = ref(60000);
const startedAt = ref(Date.now());
+const localeLang = computed(() => locale.value === 'zh' ? zhCN : enGB);
const durationMs = computed(() => {
const timeSpanMs = timeSpan.value * timeSpanUnitMultiplier.value;
return unitCount.value / (unitPerTimeSpan.value / timeSpanMs);
});
const endAt = computed(() =>
- formatRelative(addMilliseconds(startedAt.value, durationMs.value), Date.now(), { locale: enGB }),
+ formatRelative(addMilliseconds(startedAt.value, durationMs.value), Date.now(), { locale: localeLang.value }),
);
- With a concrete example, if you wash 5 plates in 3 minutes and you have 500 plates to wash, it will take you 5
- hours to wash them all.
+ {{ t('tools.eta-calculator.tips') }}
-
+
-
+
-
Amount of unit consumed by time span
+
{{ t('tools.eta-calculator.unitPerTimeSpan') }}
- in
+ {{ t('tools.eta-calculator.in') }}
@@ -61,12 +62,12 @@ const endAt = computed(() =>
-
- {{ formatMsDuration(durationMs) }}
+
+ {{ formatMsDuration(durationMs, localeLang) }}
-
+
{{ endAt }}
diff --git a/src/tools/eta-calculator/index.ts b/src/tools/eta-calculator/index.ts
index 5016ab666..c16d6ceb8 100644
--- a/src/tools/eta-calculator/index.ts
+++ b/src/tools/eta-calculator/index.ts
@@ -1,11 +1,11 @@
import { Hourglass } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.eta-calculator.title'),
+ name: t('tools.eta-calculator.title'),
path: '/eta-calculator',
- description: translate('tools.eta-calculator.description'),
+ description: t('tools.eta-calculator.description'),
keywords: ['eta', 'calculator', 'estimated', 'time', 'arrival', 'average'],
component: () => import('./eta-calculator.vue'),
icon: Hourglass,
diff --git a/src/tools/eta-calculator/locales/en.yml b/src/tools/eta-calculator/locales/en.yml
new file mode 100644
index 000000000..a24699109
--- /dev/null
+++ b/src/tools/eta-calculator/locales/en.yml
@@ -0,0 +1,17 @@
+tools:
+ eta-calculator:
+ title: ETA calculator
+ description: An ETA (Estimated Time of Arrival) calculator to know the approximate end time of a task, for example the moment of ending of a download.
+
+ tips: With a concrete example, if you wash 5 plates in 3 minutes and you have 500 plates to wash, it will take you 5 hours to wash them all.
+ unitCount: Amount of element to consume
+ startedAt: The consumption started at
+ unitPerTimeSpan: Amount of unit consumed by time span
+ in: in
+ milliseconds: milliseconds
+ seconds: seconds
+ minutes: minutes
+ hours: hours
+ days: days
+ totalDuration: Total duration
+ endAt: It will end
diff --git a/src/tools/eta-calculator/locales/fr.yml b/src/tools/eta-calculator/locales/fr.yml
new file mode 100644
index 000000000..ab50761c2
--- /dev/null
+++ b/src/tools/eta-calculator/locales/fr.yml
@@ -0,0 +1,17 @@
+tools:
+ eta-calculator:
+ title: Calculateur d'ETA
+ description: Un calculateur d'ETA (Heure d'Arrivée Estimée) pour connaître l'heure approximative de fin d'une tâche, par exemple le moment de la fin d'un téléchargement.
+
+ tips: Avec un exemple concret, si vous lavez 5 assiettes en 3 minutes et que vous avez 500 assiettes à laver, il vous faudra 5 heures pour tout laver.
+ unitCount: Quantité d'élément à consommer
+ startedAt: La consommation a commencé à
+ unitPerTimeSpan: Quantité d'unité consommée par intervalle de temps
+ in: en
+ milliseconds: millisecondes
+ seconds: secondes
+ minutes: minutes
+ hours: heures
+ days: jours
+ totalDuration: Durée totale
+ endAt: Cela se terminera à
diff --git a/src/tools/eta-calculator/locales/zh.yml b/src/tools/eta-calculator/locales/zh.yml
new file mode 100644
index 000000000..0a8a769e7
--- /dev/null
+++ b/src/tools/eta-calculator/locales/zh.yml
@@ -0,0 +1,17 @@
+tools:
+ eta-calculator:
+ title: 预计到达时间计算器
+ description: 一个预计到达时间(ETA)计算器,用于了解任务的大致结束时间,例如下载结束的时间。
+
+ tips: 以一个具体的例子来说,如果你用 3 分钟洗 5 个盘子,而你有 500 个盘子要洗,那么你需要 5 个小时来洗完所有盘子。
+ unitCount: 要消耗的元素数量
+ startedAt: 消耗开始于
+ unitPerTimeSpan: 每个时间段消耗的单位数量
+ in: 用
+ milliseconds: 毫秒
+ seconds: 秒
+ minutes: 分钟
+ hours: 小时
+ days: 天
+ totalDuration: 总持续时间
+ endAt: 它将在以下时间结束
diff --git a/src/tools/git-memo/git-memo.content.fr.md b/src/tools/git-memo/git-memo.content.fr.md
new file mode 100644
index 000000000..7d1877244
--- /dev/null
+++ b/src/tools/git-memo/git-memo.content.fr.md
@@ -0,0 +1,77 @@
+## Configuration
+
+Définir la configuration globale
+
+```shell
+git config --global user.name "[name]"
+git config --global user.email "[email]"
+```
+
+## Commencer
+
+Créer un dépôt git
+
+```shell
+git init
+```
+
+Cloner un dépôt git existant
+
+```shell
+git clone [url]
+```
+
+## Commit
+
+Valider tous les changements suivis
+
+```shell
+git commit -am "[commit message]"
+```
+
+Ajouter de nouvelles modifications au dernier commit
+
+```shell
+git commit --amend --no-edit
+```
+
+## J'ai fait une erreur
+
+Changer le message du dernier commit
+
+```shell
+git commit --amend
+```
+
+Annuler le commit le plus récent et conserver les changements
+
+```shell
+git reset HEAD~1
+```
+
+Annuler les `N` commits les plus récents et conserver les changements
+
+```shell
+git reset HEAD~N
+```
+
+Annuler le commit le plus récent et se débarrasser des changements
+
+```shell
+git reset HEAD~1 --hard
+```
+
+Réinitialiser la branche à l'état distant
+
+```shell
+git fetch origin
+git reset --hard origin/[branch-name]
+```
+
+## Divers
+
+Renommer la branche locale master en main
+
+```shell
+git branch -m master main
+```
diff --git a/src/tools/git-memo/git-memo.content.zh.md b/src/tools/git-memo/git-memo.content.zh.md
new file mode 100644
index 000000000..3cdae05db
--- /dev/null
+++ b/src/tools/git-memo/git-memo.content.zh.md
@@ -0,0 +1,77 @@
+## 配置
+
+设置全局配置
+
+```shell
+git config --global user.name "[姓名]"
+git config --global user.email "[邮箱]"
+```
+
+## 入门
+
+创建一个 git 仓库
+
+```shell
+git init
+```
+
+克隆现有的 git 仓库
+
+```shell
+git clone [url]
+```
+
+## 提交
+
+提交所有已跟踪的更改
+
+```shell
+git commit -am "[提交信息]"
+```
+
+将新修改添加到上次提交中
+
+```shell
+git commit --amend --no-edit
+```
+
+## 我犯了一个错误
+
+更改上次提交的消息
+
+```shell
+git commit --amend
+```
+
+撤消最近的提交并保留更改
+
+```shell
+git reset HEAD~1
+```
+
+撤消最近的 `N` 个提交并保留更改
+
+```shell
+git reset HEAD~N
+```
+
+撤消最近的提交并放弃更改
+
+```shell
+git reset HEAD~1 --hard
+```
+
+将分支重置为远程状态
+
+```shell
+git fetch origin
+git reset --hard origin/[分支名]
+```
+
+## 其他
+
+将本地 master 分支重命名为 main
+
+```shell
+git branch -m master main
+```
\ No newline at end of file
diff --git a/src/tools/git-memo/git-memo.vue b/src/tools/git-memo/git-memo.vue
index 12bf9fc0b..a5fd603e3 100644
--- a/src/tools/git-memo/git-memo.vue
+++ b/src/tools/git-memo/git-memo.vue
@@ -1,13 +1,16 @@
-
+
+
diff --git a/src/tools/git-memo/index.ts b/src/tools/git-memo/index.ts
index f65ffe074..8a5989e8f 100644
--- a/src/tools/git-memo/index.ts
+++ b/src/tools/git-memo/index.ts
@@ -1,11 +1,11 @@
import { BrandGit } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.git-memo.title'),
+ name: t('tools.git-memo.title'),
path: '/git-memo',
- description: translate('tools.git-memo.description'),
+ description: t('tools.git-memo.description'),
keywords: ['git', 'push', 'force', 'pull', 'commit', 'amend', 'rebase', 'merge', 'reset', 'soft', 'hard', 'lease'],
component: () => import('./git-memo.vue'),
icon: BrandGit,
diff --git a/src/tools/git-memo/locales/en.yml b/src/tools/git-memo/locales/en.yml
new file mode 100644
index 000000000..f435a3e17
--- /dev/null
+++ b/src/tools/git-memo/locales/en.yml
@@ -0,0 +1,4 @@
+tools:
+ git-memo:
+ title: Git cheatsheet
+ description: Git is a decentralized version management software. With this cheatsheet you will have a quick access to the most common git commands.
diff --git a/src/tools/git-memo/locales/fr.yml b/src/tools/git-memo/locales/fr.yml
new file mode 100644
index 000000000..e82650662
--- /dev/null
+++ b/src/tools/git-memo/locales/fr.yml
@@ -0,0 +1,4 @@
+tools:
+ git-memo:
+ title: Feuille de triche Git
+ description: Git est un logiciel de gestion de version décentralisé. Avec cette feuille de triche, vous aurez un accès rapide aux commandes Git les plus courantes.
diff --git a/src/tools/git-memo/locales/zh.yml b/src/tools/git-memo/locales/zh.yml
new file mode 100644
index 000000000..f4fb9acec
--- /dev/null
+++ b/src/tools/git-memo/locales/zh.yml
@@ -0,0 +1,4 @@
+tools:
+ git-memo:
+ title: Git 备忘录
+ description: Git 是一款分布式版本管理软件。使用这个备忘录,您将快速访问最常用的 Git 命令。
diff --git a/src/tools/hash-text/hash-text.vue b/src/tools/hash-text/hash-text.vue
index 6eae98186..300594822 100644
--- a/src/tools/hash-text/hash-text.vue
+++ b/src/tools/hash-text/hash-text.vue
@@ -22,6 +22,7 @@ type Encoding = keyof typeof enc | 'Bin';
const algoNames = Object.keys(algos) as AlgoNames[];
const encoding = useQueryParam({ defaultValue: 'Hex', name: 'encoding' });
const clearText = ref('');
+const { t } = useI18n();
function formatWithEncoding(words: lib.WordArray, encoding: Encoding) {
if (encoding === 'Bin') {
@@ -37,29 +38,38 @@ const hashText = (algo: AlgoNames, value: string) => formatWithEncoding(algos[al
diff --git a/src/tools/html-entities/index.ts b/src/tools/html-entities/index.ts
index e292f087e..74583aad0 100644
--- a/src/tools/html-entities/index.ts
+++ b/src/tools/html-entities/index.ts
@@ -1,11 +1,11 @@
import { Code } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.html-entities.title'),
+ name: t('tools.html-entities.title'),
path: '/html-entities',
- description: translate('tools.html-entities.description'),
+ description: t('tools.html-entities.description'),
keywords: ['html', 'entities', 'escape', 'unescape', 'special', 'characters', 'tags'],
component: () => import('./html-entities.vue'),
icon: Code,
diff --git a/src/tools/html-entities/locales/en.yml b/src/tools/html-entities/locales/en.yml
new file mode 100644
index 000000000..aaaf0ea45
--- /dev/null
+++ b/src/tools/html-entities/locales/en.yml
@@ -0,0 +1,19 @@
+tools:
+ html-entities:
+ title: Escape html entities
+ description: Escape or unescape html entities (replace <,>, &, " and ' to their html version)
+
+ escape:
+ title: Escape html entities
+ inputLabel: 'Your string :'
+ inputPlaceholder: The string to escape
+ outputLabel: 'Your string escaped :'
+ outputPlaceholder: Your string escaped
+ unescape:
+ title: Unescape html entities
+ inputLabel: 'Your escaped string :'
+ inputPlaceholder: The string to unescape
+ outputLabel: 'Your string unescaped :'
+ outputPlaceholder: Your string unescaped
+
+ copy: Copy
diff --git a/src/tools/html-entities/locales/fr.yml b/src/tools/html-entities/locales/fr.yml
new file mode 100644
index 000000000..69d67ffea
--- /dev/null
+++ b/src/tools/html-entities/locales/fr.yml
@@ -0,0 +1,19 @@
+tools:
+ html-entities:
+ title: Échapper aux entités HTML
+ description: Échappe ou déséchappe les entités HTML (remplace <,>, &, " et ' par leur version HTML)
+
+ escape:
+ title: Échapper aux entités HTML
+ inputLabel: 'Votre chaîne :'
+ inputPlaceholder: La chaîne à échapper
+ outputLabel: 'Votre chaîne échappée :'
+ outputPlaceholder: Votre chaîne échappée
+ unescape:
+ title: Déséchapper les entités HTML
+ inputLabel: 'Votre chaîne échappée :'
+ inputPlaceholder: La chaîne à déséchapper
+ outputLabel: 'Votre chaîne déséchappée :'
+ outputPlaceholder: Votre chaîne déséchappée
+
+ copy: Copier
diff --git a/src/tools/html-entities/locales/zh.yml b/src/tools/html-entities/locales/zh.yml
new file mode 100644
index 000000000..4288d8529
--- /dev/null
+++ b/src/tools/html-entities/locales/zh.yml
@@ -0,0 +1,19 @@
+tools:
+ html-entities:
+ title: 转义 HTML 实体
+ description: 转义或取消转义 HTML 实体(将 <,>, &, " 和 ' 替换为它们的 HTML 版本)
+
+ escape:
+ title: 转义 HTML 实体
+ inputLabel: '输入字符串:'
+ inputPlaceholder: 要转义的字符串
+ outputLabel: '转义后的字符串:'
+ outputPlaceholder: 转义后的字符串
+ unescape:
+ title: 取消转义 HTML 实体
+ inputLabel: '输入转义后的字符串:'
+ inputPlaceholder: 要取消转义的字符串
+ outputLabel: '取消转义后的字符串:'
+ outputPlaceholder: 取消转义后的字符串
+
+ copy: 复制
diff --git a/src/tools/html-wysiwyg-editor/editor/menu-bar.vue b/src/tools/html-wysiwyg-editor/editor/menu-bar.vue
index d3ad31686..cc3079c68 100644
--- a/src/tools/html-wysiwyg-editor/editor/menu-bar.vue
+++ b/src/tools/html-wysiwyg-editor/editor/menu-bar.vue
@@ -20,6 +20,7 @@ import {
} from '@vicons/tabler';
import type { Component } from 'vue';
import MenuBarItem from './menu-bar-item.vue';
+import { translate as t } from '@/plugins/i18n.plugin';
const props = defineProps<{ editor: Editor }>();
const { editor } = toRefs(props);
@@ -38,28 +39,28 @@ const items: MenuItem[] = [
{
type: 'button',
icon: Bold,
- title: 'Bold',
+ title: t('tools.html-wysiwyg-editor.bold'),
action: () => editor.value.chain().focus().toggleBold().run(),
isActive: () => editor.value.isActive('bold'),
},
{
type: 'button',
icon: Italic,
- title: 'Italic',
+ title: t('tools.html-wysiwyg-editor.italic'),
action: () => editor.value.chain().focus().toggleItalic().run(),
isActive: () => editor.value.isActive('italic'),
},
{
type: 'button',
icon: Strikethrough,
- title: 'Strike',
+ title: t('tools.html-wysiwyg-editor.strike'),
action: () => editor.value.chain().focus().toggleStrike().run(),
isActive: () => editor.value.isActive('strike'),
},
{
type: 'button',
icon: Code,
- title: 'Inline code',
+ title: t('tools.html-wysiwyg-editor.inlineCode'),
action: () => editor.value.chain().focus().toggleCode().run(),
isActive: () => editor.value.isActive('code'),
},
@@ -69,28 +70,28 @@ const items: MenuItem[] = [
{
type: 'button',
icon: H1,
- title: 'Heading 1',
+ title: t('tools.html-wysiwyg-editor.heading1'),
action: () => editor.value.chain().focus().toggleHeading({ level: 1 }).run(),
isActive: () => editor.value.isActive('heading', { level: 1 }),
},
{
type: 'button',
icon: H2,
- title: 'Heading 2',
+ title: t('tools.html-wysiwyg-editor.heading2'),
action: () => editor.value.chain().focus().toggleHeading({ level: 2 }).run(),
isActive: () => editor.value.isActive('heading', { level: 2 }),
},
{
type: 'button',
icon: H3,
- title: 'Heading 3',
+ title: t('tools.html-wysiwyg-editor.heading3'),
action: () => editor.value.chain().focus().toggleHeading({ level: 4 }).run(),
isActive: () => editor.value.isActive('heading', { level: 4 }),
},
{
type: 'button',
icon: H4,
- title: 'Heading 4',
+ title: t('tools.html-wysiwyg-editor.heading4'),
action: () => editor.value.chain().focus().toggleHeading({ level: 4 }).run(),
isActive: () => editor.value.isActive('heading', { level: 4 }),
},
@@ -100,21 +101,21 @@ const items: MenuItem[] = [
{
type: 'button',
icon: List,
- title: 'Bullet list',
+ title: t('tools.html-wysiwyg-editor.bulletList'),
action: () => editor.value.chain().focus().toggleBulletList().run(),
isActive: () => editor.value.isActive('bulletList'),
},
{
type: 'button',
icon: ListNumbers,
- title: 'Ordered list',
+ title: t('tools.html-wysiwyg-editor.orderedList'),
action: () => editor.value.chain().focus().toggleOrderedList().run(),
isActive: () => editor.value.isActive('orderedList'),
},
{
type: 'button',
icon: CodePlus,
- title: 'Code block',
+ title: t('tools.html-wysiwyg-editor.codeBlock'),
action: () => editor.value.chain().focus().toggleCodeBlock().run(),
isActive: () => editor.value.isActive('codeBlock'),
},
@@ -122,7 +123,7 @@ const items: MenuItem[] = [
{
type: 'button',
icon: Blockquote,
- title: 'Blockquote',
+ title: t('tools.html-wysiwyg-editor.blockquote'),
action: () => editor.value.chain().focus().toggleBlockquote().run(),
isActive: () => editor.value.isActive('blockquote'),
},
@@ -132,26 +133,26 @@ const items: MenuItem[] = [
{
type: 'button',
icon: TextWrap,
- title: 'Hard break',
+ title: t('tools.html-wysiwyg-editor.hardBreak'),
action: () => editor.value.chain().focus().setHardBreak().run(),
},
{
type: 'button',
icon: ClearFormatting,
- title: 'Clear format',
+ title: t('tools.html-wysiwyg-editor.clearFormat'),
action: () => editor.value.chain().focus().clearNodes().unsetAllMarks().run(),
},
{
type: 'button',
icon: ArrowBack,
- title: 'Undo',
+ title: t('tools.html-wysiwyg-editor.undo'),
action: () => editor.value.chain().focus().undo().run(),
},
{
type: 'button',
icon: ArrowForwardUp,
- title: 'Redo',
+ title: t('tools.html-wysiwyg-editor.redo'),
action: () => editor.value.chain().focus().redo().run(),
},
];
diff --git a/src/tools/html-wysiwyg-editor/index.ts b/src/tools/html-wysiwyg-editor/index.ts
index 3a2ab0077..971be977e 100644
--- a/src/tools/html-wysiwyg-editor/index.ts
+++ b/src/tools/html-wysiwyg-editor/index.ts
@@ -1,11 +1,11 @@
import { Edit } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.html-wysiwyg-editor.title'),
+ name: t('tools.html-wysiwyg-editor.title'),
path: '/html-wysiwyg-editor',
- description: translate('tools.html-wysiwyg-editor.description'),
+ description: t('tools.html-wysiwyg-editor.description'),
keywords: ['html', 'wysiwyg', 'editor', 'p', 'ul', 'ol', 'converter', 'live'],
component: () => import('./html-wysiwyg-editor.vue'),
icon: Edit,
diff --git a/src/tools/html-wysiwyg-editor/locales/en.yml b/src/tools/html-wysiwyg-editor/locales/en.yml
new file mode 100644
index 000000000..f05d4cf3e
--- /dev/null
+++ b/src/tools/html-wysiwyg-editor/locales/en.yml
@@ -0,0 +1,21 @@
+tools:
+ html-wysiwyg-editor:
+ title: HTML WYSIWYG editor
+ description: Online HTML editor with feature-rich WYSIWYG editor, get the source code of the content immediately.
+
+ bold: Bold
+ italic: Italic
+ strike: Strike
+ inlineCode: Inline code
+ heading1: Heading 1
+ heading2: Heading 2
+ heading3: Heading 3
+ heading4: Heading 4
+ bulletList: Bullet list
+ orderedList: Ordered list
+ codeBlock: Code block
+ blockquote: Blockquote
+ hardBreak: Hard break
+ clearFormat: Clear format
+ undo: Undo
+ redo: Redo
diff --git a/src/tools/html-wysiwyg-editor/locales/fr.yml b/src/tools/html-wysiwyg-editor/locales/fr.yml
new file mode 100644
index 000000000..d511fc4a6
--- /dev/null
+++ b/src/tools/html-wysiwyg-editor/locales/fr.yml
@@ -0,0 +1,21 @@
+tools:
+ html-wysiwyg-editor:
+ title: Éditeur HTML WYSIWYG
+ description: Éditeur HTML en ligne avec un éditeur WYSIWYG riche en fonctionnalités, obtenez immédiatement le code source du contenu.
+
+ bold: Gras
+ italic: Italique
+ strike: Barré
+ inlineCode: Code en ligne
+ heading1: Titre 1
+ heading2: Titre 2
+ heading3: Titre 3
+ heading4: Titre 4
+ bulletList: Liste à puces
+ orderedList: Liste ordonnée
+ codeBlock: Bloc de code
+ blockquote: Citation en bloc
+ hardBreak: Saut de ligne forcé
+ clearFormat: Effacer le formatage
+ undo: Annuler
+ redo: Rétablir
diff --git a/src/tools/html-wysiwyg-editor/locales/zh.yml b/src/tools/html-wysiwyg-editor/locales/zh.yml
new file mode 100644
index 000000000..d0e983d04
--- /dev/null
+++ b/src/tools/html-wysiwyg-editor/locales/zh.yml
@@ -0,0 +1,21 @@
+tools:
+ html-wysiwyg-editor:
+ title: HTML所见即所得编辑器
+ description: 在线 HTML 编辑器,具有功能丰富的所见即所得编辑器,可立即获取内容的源代码。
+
+ bold: 粗体
+ italic: 斜体
+ strike: 删除线
+ inlineCode: 行内代码
+ heading1: 标题 1
+ heading2: 标题 2
+ heading3: 标题 3
+ heading4: 标题 4
+ bulletList: 无序列表
+ orderedList: 有序列表
+ codeBlock: 代码块
+ blockquote: 引用块
+ hardBreak: 强制换行
+ clearFormat: 清除格式
+ undo: 撤销
+ redo: 重做
diff --git a/src/tools/http-status-codes/http-status-codes.constants.ts b/src/tools/http-status-codes/http-status-codes.constants.ts
index 279cd7ce6..49268b05a 100644
--- a/src/tools/http-status-codes/http-status-codes.constants.ts
+++ b/src/tools/http-status-codes/http-status-codes.constants.ts
@@ -1,3 +1,5 @@
+import { translate as t } from '@/plugins/i18n.plugin';
+
export const codesByCategories: {
category: string
codes: {
@@ -8,423 +10,404 @@ export const codesByCategories: {
}[]
}[] = [
{
- category: '1xx informational response',
+ category: t('tools.http-status-codes.1xx'),
codes: [
{
code: 100,
- name: 'Continue',
- description: 'Waiting for the client to emit the body of the request.',
+ name: t('tools.http-status-codes.100.name'),
+ description: t('tools.http-status-codes.100.description'),
type: 'HTTP',
},
{
code: 101,
- name: 'Switching Protocols',
- description: 'The server has agreed to change protocol.',
+ name: t('tools.http-status-codes.101.name'),
+ description: t('tools.http-status-codes.101.description'),
type: 'HTTP',
},
{
code: 102,
- name: 'Processing',
- description: 'The server is processing the request, but no response is available yet.',
+ name: t('tools.http-status-codes.102.name'),
+ description: t('tools.http-status-codes.102.description'),
type: 'WebDav',
},
{
code: 103,
- name: 'Early Hints',
- description: 'The server returns some response headers before final HTTP message.',
+ name: t('tools.http-status-codes.103.name'),
+ description: t('tools.http-status-codes.103.description'),
type: 'HTTP',
},
],
},
{
- category: '2xx success',
+ category: t('tools.http-status-codes.2xx'),
codes: [
{
code: 200,
- name: 'OK',
- description: 'Standard response for successful HTTP requests.',
+ name: t('tools.http-status-codes.200.name'),
+ description: t('tools.http-status-codes.200.description'),
type: 'HTTP',
},
{
code: 201,
- name: 'Created',
- description: 'The request has been fulfilled, resulting in the creation of a new resource.',
+ name: t('tools.http-status-codes.201.name'),
+ description: t('tools.http-status-codes.201.description'),
type: 'HTTP',
},
{
code: 202,
- name: 'Accepted',
- description: 'The request has been accepted for processing, but the processing has not been completed.',
+ name: t('tools.http-status-codes.202.name'),
+ description: t('tools.http-status-codes.202.description'),
type: 'HTTP',
},
{
code: 203,
- name: 'Non-Authoritative Information',
- description:
- 'The request is successful but the content of the original request has been modified by a transforming proxy.',
+ name: t('tools.http-status-codes.203.name'),
+ description: t('tools.http-status-codes.203.description'),
type: 'HTTP',
},
{
code: 204,
- name: 'No Content',
- description: 'The server successfully processed the request and is not returning any content.',
+ name: t('tools.http-status-codes.204.name'),
+ description: t('tools.http-status-codes.204.description'),
type: 'HTTP',
},
{
code: 205,
- name: 'Reset Content',
- description: 'The server indicates to reinitialize the document view which sent this request.',
+ name: t('tools.http-status-codes.205.name'),
+ description: t('tools.http-status-codes.205.description'),
type: 'HTTP',
},
{
code: 206,
- name: 'Partial Content',
- description: 'The server is delivering only part of the resource due to a range header sent by the client.',
+ name: t('tools.http-status-codes.206.name'),
+ description: t('tools.http-status-codes.206.description'),
type: 'HTTP',
},
{
code: 207,
- name: 'Multi-Status',
- description:
- 'The message body that follows is an XML message and can contain a number of separate response codes.',
+ name: t('tools.http-status-codes.207.name'),
+ description: t('tools.http-status-codes.207.description'),
type: 'WebDav',
},
{
code: 208,
- name: 'Already Reported',
- description:
- 'The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response.',
+ name: t('tools.http-status-codes.208.name'),
+ description: t('tools.http-status-codes.208.description'),
type: 'WebDav',
},
{
code: 226,
- name: 'IM Used',
- description:
- 'The server has fulfilled a request for the resource, and the response is a representation of the result.',
+ name: t('tools.http-status-codes.226.name'),
+ description: t('tools.http-status-codes.226.description'),
type: 'HTTP',
},
],
},
{
- category: '3xx redirection',
+ category: t('tools.http-status-codes.3xx'),
codes: [
{
code: 300,
- name: 'Multiple Choices',
- description: 'Indicates multiple options for the resource that the client may follow.',
+ name: t('tools.http-status-codes.300.name'),
+ description: t('tools.http-status-codes.300.description'),
type: 'HTTP',
},
{
code: 301,
- name: 'Moved Permanently',
- description: 'This and all future requests should be directed to the given URI.',
+ name: t('tools.http-status-codes.301.name'),
+ description: t('tools.http-status-codes.301.description'),
type: 'HTTP',
},
{
code: 302,
- name: 'Found',
- description: 'Redirect to another URL. This is an example of industry practice contradicting the standard.',
+ name: t('tools.http-status-codes.302.name'),
+ description: t('tools.http-status-codes.302.description'),
type: 'HTTP',
},
{
code: 303,
- name: 'See Other',
- description: 'The response to the request can be found under another URI using a GET method.',
+ name: t('tools.http-status-codes.303.name'),
+ description: t('tools.http-status-codes.303.description'),
type: 'HTTP',
},
{
code: 304,
- name: 'Not Modified',
- description:
- 'Indicates that the resource has not been modified since the version specified by the request headers.',
+ name: t('tools.http-status-codes.304.name'),
+ description: t('tools.http-status-codes.304.description'),
type: 'HTTP',
},
{
code: 305,
- name: 'Use Proxy',
- description:
- 'The requested resource is available only through a proxy, the address for which is provided in the response.',
+ name: t('tools.http-status-codes.305.name'),
+ description: t('tools.http-status-codes.305.description'),
type: 'HTTP',
},
{
code: 306,
- name: 'Switch Proxy',
- description: 'No longer used. Originally meant "Subsequent requests should use the specified proxy."',
+ name: t('tools.http-status-codes.306.name'),
+ description: t('tools.http-status-codes.306.description'),
type: 'HTTP',
},
{
code: 307,
- name: 'Temporary Redirect',
- description:
- 'In this case, the request should be repeated with another URI; however, future requests should still use the original URI.',
+ name: t('tools.http-status-codes.307.name'),
+ description: t('tools.http-status-codes.307.description'),
type: 'HTTP',
},
{
code: 308,
- name: 'Permanent Redirect',
- description: 'The request and all future requests should be repeated using another URI.',
+ name: t('tools.http-status-codes.308.name'),
+ description: t('tools.http-status-codes.308.description'),
type: 'HTTP',
},
],
},
{
- category: '4xx client error',
+ category: t('tools.http-status-codes.4xx'),
codes: [
{
code: 400,
- name: 'Bad Request',
- description: 'The server cannot or will not process the request due to an apparent client error.',
+ name: t('tools.http-status-codes.400.name'),
+ description: t('tools.http-status-codes.400.description'),
type: 'HTTP',
},
{
code: 401,
- name: 'Unauthorized',
- description:
- 'Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.',
+ name: t('tools.http-status-codes.401.name'),
+ description: t('tools.http-status-codes.401.description'),
type: 'HTTP',
},
{
code: 402,
- name: 'Payment Required',
- description:
- 'Reserved for future use. The original intention was that this code might be used as part of some form of digital cash or micropayment scheme.',
+ name: t('tools.http-status-codes.402.name'),
+ description: t('tools.http-status-codes.402.description'),
type: 'HTTP',
},
{
code: 403,
- name: 'Forbidden',
- description:
- 'The request was valid, but the server is refusing action. The user might not have the necessary permissions for a resource.',
+ name: t('tools.http-status-codes.403.name'),
+ description: t('tools.http-status-codes.403.description'),
type: 'HTTP',
},
{
code: 404,
- name: 'Not Found',
- description: 'The requested resource could not be found but may be available in the future.',
+ name: t('tools.http-status-codes.404.name'),
+ description: t('tools.http-status-codes.404.description'),
type: 'HTTP',
},
{
code: 405,
- name: 'Method Not Allowed',
- description: 'A request method is not supported for the requested resource.',
+ name: t('tools.http-status-codes.405.name'),
+ description: t('tools.http-status-codes.405.description'),
type: 'HTTP',
},
{
code: 406,
- name: 'Not Acceptable',
- description:
- 'The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.',
+ name: t('tools.http-status-codes.406.name'),
+ description: t('tools.http-status-codes.406.description'),
type: 'HTTP',
},
{
code: 407,
- name: 'Proxy Authentication Required',
- description: 'The client must first authenticate itself with the proxy.',
+ name: t('tools.http-status-codes.407.name'),
+ description: t('tools.http-status-codes.407.description'),
type: 'HTTP',
},
{
code: 408,
- name: 'Request Timeout',
- description: 'The server timed out waiting for the request.',
+ name: t('tools.http-status-codes.408.name'),
+ description: t('tools.http-status-codes.408.description'),
type: 'HTTP',
},
{
code: 409,
- name: 'Conflict',
- description:
- 'Indicates that the request could not be processed because of conflict in the request, such as an edit conflict.',
+ name: t('tools.http-status-codes.409.name'),
+ description: t('tools.http-status-codes.409.description'),
type: 'HTTP',
},
{
code: 410,
- name: 'Gone',
- description: 'Indicates that the resource requested is no longer available and will not be available again.',
+ name: t('tools.http-status-codes.410.name'),
+ description: t('tools.http-status-codes.410.description'),
type: 'HTTP',
},
{
code: 411,
- name: 'Length Required',
- description:
- 'The request did not specify the length of its content, which is required by the requested resource.',
+ name: t('tools.http-status-codes.411.name'),
+ description: t('tools.http-status-codes.411.description'),
type: 'HTTP',
},
{
code: 412,
- name: 'Precondition Failed',
- description: 'The server does not meet one of the preconditions that the requester put on the request.',
+ name: t('tools.http-status-codes.412.name'),
+ description: t('tools.http-status-codes.412.description'),
type: 'HTTP',
},
{
code: 413,
- name: 'Payload Too Large',
- description: 'The request is larger than the server is willing or able to process.',
+ name: t('tools.http-status-codes.413.name'),
+ description: t('tools.http-status-codes.413.description'),
type: 'HTTP',
},
{
code: 414,
- name: 'URI Too Long',
- description: 'The URI provided was too long for the server to process.',
+ name: t('tools.http-status-codes.414.name'),
+ description: t('tools.http-status-codes.414.description'),
type: 'HTTP',
},
{
code: 415,
- name: 'Unsupported Media Type',
- description: 'The request entity has a media type which the server or resource does not support.',
+ name: t('tools.http-status-codes.415.name'),
+ description: t('tools.http-status-codes.415.description'),
type: 'HTTP',
},
{
code: 416,
- name: 'Range Not Satisfiable',
- description: 'The client has asked for a portion of the file, but the server cannot supply that portion.',
+ name: t('tools.http-status-codes.416.name'),
+ description: t('tools.http-status-codes.416.description'),
type: 'HTTP',
},
{
code: 417,
- name: 'Expectation Failed',
- description: 'The server cannot meet the requirements of the Expect request-header field.',
+ name: t('tools.http-status-codes.417.name'),
+ description: t('tools.http-status-codes.417.description'),
type: 'HTTP',
},
{
code: 418,
- name: 'I\'m a teapot',
- description: 'The server refuses the attempt to brew coffee with a teapot.',
+ name: t('tools.http-status-codes.418.name'),
+ description: t('tools.http-status-codes.418.description'),
type: 'HTTP',
},
{
code: 421,
- name: 'Misdirected Request',
- description: 'The request was directed at a server that is not able to produce a response.',
+ name: t('tools.http-status-codes.421.name'),
+ description: t('tools.http-status-codes.421.description'),
type: 'HTTP',
},
{
code: 422,
- name: 'Unprocessable Entity',
- description: 'The request was well-formed but was unable to be followed due to semantic errors.',
+ name: t('tools.http-status-codes.422.name'),
+ description: t('tools.http-status-codes.422.description'),
type: 'HTTP',
},
{
code: 423,
- name: 'Locked',
- description: 'The resource that is being accessed is locked.',
+ name: t('tools.http-status-codes.423.name'),
+ description: t('tools.http-status-codes.423.description'),
type: 'HTTP',
},
{
code: 424,
- name: 'Failed Dependency',
- description: 'The request failed due to failure of a previous request.',
+ name: t('tools.http-status-codes.424.name'),
+ description: t('tools.http-status-codes.424.description'),
type: 'HTTP',
},
{
code: 425,
- name: 'Too Early',
- description: 'Indicates that the server is unwilling to risk processing a request that might be replayed.',
+ name: t('tools.http-status-codes.425.name'),
+ description: t('tools.http-status-codes.425.description'),
type: 'HTTP',
},
{
code: 426,
- name: 'Upgrade Required',
- description: 'The client should switch to a different protocol such as TLS/1.0.',
+ name: t('tools.http-status-codes.426.name'),
+ description: t('tools.http-status-codes.426.description'),
type: 'HTTP',
},
{
code: 428,
- name: 'Precondition Required',
- description: 'The origin server requires the request to be conditional.',
+ name: t('tools.http-status-codes.428.name'),
+ description: t('tools.http-status-codes.428.description'),
type: 'HTTP',
},
{
code: 429,
- name: 'Too Many Requests',
- description: 'The user has sent too many requests in a given amount of time.',
+ name: t('tools.http-status-codes.429.name'),
+ description: t('tools.http-status-codes.429.description'),
type: 'HTTP',
},
{
code: 431,
- name: 'Request Header Fields Too Large',
- description:
- 'The server is unwilling to process the request because either an individual header field, or all the header fields collectively, are too large.',
+ name: t('tools.http-status-codes.431.name'),
+ description: t('tools.http-status-codes.431.description'),
type: 'HTTP',
},
{
code: 451,
- name: 'Unavailable For Legal Reasons',
- description:
- 'A server operator has received a legal demand to deny access to a resource or to a set of resources that includes the requested resource.',
+ name: t('tools.http-status-codes.451.name'),
+ description: t('tools.http-status-codes.451.description'),
type: 'HTTP',
},
],
},
{
- category: '5xx server error',
+ category: t('tools.http-status-codes.5xx'),
codes: [
{
code: 500,
- name: 'Internal Server Error',
- description:
- 'A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.',
+ name: t('tools.http-status-codes.500.name'),
+ description: t('tools.http-status-codes.500.description'),
type: 'HTTP',
},
{
code: 501,
- name: 'Not Implemented',
- description:
- 'The server either does not recognize the request method, or it lacks the ability to fulfill the request.',
+ name: t('tools.http-status-codes.501.name'),
+ description: t('tools.http-status-codes.501.description'),
type: 'HTTP',
},
{
code: 502,
- name: 'Bad Gateway',
- description:
- 'The server was acting as a gateway or proxy and received an invalid response from the upstream server.',
+ name: t('tools.http-status-codes.502.name'),
+ description: t('tools.http-status-codes.502.description'),
type: 'HTTP',
},
{
code: 503,
- name: 'Service Unavailable',
- description: 'The server is currently unavailable (because it is overloaded or down for maintenance).',
+ name: t('tools.http-status-codes.503.name'),
+ description: t('tools.http-status-codes.503.description'),
type: 'HTTP',
},
{
code: 504,
- name: 'Gateway Timeout',
- description:
- 'The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.',
+ name: t('tools.http-status-codes.504.name'),
+ description: t('tools.http-status-codes.504.description'),
type: 'HTTP',
},
{
code: 505,
- name: 'HTTP Version Not Supported',
- description: 'The server does not support the HTTP protocol version used in the request.',
+ name: t('tools.http-status-codes.505.name'),
+ description: t('tools.http-status-codes.505.description'),
type: 'HTTP',
},
{
code: 506,
- name: 'Variant Also Negotiates',
- description: 'Transparent content negotiation for the request results in a circular reference.',
+ name: t('tools.http-status-codes.506.name'),
+ description: t('tools.http-status-codes.506.description'),
type: 'HTTP',
},
{
code: 507,
- name: 'Insufficient Storage',
- description: 'The server is unable to store the representation needed to complete the request.',
+ name: t('tools.http-status-codes.507.name'),
+ description: t('tools.http-status-codes.507.description'),
type: 'HTTP',
},
{
code: 508,
- name: 'Loop Detected',
- description: 'The server detected an infinite loop while processing the request.',
+ name: t('tools.http-status-codes.508.name'),
+ description: t('tools.http-status-codes.508.description'),
type: 'HTTP',
},
{
code: 510,
- name: 'Not Extended',
- description: 'Further extensions to the request are required for the server to fulfill it.',
+ name: t('tools.http-status-codes.510.name'),
+ description: t('tools.http-status-codes.510.description'),
type: 'HTTP',
},
{
code: 511,
- name: 'Network Authentication Required',
- description: 'The client needs to authenticate to gain network access.',
+ name: t('tools.http-status-codes.511.name'),
+ description: t('tools.http-status-codes.511.description'),
type: 'HTTP',
},
],
diff --git a/src/tools/http-status-codes/http-status-codes.vue b/src/tools/http-status-codes/http-status-codes.vue
index 84ab3137b..434ae6736 100644
--- a/src/tools/http-status-codes/http-status-codes.vue
+++ b/src/tools/http-status-codes/http-status-codes.vue
@@ -1,8 +1,10 @@
@@ -25,7 +27,7 @@ const codesByCategoryFiltered = computed(() => {
diff --git a/src/tools/http-status-codes/index.ts b/src/tools/http-status-codes/index.ts
index b31389430..9ba257fda 100644
--- a/src/tools/http-status-codes/index.ts
+++ b/src/tools/http-status-codes/index.ts
@@ -1,18 +1,18 @@
import { HttpRound } from '@vicons/material';
import { defineTool } from '../tool';
-import { codesByCategories } from './http-status-codes.constants';
-import { translate } from '@/plugins/i18n.plugin';
+// import { codesByCategories } from './http-status-codes.constants';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.http-status-codes.title'),
+ name: t('tools.http-status-codes.title'),
path: '/http-status-codes',
- description: translate('tools.http-status-codes.description'),
+ description: t('tools.http-status-codes.description'),
keywords: [
'http',
'status',
'codes',
- ...codesByCategories.flatMap(({ codes }) => codes.flatMap(({ code, name }) => [String(code), name])),
+ // ...codesByCategories.flatMap(({ codes }) => codes.flatMap(({ code, name }) => [String(code), name])),
],
component: () => import('./http-status-codes.vue'),
icon: HttpRound,
diff --git a/src/tools/http-status-codes/locales/en.yml b/src/tools/http-status-codes/locales/en.yml
new file mode 100644
index 000000000..e2a02caa4
--- /dev/null
+++ b/src/tools/http-status-codes/locales/en.yml
@@ -0,0 +1,202 @@
+tools:
+ http-status-codes:
+ title: HTTP status codes
+ description: The list of all HTTP status codes their name and their meaning.
+
+ searchPlaceholder: Search http status...
+ searchResults: Search results
+
+ 1xx: 1xx informational response
+ 100:
+ name: Continue
+ description: Waiting for the client to emit the body of the request.
+ 101:
+ name: Switching Protocols
+ description: The server has agreed to change protocol.
+ 102:
+ name: Processing
+ description: The server is processing the request, but no response is available yet.
+ 103:
+ name: Early Hints
+ description: The server returns some response headers before final HTTP message.
+ 2xx: 2xx success
+ 200:
+ name: OK
+ description: Standard response for successful HTTP requests.
+ 201:
+ name: Created
+ description: The request has been fulfilled, resulting in the creation of a new resource.
+ 202:
+ name: Accepted
+ description: The request has been accepted for processing, but the processing has not been completed.
+ 203:
+ name: Non-Authoritative Information
+ description: The request is successful but the content of the original request has been modified by a transforming proxy.
+ 204:
+ name: No Content
+ description: The server successfully processed the request and is not returning any content.
+ 205:
+ name: Reset Content
+ description: The server indicates to reinitialize the document view which sent this request.
+ 206:
+ name: Partial Content
+ description: The server is delivering only part of the resource due to a range header sent by the client.
+ 207:
+ name: Multi-Status
+ description: The message body that follows is an XML message and can contain a number of separate response codes.
+ 208:
+ name: Already Reported
+ description: The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response.
+ 226:
+ name: IM Used
+ description: The server has fulfilled a request for the resource, and the response is a representation of the result.
+ 3xx: 3xx redirection
+ 300:
+ name: Multiple Choices
+ description: Indicates multiple options for the resource that the client may follow.
+ 301:
+ name: Moved Permanently
+ description: This and all future requests should be directed to the given URI.
+ 302:
+ name: Found
+ description: Redirect to another URL. This is an example of industry practice contradicting the standard.
+ 303:
+ name: See Other
+ description: The response to the request can be found under another URI using a GET method.
+ 304:
+ name: Not Modified
+ description: Indicates that the resource has not been modified since the version specified by the request headers.
+ 305:
+ name: Use Proxy
+ description: The requested resource is available only through a proxy, the address for which is provided in the response.
+ 306:
+ name: Switch Proxy
+ description: No longer used. Originally meant "Subsequent requests should use the specified proxy."
+ 307:
+ name: Temporary Redirect
+ description: In this case, the request should be repeated with another URI; however, future requests should still use the original URI.
+ 308:
+ name: Permanent Redirect
+ description: The request and all future requests should be repeated using another URI.
+ 4xx: 4xx client error
+ 400:
+ name: Bad Request
+ description: The server cannot or will not process the request due to an apparent client error.
+ 401:
+ name: Unauthorized
+ description: Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.
+ 402:
+ name: Payment Required
+ description: Reserved for future use. The original intention was that this code might be used as part of some form of digital cash or micropayment scheme.
+ 403:
+ name: Forbidden
+ description: The request was valid, but the server is refusing action. The user might not have the necessary permissions for a resource.
+ 404:
+ name: Not Found
+ description: The requested resource could not be found but may be available in the future.
+ 405:
+ name: Method Not Allowed
+ description: A request method is not supported for the requested resource.
+ 406:
+ name: Not Acceptable
+ description: The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.
+ 407:
+ name: Proxy Authentication Required
+ description: The client must first authenticate itself with the proxy.
+ 408:
+ name: Request Timeout
+ description: The server timed out waiting for the request.
+ 409:
+ name: Conflict
+ description: Indicates that the request could not be processed because of conflict in the request, such as an edit conflict.
+ 410:
+ name: Gone
+ description: Indicates that the resource requested is no longer available and will not be available again.
+ 411:
+ name: Length Required
+ description: The request did not specify the length of its content, which is required by the requested resource.
+ 412:
+ name: Precondition Failed
+ description: The server does not meet one of the preconditions that the requester put on the request.
+ 413:
+ name: Payload Too Large
+ description: The request is larger than the server is willing or able to process.
+ 414:
+ name: URI Too Long
+ description: The URI provided was too long for the server to process.
+ 415:
+ name: Unsupported Media Type
+ description: The request entity has a media type which the server or resource does not support.
+ 416:
+ name: Range Not Satisfiable
+ description: The client has asked for a portion of the file, but the server cannot supply that portion.
+ 417:
+ name: Expectation Failed
+ description: The server cannot meet the requirements of the Expect request-header field.
+ 418:
+ name: I'm a teapot
+ description: The server refuses the attempt to brew coffee with a teapot.
+ 421:
+ name: Misdirected Request
+ description: The request was directed at a server that is not able to produce a response.
+ 422:
+ name: Unprocessable Entity
+ description: The request was well-formed but was unable to be followed due to semantic errors.
+ 423:
+ name: Locked
+ description: The resource that is being accessed is locked.
+ 424:
+ name: Failed Dependency
+ description: The request failed due to failure of a previous request.
+ 425:
+ name: Too Early
+ description: Indicates that the server is unwilling to risk processing a request that might be replayed.
+ 426:
+ name: Upgrade Required
+ description: The client should switch to a different protocol such as TLS/1.0.
+ 428:
+ name: Precondition Required
+ description: The origin server requires the request to be conditional.
+ 429:
+ name: Too Many Requests
+ description: The user has sent too many requests in a given amount of time.
+ 431:
+ name: Request Header Fields Too Large
+ description: The server is unwilling to process the request because either an individual header field, or all the header fields collectively, are too large.
+ 451:
+ name: Unavailable For Legal Reasons
+ description: A server operator has received a legal demand to deny access to a resource or to a set of resources that includes the requested resource.
+ 5xx: 5xx server error
+ 500:
+ name: Internal Server Error
+ description: A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.
+ 501:
+ name: Not Implemented
+ description: The server either does not recognize the request method, or it lacks the ability to fulfill the request.
+ 502:
+ name: Bad Gateway
+ description: The server was acting as a gateway or proxy and received an invalid response from the upstream server.
+ 503:
+ name: Service Unavailable
+ description: The server is currently unavailable (because it is overloaded or down for maintenance).
+ 504:
+ name: Gateway Timeout
+ description: The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.
+ 505:
+ name: HTTP Version Not Supported
+ description: The server does not support the HTTP protocol version used in the request.
+ 506:
+ name: Variant Also Negotiates
+ description: Transparent content negotiation for the request results in a circular reference.
+ 507:
+ name: Insufficient Storage
+ description: The server is unable to store the representation needed to complete the request.
+ 508:
+ name: Loop Detected
+ description: The server detected an infinite loop while processing the request.
+ 510:
+ name: Not Extended
+ description: Further extensions to the request are required for the server to fulfill it.
+ 511:
+ name: Network Authentication Required
+ description: The client needs to authenticate to gain network access.
diff --git a/src/tools/http-status-codes/locales/fr.yml b/src/tools/http-status-codes/locales/fr.yml
new file mode 100644
index 000000000..ca448ddb5
--- /dev/null
+++ b/src/tools/http-status-codes/locales/fr.yml
@@ -0,0 +1,202 @@
+tools:
+ http-status-codes:
+ title: Codes d'état HTTP
+ description: La liste de tous les codes d'état HTTP, leur nom et leur signification.
+
+ searchPlaceholder: Rechercher un code d'état HTTP...
+ searchResults: Résultats de la recherche
+
+ 1xx: 1xx réponse d'information
+ 100:
+ name: Continuer
+ description: En attente que le client émette le corps de la requête.
+ 101:
+ name: Changement de protocole
+ description: Le serveur a accepté de changer de protocole.
+ 102:
+ name: Traitement
+ description: Le serveur traite la requête, mais aucune réponse n'est encore disponible.
+ 103:
+ name: Premiers indices
+ description: Le serveur renvoie certains en-têtes de réponse avant le message HTTP final.
+ 2xx: 2xx succès
+ 200:
+ name: OK
+ description: Réponse standard pour les requêtes HTTP réussies.
+ 201:
+ name: Créé
+ description: La requête a été satisfaite, entraînant la création d'une nouvelle ressource.
+ 202:
+ name: Accepté
+ description: La requête a été acceptée pour traitement, mais le traitement n'est pas encore terminé.
+ 203:
+ name: Information non autorisée
+ description: La requête est réussie mais le contenu de la requête originale a été modifié par un proxy de transformation.
+ 204:
+ name: Pas de contenu
+ description: Le serveur a traité avec succès la requête et ne renvoie aucun contenu.
+ 205:
+ name: Réinitialiser le contenu
+ description: Le serveur indique de réinitialiser la vue du document qui a envoyé cette requête.
+ 206:
+ name: Contenu partiel
+ description: Le serveur ne livre qu'une partie de la ressource en raison d'un en-tête de plage envoyé par le client.
+ 207:
+ name: Multi-Status
+ description: Le corps du message qui suit est un message XML et peut contenir plusieurs codes de réponse distincts.
+ 208:
+ name: Déjà signalé
+ description: Les membres d'une liaison DAV ont déjà été énumérés dans une partie précédente de la réponse (multistatus).
+ 226:
+ name: IM utilisé
+ description: Le serveur a satisfait une demande pour la ressource et la réponse est une représentation du résultat.
+ 3xx: 3xx redirection
+ 300:
+ name: Choix multiples
+ description: Indique plusieurs options pour la ressource que le client peut suivre.
+ 301:
+ name: Déplacé de façon permanente
+ description: Cette demande et toutes les demandes futures doivent être dirigées vers l'URI donné.
+ 302:
+ name: Trouvé
+ description: Rediriger vers une autre URL. C'est un exemple de pratique industrielle contredisant la norme.
+ 303:
+ name: Voir autre
+ description: La réponse à la demande peut être trouvée sous un autre URI en utilisant une méthode GET.
+ 304:
+ name: Non modifié
+ description: Indique que la ressource n'a pas été modifiée depuis la version spécifiée par les en-têtes de requête.
+ 305:
+ name: Utiliser un proxy
+ description: La ressource demandée est disponible uniquement via un proxy, dont l'adresse est fournie dans la réponse.
+ 306:
+ name: Changer de proxy
+ description: Plus utilisé. À l'origine signifiait "Les demandes ultérieures doivent utiliser le proxy spécifié."
+ 307:
+ name: Redirection temporaire
+ description: Dans ce cas, la demande doit être répétée avec un autre URI; cependant, les demandes futures doivent toujours utiliser l'URI d'origine.
+ 308:
+ name: Redirection permanente
+ description: La demande et toutes les demandes futures doivent être répétées en utilisant un autre URI.
+ 4xx: 4xx erreur client
+ 400:
+ name: Requête incorrecte
+ description: Le serveur ne peut pas ou ne traitera pas la demande en raison d'une erreur apparente du client.
+ 401:
+ name: Non autorisé
+ description: Similaire à 403 Interdit, mais spécifiquement utilisé lorsque l'authentification est requise et a échoué ou n'a pas encore été fournie.
+ 402:
+ name: Paiement requis
+ description: Réservé pour une utilisation future. L'intention initiale était que ce code pourrait être utilisé dans le cadre d'une sorte de système de monnaie numérique ou de micropaiement.
+ 403:
+ name: Interdit
+ description: La demande était valide, mais le serveur refuse l'action. L'utilisateur pourrait ne pas avoir les autorisations nécessaires pour une ressource.
+ 404:
+ name: Non trouvé
+ description: La ressource demandée n'a pas pu être trouvée mais pourrait être disponible à l'avenir.
+ 405:
+ name: Méthode non autorisée
+ description: Une méthode de requête n'est pas prise en charge pour la ressource demandée.
+ 406:
+ name: Non acceptable
+ description: La ressource demandée est capable de générer uniquement un contenu non acceptable selon les en-têtes Accept envoyés dans la requête.
+ 407:
+ name: Authentification proxy requise
+ description: Le client doit d'abord s'authentifier auprès du proxy.
+ 408:
+ name: Délai d'attente de la requête
+ description: Le serveur a expiré en attendant la requête.
+ 409:
+ name: Conflit
+ description: Indique que la demande n'a pas pu être traitée en raison d'un conflit dans la demande, comme un conflit de modification.
+ 410:
+ name: Parti
+ description: Indique que la ressource demandée n'est plus disponible et ne le sera plus à l'avenir.
+ 411:
+ name: Longueur requise
+ description: La requête n'a pas spécifié la longueur de son contenu, ce qui est requis par la ressource demandée.
+ 412:
+ name: Échec de la condition préalable
+ description: Le serveur ne remplit pas l'une des conditions préalables que le demandeur a mises sur la demande.
+ 413:
+ name: Charge utile trop importante
+ description: La requête est plus grande que ce que le serveur est prêt ou capable de traiter.
+ 414:
+ name: URI trop long
+ description: L'URI fourni était trop long pour que le serveur le traite.
+ 415:
+ name: Type de support non pris en charge
+ description: L'entité de la requête a un type de support que le serveur ou la ressource ne prend pas en charge.
+ 416:
+ name: Plage non satisfaisante
+ description: Le client a demandé une partie du fichier, mais le serveur ne peut pas fournir cette partie.
+ 417:
+ name: Échec de l'attente
+ description: Le serveur ne peut pas répondre aux exigences du champ d'en-tête de demande Expect.
+ 418:
+ name: Je suis une théière
+ description: Le serveur refuse la tentative de préparer du café avec une théière.
+ 421:
+ name: Demande mal dirigée
+ description: La demande a été dirigée vers un serveur qui n'est pas capable de produire une réponse.
+ 422:
+ name: Entité non traitable
+ description: La demande était bien formée mais n'a pas pu être suivie en raison d'erreurs sémantiques.
+ 423:
+ name: Verrouillé
+ description: La ressource à laquelle on accède est verrouillée.
+ 424:
+ name: Échec de la dépendance
+ description: La demande a échoué en raison de l'échec d'une demande précédente.
+ 425:
+ name: Trop tôt
+ description: Indique que le serveur ne veut pas risquer de traiter une demande qui pourrait être rejouée.
+ 426:
+ name: Mise à niveau requise
+ description: Le client doit passer à un protocole différent tel que TLS/1.0.
+ 428:
+ name: Condition préalable requise
+ description: Le serveur d'origine exige que la demande soit conditionnelle.
+ 429:
+ name: Trop de requêtes
+ description: L'utilisateur a envoyé trop de requêtes dans un laps de temps donné.
+ 431:
+ name: Champs d'en-tête de la requête trop grands
+ description: Le serveur refuse de traiter la demande car soit un champ d'en-tête individuel, soit tous les champs d'en-tête collectivement, sont trop grands.
+ 451:
+ name: Indisponible pour des raisons légales
+ description: Un opérateur de serveur a reçu une demande légale de refuser l'accès à une ressource ou à un ensemble de ressources incluant la ressource demandée.
+ 5xx: 5xx erreur serveur
+ 500:
+ name: Erreur interne du serveur
+ description: Un message d'erreur générique, donné lorsqu'une condition inattendue est rencontrée et qu'aucun message plus spécifique n'est approprié.
+ 501:
+ name: Non implémenté
+ description: Le serveur ne reconnaît pas la méthode de requête, ou il lui manque la capacité de répondre à la demande.
+ 502:
+ name: Mauvaise passerelle
+ description: Le serveur agissait en tant que passerelle ou proxy et a reçu une réponse invalide du serveur amont.
+ 503:
+ name: Service non disponible
+ description: Le serveur est actuellement indisponible (car il est surchargé ou en maintenance).
+ 504:
+ name: Délai d'attente de la passerelle
+ description: Le serveur agissait en tant que passerelle ou proxy et n'a pas reçu de réponse en temps voulu du serveur amont.
+ 505:
+ name: Version HTTP non prise en charge
+ description: Le serveur ne prend pas en charge la version du protocole HTTP utilisée dans la requête.
+ 506:
+ name: Variant négocié également
+ description: La négociation transparente du contenu pour la demande entraîne une référence circulaire.
+ 507:
+ name: Espace insuffisant
+ description: Le serveur est incapable de stocker la représentation nécessaire pour compléter la demande.
+ 508:
+ name: Boucle détectée
+ description: Le serveur a détecté une boucle infinie lors du traitement de la demande.
+ 510:
+ name: Non étendu
+ description: Des extensions supplémentaires à la demande sont nécessaires pour que le serveur puisse la satisfaire.
+ 511:
+ name: Authentification réseau requise
+ description: Le client doit s'authentifier pour accéder au réseau.
diff --git a/src/tools/http-status-codes/locales/zh.yml b/src/tools/http-status-codes/locales/zh.yml
new file mode 100644
index 000000000..1fc3def2a
--- /dev/null
+++ b/src/tools/http-status-codes/locales/zh.yml
@@ -0,0 +1,202 @@
+tools:
+ http-status-codes:
+ title: HTTP 状态码
+ description: 所有 HTTP 状态码及其名称和含义的列表。
+
+ searchPlaceholder: 搜索 HTTP 状态码...
+ searchResults: 搜索结果
+
+ 1xx: 1xx 信息性响应
+ 100:
+ name: 继续
+ description: 等待客户端发送请求主体。
+ 101:
+ name: 切换协议
+ description: 服务器已同意切换协议。
+ 102:
+ name: 处理中
+ description: 服务器正在处理请求,但尚未有响应可用。
+ 103:
+ name: 早期提示
+ description: 服务器在最终 HTTP 消息之前返回一些响应头。
+ 2xx: 2xx 成功
+ 200:
+ name: OK
+ description: 成功的标准 HTTP 请求响应。
+ 201:
+ name: 已创建
+ description: 请求已成功,导致创建新资源。
+ 202:
+ name: 已接受
+ description: 请求已被接受处理,但处理尚未完成。
+ 203:
+ name: 非权威信息
+ description: 请求成功,但原始请求的内容已被转换代理修改。
+ 204:
+ name: 无内容
+ description: 服务器成功处理请求,但未返回任何内容。
+ 205:
+ name: 重置内容
+ description: 服务器指示重新初始化发送此请求的文档视图。
+ 206:
+ name: 部分内容
+ description: 服务器仅因客户端发送的范围头而传送资源的部分。
+ 207:
+ name: 多状态
+ description: 接下来的消息主体是 XML 消息,可以包含许多独立的响应代码。
+ 208:
+ name: 已报告
+ description: DAV 绑定的成员已在响应的前一部分中枚举。
+ 226:
+ name: 使用 IM
+ description: 服务器已满足对资源的请求,响应是结果的表示。
+ 3xx: 3xx 重定向
+ 300:
+ name: 多种选择
+ description: 表示客户端可以跟随的资源的多个选项。
+ 301:
+ name: 永久移动
+ description: 此次及所有后续请求应重定向到给定的 URI。
+ 302:
+ name: 找到
+ description: 重定向到另一个 URL。这是一个违反标准的行业实践示例。
+ 303:
+ name: 查看其他
+ description: 请求的响应可以在另一个 URI 下使用 GET 方法找到。
+ 304:
+ name: 未修改
+ description: 表示资源自请求标头指定的版本以来未被修改。
+ 305:
+ name: 使用代理
+ description: 请求的资源仅通过代理提供,响应中提供了代理的地址。
+ 306:
+ name: 切换代理
+ description: 不再使用。最初的含义是“后续请求应使用指定的代理”。
+ 307:
+ name: 临时重定向
+ description: 在这种情况下,应重复使用另一个 URI 进行请求;但是,将来的请求仍应使用原始 URI。
+ 308:
+ name: 永久重定向
+ description: 请求和所有后续请求应重复使用另一个 URI。
+ 4xx: 4xx 客户端错误
+ 400:
+ name: 错误请求
+ description: 由于明显的客户端错误,服务器无法处理请求或不会处理请求。
+ 401:
+ name: 未经授权
+ description: 类似于 403 Forbidden,但专门用于在需要验证但验证失败或尚未提供的情况下使用。
+ 402:
+ name: 需要付款
+ description: 保留以备将来使用。最初的意图是,该代码可能作为某种数字货币或微支付方案的一部分使用。
+ 403:
+ name: 禁止
+ description: 请求有效,但服务器拒绝执行操作。用户可能没有资源所需的必要权限。
+ 404:
+ name: 未找到
+ description: 请求的资源未找到,但将来可能会可用。
+ 405:
+ name: 方法不允许
+ description: 请求方法不受请求资源支持。
+ 406:
+ name: 不可接受
+ description: 请求的资源能够生成的内容不符合请求中发送的 Accept 标头。
+ 407:
+ name: 需要代理身份验证
+ description: 客户端必须首先通过代理进行身份验证。
+ 408:
+ name: 请求超时
+ description: 服务器在等待请求时超时。
+ 409:
+ name: 冲突
+ description: 表示由于请求中的冲突(如编辑冲突)无法处理请求。
+ 410:
+ name: 已消失
+ description: 表示请求的资源不再可用,也不会再次可用。
+ 411:
+ name: 需要长度
+ description: 请求未指定所需资源的长度。
+ 412:
+ name: 前提条件失败
+ description: 服务器未满足请求者对请求的其中一个前提条件。
+ 413:
+ name: 负载过大
+ description: 请求的大小超过服务器愿意或能够处理的范围。
+ 414:
+ name: URI 过长
+ description: 提供的 URI 对服务器来说太长,无法处理。
+ 415:
+ name: 不支持的媒体类型
+ description: 请求实体具有服务器或资源不支持的媒体类型。
+ 416:
+ name: 范围不可满足
+ description: 客户端请求文件的一部分,但服务器无法提供该部分。
+ 417:
+ name: 预期失败
+ description: 服务器无法满足 Expect 请求标头字段的要求。
+ 418:
+ name: 我是茶壶
+ description: 服务器拒绝使用茶壶煮咖啡。
+ 421:
+ name: 请求错误
+ description: 请求指向无法生成响应的服务器。
+ 422:
+ name: 无法处理的实体
+ description: 请求格式正确,但由于语义错误无法进行后续处理。
+ 423:
+ name: 已锁定
+ description: 正在访问的资源已被锁定。
+ 424:
+ name: 失败的依赖
+ description: 由于先前请求的失败,请求失败。
+ 425:
+ name: 太早
+ description: 表示服务器不愿冒险处理可能会被重播的请求。
+ 426:
+ name: 需要升级
+ description: 客户端应切换到其他协议,如 TLS/1.0。
+ 428:
+ name: 需要前提条件
+ description: 源服务器要求请求是有条件的。
+ 429:
+ name: 请求过多
+ description: 用户在一定时间内发送了太多请求。
+ 431:
+ name: 请求头字段太大
+ description: 服务器不愿处理请求,因为单个标头字段或所有标头字段的总和太大。
+ 451:
+ name: 因法律原因不可用
+ description: 服务器操作员收到法律要求拒绝访问资源或包含请求的资源集。
+ 5xx: 5xx 服务器错误
+ 500:
+ name: 内部服务器错误
+ description: 遇到意外情况并且没有更具体消息适用时给出的通用错误消息。
+ 501:
+ name: 未实现
+ description: 服务器不识别请求方法,或缺乏实现请求的能力。
+ 502:
+ name: 错误网关
+ description: 服务器作为网关或代理行事,并从上游服务器接收到无效响应。
+ 503:
+ name: 服务不可用
+ description: 服务器当前不可用(因为过载或正在维护)。
+ 504:
+ name: 网关超时
+ description: 服务器作为网关或代理行事,未从上游服务器收到及时响应。
+ 505:
+ name: 不支持的 HTTP 版本
+ description: 服务器不支持请求中使用的 HTTP 协议版本。
+ 506:
+ name: 变体也进行协商
+ description: 用于请求结果的透明内容协商导致循环引用。
+ 507:
+ name: 存储空间不足
+ description: 服务器无法存储完成请求所需的表示。
+ 508:
+ name: 检测到循环
+ description: 服务器在处理请求时检测到无限循环。
+ 510:
+ name: 未扩展
+ description: 服务器需要进一步扩展请求才能满足它。
+ 511:
+ name: 需要网络认证
+ description: 客户端需要进行身份验证以获得网络访问权限。
diff --git a/src/tools/iban-validator-and-parser/iban-validator-and-parser.service.ts b/src/tools/iban-validator-and-parser/iban-validator-and-parser.service.ts
index bde71dba7..7d4a8bd21 100644
--- a/src/tools/iban-validator-and-parser/iban-validator-and-parser.service.ts
+++ b/src/tools/iban-validator-and-parser/iban-validator-and-parser.service.ts
@@ -1,16 +1,17 @@
import { ValidationErrorsIBAN } from 'ibantools';
+import { translate as t } from '@/plugins/i18n.plugin';
export { getFriendlyErrors };
const ibanErrorToMessage = {
- [ValidationErrorsIBAN.NoIBANProvided]: 'No IBAN provided',
- [ValidationErrorsIBAN.NoIBANCountry]: 'No IBAN country',
- [ValidationErrorsIBAN.WrongBBANLength]: 'Wrong BBAN length',
- [ValidationErrorsIBAN.WrongBBANFormat]: 'Wrong BBAN format',
- [ValidationErrorsIBAN.ChecksumNotNumber]: 'Checksum is not a number',
- [ValidationErrorsIBAN.WrongIBANChecksum]: 'Wrong IBAN checksum',
- [ValidationErrorsIBAN.WrongAccountBankBranchChecksum]: 'Wrong account bank branch checksum',
- [ValidationErrorsIBAN.QRIBANNotAllowed]: 'QR-IBAN not allowed',
+ [ValidationErrorsIBAN.NoIBANProvided]: t('tools.iban-validator-and-parser.noIBANProvided'),
+ [ValidationErrorsIBAN.NoIBANCountry]: t('tools.iban-validator-and-parser.noIBANCountry'),
+ [ValidationErrorsIBAN.WrongBBANLength]: t('tools.iban-validator-and-parser.wrongBBANLength'),
+ [ValidationErrorsIBAN.WrongBBANFormat]: t('tools.iban-validator-and-parser.wrongBBANFormat'),
+ [ValidationErrorsIBAN.ChecksumNotNumber]: t('tools.iban-validator-and-parser.checksumNotNumber'),
+ [ValidationErrorsIBAN.WrongIBANChecksum]: t('tools.iban-validator-and-parser.wrongIBANChecksum'),
+ [ValidationErrorsIBAN.WrongAccountBankBranchChecksum]: t('tools.iban-validator-and-parser.wrongAccountBankBranchChecksum'),
+ [ValidationErrorsIBAN.QRIBANNotAllowed]: t('tools.iban-validator-and-parser.QRIBANNotAllowed'),
};
function getFriendlyErrors(errorCodes: ValidationErrorsIBAN[]) {
diff --git a/src/tools/iban-validator-and-parser/iban-validator-and-parser.vue b/src/tools/iban-validator-and-parser/iban-validator-and-parser.vue
index 6844dc5a2..faafa626d 100644
--- a/src/tools/iban-validator-and-parser/iban-validator-and-parser.vue
+++ b/src/tools/iban-validator-and-parser/iban-validator-and-parser.vue
@@ -3,6 +3,7 @@ import { extractIBAN, friendlyFormatIBAN, isQRIBAN, validateIBAN } from 'ibantoo
import { getFriendlyErrors } from './iban-validator-and-parser.service';
import type { CKeyValueListItems } from '@/ui/c-key-value-list/c-key-value-list.types';
+const { t } = useI18n();
const rawIban = ref('');
const ibanInfo = computed(() => {
@@ -19,31 +20,31 @@ const ibanInfo = computed(() => {
return [
{
- label: 'Is IBAN valid ?',
+ label: t('tools.iban-validator-and-parser.isIbanValid'),
value: isIbanValid,
showCopyButton: false,
},
{
- label: 'IBAN errors',
+ label: t('tools.iban-validator-and-parser.IBANErrors'),
value: errors.length === 0 ? undefined : errors,
hideOnNil: true,
showCopyButton: false,
},
{
- label: 'Is IBAN a QR-IBAN ?',
+ label: t('tools.iban-validator-and-parser.isQRIBAN'),
value: isQRIBAN(iban),
showCopyButton: false,
},
{
- label: 'Country code',
+ label: t('tools.iban-validator-and-parser.countryCode'),
value: countryCode,
},
{
- label: 'BBAN',
+ label: t('tools.iban-validator-and-parser.BBAN'),
value: bban,
},
{
- label: 'IBAN friendly format',
+ label: t('tools.iban-validator-and-parser.IBANFriendlyFormat'),
value: friendlyFormatIBAN(iban),
},
];
@@ -58,13 +59,13 @@ const ibanExamples = [
-
+
-
+
diff --git a/src/tools/iban-validator-and-parser/index.ts b/src/tools/iban-validator-and-parser/index.ts
index ff7ff135b..7c23c83bc 100644
--- a/src/tools/iban-validator-and-parser/index.ts
+++ b/src/tools/iban-validator-and-parser/index.ts
@@ -1,11 +1,11 @@
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
import Bank from '~icons/mdi/bank';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.iban-validator-and-parser.title'),
+ name: t('tools.iban-validator-and-parser.title'),
path: '/iban-validator-and-parser',
- description: translate('tools.iban-validator-and-parser.description'),
+ description: t('tools.iban-validator-and-parser.description'),
keywords: ['iban', 'validator', 'and', 'parser', 'bic', 'bank'],
component: () => import('./iban-validator-and-parser.vue'),
icon: Bank,
diff --git a/src/tools/iban-validator-and-parser/locales/en.yml b/src/tools/iban-validator-and-parser/locales/en.yml
new file mode 100644
index 000000000..b4fe9ce95
--- /dev/null
+++ b/src/tools/iban-validator-and-parser/locales/en.yml
@@ -0,0 +1,22 @@
+tools:
+ iban-validator-and-parser:
+ title: IBAN validator and parser
+ description: Validate and parse IBAN numbers. Check if IBAN is valid and get the country, BBAN, if it is a QR-IBAN and the IBAN friendly format.
+
+ inputPlaceholder: Enter an IBAN to check for validity...
+ ibanExamples: Valid IBAN examples
+
+ isIbanValid: Is IBAN valid ?
+ IBANErrors: IBAN errors
+ isQRIBAN: Is IBAN a QR-IBAN ?
+ countryCode: Country code
+ BBAN: BBAN
+ IBANFriendlyFormat: IBAN friendly format
+ noIBANProvided: No IBAN provided
+ noIBANCountry: No IBAN country
+ wrongBBANLength: Wrong BBAN length
+ wrongBBANFormat: Wrong BBAN format
+ checksumNotNumber: Checksum is not a number
+ wrongIBANChecksum: Wrong IBAN checksum
+ wrongAccountBankBranchChecksum: Wrong account bank branch checksum
+ QRIBANNotAllowed: QR-IBAN not allowed
diff --git a/src/tools/iban-validator-and-parser/locales/fr.yml b/src/tools/iban-validator-and-parser/locales/fr.yml
new file mode 100644
index 000000000..932398c9e
--- /dev/null
+++ b/src/tools/iban-validator-and-parser/locales/fr.yml
@@ -0,0 +1,22 @@
+tools:
+ iban-validator-and-parser:
+ title: Validateur et analyseur d'IBAN
+ description: Validez et analysez les numéros IBAN. Vérifiez si l'IBAN est valide et obtenez le pays, le BBAN, s'il s'agit d'un QR-IBAN et le format convivial de l'IBAN.
+
+ inputPlaceholder: Entrez un IBAN à vérifier la validité...
+ ibanExamples: Exemples d'IBAN valides
+
+ isIbanValid: L'IBAN est-il valide ?
+ IBANErrors: Erreurs d'IBAN
+ isQRIBAN: L'IBAN est-il un QR-IBAN ?
+ countryCode: Code pays
+ BBAN: BBAN
+ IBANFriendlyFormat: Format convivial de l'IBAN
+ noIBANProvided: Aucun IBAN fourni
+ noIBANCountry: Aucun pays d'IBAN
+ wrongBBANLength: Longueur BBAN incorrecte
+ wrongBBANFormat: Format BBAN incorrect
+ checksumNotNumber: Le checksum n'est pas un nombre
+ wrongIBANChecksum: Checksum IBAN incorrect
+ wrongAccountBankBranchChecksum: Checksum de compte bancaire incorrect
+ QRIBANNotAllowed: QR-IBAN non autorisé
diff --git a/src/tools/iban-validator-and-parser/locales/zh.yml b/src/tools/iban-validator-and-parser/locales/zh.yml
new file mode 100644
index 000000000..f0041ac61
--- /dev/null
+++ b/src/tools/iban-validator-and-parser/locales/zh.yml
@@ -0,0 +1,22 @@
+tools:
+ iban-validator-and-parser:
+ title: IBAN 验证器和解析器
+ description: 验证和解析 IBAN 号码。检查 IBAN 是否有效,并获取国家、BBAN、是否为 QR-IBAN 和 IBAN 友好格式。
+
+ inputPlaceholder: 输入要检查有效性的 IBAN…
+ ibanExamples: 有效的 IBAN 示例
+
+ isIbanValid: IBAN 是否有效?
+ IBANErrors: IBAN 错误
+ isQRIBAN: 是否为 QR-IBAN?
+ countryCode: 国家代码
+ BBAN: BBAN
+ IBANFriendlyFormat: IBAN 友好格式
+ noIBANProvided: 未提供 IBAN
+ noIBANCountry: 未提供 IBAN 国家
+ wrongBBANLength: BBAN 长度错误
+ wrongBBANFormat: BBAN 格式错误
+ checksumNotNumber: 校验和不是数字
+ wrongIBANChecksum: IBAN 校验和错误
+ wrongAccountBankBranchChecksum: 帐户银行分行校验和错误
+ QRIBANNotAllowed: 不允许 QR-IBAN
diff --git a/src/tools/index.ts b/src/tools/index.ts
index aa861c935..3e735f11d 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -100,11 +100,11 @@ export const toolsByCategory: ToolCategory[] = [
textToNatoAlphabet,
textToBinary,
textToUnicode,
+ listConverter,
yamlToJson,
yamlToToml,
jsonToYaml,
jsonToToml,
- listConverter,
tomlToJson,
tomlToYaml,
],
diff --git a/src/tools/integer-base-converter/index.ts b/src/tools/integer-base-converter/index.ts
index f60d996d1..b9a2431ae 100644
--- a/src/tools/integer-base-converter/index.ts
+++ b/src/tools/integer-base-converter/index.ts
@@ -1,11 +1,11 @@
import { ArrowsLeftRight } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.base-converter.title'),
+ name: t('tools.base-converter.title'),
path: '/base-converter',
- description: translate('tools.base-converter.description'),
+ description: t('tools.base-converter.description'),
keywords: ['integer', 'number', 'base', 'conversion', 'decimal', 'hexadecimal', 'binary', 'octal', 'base64'],
component: () => import('./integer-base-converter.vue'),
icon: ArrowsLeftRight,
diff --git a/src/tools/integer-base-converter/integer-base-converter.model.ts b/src/tools/integer-base-converter/integer-base-converter.model.ts
index b4470e57a..5f932d23a 100644
--- a/src/tools/integer-base-converter/integer-base-converter.model.ts
+++ b/src/tools/integer-base-converter/integer-base-converter.model.ts
@@ -1,3 +1,5 @@
+import { translate as t } from '@/plugins/i18n.plugin';
+
export function convertBase({ value, fromBase, toBase }: { value: string; fromBase: number; toBase: number }) {
const range = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/'.split('');
const fromRange = range.slice(0, fromBase);
@@ -7,7 +9,7 @@ export function convertBase({ value, fromBase, toBase }: { value: string; fromBa
.reverse()
.reduce((carry: number, digit: string, index: number) => {
if (!fromRange.includes(digit)) {
- throw new Error(`Invalid digit "${digit}" for base ${fromBase}.`);
+ throw new Error(t('tools.base-converter.invalidMessage', { digit, fromBase }));
}
return (carry += fromRange.indexOf(digit) * fromBase ** index);
}, 0);
diff --git a/src/tools/integer-base-converter/integer-base-converter.vue b/src/tools/integer-base-converter/integer-base-converter.vue
index 2445baa5a..378cc414d 100644
--- a/src/tools/integer-base-converter/integer-base-converter.vue
+++ b/src/tools/integer-base-converter/integer-base-converter.vue
@@ -11,6 +11,8 @@ const inputProps = {
'mb-2': '',
} as const;
+const { t } = useI18n();
+
const input = ref('42');
const inputBase = ref(10);
const outputBase = ref(42);
@@ -34,10 +36,10 @@ const error = computed(() =>
@@ -83,10 +84,10 @@ function onSwitchStartEndClicked() {
- old value
+ {{ t('tools.ipv4-range-expander.oldValue') }}
- new value
+ {{ t('tools.ipv4-range-expander.newValue') }}
@@ -102,17 +103,16 @@ function onSwitchStartEndClicked() {
- The end IPv4 address is lower than the start IPv4 address. This is not valid and no result could be calculated.
- In the most cases the solution to solve this problem is to change start and end address.
+ {{ t('tools.ipv4-range-expander.errorDesc') }}
- Switch start and end IPv4 address
+ {{ t('tools.ipv4-range-expander.switchStartEnd') }}
diff --git a/src/tools/ipv4-range-expander/locales/en.yml b/src/tools/ipv4-range-expander/locales/en.yml
new file mode 100644
index 000000000..c64acce4e
--- /dev/null
+++ b/src/tools/ipv4-range-expander/locales/en.yml
@@ -0,0 +1,18 @@
+tools:
+ ipv4-range-expander:
+ title: IPv4 range expander
+ description: Given a start and an end IPv4 address this tool calculates a valid IPv4 network with its CIDR notation.
+
+ startAddressPlaceholder: Start IPv4 address...
+ endAddressPlaceholder: End IPv4 address...
+ startAddress: Start address
+ endAddress: End address
+ addressesInRange: Addresses in range
+ CIDR: CIDR
+ oldValue: old value
+ newValue: new value
+
+ errorMessage: Invalid combination of start and end IPv4 address
+ errorDesc: The end IPv4 address is lower than the start IPv4 address. This is not valid and no result could be calculated. In the most cases the solution to solve this problem is to change start and end address.
+ switchStartEnd: Switch start and end IPv4 address
+ invalidMessage: Invalid ipv4 address
diff --git a/src/tools/ipv4-range-expander/locales/fr.yml b/src/tools/ipv4-range-expander/locales/fr.yml
new file mode 100644
index 000000000..1f68ac1c1
--- /dev/null
+++ b/src/tools/ipv4-range-expander/locales/fr.yml
@@ -0,0 +1,18 @@
+tools:
+ ipv4-range-expander:
+ title: Extension de plage IPv4
+ description: Étant donné une adresse IPv4 de début et de fin, cet outil calcule un réseau IPv4 valide avec sa notation CIDR.
+
+ startAddressPlaceholder: Adresse IPv4 de début...
+ endAddressPlaceholder: Adresse IPv4 de fin...
+ startAddress: Adresse de début
+ endAddress: Adresse de fin
+ addressesInRange: Adresses dans la plage
+ CIDR: CIDR
+ oldValue: ancienne valeur
+ newValue: nouvelle valeur
+
+ errorMessage: Combinaison invalide d'adresse IPv4 de début et de fin
+ errorDesc: L'adresse IPv4 de fin est inférieure à l'adresse IPv4 de début. Ceci n'est pas valide et aucun résultat ne peut être calculé. Dans la plupart des cas, la solution pour résoudre ce problème est de changer l'adresse de début et de fin.
+ switchStartEnd: Permuter l'adresse IPv4 de début et de fin
+ invalidMessage: Adresse IPv4 invalide
diff --git a/src/tools/ipv4-range-expander/locales/zh.yml b/src/tools/ipv4-range-expander/locales/zh.yml
new file mode 100644
index 000000000..33e9de194
--- /dev/null
+++ b/src/tools/ipv4-range-expander/locales/zh.yml
@@ -0,0 +1,18 @@
+tools:
+ ipv4-range-expander:
+ title: IPv4 范围扩展器
+ description: 给定起始和结束 IPv4 地址,此工具计算出一个有效的 IPv4 网络及其 CIDR 表示法。
+
+ startAddressPlaceholder: 起始 IPv4 地址...
+ endAddressPlaceholder: 结束 IPv4 地址...
+ startAddress: 起始地址
+ endAddress: 结束地址
+ addressesInRange: 范围内的地址
+ CIDR: CIDR
+ oldValue: 旧值
+ newValue: 新值
+
+ errorMessage: 起始和结束 IPv4 地址的组合无效
+ errorDesc: 结束 IPv4 地址低于起始 IPv4 地址。这是无效的,无法计算结果。大多数情况下,解决此问题的方法是更改起始和结束地址。
+ switchStartEnd: 切换起始和结束 IPv4 地址
+ invalidMessage: 无效的 IPv4 地址
diff --git a/src/tools/ipv4-subnet-calculator/index.ts b/src/tools/ipv4-subnet-calculator/index.ts
index 1bae72824..ed22535b9 100644
--- a/src/tools/ipv4-subnet-calculator/index.ts
+++ b/src/tools/ipv4-subnet-calculator/index.ts
@@ -1,11 +1,11 @@
import { RouterOutlined } from '@vicons/material';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.ipv4-subnet-calculator.title'),
+ name: t('tools.ipv4-subnet-calculator.title'),
path: '/ipv4-subnet-calculator',
- description: translate('tools.ipv4-subnet-calculator.description'),
+ description: t('tools.ipv4-subnet-calculator.description'),
keywords: ['ipv4', 'subnet', 'calculator', 'mask', 'network', 'cidr', 'netmask', 'bitmask', 'broadcast', 'address'],
component: () => import('./ipv4-subnet-calculator.vue'),
icon: RouterOutlined,
diff --git a/src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue b/src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue
index 3e2f43786..0f6be783a 100644
--- a/src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue
+++ b/src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue
@@ -7,6 +7,7 @@ import { withDefaultOnError } from '@/utils/defaults';
import { isNotThrowing } from '@/utils/boolean';
import SpanCopyable from '@/components/SpanCopyable.vue';
+const { t } = useI18n();
const ip = useStorage('ipv4-subnet-calculator:ip', '192.168.0.1/24');
const getNetworkInfo = (address: string) => new Netmask(address.trim());
@@ -15,7 +16,7 @@ const networkInfo = computed(() => withDefaultOnError(() => getNetworkInfo(ip.va
const ipValidationRules = [
{
- message: 'We cannot parse this address, check the format',
+ message: t('tools.ipv4-subnet-calculator.invalidMessage'),
validator: (value: string) => isNotThrowing(() => getNetworkInfo(value.trim())),
},
];
@@ -26,50 +27,50 @@ const sections: {
undefinedFallback?: string
}[] = [
{
- label: 'Netmask',
+ label: t('tools.ipv4-subnet-calculator.networkMask'),
getValue: block => block.toString(),
},
{
- label: 'Network address',
+ label: t('tools.ipv4-subnet-calculator.networkAddress'),
getValue: ({ base }) => base,
},
{
- label: 'Network mask',
+ label: t('tools.ipv4-subnet-calculator.networkMask'),
getValue: ({ mask }) => mask,
},
{
- label: 'Network mask in binary',
+ label: t('tools.ipv4-subnet-calculator.networkMaskInBinary'),
getValue: ({ bitmask }) => ('1'.repeat(bitmask) + '0'.repeat(32 - bitmask)).match(/.{8}/g)?.join('.') ?? '',
},
{
- label: 'CIDR notation',
+ label: t('tools.ipv4-subnet-calculator.CIDRNotation'),
getValue: ({ bitmask }) => `/${bitmask}`,
},
{
- label: 'Wildcard mask',
+ label: t('tools.ipv4-subnet-calculator.wildcardMask'),
getValue: ({ hostmask }) => hostmask,
},
{
- label: 'Network size',
+ label: t('tools.ipv4-subnet-calculator.networkSize'),
getValue: ({ size }) => String(size),
},
{
- label: 'First address',
+ label: t('tools.ipv4-subnet-calculator.firstAddress'),
getValue: ({ first }) => first,
},
{
- label: 'Last address',
+ label: t('tools.ipv4-subnet-calculator.lastAddress'),
getValue: ({ last }) => last,
},
{
- label: 'Broadcast address',
+ label: t('tools.ipv4-subnet-calculator.broadcastAddress'),
getValue: ({ broadcast }) => broadcast,
- undefinedFallback: 'No broadcast address with this mask',
+ undefinedFallback: t('tools.ipv4-subnet-calculator.broadcastFallback'),
},
{
- label: 'IP class',
+ label: t('tools.ipv4-subnet-calculator.IPClass'),
getValue: ({ base: ip }) => getIPClass({ ip }),
- undefinedFallback: 'Unknown class type',
+ undefinedFallback: t('tools.ipv4-subnet-calculator.IPClassFallback'),
},
];
@@ -86,8 +87,8 @@ function switchToBlock({ count = 1 }: { count?: number }) {
@@ -112,10 +113,10 @@ function switchToBlock({ count = 1 }: { count?: number }) {
diff --git a/src/tools/ipv4-subnet-calculator/locales/en.yml b/src/tools/ipv4-subnet-calculator/locales/en.yml
new file mode 100644
index 000000000..19e236d52
--- /dev/null
+++ b/src/tools/ipv4-subnet-calculator/locales/en.yml
@@ -0,0 +1,24 @@
+tools:
+ ipv4-subnet-calculator:
+ title: IPv4 subnet calculator
+ description: Parse your IPv4 CIDR blocks and get all the info you need about your sub network.
+
+ ipv4AddressLabel: An IPv4 address with or without mask
+ ipv4AddressPlaceholder: The ipv4 address...
+ netmask: Netmask
+ networkAddress: Network address
+ networkMask: Network mask
+ networkMaskInBinary: Network mask in binary
+ CIDRNotation: CIDR notation
+ wildcardMask: Wildcard mask
+ networkSize: Network size
+ firstAddress: First address
+ lastAddress: Last address
+ broadcastAddress: Broadcast address
+ broadcastFallback: No broadcast address with this mask
+ IPClass: IP class
+ IPClassFallback: Unknown class type
+
+ previousBlock: Previous block
+ nextBlock: Next block
+ invalidMessage: We cannot parse this address, check the format
diff --git a/src/tools/ipv4-subnet-calculator/locales/fr.yml b/src/tools/ipv4-subnet-calculator/locales/fr.yml
new file mode 100644
index 000000000..6105d9d9a
--- /dev/null
+++ b/src/tools/ipv4-subnet-calculator/locales/fr.yml
@@ -0,0 +1,24 @@
+tools:
+ ipv4-subnet-calculator:
+ title: Calculateur de sous-réseau IPv4
+ description: Analysez vos blocs CIDR IPv4 et obtenez toutes les informations dont vous avez besoin sur votre sous-réseau.
+
+ ipv4AddressLabel: Une adresse IPv4 avec ou sans masque
+ ipv4AddressPlaceholder: L'adresse IPv4...
+ netmask: Masque de sous-réseau
+ networkAddress: Adresse du réseau
+ networkMask: Masque du réseau
+ networkMaskInBinary: Masque du réseau en binaire
+ CIDRNotation: Notation CIDR
+ wildcardMask: Masque de joker
+ networkSize: Taille du réseau
+ firstAddress: Première adresse
+ lastAddress: Dernière adresse
+ broadcastAddress: Adresse de diffusion
+ broadcastFallback: Pas d'adresse de diffusion avec ce masque
+ IPClass: Classe IP
+ IPClassFallback: Type de classe inconnu
+
+ previousBlock: Bloc précédent
+ nextBlock: Bloc suivant
+ invalidMessage: Nous ne pouvons pas analyser cette adresse, vérifiez le format
diff --git a/src/tools/ipv4-subnet-calculator/locales/zh.yml b/src/tools/ipv4-subnet-calculator/locales/zh.yml
new file mode 100644
index 000000000..2c5b2f7fc
--- /dev/null
+++ b/src/tools/ipv4-subnet-calculator/locales/zh.yml
@@ -0,0 +1,24 @@
+tools:
+ ipv4-subnet-calculator:
+ title: IPv4 子网计算器
+ description: 解析您的 IPv4 CIDR 块,并获取关于您的子网络的所有所需信息。
+
+ ipv4AddressLabel: 带有或不带掩码的 IPv4 地址
+ ipv4AddressPlaceholder: IPv4 地址...
+ netmask: 子网掩码
+ networkAddress: 网络地址
+ networkMask: 网络掩码
+ networkMaskInBinary: 二进制网络掩码
+ CIDRNotation: CIDR 表示法
+ wildcardMask: 通配符掩码
+ networkSize: 网络大小
+ firstAddress: 第一个地址
+ lastAddress: 最后一个地址
+ broadcastAddress: 广播地址
+ broadcastFallback: 此掩码无广播地址
+ IPClass: IP 类别
+ IPClassFallback: 未知类别
+
+ previousBlock: 前一个块
+ nextBlock: 下一个块
+ invalidMessage: 我们无法解析此地址,请检查格式
diff --git a/src/tools/ipv6-ula-generator/index.ts b/src/tools/ipv6-ula-generator/index.ts
index 51bfd6fcd..e923c32d0 100644
--- a/src/tools/ipv6-ula-generator/index.ts
+++ b/src/tools/ipv6-ula-generator/index.ts
@@ -1,11 +1,11 @@
import { BuildingFactory } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.ipv6-ula-generator.title'),
+ name: t('tools.ipv6-ula-generator.title'),
path: '/ipv6-ula-generator',
- description: translate('tools.ipv6-ula-generator.description'),
+ description: t('tools.ipv6-ula-generator.description'),
keywords: ['ipv6', 'ula', 'generator', 'rfc4193', 'network', 'private'],
component: () => import('./ipv6-ula-generator.vue'),
icon: BuildingFactory,
diff --git a/src/tools/ipv6-ula-generator/ipv6-ula-generator.vue b/src/tools/ipv6-ula-generator/ipv6-ula-generator.vue
index 66c69c6cd..5560b7d6c 100644
--- a/src/tools/ipv6-ula-generator/ipv6-ula-generator.vue
+++ b/src/tools/ipv6-ula-generator/ipv6-ula-generator.vue
@@ -3,6 +3,7 @@ import { SHA1 } from 'crypto-js';
import InputCopyable from '@/components/InputCopyable.vue';
import { macAddressValidation } from '@/utils/macAddress';
+const { t } = useI18n();
const macAddress = ref('20:37:06:12:34:56');
const calculatedSections = computed(() => {
const timestamp = new Date().getTime();
@@ -14,15 +15,15 @@ const calculatedSections = computed(() => {
return [
{
- label: 'IPv6 ULA:',
+ label: t('tools.ipv6-ula-generator.IPv6ULA'),
value: `${ula}::/48`,
},
{
- label: 'First routable block:',
+ label: t('tools.ipv6-ula-generator.firstRoutableBlock'),
value: `${ula}:0::/64`,
},
{
- label: 'Last routable block:',
+ label: t('tools.ipv6-ula-generator.lastRoutableBlock'),
value: `${ula}:ffff::/64`,
},
];
@@ -33,16 +34,15 @@ const addressValidation = macAddressValidation(macAddress);
-
- This tool uses the first method suggested by IETF using the current timestamp plus the mac address, sha1 hashed,
- and the lower 40 bits to generate your random ULA.
+
+ {{ t('tools.ipv6-ula-generator.infoDetail') }}
();
+
+const { t } = useI18n();
const onlyShowDifferences = ref(false);
const { leftJson, rightJson } = toRefs(props);
const appTheme = useAppTheme();
@@ -20,14 +22,14 @@ const showResults = computed(() => !_.isUndefined(leftJson.value) && !_.isUndefi
-
+
- The provided JSONs are the same
+ {{ t('tools.json-diff.jsonAreTheSame') }}
diff --git a/src/tools/json-diff/index.ts b/src/tools/json-diff/index.ts
index a4c0319c0..7f21808d4 100644
--- a/src/tools/json-diff/index.ts
+++ b/src/tools/json-diff/index.ts
@@ -1,11 +1,11 @@
import { CompareArrowsRound } from '@vicons/material';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.json-diff.title'),
+ name: t('tools.json-diff.title'),
path: '/json-diff',
- description: translate('tools.json-diff.description'),
+ description: t('tools.json-diff.description'),
keywords: ['json', 'diff', 'compare', 'difference', 'object', 'data'],
component: () => import('./json-diff.vue'),
icon: CompareArrowsRound,
diff --git a/src/tools/json-diff/json-diff.vue b/src/tools/json-diff/json-diff.vue
index 80ada78bf..2fceb713b 100644
--- a/src/tools/json-diff/json-diff.vue
+++ b/src/tools/json-diff/json-diff.vue
@@ -5,6 +5,8 @@ import DiffsViewer from './diff-viewer/diff-viewer.vue';
import { withDefaultOnError } from '@/utils/defaults';
import { isNotThrowing } from '@/utils/boolean';
+const { t } = useI18n();
+
const rawLeftJson = ref('');
const rawRightJson = ref('');
@@ -14,7 +16,7 @@ const rightJson = computed(() => withDefaultOnError(() => JSON5.parse(rawRightJs
const jsonValidationRules = [
{
validator: (value: string) => value === '' || isNotThrowing(() => JSON5.parse(value)),
- message: 'Invalid JSON format',
+ message: t('tools.json-diff.invalidJSONFormat'),
},
];
@@ -23,8 +25,8 @@ const jsonValidationRules = [
import('./json-minify.vue'),
icon: Braces,
diff --git a/src/tools/json-minify/json-minify.vue b/src/tools/json-minify/json-minify.vue
index 51d627034..8cce31e8a 100644
--- a/src/tools/json-minify/json-minify.vue
+++ b/src/tools/json-minify/json-minify.vue
@@ -3,23 +3,24 @@ import JSON5 from 'json5';
import type { UseValidationRule } from '@/composable/validation';
import { withDefaultOnError } from '@/utils/defaults';
+const { t } = useI18n();
const defaultValue = '{\n\t"hello": [\n\t\t"world"\n\t]\n}';
const transformer = (value: string) => withDefaultOnError(() => JSON.stringify(JSON5.parse(value), null, 0), '');
const rules: UseValidationRule[] = [
{
validator: (v: string) => v === '' || JSON5.parse(v),
- message: 'Provided JSON is not valid.',
+ message: t('tools.json-minify.invalidMessage'),
},
];
import('./json-to-csv.vue'),
icon: List,
diff --git a/src/tools/json-to-csv/json-to-csv.vue b/src/tools/json-to-csv/json-to-csv.vue
index e2f5ddb67..ff40db2a4 100644
--- a/src/tools/json-to-csv/json-to-csv.vue
+++ b/src/tools/json-to-csv/json-to-csv.vue
@@ -13,19 +13,20 @@ function transformer(value: string) {
}, '');
}
+const { t } = useI18n();
const rules: UseValidationRule[] = [
{
validator: (v: string) => v === '' || JSON5.parse(v),
- message: 'Provided JSON is not valid.',
+ message: t('tools.json-to-csv.invalidMessage'),
},
];
diff --git a/src/tools/json-to-csv/locales/en.yml b/src/tools/json-to-csv/locales/en.yml
new file mode 100644
index 000000000..f18afead9
--- /dev/null
+++ b/src/tools/json-to-csv/locales/en.yml
@@ -0,0 +1,10 @@
+tools:
+ json-to-csv:
+ title: JSON to CSV
+ description: Convert JSON to CSV with automatic header detection.
+
+ inputLabel: Your raw JSON
+ inputPlaceholder: Paste your raw JSON here...
+ outputLabel: CSV version of your JSON
+
+ invalidMessage: Provided JSON is not valid.
diff --git a/src/tools/json-to-csv/locales/fr.yml b/src/tools/json-to-csv/locales/fr.yml
new file mode 100644
index 000000000..99677f152
--- /dev/null
+++ b/src/tools/json-to-csv/locales/fr.yml
@@ -0,0 +1,10 @@
+tools:
+ json-to-csv:
+ title: JSON vers CSV
+ description: Convertit du JSON en CSV avec détection automatique de l'en-tête.
+
+ inputLabel: Votre JSON brut
+ inputPlaceholder: Collez votre JSON brut ici...
+ outputLabel: Version CSV de votre JSON
+
+ invalidMessage: Le JSON fourni n'est pas valide.
diff --git a/src/tools/json-to-csv/locales/zh.yml b/src/tools/json-to-csv/locales/zh.yml
new file mode 100644
index 000000000..7706a1901
--- /dev/null
+++ b/src/tools/json-to-csv/locales/zh.yml
@@ -0,0 +1,10 @@
+tools:
+ json-to-csv:
+ title: JSON 转换为 CSV
+ description: 将 JSON 转换为 CSV,并自动检测标题。
+
+ inputLabel: 您的原始 JSON
+ inputPlaceholder: 在此粘贴您的原始 JSON...
+ outputLabel: 您的 JSON 的 CSV 版本
+
+ invalidMessage: 提供的 JSON 不是有效的。
diff --git a/src/tools/json-to-toml/index.ts b/src/tools/json-to-toml/index.ts
index da42c18d9..bdcae3db3 100644
--- a/src/tools/json-to-toml/index.ts
+++ b/src/tools/json-to-toml/index.ts
@@ -1,11 +1,11 @@
import { Braces } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.json-to-toml.title'),
+ name: t('tools.json-to-toml.title'),
path: '/json-to-toml',
- description: translate('tools.json-to-toml.description'),
+ description: t('tools.json-to-toml.description'),
keywords: ['json', 'parse', 'toml', 'convert', 'transform'],
component: () => import('./json-to-toml.vue'),
icon: Braces,
diff --git a/src/tools/json-to-toml/json-to-toml.vue b/src/tools/json-to-toml/json-to-toml.vue
index b1d37a38e..aa13da47b 100644
--- a/src/tools/json-to-toml/json-to-toml.vue
+++ b/src/tools/json-to-toml/json-to-toml.vue
@@ -4,6 +4,8 @@ import JSON5 from 'json5';
import { withDefaultOnError } from '../../utils/defaults';
import type { UseValidationRule } from '@/composable/validation';
+const { t } = useI18n();
+
const convertJsonToToml = (value: string) => [stringifyToml(JSON5.parse(value))].flat().join('\n').trim();
const transformer = (value: string) => value.trim() === '' ? '' : withDefaultOnError(() => convertJsonToToml(value), '');
@@ -11,16 +13,16 @@ const transformer = (value: string) => value.trim() === '' ? '' : withDefaultOnE
const rules: UseValidationRule[] = [
{
validator: (v: string) => v === '' || JSON5.parse(v),
- message: 'Provided JSON is not valid.',
+ message: t('tools.json-to-toml.invalidMessage'),
},
];
import('./json-to-yaml.vue'),
icon: Braces,
diff --git a/src/tools/json-to-yaml-converter/json-to-yaml.vue b/src/tools/json-to-yaml-converter/json-to-yaml.vue
index cbaeb22d8..389fd8833 100644
--- a/src/tools/json-to-yaml-converter/json-to-yaml.vue
+++ b/src/tools/json-to-yaml-converter/json-to-yaml.vue
@@ -5,21 +5,23 @@ import type { UseValidationRule } from '@/composable/validation';
import { isNotThrowing } from '@/utils/boolean';
import { withDefaultOnError } from '@/utils/defaults';
+const { t } = useI18n();
+
const transformer = (value: string) => withDefaultOnError(() => stringify(JSON5.parse(value)), '');
const rules: UseValidationRule[] = [
{
validator: (value: string) => value === '' || isNotThrowing(() => stringify(JSON5.parse(value))),
- message: 'Provided JSON is not valid.',
+ message: t('tools.json-to-yaml-converter.invalidMessage'),
},
];
import('./json-viewer.vue'),
icon: Braces,
diff --git a/src/tools/json-viewer/json-viewer.vue b/src/tools/json-viewer/json-viewer.vue
index 3928a44f2..42bbad2e2 100644
--- a/src/tools/json-viewer/json-viewer.vue
+++ b/src/tools/json-viewer/json-viewer.vue
@@ -6,6 +6,7 @@ import { withDefaultOnError } from '@/utils/defaults';
import { useValidation } from '@/composable/validation';
import TextareaCopyable from '@/components/TextareaCopyable.vue';
+const { t } = useI18n();
const inputElement = ref();
const rawJson = useStorage('json-prettify:raw-json', '{"hello": "world", "foo": "bar"}');
@@ -18,7 +19,7 @@ const rawJsonValidation = useValidation({
rules: [
{
validator: v => v === '' || JSON5.parse(v),
- message: 'Provided JSON is not valid.',
+ message: t('tools.json-prettify.invalidMessage'),
},
],
});
@@ -27,24 +28,24 @@ const rawJsonValidation = useValidation({
-
+
-
+
-
+
diff --git a/src/tools/json-viewer/locales/en.yml b/src/tools/json-viewer/locales/en.yml
new file mode 100644
index 000000000..abf8aa9f8
--- /dev/null
+++ b/src/tools/json-viewer/locales/en.yml
@@ -0,0 +1,12 @@
+tools:
+ json-prettify:
+ title: JSON prettify and format
+ description: Prettify your JSON string to a human friendly readable format.
+
+ sortKeys: 'Sort keys :'
+ indentSize: 'Indent size :'
+ rawJSONLabel: Your raw JSON
+ rawJSONPlaceholder: Paste your raw JSON here...
+ prettifyJSON: Prettified version of your JSON
+
+ invalidMessage: Provided JSON is not valid.
diff --git a/src/tools/json-viewer/locales/fr.yml b/src/tools/json-viewer/locales/fr.yml
new file mode 100644
index 000000000..36f20ec43
--- /dev/null
+++ b/src/tools/json-viewer/locales/fr.yml
@@ -0,0 +1,12 @@
+tools:
+ json-prettify:
+ title: Mise en forme et formatage JSON
+ description: Mettez en forme votre chaîne JSON pour un format lisible par l'homme.
+
+ sortKeys: 'Trier les clés :'
+ indentSize: "Taille de l'indentation :"
+ rawJSONLabel: Votre JSON brut
+ rawJSONPlaceholder: Collez votre JSON brut ici...
+ prettifyJSON: Version mise en forme de votre JSON
+
+ invalidMessage: Le JSON fourni n'est pas valide.
diff --git a/src/tools/json-viewer/locales/zh.yml b/src/tools/json-viewer/locales/zh.yml
new file mode 100644
index 000000000..2332c854b
--- /dev/null
+++ b/src/tools/json-viewer/locales/zh.yml
@@ -0,0 +1,12 @@
+tools:
+ json-prettify:
+ title: JSON 格式化工具
+ description: 将您的 JSON 字符串美化为易读的格式。
+
+ sortKeys: '排序键:'
+ indentSize: '缩进大小:'
+ rawJSONLabel: 您的原始 JSON
+ rawJSONPlaceholder: 在此粘贴您的原始 JSON…
+ prettifyJSON: 您的 JSON 的美化版本
+
+ invalidMessage: 提供的 JSON 不是有效的。
diff --git a/src/tools/jwt-parser/index.ts b/src/tools/jwt-parser/index.ts
index 939b4b34a..7b4a2d5df 100644
--- a/src/tools/jwt-parser/index.ts
+++ b/src/tools/jwt-parser/index.ts
@@ -1,11 +1,11 @@
import { Key } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.jwt-parser.title'),
+ name: t('tools.jwt-parser.title'),
path: '/jwt-parser',
- description: translate('tools.jwt-parser.description'),
+ description: t('tools.jwt-parser.description'),
keywords: [
'jwt',
'parser',
diff --git a/src/tools/jwt-parser/jwt-parser.constants.ts b/src/tools/jwt-parser/jwt-parser.constants.ts
index a5150a023..be8b7df70 100644
--- a/src/tools/jwt-parser/jwt-parser.constants.ts
+++ b/src/tools/jwt-parser/jwt-parser.constants.ts
@@ -1,92 +1,94 @@
+import { translate as t } from '@/plugins/i18n.plugin';
+
// From https://datatracker.ietf.org/doc/html/rfc7518#section-3.1
export const ALGORITHM_DESCRIPTIONS: { [k: string]: string } = {
- HS256: 'HMAC using SHA-256',
- HS384: 'HMAC using SHA-384',
- HS512: 'HMAC using SHA-512',
- RS256: 'RSASSA-PKCS1-v1_5 using SHA-256',
- RS384: 'RSASSA-PKCS1-v1_5 using SHA-384',
- RS512: 'RSASSA-PKCS1-v1_5 using SHA-512',
- ES256: 'ECDSA using P-256 and SHA-256',
- ES384: 'ECDSA using P-384 and SHA-384',
- ES512: 'ECDSA using P-521 and SHA-512',
- PS256: 'RSASSA-PSS using SHA-256 and MGF1 with SHA-256',
- PS384: 'RSASSA-PSS using SHA-384 and MGF1 with SHA-384',
- PS512: 'RSASSA-PSS using SHA-512 and MGF1 with SHA-512',
- none: 'No digital signature or MAC performed',
+ HS256: t('tools.jwt-parser.HS256'),
+ HS384: t('tools.jwt-parser.HS384'),
+ HS512: t('tools.jwt-parser.HS512'),
+ RS256: t('tools.jwt-parser.RS256'),
+ RS384: t('tools.jwt-parser.RS384'),
+ RS512: t('tools.jwt-parser.RS512'),
+ ES256: t('tools.jwt-parser.ES256'),
+ ES384: t('tools.jwt-parser.ES384'),
+ ES512: t('tools.jwt-parser.ES512'),
+ PS256: t('tools.jwt-parser.PS256'),
+ PS384: t('tools.jwt-parser.PS384'),
+ PS512: t('tools.jwt-parser.PS512'),
+ none: t('tools.jwt-parser.none'),
};
// List extracted from IANA: https://www.iana.org/assignments/jwt/jwt.xhtml
export const CLAIM_DESCRIPTIONS: Record = {
- typ: 'Type',
- alg: 'Algorithm',
- iss: 'Issuer',
- sub: 'Subject',
- aud: 'Audience',
- exp: 'Expiration Time',
- nbf: 'Not Before',
- iat: 'Issued At',
- jti: 'JWT ID',
- name: 'Full name',
- given_name: 'Given name(s) or first name(s)',
- family_name: 'Surname(s) or last name(s)',
- middle_name: 'Middle name(s)',
- nickname: 'Casual name',
- preferred_username: 'Shorthand name by which the End-User wishes to be referred to',
- profile: 'Profile page URL',
- picture: 'Profile picture URL',
- website: 'Web page or blog URL',
- email: 'Preferred e-mail address',
- email_verified: 'True if the e-mail address has been verified; otherwise false',
- gender: 'Gender',
- birthdate: 'Birthday',
- zoneinfo: 'Time zone',
- locale: 'Locale',
- phone_number: 'Preferred telephone number',
- phone_number_verified: 'True if the phone number has been verified; otherwise false',
- address: 'Preferred postal address',
- updated_at: 'Time the information was last updated',
- azp: 'Authorized party - the party to which the ID Token was issued',
- nonce: 'Value used to associate a Client session with an ID Token',
- auth_time: 'Time when the authentication occurred',
- at_hash: 'Access Token hash value',
- c_hash: 'Code hash value',
- acr: 'Authentication Context Class Reference',
- amr: 'Authentication Methods References',
- sub_jwk: 'Public key used to check the signature of an ID Token',
- cnf: 'Confirmation',
- sip_from_tag: 'SIP From tag header field parameter value',
- sip_date: 'SIP Date header field value',
- sip_callid: 'SIP Call-Id header field value',
- sip_cseq_num: 'SIP CSeq numeric header field parameter value',
- sip_via_branch: 'SIP Via branch header field parameter value',
- orig: 'Originating Identity String',
- dest: 'Destination Identity String',
- mky: 'Media Key Fingerprint String',
- events: 'Security Events',
- toe: 'Time of Event',
- txn: 'Transaction Identifier',
- rph: 'Resource Priority Header Authorization',
- sid: 'Session ID',
- vot: 'Vector of Trust value',
- vtm: 'Vector of Trust trustmark URL',
- attest: 'Attestation level as defined in SHAKEN framework',
- origid: 'Originating Identifier as defined in SHAKEN framework',
- act: 'Actor',
- scope: 'Scope Values',
- client_id: 'Client Identifier',
- may_act: 'Authorized Actor - the party that is authorized to become the actor',
- jcard: 'jCard data',
- at_use_nbr: 'Number of API requests for which the access token can be used',
- div: 'Diverted Target of a Call',
- opt: 'Original PASSporT (in Full Form)',
- vc: 'Verifiable Credential as specified in the W3C Recommendation',
- vp: 'Verifiable Presentation as specified in the W3C Recommendation',
- sph: 'SIP Priority header field',
- ace_profile: 'ACE profile a token is supposed to be used with.',
- cnonce: 'Client nonce',
- exi: 'Expires in',
- roles: 'Roles',
- groups: 'Groups',
- entitlements: 'Entitlements',
- token_introspection: 'Token introspection response',
+ typ: t('tools.jwt-parser.typ'),
+ alg: t('tools.jwt-parser.alg'),
+ iss: t('tools.jwt-parser.iss'),
+ sub: t('tools.jwt-parser.sub'),
+ aud: t('tools.jwt-parser.aud'),
+ exp: t('tools.jwt-parser.exp'),
+ nbf: t('tools.jwt-parser.nbf'),
+ iat: t('tools.jwt-parser.iat'),
+ jti: t('tools.jwt-parser.jti'),
+ name: t('tools.jwt-parser.name'),
+ given_name: t('tools.jwt-parser.givenName'),
+ family_name: t('tools.jwt-parser.familyName'),
+ middle_name: t('tools.jwt-parser.middleName'),
+ nickname: t('tools.jwt-parser.nickname'),
+ preferred_username: t('tools.jwt-parser.preferredUsername'),
+ profile: t('tools.jwt-parser.profile'),
+ picture: t('tools.jwt-parser.picture'),
+ website: t('tools.jwt-parser.website'),
+ email: t('tools.jwt-parser.email'),
+ email_verified: t('tools.jwt-parser.emailVerified'),
+ gender: t('tools.jwt-parser.gender'),
+ birthdate: t('tools.jwt-parser.birthdate'),
+ zoneinfo: t('tools.jwt-parser.zoneinfo'),
+ locale: t('tools.jwt-parser.locale'),
+ phone_number: t('tools.jwt-parser.phoneNumber'),
+ phone_number_verified: t('tools.jwt-parser.phoneNumberVerified'),
+ address: t('tools.jwt-parser.address'),
+ updated_at: t('tools.jwt-parser.updatedAt'),
+ azp: t('tools.jwt-parser.azp'),
+ nonce: t('tools.jwt-parser.nonce'),
+ auth_time: t('tools.jwt-parser.authTime'),
+ at_hash: t('tools.jwt-parser.atHash'),
+ c_hash: t('tools.jwt-parser.cHash'),
+ acr: t('tools.jwt-parser.acr'),
+ amr: t('tools.jwt-parser.amr'),
+ sub_jwk: t('tools.jwt-parser.subJwk'),
+ cnf: t('tools.jwt-parser.cnf'),
+ sip_from_tag: t('tools.jwt-parser.sipFromTag'),
+ sip_date: t('tools.jwt-parser.sipDate'),
+ sip_callid: t('tools.jwt-parser.sipCallid'),
+ sip_cseq_num: t('tools.jwt-parser.sipCseqNum'),
+ sip_via_branch: t('tools.jwt-parser.sipViaBranch'),
+ orig: t('tools.jwt-parser.orig'),
+ dest: t('tools.jwt-parser.dest'),
+ mky: t('tools.jwt-parser.mky'),
+ events: t('tools.jwt-parser.events'),
+ toe: t('tools.jwt-parser.toe'),
+ txn: t('tools.jwt-parser.txn'),
+ rph: t('tools.jwt-parser.rph'),
+ sid: t('tools.jwt-parser.sid'),
+ vot: t('tools.jwt-parser.vot'),
+ vtm: t('tools.jwt-parser.vtm'),
+ attest: t('tools.jwt-parser.attest'),
+ origid: t('tools.jwt-parser.origid'),
+ act: t('tools.jwt-parser.act'),
+ scope: t('tools.jwt-parser.scope'),
+ client_id: t('tools.jwt-parser.clientId'),
+ may_act: t('tools.jwt-parser.mayAct'),
+ jcard: t('tools.jwt-parser.jcard'),
+ at_use_nbr: t('tools.jwt-parser.atUseNbr'),
+ div: t('tools.jwt-parser.div'),
+ opt: t('tools.jwt-parser.opt'),
+ vc: t('tools.jwt-parser.vc'),
+ vp: t('tools.jwt-parser.vp'),
+ sph: t('tools.jwt-parser.sph'),
+ ace_profile: t('tools.jwt-parser.aceProfile'),
+ cnonce: t('tools.jwt-parser.cnonce'),
+ exi: t('tools.jwt-parser.exi'),
+ roles: t('tools.jwt-parser.roles'),
+ groups: t('tools.jwt-parser.groups'),
+ entitlements: t('tools.jwt-parser.entitlements'),
+ token_introspection: t('tools.jwt-parser.tokenIntrospection'),
};
diff --git a/src/tools/jwt-parser/jwt-parser.vue b/src/tools/jwt-parser/jwt-parser.vue
index 6b30fc0c9..791ec5718 100644
--- a/src/tools/jwt-parser/jwt-parser.vue
+++ b/src/tools/jwt-parser/jwt-parser.vue
@@ -4,6 +4,8 @@ import { useValidation } from '@/composable/validation';
import { isNotThrowing } from '@/utils/boolean';
import { withDefaultOnError } from '@/utils/defaults';
+const { t } = useI18n();
+
const rawJwt = ref(
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
);
@@ -13,8 +15,8 @@ const decodedJWT = computed(() =>
);
const sections = [
- { key: 'header', title: 'Header' },
- { key: 'payload', title: 'Payload' },
+ { key: 'header', title: t('tools.jwt-parser.header') },
+ { key: 'payload', title: t('tools.jwt-parser.payload') },
] as const;
const validation = useValidation({
@@ -22,7 +24,7 @@ const validation = useValidation({
rules: [
{
validator: value => value.length > 0 && isNotThrowing(() => decodeJwt({ jwt: rawJwt.value })),
- message: 'Invalid JWT',
+ message: t('tools.jwt-parser.invalidJWT'),
},
],
});
@@ -30,7 +32,7 @@ const validation = useValidation({
-
+
diff --git a/src/tools/jwt-parser/locales/en.yml b/src/tools/jwt-parser/locales/en.yml
new file mode 100644
index 000000000..ef3cb2d4a
--- /dev/null
+++ b/src/tools/jwt-parser/locales/en.yml
@@ -0,0 +1,98 @@
+tools:
+ jwt-parser:
+ title: JWT parser
+ description: Parse and decode your JSON Web Token (jwt) and display its content.
+
+ label: JWT to decode
+ placeholder: Put your token here...
+ header: Header
+ payload: Payload
+
+ invalidJWT: Invalid JWT
+
+ HS256: 'HMAC using SHA-256'
+ HS384: 'HMAC using SHA-384'
+ HS512: 'HMAC using SHA-512'
+ RS256: 'RSASSA-PKCS1-v1_5 using SHA-256'
+ RS384: 'RSASSA-PKCS1-v1_5 using SHA-384'
+ RS512: 'RSASSA-PKCS1-v1_5 using SHA-512'
+ ES256: 'ECDSA using P-256 and SHA-256'
+ ES384: 'ECDSA using P-384 and SHA-384'
+ ES512: 'ECDSA using P-521 and SHA-512'
+ PS256: 'RSASSA-PSS using SHA-256 and MGF1 with SHA-256'
+ PS384: 'RSASSA-PSS using SHA-384 and MGF1 with SHA-384'
+ PS512: 'RSASSA-PSS using SHA-512 and MGF1 with SHA-512'
+ none: 'No digital signature or MAC performed'
+
+ typ: 'Type'
+ alg: 'Algorithm'
+ iss: 'Issuer'
+ sub: 'Subject'
+ aud: 'Audience'
+ exp: 'Expiration Time'
+ nbf: 'Not Before'
+ iat: 'Issued At'
+ jti: 'JWT ID'
+ name: 'Full name'
+ givenName: 'Given name(s) or first name(s)'
+ familyName: 'Surname(s) or last name(s)'
+ middleName: 'Middle name(s)'
+ nickname: 'Casual name'
+ preferredUsername: 'Shorthand name by which the End-User wishes to be referred to'
+ profile: 'Profile page URL'
+ picture: 'Profile picture URL'
+ website: 'Web page or blog URL'
+ email: 'Preferred e-mail address'
+ emailVerified: 'True if the e-mail address has been verified; otherwise false'
+ gender: 'Gender'
+ birthdate: 'Birthday'
+ zoneinfo: 'Time zone'
+ locale: 'Locale'
+ phoneNumber: 'Preferred telephone number'
+ phoneNumberVerified: 'True if the phone number has been verified; otherwise false'
+ address: 'Preferred postal address'
+ updatedAt: 'Time the information was last updated'
+ azp: 'Authorized party - the party to which the ID Token was issued'
+ nonce: 'Value used to associate a Client session with an ID Token'
+ authTime: 'Time when the authentication occurred'
+ atHash: 'Access Token hash value'
+ cHash: 'Code hash value'
+ acr: 'Authentication Context Class Reference'
+ amr: 'Authentication Methods References'
+ subJwk: 'Public key used to check the signature of an ID Token'
+ cnf: 'Confirmation'
+ sipFromTag: 'SIP From tag header field parameter value'
+ sipDate: 'SIP Date header field value'
+ sipCallid: 'SIP Call-Id header field value'
+ sipCseqNum: 'SIP CSeq numeric header field parameter value'
+ sipViaBranch: 'SIP Via branch header field parameter value'
+ orig: 'Originating Identity String'
+ dest: 'Destination Identity String'
+ mky: 'Media Key Fingerprint String'
+ events: 'Security Events'
+ toe: 'Time of Event'
+ txn: 'Transaction Identifier'
+ rph: 'Resource Priority Header Authorization'
+ sid: 'Session ID'
+ vot: 'Vector of Trust value'
+ vtm: 'Vector of Trust trustmark URL'
+ attest: 'Attestation level as defined in SHAKEN framework'
+ origid: 'Originating Identifier as defined in SHAKEN framework'
+ act: 'Actor'
+ scope: 'Scope Values'
+ clientId: 'Client Identifier'
+ mayAct: 'Authorized Actor - the party that is authorized to become the actor'
+ jcard: 'jCard data'
+ atUseNbr: 'Number of API requests for which the access token can be used'
+ div: 'Diverted Target of a Call'
+ opt: 'Original PASSporT (in Full Form)'
+ vc: 'Verifiable Credential as specified in the W3C Recommendation'
+ vp: 'Verifiable Presentation as specified in the W3C Recommendation'
+ sph: 'SIP Priority header field'
+ aceProfile: 'ACE profile a token is supposed to be used with.'
+ cnonce: 'Client nonce'
+ exi: 'Expires in'
+ roles: 'Roles'
+ groups: 'Groups'
+ entitlements: 'Entitlements'
+ tokenIntrospection: 'Token introspection response'
diff --git a/src/tools/jwt-parser/locales/fr.yml b/src/tools/jwt-parser/locales/fr.yml
new file mode 100644
index 000000000..06f764580
--- /dev/null
+++ b/src/tools/jwt-parser/locales/fr.yml
@@ -0,0 +1,98 @@
+tools:
+ jwt-parser:
+ title: Analyseur JWT
+ description: Analyse et décode votre jeton JSON Web Token (JWT) et affiche son contenu.
+
+ label: JWT à décoder
+ placeholder: Mettez votre jeton ici...
+ header: En-tête
+ payload: Charge utile
+
+ invalidJWT: JWT invalide
+
+ HS256: 'HMAC utilisant SHA-256'
+ HS384: 'HMAC utilisant SHA-384'
+ HS512: 'HMAC utilisant SHA-512'
+ RS256: 'RSASSA-PKCS1-v1_5 utilisant SHA-256'
+ RS384: 'RSASSA-PKCS1-v1_5 utilisant SHA-384'
+ RS512: 'RSASSA-PKCS1-v1_5 utilisant SHA-512'
+ ES256: 'ECDSA utilisant P-256 et SHA-256'
+ ES384: 'ECDSA utilisant P-384 et SHA-384'
+ ES512: 'ECDSA utilisant P-521 et SHA-512'
+ PS256: 'RSASSA-PSS utilisant SHA-256 et MGF1 avec SHA-256'
+ PS384: 'RSASSA-PSS utilisant SHA-384 et MGF1 avec SHA-384'
+ PS512: 'RSASSA-PSS utilisant SHA-512 et MGF1 avec SHA-512'
+ none: 'Aucune signature numérique ou MAC effectuée'
+
+ typ: 'Type'
+ alg: 'Algorithme'
+ iss: 'Émetteur'
+ sub: 'Sujet'
+ aud: 'Audience'
+ exp: Heure d'expiration
+ nbf: 'Pas avant'
+ iat: 'Émis à'
+ jti: 'ID JWT'
+ name: 'Nom complet'
+ givenName: 'Prénom(s)'
+ familyName: 'Nom(s) de famille'
+ middleName: 'Deuxième(s) prénom(s)'
+ nickname: Nom d'usage
+ preferredUsername: Nom abrégé par lequel l'Utilisateur final souhaite être désigné
+ profile: URL de la page de profil
+ picture: URL de l'image de profil
+ website: URL de la page web ou du blog
+ email: Adresse e-mail préférée
+ emailVerified: Vrai si l'adresse e-mail a été vérifiée; sinon faux
+ gender: Genre
+ birthdate: Date de naissance
+ zoneinfo: Fuseau horaire
+ locale: Paramètre régional
+ phoneNumber: Numéro de téléphone préféré
+ phoneNumberVerified: 'Vrai si le numéro de téléphone a été vérifié; sinon faux'
+ address: Adresse postale préférée
+ updatedAt: 'Heure à laquelle les informations ont été mises à jour pour la dernière fois'
+ azp: 'Partie autorisée - la partie à laquelle le jeton ID a été délivré'
+ nonce: 'Valeur utilisée pour associer une session Client à un jeton ID'
+ authTime: Heure à laquelle l'authentification a eu lieu
+ atHash: Valeur de hachage du jeton d'accès
+ cHash: 'Valeur de hachage du code'
+ acr: Référence de classe de contexte d'authentification
+ amr: Références de méthodes d'authentification
+ subJwk: Clé publique utilisée pour vérifier la signature d'un jeton ID
+ cnf: Confirmation
+ sipFromTag: Valeur du paramètre champ d'en-tête SIP From tag
+ sipDate: Valeur du champ d'en-tête SIP Date
+ sipCallid: Valeur du champ d'en-tête SIP Call-Id
+ sipCseqNum: Valeur du paramètre numérique d'en-tête SIP CSeq
+ sipViaBranch: Valeur du paramètre d'en-tête SIP Via branch
+ orig: Chaîne d'identité d'origine
+ dest: Chaîne d'identité de destination
+ mky: Chaîne d'empreinte de clé média
+ events: Événements de sécurité
+ toe: Heure de l'événement
+ txn: Identifiant de transaction
+ rph: Autorisation d'en-tête de priorité de ressource
+ sid: ID de session
+ vot: Valeur du vecteur de confiance
+ vtm: URL du trustmark du vecteur de confiance
+ attest: Niveau d'attestation tel que défini dans le cadre SHAKEN
+ origid: Identifiant d'origine tel que défini dans le cadre SHAKEN
+ act: Acteur
+ scope: Valeurs de portée
+ clientId: Identifiant du Client
+ mayAct: Acteur autorisé - la partie autorisée à devenir l'acteur
+ jcard: Données jCard
+ atUseNbr: Nombre de demandes API pour lesquelles le jeton d'accès peut être utilisé
+ div: Cible détournée d'un appel
+ opt: "PASSporT d'origine (sous forme complète)"
+ vc: Justificatif vérifiable tel que spécifié dans la Recommandation W3C
+ vp: Présentation vérifiable telle que spécifiée dans la Recommandation W3C
+ sph: En-tête de priorité SIP
+ aceProfile: Profil ACE avec lequel un jeton est censé être utilisé.
+ cnonce: Nonce du Client
+ exi: Expire dans
+ roles: Rôles
+ groups: Groupes
+ entitlements: Droits
+ tokenIntrospection: Réponse d'inspection de jeton
\ No newline at end of file
diff --git a/src/tools/jwt-parser/locales/zh.yml b/src/tools/jwt-parser/locales/zh.yml
new file mode 100644
index 000000000..66f77a4b5
--- /dev/null
+++ b/src/tools/jwt-parser/locales/zh.yml
@@ -0,0 +1,98 @@
+tools:
+ jwt-parser:
+ title: JWT 解析器
+ description: 解析和解码您的 JSON Web Token (jwt) 并显示其内容。
+
+ label: 要解码的 JWT
+ placeholder: 在这里放置您的令牌...
+ header: 头部
+ payload: 负载
+
+ invalidJWT: 无效的 JWT
+
+ HS256: '使用 SHA-256 的 HMAC'
+ HS384: '使用 SHA-384 的 HMAC'
+ HS512: '使用 SHA-512 的 HMAC'
+ RS256: '使用 SHA-256 的 RSASSA-PKCS1-v1_5'
+ RS384: '使用 SHA-384 的 RSASSA-PKCS1-v1_5'
+ RS512: '使用 SHA-512 的 RSASSA-PKCS1-v1_5'
+ ES256: '使用 P-256 和 SHA-256 的 ECDSA'
+ ES384: '使用 P-384 和 SHA-384 的 ECDSA'
+ ES512: '使用 P-521 和 SHA-512 的 ECDSA'
+ PS256: '使用 SHA-256 和具有 SHA-256 的 MGF1 的 RSASSA-PSS'
+ PS384: '使用 SHA-384 和具有 SHA-384 的 MGF1 的 RSASSA-PSS'
+ PS512: '使用 SHA-512 和具有 SHA-512 的 MGF1 的 RSASSA-PSS'
+ none: '未执行数字签名或 MAC'
+
+ typ: '类型'
+ alg: '算法'
+ iss: '签发者'
+ sub: '主题'
+ aud: '受众'
+ exp: '过期时间'
+ nbf: '不早于'
+ iat: '签发时间'
+ jti: 'JWT ID'
+ name: '全名'
+ givenName: '名字'
+ familyName: '姓氏'
+ middleName: '中间名'
+ nickname: '昵称'
+ preferredUsername: '用户希望被称呼的简称'
+ profile: '个人资料页面 URL'
+ picture: '个人资料图片 URL'
+ website: '网页或博客 URL'
+ email: '首选电子邮件地址'
+ emailVerified: '如果电子邮件地址已经验证为 true;否则为 false'
+ gender: '性别'
+ birthdate: '生日'
+ zoneinfo: '时区'
+ locale: '区域设置'
+ phoneNumber: '首选电话号码'
+ phoneNumberVerified: '如果电话号码已经验证为 true;否则为 false'
+ address: '首选邮寄地址'
+ updatedAt: '信息上次更新时间'
+ azp: '授权方 - 发出 ID 令牌的一方'
+ nonce: '用于将客户端会话与 ID 令牌关联的值'
+ authTime: '认证发生时间'
+ atHash: '访问令牌哈希值'
+ cHash: '代码哈希值'
+ acr: '认证上下文类引用'
+ amr: '认证方法引用'
+ subJwk: '用于验证 ID 令牌签名的公钥'
+ cnf: '确认'
+ sipFromTag: 'SIP From 标签头字段参数值'
+ sipDate: 'SIP 日期头字段值'
+ sipCallid: 'SIP Call-Id 头字段值'
+ sipCseqNum: 'SIP CSeq 数字头字段参数值'
+ sipViaBranch: 'SIP Via 分支头字段参数值'
+ orig: '原始身份字符串'
+ dest: '目标身份字符串'
+ mky: '媒体密钥指纹字符串'
+ events: '安全事件'
+ toe: '事件时间'
+ txn: '交易标识符'
+ rph: '资源优先级头授权'
+ sid: '会话 ID'
+ vot: '信任向量值'
+ vtm: '信任向量标记 URL'
+ attest: 'SHAKEN 框架中定义的证明级别'
+ origid: 'SHAKEN 框架中定义的起始标识符'
+ act: '操作者'
+ scope: '范围值'
+ clientId: '客户端标识符'
+ mayAct: '授权操作者 - 被授权成为操作者的一方'
+ jcard: 'jCard 数据'
+ atUseNbr: '访问令牌可用于的 API 请求次数'
+ div: '呼叫的被转移目标'
+ opt: '原始 PASSporT(完整形式)'
+ vc: '根据 W3C 推荐规范指定的可验证凭证'
+ vp: '根据 W3C 推荐规范指定的可验证展示'
+ sph: 'SIP 优先级头字段'
+ aceProfile: 'ACE 配置文件应与之一起使用的令牌'
+ cnonce: '客户端随机数'
+ exi: '剩余时间'
+ roles: '角色'
+ groups: '组'
+ entitlements: '权利'
+ tokenIntrospection: '令牌内省响应'
diff --git a/src/tools/keycode-info/index.ts b/src/tools/keycode-info/index.ts
index a2f36562f..fa8ea17c5 100644
--- a/src/tools/keycode-info/index.ts
+++ b/src/tools/keycode-info/index.ts
@@ -1,11 +1,11 @@
import { Keyboard } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.keycode-info.title'),
+ name: t('tools.keycode-info.title'),
path: '/keycode-info',
- description: translate('tools.keycode-info.description'),
+ description: t('tools.keycode-info.description'),
keywords: [
'keycode',
'info',
diff --git a/src/tools/keycode-info/keycode-info.vue b/src/tools/keycode-info/keycode-info.vue
index a999d8ae8..420e9c76b 100644
--- a/src/tools/keycode-info/keycode-info.vue
+++ b/src/tools/keycode-info/keycode-info.vue
@@ -5,6 +5,8 @@ import InputCopyable from '../../components/InputCopyable.vue';
const event = ref();
+const { t } = useI18n();
+
useEventListener(document, 'keydown', (e) => {
event.value = e;
});
@@ -16,28 +18,28 @@ const fields = computed(() => {
return [
{
- label: 'Key :',
+ label: t('tools.keycode-info.keyLabel'),
value: event.value.key,
- placeholder: 'Key name...',
+ placeholder: t('tools.keycode-info.keyPlaceholder'),
},
{
- label: 'Keycode :',
+ label: t('tools.keycode-info.keycodeLabel'),
value: String(event.value.keyCode),
- placeholder: 'Keycode...',
+ placeholder: t('tools.keycode-info.keycodePlaceholder'),
},
{
- label: 'Code :',
+ label: t('tools.keycode-info.codeLabel'),
value: event.value.code,
- placeholder: 'Code...',
+ placeholder: t('tools.keycode-info.codePlaceholder'),
},
{
- label: 'Location :',
+ label: t('tools.keycode-info.locationLabel'),
value: String(event.value.location),
- placeholder: 'Code...',
+ placeholder: t('tools.keycode-info.locationPlaceholder'),
},
{
- label: 'Modifiers :',
+ label: t('tools.keycode-info.modifiersLabel'),
value: [
event.value.metaKey && 'Meta',
event.value.shiftKey && 'Shift',
@@ -46,7 +48,7 @@ const fields = computed(() => {
]
.filter(Boolean)
.join(' + '),
- placeholder: 'None',
+ placeholder: t('tools.keycode-info.modifiersPlaceholder'),
},
];
});
@@ -59,7 +61,7 @@ const fields = computed(() => {
{{ event.key }}
- Press the key on your keyboard you want to get info about this key
+ {{ t('tools.keycode-info.tips') }}
diff --git a/src/tools/keycode-info/locales/en.yml b/src/tools/keycode-info/locales/en.yml
new file mode 100644
index 000000000..dbae839fd
--- /dev/null
+++ b/src/tools/keycode-info/locales/en.yml
@@ -0,0 +1,17 @@
+tools:
+ keycode-info:
+ title: Keycode info
+ description: Find the javascript keycode, code, location and modifiers of any pressed key.
+
+ keyLabel: 'Key :'
+ keyPlaceholder: 'Key name...'
+ keycodeLabel: 'Keycode :'
+ keycodePlaceholder: 'Keycode...'
+ codeLabel: 'Code :'
+ codePlaceholder: 'Code...'
+ locationLabel: 'Location :'
+ locationPlaceholder: 'Code...'
+ modifiersLabel: 'Modifiers :'
+ modifiersPlaceholder: 'None'
+
+ tips: Press the key on your keyboard you want to get info about this key
diff --git a/src/tools/keycode-info/locales/fr.yml b/src/tools/keycode-info/locales/fr.yml
new file mode 100644
index 000000000..2d6cfe978
--- /dev/null
+++ b/src/tools/keycode-info/locales/fr.yml
@@ -0,0 +1,17 @@
+tools:
+ keycode-info:
+ title: Informations sur le code de touche
+ description: Trouvez le code, l'emplacement et les modificateurs javascript de n'importe quelle touche enfoncée.
+
+ keyLabel: 'Touche :'
+ keyPlaceholder: 'Nom de la touche...'
+ keycodeLabel: 'Code de touche :'
+ keycodePlaceholder: 'Code de touche...'
+ codeLabel: 'Code :'
+ codePlaceholder: 'Code...'
+ locationLabel: 'Emplacement :'
+ locationPlaceholder: 'Code...'
+ modifiersLabel: 'Modificateurs :'
+ modifiersPlaceholder: 'Aucun'
+
+ tips: Appuyez sur la touche de votre clavier dont vous voulez obtenir des informations
diff --git a/src/tools/keycode-info/locales/zh.yml b/src/tools/keycode-info/locales/zh.yml
new file mode 100644
index 000000000..80b5eac4b
--- /dev/null
+++ b/src/tools/keycode-info/locales/zh.yml
@@ -0,0 +1,17 @@
+tools:
+ keycode-info:
+ title: 按键信息
+ description: 查找任何按键的 JavaScript 按键码、代码、位置和修饰键。
+
+ keyLabel: '按键:'
+ keyPlaceholder: '按键名称...'
+ keycodeLabel: '按键码:'
+ keycodePlaceholder: '按键码...'
+ codeLabel: '代码:'
+ codePlaceholder: '代码...'
+ locationLabel: '位置:'
+ locationPlaceholder: '位置...'
+ modifiersLabel: '修饰键:'
+ modifiersPlaceholder: '无'
+
+ tips: 按下您键盘上想要获取信息的按键
diff --git a/src/tools/list-converter/index.ts b/src/tools/list-converter/index.ts
index 9ae7c512c..f1c20f7ee 100644
--- a/src/tools/list-converter/index.ts
+++ b/src/tools/list-converter/index.ts
@@ -1,11 +1,11 @@
import { List } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.list-converter.title'),
+ name: t('tools.list-converter.title'),
path: '/list-converter',
- description: translate('tools.list-converter.description'),
+ description: t('tools.list-converter.description'),
keywords: ['list', 'converter', 'sort', 'reverse', 'prefix', 'suffix', 'lowercase', 'truncate'],
component: () => import('./list-converter.vue'),
icon: List,
diff --git a/src/tools/list-converter/list-converter.vue b/src/tools/list-converter/list-converter.vue
index 19dd30e5c..8fb09312a 100644
--- a/src/tools/list-converter/list-converter.vue
+++ b/src/tools/list-converter/list-converter.vue
@@ -3,14 +3,16 @@ import { useStorage } from '@vueuse/core';
import { convert } from './list-converter.models';
import type { ConvertOptions } from './list-converter.types';
+const { t } = useI18n();
+
const sortOrderOptions = [
{
- label: 'Sort ascending',
+ label: t('tools.list-converter.sortOrder.asc'),
value: 'asc',
disabled: false,
},
{
- label: 'Sort descending',
+ label: t('tools.list-converter.sortOrder.desc'),
value: 'desc',
disabled: false,
},
@@ -41,14 +43,14 @@ function transformer(value: string) {
-
+
-
+
-
+
-
+
@@ -115,9 +117,9 @@ function transformer(value: string) {
diff --git a/src/tools/list-converter/locales/en.yml b/src/tools/list-converter/locales/en.yml
new file mode 100644
index 000000000..2d0e40a84
--- /dev/null
+++ b/src/tools/list-converter/locales/en.yml
@@ -0,0 +1,28 @@
+tools:
+ list-converter:
+ title: List converter
+ description: This tool can process column-based data and apply various changes (transpose, add prefix and suffix, reverse list, sort list, lowercase values, truncate values) to each row.
+
+ trimListItems: Trim list items
+ removeDuplicates: Remove duplicates
+ convertToLowercase: Convert to lowercase
+ keepLineBreaks: Keep line breaks
+
+ sortListLabel: Sort list
+ sortListPlaceholder: Sort alphabetically
+ separatorLabel: Separator
+ separatorPlaceholder: ','
+ wrapItem: Wrap item
+ itemPrefix: Item prefix
+ itemSuffix: Item suffix
+ wrapList: Wrap list
+ listPrefix: List prefix
+ listSuffix: List suffix
+
+ inputLabel: Your input data
+ inputPlaceholder: Paste your input data here...
+ outputLabel: Your transformed data
+
+ sortOrder:
+ asc: Sort ascending
+ desc: Sort descending
diff --git a/src/tools/list-converter/locales/fr.yml b/src/tools/list-converter/locales/fr.yml
new file mode 100644
index 000000000..d361f8246
--- /dev/null
+++ b/src/tools/list-converter/locales/fr.yml
@@ -0,0 +1,28 @@
+tools:
+ list-converter:
+ title: Convertisseur de liste
+ description: Cet outil peut traiter des données basées sur des colonnes et appliquer divers changements (transposer, ajouter un préfixe et un suffixe, inverser la liste, trier la liste, mettre en minuscule, tronquer les valeurs) à chaque ligne.
+
+ trimListItems: Trimmer les éléments de la liste
+ removeDuplicates: Supprimer les doublons
+ convertToLowercase: Convertir en minuscule
+ keepLineBreaks: Garder les sauts de ligne
+
+ sortListLabel: Trier la liste
+ sortListPlaceholder: Trier par ordre alphabétique
+ separatorLabel: Séparateur
+ separatorPlaceholder: ','
+ wrapItem: Envelopper l'élément
+ itemPrefix: Préfixe d'élément
+ itemSuffix: Suffixe d'élément
+ wrapList: Envelopper la liste
+ listPrefix: Préfixe de liste
+ listSuffix: Suffixe de liste
+
+ inputLabel: Vos données d'entrée
+ inputPlaceholder: Collez vos données d'entrée ici...
+ outputLabel: Vos données transformées
+
+ sortOrder:
+ asc: Trier par ordre croissant
+ desc: Trier par ordre décroissant
diff --git a/src/tools/list-converter/locales/zh.yml b/src/tools/list-converter/locales/zh.yml
new file mode 100644
index 000000000..5e2ae7fa3
--- /dev/null
+++ b/src/tools/list-converter/locales/zh.yml
@@ -0,0 +1,28 @@
+tools:
+ list-converter:
+ title: 列表转换器
+ description: 该工具可以处理基于列的数据,并对每一行应用各种更改(转置、添加前缀和后缀、反转列表、排序列表、小写值、截断值)。
+
+ trimListItems: 裁剪列表项
+ removeDuplicates: 删除重复项
+ convertToLowercase: 转换为小写
+ keepLineBreaks: 保留换行符
+
+ sortListLabel: 排序列表
+ sortListPlaceholder: 按字母顺序排序
+ separatorLabel: 分隔符
+ separatorPlaceholder: ','
+ wrapItem: 包装条目
+ itemPrefix: 条目前缀
+ itemSuffix: 条目后缀
+ wrapList: 包装列表
+ listPrefix: 列表前缀
+ listSuffix: 列表后缀
+
+ inputLabel: 您的输入数据
+ inputPlaceholder: 在此处粘贴您的输入数据...
+ outputLabel: 您的转换后的数据
+
+ sortOrder:
+ asc: 升序排序
+ desc: 降序排序
diff --git a/src/tools/lorem-ipsum-generator/index.ts b/src/tools/lorem-ipsum-generator/index.ts
index 2634d9e0c..4be3e3b6d 100644
--- a/src/tools/lorem-ipsum-generator/index.ts
+++ b/src/tools/lorem-ipsum-generator/index.ts
@@ -1,11 +1,11 @@
import { AlignJustified } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.lorem-ipsum-generator.title'),
+ name: t('tools.lorem-ipsum-generator.title'),
path: '/lorem-ipsum-generator',
- description: translate('tools.lorem-ipsum-generator.description'),
+ description: t('tools.lorem-ipsum-generator.description'),
keywords: ['lorem', 'ipsum', 'dolor', 'sit', 'amet', 'placeholder', 'text', 'filler', 'random', 'generator'],
component: () => import('./lorem-ipsum-generator.vue'),
icon: AlignJustified,
diff --git a/src/tools/lorem-ipsum-generator/locales/en.yml b/src/tools/lorem-ipsum-generator/locales/en.yml
new file mode 100644
index 000000000..2a8c762ab
--- /dev/null
+++ b/src/tools/lorem-ipsum-generator/locales/en.yml
@@ -0,0 +1,14 @@
+tools:
+ lorem-ipsum-generator:
+ title: Lorem ipsum generator
+ description: Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content.
+
+ paragraphs: Paragraphs
+ sentences: Sentences per paragraph
+ words: Words per sentence
+ startWithLoremIpsum: Start with lorem ipsum ?
+ asHTML: As html ?
+ loremIpsumText: Your lorem ipsum...
+
+ copyBtn: Copy
+ copied: Lorem ipsum copied to the clipboard
diff --git a/src/tools/lorem-ipsum-generator/locales/fr.yml b/src/tools/lorem-ipsum-generator/locales/fr.yml
new file mode 100644
index 000000000..e591c4132
--- /dev/null
+++ b/src/tools/lorem-ipsum-generator/locales/fr.yml
@@ -0,0 +1,14 @@
+tools:
+ lorem-ipsum-generator:
+ title: Générateur de Lorem Ipsum
+ description: Lorem ipsum est un texte fictif couramment utilisé pour démontrer la forme visuelle d'un document ou d'une police de caractères sans se fier à un contenu significatif.
+
+ paragraphs: Paragraphes
+ sentences: Phrases par paragraphe
+ words: Mots par phrase
+ startWithLoremIpsum: Commencer par lorem ipsum ?
+ asHTML: En tant que html ?
+ loremIpsumText: Votre Lorem Ipsum...
+
+ copyBtn: Copier
+ copied: Lorem ipsum copié dans le presse-papiers
diff --git a/src/tools/lorem-ipsum-generator/locales/zh.yml b/src/tools/lorem-ipsum-generator/locales/zh.yml
new file mode 100644
index 000000000..3951709f8
--- /dev/null
+++ b/src/tools/lorem-ipsum-generator/locales/zh.yml
@@ -0,0 +1,14 @@
+tools:
+ lorem-ipsum-generator:
+ title: Lorem Ipsum 生成器
+ description: Lorem Ipsum 是一种常用的占位文本,用于展示文档或字体的视觉形式,而不依赖于有意义的内容。
+
+ paragraphs: 段落
+ sentences: 每段句子数
+ words: 每句字数
+ startWithLoremIpsum: 以 Lorem Ipsum 开头?
+ asHTML: 作为 HTML?
+ loremIpsumText: 您的 Lorem Ipsum...
+
+ copyBtn: 复制
+ copied: Lorem Ipsum 已复制到剪贴板
diff --git a/src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue b/src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue
index 9085725f9..de9096bbf 100644
--- a/src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue
+++ b/src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue
@@ -3,6 +3,7 @@ import { generateLoremIpsum } from './lorem-ipsum-generator.service';
import { useCopy } from '@/composable/copy';
import { randIntFromInterval } from '@/utils/random';
+const { t } = useI18n();
const paragraphs = ref(1);
const sentences = ref([3, 8]);
const words = ref([8, 15]);
@@ -18,32 +19,32 @@ const loremIpsumText = computed(() =>
startWithLoremIpsum: startWithLoremIpsum.value,
}),
);
-const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to the clipboard' });
+const { copy } = useCopy({ source: loremIpsumText, text: t('tools.lorem-ipsum-generator.copied') });
-
+
-
+
-
+
-
+
-
+
-
+
- Unknown vendor for this address
+ {{ t('tools.mac-address-lookup.unknownAddress') }}
- Copy vendor info
+ {{ t('tools.mac-address-lookup.copyBtn') }}
diff --git a/src/tools/math-evaluator/index.ts b/src/tools/math-evaluator/index.ts
index eb4290ba4..588b5aaf2 100644
--- a/src/tools/math-evaluator/index.ts
+++ b/src/tools/math-evaluator/index.ts
@@ -1,11 +1,11 @@
import { Math } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.math-evaluator.title'),
+ name: t('tools.math-evaluator.title'),
path: '/math-evaluator',
- description: translate('tools.math-evaluator.description'),
+ description: t('tools.math-evaluator.description'),
keywords: [
'math',
'evaluator',
diff --git a/src/tools/math-evaluator/locales/en.yml b/src/tools/math-evaluator/locales/en.yml
new file mode 100644
index 000000000..313c387b4
--- /dev/null
+++ b/src/tools/math-evaluator/locales/en.yml
@@ -0,0 +1,7 @@
+tools:
+ math-evaluator:
+ title: Math evaluator
+ description: A calculator for evaluating mathematical expressions. You can use functions like sqrt, cos, sin, abs, etc.
+
+ inputPlaceholder: 'Your math expression (ex: 2*sqrt(6) )...'
+ result: Result
diff --git a/src/tools/math-evaluator/locales/fr.yml b/src/tools/math-evaluator/locales/fr.yml
new file mode 100644
index 000000000..31f8e04f2
--- /dev/null
+++ b/src/tools/math-evaluator/locales/fr.yml
@@ -0,0 +1,7 @@
+tools:
+ math-evaluator:
+ title: Évaluateur mathématique
+ description: Une calculatrice pour évaluer des expressions mathématiques. Vous pouvez utiliser des fonctions telles que sqrt, cos, sin, abs, etc.
+
+ inputPlaceholder: 'Votre expression mathématique (ex : 2*sqrt(6) )...'
+ result: Résultat
diff --git a/src/tools/math-evaluator/locales/zh.yml b/src/tools/math-evaluator/locales/zh.yml
new file mode 100644
index 000000000..77c32d1f2
--- /dev/null
+++ b/src/tools/math-evaluator/locales/zh.yml
@@ -0,0 +1,7 @@
+tools:
+ math-evaluator:
+ title: 数学表达式求值器
+ description: 用于计算数学表达式的计算器。您可以使用函数如sqrt,cos,sin,abs等。
+
+ inputPlaceholder: '您的数学表达式(例如:2*sqrt(6))...'
+ result: 结果
diff --git a/src/tools/math-evaluator/math-evaluator.vue b/src/tools/math-evaluator/math-evaluator.vue
index d31ed252d..86f4f6f2f 100644
--- a/src/tools/math-evaluator/math-evaluator.vue
+++ b/src/tools/math-evaluator/math-evaluator.vue
@@ -3,6 +3,7 @@ import { evaluate } from 'mathjs';
import { withDefaultOnError } from '@/utils/defaults';
+const { t } = useI18n();
const expression = ref('');
const result = computed(() => withDefaultOnError(() => evaluate(expression.value) ?? '', ''));
@@ -14,14 +15,14 @@ const result = computed(() => withDefaultOnError(() => evaluate(expression.value
v-model:value="expression"
rows="1"
multiline
- placeholder="Your math expression (ex: 2*sqrt(6) )..."
+ :placeholder="t('tools.math-evaluator.inputPlaceholder')"
raw-text
monospace
autofocus
autosize
/>
-
+
{{ result }}
diff --git a/src/tools/meta-tag-generator/index.ts b/src/tools/meta-tag-generator/index.ts
index c62244109..42f4e2907 100644
--- a/src/tools/meta-tag-generator/index.ts
+++ b/src/tools/meta-tag-generator/index.ts
@@ -1,11 +1,11 @@
import { Tags } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.og-meta-generator.title'),
+ name: t('tools.og-meta-generator.title'),
path: '/og-meta-generator',
- description: translate('tools.og-meta-generator.description'),
+ description: t('tools.og-meta-generator.description'),
keywords: [
'meta',
'tag',
diff --git a/src/tools/meta-tag-generator/locales/en.yml b/src/tools/meta-tag-generator/locales/en.yml
new file mode 100644
index 000000000..59b5fb095
--- /dev/null
+++ b/src/tools/meta-tag-generator/locales/en.yml
@@ -0,0 +1,199 @@
+tools:
+ og-meta-generator:
+ title: Open graph meta generator
+ description: Generate open-graph and socials html meta tags for your website.
+
+ yourMetaTags: Your meta tags
+
+ article:
+ title: Article
+ publishingDate:
+ label: Publishing date
+ placeholder: When the article was first published...
+ modificationDate:
+ label: Modification date
+ placeholder: When the article was last changed...
+ expirationDate:
+ label: Expiration date
+ placeholder: When the article is out of date after...
+ author:
+ label: Author
+ placeholder: Writers of the article...
+ section:
+ label: Section
+ placeholder: A high-level section name. E.g. Technology..
+ tag:
+ label: Tag
+ placeholder: Tag words associated with this article...
+ book:
+ title: Book
+ author:
+ label: Author
+ placeholder: Who wrote this book...
+ ISBN:
+ label: ISBN
+ placeholder: The International Standard Book Number...
+ releaseDate:
+ label: Release date
+ placeholder: The date the book was released...
+ tag:
+ label: Tag
+ placeholder: Tag words associated with this book...
+ image:
+ title: Image
+ imageUrl:
+ label: Image url
+ placeholder: The url of your website social image...
+ imageAlt:
+ label: Image alt
+ placeholder: The alternative text of your website social image...
+ width:
+ label: Width
+ placeholder: Width in px of your website social image...
+ height:
+ label: Height
+ placeholder: Height in px of your website social image...
+ albumDetails:
+ title: Album details
+ song:
+ label: Song
+ placeholder: The song on this album...
+ disc:
+ label: Disc
+ placeholder: The same as music:album:disc but in reverse...
+ track:
+ label: Track
+ placeholder: The same as music:album:track but in reverse...
+ musician:
+ label: Musician
+ placeholder: The musician that made this song...
+ releaseDate:
+ label: Release date
+ placeholder: The date the album was released...
+ playlistDetails:
+ title: Playlist details
+ song:
+ label: Song
+ placeholder: The song on this album...
+ disc:
+ label: Disc
+ placeholder: The same as music:album:disc but in reverse...
+ track:
+ label: Track
+ placeholder: The same as music:album:track but in reverse...
+ creator:
+ label: Creator
+ placeholder: The creator of this playlist...
+ radioStationDetails:
+ title: Radio station details
+ creator:
+ label: Creator
+ placeholder: The creator of this radio station...
+ songDetails:
+ title: Song details
+ duration:
+ lebel: Duration
+ placeholder: The duration of the song...
+ album:
+ lebel: Album
+ placeholder: The album this song is from...
+ disc:
+ lebel: Disc
+ placeholder: Which disc of the album this song is on...
+ track:
+ lebel: Track
+ placeholder: Which track this song is...
+ musician:
+ lebel: Musician
+ placeholder: The musician that made this song...
+ profile:
+ title: Profile
+ firstName:
+ lebel: First name
+ placeholder: Enter the first name of the person...
+ lastName:
+ lebel: Last name
+ placeholder: Enter the last name of the person...
+ username:
+ lebel: Username
+ placeholder: Enter the username of the person...
+ gender:
+ lebel: Gender
+ placeholder: Enter the gender of the person...
+ twitter:
+ title: Twitter
+ card:
+ label: Card type
+ placeholder: The Twitter card type...
+ summary: Summary
+ summaryWithLargeImage: Summary with large image
+ application: Application
+ player: Player
+ site:
+ label: Site account
+ placeholder: 'The name of the Twitter account of the site (ex: {example})...'
+ creator:
+ label: Creator acc.
+ placeholder: 'The name of the Twitter account of the creator (ex: {example})...'
+ videoEpisode:
+ title: Video episode details
+ series:
+ label: Series
+ placeholder: Which series this episode belongs to...
+ videoMovie:
+ title: Movie details
+ actor:
+ label: Actor
+ placeholder: Name of the actress/actor...
+ actorRole:
+ label: Actor role
+ placeholder: The role they played...
+ director:
+ label: Director
+ placeholder: Name of the director...
+ writer:
+ label: Writer
+ placeholder: Writers of the movie...
+ duration:
+ label: Duration
+ placeholder: The movie's length in seconds...
+ releaseDate:
+ label: Release date
+ placeholder: The date the movie was released...
+ tag:
+ label: Tag
+ placeholder: Tag words associated with this movie...
+ videoOther:
+ title: Other video details
+ videoTVShow:
+ title: TV show details
+ website:
+ title: General information
+ pageType:
+ label: Page type
+ placeholder: Select the type of your website...
+ pageTitle:
+ label: Title
+ placeholder: Enter the title of your website...
+ description:
+ label: Description
+ placeholder: Enter the description of your website...
+ url:
+ label: Page URL
+ placeholder: Enter the url of your website...
+ web: Website
+ article: Article
+ book: Book
+ profile: Profile
+ music:
+ label: Music
+ song: Song
+ musicAlbum: Music album
+ playlist: Playlist
+ radioStation: Radio station
+ video:
+ label: Music
+ movie: Movie
+ episode: Episode
+ tvShow: TV show
+ otherVideo: Other video
diff --git a/src/tools/meta-tag-generator/locales/fr.yml b/src/tools/meta-tag-generator/locales/fr.yml
new file mode 100644
index 000000000..e8fc9c0ba
--- /dev/null
+++ b/src/tools/meta-tag-generator/locales/fr.yml
@@ -0,0 +1,199 @@
+tools:
+ og-meta-generator:
+ title: Générateur de métadonnées Open Graph
+ description: Génère des balises meta HTML Open Graph et sociales pour votre site web.
+
+ yourMetaTags: Vos balises meta
+
+ article:
+ title: Article
+ publishingDate:
+ label: Date de publication
+ placeholder: Quand l'article a été publié pour la première fois...
+ modificationDate:
+ label: Date de modification
+ placeholder: Quand l'article a été modifié pour la dernière fois...
+ expirationDate:
+ label: Date d'expiration
+ placeholder: Quand l'article est obsolète...
+ author:
+ label: Auteur
+ placeholder: Auteurs de l'article...
+ section:
+ label: Section
+ placeholder: Nom de section de haut niveau. Par ex. Technologie...
+ tag:
+ label: Tag
+ placeholder: Mots-clés associés à cet article...
+ book:
+ title: Livre
+ author:
+ label: Auteur
+ placeholder: Qui a écrit ce livre...
+ ISBN:
+ label: ISBN
+ placeholder: Le numéro ISBN (International Standard Book Number)...
+ releaseDate:
+ label: Date de sortie
+ placeholder: Date de sortie du livre...
+ tag:
+ label: Tag
+ placeholder: Mots-clés associés à ce livre...
+ image:
+ title: Image
+ imageUrl:
+ label: URL de l'image
+ placeholder: L'URL de l'image sociale de votre site web...
+ imageAlt:
+ label: Texte alternatif de l'image
+ placeholder: Le texte alternatif de l'image sociale de votre site web...
+ width:
+ label: Largeur
+ placeholder: Largeur en pixels de l'image sociale de votre site web...
+ height:
+ label: Hauteur
+ placeholder: Hauteur en pixels de l'image sociale de votre site web...
+ albumDetails:
+ title: Détails de l'album
+ song:
+ label: Chanson
+ placeholder: La chanson de cet album...
+ disc:
+ label: Disque
+ placeholder: Identique à music:album:disc mais en sens inverse...
+ track:
+ label: Piste
+ placeholder: Identique à music:album:track mais en sens inverse...
+ musician:
+ label: Musicien
+ placeholder: Le musicien qui a créé cette chanson...
+ releaseDate:
+ label: Date de sortie
+ placeholder: Date de sortie de l'album...
+ playlistDetails:
+ title: Détails de la playlist
+ song:
+ label: Chanson
+ placeholder: La chanson de cette playlist...
+ disc:
+ label: Disque
+ placeholder: Identique à music:album:disc mais en sens inverse...
+ track:
+ label: Piste
+ placeholder: Identique à music:album:track mais en sens inverse...
+ creator:
+ label: Créateur
+ placeholder: Le créateur de cette playlist...
+ radioStationDetails:
+ title: Détails de la station de radio
+ creator:
+ label: Créateur
+ placeholder: Le créateur de cette station de radio...
+ songDetails:
+ title: Détails de la chanson
+ duration:
+ lebel: Durée
+ placeholder: La durée de la chanson...
+ album:
+ lebel: Album
+ placeholder: L'album dont est issue cette chanson...
+ disc:
+ lebel: Disque
+ placeholder: Sur quel disque de l'album se trouve cette chanson...
+ track:
+ lebel: Piste
+ placeholder: Quelle piste est cette chanson...
+ musician:
+ lebel: Musicien
+ placeholder: Le musicien qui a créé cette chanson...
+ profile:
+ title: Profil
+ firstName:
+ lebel: Prénom
+ placeholder: Entrez le prénom de la personne...
+ lastName:
+ lebel: Nom de famille
+ placeholder: Entrez le nom de famille de la personne...
+ username:
+ lebel: Nom d'utilisateur
+ placeholder: Entrez le nom d'utilisateur de la personne...
+ gender:
+ lebel: Genre
+ placeholder: Entrez le genre de la personne...
+ twitter:
+ title: Twitter
+ card:
+ label: Type de carte
+ placeholder: Le type de carte Twitter...
+ summary: Résumé
+ summaryWithLargeImage: Résumé avec grande image
+ application: Application
+ player: Lecteur
+ site:
+ label: Compte du site
+ placeholder: 'Le nom du compte Twitter du site (ex : {example})...'
+ creator:
+ label: Compte du créateur
+ placeholder: 'Le nom du compte Twitter du créateur (ex : {example})...'
+ videoEpisode:
+ title: Détails de l'épisode vidéo
+ series:
+ label: Série
+ placeholder: À quelle série cet épisode appartient...
+ videoMovie:
+ title: Détails du film
+ actor:
+ label: Acteur
+ placeholder: Nom de l'actrice / acteur...
+ actorRole:
+ label: Rôle de l'acteur
+ placeholder: Le rôle qu'ils ont joué...
+ director:
+ label: Réalisateur
+ placeholder: Nom du réalisateur...
+ writer:
+ label: Scénariste
+ placeholder: Scénaristes du film...
+ duration:
+ label: Durée
+ placeholder: La durée du film en secondes...
+ releaseDate:
+ label: Date de sortie
+ placeholder: Date de sortie du film...
+ tag:
+ label: Tag
+ placeholder: Mots-clés associés à ce film...
+ videoOther:
+ title: Autres détails vidéo
+ videoTVShow:
+ title: Détails de l'émission de télévision
+ website:
+ title: Informations générales
+ pageType:
+ label: Type de page
+ placeholder: Sélectionnez le type de votre site web...
+ pageTitle:
+ label: Titre
+ placeholder: Entrez le titre de votre site web...
+ description:
+ label: Description
+ placeholder: Entrez la description de votre site web...
+ url:
+ label: URL de la page
+ placeholder: Entrez l'URL de votre site web...
+ web: Site web
+ article: Article
+ book: Livre
+ profile: Profil
+ music:
+ label: Musique
+ song: Chanson
+ musicAlbum: Album musical
+ playlist: Playlist
+ radioStation: Station de radio
+ video:
+ label: Vidéo
+ movie: Film
+ episode: Épisode
+ tvShow: Émission de télévision
+ otherVideo: Autre vidéo
diff --git a/src/tools/meta-tag-generator/locales/zh.yml b/src/tools/meta-tag-generator/locales/zh.yml
new file mode 100644
index 000000000..bdd17a27e
--- /dev/null
+++ b/src/tools/meta-tag-generator/locales/zh.yml
@@ -0,0 +1,199 @@
+tools:
+ og-meta-generator:
+ title: 开放图谱元数据生成器
+ description: 为您的网站生成开放图谱和社交网站的 HTML 元标记。
+
+ yourMetaTags: 您的元标记
+
+ article:
+ title: 文章
+ publishingDate:
+ label: 发布日期
+ placeholder: 文章首次发布的日期...
+ modificationDate:
+ label: 修改日期
+ placeholder: 文章最后修改的日期...
+ expirationDate:
+ label: 过期日期
+ placeholder: 文章失效日期...
+ author:
+ label: 作者
+ placeholder: 文章的作者...
+ section:
+ label: 部分
+ placeholder: 高级部分名称。例如:技术...
+ tag:
+ label: 标签
+ placeholder: 与该文章相关的标签词...
+ book:
+ title: 书籍
+ author:
+ label: 作者
+ placeholder: 谁写了这本书...
+ ISBN:
+ label: ISBN
+ placeholder: 国际标准书号...
+ releaseDate:
+ label: 发行日期
+ placeholder: 书籍发布日期...
+ tag:
+ label: 标签
+ placeholder: 与该书籍相关的标签词...
+ image:
+ title: 图片
+ imageUrl:
+ label: 图片 URL
+ placeholder: 您网站社交图片的 URL...
+ imageAlt:
+ label: 图片说明
+ placeholder: 您网站社交图片的替代文本...
+ width:
+ label: 宽度
+ placeholder: 您网站社交图片的宽度(像素)...
+ height:
+ label: 高度
+ placeholder: 您网站社交图片的高度(像素)...
+ albumDetails:
+ title: 专辑详情
+ song:
+ label: 歌曲
+ placeholder: 该专辑中的歌曲...
+ disc:
+ label: 光盘
+ placeholder: 与音乐:专辑:光盘相同,但顺序相反...
+ track:
+ label: 曲目
+ placeholder: 与音乐:专辑:曲目相同,但顺序相反...
+ musician:
+ label: 音乐家
+ placeholder: 制作该歌曲的音乐家...
+ releaseDate:
+ label: 发行日期
+ placeholder: 专辑发布日期...
+ playlistDetails:
+ title: 播放列表详情
+ song:
+ label: 歌曲
+ placeholder: 该专辑中的歌曲...
+ disc:
+ label: 光盘
+ placeholder: 与音乐:专辑:光盘相同,但顺序相反...
+ track:
+ label: 曲目
+ placeholder: 与音乐:专辑:曲目相同,但顺序相反...
+ creator:
+ label: 创建者
+ placeholder: 此播放列表的创建者...
+ radioStationDetails:
+ title: 电台详情
+ creator:
+ label: 创建者
+ placeholder: 电台的创建者...
+ songDetails:
+ title: 歌曲详情
+ duration:
+ lebel: 时长
+ placeholder: 歌曲的时长...
+ album:
+ lebel: 专辑
+ placeholder: 歌曲所属的专辑...
+ disc:
+ lebel: 光盘
+ placeholder: 歌曲所在专辑的光盘...
+ track:
+ lebel: 曲目
+ placeholder: 歌曲的曲目...
+ musician:
+ lebel: 音乐家
+ placeholder: 制作该歌曲的音乐家...
+ profile:
+ title: 个人资料
+ firstName:
+ lebel: 名字
+ placeholder: 输入个人的名字...
+ lastName:
+ lebel: 姓氏
+ placeholder: 输入个人的姓氏...
+ username:
+ lebel: 用户名
+ placeholder: 输入个人的用户名...
+ gender:
+ lebel: 性别
+ placeholder: 输入个人的性别...
+ twitter:
+ title: 推特
+ card:
+ label: 卡片类型
+ placeholder: 推特卡片类型...
+ summary: 摘要
+ summaryWithLargeImage: 带大图的摘要
+ application: 应用
+ player: 播放器
+ site:
+ label: 网站账号
+ placeholder: '网站的推特账号(例如:{example})...'
+ creator:
+ label: 创建者账号
+ placeholder: '创建者的推特账号(例如:{example})...'
+ videoEpisode:
+ title: 视频剧集详情
+ series:
+ label: 系列
+ placeholder: 该剧集所属的系列...
+ videoMovie:
+ title: 电影详情
+ actor:
+ label: 演员
+ placeholder: 女演员/男演员的名字...
+ actorRole:
+ label: 演员角色
+ placeholder: 他们扮演的角色...
+ director:
+ label: 导演
+ placeholder: 导演的名字...
+ writer:
+ label: 编剧
+ placeholder: 电影的编剧...
+ duration:
+ label: 时长
+ placeholder: 电影的长度(秒)...
+ releaseDate:
+ label: 发行日期
+ placeholder: 电影的发布日期...
+ tag:
+ label: 标签
+ placeholder: 与该电影相关的标签词...
+ videoOther:
+ title: 其他视频详情
+ videoTVShow:
+ title: 电视剧详情
+ website:
+ title: 常规信息
+ pageType:
+ label: 页面类型
+ placeholder: 选择您网站的类型...
+ pageTitle:
+ label: 标题
+ placeholder: 输入您网站的标题...
+ description:
+ label: 描述
+ placeholder: 输入您网站的描述...
+ url:
+ label: 页面 URL
+ placeholder: 输入您网站的 URL...
+ web: 网站
+ article: 文章
+ book: 书籍
+ profile: 个人资料
+ music:
+ label: 音乐
+ song: 歌曲
+ musicAlbum: 音乐专辑
+ playlist: 播放列表
+ radioStation: 电台
+ video:
+ label: 视频
+ movie: 电影
+ episode: 剧集
+ tvShow: 电视剧
+ otherVideo: 其他视频
diff --git a/src/tools/meta-tag-generator/meta-tag-generator.vue b/src/tools/meta-tag-generator/meta-tag-generator.vue
index aafa7799e..0b0cd0f7b 100644
--- a/src/tools/meta-tag-generator/meta-tag-generator.vue
+++ b/src/tools/meta-tag-generator/meta-tag-generator.vue
@@ -6,7 +6,7 @@ import type { OGSchemaType, OGSchemaTypeElementSelect } from './OGSchemaType.typ
import TextareaCopyable from '@/components/TextareaCopyable.vue';
// Since type guards do not work in template
-
+const { t } = useI18n();
const metadata = ref<{ type: string; [k: string]: any }>({
'type': 'website',
'twitter:card': 'summary_large_image',
@@ -83,7 +83,7 @@ const metaTags = computed(() => {
-
+
diff --git a/src/tools/meta-tag-generator/og-schemas/article.ts b/src/tools/meta-tag-generator/og-schemas/article.ts
index 3d2ce9259..b22f81051 100644
--- a/src/tools/meta-tag-generator/og-schemas/article.ts
+++ b/src/tools/meta-tag-generator/og-schemas/article.ts
@@ -1,33 +1,44 @@
import type { OGSchemaType } from '../OGSchemaType.type';
+import { translate as t } from '@/plugins/i18n.plugin';
export const article: OGSchemaType = {
- name: 'Article',
+ name: t('tools.og-meta-generator.article.title'),
elements: [
{
type: 'input',
- label: 'Publishing date',
+ label: t('tools.og-meta-generator.article.publishingDate.label'),
key: 'article:published_time',
- placeholder: 'When the article was first published...',
+ placeholder: t('tools.og-meta-generator.article.publishingDate.placeholder'),
},
{
type: 'input',
- label: 'Modification date',
+ label: t('tools.og-meta-generator.article.modificationDate.label'),
key: 'article:modified_time',
- placeholder: 'When the article was last changed...',
+ placeholder: t('tools.og-meta-generator.article.modificationDate.placeholder'),
},
{
type: 'input',
- label: 'Expiration date',
+ label: t('tools.og-meta-generator.article.expirationDate.label'),
key: 'article:expiration_time',
- placeholder: 'When the article is out of date after...',
+ placeholder: t('tools.og-meta-generator.article.expirationDate.placeholder'),
},
- { type: 'input', label: 'Author', key: 'article:author', placeholder: 'Writers of the article...' },
{
type: 'input',
- label: 'Section',
+ label: t('tools.og-meta-generator.article.author.label'),
+ key: 'article:author',
+ placeholder: t('tools.og-meta-generator.article.author.placeholder'),
+ },
+ {
+ type: 'input',
+ label: t('tools.og-meta-generator.article.section.label'),
key: 'article:section',
- placeholder: 'A high-level section name. E.g. Technology..',
+ placeholder: t('tools.og-meta-generator.article.section.placeholder'),
+ },
+ {
+ type: 'input',
+ label: t('tools.og-meta-generator.article.tag.label'),
+ key: 'article:tag',
+ placeholder: t('tools.og-meta-generator.article.tag.placeholder'),
},
- { type: 'input', label: 'Tag', key: 'article:tag', placeholder: 'Tag words associated with this article...' },
],
};
diff --git a/src/tools/meta-tag-generator/og-schemas/book.ts b/src/tools/meta-tag-generator/og-schemas/book.ts
index f01733fa9..bbb52e507 100644
--- a/src/tools/meta-tag-generator/og-schemas/book.ts
+++ b/src/tools/meta-tag-generator/og-schemas/book.ts
@@ -1,16 +1,17 @@
import type { OGSchemaType } from '../OGSchemaType.type';
+import { translate as t } from '@/plugins/i18n.plugin';
export const book: OGSchemaType = {
- name: 'Book',
+ name: t('tools.og-meta-generator.book.title'),
elements: [
- { type: 'input', label: 'Author', key: 'book:author', placeholder: 'Who wrote this book...' },
- { type: 'input', label: 'ISBN', key: 'book:isbn', placeholder: 'The International Standard Book Number...' },
+ { type: 'input', label: t('tools.og-meta-generator.book.author.label'), key: 'book:author', placeholder: t('tools.og-meta-generator.book.author.placeholder') },
+ { type: 'input', label: t('tools.og-meta-generator.book.ISBN.label'), key: 'book:isbn', placeholder: t('tools.og-meta-generator.book.ISBN.placeholder') },
{
type: 'input',
- label: 'Release date',
+ label: t('tools.og-meta-generator.book.releaseDate.label'),
key: 'book:release_date',
- placeholder: 'The date the book was released...',
+ placeholder: t('tools.og-meta-generator.book.releaseDate.placeholder'),
},
- { type: 'input', label: 'Tag', key: 'book:tag', placeholder: 'Tag words associated with this book...' },
+ { type: 'input', label: t('tools.og-meta-generator.book.tag.label'), key: 'book:tag', placeholder: t('tools.og-meta-generator.book.tag.placeholder') },
],
};
diff --git a/src/tools/meta-tag-generator/og-schemas/image.ts b/src/tools/meta-tag-generator/og-schemas/image.ts
index 60a4c5a99..5b997582c 100644
--- a/src/tools/meta-tag-generator/og-schemas/image.ts
+++ b/src/tools/meta-tag-generator/og-schemas/image.ts
@@ -1,30 +1,31 @@
import type { OGSchemaType } from '../OGSchemaType.type';
+import { translate as t } from '@/plugins/i18n.plugin';
export const image: OGSchemaType = {
- name: 'Image',
+ name: t('tools.og-meta-generator.image.title'),
elements: [
{
type: 'input',
- label: 'Image url',
- placeholder: 'The url of your website social image...',
+ label: t('tools.og-meta-generator.image.imageUrl.label'),
+ placeholder: t('tools.og-meta-generator.image.imageUrl.placeholder'),
key: 'image',
},
{
type: 'input',
- label: 'Image alt',
- placeholder: 'The alternative text of your website social image...',
+ label: t('tools.og-meta-generator.image.imageAlt.label'),
+ placeholder: t('tools.og-meta-generator.image.imageAlt.placeholder'),
key: 'image:alt',
},
{
type: 'input',
- label: 'Width',
- placeholder: 'Width in px of your website social image...',
+ label: t('tools.og-meta-generator.image.width.label'),
+ placeholder: t('tools.og-meta-generator.image.width.placeholder'),
key: 'image:width',
},
{
type: 'input',
- label: 'Height',
- placeholder: 'Height in px of your website social image...',
+ label: t('tools.og-meta-generator.image.height.label'),
+ placeholder: t('tools.og-meta-generator.image.height.placeholder'),
key: 'image:height',
},
],
diff --git a/src/tools/meta-tag-generator/og-schemas/musicAlbum.ts b/src/tools/meta-tag-generator/og-schemas/musicAlbum.ts
index 225423c21..5a6c2d0d9 100644
--- a/src/tools/meta-tag-generator/og-schemas/musicAlbum.ts
+++ b/src/tools/meta-tag-generator/og-schemas/musicAlbum.ts
@@ -1,27 +1,28 @@
import type { OGSchemaType } from '../OGSchemaType.type';
+import { translate as t } from '@/plugins/i18n.plugin';
export const musicAlbum: OGSchemaType = {
- name: 'Album details',
+ name: t('tools.og-meta-generator.albumDetails.title'),
elements: [
- { type: 'input', label: 'Song', key: 'music:song', placeholder: 'The song on this album...' },
+ { type: 'input', label: t('tools.og-meta-generator.albumDetails.song.label'), key: 'music:song', placeholder: t('tools.og-meta-generator.albumDetails.song.placeholder') },
{
type: 'input',
- label: 'Disc',
+ label: t('tools.og-meta-generator.albumDetails.disc.label'),
key: 'music:song:disc',
- placeholder: 'The same as music:album:disc but in reverse...',
+ placeholder: t('tools.og-meta-generator.albumDetails.disc.placeholder'),
},
{
type: 'input',
- label: 'Track',
+ label: t('tools.og-meta-generator.albumDetails.track.label'),
key: 'music:song:track',
- placeholder: 'The same as music:album:track but in reverse...',
+ placeholder: t('tools.og-meta-generator.albumDetails.track.placeholder'),
},
- { type: 'input', label: 'Musician', key: 'music:musician', placeholder: 'The musician that made this song...' },
+ { type: 'input', label: t('tools.og-meta-generator.albumDetails.musician.label'), key: 'music:musician', placeholder: t('tools.og-meta-generator.albumDetails.musician.placeholder') },
{
type: 'input',
- label: 'Release date',
+ label: t('tools.og-meta-generator.albumDetails.releaseDate.label'),
key: 'music:release_date',
- placeholder: 'The date the album was released...',
+ placeholder: t('tools.og-meta-generator.albumDetails.releaseDate.placeholder'),
},
],
};
diff --git a/src/tools/meta-tag-generator/og-schemas/musicPlaylist.ts b/src/tools/meta-tag-generator/og-schemas/musicPlaylist.ts
index 610dd8e13..160ea786b 100644
--- a/src/tools/meta-tag-generator/og-schemas/musicPlaylist.ts
+++ b/src/tools/meta-tag-generator/og-schemas/musicPlaylist.ts
@@ -1,21 +1,22 @@
import type { OGSchemaType } from '../OGSchemaType.type';
+import { translate as t } from '@/plugins/i18n.plugin';
export const musicPlaylist: OGSchemaType = {
- name: 'Playlist details',
+ name: t('tools.og-meta-generator.playlistDetails.title'),
elements: [
- { type: 'input', label: 'Song', key: 'music:song', placeholder: 'The song on this album...' },
+ { type: 'input', label: t('tools.og-meta-generator.playlistDetails.song.label'), key: 'music:song', placeholder: t('tools.og-meta-generator.playlistDetails.song.placeholder') },
{
type: 'input',
- label: 'Disc',
+ label: t('tools.og-meta-generator.playlistDetails.disc.label'),
key: 'music:song:disc',
- placeholder: 'The same as music:album:disc but in reverse...',
+ placeholder: t('tools.og-meta-generator.playlistDetails.disc.placeholder'),
},
{
type: 'input',
- label: 'Track',
+ label: t('tools.og-meta-generator.playlistDetails.track.label'),
key: 'music:song:track',
- placeholder: 'The same as music:album:track but in reverse...',
+ placeholder: t('tools.og-meta-generator.playlistDetails.track.placeholder'),
},
- { type: 'input', label: 'Creator', key: 'music:creator', placeholder: 'The creator of this playlist...' },
+ { type: 'input', label: t('tools.og-meta-generator.playlistDetails.creator.label'), key: 'music:creator', placeholder: t('tools.og-meta-generator.playlistDetails.creator.placeholder') },
],
};
diff --git a/src/tools/meta-tag-generator/og-schemas/musicRadioStation.ts b/src/tools/meta-tag-generator/og-schemas/musicRadioStation.ts
index d4c1126bd..510049864 100644
--- a/src/tools/meta-tag-generator/og-schemas/musicRadioStation.ts
+++ b/src/tools/meta-tag-generator/og-schemas/musicRadioStation.ts
@@ -1,8 +1,9 @@
import type { OGSchemaType } from '../OGSchemaType.type';
+import { translate as t } from '@/plugins/i18n.plugin';
export const musicRadioStation: OGSchemaType = {
- name: 'Radio station details',
+ name: t('tools.og-meta-generator.radioStationDetails.title'),
elements: [
- { type: 'input', label: 'Creator', key: 'music:creator', placeholder: 'The creator of this radio station...' },
+ { type: 'input', label: t('tools.og-meta-generator.radioStationDetails.creator.label'), key: 'music:creator', placeholder: t('tools.og-meta-generator.radioStationDetails.creator.placeholder') },
],
};
diff --git a/src/tools/meta-tag-generator/og-schemas/musicSong.ts b/src/tools/meta-tag-generator/og-schemas/musicSong.ts
index 018ce1789..f3dae2368 100644
--- a/src/tools/meta-tag-generator/og-schemas/musicSong.ts
+++ b/src/tools/meta-tag-generator/og-schemas/musicSong.ts
@@ -1,21 +1,22 @@
import type { OGSchemaType } from '../OGSchemaType.type';
+import { translate as t } from '@/plugins/i18n.plugin';
export const musicSong: OGSchemaType = {
- name: 'Song details',
+ name: t('tools.og-meta-generator.songDetails.title'),
elements: [
- { type: 'input', label: 'Duration', placeholder: 'The duration of the song...', key: 'music:duration' },
- { type: 'input', label: 'Album', placeholder: 'The album this song is from...', key: 'music:album' },
+ { type: 'input', label: t('tools.og-meta-generator.songDetails.duration.lebel'), placeholder: t('tools.og-meta-generator.songDetails.duration.placeholder'), key: 'music:duration' },
+ { type: 'input', label: t('tools.og-meta-generator.songDetails.album.lebel'), placeholder: t('tools.og-meta-generator.songDetails.album.placeholder'), key: 'music:album' },
{
type: 'input',
- label: 'Disc',
- placeholder: 'Which disc of the album this song is on...',
+ label: t('tools.og-meta-generator.songDetails.disc.lebel'),
+ placeholder: t('tools.og-meta-generator.songDetails.disc.placeholder'),
key: 'music:album:disk',
},
- { type: 'input', label: 'Track', placeholder: ' Which track this song is...', key: 'music:album:track' },
+ { type: 'input', label: t('tools.og-meta-generator.songDetails.track.lebel'), placeholder: t('tools.og-meta-generator.songDetails.track.placeholder'), key: 'music:album:track' },
{
type: 'input-multiple',
- label: 'Musician',
- placeholder: 'The musician that made this song...',
+ label: t('tools.og-meta-generator.songDetails.musician.lebel'),
+ placeholder: t('tools.og-meta-generator.songDetails.musician.placeholder'),
key: 'music:musician',
},
],
diff --git a/src/tools/meta-tag-generator/og-schemas/profile.ts b/src/tools/meta-tag-generator/og-schemas/profile.ts
index b0bc189e9..3e5d04ff4 100644
--- a/src/tools/meta-tag-generator/og-schemas/profile.ts
+++ b/src/tools/meta-tag-generator/og-schemas/profile.ts
@@ -1,21 +1,22 @@
import type { OGSchemaType } from '../OGSchemaType.type';
+import { translate as t } from '@/plugins/i18n.plugin';
export const profile: OGSchemaType = {
- name: 'Profile',
+ name: t('tools.og-meta-generator.profile.title'),
elements: [
{
type: 'input',
- label: 'First name',
- placeholder: 'Enter the first name of the person...',
+ label: t('tools.og-meta-generator.profile.firstName.lebel'),
+ placeholder: t('tools.og-meta-generator.profile.firstName.placeholder'),
key: 'profile:first_name',
},
{
type: 'input',
- label: 'Last name',
- placeholder: 'Enter the last name of the person...',
+ label: t('tools.og-meta-generator.profile.lastName.lebel'),
+ placeholder: t('tools.og-meta-generator.profile.lastName.placeholder'),
key: 'profile:last_name',
},
- { type: 'input', label: 'Username', placeholder: 'Enter the username of the person...', key: 'profile:username' },
- { type: 'input', label: 'Gender', placeholder: 'Enter the gender of the person...', key: 'profile:gender' },
+ { type: 'input', label: t('tools.og-meta-generator.profile.username.lebel'), placeholder: t('tools.og-meta-generator.profile.username.placeholder'), key: 'profile:username' },
+ { type: 'input', label: t('tools.og-meta-generator.profile.gender.lebel'), placeholder: t('tools.og-meta-generator.profile.gender.placeholder'), key: 'profile:gender' },
],
};
diff --git a/src/tools/meta-tag-generator/og-schemas/twitter.ts b/src/tools/meta-tag-generator/og-schemas/twitter.ts
index e29f5ebf4..1bef65081 100644
--- a/src/tools/meta-tag-generator/og-schemas/twitter.ts
+++ b/src/tools/meta-tag-generator/og-schemas/twitter.ts
@@ -1,30 +1,31 @@
import type { OGSchemaType } from '../OGSchemaType.type';
+import { translate as t } from '@/plugins/i18n.plugin';
export const twitter: OGSchemaType = {
- name: 'Twitter',
+ name: t('tools.og-meta-generator.twitter.title'),
elements: [
{
type: 'select',
options: [
- { label: 'Summary', value: 'summary' },
- { label: 'Summary with large image', value: 'summary_large_image' },
- { label: 'Application', value: 'app' },
- { label: 'Player', value: 'player' },
+ { label: t('tools.og-meta-generator.twitter.card.summary'), value: 'summary' },
+ { label: t('tools.og-meta-generator.twitter.card.summaryWithLargeImage'), value: 'summary_large_image' },
+ { label: t('tools.og-meta-generator.twitter.card.application'), value: 'app' },
+ { label: t('tools.og-meta-generator.twitter.card.player'), value: 'player' },
],
- label: 'Card type',
- placeholder: 'The Twitter card type...',
+ label: t('tools.og-meta-generator.twitter.card.label'),
+ placeholder: t('tools.og-meta-generator.twitter.card.placeholder'),
key: 'twitter:card',
},
{
type: 'input',
- label: 'Site account',
- placeholder: 'The name of the Twitter account of the site (ex: @ittoolsdottech)...',
+ label: t('tools.og-meta-generator.twitter.site.label'),
+ placeholder: t('tools.og-meta-generator.twitter.site.placeholder', { example: '@ittoolsdottech' }),
key: 'twitter:site',
},
{
type: 'input',
- label: 'Creator acc.',
- placeholder: 'The name of the Twitter account of the creator (ex: @cthmsst)...',
+ label: t('tools.og-meta-generator.twitter.creator.label'),
+ placeholder: t('tools.og-meta-generator.twitter.creator.placeholder', { example: '@cthmsst' }),
key: 'twitter:creator',
},
],
diff --git a/src/tools/meta-tag-generator/og-schemas/videoEpisode.ts b/src/tools/meta-tag-generator/og-schemas/videoEpisode.ts
index b8a036e30..724c9ec05 100644
--- a/src/tools/meta-tag-generator/og-schemas/videoEpisode.ts
+++ b/src/tools/meta-tag-generator/og-schemas/videoEpisode.ts
@@ -1,10 +1,11 @@
import type { OGSchemaType } from '../OGSchemaType.type';
import { videoMovie } from './videoMovie';
+import { translate as t } from '@/plugins/i18n.plugin';
export const videoEpisode: OGSchemaType = {
- name: 'Video episode details',
+ name: t('tools.og-meta-generator.videoEpisode.title'),
elements: [
...videoMovie.elements,
- { type: 'input', label: 'Series', key: 'video:series', placeholder: 'Which series this episode belongs to...' },
+ { type: 'input', label: t('tools.og-meta-generator.videoEpisode.series.label'), key: 'video:series', placeholder: t('tools.og-meta-generator.videoEpisode.series.placeholder') },
],
};
diff --git a/src/tools/meta-tag-generator/og-schemas/videoMovie.ts b/src/tools/meta-tag-generator/og-schemas/videoMovie.ts
index 96baa1a0e..c0c055feb 100644
--- a/src/tools/meta-tag-generator/og-schemas/videoMovie.ts
+++ b/src/tools/meta-tag-generator/og-schemas/videoMovie.ts
@@ -1,29 +1,30 @@
import type { OGSchemaType } from '../OGSchemaType.type';
+import { translate as t } from '@/plugins/i18n.plugin';
export const videoMovie: OGSchemaType = {
- name: 'Movie details',
+ name: t('tools.og-meta-generator.videoMovie.title'),
elements: [
{
type: 'input-multiple',
- label: 'Actor',
+ label: t('tools.og-meta-generator.videoMovie.actor.label'),
key: 'video:actor',
- placeholder: 'Name of the actress/actor...',
+ placeholder: t('tools.og-meta-generator.videoMovie.actor.placeholder'),
},
- // { type: 'input', label: 'Actor role', key: 'video:actor:role', placeholder: 'The role they played...' },
+ // { type: 'input', label: t('tools.og-meta-generator.videoMovie.actorRole.label'), key: 'video:actor:role', placeholder: t('tools.og-meta-generator.videoMovie.actorRole.placeholder') },
{
type: 'input-multiple',
- label: 'Director',
+ label: t('tools.og-meta-generator.videoMovie.director.label'),
key: 'video:director',
- placeholder: 'Name of the director...',
+ placeholder: t('tools.og-meta-generator.videoMovie.director.placeholder'),
},
- { type: 'input-multiple', label: 'Writer', key: 'video:writer', placeholder: 'Writers of the movie...' },
- { type: 'input', label: 'Duration', key: 'video:duration', placeholder: 'The movie\'s length in seconds...' },
+ { type: 'input-multiple', label: t('tools.og-meta-generator.videoMovie.writer.label'), key: 'video:writer', placeholder: t('tools.og-meta-generator.videoMovie.writer.placeholder') },
+ { type: 'input', label: t('tools.og-meta-generator.videoMovie.duration.label'), key: 'video:duration', placeholder: t('tools.og-meta-generator.videoMovie.duration.placeholder') },
{
type: 'input',
- label: 'Release date',
+ label: t('tools.og-meta-generator.videoMovie.releaseDate.label'),
key: 'video:release_date',
- placeholder: 'The date the movie was released...',
+ placeholder: t('tools.og-meta-generator.videoMovie.releaseDate.placeholder'),
},
- { type: 'input', label: 'Tag', key: 'video:tag', placeholder: 'Tag words associated with this movie...' },
+ { type: 'input', label: t('tools.og-meta-generator.videoMovie.tag.label'), key: 'video:tag', placeholder: t('tools.og-meta-generator.videoMovie.tag.placeholder') },
],
};
diff --git a/src/tools/meta-tag-generator/og-schemas/videoOther.ts b/src/tools/meta-tag-generator/og-schemas/videoOther.ts
index 5bc9679ec..b842b1d67 100644
--- a/src/tools/meta-tag-generator/og-schemas/videoOther.ts
+++ b/src/tools/meta-tag-generator/og-schemas/videoOther.ts
@@ -1,7 +1,8 @@
import type { OGSchemaType } from '../OGSchemaType.type';
import { videoMovie } from './videoMovie';
+import { translate as t } from '@/plugins/i18n.plugin';
export const videoOther: OGSchemaType = {
- name: 'Other video details',
+ name: t('tools.og-meta-generator.videoOther.title'),
elements: [...videoMovie.elements],
};
diff --git a/src/tools/meta-tag-generator/og-schemas/videoTVShow.ts b/src/tools/meta-tag-generator/og-schemas/videoTVShow.ts
index 5180c03b8..8c6600191 100644
--- a/src/tools/meta-tag-generator/og-schemas/videoTVShow.ts
+++ b/src/tools/meta-tag-generator/og-schemas/videoTVShow.ts
@@ -1,7 +1,8 @@
import type { OGSchemaType } from '../OGSchemaType.type';
import { videoMovie } from './videoMovie';
+import { translate as t } from '@/plugins/i18n.plugin';
export const videoTVShow: OGSchemaType = {
- name: 'TV show details',
+ name: t('tools.og-meta-generator.videoTVShow.title'),
elements: [...videoMovie.elements],
};
diff --git a/src/tools/meta-tag-generator/og-schemas/website.ts b/src/tools/meta-tag-generator/og-schemas/website.ts
index 15053e3d9..09fa92a5e 100644
--- a/src/tools/meta-tag-generator/og-schemas/website.ts
+++ b/src/tools/meta-tag-generator/og-schemas/website.ts
@@ -1,55 +1,56 @@
import type { OGSchemaType } from '../OGSchemaType.type';
+import { translate as t } from '@/plugins/i18n.plugin';
const typeOptions = [
- { label: 'Website', value: 'website' },
- { label: 'Article', value: 'article' },
- { label: 'Book', value: 'book' },
- { label: 'Profile', value: 'profile' },
+ { label: t('tools.og-meta-generator.website.web'), value: 'website' },
+ { label: t('tools.og-meta-generator.website.article'), value: 'article' },
+ { label: t('tools.og-meta-generator.website.book'), value: 'book' },
+ { label: t('tools.og-meta-generator.website.profile'), value: 'profile' },
{
type: 'group',
- label: 'Music',
+ label: t('tools.og-meta-generator.website.music.label'),
key: 'Music',
children: [
- { label: 'Song', value: 'music.song' },
- { label: 'Music album', value: 'music.album' },
- { label: 'Playlist', value: 'music.playlist' },
- { label: 'Radio station', value: 'music.radio_station' },
+ { label: t('tools.og-meta-generator.website.music.song'), value: 'music.song' },
+ { label: t('tools.og-meta-generator.website.music.musicAlbum'), value: 'music.album' },
+ { label: t('tools.og-meta-generator.website.music.playlist'), value: 'music.playlist' },
+ { label: t('tools.og-meta-generator.website.music.radioStation'), value: 'music.radio_station' },
],
},
{
type: 'group',
- label: 'Video',
+ label: t('tools.og-meta-generator.website.video.label'),
key: 'Video',
children: [
- { label: 'Movie', value: 'video.movie' },
- { label: 'Episode', value: 'video.episode' },
- { label: 'TV show', value: 'video.tv_show' },
- { label: 'Other video', value: 'video.other' },
+ { label: t('tools.og-meta-generator.website.video.movie'), value: 'video.movie' },
+ { label: t('tools.og-meta-generator.website.video.episode'), value: 'video.episode' },
+ { label: t('tools.og-meta-generator.website.video.tvShow'), value: 'video.tv_show' },
+ { label: t('tools.og-meta-generator.website.video.otherVideo'), value: 'video.other' },
],
},
];
export const website: OGSchemaType = {
- name: 'General information',
+ name: t('tools.og-meta-generator.website.title'),
elements: [
{
type: 'select',
- label: 'Page type',
- placeholder: 'Select the type of your website...',
+ label: t('tools.og-meta-generator.website.pageType.label'),
+ placeholder: t('tools.og-meta-generator.website.pageType.placeholder'),
key: 'type',
options: typeOptions,
},
- { type: 'input', label: 'Title', placeholder: 'Enter the title of your website...', key: 'title' },
+ { type: 'input', label: t('tools.og-meta-generator.website.pageTitle.label'), placeholder: t('tools.og-meta-generator.website.pageTitle.placeholder'), key: 'title' },
{
type: 'input',
- label: 'Description',
- placeholder: 'Enter the description of your website...',
+ label: t('tools.og-meta-generator.website.description.label'),
+ placeholder: t('tools.og-meta-generator.website.description.placeholder'),
key: 'description',
},
{
type: 'input',
- label: 'Page URL',
- placeholder: 'Enter the url of your website...',
+ label: t('tools.og-meta-generator.website.url.label'),
+ placeholder: t('tools.og-meta-generator.website.url.placeholder'),
key: 'url',
},
],
diff --git a/src/tools/mime-types/index.ts b/src/tools/mime-types/index.ts
index da6ba0c4a..7d29399db 100644
--- a/src/tools/mime-types/index.ts
+++ b/src/tools/mime-types/index.ts
@@ -1,11 +1,11 @@
import { World } from '@vicons/tabler';
import { defineTool } from '../tool';
-import { translate } from '@/plugins/i18n.plugin';
+import { translate as t } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: translate('tools.mime-types.title'),
+ name: t('tools.mime-types.title'),
path: '/mime-types',
- description: translate('tools.mime-types.description'),
+ description: t('tools.mime-types.description'),
keywords: ['mime', 'types', 'extension', 'content', 'type'],
component: () => import('./mime-types.vue'),
icon: World,
diff --git a/src/tools/mime-types/locales/en.yml b/src/tools/mime-types/locales/en.yml
new file mode 100644
index 000000000..de4535224
--- /dev/null
+++ b/src/tools/mime-types/locales/en.yml
@@ -0,0 +1,23 @@
+tools:
+ mime-types:
+ title: Mime types
+ description: Convert mime types to extensions and vice-versa.
+
+ mimeType:
+ title: Mime type to extension
+ description: Know which file extensions are associated to a mime-type
+ placeholder: 'Select your mimetype here... (ex: application/pdf)'
+ extensionsFound:
+ before: 'Extensions of files with the '
+ after: ' mime-type:'
+ extension:
+ title: File extension to mime type
+ description: Know which mime type is associated to a file extension
+ placeholder: 'Select your mimetype here... (ex: application/pdf)'
+ selectedExtension:
+ before: 'Mime type associated to the extension '
+ after: ' file'
+ ext: 'extension:'
+ table:
+ mimeTypes: Mime types
+ extensions: Extensions
diff --git a/src/tools/mime-types/locales/fr.yml b/src/tools/mime-types/locales/fr.yml
new file mode 100644
index 000000000..ba014023d
--- /dev/null
+++ b/src/tools/mime-types/locales/fr.yml
@@ -0,0 +1,23 @@
+tools:
+ mime-types:
+ title: Types MIME
+ description: Convertir les types MIME en extensions et vice versa.
+
+ mimeType:
+ title: Type MIME vers extension
+ description: Découvrez quelles extensions de fichier sont associées à un type MIME
+ placeholder: 'Sélectionnez votre type MIME ici... (ex : application/pdf)'
+ extensionsFound:
+ before: 'Extensions des fichiers avec le '
+ after: ' type MIME :'
+ extension:
+ title: Extension de fichier vers type MIME
+ description: Découvrez quel type MIME est associé à une extension de fichier
+ placeholder: 'Sélectionnez votre type MIME ici... (ex : application/pdf)'
+ selectedExtension:
+ before: "Type MIME associé à l'extension"
+ after: ' fichier'
+ ext: 'extension :'
+ table:
+ mimeTypes: Types MIME
+ extensions: Extensions
diff --git a/src/tools/mime-types/locales/zh.yml b/src/tools/mime-types/locales/zh.yml
new file mode 100644
index 000000000..88f02c615
--- /dev/null
+++ b/src/tools/mime-types/locales/zh.yml
@@ -0,0 +1,23 @@
+tools:
+ mime-types:
+ title: MIME 类型
+ description: 将 MIME 类型转换为扩展名,反之亦然。
+
+ mimeType:
+ title: MIME 类型转扩展名
+ description: 知道哪些文件扩展名与特定 MIME 类型相关联
+ placeholder: '在此处选择您的 MIME 类型...(例如:application/pdf)'
+ extensionsFound:
+ before: '具有'
+ after: ' MIME 类型的文件扩展名:'
+ extension:
+ title: 文件扩展名转 MIME 类型
+ description: 知道哪种 MIME 类型与文件扩展名相关联
+ placeholder: '在此处选择您的 MIME 类型...(例如:application/pdf)'
+ selectedExtension:
+ before: '与扩展名'
+ after: '相关联的 MIME 类型:'
+ ext: '扩展名:'
+ table:
+ mimeTypes: MIME 类型
+ extensions: 扩展名
diff --git a/src/tools/mime-types/mime-types.vue b/src/tools/mime-types/mime-types.vue
index 3bd761191..17c11314e 100644
--- a/src/tools/mime-types/mime-types.vue
+++ b/src/tools/mime-types/mime-types.vue
@@ -1,6 +1,8 @@
@@ -13,29 +14,29 @@ const { tokens } = toRefs(props);