@jjlmoya/utils-diy 1.2.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.
Files changed (189) hide show
  1. package/package.json +2 -1
  2. package/src/category/i18n/de.ts +12 -0
  3. package/src/category/i18n/id.ts +12 -0
  4. package/src/category/i18n/it.ts +12 -0
  5. package/src/category/i18n/ja.ts +12 -0
  6. package/src/category/i18n/ko.ts +12 -0
  7. package/src/category/i18n/nl.ts +12 -0
  8. package/src/category/i18n/pl.ts +12 -0
  9. package/src/category/i18n/pt.ts +12 -0
  10. package/src/category/i18n/ru.ts +12 -0
  11. package/src/category/i18n/sv.ts +12 -0
  12. package/src/category/i18n/tr.ts +12 -0
  13. package/src/category/i18n/zh.ts +12 -0
  14. package/src/category/index.ts +13 -1
  15. package/src/tests/faq_count.test.ts +1 -1
  16. package/src/tests/i18n_coverage.test.ts +36 -0
  17. package/src/tests/locale_completeness.test.ts +2 -2
  18. package/src/tests/seo_length.test.ts +3 -0
  19. package/src/tests/slug_uniqueness.test.ts +58 -0
  20. package/src/tool/balusterCalculator/i18n/de.ts +264 -0
  21. package/src/tool/balusterCalculator/i18n/id.ts +264 -0
  22. package/src/tool/balusterCalculator/i18n/it.ts +264 -0
  23. package/src/tool/balusterCalculator/i18n/ja.ts +264 -0
  24. package/src/tool/balusterCalculator/i18n/ko.ts +264 -0
  25. package/src/tool/balusterCalculator/i18n/nl.ts +264 -0
  26. package/src/tool/balusterCalculator/i18n/pl.ts +264 -0
  27. package/src/tool/balusterCalculator/i18n/pt.ts +264 -0
  28. package/src/tool/balusterCalculator/i18n/ru.ts +264 -0
  29. package/src/tool/balusterCalculator/i18n/sv.ts +264 -0
  30. package/src/tool/balusterCalculator/i18n/tr.ts +264 -0
  31. package/src/tool/balusterCalculator/i18n/zh.ts +264 -0
  32. package/src/tool/balusterCalculator/index.ts +15 -7
  33. package/src/tool/clayCalculator/i18n/de.ts +183 -0
  34. package/src/tool/clayCalculator/i18n/id.ts +183 -0
  35. package/src/tool/clayCalculator/i18n/it.ts +183 -0
  36. package/src/tool/clayCalculator/i18n/ja.ts +182 -0
  37. package/src/tool/clayCalculator/i18n/ko.ts +183 -0
  38. package/src/tool/clayCalculator/i18n/nl.ts +183 -0
  39. package/src/tool/clayCalculator/i18n/pl.ts +183 -0
  40. package/src/tool/clayCalculator/i18n/pt.ts +183 -0
  41. package/src/tool/clayCalculator/i18n/ru.ts +183 -0
  42. package/src/tool/clayCalculator/i18n/sv.ts +183 -0
  43. package/src/tool/clayCalculator/i18n/tr.ts +183 -0
  44. package/src/tool/clayCalculator/i18n/zh.ts +183 -0
  45. package/src/tool/clayCalculator/index.ts +15 -7
  46. package/src/tool/concreteCalculator/i18n/de.ts +201 -0
  47. package/src/tool/concreteCalculator/i18n/id.ts +201 -0
  48. package/src/tool/concreteCalculator/i18n/it.ts +201 -0
  49. package/src/tool/concreteCalculator/i18n/ja.ts +201 -0
  50. package/src/tool/concreteCalculator/i18n/ko.ts +201 -0
  51. package/src/tool/concreteCalculator/i18n/nl.ts +201 -0
  52. package/src/tool/concreteCalculator/i18n/pl.ts +201 -0
  53. package/src/tool/concreteCalculator/i18n/pt.ts +201 -0
  54. package/src/tool/concreteCalculator/i18n/ru.ts +201 -0
  55. package/src/tool/concreteCalculator/i18n/sv.ts +201 -0
  56. package/src/tool/concreteCalculator/i18n/tr.ts +201 -0
  57. package/src/tool/concreteCalculator/i18n/zh.ts +201 -0
  58. package/src/tool/concreteCalculator/index.ts +17 -5
  59. package/src/tool/cutOptimizer/i18n/de.ts +178 -0
  60. package/src/tool/cutOptimizer/i18n/id.ts +178 -0
  61. package/src/tool/cutOptimizer/i18n/it.ts +178 -0
  62. package/src/tool/cutOptimizer/i18n/ja.ts +178 -0
  63. package/src/tool/cutOptimizer/i18n/ko.ts +178 -0
  64. package/src/tool/cutOptimizer/i18n/nl.ts +178 -0
  65. package/src/tool/cutOptimizer/i18n/pl.ts +178 -0
  66. package/src/tool/cutOptimizer/i18n/pt.ts +178 -0
  67. package/src/tool/cutOptimizer/i18n/ru.ts +178 -0
  68. package/src/tool/cutOptimizer/i18n/sv.ts +178 -0
  69. package/src/tool/cutOptimizer/i18n/tr.ts +178 -0
  70. package/src/tool/cutOptimizer/i18n/zh.ts +178 -0
  71. package/src/tool/cutOptimizer/index.ts +17 -5
  72. package/src/tool/drillCalculator/i18n/de.ts +137 -0
  73. package/src/tool/drillCalculator/i18n/id.ts +137 -0
  74. package/src/tool/drillCalculator/i18n/it.ts +137 -0
  75. package/src/tool/drillCalculator/i18n/ja.ts +137 -0
  76. package/src/tool/drillCalculator/i18n/ko.ts +137 -0
  77. package/src/tool/drillCalculator/i18n/nl.ts +137 -0
  78. package/src/tool/drillCalculator/i18n/pl.ts +137 -0
  79. package/src/tool/drillCalculator/i18n/pt.ts +137 -0
  80. package/src/tool/drillCalculator/i18n/ru.ts +137 -0
  81. package/src/tool/drillCalculator/i18n/sv.ts +137 -0
  82. package/src/tool/drillCalculator/i18n/tr.ts +137 -0
  83. package/src/tool/drillCalculator/i18n/zh.ts +137 -0
  84. package/src/tool/drillCalculator/index.ts +17 -5
  85. package/src/tool/drillSharpener/i18n/de.ts +120 -0
  86. package/src/tool/drillSharpener/i18n/id.ts +120 -0
  87. package/src/tool/drillSharpener/i18n/it.ts +120 -0
  88. package/src/tool/drillSharpener/i18n/ja.ts +120 -0
  89. package/src/tool/drillSharpener/i18n/ko.ts +120 -0
  90. package/src/tool/drillSharpener/i18n/nl.ts +120 -0
  91. package/src/tool/drillSharpener/i18n/pl.ts +120 -0
  92. package/src/tool/drillSharpener/i18n/pt.ts +120 -0
  93. package/src/tool/drillSharpener/i18n/ru.ts +120 -0
  94. package/src/tool/drillSharpener/i18n/sv.ts +120 -0
  95. package/src/tool/drillSharpener/i18n/tr.ts +120 -0
  96. package/src/tool/drillSharpener/i18n/zh.ts +120 -0
  97. package/src/tool/drillSharpener/index.ts +17 -5
  98. package/src/tool/epoxyCalculator/i18n/de.ts +118 -0
  99. package/src/tool/epoxyCalculator/i18n/id.ts +118 -0
  100. package/src/tool/epoxyCalculator/i18n/it.ts +118 -0
  101. package/src/tool/epoxyCalculator/i18n/ja.ts +118 -0
  102. package/src/tool/epoxyCalculator/i18n/ko.ts +118 -0
  103. package/src/tool/epoxyCalculator/i18n/nl.ts +118 -0
  104. package/src/tool/epoxyCalculator/i18n/pl.ts +118 -0
  105. package/src/tool/epoxyCalculator/i18n/pt.ts +118 -0
  106. package/src/tool/epoxyCalculator/i18n/ru.ts +118 -0
  107. package/src/tool/epoxyCalculator/i18n/sv.ts +118 -0
  108. package/src/tool/epoxyCalculator/i18n/tr.ts +118 -0
  109. package/src/tool/epoxyCalculator/i18n/zh.ts +118 -0
  110. package/src/tool/epoxyCalculator/index.ts +15 -7
  111. package/src/tool/furnitureFit/i18n/de.ts +113 -0
  112. package/src/tool/furnitureFit/i18n/id.ts +113 -0
  113. package/src/tool/furnitureFit/i18n/it.ts +113 -0
  114. package/src/tool/furnitureFit/i18n/ja.ts +113 -0
  115. package/src/tool/furnitureFit/i18n/ko.ts +113 -0
  116. package/src/tool/furnitureFit/i18n/nl.ts +113 -0
  117. package/src/tool/furnitureFit/i18n/pl.ts +113 -0
  118. package/src/tool/furnitureFit/i18n/pt.ts +113 -0
  119. package/src/tool/furnitureFit/i18n/ru.ts +113 -0
  120. package/src/tool/furnitureFit/i18n/sv.ts +113 -0
  121. package/src/tool/furnitureFit/i18n/tr.ts +113 -0
  122. package/src/tool/furnitureFit/i18n/zh.ts +113 -0
  123. package/src/tool/furnitureFit/index.ts +17 -5
  124. package/src/tool/mortarCalculator/i18n/de.ts +129 -0
  125. package/src/tool/mortarCalculator/i18n/id.ts +129 -0
  126. package/src/tool/mortarCalculator/i18n/it.ts +129 -0
  127. package/src/tool/mortarCalculator/i18n/ja.ts +129 -0
  128. package/src/tool/mortarCalculator/i18n/ko.ts +129 -0
  129. package/src/tool/mortarCalculator/i18n/nl.ts +129 -0
  130. package/src/tool/mortarCalculator/i18n/pl.ts +129 -0
  131. package/src/tool/mortarCalculator/i18n/pt.ts +129 -0
  132. package/src/tool/mortarCalculator/i18n/ru.ts +129 -0
  133. package/src/tool/mortarCalculator/i18n/sv.ts +129 -0
  134. package/src/tool/mortarCalculator/i18n/tr.ts +129 -0
  135. package/src/tool/mortarCalculator/i18n/zh.ts +129 -0
  136. package/src/tool/mortarCalculator/index.ts +17 -5
  137. package/src/tool/passepartoutCalculator/i18n/de.ts +108 -0
  138. package/src/tool/passepartoutCalculator/i18n/id.ts +108 -0
  139. package/src/tool/passepartoutCalculator/i18n/it.ts +108 -0
  140. package/src/tool/passepartoutCalculator/i18n/ja.ts +108 -0
  141. package/src/tool/passepartoutCalculator/i18n/ko.ts +108 -0
  142. package/src/tool/passepartoutCalculator/i18n/nl.ts +108 -0
  143. package/src/tool/passepartoutCalculator/i18n/pl.ts +108 -0
  144. package/src/tool/passepartoutCalculator/i18n/pt.ts +108 -0
  145. package/src/tool/passepartoutCalculator/i18n/ru.ts +108 -0
  146. package/src/tool/passepartoutCalculator/i18n/sv.ts +108 -0
  147. package/src/tool/passepartoutCalculator/i18n/tr.ts +108 -0
  148. package/src/tool/passepartoutCalculator/i18n/zh.ts +108 -0
  149. package/src/tool/passepartoutCalculator/index.ts +17 -5
  150. package/src/tool/stairCalculator/i18n/de.ts +144 -0
  151. package/src/tool/stairCalculator/i18n/id.ts +144 -0
  152. package/src/tool/stairCalculator/i18n/it.ts +144 -0
  153. package/src/tool/stairCalculator/i18n/ja.ts +144 -0
  154. package/src/tool/stairCalculator/i18n/ko.ts +144 -0
  155. package/src/tool/stairCalculator/i18n/nl.ts +144 -0
  156. package/src/tool/stairCalculator/i18n/pl.ts +144 -0
  157. package/src/tool/stairCalculator/i18n/pt.ts +144 -0
  158. package/src/tool/stairCalculator/i18n/ru.ts +144 -0
  159. package/src/tool/stairCalculator/i18n/sv.ts +144 -0
  160. package/src/tool/stairCalculator/i18n/tr.ts +144 -0
  161. package/src/tool/stairCalculator/i18n/zh.ts +144 -0
  162. package/src/tool/stairCalculator/index.ts +17 -5
  163. package/src/tool/thermalExpansionCalculator/i18n/de.ts +132 -0
  164. package/src/tool/thermalExpansionCalculator/i18n/id.ts +130 -0
  165. package/src/tool/thermalExpansionCalculator/i18n/it.ts +130 -0
  166. package/src/tool/thermalExpansionCalculator/i18n/ja.ts +130 -0
  167. package/src/tool/thermalExpansionCalculator/i18n/ko.ts +130 -0
  168. package/src/tool/thermalExpansionCalculator/i18n/nl.ts +130 -0
  169. package/src/tool/thermalExpansionCalculator/i18n/pl.ts +130 -0
  170. package/src/tool/thermalExpansionCalculator/i18n/pt.ts +130 -0
  171. package/src/tool/thermalExpansionCalculator/i18n/ru.ts +130 -0
  172. package/src/tool/thermalExpansionCalculator/i18n/sv.ts +130 -0
  173. package/src/tool/thermalExpansionCalculator/i18n/tr.ts +130 -0
  174. package/src/tool/thermalExpansionCalculator/i18n/zh.ts +130 -0
  175. package/src/tool/thermalExpansionCalculator/index.ts +17 -5
  176. package/src/tool/voltageDropCalculator/i18n/de.ts +112 -0
  177. package/src/tool/voltageDropCalculator/i18n/id.ts +110 -0
  178. package/src/tool/voltageDropCalculator/i18n/it.ts +110 -0
  179. package/src/tool/voltageDropCalculator/i18n/ja.ts +110 -0
  180. package/src/tool/voltageDropCalculator/i18n/ko.ts +110 -0
  181. package/src/tool/voltageDropCalculator/i18n/nl.ts +110 -0
  182. package/src/tool/voltageDropCalculator/i18n/pl.ts +110 -0
  183. package/src/tool/voltageDropCalculator/i18n/pt.ts +110 -0
  184. package/src/tool/voltageDropCalculator/i18n/ru.ts +110 -0
  185. package/src/tool/voltageDropCalculator/i18n/sv.ts +110 -0
  186. package/src/tool/voltageDropCalculator/i18n/tr.ts +110 -0
  187. package/src/tool/voltageDropCalculator/i18n/zh.ts +110 -0
  188. package/src/tool/voltageDropCalculator/index.ts +17 -5
  189. package/src/types.ts +1 -1
