// Loads the full KJV 1611 from the attached CSV and indexes it by book/chapter/verse. // Cached so it only parses once. function parseCSV(text){ if(text.charCodeAt(0) === 0xFEFF) text = text.slice(1); const rows = []; let field = '', row = [], inQ = false; let i = 0; const n = text.length; while(i < n){ const c = text[i]; if(inQ){ if(c === '"'){ if(text[i+1] === '"'){ field += '"'; i += 2; continue; } inQ = false; i++; continue; } field += c; i++; continue; } if(c === '"'){ inQ = true; i++; continue; } if(c === ','){ row.push(field); field = ''; i++; continue; } if(c === '\n'){ row.push(field); rows.push(row); row = []; field = ''; i++; continue; } if(c === '\r'){ i++; continue; } field += c; i++; } if(field.length || row.length){ row.push(field); rows.push(row); } return rows; } let _biblePromise = null; function loadBible(){ if(_biblePromise) return _biblePromise; _biblePromise = (async () => { const res = await fetch('uploads/kjv1611_full.csv'); if(!res.ok) throw new Error('csv fetch failed'); const txt = await res.text(); const rows = parseCSV(txt); // Baptist churches use the 66-book Protestant canon (no Apocrypha). Keep only those, // and normalise the CSV's "Psalm" to the conventional "Psalms". const canon = new Set((window.BIBLE_BOOKS||[]).map(b=>b.name)); const rename = { 'Psalm':'Psalms' }; const data = {}; // { book: { chapterNum: [ {verse, text} ] } } const order = []; // book names in canonical order as they appear for(let r = 1; r < rows.length; r++){ const row = rows[r]; if(row.length < 5) continue; let book = row[1]; if(!book) continue; book = rename[book] || book; if(canon.size && !canon.has(book)) continue; // skip Apocrypha const ch = parseInt(row[2], 10); const vs = parseInt(row[3], 10); const text = (row[4] || '').trim(); if(!ch || !vs) continue; if(!data[book]){ data[book] = {}; order.push(book); } if(!data[book][ch]) data[book][ch] = []; data[book][ch].push({ verse: vs, text }); } // ensure each chapter's verses are sorted for(const b of order){ for(const c in data[b]){ data[b][c].sort((a,z)=>a.verse-z.verse); } } return { data, order, chapterCount: (b)=> Object.keys(data[b]||{}).length }; })(); return _biblePromise; } window.loadBible = loadBible;