export default class Compressor { static compress(data, base) { const dataFirst = data[0]; const dataRest = data.slice(1); const baseFirst = base[0]; const baseRest = base.slice(1); if (dataFirst !== baseFirst || dataRest.length !== baseRest.length) { throw 'Cannot compress data, format does not match the base'; } const compressed = []; let stack = []; for (let i in dataRest) { if (dataRest[i] === baseRest[i]) { stack.push(dataRest[i]); continue; } if (stack.length) { compressed.push('!' + stack.length); } stack = []; compressed.push(dataRest[i]); } if (stack.length) { compressed.push('!' + stack.length); } return [dataFirst, ...compressed]; } static uncompress(data, base) { if (!base) { return data; } const uncompressed = []; let i = 0; for (let piece of data) { const m = piece.match(/^!(\d+)$/) if (!m) { uncompressed.push(piece); i++; continue; } let skipped = parseInt(m[1]); while(skipped--) { uncompressed.push(base[i]); i++; } } return uncompressed; } }