|
|
|
|
|
|
|
function parseCSV(str) { |
|
var arr = []; |
|
var quote = false; |
|
|
|
|
|
for (var row = 0, col = 0, c = 0; c < str.length; c++) { |
|
var cc = str[c], nc = str[c + 1]; |
|
arr[row] = arr[row] || []; |
|
arr[row][col] = arr[row][col] || ''; |
|
|
|
|
|
|
|
|
|
if (cc == '"' && quote && nc == '"') { arr[row][col] += cc; ++c; continue; } |
|
|
|
|
|
if (cc == '"') { quote = !quote; continue; } |
|
|
|
|
|
if (cc == ',' && !quote) { ++col; continue; } |
|
|
|
|
|
|
|
if (cc == '\r' && nc == '\n' && !quote) { ++row; col = 0; ++c; continue; } |
|
|
|
|
|
|
|
if (cc == '\n' && !quote) { ++row; col = 0; continue; } |
|
if (cc == '\r' && !quote) { ++row; col = 0; continue; } |
|
|
|
|
|
arr[row][col] += cc; |
|
} |
|
return arr; |
|
} |
|
|
|
|
|
async function readFile(filePath, json = false, cache = false) { |
|
if (!cache) |
|
filePath += `?${new Date().getTime()}`; |
|
|
|
let response = await fetch(`file=${filePath}`); |
|
|
|
if (response.status != 200) { |
|
console.error(`Error loading file "${filePath}": ` + response.status, response.statusText); |
|
return null; |
|
} |
|
|
|
if (json) |
|
return await response.json(); |
|
else |
|
return await response.text(); |
|
} |
|
|
|
|
|
async function loadCSV(path) { |
|
let text = await readFile(path); |
|
return parseCSV(text); |
|
} |
|
|
|
|
|
var dbTimeOut; |
|
const debounce = (func, wait = 300) => { |
|
return function (...args) { |
|
if (dbTimeOut) { |
|
clearTimeout(dbTimeOut); |
|
} |
|
|
|
dbTimeOut = setTimeout(() => { |
|
func.apply(this, args); |
|
}, wait); |
|
} |
|
} |
|
|
|
|
|
function difference(a, b) { |
|
if (a.length == 0) { |
|
return b; |
|
} |
|
if (b.length == 0) { |
|
return a; |
|
} |
|
|
|
return [...b.reduce((acc, v) => acc.set(v, (acc.get(v) || 0) - 1), |
|
a.reduce((acc, v) => acc.set(v, (acc.get(v) || 0) + 1), new Map()) |
|
)].reduce((acc, [v, count]) => acc.concat(Array(Math.abs(count)).fill(v)), []); |
|
} |
|
|
|
function escapeRegExp(string) { |
|
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); |
|
} |
|
function escapeHTML(unsafeText) { |
|
let div = document.createElement('div'); |
|
div.textContent = unsafeText; |
|
return div.innerHTML; |
|
} |
|
|
|
|
|
async function processQueue(queue, context, ...args) { |
|
for (let i = 0; i < queue.length; i++) { |
|
await queue[i].call(context, ...args); |
|
} |
|
} |
|
|
|
async function processQueueReturn(queue, context, ...args) |
|
{ |
|
let qeueueReturns = []; |
|
for (let i = 0; i < queue.length; i++) { |
|
let returnValue = await queue[i].call(context, ...args); |
|
if (returnValue) |
|
qeueueReturns.push(returnValue); |
|
} |
|
return qeueueReturns; |
|
} |
|
|
|
async function processParsers(textArea, prompt) { |
|
|
|
let matchingParsers = PARSERS.filter(parser => parser.triggerCondition()); |
|
|
|
if (matchingParsers.length === 0) { |
|
return null; |
|
} |
|
|
|
let parseFunctions = matchingParsers.map(parser => parser.parse); |
|
|
|
return await processQueueReturn(parseFunctions, null, textArea, prompt); |
|
} |