@jjlmoya/utils-diy 1.3.0 → 1.5.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 (193) 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/index.ts +1 -1
  16. package/src/tests/category_validation.test.ts +18 -0
  17. package/src/tests/faq_count.test.ts +1 -1
  18. package/src/tests/i18n_coverage.test.ts +36 -0
  19. package/src/tests/locale_completeness.test.ts +2 -2
  20. package/src/tests/seo_length.test.ts +3 -0
  21. package/src/tests/slug_language_code_format.test.ts +23 -0
  22. package/src/tests/slug_uniqueness.test.ts +81 -0
  23. package/src/tool/balusterCalculator/i18n/de.ts +264 -0
  24. package/src/tool/balusterCalculator/i18n/id.ts +264 -0
  25. package/src/tool/balusterCalculator/i18n/it.ts +264 -0
  26. package/src/tool/balusterCalculator/i18n/ja.ts +264 -0
  27. package/src/tool/balusterCalculator/i18n/ko.ts +264 -0
  28. package/src/tool/balusterCalculator/i18n/nl.ts +264 -0
  29. package/src/tool/balusterCalculator/i18n/pl.ts +264 -0
  30. package/src/tool/balusterCalculator/i18n/pt.ts +264 -0
  31. package/src/tool/balusterCalculator/i18n/ru.ts +264 -0
  32. package/src/tool/balusterCalculator/i18n/sv.ts +264 -0
  33. package/src/tool/balusterCalculator/i18n/tr.ts +264 -0
  34. package/src/tool/balusterCalculator/i18n/zh.ts +264 -0
  35. package/src/tool/balusterCalculator/index.ts +15 -7
  36. package/src/tool/clayCalculator/i18n/de.ts +183 -0
  37. package/src/tool/clayCalculator/i18n/id.ts +183 -0
  38. package/src/tool/clayCalculator/i18n/it.ts +183 -0
  39. package/src/tool/clayCalculator/i18n/ja.ts +182 -0
  40. package/src/tool/clayCalculator/i18n/ko.ts +183 -0
  41. package/src/tool/clayCalculator/i18n/nl.ts +183 -0
  42. package/src/tool/clayCalculator/i18n/pl.ts +183 -0
  43. package/src/tool/clayCalculator/i18n/pt.ts +183 -0
  44. package/src/tool/clayCalculator/i18n/ru.ts +183 -0
  45. package/src/tool/clayCalculator/i18n/sv.ts +183 -0
  46. package/src/tool/clayCalculator/i18n/tr.ts +183 -0
  47. package/src/tool/clayCalculator/i18n/zh.ts +183 -0
  48. package/src/tool/clayCalculator/index.ts +15 -7
  49. package/src/tool/concreteCalculator/i18n/de.ts +201 -0
  50. package/src/tool/concreteCalculator/i18n/id.ts +201 -0
  51. package/src/tool/concreteCalculator/i18n/it.ts +201 -0
  52. package/src/tool/concreteCalculator/i18n/ja.ts +201 -0
  53. package/src/tool/concreteCalculator/i18n/ko.ts +201 -0
  54. package/src/tool/concreteCalculator/i18n/nl.ts +201 -0
  55. package/src/tool/concreteCalculator/i18n/pl.ts +201 -0
  56. package/src/tool/concreteCalculator/i18n/pt.ts +201 -0
  57. package/src/tool/concreteCalculator/i18n/ru.ts +201 -0
  58. package/src/tool/concreteCalculator/i18n/sv.ts +201 -0
  59. package/src/tool/concreteCalculator/i18n/tr.ts +201 -0
  60. package/src/tool/concreteCalculator/i18n/zh.ts +201 -0
  61. package/src/tool/concreteCalculator/index.ts +17 -5
  62. package/src/tool/cutOptimizer/i18n/de.ts +178 -0
  63. package/src/tool/cutOptimizer/i18n/id.ts +178 -0
  64. package/src/tool/cutOptimizer/i18n/it.ts +178 -0
  65. package/src/tool/cutOptimizer/i18n/ja.ts +178 -0
  66. package/src/tool/cutOptimizer/i18n/ko.ts +178 -0
  67. package/src/tool/cutOptimizer/i18n/nl.ts +178 -0
  68. package/src/tool/cutOptimizer/i18n/pl.ts +178 -0
  69. package/src/tool/cutOptimizer/i18n/pt.ts +178 -0
  70. package/src/tool/cutOptimizer/i18n/ru.ts +178 -0
  71. package/src/tool/cutOptimizer/i18n/sv.ts +178 -0
  72. package/src/tool/cutOptimizer/i18n/tr.ts +178 -0
  73. package/src/tool/cutOptimizer/i18n/zh.ts +178 -0
  74. package/src/tool/cutOptimizer/index.ts +17 -5
  75. package/src/tool/drillCalculator/i18n/de.ts +137 -0
  76. package/src/tool/drillCalculator/i18n/id.ts +137 -0
  77. package/src/tool/drillCalculator/i18n/it.ts +137 -0
  78. package/src/tool/drillCalculator/i18n/ja.ts +137 -0
  79. package/src/tool/drillCalculator/i18n/ko.ts +137 -0
  80. package/src/tool/drillCalculator/i18n/nl.ts +137 -0
  81. package/src/tool/drillCalculator/i18n/pl.ts +137 -0
  82. package/src/tool/drillCalculator/i18n/pt.ts +137 -0
  83. package/src/tool/drillCalculator/i18n/ru.ts +137 -0
  84. package/src/tool/drillCalculator/i18n/sv.ts +137 -0
  85. package/src/tool/drillCalculator/i18n/tr.ts +137 -0
  86. package/src/tool/drillCalculator/i18n/zh.ts +137 -0
  87. package/src/tool/drillCalculator/index.ts +17 -5
  88. package/src/tool/drillSharpener/i18n/de.ts +120 -0
  89. package/src/tool/drillSharpener/i18n/id.ts +120 -0
  90. package/src/tool/drillSharpener/i18n/it.ts +120 -0
  91. package/src/tool/drillSharpener/i18n/ja.ts +120 -0
  92. package/src/tool/drillSharpener/i18n/ko.ts +120 -0
  93. package/src/tool/drillSharpener/i18n/nl.ts +120 -0
  94. package/src/tool/drillSharpener/i18n/pl.ts +120 -0
  95. package/src/tool/drillSharpener/i18n/pt.ts +120 -0
  96. package/src/tool/drillSharpener/i18n/ru.ts +120 -0
  97. package/src/tool/drillSharpener/i18n/sv.ts +120 -0
  98. package/src/tool/drillSharpener/i18n/tr.ts +120 -0
  99. package/src/tool/drillSharpener/i18n/zh.ts +120 -0
  100. package/src/tool/drillSharpener/index.ts +17 -5
  101. package/src/tool/epoxyCalculator/i18n/de.ts +118 -0
  102. package/src/tool/epoxyCalculator/i18n/id.ts +118 -0
  103. package/src/tool/epoxyCalculator/i18n/it.ts +118 -0
  104. package/src/tool/epoxyCalculator/i18n/ja.ts +118 -0
  105. package/src/tool/epoxyCalculator/i18n/ko.ts +118 -0
  106. package/src/tool/epoxyCalculator/i18n/nl.ts +118 -0
  107. package/src/tool/epoxyCalculator/i18n/pl.ts +118 -0
  108. package/src/tool/epoxyCalculator/i18n/pt.ts +118 -0
  109. package/src/tool/epoxyCalculator/i18n/ru.ts +118 -0
  110. package/src/tool/epoxyCalculator/i18n/sv.ts +118 -0
  111. package/src/tool/epoxyCalculator/i18n/tr.ts +118 -0
  112. package/src/tool/epoxyCalculator/i18n/zh.ts +118 -0
  113. package/src/tool/epoxyCalculator/index.ts +15 -7
  114. package/src/tool/furnitureFit/i18n/de.ts +113 -0
  115. package/src/tool/furnitureFit/i18n/id.ts +113 -0
  116. package/src/tool/furnitureFit/i18n/it.ts +113 -0
  117. package/src/tool/furnitureFit/i18n/ja.ts +113 -0
  118. package/src/tool/furnitureFit/i18n/ko.ts +113 -0
  119. package/src/tool/furnitureFit/i18n/nl.ts +113 -0
  120. package/src/tool/furnitureFit/i18n/pl.ts +113 -0
  121. package/src/tool/furnitureFit/i18n/pt.ts +113 -0
  122. package/src/tool/furnitureFit/i18n/ru.ts +113 -0
  123. package/src/tool/furnitureFit/i18n/sv.ts +113 -0
  124. package/src/tool/furnitureFit/i18n/tr.ts +113 -0
  125. package/src/tool/furnitureFit/i18n/zh.ts +113 -0
  126. package/src/tool/furnitureFit/index.ts +17 -5
  127. package/src/tool/mortarCalculator/i18n/de.ts +129 -0
  128. package/src/tool/mortarCalculator/i18n/id.ts +129 -0
  129. package/src/tool/mortarCalculator/i18n/it.ts +129 -0
  130. package/src/tool/mortarCalculator/i18n/ja.ts +129 -0
  131. package/src/tool/mortarCalculator/i18n/ko.ts +129 -0
  132. package/src/tool/mortarCalculator/i18n/nl.ts +129 -0
  133. package/src/tool/mortarCalculator/i18n/pl.ts +129 -0
  134. package/src/tool/mortarCalculator/i18n/pt.ts +129 -0
  135. package/src/tool/mortarCalculator/i18n/ru.ts +129 -0
  136. package/src/tool/mortarCalculator/i18n/sv.ts +129 -0
  137. package/src/tool/mortarCalculator/i18n/tr.ts +129 -0
  138. package/src/tool/mortarCalculator/i18n/zh.ts +129 -0
  139. package/src/tool/mortarCalculator/index.ts +17 -5
  140. package/src/tool/passepartoutCalculator/i18n/de.ts +108 -0
  141. package/src/tool/passepartoutCalculator/i18n/id.ts +108 -0
  142. package/src/tool/passepartoutCalculator/i18n/it.ts +108 -0
  143. package/src/tool/passepartoutCalculator/i18n/ja.ts +108 -0
  144. package/src/tool/passepartoutCalculator/i18n/ko.ts +108 -0
  145. package/src/tool/passepartoutCalculator/i18n/nl.ts +108 -0
  146. package/src/tool/passepartoutCalculator/i18n/pl.ts +108 -0
  147. package/src/tool/passepartoutCalculator/i18n/pt.ts +108 -0
  148. package/src/tool/passepartoutCalculator/i18n/ru.ts +108 -0
  149. package/src/tool/passepartoutCalculator/i18n/sv.ts +108 -0
  150. package/src/tool/passepartoutCalculator/i18n/tr.ts +108 -0
  151. package/src/tool/passepartoutCalculator/i18n/zh.ts +108 -0
  152. package/src/tool/passepartoutCalculator/index.ts +17 -5
  153. package/src/tool/stairCalculator/i18n/de.ts +144 -0
  154. package/src/tool/stairCalculator/i18n/id.ts +144 -0
  155. package/src/tool/stairCalculator/i18n/it.ts +144 -0
  156. package/src/tool/stairCalculator/i18n/ja.ts +144 -0
  157. package/src/tool/stairCalculator/i18n/ko.ts +144 -0
  158. package/src/tool/stairCalculator/i18n/nl.ts +144 -0
  159. package/src/tool/stairCalculator/i18n/pl.ts +144 -0
  160. package/src/tool/stairCalculator/i18n/pt.ts +144 -0
  161. package/src/tool/stairCalculator/i18n/ru.ts +144 -0
  162. package/src/tool/stairCalculator/i18n/sv.ts +144 -0
  163. package/src/tool/stairCalculator/i18n/tr.ts +144 -0
  164. package/src/tool/stairCalculator/i18n/zh.ts +144 -0
  165. package/src/tool/stairCalculator/index.ts +17 -5
  166. package/src/tool/thermalExpansionCalculator/i18n/de.ts +132 -0
  167. package/src/tool/thermalExpansionCalculator/i18n/id.ts +130 -0
  168. package/src/tool/thermalExpansionCalculator/i18n/it.ts +130 -0
  169. package/src/tool/thermalExpansionCalculator/i18n/ja.ts +130 -0
  170. package/src/tool/thermalExpansionCalculator/i18n/ko.ts +130 -0
  171. package/src/tool/thermalExpansionCalculator/i18n/nl.ts +130 -0
  172. package/src/tool/thermalExpansionCalculator/i18n/pl.ts +130 -0
  173. package/src/tool/thermalExpansionCalculator/i18n/pt.ts +130 -0
  174. package/src/tool/thermalExpansionCalculator/i18n/ru.ts +130 -0
  175. package/src/tool/thermalExpansionCalculator/i18n/sv.ts +130 -0
  176. package/src/tool/thermalExpansionCalculator/i18n/tr.ts +130 -0
  177. package/src/tool/thermalExpansionCalculator/i18n/zh.ts +130 -0
  178. package/src/tool/thermalExpansionCalculator/index.ts +17 -5
  179. package/src/tool/voltageDropCalculator/i18n/de.ts +112 -0
  180. package/src/tool/voltageDropCalculator/i18n/id.ts +110 -0
  181. package/src/tool/voltageDropCalculator/i18n/it.ts +110 -0
  182. package/src/tool/voltageDropCalculator/i18n/ja.ts +110 -0
  183. package/src/tool/voltageDropCalculator/i18n/ko.ts +110 -0
  184. package/src/tool/voltageDropCalculator/i18n/nl.ts +110 -0
  185. package/src/tool/voltageDropCalculator/i18n/pl.ts +110 -0
  186. package/src/tool/voltageDropCalculator/i18n/pt.ts +110 -0
  187. package/src/tool/voltageDropCalculator/i18n/ru.ts +110 -0
  188. package/src/tool/voltageDropCalculator/i18n/sv.ts +110 -0
  189. package/src/tool/voltageDropCalculator/i18n/tr.ts +110 -0
  190. package/src/tool/voltageDropCalculator/i18n/zh.ts +110 -0
  191. package/src/tool/voltageDropCalculator/index.ts +17 -5
  192. package/src/tools.ts +2 -0
  193. package/src/types.ts +1 -1