@@ -0,0 +1,201 @@
1
+ import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { ConcreteCalculatorUI } from '../ui';
4
+
5
+ const slug = 'concrete-mortar-calculator';
6
+ const title = '混凝土与砂浆计算器:水泥、沙子和水的精确用量';
7
+ const description =
8
+ '计算每立方米所需的水泥袋数、沙铲数和升水。适用于地基、地坪、墙体和找平层。技术配比指南。';
9
+
10
+ const faqData = [
11
+ {
12
+ question: '一立方米混凝土需要多少袋25公斤的水泥?',
13
+ answer:
14
+ '对于标准混凝土(强度等级约 C20/25),制作一立方米密实混合料约需14袋25公斤的水泥(总计350公斤)。',
15
+ },
16
+ {
17
+ question: '混凝土和砂浆哪个更强?',
18
+ answer:
19
+ '含有砂石(碎石)的「混凝土」在结构上更强,能承受巨大载荷。仅含沙子的「砂浆」则非常适合砌筑砖块或表面抹灰。',
20
+ },
21
+ {
22
+ question: '一立方米相当于多少铲沙子?',
23
+ answer:
24
+ '这取决于铁铲的大小,但通常按每立方米180-200铲沙子计算。我们的计算器会将立方米换算为建议的小铁铲数。',
25
+ },
26
+ {
27
+ question: '没有搅拌机可以人工手动搅拌吗?',
28
+ answer:
29
+ '可以,但这需要非常大的体力。理想做法是在清洁且不透水的表面(铁板或灰槽)上进行,以防止水分流失。',
30
+ },
31
+ {
32
+ question: '为什么混凝土干燥时会开裂?',
33
+ answer:
34
+ '通常是由于硬化期间缺乏湿度(水分蒸发过快)或拌合时水灰比过大(水太多)。建议在施工后的几天内进行洒水养护。',
35
+ },
36
+ ];
37
+
38
+ const howToData = [
39
+ {
40
+ name: '选择混合类型',
41
+ text: '选择您是要制作地基用的混凝土,还是砌墙用的砂浆。',
42
+ },
43
+ {
44
+ name: '指定体积 (m³)',
45
+ text: '输入总体积。计算公式:长 × 宽 × 厚。',
46
+ },
47
+ {
48
+ name: '查阅用量',
49
+ text: '查看需要购买的水泥袋数、沙铲数和水升数。',
50
+ },
51
+ {
52
+ name: '应用配比',
53
+ text: '遵循水泥、沙子和碎石的视觉指南进行完美配比。',
54
+ },
55
+ ];
56
+
57
+ const faqSchema: WithContext<FAQPage> = {
58
+ '@context': 'https://schema.org',
59
+ '@type': 'FAQPage',
60
+ mainEntity: faqData.map((item) => ({
61
+ '@type': 'Question',
62
+ name: item.question,
63
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
64
+ })),
65
+ };
66
+
67
+ const howToSchema: WithContext<HowToThing> = {
68
+ '@context': 'https://schema.org',
69
+ '@type': 'HowTo',
70
+ name: title,
71
+ description,
72
+ step: howToData.map((step, i) => ({
73
+ '@type': 'HowToStep',
74
+ position: i + 1,
75
+ name: step.name,
76
+ text: step.text,
77
+ })),
78
+ };
79
+
80
+ const appSchema: WithContext<SoftwareApplication> = {
81
+ '@context': 'https://schema.org',
82
+ '@type': 'SoftwareApplication',
83
+ name: title,
84
+ description,
85
+ applicationCategory: 'UtilityApplication',
86
+ operatingSystem: 'All',
87
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
88
+ inLanguage: 'zh',
89
+ };
90
+
91
+ export const content: ToolLocaleContent<ConcreteCalculatorUI> = {
92
+ slug,
93
+ title,
94
+ description,
95
+ faqTitle: '常见问题',
96
+ faq: faqData,
97
+ bibliographyTitle: '技术参考',
98
+ bibliography: [
99
+ {
100
+ name: 'GB 50204-2015 混凝土结构工程施工质量验收规范 (中国)',
101
+ url: 'http://www.mohurd.gov.cn/',
102
+ },
103
+ {
104
+ name: 'Concrete Mix Proportioning Standards (ASTM)',
105
+ url: 'https://store.astm.org/astm-bos-04.02.html',
106
+ },
107
+ {
108
+ name: '水泥砂浆配比百科',
109
+ url: 'https://zh.wikipedia.org/wiki/砂浆',
110
+ },
111
+ ],
112
+ howTo: howToData,
113
+ schemas: [faqSchema, howToSchema, appSchema],
114
+ seo: [
115
+ {
116
+ type: 'title',
117
+ text: '混凝土与砂浆配比指南',
118
+ level: 2,
119
+ },
120
+ {
121
+ type: 'paragraph',
122
+ html: '在装修或施工时,最常遇到的问题之一就是<strong>一立方米混凝土需要多少袋水泥?</strong>。这不仅仅是混合材料那么简单;结构的最终强度直接取决于水泥、沙子、碎石和水的精确比例。我们的计算器将工业标准测量值转换为工地常用的单位:25公斤袋、铁铲数和升。',
123
+ },
124
+ {
125
+ type: 'card',
126
+ icon: 'mdi:water-alert',
127
+ title: '水分过多会削弱混凝土强度',
128
+ html: '<p>一个非常常见的错误是为了让混凝土流动性更好而添加过多的水。多余的水在硬化蒸发时会产生孔隙,从而剧烈降低最终强度。理想的稠度应当像<strong>粘稠的糊状,而不是液体</strong>。请尽可能少用水。</p>',
129
+ },
130
+ {
131
+ type: 'title',
132
+ text: '根据用途的标注配比',
133
+ level: 3,
134
+ },
135
+ {
136
+ type: 'paragraph',
137
+ html: '<strong>混凝土配比</strong>因用途而异。对于<strong>标准混凝土</strong>(地基和地坪),比例为 1份水泥、2.5份沙子、3份碎石。对于<strong>砌筑砂浆</strong>(墙体),比例为 1份水泥和4份沙子。对于<strong>强力找平砂浆</strong>(地面),比例为 1份水泥和3份沙子。含碎石的混凝土承重能力更强;纯沙的砂浆则非常适合粘结和抹灰。',
138
+ },
139
+ {
140
+ type: 'title',
141
+ text: '如何计算所需的立方数 (m³)',
142
+ level: 3,
143
+ },
144
+ {
145
+ type: 'card',
146
+ icon: 'mdi:calculator-variant',
147
+ title: '地坪计算示例',
148
+ html: '<p>对于一个长4米、宽3米、厚15厘米的花园地坪:<strong>4 × 3 × 0.15 = 1.80 m³</strong>。如果您在「按尺寸计算」部分输入相关数值,计算器将自动完成此操作。</p><p>请记住始终<strong>多购买10%</strong>的材料,以弥补泼洒损失或地形不平带来的差额。</p>',
149
+ },
150
+ {
151
+ type: 'title',
152
+ text: '搅拌顺序与按袋配比',
153
+ level: 3,
154
+ },
155
+ {
156
+ type: 'paragraph',
157
+ html: '工地上常说<strong>「300公斤配合比」</strong>:即每立方米成品混凝土含300公斤水泥。在搅拌机中的正确顺序是:先放水,随后放碎石和沙子(以打散团块),最后逐渐加入水泥。',
158
+ },
159
+ {
160
+ type: 'card',
161
+ icon: 'mdi:package-variant-closed',
162
+ title: '防止料不够的10%原则',
163
+ html: '<p>请始终购买比计算值<strong>多10%的材料</strong>,以抵消遗洒损失、地形不规则或潮湿骨材实际体积的变化。这比施工停滞时再补订第二次要划算得多。</p>',
164
+ },
165
+ ],
166
+ ui: {
167
+ mixH200Label: '标准混凝土',
168
+ mixH200Hint: '适用于地基和地坪',
169
+ mixM40Label: '建筑砌筑砂浆',
170
+ mixM40Hint: '适用于墙体和隔断',
171
+ mixM80Label: '强力找平层',
172
+ mixM80Hint: '适用于地面和强力抹灰',
173
+ modeDimsLabel: '按尺寸计算',
174
+ modeDirectLabel: '直填 m³',
175
+ labelLength: '长度',
176
+ labelWidth: '宽度',
177
+ labelThickness: '厚度',
178
+ labelVolume: '总体积 (m³)',
179
+ binderCementLabel: '水泥',
180
+ binderLimeLabel: '石灰',
181
+ summaryLabel: '填补总量:',
182
+ resUnitSacks: '袋 (25kg)',
183
+ resUnitShovels: '铲',
184
+ resUnitLitres: '升',
185
+ resLabelCement: '波特兰水泥',
186
+ resLabelLime: '水硬性石灰',
187
+ resLabelSand: '沙子 / 骨料',
188
+ resLabelWater: '饮用水',
189
+ proportionsTitle: '选中混合类型的配比',
190
+ propLabelSand: '沙子',
191
+ propLabelGravel: '碎石/砂石',
192
+ adviceH200: '适用于支柱、地坪和承重结构。',
193
+ adviceM40: '非常适合砌筑砖墙或砌块墙。',
194
+ adviceM80: '用于高耐受性的地面找平层。',
195
+ adviceLimeH200: '石灰混凝土更具韧性,但硬化时间较长。',
196
+ priceTotalLabel: '估计预算',
197
+ priceSackLabel: '每袋单价',
198
+ priceSandLabel: '沙子 (m³)',
199
+ priceDisclaimer: '参考市场价格。请根据当地供应商进行调整。',
200
+ },
201
+ };
@@ -10,14 +10,26 @@ export {
10
10
  ConcreteCalculatorBibliography,
11
11
  };
