| | |
| |
|
| | |
| | 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); |
| | } |