@logseq/diff-merge
Version:
Block level diff and merge for Logseq
1,046 lines (1,045 loc) • 39.9 kB
JavaScript
var O = Object.defineProperty;
var H = (e, n, r) => n in e ? O(e, n, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[n] = r;
var F = (e, n, r) => (H(e, typeof n != "symbol" ? n + "" : n, r), r);
var B = /* @__PURE__ */ ((e) => (e[e.DIFF_DELETE = -1] = "DIFF_DELETE", e[e.DIFF_EQUAL = 0] = "DIFF_EQUAL", e[e.DIFF_INSERT = 1] = "DIFF_INSERT", e))(B || {});
class $ {
// Keeping our own length variable is faster than looking it up.
/**
* Storing the block->char hash table
* CharHash for one transact (merging), call the base version first to ensure best indent resolution
* > 65536 blocks might break DMP (see WATCH OUT 1)
* It's tolerable for our use case as LCS doesn't require the char to be unique
*/
constructor() {
F(this, "uniqueBlocks");
// Block[uniqueId][sameIdBlocksIdx]
// Case that the indent changes are lost - so we need to overwrite it by the different from the based one
F(this, "blockContentHash");
// e.g. blockHash['Hello\nWorld'] == 4
F(this, "blockUUIDHash");
// e.g. blockHash['Hello\nWorld'] == 4
F(this, "blockArrayLength", 0);
this.uniqueBlocks = [], this.uniqueBlocks[0] = [{ level: 0, body: "", src: 0, meta: {}, srcBranch: 0 }], this.blockContentHash = /* @__PURE__ */ new Map(), this.blockUUIDHash = /* @__PURE__ */ new Map();
}
diff_blocksToUniqueId(n) {
let r = [];
for (const s of n) {
const i = s.body;
if (s.uuid && this.blockUUIDHash.has(s.uuid)) {
const t = this.blockUUIDHash.get(s.uuid);
r.push(t), this.uniqueBlocks[t].push(s), this.blockContentHash.set(i, t);
} else if (!s.uuid && this.blockContentHash.has(i)) {
const t = this.blockContentHash.get(i);
r.push(t), this.uniqueBlocks[t].push(s);
} else {
const t = this.blockArrayLength;
r.push(t), this.blockContentHash.has(i) || this.blockContentHash.set(i, t), s.uuid && !this.blockUUIDHash.has(s.uuid) && this.blockUUIDHash.set(s.uuid, t), this.uniqueBlocks.push([s]), this.blockArrayLength += 1;
}
}
return r;
}
/**
* We have to keep indents of each block to ensure the best indent resolution
* @param allBlocks the lines, in the index of block
* @return Encoded string and all indents by block
*/
diff_blocksToChars(n) {
const r = this.diff_blocksToUniqueId(n);
return String.fromCodePoint(...r);
}
/**
* The golden standard of indentation is the blockIndentsTar
*
* @returns the diff of the blocks, with the original block position as index
* [ // #1 block of the original text
* [
* [0, ...], // Keep the first block
* ],
* // #2 block of the original text
* [
* [-1, ...], // Delete the original second block
* [1, ...], // Insert a new line at the position
* [1, ...], // Insert another new line at the same position
* ],
* // #3 block of the original text
* [
* [0, ...], // Keep the third block
* [1, ...], // Insert a new block at the same position
* ],
* ]
*/
diff_charsToBlocks(n, r, s) {
const i = [];
let t = -1, a = -1, l = 0;
n.length > 0 && n[0][0] != 1 && i.push([]);
for (var o = 0; o < n.length; o++) {
const h = n[o][0], f = n[o][1];
if (h != 1) {
h == -1 && (l = i.length);
for (const c of f) {
let u = [];
h == 0 ? (t += 1, a += 1, u = [[h, s[a]]]) : (t += 1, u = [[h, r[t]]]), i.push(u);
}
h == 0 && (l = i.length - 1);
} else
for (const c of f) {
a += 1;
const u = [h, s[a]];
i[l] === void 0 && (i[l] = []), i[l].push(u);
}
}
return i;
}
}
var S = /* @__PURE__ */ ((e) => (e[e.BLOCK_SOURCE_BASE = 0] = "BLOCK_SOURCE_BASE", e[e.BLOCK_SOURCE_BRANCH = 1] = "BLOCK_SOURCE_BRANCH", e))(S || {});
const Q = JSON.stringify({
format: "Markdown",
toc: !1,
parse_outline_only: !1,
export_md_remove_options: [],
heading_to_list: !1,
heading_number: !1,
keep_line_break: !0
}), K = /^[0-9a-fA-F\-]{32,40}$/, U = "$PROPERTY!!DRAWER!!UUID$", j = /^(\s*)/;
function z(e) {
for (const [n, r, s] of e)
if (n == "id")
return r;
}
class Y {
constructor(n, r = Q) {
F(this, "mldoc");
F(this, "config");
F(this, "format");
F(this, "byteEncoder", new TextEncoder());
F(this, "byteDecoder", new TextDecoder());
this.mldoc = n, this.config = r, this.format = JSON.parse(r).format;
}
parse(n) {
return JSON.parse(this.mldoc.parseJson(n, this.config));
}
parseBlocks(n) {
const r = [], s = this.parse(n), i = this.byteEncoder.encode(n);
for (const h of s) {
const f = h[1], c = i.slice(f.start_pos, f.end_pos), u = this.byteDecoder.decode(c);
u[u.length - 1] === `
` ? r.push(u.substring(0, u.length - 1)) : r.push(u);
}
const t = [];
let a = [], l, o;
for (let h = 0; h < s.length; h++) {
const f = s[h];
if (f[0][0] == "Property_Drawer") {
const c = f[0][1], u = z(c);
u && K.test(u) ? (o = u, a.push(r[h].replace(u, U))) : a.push(r[h]);
continue;
} else if (f[0][0] != "Heading") {
a.push(r[h]);
continue;
}
a.length > 0 && t.push({ lines: a, uuid: o, level: l }), a = [], o = void 0, a.push(r[h]), l = f[0][1].level;
}
return a.length > 0 && t.push({ lines: a, level: l }), t;
}
/**
* Don't use! For demo only! Doesn't fully support all features in Logseq
*/
parseMarkdownBlocksAndIndents(n, r) {
const s = this.parseBlocks(n), i = [];
for (const t of s) {
const a = t.lines, l = [];
for (const [o, h] of a.entries()) {
const f = j.exec(h), c = (f == null ? void 0 : f[1]) || "", u = h.substring(c.length + (o > 0 ? 0 : 2), h.length);
l.push(u);
}
i.push({
body: l.join(`
`),
level: t.level,
uuid: t.uuid,
meta: {},
src: r ? 0 : 1,
srcBranch: r
});
}
return i;
}
/**
*
* @param text
* @returns the line bodies and their indents, indexed by block, without EOL
*/
parseBlocksAndIndents(n, r) {
if (this.format === "Markdown")
return this.parseMarkdownBlocksAndIndents(n, r);
throw new Error(`Unimplemented format: ${this.format}`);
}
}
function J(e) {
let r = e.body.split(`
`).map((s, i) => {
const t = (e.level || 1) - 1;
return " ".repeat(t) + (i == 0 ? "- " : " ") + s;
}).join(`
`);
return r.includes(U) && (e.uuid || console.warn("Block content contains UUID placeholder but block has no UUID"), r = r.replace(U, e.uuid || "")), r;
}
function v() {
this.Diff_Timeout = 1, this.Diff_EditCost = 4, this.Match_Threshold = 0.5, this.Match_Distance = 1e3, this.Patch_DeleteThreshold = 0.5, this.Patch_Margin = 4, this.Match_MaxBits = 32;
}
var k = -1, E = 1, b = 0;
v.prototype.diff_main = function(e, n, r, s) {
typeof s > "u" && (this.Diff_Timeout <= 0 ? s = Number.MAX_VALUE : s = new Date().getTime() + this.Diff_Timeout * 1e3);
var i = s;
if (e == null || n == null)
throw new Error("Null input. (diff_main)");
if (e == n)
return e ? [[b, e]] : [];
typeof r > "u" && (r = !0);
var t = r, a = this.diff_commonPrefix(e, n), l = e.substring(0, a);
e = e.substring(a), n = n.substring(a), a = this.diff_commonSuffix(e, n);
var o = e.substring(e.length - a);
e = e.substring(0, e.length - a), n = n.substring(0, n.length - a);
var h = this.diff_compute_(e, n, t, i);
return l && h.unshift([b, l]), o && h.push([b, o]), this.diff_cleanupMerge(h), h;
};
v.prototype.diff_compute_ = function(e, n, r, s) {
var i;
if (!e)
return [[E, n]];
if (!n)
return [[k, e]];
var t = e.length > n.length ? e : n, a = e.length > n.length ? n : e, l = t.indexOf(a);
if (l != -1)
return i = [
[E, t.substring(0, l)],
[b, a],
[E, t.substring(l + a.length)]
], e.length > n.length && (i[0][0] = i[2][0] = k), i;
if (a.length == 1)
return [[k, e], [E, n]];
var o = this.diff_halfMatch_(e, n);
if (o) {
var h = o[0], f = o[1], c = o[2], u = o[3], _ = o[4], g = this.diff_main(h, c, r, s), d = this.diff_main(f, u, r, s);
return g.concat([[b, _]], d);
}
return r && e.length > 100 && n.length > 100 ? this.diff_lineMode_(e, n, s) : this.diff_bisect_(e, n, s);
};
v.prototype.diff_lineMode_ = function(e, n, r) {
var s = this.diff_linesToChars_(e, n);
e = s.chars1, n = s.chars2;
var i = s.lineArray, t = this.diff_main(e, n, !1, r);
this.diff_charsToLines_(t, i), this.diff_cleanupSemantic(t), t.push([b, ""]);
for (var a = 0, l = 0, o = 0, h = "", f = ""; a < t.length; ) {
switch (t[a][0]) {
case E:
o++, f += t[a][1];
break;
case k:
l++, h += t[a][1];
break;
case b:
if (l >= 1 && o >= 1) {
t.splice(
a - l - o,
l + o
), a = a - l - o;
for (var s = this.diff_main(h, f, !1, r), c = s.length - 1; c >= 0; c--)
t.splice(a, 0, s[c]);
a = a + s.length;
}
o = 0, l = 0, h = "", f = "";
break;
}
a++;
}
return t.pop(), t;
};
v.prototype.diff_bisect_ = function(e, n, r) {
for (var s = e.length, i = n.length, t = Math.ceil((s + i) / 2), a = t, l = 2 * t, o = new Array(l), h = new Array(l), f = 0; f < l; f++)
o[f] = -1, h[f] = -1;
o[a + 1] = 0, h[a + 1] = 0;
for (var c = s - i, u = c % 2 != 0, _ = 0, g = 0, d = 0, m = 0, p = 0; p < t && !(new Date().getTime() > r); p++) {
for (var w = -p + _; w <= p - g; w += 2) {
var M = a + w, I;
w == -p || w != p && o[M - 1] < o[M + 1] ? I = o[M + 1] : I = o[M - 1] + 1;
for (var C = I - w; I < s && C < i && e.charAt(I) == n.charAt(C); )
I++, C++;
if (o[M] = I, I > s)
g += 2;
else if (C > i)
_ += 2;
else if (u) {
var A = a + c - w;
if (A >= 0 && A < l && h[A] != -1) {
var D = s - h[A];
if (I >= D)
return this.diff_bisectSplit_(e, n, I, C, r);
}
}
}
for (var y = -p + d; y <= p - m; y += 2) {
var A = a + y, D;
y == -p || y != p && h[A - 1] < h[A + 1] ? D = h[A + 1] : D = h[A - 1] + 1;
for (var R = D - y; D < s && R < i && e.charAt(s - D - 1) == n.charAt(i - R - 1); )
D++, R++;
if (h[A] = D, D > s)
m += 2;
else if (R > i)
d += 2;
else if (!u) {
var M = a + c - y;
if (M >= 0 && M < l && o[M] != -1) {
var I = o[M], C = a + I - M;
if (D = s - D, I >= D)
return this.diff_bisectSplit_(e, n, I, C, r);
}
}
}
}
return [[k, e], [E, n]];
};
v.prototype.diff_bisectSplit_ = function(e, n, r, s, i) {
var t = e.substring(0, r), a = n.substring(0, s), l = e.substring(r), o = n.substring(s), h = this.diff_main(t, a, !1, i), f = this.diff_main(l, o, !1, i);
return h.concat(f);
};
v.prototype.diff_linesToChars_ = function(e, n) {
var r = [], s = {};
r[0] = "";
function i(l) {
for (var o = "", h = 0, f = -1, c = r.length; f < l.length - 1; ) {
f = l.indexOf(`
`, h), f == -1 && (f = l.length - 1);
var u = l.substring(h, f + 1);
h = f + 1, (s.hasOwnProperty ? s.hasOwnProperty(u) : s[u] !== void 0) ? o += String.fromCharCode(s[u]) : (o += String.fromCharCode(c), s[u] = c, r[c++] = u);
}
return o;
}
var t = i(e), a = i(n);
return { chars1: t, chars2: a, lineArray: r };
};
v.prototype.diff_charsToLines_ = function(e, n) {
for (var r = 0; r < e.length; r++) {
for (var s = e[r][1], i = [], t = 0; t < s.length; t++)
i[t] = n[s.charCodeAt(t)];
e[r][1] = i.join("");
}
};
v.prototype.diff_commonPrefix = function(e, n) {
if (!e || !n || e.charAt(0) != n.charAt(0))
return 0;
for (var r = 0, s = Math.min(e.length, n.length), i = s, t = 0; r < i; )
e.substring(t, i) == n.substring(t, i) ? (r = i, t = r) : s = i, i = Math.floor((s - r) / 2 + r);
return i;
};
v.prototype.diff_commonSuffix = function(e, n) {
if (!e || !n || e.charAt(e.length - 1) != n.charAt(n.length - 1))
return 0;
for (var r = 0, s = Math.min(e.length, n.length), i = s, t = 0; r < i; )
e.substring(e.length - i, e.length - t) == n.substring(n.length - i, n.length - t) ? (r = i, t = r) : s = i, i = Math.floor((s - r) / 2 + r);
return i;
};
v.prototype.diff_commonOverlap_ = function(e, n) {
var r = e.length, s = n.length;
if (r == 0 || s == 0)
return 0;
r > s ? e = e.substring(r - s) : r < s && (n = n.substring(0, r));
var i = Math.min(r, s);
if (e == n)
return i;
for (var t = 0, a = 1; ; ) {
var l = e.substring(i - a), o = n.indexOf(l);
if (o == -1)
return t;
a += o, (o == 0 || e.substring(i - a) == n.substring(0, a)) && (t = a, a++);
}
};
v.prototype.diff_halfMatch_ = function(e, n) {
if (this.Diff_Timeout <= 0)
return null;
var r = e.length > n.length ? e : n, s = e.length > n.length ? n : e;
if (r.length < 4 || s.length * 2 < r.length)
return null;
var i = this;
function t(g, d, m) {
for (var p = g.substring(m, m + Math.floor(g.length / 4)), w = -1, M = "", I, C, A, D; (w = d.indexOf(p, w + 1)) != -1; ) {
var y = i.diff_commonPrefix(
g.substring(m),
d.substring(w)
), R = i.diff_commonSuffix(
g.substring(0, m),
d.substring(0, w)
);
M.length < R + y && (M = d.substring(w - R, w) + d.substring(w, w + y), I = g.substring(0, m - R), C = g.substring(m + y), A = d.substring(0, w - R), D = d.substring(w + y));
}
return M.length * 2 >= g.length ? [
I,
C,
A,
D,
M
] : null;
}
var a = t(
r,
s,
Math.ceil(r.length / 4)
), l = t(
r,
s,
Math.ceil(r.length / 2)
), o;
if (!a && !l)
return null;
l ? a ? o = a[4].length > l[4].length ? a : l : o = l : o = a;
var h, f, c, u;
e.length > n.length ? (h = o[0], f = o[1], c = o[2], u = o[3]) : (c = o[0], u = o[1], h = o[2], f = o[3]);
var _ = o[4];
return [h, f, c, u, _];
};
v.prototype.diff_cleanupSemantic = function(e) {
for (var n = !1, r = [], s = 0, i = null, t = 0, a = 0, l = 0, o = 0, h = 0; t < e.length; )
e[t][0] == b ? (r[s++] = t, a = o, l = h, o = 0, h = 0, i = e[t][1]) : (e[t][0] == E ? o += e[t][1].length : h += e[t][1].length, i && i.length <= Math.max(a, l) && i.length <= Math.max(
o,
h
) && (e.splice(
r[s - 1],
0,
[k, i]
), e[r[s - 1] + 1][0] = E, s--, s--, t = s > 0 ? r[s - 1] : -1, a = 0, l = 0, o = 0, h = 0, i = null, n = !0)), t++;
for (n && this.diff_cleanupMerge(e), this.diff_cleanupSemanticLossless(e), t = 1; t < e.length; ) {
if (e[t - 1][0] == k && e[t][0] == E) {
var f = e[t - 1][1], c = e[t][1], u = this.diff_commonOverlap_(f, c), _ = this.diff_commonOverlap_(c, f);
u >= _ ? (u >= f.length / 2 || u >= c.length / 2) && (e.splice(
t,
0,
[b, c.substring(0, u)]
), e[t - 1][1] = f.substring(0, f.length - u), e[t + 1][1] = c.substring(u), t++) : (_ >= f.length / 2 || _ >= c.length / 2) && (e.splice(
t,
0,
[b, f.substring(0, _)]
), e[t - 1][0] = E, e[t - 1][1] = c.substring(0, c.length - _), e[t + 1][0] = k, e[t + 1][1] = f.substring(_), t++), t++;
}
t++;
}
};
v.prototype.diff_cleanupSemanticLossless = function(e) {
function n(_, g) {
if (!_ || !g)
return 6;
var d = _.charAt(_.length - 1), m = g.charAt(0), p = d.match(v.nonAlphaNumericRegex_), w = m.match(v.nonAlphaNumericRegex_), M = p && d.match(v.whitespaceRegex_), I = w && m.match(v.whitespaceRegex_), C = M && d.match(v.linebreakRegex_), A = I && m.match(v.linebreakRegex_), D = C && _.match(v.blanklineEndRegex_), y = A && g.match(v.blanklineStartRegex_);
return D || y ? 5 : C || A ? 4 : p && !M && I ? 3 : M || I ? 2 : p || w ? 1 : 0;
}
for (var r = 1; r < e.length - 1; ) {
if (e[r - 1][0] == b && e[r + 1][0] == b) {
var s = e[r - 1][1], i = e[r][1], t = e[r + 1][1], a = this.diff_commonSuffix(s, i);
if (a) {
var l = i.substring(i.length - a);
s = s.substring(0, s.length - a), i = l + i.substring(0, i.length - a), t = l + t;
}
for (var o = s, h = i, f = t, c = n(s, i) + n(i, t); i.charAt(0) === t.charAt(0); ) {
s += i.charAt(0), i = i.substring(1) + t.charAt(0), t = t.substring(1);
var u = n(s, i) + n(i, t);
u >= c && (c = u, o = s, h = i, f = t);
}
e[r - 1][1] != o && (o ? e[r - 1][1] = o : (e.splice(r - 1, 1), r--), e[r][1] = h, f ? e[r + 1][1] = f : (e.splice(r + 1, 1), r--));
}
r++;
}
};
v.nonAlphaNumericRegex_ = /[^a-zA-Z0-9]/;
v.whitespaceRegex_ = /\s/;
v.linebreakRegex_ = /[\r\n]/;
v.blanklineEndRegex_ = /\n\r?\n$/;
v.blanklineStartRegex_ = /^\r?\n\r?\n/;
v.prototype.diff_cleanupEfficiency = function(e) {
for (var n = !1, r = [], s = 0, i = null, t = 0, a = !1, l = !1, o = !1, h = !1; t < e.length; )
e[t][0] == b ? (e[t][1].length < this.Diff_EditCost && (o || h) ? (r[s++] = t, a = o, l = h, i = e[t][1]) : (s = 0, i = null), o = h = !1) : (e[t][0] == k ? h = !0 : o = !0, i && (a && l && o && h || i.length < this.Diff_EditCost / 2 && a + l + o + h == 3) && (e.splice(
r[s - 1],
0,
[k, i]
), e[r[s - 1] + 1][0] = E, s--, i = null, a && l ? (o = h = !0, s = 0) : (s--, t = s > 0 ? r[s - 1] : -1, o = h = !1), n = !0)), t++;
n && this.diff_cleanupMerge(e);
};
v.prototype.diff_cleanupMerge = function(e) {
e.push([b, ""]);
for (var n = 0, r = 0, s = 0, i = "", t = "", a; n < e.length; )
switch (e[n][0]) {
case E:
s++, t += e[n][1], n++;
break;
case k:
r++, i += e[n][1], n++;
break;
case b:
r + s > 1 ? (r !== 0 && s !== 0 && (a = this.diff_commonPrefix(t, i), a !== 0 && (n - r - s > 0 && e[n - r - s - 1][0] == b ? e[n - r - s - 1][1] += t.substring(0, a) : (e.splice(0, 0, [
b,
t.substring(0, a)
]), n++), t = t.substring(a), i = i.substring(a)), a = this.diff_commonSuffix(t, i), a !== 0 && (e[n][1] = t.substring(t.length - a) + e[n][1], t = t.substring(0, t.length - a), i = i.substring(0, i.length - a))), r === 0 ? e.splice(
n - s,
r + s,
[E, t]
) : s === 0 ? e.splice(
n - r,
r + s,
[k, i]
) : e.splice(
n - r - s,
r + s,
[k, i],
[E, t]
), n = n - r - s + (r ? 1 : 0) + (s ? 1 : 0) + 1) : n !== 0 && e[n - 1][0] == b ? (e[n - 1][1] += e[n][1], e.splice(n, 1)) : n++, s = 0, r = 0, i = "", t = "";
break;
}
e[e.length - 1][1] === "" && e.pop();
var l = !1;
for (n = 1; n < e.length - 1; )
e[n - 1][0] == b && e[n + 1][0] == b && (e[n][1].substring(e[n][1].length - e[n - 1][1].length) == e[n - 1][1] ? (e[n][1] = e[n - 1][1] + e[n][1].substring(0, e[n][1].length - e[n - 1][1].length), e[n + 1][1] = e[n - 1][1] + e[n + 1][1], e.splice(n - 1, 1), l = !0) : e[n][1].substring(0, e[n + 1][1].length) == e[n + 1][1] && (e[n - 1][1] += e[n + 1][1], e[n][1] = e[n][1].substring(e[n + 1][1].length) + e[n + 1][1], e.splice(n + 1, 1), l = !0)), n++;
l && this.diff_cleanupMerge(e);
};
v.prototype.diff_xIndex = function(e, n) {
var r = 0, s = 0, i = 0, t = 0, a;
for (a = 0; a < e.length && (e[a][0] !== E && (r += e[a][1].length), e[a][0] !== k && (s += e[a][1].length), !(r > n)); a++)
i = r, t = s;
return e.length != a && e[a][0] === k ? t : t + (n - i);
};
v.prototype.diff_prettyHtml = function(e) {
for (var n = [], r = /&/g, s = /</g, i = />/g, t = /\n/g, a = 0; a < e.length; a++) {
var l = e[a][0], o = e[a][1], h = o.replace(r, "&").replace(s, "<").replace(i, ">").replace(t, "¶<br>");
switch (l) {
case E:
n[a] = '<ins style="background:#e6ffe6;">' + h + "</ins>";
break;
case k:
n[a] = '<del style="background:#ffe6e6;">' + h + "</del>";
break;
case b:
n[a] = "<span>" + h + "</span>";
break;
}
}
return n.join("");
};
v.prototype.diff_text1 = function(e) {
for (var n = [], r = 0; r < e.length; r++)
e[r][0] !== E && (n[r] = e[r][1]);
return n.join("");
};
v.prototype.diff_text2 = function(e) {
for (var n = [], r = 0; r < e.length; r++)
e[r][0] !== k && (n[r] = e[r][1]);
return n.join("");
};
v.prototype.diff_levenshtein = function(e) {
for (var n = 0, r = 0, s = 0, i = 0; i < e.length; i++) {
var t = e[i][0], a = e[i][1];
switch (t) {
case E:
r += a.length;
break;
case k:
s += a.length;
break;
case b:
n += Math.max(r, s), r = 0, s = 0;
break;
}
}
return n += Math.max(r, s), n;
};
v.prototype.diff_toDelta = function(e) {
for (var n = [], r = 0; r < e.length; r++)
switch (e[r][0]) {
case E:
n[r] = "+" + encodeURI(e[r][1]);
break;
case k:
n[r] = "-" + e[r][1].length;
break;
case b:
n[r] = "=" + e[r][1].length;
break;
}
return n.join(" ").replace(/%20/g, " ");
};
v.prototype.diff_fromDelta = function(e, n) {
for (var r = [], s = 0, i = 0, t = n.split(/\t/g), a = 0; a < t.length; a++) {
var l = t[a].substring(1);
switch (t[a].charAt(0)) {
case "+":
try {
r[s++] = [E, decodeURI(l)];
} catch {
throw new Error("Illegal escape in diff_fromDelta: " + l);
}
break;
case "-":
case "=":
var o = parseInt(l, 10);
if (isNaN(o) || o < 0)
throw new Error("Invalid number in diff_fromDelta: " + l);
var h = e.substring(i, i += o);
t[a].charAt(0) == "=" ? r[s++] = [b, h] : r[s++] = [k, h];
break;
default:
if (t[a])
throw new Error("Invalid diff operation in diff_fromDelta: " + t[a]);
}
}
if (i != e.length)
throw new Error("Delta length (" + i + ") does not equal source text length (" + e.length + ").");
return r;
};
v.prototype.match_main = function(e, n, r) {
if (e == null || n == null || r == null)
throw new Error("Null input. (match_main)");
return r = Math.max(0, Math.min(r, e.length)), e == n ? 0 : e.length ? e.substring(r, r + n.length) == n ? r : this.match_bitap_(e, n, r) : -1;
};
v.prototype.match_bitap_ = function(e, n, r) {
if (n.length > this.Match_MaxBits)
throw new Error("Pattern too long for this browser.");
var s = this.match_alphabet_(n), i = this;
function t(I, C) {
var A = I / n.length, D = Math.abs(r - C);
return i.Match_Distance ? A + D / i.Match_Distance : D ? 1 : A;
}
var a = this.Match_Threshold, l = e.indexOf(n, r);
l != -1 && (a = Math.min(t(0, l), a), l = e.lastIndexOf(n, r + n.length), l != -1 && (a = Math.min(t(0, l), a)));
var o = 1 << n.length - 1;
l = -1;
for (var h, f, c = n.length + e.length, u, _ = 0; _ < n.length; _++) {
for (h = 0, f = c; h < f; )
t(_, r + f) <= a ? h = f : c = f, f = Math.floor((c - h) / 2 + h);
c = f;
var g = Math.max(1, r - f + 1), d = Math.min(r + f, e.length) + n.length, m = Array(d + 2);
m[d + 1] = (1 << _) - 1;
for (var p = d; p >= g; p--) {
var w = s[e.charAt(p - 1)];
if (_ === 0 ? m[p] = (m[p + 1] << 1 | 1) & w : m[p] = (m[p + 1] << 1 | 1) & w | ((u[p + 1] | u[p]) << 1 | 1) | u[p + 1], m[p] & o) {
var M = t(_, p - 1);
if (M <= a)
if (a = M, l = p - 1, l > r)
g = Math.max(1, 2 * r - l);
else
break;
}
}
if (t(_ + 1, r) > a)
break;
u = m;
}
return l;
};
v.prototype.match_alphabet_ = function(e) {
for (var n = {}, r = 0; r < e.length; r++)
n[e.charAt(r)] = 0;
for (var r = 0; r < e.length; r++)
n[e.charAt(r)] |= 1 << e.length - r - 1;
return n;
};
v.prototype.patch_addContext_ = function(e, n) {
if (n.length != 0) {
for (var r = n.substring(e.start2, e.start2 + e.length1), s = 0; n.indexOf(r) != n.lastIndexOf(r) && r.length < this.Match_MaxBits - this.Patch_Margin - this.Patch_Margin; )
s += this.Patch_Margin, r = n.substring(
e.start2 - s,
e.start2 + e.length1 + s
);
s += this.Patch_Margin;
var i = n.substring(e.start2 - s, e.start2);
i && e.diffs.unshift([b, i]);
var t = n.substring(
e.start2 + e.length1,
e.start2 + e.length1 + s
);
t && e.diffs.push([b, t]), e.start1 -= i.length, e.start2 -= i.length, e.length1 += i.length + t.length, e.length2 += i.length + t.length;
}
};
v.prototype.patch_make = function(e, n, r) {
var s, i;
if (typeof e == "string" && typeof n == "string" && typeof r > "u")
s = /** @type {string} */
e, i = this.diff_main(
s,
/** @type {string} */
n,
!0
), i.length > 2 && (this.diff_cleanupSemantic(i), this.diff_cleanupEfficiency(i));
else if (e && typeof e == "object" && typeof n > "u" && typeof r > "u")
i = /** @type {!Array.<!diff_match_patch.Diff>} */
e, s = this.diff_text1(i);
else if (typeof e == "string" && n && typeof n == "object" && typeof r > "u")
s = /** @type {string} */
e, i = /** @type {!Array.<!diff_match_patch.Diff>} */
n;
else if (typeof e == "string" && typeof n == "string" && r && typeof r == "object")
s = /** @type {string} */
e, i = /** @type {!Array.<!diff_match_patch.Diff>} */
r;
else
throw new Error("Unknown call format to patch_make.");
if (i.length === 0)
return [];
for (var t = [], a = new v.patch_obj(), l = 0, o = 0, h = 0, f = s, c = s, u = 0; u < i.length; u++) {
var _ = i[u][0], g = i[u][1];
switch (!l && _ !== b && (a.start1 = o, a.start2 = h), _) {
case E:
a.diffs[l++] = i[u], a.length2 += g.length, c = c.substring(0, h) + g + c.substring(h);
break;
case k:
a.length1 += g.length, a.diffs[l++] = i[u], c = c.substring(0, h) + c.substring(h + g.length);
break;
case b:
g.length <= 2 * this.Patch_Margin && l && i.length != u + 1 ? (a.diffs[l++] = i[u], a.length1 += g.length, a.length2 += g.length) : g.length >= 2 * this.Patch_Margin && l && (this.patch_addContext_(a, f), t.push(a), a = new v.patch_obj(), l = 0, f = c, o = h);
break;
}
_ !== E && (o += g.length), _ !== k && (h += g.length);
}
return l && (this.patch_addContext_(a, f), t.push(a)), t;
};
v.prototype.patch_deepCopy = function(e) {
for (var n = [], r = 0; r < e.length; r++) {
var s = e[r], i = new v.patch_obj();
i.diffs = [];
for (var t = 0; t < s.diffs.length; t++)
i.diffs[t] = s.diffs[t].slice();
i.start1 = s.start1, i.start2 = s.start2, i.length1 = s.length1, i.length2 = s.length2, n[r] = i;
}
return n;
};
v.prototype.patch_apply = function(e, n) {
if (e.length == 0)
return [n, []];
e = this.patch_deepCopy(e);
var r = this.patch_addPadding(e);
n = r + n + r, this.patch_splitMax(e);
for (var s = 0, i = [], t = 0; t < e.length; t++) {
var a = e[t].start2 + s, l = this.diff_text1(e[t].diffs), o, h = -1;
if (l.length > this.Match_MaxBits ? (o = this.match_main(
n,
l.substring(0, this.Match_MaxBits),
a
), o != -1 && (h = this.match_main(
n,
l.substring(l.length - this.Match_MaxBits),
a + l.length - this.Match_MaxBits
), (h == -1 || o >= h) && (o = -1))) : o = this.match_main(n, l, a), o == -1)
i[t] = !1, s -= e[t].length2 - e[t].length1;
else {
i[t] = !0, s = o - a;
var f;
if (h == -1 ? f = n.substring(o, o + l.length) : f = n.substring(o, h + this.Match_MaxBits), l == f)
n = n.substring(0, o) + this.diff_text2(e[t].diffs) + n.substring(o + l.length);
else {
var c = this.diff_main(l, f, !1);
if (l.length > this.Match_MaxBits && this.diff_levenshtein(c) / l.length > this.Patch_DeleteThreshold)
i[t] = !1;
else {
this.diff_cleanupSemanticLossless(c);
for (var u = 0, _, g = 0; g < e[t].diffs.length; g++) {
var d = e[t].diffs[g];
d[0] !== b && (_ = this.diff_xIndex(c, u)), d[0] === E ? n = n.substring(0, o + _) + d[1] + n.substring(o + _) : d[0] === k && (n = n.substring(0, o + _) + n.substring(o + this.diff_xIndex(
c,
u + d[1].length
))), d[0] !== k && (u += d[1].length);
}
}
}
}
}
return n = n.substring(r.length, n.length - r.length), [n, i];
};
v.prototype.patch_addPadding = function(e) {
for (var n = this.Patch_Margin, r = "", s = 1; s <= n; s++)
r += String.fromCharCode(s);
for (var s = 0; s < e.length; s++)
e[s].start1 += n, e[s].start2 += n;
var i = e[0], t = i.diffs;
if (t.length == 0 || t[0][0] != b)
t.unshift([b, r]), i.start1 -= n, i.start2 -= n, i.length1 += n, i.length2 += n;
else if (n > t[0][1].length) {
var a = n - t[0][1].length;
t[0][1] = r.substring(t[0][1].length) + t[0][1], i.start1 -= a, i.start2 -= a, i.length1 += a, i.length2 += a;
}
if (i = e[e.length - 1], t = i.diffs, t.length == 0 || t[t.length - 1][0] != b)
t.push([b, r]), i.length1 += n, i.length2 += n;
else if (n > t[t.length - 1][1].length) {
var a = n - t[t.length - 1][1].length;
t[t.length - 1][1] += r.substring(0, a), i.length1 += a, i.length2 += a;
}
return r;
};
v.prototype.patch_splitMax = function(e) {
for (var n = this.Match_MaxBits, r = 0; r < e.length; r++)
if (!(e[r].length1 <= n)) {
var s = e[r];
e.splice(r--, 1);
for (var i = s.start1, t = s.start2, a = ""; s.diffs.length !== 0; ) {
var l = new v.patch_obj(), o = !0;
for (l.start1 = i - a.length, l.start2 = t - a.length, a !== "" && (l.length1 = l.length2 = a.length, l.diffs.push([b, a])); s.diffs.length !== 0 && l.length1 < n - this.Patch_Margin; ) {
var h = s.diffs[0][0], f = s.diffs[0][1];
h === E ? (l.length2 += f.length, t += f.length, l.diffs.push(s.diffs.shift()), o = !1) : h === k && l.diffs.length == 1 && l.diffs[0][0] == b && f.length > 2 * n ? (l.length1 += f.length, i += f.length, o = !1, l.diffs.push([h, f]), s.diffs.shift()) : (f = f.substring(
0,
n - l.length1 - this.Patch_Margin
), l.length1 += f.length, i += f.length, h === b ? (l.length2 += f.length, t += f.length) : o = !1, l.diffs.push([h, f]), f == s.diffs[0][1] ? s.diffs.shift() : s.diffs[0][1] = s.diffs[0][1].substring(f.length));
}
a = this.diff_text2(l.diffs), a = a.substring(a.length - this.Patch_Margin);
var c = this.diff_text1(s.diffs).substring(0, this.Patch_Margin);
c !== "" && (l.length1 += c.length, l.length2 += c.length, l.diffs.length !== 0 && l.diffs[l.diffs.length - 1][0] === b ? l.diffs[l.diffs.length - 1][1] += c : l.diffs.push([b, c])), o || e.splice(++r, 0, l);
}
}
};
v.prototype.patch_toText = function(e) {
for (var n = [], r = 0; r < e.length; r++)
n[r] = e[r];
return n.join("");
};
v.prototype.patch_fromText = function(e) {
var n = [];
if (!e)
return n;
for (var r = e.split(`
`), s = 0, i = /^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/; s < r.length; ) {
var t = r[s].match(i);
if (!t)
throw new Error("Invalid patch string: " + r[s]);
var a = new v.patch_obj();
for (n.push(a), a.start1 = parseInt(t[1], 10), t[2] === "" ? (a.start1--, a.length1 = 1) : t[2] == "0" ? a.length1 = 0 : (a.start1--, a.length1 = parseInt(t[2], 10)), a.start2 = parseInt(t[3], 10), t[4] === "" ? (a.start2--, a.length2 = 1) : t[4] == "0" ? a.length2 = 0 : (a.start2--, a.length2 = parseInt(t[4], 10)), s++; s < r.length; ) {
var l = r[s].charAt(0);
try {
var o = decodeURI(r[s].substring(1));
} catch {
throw new Error("Illegal escape in patch_fromText: " + o);
}
if (l == "-")
a.diffs.push([k, o]);
else if (l == "+")
a.diffs.push([E, o]);
else if (l == " ")
a.diffs.push([b, o]);
else {
if (l == "@")
break;
if (l !== "")
throw new Error('Invalid patch mode "' + l + '" in: ' + o);
}
s++;
}
}
return n;
};
v.patch_obj = function() {
this.diffs = [], this.start1 = null, this.start2 = null, this.length1 = 0, this.length2 = 0;
};
v.patch_obj.prototype.toString = function() {
var e, n;
this.length1 === 0 ? e = this.start1 + ",0" : this.length1 == 1 ? e = this.start1 + 1 : e = this.start1 + 1 + "," + this.length1, this.length2 === 0 ? n = this.start2 + ",0" : this.length2 == 1 ? n = this.start2 + 1 : n = this.start2 + 1 + "," + this.length2;
for (var r = ["@@ -" + e + " +" + n + ` @@
`], s, i = 0; i < this.diffs.length; i++) {
switch (this.diffs[i][0]) {
case E:
s = "+";
break;
case k:
s = "-";
break;
case b:
s = " ";
break;
}
r[i + 1] = s + encodeURI(this.diffs[i][1]) + `
`;
}
return r.join("").replace(/%20/g, " ");
};
const L = new v();
function q(e) {
if (e.length === 0)
return !1;
const n = e.map((s) => s[1].body);
return new Set(n).size > 1;
}
function V(e) {
let n = !0, r, s = [];
for (const g of e)
g[1].src === S.BLOCK_SOURCE_BASE ? r = g : s.push(g);
if (r || (r = e[0], s = e.slice(1), n = !1), !n) {
const g = [r].concat(s), d = T(g).map((w) => w[1]), m = [[B.DIFF_EQUAL, d[0]]], p = d.slice(1).map((w) => [B.DIFF_INSERT, w]);
return m.concat(p);
}
const i = r[1], t = s.map((g) => g[1]), a = i.body, l = {
src: i.src,
uuid: i.uuid,
body: i.body,
meta: i.meta,
level: i.level,
srcBranch: i.srcBranch
};
let o = !1, h = l.body;
const f = [];
for (const g of t) {
const d = g.body;
if (g.uuid && l.uuid && g.uuid != l.uuid) {
f.push(g);
continue;
}
if (o && h != d && a != d) {
f.push(g);
continue;
}
!o && a != d && (o = !0, h = d, l.body = g.body, l.src = g.src, l.srcBranch = g.srcBranch, l.meta = g.meta), !l.uuid && g.uuid && (l.uuid = g.uuid, l.src = g.src, l.srcBranch = g.srcBranch, l.meta = g.meta, l.body = g.body, o = !0, h = d), g.level && i.level != g.level && (l.level = g.level, l.src = g.src, l.srcBranch = g.srcBranch);
}
const c = [[B.DIFF_EQUAL, l]], u = f.map((g) => [B.DIFF_INSERT, g]), _ = T(u);
return c.concat(_);
}
function T(e) {
const n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
function s(h, f) {
const c = n.get(f);
if (c) {
const u = c.get(h) || 0;
c.set(h, u + 1);
} else
n.set(f, /* @__PURE__ */ new Map([[h, 1]]));
}
function i(h, f) {
const c = n.get(f), u = r.get(h) || 0, _ = (c == null ? void 0 : c.get(h)) || 0;
return _ > u ? (r.set(h, _), !0) : !1;
}
const t = /* @__PURE__ */ new Map(), a = [], l = [];
let o = 0;
for (const h of e) {
const f = h[1].body, c = h[1].uuid, u = h[1].srcBranch;
if (s(f, u), c && t.has(c))
continue;
const _ = i(f, u);
let g = "";
(c || _) && (c && !t.has(c) && (t.set(c, o), g += `Accepted #${o} with first unique uuid ${h[1].uuid}.`), _ && (g += `Accepted #${o} with acceptable content '${h[1].body}'.`), l.push(g), a.push(h[1]), o += 1);
}
return a.map((h, f) => [B.DIFF_INSERT, h, l[f]]);
}
class W {
/**
* Can be used for only one time (charHash is shared) with maximum 65536 unique blocks, or unexpected behavior may occur
*/
constructor(n = 1) {
F(this, "charHash", new $());
L.Diff_Timeout = n;
}
/**
* The diff steps, in order of the block position in the base
*/
diff_logseqMode(n, r) {
const s = this.charHash.diff_blocksToChars(n), i = this.charHash.diff_blocksToChars(r), t = L.diff_main(s, i, !1);
return this.charHash.diff_charsToBlocks(t, n, r);
}
/**
* differentiate the baseInsert and newInsert, keep all the non-overlapping operations
*/
diff_insert_ops(n, r) {
return this.diff_logseqMode(n.map((t) => t[1]), r.map((t) => t[1])).flat(1).map((t) => [B.DIFF_INSERT, t[1]]);
}
}
function Z(e, n, r) {
const s = [];
let i = [r, ...n], t = !1;
i.length < e.length && (i = i.concat(Array(e.length - i.length).fill(r)));
for (const [a, l] of e.entries()) {
t = !0;
for (const o of l) {
const [h, f] = o;
(h === B.DIFF_EQUAL || h === B.DIFF_INSERT) && (t ? f.uuid ? (s.push(f.uuid), f.uuid == i[a] && (t = !1)) : (s.push(i[a]), t = !1) : f.uuid ? s.push(f.uuid) : s.push(r));
}
}
return s;
}
function G(e, n, r) {
const s = document.createElement("div");
let i = 0;
for (const [t, a] of e.entries())
for (const l of a) {
const [o, h, f] = l, c = J(l[1]), u = document.createElement("tr");
if (u.style.padding = "0 0.2em", u.style.borderRadius = "0.2em", n) {
const m = document.createElement("td");
m.innerText = o === B.DIFF_INSERT ? "" : n[t - 1] || "", m.style.opacity = "0.5", u.appendChild(m);
}
if (r) {
const m = document.createElement("td");
m.innerText = o === B.DIFF_DELETE ? "" : r[i] || "", m.style.opacity = "0.5", u.appendChild(m);
}
const _ = document.createElement("td");
_.innerText = t.toString(), _.style.borderRight = "1px solid #e1e4e8";
const g = document.createElement("td");
g.innerText = c, g.style.whiteSpace = "pre", u.appendChild(_), u.appendChild(g);
const d = document.createElement("td");
switch (d.innerHTML = f || "", u.appendChild(d), o) {
case B.DIFF_INSERT:
u.style.backgroundColor = "#e6ffed", u.style.color = "#24292e";
break;
case B.DIFF_EQUAL:
u.style.color = "#24292e", h.src === S.BLOCK_SOURCE_BRANCH && (u.style.backgroundColor = "#fff2cc");
break;
case B.DIFF_DELETE:
u.style.backgroundColor = "#ffeef0", u.style.color = "#24292e", u.style.textDecoration = "line-through";
break;
}
s.appendChild(u), o !== B.DIFF_DELETE && (i += 1);
}
return s;
}
function N(e) {
const n = [[], [], []];
for (const r of e)
n[r[0] + 1].push(r);
return n;
}
function P(e, n) {
return e.map((r) => (r.src = r.src || (n == 0 ? 0 : 1), r.srcBranch = r.srcBranch || n, r.uuid = r.uuid || void 0, r));
}
class x {
/**
* Merger with max 65536 unique blocks support
*
* @param timeout optional the timeout for the diff algorithm (in sec, 1 sec by default)
*/
constructor() {
}
/**
*
* @param baseText the base text (the text to be merged into, the anchor of block index)
* @param branchTexts the texts to be merged
* @returns the DMP operations of the final merged text (to be applied on the base text)
* resolvedDiffs[blockPos][DMPOP id][DMPOPType, text]
* where blockPos is the block # in the baseText
*/
mergeBlocks(n, r) {
const s = new W(1), i = r.map(
(o, h) => s.diff_logseqMode(P(n, 0), P(o, h + 1))
), t = [], a = i.reduce((o, h) => {
for (const [f, c] of h.entries())
if (o[f] === void 0)
o[f] = N(c);
else {
const u = N(c);
o[f][0] = o[f][0].concat(u[0]), o[f][1] = o[f][1].concat(u[1]), o[f][2] = s.diff_insert_ops(o[f][2], u[2]);
}
return o;
}, t), l = [];
for (const [o, h] of a.entries()) {
let f = [];
const [c, u, _] = h, g = q(c.concat(u));
c.length >= 1 && !g ? o < 1 ? console.warn(`DIFF_DELETE at position ${o} is not expected`) : f = [[B.DIFF_DELETE, n[o - 1]]] : u.length >= 1 ? o < 1 ? console.warn(`DIFF_EQUAL at position ${o} is not expected`) : f = V(u) : o !== 0 && console.warn(`No DIFF_EQUAL or DIFF_DELETE at position non-0 position ${o}`);
const d = T(_);
f = f.concat(d), l.push(f);
}
return l;
}
}
const ee = "0.2.1";
export {
W as Differ,
x as Merger,
Y as Parser,
Z as attach_uuids,
ee as version,
G as visualizeAsHTML
};