@jjlmoya/utils-converters 1.18.0 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-converters",
3
- "version": "1.18.0",
3
+ "version": "1.20.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -28,7 +28,7 @@
28
28
  "check": "astro check",
29
29
  "type-check": "astro check",
30
30
  "test": "vitest run",
31
- "preversion": "npm run lint && npm run test",
31
+ "preversion": "npm run lint && npm run test && npm run build",
32
32
  "postversion": "git push && git push --tags",
33
33
  "patch": "npm version patch",
34
34
  "minor": "npm version minor",
@@ -0,0 +1,60 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ALL_ENTRIES } from '../entries';
3
+ import type { KnownLocale } from '../types';
4
+
5
+ interface ExpectedCounts {
6
+ seo: number;
7
+ faq: number;
8
+ howTo: number;
9
+ }
10
+
11
+ function countItems(arr: unknown[] | undefined): number {
12
+ return arr?.length ?? 0;
13
+ }
14
+
15
+ async function verifyLocaleParity(
16
+ entry: typeof ALL_ENTRIES[number],
17
+ loc: KnownLocale,
18
+ expected: ExpectedCounts,
19
+ ): Promise<void> {
20
+ const locContent = await entry.i18n[loc]?.();
21
+ expect(locContent, `Locale ${loc} missing content`).toBeDefined();
22
+
23
+ const locSeoCount = countItems(locContent?.seo);
24
+ const locFaqCount = countItems(locContent?.faq);
25
+ const locHowToCount = countItems(locContent?.howTo);
26
+
27
+ expect(
28
+ locSeoCount,
29
+ `Locale ${loc} SEO sections count (${locSeoCount}) must match EN (${expected.seo})`,
30
+ ).toBe(expected.seo);
31
+ expect(
32
+ locFaqCount,
33
+ `Locale ${loc} FAQ items count (${locFaqCount}) must match EN (${expected.faq})`,
34
+ ).toBe(expected.faq);
35
+ expect(
36
+ locHowToCount,
37
+ `Locale ${loc} HowTo steps count (${locHowToCount}) must match EN (${expected.howTo})`,
38
+ ).toBe(expected.howTo);
39
+ }
40
+
41
+ describe('SEO & i18n Structural Parity Suite', () => {
42
+ ALL_ENTRIES.forEach((entry) => {
43
+ describe(`Tool: ${entry.id}`, () => {
44
+ it('all 15 locales should have identical SEO section counts and types as English', async () => {
45
+ const enContent = await entry.i18n.en?.();
46
+ expect(enContent).toBeDefined();
47
+ const expected: ExpectedCounts = {
48
+ seo: countItems(enContent?.seo),
49
+ faq: countItems(enContent?.faq),
50
+ howTo: countItems(enContent?.howTo),
51
+ };
52
+
53
+ const locales = Object.keys(entry.i18n) as KnownLocale[];
54
+ for (const loc of locales) {
55
+ await verifyLocaleParity(entry, loc, expected);
56
+ }
57
+ });
58
+ });
59
+ });
60
+ });
@@ -0,0 +1,123 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { ALL_ENTRIES } from '../entries';
3
+
4
+ const COPY_THRESHOLD = 0.9;
5
+
6
+ const STRUCTURAL_KEYS = new Set([
7
+ '@context',
8
+ '@type',
9
+ 'applicationCategory',
10
+ 'columns',
11
+ 'highlight',
12
+ 'icon',
13
+ 'level',
14
+ 'operatingSystem',
15
+ 'position',
16
+ 'positive',
17
+ 'price',
18
+ 'priceCurrency',
19
+ 'slug',
20
+ 'trend',
21
+ 'type',
22
+ 'url',
23
+ 'value',
24
+ 'variant',
25
+ ]);
26
+
27
+ function normalizeText(value: string): string {
28
+ return value
29
+ .replace(/<[^>]*>/g, ' ')
30
+ .replace(/&(?:amp|lt|gt|quot|apos|nbsp);/gi, ' ')
31
+ .replace(/[\u2018\u2019]/g, "'")
32
+ .replace(/[\u201c\u201d]/g, '"')
33
+ .replace(/\s+/g, ' ')
34
+ .trim()
35
+ .toLocaleLowerCase();
36
+ }
37
+
38
+ function collectText(value: unknown, path: string, parts: string[]): void {
39
+ if (typeof value === 'string') {
40
+ const normalized = normalizeText(value);
41
+ if (normalized.length >= 2) parts.push(normalized);
42
+ return;
43
+ }
44
+
45
+ if (Array.isArray(value)) {
46
+ value.forEach((item, index) => collectText(item, `${path}[${index}]`, parts));
47
+ return;
48
+ }
49
+
50
+ if (!value || typeof value !== 'object') return;
51
+
52
+ Object.entries(value).forEach(([key, child]) => {
53
+ if (STRUCTURAL_KEYS.has(key)) return;
54
+ collectText(child, `${path}.${key}`, parts);
55
+ });
56
+ }
57
+
58
+ function localeCorpus(content: unknown): string {
59
+ if (!content || typeof content !== 'object') return '';
60
+
61
+ const record = content as Record<string, unknown>;
62
+ const parts: string[] = [];
63
+ collectText(record.title, 'title', parts);
64
+ collectText(record.description, 'description', parts);
65
+ collectText(record.faqTitle, 'faqTitle', parts);
66
+ collectText(record.faq, 'faq', parts);
67
+ collectText(record.seo, 'seo', parts);
68
+ collectText(record.schemas, 'schemas', parts);
69
+ return parts.join(' ');
70
+ }
71
+
72
+ function tokenCounts(text: string): Map<string, number> {
73
+ const counts = new Map<string, number>();
74
+ for (const token of text.match(/[\p{L}\p{N}]+/gu) ?? []) {
75
+ counts.set(token, (counts.get(token) ?? 0) + 1);
76
+ }
77
+ return counts;
78
+ }
79
+
80
+ function copySimilarity(left: string, right: string): number {
81
+ const leftCounts = tokenCounts(left);
82
+ const rightCounts = tokenCounts(right);
83
+ const leftTotal = [...leftCounts.values()].reduce((sum, count) => sum + count, 0);
84
+ const rightTotal = [...rightCounts.values()].reduce((sum, count) => sum + count, 0);
85
+ if (leftTotal === 0 || rightTotal === 0) return 0;
86
+
87
+ let shared = 0;
88
+ for (const [token, count] of leftCounts) {
89
+ shared += Math.min(count, rightCounts.get(token) ?? 0);
90
+ }
91
+ return (2 * shared) / (leftTotal + rightTotal);
92
+ }
93
+
94
+ describe('Locales must not copy another locale wholesale', () => {
95
+ ALL_ENTRIES.forEach((entry) => {
96
+ it(`${entry.id} is not at least ${COPY_THRESHOLD * 100}% identical to another locale`, async () => {
97
+ const corpora = new Map<string, string>();
98
+
99
+ for (const [locale, loader] of Object.entries(entry.i18n)) {
100
+ if (!loader) continue;
101
+ corpora.set(locale, localeCorpus(await loader()));
102
+ }
103
+
104
+ const locales = [...corpora.keys()];
105
+ const violations: string[] = [];
106
+
107
+ for (let leftIndex = 0; leftIndex < locales.length; leftIndex += 1) {
108
+ for (let rightIndex = leftIndex + 1; rightIndex < locales.length; rightIndex += 1) {
109
+ const left = locales[leftIndex];
110
+ const right = locales[rightIndex];
111
+ const similarity = copySimilarity(corpora.get(left) ?? '', corpora.get(right) ?? '');
112
+
113
+ if (similarity >= COPY_THRESHOLD) {
114
+ violations.push(`${left} ↔ ${right}: ${(similarity * 100).toFixed(1)}%`);
115
+ }
116
+ }
117
+ }
118
+
119
+ expect(violations, `Locale copy threshold exceeded in ${entry.id}`).toEqual([]);
120
+ });
121
+ });
122
+ });
123
+
@@ -21,24 +21,24 @@ const ui: ImageConverterUI = {
21
21
 
22
22
  const faq: PngAJpgLocaleContent['faq'] = [
23
23
  {
24
- question: 'Warum sollten Sie unseren lokalen PNG-zu-JPG-Konverter wählen?',
24
+ question: '¿Por qué elegir nuestro convertidor local de PNG a JPG?',
25
25
  answer:
26
- 'Im Gegensatz zu herkömmlichen Tools verarbeitet unser Tool die Dateien vollständig in Ihrem Browser. Ihre Bilder berühren nie eine fremde Festplatte, was die totale Souveränität und Privatsphäre Ihrer Daten garantiert.',
26
+ 'A diferencia de las herramientas convencionales, nuestra utilidad procesa los archivos íntegramente en tu navegador. Tus imágenes nunca tocan un disco duro ajeno, garantizando la total soberanía y privacidad de tus datos.',
27
27
  },
28
28
  {
29
- question: 'JPG oder PNG? Was ist besser für meinen Fall?',
29
+ question: '¿JPG o PNG? ¿Cuál es mejor para mi caso?',
30
30
  answer:
31
- 'PNG ist ideal für Logos und Elemente mit Transparenz. JPG hingegen ist der Goldstandard für Fotos und Web-Banner, da es viel geringere Dateigrößen erreicht und so die Ladegeschwindigkeit einer Website drastisch verbessert.',
31
+ 'El PNG es ideal para logotipos y elementos con transparencia. Sin embargo, el JPG es el estándar de oro para fotografías y banners web, ya que logra pesos mucho más reducidos, mejorando drásticamente la velocidad de carga de un sitio.',
32
32
  },
33
33
  {
34
- question: 'Wie funktioniert die technische Konvertierung ohne Upload?',
34
+ question: '¿Cómo funciona la conversión técnica sin subir nada?',
35
35
  answer:
36
- 'Wir nutzen die Leistung des HTML5-Canvas. Der Browser stellt das Bild auf einer unsichtbaren virtuellen Leinwand dar, füllt Transparenzen mit Weiß und erzeugt einen Byte-Stream, den Sie sofort direkt herunterladen.',
36
+ 'Utilizamos la potencia del Canvas de HTML5. El navegador recrea la imagen en un lienzo virtual invisible, rellena las transparencias con blanco y genera un flujo de bytes que descargas directamente al instante.',
37
37
  },
38
38
  {
39
- question: 'Ist es sicher für vertrauliche Dokumente?',
39
+ question: '¿Es seguro para documentos confidenciales?',
40
40
  answer:
41
- 'Ja, es ist die sicherste Option für Fachleute aus den Bereichen Banken, Gesundheit oder Recht. Da es sich um eine "Black Box" handelt, die nur Ihren RAM nutzt, werden alle Daten beim Schließen des Tabs gelöscht, wodurch Lecks in Drittanbieter-Clouds vermieden werden.',
41
+ 'Sí, es la opción más segura para profesionales de la banca, salud o derecho. Al ser una "caja negra" que solo usa tu RAM, lo que pasa dentro muere al cerrar la pestaña, evitando filtraciones en nubes de terceros.',
42
42
  },
43
43
  ];
44
44
 
@@ -60,110 +60,110 @@ const howTo: PngAJpgLocaleContent['howTo'] = [
60
60
  const seo: PngAJpgLocaleContent['seo'] = [
61
61
  {
62
62
  type: 'title',
63
- text: 'PNG-zu-JPG-Konverter: Der ultimative Leitfaden zur Bildoptimierung',
63
+ text: 'Convertidor de PNG a JPG: La Guía Definitiva para la Optimización de Imágenes',
64
64
  level: 2,
65
65
  },
66
66
  {
67
67
  type: 'paragraph',
68
- html: 'In der Welt des digitalen Designs und der Webentwicklung ist Effizienz alles. Das PNG-Format (Portable Network Graphics) wird für seine Fähigkeit geliebt, Transparenzen beizubehalten und eine verlustfreie Kompression zu bieten, hat aber einen großen Feind: das Dateigewicht. Wenn Sie möchten, dass Ihre Website fliegt oder Ihre E-Mails sofort geladen werden, ist der Wechsel von PNG zu JPG die intelligenteste technische Entscheidung.',
68
+ html: 'En el mundo del diseño digital y el desarrollo web, la eficiencia lo es todo. El formato PNG (Portable Network Graphics) es amado por su capacidad de mantener transparencias y su compresión sin pérdida, pero tiene un gran enemigo: el peso del archivo. Cuando necesitas que tu sitio web vuele o que tus emails carguen instantáneamente, el paso de PNG a JPG es la decisión técnica más inteligente.',
69
69
  },
70
70
  {
71
71
  type: 'title',
72
- text: 'JPG oder PNG?',
72
+ text: '¿JPG o PNG?',
73
73
  level: 3,
74
74
  },
75
75
  {
76
76
  type: 'paragraph',
77
- html: 'Es gibt kein Format, das besser als das andere ist, sondern ein Werkzeug für jeden Bedarf. PNG ist ein verlustfreies Format, ideal für Interface-Mockups, Logos mit kleinem Text und visuelle Elemente, die einen transparenten Hintergrund erfordern. Diese Treue hat jedoch ihren Preis: Dateien, die 5- oder 10-mal schwerer sein können als ihr komprimiertes Äquivalent.',
77
+ html: 'No existe un formato mejor que otro, sino una herramienta para cada necesidad. El PNG es un formato sin pérdida, ideal para maquetas de interfaces, logotipos con texto pequeño y elementos visuales que requieren un fondo transparente. Sin embargo, esta fidelidad tiene un coste: archivos que pueden ser 5 o 10 veces más pesados que su equivalente comprimido.',
78
78
  },
79
79
  {
80
80
  type: 'paragraph',
81
- html: 'JPG (Joint Photographic Experts Group) hingegen verwendet Diskretisierungsalgorithmen, um Informationen zu entfernen, die das menschliche Auge kaum wahrnimmt, und erreicht so Federgewicht. Es ist der Goldstandard für Fotos, Werbebanner und soziale Netzwerke. Indem Sie Ihre PNGs in JPGs konvertieren, tauschen Sie geometrische Treue gegen Netzwerkgeschwindigkeit ein.',
81
+ html: 'El JPG (Joint Photographic Experts Group), por otro lado, utiliza algoritmos de discretización para eliminar información que el ojo humano apenas percibe, logrando pesos pluma. Es el estándar de oro para fotografías, banners publicitarios y redes sociales. Al convertir tus PNG a JPG, estás traduciendo fidelidad geométrica por velocidad de red.',
82
82
  },
83
83
  {
84
84
  type: 'title',
85
- text: 'Architekturvergleich: Lokal vs. Cloud',
85
+ text: 'Comparativa de Arquitectura: Local vs Nube',
86
86
  level: 3,
87
87
  },
88
88
  {
89
89
  type: 'comparative',
90
90
  items: [
91
91
  {
92
- title: 'Cloud Konverter',
93
- description: 'Herkömmliche Tools, die Ihre Fotos auf einen Remote-Server hochladen.',
92
+ title: 'Convertidores Cloud',
93
+ description: 'Herramientas tradicionales que suben tus fotos a un servidor remoto.',
94
94
  icon: 'mdi:cloud-upload',
95
95
  pointIcon: 'mdi:close-circle-outline',
96
96
  points: [
97
- 'Netzwerklatenz (Upload/Download)',
98
- 'Risiko von Datenlecks privater Daten',
99
- 'Dateigrößenbeschränkungen pro Datei',
100
- 'Werbung und Tracker',
97
+ 'Latencia de red (Upload/Download)',
98
+ 'Riesgo de filtración de datos privados',
99
+ 'Límites de tamaño por archivo',
100
+ 'Publicidad y rastreadores',
101
101
  ],
102
102
  },
103
103
  {
104
- title: 'Unsere lokale Architektur',
105
- description: 'Direkte Verarbeitung auf Ihrer Hardware mittels Vanilla JS-Technologie.',
104
+ title: 'Nuestra Arquitectura Local',
105
+ description: 'Procesamiento directo en tu hardware mediante tecnología Vanilla JS.',
106
106
  icon: 'mdi:laptop-mac',
107
107
  highlight: true,
108
108
  points: [
109
- 'Sofortige Geschwindigkeit ohne Netzwerk',
110
- 'Garantierte Privatsphäre (0 Bytes gesendet)',
111
- 'Keine MB-Limits pro Datei',
112
- 'Professionelle und saubere Schnittstelle',
109
+ 'Velocidad instantánea sin red',
110
+ 'Privacidad garantizada (0 bytes enviados)',
111
+ 'Sin límites de MB por archivo',
112
+ 'Interfaz profesional y limpia',
113
113
  ],
114
114
  },
115
115
  ],
116
116
  },
117
117
  {
118
118
  type: 'title',
119
- text: 'Wie die technische Konvertierung funktioniert',
119
+ text: 'Cómo funciona la conversión técnica',
120
120
  level: 3,
121
121
  },
122
122
  {
123
123
  type: 'paragraph',
124
- html: 'Sie fragen sich wahrscheinlich, wie es möglich ist, ein Bild zu konvertieren, ohne es an einen Server zu senden. Die Magie liegt in der Leistung moderner Browser. Wenn Sie eine Datei auswählen, erzeugen wir einen Blob, der nur in Ihrem RAM existiert. Dieser Blob wird auf ein unsichtbares HTML5-Canvas-Element gezeichnet.',
124
+ html: 'Probablemente te preguntes cómo es posible convertir una imagen sin enviarla a un servidor. La magia reside en la potencia de los navegadores modernos. Cuando seleccionas un archivo, generamos un Blob que solo existe en tu RAM. Ese Blob se dibuja en un elemento HTML5 Canvas invisible.',
125
125
  },
126
126
  {
127
127
  type: 'paragraph',
128
- html: 'Da JPG keine Transparenzen unterstützt, füllt unser Algorithmus den Hintergrund mit einer soliden weißen Farbe, bevor das PNG darauf "gemalt" wird. Sobald das Bild komponiert ist, führen wir die native Exportmethode aus und erzeugen einen Byte-Stream, den Ihr Computer direkt herunterlädt.',
128
+ html: 'Dado que el JPG no soporta transparencias, nuestro algoritmo rellena el fondo con un color blanco sólido antes de "pintar" el PNG encima. Una vez compuesta la imagen, ejecutamos el método de exportación nativo, generando un flujo de bytes que tu ordenador descarga directamente.',
129
129
  },
130
130
  {
131
131
  type: 'tip',
132
- title: 'SEO Tipp: Das ideale Gewicht',
133
- html: 'Google bestraft aktiv langsame Websites. Wenn Ihr Largest Contentful Paint (LCP) aufgrund eines 2MB großen Header-PNGs hoch ist, kann die Konvertierung in ein 200KB großes JPG Ihre PageSpeed-Metriken sofort verbessern, ohne visuelle Unterschiede.',
132
+ title: 'Consejo SEO: El Peso Ideal',
133
+ html: 'Google penaliza activamente los sitios web lentos. Si tu Largest Contentful Paint (LCP) es alto por culpa de un PNG de cabecera de 2MB, convertirlo a un JPG de 200KB puede mejorar tus métricas de PageSpeed instantáneamente sin diferencias visuales.',
134
134
  },
135
135
  {
136
136
  type: 'title',
137
- text: 'Sicherheit für Unternehmen und Fachleute',
137
+ text: 'Seguridad para Empresas y Profesionales',
138
138
  level: 3,
139
139
  },
140
140
  {
141
141
  type: 'paragraph',
142
- html: 'Wenn Sie in sensiblen Bereichen wie Banken, Gesundheit oder Recht arbeiten, ist das Hochladen von Dateien zu Online-Konvertern eine Sicherheitsverletzung. Unser Tool funktioniert wie eine "Black Box": Was drinnen passiert, bleibt in Ihrem RAM. Es ist der einzige sichere Weg, mit vertraulichen Dokumenten zu arbeiten.',
142
+ html: 'Si trabajas en sectores sensibles como la banca, la salud o el derecho, subir archivos a conversores online es una violación de seguridad. Nuestra herramienta funciona como una "caja negra": lo que pasa dentro se queda en tu RAM. Es la única forma segura de trabajar con documentos confidenciales.',
143
143
  },
144
144
  {
145
145
  type: 'title',
146
- text: 'Kompatibilität des Ergebnisses',
146
+ text: 'Compatibilidad del Resultado',
147
147
  level: 3,
148
148
  },
149
149
  {
150
150
  type: 'list',
151
151
  icon: 'mdi:check-circle',
152
152
  items: [
153
- 'Anzeige auf Windows, macOS und mobilen Geräten.',
154
- 'Soziale Netzwerke (Instagram, LinkedIn usw.).',
155
- 'Office-Tools (Word, PowerPoint).',
156
- 'Content-Management-Systeme (WordPress, Shopify).',
153
+ 'Visores de Windows, macOS y dispositivos móviles.',
154
+ 'Redes sociales (Instagram, LinkedIn, etc).',
155
+ 'Herramientas de ofimática (Word, PowerPoint).',
156
+ 'Gestores de contenido (WordPress, Shopify).',
157
157
  ],
158
158
  },
159
159
  {
160
160
  type: 'title',
161
- text: 'Fazit: Optimieren wie ein Profi',
161
+ text: 'Conclusión: Optimiza como un Pro',
162
162
  level: 3,
163
163
  },
164
164
  {
165
165
  type: 'paragraph',
166
- html: 'Dieser Konverter ist nicht nur eine weitere Seite; er ist ein Stück Ingenieurskunst, das Ihnen das Leben erleichtern soll. Egal, ob Sie Entwickler oder Privatanwender sind, hier ist die ultimative Lösung, um Megabytes zu sparen und Ihre Daten sicher aufzubewahren.',
166
+ html: 'Este convertidor no es solo una página más; es una pieza de ingeniería diseñada para facilitarte la vida. Ya seas un desarrollador o un usuario doméstico, aquí tienes la solución definitiva para ahorrar megabytes y mantener tus datos a salvo.',
167
167
  },
168
168
  ];
169
169
 
@@ -6,7 +6,7 @@ import type { PngAJpgLocaleContent } from '../index';
6
6
  const slug = 'png-to-jpg-converter';
7
7
  const title = 'Convert PNG to JPG Online';
8
8
  const description =
9
- 'Convert PNG images to JPG directly in your browser. No file uploads to servers. Fast, free and completely private.';
9
+ 'Convert PNG images to JPG format directly in your browser. No server uploads. Fast batch image optimization and guaranteed privacy.';
10
10
 
11
11
  const ui: ImageConverterUI = {
12
12
  dragText: 'Drag PNG files...',
@@ -21,85 +21,152 @@ const ui: ImageConverterUI = {
21
21
 
22
22
  const faq: PngAJpgLocaleContent['faq'] = [
23
23
  {
24
- question: 'Why convert PNG to JPG?',
24
+ question: 'Why choose our local PNG to JPG converter?',
25
25
  answer:
26
- 'PNG maintains high quality and transparency but results in large files. Converting to JPG is perfect when you need lightweight photos for emails or fast websites and a solid background is acceptable.',
26
+ 'Unlike conventional online converters, our tool processes all images locally inside your web browser. Your files never touch external servers, guaranteeing total data sovereignty and security.',
27
27
  },
28
28
  {
29
- question: 'Will I lose details during the conversion?',
29
+ question: 'JPG vs PNG: Which format is best for your use case?',
30
30
  answer:
31
- 'We apply a balanced high-quality compression ratio, so differences in photographs and gradients will be almost imperceptible to the eye, but you will notice the savings in the final file size.',
31
+ 'PNG is ideal for logos, icons, and graphics requiring transparent backgrounds. JPG is the gold standard for photos and web banners because of its higher compression ratio and significantly smaller file sizes.',
32
32
  },
33
33
  {
34
- question: 'Are my photos processed securely?',
34
+ question: 'How does client-side technical conversion work?',
35
35
  answer:
36
- 'Absolutely yes. We do not use cloud servers; the conversion algorithm runs through the HTML5 Canvas of your own web browser in an isolated environment.',
36
+ 'We utilize HTML5 Canvas element technology. The browser draws the PNG onto an invisible virtual canvas, fills transparent pixels with solid white, and exports a clean JPEG byte stream directly to your memory.',
37
+ },
38
+ {
39
+ question: 'Is it safe for confidential documents and enterprise data?',
40
+ answer:
41
+ 'Yes, it is the safest choice for banking, legal, and healthcare professionals. Since processing stays entirely within browser RAM, data vanishes completely when the browser tab is closed.',
37
42
  },
38
43
  ];
39
44
 
40
45
  const howTo: PngAJpgLocaleContent['howTo'] = [
41
46
  {
42
- name: 'Drag PNG Files',
43
- text: 'Send your static PNG images to the local processing box by dropping them there.',
47
+ name: 'File Selection',
48
+ text: 'Drag your PNG files into the processing box or click to select them from your file explorer.',
44
49
  },
45
50
  {
46
- name: 'White Re-Rendering',
47
- text: 'Each photo automatically adapts its transparency with an underlying white layer to make it compatible with the JPG environment.',
51
+ name: 'Instant Local Conversion',
52
+ text: 'Observe as each file turns to "Ready" status while your browser converts the images locally.',
48
53
  },
49
54
  {
50
- name: 'Direct Export',
51
- text: 'Click the green download icons and save your new JPG files.',
55
+ name: 'Optimized Download',
56
+ text: 'Download your newly generated JPG files individually or click "Download All (.zip)" to save everything at once.',
52
57
  },
53
58
  ];
54
59
 
55
60
  const seo: PngAJpgLocaleContent['seo'] = [
56
61
  {
57
62
  type: 'title',
58
- text: 'Free Online PNG to JPG Converter',
63
+ text: 'PNG to JPG Converter: The Definitive Image Optimization Guide',
64
+ level: 2,
59
65
  },
60
66
  {
61
67
  type: 'paragraph',
62
- html:
63
- 'PNG (Portable Network Graphics) is widely used for its lossless quality and transparency (alpha channel) support. However, this fidelity comes at a cost: PNG files are considerably larger than their JPG equivalents, especially for photographs or images with complex gradients.',
68
+ html: 'In digital design and web development, efficiency is everything. The PNG (Portable Network Graphics) format is loved for transparency and lossless compression, but its main drawback is file size. When you need fast websites or instant email attachments, converting PNG to JPG is the smartest choice.',
69
+ },
70
+ {
71
+ type: 'title',
72
+ text: 'JPG or PNG?',
73
+ level: 3,
64
74
  },
65
75
  {
66
76
  type: 'paragraph',
67
- html:
68
- 'JPG (or JPEG) uses a lossy compression algorithm that drastically reduces file size. For photographs and images where a small loss of detail is acceptable, JPG is the standard choice. A 2 MB PNG can become a 200 KB JPG with virtually identical visual quality.',
77
+ html: 'There is no universally superior format, only the right tool for each job. PNG is lossless and ideal for UI mockups, logos with small text, and graphics requiring transparent backgrounds. However, this fidelity results in files 5 to 10 times larger than compressed equivalents.',
69
78
  },
70
79
  {
71
80
  type: 'paragraph',
72
- html:
73
- 'Our PNG to JPG converter works entirely in your web browser using the HTML5 Canvas API. The process is simple: the PNG image is loaded into memory, drawn on a virtual canvas, and exported as JPG at optimal quality. Transparent areas in the PNG are replaced with a solid white background, as the JPG format does not support the alpha channel.',
81
+ html: 'JPG (Joint Photographic Experts Group) uses lossy compression algorithms to remove details barely noticeable to the human eye, delivering lightweight files. It is the gold standard for photos, web banners, and social media. Converting PNG to JPG trades micro-fidelity for network speed.',
74
82
  },
75
83
  {
76
- type: 'tip',
77
- html:
78
- 'For images with text or logos requiring transparent backgrounds, consider using WebP instead of JPG. WebP offers similar compression but retains transparency support.',
84
+ type: 'title',
85
+ text: 'Architecture Comparison: Local vs Cloud',
86
+ level: 3,
87
+ },
88
+ {
89
+ type: 'comparative',
90
+ items: [
91
+ {
92
+ title: 'Cloud Converters',
93
+ description: 'Traditional tools that upload your files to remote servers.',
94
+ icon: 'mdi:cloud-upload',
95
+ pointIcon: 'mdi:close-circle-outline',
96
+ points: [
97
+ 'Network latency (Upload/Download)',
98
+ 'Privacy leak risks',
99
+ 'File size upload limits',
100
+ 'Ads and tracking scripts',
101
+ ],
102
+ },
103
+ {
104
+ title: 'Our Local Architecture',
105
+ description: 'Direct browser hardware processing via Vanilla JS.',
106
+ icon: 'mdi:laptop-mac',
107
+ highlight: true,
108
+ points: [
109
+ 'Instant speed without network delays',
110
+ 'Guaranteed privacy (0 bytes uploaded)',
111
+ 'No file size limits',
112
+ 'Clean, ad-free interface',
113
+ ],
114
+ },
115
+ ],
116
+ },
117
+ {
118
+ type: 'title',
119
+ text: 'How Local Technical Conversion Works',
120
+ level: 3,
79
121
  },
80
122
  {
81
123
  type: 'paragraph',
82
- html:
83
- 'JPG can reduce the size of a photographic image by 70% to 90% compared to PNG, depending on image complexity and the quality settings applied.',
124
+ html: 'You might wonder how images are converted without a server. The process leverages modern browser APIs. When you select a file, a local Blob is instantiated in your RAM and drawn onto an invisible HTML5 Canvas element.',
84
125
  },
85
126
  {
86
127
  type: 'paragraph',
87
- html:
88
- 'Typical use cases for converting PNG to JPG include: preparing images for email where size matters, optimizing product photos for online stores, reducing screenshot weight before sharing, and compressing images for faster web page loading.',
128
+ html: 'Since JPG does not support alpha channels, our algorithm fills transparent areas with a solid white background before rendering. The canvas exports a native JPEG byte stream directly to your device storage.',
129
+ },
130
+ {
131
+ type: 'tip',
132
+ title: 'SEO Performance Tip',
133
+ html: 'Search engines penalize slow websites. Converting a 2MB hero PNG into a 200KB JPG significantly improves Largest Contentful Paint (LCP) and PageSpeed metrics without noticeable visual loss.',
134
+ },
135
+ {
136
+ type: 'title',
137
+ text: 'Security for Enterprise & Sensitive Data',
138
+ level: 3,
89
139
  },
90
140
  {
91
141
  type: 'paragraph',
92
- html:
93
- 'Privacy is a priority in our tool. Unlike online converters that upload your files to remote servers, our converter processes everything locally on your device. Your images never leave your computer, which is especially important for corporate documents, personal photos, or any sensitive material.',
142
+ html: 'For financial, medical, or legal professionals, uploading files to third-party conversion sites is a compliance risk. Our local web worker model operates in an isolated environment where data vanishes when the tab closes.',
143
+ },
144
+ {
145
+ type: 'title',
146
+ text: 'Output Format Compatibility',
147
+ level: 3,
148
+ },
149
+ {
150
+ type: 'list',
151
+ icon: 'mdi:check-circle',
152
+ items: [
153
+ 'Built-in image viewers on Windows, macOS, iOS and Android.',
154
+ 'Social platforms (Instagram, LinkedIn, X, Facebook).',
155
+ 'Office productivity suites (Microsoft Office, Google Workspace).',
156
+ 'Content Management Systems (WordPress, Shopify, Webflow).',
157
+ ],
158
+ },
159
+ {
160
+ type: 'title',
161
+ text: 'Conclusion: Optimize Like a Pro',
162
+ level: 3,
94
163
  },
95
164
  {
96
165
  type: 'paragraph',
97
- html:
98
- 'Convert PNG to JPG instantly, for free, and privately directly in your browser. No registration, no limits, and without compromising the security of your files.',
166
+ html: 'This converter is an engineering solution built for speed and privacy. Whether you are a web developer or home user, it provides the ultimate way to save bandwidth while keeping data safe.',
99
167
  },
100
168
  ];
101
169
 
102
-
103
170
  export const content: PngAJpgLocaleContent = {
104
171
  slug,
105
172
  title,