Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | 3x 3x 1011x 1011x 1011x 1011x 1011x 1011x 3269x 3269x 3269x 1458x 758x 758x 2023x 2023x 2023x 2023x 2023x 2023x 2023x 2023x 951x 951x 2023x 700x 1458x 1103x 1103x 708x 708x 3269x 1408x 1408x 1408x 1408x 3886x 3886x 3886x 3886x 3886x 3886x 3886x 2024x 1180x 3886x 3886x 1890x 1890x 3886x 1011x 1166x 1011x 1011x | import type {StringOp} from './types'; import {append, chunk, componentLength, isDeleteComponent, trim} from './util'; /** * Combine two operations into one, such that the changes produced by the * by the single operation are the same as if the two operations were applied * in sequence. * * ``` * apply(str, combine(op1, op2)) === apply(apply(str, op1), op2) * ``` * * @param op1 First operation. * @param op2 Second operation. * @returns A combined operation. */ export const compose = (op1: StringOp, op2: StringOp): StringOp => { const op3: StringOp = []; const len1 = op1.length; const len2 = op2.length; let off1 = 0; let i1 = 0; for (let i2 = 0; i2 < len2; i2++) { const comp2 = op2[i2]; let doDelete = false; switch (typeof comp2) { case 'number': { if (comp2 > 0) { let length2 = comp2; while (length2 > 0) { const comp1 = op1[i1]; const comp = i1 >= len1 ? length2 : chunk(comp1, off1, length2); const compLength = componentLength(comp); const isDelete = isDeleteComponent(comp); const length1 = componentLength(comp1 || comp); append(op3, comp); off1 += compLength; if (off1 >= length1) { i1++; off1 = 0; } if (!isDelete) length2 -= compLength; } } else doDelete = true; break; } case 'string': { append(op3, comp2); break; } case 'object': { doDelete = true; break; } } if (doDelete) { const isReversible = comp2 instanceof Array; const length2 = isReversible ? comp2[0].length : -comp2; let off2 = 0; while (off2 < length2) { const remaining = length2 - off2; const comp1 = op1[i1]; const comp = i1 >= len1 ? remaining : chunk(comp1, off1, remaining); const compLength = componentLength(comp); const isDelete = isDeleteComponent(comp); const length1 = componentLength(comp1 || comp); if (isDelete) append(op3, comp); else if (typeof comp === 'number') append(op3, isReversible ? [comp2[0].substring(off2, off2 + compLength)] : -compLength); off1 += compLength; if (off1 >= length1) { i1++; off1 = 0; } if (!isDelete) off2 += compLength; } } } if (i1 < len1 && off1) append(op3, chunk(op1[i1++], off1, Number.POSITIVE_INFINITY)); for (; i1 < len1; i1++) append(op3, op1[i1]); trim(op3); return op3; }; |