{"version":3,"file":"DiffHunksRenderer.js","names":["options: DiffHunksRendererOptions","onRenderUpdate?: () => unknown","workerManager?: WorkerPoolManager | undefined","createDefaultAnnotationElement","options: RenderDiffOptions","options","additionsContentAST: ElementContent[] | undefined","deletionsContentAST: ElementContent[] | undefined","unifiedContentAST: ElementContent[] | undefined","hunkData: HunkData[]","context: ProcessContext","pendingSplitContext: PendingSplitContext","renderedLineContext: RenderedLineContext","deletionSpan: AnnotationSpan","additionSpan: AnnotationSpan","createAnnotationElement"],"sources":["../../src/renderers/DiffHunksRenderer.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement, Properties } from 'hast';\nimport { toHtml } from 'hast-util-to-html';\n\nimport {\n  DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n  DEFAULT_EXPANDED_REGION,\n  DEFAULT_RENDER_RANGE,\n  DEFAULT_THEMES,\n} 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  BaseDiffOptionsWithDefaults,\n  CodeColumnType,\n  CustomPreProperties,\n  DiffLineAnnotation,\n  DiffsHighlighter,\n  ExpansionDirections,\n  FileDiffMetadata,\n  FileHeaderRenderMode,\n  HunkData,\n  HunkExpansionRegion,\n  HunkSeparators,\n  LineTypes,\n  RenderDiffOptions,\n  RenderDiffResult,\n  RenderedDiffASTCache,\n  RenderRange,\n  SupportedLanguages,\n  ThemedDiffResult,\n} from '../types';\nimport { areDiffRenderOptionsEqual } from '../utils/areDiffRenderOptionsEqual';\nimport { areRenderRangesEqual } from '../utils/areRenderRangesEqual';\nimport { createAnnotationElement as createDefaultAnnotationElement } from '../utils/createAnnotationElement';\nimport { createContentColumn } from '../utils/createContentColumn';\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 {\n  createGutterGap,\n  createGutterItem,\n  createGutterWrapper,\n  createHastElement,\n} from '../utils/hast_utils';\nimport { isDefaultRenderRange } from '../utils/isDefaultRenderRange';\nimport { isDiffPlainText } from '../utils/isDiffPlainText';\nimport type { DiffLineMetadata } from '../utils/iterateOverDiff';\nimport { iterateOverDiff } from '../utils/iterateOverDiff';\nimport { renderDiffWithHighlighter } from '../utils/renderDiffWithHighlighter';\nimport { shouldUseTokenTransformer } from '../utils/shouldUseTokenTransformer';\nimport type { WorkerPoolManager } from '../worker';\n\ninterface PushLineWithAnnotation {\n  diffStyle: 'unified' | 'split';\n  type: 'context' | 'context-expanded' | 'change';\n\n  deletionLine?: ElementContent;\n  additionLine?: ElementContent;\n\n  unifiedSpan?: AnnotationSpan;\n  deletionSpan?: AnnotationSpan;\n  additionSpan?: AnnotationSpan;\n\n  createAnnotationElement(span: AnnotationSpan): HASTElement;\n  context: ProcessContext;\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 ProcessContext {\n  rowCount: number;\n  expansionLineCount: number;\n  hunkSeparators: HunkSeparators;\n  unifiedContentAST: ElementContent[];\n  deletionsContentAST: ElementContent[];\n  additionsContentAST: ElementContent[];\n  unifiedGutterAST: HASTElement;\n  deletionsGutterAST: HASTElement;\n  additionsGutterAST: HASTElement;\n  hunkData: HunkData[];\n  pushToGutter(type: CodeColumnType, element: HASTElement): void;\n  incrementRowCount(count?: number): void;\n}\n\nexport interface DiffHunksRendererOptions extends BaseDiffOptions {\n  headerRenderMode?: FileHeaderRenderMode;\n}\n\nexport interface DiffHunksRendererOptionsWithDefaults extends Omit<\n  BaseDiffOptionsWithDefaults,\n  'themeType'\n> {\n  headerRenderMode: FileHeaderRenderMode;\n}\n\nexport interface UnifiedLineDecorationProps {\n  type: 'context' | 'context-expanded' | 'change';\n  lineType: LineTypes;\n  additionLineIndex: number | undefined;\n  deletionLineIndex: number | undefined;\n}\n\nexport interface SplitLineDecorationProps {\n  side: 'deletions' | 'additions';\n  type: 'context' | 'context-expanded' | 'change';\n  lineIndex: number | undefined;\n}\n\nexport interface LineDecoration {\n  gutterLineType: LineTypes;\n  gutterProperties?: Properties;\n  contentProperties?: Properties;\n}\n\ninterface PendingSplitContext {\n  size: number;\n  side: 'additions' | 'deletions' | undefined;\n  increment(): void;\n  flush(): void;\n}\n\nexport interface RenderedLineContext {\n  type: 'context' | 'context-expanded' | 'change';\n  hunkIndex: number;\n  lineIndex: number;\n  unifiedLineIndex: number;\n  splitLineIndex: number;\n  deletionLine?: DiffLineMetadata;\n  additionLine?: DiffLineMetadata;\n}\n\nexport interface InjectedRow {\n  content: HASTElement;\n  gutter: HASTElement;\n}\n\nexport interface SplitInjectedRow {\n  deletion: InjectedRow | undefined;\n  addition: InjectedRow | undefined;\n}\n\nexport interface UnifiedInjectedRowPlacement {\n  before?: InjectedRow[];\n  after?: InjectedRow[];\n}\n\nexport interface SplitInjectedRowPlacement {\n  before?: SplitInjectedRow[];\n  after?: SplitInjectedRow[];\n}\n\nexport interface HunksRenderResult {\n  unifiedGutterAST: ElementContent[] | undefined;\n  unifiedContentAST: ElementContent[] | undefined;\n  deletionsGutterAST: ElementContent[] | undefined;\n  deletionsContentAST: ElementContent[] | undefined;\n  additionsGutterAST: ElementContent[] | undefined;\n  additionsContentAST: 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  rowCount: number;\n  bufferBefore: number;\n  bufferAfter: number;\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: DiffHunksRendererOptions = { 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  public 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  public recycle(): void {\n    this.highlighter = undefined;\n    this.diff = undefined;\n    this.renderCache = undefined;\n    this.workerManager?.cleanUpPendingTasks(this);\n  }\n\n  public setOptions(options: DiffHunksRendererOptions): void {\n    this.options = options;\n  }\n\n  public mergeOptions(options: Partial<DiffHunksRendererOptions>): void {\n    this.options = { ...this.options, ...options };\n  }\n\n  public expandHunk(\n    index: number,\n    direction: ExpansionDirections,\n    expansionLineCount: number = this.getOptionsWithDefaults()\n      .expansionLineCount\n  ): void {\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    // NOTE(amadeus): If our render cache is not highlighted, we need to clear\n    // it, otherwise we won't have the correct AST lines\n    if (this.renderCache?.highlighted !== true) {\n      this.renderCache = undefined;\n    }\n    this.expandedHunks.set(index, region);\n  }\n\n  public getExpandedHunk(hunkIndex: number): HunkExpansionRegion {\n    return this.expandedHunks.get(hunkIndex) ?? DEFAULT_EXPANDED_REGION;\n  }\n\n  public getExpandedHunksMap(): Map<number, HunkExpansionRegion> {\n    return this.expandedHunks;\n  }\n\n  public setLineAnnotations(\n    lineAnnotations: DiffLineAnnotation<LAnnotation>[]\n  ): 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  protected getUnifiedLineDecoration({\n    lineType,\n  }: UnifiedLineDecorationProps): LineDecoration {\n    return { gutterLineType: lineType };\n  }\n\n  protected getSplitLineDecoration({\n    side,\n    type,\n  }: SplitLineDecorationProps): LineDecoration {\n    if (type !== 'change') {\n      return { gutterLineType: type };\n    }\n    return {\n      gutterLineType:\n        side === 'deletions' ? 'change-deletion' : 'change-addition',\n    };\n  }\n\n  protected createAnnotationElement(span: AnnotationSpan): HASTElement {\n    return createDefaultAnnotationElement(span);\n  }\n\n  // Unified hook returns extra rows that render before/after the current line.\n  declare protected getUnifiedInjectedRowsForLine?: (\n    ctx: RenderedLineContext\n  ) => UnifiedInjectedRowPlacement | undefined;\n\n  // Split hook returns extra rows per side before/after the current line.\n  declare protected getSplitInjectedRowsForLine?: (\n    ctx: RenderedLineContext\n  ) => SplitInjectedRowPlacement | undefined;\n\n  protected getOptionsWithDefaults(): DiffHunksRendererOptionsWithDefaults {\n    const {\n      diffIndicators = 'bars',\n      diffStyle = 'split',\n      disableBackground = false,\n      disableFileHeader = false,\n      disableLineNumbers = false,\n      disableVirtualizationBuffers = false,\n      collapsed = false,\n      expandUnchanged = false,\n      collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n      expansionLineCount = 100,\n      hunkSeparators = 'line-info',\n      lineDiffType = 'word-alt',\n      maxLineDiffLength = 1000,\n      overflow = 'scroll',\n      theme = DEFAULT_THEMES,\n      headerRenderMode = 'default',\n      tokenizeMaxLineLength = 1000,\n      useTokenTransformer = false,\n      useCSSClasses = false,\n    } = this.options;\n    return {\n      diffIndicators,\n      diffStyle,\n      disableBackground,\n      disableFileHeader,\n      disableLineNumbers,\n      disableVirtualizationBuffers,\n      collapsed,\n      expandUnchanged,\n      collapsedContextThreshold,\n      expansionLineCount,\n      hunkSeparators,\n      lineDiffType,\n      maxLineDiffLength,\n      overflow,\n      theme: this.workerManager?.getDiffRenderOptions().theme ?? theme,\n      headerRenderMode,\n      tokenizeMaxLineLength,\n      useTokenTransformer,\n      useCSSClasses,\n    };\n  }\n\n  private async initializeHighlighter(): Promise<DiffsHighlighter> {\n    this.highlighter = await getSharedHighlighter(\n      getHighlighterOptions(this.computedLang, this.options)\n    );\n    return this.highlighter;\n  }\n\n  public 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 && !areDiffRenderOptionsEqual(options, cache.options)) {\n      cache = undefined;\n    }\n    this.renderCache ??= {\n      diff,\n      highlighted: !isDiffPlainText(diff),\n      options,\n      result: cache?.result,\n      renderRange: undefined,\n    };\n    if (this.workerManager?.isWorkingPool() === true) {\n      if (this.renderCache.result == null) {\n        // We should only kick off a preload of the AST if we have a WorkerPool\n        this.workerManager.highlightDiffAST(this, this.diff);\n      }\n    }\n    // Lets attempt to get the highlighter/languages ready immediately\n    else if (this.highlighter == null) {\n      this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n      void this.initializeHighlighter();\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, maxLineDiffLength } =\n        this.getOptionsWithDefaults();\n      return {\n        theme,\n        useTokenTransformer: shouldUseTokenTransformer(this.options),\n        tokenizeMaxLineLength,\n        lineDiffType,\n        maxLineDiffLength,\n      };\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      !areDiffRenderOptionsEqual(options, renderCache.options)\n    ) {\n      return { options, forceRender: true };\n    }\n    return { options, forceRender: false };\n  }\n\n  public 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, collapsedContextThreshold } =\n      this.getOptionsWithDefaults();\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          (diff !== this.renderCache.diff ||\n            !areRenderRangesEqual(this.renderCache.renderRange, renderRange)))\n      ) {\n        this.renderCache.diff = diff;\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          collapsedContextThreshold\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          // In this case we need to force a re-render, so we can do that by\n          // reaching into renderCache\n          if (this.renderCache != null) {\n            this.renderCache.highlighted = false;\n          }\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  public 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  protected createPreElement(\n    split: boolean,\n    totalLines: number,\n    customProperties?: CustomPreProperties\n  ): HASTElement {\n    const { diffIndicators, disableBackground, disableLineNumbers, overflow } =\n      this.getOptionsWithDefaults();\n    return createPreElement({\n      type: 'diff',\n      diffIndicators,\n      disableBackground,\n      disableLineNumbers,\n      overflow,\n      split,\n      totalLines,\n      customProperties,\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 { collapsedContextThreshold } = this.getOptionsWithDefaults();\n    const result = renderDiffWithHighlighter(diff, highlighter, options, {\n      forcePlainText,\n      expandedHunks: forcePlainText ? true : undefined,\n      collapsedContextThreshold,\n    });\n    return { result, options };\n  }\n\n  public onHighlightSuccess(\n    diff: FileDiffMetadata,\n    result: ThemedDiffResult,\n    options: RenderDiffOptions\n  ): void {\n    // NOTE(amadeus): This is a bad assumption, and I should figure out\n    // something better...\n    // If renderCache was blown away, we can assume we've run cleanUp()\n    if (this.renderCache == null) {\n      return;\n    }\n\n    const triggerRenderUpdate =\n      !this.renderCache.highlighted ||\n      !areDiffRenderOptionsEqual(this.renderCache.options, options) ||\n      this.renderCache.diff !== diff;\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  public 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      expandUnchanged,\n      expansionLineCount,\n      collapsedContextThreshold,\n      hunkSeparators,\n    } = this.getOptionsWithDefaults();\n\n    this.diff = fileDiff;\n    const unified = diffStyle === 'unified';\n\n    let additionsContentAST: ElementContent[] | undefined = [];\n    let deletionsContentAST: ElementContent[] | undefined = [];\n    let unifiedContentAST: ElementContent[] | undefined = [];\n\n    const hunkData: HunkData[] = [];\n    const { additionLines, deletionLines } = code;\n    const context: ProcessContext = {\n      rowCount: 0,\n      hunkSeparators,\n      additionsContentAST,\n      deletionsContentAST,\n      unifiedContentAST,\n      unifiedGutterAST: createGutterWrapper(),\n      deletionsGutterAST: createGutterWrapper(),\n      additionsGutterAST: createGutterWrapper(),\n      expansionLineCount,\n      hunkData,\n      incrementRowCount(count = 1) {\n        context.rowCount += count;\n      },\n      pushToGutter(type: CodeColumnType, element: HASTElement) {\n        switch (type) {\n          case 'unified': {\n            context.unifiedGutterAST.children.push(element);\n            break;\n          }\n          case 'deletions': {\n            context.deletionsGutterAST.children.push(element);\n            break;\n          }\n          case 'additions': {\n            context.additionsGutterAST.children.push(element);\n            break;\n          }\n        }\n      },\n    };\n    const trailingRangeSize = calculateTrailingRangeSize(fileDiff);\n    const pendingSplitContext: PendingSplitContext = {\n      size: 0,\n      side: undefined,\n      increment() {\n        this.size += 1;\n      },\n      flush() {\n        if (diffStyle === 'unified') {\n          return;\n        }\n        if (this.size <= 0 || this.side == null) {\n          this.side = undefined;\n          this.size = 0;\n          return;\n        }\n        if (this.side === 'additions') {\n          context.pushToGutter(\n            'additions',\n            createGutterGap(undefined, 'buffer', this.size)\n          );\n          additionsContentAST?.push(createEmptyRowBuffer(this.size));\n        } else {\n          context.pushToGutter(\n            'deletions',\n            createGutterGap(undefined, 'buffer', this.size)\n          );\n          deletionsContentAST?.push(createEmptyRowBuffer(this.size));\n        }\n        this.size = 0;\n        this.side = undefined;\n      },\n    };\n\n    const pushGutterLineNumber = (\n      type: CodeColumnType,\n      lineType: LineTypes | 'buffer' | 'separator' | 'annotation',\n      lineNumber: number,\n      lineIndex: string,\n      gutterProperties: Properties | undefined\n    ) => {\n      context.pushToGutter(\n        type,\n        createGutterItem(lineType, lineNumber, lineIndex, gutterProperties)\n      );\n    };\n\n    function pushSeparators(props: PushSeparatorProps) {\n      pendingSplitContext.flush();\n      if (diffStyle === 'unified') {\n        pushSeparator('unified', props, context);\n      } else {\n        pushSeparator('deletions', props, context);\n        pushSeparator('additions', props, context);\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      collapsedContextThreshold,\n      callback: ({\n        hunkIndex,\n        hunk,\n        collapsedBefore,\n        collapsedAfter,\n        additionLine,\n        deletionLine,\n        type,\n      }) => {\n        const splitLineIndex =\n          deletionLine != null\n            ? deletionLine.splitLineIndex\n            : additionLine.splitLineIndex;\n        const unifiedLineIndex =\n          additionLine != null\n            ? additionLine.unifiedLineIndex\n            : deletionLine.unifiedLineIndex;\n\n        if (diffStyle === 'split' && type !== 'change') {\n          pendingSplitContext.flush();\n        }\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' ? unifiedLineIndex : splitLineIndex;\n        const renderedLineContext: RenderedLineContext = {\n          type,\n          hunkIndex,\n          lineIndex,\n          unifiedLineIndex,\n          splitLineIndex,\n          deletionLine,\n          additionLine,\n        };\n\n        if (diffStyle === 'unified') {\n          const injectedRows =\n            this.getUnifiedInjectedRowsForLine?.(renderedLineContext);\n          if (injectedRows?.before != null) {\n            pushUnifiedInjectedRows(injectedRows.before, context);\n          }\n          let deletionLineContent =\n            deletionLine != null\n              ? deletionLines[deletionLine.lineIndex]\n              : undefined;\n          let additionLineContent =\n            additionLine != null\n              ? additionLines[additionLine.lineIndex]\n              : undefined;\n          if (deletionLineContent == null && additionLineContent == 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          const lineType =\n            type === 'change'\n              ? additionLine != null\n                ? 'change-addition'\n                : 'change-deletion'\n              : type;\n          const lineDecoration = this.getUnifiedLineDecoration({\n            // NOTE: This function gets extended so don't remove\n            // these extra props\n            type,\n            lineType,\n            additionLineIndex: additionLine?.lineIndex,\n            deletionLineIndex: deletionLine?.lineIndex,\n          });\n          pushGutterLineNumber(\n            'unified',\n            lineDecoration.gutterLineType,\n            additionLine != null\n              ? additionLine.lineNumber\n              : deletionLine.lineNumber,\n            `${unifiedLineIndex},${splitLineIndex}`,\n            lineDecoration.gutterProperties\n          );\n          if (additionLineContent != null) {\n            additionLineContent = withContentProperties(\n              additionLineContent,\n              lineDecoration.contentProperties\n            );\n          } else if (deletionLineContent != null) {\n            deletionLineContent = withContentProperties(\n              deletionLineContent,\n              lineDecoration.contentProperties\n            );\n          }\n          pushLineWithAnnotation({\n            diffStyle: 'unified',\n            type: type,\n            deletionLine: deletionLineContent,\n            additionLine: additionLineContent,\n            unifiedSpan: this.getAnnotations(\n              'unified',\n              deletionLine?.lineNumber,\n              additionLine?.lineNumber,\n              hunkIndex,\n              lineIndex\n            ),\n            createAnnotationElement: (span) =>\n              this.createAnnotationElement(span),\n            context,\n          });\n          if (injectedRows?.after != null) {\n            pushUnifiedInjectedRows(injectedRows.after, context);\n          }\n        } else {\n          const injectedRows =\n            this.getSplitInjectedRowsForLine?.(renderedLineContext);\n          if (injectedRows?.before != null) {\n            pushSplitInjectedRows(\n              injectedRows.before,\n              context,\n              pendingSplitContext\n            );\n          }\n\n          let deletionLineContent =\n            deletionLine != null\n              ? deletionLines[deletionLine.lineIndex]\n              : undefined;\n          let additionLineContent =\n            additionLine != null\n              ? additionLines[additionLine.lineIndex]\n              : undefined;\n          const deletionLineDecoration = this.getSplitLineDecoration({\n            side: 'deletions',\n            type,\n            lineIndex: deletionLine?.lineIndex,\n          });\n          const additionLineDecoration = this.getSplitLineDecoration({\n            side: 'additions',\n            type,\n            lineIndex: additionLine?.lineIndex,\n          });\n\n          if (deletionLineContent == null && additionLineContent == 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            if (type === 'change') {\n              if (additionLineContent == null) {\n                return 'additions';\n              } else if (deletionLineContent == null) {\n                return 'deletions';\n              }\n            }\n            return undefined;\n          })();\n          if (missingSide != null) {\n            if (\n              pendingSplitContext.side != null &&\n              pendingSplitContext.side !== 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            pendingSplitContext.side = missingSide;\n            pendingSplitContext.increment();\n          }\n\n          const annotationSpans = this.getAnnotations(\n            'split',\n            deletionLine?.lineNumber,\n            additionLine?.lineNumber,\n            hunkIndex,\n            lineIndex\n          );\n          if (annotationSpans != null && pendingSplitContext.size > 0) {\n            pendingSplitContext.flush();\n          }\n\n          if (deletionLine != null) {\n            const deletionLineDecorated = withContentProperties(\n              deletionLineContent,\n              deletionLineDecoration.contentProperties\n            );\n            pushGutterLineNumber(\n              'deletions',\n              deletionLineDecoration.gutterLineType,\n              deletionLine.lineNumber,\n              `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n              deletionLineDecoration.gutterProperties\n            );\n            if (deletionLineDecorated != null) {\n              deletionLineContent = deletionLineDecorated;\n            }\n          }\n          if (additionLine != null) {\n            const additionLineDecorated = withContentProperties(\n              additionLineContent,\n              additionLineDecoration.contentProperties\n            );\n            pushGutterLineNumber(\n              'additions',\n              additionLineDecoration.gutterLineType,\n              additionLine.lineNumber,\n              `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n              additionLineDecoration.gutterProperties\n            );\n            if (additionLineDecorated != null) {\n              additionLineContent = additionLineDecorated;\n            }\n          }\n          pushLineWithAnnotation({\n            diffStyle: 'split',\n            type: type,\n            additionLine: additionLineContent,\n            deletionLine: deletionLineContent,\n            ...annotationSpans,\n            createAnnotationElement: (span) =>\n              this.createAnnotationElement(span),\n            context,\n          });\n          if (injectedRows?.after != null) {\n            pushSplitInjectedRows(\n              injectedRows.after,\n              context,\n              pendingSplitContext\n            );\n          }\n        }\n\n        const noEOFCRDeletion = deletionLine?.noEOFCR ?? false;\n        const noEOFCRAddition = additionLine?.noEOFCR ?? false;\n        if (noEOFCRAddition || noEOFCRDeletion) {\n          if (noEOFCRDeletion) {\n            const noEOFType =\n              type === 'context' || type === 'context-expanded'\n                ? type\n                : 'change-deletion';\n            if (diffStyle === 'unified') {\n              context.unifiedContentAST.push(createNoNewlineElement(noEOFType));\n              context.pushToGutter(\n                'unified',\n                createGutterGap(noEOFType, 'metadata', 1)\n              );\n            } else {\n              context.deletionsContentAST.push(\n                createNoNewlineElement(noEOFType)\n              );\n              context.pushToGutter(\n                'deletions',\n                createGutterGap(noEOFType, 'metadata', 1)\n              );\n              if (!noEOFCRAddition) {\n                context.pushToGutter(\n                  'additions',\n                  createGutterGap(undefined, 'buffer', 1)\n                );\n                context.additionsContentAST.push(createEmptyRowBuffer(1));\n              }\n            }\n          }\n          if (noEOFCRAddition) {\n            const noEOFType =\n              type === 'context' || type === 'context-expanded'\n                ? type\n                : 'change-addition';\n            if (diffStyle === 'unified') {\n              context.unifiedContentAST.push(createNoNewlineElement(noEOFType));\n              context.pushToGutter(\n                'unified',\n                createGutterGap(noEOFType, 'metadata', 1)\n              );\n            } else {\n              context.additionsContentAST.push(\n                createNoNewlineElement(noEOFType)\n              );\n              context.pushToGutter(\n                'additions',\n                createGutterGap(noEOFType, 'metadata', 1)\n              );\n              if (!noEOFCRDeletion) {\n                context.pushToGutter(\n                  'deletions',\n                  createGutterGap(undefined, 'buffer', 1)\n                );\n                context.deletionsContentAST.push(createEmptyRowBuffer(1));\n              }\n            }\n          }\n          context.incrementRowCount(1);\n        }\n\n        if (collapsedAfter > 0 && hunkSeparators !== 'simple') {\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        context.incrementRowCount(1);\n      },\n    });\n\n    if (diffStyle === 'split') {\n      pendingSplitContext.flush();\n    }\n\n    const totalLines = Math.max(\n      getTotalLineCountFromHunks(fileDiff.hunks),\n      fileDiff.additionLines.length ?? 0,\n      fileDiff.deletionLines.length ?? 0\n    );\n\n    const hasBuffer =\n      renderRange.bufferBefore > 0 || renderRange.bufferAfter > 0;\n    // Determine which ASTs to include based on diff style and file type\n    const shouldIncludeAdditions = !unified && fileDiff.type !== 'deleted';\n    const shouldIncludeDeletions = !unified && fileDiff.type !== 'new';\n    const hasContent = context.rowCount > 0 || hasBuffer;\n\n    additionsContentAST =\n      shouldIncludeAdditions && hasContent ? additionsContentAST : undefined;\n    deletionsContentAST =\n      shouldIncludeDeletions && hasContent ? deletionsContentAST : undefined;\n    unifiedContentAST = unified && hasContent ? unifiedContentAST : undefined;\n\n    const preNode = this.createPreElement(\n      deletionsContentAST != null && additionsContentAST != null,\n      totalLines\n    );\n\n    return {\n      unifiedGutterAST:\n        unified && hasContent ? context.unifiedGutterAST.children : undefined,\n      unifiedContentAST,\n      deletionsGutterAST:\n        shouldIncludeDeletions && hasContent\n          ? context.deletionsGutterAST.children\n          : undefined,\n      deletionsContentAST,\n      additionsGutterAST:\n        shouldIncludeAdditions && hasContent\n          ? context.additionsGutterAST.children\n          : undefined,\n      additionsContentAST,\n      hunkData,\n      preNode,\n      themeStyles,\n      baseThemeType,\n      headerElement: !disableFileHeader\n        ? this.renderHeader(this.diff)\n        : undefined,\n      totalLines,\n      rowCount: context.rowCount,\n      bufferBefore: renderRange.bufferBefore,\n      bufferAfter: renderRange.bufferAfter,\n      // FIXME\n      css: '',\n    };\n  }\n\n  public renderCodeAST(\n    type: 'unified' | 'deletions' | 'additions',\n    result: HunksRenderResult\n  ): ElementContent[] | undefined {\n    const gutterAST =\n      type === 'unified'\n        ? result.unifiedGutterAST\n        : type === 'deletions'\n          ? result.deletionsGutterAST\n          : result.additionsGutterAST;\n\n    const contentAST =\n      type === 'unified'\n        ? result.unifiedContentAST\n        : type === 'deletions'\n          ? result.deletionsContentAST\n          : result.additionsContentAST;\n\n    if (gutterAST == null || contentAST == null) {\n      return undefined;\n    }\n\n    const gutter = createGutterWrapper(gutterAST);\n    gutter.properties.style = `grid-row: span ${result.rowCount}`;\n    const contentColumn = createContentColumn(contentAST, result.rowCount);\n    return [gutter, contentColumn];\n  }\n\n  public renderFullAST(\n    result: HunksRenderResult,\n    children: ElementContent[] = []\n  ): HASTElement {\n    const containerSize =\n      this.getOptionsWithDefaults().hunkSeparators === 'line-info';\n    const unifiedAST = this.renderCodeAST('unified', result);\n    if (unifiedAST != null) {\n      children.push(\n        createHastElement({\n          tagName: 'code',\n          children: unifiedAST,\n          properties: {\n            'data-code': '',\n            'data-container-size': containerSize ? '' : undefined,\n            'data-unified': '',\n          },\n        })\n      );\n      return { ...result.preNode, children };\n    }\n\n    const deletionsAST = this.renderCodeAST('deletions', result);\n    if (deletionsAST != null) {\n      children.push(\n        createHastElement({\n          tagName: 'code',\n          children: deletionsAST,\n          properties: {\n            'data-code': '',\n            'data-container-size': containerSize ? '' : undefined,\n            'data-deletions': '',\n          },\n        })\n      );\n    }\n    const additionsAST = this.renderCodeAST('additions', result);\n    if (additionsAST != null) {\n      children.push(\n        createHastElement({\n          tagName: 'code',\n          children: additionsAST,\n          properties: {\n            'data-code': '',\n            'data-container-size': containerSize ? '' : undefined,\n            'data-additions': '',\n          },\n        })\n      );\n    }\n    return { ...result.preNode, children };\n  }\n\n  public renderFullHTML(\n    result: HunksRenderResult,\n    tempChildren: ElementContent[] = []\n  ): string {\n    return toHtml(this.renderFullAST(result, tempChildren));\n  }\n\n  public 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-container-size':\n            this.getOptionsWithDefaults().hunkSeparators === 'line-info'\n              ? ''\n              : undefined,\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(diff: FileDiffMetadata): HASTElement {\n    const { headerRenderMode } = this.getOptionsWithDefaults();\n    return createFileHeaderElement({\n      fileOrDiff: diff,\n      mode: headerRenderMode,\n    });\n  }\n}\n\nfunction getModifiedLinesString(lines: number) {\n  return `${lines} unmodified line${lines > 1 ? 's' : ''}`;\n}\n\nfunction pushUnifiedInjectedRows(\n  rows: InjectedRow[],\n  context: ProcessContext\n): void {\n  for (const row of rows) {\n    context.unifiedContentAST.push(row.content);\n    context.pushToGutter('unified', row.gutter);\n    context.incrementRowCount(1);\n  }\n}\n\nfunction pushSplitInjectedRows(\n  rows: SplitInjectedRow[],\n  context: ProcessContext,\n  pendingSplitContext: PendingSplitContext\n): void {\n  for (const { deletion, addition } of rows) {\n    if (deletion == null && addition == null) {\n      continue;\n    }\n    const missingSide =\n      deletion != null && addition != null\n        ? undefined\n        : deletion == null\n          ? 'deletions'\n          : 'additions';\n\n    if (missingSide == null || pendingSplitContext.side !== missingSide) {\n      pendingSplitContext.flush();\n    }\n\n    if (deletion != null) {\n      context.deletionsContentAST.push(deletion.content);\n      context.pushToGutter('deletions', deletion.gutter);\n    }\n\n    if (addition != null) {\n      context.additionsContentAST.push(addition.content);\n      context.pushToGutter('additions', addition.gutter);\n    }\n\n    if (missingSide != null) {\n      pendingSplitContext.side = missingSide;\n      pendingSplitContext.increment();\n    }\n\n    context.incrementRowCount(1);\n  }\n}\n\nfunction pushLineWithAnnotation({\n  diffStyle,\n  type,\n  deletionLine,\n  additionLine,\n  unifiedSpan,\n  deletionSpan,\n  additionSpan,\n  createAnnotationElement,\n  context,\n}: PushLineWithAnnotation) {\n  let hasAnnotationRow = false;\n  if (diffStyle === 'unified') {\n    if (additionLine != null) {\n      context.unifiedContentAST.push(additionLine);\n    } else if (deletionLine != null) {\n      context.unifiedContentAST.push(deletionLine);\n    }\n    if (unifiedSpan != null) {\n      const lineType =\n        type === 'change'\n          ? deletionLine != null\n            ? 'change-deletion'\n            : 'change-addition'\n          : type;\n      context.unifiedContentAST.push(createAnnotationElement(unifiedSpan));\n      context.pushToGutter(\n        'unified',\n        createGutterGap(lineType, 'annotation', 1)\n      );\n      hasAnnotationRow = true;\n    }\n  } else if (diffStyle === 'split') {\n    if (deletionLine != null) {\n      context.deletionsContentAST.push(deletionLine);\n    }\n    if (additionLine != null) {\n      context.additionsContentAST.push(additionLine);\n    }\n    if (deletionSpan != null) {\n      const lineType =\n        type === 'change'\n          ? deletionLine != null\n            ? 'change-deletion'\n            : 'context'\n          : type;\n      context.deletionsContentAST.push(createAnnotationElement(deletionSpan));\n      context.pushToGutter(\n        'deletions',\n        createGutterGap(lineType, 'annotation', 1)\n      );\n      hasAnnotationRow = true;\n    }\n    if (additionSpan != null) {\n      const lineType =\n        type === 'change'\n          ? additionLine != null\n            ? 'change-addition'\n            : 'context'\n          : type;\n      context.additionsContentAST.push(createAnnotationElement(additionSpan));\n      context.pushToGutter(\n        'additions',\n        createGutterGap(lineType, 'annotation', 1)\n      );\n      hasAnnotationRow = true;\n    }\n  }\n  if (hasAnnotationRow) {\n    context.incrementRowCount(1);\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  context: ProcessContext\n) {\n  if (collapsedLines <= 0) {\n    return;\n  }\n  const linesAST =\n    type === 'unified'\n      ? context.unifiedContentAST\n      : type === 'deletions'\n        ? context.deletionsContentAST\n        : context.additionsContentAST;\n\n  if (context.hunkSeparators === 'metadata') {\n    if (hunkSpecs != null) {\n      context.pushToGutter(\n        type,\n        createSeparator({\n          type: 'metadata',\n          content: hunkSpecs,\n          isFirstHunk,\n          isLastHunk,\n        })\n      );\n      linesAST.push(\n        createSeparator({\n          type: 'metadata',\n          content: hunkSpecs,\n          isFirstHunk,\n          isLastHunk,\n        })\n      );\n      if (type !== 'additions') {\n        context.incrementRowCount(1);\n      }\n    }\n    return;\n  }\n  if (context.hunkSeparators === 'simple') {\n    if (hunkIndex > 0) {\n      context.pushToGutter(\n        type,\n        createSeparator({ type: 'simple', isFirstHunk, isLastHunk: false })\n      );\n      linesAST.push(\n        createSeparator({ type: 'simple', isFirstHunk, isLastHunk: false })\n      );\n      if (type !== 'additions') {\n        context.incrementRowCount(1);\n      }\n    }\n    return;\n  }\n  const slotName = getHunkSeparatorSlotName(type, hunkIndex);\n  const chunked = rangeSize > context.expansionLineCount;\n  const expandIndex = isExpandable ? hunkIndex : undefined;\n  context.pushToGutter(\n    type,\n    createSeparator({\n      type: context.hunkSeparators,\n      content: getModifiedLinesString(collapsedLines),\n      expandIndex,\n      chunked,\n      slotName,\n      isFirstHunk,\n      isLastHunk,\n    })\n  );\n  linesAST.push(\n    createSeparator({\n      type: context.hunkSeparators,\n      content: getModifiedLinesString(collapsedLines),\n      expandIndex,\n      chunked,\n      slotName,\n      isFirstHunk,\n      isLastHunk,\n    })\n  );\n  if (type !== 'additions') {\n    context.incrementRowCount(1);\n  }\n  context.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\nfunction withContentProperties(\n  lineNode: ElementContent | undefined,\n  contentProperties: Properties | undefined\n): ElementContent | undefined {\n  if (\n    lineNode == null ||\n    lineNode.type !== 'element' ||\n    contentProperties == null\n  ) {\n    return lineNode;\n  }\n  return {\n    ...lineNode,\n    properties: {\n      ...lineNode.properties,\n      ...contentProperties,\n    },\n  };\n}\n\nfunction calculateTrailingRangeSize(fileDiff: FileDiffMetadata): number {\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"],"mappings":"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"}