UNPKG

@igo2/utils

Version:
115 lines 19.2 kB
export class StringUtils { static diff(s1, s2, p = 4) { if (!s1 && !s2) { return ''; } if (!s1) { return '<span class="inserted">' + s2 + '</span>'; } if (!s2) { return '<span class="deleted">' + s1 + '</span>'; } s1 = s1.toString(); s2 = s2.toString(); const changeData = StringUtils.getChanges(s1, s2, '', p); const nextS = s2.slice(changeData.mtc.length + changeData.ins.length + changeData.sbs.length); // remaining part of "s" const nextThis = s1.slice(changeData.mtc.length + changeData.del.length + changeData.sbs.length); // remaining part of "this" let result = ''; // the glorious result if (changeData.del.length > 0) { changeData.del = '<span class="deleted">' + changeData.del + '</span>'; } if (changeData.ins.length > 0) { changeData.ins = '<span class="inserted">' + changeData.ins + '</span>'; } result = changeData.mtc + changeData.del + changeData.ins + changeData.sbs; result += nextThis !== '' || nextS !== '' ? StringUtils.diff(nextThis, nextS, p) : ''; return result; } static getMatchingSubstring(s, l, m) { // returns the first matching substring in-between the two strings let i = 0; let match = false; const slen = s.length; const o = { fis: slen, mtc: m, sbs: '' }; // temporary object used to construct the cd (change data) object while (i < slen) { // eslint-disable-next-line @typescript-eslint/no-unused-expressions l[i] === s[i] ? match ? (o.sbs += s[i]) // o.sbs holds the matching substring itsef : ((match = true), (o.fis = i), (o.sbs = s[i])) : match ? (i = slen) // stop after the first found substring : // eslint-disable-next-line no-self-assign (i = i); ++i; } return o; } static getChanges(s1, s2, m, p) { const isThisLonger = s1.length >= s1.length ? true : false; let [longer, shorter] = isThisLonger ? [s1, s2] : [s2, s1]; // assignment of longer and shorter by es6 destructuring let bi = 0; // base index designating the index of first mismacthing character in both strings while (shorter[bi] === longer[bi] && bi < shorter.length) { ++bi; } // make bi the index of first mismatching character longer = longer.split('').slice(bi); // as the longer string will be rotated it is converted into array shorter = shorter.slice(bi); // shorter and longer now starts from the first mismatching character const len = longer.length; // length of the longer string let cd = { fis: shorter.length, // the index of matching string in the shorter string fil: len, // the index of matching string in the longer string sbs: '', // the matching substring itself mtc: m + s2.slice(0, bi) }; // if exists mtc holds the matching string at the front let sub = { sbs: '' }; // returned substring per 1 character rotation of the longer string if (shorter !== '') { for (let rc = 0; rc < len && sub.sbs.length < p; rc++) { // rc -> rotate count, p -> precision factor sub = StringUtils.getMatchingSubstring(shorter, StringUtils.rotateArray(longer, rc), cd.mtc); // rotate longer string 1 char and get substring sub.fil = rc < len - sub.fis ? sub.fis + rc // mismatch is longer than the mismatch in short : sub.fis - len + rc; // mismatch is shorter than the mismatch in short if (sub.sbs.length > cd.sbs.length) { cd = sub; // only keep the one with the longest substring. } } } // insert the mismatching delete subsrt and insert substr to the cd object and attach the previous substring [cd.del, cd.ins] = isThisLonger ? [longer.slice(0, cd.fil).join(''), shorter.slice(0, cd.fis)] : [shorter.slice(0, cd.fis), longer.slice(0, cd.fil).join('')]; return cd.del.indexOf(' ') === -1 || cd.ins.indexOf(' ') === -1 || cd.del === '' || cd.ins === '' || cd.sbs === '' ? cd : StringUtils.getChanges(cd.del, cd.ins, cd.mtc, p); } static rotateArray(array, n) { const len = array.length; const res = new Array(array.length); if (n % len === 0) { return array.slice(); } else { for (let i = 0; i < len; i++) { res[i] = array[(i + (len + (n % len))) % len]; } } return res; } static isValidNumber(value) { return !isNaN(Number(value)); } static isOctalNumber(value) { return (StringUtils.isValidNumber(value) && value.startsWith('0') && value.length > 1); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyaW5nLXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcGFja2FnZXMvdXRpbHMvc3JjL2xpYi9zdHJpbmctdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxPQUFPLFdBQVc7SUFDdEIsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFVLEVBQUUsRUFBVSxFQUFFLENBQUMsR0FBRyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNmLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUNELElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNSLE9BQU8seUJBQXlCLEdBQUcsRUFBRSxHQUFHLFNBQVMsQ0FBQztRQUNwRCxDQUFDO1FBQ0QsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ1IsT0FBTyx3QkFBd0IsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDO1FBQ25ELENBQUM7UUFDRCxFQUFFLEdBQUcsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ25CLEVBQUUsR0FBRyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDbkIsTUFBTSxVQUFVLEdBQUcsV0FBVyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN6RCxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsS0FBSyxDQUNwQixVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FDdEUsQ0FBQyxDQUFDLHdCQUF3QjtRQUMzQixNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUN2QixVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsR0FBRyxD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QUMsTUFBTSxHQUFHLENBQUMsQ0FDakIsQ0FBQztJQUNKLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjbGFzcyBTdHJpbmdVdGlscyB7XG4gIHN0YXRpYyBkaWZmKHMxOiBzdHJpbmcsIHMyOiBzdHJpbmcsIHAgPSA0KTogc3RyaW5nIHtcbiAgICBpZiAoIXMxICYmICFzMikge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICBpZiAoIXMxKSB7XG4gICAgICByZXR1cm4gJzxzcGFuIGNsYXNzPVwiaW5zZXJ0ZWRcIj4nICsgczIgKyAnPC9zcGFuPic7XG4gICAgfVxuICAgIGlmICghczIpIHtcbiAgICAgIHJldHVybiAnPHNwYW4gY2xhc3M9XCJkZWxldGVkXCI+JyArIHMxICsgJzwvc3Bhbj4nO1xuICAgIH1cbiAgICBzMSA9IHMxLnRvU3RyaW5nKCk7XG4gICAgczIgPSBzMi50b1N0cmluZygpO1xuICAgIGNvbnN0IGNoYW5nZURhdGEgPSBTdHJpbmdVdGlscy5nZXRDaGFuZ2VzKHMxLCBzMiwgJycsIHApO1xuICAgIGNvbnN0IG5leHRTID0gczIuc2xpY2UoXG4gICAgICBjaGFuZ2VEYXRhLm10Yy5sZW5ndGggKyBjaGFuZ2VEYXRhLmlucy5sZW5ndGggKyBjaGFuZ2VEYXRhLnNicy5sZW5ndGhcbiAgICApOyAvLyByZW1haW5pbmcgcGFydCBvZiBcInNcIlxuICAgIGNvbnN0IG5leHRUaGlzID0gczEuc2xpY2UoXG4gICAgICBjaGFuZ2VEYXRhLm10Yy5sZW5ndGggKyBjaGFuZ2VEYXRhLmRlbC5sZW5ndGggKyBjaGFuZ2VEYXRhLnNicy5sZW5ndGhcbiAgICApOyAvLyByZW1haW5pbmcgcGFydCBvZiBcInRoaXNcIlxuICAgIGxldCByZXN1bHQgPSAnJzsgLy8gdGhlIGdsb3Jpb3VzIHJlc3VsdFxuICAgIGlmIChjaGFuZ2VEYXRhLmRlbC5sZW5ndGggPiAwKSB7XG4gICAgICBjaGFuZ2VEYXRhLmRlbCA9ICc8c3BhbiBjbGFzcz1cImRlbGV0ZWRcIj4nICsgY2hhbmdlRGF0YS5kZWwgKyAnPC9zcGFuPic7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VEYXRhLmlucy5sZW5ndGggPiAwKSB7XG4gICAgICBjaGFuZ2VEYXRhLmlucyA9ICc8c3BhbiBjbGFzcz1cImluc2VydGVkXCI+JyArIGNoYW5nZURhdGEuaW5zICsgJzwvc3Bhbj4nO1xuICAgIH1cbiAgICByZXN1bHQgPSBjaGFuZ2VEYXRhLm10YyArIGNoYW5nZURhdGEuZGVsICsgY2hhbmdlRGF0YS5pbnMgKyBjaGFuZ2VEYXRhLnNicztcbiAgICByZXN1bHQgKz1cbiAgICAgIG5leHRUaGlzICE9PSAnJyB8fCBuZXh0UyAhPT0gJydcbiAgICAgICAgPyBTdHJpbmdVdGlscy5kaWZmKG5leHRUaGlzLCBuZXh0UywgcClcbiAgICAgICAgOiAnJztcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0TWF0Y2hpbmdTdWJzdHJpbmcocywgbCwgbSkge1xuICAgIC8vIHJldHVybnMgdGhlIGZpcnN0IG1hdGNoaW5nIHN1YnN0cmluZyBpbi1iZXR3ZWVuIHRoZSB0d28gc3RyaW5nc1xuICAgIGxldCBpID0gMDtcbiAgICBsZXQgbWF0Y2ggPSBmYWxzZTtcbiAgICBjb25zdCBzbGVuID0gcy5sZW5ndGg7XG4gICAgY29uc3QgbyA9IHsgZmlzOiBzbGVuLCBtdGM6IG0sIHNiczogJycgfTsgLy8gdGVtcG9yYXJ5IG9iamVjdCB1c2VkIHRvIGNvbnN0cnVjdCB0aGUgY2QgKGNoYW5nZSBkYXRhKSBvYmplY3RcblxuICAgIHdoaWxlIChpIDwgc2xlbikge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtZXhwcmVzc2lvbnNcbiAgICAgIGxbaV0gPT09IHNbaV1cbiAgICAgICAgPyBtYXRjaFxuICAgICAgICAgID8gKG8uc2JzICs9IHNbaV0pIC8vIG8uc2JzIGhvbGRzIHRoZSBtYXRjaGluZyBzdWJzdHJpbmcgaXRzZWZcbiAgICAgICAgICA6ICgobWF0Y2ggPSB0cnVlKSwgKG8uZmlzID0gaSksIChvLnNicyA9IHNbaV0pKVxuICAgICAgICA6IG1hdGNoXG4gICAgICAgICAgPyAoaSA9IHNsZW4pIC8vIHN0b3AgYWZ0ZXIgdGhlIGZpcnN0IGZvdW5kIHN1YnN0cmluZ1xuICAgICAgICAgIDogLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtYXNzaWduXG4gICAgICAgICAgICAoaSA9IGkpO1xuICAgICAgKytpO1xuICAgIH1cbiAgICByZXR1cm4gbztcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldENoYW5nZXMoczEsIHMyLCBtLCBwKSB7XG4gICAgY29uc3QgaXNUaGlzTG9uZ2VyID0gczEubGVuZ3RoID49IHMxLmxlbmd0aCA/IHRydWUgOiBmYWxzZTtcbiAgICBsZXQgW2xvbmdlciwgc2hvcnRlcl0gPSBpc1RoaXNMb25nZXIgPyBbczEsIHMyXSA6IFtzMiwgczFdOyAvLyBhc3NpZ25tZW50IG9mIGxvbmdlciBhbmQgc2hvcnRlciBieSBlczYgZGVzdHJ1Y3R1cmluZ1xuICAgIGxldCBiaSA9IDA7IC8vIGJhc2UgaW5kZXggZGVzaWduYXRpbmcgdGhlIGluZGV4IG9mIGZpcnN0IG1pc21hY3RoaW5nIGNoYXJhY3RlciBpbiBib3RoIHN0cmluZ3NcblxuICAgIHdoaWxlIChzaG9ydGVyW2JpXSA9PT0gbG9uZ2VyW2JpXSAmJiBiaSA8IHNob3J0ZXIubGVuZ3RoKSB7XG4gICAgICArK2JpO1xuICAgIH0gLy8gbWFrZSBiaSB0aGUgaW5kZXggb2YgZmlyc3QgbWlzbWF0Y2hpbmcgY2hhcmFjdGVyXG4gICAgbG9uZ2VyID0gbG9uZ2VyLnNwbGl0KCcnKS5zbGljZShiaSk7IC8vIGFzIHRoZSBsb25nZXIgc3RyaW5nIHdpbGwgYmUgcm90YXRlZCBpdCBpcyBjb252ZXJ0ZWQgaW50byBhcnJheVxuICAgIHNob3J0ZXIgPSBzaG9ydGVyLnNsaWNlKGJpKTsgLy8gc2hvcnRlciBhbmQgbG9uZ2VyIG5vdyBzdGFydHMgZnJvbSB0aGUgZmlyc3QgbWlzbWF0Y2hpbmcgY2hhcmFjdGVyXG5cbiAgICBjb25zdCBsZW4gPSBsb25nZXIubGVuZ3RoOyAvLyBsZW5ndGggb2YgdGhlIGxvbmdlciBzdHJpbmdcbiAgICBsZXQgY2Q6IGFueSA9IHtcbiAgICAgIGZpczogc2hvcnRlci5sZW5ndGgsIC8vIHRoZSBpbmRleCBvZiBtYXRjaGluZyBzdHJpbmcgaW4gdGhlIHNob3J0ZXIgc3RyaW5nXG4gICAgICBmaWw6IGxlbiwgLy8gdGhlIGluZGV4IG9mIG1hdGNoaW5nIHN0cmluZyBpbiB0aGUgbG9uZ2VyIHN0cmluZ1xuICAgICAgc2JzOiAnJywgLy8gdGhlIG1hdGNoaW5nIHN1YnN0cmluZyBpdHNlbGZcbiAgICAgIG10YzogbSArIHMyLnNsaWNlKDAsIGJpKVxuICAgIH07IC8vIGlmIGV4aXN0cyBtdGMgaG9sZHMgdGhlIG1hdGNoaW5nIHN0cmluZyBhdCB0aGUgZnJvbnRcbiAgICBsZXQgc3ViOiBhbnkgPSB7IHNiczogJycgfTsgLy8gcmV0dXJuZWQgc3Vic3RyaW5nIHBlciAxIGNoYXJhY3RlciByb3RhdGlvbiBvZiB0aGUgbG9uZ2VyIHN0cmluZ1xuXG4gICAgaWYgKHNob3J0ZXIgIT09ICcnKSB7XG4gICAgICBmb3IgKGxldCByYyA9IDA7IHJjIDwgbGVuICYmIHN1Yi5zYnMubGVuZ3RoIDwgcDsgcmMrKykge1xuICAgICAgICAvLyByYyAtPiByb3RhdGUgY291bnQsIHAgLT4gcHJlY2lzaW9uIGZhY3RvclxuICAgICAgICBzdWIgPSBTdHJpbmdVdGlscy5nZXRNYXRjaGluZ1N1YnN0cmluZyhcbiAgICAgICAgICBzaG9ydGVyLFxuICAgICAgICAgIFN0cmluZ1V0aWxzLnJvdGF0ZUFycmF5KGxvbmdlciwgcmMpLFxuICAgICAgICAgIGNkLm10Y1xuICAgICAgICApOyAvLyByb3RhdGUgbG9uZ2VyIHN0cmluZyAxIGNoYXIgYW5kIGdldCBzdWJzdHJpbmdcbiAgICAgICAgc3ViLmZpbCA9XG4gICAgICAgICAgcmMgPCBsZW4gLSBzdWIuZmlzXG4gICAgICAgICAgICA/IHN1Yi5maXMgKyByYyAvLyBtaXNtYXRjaCBpcyBsb25nZXIgdGhhbiB0aGUgbWlzbWF0Y2ggaW4gc2hvcnRcbiAgICAgICAgICAgIDogc3ViLmZpcyAtIGxlbiArIHJjOyAvLyBtaXNtYXRjaCBpcyBzaG9ydGVyIHRoYW4gdGhlIG1pc21hdGNoIGluIHNob3J0XG4gICAgICAgIGlmIChzdWIuc2JzLmxlbmd0aCA+IGNkLnNicy5sZW5ndGgpIHtcbiAgICAgICAgICBjZCA9IHN1YjsgLy8gb25seSBrZWVwIHRoZSBvbmUgd2l0aCB0aGUgbG9uZ2VzdCBzdWJzdHJpbmcuXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gaW5zZXJ0IHRoZSBtaXNtYXRjaGluZyBkZWxldGUgc3Vic3J0IGFuZCBpbnNlcnQgc3Vic3RyIHRvIHRoZSBjZCBvYmplY3QgYW5kIGF0dGFjaCB0aGUgcHJldmlvdXMgc3Vic3RyaW5nXG4gICAgW2NkLmRlbCwgY2QuaW5zXSA9IGlzVGhpc0xvbmdlclxuICAgICAgPyBbbG9uZ2VyLnNsaWNlKDAsIGNkLmZpbCkuam9pbignJyksIHNob3J0ZXIuc2xpY2UoMCwgY2QuZmlzKV1cbiAgICAgIDogW3Nob3J0ZXIuc2xpY2UoMCwgY2QuZmlzKSwgbG9uZ2VyLnNsaWNlKDAsIGNkLmZpbCkuam9pbignJyldO1xuICAgIHJldHVybiBjZC5kZWwuaW5kZXhPZignICcpID09PSAtMSB8fFxuICAgICAgY2QuaW5zLmluZGV4T2YoJyAnKSA9PT0gLTEgfHxcbiAgICAgIGNkLmRlbCA9PT0gJycgfHxcbiAgICAgIGNkLmlucyA9PT0gJycgfHxcbiAgICAgIGNkLnNicyA9PT0gJydcbiAgICAgID8gY2RcbiAgICAgIDogU3RyaW5nVXRpbHMuZ2V0Q2hhbmdlcyhjZC5kZWwsIGNkLmlucywgY2QubXRjLCBwKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIHJvdGF0ZUFycmF5KGFycmF5LCBuKSB7XG4gICAgY29uc3QgbGVuID0gYXJyYXkubGVuZ3RoO1xuICAgIGNvbnN0IHJlcyA9IG5ldyBBcnJheShhcnJheS5sZW5ndGgpO1xuICAgIGlmIChuICUgbGVuID09PSAwKSB7XG4gICAgICByZXR1cm4gYXJyYXkuc2xpY2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICByZXNbaV0gPSBhcnJheVsoaSArIChsZW4gKyAobiAlIGxlbikpKSAlIGxlbl07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBzdGF0aWMgaXNWYWxpZE51bWJlcih2YWx1ZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICFpc05hTihOdW1iZXIodmFsdWUpKTtcbiAgfVxuXG4gIHN0YXRpYyBpc09jdGFsTnVtYmVyKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgU3RyaW5nVXRpbHMuaXNWYWxpZE51bWJlcih2YWx1ZSkgJiZcbiAgICAgIHZhbHVlLnN0YXJ0c1dpdGgoJzAnKSAmJlxuICAgICAgdmFsdWUubGVuZ3RoID4gMVxuICAgICk7XG4gIH1cbn1cbiJdfQ==