{"version":3,"file":"index.cjs","sources":["../../src/index.ts"],"sourcesContent":["import { approxEqual, debounce, memo, notUndefined } from './utils'\n\nexport * from './utils'\n\n//\n\ntype ScrollDirection = 'forward' | 'backward'\n\ntype ScrollAlignment = 'start' | 'center' | 'end' | 'auto'\n\ntype ScrollBehavior = 'auto' | 'smooth'\n\nexport interface ScrollToOptions {\n  align?: ScrollAlignment\n  behavior?: ScrollBehavior\n}\n\ntype ScrollToOffsetOptions = ScrollToOptions\n\ntype ScrollToIndexOptions = ScrollToOptions\n\nexport interface Range {\n  startIndex: number\n  endIndex: number\n  overscan: number\n  count: number\n}\n\ntype Key = number | string | bigint\n\nexport interface VirtualItem {\n  key: Key\n  index: number\n  start: number\n  end: number\n  size: number\n  lane: number\n}\n\nexport interface Rect {\n  width: number\n  height: number\n}\n\n//\n\nconst getRect = (element: HTMLElement): Rect => {\n  const { offsetWidth, offsetHeight } = element\n  return { width: offsetWidth, height: offsetHeight }\n}\n\nexport const defaultKeyExtractor = (index: number) => index\n\nexport const defaultRangeExtractor = (range: Range) => {\n  const start = Math.max(range.startIndex - range.overscan, 0)\n  const end = Math.min(range.endIndex + range.overscan, range.count - 1)\n\n  const arr = []\n\n  for (let i = start; i <= end; i++) {\n    arr.push(i)\n  }\n\n  return arr\n}\n\nexport const observeElementRect = <T extends Element>(\n  instance: Virtualizer<T, any>,\n  cb: (rect: Rect) => void,\n) => {\n  const element = instance.scrollElement\n  if (!element) {\n    return\n  }\n  const targetWindow = instance.targetWindow\n  if (!targetWindow) {\n    return\n  }\n\n  const handler = (rect: Rect) => {\n    const { width, height } = rect\n    cb({ width: Math.round(width), height: Math.round(height) })\n  }\n\n  handler(getRect(element as unknown as HTMLElement))\n\n  if (!targetWindow.ResizeObserver) {\n    return () => {}\n  }\n\n  const observer = new targetWindow.ResizeObserver((entries) => {\n    const run = () => {\n      const entry = entries[0]\n      if (entry?.borderBoxSize) {\n        const box = entry.borderBoxSize[0]\n        if (box) {\n          handler({ width: box.inlineSize, height: box.blockSize })\n          return\n        }\n      }\n      handler(getRect(element as unknown as HTMLElement))\n    }\n\n    instance.options.useAnimationFrameWithResizeObserver\n      ? requestAnimationFrame(run)\n      : run()\n  })\n\n  observer.observe(element, { box: 'border-box' })\n\n  return () => {\n    observer.unobserve(element)\n  }\n}\n\nconst addEventListenerOptions = {\n  passive: true,\n}\n\nexport const observeWindowRect = (\n  instance: Virtualizer<Window, any>,\n  cb: (rect: Rect) => void,\n) => {\n  const element = instance.scrollElement\n  if (!element) {\n    return\n  }\n\n  const handler = () => {\n    cb({ width: element.innerWidth, height: element.innerHeight })\n  }\n  handler()\n\n  element.addEventListener('resize', handler, addEventListenerOptions)\n\n  return () => {\n    element.removeEventListener('resize', handler)\n  }\n}\n\nconst supportsScrollend =\n  typeof window == 'undefined' ? true : 'onscrollend' in window\n\ntype ObserveOffsetCallBack = (offset: number, isScrolling: boolean) => void\n\nexport const observeElementOffset = <T extends Element>(\n  instance: Virtualizer<T, any>,\n  cb: ObserveOffsetCallBack,\n) => {\n  const element = instance.scrollElement\n  if (!element) {\n    return\n  }\n  const targetWindow = instance.targetWindow\n  if (!targetWindow) {\n    return\n  }\n\n  let offset = 0\n  const fallback =\n    instance.options.useScrollendEvent && supportsScrollend\n      ? () => undefined\n      : debounce(\n          targetWindow,\n          () => {\n            cb(offset, false)\n          },\n          instance.options.isScrollingResetDelay,\n        )\n\n  const createHandler = (isScrolling: boolean) => () => {\n    const { horizontal, isRtl } = instance.options\n    offset = horizontal\n      ? element['scrollLeft'] * ((isRtl && -1) || 1)\n      : element['scrollTop']\n    fallback()\n    cb(offset, isScrolling)\n  }\n  const handler = createHandler(true)\n  const endHandler = createHandler(false)\n  endHandler()\n\n  element.addEventListener('scroll', handler, addEventListenerOptions)\n  const registerScrollendEvent =\n    instance.options.useScrollendEvent && supportsScrollend\n  if (registerScrollendEvent) {\n    element.addEventListener('scrollend', endHandler, addEventListenerOptions)\n  }\n  return () => {\n    element.removeEventListener('scroll', handler)\n    if (registerScrollendEvent) {\n      element.removeEventListener('scrollend', endHandler)\n    }\n  }\n}\n\nexport const observeWindowOffset = (\n  instance: Virtualizer<Window, any>,\n  cb: ObserveOffsetCallBack,\n) => {\n  const element = instance.scrollElement\n  if (!element) {\n    return\n  }\n  const targetWindow = instance.targetWindow\n  if (!targetWindow) {\n    return\n  }\n\n  let offset = 0\n  const fallback =\n    instance.options.useScrollendEvent && supportsScrollend\n      ? () => undefined\n      : debounce(\n          targetWindow,\n          () => {\n            cb(offset, false)\n          },\n          instance.options.isScrollingResetDelay,\n        )\n\n  const createHandler = (isScrolling: boolean) => () => {\n    offset = element[instance.options.horizontal ? 'scrollX' : 'scrollY']\n    fallback()\n    cb(offset, isScrolling)\n  }\n  const handler = createHandler(true)\n  const endHandler = createHandler(false)\n  endHandler()\n\n  element.addEventListener('scroll', handler, addEventListenerOptions)\n  const registerScrollendEvent =\n    instance.options.useScrollendEvent && supportsScrollend\n  if (registerScrollendEvent) {\n    element.addEventListener('scrollend', endHandler, addEventListenerOptions)\n  }\n  return () => {\n    element.removeEventListener('scroll', handler)\n    if (registerScrollendEvent) {\n      element.removeEventListener('scrollend', endHandler)\n    }\n  }\n}\n\nexport const measureElement = <TItemElement extends Element>(\n  element: TItemElement,\n  entry: ResizeObserverEntry | undefined,\n  instance: Virtualizer<any, TItemElement>,\n) => {\n  if (entry?.borderBoxSize) {\n    const box = entry.borderBoxSize[0]\n    if (box) {\n      const size = Math.round(\n        box[instance.options.horizontal ? 'inlineSize' : 'blockSize'],\n      )\n      return size\n    }\n  }\n\n  return (element as unknown as HTMLElement)[\n    instance.options.horizontal ? 'offsetWidth' : 'offsetHeight'\n  ]\n}\n\nexport const windowScroll = <T extends Window>(\n  offset: number,\n  {\n    adjustments = 0,\n    behavior,\n  }: { adjustments?: number; behavior?: ScrollBehavior },\n  instance: Virtualizer<T, any>,\n) => {\n  const toOffset = offset + adjustments\n\n  instance.scrollElement?.scrollTo?.({\n    [instance.options.horizontal ? 'left' : 'top']: toOffset,\n    behavior,\n  })\n}\n\nexport const elementScroll = <T extends Element>(\n  offset: number,\n  {\n    adjustments = 0,\n    behavior,\n  }: { adjustments?: number; behavior?: ScrollBehavior },\n  instance: Virtualizer<T, any>,\n) => {\n  const toOffset = offset + adjustments\n\n  instance.scrollElement?.scrollTo?.({\n    [instance.options.horizontal ? 'left' : 'top']: toOffset,\n    behavior,\n  })\n}\n\nexport interface VirtualizerOptions<\n  TScrollElement extends Element | Window,\n  TItemElement extends Element,\n> {\n  // Required from the user\n  count: number\n  getScrollElement: () => TScrollElement | null\n  estimateSize: (index: number) => number\n\n  // Required from the framework adapter (but can be overridden)\n  scrollToFn: (\n    offset: number,\n    options: { adjustments?: number; behavior?: ScrollBehavior },\n    instance: Virtualizer<TScrollElement, TItemElement>,\n  ) => void\n  observeElementRect: (\n    instance: Virtualizer<TScrollElement, TItemElement>,\n    cb: (rect: Rect) => void,\n  ) => void | (() => void)\n  observeElementOffset: (\n    instance: Virtualizer<TScrollElement, TItemElement>,\n    cb: ObserveOffsetCallBack,\n  ) => void | (() => void)\n  // Optional\n  debug?: boolean\n  initialRect?: Rect\n  onChange?: (\n    instance: Virtualizer<TScrollElement, TItemElement>,\n    sync: boolean,\n  ) => void\n  measureElement?: (\n    element: TItemElement,\n    entry: ResizeObserverEntry | undefined,\n    instance: Virtualizer<TScrollElement, TItemElement>,\n  ) => number\n  overscan?: number\n  horizontal?: boolean\n  paddingStart?: number\n  paddingEnd?: number\n  scrollPaddingStart?: number\n  scrollPaddingEnd?: number\n  initialOffset?: number | (() => number)\n  getItemKey?: (index: number) => Key\n  rangeExtractor?: (range: Range) => Array<number>\n  scrollMargin?: number\n  gap?: number\n  indexAttribute?: string\n  initialMeasurementsCache?: Array<VirtualItem>\n  lanes?: number\n  isScrollingResetDelay?: number\n  useScrollendEvent?: boolean\n  enabled?: boolean\n  isRtl?: boolean\n  useAnimationFrameWithResizeObserver?: boolean\n}\n\nexport class Virtualizer<\n  TScrollElement extends Element | Window,\n  TItemElement extends Element,\n> {\n  private unsubs: Array<void | (() => void)> = []\n  options!: Required<VirtualizerOptions<TScrollElement, TItemElement>>\n  scrollElement: TScrollElement | null = null\n  targetWindow: (Window & typeof globalThis) | null = null\n  isScrolling = false\n  measurementsCache: Array<VirtualItem> = []\n  private itemSizeCache = new Map<Key, number>()\n  private pendingMeasuredCacheIndexes: Array<number> = []\n  scrollRect: Rect | null = null\n  scrollOffset: number | null = null\n  scrollDirection: ScrollDirection | null = null\n  private scrollAdjustments = 0\n  shouldAdjustScrollPositionOnItemSizeChange:\n    | undefined\n    | ((\n        item: VirtualItem,\n        delta: number,\n        instance: Virtualizer<TScrollElement, TItemElement>,\n      ) => boolean)\n  elementsCache = new Map<Key, TItemElement>()\n  private observer = (() => {\n    let _ro: ResizeObserver | null = null\n\n    const get = () => {\n      if (_ro) {\n        return _ro\n      }\n\n      if (!this.targetWindow || !this.targetWindow.ResizeObserver) {\n        return null\n      }\n\n      return (_ro = new this.targetWindow.ResizeObserver((entries) => {\n        entries.forEach((entry) => {\n          const run = () => {\n            this._measureElement(entry.target as TItemElement, entry)\n          }\n          this.options.useAnimationFrameWithResizeObserver\n            ? requestAnimationFrame(run)\n            : run()\n        })\n      }))\n    }\n\n    return {\n      disconnect: () => {\n        get()?.disconnect()\n        _ro = null\n      },\n      observe: (target: Element) =>\n        get()?.observe(target, { box: 'border-box' }),\n      unobserve: (target: Element) => get()?.unobserve(target),\n    }\n  })()\n  range: { startIndex: number; endIndex: number } | null = null\n\n  constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {\n    this.setOptions(opts)\n  }\n\n  setOptions = (opts: VirtualizerOptions<TScrollElement, TItemElement>) => {\n    Object.entries(opts).forEach(([key, value]) => {\n      if (typeof value === 'undefined') delete (opts as any)[key]\n    })\n\n    this.options = {\n      debug: false,\n      initialOffset: 0,\n      overscan: 1,\n      paddingStart: 0,\n      paddingEnd: 0,\n      scrollPaddingStart: 0,\n      scrollPaddingEnd: 0,\n      horizontal: false,\n      getItemKey: defaultKeyExtractor,\n      rangeExtractor: defaultRangeExtractor,\n      onChange: () => {},\n      measureElement,\n      initialRect: { width: 0, height: 0 },\n      scrollMargin: 0,\n      gap: 0,\n      indexAttribute: 'data-index',\n      initialMeasurementsCache: [],\n      lanes: 1,\n      isScrollingResetDelay: 150,\n      enabled: true,\n      isRtl: false,\n      useScrollendEvent: false,\n      useAnimationFrameWithResizeObserver: false,\n      ...opts,\n    }\n  }\n\n  private notify = (sync: boolean) => {\n    this.options.onChange?.(this, sync)\n  }\n\n  private maybeNotify = memo(\n    () => {\n      this.calculateRange()\n\n      return [\n        this.isScrolling,\n        this.range ? this.range.startIndex : null,\n        this.range ? this.range.endIndex : null,\n      ]\n    },\n    (isScrolling) => {\n      this.notify(isScrolling)\n    },\n    {\n      key: process.env.NODE_ENV !== 'production' && 'maybeNotify',\n      debug: () => this.options.debug,\n      initialDeps: [\n        this.isScrolling,\n        this.range ? this.range.startIndex : null,\n        this.range ? this.range.endIndex : null,\n      ] as [boolean, number | null, number | null],\n    },\n  )\n\n  private cleanup = () => {\n    this.unsubs.filter(Boolean).forEach((d) => d!())\n    this.unsubs = []\n    this.observer.disconnect()\n    this.scrollElement = null\n    this.targetWindow = null\n  }\n\n  _didMount = () => {\n    return () => {\n      this.cleanup()\n    }\n  }\n\n  _willUpdate = () => {\n    const scrollElement = this.options.enabled\n      ? this.options.getScrollElement()\n      : null\n\n    if (this.scrollElement !== scrollElement) {\n      this.cleanup()\n\n      if (!scrollElement) {\n        this.maybeNotify()\n        return\n      }\n\n      this.scrollElement = scrollElement\n\n      if (this.scrollElement && 'ownerDocument' in this.scrollElement) {\n        this.targetWindow = this.scrollElement.ownerDocument.defaultView\n      } else {\n        this.targetWindow = this.scrollElement?.window ?? null\n      }\n\n      this.elementsCache.forEach((cached) => {\n        this.observer.observe(cached)\n      })\n\n      this._scrollToOffset(this.getScrollOffset(), {\n        adjustments: undefined,\n        behavior: undefined,\n      })\n\n      this.unsubs.push(\n        this.options.observeElementRect(this, (rect) => {\n          this.scrollRect = rect\n          this.maybeNotify()\n        }),\n      )\n\n      this.unsubs.push(\n        this.options.observeElementOffset(this, (offset, isScrolling) => {\n          this.scrollAdjustments = 0\n          this.scrollDirection = isScrolling\n            ? this.getScrollOffset() < offset\n              ? 'forward'\n              : 'backward'\n            : null\n          this.scrollOffset = offset\n          this.isScrolling = isScrolling\n\n          this.maybeNotify()\n        }),\n      )\n    }\n  }\n\n  private getSize = () => {\n    if (!this.options.enabled) {\n      this.scrollRect = null\n      return 0\n    }\n\n    this.scrollRect = this.scrollRect ?? this.options.initialRect\n\n    return this.scrollRect[this.options.horizontal ? 'width' : 'height']\n  }\n\n  private getScrollOffset = () => {\n    if (!this.options.enabled) {\n      this.scrollOffset = null\n      return 0\n    }\n\n    this.scrollOffset =\n      this.scrollOffset ??\n      (typeof this.options.initialOffset === 'function'\n        ? this.options.initialOffset()\n        : this.options.initialOffset)\n\n    return this.scrollOffset\n  }\n\n  private getFurthestMeasurement = (\n    measurements: Array<VirtualItem>,\n    index: number,\n  ) => {\n    const furthestMeasurementsFound = new Map<number, true>()\n    const furthestMeasurements = new Map<number, VirtualItem>()\n    for (let m = index - 1; m >= 0; m--) {\n      const measurement = measurements[m]!\n\n      if (furthestMeasurementsFound.has(measurement.lane)) {\n        continue\n      }\n\n      const previousFurthestMeasurement = furthestMeasurements.get(\n        measurement.lane,\n      )\n      if (\n        previousFurthestMeasurement == null ||\n        measurement.end > previousFurthestMeasurement.end\n      ) {\n        furthestMeasurements.set(measurement.lane, measurement)\n      } else if (measurement.end < previousFurthestMeasurement.end) {\n        furthestMeasurementsFound.set(measurement.lane, true)\n      }\n\n      if (furthestMeasurementsFound.size === this.options.lanes) {\n        break\n      }\n    }\n\n    return furthestMeasurements.size === this.options.lanes\n      ? Array.from(furthestMeasurements.values()).sort((a, b) => {\n          if (a.end === b.end) {\n            return a.index - b.index\n          }\n\n          return a.end - b.end\n        })[0]\n      : undefined\n  }\n\n  private getMeasurementOptions = memo(\n    () => [\n      this.options.count,\n      this.options.paddingStart,\n      this.options.scrollMargin,\n      this.options.getItemKey,\n      this.options.enabled,\n    ],\n    (count, paddingStart, scrollMargin, getItemKey, enabled) => {\n      this.pendingMeasuredCacheIndexes = []\n      return {\n        count,\n        paddingStart,\n        scrollMargin,\n        getItemKey,\n        enabled,\n      }\n    },\n    {\n      key: false,\n    },\n  )\n\n  private getMeasurements = memo(\n    () => [this.getMeasurementOptions(), this.itemSizeCache],\n    (\n      { count, paddingStart, scrollMargin, getItemKey, enabled },\n      itemSizeCache,\n    ) => {\n      if (!enabled) {\n        this.measurementsCache = []\n        this.itemSizeCache.clear()\n        return []\n      }\n\n      if (this.measurementsCache.length === 0) {\n        this.measurementsCache = this.options.initialMeasurementsCache\n        this.measurementsCache.forEach((item) => {\n          this.itemSizeCache.set(item.key, item.size)\n        })\n      }\n\n      const min =\n        this.pendingMeasuredCacheIndexes.length > 0\n          ? Math.min(...this.pendingMeasuredCacheIndexes)\n          : 0\n      this.pendingMeasuredCacheIndexes = []\n\n      const measurements = this.measurementsCache.slice(0, min)\n\n      for (let i = min; i < count; i++) {\n        const key = getItemKey(i)\n\n        const furthestMeasurement =\n          this.options.lanes === 1\n            ? measurements[i - 1]\n            : this.getFurthestMeasurement(measurements, i)\n\n        const start = furthestMeasurement\n          ? furthestMeasurement.end + this.options.gap\n          : paddingStart + scrollMargin\n\n        const measuredSize = itemSizeCache.get(key)\n        const size =\n          typeof measuredSize === 'number'\n            ? measuredSize\n            : this.options.estimateSize(i)\n\n        const end = start + size\n\n        const lane = furthestMeasurement\n          ? furthestMeasurement.lane\n          : i % this.options.lanes\n\n        measurements[i] = {\n          index: i,\n          start,\n          size,\n          end,\n          key,\n          lane,\n        }\n      }\n\n      this.measurementsCache = measurements\n\n      return measurements\n    },\n    {\n      key: process.env.NODE_ENV !== 'production' && 'getMeasurements',\n      debug: () => this.options.debug,\n    },\n  )\n\n  calculateRange = memo(\n    () => [\n      this.getMeasurements(),\n      this.getSize(),\n      this.getScrollOffset(),\n      this.options.lanes,\n    ],\n    (measurements, outerSize, scrollOffset, lanes) => {\n      return (this.range =\n        measurements.length > 0 && outerSize > 0\n          ? calculateRange({\n              measurements,\n              outerSize,\n              scrollOffset,\n              lanes,\n            })\n          : null)\n    },\n    {\n      key: process.env.NODE_ENV !== 'production' && 'calculateRange',\n      debug: () => this.options.debug,\n    },\n  )\n\n  getVirtualIndexes = memo(\n    () => {\n      let startIndex: number | null = null\n      let endIndex: number | null = null\n      const range = this.calculateRange()\n      if (range) {\n        startIndex = range.startIndex\n        endIndex = range.endIndex\n      }\n      this.maybeNotify.updateDeps([this.isScrolling, startIndex, endIndex])\n      return [\n        this.options.rangeExtractor,\n        this.options.overscan,\n        this.options.count,\n        startIndex,\n        endIndex,\n      ]\n    },\n    (rangeExtractor, overscan, count, startIndex, endIndex) => {\n      return startIndex === null || endIndex === null\n        ? []\n        : rangeExtractor({\n            startIndex,\n            endIndex,\n            overscan,\n            count,\n          })\n    },\n    {\n      key: process.env.NODE_ENV !== 'production' && 'getVirtualIndexes',\n      debug: () => this.options.debug,\n    },\n  )\n\n  indexFromElement = (node: TItemElement) => {\n    const attributeName = this.options.indexAttribute\n    const indexStr = node.getAttribute(attributeName)\n\n    if (!indexStr) {\n      console.warn(\n        `Missing attribute name '${attributeName}={index}' on measured element.`,\n      )\n      return -1\n    }\n\n    return parseInt(indexStr, 10)\n  }\n\n  private _measureElement = (\n    node: TItemElement,\n    entry: ResizeObserverEntry | undefined,\n  ) => {\n    const index = this.indexFromElement(node)\n    const item = this.measurementsCache[index]\n    if (!item) {\n      return\n    }\n    const key = item.key\n    const prevNode = this.elementsCache.get(key)\n\n    if (prevNode !== node) {\n      if (prevNode) {\n        this.observer.unobserve(prevNode)\n      }\n      this.observer.observe(node)\n      this.elementsCache.set(key, node)\n    }\n\n    if (node.isConnected) {\n      this.resizeItem(index, this.options.measureElement(node, entry, this))\n    }\n  }\n\n  resizeItem = (index: number, size: number) => {\n    const item = this.measurementsCache[index]\n    if (!item) {\n      return\n    }\n    const itemSize = this.itemSizeCache.get(item.key) ?? item.size\n    const delta = size - itemSize\n\n    if (delta !== 0) {\n      if (\n        this.shouldAdjustScrollPositionOnItemSizeChange !== undefined\n          ? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this)\n          : item.start < this.getScrollOffset() + this.scrollAdjustments\n      ) {\n        if (process.env.NODE_ENV !== 'production' && this.options.debug) {\n          console.info('correction', delta)\n        }\n\n        this._scrollToOffset(this.getScrollOffset(), {\n          adjustments: (this.scrollAdjustments += delta),\n          behavior: undefined,\n        })\n      }\n\n      this.pendingMeasuredCacheIndexes.push(item.index)\n      this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size))\n\n      this.notify(false)\n    }\n  }\n\n  measureElement = (node: TItemElement | null | undefined) => {\n    if (!node) {\n      this.elementsCache.forEach((cached, key) => {\n        if (!cached.isConnected) {\n          this.observer.unobserve(cached)\n          this.elementsCache.delete(key)\n        }\n      })\n      return\n    }\n\n    this._measureElement(node, undefined)\n  }\n\n  getVirtualItems = memo(\n    () => [this.getVirtualIndexes(), this.getMeasurements()],\n    (indexes, measurements) => {\n      const virtualItems: Array<VirtualItem> = []\n\n      for (let k = 0, len = indexes.length; k < len; k++) {\n        const i = indexes[k]!\n        const measurement = measurements[i]!\n\n        virtualItems.push(measurement)\n      }\n\n      return virtualItems\n    },\n    {\n      key: process.env.NODE_ENV !== 'production' && 'getVirtualItems',\n      debug: () => this.options.debug,\n    },\n  )\n\n  getVirtualItemForOffset = (offset: number) => {\n    const measurements = this.getMeasurements()\n    if (measurements.length === 0) {\n      return undefined\n    }\n    return notUndefined(\n      measurements[\n        findNearestBinarySearch(\n          0,\n          measurements.length - 1,\n          (index: number) => notUndefined(measurements[index]).start,\n          offset,\n        )\n      ],\n    )\n  }\n\n  getOffsetForAlignment = (\n    toOffset: number,\n    align: ScrollAlignment,\n    itemSize = 0,\n  ) => {\n    const size = this.getSize()\n    const scrollOffset = this.getScrollOffset()\n\n    if (align === 'auto') {\n      align = toOffset >= scrollOffset + size ? 'end' : 'start'\n    }\n\n    if (align === 'center') {\n      // When aligning to a particular item (e.g. with scrollToIndex),\n      // adjust offset by the size of the item to center on the item\n      toOffset += (itemSize - size) / 2\n    } else if (align === 'end') {\n      toOffset -= size\n    }\n\n    const maxOffset = this.getTotalSize() + this.options.scrollMargin - size\n\n    return Math.max(Math.min(maxOffset, toOffset), 0)\n  }\n\n  getOffsetForIndex = (index: number, align: ScrollAlignment = 'auto') => {\n    index = Math.max(0, Math.min(index, this.options.count - 1))\n\n    const item = this.measurementsCache[index]\n    if (!item) {\n      return undefined\n    }\n\n    const size = this.getSize()\n    const scrollOffset = this.getScrollOffset()\n\n    if (align === 'auto') {\n      if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) {\n        align = 'end'\n      } else if (item.start <= scrollOffset + this.options.scrollPaddingStart) {\n        align = 'start'\n      } else {\n        return [scrollOffset, align] as const\n      }\n    }\n\n    const toOffset =\n      align === 'end'\n        ? item.end + this.options.scrollPaddingEnd\n        : item.start - this.options.scrollPaddingStart\n\n    return [\n      this.getOffsetForAlignment(toOffset, align, item.size),\n      align,\n    ] as const\n  }\n\n  private isDynamicMode = () => this.elementsCache.size > 0\n\n  scrollToOffset = (\n    toOffset: number,\n    { align = 'start', behavior }: ScrollToOffsetOptions = {},\n  ) => {\n    if (behavior === 'smooth' && this.isDynamicMode()) {\n      console.warn(\n        'The `smooth` scroll behavior is not fully supported with dynamic size.',\n      )\n    }\n\n    this._scrollToOffset(this.getOffsetForAlignment(toOffset, align), {\n      adjustments: undefined,\n      behavior,\n    })\n  }\n\n  scrollToIndex = (\n    index: number,\n    { align: initialAlign = 'auto', behavior }: ScrollToIndexOptions = {},\n  ) => {\n    if (behavior === 'smooth' && this.isDynamicMode()) {\n      console.warn(\n        'The `smooth` scroll behavior is not fully supported with dynamic size.',\n      )\n    }\n\n    index = Math.max(0, Math.min(index, this.options.count - 1))\n\n    let attempts = 0\n    const maxAttempts = 10\n\n    const tryScroll = (currentAlign: ScrollAlignment) => {\n      if (!this.targetWindow) return\n\n      const offsetInfo = this.getOffsetForIndex(index, currentAlign)\n      if (!offsetInfo) {\n        console.warn('Failed to get offset for index:', index)\n        return\n      }\n      const [offset, align] = offsetInfo\n      this._scrollToOffset(offset, { adjustments: undefined, behavior })\n\n      this.targetWindow.requestAnimationFrame(() => {\n        const currentOffset = this.getScrollOffset()\n        const afterInfo = this.getOffsetForIndex(index, align)\n        if (!afterInfo) {\n          console.warn('Failed to get offset for index:', index)\n          return\n        }\n\n        if (!approxEqual(afterInfo[0], currentOffset)) {\n          scheduleRetry(align)\n        }\n      })\n    }\n\n    const scheduleRetry = (align: ScrollAlignment) => {\n      if (!this.targetWindow) return\n\n      attempts++\n      if (attempts < maxAttempts) {\n        if (process.env.NODE_ENV !== 'production' && this.options.debug) {\n          console.info('Schedule retry', attempts, maxAttempts)\n        }\n        this.targetWindow.requestAnimationFrame(() => tryScroll(align))\n      } else {\n        console.warn(\n          `Failed to scroll to index ${index} after ${maxAttempts} attempts.`,\n        )\n      }\n    }\n\n    tryScroll(initialAlign)\n  }\n\n  scrollBy = (delta: number, { behavior }: ScrollToOffsetOptions = {}) => {\n    if (behavior === 'smooth' && this.isDynamicMode()) {\n      console.warn(\n        'The `smooth` scroll behavior is not fully supported with dynamic size.',\n      )\n    }\n\n    this._scrollToOffset(this.getScrollOffset() + delta, {\n      adjustments: undefined,\n      behavior,\n    })\n  }\n\n  getTotalSize = () => {\n    const measurements = this.getMeasurements()\n\n    let end: number\n    // If there are no measurements, set the end to paddingStart\n    // If there is only one lane, use the last measurement's end\n    // Otherwise find the maximum end value among all measurements\n    if (measurements.length === 0) {\n      end = this.options.paddingStart\n    } else if (this.options.lanes === 1) {\n      end = measurements[measurements.length - 1]?.end ?? 0\n    } else {\n      const endByLane = Array<number | null>(this.options.lanes).fill(null)\n      let endIndex = measurements.length - 1\n      while (endIndex >= 0 && endByLane.some((val) => val === null)) {\n        const item = measurements[endIndex]!\n        if (endByLane[item.lane] === null) {\n          endByLane[item.lane] = item.end\n        }\n\n        endIndex--\n      }\n\n      end = Math.max(...endByLane.filter((val): val is number => val !== null))\n    }\n\n    return Math.max(\n      end - this.options.scrollMargin + this.options.paddingEnd,\n      0,\n    )\n  }\n\n  private _scrollToOffset = (\n    offset: number,\n    {\n      adjustments,\n      behavior,\n    }: {\n      adjustments: number | undefined\n      behavior: ScrollBehavior | undefined\n    },\n  ) => {\n    this.options.scrollToFn(offset, { behavior, adjustments }, this)\n  }\n\n  measure = () => {\n    this.itemSizeCache = new Map()\n    this.notify(false)\n  }\n}\n\nconst findNearestBinarySearch = (\n  low: number,\n  high: number,\n  getCurrentValue: (i: number) => number,\n  value: number,\n) => {\n  while (low <= high) {\n    const middle = ((low + high) / 2) | 0\n    const currentValue = getCurrentValue(middle)\n\n    if (currentValue < value) {\n      low = middle + 1\n    } else if (currentValue > value) {\n      high = middle - 1\n    } else {\n      return middle\n    }\n  }\n\n  if (low > 0) {\n    return low - 1\n  } else {\n    return 0\n  }\n}\n\nfunction calculateRange({\n  measurements,\n  outerSize,\n  scrollOffset,\n  lanes,\n}: {\n  measurements: Array<VirtualItem>\n  outerSize: number\n  scrollOffset: number\n  lanes: number\n}) {\n  const lastIndex = measurements.length - 1\n  const getOffset = (index: number) => measurements[index]!.start\n\n  // handle case when item count is less than or equal to lanes\n  if (measurements.length <= lanes) {\n    return {\n      startIndex: 0,\n      endIndex: lastIndex,\n    }\n  }\n\n  let startIndex = findNearestBinarySearch(\n    0,\n    lastIndex,\n    getOffset,\n    scrollOffset,\n  )\n  let endIndex = startIndex\n\n  if (lanes === 1) {\n    while (\n      endIndex < lastIndex &&\n      measurements[endIndex]!.end < scrollOffset + outerSize\n    ) {\n      endIndex++\n    }\n  } else if (lanes > 1) {\n    // Expand forward until we include the visible items from all lanes\n    // which are closer to the end of the virtualizer window\n    const endPerLane = Array(lanes).fill(0)\n    while (\n      endIndex < lastIndex &&\n      endPerLane.some((pos) => pos < scrollOffset + outerSize)\n    ) {\n      const item = measurements[endIndex]!\n      endPerLane[item.lane] = item.end\n      endIndex++\n    }\n\n    // Expand backward until we include all lanes' visible items\n    // closer to the top\n    const startPerLane = Array(lanes).fill(scrollOffset + outerSize)\n    while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {\n      const item = measurements[startIndex]!\n      startPerLane[item.lane] = item.start\n      startIndex--\n    }\n\n    // Align startIndex to the beginning of its lane\n    startIndex = Math.max(0, startIndex - (startIndex % lanes))\n    // Align endIndex to the end of its lane\n    endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - (endIndex % lanes)))\n  }\n\n  return { startIndex, endIndex }\n}\n"],"names":["debounce","opts","memo","notUndefined","approxEqual"],"mappings":"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"}