diff --git a/CHECKSUMS.sha256 b/CHECKSUMS.sha256 index 7b55422..a32b7ef 100644 --- a/CHECKSUMS.sha256 +++ b/CHECKSUMS.sha256 @@ -1 +1 @@ -1ef56afddea6d292bbbccad4222f82335b1c1897418a3e13a55f9fad18d6c4ed *index.html +725f5abfe071cd702139d9365be6e07e011ab1fcbd46832fbc73cfafe2e216b6 *index.html diff --git a/index.html b/index.html index 5c36383..d9eb85b 100644 --- a/index.html +++ b/index.html @@ -1900,13 +1900,33 @@

Duikmonitor

const resultUnits=[]; for(const arr of byDiver.values()){ arr.sort((a,b)=>a.start-b.start); + const pending = arr.slice(); let prev = null, chainBlocker = null; - for(const u of arr){ + while(pending.length){ + const u = pending.shift(); if(chainBlocker?.surface && u.start && minsBetween(chainBlocker.surface, u.start) > 1080){ chainBlocker = null; prev = null; } - const r = calcUnit(u, chainBlocker ? null : prev); + const calcPrev = chainBlocker ? null : prev; + if(u.appliedRule && u.events.length > 1){ + const startOiMin = calcPrev?.surface && u.start ? Math.floor(minsBetween(calcPrev.surface, u.start)) : null; + const startHF = chainBlocker + ? {hf:null, label:"eerdere berekening geblokkeerd"} + : getHF(calcPrev?.hgAdjusted || calcPrev?.hgRaw, startOiMin); + if(startHF.hf !== 1){ + const separateUnits = u.events.map(e => Object.assign(unitFromEvents([e], dataset), { + meterRuleStartRejected:true, + meterRuleStartHF:startHF.hf, + meterRuleStartLabel:startHF.label, + rejectedMeterRule:u.appliedRule + })); + pending.push(...separateUnits); + pending.sort((a,b)=>a.start-b.start); + continue; + } + } + const r = calcUnit(u, calcPrev, {prevBlockedByChain:!!chainBlocker}); Object.assign(u, r); if(chainBlocker){ // De korte-OI-oorzaak draagt de code van de lege tabelcel die de keten @@ -1996,7 +2016,7 @@

Duikmonitor

} } - function calcUnit(u, prev){ + function calcUnit(u, prev, context={}){ const res = {messages:[], severity:0, codes:[], oiMin:null, hf:null, hfLabel:"-", edt:null, ndl:null, hgRaw:null, hgAdjusted:null, calcType:"", safetyStop:false, chainUnreliable:false}; if((u.events || []).some(e=>e.timerNeedsCheck)){ addMsg(res,1,"Actieve timer is langer dan 8 uur; controleer starttijd of zet de duik boven/einde."); @@ -2017,6 +2037,16 @@

Duikmonitor

return res; } + if(u.meterRuleStartRejected){ + const rejectedRule = shallowRules[u.rejectedMeterRule]; + const startHF = u.meterRuleStartHF == null + ? `niet bepaald (${u.meterRuleStartLabel || "onbekende uitgangssituatie"})` + : fmtHF(u.meterRuleStartHF); + addMsg(res,1,`${rejectedRule?.label || "Meterregel"} niet toegepast: inkomende HF bij de eerste duik van deze meterregelsessie is ${startHF} en moet 1,0 zijn; normale beoordeling gebruikt.`); + if(context.prevBlockedByChain) return res; + if(u.meterRuleStartHF == null && !prev) return res; + } + if(!u.appliedRule && u.shallowRuleKey && u.rule !== "auto"){ const selectedRule = shallowRules[u.shallowRuleKey]; if(selectedRule && u.mddMax > selectedRule.maxDepth){ @@ -2027,23 +2057,38 @@

Duikmonitor

if(u.appliedRule){ const rule = shallowRules[u.appliedRule]; - res.calcType = rule.label; - if(u.rule !== "auto" && u.mddMax > rule.maxDepth){ - addMsg(res,2,`${rule.label} gekozen, maar MDD ${u.mddMax.toFixed(1)} m is dieper dan ${rule.maxDepth} m.`,"INVALID_INPUT"); - if(u.appliedRule === "s12") addMsg(res,1,over12PlannedGuidance); - } - if(u.dtTotal > rule.totalLimit){ - addMsg(res,2,`Totale duiktijd binnen meterregel ${u.dtTotal} min overschrijdt ${rule.label} (${rule.totalLimit} min).`,"BOTTOM_TIME_EXCEEDS_METER_RULE"); + const startHF = getHF(prev?.hgAdjusted || prev?.hgRaw, res.oiMin); + if(startHF.hf !== 1){ + const startHFText = startHF.hf == null ? `niet bepaald (${startHF.label})` : fmtHF(startHF.hf); + res.appliedRule = null; + res.meterRuleApplied = false; + res.meterRuleStartRejected = true; + res.meterRuleStartHF = startHF.hf; + res.meterRuleStartLabel = startHF.label; + res.rejectedMeterRule = u.appliedRule; + addMsg(res,1,`${rule.label} niet toegepast: inkomende HF bij de eerste duik van deze meterregelsessie is ${startHFText} en moet 1,0 zijn; normale beoordeling gebruikt.`); + if(startHF.hf == null && res.oiMin == null){ + addMsg(res,2,"Inkomende HF voor de meterregelsessie kan niet betrouwbaar worden bepaald; berekening geblokkeerd.","INVALID_INPUT"); + return res; + } + }else{ + res.calcType = rule.label; + if(u.rule !== "auto" && u.mddMax > rule.maxDepth){ + addMsg(res,2,`${rule.label} gekozen, maar MDD ${u.mddMax.toFixed(1)} m is dieper dan ${rule.maxDepth} m.`,"INVALID_INPUT"); + if(u.appliedRule === "s12") addMsg(res,1,over12PlannedGuidance); + } + if(u.dtTotal > rule.totalLimit){ + addMsg(res,2,`Totale duiktijd binnen meterregel ${u.dtTotal} min overschrijdt ${rule.label} (${rule.totalLimit} min).`,"BOTTOM_TIME_EXCEEDS_METER_RULE"); + } + res.hf = 1; + res.hfLabel = "start HF 1,0"; + res.edt = u.dtTotal; + res.ndl = rule.totalLimit; + res.hgRaw = getHG(rule.maxDepth, u.dtTotal); + if(!res.hgRaw) addMsg(res,2,"HG kan niet uit Airtabel 1 worden bepaald voor deze duiktijd.","BOTTOM_TIME_EXCEEDS_TABLE"); + res.hgAdjusted = res.hgRaw; + return res; } - if(prev && res.oiMin != null && res.oiMin <= 1080) addMsg(res,1,`${rule.label} vereist start met HF 1,0; vorige HG is nog niet volledig vervallen.`); - res.hf = 1; - res.hfLabel = "start HF 1,0"; - res.edt = u.dtTotal; - res.ndl = rule.totalLimit; - res.hgRaw = getHG(rule.maxDepth, u.dtTotal); - if(!res.hgRaw) addMsg(res,2,"HG kan niet uit Airtabel 1 worden bepaald voor deze duiktijd.","BOTTOM_TIME_EXCEEDS_TABLE"); - res.hgAdjusted = res.hgRaw; - return res; } if(u.mddMax > 12){ if(u.rule === "auto") addMsg(res,2,"Dieper dan 12 meter: 6/9/12-meterregel niet toepasbaar. Gebruik DCIEM standaard en beoordeel de duiken afzonderlijk.","INVALID_INPUT"); @@ -2205,7 +2250,10 @@

Duikmonitor

arr.sort((a,b)=>(a.surface||a.start)-(b.surface||b.start)); let prev = null, period = []; const flush = () => { - const meter = period.filter(e => daypartRule(e.rule, e.mdd) && Number.isFinite(e.dtMin)); + const meter = period.filter(e => { + const unit = unitByEvent.get(e.id); + return !unit?.meterRuleStartRejected && daypartRule(e.rule, e.mdd) && Number.isFinite(e.dtMin); + }); if(!meter.length){ period = []; return; } const sumDt = meter.reduce((s,e)=>s+e.dtMin, 0); const maxD = Math.max(...meter.map(e=>Number.isFinite(e.mdd)?e.mdd:0)); @@ -4683,6 +4731,56 @@

${esc(displayDiver(d))} ${s.txt}