1diff --git a/dist/components/CodeView.d.ts b/dist/components/CodeView.d.ts
2index 774c1abbf4c00586b4fd3af0bf525a5d7c45d015..8e27d2982f5c593e7204bc8fdae9a7ad5e8a85e4 100644
3--- a/dist/components/CodeView.d.ts
4+++ b/dist/components/CodeView.d.ts
5@@ -166,6 +166,13 @@ interface CodeViewOptions<LAnnotation, Caret> extends CodeViewPassThroughOptions
6 * change, and with undefined when it closes.
7 */
8 onSearchStateChange?(state: SearchPanelState | undefined): void;
9+ /**
10+ * T3 patch. Makes find cover collapsed items and collapsed diff context.
11+ * Called when find navigates to a match in a collapsed item: folding is host
12+ * state, so the host unfolds it (a controlled update with `collapsed: false`
13+ * and a new `version`) and the viewer then scrolls to the match.
14+ */
15+ onRevealSearchMatch?(item: CodeViewItem<LAnnotation>): void;
16 /**
17 * Return an in-memory retention key for an item's editable draft and
18 * undo/redo history. Called only when CodeView creates the item's editor.
19diff --git a/dist/components/CodeView.js b/dist/components/CodeView.js
20index 6ee5032aee523b4c3e10f70202874f141f28ff10..94cd3f4b2e16490994707c28fa45c4f43f0c6065 100644
21--- a/dist/components/CodeView.js
22+++ b/dist/components/CodeView.js
23@@ -213,7 +213,8 @@ var CodeView = class CodeView {
24 matchesByItem: /* @__PURE__ */ new Map(),
25 current: void 0,
26 centerNavigation: false,
27- pendingHorizontalReveal: false
28+ pendingHorizontalReveal: false,
29+ pendingReveal: void 0
30 };
31 searchMatchesDirty = false;
32 searchHighlighter;
33@@ -593,10 +594,29 @@ var CodeView = class CodeView {
34 this.searchState.centerNavigation = false;
35 this.searchMatchesDirty = false;
36 this.searchState.pendingHorizontalReveal = false;
37+ this.searchState.pendingReveal = void 0;
38+ }
39+ /** T3 patch: whether a diff match sits in collapsed context. Deletion cells carry their row's addition line. */
40+ isSearchMatchHidden(item, match) {
41+ const lineNumber = match.side === "additions" ? match.lineNumber : match.revealLineNumber;
42+ return item.type === "diff" && lineNumber != null && !item.instance.isLineRenderable(lineNumber);
43+ }
44+ /** T3 patch: finish a reveal that waited for the host to unfold the item, or for its first render. */
45+ resumeSearchReveal(updatedItems) {
46+ const { current: match, pendingReveal } = this.searchState;
47+ if (pendingReveal == null || match == null) return;
48+ for (const item of updatedItems) {
49+ if (item.item.id !== match.itemId || item.item.collapsed === true || item.type === "diff" && item.instance.getRenderedDiff() == null) continue;
50+ this.searchState.pendingReveal = void 0;
51+ if (pendingReveal === "unfold" || this.isSearchMatchHidden(item, match)) queueMicrotask(() => {
52+ if (areOptionalCodeViewSearchMatchesEqual(this.searchState.current, match)) this.scrollToSearchMatch(match);
53+ });
54+ return;
55+ }
56 }
57 isSearchMatchInView(match) {
58 const item = this.idToItem.get(match.itemId);
59- if (item == null || item.type === "diff" && match.side === "additions" && !item.instance.isLineRenderable(match.lineNumber)) return false;
60+ if (item == null || this.isSearchMatchHidden(item, match)) return false;
61 const rect = this.getScrollTargetRect({
62 type: "line",
63 id: match.itemId,
64@@ -616,13 +636,21 @@ var CodeView = class CodeView {
65 this.searchState.pendingHorizontalReveal = true;
66 this.searchState.current = match;
67 this.render();
68- if (!this.searchState.centerNavigation && this.isSearchMatchInView(match)) {
69+ const item = this.idToItem.get(match.itemId);
70+ const folded = item?.item.collapsed === true;
71+ this.searchState.pendingReveal = void 0;
72+ if (!folded && !this.searchState.centerNavigation && this.isSearchMatchInView(match)) {
73 this.clearPendingScroll();
74 return;
75 }
76 this.searchState.centerNavigation = true;
77- const item = this.idToItem.get(match.itemId);
78- if (item?.type === "diff" && match.side === "additions" && !item.instance.isLineRenderable(match.lineNumber)) item.instance.revealLine(match.lineNumber);
79+ // T3 patch: folding is host state, and a diff that has not rendered reports every line
80+ // renderable. Scroll to the item now; resumeSearchReveal finishes once it has rendered.
81+ if (folded) {
82+ this.searchState.pendingReveal = "unfold";
83+ this.options.onRevealSearchMatch?.(item.item);
84+ } else if (item?.type === "diff" && item.instance.getRenderedDiff() == null) this.searchState.pendingReveal = "render";
85+ else if (item != null && this.isSearchMatchHidden(item, match)) item.instance.revealLine(match.revealLineNumber ?? match.lineNumber);
86 this.scrollTo({
87 type: "line",
88 id: match.itemId,
89@@ -732,9 +760,12 @@ var CodeView = class CodeView {
90 for (const item of items) {
91 const remaining = MAX_SEARCH_MATCHES - matches.length;
92 if (remaining <= 0) break;
93- if (item.item.collapsed === true) continue;
94+ // T3 patch: a host that can unfold items (onRevealSearchMatch) gets them searched.
95+ if (item.item.collapsed === true && this.options.onRevealSearchMatch == null) continue;
96 const nextMatches = (scope != null || item.type === "file" ? this.searchEditedItem(item, searchParams, remaining) : void 0) ?? (item.type === "file" ? this.searchFileItem(item, searchParams, remaining) : this.searchDiffItem(item, searchParams, remaining));
97 const bounds = item.element == null ? void 0 : item.instance.getRenderedBounds();
98+ // T3 patch: a mounted folded item has no rendered lines, so its header stands in for them.
99+ if (item.item.collapsed === true && item.element != null && nextMatches.length > 0) firstRendered ??= matches.length;
100 for (const match of nextMatches) {
101 const canBeRendered = firstVisible == null && bounds != null;
102 const canBeAfter = firstAfterRendered == null && lastRenderedItem != null && item.index >= lastRenderedItem.index;
103@@ -744,7 +775,7 @@ var CodeView = class CodeView {
104 lineNumber: match.lineNumber,
105 side: match.side
106 }) : void 0;
107- if (canBeRendered && position != null && position.height > 0 && position.top >= bounds.top && position.top < bounds.bottom && (item.type !== "diff" || match.side !== "additions" || item.instance.isLineRenderable(match.lineNumber))) {
108+ if (canBeRendered && position != null && position.height > 0 && position.top >= bounds.top && position.top < bounds.bottom) {
109 firstRendered ??= matches.length;
110 if (this.isSearchMatchInView(match)) firstVisible = matches.length;
111 }
112@@ -791,9 +822,10 @@ var CodeView = class CodeView {
113 const fileDiff = doc == null ? item.item.fileDiff : item.instance.getDiffForSearch() ?? item.item.fileDiff;
114 const scoped = this.searchState.scope?.itemId === item.item.id;
115 const diffStyle = this.options.diffStyle ?? "split";
116- const expandedHunks = scoped || this.options.expandUnchanged === true ? true : item.instance.getExpandedHunksForSearch();
117+ // T3 patch: the same opt-in searches collapsed context; navigating to a match expands it.
118+ const expandedHunks = scoped || this.options.expandUnchanged === true || this.options.onRevealSearchMatch != null ? true : item.instance.getExpandedHunksForSearch();
119 const lines = [];
120- const addLine = (side, line) => {
121+ const addLine = (side, line, revealLineNumber) => {
122 if (line === void 0) return;
123 const sourceLines = side === "additions" ? fileDiff.additionLines : fileDiff.deletionLines;
124 const text = side === "additions" && doc != null ? doc.getLineText(line.lineIndex, true) : sourceLines[line.lineIndex];
125@@ -805,7 +837,8 @@ var CodeView = class CodeView {
126 itemType: "diff",
127 side,
128 lineNumber: line.lineNumber,
129- lineIndex: line.lineIndex
130+ lineIndex: line.lineIndex,
131+ revealLineNumber
132 }
133 });
134 };
135@@ -824,7 +857,7 @@ var CodeView = class CodeView {
136 else addLine("deletions", deletionLine);
137 return;
138 }
139- addLine("deletions", deletionLine);
140+ addLine("deletions", deletionLine, additionLine?.lineNumber);
141 addLine("additions", additionLine);
142 }
143 });
144@@ -1081,6 +1114,9 @@ var CodeView = class CodeView {
145 this.resetSearchState();
146 if (searchPanel == null) return;
147 searchPanel.cleanup();
148+ // T3 patch: a panel that closes while focused drops focus to the body; keep it in the viewer.
149+ const doc = this.root?.ownerDocument;
150+ if (doc != null && doc.activeElement === doc.body) this.root.focus({ preventScroll: true });
151 const { onSearchStateChange } = this.options;
152 onSearchStateChange?.(void 0);
153 }
154@@ -2239,6 +2275,7 @@ var CodeView = class CodeView {
155 if (measured) this.validateStickyContainerHeight();
156 this.fixContainerFocus();
157 this.paintSearchHighlights();
158+ this.resumeSearchReveal(updatedItems);
159 if (this.pendingScrollTarget == null) this.finishPendingScroll("settled");
160 if (fitPerfectly || this.scrollAnimation != null || this.renderState.measurementsPending) this.render();
161 };
162@@ -2340,6 +2377,7 @@ var CodeView = class CodeView {
163 clearPendingScroll = (event) => {
164 if (event != null && !isUserScrollInput(event)) return;
165 if (event != null) this.searchState.pendingHorizontalReveal = false;
166+ if (event != null) this.searchState.pendingReveal = void 0;
167 this.pendingLayoutAnchor = void 0;
168 this.cancelScroll();
169 };
170diff --git a/dist/components/FileDiff.js b/dist/components/FileDiff.js
171index 734ff9862cdfe65b8082599c6c221c4886436e01..f18798a3d56dd0749550b5aff62a06fb0513b28e 100644
172--- a/dist/components/FileDiff.js
173+++ b/dist/components/FileDiff.js
174@@ -1,7 +1,8 @@
175-import { CUSTOM_HEADER_SLOT_ID, DEFAULT_THEMES, EMPTY_LINE_ANNOTATIONS, EMPTY_RENDER_RANGE, HEADER_FILENAME_SUFFIX_SLOT_ID, HEADER_METADATA_SLOT_ID, HEADER_PREFIX_SLOT_ID } from "../constants.js";
176+import { CUSTOM_HEADER_SLOT_ID, DEFAULT_THEMES, EMPTY_LINE_ANNOTATIONS, HEADER_FILENAME_SUFFIX_SLOT_ID, HEADER_METADATA_SLOT_ID, HEADER_PREFIX_SLOT_ID } from "../constants.js";
177 import { isSafari } from "../utils/platform.js";
178 import { HighlighterDisposedError } from "../highlighter/highlighterType.js";
179 import { getThemes } from "../utils/getThemes.js";
180+import { getHighlighterThemeStyles } from "../utils/getHighlighterThemeStyles.js";
181 import { getHighlighterIfLoaded, getSharedHighlighter } from "../highlighter/shared_highlighter.js";
182 import { dequeueRender, queueRender } from "../managers/UniversalRenderingManager.js";
183 import { areObjectsEqual } from "../utils/areObjectsEqual.js";
184@@ -733,7 +734,7 @@ var FileDiff = class {
185 if (expandUnchanged) this.loadFilesIfNecessary();
186 this.hunksRenderer.setOptions(this.getHunksRendererOptions(this.options));
187 this.syncInteractionOptions();
188- this.prepareRenderData(this.hunksRenderer.getDiffForNextRender(workingDiff));
189+ this.prepareRenderData(collapsed ? workingDiff : this.hunksRenderer.getDiffForNextRender(workingDiff));
190 const { disableErrorHandling = false, disableFileHeader = false } = this.options;
191 if (disableFileHeader) {
192 if (this.headerElement != null) {
193@@ -750,11 +751,22 @@ var FileDiff = class {
194 this.removeRenderedCode();
195 this.clearAuxiliaryNodes();
196 try {
197- const hunksResult = this.hunksRenderer.renderDiff(workingDiff, EMPTY_RENDER_RANGE);
198- if (hunksResult != null) this.applyThemeState(fileContainer, hunksResult.themeStyles, themeType, hunksResult.baseThemeType);
199- if (hunksResult?.headerElement != null) this.applyHeaderToDOM(hunksResult.headerElement, fileContainer, hunksResult.fileDiff);
200+ // An empty render range still highlights the full diff. Headers only need the theme.
201+ const theme = this.getTheme();
202+ const highlighter = getHighlighterIfLoaded({ theme, lang: "text" });
203+ if (highlighter != null) this.applyThemeState(fileContainer, getHighlighterThemeStyles({ theme, highlighter }), themeType, typeof theme === "string" ? highlighter.getTheme(theme).type : void 0);
204+ else getSharedHighlighter({
205+ themes: getThemes(theme),
206+ langs: ["text"],
207+ preferredHighlighter: resolvePreferredHighlighter(this.workerManager, this.options)
208+ }).then(() => {
209+ if (this.enabled && this.fileContainer === fileContainer && this.options.collapsed && areThemesEqual(theme, this.getTheme())) this.rerender();
210+ }).catch((error) => {
211+ if (!(error instanceof HighlighterDisposedError)) console.error(error);
212+ });
213+ if (!disableFileHeader) this.applyHeaderToDOM(this.hunksRenderer.renderHeader(workingDiff), fileContainer, workingDiff);
214 this.renderSeparators([]);
215- this.adoptRenderData(hunksResult?.fileDiff ?? workingDiff);
216+ this.adoptRenderData(workingDiff);
217 this.injectUnsafeCSS();
218 } catch (error) {
219 if (disableErrorHandling) throw error;
220diff --git a/dist/components/VirtualizedFileDiff.js b/dist/components/VirtualizedFileDiff.js
221index 984f049ff3694dd353fa6637b0f09fc7dce74992..4d6599905be0fe7b5b5c1a225c0b3ff8d810c72a 100644
222--- a/dist/components/VirtualizedFileDiff.js
223+++ b/dist/components/VirtualizedFileDiff.js
224@@ -264,7 +264,8 @@ var VirtualizedFileDiff = class extends FileDiff {
225 const { pendingExpansions, pendingHydratedDiff, options: { collapsed = false } } = this;
226 if (pendingHydratedDiff != null) {
227 this.pendingHydratedDiff = void 0;
228- if (pendingHydratedDiff.expectedDiff === fileDiff) {
229+ // T3 patch: a host may re-supply an unchanged diff as a new object; it is still this diff.
230+ if (areDiffTargetsEqual(pendingHydratedDiff.expectedDiff, fileDiff)) {
231 Object.assign(fileDiff, pendingHydratedDiff.nextDiff);
232 this.setHydratedState(pendingHydratedDiff.files);
233 this.installHydratedDiff(fileDiff);
234@@ -626,7 +627,7 @@ var VirtualizedFileDiff = class extends FileDiff {
235 rerender() {
236 if (!this.enabled || this.getInputDiff() == null && this.additionFile == null && this.deletionFile == null) return;
237 const workingDiff = this.getWorkingDiff();
238- const nextRenderDiff = workingDiff == null ? void 0 : this.hunksRenderer.getDiffForNextRender(workingDiff);
239+ const nextRenderDiff = workingDiff == null || this.options.collapsed === true ? workingDiff : this.hunksRenderer.getDiffForNextRender(workingDiff);
240 if (this.isSimpleMode()) this.pendingRender = void 0;
241 this.forceRenderOverride = true;
242 if (this.isSimpleMode() && this.requestRender()) return;
243@@ -790,7 +791,7 @@ var VirtualizedFileDiff = class extends FileDiff {
244 const previousRenderedDiff = this.getRenderedDiff();
245 const { pendingRender } = this;
246 const previousLayoutDiff = pendingRender?.diff ?? previousRenderedDiff;
247- const pendingRenderDiff = this.hunksRenderer.getDiffForNextRender(workingDiff);
248+ const pendingRenderDiff = this.options.collapsed === true ? workingDiff : this.hunksRenderer.getDiffForNextRender(workingDiff);
249 this.pendingRender = {
250 workingDiff,
251 diff: pendingRenderDiff
252diff --git a/dist/editor/editor.js b/dist/editor/editor.js
253index a9905d43382de2ca03d6111ba9ab3725d8cb6981..294f537622b9a62d89111d7ed4a7c07cc24dac30 100644
254--- a/dist/editor/editor.js
255+++ b/dist/editor/editor.js
256@@ -106,6 +106,7 @@ var Editor = class {
257 #deletionsColumn;
258 #overlayElement;
259 #overlayElements;
260+ #fontProbeElement;
261 #caretElements;
262 #caretHighlightElements;
263 #primaryCaretElement;
264@@ -490,7 +491,9 @@ var Editor = class {
265 selections: this.#selections
266 });
267 const primarySelection = resolvedSelections.at(-1);
268- if (primarySelection !== void 0) this.#revealLineIfCollapsed(getCaretPosition(primarySelection).line);
269+ // Clearing keeps the selection while search matches or markers exist; scrolling to it steals focus.
270+ if (primarySelection === void 0) return;
271+ this.#revealLineIfCollapsed(getCaretPosition(primarySelection).line);
272 this.#scrollToPrimaryCaret();
273 }
274 setMarkers(markers) {
275@@ -595,6 +598,7 @@ var Editor = class {
276 this.#contentHasFocus = false;
277 this.#overlayElement?.remove();
278 this.#overlayElement = void 0;
279+ this.#fontProbeElement = void 0;
280 this.#resizeObserver?.disconnect();
281 this.#resizeObserver = void 0;
282 this.#fontRemeasureScheduled = false;
283@@ -1033,6 +1037,19 @@ var Editor = class {
284 this.#tokenizer?.applyStyle();
285 this.#spriteElement = createSpriteElement();
286 this.#overlayElement = h("div", { dataset: "editorOverlay" });
287+ // Resizes when the inherited code font changes, so the observer can re-measure.
288+ this.#fontProbeElement = h("span", {
289+ ariaHidden: "true",
290+ style: {
291+ position: "absolute",
292+ top: "0",
293+ left: "0",
294+ visibility: "hidden",
295+ pointerEvents: "none",
296+ whiteSpace: "pre"
297+ },
298+ textContent: "0"
299+ }, this.#overlayElement);
300 const replacementFocusTargetIsContent = (event) => {
301 const target = event.composedPath()[0];
302 return target instanceof Node && this.#contentElement?.contains(target) === true;
303@@ -1409,6 +1426,7 @@ var Editor = class {
304 this.#resizeObserver = new ResizeObserver(this.#handleLayoutResize);
305 this.#resizeObserver.observe(contentEl);
306 this.#resizeObserver.observe(contentEl.parentElement);
307+ if (this.#fontProbeElement !== void 0) this.#resizeObserver.observe(this.#fontProbeElement);
308 this.#computeContentOffset(contentEl);
309 }
310 #handleCustomPasteEvent = async () => {
311@@ -1864,7 +1882,9 @@ var Editor = class {
312 const change = textDocument.applyEdits(edits, true, selections, nextSelections, true);
313 if (change !== void 0) this.#applyChange(change, nextSelections);
314 }
315- #handleLayoutResize = () => {
316+ #handleLayoutResize = (entries) => {
317+ const contentElement = this.#contentElement;
318+ const metricsChanged = contentElement !== void 0 && entries.some((entry) => entry.target === this.#fontProbeElement) && this.#metrics.init(contentElement);
319 const lineAnnotations = this.#lineAnnotations?.length ?? 0;
320 const prevGutterWidth = this.#gutterWidthCache;
321 const prevContentWidth = this.#contentWidthCache;
322@@ -1872,12 +1892,12 @@ var Editor = class {
323 this.#contentWidthCache = void 0;
324 const gutterWidthChanged = this.#getGutterWidth() !== prevGutterWidth;
325 const contentWidthChanged = this.#getContentWidth() !== prevContentWidth;
326- if (!gutterWidthChanged && !contentWidthChanged) return;
327+ if (!gutterWidthChanged && !contentWidthChanged && !metricsChanged) return;
328 this.#lastAccessedCharX = void 0;
329 this.#metrics.clearTextWidthCache();
330- if (contentWidthChanged) {
331+ if (contentWidthChanged || metricsChanged) {
332 this.#wrapLineOffsetsCache.clear();
333- if (this.#isWrap || lineAnnotations > 0) this.#lineYCache.clear();
334+ if (metricsChanged || this.#isWrap || lineAnnotations > 0) this.#lineYCache.clear();
335 }
336 if (this.#selections !== void 0 || this.#matches !== void 0 || this.#markerRenderer !== void 0) {
337 this.#updateSelections(this.#selections ?? []);
338diff --git a/dist/editor/textMeasure.d.ts b/dist/editor/textMeasure.d.ts
339index 89e938d89eca77d351aeed65f3c5495383effd97..cde1d6ba89a97bbb1614754a48f8994388c186bd 100644
340--- a/dist/editor/textMeasure.d.ts
341+++ b/dist/editor/textMeasure.d.ts
342@@ -9,8 +9,8 @@ declare class Metrics {
343 lineHeight: number;
344 /** Padding top of the root element. */
345 paddingTop: number;
346- /** initialize the metrics */
347- init(root: HTMLElement): void;
348+ /** (re)read the metrics from root, returning true when they changed */
349+ init(root: HTMLElement): boolean;
350 /**
351 * Re-measure the '0' character width against the font that is loaded right
352 * now, returning true when measurement-dependent UI should refresh.
353diff --git a/dist/editor/textMeasure.js b/dist/editor/textMeasure.js
354index 96d4fb137ea683b66381b1ce6e47e8708a89366c..13f2564897a5bf53a8f311300003b3ea875c73a5 100644
355--- a/dist/editor/textMeasure.js
356+++ b/dist/editor/textMeasure.js
357@@ -16,9 +16,10 @@ var Metrics = class {
358 lineHeight = 20;
359 /** Padding top of the root element. */
360 paddingTop = 0;
361- /** initialize the metrics */
362+ /** (re)read the metrics from root, returning true when they changed */
363 init(root) {
364- if (this.#root === root && this.#canvasCtx !== void 0 && this.ch !== -1) return;
365+ const previousLineHeight = this.lineHeight;
366+ let fontChanged = false;
367 this.#root = root;
368 this.#canvas ??= h("canvas", { style: { display: "none" } });
369 this.#canvasCtx ??= this.#canvas.getContext("2d") ?? void 0;
370@@ -37,9 +38,11 @@ var Metrics = class {
371 this.#setCanvasFont(font);
372 this.ch = this.canvasMeasureTextWidth("0");
373 this.clearTextWidthCache();
374+ fontChanged = true;
375 }
376 const nextTabSize = parseInt(tabSize, 10);
377 if (!Number.isNaN(nextTabSize)) this.tabSize = nextTabSize;
378+ return fontChanged || this.lineHeight !== previousLineHeight;
379 }
380 /**
381 * Re-measure the '0' character width against the font that is loaded right
382diff --git a/dist/utils/createFileHeaderElement.js b/dist/utils/createFileHeaderElement.js
383index 19934176d0787ae1304e771c707230d5c8837e83..298b3386eac5126a7c1ec985674e799aac0ffd42 100644
384--- a/dist/utils/createFileHeaderElement.js
385+++ b/dist/utils/createFileHeaderElement.js
386@@ -73,12 +73,12 @@ function createMetadataElement(fileDiff) {
387 }
388 if (deletions > 0 || additions === 0) children.push(createHastElement({
389 tagName: "span",
390- children: [createTextNodeElement(`-${deletions}`)],
391+ children: [createTextNodeElement(`-${deletions.toLocaleString()}`)],
392 properties: { "data-deletions-count": "" }
393 }));
394 if (additions > 0 || deletions === 0) children.push(createHastElement({
395 tagName: "span",
396- children: [createTextNodeElement(`+${additions}`)],
397+ children: [createTextNodeElement(`+${additions.toLocaleString()}`)],
398 properties: { "data-additions-count": "" }
399 }));
400 }
401diff --git a/package.json b/package.json
402index 0a0acc4c8734a61cf2d684162914002adf74960d..935937d68f52ed96b7af6b1dbb890dbf512eb0fe 100644
403--- a/package.json
404+++ b/package.json
405@@ -60,6 +60,18 @@
406 "./worker/worker-portable.js": {
407 "types": "./dist/worker/worker-portable.d.ts",
408 "import": "./dist/worker/worker-portable.js"
409+ },
410+ "./types": {
411+ "types": "./dist/types.d.ts",
412+ "import": "./dist/types.js"
413+ },
414+ "./utils/getFiletypeFromFileName": {
415+ "types": "./dist/utils/getFiletypeFromFileName.d.ts",
416+ "import": "./dist/utils/getFiletypeFromFileName.js"
417+ },
418+ "./utils/parsePatchFiles": {
419+ "types": "./dist/utils/parsePatchFiles.d.ts",
420+ "import": "./dist/utils/parsePatchFiles.js"
421 }
422 },
423 "publishConfig": {