12
12
 
13
- const es = async () => (await import('./i18n/es')).content;
14
- const en = async () => (await import('./i18n/en')).content;
15
- const fr = async () => (await import('./i18n/fr')).content;
16
-
17
13
  export const concreteCalculator: DiyToolEntry<ConcreteCalculatorUI> = {
18
14
  id: 'concrete-calculator',
19
15
  icons: { bg: 'mdi:bucket-outline', fg: 'mdi:shovel' },
20
- i18n: { es, en, fr },
16
+ i18n: {
17
+ de: () => import('./i18n/de').then((m) => m.content),
18
+ en: () => import('./i18n/en').then((m) => m.content),
19
+ es: () => import('./i18n/es').then((m) => m.content),
20
+ fr: () => import('./i18n/fr').then((m) => m.content),
21
+ id: () => import('./i18n/id').then((m) => m.content),
22
+ it: () => import('./i18n/it').then((m) => m.content),
23
+ ja: () => import('./i18n/ja').then((m) => m.content),
24
+ ko: () => import('./i18n/ko').then((m) => m.content),
25
+ nl: () => import('./i18n/nl').then((m) => m.content),
26
+ pl: () => import('./i18n/pl').then((m) => m.content),
27
+ pt: () => import('./i18n/pt').then((m) => m.content),
28
+ ru: () => import('./i18n/ru').then((m) => m.content),
29
+ sv: () => import('./i18n/sv').then((m) => m.content),
30
+ tr: () => import('./i18n/tr').then((m) => m.content),
31
+ zh: () => import('./i18n/zh').then((m) => m.content),
32
+ },
21
33
  };
