@jjlmoya/utils-cooking 1.23.0 → 1.25.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 (252) hide show
  1. package/package.json +1 -1
  2. package/src/entries.ts +3 -1
  3. package/src/index.ts +1 -0
  4. package/src/pages/[locale]/[slug].astro +56 -19
  5. package/src/tests/i18n-titles.test.ts +5 -17
  6. package/src/tests/locale_completeness.test.ts +2 -13
  7. package/src/tests/shared-test-helpers.ts +56 -0
  8. package/src/tests/tool_exports.test.ts +34 -0
  9. package/src/tests/tool_validation.test.ts +2 -2
  10. package/src/tool/american-kitchen-converter/bibliography.astro +3 -3
  11. package/src/tool/american-kitchen-converter/bibliography.ts +10 -0
  12. package/src/tool/american-kitchen-converter/i18n/de.ts +2 -11
  13. package/src/tool/american-kitchen-converter/i18n/en.ts +2 -11
  14. package/src/tool/american-kitchen-converter/i18n/es.ts +40 -49
  15. package/src/tool/american-kitchen-converter/i18n/fr.ts +2 -21
  16. package/src/tool/american-kitchen-converter/i18n/id.ts +2 -11
  17. package/src/tool/american-kitchen-converter/i18n/it.ts +2 -11
  18. package/src/tool/american-kitchen-converter/i18n/ja.ts +2 -11
  19. package/src/tool/american-kitchen-converter/i18n/ko.ts +2 -11
  20. package/src/tool/american-kitchen-converter/i18n/nl.ts +2 -11
  21. package/src/tool/american-kitchen-converter/i18n/pl.ts +2 -11
  22. package/src/tool/american-kitchen-converter/i18n/pt.ts +2 -11
  23. package/src/tool/american-kitchen-converter/i18n/ru.ts +2 -11
  24. package/src/tool/american-kitchen-converter/i18n/sv.ts +2 -11
  25. package/src/tool/american-kitchen-converter/i18n/tr.ts +2 -11
  26. package/src/tool/american-kitchen-converter/i18n/zh.ts +2 -11
  27. package/src/tool/american-kitchen-converter/seo.astro +11 -4
  28. package/src/tool/banana-ripeness/bibliography.astro +3 -3
  29. package/src/tool/banana-ripeness/bibliography.ts +10 -0
  30. package/src/tool/banana-ripeness/i18n/de.ts +2 -15
  31. package/src/tool/banana-ripeness/i18n/en.ts +36 -49
  32. package/src/tool/banana-ripeness/i18n/es.ts +36 -49
  33. package/src/tool/banana-ripeness/i18n/fr.ts +36 -49
  34. package/src/tool/banana-ripeness/i18n/id.ts +2 -15
  35. package/src/tool/banana-ripeness/i18n/it.ts +2 -15
  36. package/src/tool/banana-ripeness/i18n/ja.ts +2 -15
  37. package/src/tool/banana-ripeness/i18n/ko.ts +2 -15
  38. package/src/tool/banana-ripeness/i18n/nl.ts +2 -15
  39. package/src/tool/banana-ripeness/i18n/pl.ts +2 -15
  40. package/src/tool/banana-ripeness/i18n/pt.ts +2 -15
  41. package/src/tool/banana-ripeness/i18n/ru.ts +2 -15
  42. package/src/tool/banana-ripeness/i18n/sv.ts +2 -15
  43. package/src/tool/banana-ripeness/i18n/tr.ts +2 -15
  44. package/src/tool/banana-ripeness/i18n/zh.ts +2 -15
  45. package/src/tool/banana-ripeness/seo.astro +10 -3
  46. package/src/tool/brine/bibliography.astro +3 -3
  47. package/src/tool/brine/bibliography.ts +6 -0
  48. package/src/tool/brine/i18n/de.ts +4 -19
  49. package/src/tool/brine/i18n/en.ts +3 -17
  50. package/src/tool/brine/i18n/es.ts +4 -19
  51. package/src/tool/brine/i18n/fr.ts +3 -17
  52. package/src/tool/brine/i18n/id.ts +4 -19
  53. package/src/tool/brine/i18n/it.ts +4 -19
  54. package/src/tool/brine/i18n/ja.ts +4 -19
  55. package/src/tool/brine/i18n/ko.ts +4 -19
  56. package/src/tool/brine/i18n/nl.ts +4 -19
  57. package/src/tool/brine/i18n/pl.ts +4 -19
  58. package/src/tool/brine/i18n/pt.ts +4 -19
  59. package/src/tool/brine/i18n/ru.ts +4 -19
  60. package/src/tool/brine/i18n/sv.ts +4 -19
  61. package/src/tool/brine/i18n/tr.ts +4 -19
  62. package/src/tool/brine/i18n/zh.ts +4 -19
  63. package/src/tool/brine/seo.astro +11 -4
  64. package/src/tool/cookware-guide/bibliography.astro +2 -2
  65. package/src/tool/cookware-guide/bibliography.ts +10 -0
  66. package/src/tool/cookware-guide/cookware-selector.css +470 -19
  67. package/src/tool/cookware-guide/i18n/de.ts +3 -17
  68. package/src/tool/cookware-guide/i18n/en.ts +3 -17
  69. package/src/tool/cookware-guide/i18n/es.ts +3 -17
  70. package/src/tool/cookware-guide/i18n/fr.ts +3 -17
  71. package/src/tool/cookware-guide/i18n/id.ts +3 -17
  72. package/src/tool/cookware-guide/i18n/it.ts +3 -17
  73. package/src/tool/cookware-guide/i18n/ja.ts +3 -17
  74. package/src/tool/cookware-guide/i18n/ko.ts +3 -17
  75. package/src/tool/cookware-guide/i18n/nl.ts +3 -17
  76. package/src/tool/cookware-guide/i18n/pl.ts +3 -17
  77. package/src/tool/cookware-guide/i18n/pt.ts +3 -17
  78. package/src/tool/cookware-guide/i18n/ru.ts +3 -17
  79. package/src/tool/cookware-guide/i18n/sv.ts +3 -17
  80. package/src/tool/cookware-guide/i18n/tr.ts +3 -17
  81. package/src/tool/cookware-guide/i18n/zh.ts +3 -17
  82. package/src/tool/cookware-guide/seo.astro +11 -4
  83. package/src/tool/egg-timer/bibliography.astro +3 -11
  84. package/src/tool/egg-timer/bibliography.ts +10 -0
  85. package/src/tool/egg-timer/i18n/de.ts +3 -17
  86. package/src/tool/egg-timer/i18n/en.ts +2 -15
  87. package/src/tool/egg-timer/i18n/es.ts +127 -141
  88. package/src/tool/egg-timer/i18n/fr.ts +2 -15
  89. package/src/tool/egg-timer/i18n/id.ts +4 -18
  90. package/src/tool/egg-timer/i18n/it.ts +3 -17
  91. package/src/tool/egg-timer/i18n/ja.ts +3 -17
  92. package/src/tool/egg-timer/i18n/ko.ts +3 -17
  93. package/src/tool/egg-timer/i18n/nl.ts +3 -17
  94. package/src/tool/egg-timer/i18n/pl.ts +3 -17
  95. package/src/tool/egg-timer/i18n/pt.ts +3 -17
  96. package/src/tool/egg-timer/i18n/ru.ts +3 -17
  97. package/src/tool/egg-timer/i18n/sv.ts +3 -17
  98. package/src/tool/egg-timer/i18n/tr.ts +3 -17
  99. package/src/tool/egg-timer/i18n/zh.ts +3 -17
  100. package/src/tool/egg-timer/seo.astro +6 -30
  101. package/src/tool/ingredient-rescaler/bibliography.astro +3 -3
  102. package/src/tool/ingredient-rescaler/bibliography.ts +6 -0
  103. package/src/tool/ingredient-rescaler/i18n/de.ts +3 -17
  104. package/src/tool/ingredient-rescaler/i18n/en.ts +3 -18
  105. package/src/tool/ingredient-rescaler/i18n/es.ts +4 -19
  106. package/src/tool/ingredient-rescaler/i18n/fr.ts +2 -15
  107. package/src/tool/ingredient-rescaler/i18n/id.ts +3 -17
  108. package/src/tool/ingredient-rescaler/i18n/it.ts +3 -17
  109. package/src/tool/ingredient-rescaler/i18n/ja.ts +3 -17
  110. package/src/tool/ingredient-rescaler/i18n/ko.ts +3 -17
  111. package/src/tool/ingredient-rescaler/i18n/nl.ts +3 -17
  112. package/src/tool/ingredient-rescaler/i18n/pl.ts +3 -17
  113. package/src/tool/ingredient-rescaler/i18n/pt.ts +3 -17
  114. package/src/tool/ingredient-rescaler/i18n/ru.ts +3 -17
  115. package/src/tool/ingredient-rescaler/i18n/sv.ts +3 -17
  116. package/src/tool/ingredient-rescaler/i18n/tr.ts +3 -17
  117. package/src/tool/ingredient-rescaler/i18n/zh.ts +3 -17
  118. package/src/tool/ingredient-rescaler/recipe-ingredient-scaler-converter-servings.css +290 -17
  119. package/src/tool/ingredient-rescaler/seo.astro +11 -4
  120. package/src/tool/kitchen-timer/bibliography.astro +3 -3
  121. package/src/tool/kitchen-timer/bibliography.ts +10 -0
  122. package/src/tool/kitchen-timer/i18n/de.ts +3 -13
  123. package/src/tool/kitchen-timer/i18n/en.ts +6 -22
  124. package/src/tool/kitchen-timer/i18n/es.ts +6 -22
  125. package/src/tool/kitchen-timer/i18n/fr.ts +6 -22
  126. package/src/tool/kitchen-timer/i18n/id.ts +3 -13
  127. package/src/tool/kitchen-timer/i18n/it.ts +3 -13
  128. package/src/tool/kitchen-timer/i18n/ja.ts +3 -13
  129. package/src/tool/kitchen-timer/i18n/ko.ts +3 -13
  130. package/src/tool/kitchen-timer/i18n/nl.ts +3 -13
  131. package/src/tool/kitchen-timer/i18n/pl.ts +3 -13
  132. package/src/tool/kitchen-timer/i18n/pt.ts +3 -13
  133. package/src/tool/kitchen-timer/i18n/ru.ts +3 -13
  134. package/src/tool/kitchen-timer/i18n/sv.ts +3 -13
  135. package/src/tool/kitchen-timer/i18n/tr.ts +3 -13
  136. package/src/tool/kitchen-timer/i18n/zh.ts +3 -13
  137. package/src/tool/kitchen-timer/seo.astro +10 -3
  138. package/src/tool/meringue-peak/bibliography.astro +3 -3
  139. package/src/tool/meringue-peak/bibliography.ts +14 -0
  140. package/src/tool/meringue-peak/i18n/de.ts +3 -13
  141. package/src/tool/meringue-peak/i18n/en.ts +2 -15
  142. package/src/tool/meringue-peak/i18n/es.ts +135 -149
  143. package/src/tool/meringue-peak/i18n/fr.ts +2 -15
  144. package/src/tool/meringue-peak/i18n/id.ts +3 -13
  145. package/src/tool/meringue-peak/i18n/it.ts +3 -13
  146. package/src/tool/meringue-peak/i18n/ja.ts +3 -13
  147. package/src/tool/meringue-peak/i18n/ko.ts +3 -13
  148. package/src/tool/meringue-peak/i18n/nl.ts +3 -13
  149. package/src/tool/meringue-peak/i18n/pl.ts +3 -13
  150. package/src/tool/meringue-peak/i18n/pt.ts +3 -13
  151. package/src/tool/meringue-peak/i18n/ru.ts +3 -13
  152. package/src/tool/meringue-peak/i18n/sv.ts +3 -13
  153. package/src/tool/meringue-peak/i18n/tr.ts +3 -13
  154. package/src/tool/meringue-peak/i18n/zh.ts +3 -13
  155. package/src/tool/meringue-peak/seo.astro +10 -3
  156. package/src/tool/mold-scaler/bibliography.astro +3 -3
  157. package/src/tool/mold-scaler/bibliography.ts +10 -0
  158. package/src/tool/mold-scaler/i18n/de.ts +5 -17
  159. package/src/tool/mold-scaler/i18n/en.ts +5 -20
  160. package/src/tool/mold-scaler/i18n/es.ts +5 -20
  161. package/src/tool/mold-scaler/i18n/fr.ts +5 -20
  162. package/src/tool/mold-scaler/i18n/id.ts +5 -17
  163. package/src/tool/mold-scaler/i18n/it.ts +5 -17
  164. package/src/tool/mold-scaler/i18n/ja.ts +5 -17
  165. package/src/tool/mold-scaler/i18n/ko.ts +5 -17
  166. package/src/tool/mold-scaler/i18n/nl.ts +5 -17
  167. package/src/tool/mold-scaler/i18n/pl.ts +5 -17
  168. package/src/tool/mold-scaler/i18n/pt.ts +5 -17
  169. package/src/tool/mold-scaler/i18n/ru.ts +5 -17
  170. package/src/tool/mold-scaler/i18n/sv.ts +5 -17
  171. package/src/tool/mold-scaler/i18n/tr.ts +5 -17
  172. package/src/tool/mold-scaler/i18n/zh.ts +5 -17
  173. package/src/tool/mold-scaler/seo.astro +10 -3
  174. package/src/tool/pizza/bibliography.astro +3 -3
  175. package/src/tool/pizza/bibliography.ts +18 -0
  176. package/src/tool/pizza/i18n/de.ts +3 -13
  177. package/src/tool/pizza/i18n/en.ts +58 -75
  178. package/src/tool/pizza/i18n/es.ts +2 -20
  179. package/src/tool/pizza/i18n/fr.ts +58 -75
  180. package/src/tool/pizza/i18n/id.ts +3 -9
  181. package/src/tool/pizza/i18n/it.ts +3 -13
  182. package/src/tool/pizza/i18n/ja.ts +3 -9
  183. package/src/tool/pizza/i18n/ko.ts +3 -9
  184. package/src/tool/pizza/i18n/nl.ts +3 -9
  185. package/src/tool/pizza/i18n/pl.ts +3 -9
  186. package/src/tool/pizza/i18n/pt.ts +3 -9
  187. package/src/tool/pizza/i18n/ru.ts +28 -34
  188. package/src/tool/pizza/i18n/sv.ts +3 -9
  189. package/src/tool/pizza/i18n/tr.ts +3 -9
  190. package/src/tool/pizza/i18n/zh.ts +3 -9
  191. package/src/tool/pizza/seo.astro +11 -4
  192. package/src/tool/roux-guide/bibliography.astro +3 -3
  193. package/src/tool/roux-guide/bibliography.ts +14 -0
  194. package/src/tool/roux-guide/i18n/de.ts +3 -9
  195. package/src/tool/roux-guide/i18n/en.ts +2 -15
  196. package/src/tool/roux-guide/i18n/es.ts +3 -17
  197. package/src/tool/roux-guide/i18n/fr.ts +2 -15
  198. package/src/tool/roux-guide/i18n/id.ts +3 -9
  199. package/src/tool/roux-guide/i18n/it.ts +3 -9
  200. package/src/tool/roux-guide/i18n/ja.ts +3 -9
  201. package/src/tool/roux-guide/i18n/ko.ts +3 -9
  202. package/src/tool/roux-guide/i18n/nl.ts +3 -9
  203. package/src/tool/roux-guide/i18n/pl.ts +3 -9
  204. package/src/tool/roux-guide/i18n/pt.ts +3 -9
  205. package/src/tool/roux-guide/i18n/ru.ts +3 -9
  206. package/src/tool/roux-guide/i18n/sv.ts +3 -9
  207. package/src/tool/roux-guide/i18n/tr.ts +3 -9
  208. package/src/tool/roux-guide/i18n/zh.ts +3 -9
  209. package/src/tool/roux-guide/roux-ratio-calculator-thickening-sauce-guide.css +480 -18
  210. package/src/tool/roux-guide/seo.astro +11 -4
  211. package/src/tool/sourdough-calculator/bibliography.astro +3 -3
  212. package/src/tool/sourdough-calculator/bibliography.ts +14 -0
  213. package/src/tool/sourdough-calculator/i18n/de.ts +3 -9
  214. package/src/tool/sourdough-calculator/i18n/en.ts +3 -17
  215. package/src/tool/sourdough-calculator/i18n/es.ts +4 -18
  216. package/src/tool/sourdough-calculator/i18n/fr.ts +2 -15
  217. package/src/tool/sourdough-calculator/i18n/id.ts +3 -9
  218. package/src/tool/sourdough-calculator/i18n/it.ts +3 -9
  219. package/src/tool/sourdough-calculator/i18n/ja.ts +3 -9
  220. package/src/tool/sourdough-calculator/i18n/ko.ts +3 -9
  221. package/src/tool/sourdough-calculator/i18n/nl.ts +3 -9
  222. package/src/tool/sourdough-calculator/i18n/pl.ts +3 -9
  223. package/src/tool/sourdough-calculator/i18n/pt.ts +3 -9
  224. package/src/tool/sourdough-calculator/i18n/ru.ts +3 -9
  225. package/src/tool/sourdough-calculator/i18n/sv.ts +3 -9
  226. package/src/tool/sourdough-calculator/i18n/tr.ts +3 -9
  227. package/src/tool/sourdough-calculator/i18n/zh.ts +3 -9
  228. package/src/tool/sourdough-calculator/seo.astro +11 -4
  229. package/src/tool/yeast-converter/bibliography.astro +6 -0
  230. package/src/tool/yeast-converter/bibliography.ts +6 -0
  231. package/src/tool/yeast-converter/component.astro +96 -0
  232. package/src/tool/yeast-converter/entry.ts +26 -0
  233. package/src/tool/yeast-converter/i18n/de.ts +235 -0
  234. package/src/tool/yeast-converter/i18n/en.ts +234 -0
  235. package/src/tool/yeast-converter/i18n/es.ts +235 -0
  236. package/src/tool/yeast-converter/i18n/fr.ts +235 -0
  237. package/src/tool/yeast-converter/i18n/id.ts +235 -0
  238. package/src/tool/yeast-converter/i18n/it.ts +235 -0
  239. package/src/tool/yeast-converter/i18n/ja.ts +235 -0
  240. package/src/tool/yeast-converter/i18n/ko.ts +235 -0
  241. package/src/tool/yeast-converter/i18n/nl.ts +235 -0
  242. package/src/tool/yeast-converter/i18n/pl.ts +235 -0
  243. package/src/tool/yeast-converter/i18n/pt.ts +235 -0
  244. package/src/tool/yeast-converter/i18n/ru.ts +235 -0
  245. package/src/tool/yeast-converter/i18n/sv.ts +235 -0
  246. package/src/tool/yeast-converter/i18n/tr.ts +235 -0
  247. package/src/tool/yeast-converter/i18n/zh.ts +235 -0
  248. package/src/tool/yeast-converter/index.ts +11 -0
  249. package/src/tool/yeast-converter/init.ts +277 -0
  250. package/src/tool/yeast-converter/seo.astro +15 -0
  251. package/src/tool/yeast-converter/yeast-converter-fresh-dry-sourdough-starter.css +388 -0
  252. package/src/tools.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-cooking",
