{"version":3,"sources":["node_modules/@angular/cdk/fesm2022/data-source-5320b6fd.mjs","node_modules/@angular/cdk/fesm2022/recycle-view-repeater-strategy-c1712813.mjs","node_modules/@angular/cdk/fesm2022/scrolling-module-aa1faac1.mjs"],"sourcesContent":["import { ConnectableObservable } from 'rxjs';\nclass DataSource {}\n/** Checks whether an object is a data source. */\nfunction isDataSource(value) {\n // Check if the value is a DataSource by observing if it has a connect function. Cannot\n // be checked as an `instanceof DataSource` since people could create their own sources\n // that match the interface, but don't extend DataSource. We also can't use `isObservable`\n // here, because of some internal apps.\n return value && typeof value.connect === 'function' && !(value instanceof ConnectableObservable);\n}\nexport { DataSource as D, isDataSource as i };\n","import { isObservable, of } from 'rxjs';\nimport { D as DataSource } from './data-source-5320b6fd.mjs';\nimport { InjectionToken } from '@angular/core';\n\n/** DataSource wrapper for a native array. */\nclass ArrayDataSource extends DataSource {\n _data;\n constructor(_data) {\n super();\n this._data = _data;\n }\n connect() {\n return isObservable(this._data) ? this._data : of(this._data);\n }\n disconnect() {}\n}\n\n/** Indicates how a view was changed by a {@link _ViewRepeater}. */\nvar _ViewRepeaterOperation = /*#__PURE__*/function (_ViewRepeaterOperation) {\n /** The content of an existing view was replaced with another item. */\n _ViewRepeaterOperation[_ViewRepeaterOperation[\"REPLACED\"] = 0] = \"REPLACED\";\n /** A new view was created with `createEmbeddedView`. */\n _ViewRepeaterOperation[_ViewRepeaterOperation[\"INSERTED\"] = 1] = \"INSERTED\";\n /** The position of a view changed, but the content remains the same. */\n _ViewRepeaterOperation[_ViewRepeaterOperation[\"MOVED\"] = 2] = \"MOVED\";\n /** A view was detached from the view container. */\n _ViewRepeaterOperation[_ViewRepeaterOperation[\"REMOVED\"] = 3] = \"REMOVED\";\n return _ViewRepeaterOperation;\n}(_ViewRepeaterOperation || {});\n/**\n * Injection token for {@link _ViewRepeater}. This token is for use by Angular Material only.\n * @docs-private\n */\nconst _VIEW_REPEATER_STRATEGY = /*#__PURE__*/new InjectionToken('_ViewRepeater');\n\n/**\n * A repeater that caches views when they are removed from a\n * {@link ViewContainerRef}. When new items are inserted into the container,\n * the repeater will reuse one of the cached views instead of creating a new\n * embedded view. Recycling cached views reduces the quantity of expensive DOM\n * inserts.\n *\n * @template T The type for the embedded view's $implicit property.\n * @template R The type for the item in each IterableDiffer change record.\n * @template C The type for the context passed to each embedded view.\n */\nclass _RecycleViewRepeaterStrategy {\n /**\n * The size of the cache used to store unused views.\n * Setting the cache size to `0` will disable caching. Defaults to 20 views.\n */\n viewCacheSize = 20;\n /**\n * View cache that stores embedded view instances that have been previously stamped out,\n * but don't are not currently rendered. The view repeater will reuse these views rather than\n * creating brand new ones.\n *\n * TODO(michaeljamesparsons) Investigate whether using a linked list would improve performance.\n */\n _viewCache = [];\n /** Apply changes to the DOM. */\n applyChanges(changes, viewContainerRef, itemContextFactory, itemValueResolver, itemViewChanged) {\n // Rearrange the views to put them in the right location.\n changes.forEachOperation((record, adjustedPreviousIndex, currentIndex) => {\n let view;\n let operation;\n if (record.previousIndex == null) {\n // Item added.\n const viewArgsFactory = () => itemContextFactory(record, adjustedPreviousIndex, currentIndex);\n view = this._insertView(viewArgsFactory, currentIndex, viewContainerRef, itemValueResolver(record));\n operation = view ? _ViewRepeaterOperation.INSERTED : _ViewRepeaterOperation.REPLACED;\n } else if (currentIndex == null) {\n // Item removed.\n this._detachAndCacheView(adjustedPreviousIndex, viewContainerRef);\n operation = _ViewRepeaterOperation.REMOVED;\n } else {\n // Item moved.\n view = this._moveView(adjustedPreviousIndex, currentIndex, viewContainerRef, itemValueResolver(record));\n operation = _ViewRepeaterOperation.MOVED;\n }\n if (itemViewChanged) {\n itemViewChanged({\n context: view?.context,\n operation,\n record\n });\n }\n });\n }\n detach() {\n for (const view of this._viewCache) {\n view.destroy();\n }\n this._viewCache = [];\n }\n /**\n * Inserts a view for a new item, either from the cache or by creating a new\n * one. Returns `undefined` if the item was inserted into a cached view.\n */\n _insertView(viewArgsFactory, currentIndex, viewContainerRef, value) {\n const cachedView = this._insertViewFromCache(currentIndex, viewContainerRef);\n if (cachedView) {\n cachedView.context.$implicit = value;\n return undefined;\n }\n const viewArgs = viewArgsFactory();\n return viewContainerRef.createEmbeddedView(viewArgs.templateRef, viewArgs.context, viewArgs.index);\n }\n /** Detaches the view at the given index and inserts into the view cache. */\n _detachAndCacheView(index, viewContainerRef) {\n const detachedView = viewContainerRef.detach(index);\n this._maybeCacheView(detachedView, viewContainerRef);\n }\n /** Moves view at the previous index to the current index. */\n _moveView(adjustedPreviousIndex, currentIndex, viewContainerRef, value) {\n const view = viewContainerRef.get(adjustedPreviousIndex);\n viewContainerRef.move(view, currentIndex);\n view.context.$implicit = value;\n return view;\n }\n /**\n * Cache the given detached view. If the cache is full, the view will be\n * destroyed.\n */\n _maybeCacheView(view, viewContainerRef) {\n if (this._viewCache.length < this.viewCacheSize) {\n this._viewCache.push(view);\n } else {\n const index = viewContainerRef.indexOf(view);\n // The host component could remove views from the container outside of\n // the view repeater. It's unlikely this will occur, but just in case,\n // destroy the view on its own, otherwise destroy it through the\n // container to ensure that all the references are removed.\n if (index === -1) {\n view.destroy();\n } else {\n viewContainerRef.remove(index);\n }\n }\n }\n /** Inserts a recycled view from the cache at the given index. */\n _insertViewFromCache(index, viewContainerRef) {\n const cachedView = this._viewCache.pop();\n if (cachedView) {\n viewContainerRef.insert(cachedView, index);\n }\n return cachedView || null;\n }\n}\nexport { ArrayDataSource as A, _RecycleViewRepeaterStrategy as _, _ViewRepeaterOperation as a, _VIEW_REPEATER_STRATEGY as b };\n","import * as i0 from '@angular/core';\nimport { InjectionToken, forwardRef, Directive, Input, inject, NgZone, RendererFactory2, Injectable, ElementRef, Renderer2, ChangeDetectorRef, Injector, afterNextRender, booleanAttribute, Optional, Inject, Component, ViewEncapsulation, ChangeDetectionStrategy, Output, ViewChild, ViewContainerRef, TemplateRef, IterableDiffers, NgModule } from '@angular/core';\nimport { Subject, of, Observable, Subscription, animationFrameScheduler, asapScheduler, isObservable } from 'rxjs';\nimport { distinctUntilChanged, auditTime, filter, startWith, takeUntil, pairwise, switchMap, shareReplay } from 'rxjs/operators';\nimport { a as coerceNumberProperty, c as coerceElement } from './element-08c51fcd.mjs';\nimport { P as Platform } from './platform-610a08ae.mjs';\nimport { D as Directionality } from './directionality-0a678adc.mjs';\nimport { g as getRtlScrollAxisType, R as RtlScrollAxisType, s as supportsScrollBehavior } from './scrolling-61955dd1.mjs';\nimport { DOCUMENT } from '@angular/common';\nimport { b as _VIEW_REPEATER_STRATEGY, A as ArrayDataSource, _ as _RecycleViewRepeaterStrategy } from './recycle-view-repeater-strategy-c1712813.mjs';\nimport { i as isDataSource } from './data-source-5320b6fd.mjs';\nimport { B as BidiModule } from './bidi-module-56dd006c.mjs';\n\n/** The injection token used to specify the virtual scrolling strategy. */\nconst _c0 = [\"contentWrapper\"];\nconst _c1 = [\"*\"];\nconst VIRTUAL_SCROLL_STRATEGY = /*#__PURE__*/new InjectionToken('VIRTUAL_SCROLL_STRATEGY');\n\n/** Virtual scrolling strategy for lists with items of known fixed size. */\nclass FixedSizeVirtualScrollStrategy {\n _scrolledIndexChange = /*#__PURE__*/new Subject();\n /** @docs-private Implemented as part of VirtualScrollStrategy. */\n scrolledIndexChange = /*#__PURE__*/this._scrolledIndexChange.pipe(/*#__PURE__*/distinctUntilChanged());\n /** The attached viewport. */\n _viewport = null;\n /** The size of the items in the virtually scrolling list. */\n _itemSize;\n /** The minimum amount of buffer rendered beyond the viewport (in pixels). */\n _minBufferPx;\n /** The number of buffer items to render beyond the edge of the viewport (in pixels). */\n _maxBufferPx;\n /**\n * @param itemSize The size of the items in the virtually scrolling list.\n * @param minBufferPx The minimum amount of buffer (in pixels) before needing to render more\n * @param maxBufferPx The amount of buffer (in pixels) to render when rendering more.\n */\n constructor(itemSize, minBufferPx, maxBufferPx) {\n this._itemSize = itemSize;\n this._minBufferPx = minBufferPx;\n this._maxBufferPx = maxBufferPx;\n }\n /**\n * Attaches this scroll strategy to a viewport.\n * @param viewport The viewport to attach this strategy to.\n */\n attach(viewport) {\n this._viewport = viewport;\n this._updateTotalContentSize();\n this._updateRenderedRange();\n }\n /** Detaches this scroll strategy from the currently attached viewport. */\n detach() {\n this._scrolledIndexChange.complete();\n this._viewport = null;\n }\n /**\n * Update the item size and buffer size.\n * @param itemSize The size of the items in the virtually scrolling list.\n * @param minBufferPx The minimum amount of buffer (in pixels) before needing to render more\n * @param maxBufferPx The amount of buffer (in pixels) to render when rendering more.\n */\n updateItemAndBufferSize(itemSize, minBufferPx, maxBufferPx) {\n if (maxBufferPx < minBufferPx && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error('CDK virtual scroll: maxBufferPx must be greater than or equal to minBufferPx');\n }\n this._itemSize = itemSize;\n this._minBufferPx = minBufferPx;\n this._maxBufferPx = maxBufferPx;\n this._updateTotalContentSize();\n this._updateRenderedRange();\n }\n /** @docs-private Implemented as part of VirtualScrollStrategy. */\n onContentScrolled() {\n this._updateRenderedRange();\n }\n /** @docs-private Implemented as part of VirtualScrollStrategy. */\n onDataLengthChanged() {\n this._updateTotalContentSize();\n this._updateRenderedRange();\n }\n /** @docs-private Implemented as part of VirtualScrollStrategy. */\n onContentRendered() {\n /* no-op */\n }\n /** @docs-private Implemented as part of VirtualScrollStrategy. */\n onRenderedOffsetChanged() {\n /* no-op */\n }\n /**\n * Scroll to the offset for the given index.\n * @param index The index of the element to scroll to.\n * @param behavior The ScrollBehavior to use when scrolling.\n */\n scrollToIndex(index, behavior) {\n if (this._viewport) {\n this._viewport.scrollToOffset(index * this._itemSize, behavior);\n }\n }\n /** Update the viewport's total content size. */\n _updateTotalContentSize() {\n if (!this._viewport) {\n return;\n }\n this._viewport.setTotalContentSize(this._viewport.getDataLength() * this._itemSize);\n }\n /** Update the viewport's rendered range. */\n _updateRenderedRange() {\n if (!this._viewport) {\n return;\n }\n const renderedRange = this._viewport.getRenderedRange();\n const newRange = {\n start: renderedRange.start,\n end: renderedRange.end\n };\n const viewportSize = this._viewport.getViewportSize();\n const dataLength = this._viewport.getDataLength();\n let scrollOffset = this._viewport.measureScrollOffset();\n // Prevent NaN as result when dividing by zero.\n let firstVisibleIndex = this._itemSize > 0 ? scrollOffset / this._itemSize : 0;\n // If user scrolls to the bottom of the list and data changes to a smaller list\n if (newRange.end > dataLength) {\n // We have to recalculate the first visible index based on new data length and viewport size.\n const maxVisibleItems = Math.ceil(viewportSize / this._itemSize);\n const newVisibleIndex = Math.max(0, Math.min(firstVisibleIndex, dataLength - maxVisibleItems));\n // If first visible index changed we must update scroll offset to handle start/end buffers\n // Current range must also be adjusted to cover the new position (bottom of new list).\n if (firstVisibleIndex != newVisibleIndex) {\n firstVisibleIndex = newVisibleIndex;\n scrollOffset = newVisibleIndex * this._itemSize;\n newRange.start = Math.floor(firstVisibleIndex);\n }\n newRange.end = Math.max(0, Math.min(dataLength, newRange.start + maxVisibleItems));\n }\n const startBuffer = scrollOffset - newRange.start * this._itemSize;\n if (startBuffer < this._minBufferPx && newRange.start != 0) {\n const expandStart = Math.ceil((this._maxBufferPx - startBuffer) / this._itemSize);\n newRange.start = Math.max(0, newRange.start - expandStart);\n newRange.end = Math.min(dataLength, Math.ceil(firstVisibleIndex + (viewportSize + this._minBufferPx) / this._itemSize));\n } else {\n const endBuffer = newRange.end * this._itemSize - (scrollOffset + viewportSize);\n if (endBuffer < this._minBufferPx && newRange.end != dataLength) {\n const expandEnd = Math.ceil((this._maxBufferPx - endBuffer) / this._itemSize);\n if (expandEnd > 0) {\n newRange.end = Math.min(dataLength, newRange.end + expandEnd);\n newRange.start = Math.max(0, Math.floor(firstVisibleIndex - this._minBufferPx / this._itemSize));\n }\n }\n }\n this._viewport.setRenderedRange(newRange);\n this._viewport.setRenderedContentOffset(this._itemSize * newRange.start);\n this._scrolledIndexChange.next(Math.floor(firstVisibleIndex));\n }\n}\n/**\n * Provider factory for `FixedSizeVirtualScrollStrategy` that simply extracts the already created\n * `FixedSizeVirtualScrollStrategy` from the given directive.\n * @param fixedSizeDir The instance of `CdkFixedSizeVirtualScroll` to extract the\n * `FixedSizeVirtualScrollStrategy` from.\n */\nfunction _fixedSizeVirtualScrollStrategyFactory(fixedSizeDir) {\n return fixedSizeDir._scrollStrategy;\n}\n/** A virtual scroll strategy that supports fixed-size items. */\nlet CdkFixedSizeVirtualScroll = /*#__PURE__*/(() => {\n class CdkFixedSizeVirtualScroll {\n /** The size of the items in the list (in pixels). */\n get itemSize() {\n return this._itemSize;\n }\n set itemSize(value) {\n this._itemSize = coerceNumberProperty(value);\n }\n _itemSize = 20;\n /**\n * The minimum amount of buffer rendered beyond the viewport (in pixels).\n * If the amount of buffer dips below this number, more items will be rendered. Defaults to 100px.\n */\n get minBufferPx() {\n return this._minBufferPx;\n }\n set minBufferPx(value) {\n this._minBufferPx = coerceNumberProperty(value);\n }\n _minBufferPx = 100;\n /**\n * The number of pixels worth of buffer to render for when rendering new items. Defaults to 200px.\n */\n get maxBufferPx() {\n return this._maxBufferPx;\n }\n set maxBufferPx(value) {\n this._maxBufferPx = coerceNumberProperty(value);\n }\n _maxBufferPx = 200;\n /** The scroll strategy used by this directive. */\n _scrollStrategy = new FixedSizeVirtualScrollStrategy(this.itemSize, this.minBufferPx, this.maxBufferPx);\n ngOnChanges() {\n this._scrollStrategy.updateItemAndBufferSize(this.itemSize, this.minBufferPx, this.maxBufferPx);\n }\n static ɵfac = function CdkFixedSizeVirtualScroll_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || CdkFixedSizeVirtualScroll)();\n };\n static ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: CdkFixedSizeVirtualScroll,\n selectors: [[\"cdk-virtual-scroll-viewport\", \"itemSize\", \"\"]],\n inputs: {\n itemSize: \"itemSize\",\n minBufferPx: \"minBufferPx\",\n maxBufferPx: \"maxBufferPx\"\n },\n features: [i0.ɵɵProvidersFeature([{\n provide: VIRTUAL_SCROLL_STRATEGY,\n useFactory: _fixedSizeVirtualScrollStrategyFactory,\n deps: [forwardRef(() => CdkFixedSizeVirtualScroll)]\n }]), i0.ɵɵNgOnChangesFeature]\n });\n }\n return CdkFixedSizeVirtualScroll;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/** Time in ms to throttle the scrolling events by default. */\nconst DEFAULT_SCROLL_TIME = 20;\n/**\n * Service contained all registered Scrollable references and emits an event when any one of the\n * Scrollable references emit a scrolled event.\n */\nlet ScrollDispatcher = /*#__PURE__*/(() => {\n class ScrollDispatcher {\n _ngZone = inject(NgZone);\n _platform = inject(Platform);\n _renderer = inject(RendererFactory2).createRenderer(null, null);\n _cleanupGlobalListener;\n constructor() {}\n /** Subject for notifying that a registered scrollable reference element has been scrolled. */\n _scrolled = new Subject();\n /** Keeps track of the amount of subscriptions to `scrolled`. Used for cleaning up afterwards. */\n _scrolledCount = 0;\n /**\n * Map of all the scrollable references that are registered with the service and their\n * scroll event subscriptions.\n */\n scrollContainers = new Map();\n /**\n * Registers a scrollable instance with the service and listens for its scrolled events. When the\n * scrollable is scrolled, the service emits the event to its scrolled observable.\n * @param scrollable Scrollable instance to be registered.\n */\n register(scrollable) {\n if (!this.scrollContainers.has(scrollable)) {\n this.scrollContainers.set(scrollable, scrollable.elementScrolled().subscribe(() => this._scrolled.next(scrollable)));\n }\n }\n /**\n * De-registers a Scrollable reference and unsubscribes from its scroll event observable.\n * @param scrollable Scrollable instance to be deregistered.\n */\n deregister(scrollable) {\n const scrollableReference = this.scrollContainers.get(scrollable);\n if (scrollableReference) {\n scrollableReference.unsubscribe();\n this.scrollContainers.delete(scrollable);\n }\n }\n /**\n * Returns an observable that emits an event whenever any of the registered Scrollable\n * references (or window, document, or body) fire a scrolled event. Can provide a time in ms\n * to override the default \"throttle\" time.\n *\n * **Note:** in order to avoid hitting change detection for every scroll event,\n * all of the events emitted from this stream will be run outside the Angular zone.\n * If you need to update any data bindings as a result of a scroll event, you have\n * to run the callback using `NgZone.run`.\n */\n scrolled(auditTimeInMs = DEFAULT_SCROLL_TIME) {\n if (!this._platform.isBrowser) {\n return of();\n }\n return new Observable(observer => {\n if (!this._cleanupGlobalListener) {\n this._cleanupGlobalListener = this._ngZone.runOutsideAngular(() => this._renderer.listen('document', 'scroll', () => this._scrolled.next()));\n }\n // In the case of a 0ms delay, use an observable without auditTime\n // since it does add a perceptible delay in processing overhead.\n const subscription = auditTimeInMs > 0 ? this._scrolled.pipe(auditTime(auditTimeInMs)).subscribe(observer) : this._scrolled.subscribe(observer);\n this._scrolledCount++;\n return () => {\n subscription.unsubscribe();\n this._scrolledCount--;\n if (!this._scrolledCount) {\n this._cleanupGlobalListener?.();\n this._cleanupGlobalListener = undefined;\n }\n };\n });\n }\n ngOnDestroy() {\n this._cleanupGlobalListener?.();\n this._cleanupGlobalListener = undefined;\n this.scrollContainers.forEach((_, container) => this.deregister(container));\n this._scrolled.complete();\n }\n /**\n * Returns an observable that emits whenever any of the\n * scrollable ancestors of an element are scrolled.\n * @param elementOrElementRef Element whose ancestors to listen for.\n * @param auditTimeInMs Time to throttle the scroll events.\n */\n ancestorScrolled(elementOrElementRef, auditTimeInMs) {\n const ancestors = this.getAncestorScrollContainers(elementOrElementRef);\n return this.scrolled(auditTimeInMs).pipe(filter(target => !target || ancestors.indexOf(target) > -1));\n }\n /** Returns all registered Scrollables that contain the provided element. */\n getAncestorScrollContainers(elementOrElementRef) {\n const scrollingContainers = [];\n this.scrollContainers.forEach((_subscription, scrollable) => {\n if (this._scrollableContainsElement(scrollable, elementOrElementRef)) {\n scrollingContainers.push(scrollable);\n }\n });\n return scrollingContainers;\n }\n /** Returns true if the element is contained within the provided Scrollable. */\n _scrollableContainsElement(scrollable, elementOrElementRef) {\n let element = coerceElement(elementOrElementRef);\n let scrollableElement = scrollable.getElementRef().nativeElement;\n // Traverse through the element parents until we reach null, checking if any of the elements\n // are the scrollable's element.\n do {\n if (element == scrollableElement) {\n return true;\n }\n } while (element = element.parentElement);\n return false;\n }\n static ɵfac = function ScrollDispatcher_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || ScrollDispatcher)();\n };\n static ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: ScrollDispatcher,\n factory: ScrollDispatcher.ɵfac,\n providedIn: 'root'\n });\n }\n return ScrollDispatcher;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Sends an event when the directive's element is scrolled. Registers itself with the\n * ScrollDispatcher service to include itself as part of its collection of scrolling events that it\n * can be listened to through the service.\n */\nlet CdkScrollable = /*#__PURE__*/(() => {\n class CdkScrollable {\n elementRef = inject(ElementRef);\n scrollDispatcher = inject(ScrollDispatcher);\n ngZone = inject(NgZone);\n dir = inject(Directionality, {\n optional: true\n });\n _scrollElement = this.elementRef.nativeElement;\n _destroyed = new Subject();\n _renderer = inject(Renderer2);\n _cleanupScroll;\n _elementScrolled = new Subject();\n constructor() {}\n ngOnInit() {\n this._cleanupScroll = this.ngZone.runOutsideAngular(() => this._renderer.listen(this._scrollElement, 'scroll', event => this._elementScrolled.next(event)));\n this.scrollDispatcher.register(this);\n }\n ngOnDestroy() {\n this._cleanupScroll?.();\n this._elementScrolled.complete();\n this.scrollDispatcher.deregister(this);\n this._destroyed.next();\n this._destroyed.complete();\n }\n /** Returns observable that emits when a scroll event is fired on the host element. */\n elementScrolled() {\n return this._elementScrolled;\n }\n /** Gets the ElementRef for the viewport. */\n getElementRef() {\n return this.elementRef;\n }\n /**\n * Scrolls to the specified offsets. This is a normalized version of the browser's native scrollTo\n * method, since browsers are not consistent about what scrollLeft means in RTL. For this method\n * left and right always refer to the left and right side of the scrolling container irrespective\n * of the layout direction. start and end refer to left and right in an LTR context and vice-versa\n * in an RTL context.\n * @param options specified the offsets to scroll to.\n */\n scrollTo(options) {\n const el = this.elementRef.nativeElement;\n const isRtl = this.dir && this.dir.value == 'rtl';\n // Rewrite start & end offsets as right or left offsets.\n if (options.left == null) {\n options.left = isRtl ? options.end : options.start;\n }\n if (options.right == null) {\n options.right = isRtl ? options.start : options.end;\n }\n // Rewrite the bottom offset as a top offset.\n if (options.bottom != null) {\n options.top = el.scrollHeight - el.clientHeight - options.bottom;\n }\n // Rewrite the right offset as a left offset.\n if (isRtl && getRtlScrollAxisType() != RtlScrollAxisType.NORMAL) {\n if (options.left != null) {\n options.right = el.scrollWidth - el.clientWidth - options.left;\n }\n if (getRtlScrollAxisType() == RtlScrollAxisType.INVERTED) {\n options.left = options.right;\n } else if (getRtlScrollAxisType() == RtlScrollAxisType.NEGATED) {\n options.left = options.right ? -options.right : options.right;\n }\n } else {\n if (options.right != null) {\n options.left = el.scrollWidth - el.clientWidth - options.right;\n }\n }\n this._applyScrollToOptions(options);\n }\n _applyScrollToOptions(options) {\n const el = this.elementRef.nativeElement;\n if (supportsScrollBehavior()) {\n el.scrollTo(options);\n } else {\n if (options.top != null) {\n el.scrollTop = options.top;\n }\n if (options.left != null) {\n el.scrollLeft = options.left;\n }\n }\n }\n /**\n * Measures the scroll offset relative to the specified edge of the viewport. This method can be\n * used instead of directly checking scrollLeft or scrollTop, since browsers are not consistent\n * about what scrollLeft means in RTL. The values returned by this method are normalized such that\n * left and right always refer to the left and right side of the scrolling container irrespective\n * of the layout direction. start and end refer to left and right in an LTR context and vice-versa\n * in an RTL context.\n * @param from The edge to measure from.\n */\n measureScrollOffset(from) {\n const LEFT = 'left';\n const RIGHT = 'right';\n const el = this.elementRef.nativeElement;\n if (from == 'top') {\n return el.scrollTop;\n }\n if (from == 'bottom') {\n return el.scrollHeight - el.clientHeight - el.scrollTop;\n }\n // Rewrite start & end as left or right offsets.\n const isRtl = this.dir && this.dir.value == 'rtl';\n if (from == 'start') {\n from = isRtl ? RIGHT : LEFT;\n } else if (from == 'end') {\n from = isRtl ? LEFT : RIGHT;\n }\n if (isRtl && getRtlScrollAxisType() == RtlScrollAxisType.INVERTED) {\n // For INVERTED, scrollLeft is (scrollWidth - clientWidth) when scrolled all the way left and\n // 0 when scrolled all the way right.\n if (from == LEFT) {\n return el.scrollWidth - el.clientWidth - el.scrollLeft;\n } else {\n return el.scrollLeft;\n }\n } else if (isRtl && getRtlScrollAxisType() == RtlScrollAxisType.NEGATED) {\n // For NEGATED, scrollLeft is -(scrollWidth - clientWidth) when scrolled all the way left and\n // 0 when scrolled all the way right.\n if (from == LEFT) {\n return el.scrollLeft + el.scrollWidth - el.clientWidth;\n } else {\n return -el.scrollLeft;\n }\n } else {\n // For NORMAL, as well as non-RTL contexts, scrollLeft is 0 when scrolled all the way left and\n // (scrollWidth - clientWidth) when scrolled all the way right.\n if (from == LEFT) {\n return el.scrollLeft;\n } else {\n return el.scrollWidth - el.clientWidth - el.scrollLeft;\n }\n }\n }\n static ɵfac = function CdkScrollable_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || CdkScrollable)();\n };\n static ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: CdkScrollable,\n selectors: [[\"\", \"cdk-scrollable\", \"\"], [\"\", \"cdkScrollable\", \"\"]]\n });\n }\n return CdkScrollable;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/** Time in ms to throttle the resize events by default. */\nconst DEFAULT_RESIZE_TIME = 20;\n/**\n * Simple utility for getting the bounds of the browser viewport.\n * @docs-private\n */\nlet ViewportRuler = /*#__PURE__*/(() => {\n class ViewportRuler {\n _platform = inject(Platform);\n _listeners;\n /** Cached viewport dimensions. */\n _viewportSize;\n /** Stream of viewport change events. */\n _change = new Subject();\n /** Used to reference correct document/window */\n _document = inject(DOCUMENT, {\n optional: true\n });\n constructor() {\n const ngZone = inject(NgZone);\n const renderer = inject(RendererFactory2).createRenderer(null, null);\n ngZone.runOutsideAngular(() => {\n if (this._platform.isBrowser) {\n const changeListener = event => this._change.next(event);\n this._listeners = [renderer.listen('window', 'resize', changeListener), renderer.listen('window', 'orientationchange', changeListener)];\n }\n // Clear the cached position so that the viewport is re-measured next time it is required.\n // We don't need to keep track of the subscription, because it is completed on destroy.\n this.change().subscribe(() => this._viewportSize = null);\n });\n }\n ngOnDestroy() {\n this._listeners?.forEach(cleanup => cleanup());\n this._change.complete();\n }\n /** Returns the viewport's width and height. */\n getViewportSize() {\n if (!this._viewportSize) {\n this._updateViewportSize();\n }\n const output = {\n width: this._viewportSize.width,\n height: this._viewportSize.height\n };\n // If we're not on a browser, don't cache the size since it'll be mocked out anyway.\n if (!this._platform.isBrowser) {\n this._viewportSize = null;\n }\n return output;\n }\n /** Gets a DOMRect for the viewport's bounds. */\n getViewportRect() {\n // Use the document element's bounding rect rather than the window scroll properties\n // (e.g. pageYOffset, scrollY) due to in issue in Chrome and IE where window scroll\n // properties and client coordinates (boundingClientRect, clientX/Y, etc.) are in different\n // conceptual viewports. Under most circumstances these viewports are equivalent, but they\n // can disagree when the page is pinch-zoomed (on devices that support touch).\n // See https://bugs.chromium.org/p/chromium/issues/detail?id=489206#c4\n // We use the documentElement instead of the body because, by default (without a css reset)\n // browsers typically give the document body an 8px margin, which is not included in\n // getBoundingClientRect().\n const scrollPosition = this.getViewportScrollPosition();\n const {\n width,\n height\n } = this.getViewportSize();\n return {\n top: scrollPosition.top,\n left: scrollPosition.left,\n bottom: scrollPosition.top + height,\n right: scrollPosition.left + width,\n height,\n width\n };\n }\n /** Gets the (top, left) scroll position of the viewport. */\n getViewportScrollPosition() {\n // While we can get a reference to the fake document\n // during SSR, it doesn't have getBoundingClientRect.\n if (!this._platform.isBrowser) {\n return {\n top: 0,\n left: 0\n };\n }\n // The top-left-corner of the viewport is determined by the scroll position of the document\n // body, normally just (scrollLeft, scrollTop). However, Chrome and Firefox disagree about\n // whether `document.body` or `document.documentElement` is the scrolled element, so reading\n // `scrollTop` and `scrollLeft` is inconsistent. However, using the bounding rect of\n // `document.documentElement` works consistently, where the `top` and `left` values will\n // equal negative the scroll position.\n const document = this._document;\n const window = this._getWindow();\n const documentElement = document.documentElement;\n const documentRect = documentElement.getBoundingClientRect();\n const top = -documentRect.top || document.body.scrollTop || window.scrollY || documentElement.scrollTop || 0;\n const left = -documentRect.left || document.body.scrollLeft || window.scrollX || documentElement.scrollLeft || 0;\n return {\n top,\n left\n };\n }\n /**\n * Returns a stream that emits whenever the size of the viewport changes.\n * This stream emits outside of the Angular zone.\n * @param throttleTime Time in milliseconds to throttle the stream.\n */\n change(throttleTime = DEFAULT_RESIZE_TIME) {\n return throttleTime > 0 ? this._change.pipe(auditTime(throttleTime)) : this._change;\n }\n /** Use defaultView of injected document if available or fallback to global window reference */\n _getWindow() {\n return this._document.defaultView || window;\n }\n /** Updates the cached viewport size. */\n _updateViewportSize() {\n const window = this._getWindow();\n this._viewportSize = this._platform.isBrowser ? {\n width: window.innerWidth,\n height: window.innerHeight\n } : {\n width: 0,\n height: 0\n };\n }\n static ɵfac = function ViewportRuler_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || ViewportRuler)();\n };\n static ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: ViewportRuler,\n factory: ViewportRuler.ɵfac,\n providedIn: 'root'\n });\n }\n return ViewportRuler;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nconst VIRTUAL_SCROLLABLE = /*#__PURE__*/new InjectionToken('VIRTUAL_SCROLLABLE');\n/**\n * Extending the {@link CdkScrollable} to be used as scrolling container for virtual scrolling.\n */\nlet CdkVirtualScrollable = /*#__PURE__*/(() => {\n class CdkVirtualScrollable extends CdkScrollable {\n constructor() {\n super();\n }\n /**\n * Measure the viewport size for the provided orientation.\n *\n * @param orientation The orientation to measure the size from.\n */\n measureViewportSize(orientation) {\n const viewportEl = this.elementRef.nativeElement;\n return orientation === 'horizontal' ? viewportEl.clientWidth : viewportEl.clientHeight;\n }\n static ɵfac = function CdkVirtualScrollable_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || CdkVirtualScrollable)();\n };\n static ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: CdkVirtualScrollable,\n features: [i0.ɵɵInheritDefinitionFeature]\n });\n }\n return CdkVirtualScrollable;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/** Checks if the given ranges are equal. */\nfunction rangesEqual(r1, r2) {\n return r1.start == r2.start && r1.end == r2.end;\n}\n/**\n * Scheduler to be used for scroll events. Needs to fall back to\n * something that doesn't rely on requestAnimationFrame on environments\n * that don't support it (e.g. server-side rendering).\n */\nconst SCROLL_SCHEDULER = typeof requestAnimationFrame !== 'undefined' ? animationFrameScheduler : asapScheduler;\n/** A viewport that virtualizes its scrolling with the help of `CdkVirtualForOf`. */\nlet CdkVirtualScrollViewport = /*#__PURE__*/(() => {\n class CdkVirtualScrollViewport extends CdkVirtualScrollable {\n elementRef = inject(ElementRef);\n _changeDetectorRef = inject(ChangeDetectorRef);\n _scrollStrategy = inject(VIRTUAL_SCROLL_STRATEGY, {\n optional: true\n });\n scrollable = inject(VIRTUAL_SCROLLABLE, {\n optional: true\n });\n _platform = inject(Platform);\n /** Emits when the viewport is detached from a CdkVirtualForOf. */\n _detachedSubject = new Subject();\n /** Emits when the rendered range changes. */\n _renderedRangeSubject = new Subject();\n /** The direction the viewport scrolls. */\n get orientation() {\n return this._orientation;\n }\n set orientation(orientation) {\n if (this._orientation !== orientation) {\n this._orientation = orientation;\n this._calculateSpacerSize();\n }\n }\n _orientation = 'vertical';\n /**\n * Whether rendered items should persist in the DOM after scrolling out of view. By default, items\n * will be removed.\n */\n appendOnly = false;\n // Note: we don't use the typical EventEmitter here because we need to subscribe to the scroll\n // strategy lazily (i.e. only if the user is actually listening to the events). We do this because\n // depending on how the strategy calculates the scrolled index, it may come at a cost to\n // performance.\n /** Emits when the index of the first element visible in the viewport changes. */\n scrolledIndexChange = new Observable(observer => this._scrollStrategy.scrolledIndexChange.subscribe(index => Promise.resolve().then(() => this.ngZone.run(() => observer.next(index)))));\n /** The element that wraps the rendered content. */\n _contentWrapper;\n /** A stream that emits whenever the rendered range changes. */\n renderedRangeStream = this._renderedRangeSubject;\n /**\n * The total size of all content (in pixels), including content that is not currently rendered.\n */\n _totalContentSize = 0;\n /** A string representing the `style.width` property value to be used for the spacer element. */\n _totalContentWidth = '';\n /** A string representing the `style.height` property value to be used for the spacer element. */\n _totalContentHeight = '';\n /**\n * The CSS transform applied to the rendered subset of items so that they appear within the bounds\n * of the visible viewport.\n */\n _renderedContentTransform;\n /** The currently rendered range of indices. */\n _renderedRange = {\n start: 0,\n end: 0\n };\n /** The length of the data bound to this viewport (in number of items). */\n _dataLength = 0;\n /** The size of the viewport (in pixels). */\n _viewportSize = 0;\n /** the currently attached CdkVirtualScrollRepeater. */\n _forOf;\n /** The last rendered content offset that was set. */\n _renderedContentOffset = 0;\n /**\n * Whether the last rendered content offset was to the end of the content (and therefore needs to\n * be rewritten as an offset to the start of the content).\n */\n _renderedContentOffsetNeedsRewrite = false;\n /** Whether there is a pending change detection cycle. */\n _isChangeDetectionPending = false;\n /** A list of functions to run after the next change detection cycle. */\n _runAfterChangeDetection = [];\n /** Subscription to changes in the viewport size. */\n _viewportChanges = Subscription.EMPTY;\n _injector = inject(Injector);\n _isDestroyed = false;\n constructor() {\n super();\n const viewportRuler = inject(ViewportRuler);\n if (!this._scrollStrategy && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error('Error: cdk-virtual-scroll-viewport requires the \"itemSize\" property to be set.');\n }\n this._viewportChanges = viewportRuler.change().subscribe(() => {\n this.checkViewportSize();\n });\n if (!this.scrollable) {\n // No scrollable is provided, so the virtual-scroll-viewport needs to become a scrollable\n this.elementRef.nativeElement.classList.add('cdk-virtual-scrollable');\n this.scrollable = this;\n }\n }\n ngOnInit() {\n // Scrolling depends on the element dimensions which we can't get during SSR.\n if (!this._platform.isBrowser) {\n return;\n }\n if (this.scrollable === this) {\n super.ngOnInit();\n }\n // It's still too early to measure the viewport at this point. Deferring with a promise allows\n // the Viewport to be rendered with the correct size before we measure. We run this outside the\n // zone to avoid causing more change detection cycles. We handle the change detection loop\n // ourselves instead.\n this.ngZone.runOutsideAngular(() => Promise.resolve().then(() => {\n this._measureViewportSize();\n this._scrollStrategy.attach(this);\n this.scrollable.elementScrolled().pipe(\n // Start off with a fake scroll event so we properly detect our initial position.\n startWith(null),\n // Collect multiple events into one until the next animation frame. This way if\n // there are multiple scroll events in the same frame we only need to recheck\n // our layout once.\n auditTime(0, SCROLL_SCHEDULER),\n // Usually `elementScrolled` is completed when the scrollable is destroyed, but\n // that may not be the case if a `CdkVirtualScrollableElement` is used so we have\n // to unsubscribe here just in case.\n takeUntil(this._destroyed)).subscribe(() => this._scrollStrategy.onContentScrolled());\n this._markChangeDetectionNeeded();\n }));\n }\n ngOnDestroy() {\n this.detach();\n this._scrollStrategy.detach();\n // Complete all subjects\n this._renderedRangeSubject.complete();\n this._detachedSubject.complete();\n this._viewportChanges.unsubscribe();\n this._isDestroyed = true;\n super.ngOnDestroy();\n }\n /** Attaches a `CdkVirtualScrollRepeater` to this viewport. */\n attach(forOf) {\n if (this._forOf && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error('CdkVirtualScrollViewport is already attached.');\n }\n // Subscribe to the data stream of the CdkVirtualForOf to keep track of when the data length\n // changes. Run outside the zone to avoid triggering change detection, since we're managing the\n // change detection loop ourselves.\n this.ngZone.runOutsideAngular(() => {\n this._forOf = forOf;\n this._forOf.dataStream.pipe(takeUntil(this._detachedSubject)).subscribe(data => {\n const newLength = data.length;\n if (newLength !== this._dataLength) {\n this._dataLength = newLength;\n this._scrollStrategy.onDataLengthChanged();\n }\n this._doChangeDetection();\n });\n });\n }\n /** Detaches the current `CdkVirtualForOf`. */\n detach() {\n this._forOf = null;\n this._detachedSubject.next();\n }\n /** Gets the length of the data bound to this viewport (in number of items). */\n getDataLength() {\n return this._dataLength;\n }\n /** Gets the size of the viewport (in pixels). */\n getViewportSize() {\n return this._viewportSize;\n }\n // TODO(mmalerba): This is technically out of sync with what's really rendered until a render\n // cycle happens. I'm being careful to only call it after the render cycle is complete and before\n // setting it to something else, but its error prone and should probably be split into\n // `pendingRange` and `renderedRange`, the latter reflecting whats actually in the DOM.\n /** Get the current rendered range of items. */\n getRenderedRange() {\n return this._renderedRange;\n }\n measureBoundingClientRectWithScrollOffset(from) {\n return this.getElementRef().nativeElement.getBoundingClientRect()[from];\n }\n /**\n * Sets the total size of all content (in pixels), including content that is not currently\n * rendered.\n */\n setTotalContentSize(size) {\n if (this._totalContentSize !== size) {\n this._totalContentSize = size;\n this._calculateSpacerSize();\n this._markChangeDetectionNeeded();\n }\n }\n /** Sets the currently rendered range of indices. */\n setRenderedRange(range) {\n if (!rangesEqual(this._renderedRange, range)) {\n if (this.appendOnly) {\n range = {\n start: 0,\n end: Math.max(this._renderedRange.end, range.end)\n };\n }\n this._renderedRangeSubject.next(this._renderedRange = range);\n this._markChangeDetectionNeeded(() => this._scrollStrategy.onContentRendered());\n }\n }\n /**\n * Gets the offset from the start of the viewport to the start of the rendered data (in pixels).\n */\n getOffsetToRenderedContentStart() {\n return this._renderedContentOffsetNeedsRewrite ? null : this._renderedContentOffset;\n }\n /**\n * Sets the offset from the start of the viewport to either the start or end of the rendered data\n * (in pixels).\n */\n setRenderedContentOffset(offset, to = 'to-start') {\n // In appendOnly, we always start from the top\n offset = this.appendOnly && to === 'to-start' ? 0 : offset;\n // For a horizontal viewport in a right-to-left language we need to translate along the x-axis\n // in the negative direction.\n const isRtl = this.dir && this.dir.value == 'rtl';\n const isHorizontal = this.orientation == 'horizontal';\n const axis = isHorizontal ? 'X' : 'Y';\n const axisDirection = isHorizontal && isRtl ? -1 : 1;\n let transform = `translate${axis}(${Number(axisDirection * offset)}px)`;\n this._renderedContentOffset = offset;\n if (to === 'to-end') {\n transform += ` translate${axis}(-100%)`;\n // The viewport should rewrite this as a `to-start` offset on the next render cycle. Otherwise\n // elements will appear to expand in the wrong direction (e.g. `mat-expansion-panel` would\n // expand upward).\n this._renderedContentOffsetNeedsRewrite = true;\n }\n if (this._renderedContentTransform != transform) {\n // We know this value is safe because we parse `offset` with `Number()` before passing it\n // into the string.\n this._renderedContentTransform = transform;\n this._markChangeDetectionNeeded(() => {\n if (this._renderedContentOffsetNeedsRewrite) {\n this._renderedContentOffset -= this.measureRenderedContentSize();\n this._renderedContentOffsetNeedsRewrite = false;\n this.setRenderedContentOffset(this._renderedContentOffset);\n } else {\n this._scrollStrategy.onRenderedOffsetChanged();\n }\n });\n }\n }\n /**\n * Scrolls to the given offset from the start of the viewport. Please note that this is not always\n * the same as setting `scrollTop` or `scrollLeft`. In a horizontal viewport with right-to-left\n * direction, this would be the equivalent of setting a fictional `scrollRight` property.\n * @param offset The offset to scroll to.\n * @param behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.\n */\n scrollToOffset(offset, behavior = 'auto') {\n const options = {\n behavior\n };\n if (this.orientation === 'horizontal') {\n options.start = offset;\n } else {\n options.top = offset;\n }\n this.scrollable.scrollTo(options);\n }\n /**\n * Scrolls to the offset for the given index.\n * @param index The index of the element to scroll to.\n * @param behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.\n */\n scrollToIndex(index, behavior = 'auto') {\n this._scrollStrategy.scrollToIndex(index, behavior);\n }\n /**\n * Gets the current scroll offset from the start of the scrollable (in pixels).\n * @param from The edge to measure the offset from. Defaults to 'top' in vertical mode and 'start'\n * in horizontal mode.\n */\n measureScrollOffset(from) {\n // This is to break the call cycle\n let measureScrollOffset;\n if (this.scrollable == this) {\n measureScrollOffset = _from => super.measureScrollOffset(_from);\n } else {\n measureScrollOffset = _from => this.scrollable.measureScrollOffset(_from);\n }\n return Math.max(0, measureScrollOffset(from ?? (this.orientation === 'horizontal' ? 'start' : 'top')) - this.measureViewportOffset());\n }\n /**\n * Measures the offset of the viewport from the scrolling container\n * @param from The edge to measure from.\n */\n measureViewportOffset(from) {\n let fromRect;\n const LEFT = 'left';\n const RIGHT = 'right';\n const isRtl = this.dir?.value == 'rtl';\n if (from == 'start') {\n fromRect = isRtl ? RIGHT : LEFT;\n } else if (from == 'end') {\n fromRect = isRtl ? LEFT : RIGHT;\n } else if (from) {\n fromRect = from;\n } else {\n fromRect = this.orientation === 'horizontal' ? 'left' : 'top';\n }\n const scrollerClientRect = this.scrollable.measureBoundingClientRectWithScrollOffset(fromRect);\n const viewportClientRect = this.elementRef.nativeElement.getBoundingClientRect()[fromRect];\n return viewportClientRect - scrollerClientRect;\n }\n /** Measure the combined size of all of the rendered items. */\n measureRenderedContentSize() {\n const contentEl = this._contentWrapper.nativeElement;\n return this.orientation === 'horizontal' ? contentEl.offsetWidth : contentEl.offsetHeight;\n }\n /**\n * Measure the total combined size of the given range. Throws if the range includes items that are\n * not rendered.\n */\n measureRangeSize(range) {\n if (!this._forOf) {\n return 0;\n }\n return this._forOf.measureRangeSize(range, this.orientation);\n }\n /** Update the viewport dimensions and re-render. */\n checkViewportSize() {\n // TODO: Cleanup later when add logic for handling content resize\n this._measureViewportSize();\n this._scrollStrategy.onDataLengthChanged();\n }\n /** Measure the viewport size. */\n _measureViewportSize() {\n this._viewportSize = this.scrollable.measureViewportSize(this.orientation);\n }\n /** Queue up change detection to run. */\n _markChangeDetectionNeeded(runAfter) {\n if (runAfter) {\n this._runAfterChangeDetection.push(runAfter);\n }\n // Use a Promise to batch together calls to `_doChangeDetection`. This way if we set a bunch of\n // properties sequentially we only have to run `_doChangeDetection` once at the end.\n if (!this._isChangeDetectionPending) {\n this._isChangeDetectionPending = true;\n this.ngZone.runOutsideAngular(() => Promise.resolve().then(() => {\n this._doChangeDetection();\n }));\n }\n }\n /** Run change detection. */\n _doChangeDetection() {\n if (this._isDestroyed) {\n return;\n }\n this.ngZone.run(() => {\n // Apply changes to Angular bindings. Note: We must call `markForCheck` to run change detection\n // from the root, since the repeated items are content projected in. Calling `detectChanges`\n // instead does not properly check the projected content.\n this._changeDetectorRef.markForCheck();\n // Apply the content transform. The transform can't be set via an Angular binding because\n // bypassSecurityTrustStyle is banned in Google. However the value is safe, it's composed of\n // string literals, a variable that can only be 'X' or 'Y', and user input that is run through\n // the `Number` function first to coerce it to a numeric value.\n this._contentWrapper.nativeElement.style.transform = this._renderedContentTransform;\n afterNextRender(() => {\n this._isChangeDetectionPending = false;\n const runAfterChangeDetection = this._runAfterChangeDetection;\n this._runAfterChangeDetection = [];\n for (const fn of runAfterChangeDetection) {\n fn();\n }\n }, {\n injector: this._injector\n });\n });\n }\n /** Calculates the `style.width` and `style.height` for the spacer element. */\n _calculateSpacerSize() {\n this._totalContentHeight = this.orientation === 'horizontal' ? '' : `${this._totalContentSize}px`;\n this._totalContentWidth = this.orientation === 'horizontal' ? `${this._totalContentSize}px` : '';\n }\n static ɵfac = function CdkVirtualScrollViewport_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || CdkVirtualScrollViewport)();\n };\n static ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: CdkVirtualScrollViewport,\n selectors: [[\"cdk-virtual-scroll-viewport\"]],\n viewQuery: function CdkVirtualScrollViewport_Query(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵviewQuery(_c0, 7);\n }\n if (rf & 2) {\n let _t;\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx._contentWrapper = _t.first);\n }\n },\n hostAttrs: [1, \"cdk-virtual-scroll-viewport\"],\n hostVars: 4,\n hostBindings: function CdkVirtualScrollViewport_HostBindings(rf, ctx) {\n if (rf & 2) {\n i0.ɵɵclassProp(\"cdk-virtual-scroll-orientation-horizontal\", ctx.orientation === \"horizontal\")(\"cdk-virtual-scroll-orientation-vertical\", ctx.orientation !== \"horizontal\");\n }\n },\n inputs: {\n orientation: \"orientation\",\n appendOnly: [2, \"appendOnly\", \"appendOnly\", booleanAttribute]\n },\n outputs: {\n scrolledIndexChange: \"scrolledIndexChange\"\n },\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkScrollable,\n useFactory: (virtualScrollable, viewport) => virtualScrollable || viewport,\n deps: [[new Optional(), new Inject(VIRTUAL_SCROLLABLE)], CdkVirtualScrollViewport]\n }]), i0.ɵɵInheritDefinitionFeature],\n ngContentSelectors: _c1,\n decls: 4,\n vars: 4,\n consts: [[\"contentWrapper\", \"\"], [1, \"cdk-virtual-scroll-content-wrapper\"], [1, \"cdk-virtual-scroll-spacer\"]],\n template: function CdkVirtualScrollViewport_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵprojectionDef();\n i0.ɵɵelementStart(0, \"div\", 1, 0);\n i0.ɵɵprojection(2);\n i0.ɵɵelementEnd();\n i0.ɵɵelement(3, \"div\", 2);\n }\n if (rf & 2) {\n i0.ɵɵadvance(3);\n i0.ɵɵstyleProp(\"width\", ctx._totalContentWidth)(\"height\", ctx._totalContentHeight);\n }\n },\n styles: [\"cdk-virtual-scroll-viewport{display:block;position:relative;transform:translateZ(0)}.cdk-virtual-scrollable{overflow:auto;will-change:scroll-position;contain:strict}.cdk-virtual-scroll-content-wrapper{position:absolute;top:0;left:0;contain:content}[dir=rtl] .cdk-virtual-scroll-content-wrapper{right:0;left:auto}.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper{min-height:100%}.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>dl:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>ol:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>table:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>ul:not([cdkVirtualFor]){padding-left:0;padding-right:0;margin-left:0;margin-right:0;border-left-width:0;border-right-width:0;outline:none}.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{min-width:100%}.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>dl:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>ol:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>table:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>ul:not([cdkVirtualFor]){padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;border-top-width:0;border-bottom-width:0;outline:none}.cdk-virtual-scroll-spacer{height:1px;transform-origin:0 0;flex:0 0 auto}[dir=rtl] .cdk-virtual-scroll-spacer{transform-origin:100% 0}\"],\n encapsulation: 2,\n changeDetection: 0\n });\n }\n return CdkVirtualScrollViewport;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/** Helper to extract the offset of a DOM Node in a certain direction. */\nfunction getOffset(orientation, direction, node) {\n const el = node;\n if (!el.getBoundingClientRect) {\n return 0;\n }\n const rect = el.getBoundingClientRect();\n if (orientation === 'horizontal') {\n return direction === 'start' ? rect.left : rect.right;\n }\n return direction === 'start' ? rect.top : rect.bottom;\n}\n/**\n * A directive similar to `ngForOf` to be used for rendering data inside a virtual scrolling\n * container.\n */\nlet CdkVirtualForOf = /*#__PURE__*/(() => {\n class CdkVirtualForOf {\n _viewContainerRef = inject(ViewContainerRef);\n _template = inject(TemplateRef);\n _differs = inject(IterableDiffers);\n _viewRepeater = inject(_VIEW_REPEATER_STRATEGY);\n _viewport = inject(CdkVirtualScrollViewport, {\n skipSelf: true\n });\n /** Emits when the rendered view of the data changes. */\n viewChange = new Subject();\n /** Subject that emits when a new DataSource instance is given. */\n _dataSourceChanges = new Subject();\n /** The DataSource to display. */\n get cdkVirtualForOf() {\n return this._cdkVirtualForOf;\n }\n set cdkVirtualForOf(value) {\n this._cdkVirtualForOf = value;\n if (isDataSource(value)) {\n this._dataSourceChanges.next(value);\n } else {\n // If value is an an NgIterable, convert it to an array.\n this._dataSourceChanges.next(new ArrayDataSource(isObservable(value) ? value : Array.from(value || [])));\n }\n }\n _cdkVirtualForOf;\n /**\n * The `TrackByFunction` to use for tracking changes. The `TrackByFunction` takes the index and\n * the item and produces a value to be used as the item's identity when tracking changes.\n */\n get cdkVirtualForTrackBy() {\n return this._cdkVirtualForTrackBy;\n }\n set cdkVirtualForTrackBy(fn) {\n this._needsUpdate = true;\n this._cdkVirtualForTrackBy = fn ? (index, item) => fn(index + (this._renderedRange ? this._renderedRange.start : 0), item) : undefined;\n }\n _cdkVirtualForTrackBy;\n /** The template used to stamp out new elements. */\n set cdkVirtualForTemplate(value) {\n if (value) {\n this._needsUpdate = true;\n this._template = value;\n }\n }\n /**\n * The size of the cache used to store templates that are not being used for re-use later.\n * Setting the cache size to `0` will disable caching. Defaults to 20 templates.\n */\n get cdkVirtualForTemplateCacheSize() {\n return this._viewRepeater.viewCacheSize;\n }\n set cdkVirtualForTemplateCacheSize(size) {\n this._viewRepeater.viewCacheSize = coerceNumberProperty(size);\n }\n /** Emits whenever the data in the current DataSource changes. */\n dataStream = this._dataSourceChanges.pipe(\n // Start off with null `DataSource`.\n startWith(null),\n // Bundle up the previous and current data sources so we can work with both.\n pairwise(),\n // Use `_changeDataSource` to disconnect from the previous data source and connect to the\n // new one, passing back a stream of data changes which we run through `switchMap` to give\n // us a data stream that emits the latest data from whatever the current `DataSource` is.\n switchMap(([prev, cur]) => this._changeDataSource(prev, cur)),\n // Replay the last emitted data when someone subscribes.\n shareReplay(1));\n /** The differ used to calculate changes to the data. */\n _differ = null;\n /** The most recent data emitted from the DataSource. */\n _data;\n /** The currently rendered items. */\n _renderedItems;\n /** The currently rendered range of indices. */\n _renderedRange;\n /** Whether the rendered data should be updated during the next ngDoCheck cycle. */\n _needsUpdate = false;\n _destroyed = new Subject();\n constructor() {\n const ngZone = inject(NgZone);\n this.dataStream.subscribe(data => {\n this._data = data;\n this._onRenderedDataChange();\n });\n this._viewport.renderedRangeStream.pipe(takeUntil(this._destroyed)).subscribe(range => {\n this._renderedRange = range;\n if (this.viewChange.observers.length) {\n ngZone.run(() => this.viewChange.next(this._renderedRange));\n }\n this._onRenderedDataChange();\n });\n this._viewport.attach(this);\n }\n /**\n * Measures the combined size (width for horizontal orientation, height for vertical) of all items\n * in the specified range. Throws an error if the range includes items that are not currently\n * rendered.\n */\n measureRangeSize(range, orientation) {\n if (range.start >= range.end) {\n return 0;\n }\n if ((range.start < this._renderedRange.start || range.end > this._renderedRange.end) && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error(`Error: attempted to measure an item that isn't rendered.`);\n }\n // The index into the list of rendered views for the first item in the range.\n const renderedStartIndex = range.start - this._renderedRange.start;\n // The length of the range we're measuring.\n const rangeLen = range.end - range.start;\n // Loop over all the views, find the first and land node and compute the size by subtracting\n // the top of the first node from the bottom of the last one.\n let firstNode;\n let lastNode;\n // Find the first node by starting from the beginning and going forwards.\n for (let i = 0; i < rangeLen; i++) {\n const view = this._viewContainerRef.get(i + renderedStartIndex);\n if (view && view.rootNodes.length) {\n firstNode = lastNode = view.rootNodes[0];\n break;\n }\n }\n // Find the last node by starting from the end and going backwards.\n for (let i = rangeLen - 1; i > -1; i--) {\n const view = this._viewContainerRef.get(i + renderedStartIndex);\n if (view && view.rootNodes.length) {\n lastNode = view.rootNodes[view.rootNodes.length - 1];\n break;\n }\n }\n return firstNode && lastNode ? getOffset(orientation, 'end', lastNode) - getOffset(orientation, 'start', firstNode) : 0;\n }\n ngDoCheck() {\n if (this._differ && this._needsUpdate) {\n // TODO(mmalerba): We should differentiate needs update due to scrolling and a new portion of\n // this list being rendered (can use simpler algorithm) vs needs update due to data actually\n // changing (need to do this diff).\n const changes = this._differ.diff(this._renderedItems);\n if (!changes) {\n this._updateContext();\n } else {\n this._applyChanges(changes);\n }\n this._needsUpdate = false;\n }\n }\n ngOnDestroy() {\n this._viewport.detach();\n this._dataSourceChanges.next(undefined);\n this._dataSourceChanges.complete();\n this.viewChange.complete();\n this._destroyed.next();\n this._destroyed.complete();\n this._viewRepeater.detach();\n }\n /** React to scroll state changes in the viewport. */\n _onRenderedDataChange() {\n if (!this._renderedRange) {\n return;\n }\n this._renderedItems = this._data.slice(this._renderedRange.start, this._renderedRange.end);\n if (!this._differ) {\n // Use a wrapper function for the `trackBy` so any new values are\n // picked up automatically without having to recreate the differ.\n this._differ = this._differs.find(this._renderedItems).create((index, item) => {\n return this.cdkVirtualForTrackBy ? this.cdkVirtualForTrackBy(index, item) : item;\n });\n }\n this._needsUpdate = true;\n }\n /** Swap out one `DataSource` for another. */\n _changeDataSource(oldDs, newDs) {\n if (oldDs) {\n oldDs.disconnect(this);\n }\n this._needsUpdate = true;\n return newDs ? newDs.connect(this) : of();\n }\n /** Update the `CdkVirtualForOfContext` for all views. */\n _updateContext() {\n const count = this._data.length;\n let i = this._viewContainerRef.length;\n while (i--) {\n const view = this._viewContainerRef.get(i);\n view.context.index = this._renderedRange.start + i;\n view.context.count = count;\n this._updateComputedContextProperties(view.context);\n view.detectChanges();\n }\n }\n /** Apply changes to the DOM. */\n _applyChanges(changes) {\n this._viewRepeater.applyChanges(changes, this._viewContainerRef, (record, _adjustedPreviousIndex, currentIndex) => this._getEmbeddedViewArgs(record, currentIndex), record => record.item);\n // Update $implicit for any items that had an identity change.\n changes.forEachIdentityChange(record => {\n const view = this._viewContainerRef.get(record.currentIndex);\n view.context.$implicit = record.item;\n });\n // Update the context variables on all items.\n const count = this._data.length;\n let i = this._viewContainerRef.length;\n while (i--) {\n const view = this._viewContainerRef.get(i);\n view.context.index = this._renderedRange.start + i;\n view.context.count = count;\n this._updateComputedContextProperties(view.context);\n }\n }\n /** Update the computed properties on the `CdkVirtualForOfContext`. */\n _updateComputedContextProperties(context) {\n context.first = context.index === 0;\n context.last = context.index === context.count - 1;\n context.even = context.index % 2 === 0;\n context.odd = !context.even;\n }\n _getEmbeddedViewArgs(record, index) {\n // Note that it's important that we insert the item directly at the proper index,\n // rather than inserting it and the moving it in place, because if there's a directive\n // on the same node that injects the `ViewContainerRef`, Angular will insert another\n // comment node which can throw off the move when it's being repeated for all items.\n return {\n templateRef: this._template,\n context: {\n $implicit: record.item,\n // It's guaranteed that the iterable is not \"undefined\" or \"null\" because we only\n // generate views for elements if the \"cdkVirtualForOf\" iterable has elements.\n cdkVirtualForOf: this._cdkVirtualForOf,\n index: -1,\n count: -1,\n first: false,\n last: false,\n odd: false,\n even: false\n },\n index\n };\n }\n static ngTemplateContextGuard(directive, context) {\n return true;\n }\n static ɵfac = function CdkVirtualForOf_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || CdkVirtualForOf)();\n };\n static ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: CdkVirtualForOf,\n selectors: [[\"\", \"cdkVirtualFor\", \"\", \"cdkVirtualForOf\", \"\"]],\n inputs: {\n cdkVirtualForOf: \"cdkVirtualForOf\",\n cdkVirtualForTrackBy: \"cdkVirtualForTrackBy\",\n cdkVirtualForTemplate: \"cdkVirtualForTemplate\",\n cdkVirtualForTemplateCacheSize: \"cdkVirtualForTemplateCacheSize\"\n },\n features: [i0.ɵɵProvidersFeature([{\n provide: _VIEW_REPEATER_STRATEGY,\n useClass: _RecycleViewRepeaterStrategy\n }])]\n });\n }\n return CdkVirtualForOf;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Provides a virtual scrollable for the element it is attached to.\n */\nlet CdkVirtualScrollableElement = /*#__PURE__*/(() => {\n class CdkVirtualScrollableElement extends CdkVirtualScrollable {\n constructor() {\n super();\n }\n measureBoundingClientRectWithScrollOffset(from) {\n return this.getElementRef().nativeElement.getBoundingClientRect()[from] - this.measureScrollOffset(from);\n }\n static ɵfac = function CdkVirtualScrollableElement_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || CdkVirtualScrollableElement)();\n };\n static ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: CdkVirtualScrollableElement,\n selectors: [[\"\", \"cdkVirtualScrollingElement\", \"\"]],\n hostAttrs: [1, \"cdk-virtual-scrollable\"],\n features: [i0.ɵɵProvidersFeature([{\n provide: VIRTUAL_SCROLLABLE,\n useExisting: CdkVirtualScrollableElement\n }]), i0.ɵɵInheritDefinitionFeature]\n });\n }\n return CdkVirtualScrollableElement;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Provides as virtual scrollable for the global / window scrollbar.\n */\nlet CdkVirtualScrollableWindow = /*#__PURE__*/(() => {\n class CdkVirtualScrollableWindow extends CdkVirtualScrollable {\n constructor() {\n super();\n const document = inject(DOCUMENT);\n this.elementRef = new ElementRef(document.documentElement);\n this._scrollElement = document;\n }\n measureBoundingClientRectWithScrollOffset(from) {\n return this.getElementRef().nativeElement.getBoundingClientRect()[from];\n }\n static ɵfac = function CdkVirtualScrollableWindow_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || CdkVirtualScrollableWindow)();\n };\n static ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: CdkVirtualScrollableWindow,\n selectors: [[\"cdk-virtual-scroll-viewport\", \"scrollWindow\", \"\"]],\n features: [i0.ɵɵProvidersFeature([{\n provide: VIRTUAL_SCROLLABLE,\n useExisting: CdkVirtualScrollableWindow\n }]), i0.ɵɵInheritDefinitionFeature]\n });\n }\n return CdkVirtualScrollableWindow;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nlet CdkScrollableModule = /*#__PURE__*/(() => {\n class CdkScrollableModule {\n static ɵfac = function CdkScrollableModule_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || CdkScrollableModule)();\n };\n static ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: CdkScrollableModule\n });\n static ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({});\n }\n return CdkScrollableModule;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @docs-primary-export\n */\nlet ScrollingModule = /*#__PURE__*/(() => {\n class ScrollingModule {\n static ɵfac = function ScrollingModule_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || ScrollingModule)();\n };\n static ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: ScrollingModule\n });\n static ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n imports: [BidiModule, CdkScrollableModule, BidiModule, CdkScrollableModule]\n });\n }\n return ScrollingModule;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nexport { CdkScrollableModule as C, DEFAULT_SCROLL_TIME as D, FixedSizeVirtualScrollStrategy as F, ScrollDispatcher as S, ViewportRuler as V, _fixedSizeVirtualScrollStrategyFactory as _, ScrollingModule as a, CdkScrollable as b, CdkFixedSizeVirtualScroll as c, CdkVirtualForOf as d, CdkVirtualScrollViewport as e, CdkVirtualScrollableWindow as f, CdkVirtualScrollableElement as g, DEFAULT_RESIZE_TIME as h, VIRTUAL_SCROLL_STRATEGY as i, VIRTUAL_SCROLLABLE as j, CdkVirtualScrollable as k };\n"],"names":["isDataSource","value","ConnectableObservable","_ViewRepeaterOperation","_VIEW_REPEATER_STRATEGY","InjectionToken","_RecycleViewRepeaterStrategy","changes","viewContainerRef","itemContextFactory","itemValueResolver","itemViewChanged","record","adjustedPreviousIndex","currentIndex","view","operation","viewArgsFactory","value","cachedView","viewArgs","index","detachedView","DEFAULT_SCROLL_TIME","ScrollDispatcher","inject","NgZone","Platform","RendererFactory2","Subject","scrollable","scrollableReference","auditTimeInMs","Observable","observer","subscription","auditTime","of","_","container","elementOrElementRef","ancestors","filter","target","scrollingContainers","_subscription","element","coerceElement","scrollableElement","__ngFactoryType__","ɵɵdefineInjectable","DEFAULT_RESIZE_TIME","ViewportRuler","inject","Platform","Subject","DOCUMENT","ngZone","NgZone","renderer","RendererFactory2","changeListener","event","cleanup","output","scrollPosition","width","height","document","window","documentElement","documentRect","top","left","throttleTime","auditTime","__ngFactoryType__","ɵɵdefineInjectable","CdkScrollableModule","__ngFactoryType__","ɵɵdefineNgModule","ɵɵdefineInjector","ScrollingModule","BidiModule"],"mappings":"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","debug_id":"cfea4655-c3a3-5dab-9ddb-ca9e8d6ffe6a"}