@jjlmoya/utils-cooking 1.30.0 → 1.31.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 (37) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +2 -0
  3. package/src/entries.ts +3 -1
  4. package/src/index.ts +1 -0
  5. package/src/tests/i18n-titles.test.ts +3 -2
  6. package/src/tests/i18n_coverage.test.ts +1 -0
  7. package/src/tests/locale_completeness.test.ts +2 -2
  8. package/src/tests/tool_validation.test.ts +2 -2
  9. package/src/tool/botulism-canning-safety/bibliography.astro +6 -0
  10. package/src/tool/botulism-canning-safety/bibliography.ts +10 -0
  11. package/src/tool/botulism-canning-safety/botulism-canning-safety.css +545 -0
  12. package/src/tool/botulism-canning-safety/component.astro +296 -0
  13. package/src/tool/botulism-canning-safety/components/AutoclaveDisplay.astro +62 -0
  14. package/src/tool/botulism-canning-safety/components/SporeVisualizer.astro +48 -0
  15. package/src/tool/botulism-canning-safety/components/ThermalControls.astro +60 -0
  16. package/src/tool/botulism-canning-safety/entry.ts +26 -0
  17. package/src/tool/botulism-canning-safety/i18n/de.ts +188 -0
  18. package/src/tool/botulism-canning-safety/i18n/en.ts +188 -0
  19. package/src/tool/botulism-canning-safety/i18n/es.ts +188 -0
  20. package/src/tool/botulism-canning-safety/i18n/fr.ts +188 -0
  21. package/src/tool/botulism-canning-safety/i18n/id.ts +188 -0
  22. package/src/tool/botulism-canning-safety/i18n/it.ts +188 -0
  23. package/src/tool/botulism-canning-safety/i18n/ja.ts +188 -0
  24. package/src/tool/botulism-canning-safety/i18n/ko.ts +188 -0
  25. package/src/tool/botulism-canning-safety/i18n/nl.ts +188 -0
  26. package/src/tool/botulism-canning-safety/i18n/pl.ts +188 -0
  27. package/src/tool/botulism-canning-safety/i18n/pt.ts +188 -0
  28. package/src/tool/botulism-canning-safety/i18n/ru.ts +188 -0
  29. package/src/tool/botulism-canning-safety/i18n/sv.ts +188 -0
  30. package/src/tool/botulism-canning-safety/i18n/tr.ts +188 -0
  31. package/src/tool/botulism-canning-safety/i18n/zh.ts +188 -0
  32. package/src/tool/botulism-canning-safety/index.ts +11 -0
  33. package/src/tool/botulism-canning-safety/logic.ts +47 -0
  34. package/src/tool/botulism-canning-safety/seo.astro +15 -0
  35. package/src/tool/ice-cream-pac-pod/component.astro +39 -0
  36. package/src/tool/spherification-bath-calculator/component.astro +37 -0
  37. package/src/tools.ts +2 -0
@@ -180,11 +180,49 @@ const { ui } = Astro.props;
180
180
  return { totalPAC, totalPOD, solidsPercentage: solidsPct, targetPAC };
181
181
  }
182
182
 
183
+ const STORAGE_KEY = 'cooking-ice-cream-state';
184
+
185
+ function saveState() {
186
+ const state = {
187
+ activeUnit,
188
+ base: baseInput.value,
189
+ temp: tempInput.value,
190
+ sucrose: sucroseInput.value,
191
+ dextrose: dextroseInput.value,
192
+ glucose: glucoseInput.value,
193
+ inverted: invertedInput.value,
194
+ trehalose: trehaloseInput.value
195
+ };
196
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
197
+ }
198
+
199
+ function loadState() {
200
+ try {
201
+ const state = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
202
+ if (state.activeUnit) {
203
+ activeUnit = state.activeUnit;
204
+ imperialBtn.classList.toggle('active', state.activeUnit === 'imperial');
205
+ metricBtn.classList.toggle('active', state.activeUnit === 'metric');
206
+ if (state.activeUnit === 'imperial') {
207
+ document.querySelectorAll('.weight-unit-label').forEach(l => l.textContent = ui.ozLabel);
208
+ document.querySelectorAll('.temp-unit-label').forEach(t => t.textContent = ui.fLabel);
209
+ tempSlider.min = '-13'; tempSlider.max = '23';
210
+ }
211
+ }
212
+ const sliderPairs = [['base', baseInput, baseSlider], ['temp', tempInput, tempSlider],
213
+ ['sucrose', sucroseInput, sucroseSlider], ['dextrose', dextroseInput, dextroseSlider],
214
+ ['glucose', glucoseInput, glucoseSlider], ['inverted', invertedInput, invertedSlider],
215
+ ['trehalose', trehaloseInput, trehaloseSlider]];
216
+ sliderPairs.forEach(([key, input, slider]) => { if (state[key]) { input.value = state[key]; slider.value = state[key]; } });
217
+ } catch {}
218
+ }
219
+
183
220
  function updateView() {
184
221
  const v = readValues();
185
222
  const metrics = computeMetrics(v);
186
223
  const state = computeState(metrics.totalPAC, metrics.targetPAC);
187
224
  updateUI(state, metrics);
225
+ saveState();
188
226
  }
