72 lines
2.0 KiB
JavaScript
72 lines
2.0 KiB
JavaScript
import { computeLedger } from "./ledger.js?v=__ASSET_VERSION__";
|
|
import { buildPlanCurve } from "./curve.js?v=__ASSET_VERSION__";
|
|
import { parseDuration } from "./time.js?v=__ASSET_VERSION__";
|
|
export const MILESTONES = [
|
|
["charge", "Charge"],
|
|
["tp", "Turning point"],
|
|
["yellow", "Yellow / dry end"],
|
|
["fc", "First crack"],
|
|
["drop", "Drop"],
|
|
];
|
|
export function sanitizeObservations(raw) {
|
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
|
|
const out = {};
|
|
for (const [key] of MILESTONES) {
|
|
if (raw[key] === undefined) continue;
|
|
const row = raw[key];
|
|
if (!row || typeof row !== "object" || Array.isArray(row)) return null;
|
|
const clean = {};
|
|
for (const field of ["timeS", "tempC"]) {
|
|
const v = row[field];
|
|
if (v === undefined || v === null) {
|
|
clean[field] = null;
|
|
continue;
|
|
}
|
|
if (
|
|
typeof v !== "number" ||
|
|
!Number.isFinite(v) ||
|
|
v < 0 ||
|
|
v > (field === "timeS" ? 7200 : 350)
|
|
)
|
|
return null;
|
|
clean[field] = v;
|
|
}
|
|
clean.note = String(row.note ?? "").slice(0, 2000);
|
|
out[key] = clean;
|
|
}
|
|
return out;
|
|
}
|
|
export function buildComparison(detail) {
|
|
const points = detail.plan
|
|
? buildPlanCurve(detail.plan, computeLedger(detail.plan))
|
|
: [];
|
|
return MILESTONES.map(([key, label]) => {
|
|
const target = points.find((p) => p.key === key);
|
|
const uploaded =
|
|
key === "tp"
|
|
? detail.parsed?.turningPoint
|
|
: detail.parsed?.milestones?.find((p) => p.key === key);
|
|
const saved = detail.observations?.[key],
|
|
legacy = detail.plan?.planActual?.[key];
|
|
const timeS =
|
|
saved?.timeS ?? uploaded?.timeS ?? parseDuration(legacy?.actualTime);
|
|
const legacyTemp =
|
|
legacy?.actualBt !== "" && legacy?.actualBt != null
|
|
? Number(legacy.actualBt)
|
|
: null;
|
|
const tempC =
|
|
saved?.tempC ??
|
|
uploaded?.tempC ??
|
|
(Number.isFinite(legacyTemp) ? legacyTemp : null);
|
|
return {
|
|
key,
|
|
label,
|
|
target,
|
|
timeS,
|
|
tempC,
|
|
note: saved?.note ?? legacy?.note ?? "",
|
|
deltaS: target && timeS != null ? timeS - target.timeS : null,
|
|
};
|
|
});
|
|
}
|