diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md
deleted file mode 100644
index c4bf532b..00000000
--- a/.github/ISSUE_TEMPLATE/bug-report.md
+++ /dev/null
@@ -1,34 +0,0 @@
----
-name: Bug report
-about: Create a report to help us improve our tools
-title: '[BUG] '
-labels: bug
-assignees: CorentinTh
----
-
-**Which tool is impacted?**
-Example: the token generator
-
-**To Reproduce**
-Steps to reproduce the behavior:
-
-1. Go to '...'
-2. Click on '....'
-3. Scroll down to '....'
-4. See error
-
-**Expected behavior**
-A clear and concise description of what you expected to happen.
-
-**Screenshots**
-If applicable, add screenshots to help explain your problem.
-
-**Configuration (please complete the following information):**
-
-- Device: [e.g. iPhone6, ]
-- OS: [e.g. iOS]
-- Browser [e.g. chrome, safari]
-- Version [e.g. 22]
-
-**Additional context**
-Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
new file mode 100644
index 00000000..d338fa3f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -0,0 +1,48 @@
+name: đ Bug Report
+description: File a bug report.
+labels: ['bug', 'triage']
+assignees:
+ - CorentinTh
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to fill out this bug report!
+
+ - type: textarea
+ id: bug-description
+ attributes:
+ label: Describe the bug
+ description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks!
+ placeholder: Bug description
+ validations:
+ required: true
+
+ - type: textarea
+ id: what-happened
+ attributes:
+ label: What happened?
+ description: Also tell us, what did you expect to happen? If you have a screenshot, you can paste it here.
+ placeholder: Tell us what you see!
+ value: 'A bug happened!'
+ validations:
+ required: true
+
+ - type: textarea
+ id: version
+ attributes:
+ label: System information
+ description: What is you environment? You can use the `npx envinfo --system --browsers` command to get this information.
+ validations:
+ required: true
+
+ - type: dropdown
+ id: app-type
+ attributes:
+ label: Where did you encounter the bug?
+ options:
+ - Public app (it-tools.tech)
+ - A self hosted
+ - Other (installations, docker, etc.)
+ validations:
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 00000000..3ba13e0c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1 @@
+blank_issues_enabled: false
diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml
new file mode 100644
index 00000000..edae822e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature-request.yml
@@ -0,0 +1,56 @@
+name: đ New feature proposal
+description: Propose a new feature/enhancement or tool idea for IT-Tools
+labels: ['enhancement', 'triage']
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for your interest in the project and taking the time to fill out this feature report!
+
+ - type: dropdown
+ id: request-type
+ attributes:
+ label: What type of request is this?
+ options:
+ - New tool idea
+ - New feature for an existing tool
+ - Deployment or CI/CD improvement
+ - Self-hosting improvement
+ - Other
+ validations:
+ required: true
+
+ - type: textarea
+ id: feature-description
+ attributes:
+ label: Clear and concise description of the feature you are proposing
+ description: A clear and concise description of what the feature is.
+ placeholder: 'Example: a token generator tool'
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternative
+ attributes:
+ label: Is their example of this tool in the wild?
+ description: Provide link to already existing tool (like websites, apps, cli, ...) or npm packages that could be used or provide inspiration for the feature.
+
+ - type: textarea
+ id: additional-context
+ attributes:
+ label: Additional context
+ description: Any other context or screenshots about the feature request here.
+
+ - type: checkboxes
+ id: checkboxes
+ attributes:
+ label: Validations
+ description: Before submitting the issue, please make sure you do the following
+ options:
+ - label: Check the feature is not already implemented in the project.
+ required: true
+ - label: Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
+ required: true
+ - label: Check that the feature can be implemented in a client side only app (IT-Tools is client side only, no server).
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/new-tool-request.md b/.github/ISSUE_TEMPLATE/new-tool-request.md
deleted file mode 100644
index a67a9cd0..00000000
--- a/.github/ISSUE_TEMPLATE/new-tool-request.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-name: New tool request
-about: Suggest a new tool idea
-title: '[NEW TOOL]'
-labels: new tool
-assignees: CorentinTh
----
-
-**What tool do you want?**
-Example: a token generator
-
-**Describe the solution you'd like**
-A clear and concise description of what you want to happen.
-
-**Is their example of this tool in the wild?**
-Provide link to already existing tool or npm packages if any exists
-
-**Additional context**
-Add any other context about the feature request here.
diff --git a/.github/ISSUE_TEMPLATE/other-request.md b/.github/ISSUE_TEMPLATE/other-request.md
deleted file mode 100644
index b4901ed4..00000000
--- a/.github/ISSUE_TEMPLATE/other-request.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-name: Other request
-about: Any request that does not concern a tool creation, a new feature request on a tool or a bug
-title: '[OTHER] '
-labels:
-assignees: CorentinTh
----
-
-**Describe the solution you'd like**
-A clear and concise description of what you want.
-
-**Additional context**
-Add any other context about the feature request here.
diff --git a/.github/ISSUE_TEMPLATE/tool-improvement.md b/.github/ISSUE_TEMPLATE/tool-improvement.md
deleted file mode 100644
index 8ff8bb6c..00000000
--- a/.github/ISSUE_TEMPLATE/tool-improvement.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-name: Tool improvement
-about: Improvement on an existing tool
-title: '[TOOL IMPROVEMENT]'
-labels: enhancement
-assignees: CorentinTh
----
-
-**Describe the solution you'd like**
-A clear and concise description of what you want to happen.
-
-**Additional context**
-Add any other context about the feature request here.
diff --git a/.github/logo-dark.png b/.github/logo-dark.png
new file mode 100644
index 00000000..9bee8a9c
Binary files /dev/null and b/.github/logo-dark.png differ
diff --git a/.github/logo-white.png b/.github/logo-white.png
new file mode 100644
index 00000000..560a135b
Binary files /dev/null and b/.github/logo-white.png differ
diff --git a/.github/logo.png b/.github/logo.png
deleted file mode 100644
index 18bac950..00000000
Binary files a/.github/logo.png and /dev/null differ
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
deleted file mode 100644
index 6d11e825..00000000
--- a/.github/workflows/codeql-analysis.yml
+++ /dev/null
@@ -1,69 +0,0 @@
-# For most projects, this workflow file will not need changing; you simply need
-# to commit it to your repository.
-#
-# You may wish to alter this file to override the set of languages analyzed,
-# or to provide custom queries or build logic.
-#
-# ******** NOTE ********
-# We have attempted to detect the languages in your repository. Please check
-# the `language` matrix defined below to confirm you have the correct set of
-# supported CodeQL languages.
-#
-name: "CodeQL"
-
-on:
- push:
- branches: [ dev ]
- pull_request:
- # The branches below must be a subset of the branches above
- branches: [ dev ]
-
-jobs:
- analyze:
- name: Analyze
- runs-on: ubuntu-latest
- permissions:
- actions: read
- contents: read
- security-events: write
-
- strategy:
- fail-fast: false
- matrix:
- language: [ 'javascript' ]
- # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
- # Learn more:
- # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
-
- # Initializes the CodeQL tools for scanning.
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v2
- with:
- languages: ${{ matrix.language }}
- # If you wish to specify custom queries, you can do so here or in a config file.
- # By default, queries listed here will override any specified in a config file.
- # Prefix the list here with "+" to use these queries and those in the config file.
- # queries: ./path/to/local/query, your-org/your-repo/queries@main
-
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
- # If this step fails, then you should remove it and run the build manually (see below)
- - name: Autobuild
- uses: github/codeql-action/autobuild@v2
-
- # âčïž Command-line programs to run using the OS shell.
- # đ https://git.io/JvXDl
-
- # âïž If the Autobuild fails above, remove it and uncomment the following three lines
- # and modify them (or add more) to build your code if your project
- # uses a compiled language
-
- #- run: |
- # make bootstrap
- # make release
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v2
diff --git a/.github/workflows/docker-nightly-release.yml b/.github/workflows/docker-nightly-release.yml
index 81a0898c..41dbb155 100644
--- a/.github/workflows/docker-nightly-release.yml
+++ b/.github/workflows/docker-nightly-release.yml
@@ -32,7 +32,7 @@ jobs:
- run: corepack enable
- uses: actions/setup-node@v3
with:
- node-version: 16
+ node-version: 20
cache: 'pnpm'
- name: Install dependencies
diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index 8ed4099d..d0d3febd 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -61,7 +61,7 @@ jobs:
- uses: actions/setup-node@v3
with:
- node-version: 16
+ node-version: 20
cache: 'pnpm'
- name: Install dependencies
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1c12c11c..984fa58e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,9 +2,51 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+## Version 2024.05.13-a0bc346
+
+### Features
+- **i18n**: added German translation (#1038) (2c2fb21)
+- **new tool**: Outlook Safelink Decoder (#911) (d3b32cc)
+- **new tool**: ascii art generator (#886) (fe349ad)
+- **i18n**: get locales on build (#880) (dc04615)
+- **i18n**: added vi tools translations (#876) (079aa21)
+- **i18n**: added zh tools translations (#874) (9c6b122)
+- **i18n**: added missing locale files in tools (#863) (7f5fa00)
+- **i18n**: added vietnamese language (#859) (1334bff)
+- **i18n**: added spanish language (#854) (85b50bb)
+- **i18n**: added portuguese language (#813) (c65ffb6)
+- **i18n**: added ukrainian language (#827) (693f362)
+- **new-tool**: yaml formater (#779) (fc06f01)
+- **new-tool**: added unicode conversion utilities (#858) (c46207f)
+
+### Bug fixes
+- **language**: English language cleanup (#1036) (221ddfa)
+- **url-encoder, validation**: typo in validation of url-encoder.vue #1024 (cb5b462)
+- **integer base converter**: support bigint (#872) (9eac9cb)
+- **bcrypt tool**: allow salt rounds up to 100 (#987) (23f82d9)
+
+### Refactoring
+- **lint**: removed extra semi (33e5294)
+- **auto-imports**: regen auto imports (1242842)
+- **home**: lightened tool cards (#882) (a07806c)
+- **home**: removed n-grid to prevent layout shift (#881) (10e56b3)
+- **i18n**: added locales per tool (#861) (95698cb)
+
+### Chores
+- **issues**: prevent empty issues (#1078) (a0bc346)
+- **issues**: removed old issue templates (#1077) (5a7b0f9)
+- **node**: upgraded node version in CI workflows (b59942a)
+- **version**: release 2024.05.10-33e5294 (38d5687)
+- **issues**: improved issues template (2852c30)
+- **issues**: improved bug issue template (#1046) (a799234)
+
+### Documentation
+- **changelog**: update changelog for 2024.05.10-33e5294 (9dfd347)
+
## Version 2023.12.21-5ed3693
### Features
+
- **i18n**: improve chinese i18n (#757) (2e56641)
- **i18n**: add tooltip and favoriteButton i18n (#756) (a1037cf)
- **i18n**: add Chinese translation base (#718) (8f99eb6)
@@ -12,6 +54,7 @@ All notable changes to this project will be documented in this file. See [standa
- **new tool**: numeronym generator (#729) (e07e2ae)
### Bug fixes
+
- **jwt-parser**: jwt claim array support (#799) (5ed3693)
- **camera-recorder**: stop camera on navigation (#782) (80e46c9)
- **doc**: updated create new tool command in readme (#762) (7a70dbb)
@@ -20,6 +63,7 @@ All notable changes to this project will be documented in this file. See [standa
- **eta**: corrected example (#737) (821cbea)
### Refactoring
+
- **about, i18n**: improved i18n dx with markdown (#753) (bd3edcb)
- **token, i18n**: complete fr translation (#752) (de1ee69)
- **uuid generator**: uuid version picker (#751) (38586ca)
@@ -29,6 +73,7 @@ All notable changes to this project will be documented in this file. See [standa
- **bcrypt**: fix input label align (#721) (093ff31)
### Chores
+
- **deps**: switched from oui to oui-data for mac address lookup (#693) (0fe9a20)
- **deps**: update unocss monorepo to ^0.57.0 (#638) (2e396d8)
- **docker**: added armv7 plateform for docker releases (#722) (fe1de8c)
@@ -36,19 +81,23 @@ All notable changes to this project will be documented in this file. See [standa
## Version 2023.11.02-7d94e11
### Features
+
- **i18n**: language selector (#710) (e86fd96)
### Bug fixes
+
- **dockerfile**: revert replacement of nginx image with non-privileged one (#716) (7d94e11)
- **encryption**: alert on decryption error (#711) (02b0d0d)
### Refactoring
+
- **math-evaluator**: improved description (e87f4b1)
- **math-evaluator**: improved search and UX (#713) (58de897)
## Version 2023.11.01-e164afb
### Features
+
- **command-palette**: clear prompt on palette close (#708) (d013696)
- **command-palette**: added about page in command palette (99b1eb9)
- **new tool**: random MAC address generator (#657) (cc3425d)
@@ -67,11 +116,13 @@ All notable changes to this project will be documented in this file. See [standa
- **new tool**: text diff and comparator (#588) (81bfe57)
### Bug fixes
+
- **deps**: fix issue on slugify (#593) (#673) (720201a)
- **deps**: update dependency monaco-editor to ^0.43.0 (#620) (e371ef7)
- **deps**: update dependency sql-formatter to v13 (#606) (c7d4562)
### Refactoring
+
- **ui**: better ui demo preview menu (#664) (015c673)
- **color-converter**: improved color-converter UX (#701) (abb8335)
- **docker**: improved docker config (#700) (020e9cb)
@@ -88,6 +139,7 @@ All notable changes to this project will be documented in this file. See [standa
- **bcrypt**: fix typo (#604) (e18bae1)
### Chores
+
- **deps**: clean unused dependencies (#709) (e164afb)
- **deps**: update docker/setup-qemu-action action to v3 (#627) (4365226)
- **deps**: update docker/setup-buildx-action action to v3 (#626) (57ecda1)
@@ -102,19 +154,23 @@ All notable changes to this project will be documented in this file. See [standa
- **deps**: update dependency typescript to ~5.2.0 (#587) (f3e14fc)
### Doc
+
- **readme**: added contributors list (#622) (557b304)
- **hosting**: added cloudron in the other hosting solutions section (#589) (06c3547)
## Version 2023.08.21-6f93cba
### Features
+
- **copy**: support legacy copy to clipboard for older browser (#581) (6f93cba)
- **new tool**: string obfuscator (#575) (c58d6e3)
### Bug fixes
+
- **deps**: update dependency sql-formatter to v12 (#520) (2bcb77a)
### Chores
+
- **deps**: switched to fucking typescript v5 (#501) (76b2761)
- **deps**: update dependency @antfu/eslint-config to ^0.40.0 (#552) (6ff9a01)
- **deps**: update dependency prettier to v3 (#564) (a2b9b15)
@@ -124,6 +180,7 @@ All notable changes to this project will be documented in this file. See [standa
## Version 2023.08.16-9bd4ad4
### Features
+
- **Case Converter**: Add lowercase and uppercase (#534) (7b6232a)
- **new tool**: emoji picker (#551) (93f7cf0)
- **ui**: added c-select in the ui lib (#550) (dfa1ba8)
@@ -144,6 +201,7 @@ All notable changes to this project will be documented in this file. See [standa
- **base64-string-converter**: switch to encode and decode url safe base64 strings (#392) (0b20f1c)
### Bug fixes
+
- **deps**: update dependency uuid to v9 (#566) (5e12991)
- **deps**: update dependency mathjs to v11 (#519) (7924456)
- **deps**: update dependency @vueuse/router to v10 (#516) (ea0f27c)
@@ -163,6 +221,7 @@ All notable changes to this project will be documented in this file. See [standa
- **ipv4-converter**: removed readonly on input (7aed9c5)
### Refactoring
+
- **navbar**: consistent spacing in navbar buttons (#507) (30f88fc)
- **ui**: remove n-text (#506) (72c98a3)
- **ui**: replaced some n-input to c-input (#505) (05ea545)
@@ -175,6 +234,7 @@ All notable changes to this project will be documented in this file. See [standa
- **ui**: replaced some n-input with c-input-text (f7fc779)
### Chores
+
- **deps**: update dependency vitest to ^0.34.0 (#562) (9bd4ad4)
- **deps**: update dependency node to v18.17.1 (#560) (65a9474)
- **deps**: update dependency unocss to ^0.55.0 (#561) (85cc7a8)
@@ -215,47 +275,58 @@ All notable changes to this project will be documented in this file. See [standa
- **lint**: switched to a better lint config (33c9b66)
### Refacor
+
- **transformers**: use monospace font for JSON and SQL text areas (#476) (ba4876d)
### Documentation
+
- **ide**: updated vscode extensions settings (#472) (847323c)
### Chors
+
- **deps**: updated vueuse dependency version (8515c24)
## Version 2023.05.14-77f2efc
### Features
+
- **list-converter**: a small converter who deals with column based data and do some stuff with it (#387) (83a7b3b)
- **new tool**: phone parser and normalizer (ce3150c)
### Bug fixes
+
- **phone-parser**: use default country code (a43c546)
- **home**: prevent weird blue border on card (3f6c8f0)
### Refactoring
+
- **ui**: replaced some n-input with c-input-text (77f2efc)
### Chores
+
- **issues**: updated new tool request issue template (edae4c6)
### Ui-lib
+
- **new-component**: added text input component in the c-lib (aad8d84)
- **button**: size variants (401f13f)
## Version 2023.04.23-92bd835
### Features
+
- **ui-lib**: demo pages for c-lib components (92bd835)
- **new-tool**: diff of two json objects (362f2fa)
- **ipv4-range-expander**: expands a given IPv4 start and end address to a valid IPv4 subnet (#366) (df989e2)
- **date converter**: auto focus main input (6d22025)
### Bug fixes
+
- **ts**: cleaned legacy typechecking warning (e88c1d5)
- **mac-address-lookup**: added copy handler on button click (c311e38)
### Refactoring
+
- **ui-lib**: prevent c-button to shrink (61ece23)
- **ui**: replaced naive ui cards with custom ones (f080933)
- **clean**: removed unused lodash import (bb32513)
@@ -265,48 +336,60 @@ All notable changes to this project will be documented in this file. See [standa
## Version 2023.04.14-dbad773
### Features
+
- **new-tool**: http status codes (8355bd2)
### Refactoring
+
- **uuid-generator**: prevent NaN in quantity (6fb4994)
### Chores
+
- **release**: create a github release on new version (dbad773)
- **version**: reset CHANGELOG content to support new format (85cb0ff)
## Version 2023.04.14-f9b77b7
### Features
+
- **new-tool**: http status codes (8355bd2)
### Refactoring
+
- **uuid-generator**: prevent NaN in quantity (6fb4994)
### Chores
+
- **release**: create a github release on new version (f9b77b7)
- **version**: reset CHANGELOG content to support new format (85cb0ff)
## Version 2023.04.14-2f0d239
### Features
+
- **new-tool**: http status codes (8355bd2)
### Refactoring
+
- **uuid-generator**: prevent NaN in quantity (6fb4994)
### Chores
+
- **release**: create a github release on new version (2f0d239)
- **version**: reset CHANGELOG content to support new format (85cb0ff)
## Version 2023.04.14-474cae4
### Features
+
- **new-tool**: http status codes (8355bd2)
### Refactoring
+
- **uuid-generator**: prevent NaN in quantity (6fb4994)
### Chores
+
- **release**: create a github release on new version (474cae4)
- **version**: reset CHANGELOG content to support new format (85cb0ff)
diff --git a/README.md b/README.md
index a51f9c53..b9726864 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,8 @@
-
+
+
+
+
+
Useful tools for developer and people working in IT. [Have a look !](https://it-tools.tech).
diff --git a/components.d.ts b/components.d.ts
index f2c3146f..3e65c3cc 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -72,6 +72,7 @@ declare module '@vue/runtime-core' {
DockerRunToDockerComposeConverter: typeof import('./src/tools/docker-run-to-docker-compose-converter/docker-run-to-docker-compose-converter.vue')['default']
DynamicValues: typeof import('./src/tools/benchmark-builder/dynamic-values.vue')['default']
Editor: typeof import('./src/tools/html-wysiwyg-editor/editor/editor.vue')['default']
+ EmailNormalizer: typeof import('./src/tools/email-normalizer/email-normalizer.vue')['default']
EmojiCard: typeof import('./src/tools/emoji-picker/emoji-card.vue')['default']
EmojiGrid: typeof import('./src/tools/emoji-picker/emoji-grid.vue')['default']
EmojiPicker: typeof import('./src/tools/emoji-picker/emoji-picker.vue')['default']
@@ -110,6 +111,7 @@ declare module '@vue/runtime-core' {
JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default']
JsonToCsv: typeof import('./src/tools/json-to-csv/json-to-csv.vue')['default']
JsonToToml: typeof import('./src/tools/json-to-toml/json-to-toml.vue')['default']
+ JsonToXml: typeof import('./src/tools/json-to-xml/json-to-xml.vue')['default']
JsonToYaml: typeof import('./src/tools/json-to-yaml-converter/json-to-yaml.vue')['default']
JsonViewer: typeof import('./src/tools/json-viewer/json-viewer.vue')['default']
JwtParser: typeof import('./src/tools/jwt-parser/jwt-parser.vue')['default']
@@ -119,6 +121,7 @@ declare module '@vue/runtime-core' {
LoremIpsumGenerator: typeof import('./src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue')['default']
MacAddressGenerator: typeof import('./src/tools/mac-address-generator/mac-address-generator.vue')['default']
MacAddressLookup: typeof import('./src/tools/mac-address-lookup/mac-address-lookup.vue')['default']
+ MarkdownToHtml: typeof import('./src/tools/markdown-to-html/markdown-to-html.vue')['default']
MathEvaluator: typeof import('./src/tools/math-evaluator/math-evaluator.vue')['default']
MenuBar: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar.vue')['default']
MenuBarItem: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar-item.vue')['default']
@@ -127,24 +130,19 @@ declare module '@vue/runtime-core' {
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
- NCode: typeof import('naive-ui')['NCode']
+ NCheckbox: typeof import('naive-ui')['NCheckbox']
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDivider: typeof import('naive-ui')['NDivider']
NEllipsis: typeof import('naive-ui')['NEllipsis']
- NFormItem: typeof import('naive-ui')['NFormItem']
- NGi: typeof import('naive-ui')['NGi']
- NGrid: typeof import('naive-ui')['NGrid']
NH1: typeof import('naive-ui')['NH1']
NH3: typeof import('naive-ui')['NH3']
NIcon: typeof import('naive-ui')['NIcon']
- NInputNumber: typeof import('naive-ui')['NInputNumber']
- NLabel: typeof import('naive-ui')['NLabel']
NLayout: typeof import('naive-ui')['NLayout']
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
NMenu: typeof import('naive-ui')['NMenu']
- NScrollbar: typeof import('naive-ui')['NScrollbar']
- NSpin: typeof import('naive-ui')['NSpin']
+ NSpace: typeof import('naive-ui')['NSpace']
+ NTable: typeof import('naive-ui')['NTable']
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']
@@ -154,6 +152,9 @@ declare module '@vue/runtime-core' {
PhoneParserAndFormatter: typeof import('./src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue')['default']
QrCodeGenerator: typeof import('./src/tools/qr-code-generator/qr-code-generator.vue')['default']
RandomPortGenerator: typeof import('./src/tools/random-port-generator/random-port-generator.vue')['default']
+ RegexMemo: typeof import('./src/tools/regex-memo/regex-memo.vue')['default']
+ 'RegexMemo.content': typeof import('./src/tools/regex-memo/regex-memo.content.md')['default']
+ RegexTester: typeof import('./src/tools/regex-tester/regex-tester.vue')['default']
ResultRow: typeof import('./src/tools/ipv4-range-expander/result-row.vue')['default']
RomanNumeralConverter: typeof import('./src/tools/roman-numeral-converter/roman-numeral-converter.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
@@ -186,6 +187,7 @@ declare module '@vue/runtime-core' {
UuidGenerator: typeof import('./src/tools/uuid-generator/uuid-generator.vue')['default']
WifiQrCodeGenerator: typeof import('./src/tools/wifi-qr-code-generator/wifi-qr-code-generator.vue')['default']
XmlFormatter: typeof import('./src/tools/xml-formatter/xml-formatter.vue')['default']
+ XmlToJson: typeof import('./src/tools/xml-to-json/xml-to-json.vue')['default']
YamlToJson: typeof import('./src/tools/yaml-to-json-converter/yaml-to-json.vue')['default']
YamlToToml: typeof import('./src/tools/yaml-to-toml/yaml-to-toml.vue')['default']
YamlViewer: typeof import('./src/tools/yaml-viewer/yaml-viewer.vue')['default']
diff --git a/locales/de.yml b/locales/de.yml
new file mode 100644
index 00000000..5a47c85d
--- /dev/null
+++ b/locales/de.yml
@@ -0,0 +1,455 @@
+'404':
+ notFound: 404 Nicht gefunden
+ sorry: Entschuldigung, diese Seite scheint nicht zu existieren
+ maybe: >-
+ Vielleicht macht der Cache etwas Seltsames. Mit einem erzwungenen Neuladen
+ versuchen?
+ backHome: ZurĂŒck zur Startseite
+home:
+ categories:
+ newestTools: Neueste Tools
+ favoriteTools: Deine Lieblingstools
+ allTools: Alle Tools
+ subtitle: Praktische Tools fĂŒr Entwickler
+ toggleMenu: MenĂŒ umschalten
+ home: Startseite
+ uiLib: UI-Bibliothek
+ support: UnterstĂŒtze die Entwicklung von IT-Tools
+ buyMeACoffee: Kauf mir einen Kaffee
+ follow:
+ title: Magst du IT-Tools?
+ p1: Gib uns einen Stern auf
+ githubRepository: IT-Tools GitHub-Repository
+ p2: oder folge uns auf
+ twitterAccount: IT-Tools Twitter-Konto
+ thankYou: Vielen Dank!
+ nav:
+ github: GitHub-Repository
+ githubRepository: IT-Tools GitHub-Repository
+ twitter: Twitter-Konto
+ twitterAccount: IT-Tools Twitter-Konto
+ about: Ăber IT-Tools
+ aboutLabel: Ăber
+ darkMode: Dunkelmodus
+ lightMode: Hellmodus
+ mode: Wechseln zwischen dunklem/hellem Modus
+about:
+ content: >
+ # Ăber IT-Tools
+
+ Diese wunderbare Website, erstellt mit †von [Corentin
+ Thomasset](https://github.com/CorentinTh), sammelt nĂŒtzliche Tools fĂŒr
+ Entwickler und Menschen, die in der IT arbeiten. Wenn du sie nĂŒtzlich
+ findest, teile sie gerne mit Personen, von denen du denkst, dass sie sie
+ ebenfalls nĂŒtzlich finden könnten, und vergiss nicht, sie in deiner
+ Lesezeichenleiste zu speichern!
+
+ IT-Tools ist Open Source (unter der MIT-Lizenz) und kostenlos und wird es
+ immer sein, aber es kostet mich Geld, die Website zu hosten und den
+ Domainnamen zu erneuern. Wenn du meine Arbeit unterstĂŒtzen möchtest und mich
+ ermutigen möchtest, mehr Tools hinzuzufĂŒgen, ĂŒberlege bitte, mich durch
+ [Sponsoring](https://www.buymeacoffee.com/cthmsst) zu unterstĂŒtzen.
+
+ ## Technologien
+
+ IT-Tools wurde mit Vue.js (Vue 3) und der Naive UI-Komponentenbibliothek
+ erstellt und wird von Vercel gehostet und kontinuierlich bereitgestellt. In
+ einigen Tools werden Drittanbieter-Open-Source-Bibliotheken verwendet. Du
+ findest die vollstÀndige Liste in der
+ [package.json](https://github.com/CorentinTh/it-tools/blob/main/package.json)-Datei
+ des Repositorys.
+
+ ## Einen Fehler gefunden? Ein Tool fehlt?
+
+ Wenn du ein Tool benötigst, das hier noch nicht vorhanden ist, und du
+ denkst, dass es nĂŒtzlich sein könnte, bist du herzlich eingeladen, einen
+ Feature-Request im
+ [Issues-Bereich](https://github.com/CorentinTh/it-tools/issues/new/choose)
+ im GitHub-Repository einzureichen.
+
+ Und wenn du einen Fehler gefunden hast oder etwas nicht wie erwartet
+ funktioniert, melde bitte einen Fehler im
+ [Issues-Bereich](https://github.com/CorentinTh/it-tools/issues/new/choose)
+ im GitHub-Repository.
+favoriteButton:
+ remove: Aus Favoriten entfernen
+ add: Zu Favoriten hinzufĂŒgen
+toolCard:
+ new: Neu
+search:
+ label: Suche
+tools:
+ categories:
+ favorite-tools: Deine Lieblingstools
+ crypto: Krypto
+ converter: Konverter
+ web: Web
+ images and videos: Bilder & Videos
+ development: Entwicklung
+ network: Netzwerk
+ math: Mathematik
+ measurement: Messung
+ text: Text
+ data: Daten
+ password-strength-analyser:
+ title: PasswortstÀrken-Analysator
+ description: >-
+ Ermittle die StÀrke deines Passworts mit diesem Client-seitigen
+ PasswortstÀrken-Analysator und Tool zur SchÀtzung der Knackzeit.
+ chronometer:
+ title: Chronometer
+ description: >-
+ Ăberwache die Dauer einer Sache. Im Grunde ein Chronometer mit einfachen
+ Chronometerfunktionen.
+ token-generator:
+ title: Token-Generator
+ description: >-
+ Generiere eine zufĂ€llige Zeichenfolge mit den von dir gewĂŒnschten Zeichen,
+ GroĂ- oder Kleinbuchstaben, Zahlen und/oder Symbolen.
+ uppercase: GroĂbuchstaben (ABC...)
+ lowercase: Kleinbuchstaben (abc...)
+ numbers: Zahlen (123...)
+ symbols: Symbole (!-;...)
+ length: LĂ€nge
+ tokenPlaceholder: Der Token ...
+ copied: Token in die Zwischenablage kopiert
+ button:
+ copy: Kopieren
+ refresh: Aktualisieren
+ percentage-calculator:
+ title: Prozentrechner
+ description: >-
+ Berechne einfach ProzentsÀtze von einem Wert zu einem anderen Wert oder
+ von einem Prozentsatz zu einem Wert.
+ svg-placeholder-generator:
+ title: SVG-Platzhalter-Generator
+ description: >-
+ Generiere SVG-Bilder, die als Platzhalter in deinen Anwendungen verwendet
+ werden können.
+ json-to-csv:
+ title: JSON zu CSV
+ description: Konvertiere JSON mit automatischer Headererkennung in CSV.
+ camera-recorder:
+ title: Kamera-Rekorder
+ description: Mache ein Foto oder nimm ein Video von deiner Webcam oder Kamera auf.
+ keycode-info:
+ title: Keycode-Info
+ description: >-
+ Finde den JavaScript-Keycode, den Code, den Standort und die Modifikatoren
+ einer beliebigen gedrĂŒckten Taste.
+ emoji-picker:
+ title: Emoji-Picker
+ description: >-
+ Einfaches Kopieren und EinfĂŒgen von Emojis. Erhalte auĂerdem den Unicode-
+ und Codepunkt-Wert jedes Emojis.
+ color-converter:
+ title: Farbkonverter
+ description: >-
+ Konvertiere Farben zwischen den verschiedenen Formaten (Hex, RGB, HSL und
+ CSS-Name).
+ bcrypt:
+ title: Bcrypt
+ description: >-
+ Hashen und Vergleichen von Strings mit bcrypt. Bcrypt ist eine auf der
+ Blowfish-Chiffre basierende Hash-Funktion.
+ crontab-generator:
+ title: Crontab-Generator
+ description: >-
+ ĂberprĂŒfe und generiere Crontab und erhalte die menschenlesbare
+ Beschreibung des Cron-Zeitplans.
+ http-status-codes:
+ title: HTTP-Statuscodes
+ description: Liste aller HTTP-Statuscodes, ihrer Namen und ihrer Bedeutung.
+ sql-prettify:
+ title: SQL verschönern und formatieren
+ description: >-
+ Formatiere und verschönere deine SQL-Abfragen online (unterstĂŒtzt
+ verschiedene SQL-Dialekte).
+ benchmark-builder:
+ title: Benchmark-Builder
+ description: >-
+ Vergleiche ganz einfach die AusfĂŒhrungszeit von Aufgaben mit diesem sehr
+ einfachen Online-Benchmark-Builder.
+ git-memo:
+ title: Git-Spickzettel
+ description: >-
+ Git ist eine dezentrale Versionsverwaltungssoftware. Mit diesem
+ Spickzettel hast du schnellen Zugriff auf die gÀngigsten Git-Befehle.
+ slugify-string:
+ title: Slugify String
+ description: Mache einen String URL-, Dateinamen- und ID-sicher.
+ encryption:
+ title: Text verschlĂŒsseln / entschlĂŒsseln
+ description: >-
+ VerschlĂŒssele und entschlĂŒssele Klartext mithilfe von Kryptoalgorithmen
+ wie AES, TripleDES, Rabbit oder RC4.
+ random-port-generator:
+ title: ZufÀlliger Port-Generator
+ description: >-
+ Generiere zufĂ€llige Portnummern auĂerhalb des Bereichs der "bekannten"
+ Ports (0-1023).
+ yaml-prettify:
+ title: YAML verschönern und formatieren
+ description: Verschönere deinen YAML-String in ein menschenlesbares Format.
+ eta-calculator:
+ title: ETA-Rechner
+ description: >-
+ Ein ETA (Estimated Time of Arrival)-Rechner, um die ungefÀhre Endzeit
+ einer Aufgabe zu erfahren, z. B. den Zeitpunkt des Endes eines Downloads.
+ roman-numeral-converter:
+ title: Römische Zahlen Konverter
+ description: >-
+ Konvertiere römische Zahlen in Dezimalzahlen und Dezimalzahlen in römische
+ Zahlen.
+ hmac-generator:
+ title: HMAC-Generator
+ description: >-
+ Berechnet einen hashbasierten Nachrichtenauthentifizierungscode (HMAC)
+ unter Verwendung eines geheimen SchlĂŒssels und deiner bevorzugten
+ Hash-Funktion.
+ bip39-generator:
+ title: BIP39-Passphrasengenerator
+ description: >-
+ Generiere BIP39-Passphrasen aus vorhandener oder zufÀlliger Mnemonik oder
+ erhalte die Mnemonik aus der Passphrase.
+ base64-file-converter:
+ title: Base64-Dateikonverter
+ description: Konvertiere Strings, Dateien oder Bilder in ihre Base64-ReprÀsentation.
+ list-converter:
+ title: Listenkonverter
+ description: >-
+ Dieses Tool kann spaltenbasierte Daten verarbeiten und verschiedene
+ Ănderungen (transponieren, PrĂ€fix und Suffix hinzufĂŒgen, Liste umkehren,
+ Liste sortieren, Werte in Kleinbuchstaben umwandeln, Werte abschneiden)
+ auf jede Zeile anwenden.
+ base64-string-converter:
+ title: Base64-String-Encoder/Decoder
+ description: Codiere und decodiere Strings einfach in ihre Base64-ReprÀsentation.
+ toml-to-yaml:
+ title: TOML zu YAML
+ description: Parse und konvertiere TOML zu YAML.
+ math-evaluator:
+ title: Mathematischer Auswerter
+ description: >-
+ Ein Taschenrechner zum Auswerten mathematischer AusdrĂŒcke. Du kannst
+ Funktionen wie sqrt, cos, sin, abs usw. verwenden.
+ json-to-yaml-converter:
+ title: JSON zu YAML
+ description: Konvertiere JSON einfach in YAML mit diesem Live-Online-Konverter.
+ url-parser:
+ title: URL-Parser
+ description: >-
+ Parse eine URL-Zeichenfolge, um alle verschiedenen Teile (Protokoll,
+ Ursprung, Parameter, Port, Benutzername-Passwort usw.) zu erhalten.
+ iban-validator-and-parser:
+ title: IBAN-Validator und -Parser
+ description: >-
+ Validiere und parse IBAN-Nummern. ĂberprĂŒfe, ob die IBAN gĂŒltig ist, und
+ erhalte das Land, BBAN, ob es sich um eine QR-IBAN handelt und das
+ IBAN-freundliche Format.
+ user-agent-parser:
+ title: User-Agent-Parser
+ description: >-
+ Erkenne und parse Browser, Engine, Betriebssystem, CPU und
+ GerÀtetyp/-modell aus einer User-Agent-Zeichenfolge.
+ numeronym-generator:
+ title: Numeronym-Generator
+ description: >-
+ Ein Numeronym ist ein Wort, bei dem eine Zahl verwendet wird, um eine
+ AbkĂŒrzung zu bilden. Zum Beispiel ist "i18n" ein Numeronym fĂŒr
+ "internationalization", wobei 18 fĂŒr die Anzahl der Buchstaben zwischen
+ dem ersten "i" und dem letzten "n" im Wort steht.
+ case-converter:
+ title: Fall-Konverter
+ description: >-
+ Ăndere den Fall eines Strings und wĂ€hle zwischen verschiedenen Formaten
+ aus.
+ html-entities:
+ title: HTML-Entity-Escape
+ description: >-
+ Escape oder unescape HTML-EntitÀten (ersetze <, >, &, " und ' durch ihre
+ HTML-Version).
+ json-prettify:
+ title: JSON verschönern und formatieren
+ description: Verschönere deinen JSON-String in ein menschenlesbares Format.
+ docker-run-to-docker-compose-converter:
+ title: Docker run zu Docker compose Konverter
+ description: Wandle docker run-Befehle in docker-compose-Dateien um!
+ mac-address-lookup:
+ title: MAC-Adressensuche
+ description: Finde den Anbieter und Hersteller eines GerÀts anhand seiner MAC-Adresse.
+ mime-types:
+ title: MIME-Typen
+ description: Konvertiere MIME-Typen in Erweiterungen und umgekehrt.
+ toml-to-json:
+ title: TOML zu JSON
+ description: Parse und konvertiere TOML zu JSON.
+ lorem-ipsum-generator:
+ title: Lorem Ipsum Generator
+ description: >-
+ Lorem Ipsum ist ein Platzhaltertext, der hÀufig verwendet wird, um die
+ visuelle Form eines Dokuments oder einer Schriftart ohne Verwendung von
+ bedeutendem Inhalt zu demonstrieren.
+ qrcode-generator:
+ title: QR-Code-Generator
+ description: >-
+ Generiere und downloade QR-Codes fĂŒr eine URL oder einfach einen Text und
+ passe die Hintergrund- und Vordergrundfarben an.
+ wifi-qrcode-generator:
+ title: WLAN-QR-Code-Generator
+ description: >-
+ Generiere und lade QR-Codes fĂŒr schnelle Verbindungen zu WLAN-Netzwerken
+ herunter.
+ xml-formatter:
+ title: XML-Formatter
+ description: Verschönere deinen XML-String in ein menschenlesbares Format.
+ temperature-converter:
+ title: Temperaturkonverter
+ description: >-
+ Temperaturgradumrechnungen fĂŒr Kelvin, Celsius, Fahrenheit, Rankine,
+ Delisle, Newton, Réaumur und RÞmer.
+ chmod-calculator:
+ title: Chmod-Rechner
+ description: >-
+ Berechne deine Chmod-Berechtigungen und -Befehle mit diesem
+ Online-Chmod-Rechner.
+ rsa-key-pair-generator:
+ title: RSA-SchlĂŒsselpaar-Generator
+ description: Generiere neue zufÀllige RSA-Private- und Public-Key-PEM-Zertifikate.
+ html-wysiwyg-editor:
+ title: HTML-WYSIWYG-Editor
+ description: >-
+ Online-HTML-Editor mit funktionsreichem WYSIWYG-Editor, erhalte sofort den
+ Quellcode des Inhalts.
+ yaml-to-toml:
+ title: YAML zu TOML
+ description: Parse und konvertiere YAML zu TOML.
+ mac-address-generator:
+ title: MAC-Adressen-Generator
+ description: >-
+ Gebe die Menge und das PrÀfix ein. MAC-Adressen werden in deiner gewÀhlten
+ Schreibweise (GroĂ- oder Kleinbuchstaben) generiert.
+ json-diff:
+ title: JSON-Unterschied
+ description: Vergleiche zwei JSON-Objekte und erhalte die Unterschiede zwischen ihnen.
+ jwt-parser:
+ title: JWT-Parser
+ description: >-
+ Parse und decodiere deinen JSON-Web-Token (JWT) und zeige dessen Inhalt
+ an.
+ date-converter:
+ title: Datum-Uhrzeit-Konverter
+ description: Konvertiere Datum und Uhrzeit in verschiedene Formate.
+ phone-parser-and-formatter:
+ title: Telefonnummer-Parser und -Formatter
+ description: >-
+ Parse, validiere und formatiere Telefonnummern. Erhalte Informationen zur
+ Telefonnummer, wie z. B. die Landesvorwahl, den Typ usw.
+ ipv4-subnet-calculator:
+ title: IPv4-Subnetzrechner
+ description: >-
+ Parse deine IPv4-CIDR-Blöcke und erhalte alle Informationen, die du ĂŒber
+ dein Subnetz benötigst.
+ og-meta-generator:
+ title: Open Graph Meta-Generator
+ description: Generiere Open Graph- und Social-HTML-Metatags fĂŒr deine Website.
+ ipv6-ula-generator:
+ title: IPv6-ULA-Generator
+ description: >-
+ Generiere deine eigenen lokalen, nicht routbaren IP-Adressen in deinem
+ Netzwerk gemÀà RFC4193.
+ hash-text:
+ title: Text hashen
+ description: >-
+ Hashe einen Text-String mit der von dir benötigten Funktion: MD5, SHA1,
+ SHA256, SHA224, SHA512, SHA384, SHA3 oder RIPEMD160
+ json-to-toml:
+ title: JSON zu TOML
+ description: Parse und konvertiere JSON zu TOML.
+ device-information:
+ title: GerÀteinformationen
+ description: >-
+ Informationen zu deinem aktuellen GerĂ€t (BildschirmgröĂe, PixelverhĂ€ltnis,
+ Benutzeragent, ...) erhalten.
+ pdf-signature-checker:
+ title: PDF-SignaturprĂŒfer
+ description: >-
+ ĂberprĂŒfe die Signaturen einer PDF-Datei. Eine signierte PDF-Datei enthĂ€lt
+ eine oder mehrere Signaturen, die verwendet werden können, um
+ festzustellen, ob der Inhalt der Datei seit dem Zeitpunkt der Signierung
+ geÀndert wurde.
+ json-minify:
+ title: JSON minifizieren
+ description: >-
+ Minifiziere und komprimiere dein JSON, indem unnötige Leerzeichen entfernt
+ werden.
+ ulid-generator:
+ title: ULID-Generator
+ description: >-
+ Generiere zufÀllige Universally Unique Lexicographically Sortable
+ Identifier (ULID).
+ string-obfuscator:
+ title: String-Verschleierer
+ description: >-
+ Verschleiere einen String (wie ein Secret, eine IBAN oder ein Token), um
+ ihn weitergeben zu können und identifizierbar zu machen, ohne seinen
+ Inhalt preiszugeben.
+ base-converter:
+ title: Ganzzahl-Basiskonverter
+ description: >-
+ Konvertiere Zahlen zwischen verschiedenen Basen (Dezimal, Hexadezimal,
+ BinÀr, Oktal, Base64, ...).
+ yaml-to-json-converter:
+ title: YAML zu JSON
+ description: Konvertiere YAML einfach in JSON mit diesem Live-Online-Konverter.
+ uuid-generator:
+ title: UUID-Generator
+ description: >-
+ Ein Universally Unique Identifier (UUID) ist eine 128-Bit-Nummer, die zur
+ Identifizierung von Informationen in Computersystemen verwendet wird. Die
+ Anzahl der möglichen UUIDs betrÀgt 16^32, was 2^128 oder etwa 3,4x10^38
+ entspricht (was ziemlich viel ist!).
+ ipv4-address-converter:
+ title: IPv4-Adresskonverter
+ description: >-
+ Konvertiere eine IP-Adresse in Dezimal, BinÀr, Hexadezimal oder sogar in
+ IPv6.
+ text-statistics:
+ title: Textstatistiken
+ description: >-
+ Informationen zu einem Text erhalten, wie die Anzahl der Zeichen, die
+ Anzahl der Wörter, die GröĂe usw.
+ text-to-nato-alphabet:
+ title: Text zu NATO-Alphabet
+ description: >-
+ Wandle Text in das NATO-Phonetik-Alphabet fĂŒr die mĂŒndliche Ăbermittlung
+ um.
+ basic-auth-generator:
+ title: Basic-Auth-Generator
+ description: >-
+ Generiere einen Base64-Basic-Auth-Header aus einem Benutzernamen und einem
+ Passwort.
+ text-to-unicode:
+ title: Text zu Unicode
+ description: Parse und konvertiere Text in Unicode und umgekehrt.
+ ipv4-range-expander:
+ title: IPv4-Bereichserweiterer
+ description: >-
+ Bei Angabe einer Start- und End-IPv4-Adresse berechnet dieses Tool ein
+ gĂŒltiges IPv4-Netzwerk mit seiner CIDR-Notation.
+ text-diff:
+ title: Textunterschied
+ description: Vergleiche zwei Texte und sieh die Unterschiede zwischen ihnen.
+ otp-generator:
+ title: OTP-Code-Generator
+ description: >-
+ Generiere und validiere zeitbasierte OTPs (Einmalpasswörter) fĂŒr
+ Multi-Faktor-Authentifizierung.
+ url-encoder:
+ title: Kodieren/Decodieren von URL-formatierten Zeichenfolgen
+ description: >-
+ Kodiere zum URL-kodierten Format (auch als "prozentkodiert" bekannt) oder
+ decodiere es.
+ text-to-binary:
+ title: Text zu ASCII-BinÀr
+ description: Konvertiere Text in seine ASCII-BinÀrreprÀsentation und umgekehrt.
diff --git a/locales/en.yml b/locales/en.yml
index 50d48af9..d09d435a 100644
--- a/locales/en.yml
+++ b/locales/en.yml
@@ -7,7 +7,7 @@ home:
toggleMenu: 'Toggle menu'
home: Home
uiLib: 'UI Lib'
- support: 'Support IT Tools development'
+ support: 'Support IT-Tools development'
buyMeACoffee: 'Buy me a coffee'
follow:
title: 'You like it-tools?'
@@ -15,7 +15,7 @@ home:
githubRepository: 'IT-Tools GitHub repository'
p2: 'or follow us on'
twitterAccount: 'IT-Tools Twitter account'
- thankYou: 'Thank you !'
+ thankYou: 'Thank you!'
nav:
github: 'GitHub repository'
githubRepository: 'IT-Tools GitHub repository'
@@ -72,7 +72,7 @@ tools:
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.
+ description: Discover the strength of your password with this client-side-only password strength analyser and crack time estimation tool.
chronometer:
title: Chronometer
@@ -98,7 +98,7 @@ tools:
svg-placeholder-generator:
title: SVG placeholder generator
- description: Generate svg images to use as placeholder in your applications.
+ description: Generate svg images to use as a placeholder in your applications.
json-to-csv:
title: JSON to CSV
@@ -126,11 +126,11 @@ tools:
crontab-generator:
title: Crontab generator
- description: Validate and generate crontab and get the human readable description of the cron schedule.
+ 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.
+ description: The list of all HTTP status codes, their name, and their meaning.
sql-prettify:
title: SQL prettify and format
@@ -142,7 +142,7 @@ 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.
+ description: Git is a decentralized version management software. With this cheatsheet, you will have quick access to the most common git commands.
slugify-string:
title: Slugify string
@@ -150,7 +150,7 @@ tools:
encryption:
title: Encrypt / decrypt text
- description: Encrypt and decrypt text clear text using crypto algorithm like AES, TripleDES, Rabbit or RC4.
+ description: Encrypt clear text and decrypt ciphertext using crypto algorithms like AES, TripleDES, Rabbit or RC4.
random-port-generator:
title: Random port generator
@@ -158,11 +158,11 @@ tools:
yaml-prettify:
title: YAML prettify and format
- description: Prettify your YAML string to a human friendly readable format.
+ description: Prettify your YAML string into a friendly, human-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.
+ description: An ETA (Estimated Time of Arrival) calculator to determine the approximate end time of a task, for example, the end time and duration of a file download.
roman-numeral-converter:
title: Roman numeral converter
@@ -174,11 +174,11 @@ tools:
bip39-generator:
title: BIP39 passphrase generator
- description: Generate BIP39 passphrase from existing or random mnemonic, or get the mnemonic from the passphrase.
+ description: Generate a BIP39 passphrase from an 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.
+ description: Convert a string, file, or image into its base64 representation.
list-converter:
title: List converter
@@ -186,7 +186,7 @@ tools:
base64-string-converter:
title: Base64 string encoder/decoder
- description: Simply encode and decode string into a their base64 representation.
+ description: Simply encode and decode strings into their base64 representation.
toml-to-yaml:
title: TOML to YAML
@@ -198,15 +198,15 @@ tools:
json-to-yaml-converter:
title: JSON to YAML converter
- description: Simply convert JSON to YAML with this live online converter.
+ description: Simply convert JSON to YAML with this online live converter.
url-parser:
- title: Url parser
- description: Parse an url string to get all the different parts (protocol, origin, params, port, username-password, ...)
+ title: URL parser
+ description: Parse a URL into its separate constituent 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.
+ description: Validate and parse IBAN numbers. Check if an 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
@@ -218,27 +218,27 @@ tools:
case-converter:
title: Case converter
- description: Change the case of a string and chose between different formats
+ description: Transform the case of a string and choose between different formats
html-entities:
- title: Escape html entities
- description: Escape or unescape html entities (replace <,>, &, " and \' to their html version)
+ title: Escape HTML entities
+ description: Escape or unescape HTML entities (replace characters like <,>, &, " and \' with their HTML version)
json-prettify:
title: JSON prettify and format
- description: Prettify your JSON string to a human friendly readable format.
+ description: Prettify your JSON string into a friendly, human-readable format.
docker-run-to-docker-compose-converter:
title: Docker run to Docker compose converter
- description: Turns docker run commands into docker-compose files!
+ description: Transforms "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.
+ title: MIME types
+ description: Convert MIME types to file extensions and vice-versa.
toml-to-json:
title: TOML to JSON
@@ -250,19 +250,19 @@ tools:
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.
+ description: Generate and download a QR code for a URL (or just plain 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.
+ 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.
+ description: Prettify your XML string into a friendly, human-readable format.
temperature-converter:
title: Temperature converter
- description: Temperature degrees conversions for Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Réaumur and RÞmer.
+ description: Degrees temperature conversions for Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Réaumur, and RÞmer.
chmod-calculator:
title: Chmod calculator
@@ -270,11 +270,11 @@ tools:
rsa-key-pair-generator:
title: RSA key pair generator
- description: Generate new random RSA private and public key pem certificates.
+ description: Generate a new random RSA private and public pem certificate key pair.
html-wysiwyg-editor:
title: HTML WYSIWYG editor
- description: Online HTML editor with feature-rich WYSIWYG editor, get the source code of the content immediately.
+ description: Online, feature-rich WYSIWYG HTML editor which generates the source code of the content immediately.
yaml-to-toml:
title: YAML to TOML
@@ -302,15 +302,15 @@ 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.
+ description: Parse your IPv4 CIDR blocks and get all the info you need about your subnet.
og-meta-generator:
title: Open graph meta generator
- description: Generate open-graph and socials html meta tags for your website.
+ 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.
+ description: Generate your own local, non-routable IP addresses for your network according to RFC4193.
hash-text:
title: Hash text
@@ -330,7 +330,7 @@ tools:
json-minify:
title: JSON minify
- description: Minify and compress your JSON by removing unnecessary white spaces.
+ description: Minify and compress your JSON by removing unnecessary whitespace.
ulid-generator:
title: ULID generator
@@ -342,31 +342,31 @@ tools:
base-converter:
title: Integer base converter
- description: Convert number between different bases (decimal, hexadecimal, binary, octal, base64, ...)
+ description: Convert a 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.
+ description: Simply convert YAML to JSON with this online live 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
+ title: IPv4 address converter
+ description: Convert an IP address into decimal, binary, hexadecimal, or even an IPv6 representation of it.
text-statistics:
title: Text statistics
- description: Get information about a text, the amount of characters, the amount of words, it\'s size, ...
+ description: Get information about a text, the number of characters, the number of words, its size in bytes, ...
text-to-nato-alphabet:
title: Text to NATO alphabet
- description: Transform text into NATO phonetic alphabet for oral transmission.
+ description: Transform text into the 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.
+ description: Generate a base64 basic auth header from a username and password.
text-to-unicode:
title: Text to Unicode
@@ -374,7 +374,7 @@ 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.
+ description: Given a start and an end IPv4 address, this tool calculates a valid IPv4 subnet along with its CIDR notation.
text-diff:
title: Text diff
@@ -385,9 +385,9 @@ tools:
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.
+ title: Encode/decode URL-formatted strings
+ description: Encode text 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.
+ description: Convert text to its ASCII binary representation and vice-versa.
diff --git a/package.json b/package.json
index 2bdfb7b4..8d037498 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "it-tools",
- "version": "2023.12.21-5ed3693",
+ "version": "2024.5.13-a0bc346",
"description": "Collection of handy online tools for developers, with great UX. ",
"keywords": [
"productivity",
@@ -37,11 +37,13 @@
"dependencies": {
"@it-tools/bip39": "^0.0.4",
"@it-tools/oggen": "^1.3.0",
+ "@regexper/render": "^1.0.0",
"@sindresorhus/slugify": "^2.2.1",
"@tiptap/pm": "2.1.6",
"@tiptap/starter-kit": "2.1.6",
"@tiptap/vue-3": "2.0.3",
"@types/figlet": "^1.5.8",
+ "@types/markdown-it": "^13.0.7",
"@vicons/material": "^0.12.0",
"@vicons/tabler": "^0.12.0",
"@vueuse/core": "^10.3.0",
@@ -57,6 +59,7 @@
"crypto-js": "^4.1.1",
"date-fns": "^2.29.3",
"dompurify": "^3.0.6",
+ "email-normalizer": "^1.0.0",
"emojilib": "^3.0.10",
"figlet": "^1.7.0",
"figue": "^1.2.0",
@@ -64,11 +67,13 @@
"highlight.js": "^11.7.0",
"iarna-toml-esm": "^3.0.5",
"ibantools": "^4.3.3",
+ "js-base64": "^3.7.6",
"json5": "^2.2.3",
"jwt-decode": "^3.1.2",
"korean-unpacker": "^1.0.3",
"libphonenumber-js": "^1.10.28",
"lodash": "^4.17.21",
+ "markdown-it": "^14.0.0",
"marked": "^10.0.0",
"mathjs": "^11.9.1",
"mime-types": "^2.1.35",
@@ -81,6 +86,7 @@
"pinia": "^2.0.34",
"plausible-tracker": "^0.3.8",
"qrcode": "^1.5.1",
+ "randexp": "^0.5.3",
"sql-formatter": "^13.0.0",
"ua-parser-js": "^1.0.35",
"ulid": "^2.3.0",
@@ -90,8 +96,10 @@
"vue": "^3.3.4",
"vue-i18n": "^9.9.1",
"vue-router": "^4.1.6",
+ "vue-shadow-dom": "^4.2.0",
"vue-tsc": "^1.8.1",
"xml-formatter": "^3.3.2",
+ "xml-js": "^1.6.11",
"yaml": "^2.2.1"
},
"devDependencies": {
@@ -138,5 +146,6 @@
"vitest": "^0.34.0",
"workbox-window": "^7.0.0",
"zx": "^7.2.1"
- }
+ },
+ "packageManager": "pnpm@8.15.3"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3d013aee..c66685bc 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,6 +11,9 @@ dependencies:
'@it-tools/oggen':
specifier: ^1.3.0
version: 1.3.0
+ '@regexper/render':
+ specifier: ^1.0.0
+ version: 1.0.0
'@sindresorhus/slugify':
specifier: ^2.2.1
version: 2.2.1
@@ -26,6 +29,9 @@ dependencies:
'@types/figlet':
specifier: ^1.5.8
version: 1.5.8
+ '@types/markdown-it':
+ specifier: ^13.0.7
+ version: 13.0.9
'@vicons/material':
specifier: ^0.12.0
version: 0.12.0
@@ -71,6 +77,9 @@ dependencies:
dompurify:
specifier: ^3.0.6
version: 3.0.6
+ email-normalizer:
+ specifier: ^1.0.0
+ version: 1.0.0
emojilib:
specifier: ^3.0.10
version: 3.0.10
@@ -92,6 +101,9 @@ dependencies:
ibantools:
specifier: ^4.3.3
version: 4.3.3
+ js-base64:
+ specifier: ^3.7.6
+ version: 3.7.7
json5:
specifier: ^2.2.3
version: 2.2.3
@@ -107,6 +119,9 @@ dependencies:
lodash:
specifier: ^4.17.21
version: 4.17.21
+ markdown-it:
+ specifier: ^14.0.0
+ version: 14.1.0
marked:
specifier: ^10.0.0
version: 10.0.0
@@ -143,6 +158,9 @@ dependencies:
qrcode:
specifier: ^1.5.1
version: 1.5.1
+ randexp:
+ specifier: ^0.5.3
+ version: 0.5.3
sql-formatter:
specifier: ^13.0.0
version: 13.0.0
@@ -170,12 +188,18 @@ dependencies:
vue-router:
specifier: ^4.1.6
version: 4.1.6(vue@3.3.4)
+ vue-shadow-dom:
+ specifier: ^4.2.0
+ version: 4.2.0
vue-tsc:
specifier: ^1.8.1
version: 1.8.1(typescript@5.2.2)
xml-formatter:
specifier: ^3.3.2
version: 3.3.2
+ xml-js:
+ specifier: ^1.6.11
+ version: 1.6.11
yaml:
specifier: ^2.2.1
version: 2.2.1
@@ -2468,6 +2492,17 @@ packages:
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
dev: false
+ /@regexper/parser@1.0.0:
+ resolution: {integrity: sha512-S8AWIGpCNdl9PNHdbhI6TpXZsPk6FDU/RTZI+6UFF4rVFqDQKjCIbZSgFu7NihoEZKq57wKFPbbT1EzrjVvPHA==}
+ dev: false
+
+ /@regexper/render@1.0.0:
+ resolution: {integrity: sha512-xYm9RUgnhhZotTtf8UZpK1PG2CcTRXQ3JPwfTlYUZsy2J+UcTVc7BaO/MJadpMoVuT8jrIyptH4Y0HLzqhI3hQ==}
+ dependencies:
+ '@regexper/parser': 1.0.0
+ '@svgdotjs/svg.js': 3.2.4
+ dev: false
+
/@remirror/core-constants@2.0.1:
resolution: {integrity: sha512-ZR4aihtnnT9lMbhh5DEbsriJRlukRXmLZe7HmM+6ufJNNUDoazc75UX26xbgQlNUqgAqMcUdGFAnPc1JwgAdLQ==}
dependencies:
@@ -2617,6 +2652,10 @@ packages:
string.prototype.matchall: 4.0.10
dev: true
+ /@svgdotjs/svg.js@3.2.4:
+ resolution: {integrity: sha512-BjJ/7vWNowlX3Z8O4ywT58DqbNRyYlkk6Yz/D13aB7hGmfQTvGX4Tkgtm/ApYlu9M7lCQi15xUEidqMUmdMYwg==}
+ dev: false
+
/@tiptap/core@2.1.12(@tiptap/pm@2.1.6):
resolution: {integrity: sha512-ZGc3xrBJA9KY8kln5AYTj8y+GDrKxi7u95xIl2eccrqTY5CQeRu6HRNM1yT4mAjuSaG9jmazyjGRlQuhyxCKxQ==}
peerDependencies:
@@ -2946,7 +2985,6 @@ packages:
/@types/linkify-it@3.0.2:
resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==}
- dev: true
/@types/lodash-es@4.17.10:
resolution: {integrity: sha512-YJP+w/2khSBwbUSFdGsSqmDvmnN3cCKoPOL7Zjle6s30ZtemkkqhjVfFqGwPN7ASil5VyjE2GtyU/yqYY6mC0A==}
@@ -2968,6 +3006,13 @@ packages:
'@types/mdurl': 1.0.2
dev: true
+ /@types/markdown-it@13.0.9:
+ resolution: {integrity: sha512-1XPwR0+MgXLWfTn9gCsZ55AHOKW1WN+P9vr0PaQh5aerR9LLQXUbjfEAFhjmEmyoYFWAyuN2Mqkn40MZ4ukjBw==}
+ dependencies:
+ '@types/linkify-it': 3.0.2
+ '@types/mdurl': 1.0.2
+ dev: false
+
/@types/mdast@3.0.11:
resolution: {integrity: sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==}
dependencies:
@@ -2976,7 +3021,6 @@ packages:
/@types/mdurl@1.0.2:
resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==}
- dev: true
/@types/mime-types@2.1.1:
resolution: {integrity: sha512-vXOTGVSLR2jMw440moWTC7H19iUyLtP3Z1YTj7cSsubOICinjMxFeb/V57v9QdyyPGbbWolUFSSmSiRSn94tFw==}
@@ -4945,6 +4989,11 @@ packages:
tslib: 2.5.0
dev: false
+ /drange@1.1.1:
+ resolution: {integrity: sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==}
+ engines: {node: '>=4'}
+ dev: false
+
/duplexer@0.1.2:
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
dev: true
@@ -4973,6 +5022,12 @@ packages:
/electron-to-chromium@1.4.572:
resolution: {integrity: sha512-RlFobl4D3ieetbnR+2EpxdzFl9h0RAJkPK3pfiwMug2nhBin2ZCsGIAJWdpNniLz43sgXam/CgipOmvTA+rUiA==}
+ /email-normalizer@1.0.0:
+ resolution: {integrity: sha512-wZYuuMtL4kUOmg/TPtCrf9hAZjbFq+FcjWA85Z5nr2lGllRnWJPxCJw3gy4Cx+adMoyVw4VJfGGvt/OHgIW+qg==}
+ dependencies:
+ typescript: 5.5.4
+ dev: false
+
/emitter-component@1.1.1:
resolution: {integrity: sha512-G+mpdiAySMuB7kesVRLuyvYRqDmshB7ReKEVuyBPkzQlmiDiLrt7hHHIy4Aff552bgknVN7B2/d3lzhGO5dvpQ==}
dev: false
@@ -5004,7 +5059,6 @@ packages:
/entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
- dev: true
/errno@0.1.8:
resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
@@ -6475,6 +6529,10 @@ packages:
hasBin: true
dev: true
+ /js-base64@3.7.7:
+ resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==}
+ dev: false
+
/js-beautify@1.14.6:
resolution: {integrity: sha512-GfofQY5zDp+cuHc+gsEXKPpNw2KbPddreEo35O6jT6i0RVK6LhsoYBhq5TvK4/n74wnA0QbK8gGd+jUZwTMKJw==}
engines: {node: '>=10'}
@@ -6676,6 +6734,12 @@ packages:
dependencies:
uc.micro: 1.0.6
+ /linkify-it@5.0.0:
+ resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
+ dependencies:
+ uc.micro: 2.1.0
+ dev: false
+
/local-pkg@0.4.3:
resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
engines: {node: '>=14'}
@@ -6813,6 +6877,18 @@ packages:
mdurl: 1.0.1
uc.micro: 1.0.6
+ /markdown-it@14.1.0:
+ resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
+ hasBin: true
+ dependencies:
+ argparse: 2.0.1
+ entities: 4.5.0
+ linkify-it: 5.0.0
+ mdurl: 2.0.0
+ punycode.js: 2.3.1
+ uc.micro: 2.1.0
+ dev: false
+
/marked@10.0.0:
resolution: {integrity: sha512-YiGcYcWj50YrwBgNzFoYhQ1hT6GmQbFG8SksnYJX1z4BXTHSOrz1GB5/Jm2yQvMg4nN1FHP4M6r03R10KrVUiA==}
engines: {node: '>= 18'}
@@ -6861,6 +6937,10 @@ packages:
/mdurl@1.0.1:
resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
+ /mdurl@2.0.0:
+ resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
+ dev: false
+
/merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
dev: true
@@ -7670,6 +7750,11 @@ packages:
resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==}
dev: true
+ /punycode.js@2.3.1:
+ resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
+ engines: {node: '>=6'}
+ dev: false
+
/punycode@2.3.0:
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
engines: {node: '>=6'}
@@ -7709,6 +7794,14 @@ packages:
ret: 0.1.15
dev: false
+ /randexp@0.5.3:
+ resolution: {integrity: sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==}
+ engines: {node: '>=4'}
+ dependencies:
+ drange: 1.1.1
+ ret: 0.2.2
+ dev: false
+
/randombytes@2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
dependencies:
@@ -7879,6 +7972,11 @@ packages:
engines: {node: '>=0.12'}
dev: false
+ /ret@0.2.2:
+ resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==}
+ engines: {node: '>=4'}
+ dev: false
+
/reusify@1.0.4:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
@@ -7959,8 +8057,6 @@ packages:
/sax@1.2.4:
resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==}
requiresBuild: true
- dev: true
- optional: true
/saxes@6.0.0:
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
@@ -8603,6 +8699,12 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
+ /typescript@5.5.4:
+ resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+ dev: false
+
/ua-parser-js@1.0.35:
resolution: {integrity: sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA==}
dev: false
@@ -8610,6 +8712,10 @@ packages:
/uc.micro@1.0.6:
resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==}
+ /uc.micro@2.1.0:
+ resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==}
+ dev: false
+
/ufo@1.1.2:
resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==}
@@ -9143,8 +9249,8 @@ packages:
vue: 3.3.4
dev: false
- /vue-demi@0.14.5(vue@3.3.4):
- resolution: {integrity: sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==}
+ /vue-demi@0.14.10(vue@3.3.4):
+ resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
engines: {node: '>=12'}
hasBin: true
requiresBuild: true
@@ -9211,6 +9317,10 @@ packages:
vue: 3.3.4
dev: false
+ /vue-shadow-dom@4.2.0:
+ resolution: {integrity: sha512-lguI064rT2HT/dxqSmXtz860KOvCq+W3nU1jMqroTmX3K1H46q22BMR4emh/Ld3ozy35XJKOaNGcr6mkJ/t/yg==}
+ dev: false
+
/vue-template-compiler@2.7.14:
resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==}
dependencies:
@@ -9550,6 +9660,13 @@ packages:
xml-parser-xo: 4.0.5
dev: false
+ /xml-js@1.6.11:
+ resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==}
+ hasBin: true
+ dependencies:
+ sax: 1.2.4
+ dev: false
+
/xml-name-validator@4.0.0:
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
engines: {node: '>=12'}
diff --git a/src/components/FormatTransformer.vue b/src/components/FormatTransformer.vue
index 677fc25a..bcfcdb58 100644
--- a/src/components/FormatTransformer.vue
+++ b/src/components/FormatTransformer.vue
@@ -48,7 +48,7 @@ const output = computed(() => transformer.value(input.value));
monospace
/>
-
+
{{ outputLabel }}
diff --git a/src/components/TextareaCopyable.vue b/src/components/TextareaCopyable.vue
index 8b0aae61..9585177d 100644
--- a/src/components/TextareaCopyable.vue
+++ b/src/components/TextareaCopyable.vue
@@ -7,6 +7,7 @@ import sqlHljs from 'highlight.js/lib/languages/sql';
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 markdownHljs from 'highlight.js/lib/languages/markdown';
import { useCopy } from '@/composable/copy';
const props = withDefaults(
@@ -30,6 +31,7 @@ hljs.registerLanguage('html', xmlHljs);
hljs.registerLanguage('xml', xmlHljs);
hljs.registerLanguage('yaml', yamlHljs);
hljs.registerLanguage('toml', iniHljs);
+hljs.registerLanguage('markdown', markdownHljs);
const { value, language, followHeightOf, copyPlacement, copyMessage } = toRefs(props);
const { height } = followHeightOf.value ? useElementSize(followHeightOf) : { height: ref(null) };
diff --git a/src/composable/debouncedref.ts b/src/composable/debouncedref.ts
new file mode 100644
index 00000000..09dd10e9
--- /dev/null
+++ b/src/composable/debouncedref.ts
@@ -0,0 +1,21 @@
+import _ from 'lodash';
+
+function useDebouncedRef
(initialValue: T, delay: number, immediate: boolean = false) {
+ const state = ref(initialValue);
+ const debouncedRef = customRef((track, trigger) => ({
+ get() {
+ track();
+ return state.value;
+ },
+ set: _.debounce(
+ (value) => {
+ state.value = value;
+ trigger();
+ },
+ delay,
+ { leading: immediate },
+ ),
+ }));
+ return debouncedRef;
+}
+export default useDebouncedRef;
diff --git a/src/composable/downloadBase64.ts b/src/composable/downloadBase64.ts
index 37b0428d..3bc20226 100644
--- a/src/composable/downloadBase64.ts
+++ b/src/composable/downloadBase64.ts
@@ -1,8 +1,13 @@
-import { extension as getExtensionFromMime } from 'mime-types';
+import { extension as getExtensionFromMimeType, extension as getMimeTypeFromExtension } from 'mime-types';
import type { Ref } from 'vue';
import _ from 'lodash';
-export { getMimeTypeFromBase64, useDownloadFileFromBase64 };
+export {
+ getMimeTypeFromBase64,
+ getMimeTypeFromExtension, getExtensionFromMimeType,
+ useDownloadFileFromBase64, useDownloadFileFromBase64Refs,
+ previewImageFromBase64,
+};
const commonMimeTypesSignatures = {
'JVBERi0': 'application/pdf',
@@ -36,30 +41,78 @@ function getFileExtensionFromMimeType({
defaultExtension?: string
}) {
if (mimeType) {
- return getExtensionFromMime(mimeType) ?? defaultExtension;
+ return getExtensionFromMimeType(mimeType) ?? defaultExtension;
}
return defaultExtension;
}
-function useDownloadFileFromBase64({ source, filename }: { source: Ref; filename?: string }) {
+function downloadFromBase64({ sourceValue, filename, extension, fileMimeType }:
+{ sourceValue: string; filename?: string; extension?: string; fileMimeType?: string }) {
+ if (sourceValue === '') {
+ throw new Error('Base64 string is empty');
+ }
+
+ const defaultExtension = extension ?? 'txt';
+ const { mimeType } = getMimeTypeFromBase64({ base64String: sourceValue });
+ let base64String = sourceValue;
+ if (!mimeType) {
+ const targetMimeType = fileMimeType ?? getMimeTypeFromExtension(defaultExtension);
+ base64String = `data:${targetMimeType};base64,${sourceValue}`;
+ }
+
+ const cleanExtension = extension ?? getFileExtensionFromMimeType(
+ { mimeType, defaultExtension });
+ let cleanFileName = filename ?? `file.${cleanExtension}`;
+ if (extension && !cleanFileName.endsWith(`.${extension}`)) {
+ cleanFileName = `${cleanFileName}.${cleanExtension}`;
+ }
+
+ const a = document.createElement('a');
+ a.href = base64String;
+ a.download = cleanFileName;
+ a.click();
+}
+
+function useDownloadFileFromBase64(
+ { source, filename, extension, fileMimeType }:
+ { source: Ref; filename?: string; extension?: string; fileMimeType?: string }) {
return {
download() {
- if (source.value === '') {
- throw new Error('Base64 string is empty');
- }
-
- const { mimeType } = getMimeTypeFromBase64({ base64String: source.value });
- const base64String = mimeType
- ? source.value
- : `data:text/plain;base64,${source.value}`;
-
- const cleanFileName = filename ?? `file.${getFileExtensionFromMimeType({ mimeType })}`;
-
- const a = document.createElement('a');
- a.href = base64String;
- a.download = cleanFileName;
- a.click();
+ downloadFromBase64({ sourceValue: source.value, filename, extension, fileMimeType });
},
};
}
+
+function useDownloadFileFromBase64Refs(
+ { source, filename, extension }:
+ { source: Ref; filename?: Ref; extension?: Ref }) {
+ return {
+ download() {
+ downloadFromBase64({ sourceValue: source.value, filename: filename?.value, extension: extension?.value });
+ },
+ };
+}
+
+function previewImageFromBase64(base64String: string): HTMLImageElement {
+ if (base64String === '') {
+ throw new Error('Base64 string is empty');
+ }
+
+ const img = document.createElement('img');
+ img.src = base64String;
+
+ const container = document.createElement('div');
+ container.appendChild(img);
+
+ const previewContainer = document.getElementById('previewContainer');
+ if (previewContainer) {
+ previewContainer.innerHTML = '';
+ previewContainer.appendChild(container);
+ }
+ else {
+ throw new Error('Preview container element not found');
+ }
+
+ return img;
+}
diff --git a/src/composable/queryParams.ts b/src/composable/queryParams.ts
index 9699abbc..7cc8cc0d 100644
--- a/src/composable/queryParams.ts
+++ b/src/composable/queryParams.ts
@@ -1,7 +1,8 @@
import { useRouteQuery } from '@vueuse/router';
import { computed } from 'vue';
+import { useStorage } from '@vueuse/core';
-export { useQueryParam };
+export { useQueryParam, useQueryParamOrStorage };
const transformers = {
number: {
@@ -16,6 +17,12 @@ const transformers = {
fromQuery: (value: string) => value.toLowerCase() === 'true',
toQuery: (value: boolean) => (value ? 'true' : 'false'),
},
+ object: {
+ fromQuery: (value: string) => {
+ return JSON.parse(value);
+ },
+ toQuery: (value: object) => JSON.stringify(value),
+ },
};
function useQueryParam({ name, defaultValue }: { name: string; defaultValue: T }) {
@@ -33,3 +40,27 @@ function useQueryParam({ name, defaultValue }: { name: string; defaultValue:
},
});
}
+
+function useQueryParamOrStorage({ name, storageName, defaultValue }: { name: string; storageName: string; defaultValue: T }) {
+ const type = typeof defaultValue;
+ const transformer = transformers[type as keyof typeof transformers] ?? transformers.string;
+
+ const storageRef = useStorage(storageName, defaultValue);
+ const proxyDefaultValue = transformer.toQuery(defaultValue as never);
+ const proxy = useRouteQuery(name, proxyDefaultValue);
+
+ const r = ref(defaultValue);
+
+ watch(r,
+ (value) => {
+ proxy.value = transformer.toQuery(value as never);
+ storageRef.value = value as never;
+ },
+ { deep: true });
+
+ r.value = (proxy.value && proxy.value !== proxyDefaultValue
+ ? transformer.fromQuery(proxy.value) as unknown as T
+ : storageRef.value as T) as never;
+
+ return r;
+}
diff --git a/src/composable/validation.ts b/src/composable/validation.ts
index 472ca4b2..33a6a7b2 100644
--- a/src/composable/validation.ts
+++ b/src/composable/validation.ts
@@ -3,9 +3,11 @@ import _ from 'lodash';
import { type Ref, reactive, watch } from 'vue';
type ValidatorReturnType = unknown;
+type GetErrorMessageReturnType = string;
export interface UseValidationRule {
validator: (value: T) => ValidatorReturnType
+ getErrorMessage?: (value: T) => GetErrorMessageReturnType
message: string
}
@@ -24,6 +26,15 @@ export function isFalsyOrHasThrown(cb: () => ValidatorReturnType): boolean {
}
}
+export function getErrorMessageOrThrown(cb: () => GetErrorMessageReturnType): string {
+ try {
+ return cb() || '';
+ }
+ catch (e: any) {
+ return e.toString();
+ }
+}
+
export interface ValidationAttrs {
feedback: string
validationStatus: string | undefined
@@ -61,7 +72,13 @@ export function useValidation({
for (const rule of get(rules)) {
if (isFalsyOrHasThrown(() => rule.validator(source.value))) {
- state.message = rule.message;
+ if (rule.getErrorMessage) {
+ const getErrorMessage = rule.getErrorMessage;
+ state.message = rule.message.replace('{0}', getErrorMessageOrThrown(() => getErrorMessage(source.value)));
+ }
+ else {
+ state.message = rule.message;
+ }
state.status = 'error';
}
}
diff --git a/src/main.ts b/src/main.ts
index 36ba3b7f..19d28bf2 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -3,6 +3,7 @@ import { createPinia } from 'pinia';
import { createHead } from '@vueuse/head';
import { registerSW } from 'virtual:pwa-register';
+import shadow from 'vue-shadow-dom';
import { plausible } from './plugins/plausible.plugin';
import 'virtual:uno.css';
@@ -23,5 +24,6 @@ app.use(i18nPlugin);
app.use(router);
app.use(naive);
app.use(plausible);
+app.use(shadow);
app.mount('#app');
diff --git a/src/modules/i18n/components/locale-selector.vue b/src/modules/i18n/components/locale-selector.vue
index 3f0c461c..45732bf9 100644
--- a/src/modules/i18n/components/locale-selector.vue
+++ b/src/modules/i18n/components/locale-selector.vue
@@ -3,6 +3,7 @@ const { availableLocales, locale } = useI18n();
const localesLong: Record = {
en: 'English',
+ de: 'Deutsch',
es: 'Español',
fr: 'Français',
pt: 'PortuguĂȘs',
diff --git a/src/tools/base64-file-converter/base64-file-converter.vue b/src/tools/base64-file-converter/base64-file-converter.vue
index 377625bd..a489f9a1 100644
--- a/src/tools/base64-file-converter/base64-file-converter.vue
+++ b/src/tools/base64-file-converter/base64-file-converter.vue
@@ -2,12 +2,19 @@
import { useBase64 } from '@vueuse/core';
import type { Ref } from 'vue';
import { useCopy } from '@/composable/copy';
-import { useDownloadFileFromBase64 } from '@/composable/downloadBase64';
+import { getExtensionFromMimeType, getMimeTypeFromBase64, previewImageFromBase64, useDownloadFileFromBase64Refs } from '@/composable/downloadBase64';
import { useValidation } from '@/composable/validation';
import { isValidBase64 } from '@/utils/base64';
+const fileName = ref('file');
+const fileExtension = ref('');
const base64Input = ref('');
-const { download } = useDownloadFileFromBase64({ source: base64Input });
+const { download } = useDownloadFileFromBase64Refs(
+ {
+ source: base64Input,
+ filename: fileName,
+ extension: fileExtension,
+ });
const base64InputValidation = useValidation({
source: base64Input,
rules: [
@@ -18,6 +25,35 @@ const base64InputValidation = useValidation({
],
});
+watch(
+ base64Input,
+ (newValue, _) => {
+ const { mimeType } = getMimeTypeFromBase64({ base64String: newValue });
+ if (mimeType) {
+ fileExtension.value = getExtensionFromMimeType(mimeType) || fileExtension.value;
+ }
+ },
+);
+
+function previewImage() {
+ if (!base64InputValidation.isValid) {
+ return;
+ }
+ try {
+ const image = previewImageFromBase64(base64Input.value);
+ image.style.maxWidth = '100%';
+ image.style.maxHeight = '400px';
+ const previewContainer = document.getElementById('previewContainer');
+ if (previewContainer) {
+ previewContainer.innerHTML = '';
+ previewContainer.appendChild(image);
+ }
+ }
+ catch (_) {
+ //
+ }
+}
+
function downloadFile() {
if (!base64InputValidation.isValid) {
return;
@@ -44,6 +80,24 @@ async function onUpload(file: File) {
+
+
+
+
+
+
+
+
-
+
+
+
+
+ Preview image
+
Download file
diff --git a/src/tools/bcrypt/bcrypt.vue b/src/tools/bcrypt/bcrypt.vue
index c28c20bf..d4881299 100644
--- a/src/tools/bcrypt/bcrypt.vue
+++ b/src/tools/bcrypt/bcrypt.vue
@@ -28,7 +28,7 @@ const compareMatch = computed(() => compareSync(compareString.value, compareHash
mb-2
/>
-
+
diff --git a/src/tools/email-normalizer/email-normalizer.vue b/src/tools/email-normalizer/email-normalizer.vue
new file mode 100644
index 00000000..eae97c4e
--- /dev/null
+++ b/src/tools/email-normalizer/email-normalizer.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
+ Raw emails to normalize:
+
+
+
+
+ Normalized emails:
+
+
+
+
+ Clear emails
+
+
+ Copy normalized emails
+
+
+
+
diff --git a/src/tools/email-normalizer/index.ts b/src/tools/email-normalizer/index.ts
new file mode 100644
index 00000000..299a30f7
--- /dev/null
+++ b/src/tools/email-normalizer/index.ts
@@ -0,0 +1,12 @@
+import { Mail } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+ name: 'Email normalizer',
+ path: '/email-normalizer',
+ description: 'Normalize email addresses to a standard format for easier comparison. Useful for deduplication and data cleaning.',
+ keywords: ['email', 'normalizer'],
+ component: () => import('./email-normalizer.vue'),
+ icon: Mail,
+ createdAt: new Date('2024-08-15'),
+});
diff --git a/src/tools/emoji-picker/emoji-picker.vue b/src/tools/emoji-picker/emoji-picker.vue
index 750695f5..a12b10c2 100644
--- a/src/tools/emoji-picker/emoji-picker.vue
+++ b/src/tools/emoji-picker/emoji-picker.vue
@@ -4,6 +4,7 @@ import emojiKeywords from 'emojilib';
import _ from 'lodash';
import type { EmojiInfo } from './emoji.types';
import { useFuzzySearch } from '@/composable/fuzzySearch';
+import useDebouncedRef from '@/composable/debouncedref';
const escapeUnicode = ({ emoji }: { emoji: string }) => emoji.split('').map(unit => `\\u${unit.charCodeAt(0).toString(16).padStart(4, '0')}`).join('');
const getEmojiCodePoints = ({ emoji }: { emoji: string }) => emoji.codePointAt(0) ? `0x${emoji.codePointAt(0)?.toString(16)}` : undefined;
@@ -23,7 +24,7 @@ const emojisGroups: { emojiInfos: EmojiInfo[]; group: string }[] = _
.map((emojiInfos, group) => ({ group, emojiInfos }))
.value();
-const searchQuery = ref('');
+const searchQuery = useDebouncedRef('', 500);
const { searchResult } = useFuzzySearch({
search: searchQuery,
diff --git a/src/tools/index.ts b/src/tools/index.ts
index aa861c93..388cfaf4 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -1,11 +1,17 @@
import { tool as base64FileConverter } from './base64-file-converter';
import { tool as base64StringConverter } from './base64-string-converter';
import { tool as basicAuthGenerator } from './basic-auth-generator';
+import { tool as emailNormalizer } from './email-normalizer';
import { tool as asciiTextDrawer } from './ascii-text-drawer';
import { tool as textToUnicode } from './text-to-unicode';
import { tool as safelinkDecoder } from './safelink-decoder';
+import { tool as xmlToJson } from './xml-to-json';
+import { tool as jsonToXml } from './json-to-xml';
+import { tool as regexTester } from './regex-tester';
+import { tool as regexMemo } from './regex-memo';
+import { tool as markdownToHtml } from './markdown-to-html';
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
import { tool as numeronymGenerator } from './numeronym-generator';
import { tool as macAddressGenerator } from './mac-address-generator';
@@ -107,6 +113,9 @@ export const toolsByCategory: ToolCategory[] = [
listConverter,
tomlToJson,
tomlToYaml,
+ xmlToJson,
+ jsonToXml,
+ markdownToHtml,
],
},
{
@@ -148,6 +157,9 @@ export const toolsByCategory: ToolCategory[] = [
dockerRunToDockerComposeConverter,
xmlFormatter,
yamlViewer,
+ emailNormalizer,
+ regexTester,
+ regexMemo,
],
},
{
diff --git a/src/tools/integer-base-converter/integer-base-converter.model.test.ts b/src/tools/integer-base-converter/integer-base-converter.model.test.ts
index d0387b64..c7d7db79 100644
--- a/src/tools/integer-base-converter/integer-base-converter.model.test.ts
+++ b/src/tools/integer-base-converter/integer-base-converter.model.test.ts
@@ -11,6 +11,9 @@ describe('integer-base-converter', () => {
expect(convertBase({ value: '10100101', fromBase: 2, toBase: 16 })).toEqual('a5');
expect(convertBase({ value: '192654', fromBase: 10, toBase: 8 })).toEqual('570216');
expect(convertBase({ value: 'zz', fromBase: 64, toBase: 10 })).toEqual('2275');
+ expect(convertBase({ value: '42540766411283223938465490632011909384', fromBase: 10, toBase: 10 })).toEqual('42540766411283223938465490632011909384');
+ expect(convertBase({ value: '42540766411283223938465490632011909384', fromBase: 10, toBase: 16 })).toEqual('20010db8000085a300000000ac1f8908');
+ expect(convertBase({ value: '20010db8000085a300000000ac1f8908', fromBase: 16, toBase: 10 })).toEqual('42540766411283223938465490632011909384');
});
});
});
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 b4470e57..da0fe77f 100644
--- a/src/tools/integer-base-converter/integer-base-converter.model.ts
+++ b/src/tools/integer-base-converter/integer-base-converter.model.ts
@@ -5,16 +5,16 @@ export function convertBase({ value, fromBase, toBase }: { value: string; fromBa
let decValue = value
.split('')
.reverse()
- .reduce((carry: number, digit: string, index: number) => {
+ .reduce((carry: bigint, digit: string, index: number) => {
if (!fromRange.includes(digit)) {
throw new Error(`Invalid digit "${digit}" for base ${fromBase}.`);
}
- return (carry += fromRange.indexOf(digit) * fromBase ** index);
- }, 0);
+ return (carry += BigInt(fromRange.indexOf(digit)) * BigInt(fromBase) ** BigInt(index));
+ }, 0n);
let newValue = '';
while (decValue > 0) {
- newValue = toRange[decValue % toBase] + newValue;
- decValue = (decValue - (decValue % toBase)) / toBase;
+ newValue = toRange[Number(decValue % BigInt(toBase))] + newValue;
+ decValue = (decValue - (decValue % BigInt(toBase))) / BigInt(toBase);
}
return newValue || '0';
}
diff --git a/src/tools/json-to-xml/index.ts b/src/tools/json-to-xml/index.ts
new file mode 100644
index 00000000..c35ace2b
--- /dev/null
+++ b/src/tools/json-to-xml/index.ts
@@ -0,0 +1,12 @@
+import { Braces } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+ name: 'JSON to XML',
+ path: '/json-to-xml',
+ description: 'Convert JSON to XML',
+ keywords: ['json', 'xml'],
+ component: () => import('./json-to-xml.vue'),
+ icon: Braces,
+ createdAt: new Date('2024-08-09'),
+});
diff --git a/src/tools/json-to-xml/json-to-xml.vue b/src/tools/json-to-xml/json-to-xml.vue
new file mode 100644
index 00000000..96a7cf16
--- /dev/null
+++ b/src/tools/json-to-xml/json-to-xml.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
diff --git a/src/tools/jwt-parser/jwt-parser.vue b/src/tools/jwt-parser/jwt-parser.vue
index 6b30fc0c..a26064d7 100644
--- a/src/tools/jwt-parser/jwt-parser.vue
+++ b/src/tools/jwt-parser/jwt-parser.vue
@@ -39,7 +39,7 @@ const validation = useValidation({
{{ section.title }}
-
+
{{ claim }}
@@ -47,7 +47,7 @@ const validation = useValidation({
({{ claimDescription }})
-
+
{{ value }}
({{ friendlyValue }})
diff --git a/src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue b/src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue
index 9085725f..ccd8b519 100644
--- a/src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue
+++ b/src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue
@@ -2,6 +2,7 @@
import { generateLoremIpsum } from './lorem-ipsum-generator.service';
import { useCopy } from '@/composable/copy';
import { randIntFromInterval } from '@/utils/random';
+import { computedRefreshable } from '@/composable/computedRefreshable';
const paragraphs = ref(1);
const sentences = ref([3, 8]);
@@ -9,7 +10,7 @@ const words = ref([8, 15]);
const startWithLoremIpsum = ref(true);
const asHTML = ref(false);
-const loremIpsumText = computed(() =>
+const [loremIpsumText, refreshLoremIpsum] = computedRefreshable(() =>
generateLoremIpsum({
paragraphCount: paragraphs.value,
asHTML: asHTML.value,
@@ -18,6 +19,7 @@ const loremIpsumText = computed(() =>
startWithLoremIpsum: startWithLoremIpsum.value,
}),
);
+
const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to the clipboard' });
@@ -41,10 +43,13 @@ const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to
-
+
Copy
+
+ Refresh
+
diff --git a/src/tools/markdown-to-html/index.ts b/src/tools/markdown-to-html/index.ts
new file mode 100644
index 00000000..73a6cfb3
--- /dev/null
+++ b/src/tools/markdown-to-html/index.ts
@@ -0,0 +1,12 @@
+import { Markdown } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+ name: 'Markdown to HTML',
+ path: '/markdown-to-html',
+ description: 'Convert Markdown to Html and allow to print (as PDF)',
+ keywords: ['markdown', 'html', 'converter', 'pdf'],
+ component: () => import('./markdown-to-html.vue'),
+ icon: Markdown,
+ createdAt: new Date('2024-08-25'),
+});
diff --git a/src/tools/markdown-to-html/markdown-to-html.vue b/src/tools/markdown-to-html/markdown-to-html.vue
new file mode 100644
index 00000000..c84d44ec
--- /dev/null
+++ b/src/tools/markdown-to-html/markdown-to-html.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Print as PDF
+
+
+
+
diff --git a/src/tools/regex-memo/index.ts b/src/tools/regex-memo/index.ts
new file mode 100644
index 00000000..f1f56489
--- /dev/null
+++ b/src/tools/regex-memo/index.ts
@@ -0,0 +1,12 @@
+import { BrandJavascript } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+ name: 'Regex cheatsheet',
+ path: '/regex-memo',
+ description: 'Javascript Regex/Regular Expression cheatsheet',
+ keywords: ['regex', 'regular', 'expression', 'javascript', 'memo', 'cheatsheet'],
+ component: () => import('./regex-memo.vue'),
+ icon: BrandJavascript,
+ createdAt: new Date('2024-09-20'),
+});
diff --git a/src/tools/regex-memo/regex-memo.content.md b/src/tools/regex-memo/regex-memo.content.md
new file mode 100644
index 00000000..0f779401
--- /dev/null
+++ b/src/tools/regex-memo/regex-memo.content.md
@@ -0,0 +1,121 @@
+### Normal characters
+
+Expression | Description
+:--|:--
+`.` or `[^\n\r]` | any character *excluding* a newline or carriage return
+`[A-Za-z]` | alphabet
+`[a-z]` | lowercase alphabet
+`[A-Z]` | uppercase alphabet
+`\d` or `[0-9]` | digit
+`\D` or `[^0-9]` | non-digit
+`_` | underscore
+`\w` or `[A-Za-z0-9_]` | alphabet, digit or underscore
+`\W` or `[^A-Za-z0-9_]` | inverse of `\w`
+`\S` | inverse of `\s`
+
+### Whitespace characters
+
+Expression | Description
+:--|:--
+` ` | space
+`\t` | tab
+`\n` | newline
+`\r` | carriage return
+`\s` | space, tab, newline or carriage return
+
+### Character set
+
+Expression | Description
+:--|:--
+`[xyz]` | either `x`, `y` or `z`
+`[^xyz]` | neither `x`, `y` nor `z`
+`[1-3]` | either `1`, `2` or `3`
+`[^1-3]` | neither `1`, `2` nor `3`
+
+- Think of a character set as an `OR` operation on the single characters that are enclosed between the square brackets.
+- Use `^` after the opening `[` to ânegateâ the character set.
+- Within a character set, `.` means a literal period.
+
+### Characters that require escaping
+
+#### Outside a character set
+
+Expression | Description
+:--|:--
+`\.` | period
+`\^` | caret
+`\$` | dollar sign
+`\|` | pipe
+`\\` | back slash
+`\/` | forward slash
+`\(` | opening bracket
+`\)` | closing bracket
+`\[` | opening square bracket
+`\]` | closing square bracket
+`\{` | opening curly bracket
+`\}` | closing curly bracket
+
+#### Inside a character set
+
+Expression | Description
+:--|:--
+`\\` | back slash
+`\]` | closing square bracket
+
+- A `^` must be escaped only if it occurs immediately after the opening `[` of the character set.
+- A `-` must be escaped only if it occurs between two alphabets or two digits.
+
+### Quantifiers
+
+Expression | Description
+:--|:--
+`{2}` | exactly 2
+`{2,}` | at least 2
+`{2,7}` | at least 2 but no more than 7
+`*` | 0 or more
+`+` | 1 or more
+`?` | exactly 0 or 1
+
+- The quantifier goes *after* the expression to be quantified.
+
+### Boundaries
+
+Expression | Description
+:--|:--
+`^` | start of string
+`$` | end of string
+`\b` | word boundary
+
+- How word boundary matching works:
+ - At the beginning of the string if the first character is `\w`.
+ - Between two adjacent characters within the string, if the first character is `\w` and the second character is `\W`.
+ - At the end of the string if the last character is `\w`.
+
+### Matching
+
+Expression | Description
+:--|:--
+`foo\|bar` | match either `foo` or `bar`
+`foo(?=bar)` | match `foo` if itâs before `bar`
+`foo(?!bar)` | match `foo` if itâs *not* before `bar`
+`(?<=bar)foo` | match `foo` if itâs after `bar`
+`(?
+import { useThemeVars } from 'naive-ui';
+import Memo from './regex-memo.content.md';
+
+const themeVars = useThemeVars();
+
+
+
+
+
+
+
+
+
diff --git a/src/tools/regex-tester/index.ts b/src/tools/regex-tester/index.ts
new file mode 100644
index 00000000..9cc542f0
--- /dev/null
+++ b/src/tools/regex-tester/index.ts
@@ -0,0 +1,12 @@
+import { Language } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+ name: 'Regex Tester',
+ path: '/regex-tester',
+ description: 'Regex Tester',
+ keywords: ['regex', 'tester', 'sample', 'expression'],
+ component: () => import('./regex-tester.vue'),
+ icon: Language,
+ createdAt: new Date('2024-09-20'),
+});
diff --git a/src/tools/regex-tester/regex-tester.service.test.ts b/src/tools/regex-tester/regex-tester.service.test.ts
new file mode 100644
index 00000000..bd4efbbc
--- /dev/null
+++ b/src/tools/regex-tester/regex-tester.service.test.ts
@@ -0,0 +1,106 @@
+import { describe, expect, it } from 'vitest';
+import { matchRegex } from './regex-tester.service';
+
+const regexesData = [
+ {
+ regex: '',
+ text: '',
+ flags: '',
+ result: [],
+ },
+ {
+ regex: '.*',
+ text: '',
+ flags: '',
+ result: [],
+ },
+ {
+ regex: '',
+ text: 'aaa',
+ flags: '',
+ result: [],
+ },
+ {
+ regex: 'a',
+ text: 'baaa',
+ flags: '',
+ result: [
+ {
+ captures: [],
+ groups: [],
+ index: 1,
+ value: 'a',
+ },
+ ],
+ },
+ {
+ regex: '(.)(?
r)',
+ text: 'azertyr',
+ flags: 'g',
+ result: [
+ {
+ captures: [
+ {
+ end: 3,
+ name: '1',
+ start: 2,
+ value: 'e',
+ },
+ {
+ end: 4,
+ name: '2',
+ start: 3,
+ value: 'r',
+ },
+ ],
+ groups: [
+ {
+ end: 4,
+ name: 'g',
+ start: 3,
+ value: 'r',
+ },
+ ],
+ index: 2,
+ value: 'er',
+ },
+ {
+ captures: [
+ {
+ end: 6,
+ name: '1',
+ start: 5,
+ value: 'y',
+ },
+ {
+ end: 7,
+ name: '2',
+ start: 6,
+ value: 'r',
+ },
+ ],
+ groups: [
+ {
+ end: 7,
+ name: 'g',
+ start: 6,
+ value: 'r',
+ },
+ ],
+ index: 5,
+ value: 'yr',
+ },
+ ],
+ },
+];
+
+describe('regex-tester', () => {
+ for (const reg of regexesData) {
+ const { regex, text, flags, result: expected_result } = reg;
+ it(`Should matchRegex("${regex}","${text}","${flags}") return correct result`, async () => {
+ const result = matchRegex(regex, text, `${flags}d`);
+
+ expect(result).to.deep.equal(expected_result);
+ });
+ }
+});
diff --git a/src/tools/regex-tester/regex-tester.service.ts b/src/tools/regex-tester/regex-tester.service.ts
new file mode 100644
index 00000000..ec8682c5
--- /dev/null
+++ b/src/tools/regex-tester/regex-tester.service.ts
@@ -0,0 +1,61 @@
+interface RegExpGroupIndices {
+ [name: string]: [number, number]
+}
+interface RegExpIndices extends Array<[number, number]> {
+ groups: RegExpGroupIndices
+}
+interface RegExpExecArrayWithIndices extends RegExpExecArray {
+ indices: RegExpIndices
+}
+interface GroupCapture {
+ name: string
+ value: string
+ start: number
+ end: number
+};
+
+export function matchRegex(regex: string, text: string, flags: string) {
+ // if (regex === '' || text === '') {
+ // return [];
+ // }
+
+ let lastIndex = -1;
+ const re = new RegExp(regex, flags);
+ const results = [];
+ let match = re.exec(text) as RegExpExecArrayWithIndices;
+ while (match !== null) {
+ if (re.lastIndex === lastIndex || match[0] === '') {
+ break;
+ }
+ const indices = match.indices;
+ const captures: Array = [];
+ Object.entries(match).forEach(([captureName, captureValue]) => {
+ if (captureName !== '0' && captureName.match(/\d+/)) {
+ captures.push({
+ name: captureName,
+ value: captureValue,
+ start: indices[Number(captureName)][0],
+ end: indices[Number(captureName)][1],
+ });
+ }
+ });
+ const groups: Array = [];
+ Object.entries(match.groups || {}).forEach(([groupName, groupValue]) => {
+ groups.push({
+ name: groupName,
+ value: groupValue,
+ start: indices.groups[groupName][0],
+ end: indices.groups[groupName][1],
+ });
+ });
+ results.push({
+ index: match.index,
+ value: match[0],
+ captures,
+ groups,
+ });
+ lastIndex = re.lastIndex;
+ match = re.exec(text) as RegExpExecArrayWithIndices;
+ }
+ return results;
+}
diff --git a/src/tools/regex-tester/regex-tester.vue b/src/tools/regex-tester/regex-tester.vue
new file mode 100644
index 00000000..a1fa7958
--- /dev/null
+++ b/src/tools/regex-tester/regex-tester.vue
@@ -0,0 +1,193 @@
+
+
+
+
+
+
+
+ See Regular Expression Cheatsheet
+
+
+
+ Global search. (g
)
+
+
+ Case-insensitive search. (i
)
+
+
+ Multiline(m
)
+
+
+ Singleline(s
)
+
+
+ Unicode(u
)
+
+
+ Unicode Sets (v
)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Index in text
+
+
+ Value
+
+
+ Captures
+
+
+ Groups
+
+
+
+
+
+ {{ match.index }}
+ {{ match.value }}
+
+
+
+ "{{ capture.name }}" = {{ capture.value }} [{{ capture.start }} - {{ capture.end }}]
+
+
+
+
+
+
+ "{{ group.name }}" = {{ group.value }} [{{ group.start }} - {{ group.end }}]
+
+
+
+
+
+
+
+ No match
+
+
+
+
+ {{ sample }}
+
+
+
+
+
+
+
+
+
diff --git a/src/tools/token-generator/token-generator.service.ts b/src/tools/token-generator/token-generator.service.ts
index 3733a884..f928a415 100644
--- a/src/tools/token-generator/token-generator.service.ts
+++ b/src/tools/token-generator/token-generator.service.ts
@@ -20,7 +20,7 @@ export function createToken({
withLowercase ? 'abcdefghijklmopqrstuvwxyz' : '',
withNumbers ? '0123456789' : '',
withSymbols ? '.,;:!?./-"\'#{([-|\\@)]=}*+' : '',
- ].join(''); ;
+ ].join('');
return shuffleString(allAlphabet.repeat(length)).substring(0, length);
}
diff --git a/src/tools/url-encoder/url-encoder.vue b/src/tools/url-encoder/url-encoder.vue
index c43f8193..19025190 100644
--- a/src/tools/url-encoder/url-encoder.vue
+++ b/src/tools/url-encoder/url-encoder.vue
@@ -23,7 +23,7 @@ const decodeInput = ref('Hello%20world%20%3A)');
const decodeOutput = computed(() => withDefaultOnError(() => decodeURIComponent(decodeInput.value), ''));
const decodeValidation = useValidation({
- source: encodeInput,
+ source: decodeInput,
rules: [
{
validator: value => isNotThrowing(() => decodeURIComponent(value)),
diff --git a/src/tools/xml-to-json/index.ts b/src/tools/xml-to-json/index.ts
new file mode 100644
index 00000000..8d83f4fe
--- /dev/null
+++ b/src/tools/xml-to-json/index.ts
@@ -0,0 +1,12 @@
+import { Braces } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+ name: 'XML to JSON',
+ path: '/xml-to-json',
+ description: 'Convert XML to JSON',
+ keywords: ['xml', 'json'],
+ component: () => import('./xml-to-json.vue'),
+ icon: Braces,
+ createdAt: new Date('2024-08-09'),
+});
diff --git a/src/tools/xml-to-json/xml-to-json.vue b/src/tools/xml-to-json/xml-to-json.vue
new file mode 100644
index 00000000..e1e5a477
--- /dev/null
+++ b/src/tools/xml-to-json/xml-to-json.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
diff --git a/src/utils/base64.test.ts b/src/utils/base64.test.ts
index 994f1b1b..51d15239 100644
--- a/src/utils/base64.test.ts
+++ b/src/utils/base64.test.ts
@@ -38,7 +38,8 @@ describe('base64 utils', () => {
it('should throw for incorrect base64 string', () => {
expect(() => base64ToText('a')).to.throw('Incorrect base64 string');
- expect(() => base64ToText(' ')).to.throw('Incorrect base64 string');
+ // should not really be false because trimming of space is now implied
+ // expect(() => base64ToText(' ')).to.throw('Incorrect base64 string');
expect(() => base64ToText('Ă©')).to.throw('Incorrect base64 string');
// missing final '='
expect(() => base64ToText('bG9yZW0gaXBzdW0')).to.throw('Incorrect base64 string');
@@ -56,17 +57,17 @@ describe('base64 utils', () => {
it('should return false for incorrect base64 string', () => {
expect(isValidBase64('a')).to.eql(false);
- expect(isValidBase64(' ')).to.eql(false);
expect(isValidBase64('Ă©')).to.eql(false);
expect(isValidBase64('data:text/plain;notbase64,YQ==')).to.eql(false);
// missing final '='
expect(isValidBase64('bG9yZW0gaXBzdW0')).to.eql(false);
});
- it('should return false for untrimmed correct base64 string', () => {
- expect(isValidBase64('bG9yZW0gaXBzdW0= ')).to.eql(false);
- expect(isValidBase64(' LTE=')).to.eql(false);
- expect(isValidBase64(' YQ== ')).to.eql(false);
+ it('should return true for untrimmed correct base64 string', () => {
+ expect(isValidBase64('bG9yZW0gaXBzdW0= ')).to.eql(true);
+ expect(isValidBase64(' LTE=')).to.eql(true);
+ expect(isValidBase64(' YQ== ')).to.eql(true);
+ expect(isValidBase64(' ')).to.eql(true);
});
});
diff --git a/src/utils/base64.ts b/src/utils/base64.ts
index 16912ee3..44e59f41 100644
--- a/src/utils/base64.ts
+++ b/src/utils/base64.ts
@@ -1,7 +1,9 @@
+import { Base64 } from 'js-base64';
+
export { textToBase64, base64ToText, isValidBase64, removePotentialDataAndMimePrefix };
function textToBase64(str: string, { makeUrlSafe = false }: { makeUrlSafe?: boolean } = {}) {
- const encoded = window.btoa(str);
+ const encoded = Base64.encode(str);
return makeUrlSafe ? makeUriSafe(encoded) : encoded;
}
@@ -16,7 +18,7 @@ function base64ToText(str: string, { makeUrlSafe = false }: { makeUrlSafe?: bool
}
try {
- return window.atob(cleanStr);
+ return Base64.decode(cleanStr);
}
catch (_) {
throw new Error('Incorrect base64 string');
@@ -34,10 +36,11 @@ function isValidBase64(str: string, { makeUrlSafe = false }: { makeUrlSafe?: boo
}
try {
+ const reEncodedBase64 = Base64.fromUint8Array(Base64.toUint8Array(cleanStr));
if (makeUrlSafe) {
- return removePotentialPadding(window.btoa(window.atob(cleanStr))) === cleanStr;
+ return removePotentialPadding(reEncodedBase64) === cleanStr;
}
- return window.btoa(window.atob(cleanStr)) === cleanStr;
+ return reEncodedBase64 === cleanStr.replace(/\s/g, '');
}
catch (err) {
return false;