1import{resolveColumnNames as T,stripExtension as M,previewFromAoa as N,textBlob as O,formatCount as f,parseLooseNumeric as P}from"./util-CkZ8KZK2.js";import{readText as _,parseCsvText as z,delimiterFromOption as B,serializeTable as j}from"./csvShared-8k83eY5V.js";import{d as U,s as V,p as G,b as Q,a as Y,F as L,c as J,f as I}from"./dateShared-X0Yox5Lt.js";import{n as K,f as W}from"./statsShared-DnBYzIdE.js";import"./vendor-papaparse-Btpkh8vH.js";import"./cjs-helpers-D6-XlEtG.js";import"./detectTableRegion-B60ufQHb.js";const X={sum:"Sum",avg:"Average",count:"Count",min:"Minimum",max:"Maximum",first:"First",last:"Last"},S=1e5,H={daily:"day","weekly-mon":"week-mon","weekly-sun":"week-sun",monthly:"month",quarterly:"quarter",yearly:"year"};function Z(t){return H[t??""]??"month"}function ee(t,e,a){if(a==="count")return e;if(t.length===0)return null;switch(a){case"sum":{let o=0;for(const l of t)o+=l;return o}case"avg":{let o=0;for(const l of t)o+=l;return o/t.length}case"min":return Math.min(...t);case"max":return Math.max(...t);case"first":return t[0];case"last":return t[t.length-1]}}function te(t,e){const{columns:a,warnings:o}=T(t[0]??[]),l=t.slice(1);if(a.length===0)throw new Error("That file has no columns to resample.");if(l.length===0)throw new Error("That file has a header but no data rows.");const c=a.indexOf(e.dateColumn);if(c<0)throw new Error(`There is no column called "${e.dateColumn}". The file has: ${a.join(", ")}.`);const u=e.valueColumns.map(s=>({name:s,index:a.indexOf(s)})).filter(s=>s.index>=0);if(u.length===0&&e.agg!=="count")throw new Error("Pick at least one value column to summarize, or switch the aggregate to Count.");const m=[...o],n=V(l,c);if(n.parsed.length===0)throw new Error(`No value in "${e.dateColumn}" reads as a date. Pick the column that holds the dates.`);n.formats.length>1&&m.push(`"${e.dateColumn}" mixes ${n.formats.length} date formats (${n.formats.join(", ")}). They were all read, but a column with one format is safer.`),n.badSamples.length>0&&m.push(`${f(n.badRows.length)} value${n.badRows.length===1?"":"s"} in "${e.dateColumn}" look like dates but are not real ones and were left out: ${n.badSamples.map(s=>`"${s}"`).join(", ")}${n.badRows.length>n.badSamples.length?", and more":""}.`),n.notDates>0&&m.push(`${f(n.notDates)} value${n.notDates===1?"":"s"} in "${e.dateColumn}" are not dates at all and were left out.`),n.blank>0&&m.push(`${f(n.blank)} row${n.blank===1?" has":"s have"} no date and could not be placed in a period.`);const h=new Map,x=new Array(u.length).fill(0);let v=0,g=1/0,w=-1/0;for(const s of l){const i=String(s[c]??"").trim();if(i==="")continue;const r=G(i);if(r===null)continue;const y=Q(r.time,e.frequency);y<g&&(g=y),y>w&&(w=y);let d=h.get(y);d||(d={values:u.map(()=>[]),rows:0},h.set(y,d)),d.rows+=1,v+=1,u.forEach((C,k)=>{const q=String(s[C.index]??"").trim();if(q==="")return;const R=P(q);if(R===null){x[k]+=1;return}d.values[k].push(R)})}u.forEach((s,i)=>{const r=x[i];r>0&&m.push(`${f(r)} value${r===1?"":"s"} in "${s.name}" are not numbers and were left out of the ${X[e.agg].toLowerCase()}.`)});const b=["period",...u.map(s=>`${s.name}_${e.agg}`)];e.agg==="count"&&u.length===0&&b.push("count");const D=[...h.keys()].sort((s,i)=>s-i),E=e.fill==="none"?D:Y(g,w,e.frequency,S);let p=0;for(const s of E)h.has(s)||(p+=1);e.fill!=="none"&&E.length>=S&&m.push(`The date range covers more than ${f(S)} ${L[e.frequency]} periods, so filling stopped there. Check the earliest and latest dates in the file for a typo.`);const A=new Array(Math.max(1,u.length)).fill(null),$=[];for(const s of E){const i=h.get(s),r=[J(s,e.frequency)];if(u.length===0){r.push(i?String(i.rows):e.fill==="zero"?"0":""),$.push(r);continue}u.forEach((y,d)=>{if(i){const C=ee(i.values[d],i.rows,e.agg),k=C===null?"":W(C).replace(/,/g,"");C!==null&&(A[d]=k),r.push(k);return}e.fill==="zero"?r.push("0"):e.fill==="forward"?r.push(A[d]??""):r.push("")}),$.push(r)}const F=[`${f($.length)} ${L[e.frequency]} period${$.length===1?"":"s"}`,`${f(v)} of ${f(l.length)} rows placed`,`${I(g)} to ${I(w)}`,p===0?"no empty periods":e.fill==="none"?`${f(p)} empty period${p===1?"":"s"} not shown`:`${f(p)} empty period${p===1?"":"s"} filled`];return{columns:b,rows:$,warnings:m,summary:F,gaps:p,periods:$.length}}function ne(t){const{columns:e}=T(t[0]??[]),a=t.slice(1),o=U(a,e.length),l=K(a,e).filter(c=>!o.includes(c));
1return{dateColumn:e[o[0]??0]??"",valueColumns:l.slice(0,3).map(c=>e[c])}}const ce=async t=>{t.ctx.onProgress("Reading the CSVâ¦");const e=await _(t),a=z(e,B(t.options.delimiter)),{columns:o}=T(a.rows[0]??[]),l=ne(a.rows),c=o.includes(t.options.dateColumn??"")?t.options.dateColumn:l.dateColumn;let u=l.valueColumns;const m=t.options.valueColumns??"";if(m!=="")try{const g=JSON.parse(m);if(Array.isArray(g)){const w=g.filter(b=>typeof b=="string"&&o.includes(b));w.length>0&&(u=w)}}catch{}t.ctx.onProgress("Bucketing the datesâ¦");const n=te(a.rows,{dateColumn:c,valueColumns:u,agg:t.options.agg??"sum",frequency:Z(t.options.frequency),fill:t.options.fill??"zero"}),h=j(n.columns,n.rows);return{status:"ok",output:{filename:`${M(t.filename)||"data"}-resampled.csv`,blob:O(h,"text/csv"),text:h,copyKind:"csv",preview:N([n.columns,...n.rows],25),warnings:[...a.warnings,...n.warnings],summary:n.summary,summaryStyle:"strip",discovered:{kind:"fields",columns:o,selected:{dateColumn:c}},fullRows:n.rows}}};export{X as AGG_LABELS,S as MAX_PERIODS,ce as default,ne as defaultResampleColumns,Z as frequencyFromOption,te as resampleTable};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.