/** RFC 4180-style parser, supports quoted commas and newlines. */
export function parseCsv(input: string) { const rows: string[][] = []; let row: string[] = [], field = '', quoted = false; const text = input.replace(/^\uFEFF/, ''); const delimiter = text.split(/\r?\n/)[0].includes(';') && !text.split(/\r?\n/)[0].includes(',') ? ';' : ','; for (let i = 0; i < text.length; i++) {
    const ch = text[i];
    if (ch === '"') {
        if (quoted && text[i + 1] === '"') {
            field += '"';
            i++;
        }
        else
            quoted = !quoted;
    }
    else if (ch === delimiter && !quoted) {
        row.push(field);
        field = '';
    }
    else if ((ch === '\n' || ch === '\r') && !quoted) {
        if (ch === '\r' && text[i + 1] === '\n')
            i++;
        row.push(field);
        if (row.some(v => v.trim()))
            rows.push(row);
        row = [];
        field = '';
    }
    else
        field += ch;
} if (quoted)
    throw new Error('Tanda kutip pada CSV belum ditutup.'); if (field || row.length) {
    row.push(field);
    if (row.some(v => v.trim()))
        rows.push(row);
} return rows; }
