# StdDev Ranges Implementation Checklist ## 📋 Quick Implementation Guide ### Phase 1: Add JavaScript Modules (2 files) ```bash # Copy to your static folder: cp .code/rollcalc-stddev-ranges.js /path/to/flask/static/ cp .code/rollcalc-stddev-integration.js /path/to/flask/static/ ``` ### Phase 2: Update HTML (3 lines changed) In `roll_calculator.html`, find the section where scripts are loaded (around line ~2370): **Add after the other script tags:** ```html ``` ### Phase 3: Update JavaScript - Article Selection In `rollcalc_improvements.js`, find the `populateArticleDropdowns_v14()` function. In the "DirectCalc-Article" section (~line 2340), after the existing article fill code: **ADD THESE LINES:** ```javascript // NEW: Store stddev values for later use document.getElementById('d-th').dataset.stddev = match.thickness_stddev || 0; document.getElementById('d-aw').dataset.stddev = match.area_weight_stddev || 0; console.log('[StdDev] Stored:', { thickness_stddev: match.thickness_stddev, area_weight_stddev: match.area_weight_stddev }); ``` ### Phase 4: Update Direct Calc Button Handler **FIND:** The diameter calculation section in the `d-calc` click handler (~line 2380) **Replace this block:** ```javascript if (mode === 'diameter') { if (!d_mm || !t_mm || !L_m) { alert('Please enter d, t and L.'); return; } const D_nom = Math.sqrt(d_mm*d_mm + (4*L_m*1000*t_mm)/Math.PI); resLabel.textContent = 'Roll Diameter (D)'; resVal.textContent = D_nom.toFixed(1) + ' mm'; if (tol) { const D_min = Math.sqrt(d_mm*d_mm + (4*L_m*1000*(t_mm-tol))/Math.PI); const D_max = Math.sqrt(d_mm*d_mm + (4*L_m*1000*(t_mm+tol))/Math.PI); resRange.textContent = 'Min: ' + D_min.toFixed(1) + ' mm | Max: ' + D_max.toFixed(1) + ' mm'; } else { resRange.textContent = ''; } document.getElementById('d-di').value = D_nom.toFixed(1); calculatedLength = L_m; } ``` **WITH THIS:** ```javascript if (mode === 'diameter') { const result = window.StdDevIntegration.calculateDiameterWithStddev(d_mm, t_mm, null, L_m, tol); if (!result) return; calculatedLength = result.calculatedLength; // Calculate weight with stddev ranges const weightRanges = window.StdDevIntegration.calcWeightWithStddev(calculatedLength); // Forklift check uses worst-case weight window.StdDevIntegration.evaluateForkliftWithWorstCase(d_mm, category); } ``` ### Phase 5: Update Weight Calculation **FIND:** The `calcWeight()` function (~line 2410) **Replace:** ```javascript function calcWeight(length) { const wi = parseFloat(document.getElementById('de-wi').value) || 0; const aw = parseFloat(document.getElementById('d-aw').value) || 0; if (wi > 0 && aw > 0 && length > 0) { const w = (aw * length * wi / 1000).toFixed(1); document.getElementById('d-wo').value = w; return parseFloat(w); } document.getElementById('d-wo').value = ''; return null; } ``` **WITH:** ```javascript function calcWeight(length) { return window.StdDevIntegration.calcWeightWithStddev(length); } ``` ### Phase 6: Update Forklift Check Call **FIND:** The line that calls `ForkliftChecker.evaluate()` (~line 2420) **Change from:** ```javascript const allowed = runForkliftCheck(weight); ``` **TO:** ```javascript const allowed = window.StdDevIntegration.evaluateForkliftWithWorstCase(d_mm, category); ``` --- ## ✅ Testing Checklist ### Test 1: Article with StdDev Data ``` Action: Select "180005" from dropdown Expected: ✓ thickness_stddev loaded (0.379181) ✓ area_weight_stddev loaded (133.240428) ✓ Console shows [StdDev] Stored message ``` ### Test 2: Diameter Calculation ``` Action: - Select "180005" - Length: 50 m - Click Calculate Expected: ✓ Result shows nominal: 502.8 mm ✓ Range shows: ±2σ: 491.2 – 514.4 mm ✓ Console shows diameter ranges ``` ### Test 3: Weight Calculation ``` Action: Same as Test 2 Expected: ✓ Weight field shows: 974.8 kg ✓ Data attributes set: weight_nom, weight_min, weight_max ✓ Worst-case weight: 1041.4 kg ``` ### Test 4: Forklift Checker ``` Action: Same as Test 2 Expected: ✓ Forklift checker uses worst-case (1041.4 kg) ✓ Shows appropriate warning/OK status ✓ Console shows [StdDev-Forklift] message ``` ### Test 5: Load Optimizer ``` Action: Same as Test 2, then open Load Optimizer Expected: ✓ Pre-filled with nominal weight (974.8 kg) ✓ NOT using worst-case weight ✓ Calculations correct ``` ### Test 6: Backward Compatibility ``` Action: Manually enter values (no article selection) Expected: ✓ System works as before ✓ Shows only nominal values ✓ No errors in console ``` --- ## 🐛 Debugging If something doesn't work: 1. **Open DevTools (F12) → Console** 2. **Look for these logs:** - `[StdDev] Stored:` - Article stddev loaded? - `[StdDev-Calc] Diameter with ranges:` - Calculation done? - `[StdDev-Weight] Calculated ranges:` - Weight ranges set? - `[StdDev-Forklift] Using worst-case weight:` - Forklift using right value? 3. **Common issues:** - Missing script tags → Add to HTML `
` - Article without stddev → Should default to 0 - Functions undefined → Check script load order - Wrong values → Check browser cache (Ctrl+Shift+Delete) --- ## 📊 Expected Results (Example Article 180005) | Field | Value | |-------|-------| | Thickness | 6.228 ± 0.758 mm (±2σ) | | Area Weight | 3899.02 ± 266.48 g/m² (±2σ) | | Diameter @ 50m | 502.8 mm (491.2–514.4 mm range) | | Weight @ 5m width | 974.8 kg (908.1–1041.4 kg range) | | Forklift Check | Uses 1041.4 kg (worst-case) | | Load Optimizer | Uses 974.8 kg (nominal) | --- ## 📁 Files Modified | File | Changes | |------|---------| | roll_calculator.html | Add 2 `