22
34
 
23
35
  export const CONCRETE_CALCULATOR_TOOL: ToolDefinition = {
@@ -0,0 +1,178 @@
1
+ import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { CutOptimizerUI } from '../ui';
4
+
5
+ const slug = 'schnittoptimierung';
6
+ const title = 'Schnittoptimierung für Leisten und Platten';
7
+ const description =
8
+ 'Kostenloser Rechner zur Schnittoptimierung für Holz, Metall oder Rohre. Minimieren Sie den Verschnitt mit dem 1D- und 2D-Bin-Packing-Algorithmus. Ideal für Tischlerei und Metallbau.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: 'Was ist ein 1D-Schnittoptimierer?',
13
+ answer:
14
+ 'Es ist ein Werkzeug, das mathematische Algorithmen (wie das Bin-Packing-Problem) verwendet, um zu bestimmen, wie kleinere Teile aus einem standardmäßigen Langstück (Leiste, Profil, Rohr) mit möglichst wenig Verschnitt geschnitten werden können.',
15
+ },
16
+ {
17
+ question: 'Warum muss die Schnittbreite (Kerf) berücksichtigt werden?',
18
+ answer:
19
+ 'Jedes Mal, wenn die Säge durch das Material schneidet, gehen einige Millimeter verloren (normalerweise zwischen 2 mm und 4 mm, je nach Sägeblatt). Wenn dieser Platz nicht eingerechnet wird, werden die letzten Teile auf Ihrer Liste kürzer als geplant.',
20
+ },
21
+ {
22
+ question: 'Kann ich Teile verschiedener Längen mischen?',
23
+ answer:
24
+ 'Ja, unser Rechner akzeptiert jede Kombination von Längen und Mengen. Der Algorithmus bewertet alle möglichen Kombinationen und priorisiert die maximale Ausnutzung des Lagermaterials.',
25
+ },
26
+ {
27
+ question: 'Wie speichere ich meinen Schnittplan?',
28
+ answer:
29
+ 'Nach der Optimierung können Sie die Seite ausdrucken oder einen Screenshot des visuellen Schemas machen. Dies dient als physische Anleitung in der Werkstatt, um die Reihenfolge der Schnitte nicht zu verwechseln.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Basismaterial definieren (Stock)',
36
+ text: 'Geben Sie die Gesamtlänge der verfügbaren Leiste oder des Profils an (z. B. 2400 mm oder 6000 mm).',
37
+ },
38
+ {
39
+ name: 'Sägeblattdicke konfigurieren (Kerf)',
40
+ text: 'Stellen Sie die Millimeter ein, die die Säge bei jedem Schnitt entfernt, damit die Berechnung millimetergenau ist.',
41
+ },
42
+ {
43
+ name: 'Gewünschte Teile auflisten',
44
+ text: 'Geben Sie die Länge und Anzahl jedes Teils ein, das Sie für Ihr Projekt benötigen.',
45
+ },
46
+ {
47
+ name: 'Optimierung ausführen',
48
+ text: 'Erhalten Sie das effizienteste Schnittschema und den exakten Prozentsatz des erzeugten Verschnitts.',
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<CutOptimizerUI> = {
87
+ slug,
88
+ title,
89
+ description,
90
+ faqTitle: 'Häufig gestellte Fragen',
91
+ faq: faqData,
92
+ bibliographyTitle: 'Technische Referenzen',
93
+ bibliography: [
94
+ {
95
+ name: 'Cutting Stock Problem: Wikipedia',
96
+ url: 'https://en.wikipedia.org/wiki/Cutting_stock_problem',
97
+ },
98
+ {
99
+ name: 'Bin Packing Problem: Wolfram MathWorld',
100
+ url: 'https://mathworld.wolfram.com/BinPackingProblem.html',
101
+ },
102
+ ],
103
+ howTo: howToData,
104
+ schemas: [faqSchema, howToSchema, appSchema],
105
+ seo: [
106
+ {
107
+ type: 'title',
108
+ text: 'Der definitive Leitfaden zur Schnittoptimierung',
109
+ level: 2,
110
+ },
111
+ {
112
+ type: 'paragraph',
113
+ html: 'Die Schnittoptimierung, technisch bekannt als das <strong>Zuschnittproblem (Cutting Stock Problem)</strong>, ist eine der faszinierendsten logistischen Herausforderungen in der Industrietechnik. Bei einem Projekt mit 20 Teilen und 5 Lagerstäben gibt es Millionen möglicher Kombinationen. Ein Computer-Algorithmus kann die optimale Lösung in Millisekunden finden und den üblichen Verschnitt von 15 % auf weniger als 5 % reduzieren.',
114
+ },
115
+ {
116
+ type: 'title',
117
+ text: 'Linearer 1D-Schnitt und 2D-Plattenschnitt',
118
+ level: 3,
119
+ },
120
+ {
121
+ type: 'card',
122
+ icon: 'mdi:arrow-expand-horizontal',
123
+ title: 'Linearschnitt für Leisten und Profile',
124
+ html: '<p>Beim <strong>linearen Schnitt (1D)</strong> erfolgt die Optimierung in nur einer Dimension: der Länge. Die Breite des Materials wird als konstant angenommen. Ideal für Bauholz (Leisten, Balken), Metall- und Aluminiumprofile, PVC- oder Kupferrohre und Gewindestangen.</p>',
125
+ },
126
+ {
127
+ type: 'card',
128
+ icon: 'mdi:view-grid',
129
+ title: 'Plattenschnitt für Platten und Bleche',
130
+ html: '<p>Beim <strong>Plattenschnitt (2D)</strong> werden zwei Dimensionen verwaltet: Breite und Länge. Das Tool verwendet Guillotine-Algorithmen, bei denen jeder Schnitt von Kante zu Kante verläuft. Ideal für Plattenwerkstoffe (MDF, Spanplatten), Sperrholz, Glas, Acrylglas und Metallbleche.</p>',
131
+ },
132
+ {
133
+ type: 'title',
134
+ text: 'Der kritische Faktor: Die Schnittbreite (Kerf)',
135
+ level: 3,
136
+ },
137
+ {
138
+ type: 'paragraph',
139
+ html: 'Der <strong>Kerf</strong> ist das Material, das bei jedem Schnitt entfernt wird. Ein Standard-Tischkreissägeblatt verbraucht zwischen 3,0 mm und 3,2 mm pro Schnitt. Eine Handkreissäge verbraucht 1,5 bis 2,5 mm. Ein Laserschnitt in Acrylglas verbraucht kaum 0,1 bis 0,3 mm. Das Ignorieren der Schnittbreite in einem Projekt mit 10 Schnitten an 2400-mm-Leisten kann dazu führen, dass Sie zwischen 30 mm und 32 mm nutzbares Material verlieren.',
140
+ },
141
+ {
142
+ type: 'title',
143
+ text: 'Der Best-Fit-Decreasing-Algorithmus',
144
+ level: 3,
145
+ },
146
+ {
147
+ type: 'card',
148
+ icon: 'mdi:chip',
149
+ title: 'Wie der Optimierer intern funktioniert',
150
+ html: '<p>Der Kern des Optimierers nutzt die Strategie <strong>Best Fit Decreasing (BFD)</strong>: Zuerst werden alle Teile von der größten zur kleinsten Länge sortiert (große Teile sind schwieriger einzupassen). Dann wird für jedes Teil der vorhandene Rest gesucht, in den es mit dem geringsten verbleibenden Rest passt. Nur wenn es in keinen Rest passt, wird ein neuer Rohstab angebrochen. Dieser Prozess reduziert den Verschnitt um eine Größenordnung im Vergleich zur zufälligen Auswahl.</p>',
151
+ },
152
+ ],
153
+ ui: {
154
+ modeLinearLabel: 'Linear (Stäbe)',
155
+ modePanelLabel: 'Platten',
156
+ configTitle: 'Materialkonfiguration',
157
+ labelStockLength: 'Materiallänge (mm)',
158
+ labelStockWidth: 'Materialbreite (mm)',
159
+ labelKerf: 'Schnittbreite / Kerf (mm)',
160
+ cutsTitle: 'Schnittliste',
161
+ placeholderLength: 'Länge',
162
+ placeholderWidth: 'Breite',
163
+ placeholderQty: 'Anz.',
164
+ btnRemoveTitle: 'Löschen',
165
+ statStockUsed: 'Material benutzt',
166
+ statTotalCuts: 'Gesamtschnitte',
167
+ statWaste: 'Gesamtverschnitt',
168
+ statEfficiency: 'Effizienz',
169
+ vizTitle: 'Schnittvisualisierung',
170
+ emptyState: 'Fügen Sie Schnitte hinzu und klicken Sie auf Berechnen, um den Schnittplan zu sehen.',
171
+ noValidCuts: 'Es konnten keine gültigen Schnitte generiert werden. Überprüfen Sie die Maße.',
172
+ noValidPanels: 'Es konnten keine gültigen Platten generiert werden. Prüfen Sie, ob die Teile auf die Platte passen.',
173
+ stockLabel: 'Material',
174
+ panelLabel: 'Platte',
175
+ wasteLabel: 'Verschnitt:',
176
+ effLabel: 'Eff:',
177
+ },
178
+ };
@@ -0,0 +1,178 @@
1
+ import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { CutOptimizerUI } from '../ui';
4
+
5
+ const slug = 'pengoptimal-potongan';
6
+ const title = 'Pengoptimal Potongan Kayu dan Papan';
7
+ const description =
8
+ 'Kalkulator gratis untuk mengoptimalkan potongan kayu, logam, atau pipa. Minimalkan sisa dengan algoritma Bin Packing 1D dan 2D. Ideal untuk bengkel kayu, metalurgi, dan renovasi.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: 'Apa itu pengoptimal potongan 1D?',
13
+ answer:
14
+ 'Ini adalah alat yang menggunakan algoritma matematika (seperti Bin Packing Problem) untuk menentukan cara memotong bagian yang lebih kecil dari bagian panjang standar (balok, profil, pipa) dengan sisa sesedikit mungkin.',
15
+ },
16
+ {
17
+ question: 'Mengapa harus memasukkan ketebalan potongan (Kerf)?',
18
+ answer:
19
+ 'Setiap kali gergaji memotong material, beberapa milimeter akan terbuang (biasanya antara 2mm hingga 4mm tergantung pisaunya). Jika Anda tidak menghitung ruang ini, bagian terakhir dari daftar Anda akan menjadi lebih pendek dari yang direncanakan.',
20
+ },
21
+ {
22
+ question: 'Dapatkah saya mencampur bagian dengan panjang yang berbeda?',
23
+ answer:
24
+ 'Ya, kalkulator kami menerima kombinasi panjang dan jumlah berapa pun. Algoritma akan mengevaluasi semua kombinasi yang mungkin dan memprioritaskan pemanfaatan maksimal dari material stok.',
25
+ },
26
+ {
27
+ question: 'Bagaimana cara menyimpan rencana pemotongan saya?',
28
+ answer:
29
+ 'Setelah dioptimalkan, Anda dapat mencetak halaman tersebut atau mengambil tangkapan layar dari skema visual. Ini akan berfungsi sebagai panduan fisik di bengkel agar urutan potongan tidak tertukar.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Tentukan material dasar (Stock)',
36
+ text: 'Masukkan total panjang balok atau profil yang tersedia (misalnya 2400mm atau 6000mm).',
37
+ },
38
+ {
39
+ name: 'Atur ketebalan pisau (Kerf)',
40
+ text: 'Sesuaikan milimeter yang dihilangkan gergaji pada setiap langkah agar perhitungannya akurat secara milimetrik.',
41
+ },
42
+ {
43
+ name: 'Daftar bagian yang diinginkan',
44
+ text: 'Tulis panjang dan jumlah setiap bagian yang Anda butuhkan untuk proyek Anda.',
45
+ },
46
+ {
47
+ name: 'Jalankan optimasi',
48
+ text: 'Dapatkan skema pemotongan paling efisien dan persentase tepat dari sisa yang dihasilkan.',
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: 'id',
84
+ };
85
+
86
+ export const content: ToolLocaleContent<CutOptimizerUI> = {
87
+ slug,
88
+ title,
89
+ description,
90
+ faqTitle: 'Pertanyaan Umum',
91
+ faq: faqData,
92
+ bibliographyTitle: 'Referensi Teknis',
93
+ bibliography: [
94
+ {
95
+ name: 'Cutting Stock Problem: Wikipedia',
96
+ url: 'https://en.wikipedia.org/wiki/Cutting_stock_problem',
97
+ },
98
+ {
99
+ name: 'Bin Packing Problem: Wolfram MathWorld',
100
+ url: 'https://mathworld.wolfram.com/BinPackingProblem.html',
101
+ },
102
+ ],
103
+ howTo: howToData,
104
+ schemas: [faqSchema, howToSchema, appSchema],
105
+ seo: [
106
+ {
107
+ type: 'title',
108
+ text: 'Panduan Definitif Optimasi Pemotongan',
109
+ level: 2,
110
+ },
111
+ {
112
+ type: 'paragraph',
113
+ html: 'Optimasi pemotongan, yang secara teknis dikenal sebagai <strong>Masalah Pemotongan Stok (Cutting Stock Problem)</strong>, adalah salah satu tantangan logistik paling menarik dalam teknik industri. Untuk proyek dengan 20 bagian dan 5 batang stok, ada jutaan kemungkinan kombinasi. Algoritma komputer dapat menemukan solusi optimal dalam hitungan milidetik, mengurangi sisa yang biasanya 15% menjadi kurang dari 5%.',
114
+ },
115
+ {
116
+ type: 'title',
117
+ text: 'Pemotongan Linear 1D dan Pemotongan Panel 2D',
118
+ level: 3,
119
+ },
120
+ {
121
+ type: 'card',
122
+ icon: 'mdi:arrow-expand-horizontal',
123
+ title: 'Pemotongan Linear untuk Batang dan Profil',
124
+ html: '<p>Dalam <strong>pemotongan linear (1D)</strong>, optimasi terjadi hanya dalam satu dimensi: panjang. Lebar material dianggap konstan. Sangat ideal untuk kayu dimensional (balok, gelagar), profil logam dan aluminium, pipa PVC atau tembaga, dan batang berulir.</p>',
125
+ },
126
+ {
127
+ type: 'card',
128
+ icon: 'mdi:view-grid',
129
+ title: 'Pemotongan Panel untuk Papan dan Lembaran',
130
+ html: '<p>Dalam <strong>pemotongan panel (2D)</strong>, dua dimensi dikelola: lebar dan panjang. Alat ini menggunakan algoritma tipe guillotine, di mana setiap potongan dilakukan dari tepi ke tepi. Ideal untuk papan turunan (MDF, partikel), kayu lapis, kaca, metakrilat, dan lembaran logam.</p>',
131
+ },
132
+ {
133
+ type: 'title',
134
+ text: 'Faktor Kritis: Ketebalan Potongan (Kerf)',
135
+ level: 3,
136
+ },
137
+ {
138
+ type: 'paragraph',
139
+ html: '<strong>Kerf</strong> adalah material yang hilang pada setiap potongan. Pisau gergaji meja standar menghabiskan antara 3,0mm hingga 3,2mm per potongan. Gergaji sirkuler genggam menghabiskan 1,5 hingga 2,5mm. Potongan laser pada metakrilat hanya 0,1 hingga 0,3mm. Mengabaikan kerf dalam proyek dengan 10 potongan pada balok sepanjang 2400mm dapat membuat Anda kehilangan antara 30mm hingga 32mm material yang berguna.',
140
+ },
141
+ {
142
+ type: 'title',
143
+ text: 'Algoritma Best Fit Decreasing',
144
+ level: 3,
145
+ },
146
+ {
147
+ type: 'card',
148
+ icon: 'mdi:chip',
149
+ title: 'Cara Kerja Pengoptimal Secara Internal',
150
+ html: '<p>Inti dari pengoptimal menggunakan strategi <strong>Best Fit Decreasing (BFD)</strong>: pertama-tama mengurutkan semua bagian dari panjang terbesar ke terkecil (bagian besar lebih sulit untuk dicocokkan). Kemudian, untuk setiap bagian, ia mencari sisa yang ada di mana ia dapat masuk dengan meninggalkan sisa sesedikit mungkin. Hanya jika tidak muat di sisa mana pun, ia akan membuka batang baru. Proses ini mengurangi sisa secara signifikan dibandingkan dengan pemilihan acak.</p>',
151
+ },
152
+ ],
153
+ ui: {
154
+ modeLinearLabel: 'Linear (Batang)',
155
+ modePanelLabel: 'Panel (Papan)',
156
+ configTitle: 'Konfigurasi Material',
157
+ labelStockLength: 'Panjang Material (mm)',
158
+ labelStockWidth: 'Lebar Material (mm)',
159
+ labelKerf: 'Ketebalan Pisau / Kerf (mm)',
160
+ cutsTitle: 'Daftar Potongan',
161
+ placeholderLength: 'Panjang',
162
+ placeholderWidth: 'Lebar',
163
+ placeholderQty: 'Jml.',
164
+ btnRemoveTitle: 'Hapus',
165
+ statStockUsed: 'Material Terpakai',
166
+ statTotalCuts: 'Total Potongan',
167
+ statWaste: 'Total Sisa',
168
+ statEfficiency: 'Efisiensi',
169
+ vizTitle: 'Visualisasi Potongan',
170
+ emptyState: 'Tambahkan potongan dan tekan hitung untuk melihat rencana potongan.',
171
+ noValidCuts: 'Tidak dapat menghasilkan potongan yang valid. Periksa ukurannya.',
172
+ noValidPanels: 'Tidak dapat menghasilkan panel yang valid. Pastikan bagian-bagian tersebut muat di papan.',
173
+ stockLabel: 'Material',
174
+ panelLabel: 'Panel',
175
+ wasteLabel: 'Sisa:',
176
+ effLabel: 'Efis:',
177
+ },
178
+ };