@@ -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 = 'optymalizator-ciecia';
6
+ const title = 'Optymalizator Cięcia Listew i Płyt';
7
+ const description =
8
+ 'Bezpłatny kalkulator optymalizacji cięcia drewna, metalu lub rur. Minimalizuj odpady dzięki algorytmom Bin Packing 1D i 2D. Idealny dla stolarstwa i metalurgii.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: 'Co to jest optymalizator cięcia 1D?',
13
+ answer:
14
+ 'Jest to narzędzie wykorzystujące algorytmy matematyczne (takie jak problem pakowania w pojemniki - Bin Packing Problem), aby określić, jak wyciąć mniejsze elementy ze standardowego długiego elementu (listwa, profil, rura) przy minimalnym możliwym odpadzie.',
15
+ },
16
+ {
17
+ question: 'Dlaczego należy uwzględnić grubość rzazu (Kerf)?',
18
+ answer:
19
+ 'Za każdym razem, gdy piła przecina materiał, zużywa się kilka milimetrów (zwykle od 2 do 4 mm w zależności od tarczy). Jeśli nie uwzględnisz tej przestrzeni, ostatnie elementy z Twojej listy będą krótsze niż planowano.',
20
+ },
21
+ {
22
+ question: 'Czy mogę mieszać elementy o różnych długościach?',
23
+ answer:
24
+ 'Tak, nasz kalkulator akceptuje dowolną kombinację długości i ilości. Algorytm oceni wszystkie możliwe kombinacje i nada priorytet maksymalnemu wykorzystaniu materiału z magazynu.',
25
+ },
26
+ {
27
+ question: 'Jak zapisać mój plan cięcia?',
28
+ answer:
29
+ 'Po zoptymalizowaniu możesz wydrukować stronę lub zrobić zrzut ekranu schematu wizualnego. Służy to jako fizyczny przewodnik w warsztacie, aby nie pomylić kolejności cięć.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Zdefiniuj materiał bazowy (Stock)',
36
+ text: 'Wprowadź całkowitą długość dostępnej listwy lub profilu (np. 2400 mm lub 6000 mm).',
37
+ },
38
+ {
39
+ name: 'Skonfiguruj grubość tarczy (Kerf)',
40
+ text: 'Ustaw milimetry, które piła usuwa przy każdym przejściu, aby obliczenie było co do milimetra dokładne.',
41
+ },
42
+ {
43
+ name: 'Wymień pożądane elementy',
44
+ text: 'Wpisz długość i ilość każdego elementu, którego potrzebujesz do swojego projektu.',
45
+ },
46
+ {
47
+ name: 'Uruchom optymalizację',
48
+ text: 'Uzyskaj najbardziej wydajny schemat cięcia i dokładny procent wygenerowanego odpadu.',
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: 'pl',
84
+ };
85
+
86
+ export const content: ToolLocaleContent<CutOptimizerUI> = {
87
+ slug,
88
+ title,
89
+ description,
90
+ faqTitle: 'Często Zadawane Pytania',
91
+ faq: faqData,
92
+ bibliographyTitle: 'Referencje Techniczne',
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: 'Ostateczny Przewodnik Optymalizacji Cięcia',
109
+ level: 2,
110
+ },
111
+ {
112
+ type: 'paragraph',
113
+ html: 'Optymalizacja cięcia, technicznie znana jako <strong>Problem Cięcia Magazynowego (Cutting Stock Problem)</strong>, jest jednym z najciekawszych wyzwań logistycznych w inżynierii przemysłowej. Dla projektu z 20 elementami i 5 prętami magazynowymi istnieją miliony możliwych kombinacji. Algorytm komputerowy może znaleźć optymalne rozwiązanie w milisekundy, redukując typowy odpad z 15% do mniej niż 5%.',
114
+ },
115
+ {
116
+ type: 'title',
117
+ text: 'Cięcie liniowe 1D i cięcie płyt 2D',
118
+ level: 3,
119
+ },
120
+ {
121
+ type: 'card',
122
+ icon: 'mdi:arrow-expand-horizontal',
123
+ title: 'Cięcie liniowe dla listew i profili',
124
+ html: '<p>W <strong>cięciu liniowym (1D)</strong> optymalizacja zachodzi tylko w jednym wymiarze: długości. Szerokość materiału przyjmuje się jako stałą. Idealne dla tarcicy (listwy, belki), profili metalowych i aluminiowych, rur PVC lub miedzianych oraz prętów gwintowanych.</p>',
125
+ },
126
+ {
127
+ type: 'card',
128
+ icon: 'mdi:view-grid',
129
+ title: 'Cięcie płyt dla paneli i blach',
130
+ html: '<p>W <strong>cięciu płyt (2D)</strong> zarządza się dwoma wymiarami: szerokością i długością. Narzędzie wykorzystuje algorytmy typu gilotynowego, w których każde cięcie idzie od krawędzi do krawędzi. Idealne dla płyt drewnopochodnych (MDF, wiórowa), sklejki, szkła, pleksi i blach metalowych.</p>',
131
+ },
132
+ {
133
+ type: 'title',
134
+ text: 'Czynnik krytyczny: Grubość rzazu (Kerf)',
135
+ level: 3,
136
+ },
137
+ {
138
+ type: 'paragraph',
139
+ html: '<strong>Kerf</strong> to materiał usuwany przy każdym cięciu. Standardowa tarcza piły stołowej zużywa od 3,0 mm do 3,2 mm na cięcie. Ręczna piła tarczowa zużywa 1,5 do 2,5 mm. Cięcie laserowe w pleksi zaledwie 0,1 do 0,3 mm. Zignorowanie rzazu w projekcie z 10 cięciami na listwach o długości 2400 mm może spowodować utratę od 30 mm do 32 mm użytecznego materiału.',
140
+ },
141
+ {
142
+ type: 'title',
143
+ text: 'Algorytm Best Fit Decreasing',
144
+ level: 3,
145
+ },
146
+ {
147
+ type: 'card',
148
+ icon: 'mdi:chip',
149
+ title: 'Jak działa optymalizator od środka',
150
+ html: '<p>Rdzeń optymalizatora wykorzystuje strategię <strong>Best Fit Decreasing (BFD)</strong>: najpierw sortuje wszystkie elementy od największej do najmniejszej długości (duże elementy trudniej dopasować). Następnie dla każdego elementu szuka istniejącego odpadu, w którym się zmieści, pozostawiając jak najmniejszą resztę. Tylko jeśli nie mieści się w żadnym odpadzie, otwiera nowy pełny pręt. Ten proces redukuje odpady o rząd wielkości w stosunku do losowego wyboru.</p>',
151
+ },
152
+ ],
153
+ ui: {
154
+ modeLinearLabel: 'Liniowy (Pręty)',
155
+ modePanelLabel: 'Panelowy (Płyty)',
156
+ configTitle: 'Konfiguracja Materiału',
157
+ labelStockLength: 'Długość Materiału (mm)',
158
+ labelStockWidth: 'Szerokość Materiał (mm)',
159
+ labelKerf: 'Grubość Tarczy / Kerf (mm)',
160
+ cutsTitle: 'Lista Cięć',
161
+ placeholderLength: 'Długość',
162
+ placeholderWidth: 'Szerokość',
163
+ placeholderQty: 'Ilość',
164
+ btnRemoveTitle: 'Usuń',
165
+ statStockUsed: 'Użyty Materiał',
166
+ statTotalCuts: 'Całkowite Cięcia',
167
+ statWaste: 'Całkowity Odpad',
168
+ statEfficiency: 'Wydajność',
169
+ vizTitle: 'Wizualizacja Cięcia',
170
+ emptyState: 'Dodaj cięcia i naciśnij oblicz, aby zobaczyć plan cięcia.',
171
+ noValidCuts: 'Nie udało się wygenerować prawidłowych cięć. Sprawdź wymiary.',
172
+ noValidPanels: 'Nie udało się wygenerować prawidłowych płyt. Sprawdź, czy elementy mieszczą się na płycie.',
173
+ stockLabel: 'Materiał',
174
+ panelLabel: 'Panel',
175
+ wasteLabel: 'Odpad:',
176
+ effLabel: 'Wydaj:',
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 = 'otimizador-corte';
6
+ const title = 'Otimizador de Cortes de Ripas e Painéis';
7
+ const description =
8
+ 'Calculadora gratuita para otimizar cortes em madeira, metal ou tubagens. Minimize o desperdício com o algoritmo Bin Packing 1D e 2D. Ideal para carpintaria, serralharia e reformas.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: 'O que é um otimizador de corte 1D?',
13
+ answer:
14
+ 'É uma ferramenta que utiliza algoritmos matemáticos (como o Bin Packing Problem) para determinar como cortar peças mais pequenas de uma peça longa padrão (ripa, perfil, tubo) com o mínimo desperdício possível.',
15
+ },
16
+ {
17
+ question: 'Por que incluir a espessura do corte (Kerf)?',
18
+ answer:
19
+ 'Cada vez que a serra corta o material, são consumidos alguns milímetros (normalmente entre 2mm e 4mm conforme o disco). Se não calcular este espaço, as últimas peças da sua lista ficarão mais curtas do que o planeado.',
20
+ },
21
+ {
22
+ question: 'Posso misturar peças de diferentes comprimentos?',
23
+ answer:
24
+ 'Sim, a nossa calculadora aceita qualquer combinação de comprimentos e quantidades. O algoritmo avaliará todas as combinações possíveis e priorizará o aproveitamento máximo do material de stock.',
25
+ },
26
+ {
27
+ question: 'Como guardo o meu plano de corte?',
28
+ answer:
29
+ 'Uma vez otimizado, pode imprimir a página ou fazer uma captura de ecrã do esquema visual. Isto servirá de guia físico na oficina para não confundir a ordem dos cortes.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Definir o material base (Stock)',
36
+ text: 'Introduza o comprimento total da ripa ou perfil disponível (ex. 2400mm ou 6000mm).',
37
+ },
38
+ {
39
+ name: 'Configurar a espessura do disco (Kerf)',
40
+ text: 'Ajuste os milímetros que a serra remove em cada passo para que o cálculo seja milimétrico.',
41
+ },
42
+ {
43
+ name: 'Listar as peças desejadas',
44
+ text: 'Escreva o comprimento e quantidade de cada peça de que necessita para o seu projeto.',
45
+ },
46
+ {
47
+ name: 'Executar a otimização',
48
+ text: 'Obtenha o esquema de corte mais eficiente e a percentagem exata de desperdício gerado.',
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: 'pt',
84
+ };
85
+
86
+ export const content: ToolLocaleContent<CutOptimizerUI> = {
87
+ slug,
88
+ title,
89
+ description,
90
+ faqTitle: 'Perguntas Frequentes',
91
+ faq: faqData,
92
+ bibliographyTitle: 'Referências Técnicas',
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: 'Guia Definitiva de Otimização de Corte',
109
+ level: 2,
110
+ },
111
+ {
112
+ type: 'paragraph',
113
+ html: 'La otimização de corte, conhecida tecnicamente como o <strong>Problema de Corte de Stock</strong>, é um dos desafios logísticos mais fascinantes na engenharia industrial. Para um projeto com 20 peças e 5 barras de stock, existem milhões de combinações possíveis. Um algoritmo computacional pode encontrar a solução ótima em milisegundos, reduzindo o desperdício habitual de 15% para menos de 5%.',
114
+ },
115
+ {
116
+ type: 'title',
117
+ text: 'Corte Linear 1D e Corte de Painel 2D',
118
+ level: 3,
119
+ },
120
+ {
121
+ type: 'card',
122
+ icon: 'mdi:arrow-expand-horizontal',
123
+ title: 'Corte Linear para Ripas e Perfis',
124
+ html: '<p>No <strong>corte linear (1D)</strong>, a otimização ocorre apenas numa dimensão: o comprimento. A largura do material é assumida constante. É ideal para madeira dimensional (ripas, vigas), perfis metálicos e de alumínio, tubagens de PVC ou cobre, e varões roscados.</p>',
125
+ },
126
+ {
127
+ type: 'card',
128
+ icon: 'mdi:view-grid',
129
+ title: 'Corte de Painel para Placas e Chapas',
130
+ html: '<p>No <strong>corte de painel (2D)</strong>, gerem-se duas dimensões: largura e comprimento. A ferramenta utiliza algoritmos tipo guilhotina, onde cada corte vai de borda a borda. Ideal para painéis derivados (MDF, aglomerado), contraplacado, vidro, metacrilato e chapas metálicas.</p>',
131
+ },
132
+ {
133
+ type: 'title',
134
+ text: 'O Factor Crítico: A Espessura do Corte (Kerf)',
135
+ level: 3,
136
+ },
137
+ {
138
+ type: 'paragraph',
139
+ html: 'O <strong>Kerf</strong> é o material que se remove em cada corte. Um disco de serra padrão de mesa consome entre 3,0mm e 3,2mm por corte. Uma serra circular de mão consome 1,5 a 2,5mm. Um corte laser em metacrilato apenas 0,1 a 0,3mm. Ignorar o kerf num projeto com 10 cortes em ripas de 2400mm pode fazer com que perca entre 30mm e 32mm de material útil.',
140
+ },
141
+ {
142
+ type: 'title',
143
+ text: 'O Algoritmo Best Fit Decreasing',
144
+ level: 3,
145
+ },
146
+ {
147
+ type: 'card',
148
+ icon: 'mdi:chip',
149
+ title: 'Como Funciona o Otimizador por Dentro',
150
+ html: '<p>O núcleo do otimizador usa a estratégia <strong>Best Fit Decreasing (BFD)</strong>: primeiro ordena todas as peças do maior ao menor comprimento (as grandes são mais difíceis de encaixar). Depois, para cada peça, procura a sobra existente onde caiba deixando o menor excedente possível. Só se não couber em nenhuma, abre uma nova barra virgem. Este processo reduz o desperdício numa ordem de magnitude em relação à seleção aleatória.</p>',
151
+ },
152
+ ],
153
+ ui: {
154
+ modeLinearLabel: 'Linear (Barras)',
155
+ modePanelLabel: 'Painel (Placas)',
156
+ configTitle: 'Configuração Material',
157
+ labelStockLength: 'Comprimento do Material (mm)',
158
+ labelStockWidth: 'Largura do Material (mm)',
159
+ labelKerf: 'Espessura da Folha / Kerf (mm)',
160
+ cutsTitle: 'Lista de Cortes',
161
+ placeholderLength: 'Compr.',
162
+ placeholderWidth: 'Largura',
163
+ placeholderQty: 'Quant.',
164
+ btnRemoveTitle: 'Remover',
165
+ statStockUsed: 'Material Usado',
166
+ statTotalCuts: 'Cortes Totais',
167
+ statWaste: 'Desperdício Total',
168
+ statEfficiency: 'Eficiência',
169
+ vizTitle: 'Visualização de Corte',
170
+ emptyState: 'Adicione cortes e prima calcular para ver o plano de corte.',
171
+ noValidCuts: 'Não foi possível gerar cortes válidos. Verifique as medidas.',
172
+ noValidPanels: 'Não foi possível gerar painéis válidos. Verifique se as peças cabem na placa.',
173
+ stockLabel: 'Material',
174
+ panelLabel: 'Painel',
175
+ wasteLabel: 'Desperdício:',
176
+ effLabel: 'Efic:',
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 = 'optimizator-raskroya';
6
+ const title = 'Оптимизатор раскроя полотна и досок';
7
+ const description =
8
+ 'Бесплатный калькулятор для оптимизации раскроя дерева, металла или труб. Минимизируйте отходы с помощью алгоритмов Bin Packing 1D и 2D. Идеально для столярных работ, металлообработки и ремонта.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: 'Что такое 1D оптимизатор раскроя?',
13
+ answer:
14
+ 'Это инструмент, использующий математические алгоритмы (такие как задача об упаковке в контейнеры - Bin Packing Problem), чтобы определить, как вырезать более мелкие детали из стандартной длинной заготовки (рейка, профиль, труба) с минимально возможными отходами.',
15
+ },
16
+ {
17
+ question: 'Почему нужно учитывать толщину реза (Kerf)?',
18
+ answer:
19
+ 'Каждый раз, когда пила прорезает материал, расходуется несколько миллиметров (обычно от 2 до 4 мм в зависимости от диска). Если не учитывать это пространство, последние детали в вашем списке окажутся короче, чем планировалось.',
20
+ },
21
+ {
22
+ question: 'Можно ли смешивать детали разной длины?',
23
+ answer:
24
+ 'Да, наш калькулятор принимает любые комбинации длины и количества. Алгоритм оценит все возможные комбинации и отдаст приоритет максимальному использованию имеющегося материала.',
25
+ },
26
+ {
27
+ question: 'Как сохранить план раскроя?',
28
+ answer:
29
+ 'После завершения оптимизации вы можете распечатать страницу или сделать снимок экрана визуальной схемы. Это послужит физическим руководством в мастерской, чтобы не перепутать порядок резов.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Определите исходный материал (Stock)',
36
+ text: 'Введите общую длину имеющейся рейки или профиля (например, 2400 мм или 6000 мм).',
37
+ },
38
+ {
39
+ name: 'Настройте толщину диска (Kerf)',
40
+ text: 'Установите количество миллиметров, которые пила удаляет при каждом проходе, чтобы расчет был точным до миллиметра.',
41
+ },
42
+ {
43
+ name: 'Составьте список деталей',
44
+ text: 'Введите длину и количество каждой детали, необходимой для вашего проекта.',
45
+ },
46
+ {
47
+ name: 'Запустите оптимизацию',
48
+ text: 'Получите наиболее эффективную схему раскроя и точный процент образующихся отходов.',
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: 'ru',
84
+ };
85
+
86
+ export const content: ToolLocaleContent<CutOptimizerUI> = {
87
+ slug,
88
+ title,
89
+ description,
90
+ faqTitle: 'Часто задаваемые вопросы',
91
+ faq: faqData,
92
+ bibliographyTitle: 'Технические справочники',
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: 'Полное руководство по оптимизации раскроя',
109
+ level: 2,
110
+ },
111
+ {
112
+ type: 'paragraph',
113
+ html: 'Оптимизация раскроя, технически известная как <strong>задача о раскрое материала (Cutting Stock Problem)</strong>, является одной из самых интересных логистических задач в промышленном проектировании. Для проекта из 20 деталей и 5 заготовок существуют миллионы возможных комбинаций. Компьютерный алгоритм может найти оптимальное решение за миллисекунды, сокращая обычные отходы с 15% до менее чем 5%.',
114
+ },
115
+ {
116
+ type: 'title',
117
+ text: 'Линейный 1D раскрой и раскрой щитов 2D',
118
+ level: 3,
119
+ },
120
+ {
121
+ type: 'card',
122
+ icon: 'mdi:arrow-expand-horizontal',
123
+ title: 'Линейный раскрой для реек и профилей',
124
+ html: '<p>В <strong>линейном раскрое (1D)</strong> оптимизация происходит только в одном измерении: длине. Ширина материала считается постоянной. Идеально подходит для пиломатериалов (рейки, балки), металлических и алюминиевых профилей, труб ПВХ или медных труб, а также шпилек.</p>',
125
+ },
126
+ {
127
+ type: 'card',
128
+ icon: 'mdi:view-grid',
129
+ title: 'Раскрой щитов для досок и листов',
130
+ html: '<p>В <strong>раскрое щитов (2D)</strong> учитываются два измерения: ширина и длина. Инструмент использует алгоритмы гильотинного типа, где каждый рез идет от края до края. Идеально подходит для древесных плит (МДФ, ДСП), фанеры, стекла, оргстекла и металлических листов.</p>',
131
+ },
132
+ {
133
+ type: 'title',
134
+ text: 'Критический фактор: Толщина реза (Kerf)',
135
+ level: 3,
136
+ },
137
+ {
138
+ type: 'paragraph',
139
+ html: '<strong>Kerf</strong> — это материал, который удаляется при каждом резе. Стандартный диск настольной пилы расходует от 3,0 до 3,2 мм на один рез. Ручная циркулярная пила расходует 1,5–2,5 мм. Лазерная резка оргстекла — всего 0,1–0,3 мм. Игнорирование толщины реза в проекте с 10 резами на рейках длиной 2400 мм может привести к потере от 30 до 32 мм полезного материала.',
140
+ },
141
+ {
142
+ type: 'title',
143
+ text: 'Алгоритм Best Fit Decreasing',
144
+ level: 3,
145
+ },
146
+ {
147
+ type: 'card',
148
+ icon: 'mdi:chip',
149
+ title: 'Как работает оптимизатор изнутри',
150
+ html: '<p>Ядро оптимизатора использует стратегию <strong>Best Fit Decreasing (BFD)</strong>: сначала сортируются все детали от самой длинной к самой короткой (большие детали сложнее разместить). Затем для каждой детали ищется существующий остаток, в который она помещается с минимальным лишним зазором. Только если деталь не помещается ни в один остаток, берется новая заготовка. Этот процесс сокращает отходы на порядки по сравнению со случайным выбором.</p>',
151
+ },
152
+ ],
153
+ ui: {
154
+ modeLinearLabel: 'Линейный (Заготовки)',
155
+ modePanelLabel: 'Панельный (Щиты)',
156
+ configTitle: 'Настройка материала',
157
+ labelStockLength: 'Длина материала (мм)',
158
+ labelStockWidth: 'Ширина материала (мм)',
159
+ labelKerf: 'Толщина диска / Kerf (мм)',
160
+ cutsTitle: 'Список резов',
161
+ placeholderLength: 'Длина',
162
+ placeholderWidth: 'Ширина',
163
+ placeholderQty: 'Кол-во',
164
+ btnRemoveTitle: 'Удалить',
165
+ statStockUsed: 'Использовано материала',
166
+ statTotalCuts: 'Всего резов',
167
+ statWaste: 'Всего отходов',
168
+ statEfficiency: 'Эффективность',
169
+ vizTitle: 'Визуализация раскроя',
170
+ emptyState: 'Добавьте детали и нажмите расчет, чтобы увидеть план раскроя.',
171
+ noValidCuts: 'Не удалось создать корректный раскрой. Проверьте размеры.',
172
+ noValidPanels: 'Не удалось создать корректные щиты. Убедитесь, что детали помещаются на щите.',
173
+ stockLabel: 'Материал',
174
+ panelLabel: 'Панель',
175
+ wasteLabel: 'Отходы:',
176
+ effLabel: 'Эфф:',
177
+ },
178
+ };