From 19592f2230f1558297dd669333a0e757a81dcdfa Mon Sep 17 00:00:00 2001 From: Dayowe Date: Wed, 28 Jan 2026 15:51:28 +0100 Subject: [PATCH] =?UTF-8?q?=E2=80=A2=20feat(kaya):=20use=20current=20weigh?= =?UTF-8?q?t=20for=20Fred=20&=20Felia=20MER=20grams?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add current weight input + validation to Kaya UI - Persist/restore weight in local storage - Compute Fred & Felia grams/day from MER using entered weight and age factor - Keep kibble chart-based; allow editing Fred energy density - Rebuild iframe.html from src/ --- KAYA-2.md | 43 ++++++++++++++++ KAYA.md | 38 ++++++++++++++ iframe.html | 119 +++++++++++++++++++++++++++++-------------- src/index.html | 6 +++ src/js/calculator.js | 105 +++++++++++++++++++++++++------------- src/js/config.js | 10 +++- 6 files changed, 246 insertions(+), 75 deletions(-) create mode 100644 KAYA-2.md create mode 100644 KAYA.md diff --git a/KAYA-2.md b/KAYA-2.md new file mode 100644 index 0000000..45c1b60 --- /dev/null +++ b/KAYA-2.md @@ -0,0 +1,43 @@ +Kaya’s Transition Calculator — Friendly Guide +============================================ + +This quick guide shows you how to use the calculator to move Kaya from kibble to gently cooked food at a steady, safe pace. + +How to use it +------------- +1) Enter Kaya’s age in months (e.g. "5.5") + +2) Check the energy numbers for your foods: +- Eukanuba (kibble) defaults to 372 kcal/100g (replace if your bag shows a different number) +- Fred & Felia (gently cooked) defaults to 115 kcal/100g (replace if your bag shows a different number) +- Add or rename the foods (e.g., “Treats”) and enter their energy values from the label (kcal/100 g, kcal/kg, kcal/cup, or kcal/can). + +3) Set your percentages. We will start small (e.g., GC 5%, kibble 95%), lock any values you want fixed. + +4) Choose how to view amounts: +- Per day or per meal; set meals/day if needed. +- Pick your preferred units (grams, kg). +- Use “days” to see totals for meal prep. + +Regarding treats +----- +- Keep treats ≤10% (your plan is good). Larger shares can dilute the balanced portion of the diet. +- Enter treat kcal from the package (as‑fed) for accuracy. +- Monitor body condition and stool; adjust if needed. + + +What you’ll see +--------------- +- Exact amounts for each food based on your percentages and energy labels. +- Totals per day (or per meal), and optional multi‑day batches. +- Everything updates instantly as you change inputs. + +Good to know +------------ +- Gently cooked is less calorie‑dense than kibble. As you add more GC, total grams may go up. This is normal. +- Treats count. I added a “Treats” source with its kcal so the plan stays balanced. +- When in doubt, double‑check kcal values on the package (kcal/100 g or kcal/kg are most common). + +Remember +----------------- +Every dog is unique. Monitor body condition, stool quality, and appetite. We will adjust percentages and amounts as Kaya grows and responds to the new plan. diff --git a/KAYA.md b/KAYA.md new file mode 100644 index 0000000..d4d9132 --- /dev/null +++ b/KAYA.md @@ -0,0 +1,38 @@ +Kaya Transition Calculator — Quick Guide +======================================= + +This tool helps transition Kaya (30 kg adult) from kibble to gently cooked while keeping daily energy intake continuous. Enter Kaya’s age, set food sources and their energy values, then adjust percentages to see exactly how much to feed of each food. + +How to use +---------- +- Enter Kaya’s age in months (2.0–12.0). If outside this range, the tool adjusts to the nearest valid value. +- Confirm energy values for each food source: + - “Eukanuba, kibble” defaults to 372 kcal/100 g — change if your bag shows a different value. + - “Fred & Felia, gently cooked” defaults to 115 kcal/100 g. + - Add/rename sources (e.g., “Treats”) and enter their energy (kcal/100 g, kcal/kg, kcal/cup, or kcal/can). +- Set percentages for each food; lock any you want fixed. The total always equals 100%. +- Optional: switch units (g/kg/oz/lb; cups enabled only when kcal/cup is entered), choose per‑day or per‑meal, set meals/day, and use “days” to see batch totals. + +What it calculates +------------------ +- Daily energy target is derived from the 30 kg kibble feeding curve using Kaya’s exact age (month‑level interpolation), not from generic MER. +- That daily kcal target is split across your foods by percentage and converted into amounts using each food’s energy density. +- Results include per‑food amounts and totals, per‑day or per‑meal, in your selected units. + +Formulas (at a glance) +---------------------- +- Kibble grams/day (30 kg) by month (g/day): + 2: 250, 3: 330, 4: 365, 5: 382, 6: 400, 7: 405, 8: 410, 9: 410, 10: 410, 11: 408, 12: 405. + Linear interpolation is applied between months (e.g., 5.5 months is halfway between 5 and 6). +- Daily kcal target = kibble_g/day × (kibble_kcal_per_100g ÷ 100) +- Per‑food kcal = daily_kcal × (food_percentage ÷ 100) +- Per‑food grams (kcal/100 g) = per‑food_kcal ÷ (kcal_per_100g ÷ 100) +- Per‑food grams (kcal/kg) = per‑food_kcal ÷ (kcal_per_kg ÷ 1000) +- Cups (when kcal/cup provided) = per‑food_kcal ÷ kcal_per_cup +- Internal assumptions for conversions: 1 cup ≈ 120 g (dry), 1 can ≈ 450 g (wet) + +Notes +----- +- Age input is limited to 2–12 months; values are rounded for display (per‑meal amounts round after splitting). +- Accuracy depends on correct energy values on your foods’ labels. When in doubt, confirm the kcal numbers on the packaging. +- This guide supports professional planning; your nutritionist may fine‑tune based on Kaya’s body condition and response. diff --git a/iframe.html b/iframe.html index 22bb23a..b640f90 100644 --- a/iframe.html +++ b/iframe.html @@ -1981,6 +1981,12 @@
Age adjusted to the supported 2–12 month range.
+
+ + +
Please enter a valid weight (minimum 0.1 kg)
+
+
@@ -2091,7 +2097,13 @@ const CALCULATOR_CONFIG = { defaultScale: 1.0, maxFoodSources: 5, minScale: 0.5, - maxScale: 2.0 + maxScale: 2.0, + + // Kaya fork: Fred & Felia uses MER; kibble stays chart-based (30 kg column). + // Used only when weight input is not present (back-compat). + kayaMerDefaultWeightKg: 30, + kayaMerFactorUnder4Months: 3.0, + kayaMerFactorFrom4Months: 2.0 }; /** @@ -2113,7 +2125,7 @@ const CALCULATOR_CONFIG = { this.showPerMeal = false; // Kayafied reference source tracking this.kibbleRefId = null; - this.gcRefId = null; + this.fredRefId = null; this.storageKey = 'kaya_calculator_state_v1'; this.init(); } @@ -2138,11 +2150,13 @@ const CALCULATOR_CONFIG = { saveStateToStorage() { try { const ageInput = document.getElementById('ageMonths'); + const weightInput = document.getElementById('weight'); const unitSelect = document.getElementById('unit'); const daysInput = document.getElementById('days'); const state = { version: 1, age: ageInput && ageInput.value !== '' ? parseFloat(ageInput.value) : null, + weight: weightInput && weightInput.value !== '' ? parseFloat(weightInput.value) : null, unit: unitSelect ? unitSelect.value : 'g', days: daysInput && daysInput.value ? parseInt(daysInput.value) : 1, showPerMeal: !!this.showPerMeal, @@ -2211,12 +2225,20 @@ const CALCULATOR_CONFIG = { ageInput.value = state.age; } + // Restore weight (used for Fred & Felia MER calculation) + const weightInput = document.getElementById('weight'); + if (weightInput && (state.weight || state.weight === 0)) { + weightInput.value = state.weight; + } + // Restore food sources if (Array.isArray(state.foodSources) && state.foodSources.length) { this.foodSources = []; this.kibbleRefId = null; - this.gcRefId = null; + this.fredRefId = null; state.foodSources.forEach(saved => { + // Back-compat: older Kaya state stored Fred & Felia as `chartType: "gc"`. + const chartType = saved.chartType === 'gc' ? 'mer' : (saved.chartType || null); const fs = { id: saved.id || this.generateFoodSourceId(), name: saved.name || 'Food Source', @@ -2224,13 +2246,13 @@ const CALCULATOR_CONFIG = { energyUnit: saved.energyUnit || 'kcal100g', percentage: typeof saved.percentage === 'number' ? saved.percentage : 0, isLocked: !!saved.isLocked, - chartType: saved.chartType || null, + chartType: chartType, splitByMeals: (saved.splitByMeals === undefined ? true : saved.splitByMeals) }; this.foodSources.push(fs); this.renderFoodSource(fs); if (fs.chartType === 'kibble' && !this.kibbleRefId) this.kibbleRefId = fs.id; - if (fs.chartType === 'gc' && !this.gcRefId) this.gcRefId = fs.id; + if (fs.chartType === 'mer' && !this.fredRefId) this.fredRefId = fs.id; }); this.updateAddButton(); this.updateRemoveButtons(); @@ -2284,18 +2306,18 @@ const CALCULATOR_CONFIG = { // Food Source Management Methods initializeFoodSources() { // Seed three sources for Kaya's transition - const gc = { + const fred = { id: this.generateFoodSourceId(), name: 'Fred & Felia (Junior Huhn)', energy: '115', energyUnit: 'kcal100g', percentage: 5, isLocked: false, - chartType: 'gc' + chartType: 'mer' }; - this.foodSources.push(gc); - this.renderFoodSource(gc); - this.gcRefId = gc.id; + this.foodSources.push(fred); + this.renderFoodSource(fred); + this.fredRefId = fred.id; const kibble = { id: this.generateFoodSourceId(), @@ -2363,7 +2385,7 @@ const CALCULATOR_CONFIG = { this.foodSources.splice(index, 1); // If reference IDs were removed, clear them if (this.kibbleRefId === id) this.kibbleRefId = null; - if (this.gcRefId === id) this.gcRefId = null; + if (this.fredRefId === id) this.fredRefId = null; // Remove the DOM element const element = document.getElementById(`foodSource-${id}`); @@ -2774,7 +2796,7 @@ const CALCULATOR_CONFIG = { const container = document.getElementById('foodSources'); if (!container) return; - const isChart = foodSource.chartType === 'gc' || foodSource.chartType === 'kibble'; + const isChart = foodSource.chartType === 'kibble'; const energyReadonlyAttr = isChart ? 'readonly' : ''; const energyTitle = isChart ? 'Chart-based food: kcal locked' : 'Enter energy content'; const unitDisabledAttr = isChart ? 'disabled' : ''; @@ -3065,8 +3087,8 @@ const CALCULATOR_CONFIG = { const addFoodBtn = document.getElementById('addFoodBtn'); if (weightInput) { - weightInput.addEventListener('input', () => this.updateCalorieCalculations()); - weightInput.addEventListener('blur', () => this.validateWeight()); + weightInput.addEventListener('input', () => { this.updateCalorieCalculations(); this.saveStateToStorage(); }); + weightInput.addEventListener('blur', () => { this.validateWeight(); this.saveStateToStorage(); }); } if (dogTypeSelect) dogTypeSelect.addEventListener('change', () => this.updateCalorieCalculations()); @@ -3431,26 +3453,38 @@ const CALCULATOR_CONFIG = { return lowerVal + (upperVal - lowerVal) * t; } - // Kaya: GC chart interpolation across buckets - getGCChartGramsForAge(ageMonths) { - // Buckets per guideline with boundary rule (5.0 → later bucket, 7.0 → later bucket) - // <5 mo (2.0–<5.0): 950→1350 - // 5–6 mo (5.0–6.0): 1250→1550; (6.0–<7.0): hold 1550 - // 7–12 mo (7.0–12.0): 1300→1500 - const clamp = (v, min, max) => Math.max(min, Math.min(max, v)); - const age = clamp(ageMonths, 2, 12); - if (age < 5) { - const t = (age - 2) / (5 - 2); - return 950 + t * (1350 - 950); - } else if (age < 6) { - const t = (age - 5) / (6 - 5); - return 1250 + t * (1550 - 1250); - } else if (age < 7) { - return 1550; // hold upper value until 7.0 - } else { - const t = (age - 7) / (12 - 7); - return 1300 + t * (1500 - 1300); - } + // Kaya: MER-based grams/day for Fred & Felia (kibble remains chart-based) + getKayaMerFactorForAge(ageMonths) { + if (ageMonths === null || ageMonths === undefined) return null; + if (ageMonths < 4) return CALCULATOR_CONFIG.kayaMerFactorUnder4Months; + return CALCULATOR_CONFIG.kayaMerFactorFrom4Months; + } + + getKayaCurrentWeightKg() { + const weightInput = document.getElementById('weight'); + if (!weightInput) return CALCULATOR_CONFIG.kayaMerDefaultWeightKg; + const weightKg = this.getWeightInKg(); + if (!weightKg || weightKg < 0.1) return null; + return weightKg; + } + + getKayaMerCaloriesForAge(ageMonths) { + const factor = this.getKayaMerFactorForAge(ageMonths); + if (!factor) return null; + + const weightKg = this.getKayaCurrentWeightKg(); + if (!weightKg) return null; + + const rer = this.calculateRER(weightKg); + return this.calculateMER(rer, factor); + } + + getKayaMerBasedGramsForFood(ageMonths, energyPer100g) { + if (!energyPer100g || energyPer100g <= 0.1) return null; + const merCalories = this.getKayaMerCaloriesForAge(ageMonths); + if (!merCalories) return null; + const kcalPerGram = energyPer100g / 100; + return merCalories / kcalPerGram; } @@ -3509,6 +3543,7 @@ const CALCULATOR_CONFIG = { this.showError(`energy-error-${fs.id}`, false); }); this.showError('daysError', false); + this.showError('weightError', false); // Validate days input if (!days || !this.validateInput(days, 1, true)) { @@ -3537,6 +3572,16 @@ const CALCULATOR_CONFIG = { } } + // Fred & Felia (MER-based) needs current weight to compute grams. + const needsWeight = this.foodSources.some(fs => fs.chartType === 'mer' && (fs.percentage || 0) > 0); + const weightInput = document.getElementById('weight'); + if (needsWeight && weightInput) { + const weightKg = this.getWeightInKg(); + if (!weightKg || weightKg < 0.1) { + this.showError('weightError', true); + } + } + // Calculate per-food breakdown (chart-first) const foodBreakdowns = []; let totalDailyGrams = 0; @@ -3549,8 +3594,8 @@ const CALCULATOR_CONFIG = { this.foodSources.forEach(fs => { const energyPer100g = this.getFoodSourceEnergyPer100g(fs); let chartGrams = null; - if (fs.chartType === 'gc') { - chartGrams = age !== null ? this.getGCChartGramsForAge(age) : null; + if (fs.chartType === 'mer') { + chartGrams = age !== null ? this.getKayaMerBasedGramsForFood(age, energyPer100g) : null; } else if (fs.chartType === 'kibble') { chartGrams = age !== null ? this.getKayaKibbleGramsForAge(age) : null; } @@ -3570,7 +3615,7 @@ const CALCULATOR_CONFIG = { firstPass.forEach(({ fs, energyPer100g, gramsPortion }) => { let dailyGramsForThisFood = 0; let hasEnergyContent = !!(energyPer100g && energyPer100g > 0); - if ((fs.chartType === 'gc' || fs.chartType === 'kibble')) { + if ((fs.chartType === 'mer' || fs.chartType === 'kibble')) { if (gramsPortion !== null) { dailyGramsForThisFood = gramsPortion; } diff --git a/src/index.html b/src/index.html index 672bd3b..9b294ae 100644 --- a/src/index.html +++ b/src/index.html @@ -10,6 +10,12 @@
Age adjusted to the supported 2–12 month range.
+
+ + +
Please enter a valid weight (minimum 0.1 kg)
+
+
diff --git a/src/js/calculator.js b/src/js/calculator.js index 36f5b51..ead1f53 100644 --- a/src/js/calculator.js +++ b/src/js/calculator.js @@ -17,7 +17,7 @@ this.showPerMeal = false; // Kayafied reference source tracking this.kibbleRefId = null; - this.gcRefId = null; + this.fredRefId = null; this.storageKey = 'kaya_calculator_state_v1'; this.init(); } @@ -42,11 +42,13 @@ saveStateToStorage() { try { const ageInput = document.getElementById('ageMonths'); + const weightInput = document.getElementById('weight'); const unitSelect = document.getElementById('unit'); const daysInput = document.getElementById('days'); const state = { version: 1, age: ageInput && ageInput.value !== '' ? parseFloat(ageInput.value) : null, + weight: weightInput && weightInput.value !== '' ? parseFloat(weightInput.value) : null, unit: unitSelect ? unitSelect.value : 'g', days: daysInput && daysInput.value ? parseInt(daysInput.value) : 1, showPerMeal: !!this.showPerMeal, @@ -115,12 +117,20 @@ ageInput.value = state.age; } + // Restore weight (used for Fred & Felia MER calculation) + const weightInput = document.getElementById('weight'); + if (weightInput && (state.weight || state.weight === 0)) { + weightInput.value = state.weight; + } + // Restore food sources if (Array.isArray(state.foodSources) && state.foodSources.length) { this.foodSources = []; this.kibbleRefId = null; - this.gcRefId = null; + this.fredRefId = null; state.foodSources.forEach(saved => { + // Back-compat: older Kaya state stored Fred & Felia as `chartType: "gc"`. + const chartType = saved.chartType === 'gc' ? 'mer' : (saved.chartType || null); const fs = { id: saved.id || this.generateFoodSourceId(), name: saved.name || 'Food Source', @@ -128,13 +138,13 @@ energyUnit: saved.energyUnit || 'kcal100g', percentage: typeof saved.percentage === 'number' ? saved.percentage : 0, isLocked: !!saved.isLocked, - chartType: saved.chartType || null, + chartType: chartType, splitByMeals: (saved.splitByMeals === undefined ? true : saved.splitByMeals) }; this.foodSources.push(fs); this.renderFoodSource(fs); if (fs.chartType === 'kibble' && !this.kibbleRefId) this.kibbleRefId = fs.id; - if (fs.chartType === 'gc' && !this.gcRefId) this.gcRefId = fs.id; + if (fs.chartType === 'mer' && !this.fredRefId) this.fredRefId = fs.id; }); this.updateAddButton(); this.updateRemoveButtons(); @@ -188,18 +198,18 @@ // Food Source Management Methods initializeFoodSources() { // Seed three sources for Kaya's transition - const gc = { + const fred = { id: this.generateFoodSourceId(), name: 'Fred & Felia (Junior Huhn)', energy: '115', energyUnit: 'kcal100g', percentage: 5, isLocked: false, - chartType: 'gc' + chartType: 'mer' }; - this.foodSources.push(gc); - this.renderFoodSource(gc); - this.gcRefId = gc.id; + this.foodSources.push(fred); + this.renderFoodSource(fred); + this.fredRefId = fred.id; const kibble = { id: this.generateFoodSourceId(), @@ -267,7 +277,7 @@ this.foodSources.splice(index, 1); // If reference IDs were removed, clear them if (this.kibbleRefId === id) this.kibbleRefId = null; - if (this.gcRefId === id) this.gcRefId = null; + if (this.fredRefId === id) this.fredRefId = null; // Remove the DOM element const element = document.getElementById(`foodSource-${id}`); @@ -678,7 +688,7 @@ const container = document.getElementById('foodSources'); if (!container) return; - const isChart = foodSource.chartType === 'gc' || foodSource.chartType === 'kibble'; + const isChart = foodSource.chartType === 'kibble'; const energyReadonlyAttr = isChart ? 'readonly' : ''; const energyTitle = isChart ? 'Chart-based food: kcal locked' : 'Enter energy content'; const unitDisabledAttr = isChart ? 'disabled' : ''; @@ -969,8 +979,8 @@ const addFoodBtn = document.getElementById('addFoodBtn'); if (weightInput) { - weightInput.addEventListener('input', () => this.updateCalorieCalculations()); - weightInput.addEventListener('blur', () => this.validateWeight()); + weightInput.addEventListener('input', () => { this.updateCalorieCalculations(); this.saveStateToStorage(); }); + weightInput.addEventListener('blur', () => { this.validateWeight(); this.saveStateToStorage(); }); } if (dogTypeSelect) dogTypeSelect.addEventListener('change', () => this.updateCalorieCalculations()); @@ -1335,26 +1345,38 @@ return lowerVal + (upperVal - lowerVal) * t; } - // Kaya: GC chart interpolation across buckets - getGCChartGramsForAge(ageMonths) { - // Buckets per guideline with boundary rule (5.0 → later bucket, 7.0 → later bucket) - // <5 mo (2.0–<5.0): 950→1350 - // 5–6 mo (5.0–6.0): 1250→1550; (6.0–<7.0): hold 1550 - // 7–12 mo (7.0–12.0): 1300→1500 - const clamp = (v, min, max) => Math.max(min, Math.min(max, v)); - const age = clamp(ageMonths, 2, 12); - if (age < 5) { - const t = (age - 2) / (5 - 2); - return 950 + t * (1350 - 950); - } else if (age < 6) { - const t = (age - 5) / (6 - 5); - return 1250 + t * (1550 - 1250); - } else if (age < 7) { - return 1550; // hold upper value until 7.0 - } else { - const t = (age - 7) / (12 - 7); - return 1300 + t * (1500 - 1300); - } + // Kaya: MER-based grams/day for Fred & Felia (kibble remains chart-based) + getKayaMerFactorForAge(ageMonths) { + if (ageMonths === null || ageMonths === undefined) return null; + if (ageMonths < 4) return CALCULATOR_CONFIG.kayaMerFactorUnder4Months; + return CALCULATOR_CONFIG.kayaMerFactorFrom4Months; + } + + getKayaCurrentWeightKg() { + const weightInput = document.getElementById('weight'); + if (!weightInput) return CALCULATOR_CONFIG.kayaMerDefaultWeightKg; + const weightKg = this.getWeightInKg(); + if (!weightKg || weightKg < 0.1) return null; + return weightKg; + } + + getKayaMerCaloriesForAge(ageMonths) { + const factor = this.getKayaMerFactorForAge(ageMonths); + if (!factor) return null; + + const weightKg = this.getKayaCurrentWeightKg(); + if (!weightKg) return null; + + const rer = this.calculateRER(weightKg); + return this.calculateMER(rer, factor); + } + + getKayaMerBasedGramsForFood(ageMonths, energyPer100g) { + if (!energyPer100g || energyPer100g <= 0.1) return null; + const merCalories = this.getKayaMerCaloriesForAge(ageMonths); + if (!merCalories) return null; + const kcalPerGram = energyPer100g / 100; + return merCalories / kcalPerGram; } @@ -1413,6 +1435,7 @@ this.showError(`energy-error-${fs.id}`, false); }); this.showError('daysError', false); + this.showError('weightError', false); // Validate days input if (!days || !this.validateInput(days, 1, true)) { @@ -1441,6 +1464,16 @@ } } + // Fred & Felia (MER-based) needs current weight to compute grams. + const needsWeight = this.foodSources.some(fs => fs.chartType === 'mer' && (fs.percentage || 0) > 0); + const weightInput = document.getElementById('weight'); + if (needsWeight && weightInput) { + const weightKg = this.getWeightInKg(); + if (!weightKg || weightKg < 0.1) { + this.showError('weightError', true); + } + } + // Calculate per-food breakdown (chart-first) const foodBreakdowns = []; let totalDailyGrams = 0; @@ -1453,8 +1486,8 @@ this.foodSources.forEach(fs => { const energyPer100g = this.getFoodSourceEnergyPer100g(fs); let chartGrams = null; - if (fs.chartType === 'gc') { - chartGrams = age !== null ? this.getGCChartGramsForAge(age) : null; + if (fs.chartType === 'mer') { + chartGrams = age !== null ? this.getKayaMerBasedGramsForFood(age, energyPer100g) : null; } else if (fs.chartType === 'kibble') { chartGrams = age !== null ? this.getKayaKibbleGramsForAge(age) : null; } @@ -1474,7 +1507,7 @@ firstPass.forEach(({ fs, energyPer100g, gramsPortion }) => { let dailyGramsForThisFood = 0; let hasEnergyContent = !!(energyPer100g && energyPer100g > 0); - if ((fs.chartType === 'gc' || fs.chartType === 'kibble')) { + if ((fs.chartType === 'mer' || fs.chartType === 'kibble')) { if (gramsPortion !== null) { dailyGramsForThisFood = gramsPortion; } diff --git a/src/js/config.js b/src/js/config.js index eb5ac7e..30bdc98 100644 --- a/src/js/config.js +++ b/src/js/config.js @@ -7,5 +7,11 @@ const CALCULATOR_CONFIG = { defaultScale: 1.0, maxFoodSources: 5, minScale: 0.5, - maxScale: 2.0 -}; \ No newline at end of file + maxScale: 2.0, + + // Kaya fork: Fred & Felia uses MER; kibble stays chart-based (30 kg column). + // Used only when weight input is not present (back-compat). + kayaMerDefaultWeightKg: 30, + kayaMerFactorUnder4Months: 3.0, + kayaMerFactorFrom4Months: 2.0 +};