189
227
 
190
228
  function convertInputs(targetUnit, inputs, sliders) {
@@ -247,6 +285,7 @@ const { ui } = Astro.props;
247
285
  updateView();
248
286
  });
249
287
 
288
+ loadState();
250
289
  updateView();
251
290
  </script>
252
291
 
@@ -124,6 +124,41 @@ const { ui } = Astro.props;
124
124
  };
125
125
  }
126
126
 
127
+ const STORAGE_KEY = 'cooking-spherification-state';
128
+
129
+ function saveState() {
130
+ const state = {
131
+ activeUnit,
132
+ activeMethod,
133
+ useXanthan,
134
+ useCitrate,
135
+ baseWeight: baseInput.value,
136
+ bathWeight: bathInput.value
137
+ };
138
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
139
+ }
140
+
141
+ function loadState() {
142
+ try {
143
+ const data = localStorage.getItem(STORAGE_KEY);
144
+ if (!data) return;
145
+ const state = JSON.parse(data);
146
+ if (state.activeUnit) activeUnit = state.activeUnit;
147
+ if (state.activeMethod) activeMethod = state.activeMethod;
148
+ [['xanthanBtn', 'xanthan-switch-circle', 'useXanthan'],
149
+ ['citrateBtn', 'citrate-switch-circle', 'useCitrate']].forEach(([btnId, circleId, key]) => {
150
+ if (state[key]) {
151
+ if (key === 'useXanthan') useXanthan = true; else useCitrate = true;
152
+ document.getElementById(btnId).classList.add('active');
153
+ document.getElementById(circleId).classList.add('active');
154
+ }
155
+ });
156
+ [['baseWeight', baseInput], ['bathWeight', bathInput]].forEach(([key, el]) => {
157
+ if (state[key]) el.value = state[key];
158
+ });
159
+ } catch {}
160
+ }
161
+
127
162
  function updateView() {
128
163
  let baseWeight = Math.max(0, parseFloat(baseInput.value) || 0);
129
164
  let bathWeight = Math.max(0, parseFloat(bathInput.value) || 0);
@@ -137,6 +172,7 @@ const { ui } = Astro.props;
137
172
  const displayFactor = activeUnit === 'imperial' ? 0.035274 : 1.0;
138
173
  updateRecipeList(result, displayFactor);
139
174
  updateReactorUI();
175
+ saveState();
140
176
  }
141
177
 
142
178
  function convertInputsTo(targetUnit) {
@@ -209,5 +245,6 @@ const { ui } = Astro.props;
209
245
  baseInput.addEventListener('input', updateView);
210
246
  bathInput.addEventListener('input', updateView);
211
247
 
248
+ loadState();
212
249
  updateView();
213
250
  </script>
package/src/tools.ts CHANGED
@@ -16,6 +16,7 @@ import { YEAST_CONVERTER_TOOL } from './tool/yeast-converter';
16
16
  import { LACTO_FERMENTATION_SALT_TOOL } from './tool/lacto-fermentation-salt-calculator';
17
17
  import { SPHERIFICATION_BATH_TOOL } from './tool/spherification-bath-calculator';
18
18
  import { ICE_CREAM_PAC_POD_TOOL } from './tool/ice-cream-pac-pod';
19
+ import { BOTULISM_CANNING_SAFETY_TOOL } from './tool/botulism-canning-safety';
19
20
 
20
21
  export const ALL_TOOLS: ToolDefinition[] = [
21
22
  AMERICAN_KITCHEN_CONVERTER_TOOL,
@@ -34,5 +35,6 @@ export const ALL_TOOLS: ToolDefinition[] = [
34
35
  LACTO_FERMENTATION_SALT_TOOL,
35
36
  SPHERIFICATION_BATH_TOOL,
36
37
  ICE_CREAM_PAC_POD_TOOL,
38
+ BOTULISM_CANNING_SAFETY_TOOL,
37
39
  ];
38
40