@jjlmoya/utils-diy 1.3.0 → 1.4.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 +2 -1
- package/src/category/i18n/de.ts +12 -0
- package/src/category/i18n/id.ts +12 -0
- package/src/category/i18n/it.ts +12 -0
- package/src/category/i18n/ja.ts +12 -0
- package/src/category/i18n/ko.ts +12 -0
- package/src/category/i18n/nl.ts +12 -0
- package/src/category/i18n/pl.ts +12 -0
- package/src/category/i18n/pt.ts +12 -0
- package/src/category/i18n/ru.ts +12 -0
- package/src/category/i18n/sv.ts +12 -0
- package/src/category/i18n/tr.ts +12 -0
- package/src/category/i18n/zh.ts +12 -0
- package/src/category/index.ts +13 -1
- package/src/tests/faq_count.test.ts +1 -1
- package/src/tests/i18n_coverage.test.ts +36 -0
- package/src/tests/locale_completeness.test.ts +2 -2
- package/src/tests/seo_length.test.ts +3 -0
- package/src/tests/slug_uniqueness.test.ts +58 -0
- package/src/tool/balusterCalculator/i18n/de.ts +264 -0
- package/src/tool/balusterCalculator/i18n/id.ts +264 -0
- package/src/tool/balusterCalculator/i18n/it.ts +264 -0
- package/src/tool/balusterCalculator/i18n/ja.ts +264 -0
- package/src/tool/balusterCalculator/i18n/ko.ts +264 -0
- package/src/tool/balusterCalculator/i18n/nl.ts +264 -0
- package/src/tool/balusterCalculator/i18n/pl.ts +264 -0
- package/src/tool/balusterCalculator/i18n/pt.ts +264 -0
- package/src/tool/balusterCalculator/i18n/ru.ts +264 -0
- package/src/tool/balusterCalculator/i18n/sv.ts +264 -0
- package/src/tool/balusterCalculator/i18n/tr.ts +264 -0
- package/src/tool/balusterCalculator/i18n/zh.ts +264 -0
- package/src/tool/balusterCalculator/index.ts +15 -7
- package/src/tool/clayCalculator/i18n/de.ts +183 -0
- package/src/tool/clayCalculator/i18n/id.ts +183 -0
- package/src/tool/clayCalculator/i18n/it.ts +183 -0
- package/src/tool/clayCalculator/i18n/ja.ts +182 -0
- package/src/tool/clayCalculator/i18n/ko.ts +183 -0
- package/src/tool/clayCalculator/i18n/nl.ts +183 -0
- package/src/tool/clayCalculator/i18n/pl.ts +183 -0
- package/src/tool/clayCalculator/i18n/pt.ts +183 -0
- package/src/tool/clayCalculator/i18n/ru.ts +183 -0
- package/src/tool/clayCalculator/i18n/sv.ts +183 -0
- package/src/tool/clayCalculator/i18n/tr.ts +183 -0
- package/src/tool/clayCalculator/i18n/zh.ts +183 -0
- package/src/tool/clayCalculator/index.ts +15 -7
- package/src/tool/concreteCalculator/i18n/de.ts +201 -0
- package/src/tool/concreteCalculator/i18n/id.ts +201 -0
- package/src/tool/concreteCalculator/i18n/it.ts +201 -0
- package/src/tool/concreteCalculator/i18n/ja.ts +201 -0
- package/src/tool/concreteCalculator/i18n/ko.ts +201 -0
- package/src/tool/concreteCalculator/i18n/nl.ts +201 -0
- package/src/tool/concreteCalculator/i18n/pl.ts +201 -0
- package/src/tool/concreteCalculator/i18n/pt.ts +201 -0
- package/src/tool/concreteCalculator/i18n/ru.ts +201 -0
- package/src/tool/concreteCalculator/i18n/sv.ts +201 -0
- package/src/tool/concreteCalculator/i18n/tr.ts +201 -0
- package/src/tool/concreteCalculator/i18n/zh.ts +201 -0
- package/src/tool/concreteCalculator/index.ts +17 -5
- package/src/tool/cutOptimizer/i18n/de.ts +178 -0
- package/src/tool/cutOptimizer/i18n/id.ts +178 -0
- package/src/tool/cutOptimizer/i18n/it.ts +178 -0
- package/src/tool/cutOptimizer/i18n/ja.ts +178 -0
- package/src/tool/cutOptimizer/i18n/ko.ts +178 -0
- package/src/tool/cutOptimizer/i18n/nl.ts +178 -0
- package/src/tool/cutOptimizer/i18n/pl.ts +178 -0
- package/src/tool/cutOptimizer/i18n/pt.ts +178 -0
- package/src/tool/cutOptimizer/i18n/ru.ts +178 -0
- package/src/tool/cutOptimizer/i18n/sv.ts +178 -0
- package/src/tool/cutOptimizer/i18n/tr.ts +178 -0
- package/src/tool/cutOptimizer/i18n/zh.ts +178 -0
- package/src/tool/cutOptimizer/index.ts +17 -5
- package/src/tool/drillCalculator/i18n/de.ts +137 -0
- package/src/tool/drillCalculator/i18n/id.ts +137 -0
- package/src/tool/drillCalculator/i18n/it.ts +137 -0
- package/src/tool/drillCalculator/i18n/ja.ts +137 -0
- package/src/tool/drillCalculator/i18n/ko.ts +137 -0
- package/src/tool/drillCalculator/i18n/nl.ts +137 -0
- package/src/tool/drillCalculator/i18n/pl.ts +137 -0
- package/src/tool/drillCalculator/i18n/pt.ts +137 -0
- package/src/tool/drillCalculator/i18n/ru.ts +137 -0
- package/src/tool/drillCalculator/i18n/sv.ts +137 -0
- package/src/tool/drillCalculator/i18n/tr.ts +137 -0
- package/src/tool/drillCalculator/i18n/zh.ts +137 -0
- package/src/tool/drillCalculator/index.ts +17 -5
- package/src/tool/drillSharpener/i18n/de.ts +120 -0
- package/src/tool/drillSharpener/i18n/id.ts +120 -0
- package/src/tool/drillSharpener/i18n/it.ts +120 -0
- package/src/tool/drillSharpener/i18n/ja.ts +120 -0
- package/src/tool/drillSharpener/i18n/ko.ts +120 -0
- package/src/tool/drillSharpener/i18n/nl.ts +120 -0
- package/src/tool/drillSharpener/i18n/pl.ts +120 -0
- package/src/tool/drillSharpener/i18n/pt.ts +120 -0
- package/src/tool/drillSharpener/i18n/ru.ts +120 -0
- package/src/tool/drillSharpener/i18n/sv.ts +120 -0
- package/src/tool/drillSharpener/i18n/tr.ts +120 -0
- package/src/tool/drillSharpener/i18n/zh.ts +120 -0
- package/src/tool/drillSharpener/index.ts +17 -5
- package/src/tool/epoxyCalculator/i18n/de.ts +118 -0
- package/src/tool/epoxyCalculator/i18n/id.ts +118 -0
- package/src/tool/epoxyCalculator/i18n/it.ts +118 -0
- package/src/tool/epoxyCalculator/i18n/ja.ts +118 -0
- package/src/tool/epoxyCalculator/i18n/ko.ts +118 -0
- package/src/tool/epoxyCalculator/i18n/nl.ts +118 -0
- package/src/tool/epoxyCalculator/i18n/pl.ts +118 -0
- package/src/tool/epoxyCalculator/i18n/pt.ts +118 -0
- package/src/tool/epoxyCalculator/i18n/ru.ts +118 -0
- package/src/tool/epoxyCalculator/i18n/sv.ts +118 -0
- package/src/tool/epoxyCalculator/i18n/tr.ts +118 -0
- package/src/tool/epoxyCalculator/i18n/zh.ts +118 -0
- package/src/tool/epoxyCalculator/index.ts +15 -7
- package/src/tool/furnitureFit/i18n/de.ts +113 -0
- package/src/tool/furnitureFit/i18n/id.ts +113 -0
- package/src/tool/furnitureFit/i18n/it.ts +113 -0
- package/src/tool/furnitureFit/i18n/ja.ts +113 -0
- package/src/tool/furnitureFit/i18n/ko.ts +113 -0
- package/src/tool/furnitureFit/i18n/nl.ts +113 -0
- package/src/tool/furnitureFit/i18n/pl.ts +113 -0
- package/src/tool/furnitureFit/i18n/pt.ts +113 -0
- package/src/tool/furnitureFit/i18n/ru.ts +113 -0
- package/src/tool/furnitureFit/i18n/sv.ts +113 -0
- package/src/tool/furnitureFit/i18n/tr.ts +113 -0
- package/src/tool/furnitureFit/i18n/zh.ts +113 -0
- package/src/tool/furnitureFit/index.ts +17 -5
- package/src/tool/mortarCalculator/i18n/de.ts +129 -0
- package/src/tool/mortarCalculator/i18n/id.ts +129 -0
- package/src/tool/mortarCalculator/i18n/it.ts +129 -0
- package/src/tool/mortarCalculator/i18n/ja.ts +129 -0
- package/src/tool/mortarCalculator/i18n/ko.ts +129 -0
- package/src/tool/mortarCalculator/i18n/nl.ts +129 -0
- package/src/tool/mortarCalculator/i18n/pl.ts +129 -0
- package/src/tool/mortarCalculator/i18n/pt.ts +129 -0
- package/src/tool/mortarCalculator/i18n/ru.ts +129 -0
- package/src/tool/mortarCalculator/i18n/sv.ts +129 -0
- package/src/tool/mortarCalculator/i18n/tr.ts +129 -0
- package/src/tool/mortarCalculator/i18n/zh.ts +129 -0
- package/src/tool/mortarCalculator/index.ts +17 -5
- package/src/tool/passepartoutCalculator/i18n/de.ts +108 -0
- package/src/tool/passepartoutCalculator/i18n/id.ts +108 -0
- package/src/tool/passepartoutCalculator/i18n/it.ts +108 -0
- package/src/tool/passepartoutCalculator/i18n/ja.ts +108 -0
- package/src/tool/passepartoutCalculator/i18n/ko.ts +108 -0
- package/src/tool/passepartoutCalculator/i18n/nl.ts +108 -0
- package/src/tool/passepartoutCalculator/i18n/pl.ts +108 -0
- package/src/tool/passepartoutCalculator/i18n/pt.ts +108 -0
- package/src/tool/passepartoutCalculator/i18n/ru.ts +108 -0
- package/src/tool/passepartoutCalculator/i18n/sv.ts +108 -0
- package/src/tool/passepartoutCalculator/i18n/tr.ts +108 -0
- package/src/tool/passepartoutCalculator/i18n/zh.ts +108 -0
- package/src/tool/passepartoutCalculator/index.ts +17 -5
- package/src/tool/stairCalculator/i18n/de.ts +144 -0
- package/src/tool/stairCalculator/i18n/id.ts +144 -0
- package/src/tool/stairCalculator/i18n/it.ts +144 -0
- package/src/tool/stairCalculator/i18n/ja.ts +144 -0
- package/src/tool/stairCalculator/i18n/ko.ts +144 -0
- package/src/tool/stairCalculator/i18n/nl.ts +144 -0
- package/src/tool/stairCalculator/i18n/pl.ts +144 -0
- package/src/tool/stairCalculator/i18n/pt.ts +144 -0
- package/src/tool/stairCalculator/i18n/ru.ts +144 -0
- package/src/tool/stairCalculator/i18n/sv.ts +144 -0
- package/src/tool/stairCalculator/i18n/tr.ts +144 -0
- package/src/tool/stairCalculator/i18n/zh.ts +144 -0
- package/src/tool/stairCalculator/index.ts +17 -5
- package/src/tool/thermalExpansionCalculator/i18n/de.ts +132 -0
- package/src/tool/thermalExpansionCalculator/i18n/id.ts +130 -0
- package/src/tool/thermalExpansionCalculator/i18n/it.ts +130 -0
- package/src/tool/thermalExpansionCalculator/i18n/ja.ts +130 -0
- package/src/tool/thermalExpansionCalculator/i18n/ko.ts +130 -0
- package/src/tool/thermalExpansionCalculator/i18n/nl.ts +130 -0
- package/src/tool/thermalExpansionCalculator/i18n/pl.ts +130 -0
- package/src/tool/thermalExpansionCalculator/i18n/pt.ts +130 -0
- package/src/tool/thermalExpansionCalculator/i18n/ru.ts +130 -0
- package/src/tool/thermalExpansionCalculator/i18n/sv.ts +130 -0
- package/src/tool/thermalExpansionCalculator/i18n/tr.ts +130 -0
- package/src/tool/thermalExpansionCalculator/i18n/zh.ts +130 -0
- package/src/tool/thermalExpansionCalculator/index.ts +17 -5
- package/src/tool/voltageDropCalculator/i18n/de.ts +112 -0
- package/src/tool/voltageDropCalculator/i18n/id.ts +110 -0
- package/src/tool/voltageDropCalculator/i18n/it.ts +110 -0
- package/src/tool/voltageDropCalculator/i18n/ja.ts +110 -0
- package/src/tool/voltageDropCalculator/i18n/ko.ts +110 -0
- package/src/tool/voltageDropCalculator/i18n/nl.ts +110 -0
- package/src/tool/voltageDropCalculator/i18n/pl.ts +110 -0
- package/src/tool/voltageDropCalculator/i18n/pt.ts +110 -0
- package/src/tool/voltageDropCalculator/i18n/ru.ts +110 -0
- package/src/tool/voltageDropCalculator/i18n/sv.ts +110 -0
- package/src/tool/voltageDropCalculator/i18n/tr.ts +110 -0
- package/src/tool/voltageDropCalculator/i18n/zh.ts +110 -0
- package/src/tool/voltageDropCalculator/index.ts +17 -5
- package/src/types.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jjlmoya/utils-diy",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@iconify-json/mdi": "^1.2.3",
|
|
40
|
+
"@jjlmoya/prompagate": "^1.1.0",
|
|
40
41
|
"@jjlmoya/utils-shared": "1.2.0",
|
|
41
42
|
"astro": "^6.1.2",
|
|
42
43
|
"astro-icon": "^1.1.0"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'diy',
|
|
5
|
+
title: 'Werkzeuge und Rechner für Heimwerker und Bauprojekte',
|
|
6
|
+
description: 'Planen Sie Ihre Heimwerkerprojekte mit kostenlosen Online-Tools. Rechner für Tonschrumpfung, Harzmischungen, Beton, Schnittoptimierer und Treppenlayout.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'Heimtechnik und DIY Projekte: Vom Entwurf zur Realität', level: 2 },
|
|
9
|
+
{ type: 'paragraph', html: 'Die <strong>Do-It-Yourself (DIY)</strong>-Bewegung ist kein bloßes Hobby mehr, sondern eine Form der technischen und kreativen Souveränität. In diesem Bereich bieten wir eine Reihe von <strong>kostenlosen Online-Tools</strong> an, die für Maker, Handwerker und Bauinteressierte entwickelt wurden, die professionelle Ergebnisse anstreben.' },
|
|
10
|
+
{ type: 'stats', columns: 2, items: [{ label: 'Optimierung', value: 'Material 95%+', icon: 'mdi:saw-blade' }, { label: 'Sicherheit', value: 'Normgerecht', icon: 'mdi:ruler-square' }, { label: 'Materialien', value: 'Wiederverwertung', icon: 'mdi:tools' }, { label: 'Präzision', value: 'Millimetergenau', icon: 'mdi:calculator' }] },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'diy',
|
|
5
|
+
title: 'Alat dan Kalkulator untuk Proyek DIY dan Konstruksi',
|
|
6
|
+
description: 'Rencanakan proyek DIY Anda dengan alat online gratis. Kalkulator penyusutan tanah liat, campuran resin, beton, pengoptimal pemotongan, dan tata letak tangga.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'Teknik Rumahan dan Proyek DIY: Dari Desain ke Realitas', level: 2 },
|
|
9
|
+
{ type: 'paragraph', html: 'Gerakan <strong>Do It Yourself (DIY)</strong> bukan lagi sekadar hobi, melainkan bentuk kedaulatan teknis dan kreatif. Di bagian ini, kami menyediakan serangkaian <strong>alat online gratis</strong> yang dirancang untuk maker, pengrajin, dan penggemar konstruksi yang mencari hasil profesional.' },
|
|
10
|
+
{ type: 'stats', columns: 2, items: [{ label: 'Optimasi', value: 'Material 95%+', icon: 'mdi:saw-blade' }, { label: 'Keamanan', value: 'Sesuai Standar', icon: 'mdi:ruler-square' }, { label: 'Material', value: 'Pemulihan', icon: 'mdi:tools' }, { label: 'Presisi', value: 'Milimetrik', icon: 'mdi:calculator' }] },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'diy',
|
|
5
|
+
title: 'Strumenti e Calcolatori per Progetti DIY e Costruzione',
|
|
6
|
+
description: 'Pianifica i tuoi progetti fai da te con strumenti online gratuiti. Calcolatori per il ritiro dell\'argilla, miscele di resina, cemento, ottimizzatori di taglio e layout scale.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'Ingegneria Domestica e Progetti DIY: Dal Design alla Realtà', level: 2 },
|
|
9
|
+
{ type: 'paragraph', html: 'Il movimento <strong>Do It Yourself (DIY)</strong> non è più un semplice hobby ma una forma di sovranità tecnica e creativa. In questa sezione, forniamo una suite di <strong>strumenti online gratuiti</strong> progettati per maker, artigiani e appassionati di costruzioni che cercano risultati professionali.' },
|
|
10
|
+
{ type: 'stats', columns: 2, items: [{ label: 'Ottimizzazione', value: 'Materiale 95%+', icon: 'mdi:saw-blade' }, { label: 'Sicurezza', value: 'Normativa', icon: 'mdi:ruler-square' }, { label: 'Materiali', value: 'Recupero', icon: 'mdi:tools' }, { label: 'Precisione', value: 'Millimetrica', icon: 'mdi:calculator' }] },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'diy',
|
|
5
|
+
title: 'DIY・建設プロジェクト向けツールと計算機',
|
|
6
|
+
description: '無料のオンラインツールでDIYプロジェクトを計画しましょう。粘土の収縮、レジン混合、コンクリート、カット最適化、階段の設計などの計算機。',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'ホームエンジニアリングとDIYプロジェクト:設計から実現まで', level: 2 },
|
|
9
|
+
{ type: 'paragraph', html: '<strong>DIY (Do It Yourself)</strong> ムーブメントは、単なる趣味ではなく、技術的および創造的な自立の形へと進化しました。このセクションでは、プロフェッショナルな結果を求めるメーカー、職人、建設愛好家向けに設計された一連の<strong>無料オンラインツール</strong>を提供しています。' },
|
|
10
|
+
{ type: 'stats', columns: 2, items: [{ label: '最適化', value: '材料利用率 95%+', icon: 'mdi:saw-blade' }, { label: '安全性', value: '規格準拠', icon: 'mdi:ruler-square' }, { label: '材料', value: '再利用', icon: 'mdi:tools' }, { label: '精度', value: 'ミリ単位', icon: 'mdi:calculator' }] },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'diy',
|
|
5
|
+
title: 'DIY 및 건설 프로젝트를 위한 도구와 계산기',
|
|
6
|
+
description: '무료 온라인 도구로 DIY 프로젝트를 계획하세요. 점토 수축, 레진 혼합, 콘크리트, 절단 최적화 및 계단 레이아웃 계산기.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: '홈 엔지니어링 및 DIY 프로젝트: 설계에서 현실까지', level: 2 },
|
|
9
|
+
{ type: 'paragraph', html: '<strong>DIY (Do It Yourself)</strong> 운동은 더 이상 단순한 취미가 아니라 기술적, 창의적 자립의 형태가 되었습니다. 이 섹션에서는 전문적인 결과를 원하는 메이커, 장인 및 건설 애호가들을 위해 설계된 일련의 <strong>무료 온라인 도구</strong>를 제공합니다.' },
|
|
10
|
+
{ type: 'stats', columns: 2, items: [{ label: '최적화', value: '자재 95%+', icon: 'mdi:saw-blade' }, { label: '안전', value: '규격 준수', icon: 'mdi:ruler-square' }, { label: '자재', value: '재활용', icon: 'mdi:tools' }, { label: '정밀도', value: '밀리미터 단위', icon: 'mdi:calculator' }] },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'diy',
|
|
5
|
+
title: 'Tools en Calculators voor DIY en Bouwprojecten',
|
|
6
|
+
description: 'Plan je DIY projecten met gratis online tools. Calculators voor kleikrimp, harsmengsels, beton, zaagoptimalisatie en trappenlay-out.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'Thuisengineering en DIY projecten: Van Ontwerp tot Realiteit', level: 2 },
|
|
9
|
+
{ type: 'paragraph', html: 'De <strong>Do It Yourself (DIY)</strong> beweging is niet langer een simpele hobby, maar een vorm van technische en creatieve soevereiniteit. In deze sectie bieden we een reeks <strong>gratis online tools</strong> aan, ontworpen voor makers, ambachtslieden en bouwliefhebbers die op zoek zijn naar professionele resultaten.' },
|
|
10
|
+
{ type: 'stats', columns: 2, items: [{ label: 'Optimalisatie', value: 'Materiaal 95%+', icon: 'mdi:saw-blade' }, { label: 'Veiligheid', value: 'Volgens Normen', icon: 'mdi:ruler-square' }, { label: 'Materialen', value: 'Hergebruik', icon: 'mdi:tools' }, { label: 'Precisie', value: 'Millimeternauwkeurig', icon: 'mdi:calculator' }] },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'diy',
|
|
5
|
+
title: 'Narzędzia i Kalkulatory dla Projektów DIY i Budowlanych',
|
|
6
|
+
description: 'Zaplanuj swoje projekty DIY dzięki darmowym narzędziom online. Kalkulatory skurczu gliny, mieszanek żywicy, betonu, optymalizatory cięcia i tyczenia schodów.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'Inżynieria domowa i projekty DIY: Od projektu do rzeczywistości', level: 2 },
|
|
9
|
+
{ type: 'paragraph', html: 'Ruch <strong>Do It Yourself (DIY)</strong> przestał być zwykłym hobby, stając się formą technicznej i kreatywnej suwerenności. W tej sekcji udostępniamy zestaw <strong>darmowych narzędzi online</strong> zaprojektowanych dla twórców, rzemieślników i entuzjastów budownictwa szukających profesjonalnych efektów.' },
|
|
10
|
+
{ type: 'stats', columns: 2, items: [{ label: 'Optymalizacja', value: 'Materiał 95%+', icon: 'mdi:saw-blade' }, { label: 'Bezpieczeństwo', value: 'Zgodne z Normatywami', icon: 'mdi:ruler-square' }, { label: 'Materiały', value: 'Odzysk', icon: 'mdi:tools' }, { label: 'Precyzja', value: 'Milimetrowa', icon: 'mdi:calculator' }] },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'diy',
|
|
5
|
+
title: 'Ferramentas e Calculadoras para Projetos DIY e Construção',
|
|
6
|
+
description: 'Planeie os seus projetos de bricolage com ferramentas online gratuitas. Calculadoras de contração de argila, misturas de resina, betão, otimizadores de corte e traçado de escadas.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'Engenharia Doméstica e Projetos DIY: Do Design à Realidade', level: 2 },
|
|
9
|
+
{ type: 'paragraph', html: 'O movimento <strong>Do It Yourself (DIY)</strong> deixou de ser um simples passatempo para se tornar uma forma de soberania técnica e criativa. Nesta secção, fornecemos uma suite de <strong>ferramentas online gratuitas</strong> concebidas para makers, artesãos e entusiastas da construção que procuram resultados profissionais.' },
|
|
10
|
+
{ type: 'stats', columns: 2, items: [{ label: 'Otimização', value: 'Material 95%+', icon: 'mdi:saw-blade' }, { label: 'Segurança', value: 'Normativa', icon: 'mdi:ruler-square' }, { label: 'Materiais', value: 'Recuperação', icon: 'mdi:tools' }, { label: 'Precisão', value: 'Milimétrica', icon: 'mdi:calculator' }] },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'diy',
|
|
5
|
+
title: 'Инструменты и калькуляторы для DIY и строительных проектов',
|
|
6
|
+
description: 'Планируйте свои DIY-проекты с помощью бесплатных онлайн-инструментов. Калькуляторы усадки глины, смесей смол, бетона, оптимизаторы резки и планировка лестниц.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'Домашняя инженерия и DIY-проекты: от идеи к реальности', level: 2 },
|
|
9
|
+
{ type: 'paragraph', html: 'Движение <strong>Do It Yourself (DIY)</strong> перестало быть просто хобби, превратившись в форму технического и творческого суверенитета. В этом разделе мы предоставляем набор <strong>бесплатных онлайн-инструментов</strong>, разработанных для мейкеров, мастеров и любителей строительства, стремящихся к профессиональным результатам.' },
|
|
10
|
+
{ type: 'stats', columns: 2, items: [{ label: 'Оптимизация', value: 'Материал 95%+', icon: 'mdi:saw-blade' }, { label: 'Безопасность', value: 'Нормативы', icon: 'mdi:ruler-square' }, { label: 'Материалы', value: 'Восстановление', icon: 'mdi:tools' }, { label: 'Точность', value: 'Миллиметровая', icon: 'mdi:calculator' }] },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'diy',
|
|
5
|
+
title: 'Verktyg och kalkylatorer för DIY och byggprojekt',
|
|
6
|
+
description: 'Planera dina DIY projekt med kostnadsfria onlineverktyg. Kalkylatorer för lerkrympning, hartsmixer, betong, skäroptimerare och trapplayout.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'Hemteknik och DIY projekt: Från design till verklighet', level: 2 },
|
|
9
|
+
{ type: 'paragraph', html: '<strong>Do It Yourself (DIY)</strong>-rörelsen är inte längre bara en hobby utan en form av teknisk och kreativ självständighet. I den här sektionen tillhandahåller vi en uppsättning <strong>kostnadsfria onlineverktyg</strong> designade för makare, hantverkare och byggentusiaster som söker professionella resultat.' },
|
|
10
|
+
{ type: 'stats', columns: 2, items: [{ label: 'Optimering', value: 'Material 95%+', icon: 'mdi:saw-blade' }, { label: 'Säkerhet', value: 'Enligt Standard', icon: 'mdi:ruler-square' }, { label: 'Material', value: 'Återvinning', icon: 'mdi:tools' }, { label: 'Precision', value: 'Millimeterprecision', icon: 'mdi:calculator' }] },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'diy',
|
|
5
|
+
title: 'Kendin Yap (DIY) ve İnşaat Projeleri için Araçlar ve Hesaplayıcılar',
|
|
6
|
+
description: 'Ücretsiz çevrimiçi araçlarla DIY projelerinizi planlayın. Kil çekmesi, reçine karışımları, beton, kesim optimizasyonu ve merdiven düzeni hesaplayıcıları.',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: 'Ev Mühendisliği ve DIY Projeleri: Tasarımdan Gerçeğe', level: 2 },
|
|
9
|
+
{ type: 'paragraph', html: '<strong>Do It Yourself (DIY)</strong> hareketi artık basit bir hobiden öte, teknik ve yaratıcı bir egemenlik biçimi haline geldi. Bu bölümde, profesyonel sonuçlar arayan yapımcılar, zanaatkarlar ve inşaat meraklıları için tasarlanmış bir dizi <strong>ücretsiz çevrimiçi araç</strong> sunuyoruz.' },
|
|
10
|
+
{ type: 'stats', columns: 2, items: [{ label: 'Optimizasyon', value: 'Malzeme %95+', icon: 'mdi:saw-blade' }, { label: 'Güvenlik', value: 'Standartlara Uygun', icon: 'mdi:ruler-square' }, { label: 'Malzeme', value: 'Geri Kazanım', icon: 'mdi:tools' }, { label: 'Hassasiyet', value: 'Milimetrik', icon: 'mdi:calculator' }] },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CategoryLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const content: CategoryLocaleContent = {
|
|
4
|
+
slug: 'diy',
|
|
5
|
+
title: '针对 DIY 和建筑项目的工具与计算器',
|
|
6
|
+
description: '使用免费在线工具规划您的 DIY 项目。包含粘土收缩、树脂混合、混凝土、切割优化和楼梯布局等计算器。',
|
|
7
|
+
seo: [
|
|
8
|
+
{ type: 'title', text: '居家工程与 DIY 项目:从设计到现实', level: 2 },
|
|
9
|
+
{ type: 'paragraph', html: '<strong>DIY (Do It Yourself)</strong> 运动已不再仅仅是一种简单的爱好,而是一种技术和创造力的自主形式。在本节中,我们为寻求专业效果的高手、工匠和建筑爱好者提供了一系列<strong>免费在线工具</strong>。' },
|
|
10
|
+
{ type: 'stats', columns: 2, items: [{ label: '优化', value: '材料利用 95%+', icon: 'mdi:saw-blade' }, { label: '安全', value: '符合标准', icon: 'mdi:ruler-square' }, { label: '材料', value: '回收利用', icon: 'mdi:tools' }, { label: '精度', value: '毫米级', icon: 'mdi:calculator' }] },
|
|
11
|
+
],
|
|
12
|
+
};
|
package/src/category/index.ts
CHANGED
|
@@ -17,9 +17,21 @@ export const diyCategory: DiyCategoryEntry = {
|
|
|
17
17
|
icon: 'mdi:hand',
|
|
18
18
|
tools: [clayCalculator, epoxyCalculator, balusterCalculator, mortarCalculator, passepartoutCalculator, concreteCalculator, cutOptimizer, voltageDropCalculator, furnitureFit, thermalExpansionCalculator, drillCalculator, stairCalculator, drillSharpener],
|
|
19
19
|
i18n: {
|
|
20
|
-
|
|
20
|
+
de: () => import('./i18n/de').then((m) => m.content),
|
|
21
21
|
en: () => import('./i18n/en').then((m) => m.content),
|
|
22
|
+
es: () => import('./i18n/es').then((m) => m.content),
|
|
22
23
|
fr: () => import('./i18n/fr').then((m) => m.content),
|
|
24
|
+
id: () => import('./i18n/id').then((m) => m.content),
|
|
25
|
+
it: () => import('./i18n/it').then((m) => m.content),
|
|
26
|
+
ja: () => import('./i18n/ja').then((m) => m.content),
|
|
27
|
+
ko: () => import('./i18n/ko').then((m) => m.content),
|
|
28
|
+
nl: () => import('./i18n/nl').then((m) => m.content),
|
|
29
|
+
pl: () => import('./i18n/pl').then((m) => m.content),
|
|
30
|
+
pt: () => import('./i18n/pt').then((m) => m.content),
|
|
31
|
+
ru: () => import('./i18n/ru').then((m) => m.content),
|
|
32
|
+
sv: () => import('./i18n/sv').then((m) => m.content),
|
|
33
|
+
tr: () => import('./i18n/tr').then((m) => m.content),
|
|
34
|
+
zh: () => import('./i18n/zh').then((m) => m.content),
|
|
23
35
|
},
|
|
24
36
|
};
|
|
25
37
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import type * as DATA from '../data';
|
|
3
3
|
|
|
4
|
-
const TOOLS: typeof DATA.
|
|
4
|
+
const TOOLS: typeof DATA.audiovisualCategory[] = [];
|
|
5
5
|
|
|
6
6
|
describe('FAQ Content Validation', () => {
|
|
7
7
|
TOOLS.forEach((entry) => {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { ALL_TOOLS } from '../tools';
|
|
3
|
+
|
|
4
|
+
const EXPECTED_LOCALES = [
|
|
5
|
+
'de', 'en', 'es', 'fr', 'id', 'it', 'ja', 'ko', 'nl', 'pl', 'pt', 'ru', 'sv', 'tr', 'zh'
|
|
6
|
+
];
|
|
7
|
+
|
|
8
|
+
describe('I18n Coverage Validation', () => {
|
|
9
|
+
it('all tools should be registered', () => {
|
|
10
|
+
expect(ALL_TOOLS.length).toBeGreaterThan(0);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
ALL_TOOLS.forEach(({ entry }: { entry: any }) => {
|
|
14
|
+
describe(`Tool: ${entry.id}`, () => {
|
|
15
|
+
it('should have all 15 required locales', () => {
|
|
16
|
+
const registeredLocales = Object.keys(entry.i18n);
|
|
17
|
+
EXPECTED_LOCALES.forEach((locale) => {
|
|
18
|
+
expect(
|
|
19
|
+
registeredLocales,
|
|
20
|
+
`Tool "${entry.id}" is missing locale "${locale}"`,
|
|
21
|
+
).toContain(locale);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('all locale loaders should be functions', () => {
|
|
26
|
+
EXPECTED_LOCALES.forEach((locale) => {
|
|
27
|
+
const loader = entry.i18n[locale as keyof typeof entry.i18n];
|
|
28
|
+
expect(
|
|
29
|
+
typeof loader,
|
|
30
|
+
`Tool "${entry.id}" locale "${locale}" loader is not a function`,
|
|
31
|
+
).toBe('function');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -35,8 +35,8 @@ describe('Locale Completeness Validation', () => {
|
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
it('
|
|
39
|
-
expect(ALL_TOOLS.length).
|
|
38
|
+
it('all 13 tools registered', () => {
|
|
39
|
+
expect(ALL_TOOLS.length).toBe(13);
|
|
40
40
|
});
|
|
41
41
|
});
|
|
42
42
|
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import * as DATA from '../data';
|
|
3
3
|
|
|
4
|
+
import { ALL_TOOLS } from '../tools';
|
|
5
|
+
|
|
4
6
|
const ENTRIES = [
|
|
5
7
|
{ id: 'diyCategory', i18n: DATA.diyCategory.i18n },
|
|
8
|
+
...ALL_TOOLS.map(tool => ({ id: tool.entry.id, i18n: tool.entry.i18n }))
|
|
6
9
|
];
|
|
7
10
|
|
|
8
11
|
describe('SEO Content Length Validation', () => {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { ALL_TOOLS } from '../tools';
|
|
3
|
+
import type { ToolLocaleContent } from '../types';
|
|
4
|
+
|
|
5
|
+
describe('Slug Localization and Uniqueness Validation', () => {
|
|
6
|
+
ALL_TOOLS.forEach((tool) => {
|
|
7
|
+
describe(`Tool: ${tool.entry.id}`, () => {
|
|
8
|
+
it('every locale should have a unique, translated slug', async () => {
|
|
9
|
+
const slugs = new Map<string, string>();
|
|
10
|
+
const locales = Object.keys(tool.entry.i18n);
|
|
11
|
+
|
|
12
|
+
let enSlug = '';
|
|
13
|
+
if (locales.includes('en')) {
|
|
14
|
+
const enLoader = tool.entry.i18n['en' as keyof typeof tool.entry.i18n];
|
|
15
|
+
const enContent = (await enLoader?.()) as ToolLocaleContent;
|
|
16
|
+
enSlug = enContent.slug;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const sharingLocales = ['ja', 'ko', 'zh'];
|
|
20
|
+
|
|
21
|
+
for (const locale of locales) {
|
|
22
|
+
const loader = tool.entry.i18n[locale as keyof typeof tool.entry.i18n];
|
|
23
|
+
const content = (await loader?.()) as ToolLocaleContent;
|
|
24
|
+
|
|
25
|
+
expect(
|
|
26
|
+
content.slug,
|
|
27
|
+
`Tool "${tool.entry.id}" locale "${locale}" has an invalid slug ("${content.slug}"). Slugs must be transliterated (only a-z, 0-9, and -).`,
|
|
28
|
+
).toMatch(/^[a-z0-9-]+$/);
|
|
29
|
+
|
|
30
|
+
if (locale === 'en') {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (sharingLocales.includes(locale)) {
|
|
35
|
+
expect(
|
|
36
|
+
content.slug,
|
|
37
|
+
`Tool "${tool.entry.id}" locale "${locale}" must use the same slug as "en" ("${enSlug}").`,
|
|
38
|
+
).toBe(enSlug);
|
|
39
|
+
} else {
|
|
40
|
+
expect(
|
|
41
|
+
content.slug,
|
|
42
|
+
`Tool "${tool.entry.id}" locale "${locale}" has the same slug as "en" ("${enSlug}"). Cada slug tiene que estar en su propia idioma`,
|
|
43
|
+
).not.toBe(enSlug);
|
|
44
|
+
|
|
45
|
+
const previousLocale = slugs.get(content.slug);
|
|
46
|
+
if (previousLocale) {
|
|
47
|
+
expect(
|
|
48
|
+
false,
|
|
49
|
+
`Tool "${tool.entry.id}" locales "${locale}" and "${previousLocale}" share the same slug ("${content.slug}"). Cada slug tiene que estar en su propia idioma`,
|
|
50
|
+
).toBe(true);
|
|
51
|
+
}
|
|
52
|
+
slugs.set(content.slug, locale);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { BalusterCalculatorUI } from '../ui';
|
|
4
|
+
|
|
5
|
+
const slug = 'baluster-rechner';
|
|
6
|
+
const title = 'Baluster Rechner: Exakter Abstand für Geländer';
|
|
7
|
+
const description =
|
|
8
|
+
'Berechnen Sie den exakten Abstand zwischen Stäben oder Balustern für Geländer unter Einhaltung der 10-cm-Regel. Automatische Pläne.';
|
|
9
|
+
|
|
10
|
+
const faqData = [
|
|
11
|
+
{
|
|
12
|
+
question: 'Was ist der gesetzliche Maximalabstand zwischen Balustern?',
|
|
13
|
+
answer:
|
|
14
|
+
'In den meisten internationalen Bauvorschriften darf der lichte Abstand zwischen den Elementen eines Geländers den Durchgang einer Kugel mit 10 cm Durchmesser nicht zulassen, um Unfälle mit Kindern zu vermeiden.',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
question: 'Wie wird der Abstand gemessen: zwischen den Mitten oder den Lücken?',
|
|
18
|
+
answer:
|
|
19
|
+
"Unser Rechner liefert beides. Der 'lichte Abstand' ist die tatsächliche Lücke zwischen den Stäben (entscheidend für die Sicherheit), während der 'Mittenabstand' (on-center) angibt, wo jeder Baluster gebohrt oder befestigt werden muss.",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
question: 'Was passiert, wenn die Verteilung nicht exakt aufgeht?',
|
|
23
|
+
answer:
|
|
24
|
+
'Der Rechner passt die Anzahl der Stäbe automatisch so an, dass die erste und die letzte Lücke identisch sind, was visuelle Symmetrie und die strikte Einhaltung der maximal zulässigen Lücke garantiert.',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
question: 'Ist es besser, Baluster zu schweißen oder zu schrauben?',
|
|
28
|
+
answer:
|
|
29
|
+
'Das hängt vom Material ab. Bei Stahl bietet Schweißen maximale strukturelle Steifigkeit. Bei Holz oder Aluminium werden mechanische Verankerungen oder durchgehende Schrauben verwendet. Wichtig ist, dass das Geländer einer horizontalen Kraft von mindestens 0,8 kN/m standhält.',
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
const howToData = [
|
|
34
|
+
{
|
|
35
|
+
name: 'Gesamtlänge messen',
|
|
36
|
+
text: 'Messen Sie den exakten Abstand zwischen dem ersten und dem letzten Pfosten, an dem das Geländer installiert wird.',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'Balusterbreite definieren',
|
|
40
|
+
text: 'Messen Sie die Breite eines einzelnen Stabes (z. B. 2x2 cm bei Quadratrohr oder den Durchmesser bei Rundstäben).',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'Maximale Lücke festlegen',
|
|
44
|
+
text: 'Geben Sie den gewünschten maximalen Abstand an (empfohlen sind 10 cm zur Einhaltung der Vorschriften).',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'Installationsmarkierungen erhalten',
|
|
48
|
+
text: 'Überprüfen Sie die Liste der exakten Positionen für die Bohrungen, um eine symmetrische und sichere Verteilung zu gewährleisten.',
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
53
|
+
'@context': 'https://schema.org',
|
|
54
|
+
'@type': 'FAQPage',
|
|
55
|
+
mainEntity: faqData.map((item) => ({
|
|
56
|
+
'@type': 'Question',
|
|
57
|
+
name: item.question,
|
|
58
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
59
|
+
})),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const howToSchema: WithContext<HowToThing> = {
|
|
63
|
+
'@context': 'https://schema.org',
|
|
64
|
+
'@type': 'HowTo',
|
|
65
|
+
name: title,
|
|
66
|
+
description,
|
|
67
|
+
step: howToData.map((step, i) => ({
|
|
68
|
+
'@type': 'HowToStep',
|
|
69
|
+
position: i + 1,
|
|
70
|
+
name: step.name,
|
|
71
|
+
text: step.text,
|
|
72
|
+
})),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
76
|
+
'@context': 'https://schema.org',
|
|
77
|
+
'@type': 'SoftwareApplication',
|
|
78
|
+
name: title,
|
|
79
|
+
description,
|
|
80
|
+
applicationCategory: 'UtilityApplication',
|
|
81
|
+
operatingSystem: 'All',
|
|
82
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
83
|
+
inLanguage: 'de',
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const content: ToolLocaleContent<BalusterCalculatorUI> = {
|
|
87
|
+
slug,
|
|
88
|
+
title,
|
|
89
|
+
description,
|
|
90
|
+
faqTitle: 'Häufig gestellte Fragen',
|
|
91
|
+
faq: faqData,
|
|
92
|
+
bibliographyTitle: 'Technische Referenzen',
|
|
93
|
+
bibliography: [
|
|
94
|
+
{
|
|
95
|
+
name: 'DIN 18065 - Treppenmaße und Geländer (Deutschland)',
|
|
96
|
+
url: 'https://www.beuth.de/de/norm/din-18065/324683526',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'IRC - International Residential Code (USA)',
|
|
100
|
+
url: 'https://codes.iccsafe.org/content/IRC2021',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'IBC - International Building Code',
|
|
104
|
+
url: 'https://codes.iccsafe.org/content/IBC2021',
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
howTo: howToData,
|
|
108
|
+
schemas: [faqSchema, howToSchema, appSchema],
|
|
109
|
+
seo: [
|
|
110
|
+
{
|
|
111
|
+
type: 'title',
|
|
112
|
+
text: 'Ultimativer Leitfaden: So berechnen Sie den Balusterabstand für Geländer',
|
|
113
|
+
level: 2,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
type: 'paragraph',
|
|
117
|
+
html: 'Die Gestaltung eines sicheren und ästhetisch perfekten Geländers ist eine Kunst, die mathematische Präzision mit Bauvorschriften kombiniert. Ob für eine Terrasse, einen Balkon oder eine Innentreppe, die korrekte Berechnung der Baluster (oder Stäbe) ist der kritischste Schritt des Projekts. Ein Rechenfehler ruiniert nicht nur die visuelle Symmetrie, sondern kann Ihre Struktur illegal und unsicher machen.',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
type: 'card',
|
|
121
|
+
icon: 'mdi:alert-circle-outline',
|
|
122
|
+
title: 'Warum ist diese Berechnung so wichtig?',
|
|
123
|
+
html: '<p>Es geht nicht nur darum, eine Lücke zu füllen. Es geht um die Einhaltung der <strong>4-Zoll-Kugel-Regel (10 cm)</strong>, einer internationalen Sicherheitsnorm zur Vermeidung von Unfällen mit Kindern.</p>',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
type: 'title',
|
|
127
|
+
text: '1. Sicherheitsvorschriften: Die 10-cm-Regel',
|
|
128
|
+
level: 3,
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
type: 'paragraph',
|
|
132
|
+
html: 'Bevor Sie das erste Stück Holz oder Metall schneiden, müssen Sie das „Warum“ hinter der Mathematik verstehen. Die Bauvorschriften in vielen Ländern, wie auch der IRC (International Residential Code) in den USA, legen eine klare Norm fest: <em>„Der lichte Abstand zwischen vertikalen Elementen darf den Durchgang einer Kugel mit 10 cm (4 Zoll) Durchmesser nicht zulassen.“</em>',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
type: 'paragraph',
|
|
136
|
+
html: 'Dieses Maß ist nicht willkürlich. Es ist der durchschnittliche Kopfdurchmesser eines Kleinkindes (normalerweise unter einem Jahr). Wenn ein Kind mit dem Körper hindurchkommt, aber der Kopf stecken bleibt, ist das Erstickungsrisiko extrem hoch. Wenn es mit dem Kopf hindurchkommt, kann es in die Tiefe stürzen. Daher ist das Ziel unseres <strong>Baluster-Rechners</strong> nicht nur die Ästhetik, sondern das Retten von Leben.',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
type: 'title',
|
|
140
|
+
text: '2. Das mathematische Problem: Der Zaunpfostenfehler',
|
|
141
|
+
level: 3,
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
type: 'paragraph',
|
|
145
|
+
html: 'In der Programmierung und im Bauwesen gibt es ein klassisches Problem namens <em>„Fencepost Error“</em> (Zaunpfostenfehler). Wenn Sie einen 10 Meter langen Zaun mit Pfosten alle 1 Meter bauen wollen, wie viele Pfosten benötigen Sie? Die intuitive Antwort ist 10, aber die richtige ist 11.',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
type: 'paragraph',
|
|
149
|
+
html: 'Bei Balustern ist es ähnlich, aber komplexer, da die Breite des Balusters selbst Platz beansprucht. Die Formel, die unser Tool verwendet, löst dieses Gleichungssystem für Sie:',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
type: 'grid',
|
|
153
|
+
columns: [
|
|
154
|
+
{
|
|
155
|
+
type: 'card',
|
|
156
|
+
icon: 'mdi:calculator',
|
|
157
|
+
title: 'Schritt A: Lücken berechnen',
|
|
158
|
+
html: '<p class="bc-formula">n = (L - g_max) / (w + g_max)</p><p>Zuerst bestimmen wir, wie viele Baluster theoretisch passen würden, wenn wir den maximal zulässigen Raum nutzen würden. Wir runden diese Zahl auf, um sicherzustellen, dass die resultierenden Lücken <em>kleiner</em> als das Maximum sind.</p>',
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: 'card',
|
|
162
|
+
icon: 'mdi:function-variant',
|
|
163
|
+
title: 'Schritt B: Exakten Abstand neuberechnen',
|
|
164
|
+
html: '<p class="bc-formula">g = (L - n × w) / (n + 1)</p><p>Sobald wir die exakte Anzahl der Baluster (n) kennen, berechnen wir, wie viel Platz „übrig bleibt“, wenn wir die Breite des gesamten Materials abziehen, und verteilen diesen gleichmäßig auf die Lücken (n+1).</p>',
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
type: 'title',
|
|
170
|
+
text: '3. Schritt-für-Schritt-Anleitung für die perfekte Installation',
|
|
171
|
+
level: 3,
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
type: 'paragraph',
|
|
175
|
+
html: 'Die Zahlen zu haben, ist nur die halbe Miete. Hier erklären wir, wie Sie diese Zahlen vom Papier (oder Bildschirm) in die Realität Ihres Bauprojekts übertragen.',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
type: 'title',
|
|
179
|
+
text: 'Schritt 1: Präzisionsmessung',
|
|
180
|
+
level: 3,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
type: 'paragraph',
|
|
184
|
+
html: 'Messen Sie den <strong>inneren</strong> Abstand zwischen Pfosten und Pfosten. Messen Sie nicht von der Mitte des Pfostens. Sie müssen das exakte lichte Maß kennen, das Sie füllen werden (L). Wenn Ihr Geländer mehrere Abschnitte hat, messen Sie jeden einzeln; Konstruktionen sind selten perfekt rechtwinklig, und ein Fehler von 0,5 cm kann die Symmetrie ruinieren.',
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
type: 'title',
|
|
188
|
+
text: 'Schritt 2: Die Mitte finden',
|
|
189
|
+
level: 3,
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
type: 'paragraph',
|
|
193
|
+
html: 'Der Anfängerfehler Nummer eins ist, mit dem Setzen der Baluster von einem Ende zum anderen zu beginnen. Dies führt fast immer zu einer seltsam großen oder kleinen letzten Lücke, was die visuelle Harmonie stört.<ul><li>Markieren Sie die <strong>exakte Mitte</strong> des Geländers (L / 2).</li><li>Entscheiden Sie, ob Sie in der Mitte einen <em>Baluster</em> oder eine <em>Lücke</em> haben möchten.</li><li>Wenn Sie einen Baluster in der Mitte möchten: Markieren Sie die Hälfte der Balusterbreite auf jeder Seite Ihrer Mittelmarkierung.</li><li>Wenn Sie eine Lücke in der Mitte möchten: Markieren Sie die Hälfte des Lückenabstands (g / 2) auf jeder Seite.</li></ul>',
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
type: 'title',
|
|
197
|
+
text: 'Schritt 3: Einen Abstandshalter (Spacer) anfertigen',
|
|
198
|
+
level: 3,
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
type: 'paragraph',
|
|
202
|
+
html: 'Verwenden Sie nicht für jeden Baluster das Maßband. Der kumulative menschliche Fehler wird dazu führen, dass der letzte Baluster um mehrere Zentimeter abweicht. Professionell ist es, einen Holzblock (oder zwei) mit dem exakten Maß der Lücke (g) zuzuschneiden, das Ihnen unser Rechner ausgegeben hat.',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
type: 'paragraph',
|
|
206
|
+
html: 'Verwenden Sie diesen Block als physische Schablone. Setzen Sie einen Baluster, legen Sie den Block an, setzen Sie den nächsten Baluster fest gegen den Block und fixieren Sie ihn. Dies garantiert millimetergenaue Konsistenz.',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
type: 'title',
|
|
210
|
+
text: '4. Benötigte Materialien und Werkzeuge',
|
|
211
|
+
level: 3,
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
type: 'card',
|
|
215
|
+
icon: 'mdi:tools',
|
|
216
|
+
title: 'Ausrüstung für ein professionelles Finish',
|
|
217
|
+
html: '<ul><li>Hochpräzises Maßband</li><li>Zimmermannsbleistift</li><li>Wasserwaage (für die Vertikalität)</li><li>Kappsäge (für saubere Schnitte)</li><li>Bohrer und Holzschrauben</li><li>Abstandshalter (maßgefertigt)</li></ul>',
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
type: 'title',
|
|
221
|
+
text: '5. Zusätzliche technische Fragen',
|
|
222
|
+
level: 3,
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
type: 'card',
|
|
226
|
+
icon: 'mdi:help-circle-outline',
|
|
227
|
+
title: 'Was passiert, wenn die letzte Lücke nicht passt?',
|
|
228
|
+
html: '<p>Wenn Sie unseren Rechner verwendet haben, sollte dies nicht passieren. In der realen Welt verbiegt sich jedoch Holz, und Pfosten sind nicht immer gerade. Wenn Ihnen am Ende 1-2 mm fehlen oder zu viel sind, ist das unmerklich. Wenn Ihnen 1 cm fehlt, überprüfen Sie Ihre Abstandshalter; wahrscheinlich haben Sie sich bei jedem Schritt Millimeter „eingefressen“.</p>',
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
type: 'card',
|
|
232
|
+
icon: 'mdi:shield-check-outline',
|
|
233
|
+
title: 'Kann ich die Baluster weiter auseinander setzen, wenn ich keine Kinder habe?',
|
|
234
|
+
html: '<p>Rechtlich gesehen: Nein. Die Bauvorschriften gelten für das Haus, nicht für die aktuellen Bewohner. Wenn Sie das Haus eines Tages verkaufen, wird ein Geländer außerhalb der Norm bei der Inspektion ein Problem sein. Zudem können Besucher (Nichten, Enkel) in Gefahr sein.</p>',
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
type: 'card',
|
|
238
|
+
icon: 'mdi:wrench-outline',
|
|
239
|
+
title: 'Holz, Metall oder Glas?',
|
|
240
|
+
html: '<p>Dieser Rechner funktioniert für <strong>jedes sich wiederholende vertikale Element</strong>. Wenn Sie horizontale Stahlseile verwenden, sind die Vorschriften anders (normalerweise dürfen sie nicht zum Klettern einladen, „Leitereffekt“). Bei Glas wird es als durchgehende Platte betrachtet, und es gilt kein Abstand, sondern die Schlagfestigkeit.</p>',
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
type: 'card',
|
|
244
|
+
icon: 'mdi:format-quote-close',
|
|
245
|
+
title: 'Mies van der Rohe',
|
|
246
|
+
html: '<p><em>„Architektur ist der Wille der Epoche, in den Raum übersetzt.“</em></p><p>Wir hoffen, dass dieses Tool Ihnen hilft, sicherere und schönere Räume zu bauen. Denken Sie immer daran, die örtlichen Bauvorschriften Ihrer Gemeinde zu konsultieren, da es spezifische Variationen bei der Mindesthöhe (normalerweise 90–110 cm) oder den Belastungen geben kann.</p>',
|
|
247
|
+
},
|
|
248
|
+
],
|
|
249
|
+
ui: {
|
|
250
|
+
sectionTitle: 'Abmessungen',
|
|
251
|
+
sectionDesc: 'Geben Sie die Maße Ihres Geländers ein',
|
|
252
|
+
labelRailLength: 'Gesamtlänge (L)',
|
|
253
|
+
labelBalusterWidth: 'Balusterbreite (w)',
|
|
254
|
+
labelMaxGap: 'Maximaler Abstand (g)',
|
|
255
|
+
blueprintTitle: 'Montageplan',
|
|
256
|
+
blueprintRef: 'REF: BAL-001 // SKALA: AUTO',
|
|
257
|
+
labelRequired: 'Benötigte Baluster',
|
|
258
|
+
labelExactGap: 'Exakte Lücke',
|
|
259
|
+
labelOnCenter: 'Mitte zu Mitte',
|
|
260
|
+
labelTotalSpaces: 'Gesamtanzahl Lücken',
|
|
261
|
+
labelCoveredLength: 'Abgedeckte Länge',
|
|
262
|
+
labelDisclaimer: '* Die gezeigten Dimensionen sind Näherungswerte zur Visualisierung.',
|
|
263
|
+
},
|
|
264
|
+
};
|