async function parseECSV(source) {
return source.text()
.then(txt=>{
const lines=txt.split("\n");
let comments=lines.filter(line=>line.startsWith("# ")).map(line=>line.slice(2));
if(!comments[0].trim().startsWith("%ECSV")) throw new Error("Missing %ECSV header");
const version=Number(comments[0].trim().slice(6));
comments=comments.slice(1).join("\n");
const body=lines.filter(line=>line[0]!="#").join("\n");
return {version,comments,body};
})
.then(({version,comments,body})=>{
const header=yaml.load(comments);
if(!header?.datatype) throw new Error("Header is missing required datatype");
const delimiter=header?.delimiter ?? " ";
const data=d3.dsvFormat(delimiter).parse(body, d3.autoType);
return Object.assign({version,data},header);
});
}