3
- "version": "1.23.0",
3
+ "version": "1.25.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
package/src/entries.ts CHANGED
@@ -10,6 +10,7 @@ export { moldScaler } from './tool/mold-scaler/entry';
10
10
  export { pizza } from './tool/pizza/entry';
11
11
  export { rouxGuide } from './tool/roux-guide/entry';
12
12
  export { sourdoughCalculator } from './tool/sourdough-calculator/entry';
13
+ export { yeastConverter } from './tool/yeast-converter/entry';
13
14
  export { cookingCategory } from './category';
14
15
  import { americanKitchenConverter } from './tool/american-kitchen-converter/entry';
15
16
  import { bananaCare } from './tool/banana-ripeness/entry';
@@ -23,4 +24,5 @@ import { moldScaler } from './tool/mold-scaler/entry';
23
24
  import { pizza } from './tool/pizza/entry';
24
25
  import { rouxGuide } from './tool/roux-guide/entry';
25
26
  import { sourdoughCalculator } from './tool/sourdough-calculator/entry';
26
- export const ALL_ENTRIES = [americanKitchenConverter, bananaCare, brine, cookwareGuide, eggTimer, ingredientRescaler, kitchenTimer, meringuePeak, moldScaler, pizza, rouxGuide, sourdoughCalculator];
27
+ import { yeastConverter } from './tool/yeast-converter/entry';
28
+ export const ALL_ENTRIES = [americanKitchenConverter, bananaCare, brine, cookwareGuide, eggTimer, ingredientRescaler, kitchenTimer, meringuePeak, moldScaler, pizza, rouxGuide, sourdoughCalculator, yeastConverter];
package/src/index.ts CHANGED
@@ -13,6 +13,7 @@ export { INGREDIENT_RESCALER_TOOL } from './tool/ingredient-rescaler';
13
13
  export { SOURDOUGH_CALCULATOR_TOOL } from './tool/sourdough-calculator';
