mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-04 13:29:13 -04:00
Merge 26ffcd508f
into f1a5489e21
This commit is contained in:
commit
1f7f1cd697
7 changed files with 6755 additions and 5100 deletions
34
components.d.ts
vendored
34
components.d.ts
vendored
|
@ -13,6 +13,7 @@ declare module '@vue/runtime-core' {
|
||||||
About: typeof import('./src/pages/About.vue')['default']
|
About: typeof import('./src/pages/About.vue')['default']
|
||||||
App: typeof import('./src/App.vue')['default']
|
App: typeof import('./src/App.vue')['default']
|
||||||
AsciiTextDrawer: typeof import('./src/tools/ascii-text-drawer/ascii-text-drawer.vue')['default']
|
AsciiTextDrawer: typeof import('./src/tools/ascii-text-drawer/ascii-text-drawer.vue')['default']
|
||||||
|
AspectRatioCalculator: typeof import('./src/tools/aspect-ratio-calculator/aspect-ratio-calculator.vue')['default']
|
||||||
'Base.layout': typeof import('./src/layouts/base.layout.vue')['default']
|
'Base.layout': typeof import('./src/layouts/base.layout.vue')['default']
|
||||||
Base64FileConverter: typeof import('./src/tools/base64-file-converter/base64-file-converter.vue')['default']
|
Base64FileConverter: typeof import('./src/tools/base64-file-converter/base64-file-converter.vue')['default']
|
||||||
Base64StringConverter: typeof import('./src/tools/base64-string-converter/base64-string-converter.vue')['default']
|
Base64StringConverter: typeof import('./src/tools/base64-string-converter/base64-string-converter.vue')['default']
|
||||||
|
@ -89,17 +90,28 @@ declare module '@vue/runtime-core' {
|
||||||
HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
|
HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
|
||||||
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
|
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
|
||||||
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
|
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
|
||||||
|
'IconMdi:contentCopy': typeof import('~icons/mdi/content-copy')['default']
|
||||||
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
|
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
|
||||||
|
IconMdiArrowDown: typeof import('~icons/mdi/arrow-down')['default']
|
||||||
|
IconMdiArrowRightBottom: typeof import('~icons/mdi/arrow-right-bottom')['default']
|
||||||
|
IconMdiCamera: typeof import('~icons/mdi/camera')['default']
|
||||||
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
|
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
|
||||||
IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
|
IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
|
||||||
IconMdiClose: typeof import('~icons/mdi/close')['default']
|
IconMdiClose: typeof import('~icons/mdi/close')['default']
|
||||||
IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
|
IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
|
||||||
|
IconMdiDeleteOutline: typeof import('~icons/mdi/delete-outline')['default']
|
||||||
|
IconMdiDownload: typeof import('~icons/mdi/download')['default']
|
||||||
IconMdiEye: typeof import('~icons/mdi/eye')['default']
|
IconMdiEye: typeof import('~icons/mdi/eye')['default']
|
||||||
IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
|
IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
|
||||||
IconMdiHeart: typeof import('~icons/mdi/heart')['default']
|
IconMdiHeart: typeof import('~icons/mdi/heart')['default']
|
||||||
|
IconMdiPause: typeof import('~icons/mdi/pause')['default']
|
||||||
|
IconMdiPlay: typeof import('~icons/mdi/play')['default']
|
||||||
|
IconMdiRecord: typeof import('~icons/mdi/record')['default']
|
||||||
|
IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
|
||||||
IconMdiSearch: typeof import('~icons/mdi/search')['default']
|
IconMdiSearch: typeof import('~icons/mdi/search')['default']
|
||||||
IconMdiTranslate: typeof import('~icons/mdi/translate')['default']
|
IconMdiTranslate: typeof import('~icons/mdi/translate')['default']
|
||||||
IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
|
IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
|
||||||
|
IconMdiVideo: typeof import('~icons/mdi/video')['default']
|
||||||
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
|
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
|
||||||
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
|
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
|
||||||
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
|
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
|
||||||
|
@ -127,18 +139,40 @@ declare module '@vue/runtime-core' {
|
||||||
MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
|
MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
|
||||||
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
|
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
|
||||||
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
|
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
|
||||||
|
NAlert: typeof import('naive-ui')['NAlert']
|
||||||
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
|
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
|
||||||
|
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||||
NCode: typeof import('naive-ui')['NCode']
|
NCode: typeof import('naive-ui')['NCode']
|
||||||
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
|
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
|
||||||
|
NColorPicker: typeof import('naive-ui')['NColorPicker']
|
||||||
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
||||||
|
NDatePicker: typeof import('naive-ui')['NDatePicker']
|
||||||
|
NDivider: typeof import('naive-ui')['NDivider']
|
||||||
|
NDynamicInput: typeof import('naive-ui')['NDynamicInput']
|
||||||
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
||||||
|
NForm: typeof import('naive-ui')['NForm']
|
||||||
|
NFormItem: typeof import('naive-ui')['NFormItem']
|
||||||
|
NGi: typeof import('naive-ui')['NGi']
|
||||||
|
NGrid: typeof import('naive-ui')['NGrid']
|
||||||
NH1: typeof import('naive-ui')['NH1']
|
NH1: typeof import('naive-ui')['NH1']
|
||||||
|
NH2: typeof import('naive-ui')['NH2']
|
||||||
NH3: typeof import('naive-ui')['NH3']
|
NH3: typeof import('naive-ui')['NH3']
|
||||||
NIcon: typeof import('naive-ui')['NIcon']
|
NIcon: typeof import('naive-ui')['NIcon']
|
||||||
|
NImage: typeof import('naive-ui')['NImage']
|
||||||
|
NInputGroup: typeof import('naive-ui')['NInputGroup']
|
||||||
|
NInputGroupLabel: typeof import('naive-ui')['NInputGroupLabel']
|
||||||
|
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
||||||
NLayout: typeof import('naive-ui')['NLayout']
|
NLayout: typeof import('naive-ui')['NLayout']
|
||||||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||||
NMenu: typeof import('naive-ui')['NMenu']
|
NMenu: typeof import('naive-ui')['NMenu']
|
||||||
|
NProgress: typeof import('naive-ui')['NProgress']
|
||||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||||
|
NSlider: typeof import('naive-ui')['NSlider']
|
||||||
|
NSpin: typeof import('naive-ui')['NSpin']
|
||||||
|
NStatistic: typeof import('naive-ui')['NStatistic']
|
||||||
|
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||||
|
NTable: typeof import('naive-ui')['NTable']
|
||||||
|
NTag: typeof import('naive-ui')['NTag']
|
||||||
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
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']
|
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']
|
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
|
||||||
|
|
11545
pnpm-lock.yaml
generated
11545
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,70 @@
|
||||||
|
// aspect-ratio-calculator.service.test.ts
|
||||||
|
|
||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import {
|
||||||
|
type AspectRatio,
|
||||||
|
calculateAspectRatio,
|
||||||
|
calculateDimensions,
|
||||||
|
simplifyRatio,
|
||||||
|
} from './aspect-ratio-calculator.service';
|
||||||
|
|
||||||
|
describe('Aspect Ratio Calculator Service', () => {
|
||||||
|
describe('calculateAspectRatio', () => {
|
||||||
|
it('calculates correct aspect ratio for 1920x1080', () => {
|
||||||
|
const result = calculateAspectRatio(1920, 1080);
|
||||||
|
expect(result).toEqual({ r1: 16, r2: 9 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calculates correct aspect ratio for 640x480', () => {
|
||||||
|
const result = calculateAspectRatio(640, 480);
|
||||||
|
expect(result).toEqual({ r1: 4, r2: 3 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles square aspect ratio', () => {
|
||||||
|
const result = calculateAspectRatio(1000, 1000);
|
||||||
|
expect(result).toEqual({ r1: 1, r2: 1 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('calculateDimensions', () => {
|
||||||
|
it('calculates correct height given width and 16:9 ratio', () => {
|
||||||
|
const ratio: AspectRatio = { r1: 16, r2: 9 };
|
||||||
|
const result = calculateDimensions(1920, ratio, true);
|
||||||
|
expect(result).toEqual({ width: 1920, height: 1080 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calculates correct width given height and 4:3 ratio', () => {
|
||||||
|
const ratio: AspectRatio = { r1: 4, r2: 3 };
|
||||||
|
const result = calculateDimensions(480, ratio, false);
|
||||||
|
expect(result).toEqual({ width: 640, height: 480 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles 1:1 ratio', () => {
|
||||||
|
const ratio: AspectRatio = { r1: 1, r2: 1 };
|
||||||
|
const result = calculateDimensions(500, ratio, true);
|
||||||
|
expect(result).toEqual({ width: 500, height: 500 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('simplifyRatio', () => {
|
||||||
|
it('simplifies 16:9 ratio', () => {
|
||||||
|
const result = simplifyRatio(16, 9);
|
||||||
|
expect(result).toEqual({ r1: 16, r2: 9 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('simplifies 1920:1080 to 16:9', () => {
|
||||||
|
const result = simplifyRatio(1920, 1080);
|
||||||
|
expect(result).toEqual({ r1: 16, r2: 9 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('simplifies 4:2 to 2:1', () => {
|
||||||
|
const result = simplifyRatio(4, 2);
|
||||||
|
expect(result).toEqual({ r1: 2, r2: 1 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles already simplified ratios', () => {
|
||||||
|
const result = simplifyRatio(7, 5);
|
||||||
|
expect(result).toEqual({ r1: 7, r2: 5 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,44 @@
|
||||||
|
// aspect-ratio-calculator.service.ts
|
||||||
|
|
||||||
|
export interface AspectRatio {
|
||||||
|
r1: number
|
||||||
|
r2: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Dimensions {
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateAspectRatio(width: number, height: number): AspectRatio {
|
||||||
|
const gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b));
|
||||||
|
const divisor = gcd(width, height);
|
||||||
|
return {
|
||||||
|
r1: width / divisor,
|
||||||
|
r2: height / divisor,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateDimensions(
|
||||||
|
knownDimension: number,
|
||||||
|
ratio: AspectRatio,
|
||||||
|
isWidth: boolean,
|
||||||
|
): Dimensions {
|
||||||
|
if (isWidth) {
|
||||||
|
const height = Math.round((knownDimension * ratio.r2) / ratio.r1);
|
||||||
|
return { width: knownDimension, height };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const width = Math.round((knownDimension * ratio.r1) / ratio.r2);
|
||||||
|
return { width, height: knownDimension };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function simplifyRatio(r1: number, r2: number): AspectRatio {
|
||||||
|
const gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b));
|
||||||
|
const divisor = gcd(r1, r2);
|
||||||
|
return {
|
||||||
|
r1: r1 / divisor,
|
||||||
|
r2: r2 / divisor,
|
||||||
|
};
|
||||||
|
}
|
147
src/tools/aspect-ratio-calculator/aspect-ratio-calculator.vue
Normal file
147
src/tools/aspect-ratio-calculator/aspect-ratio-calculator.vue
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
<!-- AspectRatioCalculator.vue -->
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { NButton, NInputNumber, NRadio, NRadioGroup, NSpace } from 'naive-ui';
|
||||||
|
import {
|
||||||
|
calculateAspectRatio,
|
||||||
|
calculateDimensions,
|
||||||
|
} from './aspect-ratio-calculator.service';
|
||||||
|
|
||||||
|
const width = ref<number | null>(null);
|
||||||
|
const height = ref<number | null>(null);
|
||||||
|
const r1 = ref<number | null>(null);
|
||||||
|
const r2 = ref<number | null>(null);
|
||||||
|
const mode = ref<'ratio' | 'dimensions'>('ratio');
|
||||||
|
const result = ref<string | null>(null);
|
||||||
|
|
||||||
|
function calculateResult() {
|
||||||
|
if (mode.value === 'ratio' && width.value && height.value) {
|
||||||
|
const ratio = calculateAspectRatio(width.value, height.value);
|
||||||
|
r1.value = ratio.r1;
|
||||||
|
r2.value = ratio.r2;
|
||||||
|
result.value = `Aspect Ratio: ${ratio.r1}:${ratio.r2}`;
|
||||||
|
}
|
||||||
|
else if (mode.value === 'dimensions' && r1.value && r2.value) {
|
||||||
|
if (width.value) {
|
||||||
|
const dimensions = calculateDimensions(width.value, { r1: r1.value, r2: r2.value }, true);
|
||||||
|
height.value = dimensions.height;
|
||||||
|
result.value = `Dimensions: ${dimensions.width}x${dimensions.height}`;
|
||||||
|
}
|
||||||
|
else if (height.value) {
|
||||||
|
const dimensions = calculateDimensions(height.value, { r1: r1.value, r2: r2.value }, false);
|
||||||
|
width.value = dimensions.width;
|
||||||
|
result.value = `Dimensions: ${dimensions.width}x${dimensions.height}`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.value = 'Please enter either width or height to calculate dimensions';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.value = 'Please fill in the required fields';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearAll() {
|
||||||
|
width.value = null;
|
||||||
|
height.value = null;
|
||||||
|
r1.value = null;
|
||||||
|
r2.value = null;
|
||||||
|
result.value = null;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NSpace vertical :size="24">
|
||||||
|
<NRadioGroup v-model:value="mode">
|
||||||
|
<NRadio value="ratio">
|
||||||
|
Calculate Aspect Ratio
|
||||||
|
</NRadio>
|
||||||
|
<NRadio value="dimensions">
|
||||||
|
Calculate Dimensions
|
||||||
|
</NRadio>
|
||||||
|
</NRadioGroup>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-pair">
|
||||||
|
<label>Pixels width</label>
|
||||||
|
<NInputNumber v-model:value="width" placeholder="Pixels width" :min="1" />
|
||||||
|
</div>
|
||||||
|
<div class="input-pair">
|
||||||
|
<label>Pixels height</label>
|
||||||
|
<NInputNumber v-model:value="height" placeholder="Pixels height" :min="1" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-pair">
|
||||||
|
<label>Ratio width</label>
|
||||||
|
<NInputNumber v-model:value="r1" placeholder="Ratio width" :min="1" />
|
||||||
|
</div>
|
||||||
|
<div class="separator">
|
||||||
|
:
|
||||||
|
</div>
|
||||||
|
<div class="input-pair">
|
||||||
|
<label>Ratio height</label>
|
||||||
|
<NInputNumber v-model:value="r2" placeholder="Ratio height" :min="1" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="button-container">
|
||||||
|
<NButton type="primary" @click="calculateResult">
|
||||||
|
Calculate
|
||||||
|
</NButton>
|
||||||
|
<NButton @click="clearAll">
|
||||||
|
Clear All
|
||||||
|
</NButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="result" class="result">
|
||||||
|
{{ result }}
|
||||||
|
</div>
|
||||||
|
</NSpace>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.input-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-pair {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-pair label {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
align-self: flex-end;
|
||||||
|
margin-bottom: 7px;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-container .n-button {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.n-input-number) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
12
src/tools/aspect-ratio-calculator/index.ts
Normal file
12
src/tools/aspect-ratio-calculator/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { AspectRatio } from '@vicons/tabler';
|
||||||
|
import { defineTool } from '../tool';
|
||||||
|
|
||||||
|
export const tool = defineTool({
|
||||||
|
name: 'Aspect Ratio Calculator',
|
||||||
|
path: '/aspect-ratio-calculator',
|
||||||
|
description: 'Use this ratio calculator to check the dimensions when resizing images.',
|
||||||
|
keywords: ['aspect', 'ratio', 'calculator'],
|
||||||
|
component: () => import('./aspect-ratio-calculator.vue'),
|
||||||
|
icon: AspectRatio,
|
||||||
|
createdAt: new Date('2024-08-14'),
|
||||||
|
});
|
|
@ -1,6 +1,7 @@
|
||||||
import { tool as base64FileConverter } from './base64-file-converter';
|
import { tool as base64FileConverter } from './base64-file-converter';
|
||||||
import { tool as base64StringConverter } from './base64-string-converter';
|
import { tool as base64StringConverter } from './base64-string-converter';
|
||||||
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
||||||
|
import { tool as aspectRatioCalculator } from './aspect-ratio-calculator';
|
||||||
|
|
||||||
import { tool as asciiTextDrawer } from './ascii-text-drawer';
|
import { tool as asciiTextDrawer } from './ascii-text-drawer';
|
||||||
|
|
||||||
|
@ -136,7 +137,7 @@ export const toolsByCategory: ToolCategory[] = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Images and videos',
|
name: 'Images and videos',
|
||||||
components: [qrCodeGenerator, wifiQrCodeGenerator, svgPlaceholderGenerator, cameraRecorder],
|
components: [qrCodeGenerator, wifiQrCodeGenerator, svgPlaceholderGenerator, cameraRecorder, aspectRatioCalculator],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Development',
|
name: 'Development',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue