@pierre/diffs 1.0.7 → 1.1.0-beta.1

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.
Files changed (128) hide show
  1. package/dist/components/File.d.ts +4 -2
  2. package/dist/components/File.d.ts.map +1 -1
  3. package/dist/components/File.js +80 -34
  4. package/dist/components/File.js.map +1 -1
  5. package/dist/components/FileDiff.d.ts +50 -28
  6. package/dist/components/FileDiff.d.ts.map +1 -1
  7. package/dist/components/FileDiff.js +220 -79
  8. package/dist/components/FileDiff.js.map +1 -1
  9. package/dist/components/FileStream.d.ts +1 -0
  10. package/dist/components/FileStream.d.ts.map +1 -1
  11. package/dist/components/FileStream.js +8 -4
  12. package/dist/components/FileStream.js.map +1 -1
  13. package/dist/constants.d.ts +8 -2
  14. package/dist/constants.d.ts.map +1 -1
  15. package/dist/constants.js +10 -1
  16. package/dist/constants.js.map +1 -1
  17. package/dist/index.d.ts +19 -10
  18. package/dist/index.js +14 -5
  19. package/dist/managers/LineSelectionManager.d.ts.map +1 -1
  20. package/dist/managers/LineSelectionManager.js +8 -9
  21. package/dist/managers/LineSelectionManager.js.map +1 -1
  22. package/dist/react/MultiFileDiff.js +2 -2
  23. package/dist/react/MultiFileDiff.js.map +1 -1
  24. package/dist/react/index.d.ts +2 -2
  25. package/dist/react/utils/renderDiffChildren.d.ts +4 -4
  26. package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
  27. package/dist/react/utils/renderDiffChildren.js +3 -3
  28. package/dist/react/utils/renderDiffChildren.js.map +1 -1
  29. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  30. package/dist/renderers/DiffHunksRenderer.d.ts +7 -6
  31. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  32. package/dist/renderers/DiffHunksRenderer.js +263 -337
  33. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  34. package/dist/renderers/FileRenderer.d.ts +1 -0
  35. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  36. package/dist/renderers/FileRenderer.js +11 -4
  37. package/dist/renderers/FileRenderer.js.map +1 -1
  38. package/dist/ssr/index.d.ts +2 -2
  39. package/dist/style.js +1 -1
  40. package/dist/style.js.map +1 -1
  41. package/dist/types.d.ts +246 -42
  42. package/dist/types.d.ts.map +1 -1
  43. package/dist/utils/areDiffLineAnnotationsEqual.d.ts +7 -0
  44. package/dist/utils/areDiffLineAnnotationsEqual.d.ts.map +1 -0
  45. package/dist/utils/areDiffLineAnnotationsEqual.js +8 -0
  46. package/dist/utils/areDiffLineAnnotationsEqual.js.map +1 -0
  47. package/dist/utils/areHunkDataEqual.d.ts +7 -0
  48. package/dist/utils/areHunkDataEqual.d.ts.map +1 -0
  49. package/dist/utils/areHunkDataEqual.js +8 -0
  50. package/dist/utils/areHunkDataEqual.js.map +1 -0
  51. package/dist/utils/areLineAnnotationsEqual.d.ts +7 -0
  52. package/dist/utils/areLineAnnotationsEqual.d.ts.map +1 -0
  53. package/dist/utils/areLineAnnotationsEqual.js +8 -0
  54. package/dist/utils/areLineAnnotationsEqual.js.map +1 -0
  55. package/dist/utils/arePrePropertiesEqual.d.ts +7 -0
  56. package/dist/utils/arePrePropertiesEqual.d.ts.map +1 -0
  57. package/dist/utils/arePrePropertiesEqual.js +9 -0
  58. package/dist/utils/arePrePropertiesEqual.js.map +1 -0
  59. package/dist/utils/areRenderRangesEqual.d.ts +7 -0
  60. package/dist/utils/areRenderRangesEqual.d.ts.map +1 -0
  61. package/dist/utils/areRenderRangesEqual.js +9 -0
  62. package/dist/utils/areRenderRangesEqual.js.map +1 -0
  63. package/dist/utils/areVirtualWindowSpecsEqual.d.ts +7 -0
  64. package/dist/utils/areVirtualWindowSpecsEqual.d.ts.map +1 -0
  65. package/dist/utils/areVirtualWindowSpecsEqual.js +9 -0
  66. package/dist/utils/areVirtualWindowSpecsEqual.js.map +1 -0
  67. package/dist/utils/areWorkerStatsEqual.d.ts +8 -0
  68. package/dist/utils/areWorkerStatsEqual.d.ts.map +1 -0
  69. package/dist/utils/areWorkerStatsEqual.js +9 -0
  70. package/dist/utils/areWorkerStatsEqual.js.map +1 -0
  71. package/dist/utils/createTransformerWithState.js +1 -1
  72. package/dist/utils/createTransformerWithState.js.map +1 -1
  73. package/dist/utils/createWindowFromScrollPosition.d.ts +22 -0
  74. package/dist/utils/createWindowFromScrollPosition.d.ts.map +1 -0
  75. package/dist/utils/createWindowFromScrollPosition.js +26 -0
  76. package/dist/utils/createWindowFromScrollPosition.js.map +1 -0
  77. package/dist/utils/diffAcceptRejectHunk.js +36 -21
  78. package/dist/utils/diffAcceptRejectHunk.js.map +1 -1
  79. package/dist/utils/getOrCreateCodeNode.d.ts +14 -0
  80. package/dist/utils/getOrCreateCodeNode.d.ts.map +1 -0
  81. package/dist/utils/getOrCreateCodeNode.js +13 -0
  82. package/dist/utils/getOrCreateCodeNode.js.map +1 -0
  83. package/dist/utils/getTotalLineCountFromHunks.js +1 -1
  84. package/dist/utils/getTotalLineCountFromHunks.js.map +1 -1
  85. package/dist/utils/hast_utils.d.ts +2 -1
  86. package/dist/utils/hast_utils.d.ts.map +1 -1
  87. package/dist/utils/hast_utils.js +10 -1
  88. package/dist/utils/hast_utils.js.map +1 -1
  89. package/dist/utils/isDefaultRenderRange.d.ts +7 -0
  90. package/dist/utils/isDefaultRenderRange.d.ts.map +1 -0
  91. package/dist/utils/isDefaultRenderRange.js +8 -0
  92. package/dist/utils/isDefaultRenderRange.js.map +1 -0
  93. package/dist/utils/iterateOverDiff.d.ts +39 -0
  94. package/dist/utils/iterateOverDiff.d.ts.map +1 -0
  95. package/dist/utils/iterateOverDiff.js +356 -0
  96. package/dist/utils/iterateOverDiff.js.map +1 -0
  97. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  98. package/dist/utils/parseDiffFromFile.js +8 -6
  99. package/dist/utils/parseDiffFromFile.js.map +1 -1
  100. package/dist/utils/parsePatchFiles.d.ts +15 -3
  101. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  102. package/dist/utils/parsePatchFiles.js +207 -158
  103. package/dist/utils/parsePatchFiles.js.map +1 -1
  104. package/dist/utils/processLine.js +4 -3
  105. package/dist/utils/processLine.js.map +1 -1
  106. package/dist/utils/renderDiffWithHighlighter.d.ts +7 -2
  107. package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
  108. package/dist/utils/renderDiffWithHighlighter.js +149 -227
  109. package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  110. package/dist/utils/setWrapperNodeProps.d.ts +3 -7
  111. package/dist/utils/setWrapperNodeProps.d.ts.map +1 -1
  112. package/dist/utils/setWrapperNodeProps.js +1 -1
  113. package/dist/utils/setWrapperNodeProps.js.map +1 -1
  114. package/dist/worker/WorkerPoolManager.d.ts +9 -2
  115. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  116. package/dist/worker/WorkerPoolManager.js +124 -45
  117. package/dist/worker/WorkerPoolManager.js.map +1 -1
  118. package/dist/worker/types.d.ts +7 -0
  119. package/dist/worker/types.d.ts.map +1 -1
  120. package/dist/worker/worker-portable.js +634 -242
  121. package/dist/worker/worker-portable.js.map +1 -1
  122. package/dist/worker/worker.js +511 -231
  123. package/dist/worker/worker.js.map +1 -1
  124. package/package.json +20 -1
  125. package/dist/utils/createCodeNode.d.ts +0 -12
  126. package/dist/utils/createCodeNode.d.ts.map +0 -1
  127. package/dist/utils/createCodeNode.js +0 -12
  128. package/dist/utils/createCodeNode.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"DiffHunksRenderer.js","names":["EXPANDED_REGION: ExpansionRegion","options: BaseDiffOptions","onRenderUpdate?: () => unknown","workerManager?: WorkerPoolManager | undefined","options","options: RenderDiffOptions","additionsAST: ElementContent[] | undefined","deletionsAST: ElementContent[] | undefined","unifiedAST: ElementContent[] | undefined","hunkData: HunkData[]","prevHunk: Hunk | undefined","oldLine: ElementContent | undefined","newLine: ElementContent | undefined","oldLine","newLine","deletionSpan: AnnotationSpan","additionSpan: AnnotationSpan"],"sources":["../../src/renderers/DiffHunksRenderer.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement } from 'hast';\nimport { toHtml } from 'hast-util-to-html';\n\nimport { DEFAULT_THEMES } from '../constants';\nimport { areLanguagesAttached } from '../highlighter/languages/areLanguagesAttached';\nimport {\n getHighlighterIfLoaded,\n getSharedHighlighter,\n} from '../highlighter/shared_highlighter';\nimport { areThemesAttached } from '../highlighter/themes/areThemesAttached';\nimport type {\n AnnotationLineMap,\n AnnotationSpan,\n BaseDiffOptions,\n DiffLineAnnotation,\n DiffsHighlighter,\n ExpansionDirections,\n FileDiffMetadata,\n Hunk,\n HunkData,\n RenderDiffFilesResult,\n RenderDiffHunksResult,\n RenderDiffOptions,\n RenderDiffResult,\n RenderedDiffASTCache,\n SupportedLanguages,\n ThemeTypes,\n ThemedDiffResult,\n} from '../types';\nimport { areThemesEqual } from '../utils/areThemesEqual';\nimport { createAnnotationElement } from '../utils/createAnnotationElement';\nimport { createEmptyRowBuffer } from '../utils/createEmptyRowBuffer';\nimport { createFileHeaderElement } from '../utils/createFileHeaderElement';\nimport { createNoNewlineElement } from '../utils/createNoNewlineElement';\nimport { createPreElement } from '../utils/createPreElement';\nimport { createSeparator } from '../utils/createSeparator';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { getHighlighterOptions } from '../utils/getHighlighterOptions';\nimport { getHunkSeparatorSlotName } from '../utils/getHunkSeparatorSlotName';\nimport { getLineAnnotationName } from '../utils/getLineAnnotationName';\nimport { getTotalLineCountFromHunks } from '../utils/getTotalLineCountFromHunks';\nimport { createHastElement } from '../utils/hast_utils';\nimport { renderDiffWithHighlighter } from '../utils/renderDiffWithHighlighter';\nimport type { WorkerPoolManager } from '../worker';\n\nconst EXPANDED_REGION: ExpansionRegion = {\n fromStart: 0,\n fromEnd: 0,\n};\n\ninterface PushHunkSeparatorProps {\n type: 'additions' | 'deletions' | 'unified';\n linesAST: ElementContent[];\n}\n\ninterface RenderRangeProps {\n rangeLen: number;\n fromStart: boolean;\n}\n\ninterface PushLineWithAnnotation {\n newLine?: ElementContent;\n oldLine?: ElementContent;\n\n unifiedAST?: ElementContent[];\n deletionsAST?: ElementContent[];\n additionsAST?: ElementContent[];\n\n unifiedSpan?: AnnotationSpan;\n deletionSpan?: AnnotationSpan;\n additionSpan?: AnnotationSpan;\n}\n\ninterface RenderCollapsedHunksProps {\n ast: RenderDiffFilesResult | RenderDiffHunksResult;\n hunkData: HunkData[];\n hunkIndex: number;\n hunkSpecs: string | undefined;\n isFirstHunk: boolean;\n isLastHunk: boolean;\n rangeSize: number;\n\n lineIndex: number;\n additionLineNumber: number;\n deletionLineNumber: number;\n\n additionsAST: ElementContent[];\n deletionsAST: ElementContent[];\n unifiedAST: ElementContent[];\n}\n\ninterface RenderHunkProps {\n hunk: Hunk;\n hunkData: HunkData[];\n hunkIndex: number;\n lineIndex: number;\n isLastHunk: boolean;\n prevHunk: Hunk | undefined;\n\n ast: RenderDiffFilesResult | RenderDiffHunksResult;\n unifiedAST: ElementContent[];\n deletionsAST: ElementContent[];\n additionsAST: ElementContent[];\n}\n\ninterface GetRenderOptionsReturn {\n options: RenderDiffOptions;\n forceRender: boolean;\n}\n\ntype OptionsWithDefaults = Required<\n Omit<BaseDiffOptions, 'lang' | 'unsafeCSS'>\n>;\n\ninterface ExpansionRegion {\n fromStart: number;\n fromEnd: number;\n}\n\nexport interface HunksRenderResult {\n additionsAST: ElementContent[] | undefined;\n deletionsAST: ElementContent[] | undefined;\n unifiedAST: ElementContent[] | undefined;\n hunkData: HunkData[];\n css: string;\n preNode: HASTElement;\n headerElement: HASTElement | undefined;\n totalLines: number;\n themeStyles: string;\n baseThemeType: 'light' | 'dark' | undefined;\n}\n\nexport class DiffHunksRenderer<LAnnotation = undefined> {\n private highlighter: DiffsHighlighter | undefined;\n private diff: FileDiffMetadata | undefined;\n\n private expandedHunks = new Map<number, ExpansionRegion>();\n\n private deletionAnnotations: AnnotationLineMap<LAnnotation> = {};\n private additionAnnotations: AnnotationLineMap<LAnnotation> = {};\n\n private computedLang: SupportedLanguages = 'text';\n private renderCache: RenderedDiffASTCache | undefined;\n\n constructor(\n public options: BaseDiffOptions = { theme: DEFAULT_THEMES },\n private onRenderUpdate?: () => unknown,\n private workerManager?: WorkerPoolManager | undefined\n ) {\n if (workerManager?.isWorkingPool() !== true) {\n this.highlighter = areThemesAttached(options.theme ?? DEFAULT_THEMES)\n ? getHighlighterIfLoaded()\n : undefined;\n }\n }\n\n cleanUp(): void {\n this.highlighter = undefined;\n this.diff = undefined;\n this.renderCache = undefined;\n this.workerManager = undefined;\n this.onRenderUpdate = undefined;\n }\n\n setOptions(options: BaseDiffOptions): void {\n this.options = options;\n }\n\n private mergeOptions(options: Partial<BaseDiffOptions>) {\n this.options = { ...this.options, ...options };\n }\n\n setThemeType(themeType: ThemeTypes): void {\n if (this.getOptionsWithDefaults().themeType === themeType) {\n return;\n }\n this.mergeOptions({ themeType });\n }\n\n expandHunk(index: number, direction: ExpansionDirections): void {\n const { expansionLineCount } = this.getOptionsWithDefaults();\n const region = this.expandedHunks.get(index) ?? {\n fromStart: 0,\n fromEnd: 0,\n };\n if (direction === 'up' || direction === 'both') {\n region.fromStart += expansionLineCount;\n }\n if (direction === 'down' || direction === 'both') {\n region.fromEnd += expansionLineCount;\n }\n this.expandedHunks.set(index, region);\n }\n\n setLineAnnotations(lineAnnotations: DiffLineAnnotation<LAnnotation>[]): void {\n this.additionAnnotations = {};\n this.deletionAnnotations = {};\n for (const annotation of lineAnnotations) {\n const map = ((): AnnotationLineMap<LAnnotation> => {\n switch (annotation.side) {\n case 'deletions':\n return this.deletionAnnotations;\n case 'additions':\n return this.additionAnnotations;\n }\n })();\n const arr = map[annotation.lineNumber] ?? [];\n map[annotation.lineNumber] = arr;\n arr.push(annotation);\n }\n }\n\n getOptionsWithDefaults(): OptionsWithDefaults {\n const {\n diffIndicators = 'bars',\n diffStyle = 'split',\n disableBackground = false,\n disableFileHeader = false,\n disableLineNumbers = false,\n expandUnchanged = false,\n expansionLineCount = 100,\n hunkSeparators = 'line-info',\n lineDiffType = 'word-alt',\n maxLineDiffLength = 1000,\n overflow = 'scroll',\n theme = DEFAULT_THEMES,\n themeType = 'system',\n tokenizeMaxLineLength = 1000,\n useCSSClasses = false,\n } = this.options;\n return {\n diffIndicators,\n diffStyle,\n disableBackground,\n disableFileHeader,\n disableLineNumbers,\n expandUnchanged,\n expansionLineCount,\n hunkSeparators,\n lineDiffType,\n maxLineDiffLength,\n overflow,\n theme: this.workerManager?.getDiffRenderOptions().theme ?? theme,\n themeType,\n tokenizeMaxLineLength,\n useCSSClasses,\n };\n }\n\n async initializeHighlighter(): Promise<DiffsHighlighter> {\n this.highlighter = await getSharedHighlighter(\n getHighlighterOptions(this.computedLang, this.options)\n );\n return this.highlighter;\n }\n\n hydrate(diff: FileDiffMetadata | undefined): void {\n if (diff == null) {\n return;\n }\n this.diff = diff;\n const { options } = this.getRenderOptions(diff);\n let cache = this.workerManager?.getDiffResultCache(diff);\n if (cache != null && !areRenderOptionsEqual(options, cache.options)) {\n cache = undefined;\n }\n this.renderCache ??= {\n diff,\n // NOTE(amadeus): If we're hydrating, we can assume there was\n // pre-rendered HTML, otherwise one should not be hydrating\n highlighted: true,\n options,\n result: cache?.result,\n };\n if (\n this.workerManager?.isWorkingPool() === true &&\n this.renderCache.result == null\n ) {\n this.workerManager.highlightDiffAST(this, this.diff);\n } else {\n void this.asyncHighlight(diff).then(({ result, options }) => {\n this.onHighlightSuccess(diff, result, options);\n });\n }\n }\n\n private getRenderOptions(diff: FileDiffMetadata): GetRenderOptionsReturn {\n const options: RenderDiffOptions = (() => {\n if (this.workerManager?.isWorkingPool() === true) {\n return this.workerManager.getDiffRenderOptions();\n }\n const { theme, tokenizeMaxLineLength, lineDiffType } =\n this.getOptionsWithDefaults();\n return { theme, tokenizeMaxLineLength, lineDiffType };\n })();\n this.getOptionsWithDefaults();\n const { renderCache } = this;\n if (renderCache?.result == null) {\n return { options, forceRender: true };\n }\n if (\n diff !== renderCache.diff ||\n !areRenderOptionsEqual(options, renderCache.options)\n ) {\n return { options, forceRender: true };\n }\n return { options, forceRender: false };\n }\n\n renderDiff(\n diff: FileDiffMetadata | undefined = this.renderCache?.diff\n ): HunksRenderResult | undefined {\n if (diff == null) {\n return undefined;\n }\n const cache = this.workerManager?.getDiffResultCache(diff);\n if (cache != null && this.renderCache == null) {\n this.renderCache = { diff, highlighted: true, ...cache };\n }\n const { options, forceRender } = this.getRenderOptions(diff);\n this.renderCache ??= {\n diff,\n highlighted: false,\n options,\n result: undefined,\n };\n if (this.workerManager?.isWorkingPool() === true) {\n this.renderCache.result ??= this.workerManager.getPlainDiffAST(diff);\n if (!this.renderCache.highlighted || forceRender) {\n this.workerManager.highlightDiffAST(this, diff);\n }\n } else {\n this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n const hasThemes =\n this.highlighter != null && areThemesAttached(options.theme);\n const hasLangs =\n this.highlighter != null && areLanguagesAttached(this.computedLang);\n\n // If we have any semblance of a highlighter with the correct theme(s)\n // attached, we can kick off some form of rendering. If we don't have\n // the correct language, then we can render plain text and after kick off\n // an async job to get the highlighted AST\n if (\n this.highlighter != null &&\n hasThemes &&\n (forceRender ||\n (!this.renderCache.highlighted && hasLangs) ||\n this.renderCache.result == null)\n ) {\n const { result, options } = this.renderDiffWithHighlighter(\n diff,\n this.highlighter,\n !hasLangs\n );\n this.renderCache = {\n diff,\n options,\n highlighted: hasLangs,\n result,\n };\n }\n\n // If we get in here it means we'll have to kick off an async highlight\n // process which will involve initializing the highlighter with new themes\n // and languages\n if (!hasThemes || !hasLangs) {\n void this.asyncHighlight(diff).then(({ result, options }) => {\n this.onHighlightSuccess(diff, result, options);\n });\n }\n }\n return this.renderCache.result != null\n ? this.processDiffResult(this.renderCache.diff, this.renderCache.result)\n : undefined;\n }\n\n async asyncRender(diff: FileDiffMetadata): Promise<HunksRenderResult> {\n const { result } = await this.asyncHighlight(diff);\n return this.processDiffResult(diff, result);\n }\n\n private createPreElement(\n split: boolean,\n totalLines: number,\n themeStyles: string,\n baseThemeType: 'light' | 'dark' | undefined\n ): HASTElement {\n const {\n diffIndicators,\n disableBackground,\n disableLineNumbers,\n overflow,\n themeType,\n } = this.getOptionsWithDefaults();\n return createPreElement({\n diffIndicators,\n disableBackground,\n disableLineNumbers,\n overflow,\n themeStyles,\n split,\n themeType: baseThemeType ?? themeType,\n totalLines,\n });\n }\n\n private async asyncHighlight(\n diff: FileDiffMetadata\n ): Promise<RenderDiffResult> {\n this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n const hasThemes =\n this.highlighter != null &&\n areThemesAttached(this.options.theme ?? DEFAULT_THEMES);\n const hasLangs =\n this.highlighter != null && areLanguagesAttached(this.computedLang);\n // If we don't have the required langs or themes, then we need to\n // initialize the highlighter to load the appropriate languages and themes\n if (this.highlighter == null || !hasThemes || !hasLangs) {\n this.highlighter = await this.initializeHighlighter();\n }\n return this.renderDiffWithHighlighter(diff, this.highlighter);\n }\n\n private renderDiffWithHighlighter(\n diff: FileDiffMetadata,\n highlighter: DiffsHighlighter,\n plainText = false\n ): RenderDiffResult {\n const { options } = this.getRenderOptions(diff);\n const result = renderDiffWithHighlighter(\n diff,\n highlighter,\n options,\n plainText\n );\n return { result, options };\n }\n\n onHighlightSuccess(\n diff: FileDiffMetadata,\n result: ThemedDiffResult,\n options: RenderDiffOptions\n ): void {\n // If renderCache was blown away, we can assume we've run cleanUp()\n if (this.renderCache == null) {\n return;\n }\n const triggerRenderUpdate =\n this.renderCache.diff !== diff ||\n !this.renderCache.highlighted ||\n !areRenderOptionsEqual(this.renderCache.options, options);\n\n this.renderCache = {\n diff,\n options,\n highlighted: true,\n result,\n };\n if (triggerRenderUpdate) {\n this.onRenderUpdate?.();\n }\n }\n\n onHighlightError(error: unknown): void {\n console.error(error);\n }\n\n private processDiffResult(\n fileDiff: FileDiffMetadata,\n { code, themeStyles, baseThemeType }: ThemedDiffResult\n ): HunksRenderResult {\n const { diffStyle, disableFileHeader } = this.getOptionsWithDefaults();\n\n this.diff = fileDiff;\n const unified = diffStyle === 'unified';\n\n let additionsAST: ElementContent[] | undefined = [];\n let deletionsAST: ElementContent[] | undefined = [];\n let unifiedAST: ElementContent[] | undefined = [];\n\n let hunkIndex = 0;\n const hunkData: HunkData[] = [];\n\n let prevHunk: Hunk | undefined;\n let lineIndex = 0;\n for (const hunk of fileDiff.hunks) {\n lineIndex += hunk.collapsedBefore;\n lineIndex = this.renderHunks({\n ast: code,\n hunk,\n prevHunk,\n hunkIndex,\n isLastHunk: hunkIndex === fileDiff.hunks.length - 1,\n additionsAST,\n deletionsAST,\n unifiedAST,\n hunkData,\n lineIndex,\n });\n hunkIndex++;\n prevHunk = hunk;\n }\n\n const totalLines = Math.max(\n getTotalLineCountFromHunks(fileDiff.hunks),\n fileDiff.newLines?.length ?? 0,\n fileDiff.oldLines?.length ?? 0\n );\n\n additionsAST =\n !unified && (code.hunks != null || code.newLines.length > 0)\n ? additionsAST\n : undefined;\n deletionsAST =\n !unified && (code.hunks != null || code.oldLines.length > 0)\n ? deletionsAST\n : undefined;\n unifiedAST = unifiedAST.length > 0 ? unifiedAST : undefined;\n\n const preNode = this.createPreElement(\n deletionsAST != null && additionsAST != null,\n totalLines,\n themeStyles,\n baseThemeType\n );\n\n return {\n additionsAST,\n deletionsAST,\n unifiedAST,\n hunkData,\n preNode,\n themeStyles,\n baseThemeType,\n headerElement: !disableFileHeader\n ? this.renderHeader(this.diff, themeStyles, baseThemeType)\n : undefined,\n totalLines,\n // FIXME\n css: '',\n };\n }\n\n renderFullAST(\n result: HunksRenderResult,\n children: ElementContent[] = []\n ): HASTElement {\n if (result.unifiedAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: result.unifiedAST,\n properties: {\n 'data-code': '',\n 'data-unified': '',\n },\n })\n );\n }\n if (result.deletionsAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: result.deletionsAST,\n properties: {\n 'data-code': '',\n 'data-deletions': '',\n },\n })\n );\n }\n if (result.additionsAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: result.additionsAST,\n properties: {\n 'data-code': '',\n 'data-additions': '',\n },\n })\n );\n }\n return { ...result.preNode, children };\n }\n\n renderFullHTML(\n result: HunksRenderResult,\n tempChildren: ElementContent[] = []\n ): string {\n return toHtml(this.renderFullAST(result, tempChildren));\n }\n\n renderPartialHTML(\n children: ElementContent[],\n columnType?: 'unified' | 'deletions' | 'additions'\n ): string {\n if (columnType == null) {\n return toHtml(children);\n }\n return toHtml(\n createHastElement({\n tagName: 'code',\n children,\n properties: {\n 'data-code': '',\n [`data-${columnType}`]: '',\n },\n })\n );\n }\n\n private renderCollapsedHunks({\n ast,\n hunkData,\n hunkIndex,\n hunkSpecs,\n isFirstHunk,\n isLastHunk,\n rangeSize,\n lineIndex,\n additionLineNumber,\n deletionLineNumber,\n unifiedAST,\n deletionsAST,\n additionsAST,\n }: RenderCollapsedHunksProps) {\n if (rangeSize <= 0) {\n return;\n }\n const { hunkSeparators, expandUnchanged, diffStyle, expansionLineCount } =\n this.getOptionsWithDefaults();\n const expandable =\n ast.hunks == null && ast.newLines.length > 0 && ast.oldLines.length > 0;\n const expandedRegion = this.expandedHunks.get(hunkIndex) ?? EXPANDED_REGION;\n const chunked = rangeSize > expansionLineCount;\n const collapsedLines = Math.max(\n !expandUnchanged\n ? rangeSize - (expandedRegion.fromEnd + expandedRegion.fromStart)\n : 0,\n 0\n );\n\n const pushHunkSeparator = ({ type, linesAST }: PushHunkSeparatorProps) => {\n if (hunkSeparators === 'line-info' || hunkSeparators === 'custom') {\n const slotName = getHunkSeparatorSlotName(type, hunkIndex);\n linesAST.push(\n createSeparator({\n type: hunkSeparators,\n content: getModifiedLinesString(collapsedLines),\n expandIndex: expandable ? hunkIndex : undefined,\n chunked,\n slotName,\n isFirstHunk,\n isLastHunk,\n })\n );\n hunkData.push({\n slotName,\n hunkIndex,\n lines: collapsedLines,\n type,\n expandable: expandable\n ? {\n up: expandable && !isFirstHunk,\n down: expandable,\n chunked,\n }\n : undefined,\n });\n } else if (hunkSeparators === 'metadata' && hunkSpecs != null) {\n linesAST.push(\n createSeparator({\n type: 'metadata',\n content: hunkSpecs,\n isFirstHunk,\n isLastHunk,\n })\n );\n } else if (hunkSeparators === 'simple' && hunkIndex > 0) {\n linesAST.push(\n createSeparator({ type: 'simple', isFirstHunk, isLastHunk: false })\n );\n }\n };\n\n const renderRange = ({ rangeLen, fromStart }: RenderRangeProps) => {\n if (ast.newLines == null || ast.oldLines == null) {\n return;\n }\n\n const offset = isLastHunk ? 0 : fromStart ? rangeSize : rangeLen;\n let dLineNumber = deletionLineNumber - offset;\n let aLineNumber = additionLineNumber - offset;\n let lIndex = lineIndex - offset;\n\n for (let i = 0; i < rangeLen; i++) {\n const oldLine = ast.oldLines[dLineNumber];\n const newLine = ast.newLines[aLineNumber];\n if (oldLine == null || newLine == null) {\n console.error({ aLineNumber, dLineNumber, ast });\n throw new Error(\n 'DiffHunksRenderer.renderHunks prefill context invalid. Must include data for old and new lines'\n );\n }\n dLineNumber++;\n aLineNumber++;\n\n if (diffStyle === 'unified') {\n this.pushLineWithAnnotation({\n newLine,\n unifiedAST,\n unifiedSpan: this.getAnnotations(\n 'unified',\n dLineNumber,\n aLineNumber,\n hunkIndex,\n lIndex\n ),\n });\n } else {\n this.pushLineWithAnnotation({\n newLine,\n oldLine,\n additionsAST,\n deletionsAST,\n ...this.getAnnotations(\n 'split',\n dLineNumber,\n aLineNumber,\n hunkIndex,\n lIndex\n ),\n });\n }\n lIndex++;\n }\n };\n\n if (expandable) {\n renderRange({\n rangeLen: Math.min(\n collapsedLines === 0 || expandUnchanged\n ? rangeSize\n : expandedRegion.fromStart,\n rangeSize\n ),\n fromStart: true,\n });\n }\n\n if (collapsedLines > 0) {\n if (diffStyle === 'unified') {\n pushHunkSeparator({ type: 'unified', linesAST: unifiedAST });\n } else {\n pushHunkSeparator({ type: 'deletions', linesAST: deletionsAST });\n pushHunkSeparator({ type: 'additions', linesAST: additionsAST });\n }\n }\n\n if (collapsedLines > 0 && expandedRegion.fromEnd > 0 && !isLastHunk) {\n renderRange({\n rangeLen: Math.min(expandedRegion.fromEnd, rangeSize),\n fromStart: false,\n });\n }\n }\n\n private renderHunks({\n hunk,\n hunkData,\n hunkIndex,\n lineIndex,\n isLastHunk,\n prevHunk,\n ast,\n deletionsAST,\n additionsAST,\n unifiedAST,\n }: RenderHunkProps): number {\n const { diffStyle } = this.getOptionsWithDefaults();\n const unified = diffStyle === 'unified';\n let additionLineNumber = hunk.additionStart - 1;\n let deletionLineNumber = hunk.deletionStart - 1;\n\n this.renderCollapsedHunks({\n additionLineNumber,\n additionsAST,\n ast,\n deletionLineNumber,\n deletionsAST,\n hunkData,\n hunkIndex,\n hunkSpecs: hunk.hunkSpecs,\n isFirstHunk: prevHunk == null,\n isLastHunk: false,\n lineIndex,\n rangeSize: Math.max(hunk.collapsedBefore, 0),\n unifiedAST,\n });\n\n let { oldLines, newLines, oldIndex, newIndex } = (() => {\n if (ast.hunks != null) {\n const lineHunk = ast.hunks[hunkIndex];\n if (lineHunk == null) {\n console.error({ ast, hunkIndex });\n throw new Error(\n `DiffHunksRenderer.renderHunks: lineHunk doesn't exist`\n );\n }\n return {\n oldLines: lineHunk.oldLines,\n newLines: lineHunk.newLines,\n oldIndex: 0,\n newIndex: 0,\n };\n }\n return {\n oldLines: ast.oldLines,\n newLines: ast.newLines,\n oldIndex: deletionLineNumber,\n newIndex: additionLineNumber,\n };\n })();\n\n // Render hunk/diff content\n for (const hunkContent of hunk.hunkContent) {\n if (hunkContent.type === 'context') {\n const { length: len } = hunkContent.lines;\n for (let i = 0; i < len; i++) {\n const oldLine = oldLines[oldIndex];\n const newLine = newLines[newIndex];\n oldIndex++;\n newIndex++;\n additionLineNumber++;\n deletionLineNumber++;\n if (unified) {\n if (newLine == null) {\n throw new Error(\n 'DiffHunksRenderer.renderHunks: newLine doesnt exist for context...'\n );\n }\n this.pushLineWithAnnotation({\n newLine,\n unifiedAST,\n unifiedSpan: this.getAnnotations(\n 'unified',\n deletionLineNumber,\n additionLineNumber,\n hunkIndex,\n lineIndex\n ),\n });\n } else {\n if (newLine == null || oldLine == null) {\n throw new Error(\n 'DiffHunksRenderer.renderHunks: newLine or oldLine doesnt exist for context...'\n );\n }\n this.pushLineWithAnnotation({\n oldLine,\n newLine,\n deletionsAST,\n additionsAST,\n ...this.getAnnotations(\n 'split',\n deletionLineNumber,\n additionLineNumber,\n hunkIndex,\n lineIndex\n ),\n });\n }\n lineIndex++;\n }\n if (hunkContent.noEOFCR) {\n const node = createNoNewlineElement('context');\n if (unified) {\n unifiedAST.push(node);\n } else {\n deletionsAST.push(node);\n additionsAST.push(node);\n }\n }\n } else {\n const { length: dLen } = hunkContent.deletions;\n const { length: aLen } = hunkContent.additions;\n const len = unified ? dLen + aLen : Math.max(dLen, aLen);\n let spanSize = 0;\n for (let i = 0; i < len; i++) {\n const { oldLine, newLine } = (() => {\n let oldLine: ElementContent | undefined = oldLines[oldIndex];\n let newLine: ElementContent | undefined = newLines[newIndex];\n if (unified) {\n if (i < dLen) {\n newLine = undefined;\n } else {\n oldLine = undefined;\n }\n } else {\n if (i >= dLen) {\n oldLine = undefined;\n }\n if (i >= aLen) {\n newLine = undefined;\n }\n }\n if (oldLine == null && newLine == null) {\n console.error({ i, len, ast, hunkContent });\n throw new Error(\n 'renderHunks: oldLine and newLine are null, something is wrong'\n );\n }\n return { oldLine, newLine };\n })();\n\n if (oldLine != null) {\n oldIndex++;\n deletionLineNumber++;\n }\n if (newLine != null) {\n newIndex++;\n additionLineNumber++;\n }\n\n if (unified) {\n this.pushLineWithAnnotation({\n oldLine,\n newLine,\n unifiedAST,\n unifiedSpan: this.getAnnotations(\n 'unified',\n oldLine != null ? deletionLineNumber : undefined,\n newLine != null ? additionLineNumber : undefined,\n hunkIndex,\n lineIndex\n ),\n });\n lineIndex++;\n } else {\n if (oldLine == null || newLine == null) {\n spanSize++;\n }\n const annotationSpans = this.getAnnotations(\n 'split',\n oldLine != null ? deletionLineNumber : undefined,\n newLine != null ? additionLineNumber : undefined,\n hunkIndex,\n lineIndex\n );\n if (annotationSpans != null) {\n if (spanSize > 0) {\n if (aLen > dLen) {\n deletionsAST.push(createEmptyRowBuffer(spanSize));\n } else {\n additionsAST.push(createEmptyRowBuffer(spanSize));\n }\n spanSize = 0;\n }\n }\n this.pushLineWithAnnotation({\n newLine,\n oldLine,\n deletionsAST,\n additionsAST,\n ...annotationSpans,\n });\n lineIndex++;\n }\n }\n if (!unified) {\n if (spanSize > 0) {\n if (aLen > dLen) {\n deletionsAST.push(createEmptyRowBuffer(spanSize));\n } else {\n additionsAST.push(createEmptyRowBuffer(spanSize));\n }\n spanSize = 0;\n }\n if (hunkContent.noEOFCRDeletions) {\n deletionsAST.push(createNoNewlineElement('change-deletion'));\n if (!hunkContent.noEOFCRAdditions) {\n additionsAST.push(createEmptyRowBuffer(1));\n }\n }\n if (hunkContent.noEOFCRAdditions) {\n additionsAST.push(createNoNewlineElement('change-addition'));\n if (!hunkContent.noEOFCRDeletions) {\n deletionsAST.push(createEmptyRowBuffer(1));\n }\n }\n }\n }\n }\n\n if (isLastHunk && ast.newLines != null && ast.newLines.length > 0) {\n this.renderCollapsedHunks({\n additionLineNumber,\n additionsAST,\n ast,\n deletionLineNumber,\n deletionsAST,\n hunkData,\n hunkIndex: hunkIndex + 1,\n hunkSpecs: undefined,\n isFirstHunk: false,\n isLastHunk: true,\n lineIndex,\n rangeSize: Math.max(\n ast.newLines.length -\n Math.max(hunk.additionStart + hunk.additionCount - 1, 0),\n 0\n ),\n unifiedAST,\n });\n }\n return lineIndex;\n }\n\n private pushLineWithAnnotation({\n newLine,\n oldLine,\n unifiedAST,\n additionsAST,\n deletionsAST,\n unifiedSpan,\n deletionSpan,\n additionSpan,\n }: PushLineWithAnnotation) {\n if (unifiedAST != null) {\n if (oldLine != null) {\n unifiedAST.push(oldLine);\n } else if (newLine != null) {\n unifiedAST.push(newLine);\n }\n if (unifiedSpan != null) {\n unifiedAST.push(createAnnotationElement(unifiedSpan));\n }\n } else if (deletionsAST != null && additionsAST != null) {\n if (oldLine != null) {\n deletionsAST.push(oldLine);\n }\n if (newLine != null) {\n additionsAST.push(newLine);\n }\n if (deletionSpan != null) {\n deletionsAST.push(createAnnotationElement(deletionSpan));\n }\n if (additionSpan != null) {\n additionsAST.push(createAnnotationElement(additionSpan));\n }\n }\n }\n\n private getAnnotations(\n type: 'unified',\n oldLineNumber: number | undefined,\n newLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ): AnnotationSpan | undefined;\n private getAnnotations(\n type: 'split',\n oldLineNumber: number | undefined,\n newLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ): { deletionSpan: AnnotationSpan; additionSpan: AnnotationSpan } | undefined;\n private getAnnotations(\n type: 'unified' | 'split',\n oldLineNumber: number | undefined,\n newLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ):\n | AnnotationSpan\n | { deletionSpan: AnnotationSpan; additionSpan: AnnotationSpan }\n | undefined {\n const deletionSpan: AnnotationSpan = {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: [],\n };\n if (oldLineNumber != null) {\n for (const anno of this.deletionAnnotations[oldLineNumber] ?? []) {\n deletionSpan.annotations.push(getLineAnnotationName(anno));\n }\n }\n const additionSpan: AnnotationSpan = {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: [],\n };\n if (newLineNumber != null) {\n for (const anno of this.additionAnnotations[newLineNumber] ?? []) {\n (type === 'unified' ? deletionSpan : additionSpan).annotations.push(\n getLineAnnotationName(anno)\n );\n }\n }\n if (type === 'unified') {\n if (deletionSpan.annotations.length > 0) {\n return deletionSpan;\n }\n return undefined;\n }\n if (\n additionSpan.annotations.length === 0 &&\n deletionSpan.annotations.length === 0\n ) {\n return undefined;\n }\n return { deletionSpan, additionSpan };\n }\n\n private renderHeader(\n diff: FileDiffMetadata,\n themeStyles: string,\n baseThemeType: 'light' | 'dark' | undefined\n ): HASTElement {\n const { themeType } = this.getOptionsWithDefaults();\n return createFileHeaderElement({\n fileOrDiff: diff,\n themeStyles,\n themeType: baseThemeType ?? themeType,\n });\n }\n}\n\nfunction areRenderOptionsEqual(\n optionsA: RenderDiffOptions,\n optionsB: RenderDiffOptions\n): boolean {\n return (\n areThemesEqual(optionsA.theme, optionsB.theme) &&\n optionsA.tokenizeMaxLineLength === optionsB.tokenizeMaxLineLength &&\n optionsA.lineDiffType === optionsB.lineDiffType\n );\n}\n\nfunction getModifiedLinesString(lines: number) {\n return `${lines} unmodified line${lines > 1 ? 's' : ''}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA6CA,MAAMA,kBAAmC;CACvC,WAAW;CACX,SAAS;CACV;AAoFD,IAAa,oBAAb,MAAwD;CACtD,AAAQ;CACR,AAAQ;CAER,AAAQ,gCAAgB,IAAI,KAA8B;CAE1D,AAAQ,sBAAsD,EAAE;CAChE,AAAQ,sBAAsD,EAAE;CAEhE,AAAQ,eAAmC;CAC3C,AAAQ;CAER,YACE,AAAOC,UAA2B,EAAE,OAAO,gBAAgB,EAC3D,AAAQC,gBACR,AAAQC,eACR;EAHO;EACC;EACA;AAER,MAAI,eAAe,eAAe,KAAK,KACrC,MAAK,cAAc,kBAAkB,QAAQ,SAAS,eAAe,GACjE,wBAAwB,GACxB;;CAIR,UAAgB;AACd,OAAK,cAAc;AACnB,OAAK,OAAO;AACZ,OAAK,cAAc;AACnB,OAAK,gBAAgB;AACrB,OAAK,iBAAiB;;CAGxB,WAAW,SAAgC;AACzC,OAAK,UAAU;;CAGjB,AAAQ,aAAa,SAAmC;AACtD,OAAK,UAAU;GAAE,GAAG,KAAK;GAAS,GAAG;GAAS;;CAGhD,aAAa,WAA6B;AACxC,MAAI,KAAK,wBAAwB,CAAC,cAAc,UAC9C;AAEF,OAAK,aAAa,EAAE,WAAW,CAAC;;CAGlC,WAAW,OAAe,WAAsC;EAC9D,MAAM,EAAE,uBAAuB,KAAK,wBAAwB;EAC5D,MAAM,SAAS,KAAK,cAAc,IAAI,MAAM,IAAI;GAC9C,WAAW;GACX,SAAS;GACV;AACD,MAAI,cAAc,QAAQ,cAAc,OACtC,QAAO,aAAa;AAEtB,MAAI,cAAc,UAAU,cAAc,OACxC,QAAO,WAAW;AAEpB,OAAK,cAAc,IAAI,OAAO,OAAO;;CAGvC,mBAAmB,iBAA0D;AAC3E,OAAK,sBAAsB,EAAE;AAC7B,OAAK,sBAAsB,EAAE;AAC7B,OAAK,MAAM,cAAc,iBAAiB;GACxC,MAAM,aAA6C;AACjD,YAAQ,WAAW,MAAnB;KACE,KAAK,YACH,QAAO,KAAK;KACd,KAAK,YACH,QAAO,KAAK;;OAEd;GACJ,MAAM,MAAM,IAAI,WAAW,eAAe,EAAE;AAC5C,OAAI,WAAW,cAAc;AAC7B,OAAI,KAAK,WAAW;;;CAIxB,yBAA8C;EAC5C,MAAM,EACJ,iBAAiB,QACjB,YAAY,SACZ,oBAAoB,OACpB,oBAAoB,OACpB,qBAAqB,OACrB,kBAAkB,OAClB,qBAAqB,KACrB,iBAAiB,aACjB,eAAe,YACf,oBAAoB,KACpB,WAAW,UACX,QAAQ,gBACR,YAAY,UACZ,wBAAwB,KACxB,gBAAgB,UACd,KAAK;AACT,SAAO;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,OAAO,KAAK,eAAe,sBAAsB,CAAC,SAAS;GAC3D;GACA;GACA;GACD;;CAGH,MAAM,wBAAmD;AACvD,OAAK,cAAc,MAAM,qBACvB,sBAAsB,KAAK,cAAc,KAAK,QAAQ,CACvD;AACD,SAAO,KAAK;;CAGd,QAAQ,MAA0C;AAChD,MAAI,QAAQ,KACV;AAEF,OAAK,OAAO;EACZ,MAAM,EAAE,YAAY,KAAK,iBAAiB,KAAK;EAC/C,IAAI,QAAQ,KAAK,eAAe,mBAAmB,KAAK;AACxD,MAAI,SAAS,QAAQ,CAAC,sBAAsB,SAAS,MAAM,QAAQ,CACjE,SAAQ;AAEV,OAAK,gBAAgB;GACnB;GAGA,aAAa;GACb;GACA,QAAQ,OAAO;GAChB;AACD,MACE,KAAK,eAAe,eAAe,KAAK,QACxC,KAAK,YAAY,UAAU,KAE3B,MAAK,cAAc,iBAAiB,MAAM,KAAK,KAAK;MAEpD,CAAK,KAAK,eAAe,KAAK,CAAC,MAAM,EAAE,QAAQ,yBAAc;AAC3D,QAAK,mBAAmB,MAAM,QAAQC,UAAQ;IAC9C;;CAIN,AAAQ,iBAAiB,MAAgD;EACvE,MAAMC,iBAAoC;AACxC,OAAI,KAAK,eAAe,eAAe,KAAK,KAC1C,QAAO,KAAK,cAAc,sBAAsB;GAElD,MAAM,EAAE,OAAO,uBAAuB,iBACpC,KAAK,wBAAwB;AAC/B,UAAO;IAAE;IAAO;IAAuB;IAAc;MACnD;AACJ,OAAK,wBAAwB;EAC7B,MAAM,EAAE,gBAAgB;AACxB,MAAI,aAAa,UAAU,KACzB,QAAO;GAAE;GAAS,aAAa;GAAM;AAEvC,MACE,SAAS,YAAY,QACrB,CAAC,sBAAsB,SAAS,YAAY,QAAQ,CAEpD,QAAO;GAAE;GAAS,aAAa;GAAM;AAEvC,SAAO;GAAE;GAAS,aAAa;GAAO;;CAGxC,WACE,OAAqC,KAAK,aAAa,MACxB;AAC/B,MAAI,QAAQ,KACV;EAEF,MAAM,QAAQ,KAAK,eAAe,mBAAmB,KAAK;AAC1D,MAAI,SAAS,QAAQ,KAAK,eAAe,KACvC,MAAK,cAAc;GAAE;GAAM,aAAa;GAAM,GAAG;GAAO;EAE1D,MAAM,EAAE,SAAS,gBAAgB,KAAK,iBAAiB,KAAK;AAC5D,OAAK,gBAAgB;GACnB;GACA,aAAa;GACb;GACA,QAAQ;GACT;AACD,MAAI,KAAK,eAAe,eAAe,KAAK,MAAM;AAChD,QAAK,YAAY,WAAW,KAAK,cAAc,gBAAgB,KAAK;AACpE,OAAI,CAAC,KAAK,YAAY,eAAe,YACnC,MAAK,cAAc,iBAAiB,MAAM,KAAK;SAE5C;AACL,QAAK,eAAe,KAAK,QAAQ,wBAAwB,KAAK,KAAK;GACnE,MAAM,YACJ,KAAK,eAAe,QAAQ,kBAAkB,QAAQ,MAAM;GAC9D,MAAM,WACJ,KAAK,eAAe,QAAQ,qBAAqB,KAAK,aAAa;AAMrE,OACE,KAAK,eAAe,QACpB,cACC,eACE,CAAC,KAAK,YAAY,eAAe,YAClC,KAAK,YAAY,UAAU,OAC7B;IACA,MAAM,EAAE,QAAQ,uBAAY,KAAK,0BAC/B,MACA,KAAK,aACL,CAAC,SACF;AACD,SAAK,cAAc;KACjB;KACA;KACA,aAAa;KACb;KACD;;AAMH,OAAI,CAAC,aAAa,CAAC,SACjB,CAAK,KAAK,eAAe,KAAK,CAAC,MAAM,EAAE,QAAQ,yBAAc;AAC3D,SAAK,mBAAmB,MAAM,QAAQD,UAAQ;KAC9C;;AAGN,SAAO,KAAK,YAAY,UAAU,OAC9B,KAAK,kBAAkB,KAAK,YAAY,MAAM,KAAK,YAAY,OAAO,GACtE;;CAGN,MAAM,YAAY,MAAoD;EACpE,MAAM,EAAE,WAAW,MAAM,KAAK,eAAe,KAAK;AAClD,SAAO,KAAK,kBAAkB,MAAM,OAAO;;CAG7C,AAAQ,iBACN,OACA,YACA,aACA,eACa;EACb,MAAM,EACJ,gBACA,mBACA,oBACA,UACA,cACE,KAAK,wBAAwB;AACjC,SAAO,iBAAiB;GACtB;GACA;GACA;GACA;GACA;GACA;GACA,WAAW,iBAAiB;GAC5B;GACD,CAAC;;CAGJ,MAAc,eACZ,MAC2B;AAC3B,OAAK,eAAe,KAAK,QAAQ,wBAAwB,KAAK,KAAK;EACnE,MAAM,YACJ,KAAK,eAAe,QACpB,kBAAkB,KAAK,QAAQ,SAAS,eAAe;EACzD,MAAM,WACJ,KAAK,eAAe,QAAQ,qBAAqB,KAAK,aAAa;AAGrE,MAAI,KAAK,eAAe,QAAQ,CAAC,aAAa,CAAC,SAC7C,MAAK,cAAc,MAAM,KAAK,uBAAuB;AAEvD,SAAO,KAAK,0BAA0B,MAAM,KAAK,YAAY;;CAG/D,AAAQ,0BACN,MACA,aACA,YAAY,OACM;EAClB,MAAM,EAAE,YAAY,KAAK,iBAAiB,KAAK;AAO/C,SAAO;GAAE,QANM,0BACb,MACA,aACA,SACA,UACD;GACgB;GAAS;;CAG5B,mBACE,MACA,QACA,SACM;AAEN,MAAI,KAAK,eAAe,KACtB;EAEF,MAAM,sBACJ,KAAK,YAAY,SAAS,QAC1B,CAAC,KAAK,YAAY,eAClB,CAAC,sBAAsB,KAAK,YAAY,SAAS,QAAQ;AAE3D,OAAK,cAAc;GACjB;GACA;GACA,aAAa;GACb;GACD;AACD,MAAI,oBACF,MAAK,kBAAkB;;CAI3B,iBAAiB,OAAsB;AACrC,UAAQ,MAAM,MAAM;;CAGtB,AAAQ,kBACN,UACA,EAAE,MAAM,aAAa,iBACF;EACnB,MAAM,EAAE,WAAW,sBAAsB,KAAK,wBAAwB;AAEtE,OAAK,OAAO;EACZ,MAAM,UAAU,cAAc;EAE9B,IAAIE,eAA6C,EAAE;EACnD,IAAIC,eAA6C,EAAE;EACnD,IAAIC,aAA2C,EAAE;EAEjD,IAAI,YAAY;EAChB,MAAMC,WAAuB,EAAE;EAE/B,IAAIC;EACJ,IAAI,YAAY;AAChB,OAAK,MAAM,QAAQ,SAAS,OAAO;AACjC,gBAAa,KAAK;AAClB,eAAY,KAAK,YAAY;IAC3B,KAAK;IACL;IACA;IACA;IACA,YAAY,cAAc,SAAS,MAAM,SAAS;IAClD;IACA;IACA;IACA;IACA;IACD,CAAC;AACF;AACA,cAAW;;EAGb,MAAM,aAAa,KAAK,IACtB,2BAA2B,SAAS,MAAM,EAC1C,SAAS,UAAU,UAAU,GAC7B,SAAS,UAAU,UAAU,EAC9B;AAED,iBACE,CAAC,YAAY,KAAK,SAAS,QAAQ,KAAK,SAAS,SAAS,KACtD,eACA;AACN,iBACE,CAAC,YAAY,KAAK,SAAS,QAAQ,KAAK,SAAS,SAAS,KACtD,eACA;AACN,eAAa,WAAW,SAAS,IAAI,aAAa;EAElD,MAAM,UAAU,KAAK,iBACnB,gBAAgB,QAAQ,gBAAgB,MACxC,YACA,aACA,cACD;AAED,SAAO;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA,eAAe,CAAC,oBACZ,KAAK,aAAa,KAAK,MAAM,aAAa,cAAc,GACxD;GACJ;GAEA,KAAK;GACN;;CAGH,cACE,QACA,WAA6B,EAAE,EAClB;AACb,MAAI,OAAO,cAAc,KACvB,UAAS,KACP,kBAAkB;GAChB,SAAS;GACT,UAAU,OAAO;GACjB,YAAY;IACV,aAAa;IACb,gBAAgB;IACjB;GACF,CAAC,CACH;AAEH,MAAI,OAAO,gBAAgB,KACzB,UAAS,KACP,kBAAkB;GAChB,SAAS;GACT,UAAU,OAAO;GACjB,YAAY;IACV,aAAa;IACb,kBAAkB;IACnB;GACF,CAAC,CACH;AAEH,MAAI,OAAO,gBAAgB,KACzB,UAAS,KACP,kBAAkB;GAChB,SAAS;GACT,UAAU,OAAO;GACjB,YAAY;IACV,aAAa;IACb,kBAAkB;IACnB;GACF,CAAC,CACH;AAEH,SAAO;GAAE,GAAG,OAAO;GAAS;GAAU;;CAGxC,eACE,QACA,eAAiC,EAAE,EAC3B;AACR,SAAO,OAAO,KAAK,cAAc,QAAQ,aAAa,CAAC;;CAGzD,kBACE,UACA,YACQ;AACR,MAAI,cAAc,KAChB,QAAO,OAAO,SAAS;AAEzB,SAAO,OACL,kBAAkB;GAChB,SAAS;GACT;GACA,YAAY;IACV,aAAa;KACZ,QAAQ,eAAe;IACzB;GACF,CAAC,CACH;;CAGH,AAAQ,qBAAqB,EAC3B,KACA,UACA,WACA,WACA,aACA,YACA,WACA,WACA,oBACA,oBACA,YACA,cACA,gBAC4B;AAC5B,MAAI,aAAa,EACf;EAEF,MAAM,EAAE,gBAAgB,iBAAiB,WAAW,uBAClD,KAAK,wBAAwB;EAC/B,MAAM,aACJ,IAAI,SAAS,QAAQ,IAAI,SAAS,SAAS,KAAK,IAAI,SAAS,SAAS;EACxE,MAAM,iBAAiB,KAAK,cAAc,IAAI,UAAU,IAAI;EAC5D,MAAM,UAAU,YAAY;EAC5B,MAAM,iBAAiB,KAAK,IAC1B,CAAC,kBACG,aAAa,eAAe,UAAU,eAAe,aACrD,GACJ,EACD;EAED,MAAM,qBAAqB,EAAE,MAAM,eAAuC;AACxE,OAAI,mBAAmB,eAAe,mBAAmB,UAAU;IACjE,MAAM,WAAW,yBAAyB,MAAM,UAAU;AAC1D,aAAS,KACP,gBAAgB;KACd,MAAM;KACN,SAAS,uBAAuB,eAAe;KAC/C,aAAa,aAAa,YAAY;KACtC;KACA;KACA;KACA;KACD,CAAC,CACH;AACD,aAAS,KAAK;KACZ;KACA;KACA,OAAO;KACP;KACA,YAAY,aACR;MACE,IAAI,cAAc,CAAC;MACnB,MAAM;MACN;MACD,GACD;KACL,CAAC;cACO,mBAAmB,cAAc,aAAa,KACvD,UAAS,KACP,gBAAgB;IACd,MAAM;IACN,SAAS;IACT;IACA;IACD,CAAC,CACH;YACQ,mBAAmB,YAAY,YAAY,EACpD,UAAS,KACP,gBAAgB;IAAE,MAAM;IAAU;IAAa,YAAY;IAAO,CAAC,CACpE;;EAIL,MAAM,eAAe,EAAE,UAAU,gBAAkC;AACjE,OAAI,IAAI,YAAY,QAAQ,IAAI,YAAY,KAC1C;GAGF,MAAM,SAAS,aAAa,IAAI,YAAY,YAAY;GACxD,IAAI,cAAc,qBAAqB;GACvC,IAAI,cAAc,qBAAqB;GACvC,IAAI,SAAS,YAAY;AAEzB,QAAK,IAAI,IAAI,GAAG,IAAI,UAAU,KAAK;IACjC,MAAM,UAAU,IAAI,SAAS;IAC7B,MAAM,UAAU,IAAI,SAAS;AAC7B,QAAI,WAAW,QAAQ,WAAW,MAAM;AACtC,aAAQ,MAAM;MAAE;MAAa;MAAa;MAAK,CAAC;AAChD,WAAM,IAAI,MACR,iGACD;;AAEH;AACA;AAEA,QAAI,cAAc,UAChB,MAAK,uBAAuB;KAC1B;KACA;KACA,aAAa,KAAK,eAChB,WACA,aACA,aACA,WACA,OACD;KACF,CAAC;QAEF,MAAK,uBAAuB;KAC1B;KACA;KACA;KACA;KACA,GAAG,KAAK,eACN,SACA,aACA,aACA,WACA,OACD;KACF,CAAC;AAEJ;;;AAIJ,MAAI,WACF,aAAY;GACV,UAAU,KAAK,IACb,mBAAmB,KAAK,kBACpB,YACA,eAAe,WACnB,UACD;GACD,WAAW;GACZ,CAAC;AAGJ,MAAI,iBAAiB,EACnB,KAAI,cAAc,UAChB,mBAAkB;GAAE,MAAM;GAAW,UAAU;GAAY,CAAC;OACvD;AACL,qBAAkB;IAAE,MAAM;IAAa,UAAU;IAAc,CAAC;AAChE,qBAAkB;IAAE,MAAM;IAAa,UAAU;IAAc,CAAC;;AAIpE,MAAI,iBAAiB,KAAK,eAAe,UAAU,KAAK,CAAC,WACvD,aAAY;GACV,UAAU,KAAK,IAAI,eAAe,SAAS,UAAU;GACrD,WAAW;GACZ,CAAC;;CAIN,AAAQ,YAAY,EAClB,MACA,UACA,WACA,WACA,YACA,UACA,KACA,cACA,cACA,cAC0B;EAC1B,MAAM,EAAE,cAAc,KAAK,wBAAwB;EACnD,MAAM,UAAU,cAAc;EAC9B,IAAI,qBAAqB,KAAK,gBAAgB;EAC9C,IAAI,qBAAqB,KAAK,gBAAgB;AAE9C,OAAK,qBAAqB;GACxB;GACA;GACA;GACA;GACA;GACA;GACA;GACA,WAAW,KAAK;GAChB,aAAa,YAAY;GACzB,YAAY;GACZ;GACA,WAAW,KAAK,IAAI,KAAK,iBAAiB,EAAE;GAC5C;GACD,CAAC;EAEF,IAAI,EAAE,UAAU,UAAU,UAAU,oBAAoB;AACtD,OAAI,IAAI,SAAS,MAAM;IACrB,MAAM,WAAW,IAAI,MAAM;AAC3B,QAAI,YAAY,MAAM;AACpB,aAAQ,MAAM;MAAE;MAAK;MAAW,CAAC;AACjC,WAAM,IAAI,MACR,wDACD;;AAEH,WAAO;KACL,UAAU,SAAS;KACnB,UAAU,SAAS;KACnB,UAAU;KACV,UAAU;KACX;;AAEH,UAAO;IACL,UAAU,IAAI;IACd,UAAU,IAAI;IACd,UAAU;IACV,UAAU;IACX;MACC;AAGJ,OAAK,MAAM,eAAe,KAAK,YAC7B,KAAI,YAAY,SAAS,WAAW;GAClC,MAAM,EAAE,QAAQ,QAAQ,YAAY;AACpC,QAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK;IAC5B,MAAM,UAAU,SAAS;IACzB,MAAM,UAAU,SAAS;AACzB;AACA;AACA;AACA;AACA,QAAI,SAAS;AACX,SAAI,WAAW,KACb,OAAM,IAAI,MACR,qEACD;AAEH,UAAK,uBAAuB;MAC1B;MACA;MACA,aAAa,KAAK,eAChB,WACA,oBACA,oBACA,WACA,UACD;MACF,CAAC;WACG;AACL,SAAI,WAAW,QAAQ,WAAW,KAChC,OAAM,IAAI,MACR,gFACD;AAEH,UAAK,uBAAuB;MAC1B;MACA;MACA;MACA;MACA,GAAG,KAAK,eACN,SACA,oBACA,oBACA,WACA,UACD;MACF,CAAC;;AAEJ;;AAEF,OAAI,YAAY,SAAS;IACvB,MAAM,OAAO,uBAAuB,UAAU;AAC9C,QAAI,QACF,YAAW,KAAK,KAAK;SAChB;AACL,kBAAa,KAAK,KAAK;AACvB,kBAAa,KAAK,KAAK;;;SAGtB;GACL,MAAM,EAAE,QAAQ,SAAS,YAAY;GACrC,MAAM,EAAE,QAAQ,SAAS,YAAY;GACrC,MAAM,MAAM,UAAU,OAAO,OAAO,KAAK,IAAI,MAAM,KAAK;GACxD,IAAI,WAAW;AACf,QAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK;IAC5B,MAAM,EAAE,SAAS,mBAAmB;KAClC,IAAIC,YAAsC,SAAS;KACnD,IAAIC,YAAsC,SAAS;AACnD,SAAI,QACF,KAAI,IAAI,KACN,aAAU;SAEV,aAAU;UAEP;AACL,UAAI,KAAK,KACP,aAAU;AAEZ,UAAI,KAAK,KACP,aAAU;;AAGd,SAAIC,aAAW,QAAQC,aAAW,MAAM;AACtC,cAAQ,MAAM;OAAE;OAAG;OAAK;OAAK;OAAa,CAAC;AAC3C,YAAM,IAAI,MACR,gEACD;;AAEH,YAAO;MAAE;MAAS;MAAS;QACzB;AAEJ,QAAI,WAAW,MAAM;AACnB;AACA;;AAEF,QAAI,WAAW,MAAM;AACnB;AACA;;AAGF,QAAI,SAAS;AACX,UAAK,uBAAuB;MAC1B;MACA;MACA;MACA,aAAa,KAAK,eAChB,WACA,WAAW,OAAO,qBAAqB,QACvC,WAAW,OAAO,qBAAqB,QACvC,WACA,UACD;MACF,CAAC;AACF;WACK;AACL,SAAI,WAAW,QAAQ,WAAW,KAChC;KAEF,MAAM,kBAAkB,KAAK,eAC3B,SACA,WAAW,OAAO,qBAAqB,QACvC,WAAW,OAAO,qBAAqB,QACvC,WACA,UACD;AACD,SAAI,mBAAmB,MACrB;UAAI,WAAW,GAAG;AAChB,WAAI,OAAO,KACT,cAAa,KAAK,qBAAqB,SAAS,CAAC;WAEjD,cAAa,KAAK,qBAAqB,SAAS,CAAC;AAEnD,kBAAW;;;AAGf,UAAK,uBAAuB;MAC1B;MACA;MACA;MACA;MACA,GAAG;MACJ,CAAC;AACF;;;AAGJ,OAAI,CAAC,SAAS;AACZ,QAAI,WAAW,GAAG;AAChB,SAAI,OAAO,KACT,cAAa,KAAK,qBAAqB,SAAS,CAAC;SAEjD,cAAa,KAAK,qBAAqB,SAAS,CAAC;AAEnD,gBAAW;;AAEb,QAAI,YAAY,kBAAkB;AAChC,kBAAa,KAAK,uBAAuB,kBAAkB,CAAC;AAC5D,SAAI,CAAC,YAAY,iBACf,cAAa,KAAK,qBAAqB,EAAE,CAAC;;AAG9C,QAAI,YAAY,kBAAkB;AAChC,kBAAa,KAAK,uBAAuB,kBAAkB,CAAC;AAC5D,SAAI,CAAC,YAAY,iBACf,cAAa,KAAK,qBAAqB,EAAE,CAAC;;;;AAOpD,MAAI,cAAc,IAAI,YAAY,QAAQ,IAAI,SAAS,SAAS,EAC9D,MAAK,qBAAqB;GACxB;GACA;GACA;GACA;GACA;GACA;GACA,WAAW,YAAY;GACvB,WAAW;GACX,aAAa;GACb,YAAY;GACZ;GACA,WAAW,KAAK,IACd,IAAI,SAAS,SACX,KAAK,IAAI,KAAK,gBAAgB,KAAK,gBAAgB,GAAG,EAAE,EAC1D,EACD;GACD;GACD,CAAC;AAEJ,SAAO;;CAGT,AAAQ,uBAAuB,EAC7B,SACA,SACA,YACA,cACA,cACA,aACA,cACA,gBACyB;AACzB,MAAI,cAAc,MAAM;AACtB,OAAI,WAAW,KACb,YAAW,KAAK,QAAQ;YACf,WAAW,KACpB,YAAW,KAAK,QAAQ;AAE1B,OAAI,eAAe,KACjB,YAAW,KAAK,wBAAwB,YAAY,CAAC;aAE9C,gBAAgB,QAAQ,gBAAgB,MAAM;AACvD,OAAI,WAAW,KACb,cAAa,KAAK,QAAQ;AAE5B,OAAI,WAAW,KACb,cAAa,KAAK,QAAQ;AAE5B,OAAI,gBAAgB,KAClB,cAAa,KAAK,wBAAwB,aAAa,CAAC;AAE1D,OAAI,gBAAgB,KAClB,cAAa,KAAK,wBAAwB,aAAa,CAAC;;;CAmB9D,AAAQ,eACN,MACA,eACA,eACA,WACA,WAIY;EACZ,MAAMC,eAA+B;GACnC,MAAM;GACN;GACA;GACA,aAAa,EAAE;GAChB;AACD,MAAI,iBAAiB,KACnB,MAAK,MAAM,QAAQ,KAAK,oBAAoB,kBAAkB,EAAE,CAC9D,cAAa,YAAY,KAAK,sBAAsB,KAAK,CAAC;EAG9D,MAAMC,eAA+B;GACnC,MAAM;GACN;GACA;GACA,aAAa,EAAE;GAChB;AACD,MAAI,iBAAiB,KACnB,MAAK,MAAM,QAAQ,KAAK,oBAAoB,kBAAkB,EAAE,CAC9D,EAAC,SAAS,YAAY,eAAe,cAAc,YAAY,KAC7D,sBAAsB,KAAK,CAC5B;AAGL,MAAI,SAAS,WAAW;AACtB,OAAI,aAAa,YAAY,SAAS,EACpC,QAAO;AAET;;AAEF,MACE,aAAa,YAAY,WAAW,KACpC,aAAa,YAAY,WAAW,EAEpC;AAEF,SAAO;GAAE;GAAc;GAAc;;CAGvC,AAAQ,aACN,MACA,aACA,eACa;EACb,MAAM,EAAE,cAAc,KAAK,wBAAwB;AACnD,SAAO,wBAAwB;GAC7B,YAAY;GACZ;GACA,WAAW,iBAAiB;GAC7B,CAAC;;;AAIN,SAAS,sBACP,UACA,UACS;AACT,QACE,eAAe,SAAS,OAAO,SAAS,MAAM,IAC9C,SAAS,0BAA0B,SAAS,yBAC5C,SAAS,iBAAiB,SAAS;;AAIvC,SAAS,uBAAuB,OAAe;AAC7C,QAAO,GAAG,MAAM,kBAAkB,QAAQ,IAAI,MAAM"}