14
14
  export { ROUX_GUIDE_TOOL } from './tool/roux-guide';
15
15
  export { COOKWARE_GUIDE_TOOL } from './tool/cookware-guide';
16
+ export { YEAST_CONVERTER_TOOL } from './tool/yeast-converter';
16
17
 
17
18
  export type {
18
19
  KnownLocale,
@@ -34,18 +34,35 @@ export async function getStaticPaths() {
34
34
  ]),
35
35
  ) as Partial<Record<KnownLocale, string>>;
36
36
 
37
+ const firstLoader = entry.i18n.en ?? Object.values(entry.i18n)[0];
38
+ const englishSlug = firstLoader ? (await firstLoader()).slug : entry.id;
39
+
37
40
  for (const { locale, content } of localeContents) {
38
- const allToolsNav = await Promise.all(
39
- ALL_TOOLS.map(async ({ entry: navEntry }) => ({
40
- id: navEntry.id,
41
- title: (await navEntry.i18n[locale]!()).title,
42
- href: `/${locale}/${(await navEntry.i18n[locale]!()).slug}`,
43
- isActive: navEntry.id === entry.id,
44
- })),
45
- );
41
+ const allToolsNav = (
42
+ await Promise.all(
43
+ ALL_TOOLS.map(async ({ entry: navEntry }) => {
44
+ const loader = navEntry.i18n[locale] ?? navEntry.i18n.en;
45
+ if (!loader) return null;
46
+ const navContent = await loader();
47
+ return {
48
+ id: navEntry.id,
49
+ title: navContent.title,
50
+ href: `/${locale}/${navContent.slug}`,
51
+ isActive: navEntry.id === entry.id,
52
+ };
53
+ }),
54
+ )
55
+ ).filter(Boolean) as NavItem[];
46
56
  paths.push({
47
57
  params: { locale, slug: content.slug },
48
- props: { Component, locale, content, localeUrls, allToolsNav },
58
+ props: {
59
+ Component,
60
+ locale,
61
+ content,
62
+ localeUrls,
63
+ allToolsNav,
64
+ englishSlug,
65
+ },
49
66
  });
50
67
  }
