{"version":3,"file":"index.cjs","sources":["../../src/src/core/utils.ts","../../src/src/core/cache.ts","../../src/src/core/environment.ts","../../src/src/core/store.ts","../../src/src/core/scroller.ts","../../src/src/core/resizer.ts","../../src/src/vue/ListItem.tsx","../../src/src/vue/utils.ts","../../src/src/vue/Virtualizer.tsx","../../src/src/vue/VList.tsx","../../src/src/vue/WindowVirtualizer.tsx"],"sourcesContent":["/** @internal */\nexport const NULL = null;\n\n/** @internal */\nexport const { min, max, abs, floor } = Math;\n\n/**\n * @internal\n */\nexport const clamp = (\n  value: number,\n  minValue: number,\n  maxValue: number,\n): number => min(maxValue, max(minValue, value));\n\n/**\n * @internal\n */\nexport const sort = <T extends number>(arr: readonly T[]): T[] => {\n  return [...arr].sort((a, b) => a - b);\n};\n\n/**\n * @internal\n */\nexport const microtask: (fn: () => void) => void =\n  typeof queueMicrotask === \"function\"\n    ? queueMicrotask\n    : (fn) => {\n        Promise.resolve().then(fn);\n      };\n\n/**\n * @internal\n */\nexport const createPromise = <T = void>(): [Promise<T>, (arg: T) => void] => {\n  let resolve: ((arg: T) => void) | undefined;\n  const promise = new Promise<T>((res) => {\n    resolve = res;\n  });\n  return [promise, resolve!];\n};\n\n/**\n * @internal\n */\nexport const once = <T>(fn: () => T): (() => T) => {\n  let cache: T;\n\n  return () => {\n    if (fn) {\n      cache = fn();\n      fn = undefined!;\n    }\n    return cache;\n  };\n};\n","import { type InternalCacheSnapshot, type ItemsRange } from \"./types.js\";\nimport { clamp, floor, max, min, sort } from \"./utils.js\";\n\ntype Writeable<T> = {\n  -readonly [key in keyof T]: Writeable<T[key]>;\n};\n\n/** @internal */\nexport const UNCACHED = -1;\n\n/**\n * @internal\n */\nexport type Cache = {\n  readonly _length: number;\n  // sizes\n  readonly _sizes: number[];\n  readonly _defaultItemSize: number;\n  // offsets\n  readonly _computedOffsetIndex: number;\n  readonly _offsets: number[];\n};\n\nconst fill = (array: number[], length: number, prepend?: boolean): number[] => {\n  const key = prepend ? \"unshift\" : \"push\";\n  for (let i = 0; i < length; i++) {\n    array[key](UNCACHED);\n  }\n  return array;\n};\n\n/**\n * @internal\n */\nexport const getItemSize = (cache: Cache, index: number): number => {\n  const size = cache._sizes[index]!;\n  return size === UNCACHED ? cache._defaultItemSize : size;\n};\n\n/**\n * @internal\n */\nexport const setItemSize = (\n  cache: Writeable<Cache>,\n  index: number,\n  size: number,\n): boolean => {\n  const isInitialMeasurement = cache._sizes[index] === UNCACHED;\n  cache._sizes[index] = size;\n  // mark as dirty\n  cache._computedOffsetIndex = min(index, cache._computedOffsetIndex);\n  return isInitialMeasurement;\n};\n\n/**\n * @internal\n */\nexport const getItemOffset = (\n  cache: Writeable<Cache>,\n  index: number,\n): number => {\n  if (!cache._length) return 0;\n  if (cache._computedOffsetIndex >= index) {\n    return cache._offsets[index]!;\n  }\n\n  if (cache._computedOffsetIndex < 0) {\n    // first offset must be 0 to avoid returning NaN, which can cause infinite rerender.\n    // https://github.com/inokawa/virtua/pull/160\n    cache._offsets[0] = 0;\n    cache._computedOffsetIndex = 0;\n  }\n  let i = cache._computedOffsetIndex;\n  let top = cache._offsets[i]!;\n  while (i < index) {\n    top += getItemSize(cache, i);\n    cache._offsets[++i] = top;\n  }\n  // mark as measured\n  cache._computedOffsetIndex = index;\n  return top;\n};\n\n/**\n * Finds the index of an item in the cache whose computed offset is closest to the specified offset.\n *\n * @internal\n */\nexport const findIndex = (\n  cache: Cache,\n  offset: number,\n  low: number = 0,\n  high: number = cache._length - 1,\n): number => {\n  // Find with binary search\n  let found: number = low;\n  while (low <= high) {\n    const mid = floor((low + high) / 2);\n    if (getItemOffset(cache, mid) <= offset) {\n      found = mid;\n      low = mid + 1;\n    } else {\n      high = mid - 1;\n    }\n  }\n  return clamp(found, 0, cache._length - 1);\n};\n\n/**\n * @internal\n */\nexport const computeRange = (\n  cache: Cache,\n  startOffset: number,\n  endOffset: number,\n  prevStartIndex: number,\n): ItemsRange => {\n  // Clamp because prevStartIndex may exceed the limit when children decreased a lot after scrolling\n  prevStartIndex = min(prevStartIndex, cache._length - 1);\n\n  if (getItemOffset(cache, prevStartIndex) <= startOffset) {\n    // search forward\n    // start <= end, prevStartIndex <= start\n    const end = findIndex(cache, endOffset, prevStartIndex);\n    return [findIndex(cache, startOffset, prevStartIndex, end), end];\n  } else {\n    // search backward\n    // start <= end, start <= prevStartIndex\n    const start = findIndex(cache, startOffset, undefined, prevStartIndex);\n    return [start, findIndex(cache, endOffset, start)];\n  }\n};\n\n/**\n * @internal\n */\nexport const estimateDefaultItemSize = (\n  cache: Writeable<Cache>,\n  startIndex: number,\n): number => {\n  let measuredCountBeforeStart = 0;\n  // This function will be called after measurement so measured size array must be longer than 0\n  const measuredSizes: number[] = [];\n  cache._sizes.forEach((s, i) => {\n    if (s !== UNCACHED) {\n      measuredSizes.push(s);\n      if (i < startIndex) {\n        measuredCountBeforeStart++;\n      }\n    }\n  });\n\n  // Discard cache for now\n  cache._computedOffsetIndex = -1;\n\n  // Calculate median\n  const sorted = sort(measuredSizes);\n  const len = sorted.length;\n  const mid = (len / 2) | 0;\n  const median =\n    len % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;\n\n  const prevDefaultItemSize = cache._defaultItemSize;\n\n  // Calculate diff of unmeasured items before start\n  return (\n    ((cache._defaultItemSize = median) - prevDefaultItemSize) *\n    max(startIndex - measuredCountBeforeStart, 0)\n  );\n};\n\n/**\n * @internal\n */\nexport const initCache = (\n  length: number,\n  itemSize: number,\n  sizes?: readonly number[],\n): Cache => {\n  return {\n    _defaultItemSize: itemSize,\n    _sizes: sizes\n      ? // https://github.com/inokawa/virtua/issues/441\n        fill(\n          sizes.slice(0, min(length, sizes.length)),\n          max(0, length - sizes.length),\n        )\n      : fill([], length),\n    _length: length,\n    _computedOffsetIndex: -1,\n    _offsets: fill([], length + 1),\n  };\n};\n\n/**\n * @internal\n */\nexport const takeCacheSnapshot = (cache: Cache): InternalCacheSnapshot => {\n  return [cache._sizes.slice(), cache._defaultItemSize];\n};\n\n/**\n * @internal\n */\nexport const updateCacheLength = (\n  cache: Writeable<Cache>,\n  length: number,\n  isShift?: boolean,\n): number => {\n  const diff = length - cache._length;\n\n  cache._computedOffsetIndex = isShift\n    ? // Discard cache for now\n      -1\n    : min(length - 1, cache._computedOffsetIndex);\n  cache._length = length;\n\n  if (diff > 0) {\n    // Added\n    fill(cache._offsets, diff);\n    fill(cache._sizes, diff, isShift);\n    return cache._defaultItemSize * diff;\n  } else {\n    // Removed\n    cache._offsets.splice(diff);\n    return (\n      isShift ? cache._sizes.splice(0, -diff) : cache._sizes.splice(diff)\n    ).reduce(\n      (acc, removed) =>\n        acc - (removed === UNCACHED ? cache._defaultItemSize : removed),\n      0,\n    );\n  }\n};\n","import { once } from \"./utils.js\";\n\n/**\n * @internal\n */\nexport const isBrowser = typeof window !== \"undefined\";\n\n/**\n * @internal\n */\nexport const getDocumentElement = (doc: Document): HTMLElement =>\n  doc.documentElement;\n\n/**\n * @internal\n */\nexport const getCurrentDocument = (node: HTMLElement): Document =>\n  node.ownerDocument;\n\n/**\n * @internal\n */\nexport const getCurrentWindow = (doc: Document) => doc.defaultView!;\n\n/**\n * Currently, all browsers on iOS/iPadOS are WebKit, including WebView.\n * @internal\n */\nexport const isIOSWebKit = /*#__PURE__*/ once((): boolean => {\n  if (/iP(hone|od|ad)/.test(navigator.userAgent)) {\n    return true;\n  }\n  // Modern iPad detection (iPadOS 13+)\n  // iPadOS 13+ reports the same userAgent/platform information as macOS, to enable desktop sites.\n  // So we treat devices that have macOS like information but with touch support as iPadOS.\n  // https://stackoverflow.com/questions/57776001/how-to-detect-ipad-pro-as-ipad-using-javascript\n  return navigator.platform === \"MacIntel\" && navigator.maxTouchPoints > 0;\n});\n\n/**\n * @internal\n */\nexport const isSmoothScrollSupported = /*#__PURE__*/ once((): boolean => {\n  return \"scrollBehavior\" in getDocumentElement(document).style;\n});\n","import {\n  initCache,\n  getItemSize as _getItemSize,\n  getItemOffset as _getItemOffset,\n  UNCACHED,\n  setItemSize,\n  estimateDefaultItemSize,\n  updateCacheLength,\n  computeRange,\n  takeCacheSnapshot,\n  findIndex,\n} from \"./cache.js\";\nimport { isIOSWebKit } from \"./environment.js\";\nimport type {\n  CacheSnapshot,\n  InternalCacheSnapshot,\n  ItemResize,\n  ItemsRange,\n} from \"./types.js\";\nimport { abs, max, min, NULL } from \"./utils.js\";\n\nconst MAX_INT_32 = 0x7fffffff;\n\nconst SCROLL_IDLE = 0;\nconst SCROLL_DOWN = 1;\nconst SCROLL_UP = 2;\ntype ScrollDirection =\n  | typeof SCROLL_IDLE\n  | typeof SCROLL_DOWN\n  | typeof SCROLL_UP;\n\nconst SCROLL_BY_NATIVE = 0;\nconst SCROLL_BY_MANUAL_SCROLL = 1;\nconst SCROLL_BY_SHIFT = 2;\ntype ScrollMode =\n  | typeof SCROLL_BY_NATIVE\n  | typeof SCROLL_BY_MANUAL_SCROLL\n  | typeof SCROLL_BY_SHIFT;\n\n/** @internal */\nexport const ACTION_SCROLL = 1;\n/** @internal */\nexport const ACTION_SCROLL_END = 2;\n/** @internal */\nexport const ACTION_ITEM_RESIZE = 3;\n/** @internal */\nexport const ACTION_VIEWPORT_RESIZE = 4;\n/** @internal */\nexport const ACTION_ITEMS_LENGTH_CHANGE = 5;\n/** @internal */\nexport const ACTION_START_OFFSET_CHANGE = 6;\n/** @internal */\nexport const ACTION_MANUAL_SCROLL = 7;\n/** @internal */\nexport const ACTION_BEFORE_MANUAL_SMOOTH_SCROLL = 8;\n\ntype Actions =\n  | [type: typeof ACTION_SCROLL, offset: number]\n  | [type: typeof ACTION_SCROLL_END, dummy?: void]\n  | [type: typeof ACTION_ITEM_RESIZE, entries: ItemResize[]]\n  | [type: typeof ACTION_VIEWPORT_RESIZE, size: number]\n  | [\n      type: typeof ACTION_ITEMS_LENGTH_CHANGE,\n      arg: [length: number, isShift?: boolean | undefined],\n    ]\n  | [type: typeof ACTION_START_OFFSET_CHANGE, offset: number]\n  | [type: typeof ACTION_MANUAL_SCROLL, dummy?: void]\n  | [type: typeof ACTION_BEFORE_MANUAL_SMOOTH_SCROLL, offset: number];\n\n/** @internal */\nexport const UPDATE_VIRTUAL_STATE = 0b0001;\n/** @internal */\nexport const UPDATE_SIZE_EVENT = 0b0010;\n/** @internal */\nexport const UPDATE_SCROLL_EVENT = 0b0100;\n/** @internal */\nexport const UPDATE_SCROLL_END_EVENT = 0b1000;\n\n/**\n * @internal\n */\nexport const getScrollSize = (store: VirtualStore): number => {\n  return max(store.$getTotalSize(), store.$getViewportSize());\n};\n\ntype Subscriber = (sync?: boolean) => void;\n\n/** @internal */\nexport type StateVersion =\n  number & {} /* hack for typescript to pretend as not falsy */;\n\n/**\n * @internal\n */\nexport type VirtualStore = {\n  $dispose(): void;\n  $getStateVersion(): StateVersion;\n  $getCacheSnapshot(): CacheSnapshot;\n  $getRange(bufferSize?: number): ItemsRange;\n  $findItemIndex(offset: number): number;\n  $isUnmeasuredItem(index: number): boolean;\n  $getItemOffset(index: number, fromEnd?: boolean): number;\n  $getItemSize(index: number): number;\n  $getItemsLength(): number;\n  $getScrollOffset(): number;\n  $isScrolling(): boolean;\n  $getViewportSize(): number;\n  $getStartSpacerSize(): number;\n  $getTotalSize(): number;\n  _flushJump(): [number, boolean];\n  $subscribe(target: number, cb: Subscriber): () => void;\n  $update(...action: Actions): void;\n};\n\n/**\n * @internal\n */\nexport const createVirtualStore = (\n  elementsCount: number,\n  itemSize: number = 40,\n  ssrCount: number = 0,\n  cacheSnapshot?: CacheSnapshot | undefined,\n  shouldAutoEstimateItemSize: boolean = false,\n): VirtualStore => {\n  let isSSR = !!ssrCount;\n  let stateVersion: StateVersion = 1;\n  let viewportSize = 0;\n  let startSpacerSize = 0;\n  let scrollOffset = 0;\n  let jump = 0;\n  let pendingJump = 0;\n  let _flushedJump = 0;\n  let _scrollDirection: ScrollDirection = SCROLL_IDLE;\n  let _scrollMode: ScrollMode = SCROLL_BY_NATIVE;\n  let _frozenRange: ItemsRange | null = NULL;\n  let _prevRange: ItemsRange = [0, isSSR ? max(ssrCount - 1, 0) : -1];\n  let _totalMeasuredSize = 0;\n  let _isViewportMeasured = false;\n\n  const cache = initCache(\n    elementsCount,\n    cacheSnapshot\n      ? (cacheSnapshot as unknown as InternalCacheSnapshot)[1]\n      : itemSize,\n    cacheSnapshot && (cacheSnapshot as unknown as InternalCacheSnapshot)[0],\n  );\n  const subscribers = new Set<[number, Subscriber]>();\n  const getRelativeScrollOffset = () => scrollOffset - startSpacerSize;\n  const getVisibleOffset = () => getRelativeScrollOffset() + pendingJump + jump;\n  const getRange = (startOffset: number, endOffset: number) => {\n    return computeRange(cache, startOffset, endOffset, _prevRange[0]);\n  };\n  const getTotalSize = (): number => _getItemOffset(cache, cache._length);\n  const getItemOffset = (index: number, fromEnd?: boolean): number => {\n    const offset = _getItemOffset(cache, index) - pendingJump;\n    if (fromEnd) {\n      return getTotalSize() - offset - getItemSize(index);\n    }\n    return offset;\n  };\n  const getItemSize = (index: number): number => {\n    return _getItemSize(cache, index);\n  };\n  const isSizeEqual = (index: number, value: number = UNCACHED): boolean => {\n    return cache._sizes[index] === value;\n  };\n\n  const applyJump = (j: number) => {\n    if (j) {\n      if (\n        // In iOS WebKit browsers, updating scroll position will stop scrolling so it have to be deferred during scrolling.\n        (isIOSWebKit() && _scrollDirection !== SCROLL_IDLE) ||\n        // Before imperative smooth scrolling, we measure all items which may be visible during scrolling.\n        // However, especially in Firefox, there are rare cases where items resize while scrolling, which can stop smooth scrolling.\n        (_frozenRange && _scrollMode === SCROLL_BY_MANUAL_SCROLL)\n      ) {\n        pendingJump += j;\n      } else {\n        jump += j;\n      }\n    }\n  };\n\n  return {\n    $dispose: () => {\n      subscribers.clear();\n    },\n    $getStateVersion: () => stateVersion,\n    $getCacheSnapshot: () => {\n      return takeCacheSnapshot(cache) as unknown as CacheSnapshot;\n    },\n    $getRange: (bufferSize = 200) => {\n      if (!_isViewportMeasured || isSSR) {\n        // Return range for SSR, or return [0, -1] to render nothing, until the scroll offset and viewport size are determined.\n        // https://github.com/inokawa/virtua/issues/415\n        // https://github.com/inokawa/virtua/pull/818\n        return _prevRange;\n      }\n      let startIndex: number;\n      let endIndex: number;\n      if (_flushedJump) {\n        // Return previous range for consistent render until next scroll event comes in.\n        // And it must be clamped. https://github.com/inokawa/virtua/issues/597\n        [startIndex, endIndex] = _prevRange;\n      } else {\n        let startOffset = max(0, getVisibleOffset());\n        let endOffset = startOffset + viewportSize;\n\n        // For faster initial render pass, returns without buffer if measurement seems to be in progress.\n        if (!shouldAutoEstimateItemSize) {\n          bufferSize = max(0, bufferSize);\n\n          if (_scrollDirection !== SCROLL_DOWN) {\n            startOffset -= bufferSize;\n          }\n          if (_scrollDirection !== SCROLL_UP) {\n            endOffset += bufferSize;\n          }\n        }\n\n        [startIndex, endIndex] = _prevRange = getRange(\n          max(0, startOffset),\n          max(0, endOffset),\n        );\n        if (_frozenRange) {\n          startIndex = min(startIndex, _frozenRange[0]);\n          endIndex = max(endIndex, _frozenRange[1]);\n        }\n      }\n\n      return [max(startIndex, 0), min(endIndex, cache._length - 1)];\n    },\n    $findItemIndex: (offset) => findIndex(cache, offset - startSpacerSize),\n    $isUnmeasuredItem: isSizeEqual,\n    $getItemOffset: getItemOffset,\n    $getItemSize: getItemSize,\n    $getItemsLength: () => cache._length,\n    $getScrollOffset: () => scrollOffset,\n    $isScrolling: () => _scrollDirection !== SCROLL_IDLE,\n    $getViewportSize: () => viewportSize,\n    $getStartSpacerSize: () => startSpacerSize,\n    $getTotalSize: getTotalSize,\n    _flushJump: () => {\n      _flushedJump = jump;\n      jump = 0;\n      return [_flushedJump, _scrollMode === SCROLL_BY_SHIFT];\n    },\n    $subscribe: (target, cb) => {\n      const sub: [number, Subscriber] = [target, cb];\n      subscribers.add(sub);\n      return () => {\n        subscribers.delete(sub);\n      };\n    },\n    $update: (type, payload): void => {\n      let shouldFlushPendingJump: boolean | undefined;\n      let shouldSync: boolean | undefined;\n      let mutated = 0;\n\n      switch (type) {\n        case ACTION_SCROLL: {\n          if (payload === scrollOffset && _scrollMode === SCROLL_BY_NATIVE) {\n            // Ignore scroll events from different direction\n            break;\n          }\n\n          const flushedJump = _flushedJump;\n          _flushedJump = 0;\n\n          const delta = payload - scrollOffset;\n          const distance = abs(delta);\n\n          // Scroll event after jump compensation is not reliable because it may result in the opposite direction.\n          // The delta of artificial scroll may not be equal with the jump because it may be batched with other scrolls.\n          // And at least in latest Chrome/Firefox/Safari in 2023, setting value to scrollTop/scrollLeft can lose subpixel because its integer (sometimes float probably depending on dpr).\n          const isJustJumped = flushedJump && distance < abs(flushedJump) + 1;\n\n          // Scroll events are dispatched enough so it's ok to skip some of them.\n          if (\n            !isJustJumped &&\n            // Ignore until manual scrolling\n            _scrollMode === SCROLL_BY_NATIVE\n          ) {\n            _scrollDirection = delta < 0 ? SCROLL_UP : SCROLL_DOWN;\n          }\n\n          // TODO This will cause glitch in reverse infinite scrolling. Disable this until better solution is found.\n          // if (\n          //   pendingJump &&\n          //   ((_scrollDirection === SCROLL_UP &&\n          //     payload - max(pendingJump, 0) <= 0) ||\n          //     (_scrollDirection === SCROLL_DOWN &&\n          //       payload - min(pendingJump, 0) >= getScrollOffsetMax()))\n          // ) {\n          //   // Flush if almost reached to start or end\n          //   shouldFlushPendingJump = true;\n          // }\n\n          if (isSSR) {\n            isSSR = false;\n          }\n\n          scrollOffset = payload;\n          mutated = UPDATE_SCROLL_EVENT;\n\n          // Skip if offset is not changed\n          // Scroll offset may exceed min or max especially in Safari's elastic scrolling.\n          const relativeOffset = getRelativeScrollOffset();\n          if (\n            relativeOffset >= -viewportSize &&\n            relativeOffset <= getTotalSize()\n          ) {\n            mutated += UPDATE_VIRTUAL_STATE;\n\n            // Update synchronously if scrolled a lot\n            shouldSync = distance > viewportSize;\n          }\n          break;\n        }\n        case ACTION_SCROLL_END: {\n          mutated = UPDATE_SCROLL_END_EVENT;\n          if (_scrollDirection !== SCROLL_IDLE) {\n            shouldFlushPendingJump = true;\n            mutated += UPDATE_VIRTUAL_STATE;\n          }\n          _scrollDirection = SCROLL_IDLE;\n          _scrollMode = SCROLL_BY_NATIVE;\n          _frozenRange = NULL;\n          break;\n        }\n        case ACTION_ITEM_RESIZE: {\n          const updated = payload.filter(\n            ([index, size]) => !isSizeEqual(index, size),\n          );\n\n          // Skip if all items are cached and not updated\n          if (!updated.length) {\n            break;\n          }\n\n          // Calculate jump by resize to minimize junks in appearance\n          applyJump(\n            updated.reduce((acc, [index, size]) => {\n              let shouldKeep: boolean;\n              if (\n                // Keep distance from end during shifting\n                _scrollMode === SCROLL_BY_SHIFT\n              ) {\n                shouldKeep = true;\n              } else if (\n                _frozenRange &&\n                _scrollMode === SCROLL_BY_MANUAL_SCROLL\n              ) {\n                // https://github.com/inokawa/virtua/issues/380\n                // https://github.com/inokawa/virtua/issues/758\n                shouldKeep = index < _frozenRange[0];\n              } else {\n                // Otherwise we should maintain visible position\n                const start = getRelativeScrollOffset();\n                const itemOffset = getItemOffset(index);\n                const itemSize = getItemSize(index);\n                shouldKeep =\n                  _scrollDirection !== SCROLL_DOWN &&\n                  _scrollMode === SCROLL_BY_NATIVE\n                    ? // https://github.com/inokawa/virtua/issues/385\n                      // https://github.com/inokawa/virtua/discussions/865\n                      itemOffset + itemSize < start\n                    : // https://github.com/inokawa/virtua/pull/868\n                      itemOffset < start &&\n                      itemOffset + itemSize < start + viewportSize;\n              }\n\n              if (shouldKeep) {\n                acc += size - getItemSize(index);\n              }\n              return acc;\n            }, 0),\n          );\n\n          // Update item sizes\n          for (const [index, size] of updated) {\n            const prevSize = getItemSize(index);\n            const isInitialMeasurement = setItemSize(cache, index, size);\n\n            if (shouldAutoEstimateItemSize) {\n              _totalMeasuredSize += isInitialMeasurement\n                ? size\n                : size - prevSize;\n            }\n          }\n\n          // Estimate initial item size from measured sizes\n          if (\n            shouldAutoEstimateItemSize &&\n            viewportSize &&\n            // If the total size is lower than the viewport, the item may be a empty state\n            _totalMeasuredSize > viewportSize\n          ) {\n            applyJump(\n              estimateDefaultItemSize(\n                cache,\n                findIndex(cache, getVisibleOffset()),\n              ),\n            );\n            shouldAutoEstimateItemSize = false;\n          }\n\n          mutated = UPDATE_VIRTUAL_STATE + UPDATE_SIZE_EVENT;\n\n          // Synchronous update is necessary in current design to minimize visible glitch in concurrent rendering.\n          // However this seems to be the main cause of the errors from ResizeObserver.\n          // https://github.com/inokawa/virtua/issues/470\n          //\n          // And in React, synchronous update with flushSync after asynchronous update will overtake the asynchronous one.\n          // If items resize happens just after scroll, race condition can occur depending on implementation.\n          shouldSync = true;\n          break;\n        }\n        case ACTION_VIEWPORT_RESIZE: {\n          if (viewportSize !== payload) {\n            if (!viewportSize) {\n              _isViewportMeasured = shouldSync = true;\n            }\n            viewportSize = payload;\n            mutated = UPDATE_VIRTUAL_STATE + UPDATE_SIZE_EVENT;\n          }\n          break;\n        }\n        case ACTION_ITEMS_LENGTH_CHANGE: {\n          if (payload[1]) {\n            applyJump(updateCacheLength(cache, payload[0], true));\n            _scrollMode = SCROLL_BY_SHIFT;\n            mutated = UPDATE_VIRTUAL_STATE;\n          } else {\n            updateCacheLength(cache, payload[0]);\n            // https://github.com/inokawa/virtua/issues/552\n            // https://github.com/inokawa/virtua/issues/557\n            mutated = UPDATE_VIRTUAL_STATE;\n          }\n          break;\n        }\n        case ACTION_START_OFFSET_CHANGE: {\n          startSpacerSize = payload;\n          break;\n        }\n        case ACTION_MANUAL_SCROLL: {\n          _scrollMode = SCROLL_BY_MANUAL_SCROLL;\n          break;\n        }\n        case ACTION_BEFORE_MANUAL_SMOOTH_SCROLL: {\n          _frozenRange = getRange(payload, payload + viewportSize);\n          mutated = UPDATE_VIRTUAL_STATE;\n          break;\n        }\n      }\n\n      if (mutated) {\n        stateVersion = (stateVersion & MAX_INT_32) + 1;\n\n        if (shouldFlushPendingJump && pendingJump) {\n          jump += pendingJump;\n          pendingJump = 0;\n        }\n\n        subscribers.forEach(([target, cb]) => {\n          // Early return to skip React's computation\n          if (!(mutated & target)) {\n            return;\n          }\n          // https://github.com/facebook/react/issues/25191\n          // https://github.com/facebook/react/blob/a5fc797db14c6e05d4d5c4dbb22a0dd70d41f5d5/packages/react-reconciler/src/ReactFiberWorkLoop.js#L1443-L1447\n          cb(shouldSync);\n        });\n      }\n    },\n  };\n};\n","import {\n  getCurrentDocument,\n  getCurrentWindow,\n  getDocumentElement,\n  isIOSWebKit,\n  isSmoothScrollSupported,\n} from \"./environment.js\";\nimport {\n  ACTION_SCROLL,\n  type VirtualStore,\n  ACTION_SCROLL_END,\n  UPDATE_SIZE_EVENT,\n  ACTION_MANUAL_SCROLL,\n  ACTION_BEFORE_MANUAL_SMOOTH_SCROLL,\n  ACTION_START_OFFSET_CHANGE,\n} from \"./store.js\";\nimport { type ScrollToIndexOpts } from \"./types.js\";\nimport { clamp, createPromise, microtask, NULL } from \"./utils.js\";\n\nconst timeout = setTimeout;\n\nconst debounce = <T extends () => void>(fn: T, ms: number) => {\n  let id: ReturnType<typeof setTimeout> | undefined | null;\n\n  const cancel = () => {\n    if (id != NULL) {\n      clearTimeout(id);\n    }\n  };\n  const debouncedFn = () => {\n    cancel();\n    id = timeout(() => {\n      id = NULL;\n      fn();\n    }, ms);\n  };\n  debouncedFn._cancel = cancel;\n  return debouncedFn;\n};\n\n/**\n * scrollTop/scrollLeft can be negative value under certain styles.\n * - direction: rtl https://github.com/othree/jquery.rtl-scroll-type\n * - writing-mode   https://people.igalia.com/fwang/scrollable-elements-in-non-default-writing-modes/\n * - flex-direction: column-reverse/row-reverse\n *\n * top/left bottom/right\n * 0        100          spec compliant bottom/right overflow, or possibly top/left overflow in Chrome earlier than v85\n * -100     0            spec compliant top/left overflow\n * https://drafts.csswg.org/cssom-view/#scroll-an-element\n */\nconst normalizeScrollOffset = (offset: number, isNegative: boolean): number => {\n  return isNegative ? -offset : offset;\n};\n\nconst createScrollObserver = (\n  store: VirtualStore,\n  viewport: HTMLElement | Window,\n  isHorizontal: boolean,\n  getScrollOffset: () => number,\n  updateScrollOffset: (\n    value: number,\n    shift: boolean,\n    isMomentumScrolling: boolean,\n  ) => void,\n  getStartOffset?: () => number,\n) => {\n  const now = Date.now;\n\n  let lastScrollTime = 0;\n  let wheeling = false;\n  let touching = false;\n  let justTouchEnded = false;\n  let stillMomentumScrolling = false;\n\n  const onScrollEnd = debounce(() => {\n    if (wheeling || touching) {\n      wheeling = false;\n\n      // Wait while wheeling or touching\n      onScrollEnd();\n      return;\n    }\n\n    justTouchEnded = false;\n\n    store.$update(ACTION_SCROLL_END);\n  }, 150);\n\n  const onScroll = () => {\n    lastScrollTime = now();\n\n    if (justTouchEnded) {\n      stillMomentumScrolling = true;\n    }\n\n    if (getStartOffset) {\n      store.$update(ACTION_START_OFFSET_CHANGE, getStartOffset());\n    }\n    store.$update(ACTION_SCROLL, getScrollOffset());\n\n    onScrollEnd();\n  };\n\n  // Infer scroll state also from wheel events\n  // Sometimes scroll events do not fire when frame dropped even if the visual have been already scrolled\n  const onWheel = ((e: WheelEvent) => {\n    if (\n      wheeling ||\n      // Scroll start should be detected with scroll event\n      !store.$isScrolling() ||\n      // Probably a pinch-to-zoom gesture\n      e.ctrlKey\n    ) {\n      return;\n    }\n\n    const timeDelta = now() - lastScrollTime;\n    if (\n      // Check if wheel event occurs some time after scrolling\n      150 > timeDelta &&\n      50 < timeDelta &&\n      // Get delta before checking deltaMode for firefox behavior\n      // https://github.com/w3c/uievents/issues/181#issuecomment-392648065\n      // https://bugzilla.mozilla.org/show_bug.cgi?id=1392460#c34\n      (isHorizontal ? e.deltaX : e.deltaY)\n    ) {\n      wheeling = true;\n    }\n  }) as (e: Event) => void; // FIXME type error. why only here?\n\n  const onTouchStart = () => {\n    touching = true;\n    justTouchEnded = stillMomentumScrolling = false;\n  };\n  const onTouchEnd = () => {\n    touching = false;\n    if (isIOSWebKit()) {\n      justTouchEnded = true;\n    }\n  };\n\n  viewport.addEventListener(\"scroll\", onScroll);\n  viewport.addEventListener(\"wheel\", onWheel, { passive: true });\n  viewport.addEventListener(\"touchstart\", onTouchStart, { passive: true });\n  viewport.addEventListener(\"touchend\", onTouchEnd, { passive: true });\n\n  return {\n    _dispose: () => {\n      viewport.removeEventListener(\"scroll\", onScroll);\n      viewport.removeEventListener(\"wheel\", onWheel);\n      viewport.removeEventListener(\"touchstart\", onTouchStart);\n      viewport.removeEventListener(\"touchend\", onTouchEnd);\n      onScrollEnd._cancel();\n    },\n    _fixScrollJump: () => {\n      const [jump, shift] = store._flushJump();\n      if (!jump) return;\n      updateScrollOffset(jump, shift, stillMomentumScrolling);\n      stillMomentumScrolling = false;\n\n      if (shift && store.$getViewportSize() > store.$getTotalSize()) {\n        // In this case applying jump may not cause scroll.\n        // Current logic expects scroll event occurs after applying jump so we dispatch it manually.\n        store.$update(ACTION_SCROLL, getScrollOffset());\n      }\n    },\n  };\n};\n\ntype ScrollObserver = ReturnType<typeof createScrollObserver>;\n\ntype ScheduleScrollFunction = (\n  getTargetOffset: () => number,\n  smooth?: boolean,\n) => Promise<void>;\n\nconst createScrollScheduler = (\n  store: VirtualStore,\n  initialized: () => Promise<boolean>,\n  scroll: (offset: number, smooth?: boolean) => void,\n): [scroll: ScheduleScrollFunction, cancel: () => void] => {\n  let cancelScroll: (() => void) | undefined;\n\n  // The given offset will be clamped by browser\n  // https://drafts.csswg.org/cssom-view/#dom-element-scrolltop\n  return [\n    async (getTargetOffset, smooth) => {\n      // Wait for element assign. The element may be undefined if scrollRef prop is used and scroll is scheduled on mount.\n      // https://github.com/inokawa/virtua/pull/733\n      // https://github.com/inokawa/virtua/pull/750\n      if (!(await initialized())) {\n        return;\n      }\n\n      if (cancelScroll) {\n        // Cancel waiting scrollTo\n        cancelScroll();\n      }\n\n      const waitForMeasurement = (): [Promise<boolean>, () => void] => {\n        // Wait for the scroll destination items to be measured.\n        // The measurement will be done asynchronously and the timing is not predictable so we use promise.\n        const [promise, resolve] = createPromise<boolean>();\n        cancelScroll = () => {\n          resolve(false);\n        };\n\n        // Resize event may not happen when the window/tab is not visible, or during browser back in Safari.\n        // We have to wait for the initial measurement to avoid failing imperative scroll on mount.\n        // https://github.com/inokawa/virtua/issues/450\n        if (store.$getViewportSize()) {\n          // Cancel when items around scroll destination completely measured\n          timeout(cancelScroll, 150);\n        }\n        return [\n          promise,\n          store.$subscribe(UPDATE_SIZE_EVENT, () => {\n            resolve(true);\n          }),\n        ];\n      };\n\n      if (smooth && isSmoothScrollSupported()) {\n        store.$update(ACTION_BEFORE_MANUAL_SMOOTH_SCROLL, getTargetOffset());\n\n        // https://github.com/inokawa/virtua/issues/590\n        microtask(async () => {\n          while (true) {\n            let done = true;\n            for (let [i, end] = store.$getRange(); i <= end; i++) {\n              if (store.$isUnmeasuredItem(i)) {\n                done = false;\n                break;\n              }\n            }\n            if (done) {\n              break;\n            }\n            const [promise, unsubscribe] = waitForMeasurement();\n\n            try {\n              if (!(await promise)) {\n                // canceled\n                return;\n              }\n            } finally {\n              unsubscribe();\n            }\n          }\n\n          store.$update(ACTION_MANUAL_SCROLL);\n          scroll(getTargetOffset(), smooth);\n        });\n      } else {\n        while (true) {\n          const [promise, unsubscribe] = waitForMeasurement();\n\n          try {\n            store.$update(ACTION_MANUAL_SCROLL);\n            scroll(getTargetOffset());\n\n            if (!(await promise)) {\n              // canceled or finished\n              return;\n            }\n          } finally {\n            unsubscribe();\n          }\n        }\n      }\n    },\n    () => {\n      cancelScroll && cancelScroll();\n    },\n  ];\n};\n\ninterface Scroller<T extends HTMLElement | void> {\n  $observe: (containerElement: HTMLElement, viewport: T) => void;\n  $dispose(): void;\n  $fixScrollJump: () => void;\n  $isNegative(): boolean;\n}\n\n/**\n * @internal\n */\nexport const createScroller = (\n  store: VirtualStore,\n  isHorizontal: boolean,\n): Scroller<HTMLElement> & {\n  $scrollTo: (offset: number) => void;\n  $scrollBy: (offset: number) => void;\n  $scrollToIndex: (index: number, opts?: ScrollToIndexOpts) => void;\n} => {\n  let viewportElement: HTMLElement | undefined;\n  let scrollObserver: ScrollObserver | undefined;\n  let initialized = createPromise<boolean>();\n  let isNegative = false;\n  const scrollOffsetKey = isHorizontal ? \"scrollLeft\" : \"scrollTop\";\n  const overflowKey = isHorizontal ? \"overflowX\" : \"overflowY\";\n\n  const [scheduleScroll, cancelScroll] = createScrollScheduler(\n    store,\n    () => initialized[0],\n    (offset, smooth) => {\n      offset = normalizeScrollOffset(offset, isNegative);\n\n      if (smooth) {\n        viewportElement!.scrollTo({\n          [isHorizontal ? \"left\" : \"top\"]: offset,\n          behavior: \"smooth\",\n        });\n      } else {\n        viewportElement![scrollOffsetKey] = offset;\n      }\n    },\n  );\n\n  return {\n    $observe(_, viewport) {\n      viewportElement = viewport;\n\n      if (isHorizontal) {\n        isNegative = getComputedStyle(viewport).direction === \"rtl\";\n      }\n\n      scrollObserver = createScrollObserver(\n        store,\n        viewport,\n        isHorizontal,\n        () => normalizeScrollOffset(viewport[scrollOffsetKey], isNegative),\n        (jump, shift, isMomentumScrolling) => {\n          // If we update scroll position while touching on iOS, the position will be reverted.\n          // However iOS WebKit fires touch events only once at the beginning of momentum scrolling.\n          // That means we have no reliable way to confirm still touched or not if user touches more than once during momentum scrolling...\n          // This is a hack for the suspectable situations, inspired by https://github.com/prud/ios-overflow-scroll-to-top\n          if (isMomentumScrolling) {\n            const style = viewport.style;\n            const prev = style[overflowKey];\n            style[overflowKey] = \"hidden\";\n            timeout(() => {\n              style[overflowKey] = prev;\n            });\n          }\n\n          // Use absolute position not to exceed scrollable bounds\n          // https://github.com/inokawa/virtua/discussions/475\n          viewport[scrollOffsetKey] = normalizeScrollOffset(\n            store.$getScrollOffset() + jump,\n            isNegative,\n          );\n          if (shift) {\n            // https://github.com/inokawa/virtua/issues/357\n            cancelScroll();\n          }\n        },\n      );\n\n      initialized[1](true);\n    },\n    $dispose() {\n      scrollObserver && scrollObserver._dispose();\n      initialized[1](false);\n      // https://github.com/inokawa/virtua/pull/765\n      initialized = createPromise();\n    },\n    $isNegative: () => isNegative,\n    $scrollTo(offset) {\n      scheduleScroll(() => offset);\n    },\n    $scrollBy(offset) {\n      offset += store.$getScrollOffset();\n      scheduleScroll(() => offset);\n    },\n    $scrollToIndex(index, { align, smooth, offset = 0 } = {}) {\n      index = clamp(index, 0, store.$getItemsLength() - 1);\n\n      if (align === \"nearest\") {\n        const itemOffset = store.$getItemOffset(index);\n        const scrollOffset = store.$getScrollOffset();\n\n        if (itemOffset < scrollOffset) {\n          align = \"start\";\n        } else if (\n          itemOffset + store.$getItemSize(index) >\n          scrollOffset + store.$getViewportSize()\n        ) {\n          align = \"end\";\n        } else {\n          // already completely visible\n          return;\n        }\n      }\n\n      scheduleScroll(() => {\n        return (\n          offset +\n          store.$getStartSpacerSize() +\n          store.$getItemOffset(index) +\n          (align === \"end\"\n            ? store.$getItemSize(index) - store.$getViewportSize()\n            : align === \"center\"\n              ? (store.$getItemSize(index) - store.$getViewportSize()) / 2\n              : 0)\n        );\n      }, smooth);\n    },\n    $fixScrollJump: () => {\n      scrollObserver && scrollObserver._fixScrollJump();\n    },\n  };\n};\n\n/**\n * @internal\n */\nexport const createWindowScroller = (\n  store: VirtualStore,\n  isHorizontal: boolean,\n): Scroller<void> & {\n  $scrollToIndex: (index: number, opts?: ScrollToIndexOpts) => void;\n} => {\n  let containerElement: HTMLElement | undefined;\n  let scrollObserver: ScrollObserver | undefined;\n  let initialized = createPromise<boolean>();\n  let isNegative = false;\n  const scrollToKey = isHorizontal ? \"left\" : \"top\";\n\n  const [scheduleScroll] = createScrollScheduler(\n    store,\n    () => initialized[0],\n    (offset, smooth) => {\n      offset = normalizeScrollOffset(offset, isNegative);\n\n      const window = getCurrentWindow(getCurrentDocument(containerElement!));\n\n      if (smooth) {\n        window.scroll({\n          [scrollToKey]: offset,\n          behavior: \"smooth\",\n        });\n      } else {\n        window.scroll({\n          [scrollToKey]: offset,\n        });\n      }\n    },\n  );\n\n  const calcOffsetToViewport = (\n    node: HTMLElement,\n    viewport: HTMLElement,\n    window: Window,\n    isHorizontal: boolean,\n    offset: number = 0,\n  ): number => {\n    // TODO calc offset only when it changes (maybe impossible)\n    const offsetKey = isHorizontal ? \"offsetLeft\" : \"offsetTop\";\n    const offsetSum =\n      offset +\n      (isHorizontal && isNegative\n        ? window.innerWidth - node[offsetKey] - node.offsetWidth\n        : node[offsetKey]);\n\n    const parent = node.offsetParent;\n    if (node === viewport || !parent) {\n      return offsetSum;\n    }\n\n    return calcOffsetToViewport(\n      parent as HTMLElement,\n      viewport,\n      window,\n      isHorizontal,\n      offsetSum,\n    );\n  };\n\n  return {\n    $observe(container) {\n      containerElement = container;\n      const scrollOffsetKey = isHorizontal ? \"scrollX\" : \"scrollY\";\n\n      const document = getCurrentDocument(container);\n      const window = getCurrentWindow(document);\n\n      if (isHorizontal) {\n        // Detect RTL document\n        isNegative =\n          getComputedStyle(getDocumentElement(document)).direction === \"rtl\";\n      }\n\n      scrollObserver = createScrollObserver(\n        store,\n        window,\n        isHorizontal,\n        () => normalizeScrollOffset(window[scrollOffsetKey], isNegative),\n        (jump, shift) => {\n          // TODO support case two window scrollers exist in the same view\n          if (shift) {\n            // Use absolute position not to exceed scrollable bounds\n            window.scroll({\n              [scrollToKey]: normalizeScrollOffset(\n                store.$getScrollOffset() + jump,\n                isNegative,\n              ),\n            });\n          } else {\n            // Use window.scrollBy here, which causes less layout shift for some reason.\n            window.scrollBy({\n              [scrollToKey]: normalizeScrollOffset(jump, isNegative),\n            });\n          }\n        },\n        () =>\n          calcOffsetToViewport(container, document.body, window, isHorizontal),\n      );\n\n      initialized[1](true);\n    },\n    $dispose() {\n      scrollObserver && scrollObserver._dispose();\n      containerElement = undefined;\n      initialized[1](false);\n      // https://github.com/inokawa/virtua/pull/765\n      initialized = createPromise();\n    },\n    $isNegative: () => isNegative,\n    $fixScrollJump: () => {\n      scrollObserver && scrollObserver._fixScrollJump();\n    },\n    $scrollToIndex(index, { align, smooth, offset = 0 } = {}) {\n      if (!containerElement) return;\n\n      index = clamp(index, 0, store.$getItemsLength() - 1);\n\n      if (align === \"nearest\") {\n        const itemOffset = store.$getItemOffset(index);\n        const scrollOffset = store.$getScrollOffset();\n\n        if (itemOffset < scrollOffset) {\n          align = \"start\";\n        } else if (\n          itemOffset + store.$getItemSize(index) >\n          scrollOffset + store.$getViewportSize()\n        ) {\n          align = \"end\";\n        } else {\n          return;\n        }\n      }\n\n      const document = getCurrentDocument(containerElement);\n      const window = getCurrentWindow(document);\n      const html = getDocumentElement(document);\n      const getScrollbarSize = () =>\n        store.$getViewportSize() -\n        (isHorizontal ? html.clientWidth : html.clientHeight);\n\n      scheduleScroll(() => {\n        return (\n          offset +\n          // Calculate target scroll position including container's offset from document\n          calcOffsetToViewport(\n            containerElement!,\n            document.body,\n            window,\n            isHorizontal,\n          ) +\n          // store._getStartSpacerSize() +\n          store.$getItemOffset(index) +\n          (align === \"end\"\n            ? store.$getItemSize(index) -\n              (store.$getViewportSize() - getScrollbarSize())\n            : align === \"center\"\n              ? (store.$getItemSize(index) -\n                  (store.$getViewportSize() - getScrollbarSize())) /\n                2\n              : 0)\n        );\n      }, smooth);\n    },\n  };\n};\n\n/**\n * @internal\n */\nexport interface GridScroller extends Scroller<HTMLElement> {\n  $scrollTo: (offsetX?: number, offsetY?: number) => void;\n  $scrollBy: (offsetX?: number, offsetY?: number) => void;\n  $scrollToIndex: (indexX?: number, indexY?: number) => void;\n}\n\n/**\n * @internal\n */\nexport const createGridScroller = (\n  rowStore: VirtualStore,\n  colStore: VirtualStore,\n): GridScroller => {\n  const rowScroller = createScroller(rowStore, false);\n  const colScroller = createScroller(colStore, true);\n  return {\n    $observe(container, viewport) {\n      rowScroller.$observe(container, viewport);\n      colScroller.$observe(container, viewport);\n    },\n    $dispose() {\n      rowScroller.$dispose();\n      colScroller.$dispose();\n    },\n    $isNegative: colScroller.$isNegative,\n    $scrollTo(row, col) {\n      if (row != null) {\n        rowScroller.$scrollTo(row);\n      }\n      if (col != null) {\n        colScroller.$scrollTo(col);\n      }\n    },\n    $scrollBy(row, col) {\n      if (row != null) {\n        rowScroller.$scrollBy(row);\n      }\n      if (col != null) {\n        colScroller.$scrollBy(col);\n      }\n    },\n    $scrollToIndex(row, col) {\n      if (row != null) {\n        rowScroller.$scrollToIndex(row);\n      }\n      if (col != null) {\n        colScroller.$scrollToIndex(col);\n      }\n    },\n    $fixScrollJump() {\n      rowScroller.$fixScrollJump();\n      colScroller.$fixScrollJump();\n    },\n  };\n};\n","import { getCurrentDocument, getCurrentWindow } from \"./environment.js\";\nimport {\n  ACTION_ITEM_RESIZE,\n  ACTION_VIEWPORT_RESIZE,\n  type VirtualStore,\n} from \"./store.js\";\nimport { type ItemResize } from \"./types.js\";\nimport { max, microtask, NULL } from \"./utils.js\";\n\nconst createResizeObserver = (cb: ResizeObserverCallback) => {\n  let ro: ResizeObserver | undefined;\n\n  return {\n    _observe(e: HTMLElement) {\n      // Initialize ResizeObserver lazily for SSR\n      // https://www.w3.org/TR/resize-observer/#intro\n      (\n        ro ||\n        // https://bugs.chromium.org/p/chromium/issues/detail?id=1491739\n        (ro = new (getCurrentWindow(getCurrentDocument(e)).ResizeObserver)(cb))\n      ).observe(e);\n    },\n    _unobserve(e: HTMLElement) {\n      ro!.unobserve(e);\n    },\n    _dispose() {\n      ro && ro.disconnect();\n    },\n  };\n};\n\n/**\n * @internal\n */\nexport type ItemResizeObserver = (el: HTMLElement, i: number) => () => void;\n\ninterface ListResizer {\n  $observeRoot(viewportElement: HTMLElement): void;\n  $observeItem: ItemResizeObserver;\n  $dispose(): void;\n}\n\n/**\n * @internal\n */\nexport const createResizer = (\n  store: VirtualStore,\n  isHorizontal: boolean,\n): ListResizer => {\n  let viewportElement: HTMLElement | undefined;\n  const sizeKey = isHorizontal ? \"width\" : \"height\";\n  const mountedIndexes = new WeakMap<Element, number>();\n\n  const resizeObserver = createResizeObserver((entries) => {\n    const resizes: ItemResize[] = [];\n    for (const { target, contentRect } of entries) {\n      // Skip zero-sized rects that may be observed under `display: none` style\n      if (!(target as HTMLElement).offsetParent) continue;\n\n      if (target === viewportElement) {\n        store.$update(ACTION_VIEWPORT_RESIZE, contentRect[sizeKey]);\n      } else {\n        const index = mountedIndexes.get(target);\n        if (index != NULL) {\n          resizes.push([index, contentRect[sizeKey]]);\n        }\n      }\n    }\n\n    if (resizes.length) {\n      store.$update(ACTION_ITEM_RESIZE, resizes);\n    }\n  });\n\n  return {\n    $observeRoot(viewport: HTMLElement) {\n      resizeObserver._observe((viewportElement = viewport));\n    },\n    $observeItem: (el: HTMLElement, i: number) => {\n      mountedIndexes.set(el, i);\n      resizeObserver._observe(el);\n      return () => {\n        mountedIndexes.delete(el);\n        resizeObserver._unobserve(el);\n      };\n    },\n    $dispose: resizeObserver._dispose,\n  };\n};\n\ninterface WindowListResizer {\n  $observeRoot(container: HTMLElement): void;\n  $observeItem: ItemResizeObserver;\n  $dispose(): void;\n}\n\n/**\n * @internal\n */\nexport const createWindowResizer = (\n  store: VirtualStore,\n  isHorizontal: boolean,\n): WindowListResizer => {\n  const sizeKey = isHorizontal ? \"width\" : \"height\";\n  const windowSizeKey = isHorizontal ? \"innerWidth\" : \"innerHeight\";\n  const mountedIndexes = new WeakMap<Element, number>();\n\n  const resizeObserver = createResizeObserver((entries) => {\n    const resizes: ItemResize[] = [];\n    for (const { target, contentRect } of entries) {\n      // Skip zero-sized rects that may be observed under `display: none` style\n      if (!(target as HTMLElement).offsetParent) continue;\n\n      const index = mountedIndexes.get(target);\n      if (index != NULL) {\n        resizes.push([index, contentRect[sizeKey]]);\n      }\n    }\n\n    if (resizes.length) {\n      store.$update(ACTION_ITEM_RESIZE, resizes);\n    }\n  });\n\n  let cleanupOnWindowResize: (() => void) | undefined;\n\n  return {\n    $observeRoot(container) {\n      const window = getCurrentWindow(getCurrentDocument(container));\n      const onWindowResize = () => {\n        store.$update(ACTION_VIEWPORT_RESIZE, window[windowSizeKey]);\n      };\n      window.addEventListener(\"resize\", onWindowResize);\n\n      // https://github.com/inokawa/virtua/issues/792\n      microtask(onWindowResize);\n\n      cleanupOnWindowResize = () => {\n        window.removeEventListener(\"resize\", onWindowResize);\n      };\n    },\n    $observeItem: (el: HTMLElement, i: number) => {\n      mountedIndexes.set(el, i);\n      resizeObserver._observe(el);\n      return () => {\n        mountedIndexes.delete(el);\n        resizeObserver._unobserve(el);\n      };\n    },\n    $dispose() {\n      cleanupOnWindowResize && cleanupOnWindowResize();\n      resizeObserver._dispose();\n    },\n  };\n};\n\n/**\n * @internal\n */\nexport const createGridResizer = (\n  rowStore: VirtualStore,\n  colStore: VirtualStore,\n) => {\n  let viewportElement: HTMLElement | undefined;\n\n  const mountedIndexes = new WeakMap<\n    Element,\n    [rowIndex: number, colIndex: number]\n  >();\n\n  type CellSize = [height: number, width: number];\n  const maybeCachedRowIndexes = new Set<number>();\n  const maybeCachedColIndexes = new Set<number>();\n  const sizeCache = new Map<string, CellSize>();\n  const getKey = (rowIndex: number, colIndex: number): string =>\n    `${rowIndex}-${colIndex}`;\n\n  const resizeObserver = createResizeObserver((entries) => {\n    const resizedRows = new Set<number>();\n    const resizedCols = new Set<number>();\n    for (const {\n      target,\n      contentRect: { width, height },\n    } of entries) {\n      // Skip zero-sized rects that may be observed under `display: none` style\n      if (!(target as HTMLElement).offsetParent) continue;\n\n      if (target === viewportElement) {\n        rowStore.$update(ACTION_VIEWPORT_RESIZE, height);\n        colStore.$update(ACTION_VIEWPORT_RESIZE, width);\n      } else {\n        const cell = mountedIndexes.get(target);\n        if (cell) {\n          const [rowIndex, colIndex] = cell;\n          const key = getKey(rowIndex, colIndex);\n          const prevSize = sizeCache.get(key);\n          let rowResized: boolean | undefined;\n          let colResized: boolean | undefined;\n          if (!prevSize) {\n            rowResized = colResized = true;\n          } else {\n            if (prevSize[0] !== height) {\n              rowResized = true;\n            }\n            if (prevSize[1] !== width) {\n              colResized = true;\n            }\n          }\n          if (rowResized) {\n            resizedRows.add(rowIndex);\n          }\n          if (colResized) {\n            resizedCols.add(colIndex);\n          }\n          if (rowResized || colResized) {\n            sizeCache.set(key, [height, width]);\n          }\n        }\n      }\n    }\n\n    if (resizedRows.size) {\n      const heightResizes: ItemResize[] = [];\n      resizedRows.forEach((rowIndex) => {\n        let maxHeight = 0;\n        maybeCachedColIndexes.forEach((colIndex) => {\n          const size = sizeCache.get(getKey(rowIndex, colIndex));\n          if (size) {\n            maxHeight = max(maxHeight, size[0]);\n          }\n        });\n        if (maxHeight) {\n          heightResizes.push([rowIndex, maxHeight]);\n        }\n      });\n      rowStore.$update(ACTION_ITEM_RESIZE, heightResizes);\n    }\n    if (resizedCols.size) {\n      const widthResizes: ItemResize[] = [];\n      resizedCols.forEach((colIndex) => {\n        let maxWidth = 0;\n        maybeCachedRowIndexes.forEach((rowIndex) => {\n          const size = sizeCache.get(getKey(rowIndex, colIndex));\n          if (size) {\n            maxWidth = max(maxWidth, size[1]);\n          }\n        });\n        if (maxWidth) {\n          widthResizes.push([colIndex, maxWidth]);\n        }\n      });\n      colStore.$update(ACTION_ITEM_RESIZE, widthResizes);\n    }\n  });\n\n  return {\n    $observeRoot(viewport: HTMLElement) {\n      resizeObserver._observe((viewportElement = viewport));\n    },\n    $observeItem(el: HTMLElement, rowIndex: number, colIndex: number) {\n      mountedIndexes.set(el, [rowIndex, colIndex]);\n      maybeCachedRowIndexes.add(rowIndex);\n      maybeCachedColIndexes.add(colIndex);\n      resizeObserver._observe(el);\n      return () => {\n        mountedIndexes.delete(el);\n        resizeObserver._unobserve(el);\n      };\n    },\n    $resizeCols(cols: ItemResize[]) {\n      for (const [c] of cols) {\n        for (let r = 0; r < rowStore.$getItemsLength(); r++) {\n          sizeCache.delete(getKey(r, c));\n        }\n      }\n      colStore.$update(ACTION_ITEM_RESIZE, cols);\n    },\n    $resizeRows(rows: ItemResize[]) {\n      for (const [r] of rows) {\n        for (let c = 0; c < colStore.$getItemsLength(); c++) {\n          sizeCache.delete(getKey(r, c));\n        }\n      }\n      rowStore.$update(ACTION_ITEM_RESIZE, rows);\n    },\n    $dispose: resizeObserver._dispose,\n  };\n};\n\n/**\n * @internal\n */\nexport type GridResizer = ReturnType<typeof createGridResizer>;\n","/** @jsxImportSource vue */\nimport {\n  ref,\n  defineComponent,\n  watch,\n  type StyleValue,\n  type PropType,\n  type VNode,\n  type NativeElements,\n  computed,\n  type Ref,\n} from \"vue\";\nimport {\n  type ItemResizeObserver,\n  type StateVersion,\n  type VirtualStore,\n} from \"../core/index.js\";\nimport { type ItemProps } from \"./utils.js\";\n\n/**\n * @internal\n */\nexport const ListItem = /*#__PURE__*/ defineComponent({\n  props: {\n    _stateVersion: {\n      type: Object as PropType<Ref<StateVersion>>,\n      required: true,\n    },\n    _store: { type: Object as PropType<VirtualStore>, required: true },\n    _children: { type: Object as PropType<VNode[]>, required: true },\n    _resizer: {\n      type: Function as PropType<ItemResizeObserver>,\n      required: true,\n    },\n    _index: { type: Number, required: true },\n    _isHorizontal: { type: Boolean },\n    _isSSR: { type: Boolean },\n    _isNegative: { type: Boolean },\n    _as: { type: String as PropType<keyof NativeElements>, required: true },\n    _itemProps: Object as PropType<ReturnType<ItemProps>>,\n  },\n  setup(props) {\n    const elementRef = ref<HTMLDivElement>();\n\n    const offset = computed(\n      () =>\n        props._stateVersion.value &&\n        props._store.$getItemOffset(props._index, props._isNegative),\n    );\n    const hide = computed(\n      () =>\n        props._stateVersion.value &&\n        props._store.$isUnmeasuredItem(props._index),\n    );\n\n    // The index may be changed if elements are inserted to or removed from the start of props.children\n    watch(\n      () => elementRef.value && props._index,\n      (_, __, onCleanup) => {\n        onCleanup(props._resizer(elementRef.value!, props._index));\n      },\n      {\n        flush: \"post\",\n      },\n    );\n\n    return () => {\n      const {\n        _children: children,\n        _isHorizontal: isHorizontal,\n        _isSSR: isSSR,\n        _as: Element,\n      } = props;\n      const isHide = hide.value;\n\n      const { style: styleProp, ...rest } = props._itemProps ?? {};\n\n      const style: StyleValue = {\n        contain: \"layout style\",\n        position: isHide && isSSR ? undefined : \"absolute\",\n        [isHorizontal ? \"height\" : \"width\"]: \"100%\",\n        [isHorizontal ? \"top\" : \"left\"]: \"0px\",\n        [isHorizontal ? \"left\" : \"top\"]: offset.value + \"px\",\n        visibility: !isHide || isSSR ? undefined : \"hidden\",\n        ...styleProp,\n      };\n      if (isHorizontal) {\n        style.display = \"inline-flex\";\n      }\n\n      return (\n        <Element ref={elementRef} style={style} {...rest}>\n          {children}\n        </Element>\n      );\n    };\n  },\n});\n","import { type CSSProperties, type VNode } from \"vue\";\nimport { type ItemsRange } from \"../core/index.js\";\n\n/**\n * @internal\n */\nexport const getKey = (e: VNode[], i: number): Exclude<VNode[\"key\"], null> => {\n  // https://github.com/inokawa/virtua/pull/846\n  if (e.length === 1) {\n    const key = e[0]!.key;\n    if (key != null) {\n      return key;\n    }\n  }\n  return \"_\" + i;\n};\n\n/**\n * @internal\n */\nexport const isSameRange = (prev: ItemsRange, next: ItemsRange): boolean => {\n  return prev[0] === next[0] && prev[1] === next[1];\n};\n\nexport type ItemProps<T = unknown> = (payload: {\n  item: T;\n  index: number;\n}) => { [key: string]: any; style?: CSSProperties; class?: string } | undefined;\n","/** @jsxImportSource vue */\nimport {\n  ref,\n  onMounted,\n  defineComponent,\n  onUnmounted,\n  type VNode,\n  watch,\n  type PublicProps,\n  type PropType,\n  type NativeElements,\n  computed,\n} from \"vue\";\nimport {\n  UPDATE_SCROLL_EVENT,\n  UPDATE_SCROLL_END_EVENT,\n  UPDATE_VIRTUAL_STATE,\n  createVirtualStore,\n  ACTION_ITEMS_LENGTH_CHANGE,\n  getScrollSize,\n  ACTION_START_OFFSET_CHANGE,\n  createResizer,\n  createScroller,\n  type ItemsRange,\n  type ScrollToIndexOpts,\n  sort,\n  type CacheSnapshot,\n} from \"../core/index.js\";\nimport { ListItem } from \"./ListItem.js\";\nimport { getKey, isSameRange, type ItemProps } from \"./utils.js\";\n\n/**\n * Props of {@link Virtualizer}.\n */\nexport interface VirtualizerProps<T = unknown> extends PublicProps {\n  /**\n   * The data items rendered by this component.\n   */\n  data: T[];\n  /**\n   * Extra item space in pixels to render before/after the viewport. The minimum value is 0. Lower value will give better performance but you can increase to avoid showing blank items in fast scrolling.\n   * @defaultValue 200\n   */\n  bufferSize?: number;\n  /**\n   * Item size hint for unmeasured items in pixels. It will help to reduce scroll jump when items are measured if used properly.\n   *\n   * - If not set, initial item sizes will be automatically estimated from measured sizes. This is recommended for most cases.\n   * - If set, you can opt out estimation and use the value as initial item size.\n   */\n  itemSize?: number;\n  /**\n   * While true is set, scroll position will be maintained from the end not usual start when items are added to/removed from start. It's recommended to set false if you add to/remove from mid/end of the list because it can cause unexpected behavior. This prop is useful for reverse infinite scrolling.\n   */\n  shift?: boolean;\n  /**\n   * If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list.\n   */\n  horizontal?: boolean;\n  /**\n   * The offset to the scrollable parent before virtualizer in pixels. If you put an element before virtualizer, you have to set its height to this prop.\n   */\n  startMargin?: number;\n  /**\n   * A prop for SSR. If set, the specified amount of items will be mounted in the initial rendering regardless of the container size until hydrated. The minimum value is 0.\n   */\n  ssrCount?: number;\n  /**\n   * Reference to the scrollable element. The default will get the direct parent element of virtualizer.\n   */\n  scrollRef?: HTMLElement;\n  /**\n   * Component or element type for container element.\n   * @defaultValue \"div\"\n   */\n  as?: keyof NativeElements;\n  /**\n   * Component or element type for item element.\n   * @defaultValue \"div\"\n   */\n  item?: keyof NativeElements;\n  /**\n   * A function that provides properties/attributes for item element\n   *\n   * **This prop will be merged into `item` prop in the future**\n   */\n  itemProps?: ItemProps<T>;\n  /**\n   * List of indexes that should be always mounted, even when off screen.\n   */\n  keepMounted?: readonly number[];\n  /**\n   * You can restore cache by passing a {@link CacheSnapshot} on mount. This is useful when you want to restore scroll position after navigation. The snapshot can be obtained from {@link VirtualizerHandle.cache}.\n   *\n   * **The length of items should be the same as when you take the snapshot, otherwise restoration may not work as expected.**\n   */\n  cache?: CacheSnapshot;\n  /**\n   * Callback invoked whenever scroll offset changes.\n   * @param offset Current scrollTop, or scrollLeft if horizontal: true.\n   */\n  onScroll?: (offset: number) => void;\n  /**\n   * Callback invoked when scrolling stops.\n   */\n  onScrollEnd?: () => void;\n}\n\ninterface VirtualizerInstance<T = unknown> extends VirtualizerHandle {\n  $props: VirtualizerProps<T>;\n  $slots: { default: (arg: { item: T; index: number }) => VNode[] };\n}\n\n/**\n * Methods of {@link Virtualizer}.\n */\nexport interface VirtualizerHandle {\n  /**\n   * Get current {@link CacheSnapshot}.\n   */\n  readonly cache: CacheSnapshot;\n  /**\n   * Get current scrollTop, or scrollLeft if horizontal: true.\n   */\n  readonly scrollOffset: number;\n  /**\n   * Get current scrollHeight, or scrollWidth if horizontal: true.\n   */\n  readonly scrollSize: number;\n  /**\n   * Get current offsetHeight, or offsetWidth if horizontal: true.\n   */\n  readonly viewportSize: number;\n  /**\n   * Find nearest item index from offset.\n   * @param offset offset in pixels from the start of the scroll container\n   */\n  findItemIndex(offset: number): number;\n  /**\n   * Get item offset from start.\n   * @param index index of item\n   */\n  getItemOffset(index: number): number;\n  /**\n   * Get item size.\n   * @param index index of item\n   */\n  getItemSize(index: number): number;\n  /**\n   * Scroll to the item specified by index.\n   * @param index index of item\n   * @param opts options\n   */\n  scrollToIndex(index: number, opts?: ScrollToIndexOpts): void;\n  /**\n   * Scroll to the given offset.\n   * @param offset offset from start\n   */\n  scrollTo(offset: number): void;\n  /**\n   * Scroll by the given offset.\n   * @param offset offset from current position\n   */\n  scrollBy(offset: number): void;\n}\n\n/**\n * Customizable list virtualizer for advanced usage. See {@link VirtualizerProps} and {@link VirtualizerHandle}.\n */\nexport const Virtualizer = /*#__PURE__*/ defineComponent({\n  props: {\n    data: { type: Array, required: true },\n    bufferSize: Number,\n    itemSize: Number,\n    shift: Boolean,\n    horizontal: Boolean,\n    startMargin: { type: Number, default: 0 },\n    ssrCount: Number,\n    scrollRef: Object as PropType<VirtualizerProps[\"scrollRef\"]>,\n    as: { type: String as PropType<VirtualizerProps[\"as\"]>, default: \"div\" },\n    item: {\n      type: String as PropType<VirtualizerProps[\"item\"]>,\n      default: \"div\",\n    },\n    itemProps: Function as PropType<VirtualizerProps[\"itemProps\"]>,\n    keepMounted: Array as PropType<VirtualizerProps[\"keepMounted\"]>,\n    cache: Object as PropType<VirtualizerProps[\"cache\"]>,\n  },\n  emits: [\"scroll\", \"scrollEnd\"],\n  setup(props, { emit, expose, slots }) {\n    let isSSR = !!props.ssrCount;\n\n    const isHorizontal = props.horizontal;\n    const containerRef = ref<HTMLDivElement>();\n    const store = createVirtualStore(\n      props.data.length,\n      props.itemSize,\n      props.ssrCount,\n      props.cache,\n      !props.itemSize,\n    );\n    const resizer = createResizer(store, isHorizontal);\n    const scroller = createScroller(store, isHorizontal);\n\n    const stateVersion = ref(store.$getStateVersion());\n    store.$subscribe(UPDATE_VIRTUAL_STATE, () => {\n      stateVersion.value = store.$getStateVersion();\n    });\n    store.$subscribe(UPDATE_SCROLL_EVENT, () => {\n      emit(\"scroll\", store.$getScrollOffset());\n    });\n    store.$subscribe(UPDATE_SCROLL_END_EVENT, () => {\n      emit(\"scrollEnd\");\n    });\n\n    const range = computed<ItemsRange>((prev) => {\n      stateVersion.value;\n      const next = store.$getRange(props.bufferSize);\n      if (prev && isSameRange(prev, next)) {\n        return prev;\n      }\n      return next;\n    });\n    const isScrolling = computed(\n      () => stateVersion.value && store.$isScrolling(),\n    );\n    const totalSize = computed(\n      () => stateVersion.value && store.$getTotalSize(),\n    );\n\n    onMounted(() => {\n      isSSR = false;\n\n      // https://github.com/inokawa/virtua/issues/784\n      const container = containerRef.value!;\n      const raf = requestAnimationFrame(() => {\n        const assignScrollableElement = (e: HTMLElement) => {\n          resizer.$observeRoot(e);\n          scroller.$observe(container, e);\n        };\n        if (props.scrollRef) {\n          // parent's ref doesn't exist when onMounted is called\n          assignScrollableElement(props.scrollRef!);\n        } else {\n          assignScrollableElement(container.parentElement!);\n        }\n      });\n\n      onUnmounted(() => {\n        cancelAnimationFrame(raf);\n      });\n    });\n    onUnmounted(() => {\n      store.$dispose();\n      resizer.$dispose();\n      scroller.$dispose();\n    });\n\n    watch(\n      () => props.data.length,\n      (count) => {\n        store.$update(ACTION_ITEMS_LENGTH_CHANGE, [count, props.shift]);\n      },\n    );\n    watch(\n      () => props.startMargin,\n      (value) => {\n        store.$update(ACTION_START_OFFSET_CHANGE, value);\n      },\n      { immediate: true },\n    );\n\n    watch(\n      [stateVersion],\n      () => {\n        scroller.$fixScrollJump();\n      },\n      { flush: \"post\" },\n    );\n\n    expose({\n      get cache() {\n        return store.$getCacheSnapshot();\n      },\n      get scrollOffset() {\n        return store.$getScrollOffset();\n      },\n      get scrollSize() {\n        return getScrollSize(store);\n      },\n      get viewportSize() {\n        return store.$getViewportSize();\n      },\n      findItemIndex: store.$findItemIndex,\n      getItemOffset: store.$getItemOffset,\n      getItemSize: store.$getItemSize,\n      scrollToIndex: scroller.$scrollToIndex,\n      scrollTo: scroller.$scrollTo,\n      scrollBy: scroller.$scrollBy,\n    } satisfies VirtualizerHandle);\n\n    return () => {\n      const Element = props.as;\n      const ItemElement = props.item;\n\n      const total = totalSize.value;\n      const isNegative = scroller.$isNegative();\n\n      const items: VNode[] = [];\n\n      const renderItem = (i: number) => {\n        const e = slots[\"default\"]!({ item: props.data![i]!, index: i });\n        return (\n          <ListItem\n            key={getKey(e, i)}\n            _stateVersion={stateVersion}\n            _store={store}\n            _resizer={resizer.$observeItem}\n            _index={i}\n            _children={e}\n            _isHorizontal={isHorizontal}\n            _isNegative={isNegative}\n            _isSSR={isSSR}\n            _as={ItemElement}\n            _itemProps={props.itemProps?.({ item: props.data![i]!, index: i })}\n          />\n        );\n      };\n\n      if (props.keepMounted) {\n        const mounted = new Set(props.keepMounted);\n        for (let [i, j] = range.value; i <= j; i++) {\n          mounted.add(i);\n        }\n        sort([...mounted]).forEach((index) => {\n          items.push(renderItem(index));\n        });\n      } else {\n        for (let [i, j] = range.value; i <= j; i++) {\n          items.push(renderItem(i));\n        }\n      }\n\n      return (\n        <Element\n          ref={containerRef}\n          style={{\n            contain: \"size style\", // https://github.com/inokawa/virtua/pull/775 https://github.com/inokawa/virtua/issues/800\n            overflowAnchor: \"none\", // opt out browser's scroll anchoring because it will conflict to scroll anchoring of virtualizer\n            flex: \"none\", // flex style can break layout\n            position: \"relative\",\n            width: isHorizontal ? total + \"px\" : \"100%\",\n            height: isHorizontal ? \"100%\" : total + \"px\",\n            pointerEvents: isScrolling.value ? \"none\" : undefined,\n          }}\n        >\n          {items}\n        </Element>\n      );\n    };\n  },\n}) as unknown as {\n  new <T = unknown>(props: VirtualizerProps<T>): VirtualizerInstance<T>;\n};\n","/** @jsxImportSource vue */\nimport {\n  defineComponent,\n  ref,\n  type VNode,\n  type PropType,\n  type PublicProps,\n} from \"vue\";\nimport {\n  Virtualizer,\n  VirtualizerProps,\n  type VirtualizerHandle,\n} from \"./Virtualizer.js\";\n\n/**\n * Methods of {@link VList}.\n */\nexport interface VListHandle extends VirtualizerHandle {}\n\n/**\n * Props of {@link VList}.\n */\nexport interface VListProps<T = unknown>\n  extends\n    PublicProps,\n    Pick<\n      VirtualizerProps<T>,\n      | \"data\"\n      | \"bufferSize\"\n      | \"itemSize\"\n      | \"shift\"\n      | \"horizontal\"\n      | \"cache\"\n      | \"ssrCount\"\n      | \"itemProps\"\n      | \"onScroll\"\n      | \"onScrollEnd\"\n      | \"keepMounted\"\n    > {}\n\ninterface VListInstance<T = unknown> extends VListHandle {\n  $props: VListProps<T>;\n  $slots: { default: (arg: { item: T; index: number }) => VNode[] };\n}\n\n/**\n * Virtualized list component. See {@link VListProps} and {@link VListHandle}.\n */\nexport const VList = /*#__PURE__*/ defineComponent({\n  props: {\n    data: { type: Array, required: true },\n    bufferSize: Number,\n    itemSize: Number,\n    shift: Boolean,\n    horizontal: Boolean,\n    ssrCount: Number,\n    itemProps: Function as PropType<VListProps[\"itemProps\"]>,\n    keepMounted: Array as PropType<VListProps[\"keepMounted\"]>,\n    cache: Object as PropType<VListProps[\"cache\"]>,\n  },\n  emits: [\"scroll\", \"scrollEnd\"],\n  setup(props, { emit, expose, slots }) {\n    const horizontal = props.horizontal;\n\n    const onScroll = (offset: number) => {\n      emit(\"scroll\", offset);\n    };\n    const onScrollEnd = () => {\n      emit(\"scrollEnd\");\n    };\n\n    const handle = ref<InstanceType<typeof Virtualizer>>();\n\n    expose({\n      get cache() {\n        return handle.value!.cache;\n      },\n      get scrollOffset() {\n        return handle.value!.scrollOffset;\n      },\n      get scrollSize() {\n        return handle.value!.scrollSize;\n      },\n      get viewportSize() {\n        return handle.value!.viewportSize;\n      },\n      findItemIndex: (...args) => handle.value!.findItemIndex(...args),\n      getItemOffset: (...args) => handle.value!.getItemOffset(...args),\n      getItemSize: (...args) => handle.value!.getItemSize(...args),\n      scrollToIndex: (...args) => handle.value!.scrollToIndex(...args),\n      scrollTo: (...args) => handle.value!.scrollTo(...args),\n      scrollBy: (...args) => handle.value!.scrollBy(...args),\n    } satisfies VListHandle);\n\n    return () => {\n      return (\n        <div\n          style={{\n            display: horizontal ? \"inline-block\" : \"block\",\n            [horizontal ? \"overflowX\" : \"overflowY\"]: \"auto\",\n            contain: \"strict\",\n            width: \"100%\",\n            height: \"100%\",\n          }}\n        >\n          <Virtualizer\n            ref={handle}\n            data={props.data}\n            bufferSize={props.bufferSize}\n            itemSize={props.itemSize}\n            itemProps={props.itemProps}\n            shift={props.shift}\n            ssrCount={props.ssrCount}\n            horizontal={horizontal}\n            keepMounted={props.keepMounted}\n            cache={props.cache}\n            onScroll={onScroll}\n            onScrollEnd={onScrollEnd}\n          >\n            {slots}\n          </Virtualizer>\n        </div>\n      );\n    };\n  },\n}) as unknown as {\n  new <T = unknown>(props: VListProps<T>): VListInstance<T>;\n};\n","/** @jsxImportSource vue */\nimport {\n  ref,\n  onMounted,\n  defineComponent,\n  onUnmounted,\n  type VNode,\n  watch,\n  type PropType,\n  type NativeElements,\n  computed,\n  type PublicProps,\n} from \"vue\";\nimport {\n  UPDATE_SCROLL_END_EVENT,\n  UPDATE_VIRTUAL_STATE,\n  createVirtualStore,\n  ACTION_ITEMS_LENGTH_CHANGE,\n  UPDATE_SCROLL_EVENT,\n  createWindowResizer,\n  createWindowScroller,\n  type ItemsRange,\n  type ScrollToIndexOpts,\n  type CacheSnapshot,\n} from \"../core/index.js\";\nimport { ListItem } from \"./ListItem.js\";\nimport { getKey, isSameRange } from \"./utils.js\";\n\n/**\n * Props of {@link WindowVirtualizer}.\n */\nexport interface WindowVirtualizerProps<T = unknown> extends PublicProps {\n  /**\n   * The data items rendered by this component.\n   */\n  data: T[];\n  /**\n   * Extra item space in pixels to render before/after the viewport. The minimum value is 0. Lower value will give better performance but you can increase to avoid showing blank items in fast scrolling.\n   * @defaultValue 200\n   */\n  bufferSize?: number;\n  /**\n   * Item size hint for unmeasured items in pixels. It will help to reduce scroll jump when items are measured if used properly.\n   *\n   * - If not set, initial item sizes will be automatically estimated from measured sizes. This is recommended for most cases.\n   * - If set, you can opt out estimation and use the value as initial item size.\n   */\n  itemSize?: number;\n  /**\n   * While true is set, scroll position will be maintained from the end not usual start when items are added to/removed from start. It's recommended to set false if you add to/remove from mid/end of the list because it can cause unexpected behavior. This prop is useful for reverse infinite scrolling.\n   */\n  shift?: boolean;\n  /**\n   * If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list.\n   */\n  horizontal?: boolean;\n  /**\n   * Component or element type for container element.\n   * @defaultValue \"div\"\n   */\n  as?: keyof NativeElements;\n  /**\n   * Component or element type for item element.\n   * @defaultValue \"div\"\n   */\n  item?: keyof NativeElements;\n  /**\n   * You can restore cache by passing a {@link CacheSnapshot} on mount. This is useful when you want to restore scroll position after navigation. The snapshot can be obtained from {@link WindowVirtualizerHandle.cache}.\n   *\n   * **The length of items should be the same as when you take the snapshot, otherwise restoration may not work as expected.**\n   */\n  cache?: CacheSnapshot;\n  /**\n   * Callback invoked whenever scroll offset changes.\n   */\n  onScroll?: () => void;\n  /**\n   * Callback invoked when scrolling stops.\n   */\n  onScrollEnd?: () => void;\n}\n\ninterface WindowVirtualizerInstance<\n  T = unknown,\n> extends WindowVirtualizerHandle {\n  $props: WindowVirtualizerProps<T>;\n  $slots: { default: (arg: { item: T; index: number }) => VNode[] };\n}\n\n/**\n * Methods of {@link WindowVirtualizer}.\n */\nexport interface WindowVirtualizerHandle {\n  /**\n   * Get current {@link CacheSnapshot}.\n   */\n  readonly cache: CacheSnapshot;\n  /**\n   * Get current scrollTop, or scrollLeft if horizontal: true.\n   */\n  readonly scrollOffset: number;\n  /**\n   * Get current offsetHeight, or offsetWidth if horizontal: true.\n   */\n  readonly viewportSize: number;\n  /**\n   * Find nearest item index from offset.\n   * @param offset offset in pixels from the start of the scroll container\n   */\n  findItemIndex(offset: number): number;\n  /**\n   * Get item offset from start.\n   * @param index index of item\n   */\n  getItemOffset(index: number): number;\n  /**\n   * Get item size.\n   * @param index index of item\n   */\n  getItemSize(index: number): number;\n  /**\n   * Scroll to the item specified by index.\n   * @param index index of item\n   * @param opts options\n   */\n  scrollToIndex(index: number, opts?: ScrollToIndexOpts): void;\n}\n\n/**\n * {@link Virtualizer} controlled by the window scrolling. See {@link WindowVirtualizerProps} and {@link WindowVirtualizerHandle}.\n */\nexport const WindowVirtualizer = /*#__PURE__*/ defineComponent({\n  props: {\n    data: { type: Array, required: true },\n    bufferSize: Number,\n    itemSize: Number,\n    shift: Boolean,\n    horizontal: Boolean,\n    as: {\n      type: String as PropType<WindowVirtualizerProps[\"as\"]>,\n      default: \"div\",\n    },\n    item: {\n      type: String as PropType<WindowVirtualizerProps[\"item\"]>,\n      default: \"div\",\n    },\n    cache: Object as PropType<WindowVirtualizerProps[\"cache\"]>,\n  },\n  emits: [\"scroll\", \"scrollEnd\"],\n  setup(props, { emit, slots, expose }) {\n    const isHorizontal = props.horizontal;\n    const containerRef = ref<HTMLDivElement>();\n    const store = createVirtualStore(\n      props.data.length,\n      props.itemSize,\n      undefined,\n      props.cache,\n      !props.itemSize,\n    );\n    const resizer = createWindowResizer(store, isHorizontal);\n    const scroller = createWindowScroller(store, isHorizontal);\n\n    const stateVersion = ref(store.$getStateVersion());\n    store.$subscribe(UPDATE_VIRTUAL_STATE, () => {\n      stateVersion.value = store.$getStateVersion();\n    });\n    store.$subscribe(UPDATE_SCROLL_EVENT, () => {\n      // https://github.com/inokawa/virtua/discussions/580\n      emit(\"scroll\");\n    });\n    store.$subscribe(UPDATE_SCROLL_END_EVENT, () => {\n      emit(\"scrollEnd\");\n    });\n\n    const range = computed<ItemsRange>((prev) => {\n      stateVersion.value;\n      const next = store.$getRange(props.bufferSize);\n      if (prev && isSameRange(prev, next)) {\n        return prev;\n      }\n      return next;\n    });\n    const isScrolling = computed(\n      () => stateVersion.value && store.$isScrolling(),\n    );\n    const totalSize = computed(\n      () => stateVersion.value && store.$getTotalSize(),\n    );\n\n    onMounted(() => {\n      const el = containerRef.value;\n      if (!el) return;\n      resizer.$observeRoot(el);\n      scroller.$observe(el);\n    });\n    onUnmounted(() => {\n      store.$dispose();\n      resizer.$dispose();\n      scroller.$dispose();\n    });\n\n    watch(\n      () => props.data.length,\n      (count) => {\n        store.$update(ACTION_ITEMS_LENGTH_CHANGE, [count, props.shift]);\n      },\n    );\n\n    watch(\n      [stateVersion],\n      () => {\n        scroller.$fixScrollJump();\n      },\n      { flush: \"post\" },\n    );\n\n    expose({\n      get cache() {\n        return store.$getCacheSnapshot();\n      },\n      get scrollOffset() {\n        return store.$getScrollOffset();\n      },\n      get viewportSize() {\n        return store.$getViewportSize();\n      },\n      findItemIndex: store.$findItemIndex,\n      getItemOffset: store.$getItemOffset,\n      getItemSize: store.$getItemSize,\n      scrollToIndex: scroller.$scrollToIndex,\n    } satisfies WindowVirtualizerHandle);\n\n    return () => {\n      const Element = props.as;\n      const ItemElement = props.item;\n\n      const total = totalSize.value;\n      const isNegative = scroller.$isNegative();\n\n      const items: VNode[] = [];\n      for (let [i, j] = range.value; i <= j; i++) {\n        const e = slots[\"default\"]!({ item: props.data![i]!, index: i });\n        items.push(\n          <ListItem\n            key={getKey(e, i)}\n            _stateVersion={stateVersion}\n            _store={store}\n            _resizer={resizer.$observeItem}\n            _index={i}\n            _children={e}\n            _isHorizontal={isHorizontal}\n            _isNegative={isNegative}\n            _as={ItemElement}\n          />,\n        );\n      }\n\n      return (\n        <Element\n          ref={containerRef}\n          style={{\n            contain: \"size style\", // https://github.com/inokawa/virtua/pull/775 https://github.com/inokawa/virtua/issues/800\n            overflowAnchor: \"none\", // opt out browser's scroll anchoring because it will conflict to scroll anchoring of virtualizer\n            flex: \"none\", // flex style can break layout\n            position: \"relative\",\n            width: isHorizontal ? total + \"px\" : \"100%\",\n            height: isHorizontal ? \"100%\" : total + \"px\",\n            pointerEvents: isScrolling.value ? \"none\" : undefined,\n          }}\n        >\n          {items}\n        </Element>\n      );\n    };\n  },\n}) as unknown as {\n  new <T = unknown>(\n    props: WindowVirtualizerProps<T>,\n  ): WindowVirtualizerInstance<T>;\n};\n"],"names":["NULL","min","max","abs","floor","Math","clamp","value","minValue","maxValue","sort","arr","a","b","microtask","queueMicrotask","fn","Promise","resolve","then","createPromise","res","once","cache","undefined","fill","array","length","prepend","key","i","getItemSize","index","size","_sizes","_defaultItemSize","setItemSize","isInitialMeasurement","_computedOffsetIndex","getItemOffset","_length","_offsets","top","findIndex","offset","low","high","found","mid","updateCacheLength","isShift","diff","splice","reduce","acc","removed","getDocumentElement","doc","documentElement","getCurrentDocument","node","ownerDocument","getCurrentWindow","defaultView","isIOSWebKit","test","navigator","userAgent","platform","maxTouchPoints","isSmoothScrollSupported","document","style","createVirtualStore","elementsCount","itemSize","ssrCount","cacheSnapshot","shouldAutoEstimateItemSize","isSSR","stateVersion","viewportSize","startSpacerSize","scrollOffset","jump","pendingJump","_flushedJump","_scrollDirection","_scrollMode","_frozenRange","_prevRange","_totalMeasuredSize","_isViewportMeasured","initCache","sizes","slice","subscribers","Set","getRelativeScrollOffset","getVisibleOffset","getRange","startOffset","endOffset","computeRange","prevStartIndex","end","start","getTotalSize","_getItemOffset","getItemOffset$1","fromEnd","_getItemSize","isSizeEqual","UNCACHED","applyJump","j","$dispose","clear","$getStateVersion","$getCacheSnapshot","takeCacheSnapshot","$getRange","bufferSize","startIndex","endIndex","$findItemIndex","$isUnmeasuredItem","$getItemOffset","$getItemSize","$getItemsLength","$getScrollOffset","$isScrolling","$getViewportSize","$getStartSpacerSize","$getTotalSize","_flushJump","$subscribe","target","cb","sub","add","delete","$update","type","payload","shouldFlushPendingJump","shouldSync","mutated","flushedJump","delta","distance","relativeOffset","updated","filter","shouldKeep","itemOffset","prevSize","estimateDefaultItemSize","measuredCountBeforeStart","measuredSizes","forEach","s","push","sorted","len","median","prevDefaultItemSize","UPDATE_VIRTUAL_STATE","timeout","setTimeout","normalizeScrollOffset","isNegative","createScrollObserver","store","viewport","isHorizontal","getScrollOffset","updateScrollOffset","getStartOffset","now","Date","lastScrollTime","wheeling","touching","justTouchEnded","stillMomentumScrolling","onScrollEnd","debounce","id","cancel","clearTimeout","debouncedFn","_cancel","onScroll","onWheel","e","ctrlKey","timeDelta","deltaX","deltaY","onTouchStart","onTouchEnd","addEventListener","passive","_dispose","removeEventListener","_fixScrollJump","shift","createScrollScheduler","initialized","scroll","cancelScroll","async","getTargetOffset","smooth","waitForMeasurement","promise","done","unsubscribe","createResizeObserver","ro","_observe","observe","_unobserve","unobserve","disconnect","ListItem","defineComponent","props","_stateVersion","Object","required","_store","_children","_resizer","Function","_index","Number","_isHorizontal","Boolean","_isSSR","_isNegative","_as","String","_itemProps","setup","elementRef","ref","computed","hide","watch","_","__","onCleanup","flush","children","Element","isHide","styleProp","rest","contain","position","visibility","display","_createVNode","_mergeProps","prototype","toString","call","_isVNode","default","getKey","isSameRange","prev","next","Virtualizer","data","Array","horizontal","startMargin","scrollRef","as","item","itemProps","keepMounted","emits","emit","expose","slots","containerRef","resizer","createResizer","viewportElement","sizeKey","mountedIndexes","WeakMap","resizeObserver","entries","resizes","contentRect","offsetParent","get","$observeRoot","$observeItem","el","set","scroller","createScroller","scrollObserver","scrollOffsetKey","overflowKey","scheduleScroll","scrollTo","behavior","$observe","getComputedStyle","direction","isMomentumScrolling","$isNegative","$scrollTo","$scrollBy","$scrollToIndex","align","$fixScrollJump","range","isScrolling","totalSize","onMounted","container","raf","requestAnimationFrame","assignScrollableElement","parentElement","onUnmounted","cancelAnimationFrame","count","immediate","scrollSize","getScrollSize","findItemIndex","scrollToIndex","scrollBy","ItemElement","total","items","renderItem","L","W","Y","D","X","U","K","G","Z","ee","mounted","overflowAnchor","flex","width","height","pointerEvents","VList","handle","args","WindowVirtualizer","createWindowResizer","windowSizeKey","cleanupOnWindowResize","window","onWindowResize","createWindowScroller","containerElement","scrollToKey","calcOffsetToViewport","offsetKey","offsetSum","innerWidth","offsetWidth","parent","body","html","getScrollbarSize","clientWidth","clientHeight"],"mappings":"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"}