1
+ {"version":3,"file":"DiffHunksRenderer.js","names":["DEFAULT_RENDER_RANGE: RenderRange","options: BaseDiffOptions","onRenderUpdate?: () => unknown","workerManager?: WorkerPoolManager | undefined","options","options: RenderDiffOptions","additionsAST: ElementContent[] | undefined","deletionsAST: ElementContent[] | undefined","unifiedAST: ElementContent[] | undefined","hunkData: HunkData[]","separatorContext: PushSeparatorContext","pendingSplitMissing: 'additions' | 'deletions' | undefined","lastHunkIndex: number | undefined","deletionSpan: AnnotationSpan","additionSpan: AnnotationSpan"],"sources":["../../src/renderers/DiffHunksRenderer.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement } from 'hast';\nimport { toHtml } from 'hast-util-to-html';\n\nimport { DEFAULT_EXPANDED_REGION, DEFAULT_THEMES } from '../constants';\nimport { areLanguagesAttached } from '../highlighter/languages/areLanguagesAttached';\nimport {\n getHighlighterIfLoaded,\n getSharedHighlighter,\n} from '../highlighter/shared_highlighter';\nimport { areThemesAttached } from '../highlighter/themes/areThemesAttached';\nimport type {\n AnnotationLineMap,\n AnnotationSpan,\n BaseDiffOptions,\n DiffLineAnnotation,\n DiffsHighlighter,\n ExpansionDirections,\n FileDiffMetadata,\n HunkData,\n HunkExpansionRegion,\n HunkSeparators,\n RenderDiffOptions,\n RenderDiffResult,\n RenderRange,\n RenderedDiffASTCache,\n SupportedLanguages,\n ThemeTypes,\n ThemedDiffResult,\n} from '../types';\nimport { areRenderRangesEqual } from '../utils/areRenderRangesEqual';\nimport { areThemesEqual } from '../utils/areThemesEqual';\nimport { createAnnotationElement } from '../utils/createAnnotationElement';\nimport { createEmptyRowBuffer } from '../utils/createEmptyRowBuffer';\nimport { createFileHeaderElement } from '../utils/createFileHeaderElement';\nimport { createNoNewlineElement } from '../utils/createNoNewlineElement';\nimport { createPreElement } from '../utils/createPreElement';\nimport { createSeparator } from '../utils/createSeparator';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { getHighlighterOptions } from '../utils/getHighlighterOptions';\nimport { getHunkSeparatorSlotName } from '../utils/getHunkSeparatorSlotName';\nimport { getLineAnnotationName } from '../utils/getLineAnnotationName';\nimport { getTotalLineCountFromHunks } from '../utils/getTotalLineCountFromHunks';\nimport { createBufferElement, createHastElement } from '../utils/hast_utils';\nimport { isDefaultRenderRange } from '../utils/isDefaultRenderRange';\nimport { iterateOverDiff } from '../utils/iterateOverDiff';\nimport { renderDiffWithHighlighter } from '../utils/renderDiffWithHighlighter';\nimport type { WorkerPoolManager } from '../worker';\n\ninterface PushLineWithAnnotation {\n deletionLine?: ElementContent;\n additionLine?: ElementContent;\n\n unifiedAST?: ElementContent[];\n deletionsAST?: ElementContent[];\n additionsAST?: ElementContent[];\n\n unifiedSpan?: AnnotationSpan;\n deletionSpan?: AnnotationSpan;\n additionSpan?: AnnotationSpan;\n}\n\nconst DEFAULT_RENDER_RANGE: RenderRange = {\n startingLine: 0,\n totalLines: Infinity,\n bufferBefore: 0,\n bufferAfter: 0,\n};\n\ninterface GetRenderOptionsReturn {\n options: RenderDiffOptions;\n forceRender: boolean;\n}\n\ninterface PushSeparatorProps {\n hunkIndex: number;\n collapsedLines: number;\n rangeSize: number;\n hunkSpecs: string | undefined;\n isFirstHunk: boolean;\n isLastHunk: boolean;\n isExpandable: boolean;\n}\n\ninterface PushSeparatorContext {\n expansionLineCount: number;\n hunkSeparators: HunkSeparators;\n unifiedAST: ElementContent[];\n deletionsAST: ElementContent[];\n additionsAST: ElementContent[];\n hunkData: HunkData[];\n}\n\ntype OptionsWithDefaults = Required<\n Omit<BaseDiffOptions, 'lang' | 'unsafeCSS'>\n>;\n\nexport interface HunksRenderResult {\n additionsAST: ElementContent[] | undefined;\n deletionsAST: ElementContent[] | undefined;\n unifiedAST: ElementContent[] | undefined;\n hunkData: HunkData[];\n css: string;\n preNode: HASTElement;\n headerElement: HASTElement | undefined;\n totalLines: number;\n themeStyles: string;\n baseThemeType: 'light' | 'dark' | undefined;\n}\n\nlet instanceId = -1;\n\nexport class DiffHunksRenderer<LAnnotation = undefined> {\n readonly __id: string = `diff-hunks-renderer:${++instanceId}`;\n\n private highlighter: DiffsHighlighter | undefined;\n private diff: FileDiffMetadata | undefined;\n\n private expandedHunks = new Map<number, HunkExpansionRegion>();\n\n private deletionAnnotations: AnnotationLineMap<LAnnotation> = {};\n private additionAnnotations: AnnotationLineMap<LAnnotation> = {};\n\n private computedLang: SupportedLanguages = 'text';\n private renderCache: RenderedDiffASTCache | undefined;\n\n constructor(\n public options: BaseDiffOptions = { theme: DEFAULT_THEMES },\n private onRenderUpdate?: () => unknown,\n private workerManager?: WorkerPoolManager | undefined\n ) {\n if (workerManager?.isWorkingPool() !== true) {\n this.highlighter = areThemesAttached(options.theme ?? DEFAULT_THEMES)\n ? getHighlighterIfLoaded()\n : undefined;\n }\n }\n\n cleanUp(): void {\n this.highlighter = undefined;\n this.diff = undefined;\n this.renderCache = undefined;\n this.workerManager?.cleanUpPendingTasks(this);\n this.workerManager = undefined;\n this.onRenderUpdate = undefined;\n }\n\n recycle(): void {\n this.highlighter = undefined;\n this.diff = undefined;\n this.renderCache = undefined;\n this.workerManager?.cleanUpPendingTasks(this);\n }\n\n setOptions(options: BaseDiffOptions): void {\n this.options = options;\n }\n\n private mergeOptions(options: Partial<BaseDiffOptions>) {\n this.options = { ...this.options, ...options };\n }\n\n setThemeType(themeType: ThemeTypes): void {\n if (this.getOptionsWithDefaults().themeType === themeType) {\n return;\n }\n this.mergeOptions({ themeType });\n }\n\n expandHunk(index: number, direction: ExpansionDirections): void {\n const { expansionLineCount } = this.getOptionsWithDefaults();\n const region = {\n ...(this.expandedHunks.get(index) ?? {\n fromStart: 0,\n fromEnd: 0,\n }),\n };\n if (direction === 'up' || direction === 'both') {\n region.fromStart += expansionLineCount;\n }\n if (direction === 'down' || direction === 'both') {\n region.fromEnd += expansionLineCount;\n }\n this.expandedHunks.set(index, region);\n }\n\n getExpandedHunk(hunkIndex: number): HunkExpansionRegion {\n return this.expandedHunks.get(hunkIndex) ?? DEFAULT_EXPANDED_REGION;\n }\n\n getExpandedHunksMap(): Map<number, HunkExpansionRegion> {\n return this.expandedHunks;\n }\n\n setLineAnnotations(lineAnnotations: DiffLineAnnotation<LAnnotation>[]): void {\n this.additionAnnotations = {};\n this.deletionAnnotations = {};\n for (const annotation of lineAnnotations) {\n const map = ((): AnnotationLineMap<LAnnotation> => {\n switch (annotation.side) {\n case 'deletions':\n return this.deletionAnnotations;\n case 'additions':\n return this.additionAnnotations;\n }\n })();\n const arr = map[annotation.lineNumber] ?? [];\n map[annotation.lineNumber] = arr;\n arr.push(annotation);\n }\n }\n\n getOptionsWithDefaults(): OptionsWithDefaults {\n const {\n diffIndicators = 'bars',\n diffStyle = 'split',\n disableBackground = false,\n disableFileHeader = false,\n disableLineNumbers = false,\n disableVirtualizationBuffers = false,\n expandUnchanged = false,\n expansionLineCount = 100,\n hunkSeparators = 'line-info',\n lineDiffType = 'word-alt',\n maxLineDiffLength = 1000,\n overflow = 'scroll',\n theme = DEFAULT_THEMES,\n themeType = 'system',\n tokenizeMaxLineLength = 1000,\n useCSSClasses = false,\n } = this.options;\n return {\n diffIndicators,\n diffStyle,\n disableBackground,\n disableFileHeader,\n disableLineNumbers,\n disableVirtualizationBuffers,\n expandUnchanged,\n expansionLineCount,\n hunkSeparators,\n lineDiffType,\n maxLineDiffLength,\n overflow,\n theme: this.workerManager?.getDiffRenderOptions().theme ?? theme,\n themeType,\n tokenizeMaxLineLength,\n useCSSClasses,\n };\n }\n\n async initializeHighlighter(): Promise<DiffsHighlighter> {\n this.highlighter = await getSharedHighlighter(\n getHighlighterOptions(this.computedLang, this.options)\n );\n return this.highlighter;\n }\n\n hydrate(diff: FileDiffMetadata | undefined): void {\n if (diff == null) {\n return;\n }\n this.diff = diff;\n const { options } = this.getRenderOptions(diff);\n let cache = this.workerManager?.getDiffResultCache(diff);\n if (cache != null && !areRenderOptionsEqual(options, cache.options)) {\n cache = undefined;\n }\n this.renderCache ??= {\n diff,\n // NOTE(amadeus): If we're hydrating, we can assume there was\n // pre-rendered HTML, otherwise one should not be hydrating\n highlighted: true,\n options,\n result: cache?.result,\n renderRange: undefined,\n };\n if (\n this.workerManager?.isWorkingPool() === true &&\n this.renderCache.result == null\n ) {\n this.workerManager.highlightDiffAST(this, this.diff);\n } else {\n void this.asyncHighlight(diff).then(({ result, options }) => {\n this.onHighlightSuccess(diff, result, options);\n });\n }\n }\n\n private getRenderOptions(diff: FileDiffMetadata): GetRenderOptionsReturn {\n const options: RenderDiffOptions = (() => {\n if (this.workerManager?.isWorkingPool() === true) {\n return this.workerManager.getDiffRenderOptions();\n }\n const { theme, tokenizeMaxLineLength, lineDiffType } =\n this.getOptionsWithDefaults();\n return { theme, tokenizeMaxLineLength, lineDiffType };\n })();\n this.getOptionsWithDefaults();\n const { renderCache } = this;\n if (renderCache?.result == null) {\n return { options, forceRender: true };\n }\n if (\n diff !== renderCache.diff ||\n !areRenderOptionsEqual(options, renderCache.options)\n ) {\n return { options, forceRender: true };\n }\n return { options, forceRender: false };\n }\n\n renderDiff(\n diff: FileDiffMetadata | undefined = this.renderCache?.diff,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): HunksRenderResult | undefined {\n if (diff == null) {\n return undefined;\n }\n const { expandUnchanged = false } = this.options;\n const cache = this.workerManager?.getDiffResultCache(diff);\n if (cache != null && this.renderCache == null) {\n this.renderCache = {\n diff,\n highlighted: true,\n renderRange: undefined,\n ...cache,\n };\n }\n const { options, forceRender } = this.getRenderOptions(diff);\n this.renderCache ??= {\n diff,\n highlighted: false,\n options,\n result: undefined,\n renderRange: undefined,\n };\n if (this.workerManager?.isWorkingPool() === true) {\n if (\n this.renderCache.result == null ||\n (!this.renderCache.highlighted &&\n !areRenderRangesEqual(this.renderCache.renderRange, renderRange))\n ) {\n this.renderCache.result = this.workerManager.getPlainDiffAST(\n diff,\n renderRange.startingLine,\n renderRange.totalLines,\n // If we aren't using a windowed render, then we need to render\n // everything\n isDefaultRenderRange(renderRange)\n ? true\n : expandUnchanged\n ? true\n : this.expandedHunks\n );\n this.renderCache.renderRange = renderRange;\n }\n if (\n // We should only attempt to kick off the worker highlighter if there\n // are lines to render\n renderRange.totalLines > 0 &&\n (!this.renderCache.highlighted || forceRender)\n ) {\n this.workerManager.highlightDiffAST(this, diff);\n }\n } else {\n this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n const hasThemes =\n this.highlighter != null && areThemesAttached(options.theme);\n const hasLangs =\n this.highlighter != null && areLanguagesAttached(this.computedLang);\n\n // If we have any semblance of a highlighter with the correct theme(s)\n // attached, we can kick off some form of rendering. If we don't have\n // the correct language, then we can render plain text and after kick off\n // an async job to get the highlighted AST\n if (\n this.highlighter != null &&\n hasThemes &&\n (forceRender ||\n (!this.renderCache.highlighted && hasLangs) ||\n this.renderCache.result == null)\n ) {\n const { result, options } = this.renderDiffWithHighlighter(\n diff,\n this.highlighter,\n !hasLangs\n );\n this.renderCache = {\n diff,\n options,\n highlighted: hasLangs,\n result,\n renderRange: undefined,\n };\n }\n\n // If we get in here it means we'll have to kick off an async highlight\n // process which will involve initializing the highlighter with new themes\n // and languages\n if (!hasThemes || !hasLangs) {\n void this.asyncHighlight(diff).then(({ result, options }) => {\n this.onHighlightSuccess(diff, result, options);\n });\n }\n }\n return this.renderCache.result != null\n ? this.processDiffResult(\n this.renderCache.diff,\n renderRange,\n this.renderCache.result\n )\n : undefined;\n }\n\n async asyncRender(\n diff: FileDiffMetadata,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): Promise<HunksRenderResult> {\n const { result } = await this.asyncHighlight(diff);\n return this.processDiffResult(diff, renderRange, result);\n }\n\n private createPreElement(\n split: boolean,\n totalLines: number,\n themeStyles: string,\n baseThemeType: 'light' | 'dark' | undefined\n ): HASTElement {\n const {\n diffIndicators,\n disableBackground,\n disableLineNumbers,\n overflow,\n themeType,\n } = this.getOptionsWithDefaults();\n return createPreElement({\n diffIndicators,\n disableBackground,\n disableLineNumbers,\n overflow,\n themeStyles,\n split,\n themeType: baseThemeType ?? themeType,\n totalLines,\n });\n }\n\n private async asyncHighlight(\n diff: FileDiffMetadata\n ): Promise<RenderDiffResult> {\n this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n const hasThemes =\n this.highlighter != null &&\n areThemesAttached(this.options.theme ?? DEFAULT_THEMES);\n const hasLangs =\n this.highlighter != null && areLanguagesAttached(this.computedLang);\n // If we don't have the required langs or themes, then we need to\n // initialize the highlighter to load the appropriate languages and themes\n if (this.highlighter == null || !hasThemes || !hasLangs) {\n this.highlighter = await this.initializeHighlighter();\n }\n return this.renderDiffWithHighlighter(diff, this.highlighter);\n }\n\n private renderDiffWithHighlighter(\n diff: FileDiffMetadata,\n highlighter: DiffsHighlighter,\n forcePlainText = false\n ): RenderDiffResult {\n const { options } = this.getRenderOptions(diff);\n const result = renderDiffWithHighlighter(diff, highlighter, options, {\n forcePlainText,\n expandedHunks: forcePlainText ? true : undefined,\n });\n return { result, options };\n }\n\n onHighlightSuccess(\n diff: FileDiffMetadata,\n result: ThemedDiffResult,\n options: RenderDiffOptions\n ): void {\n // If renderCache was blown away, we can assume we've run cleanUp()\n if (this.renderCache == null) {\n return;\n }\n const triggerRenderUpdate =\n this.renderCache.diff !== diff ||\n !this.renderCache.highlighted ||\n !areRenderOptionsEqual(this.renderCache.options, options);\n\n this.renderCache = {\n diff,\n options,\n highlighted: true,\n result,\n renderRange: undefined,\n };\n if (triggerRenderUpdate) {\n this.onRenderUpdate?.();\n }\n }\n\n onHighlightError(error: unknown): void {\n console.error(error);\n }\n\n private processDiffResult(\n fileDiff: FileDiffMetadata,\n renderRange: RenderRange,\n { code, themeStyles, baseThemeType }: ThemedDiffResult\n ): HunksRenderResult {\n const {\n diffStyle,\n disableFileHeader,\n disableVirtualizationBuffers,\n expandUnchanged,\n expansionLineCount,\n hunkSeparators,\n } = this.getOptionsWithDefaults();\n\n this.diff = fileDiff;\n const unified = diffStyle === 'unified';\n\n let additionsAST: ElementContent[] | undefined = [];\n let deletionsAST: ElementContent[] | undefined = [];\n let unifiedAST: ElementContent[] | undefined = [];\n\n const hunkData: HunkData[] = [];\n const { additionLines, deletionLines } = code;\n const separatorContext: PushSeparatorContext = {\n hunkSeparators,\n additionsAST,\n deletionsAST,\n unifiedAST,\n expansionLineCount,\n hunkData,\n };\n const trailingRangeSize = (() => {\n const lastHunk = fileDiff.hunks.at(-1);\n if (\n lastHunk == null ||\n fileDiff.isPartial ||\n fileDiff.additionLines.length === 0 ||\n fileDiff.deletionLines.length === 0\n ) {\n return 0;\n }\n const additionRemaining =\n fileDiff.additionLines.length -\n (lastHunk.additionLineIndex + lastHunk.additionCount);\n const deletionRemaining =\n fileDiff.deletionLines.length -\n (lastHunk.deletionLineIndex + lastHunk.deletionCount);\n if (additionRemaining !== deletionRemaining) {\n throw new Error(\n `DiffHunksRenderer.processDiffResult: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${fileDiff.name}`\n );\n }\n return Math.min(additionRemaining, deletionRemaining);\n })();\n\n let pendingSplitSpanSize = 0;\n let pendingSplitMissing: 'additions' | 'deletions' | undefined;\n let lastHunkIndex: number | undefined;\n\n function flushSplitSpan() {\n if (pendingSplitSpanSize <= 0 || pendingSplitMissing == null) {\n pendingSplitSpanSize = 0;\n pendingSplitMissing = undefined;\n return;\n }\n if (pendingSplitMissing === 'additions') {\n additionsAST?.push(createEmptyRowBuffer(pendingSplitSpanSize));\n } else {\n deletionsAST?.push(createEmptyRowBuffer(pendingSplitSpanSize));\n }\n pendingSplitSpanSize = 0;\n pendingSplitMissing = undefined;\n }\n\n function pushSeparators(props: PushSeparatorProps) {\n // NOTE(amadeus): This should technically never apply,\n // but just in case...\n flushSplitSpan();\n if (diffStyle === 'unified') {\n pushSeparator('unified', props, separatorContext);\n } else {\n pushSeparator('deletions', props, separatorContext);\n pushSeparator('additions', props, separatorContext);\n }\n }\n\n iterateOverDiff({\n diff: fileDiff,\n diffStyle,\n startingLine: renderRange.startingLine,\n totalLines: renderRange.totalLines,\n expandedHunks: expandUnchanged ? true : this.expandedHunks,\n callback: ({\n hunkIndex,\n hunk,\n collapsedBefore,\n collapsedAfter,\n unifiedDeletionLineIndex,\n unifiedAdditionLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n type,\n noEOFCRAddition,\n noEOFCRDeletion,\n }) => {\n if (diffStyle === 'split') {\n if (lastHunkIndex != null && lastHunkIndex !== hunkIndex) {\n flushSplitSpan();\n }\n if (type !== 'change') {\n flushSplitSpan();\n }\n }\n lastHunkIndex = hunkIndex;\n\n if (collapsedBefore > 0) {\n pushSeparators({\n hunkIndex,\n collapsedLines: collapsedBefore,\n rangeSize: Math.max(hunk?.collapsedBefore ?? 0, 0),\n hunkSpecs: hunk?.hunkSpecs,\n isFirstHunk: hunkIndex === 0,\n isLastHunk: false,\n isExpandable: !fileDiff.isPartial,\n });\n }\n\n const lineIndex =\n diffStyle === 'unified'\n ? (unifiedDeletionLineIndex ?? unifiedAdditionLineIndex)\n : splitLineIndex;\n\n if (lineIndex == null) {\n const errorMessage =\n 'DiffHunksRenderer.processDiffResult: iterateOverDiff, no valid line index';\n console.error(errorMessage, { file: fileDiff.name });\n throw new Error(errorMessage);\n }\n\n if (diffStyle === 'unified') {\n const deletionLine =\n additionLineIndex != null\n ? undefined\n : deletionLineIndex != null\n ? deletionLines[deletionLineIndex]\n : undefined;\n const additionLine =\n additionLineIndex != null\n ? additionLines[additionLineIndex]\n : undefined;\n\n if (deletionLine == null && additionLine == null) {\n const errorMessage =\n 'DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong';\n console.error(errorMessage, { file: fileDiff.name });\n throw new Error(errorMessage);\n }\n\n pushLineWithAnnotation({\n deletionLine,\n additionLine,\n unifiedAST,\n unifiedSpan: this.getAnnotations(\n 'unified',\n deletionLineNumber,\n additionLineNumber,\n hunkIndex,\n lineIndex\n ),\n });\n } else {\n const deletionLine =\n deletionLineIndex != null\n ? deletionLines[deletionLineIndex]\n : undefined;\n const additionLine =\n additionLineIndex != null\n ? additionLines[additionLineIndex]\n : undefined;\n\n if (deletionLine == null && additionLine == null) {\n const errorMessage =\n 'DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong';\n console.error(errorMessage, { file: fileDiff.name });\n throw new Error(errorMessage);\n }\n\n const missingSide =\n deletionLine == null\n ? 'deletions'\n : additionLine == null\n ? 'additions'\n : undefined;\n if (missingSide != null) {\n if (\n pendingSplitMissing != null &&\n pendingSplitMissing !== missingSide\n ) {\n // NOTE(amadeus): If we see this error, we might need to bring back: flushSplitSpan();\n throw new Error(\n 'DiffHunksRenderer.processDiffResult: iterateOverDiff, invalid pending splits'\n );\n }\n pendingSplitMissing = missingSide;\n pendingSplitSpanSize++;\n }\n\n const annotationSpans = this.getAnnotations(\n 'split',\n deletionLineNumber,\n additionLineNumber,\n hunkIndex,\n lineIndex\n );\n if (annotationSpans != null && pendingSplitSpanSize > 0) {\n flushSplitSpan();\n }\n pushLineWithAnnotation({\n additionLine,\n deletionLine,\n deletionsAST,\n additionsAST,\n ...annotationSpans,\n });\n }\n\n if (noEOFCRDeletion || noEOFCRAddition) {\n const noEOFType =\n type === 'context' || type === 'context-expanded'\n ? 'context'\n : deletionLineIndex != null\n ? 'change-deletion'\n : 'change-addition';\n if (noEOFCRDeletion) {\n if (diffStyle === 'unified') {\n unifiedAST?.push(createNoNewlineElement(noEOFType));\n } else {\n deletionsAST?.push(createNoNewlineElement('change-deletion'));\n if (!noEOFCRAddition) {\n additionsAST?.push(createEmptyRowBuffer(1));\n }\n }\n }\n if (noEOFCRAddition) {\n if (diffStyle === 'unified') {\n unifiedAST?.push(createNoNewlineElement('change-addition'));\n } else {\n additionsAST?.push(createNoNewlineElement('change-addition'));\n if (!noEOFCRDeletion) {\n deletionsAST?.push(createEmptyRowBuffer(1));\n }\n }\n }\n }\n\n if (collapsedAfter > 0) {\n pushSeparators({\n hunkIndex: type === 'context-expanded' ? hunkIndex : hunkIndex + 1,\n collapsedLines: collapsedAfter,\n rangeSize: trailingRangeSize,\n hunkSpecs: undefined,\n isFirstHunk: false,\n isLastHunk: true,\n isExpandable: !fileDiff.isPartial,\n });\n }\n },\n });\n\n if (diffStyle === 'split') {\n flushSplitSpan();\n }\n\n const totalLines = Math.max(\n getTotalLineCountFromHunks(fileDiff.hunks),\n fileDiff.additionLines.length ?? 0,\n fileDiff.deletionLines.length ?? 0\n );\n\n // Some specialized logic to set our AST lists to be undefinable under\n // certain conditions\n // * If the type of change is a full addition or a full deletion, we don't\n // want to show a split view as that creates wasted space\n // * We'll do some further refinement below if necessary with list length,\n // but first we need to inject buffers if we are virtualized before we can\n // do the length check\n additionsAST =\n !unified && fileDiff.type !== 'deleted' ? additionsAST : undefined;\n deletionsAST =\n !unified && fileDiff.type !== 'new' ? deletionsAST : undefined;\n unifiedAST = unified ? unifiedAST : undefined;\n\n if (!disableVirtualizationBuffers) {\n if (renderRange.bufferBefore > 0) {\n const element = createBufferElement('before', renderRange.bufferBefore);\n unifiedAST?.unshift(element);\n deletionsAST?.unshift(element);\n additionsAST?.unshift(element);\n }\n if (renderRange.bufferAfter > 0) {\n const element = createBufferElement('after', renderRange.bufferAfter);\n unifiedAST?.push(element);\n deletionsAST?.push(element);\n additionsAST?.push(element);\n }\n }\n\n // If any of our arrays are empty, lets null them out to optimize rendering\n if (unifiedAST?.length === 0) {\n unifiedAST = undefined;\n }\n if (deletionsAST?.length === 0) {\n deletionsAST = undefined;\n }\n if (additionsAST?.length === 0) {\n additionsAST = undefined;\n }\n\n const preNode = this.createPreElement(\n deletionsAST != null && additionsAST != null,\n totalLines,\n themeStyles,\n baseThemeType\n );\n\n return {\n additionsAST,\n deletionsAST,\n unifiedAST,\n hunkData,\n preNode,\n themeStyles,\n baseThemeType,\n headerElement: !disableFileHeader\n ? this.renderHeader(this.diff, themeStyles, baseThemeType)\n : undefined,\n totalLines,\n // FIXME\n css: '',\n };\n }\n\n renderFullAST(\n result: HunksRenderResult,\n children: ElementContent[] = []\n ): HASTElement {\n if (result.unifiedAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: result.unifiedAST,\n properties: {\n 'data-code': '',\n 'data-unified': '',\n },\n })\n );\n }\n if (result.deletionsAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: result.deletionsAST,\n properties: {\n 'data-code': '',\n 'data-deletions': '',\n },\n })\n );\n }\n if (result.additionsAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: result.additionsAST,\n properties: {\n 'data-code': '',\n 'data-additions': '',\n },\n })\n );\n }\n return { ...result.preNode, children };\n }\n\n renderFullHTML(\n result: HunksRenderResult,\n tempChildren: ElementContent[] = []\n ): string {\n return toHtml(this.renderFullAST(result, tempChildren));\n }\n\n renderPartialHTML(\n children: ElementContent[],\n columnType?: 'unified' | 'deletions' | 'additions'\n ): string {\n if (columnType == null) {\n return toHtml(children);\n }\n return toHtml(\n createHastElement({\n tagName: 'code',\n children,\n properties: {\n 'data-code': '',\n [`data-${columnType}`]: '',\n },\n })\n );\n }\n\n private getAnnotations(\n type: 'unified',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ): AnnotationSpan | undefined;\n private getAnnotations(\n type: 'split',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ): { deletionSpan: AnnotationSpan; additionSpan: AnnotationSpan } | undefined;\n private getAnnotations(\n type: 'unified' | 'split',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ):\n | AnnotationSpan\n | { deletionSpan: AnnotationSpan; additionSpan: AnnotationSpan }\n | undefined {\n const deletionSpan: AnnotationSpan = {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: [],\n };\n if (deletionLineNumber != null) {\n for (const anno of this.deletionAnnotations[deletionLineNumber] ?? []) {\n deletionSpan.annotations.push(getLineAnnotationName(anno));\n }\n }\n const additionSpan: AnnotationSpan = {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: [],\n };\n if (additionLineNumber != null) {\n for (const anno of this.additionAnnotations[additionLineNumber] ?? []) {\n (type === 'unified' ? deletionSpan : additionSpan).annotations.push(\n getLineAnnotationName(anno)\n );\n }\n }\n if (type === 'unified') {\n if (deletionSpan.annotations.length > 0) {\n return deletionSpan;\n }\n return undefined;\n }\n if (\n additionSpan.annotations.length === 0 &&\n deletionSpan.annotations.length === 0\n ) {\n return undefined;\n }\n return { deletionSpan, additionSpan };\n }\n\n private renderHeader(\n diff: FileDiffMetadata,\n themeStyles: string,\n baseThemeType: 'light' | 'dark' | undefined\n ): HASTElement {\n const { themeType } = this.getOptionsWithDefaults();\n return createFileHeaderElement({\n fileOrDiff: diff,\n themeStyles,\n themeType: baseThemeType ?? themeType,\n });\n }\n}\n\nfunction areRenderOptionsEqual(\n optionsA: RenderDiffOptions,\n optionsB: RenderDiffOptions\n): boolean {\n return (\n areThemesEqual(optionsA.theme, optionsB.theme) &&\n optionsA.tokenizeMaxLineLength === optionsB.tokenizeMaxLineLength &&\n optionsA.lineDiffType === optionsB.lineDiffType\n );\n}\n\nfunction getModifiedLinesString(lines: number) {\n return `${lines} unmodified line${lines > 1 ? 's' : ''}`;\n}\n\nfunction pushLineWithAnnotation({\n deletionLine,\n additionLine,\n unifiedAST,\n additionsAST,\n deletionsAST,\n unifiedSpan,\n deletionSpan,\n additionSpan,\n}: PushLineWithAnnotation) {\n if (unifiedAST != null) {\n if (deletionLine != null) {\n unifiedAST.push(deletionLine);\n } else if (additionLine != null) {\n unifiedAST.push(additionLine);\n }\n if (unifiedSpan != null) {\n unifiedAST.push(createAnnotationElement(unifiedSpan));\n }\n } else if (deletionsAST != null && additionsAST != null) {\n if (deletionLine != null) {\n deletionsAST.push(deletionLine);\n }\n if (additionLine != null) {\n additionsAST.push(additionLine);\n }\n if (deletionSpan != null) {\n deletionsAST.push(createAnnotationElement(deletionSpan));\n }\n if (additionSpan != null) {\n additionsAST.push(createAnnotationElement(additionSpan));\n }\n }\n}\n\nfunction pushSeparator(\n type: 'additions' | 'deletions' | 'unified',\n {\n hunkIndex,\n collapsedLines,\n rangeSize,\n hunkSpecs,\n isFirstHunk,\n isLastHunk,\n isExpandable,\n }: PushSeparatorProps,\n {\n expansionLineCount,\n hunkSeparators,\n unifiedAST,\n deletionsAST,\n additionsAST,\n hunkData,\n }: PushSeparatorContext\n) {\n if (collapsedLines <= 0) {\n return;\n }\n const linesAST =\n type === 'unified'\n ? unifiedAST\n : type === 'deletions'\n ? deletionsAST\n : additionsAST;\n\n if (hunkSeparators === 'metadata') {\n if (hunkSpecs != null) {\n linesAST.push(\n createSeparator({\n type: 'metadata',\n content: hunkSpecs,\n isFirstHunk,\n isLastHunk,\n })\n );\n }\n return;\n }\n if (hunkSeparators === 'simple') {\n if (hunkIndex > 0) {\n linesAST.push(\n createSeparator({ type: 'simple', isFirstHunk, isLastHunk: false })\n );\n }\n return;\n }\n const slotName = getHunkSeparatorSlotName(type, hunkIndex);\n const chunked = rangeSize > expansionLineCount;\n const expandIndex = isExpandable ? hunkIndex : undefined;\n linesAST.push(\n createSeparator({\n type: hunkSeparators,\n content: getModifiedLinesString(collapsedLines),\n expandIndex,\n chunked,\n slotName,\n isFirstHunk,\n isLastHunk,\n })\n );\n hunkData.push({\n slotName,\n hunkIndex,\n lines: collapsedLines,\n type,\n expandable: isExpandable\n ? { up: !isFirstHunk, down: !isLastHunk, chunked }\n : undefined,\n });\n}\n"],"mappings":"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"}
@@ -18,6 +18,7 @@ declare class FileRenderer<LAnnotation = undefined> {
18
18
  options: FileRendererOptions;
19
19
  private onRenderUpdate?;
20
20
  private workerManager?;
21
+ readonly __id: string;
21
22
  private highlighter;
22
23
  private renderCache;
23
24
  private computedLang;
@@ -1 +1 @@
1
- {"version":3,"file":"FileRenderer.d.ts","names":["options: FileRendererOptions","onRenderUpdate?: () => unknown","workerManager?: WorkerPoolManager | undefined"],"sources":["../../src/renderers/FileRenderer.ts"],"sourcesContent":[],"mappings":";;;;;;UA6CiB,gBAAA;WACN;UACD;EAFV,SAAiB,EAGJ,OAHI,GAAA,SAAA;EACN,GAAA,EAAA,MAAA;EACD,UAAA,EAAA,MAAA;EACG,WAAA,EAAA,MAAA;EAAA,aAAA,EAAA,OAAA,GAAA,MAAA,GAAA,SAAA;AAQb;AAEa,UAFI,mBAAA,SAA4B,eAEhC,CAAA,CAAA;AAOO,cAPP,YAOO,CAAA,cAAA,SAAA,CAAA,CAAA;EAAA,OAAA,EAAA,mBAAA;EAEQ,QAAA,cAAA;EASN,QAAA,aAAA;EAQI,QAAA,WAAA;EAQ2B,QAAA,WAAA;EAAf,QAAA,YAAA;EAgBtB,QAAA,eAAA;EAiDN,WAAA,CAAA,OAAA,CAAA,EA5FU,mBA4FV,EAAA,cAAA,CAAA,EAAA,CAAA,GAAA,GAAA,OAAA,CAAA,GAAA,SAAA,EAAA,aAAA,CAAA,EA1FkB,iBA0FlB,GAAA,SAAA;EACL,UAAA,CAAA,OAAA,EAlFiB,mBAkFjB,CAAA,EAAA,IAAA;EAqEqB,QAAA,YAAA;EAAuB,YAAA,CAAA,SAAA,EA/IvB,UA+IuB,CAAA,EAAA,IAAA;EAAR,kBAAA,CAAA,eAAA,EAvIH,cAuIG,CAvIY,WAuIZ,CAAA,EAAA,CAAA,EAAA,IAAA;EA2FhB,OAAA,CAAA,CAAA,EAAA,IAAA;EAKb,OAAA,CAAA,IAAA,EAvNI,YAuNJ,CAAA,EAAA,IAAA;EACE,QAAA,gBAAA;EACT,UAAA,CAAA,IAAA,CAAA,EAxKK,YAwKL,GAAA,SAAA,CAAA,EAvKA,gBAuKA,GAAA,SAAA;EAYS,WAAA,CAAA,IAAA,EA9GY,YA8GZ,CAAA,EA9G2B,OA8G3B,CA9GmC,gBA8GnC,CAAA;EAe2B,QAAA,cAAA;EAAR,QAAA,yBAAA;EAQvB,QAAA,iBAAA;EACE,QAAA,YAAA;EACC,cAAA,CAAA,MAAA,EA5CY,gBA4CZ,CAAA,EAAA,MAAA;EAAA,aAAA,CAAA,MAAA,EAvCD,gBAuCC,EAAA,QAAA,CAAA,EAtCC,cAsCD,EAAA,CAAA,EArCR,OAqCQ;8BAzBC;2BAemB,QAAQ;2BAQ/B,sBACE,2BACC"}
1
+ {"version":3,"file":"FileRenderer.d.ts","names":["options: FileRendererOptions","onRenderUpdate?: () => unknown","workerManager?: WorkerPoolManager | undefined"],"sources":["../../src/renderers/FileRenderer.ts"],"sourcesContent":[],"mappings":";;;;;;UA6CiB,gBAAA;WACN;UACD;EAFV,SAAiB,EAGJ,OAHI,GAAA,SAAA;EACN,GAAA,EAAA,MAAA;EACD,UAAA,EAAA,MAAA;EACG,WAAA,EAAA,MAAA;EAAA,aAAA,EAAA,OAAA,GAAA,MAAA,GAAA,SAAA;AAQb;AAIa,UAJI,mBAAA,SAA4B,eAIhC,CAAA,CAAA;AASO,cATP,YASO,CAAA,cAAA,SAAA,CAAA,CAAA;EAAA,OAAA,EAAA,mBAAA;EAEQ,QAAA,cAAA;EASN,QAAA,aAAA;EAQI,SAAA,IAAA,EAAA,MAAA;EAQ2B,QAAA,WAAA;EAAf,QAAA,WAAA;EAgBtB,QAAA,YAAA;EAmDN,QAAA,eAAA;EACL,WAAA,CAAA,OAAA,CAAA,EA/Fe,mBA+Ff,EAAA,cAAA,CAAA,EAAA,CAAA,GAAA,GAAA,OAAA,CAAA,GAAA,SAAA,EAAA,aAAA,CAAA,EA7FuB,iBA6FvB,GAAA,SAAA;EA4EqB,UAAA,CAAA,OAAA,EAhKJ,mBAgKI,CAAA,EAAA,IAAA;EAAuB,QAAA,YAAA;EAAR,YAAA,CAAA,SAAA,EAxJf,UAwJe,CAAA,EAAA,IAAA;EA2FhB,kBAAA,CAAA,eAAA,EA3Oa,cA2Ob,CA3O4B,WA2O5B,CAAA,EAAA,CAAA,EAAA,IAAA;EAKb,OAAA,CAAA,CAAA,EAAA,IAAA;EACE,OAAA,CAAA,IAAA,EAjOE,YAiOF,CAAA,EAAA,IAAA;EACT,QAAA,gBAAA;EAYS,UAAA,CAAA,IAAA,CAAA,EA3LJ,YA2LI,GAAA,SAAA,CAAA,EA1LT,gBA0LS,GAAA,SAAA;EAe2B,WAAA,CAAA,IAAA,EA7Hf,YA6He,CAAA,EA7HA,OA6HA,CA7HQ,gBA6HR,CAAA;EAAR,QAAA,cAAA;EAQvB,QAAA,yBAAA;EACE,QAAA,iBAAA;EACC,QAAA,YAAA;EAAA,cAAA,CAAA,MAAA,EA5CY,gBA4CZ,CAAA,EAAA,MAAA;wBAvCD,6BACE,mBACT;8BAYS;2BAemB,QAAQ;2BAQ/B,sBACE,2BACC"}
@@ -16,7 +16,9 @@ import { renderFileWithHighlighter } from "../utils/renderFileWithHighlighter.js
16
16
  import { toHtml } from "hast-util-to-html";
17
17
 
18
18
  //#region src/renderers/FileRenderer.ts
19
+ let instanceId = -1;
19
20
  var FileRenderer = class {
21
+ __id = `file-renderer:${++instanceId}`;
20
22
  highlighter;
21
23
  renderCache;
22
24
  computedLang = "text";
@@ -62,7 +64,8 @@ var FileRenderer = class {
62
64
  file,
63
65
  options,
64
66
  highlighted: true,
65
- result: cache?.result
67
+ result: cache?.result,
68
+ renderRange: void 0
66
69
  };
67
70
  if (this.workerManager?.isWorkingPool() === true && this.renderCache.result == null) this.workerManager.highlightFileAST(this, file);
68
71
  else this.asyncHighlight(file).then(({ result, options: options$1 }) => {
@@ -98,6 +101,7 @@ var FileRenderer = class {
98
101
  if (cache != null && this.renderCache == null) this.renderCache = {
99
102
  file,
100
103
  highlighted: true,
104
+ renderRange: void 0,
101
105
  ...cache
102
106
  };
103
107
  const { options, forceRender } = this.getRenderOptions(file);
@@ -105,7 +109,8 @@ var FileRenderer = class {
105
109
  file,
106
110
  highlighted: false,
107
111
  options,
108
- result: void 0
112
+ result: void 0,
113
+ renderRange: void 0
109
114
  };
110
115
  if (this.workerManager?.isWorkingPool() === true) {
111
116
  this.renderCache.result ??= this.workerManager.getPlainFileAST(file);
@@ -120,7 +125,8 @@ var FileRenderer = class {
120
125
  file,
121
126
  options: options$1,
122
127
  highlighted: hasLangs,
123
- result
128
+ result,
129
+ renderRange: void 0
124
130
  };
125
131
  }
126
132
  if (!hasThemes || !hasLangs) this.asyncHighlight(file).then(({ result, options: options$1 }) => {
@@ -213,7 +219,8 @@ var FileRenderer = class {
213
219
  file,
214
220
  options,
215
221
  highlighted: true,
216
- result
222
+ result,
223
+ renderRange: void 0
217
224
  };
218
225
  if (triggerRenderUpdate) this.onRenderUpdate?.();
219
226
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FileRenderer.js","names":["options: FileRendererOptions","onRenderUpdate?: () => unknown","workerManager?: WorkerPoolManager | undefined","options","options: RenderFileOptions","codeAST: ElementContent[]"],"sources":["../../src/renderers/FileRenderer.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement } from 'hast';\nimport { toHtml } from 'hast-util-to-html';\n\nimport { DEFAULT_THEMES } from '../constants';\nimport { areLanguagesAttached } from '../highlighter/languages/areLanguagesAttached';\nimport {\n getHighlighterIfLoaded,\n getSharedHighlighter,\n} from '../highlighter/shared_highlighter';\nimport { areThemesAttached } from '../highlighter/themes/areThemesAttached';\nimport { hasResolvedThemes } from '../highlighter/themes/hasResolvedThemes';\nimport type {\n BaseCodeOptions,\n DiffsHighlighter,\n FileContents,\n LineAnnotation,\n RenderFileOptions,\n RenderFileResult,\n RenderedFileASTCache,\n SupportedLanguages,\n ThemeTypes,\n ThemedFileResult,\n} from '../types';\nimport { areThemesEqual } from '../utils/areThemesEqual';\nimport { createAnnotationElement } from '../utils/createAnnotationElement';\nimport { createFileHeaderElement } from '../utils/createFileHeaderElement';\nimport { createPreElement } from '../utils/createPreElement';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { getHighlighterOptions } from '../utils/getHighlighterOptions';\nimport { getLineAnnotationName } from '../utils/getLineAnnotationName';\nimport { getThemes } from '../utils/getThemes';\nimport { createHastElement } from '../utils/hast_utils';\nimport { renderFileWithHighlighter } from '../utils/renderFileWithHighlighter';\nimport type { WorkerPoolManager } from '../worker';\n\ntype AnnotationLineMap<LAnnotation> = Record<\n number,\n LineAnnotation<LAnnotation>[] | undefined\n>;\n\ninterface GetRenderOptionsReturn {\n options: RenderFileOptions;\n forceRender: boolean;\n}\n\nexport interface FileRenderResult {\n codeAST: ElementContent[];\n preAST: HASTElement;\n headerAST: HASTElement | undefined;\n css: string;\n totalLines: number;\n themeStyles: string;\n baseThemeType: 'light' | 'dark' | undefined;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface FileRendererOptions extends BaseCodeOptions {}\n\nexport class FileRenderer<LAnnotation = undefined> {\n private highlighter: DiffsHighlighter | undefined;\n private renderCache: RenderedFileASTCache | undefined;\n private computedLang: SupportedLanguages = 'text';\n private lineAnnotations: AnnotationLineMap<LAnnotation> = {};\n\n constructor(\n public options: FileRendererOptions = { theme: DEFAULT_THEMES },\n private onRenderUpdate?: () => unknown,\n private workerManager?: WorkerPoolManager | undefined\n ) {\n if (workerManager?.isWorkingPool() !== true) {\n this.highlighter = areThemesAttached(options.theme ?? DEFAULT_THEMES)\n ? getHighlighterIfLoaded()\n : undefined;\n }\n }\n\n setOptions(options: FileRendererOptions): void {\n this.options = options;\n }\n\n private mergeOptions(options: Partial<FileRendererOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n setThemeType(themeType: ThemeTypes): void {\n const currentThemeType = this.options.themeType ?? 'system';\n if (currentThemeType === themeType) {\n return;\n }\n this.mergeOptions({ themeType });\n }\n\n setLineAnnotations(lineAnnotations: LineAnnotation<LAnnotation>[]): void {\n this.lineAnnotations = {};\n for (const annotation of lineAnnotations) {\n const arr = this.lineAnnotations[annotation.lineNumber] ?? [];\n this.lineAnnotations[annotation.lineNumber] = arr;\n arr.push(annotation);\n }\n }\n\n cleanUp(): void {\n this.renderCache = undefined;\n this.highlighter = undefined;\n this.workerManager = undefined;\n this.onRenderUpdate = undefined;\n }\n\n hydrate(file: FileContents): void {\n const { options } = this.getRenderOptions(file);\n let cache = this.workerManager?.getFileResultCache(file);\n if (cache != null && !areRenderOptionsEqual(options, cache.options)) {\n cache = undefined;\n }\n this.renderCache ??= {\n file,\n options,\n // NOTE(amadeus): If we're hydrating, we can assume there was\n // pre-rendered HTML, otherwise one should not be hydrating\n highlighted: true,\n result: cache?.result,\n };\n if (\n this.workerManager?.isWorkingPool() === true &&\n this.renderCache.result == null\n ) {\n this.workerManager.highlightFileAST(this, file);\n } else {\n void this.asyncHighlight(file).then(({ result, options }) => {\n this.onHighlightSuccess(file, result, options);\n });\n }\n }\n\n private getRenderOptions(file: FileContents): GetRenderOptionsReturn {\n const options: RenderFileOptions = (() => {\n if (this.workerManager?.isWorkingPool() === true) {\n return this.workerManager.getFileRenderOptions();\n }\n const { theme = DEFAULT_THEMES, tokenizeMaxLineLength = 1000 } =\n this.options;\n return { theme, tokenizeMaxLineLength };\n })();\n const { renderCache } = this;\n if (renderCache?.result == null) {\n return { options, forceRender: true };\n }\n if (\n file !== renderCache.file ||\n !areRenderOptionsEqual(options, renderCache.options)\n ) {\n return { options, forceRender: true };\n }\n return { options, forceRender: false };\n }\n\n renderFile(\n file: FileContents | undefined = this.renderCache?.file\n ): FileRenderResult | undefined {\n if (file == null) {\n return undefined;\n }\n const cache = this.workerManager?.getFileResultCache(file);\n if (cache != null && this.renderCache == null) {\n this.renderCache = { file, highlighted: true, ...cache };\n }\n const { options, forceRender } = this.getRenderOptions(file);\n this.renderCache ??= {\n file,\n highlighted: false,\n options,\n result: undefined,\n };\n if (this.workerManager?.isWorkingPool() === true) {\n this.renderCache.result ??= this.workerManager.getPlainFileAST(file);\n // TODO(amadeus): Figure out how to only fire this on a per file\n // basis... (maybe the poolManager can figure it out based on file name\n // and file contents probably?)\n if (!this.renderCache.highlighted || forceRender) {\n this.workerManager.highlightFileAST(this, file);\n }\n } else {\n this.computedLang = file.lang ?? getFiletypeFromFileName(file.name);\n const hasThemes =\n this.highlighter != null && areThemesAttached(options.theme);\n const hasLangs =\n this.highlighter != null && areLanguagesAttached(this.computedLang);\n\n // If we have any semblance of a highlighter with the correct theme(s)\n // attached, we can kick off some form of rendering. If we don't have\n // the correct language, then we can render plain text and after kick off\n // an async job to get the highlighted AST\n if (\n this.highlighter != null &&\n hasThemes &&\n (forceRender ||\n (!this.renderCache.highlighted && hasLangs) ||\n this.renderCache.result == null)\n ) {\n const { result, options } = this.renderFileWithHighlighter(\n file,\n this.highlighter,\n !hasLangs\n );\n this.renderCache = {\n file,\n options,\n highlighted: hasLangs,\n result,\n };\n }\n\n // If we get in here it means we'll have to kick off an async highlight\n // process which will involve initializing the highlighter with new themes\n // and languages\n if (!hasThemes || !hasLangs) {\n void this.asyncHighlight(file).then(({ result, options }) => {\n this.onHighlightSuccess(file, result, options);\n });\n }\n }\n\n return this.renderCache.result != null\n ? this.processFileResult(this.renderCache.file, this.renderCache.result)\n : undefined;\n }\n\n async asyncRender(file: FileContents): Promise<FileRenderResult> {\n const { result } = await this.asyncHighlight(file);\n return this.processFileResult(file, result);\n }\n\n private async asyncHighlight(file: FileContents): Promise<RenderFileResult> {\n this.computedLang = file.lang ?? getFiletypeFromFileName(file.name);\n const hasThemes =\n this.highlighter != null &&\n hasResolvedThemes(getThemes(this.options.theme));\n const hasLangs =\n this.highlighter != null && areLanguagesAttached(this.computedLang);\n // If we don't have the required langs or themes, then we need to\n // initialize the highlighter to load the appropriate languages and themes\n if (this.highlighter == null || !hasThemes || !hasLangs) {\n this.highlighter = await this.initializeHighlighter();\n }\n return this.renderFileWithHighlighter(file, this.highlighter);\n }\n\n private renderFileWithHighlighter(\n file: FileContents,\n highlighter: DiffsHighlighter,\n plainText = false\n ): RenderFileResult {\n const { options } = this.getRenderOptions(file);\n const result = renderFileWithHighlighter(\n file,\n highlighter,\n options,\n plainText\n );\n return { result, options };\n }\n\n private processFileResult(\n file: FileContents,\n result: ThemedFileResult\n ): FileRenderResult {\n const { disableFileHeader = false } = this.options;\n const codeAST: ElementContent[] = [];\n let lineIndex = 1;\n for (const line of result.code) {\n codeAST.push(line);\n const annotations = this.lineAnnotations[lineIndex];\n if (annotations != null) {\n codeAST.push(\n createAnnotationElement({\n type: 'annotation',\n hunkIndex: 0,\n lineIndex,\n annotations: annotations.map((annotation) =>\n getLineAnnotationName(annotation)\n ),\n })\n );\n }\n lineIndex++;\n }\n\n return {\n codeAST,\n preAST: this.createPreElement(\n result.code.length,\n result.themeStyles,\n result.baseThemeType\n ),\n headerAST: !disableFileHeader\n ? this.renderHeader(file, result.themeStyles, result.baseThemeType)\n : undefined,\n totalLines: result.code.length,\n themeStyles: result.themeStyles,\n baseThemeType: result.baseThemeType,\n // FIXME(amadeus): Fix this\n css: '',\n };\n }\n\n private renderHeader(\n file: FileContents,\n themeStyles: string,\n baseThemeType: 'light' | 'dark' | undefined\n ) {\n const { themeType = 'system' } = this.options;\n return createFileHeaderElement({\n fileOrDiff: file,\n themeStyles,\n themeType: baseThemeType ?? themeType,\n });\n }\n\n renderFullHTML(result: FileRenderResult): string {\n return toHtml(this.renderFullAST(result));\n }\n\n renderFullAST(\n result: FileRenderResult,\n children: ElementContent[] = []\n ): HASTElement {\n children.push(\n createHastElement({\n tagName: 'code',\n children: result.codeAST,\n properties: { 'data-code': '' },\n })\n );\n return { ...result.preAST, children };\n }\n\n renderPartialHTML(\n children: ElementContent[],\n includeCodeNode: boolean = false\n ): string {\n if (!includeCodeNode) {\n return toHtml(children);\n }\n return toHtml(\n createHastElement({\n tagName: 'code',\n children,\n properties: { 'data-code': '' },\n })\n );\n }\n\n async initializeHighlighter(): Promise<DiffsHighlighter> {\n this.highlighter = await getSharedHighlighter(\n getHighlighterOptions(this.computedLang, this.options)\n );\n return this.highlighter;\n }\n\n onHighlightSuccess(\n file: FileContents,\n result: ThemedFileResult,\n options: RenderFileOptions\n ): void {\n if (this.renderCache == null) {\n return;\n }\n const triggerRenderUpdate =\n this.renderCache.file !== file ||\n !this.renderCache.highlighted ||\n !areRenderOptionsEqual(options, this.renderCache.options);\n\n this.renderCache = {\n file,\n options,\n highlighted: true,\n result,\n };\n\n if (triggerRenderUpdate) {\n this.onRenderUpdate?.();\n }\n }\n\n onHighlightError(error: unknown): void {\n console.error(error);\n }\n\n private createPreElement(\n totalLines: number,\n themeStyles: string,\n baseThemeType: 'light' | 'dark' | undefined\n ): HASTElement {\n const {\n disableLineNumbers = false,\n overflow = 'scroll',\n themeType = 'system',\n } = this.options;\n return createPreElement({\n diffIndicators: 'none',\n disableBackground: true,\n disableLineNumbers,\n overflow,\n themeStyles,\n themeType: baseThemeType ?? themeType,\n split: false,\n totalLines,\n });\n }\n}\n\nfunction areRenderOptionsEqual(\n optionsA: RenderFileOptions,\n optionsB: RenderFileOptions\n): boolean {\n return (\n areThemesEqual(optionsA.theme, optionsB.theme) &&\n optionsA.tokenizeMaxLineLength === optionsB.tokenizeMaxLineLength\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"FileRenderer.js","names":["options: FileRendererOptions","onRenderUpdate?: () => unknown","workerManager?: WorkerPoolManager | undefined","options","options: RenderFileOptions","codeAST: ElementContent[]"],"sources":["../../src/renderers/FileRenderer.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement } from 'hast';\nimport { toHtml } from 'hast-util-to-html';\n\nimport { DEFAULT_THEMES } from '../constants';\nimport { areLanguagesAttached } from '../highlighter/languages/areLanguagesAttached';\nimport {\n getHighlighterIfLoaded,\n getSharedHighlighter,\n} from '../highlighter/shared_highlighter';\nimport { areThemesAttached } from '../highlighter/themes/areThemesAttached';\nimport { hasResolvedThemes } from '../highlighter/themes/hasResolvedThemes';\nimport type {\n BaseCodeOptions,\n DiffsHighlighter,\n FileContents,\n LineAnnotation,\n RenderFileOptions,\n RenderFileResult,\n RenderedFileASTCache,\n SupportedLanguages,\n ThemeTypes,\n ThemedFileResult,\n} from '../types';\nimport { areThemesEqual } from '../utils/areThemesEqual';\nimport { createAnnotationElement } from '../utils/createAnnotationElement';\nimport { createFileHeaderElement } from '../utils/createFileHeaderElement';\nimport { createPreElement } from '../utils/createPreElement';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { getHighlighterOptions } from '../utils/getHighlighterOptions';\nimport { getLineAnnotationName } from '../utils/getLineAnnotationName';\nimport { getThemes } from '../utils/getThemes';\nimport { createHastElement } from '../utils/hast_utils';\nimport { renderFileWithHighlighter } from '../utils/renderFileWithHighlighter';\nimport type { WorkerPoolManager } from '../worker';\n\ntype AnnotationLineMap<LAnnotation> = Record<\n number,\n LineAnnotation<LAnnotation>[] | undefined\n>;\n\ninterface GetRenderOptionsReturn {\n options: RenderFileOptions;\n forceRender: boolean;\n}\n\nexport interface FileRenderResult {\n codeAST: ElementContent[];\n preAST: HASTElement;\n headerAST: HASTElement | undefined;\n css: string;\n totalLines: number;\n themeStyles: string;\n baseThemeType: 'light' | 'dark' | undefined;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface FileRendererOptions extends BaseCodeOptions {}\n\nlet instanceId = -1;\n\nexport class FileRenderer<LAnnotation = undefined> {\n readonly __id: string = `file-renderer:${++instanceId}`;\n\n private highlighter: DiffsHighlighter | undefined;\n private renderCache: RenderedFileASTCache | undefined;\n private computedLang: SupportedLanguages = 'text';\n private lineAnnotations: AnnotationLineMap<LAnnotation> = {};\n\n constructor(\n public options: FileRendererOptions = { theme: DEFAULT_THEMES },\n private onRenderUpdate?: () => unknown,\n private workerManager?: WorkerPoolManager | undefined\n ) {\n if (workerManager?.isWorkingPool() !== true) {\n this.highlighter = areThemesAttached(options.theme ?? DEFAULT_THEMES)\n ? getHighlighterIfLoaded()\n : undefined;\n }\n }\n\n setOptions(options: FileRendererOptions): void {\n this.options = options;\n }\n\n private mergeOptions(options: Partial<FileRendererOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n setThemeType(themeType: ThemeTypes): void {\n const currentThemeType = this.options.themeType ?? 'system';\n if (currentThemeType === themeType) {\n return;\n }\n this.mergeOptions({ themeType });\n }\n\n setLineAnnotations(lineAnnotations: LineAnnotation<LAnnotation>[]): void {\n this.lineAnnotations = {};\n for (const annotation of lineAnnotations) {\n const arr = this.lineAnnotations[annotation.lineNumber] ?? [];\n this.lineAnnotations[annotation.lineNumber] = arr;\n arr.push(annotation);\n }\n }\n\n cleanUp(): void {\n this.renderCache = undefined;\n this.highlighter = undefined;\n this.workerManager = undefined;\n this.onRenderUpdate = undefined;\n }\n\n hydrate(file: FileContents): void {\n const { options } = this.getRenderOptions(file);\n let cache = this.workerManager?.getFileResultCache(file);\n if (cache != null && !areRenderOptionsEqual(options, cache.options)) {\n cache = undefined;\n }\n this.renderCache ??= {\n file,\n options,\n // NOTE(amadeus): If we're hydrating, we can assume there was\n // pre-rendered HTML, otherwise one should not be hydrating\n highlighted: true,\n result: cache?.result,\n // FIXME(amadeus): Add support for renderRanges\n renderRange: undefined,\n };\n if (\n this.workerManager?.isWorkingPool() === true &&\n this.renderCache.result == null\n ) {\n this.workerManager.highlightFileAST(this, file);\n } else {\n void this.asyncHighlight(file).then(({ result, options }) => {\n this.onHighlightSuccess(file, result, options);\n });\n }\n }\n\n private getRenderOptions(file: FileContents): GetRenderOptionsReturn {\n const options: RenderFileOptions = (() => {\n if (this.workerManager?.isWorkingPool() === true) {\n return this.workerManager.getFileRenderOptions();\n }\n const { theme = DEFAULT_THEMES, tokenizeMaxLineLength = 1000 } =\n this.options;\n return { theme, tokenizeMaxLineLength };\n })();\n const { renderCache } = this;\n if (renderCache?.result == null) {\n return { options, forceRender: true };\n }\n if (\n file !== renderCache.file ||\n !areRenderOptionsEqual(options, renderCache.options)\n ) {\n return { options, forceRender: true };\n }\n return { options, forceRender: false };\n }\n\n renderFile(\n file: FileContents | undefined = this.renderCache?.file\n ): FileRenderResult | undefined {\n if (file == null) {\n return undefined;\n }\n const cache = this.workerManager?.getFileResultCache(file);\n if (cache != null && this.renderCache == null) {\n this.renderCache = {\n file,\n highlighted: true,\n renderRange: undefined,\n ...cache,\n };\n }\n const { options, forceRender } = this.getRenderOptions(file);\n this.renderCache ??= {\n file,\n highlighted: false,\n options,\n result: undefined,\n renderRange: undefined,\n };\n if (this.workerManager?.isWorkingPool() === true) {\n this.renderCache.result ??= this.workerManager.getPlainFileAST(file);\n // TODO(amadeus): Figure out how to only fire this on a per file\n // basis... (maybe the poolManager can figure it out based on file name\n // and file contents probably?)\n if (!this.renderCache.highlighted || forceRender) {\n this.workerManager.highlightFileAST(this, file);\n }\n } else {\n this.computedLang = file.lang ?? getFiletypeFromFileName(file.name);\n const hasThemes =\n this.highlighter != null && areThemesAttached(options.theme);\n const hasLangs =\n this.highlighter != null && areLanguagesAttached(this.computedLang);\n\n // If we have any semblance of a highlighter with the correct theme(s)\n // attached, we can kick off some form of rendering. If we don't have\n // the correct language, then we can render plain text and after kick off\n // an async job to get the highlighted AST\n if (\n this.highlighter != null &&\n hasThemes &&\n (forceRender ||\n (!this.renderCache.highlighted && hasLangs) ||\n this.renderCache.result == null)\n ) {\n const { result, options } = this.renderFileWithHighlighter(\n file,\n this.highlighter,\n !hasLangs\n );\n this.renderCache = {\n file,\n options,\n highlighted: hasLangs,\n result,\n renderRange: undefined,\n };\n }\n\n // If we get in here it means we'll have to kick off an async highlight\n // process which will involve initializing the highlighter with new themes\n // and languages\n if (!hasThemes || !hasLangs) {\n void this.asyncHighlight(file).then(({ result, options }) => {\n this.onHighlightSuccess(file, result, options);\n });\n }\n }\n\n return this.renderCache.result != null\n ? this.processFileResult(this.renderCache.file, this.renderCache.result)\n : undefined;\n }\n\n async asyncRender(file: FileContents): Promise<FileRenderResult> {\n const { result } = await this.asyncHighlight(file);\n return this.processFileResult(file, result);\n }\n\n private async asyncHighlight(file: FileContents): Promise<RenderFileResult> {\n this.computedLang = file.lang ?? getFiletypeFromFileName(file.name);\n const hasThemes =\n this.highlighter != null &&\n hasResolvedThemes(getThemes(this.options.theme));\n const hasLangs =\n this.highlighter != null && areLanguagesAttached(this.computedLang);\n // If we don't have the required langs or themes, then we need to\n // initialize the highlighter to load the appropriate languages and themes\n if (this.highlighter == null || !hasThemes || !hasLangs) {\n this.highlighter = await this.initializeHighlighter();\n }\n return this.renderFileWithHighlighter(file, this.highlighter);\n }\n\n private renderFileWithHighlighter(\n file: FileContents,\n highlighter: DiffsHighlighter,\n plainText = false\n ): RenderFileResult {\n const { options } = this.getRenderOptions(file);\n const result = renderFileWithHighlighter(\n file,\n highlighter,\n options,\n plainText\n );\n return { result, options };\n }\n\n private processFileResult(\n file: FileContents,\n result: ThemedFileResult\n ): FileRenderResult {\n const { disableFileHeader = false } = this.options;\n const codeAST: ElementContent[] = [];\n let lineIndex = 1;\n for (const line of result.code) {\n codeAST.push(line);\n const annotations = this.lineAnnotations[lineIndex];\n if (annotations != null) {\n codeAST.push(\n createAnnotationElement({\n type: 'annotation',\n hunkIndex: 0,\n lineIndex,\n annotations: annotations.map((annotation) =>\n getLineAnnotationName(annotation)\n ),\n })\n );\n }\n lineIndex++;\n }\n\n return {\n codeAST,\n preAST: this.createPreElement(\n result.code.length,\n result.themeStyles,\n result.baseThemeType\n ),\n headerAST: !disableFileHeader\n ? this.renderHeader(file, result.themeStyles, result.baseThemeType)\n : undefined,\n totalLines: result.code.length,\n themeStyles: result.themeStyles,\n baseThemeType: result.baseThemeType,\n // FIXME(amadeus): Fix this\n css: '',\n };\n }\n\n private renderHeader(\n file: FileContents,\n themeStyles: string,\n baseThemeType: 'light' | 'dark' | undefined\n ) {\n const { themeType = 'system' } = this.options;\n return createFileHeaderElement({\n fileOrDiff: file,\n themeStyles,\n themeType: baseThemeType ?? themeType,\n });\n }\n\n renderFullHTML(result: FileRenderResult): string {\n return toHtml(this.renderFullAST(result));\n }\n\n renderFullAST(\n result: FileRenderResult,\n children: ElementContent[] = []\n ): HASTElement {\n children.push(\n createHastElement({\n tagName: 'code',\n children: result.codeAST,\n properties: { 'data-code': '' },\n })\n );\n return { ...result.preAST, children };\n }\n\n renderPartialHTML(\n children: ElementContent[],\n includeCodeNode: boolean = false\n ): string {\n if (!includeCodeNode) {\n return toHtml(children);\n }\n return toHtml(\n createHastElement({\n tagName: 'code',\n children,\n properties: { 'data-code': '' },\n })\n );\n }\n\n async initializeHighlighter(): Promise<DiffsHighlighter> {\n this.highlighter = await getSharedHighlighter(\n getHighlighterOptions(this.computedLang, this.options)\n );\n return this.highlighter;\n }\n\n onHighlightSuccess(\n file: FileContents,\n result: ThemedFileResult,\n options: RenderFileOptions\n ): void {\n if (this.renderCache == null) {\n return;\n }\n const triggerRenderUpdate =\n this.renderCache.file !== file ||\n !this.renderCache.highlighted ||\n !areRenderOptionsEqual(options, this.renderCache.options);\n\n this.renderCache = {\n file,\n options,\n highlighted: true,\n result,\n renderRange: undefined,\n };\n\n if (triggerRenderUpdate) {\n this.onRenderUpdate?.();\n }\n }\n\n onHighlightError(error: unknown): void {\n console.error(error);\n }\n\n private createPreElement(\n totalLines: number,\n themeStyles: string,\n baseThemeType: 'light' | 'dark' | undefined\n ): HASTElement {\n const {\n disableLineNumbers = false,\n overflow = 'scroll',\n themeType = 'system',\n } = this.options;\n return createPreElement({\n diffIndicators: 'none',\n disableBackground: true,\n disableLineNumbers,\n overflow,\n themeStyles,\n themeType: baseThemeType ?? themeType,\n split: false,\n totalLines,\n });\n }\n}\n\nfunction areRenderOptionsEqual(\n optionsA: RenderFileOptions,\n optionsB: RenderFileOptions\n): boolean {\n return (\n areThemesEqual(optionsA.theme, optionsB.theme) &&\n optionsA.tokenizeMaxLineLength === optionsB.tokenizeMaxLineLength\n );\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { AnnotationLineMap, AnnotationSide, AnnotationSpan, BaseCodeOptions, BaseDiffOptions, BundledLanguage, ChangeContent, ChangeHunk, ChangeTypes, CodeToHastOptions, ContextContent, DecorationItem, DiffLineAnnotation, DiffLineEventBaseProps, DiffsHighlighter, DiffsThemeNames, ExpansionDirections, ExtensionFormatMap, FileContents, FileDiffMetadata, GapSpan, Hunk, HunkData, HunkLineType, HunkSeparators, LanguageRegistration, LineAnnotation, LineDiffTypes, LineEventBaseProps, LineInfo, LineSpans, LineTypes, ObservedAnnotationNodes, ObservedGridNodes, ParsedPatch, PrePropertiesConfig, RenderDiffFilesResult, RenderDiffHunksResult, RenderDiffOptions, RenderDiffResult, RenderFileMetadata, RenderFileOptions, RenderFileResult, RenderHeaderMetadataCallback, RenderHeaderMetadataProps, RenderedDiffASTCache, RenderedFileASTCache, SharedRenderState, ShikiTransformer, SupportedLanguages, ThemeRegistrationResolved, ThemeTypes, ThemedDiffResult, ThemedFileResult, ThemedToken, ThemesType } from "../types.js";
1
+ import { AnnotationLineMap, AnnotationSide, AnnotationSpan, BaseCodeOptions, BaseDiffOptions, BundledLanguage, ChangeContent, ChangeTypes, CodeToHastOptions, ContextContent, DecorationItem, DiffLineAnnotation, DiffLineEventBaseProps, DiffsHighlighter, DiffsThemeNames, ExpansionDirections, ExtensionFormatMap, FileContents, FileDiffMetadata, ForcePlainTextOptions, GapSpan, Hunk, HunkData, HunkExpansionRegion, HunkLineType, HunkSeparators, LanguageRegistration, LineAnnotation, LineDiffTypes, LineEventBaseProps, LineInfo, LineSpans, LineTypes, ObservedAnnotationNodes, ObservedGridNodes, ParsedPatch, PrePropertiesConfig, RenderDiffFilesResult, RenderDiffOptions, RenderDiffResult, RenderFileMetadata, RenderFileOptions, RenderFileResult, RenderHeaderMetadataCallback, RenderHeaderMetadataProps, RenderRange, RenderWindow, RenderedDiffASTCache, RenderedFileASTCache, SharedRenderState, ShikiTransformer, SupportedLanguages, ThemeRegistrationResolved, ThemeTypes, ThemedDiffResult, ThemedFileResult, ThemedToken, ThemesType, VirtualWindowSpecs } from "../types.js";
2
2
  import { PreloadDiffOptions, PreloadFileDiffOptions, PreloadFileDiffResult, PreloadMultiFileDiffOptions, PreloadMultiFileDiffResult, PreloadPatchDiffOptions, PreloadPatchDiffResult, preloadDiffHTML, preloadFileDiff, preloadMultiFileDiff, preloadPatchDiff } from "./preloadDiffs.js";
3
3
  import { PreloadFileOptions, PreloadedFileResult, preloadFile } from "./preloadFile.js";
4
4
  import { PreloadPatchFileOptions, preloadPatchFile } from "./preloadPatchFile.js";
5
5
  import { renderHTML } from "./renderHTML.js";
6
- export { AnnotationLineMap, AnnotationSide, AnnotationSpan, BaseCodeOptions, BaseDiffOptions, BundledLanguage, ChangeContent, ChangeHunk, ChangeTypes, CodeToHastOptions, ContextContent, DecorationItem, DiffLineAnnotation, DiffLineEventBaseProps, DiffsHighlighter, DiffsThemeNames, ExpansionDirections, ExtensionFormatMap, FileContents, FileDiffMetadata, GapSpan, Hunk, HunkData, HunkLineType, HunkSeparators, LanguageRegistration, LineAnnotation, LineDiffTypes, LineEventBaseProps, LineInfo, LineSpans, LineTypes, ObservedAnnotationNodes, ObservedGridNodes, ParsedPatch, PrePropertiesConfig, PreloadDiffOptions, PreloadFileDiffOptions, PreloadFileDiffResult, PreloadFileOptions, PreloadMultiFileDiffOptions, PreloadMultiFileDiffResult, PreloadPatchDiffOptions, PreloadPatchDiffResult, PreloadPatchFileOptions, PreloadedFileResult, RenderDiffFilesResult, RenderDiffHunksResult, RenderDiffOptions, RenderDiffResult, RenderFileMetadata, RenderFileOptions, RenderFileResult, RenderHeaderMetadataCallback, RenderHeaderMetadataProps, RenderedDiffASTCache, RenderedFileASTCache, SharedRenderState, ShikiTransformer, SupportedLanguages, ThemeRegistrationResolved, ThemeTypes, ThemedDiffResult, ThemedFileResult, ThemedToken, ThemesType, preloadDiffHTML, preloadFile, preloadFileDiff, preloadMultiFileDiff, preloadPatchDiff, preloadPatchFile, renderHTML };
6
+ export { AnnotationLineMap, AnnotationSide, AnnotationSpan, BaseCodeOptions, BaseDiffOptions, BundledLanguage, ChangeContent, ChangeTypes, CodeToHastOptions, ContextContent, DecorationItem, DiffLineAnnotation, DiffLineEventBaseProps, DiffsHighlighter, DiffsThemeNames, ExpansionDirections, ExtensionFormatMap, FileContents, FileDiffMetadata, ForcePlainTextOptions, GapSpan, Hunk, HunkData, HunkExpansionRegion, HunkLineType, HunkSeparators, LanguageRegistration, LineAnnotation, LineDiffTypes, LineEventBaseProps, LineInfo, LineSpans, LineTypes, ObservedAnnotationNodes, ObservedGridNodes, ParsedPatch, PrePropertiesConfig, PreloadDiffOptions, PreloadFileDiffOptions, PreloadFileDiffResult, PreloadFileOptions, PreloadMultiFileDiffOptions, PreloadMultiFileDiffResult, PreloadPatchDiffOptions, PreloadPatchDiffResult, PreloadPatchFileOptions, PreloadedFileResult, RenderDiffFilesResult, RenderDiffOptions, RenderDiffResult, RenderFileMetadata, RenderFileOptions, RenderFileResult, RenderHeaderMetadataCallback, RenderHeaderMetadataProps, RenderRange, RenderWindow, RenderedDiffASTCache, RenderedFileASTCache, SharedRenderState, ShikiTransformer, SupportedLanguages, ThemeRegistrationResolved, ThemeTypes, ThemedDiffResult, ThemedFileResult, ThemedToken, ThemesType, VirtualWindowSpecs, preloadDiffHTML, preloadFile, preloadFileDiff, preloadMultiFileDiff, preloadPatchDiff, preloadPatchFile, renderHTML };
package/dist/style.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/style.css
2
- var style_default = "@layer base, theme, unsafe;\n\n@layer base {\n :host {\n --diffs-bg: #fff;\n --diffs-fg: #000;\n --diffs-font-fallback:\n 'SF Mono', Monaco, Consolas, 'Ubuntu Mono', 'Liberation Mono',\n 'Courier New', monospace;\n --diffs-header-font-fallback:\n system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue',\n 'Noto Sans', 'Liberation Sans', Arial, sans-serif;\n\n --diffs-mixer: light-dark(black, white);\n --diffs-gap-fallback: 8px;\n\n /*\n // Available CSS Color Overrides\n --diffs-bg-buffer-override\n --diffs-bg-hover-override\n --diffs-bg-context-override\n --diffs-bg-separator-override\n\n --diffs-fg-number-override\n --diffs-fg-number-addition-override\n --diffs-fg-number-deletion-override\n\n --diffs-deletion-color-override\n --diffs-addition-color-override\n --diffs-modified-color-override\n\n --diffs-bg-deletion-override\n --diffs-bg-deletion-number-override\n --diffs-bg-deletion-hover-override\n --diffs-bg-deletion-emphasis-override\n\n --diffs-bg-addition-override\n --diffs-bg-addition-number-override\n --diffs-bg-addition-hover-override\n --diffs-bg-addition-emphasis-override\n\n // Line Selection Color Overrides (for enableLineSelection)\n --diffs-selection-color-override\n --diffs-bg-selection-override\n --diffs-bg-selection-number-override\n --diffs-bg-selection-background-override\n --diffs-bg-selection-number-background-override\n\n // Available CSS Layout Overrides\n --diffs-gap-inline\n --diffs-gap-block\n --diffs-gap-style\n --diffs-tab-size\n */\n\n color-scheme: light dark;\n display: block;\n font-family: var(\n --diffs-header-font-family,\n var(--diffs-header-font-fallback)\n );\n font-size: var(--diffs-font-size, 13px);\n line-height: var(--diffs-line-height, 20px);\n font-feature-settings: var(--diffs-font-features);\n }\n\n /* NOTE(mdo): Some semantic HTML elements (e.g. `pre`, `code`) have default\n * user-agent styles. These must be overridden to use our custom styles. */\n pre,\n code,\n [data-error-wrapper] {\n margin: 0;\n padding: 0;\n display: block;\n outline: none;\n font-family: var(--diffs-font-family, var(--diffs-font-fallback));\n }\n\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n [data-icon-sprite] {\n display: none;\n }\n\n /* NOTE(mdo): Headers and separators are within pre/code, so we need to reset\n * their font-family explicitly. */\n [data-diffs-header],\n [data-separator] {\n font-family: var(\n --diffs-header-font-family,\n var(--diffs-header-font-fallback)\n );\n }\n\n [data-file-info] {\n padding: 10px;\n font-weight: 700;\n color: var(--fg);\n /* NOTE(amadeus): we cannot use 'in oklch' because current versions of cursor\n * and vscode use an older build of chrome that appears to have a bug with\n * color-mix and 'in oklch', so use 'in lab' instead */\n background-color: color-mix(in lab, var(--bg) 98%, var(--fg));\n border-block: 1px solid color-mix(in lab, var(--bg) 95%, var(--fg));\n }\n\n [data-diffs-header],\n [data-diffs],\n [data-error-wrapper] {\n --diffs-bg: light-dark(var(--diffs-light-bg), var(--diffs-dark-bg));\n /* NOTE(amadeus): we cannot use 'in oklch' because current versions of cursor\n * and vscode use an older build of chrome that appears to have a bug with\n * color-mix and 'in oklch', so use 'in lab' instead */\n --diffs-bg-buffer: var(\n --diffs-bg-buffer-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 92%, var(--diffs-mixer)),\n color-mix(in lab, var(--diffs-bg) 92%, var(--diffs-mixer))\n )\n );\n --diffs-bg-hover: var(\n --diffs-bg-hover-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 97%, var(--diffs-mixer)),\n color-mix(in lab, var(--diffs-bg) 91%, var(--diffs-mixer))\n )\n );\n --diffs-bg-context: var(\n --diffs-bg-context-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 98.5%, var(--diffs-mixer)),\n color-mix(in lab, var(--diffs-bg) 92.5%, var(--diffs-mixer))\n )\n );\n --diffs-bg-separator: var(\n --diffs-bg-separator-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 96%, var(--diffs-mixer)),\n color-mix(in lab, var(--diffs-bg) 85%, var(--diffs-mixer))\n )\n );\n\n --diffs-fg: light-dark(var(--diffs-light), var(--diffs-dark));\n --diffs-fg-number: var(\n --diffs-fg-number-override,\n light-dark(\n color-mix(in lab, var(--diffs-fg) 65%, var(--diffs-bg)),\n color-mix(in lab, var(--diffs-fg) 65%, var(--diffs-bg))\n )\n );\n\n --diffs-deletion-base: var(\n --diffs-deletion-color-override,\n light-dark(\n var(\n --diffs-light-deletion-color,\n var(--diffs-deletion-color, rgb(255, 0, 0))\n ),\n var(\n --diffs-dark-deletion-color,\n var(--diffs-deletion-color, rgb(255, 0, 0))\n )\n )\n );\n --diffs-addition-base: var(\n --diffs-addition-color-override,\n light-dark(\n var(\n --diffs-light-addition-color,\n var(--diffs-addition-color, rgb(0, 255, 0))\n ),\n var(\n --diffs-dark-addition-color,\n var(--diffs-addition-color, rgb(0, 255, 0))\n )\n )\n );\n --diffs-modified-base: var(\n --diffs-modified-color-override,\n light-dark(\n var(\n --diffs-light-modified-color,\n var(--diffs-modified-color, rgb(0, 0, 255))\n ),\n var(\n --diffs-dark-modified-color,\n var(--diffs-modified-color, rgb(0, 0, 255))\n )\n )\n );\n\n /* NOTE(amadeus): we cannot use 'in oklch' because current versions of cursor\n * and vscode use an older build of chrome that appears to have a bug with\n * color-mix and 'in oklch', so use 'in lab' instead */\n --diffs-bg-deletion: var(\n --diffs-bg-deletion-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 88%, var(--diffs-deletion-base)),\n color-mix(in lab, var(--diffs-bg) 80%, var(--diffs-deletion-base))\n )\n );\n --diffs-bg-deletion-number: var(\n --diffs-bg-deletion-number-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 91%, var(--diffs-deletion-base)),\n color-mix(in lab, var(--diffs-bg) 85%, var(--diffs-deletion-base))\n )\n );\n --diffs-bg-deletion-hover: var(\n --diffs-bg-deletion-hover-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 80%, var(--diffs-deletion-base)),\n color-mix(in lab, var(--diffs-bg) 75%, var(--diffs-deletion-base))\n )\n );\n --diffs-bg-deletion-emphasis: var(\n --diffs-bg-deletion-emphasis-override,\n light-dark(\n rgb(from var(--diffs-deletion-base) r g b / 0.15),\n rgb(from var(--diffs-deletion-base) r g b / 0.2)\n )\n );\n\n --diffs-bg-addition: var(\n --diffs-bg-addition-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 88%, var(--diffs-addition-base)),\n color-mix(in lab, var(--diffs-bg) 80%, var(--diffs-addition-base))\n )\n );\n --diffs-bg-addition-number: var(\n --diffs-bg-addition-number-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 91%, var(--diffs-addition-base)),\n color-mix(in lab, var(--diffs-bg) 85%, var(--diffs-addition-base))\n )\n );\n --diffs-bg-addition-hover: var(\n --diffs-bg-addition-hover-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 80%, var(--diffs-addition-base)),\n color-mix(in lab, var(--diffs-bg) 70%, var(--diffs-addition-base))\n )\n );\n --diffs-bg-addition-emphasis: var(\n --diffs-bg-addition-emphasis-override,\n light-dark(\n rgb(from var(--diffs-addition-base) r g b / 0.15),\n rgb(from var(--diffs-addition-base) r g b / 0.2)\n )\n );\n\n --diffs-selection-base: var(--diffs-modified-base);\n --diffs-selection-number-fg: light-dark(\n color-mix(in lab, var(--diffs-selection-base) 65%, var(--diffs-mixer)),\n color-mix(in lab, var(--diffs-selection-base) 75%, var(--diffs-mixer))\n );\n --diffs-bg-selection: var(\n --diffs-bg-selection-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 82%, var(--diffs-selection-base)),\n color-mix(in lab, var(--diffs-bg) 75%, var(--diffs-selection-base))\n )\n );\n --diffs-bg-selection-number: var(\n --diffs-bg-selection-number-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 75%, var(--diffs-selection-base)),\n color-mix(in lab, var(--diffs-bg) 60%, var(--diffs-selection-base))\n )\n );\n\n background-color: var(--diffs-bg);\n color: var(--diffs-fg);\n }\n\n [data-diffs] {\n --diffs-code-grid: minmax(min-content, max-content) 1fr;\n\n [data-column-content] span {\n color: light-dark(\n var(--diffs-token-light, var(--diffs-light)),\n var(--diffs-token-dark, var(--diffs-dark))\n );\n font-weight: var(--diffs-token-light-font-weight, inherit);\n font-style: var(--diffs-token-light-font-style, inherit);\n -webkit-text-decoration: var(--diffs-token-light-text-decoration, inherit);\n text-decoration: var(--diffs-token-light-text-decoration, inherit);\n }\n }\n\n /* Since span is a pretty innocuous selector, we need to make sure we don't\n * apply tokenized BG colors to diff-spans */\n [data-column-content] span:not([data-diff-span]) {\n background-color: light-dark(\n var(--diffs-token-light-bg, inherit),\n var(--diffs-token-dark-bg, inherit)\n );\n }\n\n [data-column-content] {\n background-color: var(--diffs-line-bg, 'transparent');\n grid-column: 2 / 3;\n }\n\n [data-diffs][data-dehydrated] {\n --diffs-code-grid: minmax(min-content, max-content) minmax(0, 1fr);\n }\n\n @media (prefers-color-scheme: dark) {\n [data-diffs-header],\n [data-diffs] {\n color-scheme: dark;\n }\n\n [data-diffs] [data-column-content] span {\n font-weight: var(--diffs-token-dark-font-weight, inherit);\n font-style: var(--diffs-token-dark-font-style, inherit);\n -webkit-text-decoration: var(--diffs-token-dark-text-decoration, inherit);\n text-decoration: var(--diffs-token-dark-text-decoration, inherit);\n }\n }\n\n [data-diffs-header][data-theme-type='light'],\n [data-diffs][data-theme-type='light'] {\n color-scheme: light;\n }\n\n [data-diffs][data-theme-type='light'] [data-column-content] span {\n font-weight: var(--diffs-token-light-font-weight, inherit);\n font-style: var(--diffs-token-light-font-style, inherit);\n -webkit-text-decoration: var(--diffs-token-light-text-decoration, inherit);\n text-decoration: var(--diffs-token-light-text-decoration, inherit);\n }\n\n [data-diffs-header][data-theme-type='dark'],\n [data-diffs][data-theme-type='dark'] {\n color-scheme: dark;\n }\n\n [data-diffs][data-theme-type='dark'] [data-column-content] span {\n font-weight: var(--diffs-token-dark-font-weight, inherit);\n font-style: var(--diffs-token-dark-font-style, inherit);\n -webkit-text-decoration: var(--diffs-token-dark-text-decoration, inherit);\n text-decoration: var(--diffs-token-dark-text-decoration, inherit);\n }\n\n [data-type='split'][data-overflow='wrap'] {\n display: grid;\n grid-auto-flow: dense;\n grid-template-columns: repeat(2, var(--diffs-code-grid));\n }\n\n [data-type='split'][data-overflow='scroll'] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 2px;\n }\n\n [data-code] {\n display: block;\n display: grid;\n grid-auto-flow: dense;\n grid-template-columns: var(--diffs-code-grid);\n overflow: scroll clip;\n overscroll-behavior-x: none;\n tab-size: var(--diffs-tab-size, 2);\n align-self: flex-start;\n padding-top: var(--diffs-gap-block, var(--diffs-gap-fallback));\n padding-bottom: max(\n 0px,\n calc(var(--diffs-gap-block, var(--diffs-gap-fallback)) - 6px)\n );\n }\n\n [data-code]::-webkit-scrollbar {\n width: 0;\n height: 6px;\n }\n\n [data-code]::-webkit-scrollbar-track {\n background: transparent;\n }\n\n [data-code]::-webkit-scrollbar-thumb {\n background-color: transparent;\n border: 1px solid transparent;\n background-clip: content-box;\n border-radius: 3px;\n }\n\n [data-diffs]:hover [data-code]::-webkit-scrollbar-thumb {\n background-color: var(--diffs-bg-context);\n }\n\n [data-code]::-webkit-scrollbar-corner {\n background-color: transparent;\n }\n\n /*\n * If we apply these rules globally it will mean that webkit will opt into the\n * standards compliant version of custom css scrollbars, which we do not want\n * because the custom stuff will look better\n */\n @supports (-moz-appearance: none) {\n [data-code] {\n scrollbar-width: thin;\n scrollbar-color: var(--diffs-bg-context) transparent;\n padding-bottom: var(--diffs-gap-block, var(--diffs-gap-fallback));\n }\n }\n\n [data-diffs][data-type='split'][data-overflow='wrap'] {\n padding-block: var(--diffs-gap-block, var(--diffs-gap-fallback));\n }\n\n [data-diffs-header] ~ [data-diffs] [data-code],\n [data-diffs-header] ~ [data-diffs][data-overflow='wrap'] {\n padding-top: 0;\n }\n\n [data-type='split'][data-overflow='wrap'] [data-code] {\n display: contents;\n }\n\n [data-line-annotation],\n [data-no-newline],\n [data-line] {\n position: relative;\n display: grid;\n grid-template-columns: subgrid;\n grid-column: 1 / 3;\n }\n\n [data-line-annotation][data-selected-line] {\n background-color: unset;\n\n &::before {\n content: '';\n position: sticky;\n top: 0;\n left: 0;\n display: block;\n border-right: var(--diffs-gap-style, 1px solid var(--diffs-bg));\n background-color: var(--diffs-bg-selection-number);\n }\n\n [data-annotation-content] {\n background-color: var(--diffs-bg-selection);\n }\n }\n\n [data-interactive-lines] [data-line] {\n cursor: pointer;\n }\n\n [data-buffer] {\n position: sticky;\n left: 0;\n grid-column: 1 / 3;\n -webkit-user-select: none;\n user-select: none;\n /* We multiply by 1.414 (√2) to better approximate the diagonal repeat distance */\n background-image: repeating-linear-gradient(\n -45deg,\n transparent,\n transparent calc(3px * 1.414),\n var(--diffs-bg-buffer) calc(3px * 1.414),\n var(--diffs-bg-buffer) calc(4px * 1.414)\n );\n min-height: 1lh;\n width: var(--diffs-column-width, auto);\n }\n\n [data-separator] {\n grid-column: span 2;\n }\n\n [data-separator='metadata'],\n [data-separator]:empty {\n min-height: 4px;\n background-color: var(--diffs-bg-separator);\n display: grid;\n grid-template-columns: subgrid;\n }\n\n [data-separator-wrapper] {\n -webkit-user-select: none;\n user-select: none;\n fill: currentColor;\n overflow: hidden;\n }\n\n [data-separator='metadata'] [data-separator-wrapper] {\n grid-column: 2 / 3;\n width: var(--diffs-column-content-width);\n position: sticky;\n left: var(--diffs-column-number-width);\n padding: 4px 1ch;\n }\n\n [data-separator='line-info'] {\n margin-block: var(--diffs-gap-block, var(--diffs-gap-fallback));\n }\n\n [data-separator='line-info'][data-separator-first] {\n margin-top: 0;\n }\n\n [data-separator='line-info'][data-separator-last] {\n margin-bottom: 0;\n }\n\n [data-separator='line-info'] [data-separator-wrapper] {\n position: sticky;\n display: flex;\n align-items: center;\n gap: 2px;\n width: auto;\n width: calc(var(--diffs-column-width) - var(--diffs-gap-fallback));\n border-radius: 6px;\n }\n\n @media (pointer: fine) {\n [data-separator-wrapper][data-separator-multi-button] {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr);\n grid-template-rows: 15px 15px;\n\n [data-expand-button] {\n height: 15px;\n }\n }\n\n [data-type='split']\n [data-additions]\n [data-separator-wrapper][data-separator-multi-button] {\n grid-template-columns: minmax(0, 1fr) auto;\n }\n\n [data-type='split'] [data-additions] [data-expand-button] {\n grid-column: 2;\n }\n\n [data-type='split'] [data-additions] [data-separator-content] {\n grid-column: 1;\n }\n }\n\n [data-expand-button],\n [data-separator-content] {\n display: flex;\n align-items: center;\n background-color: var(--diffs-bg-separator);\n }\n\n [data-expand-button] {\n justify-content: center;\n flex-shrink: 0;\n cursor: pointer;\n width: 32px;\n height: 32px;\n opacity: 0.65;\n }\n\n [data-hover-slot] {\n position: absolute;\n top: 0;\n bottom: 0;\n right: 0;\n display: flex;\n justify-content: flex-end;\n }\n\n @media (pointer: fine) {\n [data-expand-button]:hover {\n opacity: 1;\n }\n\n [data-line]:hover {\n z-index: 2;\n }\n }\n\n [data-expand-up] [data-icon] {\n transform: scaleY(-1);\n }\n\n [data-separator-content] {\n flex: 1 1 auto;\n padding: 0 1ch;\n height: 32px;\n opacity: 0.65;\n overflow: hidden;\n justify-content: flex-start;\n\n grid-column: 2;\n grid-row: 1 / -1;\n }\n\n [data-unmodified-lines] {\n display: block;\n overflow: hidden;\n min-width: 0;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 0 1 auto;\n }\n\n [data-type='split'] [data-additions] [data-separator-content] {\n justify-content: flex-end;\n }\n\n [data-type='file']\n [data-code]\n [data-separator='line-info']\n [data-separator-wrapper] {\n left: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n margin-left: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n margin-right: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n width: calc(\n var(--diffs-column-width) -\n (var(--diffs-gap-inline, var(--diffs-gap-fallback)) * 2)\n );\n }\n\n [data-type='split']\n [data-deletions]\n [data-separator='line-info']\n [data-separator-wrapper] {\n left: var(--diffs-gap-fallback);\n margin-left: var(--diffs-gap-fallback);\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n [data-type='split']\n [data-additions]\n [data-separator='line-info']\n [data-separator-wrapper] {\n left: 0;\n margin-right: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n flex-direction: row-reverse;\n }\n\n [data-line] {\n background-color: var(--diffs-bg);\n color: var(--diffs-fg);\n }\n\n [data-type='split'][data-overflow='wrap'] [data-deletions] {\n [data-line-annotation],\n [data-buffer],\n [data-line],\n [data-separator] {\n grid-column: 1 / 3;\n }\n }\n\n [data-line-annotation] {\n min-height: var(--diffs-annotation-min-height, 0);\n background-color: var(--diffs-bg-context);\n z-index: 3;\n }\n\n [data-type='split'][data-overflow='wrap'] [data-additions] {\n [data-line-annotation],\n [data-buffer],\n [data-line],\n [data-separator] {\n margin-left: 2px;\n grid-column: 3 / 5;\n }\n }\n\n [data-separator='custom'] {\n display: grid;\n grid-template-columns: subgrid;\n }\n\n [data-column-content],\n [data-column-number] {\n position: relative;\n padding-inline: 1ch;\n }\n\n [data-indicators='classic'] [data-column-content] {\n padding-inline-start: 2ch;\n }\n\n [data-indicators='classic'] {\n [data-line-type='change-addition'] [data-column-content]::before,\n [data-line-type='change-deletion'] [data-column-content]::before {\n display: inline-block;\n width: 1ch;\n height: 1lh;\n position: absolute;\n top: 0;\n left: 0;\n -webkit-user-select: none;\n user-select: none;\n }\n\n [data-line-type='change-addition'] [data-column-content]::before {\n content: '+';\n color: var(--diffs-addition-base);\n }\n\n [data-line-type='change-deletion'] [data-column-content]::before {\n content: '-';\n color: var(--diffs-deletion-base);\n }\n }\n\n [data-indicators='bars'] {\n [data-line-type='change-deletion'] [data-column-number]::before,\n [data-line-type='change-addition'] [data-column-number]::before {\n content: '';\n display: block;\n width: 4px;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n -webkit-user-select: none;\n user-select: none;\n }\n\n [data-line-type='change-deletion'] [data-column-number]::before {\n background-image: linear-gradient(\n 0deg,\n var(--diffs-bg-deletion) 50%,\n var(--diffs-deletion-base) 50%\n );\n background-repeat: repeat;\n background-size: 2px 2px;\n background-size: calc(1lh / round(1lh / 2px)) calc(1lh / round(1lh / 2px));\n }\n\n [data-line-type='change-addition'] [data-column-number]::before {\n background-color: var(--diffs-addition-base);\n }\n }\n\n [data-overflow='wrap'] [data-column-content],\n [data-overflow='wrap'] [data-annotation-content] {\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n [data-overflow='scroll'] [data-column-content] {\n white-space: pre;\n min-height: 1lh;\n }\n\n [data-column-number] {\n grid-column: 1 / 2;\n box-sizing: content-box;\n text-align: right;\n position: sticky;\n left: 0;\n -webkit-user-select: none;\n user-select: none;\n background-color: var(--diffs-bg);\n color: var(--diffs-fg-number);\n z-index: 1;\n min-width: var(\n --diffs-min-number-column-width,\n var(--diffs-min-number-column-width-default, 3ch)\n );\n padding-left: 2ch;\n border-right: var(--diffs-gap-style, 1px solid var(--diffs-bg));\n }\n\n [data-disable-line-numbers] {\n &[data-indicators='bars'] [data-column-number] {\n min-width: 4px;\n border-right: var(--diffs-gap-style, 1px solid var(--diffs-bg));\n }\n\n [data-column-number] {\n border-right: none;\n min-width: 0;\n padding: 0;\n }\n\n [data-line-number-content] {\n display: none;\n }\n\n [data-hover-slot] {\n right: unset;\n left: 0;\n justify-content: flex-start;\n }\n\n &[data-indicators='bars'] [data-hover-slot] {\n /* Using 5px here because theres a 1px separator after the bar */\n left: 5px;\n }\n }\n\n [data-interactive-line-numbers] [data-column-number] {\n cursor: pointer;\n }\n\n [data-diff-span] {\n border-radius: 3px;\n -webkit-box-decoration-break: clone;\n box-decoration-break: clone;\n }\n\n [data-line-type='change-addition'] {\n [data-column-number] {\n color: var(\n --diffs-fg-number-addition-override,\n var(--diffs-addition-base)\n );\n }\n\n [data-diff-span] {\n background-color: var(--diffs-bg-addition-emphasis);\n }\n }\n\n [data-line-type='change-deletion'] {\n [data-column-number] {\n color: var(\n --diffs-fg-number-deletion-override,\n var(--diffs-deletion-base)\n );\n }\n\n [data-diff-span] {\n background-color: var(--diffs-bg-deletion-emphasis);\n }\n }\n\n [data-background] [data-line-type='change-addition'] {\n --diffs-line-bg: var(--diffs-bg-addition);\n\n [data-column-number] {\n background-color: var(--diffs-bg-addition-number);\n }\n }\n\n [data-background] [data-line-type='change-deletion'] {\n --diffs-line-bg: var(--diffs-bg-deletion);\n\n [data-column-number] {\n background-color: var(--diffs-bg-deletion-number);\n }\n }\n\n [data-line-type='context-expanded'] {\n --diffs-line-bg: var(--diffs-bg-context);\n\n [data-column-number] {\n background-color: var(--diffs-bg-context);\n }\n }\n\n /* By wrapping hovers in a pointer: fine, we ensure that mobile devices don't\n* require a double click */\n @media (pointer: fine) {\n [data-line]:hover:not([data-selected-line]) {\n [data-column-number],\n [data-column-content] {\n background-color: var(--diffs-bg-hover);\n }\n }\n\n [data-background] [data-line]:hover:not([data-selected-line]) {\n &[data-line-type='change-deletion'] [data-column-number],\n &[data-line-type='change-deletion'] [data-column-content] {\n background-color: var(--diffs-bg-deletion-hover);\n }\n\n &[data-line-type='change-addition'] [data-column-number],\n &[data-line-type='change-addition'] [data-column-content] {\n background-color: var(--diffs-bg-addition-hover);\n }\n }\n }\n\n [data-diffs-header] {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n gap: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n min-height: calc(\n 1lh + (var(--diffs-gap-block, var(--diffs-gap-fallback)) * 3)\n );\n padding-inline: 16px;\n }\n\n [data-header-content] {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n min-width: 0;\n white-space: nowrap;\n }\n\n [data-header-content] [data-prev-name],\n [data-header-content] [data-title] {\n direction: rtl;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n white-space: nowrap;\n }\n\n [data-prev-name] {\n opacity: 0.7;\n }\n\n [data-rename-icon] {\n fill: currentColor;\n flex-shrink: 0;\n flex-grow: 0;\n }\n\n [data-diffs-header] [data-metadata] {\n display: flex;\n align-items: center;\n gap: 1ch;\n white-space: nowrap;\n }\n\n [data-diffs-header] [data-additions-count] {\n font-family: var(--diffs-font-family, var(--diffs-font-fallback));\n color: var(--diffs-addition-base);\n }\n\n [data-diffs-header] [data-deletions-count] {\n font-family: var(--diffs-font-family, var(--diffs-font-fallback));\n color: var(--diffs-deletion-base);\n }\n\n [data-no-newline] {\n -webkit-user-select: none;\n user-select: none;\n\n [data-column-content] {\n opacity: 0.6;\n }\n }\n\n [data-annotation-content] {\n position: sticky;\n left: var(--diffs-column-number-width, 0);\n grid-column: 2 / -1;\n width: var(--diffs-column-content-width, auto);\n align-self: flex-start;\n z-index: 2;\n height: 100%;\n }\n\n /* Undo some of the stuff that the 'pre' tag does */\n [data-annotation-slot] {\n text-wrap-mode: wrap;\n word-break: normal;\n white-space-collapse: collapse;\n }\n\n [data-change-icon] {\n fill: currentColor;\n flex-shrink: 0;\n }\n\n [data-change-icon='change'],\n [data-change-icon='rename-pure'],\n [data-change-icon='rename-changed'] {\n color: var(--diffs-modified-base);\n }\n\n [data-change-icon='new'] {\n color: var(--diffs-addition-base);\n }\n\n [data-change-icon='deleted'] {\n color: var(--diffs-deletion-base);\n }\n\n [data-change-icon='file'] {\n opacity: 0.6;\n }\n\n /* Line selection highlighting */\n [data-line-type='context'][data-selected-line] {\n [data-column-number] {\n color: var(--diffs-selection-number-fg);\n background-color: var(--diffs-bg-selection-number);\n }\n\n [data-column-content] {\n background-color: var(--diffs-bg-selection);\n }\n }\n\n [data-line-type='context-expanded'],\n [data-line-type='change-addition'],\n [data-line-type='change-deletion'] {\n &[data-selected-line] {\n [data-column-content] {\n background-color: light-dark(\n color-mix(\n in lab,\n var(--diffs-line-bg, var(--diffs-bg)) 82%,\n var(--diffs-selection-base)\n ),\n color-mix(\n in lab,\n var(--diffs-line-bg, var(--diffs-bg)) 75%,\n var(--diffs-selection-base)\n )\n );\n }\n\n [data-column-number] {\n color: var(--diffs-selection-number-fg);\n background-color: light-dark(\n color-mix(\n in lab,\n var(--diffs-line-bg, var(--diffs-bg)) 75%,\n var(--diffs-selection-base)\n ),\n color-mix(\n in lab,\n var(--diffs-line-bg, var(--diffs-bg)) 60%,\n var(--diffs-selection-base)\n )\n );\n }\n }\n }\n\n [data-error-wrapper] {\n overflow: auto;\n padding: var(--diffs-gap-block, var(--diffs-gap-fallback))\n var(--diffs-gap-inline, var(--diffs-gap-fallback));\n max-height: 400px;\n scrollbar-width: none;\n\n [data-error-message] {\n font-weight: bold;\n font-size: 18px;\n color: var(--diffs-deletion-base);\n }\n\n [data-error-stack] {\n color: var(--diffs-fg-number);\n }\n }\n}\n";
2
+ var style_default = "@layer base, theme, unsafe;\n\n@layer base {\n :host {\n --diffs-bg: #fff;\n --diffs-fg: #000;\n --diffs-font-fallback:\n 'SF Mono', Monaco, Consolas, 'Ubuntu Mono', 'Liberation Mono',\n 'Courier New', monospace;\n --diffs-header-font-fallback:\n system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue',\n 'Noto Sans', 'Liberation Sans', Arial, sans-serif;\n\n --diffs-mixer: light-dark(black, white);\n --diffs-gap-fallback: 8px;\n\n /*\n // Available CSS Color Overrides\n --diffs-bg-buffer-override\n --diffs-bg-hover-override\n --diffs-bg-context-override\n --diffs-bg-separator-override\n\n --diffs-fg-number-override\n --diffs-fg-number-addition-override\n --diffs-fg-number-deletion-override\n\n --diffs-deletion-color-override\n --diffs-addition-color-override\n --diffs-modified-color-override\n\n --diffs-bg-deletion-override\n --diffs-bg-deletion-number-override\n --diffs-bg-deletion-hover-override\n --diffs-bg-deletion-emphasis-override\n\n --diffs-bg-addition-override\n --diffs-bg-addition-number-override\n --diffs-bg-addition-hover-override\n --diffs-bg-addition-emphasis-override\n\n // Line Selection Color Overrides (for enableLineSelection)\n --diffs-selection-color-override\n --diffs-bg-selection-override\n --diffs-bg-selection-number-override\n --diffs-bg-selection-background-override\n --diffs-bg-selection-number-background-override\n\n // Available CSS Layout Overrides\n --diffs-gap-inline\n --diffs-gap-block\n --diffs-gap-style\n --diffs-tab-size\n */\n\n color-scheme: light dark;\n display: block;\n font-family: var(\n --diffs-header-font-family,\n var(--diffs-header-font-fallback)\n );\n font-size: var(--diffs-font-size, 13px);\n line-height: var(--diffs-line-height, 20px);\n font-feature-settings: var(--diffs-font-features);\n }\n\n /* NOTE(mdo): Some semantic HTML elements (e.g. `pre`, `code`) have default\n * user-agent styles. These must be overridden to use our custom styles. */\n pre,\n code,\n [data-error-wrapper] {\n isolation: isolate;\n margin: 0;\n padding: 0;\n display: block;\n outline: none;\n font-family: var(--diffs-font-family, var(--diffs-font-fallback));\n }\n\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n [data-icon-sprite] {\n display: none;\n }\n\n /* NOTE(mdo): Headers and separators are within pre/code, so we need to reset\n * their font-family explicitly. */\n [data-diffs-header],\n [data-separator] {\n font-family: var(\n --diffs-header-font-family,\n var(--diffs-header-font-fallback)\n );\n }\n\n [data-file-info] {\n padding: 10px;\n font-weight: 700;\n color: var(--fg);\n /* NOTE(amadeus): we cannot use 'in oklch' because current versions of cursor\n * and vscode use an older build of chrome that appears to have a bug with\n * color-mix and 'in oklch', so use 'in lab' instead */\n background-color: color-mix(in lab, var(--bg) 98%, var(--fg));\n border-block: 1px solid color-mix(in lab, var(--bg) 95%, var(--fg));\n }\n\n [data-diffs-header],\n [data-diffs],\n [data-error-wrapper] {\n --diffs-bg: light-dark(var(--diffs-light-bg), var(--diffs-dark-bg));\n /* NOTE(amadeus): we cannot use 'in oklch' because current versions of cursor\n * and vscode use an older build of chrome that appears to have a bug with\n * color-mix and 'in oklch', so use 'in lab' instead */\n --diffs-bg-buffer: var(\n --diffs-bg-buffer-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 92%, var(--diffs-mixer)),\n color-mix(in lab, var(--diffs-bg) 92%, var(--diffs-mixer))\n )\n );\n --diffs-bg-hover: var(\n --diffs-bg-hover-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 97%, var(--diffs-mixer)),\n color-mix(in lab, var(--diffs-bg) 91%, var(--diffs-mixer))\n )\n );\n --diffs-bg-context: var(\n --diffs-bg-context-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 98.5%, var(--diffs-mixer)),\n color-mix(in lab, var(--diffs-bg) 92.5%, var(--diffs-mixer))\n )\n );\n --diffs-bg-separator: var(\n --diffs-bg-separator-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 96%, var(--diffs-mixer)),\n color-mix(in lab, var(--diffs-bg) 85%, var(--diffs-mixer))\n )\n );\n\n --diffs-fg: light-dark(var(--diffs-light), var(--diffs-dark));\n --diffs-fg-number: var(\n --diffs-fg-number-override,\n light-dark(\n color-mix(in lab, var(--diffs-fg) 65%, var(--diffs-bg)),\n color-mix(in lab, var(--diffs-fg) 65%, var(--diffs-bg))\n )\n );\n\n --diffs-deletion-base: var(\n --diffs-deletion-color-override,\n light-dark(\n var(\n --diffs-light-deletion-color,\n var(--diffs-deletion-color, rgb(255, 0, 0))\n ),\n var(\n --diffs-dark-deletion-color,\n var(--diffs-deletion-color, rgb(255, 0, 0))\n )\n )\n );\n --diffs-addition-base: var(\n --diffs-addition-color-override,\n light-dark(\n var(\n --diffs-light-addition-color,\n var(--diffs-addition-color, rgb(0, 255, 0))\n ),\n var(\n --diffs-dark-addition-color,\n var(--diffs-addition-color, rgb(0, 255, 0))\n )\n )\n );\n --diffs-modified-base: var(\n --diffs-modified-color-override,\n light-dark(\n var(\n --diffs-light-modified-color,\n var(--diffs-modified-color, rgb(0, 0, 255))\n ),\n var(\n --diffs-dark-modified-color,\n var(--diffs-modified-color, rgb(0, 0, 255))\n )\n )\n );\n\n /* NOTE(amadeus): we cannot use 'in oklch' because current versions of cursor\n * and vscode use an older build of chrome that appears to have a bug with\n * color-mix and 'in oklch', so use 'in lab' instead */\n --diffs-bg-deletion: var(\n --diffs-bg-deletion-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 88%, var(--diffs-deletion-base)),\n color-mix(in lab, var(--diffs-bg) 80%, var(--diffs-deletion-base))\n )\n );\n --diffs-bg-deletion-number: var(\n --diffs-bg-deletion-number-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 91%, var(--diffs-deletion-base)),\n color-mix(in lab, var(--diffs-bg) 85%, var(--diffs-deletion-base))\n )\n );\n --diffs-bg-deletion-hover: var(\n --diffs-bg-deletion-hover-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 80%, var(--diffs-deletion-base)),\n color-mix(in lab, var(--diffs-bg) 75%, var(--diffs-deletion-base))\n )\n );\n --diffs-bg-deletion-emphasis: var(\n --diffs-bg-deletion-emphasis-override,\n light-dark(\n rgb(from var(--diffs-deletion-base) r g b / 0.15),\n rgb(from var(--diffs-deletion-base) r g b / 0.2)\n )\n );\n\n --diffs-bg-addition: var(\n --diffs-bg-addition-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 88%, var(--diffs-addition-base)),\n color-mix(in lab, var(--diffs-bg) 80%, var(--diffs-addition-base))\n )\n );\n --diffs-bg-addition-number: var(\n --diffs-bg-addition-number-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 91%, var(--diffs-addition-base)),\n color-mix(in lab, var(--diffs-bg) 85%, var(--diffs-addition-base))\n )\n );\n --diffs-bg-addition-hover: var(\n --diffs-bg-addition-hover-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 80%, var(--diffs-addition-base)),\n color-mix(in lab, var(--diffs-bg) 70%, var(--diffs-addition-base))\n )\n );\n --diffs-bg-addition-emphasis: var(\n --diffs-bg-addition-emphasis-override,\n light-dark(\n rgb(from var(--diffs-addition-base) r g b / 0.15),\n rgb(from var(--diffs-addition-base) r g b / 0.2)\n )\n );\n\n --diffs-selection-base: var(--diffs-modified-base);\n --diffs-selection-number-fg: light-dark(\n color-mix(in lab, var(--diffs-selection-base) 65%, var(--diffs-mixer)),\n color-mix(in lab, var(--diffs-selection-base) 75%, var(--diffs-mixer))\n );\n --diffs-bg-selection: var(\n --diffs-bg-selection-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 82%, var(--diffs-selection-base)),\n color-mix(in lab, var(--diffs-bg) 75%, var(--diffs-selection-base))\n )\n );\n --diffs-bg-selection-number: var(\n --diffs-bg-selection-number-override,\n light-dark(\n color-mix(in lab, var(--diffs-bg) 75%, var(--diffs-selection-base)),\n color-mix(in lab, var(--diffs-bg) 60%, var(--diffs-selection-base))\n )\n );\n\n background-color: var(--diffs-bg);\n color: var(--diffs-fg);\n }\n\n [data-diffs] {\n /* This feels a bit crazy to me... so I need to think about it a bit more... */\n --diffs-grid-number-column-width: minmax(min-content, max-content);\n --diffs-code-grid: var(--diffs-grid-number-column-width) 1fr;\n\n [data-column-content] span {\n color: light-dark(\n var(--diffs-token-light, var(--diffs-light)),\n var(--diffs-token-dark, var(--diffs-dark))\n );\n font-weight: var(--diffs-token-light-font-weight, inherit);\n font-style: var(--diffs-token-light-font-style, inherit);\n -webkit-text-decoration: var(--diffs-token-light-text-decoration, inherit);\n text-decoration: var(--diffs-token-light-text-decoration, inherit);\n }\n }\n\n /* Since span is a pretty innocuous selector, we need to make sure we don't\n * apply tokenized BG colors to diff-spans */\n [data-column-content] span:not([data-diff-span]) {\n background-color: light-dark(\n var(--diffs-token-light-bg, inherit),\n var(--diffs-token-dark-bg, inherit)\n );\n }\n\n [data-column-content] {\n background-color: var(--diffs-line-bg, 'transparent');\n grid-column: 2 / 3;\n }\n\n [data-diffs][data-dehydrated] {\n --diffs-code-grid: var(--diffs-grid-number-column-width) minmax(0, 1fr);\n }\n\n @media (prefers-color-scheme: dark) {\n [data-diffs-header],\n [data-diffs] {\n color-scheme: dark;\n }\n\n [data-diffs] [data-column-content] span {\n font-weight: var(--diffs-token-dark-font-weight, inherit);\n font-style: var(--diffs-token-dark-font-style, inherit);\n -webkit-text-decoration: var(--diffs-token-dark-text-decoration, inherit);\n text-decoration: var(--diffs-token-dark-text-decoration, inherit);\n }\n }\n\n [data-diffs-header][data-theme-type='light'],\n [data-diffs][data-theme-type='light'] {\n color-scheme: light;\n }\n\n [data-diffs][data-theme-type='light'] [data-column-content] span {\n font-weight: var(--diffs-token-light-font-weight, inherit);\n font-style: var(--diffs-token-light-font-style, inherit);\n -webkit-text-decoration: var(--diffs-token-light-text-decoration, inherit);\n text-decoration: var(--diffs-token-light-text-decoration, inherit);\n }\n\n [data-diffs-header][data-theme-type='dark'],\n [data-diffs][data-theme-type='dark'] {\n color-scheme: dark;\n }\n\n [data-diffs][data-theme-type='dark'] [data-column-content] span {\n font-weight: var(--diffs-token-dark-font-weight, inherit);\n font-style: var(--diffs-token-dark-font-style, inherit);\n -webkit-text-decoration: var(--diffs-token-dark-text-decoration, inherit);\n text-decoration: var(--diffs-token-dark-text-decoration, inherit);\n }\n\n [data-type='split'][data-overflow='wrap'] {\n display: grid;\n grid-auto-flow: dense;\n grid-template-columns: repeat(2, var(--diffs-code-grid));\n }\n\n [data-type='split'][data-overflow='scroll'] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 2px;\n }\n\n [data-code] {\n display: block;\n display: grid;\n grid-auto-flow: dense;\n grid-template-columns: var(--diffs-code-grid);\n overflow: scroll clip;\n overscroll-behavior-x: none;\n tab-size: var(--diffs-tab-size, 2);\n align-self: flex-start;\n padding-top: var(--diffs-gap-block, var(--diffs-gap-fallback));\n padding-bottom: max(\n 0px,\n calc(var(--diffs-gap-block, var(--diffs-gap-fallback)) - 6px)\n );\n }\n\n [data-code]::-webkit-scrollbar {\n width: 0;\n height: 6px;\n }\n\n [data-code]::-webkit-scrollbar-track {\n background: transparent;\n }\n\n [data-code]::-webkit-scrollbar-thumb {\n background-color: transparent;\n border: 1px solid transparent;\n background-clip: content-box;\n border-radius: 3px;\n }\n\n [data-diffs]:hover [data-code]::-webkit-scrollbar-thumb {\n background-color: var(--diffs-bg-context);\n }\n\n [data-code]::-webkit-scrollbar-corner {\n background-color: transparent;\n }\n\n /*\n * If we apply these rules globally it will mean that webkit will opt into the\n * standards compliant version of custom css scrollbars, which we do not want\n * because the custom stuff will look better\n */\n @supports (-moz-appearance: none) {\n [data-code] {\n scrollbar-width: thin;\n scrollbar-color: var(--diffs-bg-context) transparent;\n padding-bottom: var(--diffs-gap-block, var(--diffs-gap-fallback));\n }\n }\n\n [data-diffs][data-type='split'][data-overflow='wrap'] {\n padding-block: var(--diffs-gap-block, var(--diffs-gap-fallback));\n }\n\n [data-diffs-header] ~ [data-diffs] [data-code],\n [data-diffs-header] ~ [data-diffs][data-overflow='wrap'] {\n padding-top: 0;\n }\n\n [data-type='split'][data-overflow='wrap'] [data-code] {\n display: contents;\n }\n\n [data-line-annotation],\n [data-no-newline],\n [data-line] {\n position: relative;\n display: grid;\n grid-template-columns: subgrid;\n grid-column: 1 / 3;\n }\n\n [data-line-annotation][data-selected-line] {\n background-color: unset;\n\n &::before {\n content: '';\n position: sticky;\n top: 0;\n left: 0;\n display: block;\n border-right: var(--diffs-gap-style, 1px solid var(--diffs-bg));\n background-color: var(--diffs-bg-selection-number);\n }\n\n [data-annotation-content] {\n background-color: var(--diffs-bg-selection);\n }\n }\n\n [data-interactive-lines] [data-line] {\n cursor: pointer;\n }\n\n [data-buffer] {\n display: grid;\n grid-column: 1 / 3;\n grid-template-columns: subgrid;\n -webkit-user-select: none;\n user-select: none;\n /* We multiply by 1.414 (√2) to better approximate the diagonal repeat distance */\n background-image: repeating-linear-gradient(\n -45deg,\n transparent,\n transparent calc(3px * 1.414),\n var(--diffs-bg-buffer) calc(3px * 1.414),\n var(--diffs-bg-buffer) calc(4px * 1.414)\n );\n min-height: 1lh;\n /* lol not sure this is worth it… */\n /* position: sticky; */\n /* left: 0; */\n /* width: var(--diffs-column-width, auto); */\n /* background-attachment: fixed; */\n\n &::before,\n &::after {\n content: '';\n display: block;\n }\n\n &::before {\n box-sizing: content-box;\n padding-left: 2ch;\n padding-right: 1ch;\n border-left: 4px solid transparent;\n border-right: 1px solid transparent;\n min-width: var(\n --diffs-min-number-column-width,\n var(--diffs-min-number-column-width-default, 3ch)\n );\n }\n }\n\n [data-separator] {\n grid-column: span 2;\n }\n\n [data-separator='metadata'],\n [data-separator]:empty {\n min-height: 4px;\n background-color: var(--diffs-bg-separator);\n display: grid;\n grid-template-columns: subgrid;\n }\n\n [data-separator-wrapper] {\n -webkit-user-select: none;\n user-select: none;\n fill: currentColor;\n overflow: hidden;\n }\n\n [data-separator='metadata'] [data-separator-wrapper] {\n grid-column: 2 / 3;\n width: var(--diffs-column-content-width);\n position: sticky;\n left: var(--diffs-column-number-width);\n padding: 4px 1ch;\n }\n\n [data-separator='line-info'] {\n margin-block: var(--diffs-gap-block, var(--diffs-gap-fallback));\n }\n\n [data-separator='line-info'][data-separator-first] {\n margin-top: 0;\n }\n\n [data-separator='line-info'][data-separator-last] {\n margin-bottom: 0;\n }\n\n [data-separator='line-info'] [data-separator-wrapper] {\n position: relative;\n display: flex;\n align-items: center;\n gap: 2px;\n width: auto;\n width: calc(var(--diffs-column-width) - var(--diffs-gap-fallback));\n border-radius: 6px;\n }\n\n [data-overflow='scroll']\n [data-separator='line-info']\n [data-separator-wrapper] {\n position: sticky;\n }\n\n @media (pointer: fine) {\n [data-separator-wrapper][data-separator-multi-button] {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr);\n grid-template-rows: 15px 15px;\n\n [data-expand-button] {\n height: 15px;\n }\n }\n\n [data-type='split']\n [data-additions]\n [data-separator-wrapper][data-separator-multi-button] {\n grid-template-columns: minmax(0, 1fr) auto;\n }\n\n [data-type='split'] [data-additions] [data-expand-button] {\n grid-column: 2;\n }\n\n [data-type='split'] [data-additions] [data-separator-content] {\n grid-column: 1;\n }\n }\n\n [data-expand-button],\n [data-separator-content] {\n display: flex;\n align-items: center;\n background-color: var(--diffs-bg-separator);\n }\n\n [data-expand-button] {\n justify-content: center;\n flex-shrink: 0;\n cursor: pointer;\n width: 32px;\n height: 32px;\n opacity: 0.65;\n }\n\n [data-hover-slot] {\n position: absolute;\n top: 0;\n bottom: 0;\n right: 0;\n display: flex;\n justify-content: flex-end;\n }\n\n @media (pointer: fine) {\n [data-expand-button]:hover {\n opacity: 1;\n }\n\n /* FIXME(amadeus): We need to figure out how/when to apply hover effects in\n * a more performant way because it'll trigger layout/paint re-calcs\n * probably when we dont want them... */\n [data-line]:hover {\n z-index: 2;\n }\n }\n\n [data-expand-up] [data-icon] {\n transform: scaleY(-1);\n }\n\n [data-separator-content] {\n flex: 1 1 auto;\n padding: 0 1ch;\n height: 32px;\n opacity: 0.65;\n overflow: hidden;\n justify-content: flex-start;\n\n grid-column: 2;\n grid-row: 1 / -1;\n }\n\n [data-unmodified-lines] {\n display: block;\n overflow: hidden;\n min-width: 0;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 0 1 auto;\n }\n\n [data-type='split'] [data-additions] [data-separator-content] {\n justify-content: flex-end;\n }\n\n [data-type='file']\n [data-code]\n [data-separator='line-info']\n [data-separator-wrapper] {\n margin-left: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n margin-right: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n width: calc(\n var(--diffs-column-width) -\n (var(--diffs-gap-inline, var(--diffs-gap-fallback)) * 2)\n );\n }\n\n [data-type='split']\n [data-deletions]\n [data-separator='line-info']\n [data-separator-wrapper] {\n margin-left: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n [data-type='file'][data-overflow='scroll'],\n [data-type='split'][data-overflow='scroll'] {\n [data-deletions] [data-separator='line-info'] [data-separator-wrapper] {\n left: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n }\n }\n\n [data-type='split']\n [data-additions]\n [data-separator='line-info']\n [data-separator-wrapper] {\n margin-right: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n flex-direction: row-reverse;\n }\n\n [data-type='split'][data-overflow='scroll']\n [data-additions]\n [data-separator='line-info']\n [data-separator-wrapper] {\n left: 0;\n }\n\n [data-line] {\n background-color: var(--diffs-bg);\n color: var(--diffs-fg);\n }\n\n [data-type='split'][data-overflow='wrap'] [data-deletions] {\n [data-line-annotation],\n [data-buffer],\n [data-line],\n [data-separator],\n [data-virtualized-buffer],\n [data-no-newline] {\n margin-right: 1px;\n grid-column: 1 / 3;\n }\n }\n\n [data-line-annotation] {\n min-height: var(--diffs-annotation-min-height, 0);\n background-color: var(--diffs-bg-context);\n z-index: 3;\n }\n\n [data-type='split'][data-overflow='wrap'] [data-additions] {\n [data-line-annotation],\n [data-buffer],\n [data-line],\n [data-separator],\n [data-virtualized-buffer],\n [data-no-newline] {\n margin-left: 1px;\n grid-column: 3 / 5;\n }\n }\n\n [data-separator='custom'] {\n display: grid;\n grid-template-columns: subgrid;\n }\n\n [data-column-content],\n [data-column-number] {\n position: relative;\n padding-inline: 1ch;\n }\n\n [data-indicators='classic'] [data-column-content] {\n padding-inline-start: 2ch;\n }\n\n [data-indicators='classic'] {\n [data-line-type='change-addition'] [data-column-content]::before,\n [data-line-type='change-deletion'] [data-column-content]::before {\n display: inline-block;\n width: 1ch;\n height: 1lh;\n position: absolute;\n top: 0;\n left: 0;\n -webkit-user-select: none;\n user-select: none;\n }\n\n [data-line-type='change-addition'] [data-column-content]::before {\n content: '+';\n color: var(--diffs-addition-base);\n }\n\n [data-line-type='change-deletion'] [data-column-content]::before {\n content: '-';\n color: var(--diffs-deletion-base);\n }\n }\n\n [data-indicators='bars'] {\n [data-line-type='change-deletion'],\n [data-line-type='change-addition'] {\n [data-column-number]::before {\n content: '';\n display: block;\n width: 4px;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n -webkit-user-select: none;\n user-select: none;\n contain: strict;\n }\n }\n\n [data-line-type='change-deletion'] [data-column-number]::before {\n background-image: linear-gradient(\n 0deg,\n var(--diffs-bg-deletion) 50%,\n var(--diffs-deletion-base) 50%\n );\n background-repeat: repeat;\n background-size: 2px 2px;\n background-size: calc(1lh / round(1lh / 2px)) calc(1lh / round(1lh / 2px));\n }\n\n [data-line-type='change-addition'] [data-column-number]::before {\n background-color: var(--diffs-addition-base);\n }\n }\n\n [data-overflow='wrap'] [data-column-content],\n [data-overflow='wrap'] [data-annotation-content] {\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n [data-overflow='scroll'] [data-column-content] {\n white-space: pre;\n min-height: 1lh;\n }\n\n [data-column-number] {\n grid-column: 1 / 2;\n box-sizing: content-box;\n text-align: right;\n -webkit-user-select: none;\n user-select: none;\n background-color: var(--diffs-bg);\n color: var(--diffs-fg-number);\n z-index: 1;\n min-width: var(\n --diffs-min-number-column-width,\n var(--diffs-min-number-column-width-default, 3ch)\n );\n padding-left: 2ch;\n border-right: var(--diffs-gap-style, 1px solid var(--diffs-bg));\n }\n\n [data-overflow='scroll'] [data-column-number] {\n position: sticky;\n left: 0;\n }\n\n [data-disable-line-numbers] {\n &[data-indicators='bars'] [data-column-number] {\n min-width: 4px;\n border-right: var(--diffs-gap-style, 1px solid var(--diffs-bg));\n }\n\n [data-column-number],\n [data-buffer]::before {\n min-width: 0;\n padding: 0;\n }\n\n [data-line-number-content] {\n display: none;\n }\n\n [data-hover-slot] {\n right: unset;\n left: 0;\n justify-content: flex-start;\n }\n\n &[data-indicators='bars'] [data-hover-slot] {\n /* Using 5px here because theres a 1px separator after the bar */\n left: 5px;\n }\n }\n\n [data-interactive-line-numbers] [data-column-number] {\n cursor: pointer;\n }\n\n [data-diff-span] {\n border-radius: 3px;\n -webkit-box-decoration-break: clone;\n box-decoration-break: clone;\n }\n\n [data-line-type='change-addition'] {\n [data-column-number] {\n color: var(\n --diffs-fg-number-addition-override,\n var(--diffs-addition-base)\n );\n }\n\n [data-diff-span] {\n background-color: var(--diffs-bg-addition-emphasis);\n }\n }\n\n [data-line-type='change-deletion'] {\n [data-column-number] {\n color: var(\n --diffs-fg-number-deletion-override,\n var(--diffs-deletion-base)\n );\n }\n\n [data-diff-span] {\n background-color: var(--diffs-bg-deletion-emphasis);\n }\n }\n\n [data-background] [data-line-type='change-addition'] {\n --diffs-line-bg: var(--diffs-bg-addition);\n\n [data-column-number] {\n background-color: var(--diffs-bg-addition-number);\n }\n }\n\n [data-background] [data-line-type='change-deletion'] {\n --diffs-line-bg: var(--diffs-bg-deletion);\n\n [data-column-number] {\n background-color: var(--diffs-bg-deletion-number);\n }\n }\n\n [data-line-type='context-expanded'] {\n --diffs-line-bg: var(--diffs-bg-context);\n\n [data-column-number] {\n background-color: var(--diffs-bg-context);\n }\n }\n\n /* By wrapping hovers in a pointer: fine, we ensure that mobile devices don't\n * require a double click */\n @media (pointer: fine) {\n [data-line]:hover:not([data-selected-line]) {\n [data-column-number],\n [data-column-content] {\n background-color: var(--diffs-bg-hover);\n }\n }\n\n [data-background] [data-line]:hover:not([data-selected-line]) {\n &[data-line-type='change-deletion'] [data-column-number],\n &[data-line-type='change-deletion'] [data-column-content] {\n background-color: var(--diffs-bg-deletion-hover);\n }\n\n &[data-line-type='change-addition'] [data-column-number],\n &[data-line-type='change-addition'] [data-column-content] {\n background-color: var(--diffs-bg-addition-hover);\n }\n }\n }\n\n [data-diffs-header] {\n position: relative;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n gap: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n min-height: calc(\n 1lh + (var(--diffs-gap-block, var(--diffs-gap-fallback)) * 3)\n );\n padding-inline: 16px;\n top: 0;\n z-index: 2;\n }\n\n [data-header-content] {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--diffs-gap-inline, var(--diffs-gap-fallback));\n min-width: 0;\n white-space: nowrap;\n }\n\n [data-header-content] [data-prev-name],\n [data-header-content] [data-title] {\n direction: rtl;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n white-space: nowrap;\n }\n\n [data-prev-name] {\n opacity: 0.7;\n }\n\n [data-rename-icon] {\n fill: currentColor;\n flex-shrink: 0;\n flex-grow: 0;\n }\n\n [data-diffs-header] [data-metadata] {\n display: flex;\n align-items: center;\n gap: 1ch;\n white-space: nowrap;\n }\n\n [data-diffs-header] [data-additions-count] {\n font-family: var(--diffs-font-family, var(--diffs-font-fallback));\n color: var(--diffs-addition-base);\n }\n\n [data-diffs-header] [data-deletions-count] {\n font-family: var(--diffs-font-family, var(--diffs-font-fallback));\n color: var(--diffs-deletion-base);\n }\n\n [data-no-newline] {\n -webkit-user-select: none;\n user-select: none;\n\n [data-column-content] {\n opacity: 0.6;\n }\n }\n\n [data-annotation-content] {\n position: relative;\n grid-column: 2 / -1;\n width: var(--diffs-column-content-width, auto);\n align-self: flex-start;\n z-index: 2;\n height: 100%;\n }\n\n /* Sticky positioning has a composite costs, so we should _only_ pay it if we\n * need to */\n [data-overflow='scroll'] [data-annotation-content] {\n position: sticky;\n left: var(--diffs-column-number-width, 0);\n }\n\n /* Undo some of the stuff that the 'pre' tag does */\n [data-annotation-slot] {\n text-wrap-mode: wrap;\n word-break: normal;\n white-space-collapse: collapse;\n }\n\n [data-change-icon] {\n fill: currentColor;\n flex-shrink: 0;\n }\n\n [data-change-icon='change'],\n [data-change-icon='rename-pure'],\n [data-change-icon='rename-changed'] {\n color: var(--diffs-modified-base);\n }\n\n [data-change-icon='new'] {\n color: var(--diffs-addition-base);\n }\n\n [data-change-icon='deleted'] {\n color: var(--diffs-deletion-base);\n }\n\n [data-change-icon='file'] {\n opacity: 0.6;\n }\n\n /* Line selection highlighting */\n [data-line-type='context'][data-selected-line] {\n [data-column-number] {\n color: var(--diffs-selection-number-fg);\n background-color: var(--diffs-bg-selection-number);\n }\n\n [data-column-content] {\n background-color: var(--diffs-bg-selection);\n }\n }\n\n [data-line-type='context-expanded'],\n [data-line-type='change-addition'],\n [data-line-type='change-deletion'] {\n &[data-selected-line] {\n [data-column-content] {\n background-color: light-dark(\n color-mix(\n in lab,\n var(--diffs-line-bg, var(--diffs-bg)) 82%,\n var(--diffs-selection-base)\n ),\n color-mix(\n in lab,\n var(--diffs-line-bg, var(--diffs-bg)) 75%,\n var(--diffs-selection-base)\n )\n );\n }\n\n [data-column-number] {\n color: var(--diffs-selection-number-fg);\n background-color: light-dark(\n color-mix(\n in lab,\n var(--diffs-line-bg, var(--diffs-bg)) 75%,\n var(--diffs-selection-base)\n ),\n color-mix(\n in lab,\n var(--diffs-line-bg, var(--diffs-bg)) 60%,\n var(--diffs-selection-base)\n )\n );\n }\n }\n }\n\n [data-error-wrapper] {\n overflow: auto;\n padding: var(--diffs-gap-block, var(--diffs-gap-fallback))\n var(--diffs-gap-inline, var(--diffs-gap-fallback));\n max-height: 400px;\n scrollbar-width: none;\n\n [data-error-message] {\n font-weight: bold;\n font-size: 18px;\n color: var(--diffs-deletion-base);\n }\n\n [data-error-stack] {\n color: var(--diffs-fg-number);\n }\n }\n\n [data-virtualized-buffer] {\n /* for blanking debugging purposes */\n /* background-color: red; */\n grid-column: 1 / 3;\n }\n}\n";
3
3
 
4
4
  //#endregion
5
5
  export { style_default as default };