51
68
  }
@@ -66,11 +83,23 @@ interface Props {
66
83
  content: ToolLocaleContent;
67
84
  localeUrls: Partial<Record<KnownLocale, string>>;
68
85
  allToolsNav: NavItem[];
86
+ englishSlug: string;
69
87
  }
70
88
 
71
- const { Component, locale, content, localeUrls, allToolsNav } = Astro.props;
89
+ const { Component, locale, content, localeUrls, allToolsNav, englishSlug } =
90
+ Astro.props;
91
+
92
+ const cssFiles = import.meta.glob("../../tool/**/*.css", {
93
+ query: "?raw",
94
+ import: "default",
95
+ });
96
+ const cssKey = Object.keys(cssFiles).find((k) =>
97
+ k.endsWith(`/${englishSlug}.css`),
98
+ );
99
+ const toolCss =
100
+ cssKey && cssFiles[cssKey] ? ((await cssFiles[cssKey]()) as string) : "";
72
101
 
73
- const seoContent: UtilitySEOContent = { locale, sections: content.seo };
102
+ const seoContent: UtilitySEOContent = { locale, sections: content.seo ?? [] };
74
103
 
75
104
  const words = content.title.split(" ");
76
105
  const titleHighlight = words[0] || "";
@@ -83,14 +112,15 @@ const titleBase = words.slice(1).join(" ") || "";
83
112
  localeUrls={localeUrls}
84
113
  hasSidebar={true}
85
114
  >
86
- <PreviewNavSidebar
87
- slot="sidebar"
88
- categoryTitle="Tools"
89
- tools={allToolsNav}
90
- />
115
+ <PreviewNavSidebar slot="sidebar" categoryTitle="Tools" tools={allToolsNav} />
91
116
  <Fragment slot="head">
