@git-diff-view/react 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -72,334 +72,79 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
72
72
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
73
73
  };
74
74
 
75
- /******************************************************************************
76
- Copyright (c) Microsoft Corporation.
77
-
78
- Permission to use, copy, modify, and/or distribute this software for any
79
- purpose with or without fee is hereby granted.
80
-
81
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
82
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
83
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
84
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
85
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
86
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
87
- PERFORMANCE OF THIS SOFTWARE.
88
- ***************************************************************************** */
89
- /* global Reflect, Promise, SuppressedError, Symbol */
90
-
91
-
92
- function __classPrivateFieldGet(receiver, state, kind, f) {
93
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
94
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
95
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
96
- }
97
-
98
- function __classPrivateFieldSet(receiver, state, value, kind, f) {
99
- if (kind === "m") throw new TypeError("Private method is not writable");
100
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
101
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
102
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
103
- }
104
-
105
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
106
- var e = new Error(message);
107
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
108
- };
109
-
110
- const processAST = (ast) => {
111
- let lineNumber = 1;
112
- const syntaxObj = {};
113
- const loopAST = (nodes, wrapper) => {
114
- nodes.forEach((node) => {
115
- if (node.type === "text") {
116
- if (node.value.indexOf("\n") === -1) {
117
- const valueLength = node.value.length;
118
- if (!syntaxObj[lineNumber]) {
119
- node.startIndex = 0;
120
- node.endIndex = valueLength - 1;
121
- const item = {
122
- value: node.value,
123
- lineNumber,
124
- valueLength,
125
- nodeList: [{ node, wrapper }],
126
- };
127
- syntaxObj[lineNumber] = item;
128
- }
129
- else {
130
- node.startIndex = syntaxObj[lineNumber].valueLength;
131
- node.endIndex = node.startIndex + valueLength - 1;
132
- syntaxObj[lineNumber].value += node.value;
133
- syntaxObj[lineNumber].valueLength += valueLength;
134
- syntaxObj[lineNumber].nodeList.push({ node, wrapper });
135
- }
136
- node.lineNumber = lineNumber;
137
- return;
138
- }
139
- const lines = node.value.split("\n");
140
- node.children = node.children || [];
141
- for (let i = 0; i < lines.length; i++) {
142
- const _value = i === lines.length - 1 ? lines[i] : lines[i] + "\n";
143
- const _lineNumber = i === 0 ? lineNumber : ++lineNumber;
144
- const _valueLength = _value.length;
145
- const _node = {
146
- type: "text",
147
- value: _value,
148
- startIndex: Infinity,
149
- endIndex: Infinity,
150
- lineNumber: _lineNumber,
151
- };
152
- if (!syntaxObj[_lineNumber]) {
153
- _node.startIndex = 0;
154
- _node.endIndex = _valueLength - 1;
155
- const item = {
156
- value: _value,
157
- lineNumber: _lineNumber,
158
- valueLength: _valueLength,
159
- nodeList: [{ node: _node, wrapper }],
160
- };
161
- syntaxObj[_lineNumber] = item;
162
- }
163
- else {
164
- _node.startIndex = syntaxObj[_lineNumber].valueLength;
165
- _node.endIndex = _node.startIndex + _valueLength - 1;
166
- syntaxObj[_lineNumber].value += _value;
167
- syntaxObj[_lineNumber].valueLength += _valueLength;
168
- syntaxObj[_lineNumber].nodeList.push({ node: _node, wrapper });
169
- }
170
- node.children.push(_node);
171
- }
172
- node.lineNumber = lineNumber;
173
- return;
174
- }
175
- if (node.children) {
176
- loopAST(node.children, node);
177
- node.lineNumber = lineNumber;
178
- }
179
- });
180
- };
181
- loopAST(ast.children);
182
- return { syntaxFileObject: syntaxObj, syntaxFileLineNumber: lineNumber };
183
- };
184
-
185
- const lowlight = lowlight$1.createLowlight(lowlight$1.all);
186
- // !SEE https://github.com/highlightjs/highlightjs-vue
187
- lowlight.register("vue", function hljsDefineVue(hljs) {
188
- return {
189
- subLanguage: "xml",
190
- contains: [
191
- hljs.COMMENT("<!--", "-->", {
192
- relevance: 10,
193
- }),
194
- {
195
- begin: /^(\s*)(<script>)/gm,
196
- end: /^(\s*)(<\/script>)/gm,
197
- subLanguage: "javascript",
198
- excludeBegin: true,
199
- excludeEnd: true,
200
- },
201
- {
202
- begin: /^(?:\s*)(?:<script\s+lang=(["'])ts\1>)/gm,
203
- end: /^(\s*)(<\/script>)/gm,
204
- subLanguage: "typescript",
205
- excludeBegin: true,
206
- excludeEnd: true,
207
- },
208
- {
209
- begin: /^(\s*)(<style(\s+scoped)?>)/gm,
210
- end: /^(\s*)(<\/style>)/gm,
211
- subLanguage: "css",
212
- excludeBegin: true,
213
- excludeEnd: true,
214
- },
215
- {
216
- begin: /^(?:\s*)(?:<style(?:\s+scoped)?\s+lang=(["'])(?:s[ca]ss)\1(?:\s+scoped)?>)/gm,
217
- end: /^(\s*)(<\/style>)/gm,
218
- subLanguage: "scss",
219
- excludeBegin: true,
220
- excludeEnd: true,
221
- },
222
- {
223
- begin: /^(?:\s*)(?:<style(?:\s+scoped)?\s+lang=(["'])stylus\1(?:\s+scoped)?>)/gm,
224
- end: /^(\s*)(<\/style>)/gm,
225
- subLanguage: "stylus",
226
- excludeBegin: true,
227
- excludeEnd: true,
228
- },
229
- ],
230
- };
231
- });
232
- const instance = { name: "lowlight" };
233
- let _maxLineToIgnoreSyntax = 2000;
234
- const _ignoreSyntaxHighlightList = [];
235
- Object.defineProperty(instance, "maxLineToIgnoreSyntax", {
236
- get: () => _maxLineToIgnoreSyntax,
237
- });
238
- Object.defineProperty(instance, "setMaxLineToIgnoreSyntax", {
239
- value: (v) => {
240
- _maxLineToIgnoreSyntax = v;
241
- },
242
- });
243
- Object.defineProperty(instance, "ignoreSyntaxHighlightList", {
244
- get: () => _ignoreSyntaxHighlightList,
245
- });
246
- Object.defineProperty(instance, "setIgnoreSyntaxHighlightList", {
247
- value: (v) => {
248
- _ignoreSyntaxHighlightList.length = 0;
249
- _ignoreSyntaxHighlightList.push(...v);
250
- },
251
- });
252
- Object.defineProperty(instance, "getAST", {
253
- value: (raw, fileName, lang) => {
254
- let hasRegisteredLang = true;
255
- if (!lowlight.registered(lang)) {
256
- console.warn(`not support current lang: ${lang} yet`);
257
- hasRegisteredLang = false;
258
- }
259
- if (fileName &&
260
- highlighter.ignoreSyntaxHighlightList.some((item) => item instanceof RegExp ? item.test(fileName) : fileName === item)) {
261
- console.warn(`ignore syntax for current file, because the fileName is in the ignoreSyntaxHighlightList: ${fileName}`);
262
- return;
263
- }
264
- if (hasRegisteredLang) {
265
- return lowlight.highlight(lang, raw);
266
- }
267
- else {
268
- return lowlight.highlightAuto(raw);
269
- }
270
- },
271
- });
272
- Object.defineProperty(instance, "processAST", {
273
- value: (ast) => {
274
- return processAST(ast);
275
- },
276
- });
277
- const highlighter = instance;
278
-
279
- var _Cache_keyArray, _Cache_maxLength;
280
- class Cache extends Map {
281
- constructor() {
282
- super(...arguments);
283
- _Cache_keyArray.set(this, []);
284
- _Cache_maxLength.set(this, 30);
285
- }
286
- setMaxLength(length) {
287
- __classPrivateFieldSet(this, _Cache_maxLength, length, "f");
288
- this._checkLength();
289
- }
290
- set(key, value) {
291
- if (this.has(key))
292
- return this;
293
- __classPrivateFieldGet(this, _Cache_keyArray, "f").push(key);
294
- this._checkLength();
295
- return super.set(key, value);
296
- }
297
- _checkLength() {
298
- while (__classPrivateFieldGet(this, _Cache_keyArray, "f").length > __classPrivateFieldGet(this, _Cache_maxLength, "f")) {
299
- const key = __classPrivateFieldGet(this, _Cache_keyArray, "f").shift();
300
- this.delete(key);
301
- }
302
- }
303
- }
304
- _Cache_keyArray = new WeakMap(), _Cache_maxLength = new WeakMap();
305
-
306
- var _File_instances, _File_doCheck;
307
- const map = new Cache();
308
- const devKey = "@git-diff-cache";
309
- map.setMaxLength(50);
310
- map.name = "@git-diff-view/core";
311
- if (typeof globalThis !== "undefined") {
312
- if (Array.isArray(globalThis[devKey])) {
313
- globalThis[devKey] = globalThis[devKey].filter((i) => i !== map);
314
- if (globalThis[devKey].length > 0) {
315
- console.warn("there are multiple instance of @git-diff-view/core in the one environment!");
316
- }
317
- globalThis[devKey].push(map);
318
- }
319
- else {
320
- globalThis[devKey] = [map];
321
- }
322
- }
323
- class File {
324
- constructor(raw, lang, fileName) {
325
- _File_instances.add(this);
326
- this.raw = raw;
327
- this.lang = lang;
328
- this.fileName = fileName;
329
- this.rawFile = {};
330
- this.hasDoRaw = false;
331
- this.syntaxFile = {};
332
- this.hasDoSyntax = false;
333
- this.maxLineNumber = 0;
334
- Object.defineProperty(this, "__v_skip", { value: true });
335
- }
336
- doSyntax({ registerHighlighter }) {
337
- if (!this.raw || this.hasDoSyntax)
338
- return;
339
- const _highlighter = registerHighlighter || highlighter;
340
- if (this.syntaxLength) {
341
- console.error("current file already doSyntax before!");
342
- return;
343
- }
344
- if (this.rawLength > _highlighter.maxLineToIgnoreSyntax) {
345
- console.warn(`ignore syntax for current file, because the rawLength is too long: ${this.rawLength}`);
346
- return;
347
- }
348
- this.ast = _highlighter.getAST(this.raw, this.fileName, this.lang);
349
- if (!this.ast)
350
- return;
351
- const { syntaxFileObject, syntaxFileLineNumber } = _highlighter.processAST(this.ast);
352
- this.syntaxFile = syntaxFileObject;
353
- this.syntaxLength = syntaxFileLineNumber;
354
- this.highlighterName = _highlighter.name;
355
- {
356
- __classPrivateFieldGet(this, _File_instances, "m", _File_doCheck).call(this);
357
- }
358
- this.hasDoSyntax = true;
359
- }
360
- doRaw() {
361
- if (!this.raw || this.hasDoRaw)
362
- return;
363
- const rawString = this.raw;
364
- const rawArray = rawString.split("\n");
365
- this.rawLength = rawArray.length;
366
- this.maxLineNumber = rawArray.length;
367
- this.rawFile = {};
368
- for (let i = 0; i < rawArray.length; i++) {
369
- this.rawFile[i + 1] = i < rawArray.length - 1 ? rawArray[i] + "\n" : rawArray[i];
75
+ exports.DiffHunkExpansionType = void 0;
76
+ (function (DiffHunkExpansionType) {
77
+ /** The hunk header cannot be expanded at all. */
78
+ DiffHunkExpansionType["None"] = "None";
79
+ /**
80
+ * The hunk header can be expanded up exclusively. Only the first hunk can be
81
+ * expanded up exclusively.
82
+ */
83
+ DiffHunkExpansionType["Up"] = "Up";
84
+ /**
85
+ * The hunk header can be expanded down exclusively. Only the last hunk (if
86
+ * it's the dummy hunk with only one line) can be expanded down exclusively.
87
+ */
88
+ DiffHunkExpansionType["Down"] = "Down";
89
+ /** The hunk header can be expanded both up and down. */
90
+ DiffHunkExpansionType["Both"] = "Both";
91
+ /**
92
+ * The hunk header represents a short gap that, when expanded, will
93
+ * result in merging this hunk and the hunk above.
94
+ */
95
+ DiffHunkExpansionType["Short"] = "Short";
96
+ })(exports.DiffHunkExpansionType || (exports.DiffHunkExpansionType = {}));
97
+ /** each diff is made up of a number of hunks */
98
+ class DiffHunk {
99
+ /**
100
+ * @param header The details from the diff hunk header about the line start and patch length.
101
+ * @param lines The contents - context and changes - of the diff section.
102
+ * @param unifiedDiffStart The diff hunk's start position in the overall file diff.
103
+ * @param unifiedDiffEnd The diff hunk's end position in the overall file diff.
104
+ */
105
+ constructor(header, lines, unifiedDiffStart, unifiedDiffEnd, expansionType) {
106
+ this.header = header;
107
+ this.lines = lines;
108
+ this.unifiedDiffStart = unifiedDiffStart;
109
+ this.unifiedDiffEnd = unifiedDiffEnd;
110
+ this.expansionType = expansionType;
111
+ }
112
+ equals(other) {
113
+ if (this === other) {
114
+ return true;
370
115
  }
371
- // reduce 对于大数组性能很差
372
- // this.rawFile = rawArray.reduce(
373
- // (p, item, index) => ({
374
- // ...p,
375
- // [index + 1]: index < rawArray.length - 1 ? item + "\n" : item,
376
- // }),
377
- // {}
378
- // );
379
- this.hasDoRaw = true;
116
+ return (this.header.equals(other.header) &&
117
+ this.unifiedDiffStart === other.unifiedDiffStart &&
118
+ this.unifiedDiffEnd === other.unifiedDiffEnd &&
119
+ this.expansionType === other.expansionType &&
120
+ this.lines.length === other.lines.length &&
121
+ this.lines.every((xLine, ix) => xLine.equals(other.lines[ix])));
380
122
  }
381
123
  }
382
- _File_instances = new WeakSet(), _File_doCheck = function _File_doCheck() {
383
- if (this.rawLength && this.syntaxLength) {
384
- if (this.rawLength !== this.syntaxLength) {
385
- console.warn("the rawLength not match for the syntaxLength");
386
- }
387
- Object.values(this.syntaxFile).forEach(({ value, lineNumber }) => {
388
- if (value !== this.rawFile[lineNumber]) {
389
- console.log("some line not match:" + value + " __ " + this.rawFile[lineNumber] + " __ at: " + lineNumber + " lineNumber");
390
- }
391
- });
124
+ /** details about the start and end of a diff hunk */
125
+ class DiffHunkHeader {
126
+ /**
127
+ * @param oldStartLine The line in the old (or original) file where this diff hunk starts.
128
+ * @param oldLineCount The number of lines in the old (or original) file that this diff hunk covers
129
+ * @param newStartLine The line in the new file where this diff hunk starts.
130
+ * @param newLineCount The number of lines in the new file that this diff hunk covers.
131
+ */
132
+ constructor(oldStartLine, oldLineCount, newStartLine, newLineCount) {
133
+ this.oldStartLine = oldStartLine;
134
+ this.oldLineCount = oldLineCount;
135
+ this.newStartLine = newStartLine;
136
+ this.newLineCount = newLineCount;
392
137
  }
393
- };
394
- const getFile = (raw, lang, fileName) => {
395
- const key = raw + "--" + "0.0.11" + "--" + lang;
396
- if (map.has(key))
397
- return map.get(key);
398
- const file = new File(raw, lang, fileName);
399
- map.set(key, file);
400
- return file;
401
- };
402
- const _cacheMap = map;
138
+ toDiffLineRepresentation() {
139
+ return `@@ -${this.oldStartLine},${this.oldLineCount} +${this.newStartLine},${this.newLineCount} @@`;
140
+ }
141
+ equals(other) {
142
+ return (this.oldStartLine === other.oldStartLine &&
143
+ this.oldLineCount === other.oldLineCount &&
144
+ this.newStartLine === other.newStartLine &&
145
+ this.oldStartLine === other.oldStartLine);
146
+ }
147
+ }
403
148
 
404
149
  exports.NewLineSymbol = void 0;
405
150
  (function (NewLineSymbol) {
@@ -443,29 +188,19 @@ function relativeChanges(addition, deletion) {
443
188
  const aEndStr = stringA.slice(-2);
444
189
  const bEndStr = stringB.slice(-2);
445
190
  const hasNewLineChanged = addition.noTrailingNewLine !== deletion.noTrailingNewLine;
446
- if (_stringA === _stringB && (hasNewLineChanged || aEndStr !== bEndStr)) {
191
+ const aSymbol = aEndStr === "\r\n" ? exports.NewLineSymbol.CRLF : aEndStr.endsWith("\r") ? exports.NewLineSymbol.CR : exports.NewLineSymbol.LF;
192
+ const bSymbol = bEndStr === "\r\n" ? exports.NewLineSymbol.CRLF : bEndStr.endsWith("\r") ? exports.NewLineSymbol.CR : exports.NewLineSymbol.LF;
193
+ if (_stringA === _stringB && (hasNewLineChanged || aSymbol !== bSymbol)) {
447
194
  return {
448
195
  stringARange: {
449
196
  location: _stringA.length,
450
197
  length: stringA.length - _stringA.length,
451
- newLineSymbol: hasNewLineChanged
452
- ? exports.NewLineSymbol.NEWLINE
453
- : aEndStr === "\r\n"
454
- ? exports.NewLineSymbol.CRLF
455
- : aEndStr.endsWith("\r")
456
- ? exports.NewLineSymbol.CR
457
- : exports.NewLineSymbol.LF,
198
+ newLineSymbol: hasNewLineChanged ? exports.NewLineSymbol.NEWLINE : aSymbol,
458
199
  },
459
200
  stringBRange: {
460
201
  location: _stringB.length,
461
202
  length: stringB.length - _stringB.length,
462
- newLineSymbol: hasNewLineChanged
463
- ? exports.NewLineSymbol.NEWLINE
464
- : bEndStr === "\r\n"
465
- ? exports.NewLineSymbol.CRLF
466
- : bEndStr.endsWith("\r")
467
- ? exports.NewLineSymbol.CR
468
- : exports.NewLineSymbol.LF,
203
+ newLineSymbol: hasNewLineChanged ? exports.NewLineSymbol.NEWLINE : bSymbol,
469
204
  },
470
205
  };
471
206
  }
@@ -527,530 +262,799 @@ class DiffLine {
527
262
  withNoTrailingNewLine(noTrailingNewLine) {
528
263
  return new DiffLine(this.text, this.type, this.originalLineNumber, this.oldLineNumber, this.newLineNumber, noTrailingNewLine);
529
264
  }
530
- isIncludeableLine() {
531
- return this.type === exports.DiffLineType.Add || this.type === exports.DiffLineType.Delete;
265
+ isIncludeableLine() {
266
+ return this.type === exports.DiffLineType.Add || this.type === exports.DiffLineType.Delete;
267
+ }
268
+ /** The content of the line, i.e., without the line type marker. */
269
+ get content() {
270
+ return this.text.substring(1);
271
+ }
272
+ equals(other) {
273
+ return (this.text === other.text &&
274
+ this.type === other.type &&
275
+ this.originalLineNumber === other.originalLineNumber &&
276
+ this.oldLineNumber === other.oldLineNumber &&
277
+ this.newLineNumber === other.newLineNumber &&
278
+ this.noTrailingNewLine === other.noTrailingNewLine);
279
+ }
280
+ clone(text) {
281
+ return new DiffLine(text, this.type, this.originalLineNumber, this.oldLineNumber, this.newLineNumber);
282
+ }
283
+ }
284
+ const checkDiffLineIncludeChange = (diffLine) => {
285
+ if (!diffLine)
286
+ return false;
287
+ return diffLine.type === exports.DiffLineType.Add || diffLine.type === exports.DiffLineType.Delete;
288
+ };
289
+
290
+ /** How many new lines will be added to a diff hunk by default. */
291
+ const DefaultDiffExpansionStep = 40;
292
+ function assertNever(_, message) {
293
+ throw new Error(message);
294
+ }
295
+ /** Utility function for getting the digit count of the largest line number in an array of diff hunks */
296
+ function getLargestLineNumber(hunks) {
297
+ var _a, _b;
298
+ if (hunks.length === 0) {
299
+ return 0;
300
+ }
301
+ for (let i = hunks.length - 1; i >= 0; i--) {
302
+ const hunk = hunks[i];
303
+ for (let j = hunk.lines.length - 1; j >= 0; j--) {
304
+ const line = hunk.lines[j];
305
+ if (line.type === exports.DiffLineType.Hunk) {
306
+ continue;
307
+ }
308
+ const newLineNumber = (_a = line.newLineNumber) !== null && _a !== void 0 ? _a : 0;
309
+ const oldLineNumber = (_b = line.oldLineNumber) !== null && _b !== void 0 ? _b : 0;
310
+ return newLineNumber > oldLineNumber ? newLineNumber : oldLineNumber;
311
+ }
312
+ }
313
+ return 0;
314
+ }
315
+ /**
316
+ * Calculates whether or not a hunk header can be expanded up, down, both, or if
317
+ * the space represented by the hunk header is short and expansion there would
318
+ * mean merging with the hunk above.
319
+ *
320
+ * @param hunkIndex Index of the hunk to evaluate within the whole diff.
321
+ * @param hunkHeader Header of the hunk to evaluate.
322
+ * @param previousHunk Hunk previous to the one to evaluate. Null if the
323
+ * evaluated hunk is the first one.
324
+ */
325
+ function getHunkHeaderExpansionType(hunkIndex, hunkHeader, previousHunk) {
326
+ const distanceToPrevious = previousHunk === null
327
+ ? Infinity
328
+ : hunkHeader.oldStartLine - previousHunk.header.oldStartLine - previousHunk.header.oldLineCount;
329
+ // In order to simplify the whole logic around expansion, only the hunk at the
330
+ // top can be expanded up exclusively, and only the hunk at the bottom (the
331
+ // dummy one, see getTextDiffWithBottomDummyHunk) can be expanded down
332
+ // exclusively.
333
+ // The rest of the hunks can be expanded both ways, except those which are too
334
+ // short and therefore the direction of expansion doesn't matter.
335
+ if (hunkIndex === 0) {
336
+ // The top hunk can only be expanded if there is content above it
337
+ if (hunkHeader.oldStartLine > 1 && hunkHeader.newStartLine > 1) {
338
+ return exports.DiffHunkExpansionType.Up;
339
+ }
340
+ else {
341
+ return exports.DiffHunkExpansionType.None;
342
+ }
343
+ }
344
+ else if (distanceToPrevious <= DefaultDiffExpansionStep) {
345
+ return exports.DiffHunkExpansionType.Short;
346
+ }
347
+ else {
348
+ return exports.DiffHunkExpansionType.Both;
349
+ }
350
+ }
351
+ const numIterator = (num, cb) => {
352
+ const re = [];
353
+ for (let i = 0; i < num; i++) {
354
+ re.push(cb(i));
355
+ }
356
+ return re;
357
+ };
358
+ const getLang = (fileName) => {
359
+ const dotIndex = fileName.lastIndexOf(".");
360
+ const extension = fileName.slice(dotIndex + 1);
361
+ return extension;
362
+ };
363
+ const getDiffRange = (additions, deletions) => {
364
+ if (additions.length === deletions.length) {
365
+ const len = additions.length;
366
+ for (let i = 0; i < len; i++) {
367
+ const addition = additions[i];
368
+ const deletion = deletions[i];
369
+ const hasDiffRange = hasRelativeChange(addition, deletion);
370
+ if (hasDiffRange) {
371
+ const { stringARange, stringBRange } = relativeChanges(addition, deletion);
372
+ addition.needRematch = true;
373
+ addition.range = stringARange;
374
+ deletion.needRematch = true;
375
+ deletion.range = stringBRange;
376
+ }
377
+ }
378
+ }
379
+ };
380
+
381
+ /* eslint-disable max-lines */
382
+ // !NOTE: ALL of the diff parse logic copy from desktop, SEE https://github.com/desktop/desktop
383
+ // https://en.wikipedia.org/wiki/Diff_utility
384
+ //
385
+ // @@ -l,s +l,s @@ optional section heading
386
+ //
387
+ // The hunk range information contains two hunk ranges. The range for the hunk of the original
388
+ // file is preceded by a minus symbol, and the range for the new file is preceded by a plus
389
+ // symbol. Each hunk range is of the format l,s where l is the starting line number and s is
390
+ // the number of lines the change hunk applies to for each respective file.
391
+ //
392
+ // In many versions of GNU diff, each range can omit the comma and trailing value s,
393
+ // in which case s defaults to 1
394
+ const diffHeaderRe = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
395
+ /**
396
+ * Regular expression matching invisible bidirectional Unicode characters that
397
+ * may be interpreted or compiled differently than what it appears. More info:
398
+ * https://github.co/hiddenchars
399
+ */
400
+ const HiddenBidiCharsRegex = /[\u202A-\u202E]|[\u2066-\u2069]/;
401
+ const DiffPrefixAdd = "+";
402
+ const DiffPrefixDelete = "-";
403
+ const DiffPrefixContext = " ";
404
+ const DiffPrefixNoNewline = "\\";
405
+ const DiffLinePrefixChars = new Set([
406
+ DiffPrefixAdd,
407
+ DiffPrefixDelete,
408
+ DiffPrefixContext,
409
+ DiffPrefixNoNewline,
410
+ ]);
411
+ /**
412
+ * A parser for the GNU unified diff format
413
+ *
414
+ * See https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html
415
+ */
416
+ class DiffParser {
417
+ constructor() {
418
+ Object.defineProperty(this, "__v_skip", { value: true });
419
+ this.reset();
420
+ }
421
+ /**
422
+ * Resets the internal parser state so that it can be reused.
423
+ *
424
+ * This is done automatically at the end of each parse run.
425
+ */
426
+ reset() {
427
+ this.ls = 0;
428
+ this.le = -1;
429
+ this.text = "";
430
+ }
431
+ /**
432
+ * Aligns the internal character pointers at the boundaries of
433
+ * the next line.
434
+ *
435
+ * Returns true if successful or false if the end of the diff
436
+ * has been reached.
437
+ */
438
+ nextLine() {
439
+ this.ls = this.le + 1;
440
+ // We've reached the end of the diff
441
+ if (this.ls >= this.text.length) {
442
+ return false;
443
+ }
444
+ this.le = this.text.indexOf("\n", this.ls);
445
+ // If we can't find the next newline character we'll put our
446
+ // end pointer at the end of the diff string
447
+ if (this.le === -1) {
448
+ this.le = this.text.length;
449
+ }
450
+ // We've succeeded if there's anything to read in between the
451
+ // start and the end
452
+ return this.ls !== this.le;
453
+ }
454
+ /**
455
+ * Advances to the next line and returns it as a substring
456
+ * of the raw diff text. Returns null if end of diff was
457
+ * reached.
458
+ */
459
+ readLine(header) {
460
+ if (header) {
461
+ return this.nextLine() ? this.text.substring(this.ls, this.le) : null;
462
+ }
463
+ else {
464
+ return this.nextLine() ? this.text.substring(this.ls + 1, this.le + 1) : null;
465
+ }
466
+ }
467
+ /** Tests if the current line starts with the given search text */
468
+ lineStartsWith(searchString) {
469
+ return this.text.startsWith(searchString, this.ls);
532
470
  }
533
- /** The content of the line, i.e., without the line type marker. */
534
- get content() {
535
- return this.text.substring(1);
471
+ /** Tests if the current line ends with the given search text */
472
+ lineEndsWith(searchString) {
473
+ return this.text.endsWith(searchString, this.le);
536
474
  }
537
- equals(other) {
538
- return (this.text === other.text &&
539
- this.type === other.type &&
540
- this.originalLineNumber === other.originalLineNumber &&
541
- this.oldLineNumber === other.oldLineNumber &&
542
- this.newLineNumber === other.newLineNumber &&
543
- this.noTrailingNewLine === other.noTrailingNewLine);
475
+ /**
476
+ * Returns the starting character of the next line without
477
+ * advancing the internal state. Returns null if advancing
478
+ * would mean reaching the end of the diff.
479
+ */
480
+ peek() {
481
+ const p = this.le + 1;
482
+ return p < this.text.length ? this.text[p] : null;
544
483
  }
545
- clone(text) {
546
- return new DiffLine(text, this.type, this.originalLineNumber, this.oldLineNumber, this.newLineNumber);
484
+ /**
485
+ * Parse the diff header, meaning everything from the
486
+ * start of the diff output to the end of the line beginning
487
+ * with +++
488
+ *
489
+ * Example diff header:
490
+ *
491
+ * diff --git a/app/src/lib/diff-parser.ts b/app/src/lib/diff-parser.ts
492
+ * index e1d4871..3bd3ee0 100644
493
+ * --- a/app/src/lib/diff-parser.ts
494
+ * +++ b/app/src/lib/diff-parser.ts
495
+ *
496
+ * Returns an object with information extracted from the diff
497
+ * header (currently whether it's a binary patch) or null if
498
+ * the end of the diff was reached before the +++ line could be
499
+ * found (which is a valid state).
500
+ */
501
+ parseDiffHeader() {
502
+ // TODO: There's information in here that we might want to
503
+ // capture, such as mode changes
504
+ while (this.nextLine()) {
505
+ if (this.lineStartsWith("Binary files ") && this.lineEndsWith("differ")) {
506
+ return { isBinary: true };
507
+ }
508
+ if (this.lineStartsWith("+++")) {
509
+ return { isBinary: false };
510
+ }
511
+ }
512
+ // It's not an error to not find the +++ line, see the
513
+ // 'parses diff of empty file' test in diff-parser-tests.ts
514
+ return null;
547
515
  }
548
- }
549
- const checkDiffLineIncludeChange = (diffLine) => {
550
- if (!diffLine)
551
- return false;
552
- return diffLine.type === exports.DiffLineType.Add || diffLine.type === exports.DiffLineType.Delete;
553
- };
554
-
555
- var DiffHunkExpansionType;
556
- (function (DiffHunkExpansionType) {
557
- /** The hunk header cannot be expanded at all. */
558
- DiffHunkExpansionType["None"] = "None";
559
516
  /**
560
- * The hunk header can be expanded up exclusively. Only the first hunk can be
561
- * expanded up exclusively.
517
+ * Attempts to convert a RegExp capture group into a number.
518
+ * If the group doesn't exist or wasn't captured the function
519
+ * will return the value of the defaultValue parameter or throw
520
+ * an error if no default value was provided. If the captured
521
+ * string can't be converted to a number an error will be thrown.
562
522
  */
563
- DiffHunkExpansionType["Up"] = "Up";
523
+ numberFromGroup(m, group, defaultValue = null) {
524
+ const str = m[group];
525
+ if (!str) {
526
+ if (!defaultValue) {
527
+ throw new Error(`Group ${group} missing from regexp match and no defaultValue was provided`);
528
+ }
529
+ return defaultValue;
530
+ }
531
+ const num = parseInt(str, 10);
532
+ if (isNaN(num)) {
533
+ throw new Error(`Could not parse capture group ${group} into number: ${str}`);
534
+ }
535
+ return num;
536
+ }
564
537
  /**
565
- * The hunk header can be expanded down exclusively. Only the last hunk (if
566
- * it's the dummy hunk with only one line) can be expanded down exclusively.
538
+ * Parses a hunk header or throws an error if the given line isn't
539
+ * a well-formed hunk header.
540
+ *
541
+ * We currently only extract the line number information and
542
+ * ignore any hunk headings.
543
+ *
544
+ * Example hunk header (text within ``):
545
+ *
546
+ * `@@ -84,10 +82,8 @@ export function parseRawDiff(lines: ReadonlyArray<string>): Diff {`
547
+ *
548
+ * Where everything after the last @@ is what's known as the hunk, or section, heading
567
549
  */
568
- DiffHunkExpansionType["Down"] = "Down";
569
- /** The hunk header can be expanded both up and down. */
570
- DiffHunkExpansionType["Both"] = "Both";
550
+ parseHunkHeader(line) {
551
+ const m = diffHeaderRe.exec(line);
552
+ if (!m) {
553
+ throw new Error(`Invalid hunk header format`);
554
+ }
555
+ // If endLines are missing default to 1, see diffHeaderRe docs
556
+ const oldStartLine = this.numberFromGroup(m, 1);
557
+ const oldLineCount = this.numberFromGroup(m, 2, 1);
558
+ const newStartLine = this.numberFromGroup(m, 3);
559
+ const newLineCount = this.numberFromGroup(m, 4, 1);
560
+ return new DiffHunkHeader(oldStartLine, oldLineCount, newStartLine, newLineCount);
561
+ }
571
562
  /**
572
- * The hunk header represents a short gap that, when expanded, will
573
- * result in merging this hunk and the hunk above.
563
+ * Convenience function which lets us leverage the type system to
564
+ * prove exhaustive checks in parseHunk.
565
+ *
566
+ * Takes an arbitrary string and checks to see if the first character
567
+ * of that string is one of the allowed prefix characters for diff
568
+ * lines (ie lines in between hunk headers).
574
569
  */
575
- DiffHunkExpansionType["Short"] = "Short";
576
- })(DiffHunkExpansionType || (DiffHunkExpansionType = {}));
577
- /** each diff is made up of a number of hunks */
578
- class DiffHunk {
570
+ parseLinePrefix(c) {
571
+ // Since we know that DiffLinePrefixChars and the DiffLinePrefix type
572
+ // include the same characters we can tell the type system that we
573
+ // now know that c[0] is one of the characters in the DifflinePrefix set
574
+ if (c && c.length && DiffLinePrefixChars.has(c[0])) {
575
+ return c[0];
576
+ }
577
+ return null;
578
+ }
579
579
  /**
580
- * @param header The details from the diff hunk header about the line start and patch length.
581
- * @param lines The contents - context and changes - of the diff section.
582
- * @param unifiedDiffStart The diff hunk's start position in the overall file diff.
583
- * @param unifiedDiffEnd The diff hunk's end position in the overall file diff.
580
+ * Parses a hunk, including its header or throws an error if the diff doesn't
581
+ * contain a well-formed diff hunk at the current position.
582
+ *
583
+ * Expects that the position has been advanced to the beginning of a presumed
584
+ * diff hunk header.
585
+ *
586
+ * @param linesConsumed The number of unified diff lines consumed up until
587
+ * this point by the diff parser. Used to give the
588
+ * position and length (in lines) of the parsed hunk
589
+ * relative to the overall parsed diff. These numbers
590
+ * have no real meaning in the context of a diff and
591
+ * are only used to aid the app in line-selections.
584
592
  */
585
- constructor(header, lines, unifiedDiffStart, unifiedDiffEnd, expansionType) {
586
- this.header = header;
587
- this.lines = lines;
588
- this.unifiedDiffStart = unifiedDiffStart;
589
- this.unifiedDiffEnd = unifiedDiffEnd;
590
- this.expansionType = expansionType;
593
+ parseHunk(linesConsumed, hunkIndex, previousHunk) {
594
+ const headerLine = this.readLine(true);
595
+ if (!headerLine) {
596
+ throw new Error("Expected hunk header but reached end of diff");
597
+ }
598
+ const header = this.parseHunkHeader(headerLine);
599
+ const lines = new Array();
600
+ lines.push(new DiffLine(headerLine, exports.DiffLineType.Hunk, 1, null, null));
601
+ let c;
602
+ let rollingDiffBeforeCounter = header.oldStartLine;
603
+ let rollingDiffAfterCounter = header.newStartLine;
604
+ let diffLineNumber = linesConsumed;
605
+ while ((c = this.parseLinePrefix(this.peek()))) {
606
+ const line = this.readLine(false);
607
+ diffLineNumber++;
608
+ if (!line) {
609
+ throw new Error("Expected unified diff line but reached end of diff");
610
+ }
611
+ // A marker indicating that the last line in the original or the new file
612
+ // is missing a trailing newline. In other words, the presence of this marker
613
+ // means that the new and/or original file lacks a trailing newline.
614
+ //
615
+ // When we find it we have to look up the previous line and set the
616
+ // noTrailingNewLine flag
617
+ if (c === DiffPrefixNoNewline) {
618
+ // See https://github.com/git/git/blob/21f862b498925194f8f1ebe8203b7a7df756555b/apply.c#L1725-L1732
619
+ if (line.length < 12) {
620
+ throw new Error(`Expected "no newline at end of file" marker to be at least 12 bytes long`);
621
+ }
622
+ const previousLineIndex = lines.length - 1;
623
+ const previousLine = lines[previousLineIndex];
624
+ lines[previousLineIndex] = previousLine.withNoTrailingNewLine(true);
625
+ continue;
626
+ }
627
+ let diffLine;
628
+ if (c === DiffPrefixAdd) {
629
+ diffLine = new DiffLine(line, exports.DiffLineType.Add, diffLineNumber, null, rollingDiffAfterCounter++);
630
+ }
631
+ else if (c === DiffPrefixDelete) {
632
+ diffLine = new DiffLine(line, exports.DiffLineType.Delete, diffLineNumber, rollingDiffBeforeCounter++, null);
633
+ }
634
+ else if (c === DiffPrefixContext) {
635
+ diffLine = new DiffLine(line, exports.DiffLineType.Context, diffLineNumber, rollingDiffBeforeCounter++, rollingDiffAfterCounter++);
636
+ }
637
+ else {
638
+ return assertNever(c, `Unknown DiffLinePrefix: ${c}`);
639
+ }
640
+ lines.push(diffLine);
641
+ }
642
+ if (lines.length === 1) {
643
+ throw new Error("Malformed diff, empty hunk");
644
+ }
645
+ return new DiffHunk(header, lines, linesConsumed, linesConsumed + lines.length - 1, getHunkHeaderExpansionType(hunkIndex, header, previousHunk));
591
646
  }
592
- equals(other) {
593
- if (this === other) {
594
- return true;
647
+ /**
648
+ * Parse a well-formed unified diff into hunks and lines.
649
+ *
650
+ * @param text A unified diff produced by git diff, git log --patch
651
+ * or any other git plumbing command that produces unified
652
+ * diffs.
653
+ */
654
+ parse(text) {
655
+ this.text = text;
656
+ try {
657
+ const headerInfo = this.parseDiffHeader();
658
+ const headerEnd = this.le;
659
+ const header = this.text.substring(0, headerEnd);
660
+ // empty diff
661
+ if (!headerInfo) {
662
+ return {
663
+ header,
664
+ contents: "",
665
+ hunks: [],
666
+ isBinary: false,
667
+ maxLineNumber: 0,
668
+ hasHiddenBidiChars: false,
669
+ };
670
+ }
671
+ if (headerInfo.isBinary) {
672
+ return {
673
+ header,
674
+ contents: "",
675
+ hunks: [],
676
+ isBinary: true,
677
+ maxLineNumber: 0,
678
+ hasHiddenBidiChars: false,
679
+ };
680
+ }
681
+ const hunks = new Array();
682
+ let linesConsumed = 0;
683
+ let previousHunk = null;
684
+ do {
685
+ const hunk = this.parseHunk(linesConsumed, hunks.length, previousHunk);
686
+ hunks.push(hunk);
687
+ previousHunk = hunk;
688
+ linesConsumed += hunk.lines.length;
689
+ } while (this.peek());
690
+ const contents = this.text
691
+ .substring(headerEnd + 1, this.le)
692
+ // Note that this simply returns a reference to the
693
+ // substring if no match is found, it does not create
694
+ // a new string instance.
695
+ .replace(/\n\/g, "");
696
+ return {
697
+ header,
698
+ contents,
699
+ hunks,
700
+ isBinary: headerInfo.isBinary,
701
+ maxLineNumber: getLargestLineNumber(hunks),
702
+ hasHiddenBidiChars: HiddenBidiCharsRegex.test(text),
703
+ };
704
+ }
705
+ finally {
706
+ this.reset();
595
707
  }
596
- return (this.header.equals(other.header) &&
597
- this.unifiedDiffStart === other.unifiedDiffStart &&
598
- this.unifiedDiffEnd === other.unifiedDiffEnd &&
599
- this.expansionType === other.expansionType &&
600
- this.lines.length === other.lines.length &&
601
- this.lines.every((xLine, ix) => xLine.equals(other.lines[ix])));
602
- }
603
- }
604
- /** details about the start and end of a diff hunk */
605
- class DiffHunkHeader {
606
- /**
607
- * @param oldStartLine The line in the old (or original) file where this diff hunk starts.
608
- * @param oldLineCount The number of lines in the old (or original) file that this diff hunk covers
609
- * @param newStartLine The line in the new file where this diff hunk starts.
610
- * @param newLineCount The number of lines in the new file that this diff hunk covers.
611
- */
612
- constructor(oldStartLine, oldLineCount, newStartLine, newLineCount) {
613
- this.oldStartLine = oldStartLine;
614
- this.oldLineCount = oldLineCount;
615
- this.newStartLine = newStartLine;
616
- this.newLineCount = newLineCount;
617
- }
618
- toDiffLineRepresentation() {
619
- return `@@ -${this.oldStartLine},${this.oldLineCount} +${this.newStartLine},${this.newLineCount} @@`;
620
- }
621
- equals(other) {
622
- return (this.oldStartLine === other.oldStartLine &&
623
- this.oldLineCount === other.oldLineCount &&
624
- this.newStartLine === other.newStartLine &&
625
- this.oldStartLine === other.oldStartLine);
626
708
  }
627
709
  }
710
+ const parseInstance = new DiffParser();
628
711
 
629
- /** How many new lines will be added to a diff hunk by default. */
630
- const DefaultDiffExpansionStep = 20;
631
- function assertNever(_, message) {
632
- throw new Error(message);
633
- }
634
- /** Utility function for getting the digit count of the largest line number in an array of diff hunks */
635
- function getLargestLineNumber(hunks) {
636
- var _a, _b;
637
- if (hunks.length === 0) {
638
- return 0;
639
- }
640
- for (let i = hunks.length - 1; i >= 0; i--) {
641
- const hunk = hunks[i];
642
- for (let j = hunk.lines.length - 1; j >= 0; j--) {
643
- const line = hunk.lines[j];
644
- if (line.type === exports.DiffLineType.Hunk) {
645
- continue;
712
+ /******************************************************************************
713
+ Copyright (c) Microsoft Corporation.
714
+
715
+ Permission to use, copy, modify, and/or distribute this software for any
716
+ purpose with or without fee is hereby granted.
717
+
718
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
719
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
720
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
721
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
722
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
723
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
724
+ PERFORMANCE OF THIS SOFTWARE.
725
+ ***************************************************************************** */
726
+ /* global Reflect, Promise, SuppressedError, Symbol */
727
+
728
+
729
+ function __classPrivateFieldGet(receiver, state, kind, f) {
730
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
731
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
732
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
733
+ }
734
+
735
+ function __classPrivateFieldSet(receiver, state, value, kind, f) {
736
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
737
+ return (state.set(receiver, value)), value;
738
+ }
739
+
740
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
741
+ var e = new Error(message);
742
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
743
+ };
744
+
745
+ const processAST = (ast) => {
746
+ let lineNumber = 1;
747
+ const syntaxObj = {};
748
+ const loopAST = (nodes, wrapper) => {
749
+ nodes.forEach((node) => {
750
+ if (node.type === "text") {
751
+ if (node.value.indexOf("\n") === -1) {
752
+ const valueLength = node.value.length;
753
+ if (!syntaxObj[lineNumber]) {
754
+ node.startIndex = 0;
755
+ node.endIndex = valueLength - 1;
756
+ const item = {
757
+ value: node.value,
758
+ lineNumber,
759
+ valueLength,
760
+ nodeList: [{ node, wrapper }],
761
+ };
762
+ syntaxObj[lineNumber] = item;
763
+ }
764
+ else {
765
+ node.startIndex = syntaxObj[lineNumber].valueLength;
766
+ node.endIndex = node.startIndex + valueLength - 1;
767
+ syntaxObj[lineNumber].value += node.value;
768
+ syntaxObj[lineNumber].valueLength += valueLength;
769
+ syntaxObj[lineNumber].nodeList.push({ node, wrapper });
770
+ }
771
+ node.lineNumber = lineNumber;
772
+ return;
773
+ }
774
+ const lines = node.value.split("\n");
775
+ node.children = node.children || [];
776
+ for (let i = 0; i < lines.length; i++) {
777
+ const _value = i === lines.length - 1 ? lines[i] : lines[i] + "\n";
778
+ const _lineNumber = i === 0 ? lineNumber : ++lineNumber;
779
+ const _valueLength = _value.length;
780
+ const _node = {
781
+ type: "text",
782
+ value: _value,
783
+ startIndex: Infinity,
784
+ endIndex: Infinity,
785
+ lineNumber: _lineNumber,
786
+ };
787
+ if (!syntaxObj[_lineNumber]) {
788
+ _node.startIndex = 0;
789
+ _node.endIndex = _valueLength - 1;
790
+ const item = {
791
+ value: _value,
792
+ lineNumber: _lineNumber,
793
+ valueLength: _valueLength,
794
+ nodeList: [{ node: _node, wrapper }],
795
+ };
796
+ syntaxObj[_lineNumber] = item;
797
+ }
798
+ else {
799
+ _node.startIndex = syntaxObj[_lineNumber].valueLength;
800
+ _node.endIndex = _node.startIndex + _valueLength - 1;
801
+ syntaxObj[_lineNumber].value += _value;
802
+ syntaxObj[_lineNumber].valueLength += _valueLength;
803
+ syntaxObj[_lineNumber].nodeList.push({ node: _node, wrapper });
804
+ }
805
+ node.children.push(_node);
806
+ }
807
+ node.lineNumber = lineNumber;
808
+ return;
646
809
  }
647
- const newLineNumber = (_a = line.newLineNumber) !== null && _a !== void 0 ? _a : 0;
648
- const oldLineNumber = (_b = line.oldLineNumber) !== null && _b !== void 0 ? _b : 0;
649
- return newLineNumber > oldLineNumber ? newLineNumber : oldLineNumber;
810
+ if (node.children) {
811
+ loopAST(node.children, node);
812
+ node.lineNumber = lineNumber;
813
+ }
814
+ });
815
+ };
816
+ loopAST(ast.children);
817
+ return { syntaxFileObject: syntaxObj, syntaxFileLineNumber: lineNumber };
818
+ };
819
+
820
+ const lowlight = lowlight$1.createLowlight(lowlight$1.all);
821
+ // !SEE https://github.com/highlightjs/highlightjs-vue
822
+ lowlight.register("vue", function hljsDefineVue(hljs) {
823
+ return {
824
+ subLanguage: "xml",
825
+ contains: [
826
+ hljs.COMMENT("<!--", "-->", {
827
+ relevance: 10,
828
+ }),
829
+ {
830
+ begin: /^(\s*)(<script>)/gm,
831
+ end: /^(\s*)(<\/script>)/gm,
832
+ subLanguage: "javascript",
833
+ excludeBegin: true,
834
+ excludeEnd: true,
835
+ },
836
+ {
837
+ begin: /^(?:\s*)(?:<script\s+lang=(["'])ts\1>)/gm,
838
+ end: /^(\s*)(<\/script>)/gm,
839
+ subLanguage: "typescript",
840
+ excludeBegin: true,
841
+ excludeEnd: true,
842
+ },
843
+ {
844
+ begin: /^(\s*)(<style(\s+scoped)?>)/gm,
845
+ end: /^(\s*)(<\/style>)/gm,
846
+ subLanguage: "css",
847
+ excludeBegin: true,
848
+ excludeEnd: true,
849
+ },
850
+ {
851
+ begin: /^(?:\s*)(?:<style(?:\s+scoped)?\s+lang=(["'])(?:s[ca]ss)\1(?:\s+scoped)?>)/gm,
852
+ end: /^(\s*)(<\/style>)/gm,
853
+ subLanguage: "scss",
854
+ excludeBegin: true,
855
+ excludeEnd: true,
856
+ },
857
+ {
858
+ begin: /^(?:\s*)(?:<style(?:\s+scoped)?\s+lang=(["'])stylus\1(?:\s+scoped)?>)/gm,
859
+ end: /^(\s*)(<\/style>)/gm,
860
+ subLanguage: "stylus",
861
+ excludeBegin: true,
862
+ excludeEnd: true,
863
+ },
864
+ ],
865
+ };
866
+ });
867
+ const instance = { name: "lowlight" };
868
+ let _maxLineToIgnoreSyntax = 2000;
869
+ const _ignoreSyntaxHighlightList = [];
870
+ Object.defineProperty(instance, "maxLineToIgnoreSyntax", {
871
+ get: () => _maxLineToIgnoreSyntax,
872
+ });
873
+ Object.defineProperty(instance, "setMaxLineToIgnoreSyntax", {
874
+ value: (v) => {
875
+ _maxLineToIgnoreSyntax = v;
876
+ },
877
+ });
878
+ Object.defineProperty(instance, "ignoreSyntaxHighlightList", {
879
+ get: () => _ignoreSyntaxHighlightList,
880
+ });
881
+ Object.defineProperty(instance, "setIgnoreSyntaxHighlightList", {
882
+ value: (v) => {
883
+ _ignoreSyntaxHighlightList.length = 0;
884
+ _ignoreSyntaxHighlightList.push(...v);
885
+ },
886
+ });
887
+ Object.defineProperty(instance, "getAST", {
888
+ value: (raw, fileName, lang) => {
889
+ let hasRegisteredLang = true;
890
+ if (!lowlight.registered(lang)) {
891
+ console.warn(`not support current lang: ${lang} yet`);
892
+ hasRegisteredLang = false;
893
+ }
894
+ if (fileName &&
895
+ highlighter.ignoreSyntaxHighlightList.some((item) => item instanceof RegExp ? item.test(fileName) : fileName === item)) {
896
+ console.warn(`ignore syntax for current file, because the fileName is in the ignoreSyntaxHighlightList: ${fileName}`);
897
+ return;
650
898
  }
651
- }
652
- return 0;
653
- }
654
- /**
655
- * Calculates whether or not a hunk header can be expanded up, down, both, or if
656
- * the space represented by the hunk header is short and expansion there would
657
- * mean merging with the hunk above.
658
- *
659
- * @param hunkIndex Index of the hunk to evaluate within the whole diff.
660
- * @param hunkHeader Header of the hunk to evaluate.
661
- * @param previousHunk Hunk previous to the one to evaluate. Null if the
662
- * evaluated hunk is the first one.
663
- */
664
- function getHunkHeaderExpansionType(hunkIndex, hunkHeader, previousHunk) {
665
- const distanceToPrevious = previousHunk === null
666
- ? Infinity
667
- : hunkHeader.oldStartLine - previousHunk.header.oldStartLine - previousHunk.header.oldLineCount;
668
- // In order to simplify the whole logic around expansion, only the hunk at the
669
- // top can be expanded up exclusively, and only the hunk at the bottom (the
670
- // dummy one, see getTextDiffWithBottomDummyHunk) can be expanded down
671
- // exclusively.
672
- // The rest of the hunks can be expanded both ways, except those which are too
673
- // short and therefore the direction of expansion doesn't matter.
674
- if (hunkIndex === 0) {
675
- // The top hunk can only be expanded if there is content above it
676
- if (hunkHeader.oldStartLine > 1 && hunkHeader.newStartLine > 1) {
677
- return DiffHunkExpansionType.Up;
899
+ if (hasRegisteredLang) {
900
+ return lowlight.highlight(lang, raw);
678
901
  }
679
902
  else {
680
- return DiffHunkExpansionType.None;
681
- }
682
- }
683
- else if (distanceToPrevious <= DefaultDiffExpansionStep) {
684
- return DiffHunkExpansionType.Short;
685
- }
686
- else {
687
- return DiffHunkExpansionType.Both;
688
- }
689
- }
690
- const numIterator = (num, cb) => {
691
- const re = [];
692
- for (let i = 0; i < num; i++) {
693
- re.push(cb(i));
694
- }
695
- return re;
696
- };
697
- const getLang = (fileName) => {
698
- const dotIndex = fileName.lastIndexOf(".");
699
- const extension = fileName.slice(dotIndex + 1);
700
- return extension;
701
- };
702
- const getDiffRange = (additions, deletions) => {
703
- if (additions.length === deletions.length) {
704
- const len = additions.length;
705
- for (let i = 0; i < len; i++) {
706
- const addition = additions[i];
707
- const deletion = deletions[i];
708
- const hasDiffRange = hasRelativeChange(addition, deletion);
709
- if (hasDiffRange) {
710
- const { stringARange, stringBRange } = relativeChanges(addition, deletion);
711
- addition.needRematch = true;
712
- addition.range = stringARange;
713
- deletion.needRematch = true;
714
- deletion.range = stringBRange;
715
- }
903
+ return lowlight.highlightAuto(raw);
716
904
  }
717
- }
718
- };
905
+ },
906
+ });
907
+ Object.defineProperty(instance, "processAST", {
908
+ value: (ast) => {
909
+ return processAST(ast);
910
+ },
911
+ });
912
+ Object.defineProperty(instance, "hasRegisteredCurrentLang", {
913
+ value: (lang) => {
914
+ return lowlight.registered(lang);
915
+ },
916
+ });
917
+ const highlighter = instance;
719
918
 
720
- /* eslint-disable max-lines */
721
- // !NOTE: ALL of the diff parse logic copy from desktop, SEE https://github.com/desktop/desktop
722
- // https://en.wikipedia.org/wiki/Diff_utility
723
- //
724
- // @@ -l,s +l,s @@ optional section heading
725
- //
726
- // The hunk range information contains two hunk ranges. The range for the hunk of the original
727
- // file is preceded by a minus symbol, and the range for the new file is preceded by a plus
728
- // symbol. Each hunk range is of the format l,s where l is the starting line number and s is
729
- // the number of lines the change hunk applies to for each respective file.
730
- //
731
- // In many versions of GNU diff, each range can omit the comma and trailing value s,
732
- // in which case s defaults to 1
733
- const diffHeaderRe = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
734
- /**
735
- * Regular expression matching invisible bidirectional Unicode characters that
736
- * may be interpreted or compiled differently than what it appears. More info:
737
- * https://github.co/hiddenchars
738
- */
739
- const HiddenBidiCharsRegex = /[\u202A-\u202E]|[\u2066-\u2069]/;
740
- const DiffPrefixAdd = "+";
741
- const DiffPrefixDelete = "-";
742
- const DiffPrefixContext = " ";
743
- const DiffPrefixNoNewline = "\\";
744
- const DiffLinePrefixChars = new Set([
745
- DiffPrefixAdd,
746
- DiffPrefixDelete,
747
- DiffPrefixContext,
748
- DiffPrefixNoNewline,
749
- ]);
750
- /**
751
- * A parser for the GNU unified diff format
752
- *
753
- * See https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html
754
- */
755
- class DiffParser {
919
+ var _Cache_keyArray, _Cache_maxLength;
920
+ class Cache extends Map {
756
921
  constructor() {
757
- Object.defineProperty(this, "__v_skip", { value: true });
758
- this.reset();
759
- }
760
- /**
761
- * Resets the internal parser state so that it can be reused.
762
- *
763
- * This is done automatically at the end of each parse run.
764
- */
765
- reset() {
766
- this.ls = 0;
767
- this.le = -1;
768
- this.text = "";
769
- }
770
- /**
771
- * Aligns the internal character pointers at the boundaries of
772
- * the next line.
773
- *
774
- * Returns true if successful or false if the end of the diff
775
- * has been reached.
776
- */
777
- nextLine() {
778
- this.ls = this.le + 1;
779
- // We've reached the end of the diff
780
- if (this.ls >= this.text.length) {
781
- return false;
782
- }
783
- this.le = this.text.indexOf("\n", this.ls);
784
- // If we can't find the next newline character we'll put our
785
- // end pointer at the end of the diff string
786
- if (this.le === -1) {
787
- this.le = this.text.length;
788
- }
789
- // We've succeeded if there's anything to read in between the
790
- // start and the end
791
- return this.ls !== this.le;
792
- }
793
- /**
794
- * Advances to the next line and returns it as a substring
795
- * of the raw diff text. Returns null if end of diff was
796
- * reached.
797
- */
798
- readLine(header) {
799
- if (header) {
800
- return this.nextLine() ? this.text.substring(this.ls, this.le) : null;
801
- }
802
- else {
803
- return this.nextLine() ? this.text.substring(this.ls + 1, this.le + 1) : null;
804
- }
805
- }
806
- /** Tests if the current line starts with the given search text */
807
- lineStartsWith(searchString) {
808
- return this.text.startsWith(searchString, this.ls);
809
- }
810
- /** Tests if the current line ends with the given search text */
811
- lineEndsWith(searchString) {
812
- return this.text.endsWith(searchString, this.le);
813
- }
814
- /**
815
- * Returns the starting character of the next line without
816
- * advancing the internal state. Returns null if advancing
817
- * would mean reaching the end of the diff.
818
- */
819
- peek() {
820
- const p = this.le + 1;
821
- return p < this.text.length ? this.text[p] : null;
822
- }
823
- /**
824
- * Parse the diff header, meaning everything from the
825
- * start of the diff output to the end of the line beginning
826
- * with +++
827
- *
828
- * Example diff header:
829
- *
830
- * diff --git a/app/src/lib/diff-parser.ts b/app/src/lib/diff-parser.ts
831
- * index e1d4871..3bd3ee0 100644
832
- * --- a/app/src/lib/diff-parser.ts
833
- * +++ b/app/src/lib/diff-parser.ts
834
- *
835
- * Returns an object with information extracted from the diff
836
- * header (currently whether it's a binary patch) or null if
837
- * the end of the diff was reached before the +++ line could be
838
- * found (which is a valid state).
839
- */
840
- parseDiffHeader() {
841
- // TODO: There's information in here that we might want to
842
- // capture, such as mode changes
843
- while (this.nextLine()) {
844
- if (this.lineStartsWith("Binary files ") && this.lineEndsWith("differ")) {
845
- return { isBinary: true };
846
- }
847
- if (this.lineStartsWith("+++")) {
848
- return { isBinary: false };
849
- }
850
- }
851
- // It's not an error to not find the +++ line, see the
852
- // 'parses diff of empty file' test in diff-parser-tests.ts
853
- return null;
922
+ super(...arguments);
923
+ _Cache_keyArray.set(this, []);
924
+ _Cache_maxLength.set(this, 30);
854
925
  }
855
- /**
856
- * Attempts to convert a RegExp capture group into a number.
857
- * If the group doesn't exist or wasn't captured the function
858
- * will return the value of the defaultValue parameter or throw
859
- * an error if no default value was provided. If the captured
860
- * string can't be converted to a number an error will be thrown.
861
- */
862
- numberFromGroup(m, group, defaultValue = null) {
863
- const str = m[group];
864
- if (!str) {
865
- if (!defaultValue) {
866
- throw new Error(`Group ${group} missing from regexp match and no defaultValue was provided`);
867
- }
868
- return defaultValue;
869
- }
870
- const num = parseInt(str, 10);
871
- if (isNaN(num)) {
872
- throw new Error(`Could not parse capture group ${group} into number: ${str}`);
873
- }
874
- return num;
926
+ setMaxLength(length) {
927
+ __classPrivateFieldSet(this, _Cache_maxLength, length);
928
+ this._checkLength();
875
929
  }
876
- /**
877
- * Parses a hunk header or throws an error if the given line isn't
878
- * a well-formed hunk header.
879
- *
880
- * We currently only extract the line number information and
881
- * ignore any hunk headings.
882
- *
883
- * Example hunk header (text within ``):
884
- *
885
- * `@@ -84,10 +82,8 @@ export function parseRawDiff(lines: ReadonlyArray<string>): Diff {`
886
- *
887
- * Where everything after the last @@ is what's known as the hunk, or section, heading
888
- */
889
- parseHunkHeader(line) {
890
- const m = diffHeaderRe.exec(line);
891
- if (!m) {
892
- throw new Error(`Invalid hunk header format`);
930
+ set(key, value) {
931
+ if (this.has(key))
932
+ return this;
933
+ __classPrivateFieldGet(this, _Cache_keyArray, "f").push(key);
934
+ this._checkLength();
935
+ return super.set(key, value);
936
+ }
937
+ _checkLength() {
938
+ while (__classPrivateFieldGet(this, _Cache_keyArray, "f").length > __classPrivateFieldGet(this, _Cache_maxLength, "f")) {
939
+ const key = __classPrivateFieldGet(this, _Cache_keyArray, "f").shift();
940
+ this.delete(key);
893
941
  }
894
- // If endLines are missing default to 1, see diffHeaderRe docs
895
- const oldStartLine = this.numberFromGroup(m, 1);
896
- const oldLineCount = this.numberFromGroup(m, 2, 1);
897
- const newStartLine = this.numberFromGroup(m, 3);
898
- const newLineCount = this.numberFromGroup(m, 4, 1);
899
- return new DiffHunkHeader(oldStartLine, oldLineCount, newStartLine, newLineCount);
900
942
  }
901
- /**
902
- * Convenience function which lets us leverage the type system to
903
- * prove exhaustive checks in parseHunk.
904
- *
905
- * Takes an arbitrary string and checks to see if the first character
906
- * of that string is one of the allowed prefix characters for diff
907
- * lines (ie lines in between hunk headers).
908
- */
909
- parseLinePrefix(c) {
910
- // Since we know that DiffLinePrefixChars and the DiffLinePrefix type
911
- // include the same characters we can tell the type system that we
912
- // now know that c[0] is one of the characters in the DifflinePrefix set
913
- if (c && c.length && DiffLinePrefixChars.has(c[0])) {
914
- return c[0];
943
+ }
944
+ _Cache_keyArray = new WeakMap(), _Cache_maxLength = new WeakMap();
945
+
946
+ var _File_instances, _File_doCheck;
947
+ const map = new Cache();
948
+ const devKey = "@git-diff-cache";
949
+ map.setMaxLength(50);
950
+ map.name = "@git-diff-view/core";
951
+ if (typeof globalThis !== "undefined") {
952
+ if (Array.isArray(globalThis[devKey])) {
953
+ globalThis[devKey] = globalThis[devKey].filter((i) => i !== map);
954
+ if (globalThis[devKey].length > 0) {
955
+ console.warn("there are multiple instance of @git-diff-view/core in the one environment!");
915
956
  }
916
- return null;
957
+ globalThis[devKey].push(map);
917
958
  }
918
- /**
919
- * Parses a hunk, including its header or throws an error if the diff doesn't
920
- * contain a well-formed diff hunk at the current position.
921
- *
922
- * Expects that the position has been advanced to the beginning of a presumed
923
- * diff hunk header.
924
- *
925
- * @param linesConsumed The number of unified diff lines consumed up until
926
- * this point by the diff parser. Used to give the
927
- * position and length (in lines) of the parsed hunk
928
- * relative to the overall parsed diff. These numbers
929
- * have no real meaning in the context of a diff and
930
- * are only used to aid the app in line-selections.
931
- */
932
- parseHunk(linesConsumed, hunkIndex, previousHunk) {
933
- const headerLine = this.readLine(true);
934
- if (!headerLine) {
935
- throw new Error("Expected hunk header but reached end of diff");
959
+ else {
960
+ globalThis[devKey] = [map];
961
+ }
962
+ }
963
+ class File {
964
+ static createInstance(data) {
965
+ const file = new File(data === null || data === void 0 ? void 0 : data.raw, data === null || data === void 0 ? void 0 : data.lang, data === null || data === void 0 ? void 0 : data.fileName);
966
+ file.ast = data === null || data === void 0 ? void 0 : data.ast;
967
+ file.rawFile = data === null || data === void 0 ? void 0 : data.rawFile;
968
+ file.hasDoRaw = data === null || data === void 0 ? void 0 : data.hasDoRaw;
969
+ file.rawLength = data === null || data === void 0 ? void 0 : data.rawLength;
970
+ file.syntaxFile = data === null || data === void 0 ? void 0 : data.syntaxFile;
971
+ file.hasDoSyntax = data === null || data === void 0 ? void 0 : data.hasDoSyntax;
972
+ file.syntaxLength = data === null || data === void 0 ? void 0 : data.syntaxLength;
973
+ file.highlighterName = data === null || data === void 0 ? void 0 : data.highlighterName;
974
+ file.maxLineNumber = data === null || data === void 0 ? void 0 : data.maxLineNumber;
975
+ return file;
976
+ }
977
+ constructor(raw, lang, fileName) {
978
+ _File_instances.add(this);
979
+ this.raw = raw;
980
+ this.lang = lang;
981
+ this.fileName = fileName;
982
+ this.rawFile = {};
983
+ this.hasDoRaw = false;
984
+ this.syntaxFile = {};
985
+ this.hasDoSyntax = false;
986
+ this.maxLineNumber = 0;
987
+ Object.defineProperty(this, "__v_skip", { value: true });
988
+ }
989
+ doSyntax({ registerHighlighter }) {
990
+ if (!this.raw || this.hasDoSyntax)
991
+ return;
992
+ const _highlighter = registerHighlighter || highlighter;
993
+ if (this.syntaxLength) {
994
+ console.error("current file already doSyntax before!");
995
+ return;
936
996
  }
937
- const header = this.parseHunkHeader(headerLine);
938
- const lines = new Array();
939
- lines.push(new DiffLine(headerLine, exports.DiffLineType.Hunk, 1, null, null));
940
- let c;
941
- let rollingDiffBeforeCounter = header.oldStartLine;
942
- let rollingDiffAfterCounter = header.newStartLine;
943
- let diffLineNumber = linesConsumed;
944
- while ((c = this.parseLinePrefix(this.peek()))) {
945
- const line = this.readLine(false);
946
- diffLineNumber++;
947
- if (!line) {
948
- throw new Error("Expected unified diff line but reached end of diff");
949
- }
950
- // A marker indicating that the last line in the original or the new file
951
- // is missing a trailing newline. In other words, the presence of this marker
952
- // means that the new and/or original file lacks a trailing newline.
953
- //
954
- // When we find it we have to look up the previous line and set the
955
- // noTrailingNewLine flag
956
- if (c === DiffPrefixNoNewline) {
957
- // See https://github.com/git/git/blob/21f862b498925194f8f1ebe8203b7a7df756555b/apply.c#L1725-L1732
958
- if (line.length < 12) {
959
- throw new Error(`Expected "no newline at end of file" marker to be at least 12 bytes long`);
960
- }
961
- const previousLineIndex = lines.length - 1;
962
- const previousLine = lines[previousLineIndex];
963
- lines[previousLineIndex] = previousLine.withNoTrailingNewLine(true);
964
- continue;
965
- }
966
- let diffLine;
967
- if (c === DiffPrefixAdd) {
968
- diffLine = new DiffLine(line, exports.DiffLineType.Add, diffLineNumber, null, rollingDiffAfterCounter++);
969
- }
970
- else if (c === DiffPrefixDelete) {
971
- diffLine = new DiffLine(line, exports.DiffLineType.Delete, diffLineNumber, rollingDiffBeforeCounter++, null);
972
- }
973
- else if (c === DiffPrefixContext) {
974
- diffLine = new DiffLine(line, exports.DiffLineType.Context, diffLineNumber, rollingDiffBeforeCounter++, rollingDiffAfterCounter++);
975
- }
976
- else {
977
- return assertNever(c, `Unknown DiffLinePrefix: ${c}`);
978
- }
979
- lines.push(diffLine);
997
+ if (this.rawLength > _highlighter.maxLineToIgnoreSyntax) {
998
+ console.warn(`ignore syntax for current file, because the rawLength is too long: ${this.rawLength}`);
999
+ return;
980
1000
  }
981
- if (lines.length === 1) {
982
- throw new Error("Malformed diff, empty hunk");
1001
+ this.ast = _highlighter.getAST(this.raw, this.fileName, this.lang);
1002
+ if (!this.ast)
1003
+ return;
1004
+ const { syntaxFileObject, syntaxFileLineNumber } = _highlighter.processAST(this.ast);
1005
+ this.syntaxFile = syntaxFileObject;
1006
+ this.syntaxLength = syntaxFileLineNumber;
1007
+ this.highlighterName = _highlighter.name;
1008
+ {
1009
+ __classPrivateFieldGet(this, _File_instances, "m", _File_doCheck).call(this);
983
1010
  }
984
- return new DiffHunk(header, lines, linesConsumed, linesConsumed + lines.length - 1, getHunkHeaderExpansionType(hunkIndex, header, previousHunk));
1011
+ this.hasDoSyntax = true;
985
1012
  }
986
- /**
987
- * Parse a well-formed unified diff into hunks and lines.
988
- *
989
- * @param text A unified diff produced by git diff, git log --patch
990
- * or any other git plumbing command that produces unified
991
- * diffs.
992
- */
993
- parse(text) {
994
- this.text = text;
995
- try {
996
- const headerInfo = this.parseDiffHeader();
997
- const headerEnd = this.le;
998
- const header = this.text.substring(0, headerEnd);
999
- // empty diff
1000
- if (!headerInfo) {
1001
- return {
1002
- header,
1003
- contents: "",
1004
- hunks: [],
1005
- isBinary: false,
1006
- maxLineNumber: 0,
1007
- hasHiddenBidiChars: false,
1008
- };
1009
- }
1010
- if (headerInfo.isBinary) {
1011
- return {
1012
- header,
1013
- contents: "",
1014
- hunks: [],
1015
- isBinary: true,
1016
- maxLineNumber: 0,
1017
- hasHiddenBidiChars: false,
1018
- };
1019
- }
1020
- const hunks = new Array();
1021
- let linesConsumed = 0;
1022
- let previousHunk = null;
1023
- do {
1024
- const hunk = this.parseHunk(linesConsumed, hunks.length, previousHunk);
1025
- hunks.push(hunk);
1026
- previousHunk = hunk;
1027
- linesConsumed += hunk.lines.length;
1028
- } while (this.peek());
1029
- const contents = this.text
1030
- .substring(headerEnd + 1, this.le)
1031
- // Note that this simply returns a reference to the
1032
- // substring if no match is found, it does not create
1033
- // a new string instance.
1034
- .replace(/\n\/g, "");
1035
- return {
1036
- header,
1037
- contents,
1038
- hunks,
1039
- isBinary: headerInfo.isBinary,
1040
- maxLineNumber: getLargestLineNumber(hunks),
1041
- hasHiddenBidiChars: HiddenBidiCharsRegex.test(text),
1042
- };
1043
- }
1044
- finally {
1045
- this.reset();
1013
+ doRaw() {
1014
+ if (!this.raw || this.hasDoRaw)
1015
+ return;
1016
+ const rawString = this.raw;
1017
+ const rawArray = rawString.split("\n");
1018
+ this.rawLength = rawArray.length;
1019
+ this.maxLineNumber = rawArray.length;
1020
+ this.rawFile = {};
1021
+ for (let i = 0; i < rawArray.length; i++) {
1022
+ this.rawFile[i + 1] = i < rawArray.length - 1 ? rawArray[i] + "\n" : rawArray[i];
1046
1023
  }
1024
+ // reduce 对于大数组性能很差
1025
+ // this.rawFile = rawArray.reduce(
1026
+ // (p, item, index) => ({
1027
+ // ...p,
1028
+ // [index + 1]: index < rawArray.length - 1 ? item + "\n" : item,
1029
+ // }),
1030
+ // {}
1031
+ // );
1032
+ this.hasDoRaw = true;
1047
1033
  }
1048
1034
  }
1049
- const parseInstance = new DiffParser();
1035
+ _File_instances = new WeakSet(), _File_doCheck = function _File_doCheck() {
1036
+ if (this.rawLength && this.syntaxLength) {
1037
+ if (this.rawLength !== this.syntaxLength) {
1038
+ console.warn("the rawLength not match for the syntaxLength");
1039
+ }
1040
+ Object.values(this.syntaxFile).forEach(({ value, lineNumber }) => {
1041
+ if (value !== this.rawFile[lineNumber]) {
1042
+ console.log("some line not match:" + value + " __ " + this.rawFile[lineNumber] + " __ at: " + lineNumber + " lineNumber");
1043
+ }
1044
+ });
1045
+ }
1046
+ };
1047
+ const getFile = (raw, lang, fileName) => {
1048
+ const key = raw + "--" + "0.0.13" + "--" + lang;
1049
+ if (map.has(key))
1050
+ return map.get(key);
1051
+ const file = new File(raw, lang, fileName);
1052
+ map.set(key, file);
1053
+ return file;
1054
+ };
1055
+ const _cacheMap = map;
1050
1056
 
1051
- /* eslint-disable @typescript-eslint/ban-ts-comment */
1052
- /* eslint-disable max-lines */
1053
- var _DiffFile_instances, _DiffFile_oldFileResult, _DiffFile_newFileResult, _DiffFile_diffListResults, _DiffFile_diffLines, _DiffFile_oldFileDiffLines, _DiffFile_newFileDiffLines, _DiffFile_oldFileLines, _DiffFile_newFileLines, _DiffFile_oldFileSyntaxLines, _DiffFile_newFileSyntaxLines, _DiffFile_oldFilePlaceholderLines, _DiffFile_newFilePlaceholderLines, _DiffFile_splitLeftLines, _DiffFile_splitRightLines, _DiffFile_splitHunksLines, _DiffFile_unifiedLines, _DiffFile_unifiedHunksLines, _DiffFile_listeners, _DiffFile_hasInitRaw, _DiffFile_hasInitSyntax, _DiffFile_hasBuildSplit, _DiffFile_hasBuildUnified, _DiffFile_updateCount, _DiffFile_composeByDiff, _DiffFile_highlighterName, _DiffFile_id, _DiffFile_clonedInstance, _DiffFile_doDiff, _DiffFile_doFile, _DiffFile_composeRaw, _DiffFile_composeFile, _DiffFile_composeDiff, _DiffFile_composeSyntax, _DiffFile_getOldDiffLine, _DiffFile_getNewDiffLine, _DiffFile_getOldRawLine, _DiffFile_getNewRawLine;
1057
+ var _DiffFile_instances, _DiffFile_oldFileResult, _DiffFile_newFileResult, _DiffFile_diffListResults, _DiffFile_diffLines, _DiffFile_oldFileDiffLines, _DiffFile_newFileDiffLines, _DiffFile_oldFileLines, _DiffFile_newFileLines, _DiffFile_oldFileSyntaxLines, _DiffFile_newFileSyntaxLines, _DiffFile_oldFilePlaceholderLines, _DiffFile_newFilePlaceholderLines, _DiffFile_splitLeftLines, _DiffFile_splitRightLines, _DiffFile_splitHunksLines, _DiffFile_unifiedLines, _DiffFile_unifiedHunksLines, _DiffFile_listeners, _DiffFile_hasInitRaw, _DiffFile_hasInitSyntax, _DiffFile_hasBuildSplit, _DiffFile_hasBuildUnified, _DiffFile_updateCount, _DiffFile_composeByDiff, _DiffFile_composeByMerge, _DiffFile_composeByFullMerge, _DiffFile_highlighterName, _DiffFile_id, _DiffFile_clonedInstance, _DiffFile_doDiff, _DiffFile_doFile, _DiffFile_composeRaw, _DiffFile_composeFile, _DiffFile_composeDiff, _DiffFile_composeSyntax, _DiffFile_getOldDiffLine, _DiffFile_getNewDiffLine, _DiffFile_getOldRawLine, _DiffFile_getNewRawLine;
1054
1058
  const composeLen = 40;
1055
1059
  const idSet = new Set();
1056
1060
  class DiffFile {
@@ -1058,7 +1062,12 @@ class DiffFile {
1058
1062
  var _a, _b, _c, _d, _e, _f;
1059
1063
  const instance = new DiffFile(((_a = data === null || data === void 0 ? void 0 : data.oldFile) === null || _a === void 0 ? void 0 : _a.fileName) || "", ((_b = data === null || data === void 0 ? void 0 : data.oldFile) === null || _b === void 0 ? void 0 : _b.content) || "", ((_c = data === null || data === void 0 ? void 0 : data.newFile) === null || _c === void 0 ? void 0 : _c.fileName) || "", ((_d = data === null || data === void 0 ? void 0 : data.newFile) === null || _d === void 0 ? void 0 : _d.content) || "", (data === null || data === void 0 ? void 0 : data.hunks) || [], ((_e = data === null || data === void 0 ? void 0 : data.oldFile) === null || _e === void 0 ? void 0 : _e.fileLang) || "", ((_f = data === null || data === void 0 ? void 0 : data.newFile) === null || _f === void 0 ? void 0 : _f.fileLang) || "");
1060
1064
  if (bundle) {
1061
- instance.mergeBundle(bundle);
1065
+ if (bundle.isFullMerge) {
1066
+ instance._mergeFullBundle(bundle);
1067
+ }
1068
+ else {
1069
+ instance.mergeBundle(bundle);
1070
+ }
1062
1071
  }
1063
1072
  return instance;
1064
1073
  }
@@ -1091,8 +1100,10 @@ class DiffFile {
1091
1100
  _DiffFile_hasBuildUnified.set(this, false);
1092
1101
  _DiffFile_updateCount.set(this, 0);
1093
1102
  _DiffFile_composeByDiff.set(this, false);
1103
+ _DiffFile_composeByMerge.set(this, false);
1104
+ _DiffFile_composeByFullMerge.set(this, false);
1094
1105
  _DiffFile_highlighterName.set(this, void 0);
1095
- this._version_ = "0.0.11";
1106
+ this._version_ = "0.0.13";
1096
1107
  this._oldFileContent = "";
1097
1108
  this._oldFileLang = "";
1098
1109
  this._newFileContent = "";
@@ -1100,9 +1111,10 @@ class DiffFile {
1100
1111
  this.diffLineLength = 0;
1101
1112
  this.splitLineLength = 0;
1102
1113
  this.unifiedLineLength = 0;
1103
- this.expandSplitAll = false;
1104
- this.expandUnifiedAll = false;
1105
- this.hasCollapsed = false;
1114
+ this.fileLineLength = 0;
1115
+ this.hasExpandSplitAll = false;
1116
+ this.hasExpandUnifiedAll = false;
1117
+ this.hasSomeLineCollapsed = false;
1106
1118
  _DiffFile_id.set(this, "");
1107
1119
  _DiffFile_clonedInstance.set(this, new Map());
1108
1120
  this.getSplitLeftLine = (index) => {
@@ -1241,13 +1253,13 @@ class DiffFile {
1241
1253
  Object.keys(__classPrivateFieldGet(this, _DiffFile_splitHunksLines, "f") || {}).forEach((key) => {
1242
1254
  this.onSplitHunkExpand("all", +key, false);
1243
1255
  });
1244
- this.expandSplitAll = true;
1256
+ this.hasExpandSplitAll = true;
1245
1257
  }
1246
1258
  else {
1247
1259
  Object.keys(__classPrivateFieldGet(this, _DiffFile_unifiedHunksLines, "f") || {}).forEach((key) => {
1248
1260
  this.onUnifiedHunkExpand("all", +key, false);
1249
1261
  });
1250
- this.expandUnifiedAll = true;
1262
+ this.hasExpandUnifiedAll = true;
1251
1263
  }
1252
1264
  this.notifyAll();
1253
1265
  };
@@ -1279,7 +1291,7 @@ class DiffFile {
1279
1291
  __classPrivateFieldGet(this, _DiffFile_splitHunksLines, "f")[item.splitInfo.endHiddenIndex] = item;
1280
1292
  }
1281
1293
  });
1282
- this.expandSplitAll = false;
1294
+ this.hasExpandSplitAll = false;
1283
1295
  }
1284
1296
  else {
1285
1297
  Object.values(__classPrivateFieldGet(this, _DiffFile_unifiedLines, "f") || {}).forEach((item) => {
@@ -1301,7 +1313,7 @@ class DiffFile {
1301
1313
  __classPrivateFieldGet(this, _DiffFile_unifiedHunksLines, "f")[item.unifiedInfo.endHiddenIndex] = item;
1302
1314
  }
1303
1315
  });
1304
- this.expandUnifiedAll = false;
1316
+ this.hasExpandUnifiedAll = false;
1305
1317
  }
1306
1318
  this.notifyAll();
1307
1319
  };
@@ -1321,7 +1333,7 @@ class DiffFile {
1321
1333
  };
1322
1334
  this.notifyAll = (skipSyncExternal) => {
1323
1335
  var _a;
1324
- __classPrivateFieldSet(this, _DiffFile_updateCount, (_a = __classPrivateFieldGet(this, _DiffFile_updateCount, "f"), _a++, _a), "f");
1336
+ __classPrivateFieldSet(this, _DiffFile_updateCount, (_a = __classPrivateFieldGet(this, _DiffFile_updateCount, "f"), _a++, _a));
1325
1337
  __classPrivateFieldGet(this, _DiffFile_listeners, "f").forEach((f) => {
1326
1338
  if (skipSyncExternal && f.isSyncExternal) {
1327
1339
  return;
@@ -1351,9 +1363,10 @@ class DiffFile {
1351
1363
  const newFilePlaceholderLines = __classPrivateFieldGet(this, _DiffFile_newFilePlaceholderLines, "f");
1352
1364
  const splitLineLength = this.splitLineLength;
1353
1365
  const unifiedLineLength = this.unifiedLineLength;
1366
+ const fileLineLength = this.fileLineLength;
1354
1367
  const composeByDiff = __classPrivateFieldGet(this, _DiffFile_composeByDiff, "f");
1355
1368
  const highlighterName = __classPrivateFieldGet(this, _DiffFile_highlighterName, "f");
1356
- const hasCollapsed = this.hasCollapsed;
1369
+ const hasSomeLineCollapsed = this.hasSomeLineCollapsed;
1357
1370
  // split
1358
1371
  const splitLeftLines = __classPrivateFieldGet(this, _DiffFile_splitLeftLines, "f");
1359
1372
  const splitRightLines = __classPrivateFieldGet(this, _DiffFile_splitRightLines, "f");
@@ -1377,6 +1390,7 @@ class DiffFile {
1377
1390
  newFilePlaceholderLines,
1378
1391
  splitLineLength,
1379
1392
  unifiedLineLength,
1393
+ fileLineLength,
1380
1394
  splitLeftLines,
1381
1395
  splitRightLines,
1382
1396
  splitHunkLines,
@@ -1384,33 +1398,37 @@ class DiffFile {
1384
1398
  unifiedHunkLines,
1385
1399
  highlighterName,
1386
1400
  composeByDiff,
1387
- hasCollapsed,
1401
+ hasSomeLineCollapsed,
1388
1402
  version,
1403
+ isFullMerge: false,
1389
1404
  };
1390
1405
  };
1391
1406
  this.mergeBundle = (data) => {
1392
- __classPrivateFieldSet(this, _DiffFile_hasInitRaw, data.hasInitRaw, "f");
1393
- __classPrivateFieldSet(this, _DiffFile_hasInitSyntax, data.hasInitSyntax, "f");
1394
- __classPrivateFieldSet(this, _DiffFile_hasBuildSplit, data.hasBuildSplit, "f");
1395
- __classPrivateFieldSet(this, _DiffFile_hasBuildUnified, data.hasBuildUnified, "f");
1396
- __classPrivateFieldSet(this, _DiffFile_composeByDiff, data.composeByDiff, "f");
1397
- __classPrivateFieldSet(this, _DiffFile_highlighterName, data.highlighterName, "f");
1398
- __classPrivateFieldSet(this, _DiffFile_oldFileLines, data.oldFileLines, "f");
1399
- __classPrivateFieldSet(this, _DiffFile_oldFileDiffLines, data.oldFileDiffLines, "f");
1400
- __classPrivateFieldSet(this, _DiffFile_oldFileSyntaxLines, data.oldFileSyntaxLines, "f");
1401
- __classPrivateFieldSet(this, _DiffFile_oldFilePlaceholderLines, data.oldFilePlaceholderLines, "f");
1402
- __classPrivateFieldSet(this, _DiffFile_newFileLines, data.newFileLines, "f");
1403
- __classPrivateFieldSet(this, _DiffFile_newFileDiffLines, data.newFileDiffLines, "f");
1404
- __classPrivateFieldSet(this, _DiffFile_newFileSyntaxLines, data.newFileSyntaxLines, "f");
1405
- __classPrivateFieldSet(this, _DiffFile_newFilePlaceholderLines, data.newFilePlaceholderLines, "f");
1407
+ __classPrivateFieldSet(this, _DiffFile_hasInitRaw, data.hasInitRaw);
1408
+ __classPrivateFieldSet(this, _DiffFile_hasInitSyntax, data.hasInitSyntax);
1409
+ __classPrivateFieldSet(this, _DiffFile_hasBuildSplit, data.hasBuildSplit);
1410
+ __classPrivateFieldSet(this, _DiffFile_hasBuildUnified, data.hasBuildUnified);
1411
+ __classPrivateFieldSet(this, _DiffFile_composeByDiff, data.composeByDiff);
1412
+ __classPrivateFieldSet(this, _DiffFile_highlighterName, data.highlighterName);
1413
+ __classPrivateFieldSet(this, _DiffFile_oldFileLines, data.oldFileLines);
1414
+ __classPrivateFieldSet(this, _DiffFile_oldFileDiffLines, data.oldFileDiffLines);
1415
+ __classPrivateFieldSet(this, _DiffFile_oldFileSyntaxLines, data.oldFileSyntaxLines);
1416
+ __classPrivateFieldSet(this, _DiffFile_oldFilePlaceholderLines, data.oldFilePlaceholderLines);
1417
+ __classPrivateFieldSet(this, _DiffFile_newFileLines, data.newFileLines);
1418
+ __classPrivateFieldSet(this, _DiffFile_newFileDiffLines, data.newFileDiffLines);
1419
+ __classPrivateFieldSet(this, _DiffFile_newFileSyntaxLines, data.newFileSyntaxLines);
1420
+ __classPrivateFieldSet(this, _DiffFile_newFilePlaceholderLines, data.newFilePlaceholderLines);
1406
1421
  this.splitLineLength = data.splitLineLength;
1407
1422
  this.unifiedLineLength = data.unifiedLineLength;
1408
- this.hasCollapsed = data.hasCollapsed;
1409
- __classPrivateFieldSet(this, _DiffFile_splitLeftLines, data.splitLeftLines, "f");
1410
- __classPrivateFieldSet(this, _DiffFile_splitRightLines, data.splitRightLines, "f");
1411
- __classPrivateFieldSet(this, _DiffFile_splitHunksLines, data.splitHunkLines, "f");
1412
- __classPrivateFieldSet(this, _DiffFile_unifiedLines, data.unifiedLines, "f");
1413
- __classPrivateFieldSet(this, _DiffFile_unifiedHunksLines, data.unifiedHunkLines, "f");
1423
+ this.fileLineLength = data.fileLineLength;
1424
+ this.hasSomeLineCollapsed = data.hasSomeLineCollapsed;
1425
+ __classPrivateFieldSet(this, _DiffFile_splitLeftLines, data.splitLeftLines);
1426
+ __classPrivateFieldSet(this, _DiffFile_splitRightLines, data.splitRightLines);
1427
+ __classPrivateFieldSet(this, _DiffFile_splitHunksLines, data.splitHunkLines);
1428
+ __classPrivateFieldSet(this, _DiffFile_unifiedLines, data.unifiedLines);
1429
+ __classPrivateFieldSet(this, _DiffFile_unifiedHunksLines, data.unifiedHunkLines);
1430
+ // mark this instance as a merged instance
1431
+ __classPrivateFieldSet(this, _DiffFile_composeByMerge, true);
1414
1432
  if (this._version_ !== data.version) {
1415
1433
  console.error("the version of the `diffInstance` is not match, some error may happen!");
1416
1434
  }
@@ -1447,14 +1465,21 @@ class DiffFile {
1447
1465
  return Object.assign(Object.assign({}, bundle), { oldFileResult,
1448
1466
  newFileResult,
1449
1467
  diffLines,
1450
- diffListResults });
1468
+ diffListResults,
1469
+ // get current instance is a fullMerge instance or not
1470
+ isFullMerge: __classPrivateFieldGet(this, _DiffFile_composeByMerge, "f") ? __classPrivateFieldGet(this, _DiffFile_composeByFullMerge, "f") : true });
1451
1471
  };
1452
1472
  this._mergeFullBundle = (data) => {
1453
1473
  this.mergeBundle(data);
1454
- __classPrivateFieldSet(this, _DiffFile_oldFileResult, data.oldFileResult, "f");
1455
- __classPrivateFieldSet(this, _DiffFile_newFileResult, data.newFileResult, "f");
1456
- __classPrivateFieldSet(this, _DiffFile_diffLines, data.diffLines, "f");
1457
- __classPrivateFieldSet(this, _DiffFile_diffListResults, data.diffListResults, "f");
1474
+ try {
1475
+ __classPrivateFieldSet(this, _DiffFile_oldFileResult, File.createInstance(data.oldFileResult), "f");
1476
+ __classPrivateFieldSet(this, _DiffFile_newFileResult, File.createInstance(data.newFileResult), "f");
1477
+ __classPrivateFieldSet(this, _DiffFile_diffLines, data.diffLines, "f");
1478
+ __classPrivateFieldSet(this, _DiffFile_diffListResults, data.diffListResults, "f");
1479
+ __classPrivateFieldSet(this, _DiffFile_composeByFullMerge, data.isFullMerge, "f");
1480
+ }
1481
+ catch (_a) {
1482
+ }
1458
1483
  };
1459
1484
  this._destroy = () => {
1460
1485
  this.clearId();
@@ -1464,21 +1489,21 @@ class DiffFile {
1464
1489
  };
1465
1490
  this.clear = () => {
1466
1491
  this._destroy();
1467
- __classPrivateFieldSet(this, _DiffFile_oldFileResult, null, "f");
1468
- __classPrivateFieldSet(this, _DiffFile_newFileResult, null, "f");
1469
- __classPrivateFieldSet(this, _DiffFile_diffLines, null, "f");
1470
- __classPrivateFieldSet(this, _DiffFile_diffListResults, null, "f");
1471
- __classPrivateFieldSet(this, _DiffFile_newFileDiffLines, null, "f");
1472
- __classPrivateFieldSet(this, _DiffFile_oldFileDiffLines, null, "f");
1473
- __classPrivateFieldSet(this, _DiffFile_newFileLines, null, "f");
1474
- __classPrivateFieldSet(this, _DiffFile_oldFileLines, null, "f");
1475
- __classPrivateFieldSet(this, _DiffFile_newFileSyntaxLines, null, "f");
1476
- __classPrivateFieldSet(this, _DiffFile_oldFileSyntaxLines, null, "f");
1477
- __classPrivateFieldSet(this, _DiffFile_splitHunksLines, null, "f");
1478
- __classPrivateFieldSet(this, _DiffFile_splitLeftLines, null, "f");
1479
- __classPrivateFieldSet(this, _DiffFile_splitRightLines, null, "f");
1480
- __classPrivateFieldSet(this, _DiffFile_unifiedHunksLines, null, "f");
1481
- __classPrivateFieldSet(this, _DiffFile_unifiedLines, null, "f");
1492
+ __classPrivateFieldSet(this, _DiffFile_oldFileResult, null);
1493
+ __classPrivateFieldSet(this, _DiffFile_newFileResult, null);
1494
+ __classPrivateFieldSet(this, _DiffFile_diffLines, null);
1495
+ __classPrivateFieldSet(this, _DiffFile_diffListResults, null);
1496
+ __classPrivateFieldSet(this, _DiffFile_newFileDiffLines, null);
1497
+ __classPrivateFieldSet(this, _DiffFile_oldFileDiffLines, null);
1498
+ __classPrivateFieldSet(this, _DiffFile_newFileLines, null);
1499
+ __classPrivateFieldSet(this, _DiffFile_oldFileLines, null);
1500
+ __classPrivateFieldSet(this, _DiffFile_newFileSyntaxLines, null);
1501
+ __classPrivateFieldSet(this, _DiffFile_oldFileSyntaxLines, null);
1502
+ __classPrivateFieldSet(this, _DiffFile_splitHunksLines, null);
1503
+ __classPrivateFieldSet(this, _DiffFile_splitLeftLines, null);
1504
+ __classPrivateFieldSet(this, _DiffFile_splitRightLines, null);
1505
+ __classPrivateFieldSet(this, _DiffFile_unifiedHunksLines, null);
1506
+ __classPrivateFieldSet(this, _DiffFile_unifiedLines, null);
1482
1507
  };
1483
1508
  Object.defineProperty(this, "__v_skip", { value: true });
1484
1509
  let oldContent = _oldFileContent;
@@ -1507,7 +1532,7 @@ class DiffFile {
1507
1532
  id = "--" + Math.random().toString().slice(2);
1508
1533
  }
1509
1534
  idSet.add(id);
1510
- __classPrivateFieldSet(this, _DiffFile_id, id, "f");
1535
+ __classPrivateFieldSet(this, _DiffFile_id, id);
1511
1536
  }
1512
1537
  getId() {
1513
1538
  return __classPrivateFieldGet(this, _DiffFile_id, "f");
@@ -1523,15 +1548,19 @@ class DiffFile {
1523
1548
  __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_doFile).call(this);
1524
1549
  __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_composeRaw).call(this);
1525
1550
  __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_composeFile).call(this);
1526
- __classPrivateFieldSet(this, _DiffFile_hasInitRaw, true, "f");
1551
+ __classPrivateFieldSet(this, _DiffFile_hasInitRaw, true);
1527
1552
  }
1528
1553
  initSyntax({ registerHighlighter } = {}) {
1529
1554
  var _a, _b;
1530
1555
  if (__classPrivateFieldGet(this, _DiffFile_hasInitSyntax, "f"))
1531
1556
  return;
1557
+ if (__classPrivateFieldGet(this, _DiffFile_composeByMerge, "f") && !__classPrivateFieldGet(this, _DiffFile_composeByFullMerge, "f")) {
1558
+ console.error(`this instance can not do syntax because of the data missing, try to use '_getFullBundle' & '_mergeFullBundle' instead of 'getBundle' & 'mergeBundle'`);
1559
+ return;
1560
+ }
1532
1561
  __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_composeSyntax).call(this, { registerHighlighter });
1533
- __classPrivateFieldSet(this, _DiffFile_highlighterName, ((_a = __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f")) === null || _a === void 0 ? void 0 : _a.highlighterName) || ((_b = __classPrivateFieldGet(this, _DiffFile_newFileResult, "f")) === null || _b === void 0 ? void 0 : _b.highlighterName) || __classPrivateFieldGet(this, _DiffFile_highlighterName, "f"), "f");
1534
- __classPrivateFieldSet(this, _DiffFile_hasInitSyntax, true, "f");
1562
+ __classPrivateFieldSet(this, _DiffFile_highlighterName, ((_a = __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f")) === null || _a === void 0 ? void 0 : _a.highlighterName) || ((_b = __classPrivateFieldGet(this, _DiffFile_newFileResult, "f")) === null || _b === void 0 ? void 0 : _b.highlighterName) || __classPrivateFieldGet(this, _DiffFile_highlighterName, "f"));
1563
+ __classPrivateFieldSet(this, _DiffFile_hasInitSyntax, true);
1535
1564
  }
1536
1565
  init() {
1537
1566
  this.initRaw();
@@ -1631,7 +1660,7 @@ class DiffFile {
1631
1660
  hideStart = len;
1632
1661
  }
1633
1662
  if (isHidden) {
1634
- this.hasCollapsed = true;
1663
+ this.hasSomeLineCollapsed = true;
1635
1664
  }
1636
1665
  prevIsHidden = isHidden;
1637
1666
  if (oldDiffLine && newDiffLine && !oldLineHasChange && !newLineHasChange) {
@@ -1643,7 +1672,7 @@ class DiffFile {
1643
1672
  typedPrevious.splitInfo = Object.assign(Object.assign({}, typedPrevious.hunkInfo), { startHiddenIndex: hideStart, endHiddenIndex: len, plainText: typedPrevious.text, _startHiddenIndex: hideStart, _endHiddenIndex: len, _plainText: typedPrevious.text });
1644
1673
  hideStart = Infinity;
1645
1674
  }
1646
- __classPrivateFieldSet(this, _DiffFile_splitHunksLines, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _DiffFile_splitHunksLines, "f")), { [len]: typedPrevious }), "f");
1675
+ __classPrivateFieldSet(this, _DiffFile_splitHunksLines, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _DiffFile_splitHunksLines, "f")), { [len]: typedPrevious }));
1647
1676
  }
1648
1677
  }
1649
1678
  }
@@ -1669,11 +1698,11 @@ class DiffFile {
1669
1698
  _oldLength: 0,
1670
1699
  _newLength: 0,
1671
1700
  };
1672
- __classPrivateFieldSet(this, _DiffFile_splitHunksLines, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _DiffFile_splitHunksLines, "f")), { [__classPrivateFieldGet(this, _DiffFile_splitRightLines, "f").length]: lastHunk }), "f");
1701
+ __classPrivateFieldSet(this, _DiffFile_splitHunksLines, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _DiffFile_splitHunksLines, "f")), { [__classPrivateFieldGet(this, _DiffFile_splitRightLines, "f").length]: lastHunk }));
1673
1702
  hideStart = Infinity;
1674
1703
  }
1675
1704
  this.splitLineLength = __classPrivateFieldGet(this, _DiffFile_splitRightLines, "f").length;
1676
- __classPrivateFieldSet(this, _DiffFile_hasBuildSplit, true, "f");
1705
+ __classPrivateFieldSet(this, _DiffFile_hasBuildSplit, true);
1677
1706
  this.notifyAll();
1678
1707
  }
1679
1708
  buildUnifiedDiffLines() {
@@ -1762,7 +1791,7 @@ class DiffFile {
1762
1791
  hideStart = len;
1763
1792
  }
1764
1793
  if (isHidden) {
1765
- this.hasCollapsed = true;
1794
+ this.hasSomeLineCollapsed = true;
1766
1795
  }
1767
1796
  prevIsHidden = isHidden;
1768
1797
  if (oldDiffLine && newDiffLine && !oldLineHasChange && !newLineHasChange) {
@@ -1774,7 +1803,7 @@ class DiffFile {
1774
1803
  typedPrevious.unifiedInfo = Object.assign(Object.assign({}, typedPrevious.hunkInfo), { startHiddenIndex: hideStart, endHiddenIndex: len, plainText: typedPrevious.text, _startHiddenIndex: hideStart, _endHiddenIndex: len, _plainText: typedPrevious.text });
1775
1804
  hideStart = Infinity;
1776
1805
  }
1777
- __classPrivateFieldSet(this, _DiffFile_unifiedHunksLines, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _DiffFile_unifiedHunksLines, "f")), { [len]: typedPrevious }), "f");
1806
+ __classPrivateFieldSet(this, _DiffFile_unifiedHunksLines, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _DiffFile_unifiedHunksLines, "f")), { [len]: typedPrevious }));
1778
1807
  }
1779
1808
  }
1780
1809
  }
@@ -1800,33 +1829,35 @@ class DiffFile {
1800
1829
  _oldLength: 0,
1801
1830
  _newLength: 0,
1802
1831
  };
1803
- __classPrivateFieldSet(this, _DiffFile_unifiedHunksLines, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _DiffFile_unifiedHunksLines, "f")), { [__classPrivateFieldGet(this, _DiffFile_unifiedLines, "f").length]: lastHunk }), "f");
1832
+ __classPrivateFieldSet(this, _DiffFile_unifiedHunksLines, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _DiffFile_unifiedHunksLines, "f")), { [__classPrivateFieldGet(this, _DiffFile_unifiedLines, "f").length]: lastHunk }));
1804
1833
  hideStart = Infinity;
1805
1834
  }
1806
1835
  this.unifiedLineLength = __classPrivateFieldGet(this, _DiffFile_unifiedLines, "f").length;
1807
- __classPrivateFieldSet(this, _DiffFile_hasBuildUnified, true, "f");
1836
+ __classPrivateFieldSet(this, _DiffFile_hasBuildUnified, true);
1808
1837
  this.notifyAll();
1809
1838
  }
1810
1839
  }
1811
- _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap(), _DiffFile_diffListResults = new WeakMap(), _DiffFile_diffLines = new WeakMap(), _DiffFile_oldFileDiffLines = new WeakMap(), _DiffFile_newFileDiffLines = new WeakMap(), _DiffFile_oldFileLines = new WeakMap(), _DiffFile_newFileLines = new WeakMap(), _DiffFile_oldFileSyntaxLines = new WeakMap(), _DiffFile_newFileSyntaxLines = new WeakMap(), _DiffFile_oldFilePlaceholderLines = new WeakMap(), _DiffFile_newFilePlaceholderLines = new WeakMap(), _DiffFile_splitLeftLines = new WeakMap(), _DiffFile_splitRightLines = new WeakMap(), _DiffFile_splitHunksLines = new WeakMap(), _DiffFile_unifiedLines = new WeakMap(), _DiffFile_unifiedHunksLines = new WeakMap(), _DiffFile_listeners = new WeakMap(), _DiffFile_hasInitRaw = new WeakMap(), _DiffFile_hasInitSyntax = new WeakMap(), _DiffFile_hasBuildSplit = new WeakMap(), _DiffFile_hasBuildUnified = new WeakMap(), _DiffFile_updateCount = new WeakMap(), _DiffFile_composeByDiff = new WeakMap(), _DiffFile_highlighterName = new WeakMap(), _DiffFile_id = new WeakMap(), _DiffFile_clonedInstance = new WeakMap(), _DiffFile_instances = new WeakSet(), _DiffFile_doDiff = function _DiffFile_doDiff() {
1840
+ _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap(), _DiffFile_diffListResults = new WeakMap(), _DiffFile_diffLines = new WeakMap(), _DiffFile_oldFileDiffLines = new WeakMap(), _DiffFile_newFileDiffLines = new WeakMap(), _DiffFile_oldFileLines = new WeakMap(), _DiffFile_newFileLines = new WeakMap(), _DiffFile_oldFileSyntaxLines = new WeakMap(), _DiffFile_newFileSyntaxLines = new WeakMap(), _DiffFile_oldFilePlaceholderLines = new WeakMap(), _DiffFile_newFilePlaceholderLines = new WeakMap(), _DiffFile_splitLeftLines = new WeakMap(), _DiffFile_splitRightLines = new WeakMap(), _DiffFile_splitHunksLines = new WeakMap(), _DiffFile_unifiedLines = new WeakMap(), _DiffFile_unifiedHunksLines = new WeakMap(), _DiffFile_listeners = new WeakMap(), _DiffFile_hasInitRaw = new WeakMap(), _DiffFile_hasInitSyntax = new WeakMap(), _DiffFile_hasBuildSplit = new WeakMap(), _DiffFile_hasBuildUnified = new WeakMap(), _DiffFile_updateCount = new WeakMap(), _DiffFile_composeByDiff = new WeakMap(), _DiffFile_composeByMerge = new WeakMap(), _DiffFile_composeByFullMerge = new WeakMap(), _DiffFile_highlighterName = new WeakMap(), _DiffFile_id = new WeakMap(), _DiffFile_clonedInstance = new WeakMap(), _DiffFile_instances = new WeakSet(), _DiffFile_doDiff = function _DiffFile_doDiff() {
1812
1841
  if (!this._diffList)
1813
1842
  return;
1814
- __classPrivateFieldSet(this, _DiffFile_diffListResults, this._diffList.map((s) => parseInstance.parse(s)), "f");
1843
+ __classPrivateFieldSet(this, _DiffFile_diffListResults, this._diffList.map((s) => parseInstance.parse(s)));
1815
1844
  }, _DiffFile_doFile = function _DiffFile_doFile() {
1816
1845
  if (!this._oldFileContent && !this._newFileContent)
1817
1846
  return;
1818
1847
  if (this._oldFileContent) {
1819
- __classPrivateFieldSet(this, _DiffFile_oldFileResult, getFile(this._oldFileContent, this._oldFileLang, this._oldFileName), "f");
1848
+ __classPrivateFieldSet(this, _DiffFile_oldFileResult, getFile(this._oldFileContent, this._oldFileLang, this._oldFileName));
1849
+ this.fileLineLength = Math.max(this.fileLineLength, __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f").maxLineNumber);
1820
1850
  }
1821
1851
  if (this._newFileContent) {
1822
- __classPrivateFieldSet(this, _DiffFile_newFileResult, getFile(this._newFileContent, this._newFileLang, this._newFileName), "f");
1852
+ __classPrivateFieldSet(this, _DiffFile_newFileResult, getFile(this._newFileContent, this._newFileLang, this._newFileName));
1853
+ this.fileLineLength = Math.max(this.fileLineLength, __classPrivateFieldGet(this, _DiffFile_newFileResult, "f").maxLineNumber);
1823
1854
  }
1824
1855
  }, _DiffFile_composeRaw = function _DiffFile_composeRaw() {
1825
1856
  var _a, _b, _c, _d;
1826
1857
  (_a = __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f")) === null || _a === void 0 ? void 0 : _a.doRaw();
1827
- __classPrivateFieldSet(this, _DiffFile_oldFileLines, (_b = __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f")) === null || _b === void 0 ? void 0 : _b.rawFile, "f");
1858
+ __classPrivateFieldSet(this, _DiffFile_oldFileLines, (_b = __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f")) === null || _b === void 0 ? void 0 : _b.rawFile);
1828
1859
  (_c = __classPrivateFieldGet(this, _DiffFile_newFileResult, "f")) === null || _c === void 0 ? void 0 : _c.doRaw();
1829
- __classPrivateFieldSet(this, _DiffFile_newFileLines, (_d = __classPrivateFieldGet(this, _DiffFile_newFileResult, "f")) === null || _d === void 0 ? void 0 : _d.rawFile, "f");
1860
+ __classPrivateFieldSet(this, _DiffFile_newFileLines, (_d = __classPrivateFieldGet(this, _DiffFile_newFileResult, "f")) === null || _d === void 0 ? void 0 : _d.rawFile);
1830
1861
  }, _DiffFile_composeFile = function _DiffFile_composeFile() {
1831
1862
  if (this._oldFileContent && this._newFileContent)
1832
1863
  return;
@@ -1868,12 +1899,13 @@ _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap()
1868
1899
  return;
1869
1900
  this._oldFileContent = oldFileContent;
1870
1901
  this._newFileContent = newFileContent;
1871
- __classPrivateFieldSet(this, _DiffFile_oldFileResult, getFile(this._oldFileContent, this._oldFileLang, this._oldFileName), "f");
1872
- __classPrivateFieldSet(this, _DiffFile_newFileResult, getFile(this._newFileContent, this._newFileLang, this._newFileName), "f");
1873
- __classPrivateFieldSet(this, _DiffFile_oldFilePlaceholderLines, oldFilePlaceholderLines, "f");
1874
- __classPrivateFieldSet(this, _DiffFile_newFilePlaceholderLines, newFilePlaceholderLines, "f");
1902
+ __classPrivateFieldSet(this, _DiffFile_oldFileResult, getFile(this._oldFileContent, this._oldFileLang, this._oldFileName));
1903
+ __classPrivateFieldSet(this, _DiffFile_newFileResult, getFile(this._newFileContent, this._newFileLang, this._newFileName));
1904
+ __classPrivateFieldSet(this, _DiffFile_oldFilePlaceholderLines, oldFilePlaceholderLines);
1905
+ __classPrivateFieldSet(this, _DiffFile_newFilePlaceholderLines, newFilePlaceholderLines);
1906
+ this.fileLineLength = Math.max(this.fileLineLength, __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f").maxLineNumber, __classPrivateFieldGet(this, _DiffFile_newFileResult, "f").maxLineNumber);
1875
1907
  // all of the file just compose by diff, so we can not do the expand action
1876
- __classPrivateFieldSet(this, _DiffFile_composeByDiff, true, "f");
1908
+ __classPrivateFieldSet(this, _DiffFile_composeByDiff, true);
1877
1909
  }
1878
1910
  else if (__classPrivateFieldGet(this, _DiffFile_oldFileResult, "f")) {
1879
1911
  let newLineNumber = 1;
@@ -1900,7 +1932,8 @@ _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap()
1900
1932
  if (!hasSymbolChanged && newFileContent === this._oldFileContent)
1901
1933
  return;
1902
1934
  this._newFileContent = newFileContent;
1903
- __classPrivateFieldSet(this, _DiffFile_newFileResult, getFile(this._newFileContent, this._newFileLang, this._newFileName), "f");
1935
+ __classPrivateFieldSet(this, _DiffFile_newFileResult, getFile(this._newFileContent, this._newFileLang, this._newFileName));
1936
+ this.fileLineLength = Math.max(this.fileLineLength, __classPrivateFieldGet(this, _DiffFile_newFileResult, "f").maxLineNumber);
1904
1937
  }
1905
1938
  else if (__classPrivateFieldGet(this, _DiffFile_newFileResult, "f")) {
1906
1939
  let oldLineNumber = 1;
@@ -1927,7 +1960,8 @@ _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap()
1927
1960
  if (!hasSymbolChanged && oldFileContent === this._newFileContent)
1928
1961
  return;
1929
1962
  this._oldFileContent = oldFileContent;
1930
- __classPrivateFieldSet(this, _DiffFile_oldFileResult, getFile(this._oldFileContent, this._oldFileLang, this._oldFileName), "f");
1963
+ __classPrivateFieldSet(this, _DiffFile_oldFileResult, getFile(this._oldFileContent, this._oldFileLang, this._oldFileName));
1964
+ this.fileLineLength = Math.max(this.fileLineLength, __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f").maxLineNumber);
1931
1965
  }
1932
1966
  __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_composeRaw).call(this);
1933
1967
  }, _DiffFile_composeDiff = function _DiffFile_composeDiff() {
@@ -1955,7 +1989,7 @@ _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap()
1955
1989
  getDiffRange(additions, deletions);
1956
1990
  });
1957
1991
  });
1958
- __classPrivateFieldSet(this, _DiffFile_diffLines, [], "f");
1992
+ __classPrivateFieldSet(this, _DiffFile_diffLines, []);
1959
1993
  const tmp = [];
1960
1994
  __classPrivateFieldGet(this, _DiffFile_diffListResults, "f").forEach((item) => {
1961
1995
  item.hunks.forEach((_item) => {
@@ -1985,7 +2019,7 @@ _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap()
1985
2019
  };
1986
2020
  }
1987
2021
  return typedI;
1988
- }), "f");
2022
+ }));
1989
2023
  // this.#diffLines = this.#diffListResults
1990
2024
  // .reduce<DiffLine[]>((p, c) => p.concat(...c.hunks.reduce<DiffLine[]>((_p, _c) => _p.concat(..._c.lines), [])), [])
1991
2025
  // .map<DiffLineItem>((i, index) => {
@@ -2007,14 +2041,14 @@ _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap()
2007
2041
  // }
2008
2042
  // return typedI;
2009
2043
  // });
2010
- __classPrivateFieldSet(this, _DiffFile_oldFileDiffLines, {}, "f");
2044
+ __classPrivateFieldSet(this, _DiffFile_oldFileDiffLines, {});
2011
2045
  __classPrivateFieldGet(this, _DiffFile_diffLines, "f").forEach((item) => {
2012
2046
  if (item.oldLineNumber) {
2013
2047
  this.diffLineLength = Math.max(this.diffLineLength, item.oldLineNumber);
2014
2048
  __classPrivateFieldGet(this, _DiffFile_oldFileDiffLines, "f")[item.oldLineNumber] = item;
2015
2049
  }
2016
2050
  });
2017
- __classPrivateFieldSet(this, _DiffFile_newFileDiffLines, {}, "f");
2051
+ __classPrivateFieldSet(this, _DiffFile_newFileDiffLines, {});
2018
2052
  __classPrivateFieldGet(this, _DiffFile_diffLines, "f").forEach((item) => {
2019
2053
  if (item.newLineNumber) {
2020
2054
  this.diffLineLength = Math.max(this.diffLineLength, item.newLineNumber);
@@ -2024,9 +2058,9 @@ _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap()
2024
2058
  }, _DiffFile_composeSyntax = function _DiffFile_composeSyntax({ registerHighlighter }) {
2025
2059
  var _a, _b, _c, _d;
2026
2060
  (_a = __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f")) === null || _a === void 0 ? void 0 : _a.doSyntax({ registerHighlighter });
2027
- __classPrivateFieldSet(this, _DiffFile_oldFileSyntaxLines, (_b = __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f")) === null || _b === void 0 ? void 0 : _b.syntaxFile, "f");
2061
+ __classPrivateFieldSet(this, _DiffFile_oldFileSyntaxLines, (_b = __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f")) === null || _b === void 0 ? void 0 : _b.syntaxFile);
2028
2062
  (_c = __classPrivateFieldGet(this, _DiffFile_newFileResult, "f")) === null || _c === void 0 ? void 0 : _c.doSyntax({ registerHighlighter });
2029
- __classPrivateFieldSet(this, _DiffFile_newFileSyntaxLines, (_d = __classPrivateFieldGet(this, _DiffFile_newFileResult, "f")) === null || _d === void 0 ? void 0 : _d.syntaxFile, "f");
2063
+ __classPrivateFieldSet(this, _DiffFile_newFileSyntaxLines, (_d = __classPrivateFieldGet(this, _DiffFile_newFileResult, "f")) === null || _d === void 0 ? void 0 : _d.syntaxFile);
2030
2064
  }, _DiffFile_getOldDiffLine = function _DiffFile_getOldDiffLine(lineNumber) {
2031
2065
  var _a;
2032
2066
  if (!lineNumber)
@@ -2122,7 +2156,7 @@ const getUnifiedContentLine = (diffFile) => {
2122
2156
  return lines.filter((line) => line.type === exports.DiffFileLineType.content);
2123
2157
  };
2124
2158
 
2125
- const versions = "0.0.11";
2159
+ const versions = "0.0.13";
2126
2160
 
2127
2161
  const useUnmount = (cb, deps) => {
2128
2162
  const ref = React.useRef(cb);
@@ -2799,7 +2833,7 @@ const DiffSplitViewTable = ({ side, diffFile }) => {
2799
2833
  const DiffSplitViewNormal = React.memo(({ diffFile }) => {
2800
2834
  const ref1 = React.useRef(null);
2801
2835
  const ref2 = React.useRef(null);
2802
- const splitLineLength = diffFile.splitLineLength;
2836
+ const splitLineLength = Math.max(diffFile.splitLineLength, diffFile.fileLineLength);
2803
2837
  const { useDiffContext } = useDiffViewContext();
2804
2838
  const fontSize = useDiffContext(React.useCallback((s) => s.fontSize, []));
2805
2839
  shim.useSyncExternalStore(diffFile.subscribe, diffFile.getUpdateCount);
@@ -3080,7 +3114,7 @@ const Style = ({ useSelector, id, }) => {
3080
3114
  : ""));
3081
3115
  };
3082
3116
  const DiffSplitViewWrap = React.memo(({ diffFile }) => {
3083
- const splitLineLength = diffFile.splitLineLength;
3117
+ const splitLineLength = Math.max(diffFile.splitLineLength, diffFile.fileLineLength);
3084
3118
  const { useDiffContext } = useDiffViewContext();
3085
3119
  const splitSideInfo = React.useMemo(() => reactivityStore.createStore(() => {
3086
3120
  const splitRef = reactivityStore.ref(undefined);
@@ -3422,7 +3456,7 @@ const DiffUnifiedView = React.memo(({ diffFile }) => {
3422
3456
  const { setWidget } = useWidget.getReadonlyState();
3423
3457
  setWidget({});
3424
3458
  }, [diffFile, useWidget]);
3425
- const unifiedLineLength = diffFile.unifiedLineLength;
3459
+ const unifiedLineLength = Math.max(diffFile.unifiedLineLength, diffFile.fileLineLength);
3426
3460
  const _width = useTextWidth({
3427
3461
  text: unifiedLineLength.toString(),
3428
3462
  font: { fontSize: fontSize + "px", fontFamily: "Menlo, Consolas, monospace" },
@@ -3565,7 +3599,7 @@ const _InternalDiffView = (props) => {
3565
3599
  ]);
3566
3600
  const value = React.useMemo(() => ({ useDiffContext }), [useDiffContext]);
3567
3601
  return (React__namespace.createElement(DiffViewContext.Provider, { value: value },
3568
- React__namespace.createElement("div", { className: "diff-tailwindcss-wrapper", "data-component": "git-diff-view", "data-version": `${"0.0.11"}`, "data-highlighter": diffFile._getHighlighterName() },
3602
+ React__namespace.createElement("div", { className: "diff-tailwindcss-wrapper", "data-component": "git-diff-view", "data-version": `${"0.0.13"}`, "data-highlighter": diffFile._getHighlighterName() },
3569
3603
  React__namespace.createElement("div", { className: "diff-style-root", style: {
3570
3604
  // @ts-ignore
3571
3605
  [diffFontSizeName]: diffViewFontSize + "px",
@@ -3618,14 +3652,18 @@ const DiffViewWithRef = (props, ref) => {
3618
3652
  };
3619
3653
  const DiffView = React.forwardRef(DiffViewWithRef);
3620
3654
  DiffView.displayName = "DiffView";
3621
- const version = "0.0.11";
3655
+ const version = "0.0.13";
3622
3656
 
3623
3657
  exports.DefaultDiffExpansionStep = DefaultDiffExpansionStep;
3624
3658
  exports.DiffFile = DiffFile;
3659
+ exports.DiffHunk = DiffHunk;
3660
+ exports.DiffHunkHeader = DiffHunkHeader;
3625
3661
  exports.DiffLine = DiffLine;
3662
+ exports.DiffParser = DiffParser;
3626
3663
  exports.DiffView = DiffView;
3627
3664
  exports.DiffViewContext = DiffViewContext;
3628
3665
  exports.File = File;
3666
+ exports.HiddenBidiCharsRegex = HiddenBidiCharsRegex;
3629
3667
  exports._cacheMap = _cacheMap;
3630
3668
  exports.assertNever = assertNever;
3631
3669
  exports.checkDiffLineIncludeChange = checkDiffLineIncludeChange;
@@ -3643,6 +3681,7 @@ exports.getUnifiedLines = getUnifiedLines;
3643
3681
  exports.hasRelativeChange = hasRelativeChange;
3644
3682
  exports.highlighter = highlighter;
3645
3683
  exports.numIterator = numIterator;
3684
+ exports.parseInstance = parseInstance;
3646
3685
  exports.processAST = processAST;
3647
3686
  exports.relativeChanges = relativeChanges;
3648
3687
  exports.useDiffViewContext = useDiffViewContext;