92
117
  {
93
- content.schemas.map((schema: unknown) => (
118
+ toolCss ? (
119
+ <Fragment set:html={`<style is:inline>${toolCss}</style>`} />
120
+ ) : null
121
+ }
122
+ {
123
+ (content.schemas ?? []).map((schema: unknown) => (
94
124
  <script
95
125
  is:inline
96
126
  type="application/ld+json"
@@ -116,11 +146,18 @@ const titleBase = words.slice(1).join(" ") || "";
116
146
  </section>
117
147
 
118
148
  <section class="section-faq">
119
- <FAQSection items={content.faq} title={content.faqTitle} inLanguage={locale} />
149
+ <FAQSection
150
+ items={content.faq}
151
+ title={content.ui.faqTitle}
152
+ inLanguage={locale}
153
+ />
120
154
  </section>
121
155
 
122
156
  <section class="section-bibliography">
123
- <Bibliography links={content.bibliography} title={content.bibliographyTitle} />
157
+ <Bibliography
158
+ links={content.bibliography}
159
+ title={content.ui.bibliographyTitle}
160
+ />
124
161
  </section>
125
162
  </div>
126
163
  </PreviewLayout>
@@ -1,8 +1,8 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
  import { ALL_TOOLS } from "../index";
3
3
 
4
- describe("i18n titles for FAQ and Bibliography", () => {
5
- it("all tools should have faqTitle and bibliographyTitle at root level", async () => {
4
+ describe("i18n titles for FAQ", () => {
5
+ it("all tools should have faqTitle at root level", async () => {
6
6
  expect(ALL_TOOLS.length).toBeGreaterThan(0);
7
7
 
8
8
  for (const { entry } of ALL_TOOLS) {
@@ -11,23 +11,16 @@ describe("i18n titles for FAQ and Bibliography", () => {
11
11
 
12
12
  expect(esContent.faqTitle, `Tool ${entry.id} missing Spanish faqTitle`).toBeDefined();
13
13
  expect(esContent.faqTitle).not.toBe("");
14
- expect(esContent.bibliographyTitle, `Tool ${entry.id} missing Spanish bibliographyTitle`).toBeDefined();
15
- expect(esContent.bibliographyTitle).not.toBe("");
16
-
17
14
 
18
15
  expect(enContent.faqTitle, `Tool ${entry.id} missing English faqTitle`).toBeDefined();
19
16
  expect(enContent.faqTitle).not.toBe("");
20
- expect(enContent.bibliographyTitle, `Tool ${entry.id} missing English bibliographyTitle`).toBeDefined();
21
- expect(enContent.bibliographyTitle).not.toBe("");
22
17
 
23
18
  expect(esContent.hasOwnProperty("faqTitle")).toBe(true);
24
- expect(esContent.hasOwnProperty("bibliographyTitle")).toBe(true);
25
19
  expect(enContent.hasOwnProperty("faqTitle")).toBe(true);
26
- expect(enContent.hasOwnProperty("bibliographyTitle")).toBe(true);
27
20
  }
28
21
  });
29
22
 
30
- it("all tools should have non-empty faq and bibliography arrays", async () => {
23
+ it("all tools should have non-empty faq arrays", async () => {
31
24
  for (const { entry } of ALL_TOOLS) {
32
25
  const esContent = await entry.i18n.es();
33
26
  const enContent = await entry.i18n.en();
@@ -36,16 +29,11 @@ describe("i18n titles for FAQ and Bibliography", () => {
36
29
  expect(Array.isArray(enContent.faq), `Tool ${entry.id} English faq should be an array`).toBe(true);
37
30
  expect(esContent.faq.length, `Tool ${entry.id} should have FAQ items`).toBeGreaterThan(0);
38
31
  expect(enContent.faq.length, `Tool ${entry.id} should have English FAQ items`).toBeGreaterThan(0);
39
-
40
- expect(Array.isArray(esContent.bibliography), `Tool ${entry.id} bibliography should be an array`).toBe(true);
41
- expect(Array.isArray(enContent.bibliography), `Tool ${entry.id} English bibliography should be an array`).toBe(true);
42
- expect(esContent.bibliography.length, `Tool ${entry.id} should have bibliography entries`).toBeGreaterThan(0);
43
- expect(enContent.bibliography.length, `Tool ${entry.id} should have English bibliography entries`).toBeGreaterThan(0);
44
32
  }
45
33
  });
46
34
 
47
- it("should have 12 tools with complete i18n setup", async () => {
48
- expect(ALL_TOOLS.length).toBe(12);
35
+ it("should have 13 tools with complete i18n setup", async () => {
36
+ expect(ALL_TOOLS.length).toBe(13);
49
37
  });
50
38
 
51
39
  it("tool IDs should be correctly registered", () => {
@@ -19,24 +19,13 @@ describe('Locale Completeness Validation', () => {
19
19
  }
20
20
  });
21
21
 
22
- it('bibliographyTitle should be defined when bibliography items exist', async () => {
23
- const loader = tool.entry.i18n[locale as keyof typeof tool.entry.i18n];
24
- const content = (await loader?.()) as ToolLocaleContent;
25
-
26
- if (content.bibliography.length > 0) {
27
- expect(
28
- content.bibliographyTitle,
29
- `Tool "${tool.entry.id}" locale "${locale}" has ${content.bibliography.length} bibliography items but is missing bibliographyTitle`,
30
- ).toBeTruthy();
31
- }
32
- });
33
22
  });
34
23
  });
35
24
  });
36
25
  });
37
26
 
38
- it('all 12 tools registered', () => {
39
- expect(ALL_TOOLS.length).toBe(12);
27
+ it('all 13 tools registered', () => {
28
+ expect(ALL_TOOLS.length).toBe(13);
40
29
  });
41
30
  });
42
31
 
@@ -0,0 +1,56 @@
1
+ import type { ToolDefinition } from '../types';
2
+
3
+ export interface ToolExportValidationResult {
4
+ passed: boolean;
5
+ failures: string[];
6
+ }
7
+
8
+ function validateComponentType(
9
+ toolId: string,
10
+ componentName: string,
11
+ component: unknown,
12
+ failures: string[],
13
+ ): void {
14
+ if (typeof component !== 'function') {
15
+ failures.push(`${toolId}: ${componentName} is not a function (${typeof component})`);
16
+ }
17
+ }
18
+
19
+ async function validateComponentExecution(
20
+ toolId: string,
21
+ componentName: string,
22
+ fn: () => Promise<unknown>,
23
+ failures: string[],
24
+ ): Promise<void> {
25
+ try {
26
+ const result = await fn();
27
+ if (!result || typeof result !== 'object') {
28
+ failures.push(`${toolId}: ${componentName} import returned invalid result`);
29
+ }
30
+ } catch (error) {
31
+ failures.push(`${toolId}: ${componentName} execution error - ${error instanceof Error ? error.message : 'unknown'}`);
32
+ }
33
+ }
34
+
35
+ export async function validateToolExports(tools: ToolDefinition[]): Promise<ToolExportValidationResult> {
36
+ const failures: string[] = [];
37
+
38
+ for (const tool of tools) {
39
+ validateComponentType(tool.entry.id, 'Component', tool.Component, failures);
40
+ validateComponentType(tool.entry.id, 'SEOComponent', tool.SEOComponent, failures);
41
+ validateComponentType(tool.entry.id, 'BibliographyComponent', tool.BibliographyComponent, failures);
42
+
43
+ const componentFn = tool.Component as () => Promise<unknown>;
44
+ const seoFn = tool.SEOComponent as () => Promise<unknown>;
45
+ const bibFn = tool.BibliographyComponent as () => Promise<unknown>;
46
+
47
+ await validateComponentExecution(tool.entry.id, 'Component', componentFn, failures);
48
+ await validateComponentExecution(tool.entry.id, 'SEOComponent', seoFn, failures);
49
+ await validateComponentExecution(tool.entry.id, 'BibliographyComponent', bibFn, failures);
50
+ }
51
+
52
+ return {
53
+ passed: failures.length === 0,
54
+ failures,
55
+ };
56
+ }
@@ -0,0 +1,34 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ALL_TOOLS } from '../tools';
3
+ import { validateToolExports } from './shared-test-helpers';
4
+
5
+ describe('Tool Exports Pattern Validation', () => {
6
+ describe('Component Exports Format', () => {
7
+ ALL_TOOLS.forEach((tool) => {
8
+ it(`${tool.entry.id}: Component should be a lazy-loaded function`, () => {
9
+ expect(typeof tool.Component).toBe('function');
10
+ expect(tool.Component).toBeInstanceOf(Function);
11
+ });
12
+
13
+ it(`${tool.entry.id}: SEOComponent should be a lazy-loaded function`, () => {
14
+ expect(typeof tool.SEOComponent).toBe('function');
15
+ expect(tool.SEOComponent).toBeInstanceOf(Function);
16
+ });
17
+
18
+ it(`${tool.entry.id}: BibliographyComponent should be a lazy-loaded function`, () => {
19
+ expect(typeof tool.BibliographyComponent).toBe('function');
20
+ expect(tool.BibliographyComponent).toBeInstanceOf(Function);
21
+ });
22
+ });
23
+ });
24
+
25
+ describe('Dynamic Import Validation', () => {
26
+ it('all tools must have functional dynamic imports', async () => {
27
+ const result = await validateToolExports(ALL_TOOLS);
28
+ if (!result.passed) {
29
+ throw new Error(`Tool export validation failed:\n${result.failures.join('\n')}`);
30
+ }
31
+ expect(result.passed).toBe(true);
32
+ });
33
+ });
34
+ });
@@ -4,8 +4,8 @@ import { cookingCategory } from '../data';
4
4
 
5
5
  describe('Tool Validation Suite', () => {
6
6
  describe('Library Registration', () => {
7
- it('should have 12 tools in ALL_TOOLS', () => {
8
- expect(ALL_TOOLS.length).toBe(12);
7
+ it('should have 13 tools in ALL_TOOLS', () => {
8
+ expect(ALL_TOOLS.length).toBe(13);
9
9
  });
10
10
 
11
11
  it('cookingCategory should be defined', () => {
@@ -1,6 +1,6 @@
1
1
  ---
2
- import { Bibliography } from "@jjlmoya/utils-shared";
3
- import { content } from "./i18n/es";
2
+ import { Bibliography as BibliographyComponent } from '@jjlmoya/utils-shared';
3
+ import { bibliography } from './bibliography';
4
4
  ---
5
5
 
6
- <Bibliography links={content.bibliography} />
6
+ <BibliographyComponent links={bibliography} />
@@ -0,0 +1,10 @@
1
+ export const bibliography = [
2
+ {
3
+ name: 'King Arthur Baking: Ingredient Weight Chart',
4
+ url: 'https://www.kingarthurbaking.com/learn/ingredient-weight-chart',
5
+ },
6
+ {
7
+ name: 'Culinary Institute of America: Conversions and Equivalents',
8
+ url: 'https://www.ciachef.edu/',
9
+ },
10
+ ];
@@ -1,4 +1,5 @@
1
1
  import type { ToolLocaleContent } from '../../../types';
2
+ import { bibliography } from '../bibliography';
2
3
 
3
4
  const title = "Küchen Umrechner: Cups in Gramm und Temperaturen";
4
5
  const description = "Rechnen Sie Cups, Esslöffel und Fahrenheit in das metrische System um. Der Kompass, um US-Rezepte mit professioneller Präzision zu entschlüsseln.";
@@ -80,7 +81,6 @@ export const content: ToolLocaleContent = {
80
81
  title: 'Küchen Umrechner: Cups in Gramm und Temperaturen',
81
82
  description: 'Rechnen Sie Cups, Esslöffel und Fahrenheit in das metrische System um. Der Kompass, um US-Rezepte mit professioneller Präzision zu entschlüsseln.',
82
83
  faqTitle: 'Häufig gestellte Fragen',
83
- bibliographyTitle: 'Literaturverzeichnis',
84
84
  ui: {
85
85
  copied: 'Kopiert',
86
86
  noHistory: 'Kein Verlauf',
@@ -324,16 +324,6 @@ export const content: ToolLocaleContent = {
324
324
  answer: 'Gas 4 = 180°C = 350°F. Dies ist die britische Skala. In der hiesigen Küche suchen wir den entsprechenden Wert an Ihrem Ofen: Einige verwenden Gasstufen, andere elektronische Gradanzeigen.',
325
325
  },
326
326
  ],
327
- bibliography: [
328
- {
329
- name: 'King Arthur Baking: Ingredient Weight Chart',
330
- url: 'https://www.kingarthurbaking.com/learn/ingredient-weight-chart',
331
- },
332
- {
333
- name: 'Culinary Institute of America: Conversions and Equivalents',
334
- url: 'https://www.ciachef.edu/',
335
- },
336
- ],
337
327
  howTo: [
338
328
  {
339
329
  name: 'Wählen Sie die Umrechnungsart',
@@ -352,5 +342,6 @@ export const content: ToolLocaleContent = {
352
342
  text: 'Mit der exakten Umrechnung können Sie nun das US-Rezept mit professioneller Präzision nachkochen.',
353
343
  },
354
344
  ],
345
+ bibliography,
355
346
  schemas: [faqSchema, howToSchema, appSchema],
356
347
  };
@@ -1,4 +1,5 @@
1
1
  import type { ToolLocaleContent } from "../../../types";
2
+ import { bibliography } from '../bibliography';
2
3
 
3
4
  const title = "US Cooking Conversion Calculator: Cups to Grams";
4
5
  const description = "Convert cups, tablespoons, and Fahrenheit to the metric system. Your professional compass for decoding American recipes with absolute precision.";
@@ -196,17 +197,6 @@ export const content: ToolLocaleContent = {
196
197
  answer: "Gas Mark 4 is equivalent to 350°F or 175°C. This is the most common temperature for standard cake baking.",
197
198
  },
198
199
  ],
199
- bibliographyTitle: "Bibliography & Resources",
200
- bibliography: [
201
- {
202
- name: "King Arthur Baking: Ingredient Weight Chart",
203
- url: "https://www.kingarthurbaking.com/learn/ingredient-weight-chart",
204
- },
205
- {
206
- name: "Culinary Institute of America: Conversions and Equivalents",
207
- url: "https://www.ciachef.edu/",
208
- },
209
- ],
210
200
  howTo: [
211
201
  {
212
202
  name: "Select conversion type",
@@ -353,5 +343,6 @@ export const content: ToolLocaleContent = {
353
343
  html: "Using a professional converter turns the frustration of foreign recipes into the success of a perfect bake.",
354
344
  },
355
345
  ],
346
+ bibliography,
356
347
  schemas: [faqSchema, howToSchema, appSchema],
357
348
  };
@@ -1,47 +1,48 @@
1
1
  import type { ToolLocaleContent } from '../../../types';
2
+ import { bibliography } from '../bibliography';
2
3
 
3
4
  const title = "Conversor Cocina Americana Cups a Gramos y Temperaturas";
4
5
  const description = "Convierte cups, tablespoons y Fahrenheit al sistema métrico. La brújula para descifrar recetas estadounidenses con precisión profesional.";
5
6
  const faq = [
6
- {
7
- question: '¿Cuál es la diferencia entre 1 cup y 250ml?',
8
- answer: '1 cup estadounidense = 236.588ml, no 250ml. Para propósitos prácticos, usamos 240ml. Aunque parece pequeña, esta diferencia de 4% puede afectar en recetas sensibles como macarons o mousses.',
9
- },
10
- {
11
- question: '¿Por qué la harina no siempre pesa lo mismo?',
12
- answer: 'Porque la harina se compacta con el tiempo y el transporte. Una harina recién tamizada pesa menos que una que ha estado en la despensa. Por eso, los panaderos profesionales siempre pesan, nunca miden volumen.',
13
- },
14
- {
15
- question: '¿Cuál es la diferencia entre Tbsp y tsp?',
16
- answer: '1 Tablespoon (Tbsp) = 15ml. 1 Teaspoon (tsp) = 5ml. Una cucharada es 3 veces una cucharita. En recetas de repostería, los errores con especias (que se miden en tsp) son comunes.',
17
- },
18
- {
19
- question: '¿Es lo mismo una cup US que una cup imperial?',
20
- answer: 'No. 1 US cup = 236ml. 1 Imperial cup (UK) = 284ml. Una diferencia del 20%. La mayoría de blogs estadounidenses usan US cups. Si la receta no especifica, asume US.',
21
- },
22
- {
23
- question: '¿A qué temperatura corresponde el "gas 4" del horno?',
24
- answer: 'Gas 4 = 180°C = 350°F. Es la escala británica. En repostería española, buscamos el número equivalente en tu horno: algunos usan gas, otros electrónico.',
25
- },
26
- ];
7
+ {
8
+ question: '¿Cuál es la diferencia entre 1 cup y 250ml?',
9
+ answer: '1 cup estadounidense = 236.588ml, no 250ml. Para propósitos prácticos, usamos 240ml. Aunque parece pequeña, esta diferencia de 4% puede afectar en recetas sensibles como macarons o mousses.',
10
+ },
11
+ {
12
+ question: '¿Por qué la harina no siempre pesa lo mismo?',
13
+ answer: 'Porque la harina se compacta con el tiempo y el transporte. Una harina recién tamizada pesa menos que una que ha estado en la despensa. Por eso, los panaderos profesionales siempre pesan, nunca miden volumen.',
14
+ },
15
+ {
16
+ question: '¿Cuál es la diferencia entre Tbsp y tsp?',
17
+ answer: '1 Tablespoon (Tbsp) = 15ml. 1 Teaspoon (tsp) = 5ml. Una cucharada es 3 veces una cucharita. En recetas de repostería, los errores con especias (que se miden en tsp) son comunes.',
18
+ },
19
+ {
20
+ question: '¿Es lo mismo una cup US que una cup imperial?',
21
+ answer: 'No. 1 US cup = 236ml. 1 Imperial cup (UK) = 284ml. Una diferencia del 20%. La mayoría de blogs estadounidenses usan US cups. Si la receta no especifica, asume US.',
22
+ },
23
+ {
24
+ question: '¿A qué temperatura corresponde el "gas 4" del horno?',
25
+ answer: 'Gas 4 = 180°C = 350°F. Es la escala británica. En repostería española, buscamos el número equivalente en tu horno: algunos usan gas, otros electrónico.',
26
+ },
27
+ ];
27
28
  const howTo = [
28
- {
29
- name: 'Selecciona el tipo de conversión',
30
- text: 'Elige entre Cups a Gramos, Tablespoons/Teaspoons a Gramos, o Fahrenheit a Celsius.',
31
- },
32
- {
33
- name: 'Escoge el ingrediente',
34
- text: 'Cada alimento tiene una densidad diferente. La harina, azúcar, mantequilla: todos pesan distinto.',
35
- },
36
- {
37
- name: 'Ingresa la cantidad',
38
- text: 'Escribe el número de cups, cucharas o grados. El conversor calcula el equivalente al instante.',
39
- },
40
- {
41
- name: 'Ajusta tu receta',
42
- text: 'Con la conversión exacta, ahora puedes seguir la receta estadounidense con precisión profesional.',
43
- },
44
- ];
29
+ {
30
+ name: 'Selecciona el tipo de conversión',
31
+ text: 'Elige entre Cups a Gramos, Tablespoons/Teaspoons a Gramos, o Fahrenheit a Celsius.',
32
+ },
33
+ {
34
+ name: 'Escoge el ingrediente',
35
+ text: 'Cada alimento tiene una densidad diferente. La harina, azúcar, mantequilla: todos pesan distinto.',
36
+ },
37
+ {
38
+ name: 'Ingresa la cantidad',
39
+ text: 'Escribe el número de cups, cucharas o grados. El conversor calcula el equivalente al instante.',
40
+ },
41
+ {
42
+ name: 'Ajusta tu receta',
43
+ text: 'Con la conversión exacta, ahora puedes seguir la receta estadounidense con precisión profesional.',
44
+ },
45
+ ];
45
46
 
46
47
  const faqSchema = {
47
48
  '@context': 'https://schema.org',
@@ -80,7 +81,6 @@ export const content: ToolLocaleContent = {
80
81
  title: 'Conversor Cocina Americana Cups a Gramos y Temperaturas',
81
82
  description: 'Convierte cups, tablespoons y Fahrenheit al sistema métrico. La brújula para descifrar recetas estadounidenses con precisión profesional.',
82
83
  faqTitle: 'Preguntas Frecuentes',
83
- bibliographyTitle: 'Bibliografía',
84
84
  ui: {
85
85
  copied: 'Copiado',
86
86
  noHistory: 'Sin historial',
@@ -324,16 +324,6 @@ export const content: ToolLocaleContent = {
324
324
  answer: 'Gas 4 = 180°C = 350°F. Es la escala británica. En repostería española, buscamos el número equivalente en tu horno: algunos usan gas, otros electrónico.',
325
325
  },
326
326
  ],
327
- bibliography: [
328
- {
329
- name: 'King Arthur Baking: Ingredient Weight Chart',
330
- url: 'https://www.kingarthurbaking.com/learn/ingredient-weight-chart',
331
- },
332
- {
333
- name: 'Culinary Institute of America: Conversions and Equivalents',
334
- url: 'https://www.ciachef.edu/',
335
- },
336
- ],
337
327
  howTo: [
338
328
  {
339
329
  name: 'Selecciona el tipo de conversión',
@@ -352,5 +342,6 @@ export const content: ToolLocaleContent = {
352
342
  text: 'Con la conversión exacta, ahora puedes seguir la receta estadounidense con precisión profesional.',
353
343
  },
354
344
  ],
345
+ bibliography,
355
346
  schemas: [faqSchema, howToSchema, appSchema],
356
347
  };
@@ -1,4 +1,5 @@
1
1
  import type { ToolLocaleContent } from "../../../types";
2
+ import { bibliography } from '../bibliography';
2
3
 
3
4
  const title = "Convertisseur de Cuisine Américaine : Cups en Grammes, Fahrenheit";
4
5
  const description = "Convertissez les cups, tablespoons et Fahrenheit en système métrique. Votre boussole pour décoder les recettes américaines avec une précision professionnelle.";
@@ -196,17 +197,6 @@ export const content: ToolLocaleContent = {
196
197
  answer: "Le Thermostat 6 correspond à 180°C, soit environ 350°F. C'est la température de cuisson la plus courante.",
197
198
  },
198
199
  ],
199
- bibliographyTitle: "Bibliographie et Ressources",
200
- bibliography: [
201
- {
202
- name: "King Arthur Baking: Ingredient Weight Chart",
203
- url: "https://www.kingarthurbaking.com/learn/ingredient-weight-chart",
204
- },
205
- {
206
- name: "Culinary Institute of America: Conversions and Equivalents",
207
- url: "https://www.ciachef.edu/",
208
- },
209
- ],
210
200
  howTo: [
211
201
  {
212
202
  name: "Sélectionnez le type de conversion",
@@ -225,16 +215,6 @@ export const content: ToolLocaleContent = {
225
215
  text: "Avec des mesures précises, vous pouvez reproduire n'importe quelle recette internationale avec succès.",
226
216
  },
227
217
  ],
228
- bibliography: [
229
- {
230
- name: "King Arthur Baking: Ingredient Weight Chart",
231
- url: "https://www.kingarthurbaking.com/learn/ingredient-weight-chart",
232
- },
233
- {
234
- name: "Culinary Institute of America: Conversions and Equivalents",
235
- url: "https://www.ciachef.edu/",
236
- },
237
- ],
238
218
  seo: [
239
219
  {
240
220
  type: "title",
@@ -363,5 +343,6 @@ export const content: ToolLocaleContent = {
363
343
  html: "Utiliser un convertisseur professionnel transforme la frustration des recettes étrangères en succès culinaire.",
364
344
  },
365
345
  ],
346
+ bibliography,
366
347
  schemas: [faqSchema, howToSchema, appSchema],
367
348
  };
@@ -1,4 +1,5 @@
1
1
  import type { ToolLocaleContent } from '../../../types';
2
+ import { bibliography } from '../bibliography';
2
3
 
3
4
  const title = "Konverter Dapur Amerika: Cups ke Gram dan Suhu";
4
5
  const description = "Konversikan cups, sendok makan, dan Fahrenheit ke sistem metrik. Kompas untuk memahami resep Amerika dengan presisi profesional.";
@@ -80,7 +81,6 @@ export const content: ToolLocaleContent = {
80
81
  title: 'Konverter Dapur Amerika: Cups ke Gram dan Suhu',
81
82
  description: 'Konversikan cups, sendok makan, dan Fahrenheit ke sistem metrik. Kompas untuk memahami resep Amerika dengan presisi profesional.',
82
83
  faqTitle: 'Pertanyaan yang Sering Diajukan',
83
- bibliographyTitle: 'Bibliografi',
84
84
  ui: {
85
85
  copied: 'Disalin',
86
86
  noHistory: 'Tidak ada riwayat',
@@ -324,16 +324,6 @@ export const content: ToolLocaleContent = {
324
324
  answer: 'Gas 4 = 180°C = 350°F. Ini adalah skala Inggris. Di dapur, kita mencari angka yang setara pada oven Anda: beberapa menggunakan pengaturan gas, yang lain menggunakan derajat elektronik.',
325
325
  },
326
326
  ],
327
- bibliography: [
328
- {
329
- name: 'King Arthur Baking: Ingredient Weight Chart',
330
- url: 'https://www.kingarthurbaking.com/learn/ingredient-weight-chart',
331
- },
332
- {
333
- name: 'Culinary Institute of America: Conversions and Equivalents',
334
- url: 'https://www.ciachef.edu/',
335
- },
336
- ],
337
327
  howTo: [
338
328
  {
339
329
  name: 'Pilih jenis konversi',
@@ -352,5 +342,6 @@ export const content: ToolLocaleContent = {
352
342
  text: 'Dengan konversi yang akurat, kini Anda dapat mengikuti resep Amerika dengan presisi profesional.',
353
343
  },
354
344
  ],
345
+ bibliography,
355
346
  schemas: [faqSchema, howToSchema, appSchema],
356
347
  };