{"version":3,"file":"mat-image-grid.mjs","sources":["../../../projects/mat-image-grid-lib/src/lib/classes/floating-average.class.ts","../../../projects/mat-image-grid-lib/src/lib/classes/loading-service.class.ts","../../../projects/mat-image-grid-lib/src/lib/classes/mig-data-source.class.ts","../../../projects/mat-image-grid-lib/src/lib/classes/progressive-image.class.ts","../../../projects/mat-image-grid-lib/src/lib/directives/mig-resizable-directive.ts","../../../projects/mat-image-grid-lib/src/lib/mat-image-grid.component.ts","../../../projects/mat-image-grid-lib/src/lib/mat-image-grid.component.html","../../../projects/mat-image-grid-lib/src/lib/classes/datastore-adapter.service.base.ts","../../../projects/mat-image-grid-lib/src/public-api.ts","../../../projects/mat-image-grid-lib/src/mat-image-grid.ts"],"sourcesContent":["/**\n * Calculate the floating average of the entries in a moving window.\n * The width of the window can be defined while creating an instance of this class.\n * All values to inspect are numbers.\n * @class FloatingAverage\n */\nexport class FloatingAverage {\n  private entries: number[] = [];\n  private widthOfWindow = 0;\n  private currentAverage: number;\n\n  /**\n   * Creates an instance of FloatingAverage.\n   * @param entriesInWindow - number of entries in window\n   * @param initialAverage - initial value for average (if no entries received)\n   */\n  constructor(entriesInWindow: number, initialAverage: number) {\n    this.widthOfWindow = entriesInWindow;\n    this.currentAverage = initialAverage;\n    this.entries.push(initialAverage);\n  }\n\n  /**\n   * Add new value to the window and remove oldest value if window\n   * has reached maximum number of values.\n   * @param value - new value to add\n   */\n  addEntry(value: number) {\n    this.entries.push(value);\n    if (this.entries.length > this.widthOfWindow) {\n      const droppedEntry = this.entries.shift() || 0;\n      this.currentAverage =\n        this.currentAverage + (value - droppedEntry) / this.widthOfWindow;\n    } else {\n      const newLength = this.entries.length;\n      this.currentAverage =\n        this.currentAverage * ((newLength - 1) / newLength) + value / newLength;\n    }\n  }\n\n  /**\n   * Get average of entries in window.\n   * @returns average of values in window\n   */\n  public get average(): number {\n    return this.currentAverage;\n  }\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\n@Injectable()\nexport class LoadingService {\n  private loadingSubject = new BehaviorSubject<boolean>(false);\n\n  // Observable that emits, when a loading indicator should be displayed / hidden\n  loading$ = this.loadingSubject as Observable<boolean>;\n\n  private openRequests = 0;\n\n  /**\n   * Change status of loading indicator when sending a request.\n   * Only when the first response is send, a new status is emitted.\n   */\n  startRequest() {\n    this.openRequests += 1;\n\n    // only send a new status on first request\n    if (this.openRequests === 1) {\n      this.loadingSubject.next(true);\n    }\n  }\n\n  /**\n   * Change status of loading indicator when receiving a response.\n   * Only when the last response arrived, a new status is emitted.\n   */\n  receivedResponse() {\n    this.openRequests -= 1;\n\n    // only send a new status on last response\n    if (this.openRequests === 0) {\n      this.loadingSubject.next(false);\n    }\n\n    // limit number of open requests to '0' as the minimum\n    this.openRequests = Math.max(this.openRequests, 0);\n  }\n}\n","import { CollectionViewer } from '@angular/cdk/collections';\nimport { BehaviorSubject, Observable, Subscription, first } from 'rxjs';\n\nimport { RequestImagesRange } from '../interfaces/datastore-adapter.interface';\nimport { MigImageData } from '../interfaces/mig-image-data.interface';\nimport { Page } from '../interfaces/page.interface';\n\nimport { DatastoreAdapterServiceBase } from './datastore-adapter.service.base';\n\n/**\n * Class to get a list of images data to display in a mat-image-grid.\n * This class converts the raw data received fom a datastore adapter to a format\n * required by mat-image-grid.\n */\nexport class MigDataSource<T extends MigImageData = MigImageData> {\n  private readonly emptyPage = {\n    content: [] as T[],\n    startImageIndex: 0,\n    returnedElements: 0,\n    totalElements: 0,\n    totalFilteredElements: 0,\n  } as Page<T>;\n\n  private datastore: DatastoreAdapterServiceBase<T>;\n\n  /** Stream emitting data to render. */\n  private readonly _data: BehaviorSubject<Page<T>>;\n  private collectionViewerSubscription!: Subscription;\n\n  /**\n   * @param datastore - datastore adapter for datastore to use\n   */\n  public constructor(datastore: DatastoreAdapterServiceBase<T>) {\n    this.datastore = datastore;\n    this._data = new BehaviorSubject<Page<T>>(this.emptyPage);\n  }\n\n  /**\n   * Connects a collection viewer (such as a mat-image-grid) to this data source.\n   * The viewChange observable of the CollectionViewer should return no images, when\n   * the 'end' property of the ListRange is less than 0.\n   * @param collectionViewer - The component that exposes a view over the data provided by this data source.\n   * @returns Observable that emits a new value when the data changes.\n   */\n  connect(collectionViewer: CollectionViewer): Observable<Page<T>> {\n    this.collectionViewerSubscription = collectionViewer.viewChange.subscribe(\n      (listRange) => {\n        // start is inclusive, end is exclusive\n        const numberOfRequestedImages = Math.max(\n          listRange.end - listRange.start,\n          0,\n        );\n\n        const requestedRange = {\n          startImageIndex: listRange.start,\n          numberOfImages: numberOfRequestedImages,\n        } as RequestImagesRange;\n\n        this.datastore\n          .getPagedData(requestedRange)\n          .pipe(first())\n          .subscribe((page: Page<T>) => {\n            return this._data.next(page);\n          });\n      },\n    );\n    return this._data.asObservable();\n  }\n\n  /**\n   * Disconnects a collection viewer (such as a mat-image-grid) from this data source.\n   * @param collectionViewer - The component that exposes a view over the data provided by this data source.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  disconnect(collectionViewer: CollectionViewer): void {\n    this.collectionViewerSubscription.unsubscribe();\n  }\n}\n","import { Renderer2 } from '@angular/core';\nimport { Subject } from 'rxjs';\n\nimport { UnloadHandler } from '../interfaces/mig-common.types';\nimport { MigImageClassNames } from '../interfaces/mig-image-class-names.interface';\nimport { MigImageConfiguration } from '../interfaces/mig-image-configuration.interface';\nimport { MigImageData } from '../interfaces/mig-image-data.interface';\nimport { MigImageStyle } from '../interfaces/mig-Image-style.interface';\nimport { imageElementBase } from '../interfaces/progressive-image.interface';\n\n/**\n * This class manages a single image. It keeps track of the image's height,\n * width, and position in the grid. An instance of this class is associated\n * with a single image figure, which looks like this:\n *\n *   <figure class=\"mat-image-grid-figure\" style=\"transform: ...\">\n *     <img class=\"mat-image-grid-thumbnail mat-image-grid-loaded\" src=\"/path/to/thumbnail/image.jpg\" />\n *     <img class=\"mat-image-grid-full-image mat-image-grid-loaded\" src=\"/path/to/500px/image.jpg\" />\n *   </figure>\n *\n * However, this element may or may not actually exist in the DOM. The actual\n * DOM element may loaded and unloaded depending on where it is with respect\n * to the viewport. This class is responsible for managing the DOM elements,\n * but does not include logic to determine _when_ the DOM elements should\n * be removed.\n *\n * This class also manages the blur-into-focus load effect.  First, the\n * <figure> element is inserted into the page. Then, a very small thumbnail\n * is loaded, stretched out to the full size of the image.  This pixelated\n * image is then blurred using CSS filter: blur(). Then, the full image is\n * loaded, with opacity:0.  Once it has loaded, it is given the\n * `mat-image-grid-loaded` class, and its opacity is set to 1.  This creates\n * an effect where there is first a blurred version of the image, and then it\n * appears to come into focus.\n */\nexport class ProgressiveImage<ServerData extends MigImageData> {\n  public aspectRatio: number;\n  public existsOnPage = false;\n  public style?: MigImageStyle;\n\n  private readonly onClickSubject = new Subject<ServerData>();\n  public onClick$ = this.onClickSubject.asObservable();\n\n  protected elements = new Map<string, imageElementBase>();\n\n  protected singleImageData: ServerData;\n  protected imageIndex: number;\n  protected classNames: MigImageClassNames;\n  protected createSubelementDelayInMs = 100;\n  protected renderer: Renderer2;\n\n  private configuration: MigImageConfiguration;\n  private readonly mainElementsKey = 'main';\n\n  /**\n   * Creates an instance of ProgressiveImage.\n   * @param renderer2 - Angular class to modify DOM.\n   * @param singleImageData - An array of metadata about each image.\n   * @param index - Index of image in data source.\n   * @param configuration - Object with the configuration data from the parent object.\n   */\n  constructor(\n    renderer2: Renderer2,\n    singleImageData: ServerData,\n    index: number,\n    configuration: MigImageConfiguration,\n  ) {\n    this.renderer = renderer2;\n    this.configuration = configuration;\n    this.singleImageData = singleImageData;\n    this.aspectRatio = singleImageData.aspectRatio;\n    this.imageIndex = index;\n\n    this.classNames = {\n      figure: 'mat-image-grid-figure',\n      fullImage: 'mat-image-grid-full-image',\n      thumbnail: 'mat-image-grid-thumbnail',\n      loaded: 'mat-image-grid-loaded',\n    } as MigImageClassNames;\n  }\n\n  /**\n   * Load the image element associated with this ProgressiveImage into the DOM.\n   * This function will append the figure tag into the DOM, create and insert the\n   * thumbnail, and create and insert the full image.\n   */\n  load() {\n    // Create a new image element, and insert it into the DOM.\n    // The order of the figure elements don't matter, because\n    // all positioning is done using css transforms.\n    const mainElement = this.getMainElement();\n    this.renderer.appendChild(\n      this.configuration.container.nativeElement,\n      mainElement,\n    );\n    this.existsOnPage = true;\n\n    // We run the rest of the function in a 100ms setTimeout so that if the\n    // user is scrolling down the page very fast and hide() is called within\n    // 100ms of load(), the hide() function will set this.existsOnPage to false\n    // and we can exit.\n    setTimeout(() => {\n      // The image was hidden very quickly after being loaded, so don't bother\n      // loading it at all.\n      if (!this.existsOnPage) {\n        return;\n      }\n\n      this.addAllSubElements();\n    }, this.createSubelementDelayInMs);\n  }\n\n  /**\n   * Removes the main element (<figure> tag) and all subelements (thumbnail and\n   * full image) from the DOM and this ProgressiveImage object.\n   */\n  hide() {\n    // Remove the sub elements from the main element, so that if a user is scrolling\n    // super fast, we won't try to load every image we scroll past.\n    const mainElement = this.elements.get(this.mainElementsKey);\n    if (mainElement) {\n      this.removeAllSubElements();\n\n      mainElement.eventUnloadHandlers.forEach((unloadHandler: UnloadHandler) =>\n        unloadHandler(),\n      );\n\n      this.renderer.removeChild(\n        this.configuration.container.nativeElement,\n        mainElement.element,\n      );\n\n      this.elements.delete(this.mainElementsKey);\n    }\n\n    this.existsOnPage = false;\n  }\n\n  /**\n   * Prepare class for disposing (e.g. complete all observables).\n   */\n  dispose() {\n    this.onClickSubject.complete();\n    if (this.existsOnPage) {\n      this.hide();\n    }\n  }\n\n  /**\n   * Event handler for the image clicked event (attached to the figure tag).\n   * The event handler emits a value to the onClickSubject.\n   */\n  imageClicked = () => {\n    this.onClickSubject.next(this.singleImageData);\n  };\n\n  /**\n   * Gets the Y position of the top of the image in the web page\n   * @returns Y position of the top of the image\n   */\n  get yTop(): number {\n    return this.style?.translateY ?? 0;\n  }\n\n  /**\n   * Gets the Y position of the bottom of the image in the web page\n   * @returns Y position of the bottom of the image\n   */\n  get yBottom(): number {\n    let bottom = 0;\n    const style = this.style;\n    if (style !== undefined) {\n      bottom = style.translateY + style.height;\n    }\n    return bottom;\n  }\n\n  /**\n   * Get the wrapper DOM element (<figure> tag) associated with this ProgressiveImage.\n   * We create it, if it doesn't exist. The DOM element is not added to the page.\n   * @returns The wrapper DOM element associated with this instance.\n   */\n  protected getMainElement(): HTMLElement {\n    let figureElement = this.elements.get(this.mainElementsKey)?.element;\n    if (figureElement) {\n      this.updateStyles(figureElement);\n    } else {\n      const element = this.renderer.createElement('figure') as HTMLElement;\n      this.renderer.addClass(element, this.classNames.figure);\n      this.updateStyles(element);\n      this.renderer.setAttribute(\n        element,\n        'data-image-index',\n        this.imageIndex.toString(),\n      );\n\n      const mainElement = {\n        element: element,\n        eventUnloadHandlers: [],\n      } as imageElementBase;\n\n      let figureClickUnloadHandler: UnloadHandler;\n      if (this.configuration.withClickEvent) {\n        figureClickUnloadHandler = this.renderer.listen(\n          element,\n          'click',\n          this.imageClicked,\n        );\n        mainElement.eventUnloadHandlers.push(figureClickUnloadHandler);\n      }\n\n      this.elements.set(this.mainElementsKey, mainElement);\n      figureElement = mainElement.element;\n    }\n\n    return figureElement;\n  }\n\n  /**\n   * Add an image as a subelement to the <figure> tag.\n   * @param mainElement - Main element of this image (<figure> tag)\n   * @param subElementName - Name of the subelement\n   * @param className - Name of the class to be added to the new subelement (default value='' - i.e. no class added)\n   * @param src - source string of image element (default value = '')\n   */\n  protected addImageAsSubElement(\n    mainElement: HTMLElement,\n    subElementName: string,\n    className = '',\n    src = '',\n  ) {\n    if (!this.elements.get(subElementName)) {\n      const element = this.renderer.createElement('img') as HTMLImageElement;\n      this.renderer.setAttribute(element, 'src', src);\n\n      if (className.length > 0) {\n        this.renderer.addClass(element, className);\n      }\n\n      const onloadHandlerUnload = this.renderer.listen(element, 'load', () => {\n        // We have to make sure thumbnail still exists, it may already have been\n        // deallocated if the user scrolls too fast.\n        if (this.elements.get(subElementName)) {\n          this.renderer.addClass(element, 'mat-image-grid-loaded');\n        }\n      });\n\n      const subElement = {\n        element: element,\n        eventUnloadHandlers: [onloadHandlerUnload],\n      } as imageElementBase;\n\n      this.elements.set(subElementName, subElement);\n\n      this.renderer.appendChild(mainElement, element);\n    }\n  }\n\n  /**\n   * Add all subelements of the <figure> tag (default: 'thumbnail' and 'fullImage').\n   */\n  protected addAllSubElements() {\n    const mainElement = this.getMainElement();\n\n    // Add thumbnail\n    let height = this.configuration.thumbnailSize;\n    let width = Math.round(this.aspectRatio * height);\n    this.addImageAsSubElement(\n      mainElement,\n      'thumbnail',\n      this.classNames.thumbnail,\n      this.configuration.urlForThumbnail(this.singleImageData, width, height),\n    );\n\n    // Add full image\n    height = this.configuration.getImageSize(\n      this.configuration.lastWindowWidth,\n    );\n    width = Math.round(this.aspectRatio * height);\n    this.addImageAsSubElement(\n      mainElement,\n      'fullImage',\n      this.classNames.fullImage,\n      this.configuration.urlForImage(this.singleImageData, width, height),\n    );\n  }\n\n  /**\n   * Remove a subelement (e.g. an image) of the main element.\n   * @param mainElement - Main element of this image (<figure> tag)\n   * @param subElementName - Name of the subElement (e.g. 'fullImage')\n   */\n  protected removeSubElement(mainElement: HTMLElement, subElementName: string) {\n    const subElement = this.elements.get(subElementName);\n    if (subElement) {\n      const element = subElement.element;\n      subElement.eventUnloadHandlers.forEach((unloadHandler: UnloadHandler) =>\n        unloadHandler(),\n      );\n      this.renderer.setAttribute(element, 'src', '');\n\n      this.renderer.removeChild(mainElement, element);\n      this.elements.delete(subElementName);\n    }\n  }\n\n  /**\n   * Remove all subelements of the <figure> tag (default: 'thumbnail' and 'fullImage')\n   * and the event handler for the figure click event (if one exists).\n   */\n  protected removeAllSubElements() {\n    const mainElement = this.getMainElement();\n    this.removeSubElement(mainElement, 'thumbnail');\n    this.removeSubElement(mainElement, 'fullImage');\n  }\n\n  /**\n   * Updates the style attribute to reflect the style property of this object.\n   * The style property is used to position the main element in the grid.\n   * @param element - HTML element where to set the styles.\n   */\n  protected updateStyles(element: HTMLElement) {\n    if (this.style) {\n      this.renderer.setStyle(element, 'width', `${this.style.width}px`);\n      this.renderer.setStyle(element, 'height', `${this.style.height}px`);\n      this.renderer.setStyle(\n        element,\n        'transform',\n        `translate3d(${this.style.translateX}px, ${this.style.translateY}px, 0)`,\n      );\n    }\n  }\n}\n","/* eslint-disable @angular-eslint/directive-selector */\n\nimport { DOCUMENT } from '@angular/common';\nimport {\n  AfterViewInit,\n  Directive,\n  ElementRef,\n  Inject,\n  OnDestroy,\n  Renderer2,\n} from '@angular/core';\nimport {\n  animationFrameScheduler,\n  asapScheduler,\n  auditTime,\n  Observable,\n  Subject,\n  takeUntil,\n} from 'rxjs';\n\nimport { UnloadHandler } from '../interfaces/mig-common.types';\n\n/**\n * Scheduler to be used for resize 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 RESIZE_SCHEDULER =\n  typeof requestAnimationFrame !== 'undefined'\n    ? animationFrameScheduler\n    : asapScheduler;\n\n/**\n * This is a manager for our resize events. You can add disable\n * the resize handlers, and (re-)enable handlers after they have been disabled.\n *\n * OptimizedResize uses the ResizeObserver object with a fallback to the\n * window.resize event.\n * The events emitted by the 'elementResized' property run out of\n * Angular ngZone.\n */\n@Directive({\n  selector: '[migResizable]',\n  standalone: true,\n})\nexport class MigResizableDirective implements AfterViewInit, OnDestroy {\n  private window: (Window & typeof globalThis) | null;\n  private migContainerNative: HTMLDivElement;\n  private resizeUnloadHandler: UnloadHandler | null = null;\n  private containerResizeObserver: ResizeObserver | undefined;\n  private lastContainerHeight = 0;\n  private lastContainerWidth = 0;\n  private resizeObserverEnabled = false;\n\n  private readonly unsubscribe$ = new Subject<void>();\n  private resizingSubject = new Subject<void>();\n\n  /**\n   * Observable that emits, when element resized.\n   * Collects multiple events into one until the next animation frame.\n   */\n  public elementResized: Observable<void> = this.resizingSubject.pipe(\n    // Collect multiple events into one until the next animation frame. This way if\n    // there are multiple resize events in the same frame we only need to recheck\n    // our layout once.\n    auditTime(0, RESIZE_SCHEDULER),\n    takeUntil(this.unsubscribe$),\n  );\n\n  /**\n   *Creates an instance of OptimizedResize.\n   * @param documentRef - Reference to the angular DOCUMENT element.\n   * @param renderer - Angular class to modify DOM (here: add / remove event handlers).\n   * @param containerElement - elementRef of the container element\n   */\n  constructor(\n    @Inject(DOCUMENT) documentRef: Document,\n    private renderer: Renderer2,\n    containerElement: ElementRef<HTMLDivElement>,\n  ) {\n    // get a reference to the 'window' object that can be used in ssr environments too.\n    this.window = documentRef.defaultView;\n    this.migContainerNative = containerElement.nativeElement;\n\n    if (this.window?.ResizeObserver) {\n      this.createContainerWidthResizeObserver();\n    }\n  }\n\n  ngAfterViewInit(): void {\n    this.enable();\n  }\n\n  ngOnDestroy(): void {\n    this.disable();\n    this.unsubscribe$.next();\n    this.unsubscribe$.complete();\n  }\n\n  /**\n   * Enables all resize handlers, if they do not exist or were disabled.\n   */\n  enable() {\n    if (this.containerResizeObserver) {\n      if (!this.resizeObserverEnabled) {\n        this.containerResizeObserver.observe(this.migContainerNative);\n        this.resizeObserverEnabled = true;\n      }\n    } else {\n      if (!this.resizeUnloadHandler) {\n        this.resizeUnloadHandler = this.renderer.listen(\n          this.window,\n          'resize',\n          this.resize.bind(this),\n        );\n      }\n    }\n  }\n\n  /**\n   * Disables (but do not remove) all resize handlers.\n   */\n  disable() {\n    if (this.containerResizeObserver) {\n      if (this.resizeObserverEnabled) {\n        this.containerResizeObserver.unobserve(this.migContainerNative);\n        this.resizeObserverEnabled = false;\n      }\n    } else {\n      if (this.resizeUnloadHandler) {\n        this.resizeUnloadHandler();\n        this.resizeUnloadHandler = null;\n      }\n    }\n  }\n\n  /**\n   * Create observer for resize events of the container element to update the\n   * image grid. When the height or width of the container changes, all resize\n   * callbacks get called.\n   */\n  private createContainerWidthResizeObserver() {\n    this.containerResizeObserver = new ResizeObserver((entries) => {\n      for (const entry of entries) {\n        if (entry.contentBoxSize) {\n          // Using '[0]': the css standard makes contentBoxSize an array\n          if (\n            entry.contentBoxSize &&\n            Array.isArray(entry.contentBoxSize) &&\n            entry.contentBoxSize[0]\n          ) {\n            const contentBoxSize =\n              entry.contentBoxSize as ReadonlyArray<ResizeObserverSize>;\n            const newHeight = contentBoxSize[0].blockSize;\n            const newWidth = contentBoxSize[0].inlineSize;\n\n            if (\n              newHeight !== this.lastContainerHeight ||\n              newWidth !== this.lastContainerWidth\n            ) {\n              // ResizeObserver runs out of angular zone\n              this.resize();\n              this.lastContainerHeight = newHeight;\n              this.lastContainerWidth = newWidth;\n            }\n          }\n        }\n      }\n    });\n  }\n\n  /**\n   * Handle the resize event.\n   */\n  private resize() {\n    this.resizingSubject.next();\n  }\n}\n","import { CollectionViewer, ListRange } from '@angular/cdk/collections';\nimport { CdkScrollable, ScrollingModule } from '@angular/cdk/scrolling';\nimport { CommonModule } from '@angular/common';\nimport {\n  AfterViewInit,\n  Component,\n  ElementRef,\n  EventEmitter,\n  Input,\n  NgZone,\n  OnDestroy,\n  OnInit,\n  Output,\n  Renderer2,\n  ViewChild,\n} from '@angular/core';\nimport { MatProgressBar } from '@angular/material/progress-bar';\nimport {\n  Observable,\n  Subject,\n  animationFrameScheduler,\n  asapScheduler,\n  auditTime,\n  delay,\n  distinctUntilChanged,\n  filter,\n  map,\n  startWith,\n  takeUntil,\n  tap,\n} from 'rxjs';\n\nimport { DatastoreAdapterServiceBase } from './classes/datastore-adapter.service.base';\nimport { FloatingAverage } from './classes/floating-average.class';\nimport { LoadingService } from './classes/loading-service.class';\nimport { MigDataSource } from './classes/mig-data-source.class';\nimport { ProgressiveImage } from './classes/progressive-image.class';\nimport { MigResizableDirective } from './directives/mig-resizable-directive';\nimport {\n  CreateMigImage,\n  GetImageSize,\n  GetMinAspectRatio,\n  UrlForImageFromDimensions,\n} from './interfaces/mig-common.types';\nimport { MigImageConfiguration } from './interfaces/mig-image-configuration.interface';\nimport { MigImageData } from './interfaces/mig-image-data.interface';\nimport { Page } from './interfaces/page.interface';\n\ntype ServerDataTotals = {\n  totalElements: number;\n  totalFilteredElements: number;\n};\ntype serverDataImages<T> = {\n  content: T[];\n  startImageIndex: number;\n  returnedElements: number;\n};\n\nenum ScrollDirection {\n  'down',\n  'up',\n}\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 =\n  typeof requestAnimationFrame !== 'undefined'\n    ? animationFrameScheduler\n    : asapScheduler;\n\n@Component({\n  selector: 'mat-image-grid',\n  standalone: true,\n  imports: [\n    CommonModule,\n    MatProgressBar,\n    MigResizableDirective,\n    ScrollingModule,\n  ],\n  templateUrl: './mat-image-grid.component.html',\n  styleUrl: './mat-image-grid.component.scss',\n})\nexport class MatImageGridLibComponent<\n    ServerData extends MigImageData = MigImageData,\n    MigImage extends\n      ProgressiveImage<ServerData> = ProgressiveImage<ServerData>,\n  >\n  implements AfterViewInit, OnDestroy, OnInit, CollectionViewer\n{\n  /**\n   * Default implementation of the function that gets the URL for a thumbnail image with the given data & dimensions.\n   * This is a arrow function as it uses the 'this' context of the instance.\n   * This method is located here so that it can be used as a default value for 'urlForThumbnail'.\n   * @param singleImageData - The properties of one image (e.g. containing the imageId).\n   * @param imageWidth - The width (in pixels) of the image.\n   * @param imageHeight - The height (in pixels) of the image.\n   * @returns The URL of the image with the given size.\n   */\n  private urlForThumbnailDefault = (\n    singleImageData: ServerData,\n    imageWidth: number,\n    imageHeight: number,\n  ): string => {\n    return this.urlForImage(singleImageData, imageWidth, imageHeight);\n  };\n\n  @Input() PostViewportLoadBufferMultiplier = 3; // remove images before this point\n  @Input() PostViewportDomBufferMultiplier = 1; // buffer for images that just scrolled out of view\n  @Input() PreViewportDomBufferMultiplier = 1; // buffer for images that are ready to scroll into view\n  @Input() PreViewportTriggerLoadBufferMultiplier = 1.9; // start loading more images, although we have more to scroll into view\n  @Input() PreViewportLoadBufferMultiplier = 3; // remove images after this point\n  @Input() ScrollDirectionChangeThreshold = 2; // minimum number of pixels to scroll, before a change in scroll direction is recognized\n  @Input() spaceBetweenImages = 8;\n  @Input() thumbnailSize = 20;\n  @Input() withImageClickEvents = false;\n  // dataStore is an input parameter (and not injected via DI) to enable more than 1 grid on a page\n  @Input({ required: true })\n  datastore!: DatastoreAdapterServiceBase<ServerData>; // Do not use before ngAfterViewInit\n  @Input({ required: true })\n  urlForImage: UrlForImageFromDimensions<ServerData> = this.urlForImageDefault;\n  @Input() urlForThumbnail: UrlForImageFromDimensions<ServerData> =\n    this.urlForThumbnailDefault;\n  @Input() createMigImage: CreateMigImage<ServerData, MigImage> =\n    this.createMigImageDefault;\n  @Input() getMinAspectRatio: GetMinAspectRatio = this.getMinAspectRatioDefault;\n  @Input() getImageSize: GetImageSize = this.getImageSizeDefault;\n  @Output() numberOfImagesOnServer = new EventEmitter<number>();\n  @Output() numberOfImagesOnServerFiltered = new EventEmitter<number>();\n  @Output() imageClicked = new EventEmitter<ServerData>();\n\n  /**\n    Implementation of the 'CollectionViewer' interface.\n    Used by the dataSource object as parameter of the connect method.\n    Emits when the rendered view of the data changes.\n   */\n  public readonly viewChange = new Subject<ListRange>();\n  public loading$: Observable<boolean>;\n\n  @ViewChild('migContainer') private migContainer!: ElementRef<HTMLDivElement>;\n  @ViewChild('migGrid') private migGrid!: ElementRef<HTMLDivElement>;\n  @ViewChild(CdkScrollable) private scrollable!: CdkScrollable;\n  @ViewChild(MigResizableDirective) private resizable!: MigResizableDirective;\n  private migContainerNative!: HTMLDivElement; // Do not use before AfterViewInit\n  private migGridNative!: HTMLDivElement; // Do not use before AfterViewInit\n  private images: MigImage[] = []; // Cached data from server (with positions added)\n\n  private containerWidth = window.innerWidth; // width of element that contains the image grid\n  private containerHeight = 0; // height of element that contains the image grid\n  private totalHeight = 0; // total height of the image grid\n  private latestViewportTop = 0; // current top of the viewport\n  private minAspectRatio: number | null = null;\n  private scrollDirection: ScrollDirection = ScrollDirection.down;\n  private triggerPointLoadImages = 0; // Y coordinate that will trigger loading more images from server\n\n  private indexFirstLoadedImage = -1; // index of first loaded image in this.images\n\n  // The position of images in this.images is only calculated for complete rows.\n  // Images that have not yet been positioned can exist at the beginning or at\n  // the end of this.images.\n  private indexFirstPositionedImage = -1; // Index of the first positioned image in this.images.\n  private indexLastPositionedImage = -1; // index of last positioned image in this.images\n\n  // Images up to this index were already used to calculate the average values.\n  // The average values are used to estimate / calculate the height of the whole image-grid.\n  private indexLastImageEverPositioned = -1;\n  private yBottomLastImageEverPositioned = -1;\n\n  private averageImagesPerRow!: FloatingAverage; // Do not use before AfterViewInit\n  private averageHeightOfRow!: FloatingAverage; // Do not use before AfterViewInit\n\n  private serverDataTotals = {\n    totalElements: 0,\n    totalFilteredElements: 0,\n  } as ServerDataTotals;\n\n  private readonly unsubscribe$ = new Subject<void>();\n\n  private dataSource!: MigDataSource<ServerData>;\n\n  /** Emits when new data is available. */\n  private dataFromDataSource!: Observable<Page<ServerData>>; // Do not use before AfterViewInit\n  private dataFromDataSourceTotals!: Observable<ServerDataTotals>; // Do not use before AfterViewInit\n  private dataFromDataSourceImages!: Observable<serverDataImages<ServerData>>; // Do not use before AfterViewInit\n\n  /* request new data from server when range changes only */\n  private requestDataFromServer$!: Subject<ListRange>;\n\n  private loadingService: LoadingService;\n\n  constructor(\n    private renderer2: Renderer2,\n    private ngZone: NgZone,\n  ) {\n    this.initRequestSubject();\n    this.loadingService = new LoadingService();\n    this.loading$ = this.loadingService.loading$.pipe(delay(0));\n  }\n\n  public ngOnInit(): void {\n    this.dataSource = new MigDataSource<ServerData>(this.datastore);\n    this.dataFromDataSource = this.dataSource.connect(this);\n    this.initDataFromDataSourceTotals();\n    this.initDataFromDataSourceImages();\n    this.initOnScroll();\n  }\n\n  public ngAfterViewInit(): void {\n    this.initOnResize();\n    this.resetAverageValues();\n    this.migContainerNative = this.migContainer.nativeElement;\n    this.migGridNative = this.migGrid.nativeElement;\n  }\n\n  public ngOnDestroy(): void {\n    this.dataSource?.disconnect(this);\n    this.unsubscribe$.next();\n    this.unsubscribe$.complete();\n    this.clearImageData();\n  }\n\n  /**\n   * Reset the variables used to create the floating average of\n   * the height of a row and the number of images per row.\n   * These values are used to calculate the total height of the grid,\n   * even when we do not have loaded all images.\n   */\n  private resetAverageValues() {\n    // reset values used to determine, when to add a value to the floating average\n    this.indexLastImageEverPositioned = -1;\n    this.yBottomLastImageEverPositioned = -1;\n\n    this.averageHeightOfRow = new FloatingAverage(\n      25,\n      this.getImageSize(this.containerWidth),\n    );\n\n    const defaultAspectRatioForRow = this.getMinAspectRatio(\n      this.containerWidth,\n    );\n    const defaultAspectRatioForImage = 0.75;\n    this.averageImagesPerRow = new FloatingAverage(\n      25,\n      defaultAspectRatioForRow / defaultAspectRatioForImage,\n    );\n  }\n\n  /**\n   * Get the Y position of the top of an image.\n   * @param index index of the image in this.images\n   * @returns Y position of the top of an image\n   */\n  private topOfImage(index: number) {\n    const yTop = this.images[index]?.yTop;\n    return yTop !== undefined ? yTop : 0;\n  }\n\n  private get topFirstPositionedRow() {\n    return this.topOfImage(this.indexFirstPositionedImage);\n  }\n\n  /**\n   * Get the Y position of the bottom of an image including\n   * the space between the rows.\n   * @param index index of the image in this.images\n   * @returns Y position of the bottom of the image including the space between the rows\n   */\n  private bottomOfImage(index: number) {\n    const yBottom = this.images[index]?.yBottom;\n    if (yBottom !== undefined) {\n      return yBottom + this.spaceBetweenImages;\n    }\n\n    return 0;\n  }\n\n  private get bottomLastPositionedRow() {\n    return this.bottomOfImage(this.indexLastPositionedImage);\n  }\n\n  /**\n   * Get the y-position above the viewport, from where we don't need\n   * images in the load buffer any more, when scrolling down.\n   * @returns y-position of the start of the load buffer when scrolling down\n   */\n  private loadBufferStartScrollDown() {\n    return (\n      this.latestViewportTop -\n      this.containerHeight *\n        (this.PostViewportDomBufferMultiplier +\n          this.PostViewportLoadBufferMultiplier)\n    );\n  }\n\n  /**\n   * Get the y-position above the viewport, from where we don't need\n   * images in the load buffer any more, when scrolling up.\n   * @returns y-position of the start of the load buffer when scrolling up\n   */\n  private loadBufferStartScrollUp() {\n    return (\n      this.latestViewportTop -\n      this.containerHeight *\n        (this.PreViewportDomBufferMultiplier +\n          this.PreViewportLoadBufferMultiplier)\n    );\n  }\n\n  /**\n   * Get the y-position above the viewport, from where we don't need\n   * images in the load buffer any more,\n   * @returns y-position of the start of the load buffer\n   */\n  private get loadBufferStart() {\n    if (this.scrollDirection === ScrollDirection.down) {\n      return this.loadBufferStartScrollDown();\n    }\n\n    return this.loadBufferStartScrollUp();\n  }\n\n  /**\n   * Get the y-position below the viewport, from where we don't need images\n   * in the load buffer any more, when scrolling down.\n   * @returns y-position of the end of the load buffer when scrolling down\n   */\n  private loadBufferEndScrollDown() {\n    return (\n      this.latestViewportTop +\n      this.containerHeight *\n        (1 +\n          this.PreViewportDomBufferMultiplier +\n          this.PreViewportLoadBufferMultiplier)\n    );\n  }\n\n  /**\n   * Get the y-position below the viewport, from where we don't need images\n   * in the load buffer any more, when scrolling up.\n   * @returns y-position of the end of the load buffer when scrolling up\n   */\n  private loadBufferEndScrollUp() {\n    return (\n      this.latestViewportTop +\n      this.containerHeight *\n        (1 +\n          this.PostViewportDomBufferMultiplier +\n          this.PostViewportLoadBufferMultiplier)\n    );\n  }\n\n  /**\n   * Get the y-position below the viewport, from where we don't need\n   * images in the load buffer any more,\n   * @returns y-position of the end of the load buffer\n   */\n  private get loadBufferEnd() {\n    if (this.scrollDirection === ScrollDirection.down) {\n      return this.loadBufferEndScrollDown();\n    }\n\n    return this.loadBufferEndScrollUp();\n  }\n\n  /**\n   * Get the y-position above the viewport, from where we don't need\n   * images in the DOM any more, when scrolling down.\n   * @returns y-position of the start of the DOM buffer when scrolling down\n   */\n  private domBufferStartScrollDown() {\n    return (\n      this.latestViewportTop -\n      this.containerHeight * this.PostViewportDomBufferMultiplier\n    );\n  }\n\n  /**\n   * Get the y-position above the viewport, from where we don't need\n   * images in the DOM any more, when scrolling up.\n   * @returns y-position of the start of the DOM buffer when scrolling up\n   */\n  private domBufferStartScrollUp() {\n    return (\n      this.latestViewportTop -\n      this.containerHeight * this.PreViewportDomBufferMultiplier\n    );\n  }\n\n  /**\n   * Get the y-position above the viewport, from where we don't need\n   * images in the DOM buffer any more,\n   * @returns y-position of the start of the DOM buffer\n   */\n  private get domBufferStart() {\n    if (this.scrollDirection === ScrollDirection.down) {\n      return this.domBufferStartScrollDown();\n    }\n\n    return this.domBufferStartScrollUp();\n  }\n\n  /**\n   * Get the y-position below the viewport, from where we don't need\n   * images in the DOM any more, when scrolling down.\n   * @returns y-position of the end of the DOM buffer when scrolling down\n   */\n  private domBufferEndScrollDown() {\n    return (\n      this.latestViewportTop +\n      this.containerHeight * (1 + this.PreViewportDomBufferMultiplier)\n    );\n  }\n\n  /**\n   * Get the y-position below the viewport, from where we don't need\n   * from where we don't need images in the DOM any more.\n   * @returns y-position of the end of the DOM buffer when scrolling up\n   */\n  private domBufferEndScrollUp() {\n    return (\n      this.latestViewportTop +\n      this.containerHeight * (1 + this.PostViewportDomBufferMultiplier)\n    );\n  }\n\n  /**\n   * Get the y-position below the viewport, from where we don't need\n   * images in the DOM buffer any more,\n   * @returns y-position of the end of the DOM buffer\n   */\n  private get domBufferEnd() {\n    if (this.scrollDirection === ScrollDirection.down) {\n      return this.domBufferEndScrollDown();\n    }\n\n    return this.domBufferEndScrollUp();\n  }\n\n  /**\n   * Initialize requestDataFromServer$.\n   * Remove duplicate requests and set loading indicator.\n   */\n  private initRequestSubject() {\n    this.requestDataFromServer$ = new Subject<ListRange>();\n    this.requestDataFromServer$\n      .pipe(\n        takeUntil(this.unsubscribe$),\n        distinctUntilChanged((previous: ListRange, current: ListRange) => {\n          return (\n            previous.start === current.start && previous.end === current.end\n          );\n        }),\n      )\n      .subscribe((range) => {\n        this.ngZone.run(() => this.loadingService.startRequest());\n        this.viewChange.next(range);\n      });\n  }\n\n  private initDataFromDataSourceTotals() {\n    this.dataFromDataSourceTotals = this.dataFromDataSource.pipe(\n      takeUntil(this.unsubscribe$),\n      filter((entry) => entry.totalElements !== 0),\n      map((serverResponse) => {\n        return {\n          totalElements: serverResponse.totalElements,\n          totalFilteredElements: serverResponse.totalFilteredElements,\n        } as ServerDataTotals;\n      }),\n    );\n    this.dataFromDataSourceTotals.pipe(takeUntil(this.unsubscribe$)).subscribe({\n      next: (serverTotals) => {\n        this.serverDataTotals = { ...serverTotals };\n        this.numberOfImagesOnServer.emit(serverTotals.totalElements);\n        this.numberOfImagesOnServerFiltered.emit(\n          serverTotals.totalFilteredElements,\n        );\n      },\n      error: (err: Error) =>\n        console.error(`dataFromDataSourceTotals: '${err.message}'`),\n    });\n  }\n\n  private initDataFromDataSourceImages() {\n    this.dataFromDataSourceImages = this.dataFromDataSource.pipe(\n      takeUntil(this.unsubscribe$),\n      map((serverResponse) => {\n        return {\n          content: serverResponse.content,\n          startImageIndex: serverResponse.startImageIndex,\n          returnedElements: serverResponse.returnedElements,\n        } as serverDataImages<ServerData>;\n      }),\n      tap(() => this.ngZone.run(() => this.loadingService.receivedResponse())),\n    );\n    this.dataFromDataSourceImages\n      .pipe(\n        takeUntil(this.unsubscribe$),\n        filter((entry) => entry.returnedElements !== 0),\n      )\n      .subscribe({\n        next: (serverImages) => {\n          if (this.migGrid === undefined) {\n            // received data while the app is already shutting down\n            return;\n          }\n\n          let adjustImageGridHeight = false;\n          const startIndexForImport = serverImages.startImageIndex;\n          const dataToImport = serverImages.content;\n\n          // handle data to import at the end of this.images\n          // or if this.images is empty\n          const dataToEndOfImages = this.selectDataToImportAtEnd(\n            dataToImport,\n            startIndexForImport,\n          );\n          if (dataToEndOfImages.length > 0) {\n            this.importImageDataAtEnd(dataToEndOfImages);\n            adjustImageGridHeight = this.computeLayoutAtEnd(\n              this.indexLastPositionedImage + 1,\n              this.images.length,\n            );\n          }\n\n          // handle data to import at the start of this.images\n          const dataToStartOfImages = this.selectDataToImportAtStart(\n            dataToImport,\n            startIndexForImport,\n          );\n          if (dataToStartOfImages.length > 0) {\n            this.importImageDataAtStart(\n              dataToStartOfImages,\n              startIndexForImport,\n            );\n            const endIndexExcl = Math.max(\n              startIndexForImport + dataToStartOfImages.length,\n              this.indexFirstPositionedImage,\n            );\n            this.computeLayoutAtStart(startIndexForImport, endIndexExcl);\n\n            // if we scrolled to the start of the container, but the first row is below\n            // or above the start of the container, then move all positioned images\n            // to the correct position\n            if (\n              this.topFirstPositionedRow < 0 ||\n              (this.topFirstPositionedRow > 0 &&\n                this.indexFirstPositionedImage === 0)\n            ) {\n              // how many px do we have to move the loaded images down?\n              // diffOfTopInPx is positive, if the first image has Y > 0 and negative else\n              let diffOfTopInPx = this.topFirstPositionedRow;\n              if (this.indexFirstPositionedImage !== 0) {\n                // we are already at Y < 0 and this is not  the 1st image; therefore\n                // we have even to add the estimated space required for the missing images\n                diffOfTopInPx -=\n                  (this.indexFirstPositionedImage /\n                    this.averageImagesPerRow.average) *\n                  this.averageHeightOfRow.average;\n              }\n\n              this.moveAllPositionedImagesBy(diffOfTopInPx);\n\n              this.yBottomLastImageEverPositioned -= diffOfTopInPx;\n              adjustImageGridHeight = true;\n            }\n          }\n\n          if (dataToEndOfImages.length > 0 || dataToStartOfImages.length > 0) {\n            if (adjustImageGridHeight) {\n              this.setImageGridHeight();\n            }\n            this.showImagesInViewport();\n\n            // load more images, if estimation of visible images was too little\n            this.setReloadTrigger();\n            this.fillViewport();\n\n            // remove buffered data that is out of bounds for the current scroll position\n            if (this.scrollDirection === ScrollDirection.down) {\n              this.deleteImagesAtStart();\n            } else {\n              this.deleteImagesAtEnd();\n            }\n          }\n        },\n        error: (err: Error) =>\n          console.error(`dataFromDataSourceImages: '${err.message}'`),\n      });\n  }\n\n  /**\n   * Get the definition for the data to import at the beginning of the images array.\n   * @param imagesFromServer - list of images data returned by the server\n   * @param indexOfFirstImageFromServer - where to place the first image from the server into this.images array\n   * @returns ServerData[] with the definition for the data to import\n   */\n  private selectDataToImportAtStart(\n    imagesFromServer: ServerData[],\n    indexOfFirstImageFromServer: number,\n  ): ServerData[] {\n    let result = [] as ServerData[];\n\n    if (imagesFromServer.length > 0) {\n      if (\n        this.indexFirstLoadedImage < 0 &&\n        indexOfFirstImageFromServer === 0 &&\n        this.images.length === 0\n      ) {\n        // import to empty images array\n        result = imagesFromServer;\n      } else if (\n        indexOfFirstImageFromServer < this.indexFirstLoadedImage &&\n        (this.scrollDirection === ScrollDirection.up ||\n          this.topFirstPositionedRow > this.loadBufferStart)\n      ) {\n        // import to the start of the images array\n        const importLength =\n          this.indexFirstLoadedImage - indexOfFirstImageFromServer;\n        if (imagesFromServer.length >= importLength) {\n          // get segment of data to import into images array without creating holes;\n          // on fast scrolling images requested from server may already have been\n          // scrolled out of the buffer (start and end defined by the given limits)\n          result = imagesFromServer.slice(0, importLength);\n        }\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * Convert list of images information from server to internal representation required\n   * by the image grid and add it to the start of this.images.\n   * @param imageDataToAdd - list of Image details from server (information about each image)\n   * @param startIndex - index in this.images array, where to insert the new images\n   */\n  private importImageDataAtStart(\n    imageDataToAdd: ServerData[],\n    startIndex: number,\n  ): void {\n    if (imageDataToAdd.length > 0) {\n      const imagesFromImageData = this.parseImageData(\n        imageDataToAdd,\n        startIndex,\n      );\n      this.images.splice(\n        startIndex,\n        imagesFromImageData.length,\n        ...imagesFromImageData,\n      );\n\n      // remember the new index of the first image in this.images\n      if (\n        this.indexFirstLoadedImage < 0 ||\n        startIndex < this.indexFirstLoadedImage\n      ) {\n        this.indexFirstLoadedImage = startIndex;\n      }\n    }\n  }\n\n  /**\n   * Extract the data to import at the end of the images array from the data returned by the server.\n   * @param imagesFromServer - list of images data returned by the server\n   * @param indexOfFirstImageFromServer - where to place the first image from the server into this.images array\n   * @returns ServerData[] with the definition for the data to import\n   */\n  private selectDataToImportAtEnd(\n    imagesFromServer: ServerData[],\n    indexOfFirstImageFromServer: number,\n  ): ServerData[] {\n    let result = [] as ServerData[];\n\n    if (imagesFromServer.length > 0) {\n      if (\n        this.indexFirstLoadedImage < 0 &&\n        indexOfFirstImageFromServer === 0 &&\n        this.images.length === 0\n      ) {\n        // import to empty images array\n        result = imagesFromServer;\n      } else if (\n        indexOfFirstImageFromServer <= this.images.length &&\n        (this.scrollDirection === ScrollDirection.down ||\n          this.bottomLastPositionedRow < this.loadBufferEnd)\n      ) {\n        // add images not yet available in this.images to the end of the images array\n        const startOfNewData = this.images.length - indexOfFirstImageFromServer;\n\n        if (startOfNewData >= 0) {\n          // get segment of data to import to images array without creating holes\n          result = imagesFromServer.slice(startOfNewData);\n        }\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Convert list of images information from server to internal representation required\n   * by the image grid and add it to the end of this.images.\n   * @param imageDataToAppend - list of Image details (information about each image) to append\n   */\n  private importImageDataAtEnd(imageDataToAppend: ServerData[]): void {\n    if (imageDataToAppend.length > 0) {\n      const imagesFromImageData = this.parseImageData(\n        imageDataToAppend,\n        this.images.length,\n      );\n      this.images.splice(this.images.length, 0, ...imagesFromImageData);\n\n      // on first load: remember where the image data starts\n      if (this.indexFirstLoadedImage < 0) {\n        this.indexFirstLoadedImage = 0;\n      }\n    }\n  }\n\n  /**\n   *\n   * subtract diffOfTopInPx from the Y position of each positioned image\n   * to move all images in grid to a new vertical position.\n   * @param diffOfTopInPx - number of pixels to subtract from the Y position of each image\n   */\n  private moveAllPositionedImagesBy(diffOfTopInPx: number): void {\n    if (this.indexFirstPositionedImage < 0 || diffOfTopInPx === 0) {\n      return;\n    }\n\n    for (\n      let i = this.indexFirstPositionedImage;\n      i <= this.indexLastPositionedImage;\n      i++\n    ) {\n      const image = this.images[i];\n      if (image?.style) {\n        image.style.translateY -= diffOfTopInPx;\n      }\n    }\n  }\n\n  private initOnScroll() {\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    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    this.ngZone.runOutsideAngular(() =>\n      Promise.resolve().then(() => {\n        this.scrollable\n          .elementScrolled()\n          .pipe(\n            // Start off with a fake scroll event so we properly detect our initial position.\n            startWith(null),\n\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            takeUntil(this.unsubscribe$),\n          )\n          .subscribe(() => this.onContentScrolled());\n      }),\n    );\n  }\n\n  private initOnResize() {\n    this.resizable.elementResized\n      .pipe(takeUntil(this.unsubscribe$))\n      .subscribe(() => {\n        // ResizeObserver runs out of angular ngZone\n        this.onResized();\n      });\n  }\n\n  /**\n   * Clear internal ist of images information.\n   * This method must be called, while material-image-grid is disabled (with method 'disable()')!\n   */\n  private clearImageData(): void {\n    this.images.forEach((image) => {\n      if (image.existsOnPage) {\n        image.hide();\n      }\n      image.dispose();\n    });\n\n    if (this.migGridNative !== undefined) {\n      this.renderer2.setStyle(this.migGridNative, 'height', 'auto');\n    }\n  }\n\n  /**\n   * Creates new instances of the MigImage class for each of the images defined in `imageData`.\n   * @param imageData - An array of metadata about each image from the matImageGridImageService\n   * @param startImageIndex - index of first image in imageData, after adding it to this.images array\n   * @returns An array of MigImage instances\n   */\n  private parseImageData(\n    imageData: ServerData[],\n    startImageIndex: number,\n  ): MigImage[] {\n    const progressiveImages: MigImage[] = [];\n    const configurationParameters = {\n      container: this.migGrid,\n      thumbnailSize: this.thumbnailSize,\n      lastWindowWidth: this.containerWidth,\n      withClickEvent: this.withImageClickEvents,\n      getImageSize: this.getImageSize,\n      urlForImage: this.urlForImage,\n      urlForThumbnail: this.urlForThumbnail,\n    } as MigImageConfiguration;\n\n    let imageIndex = startImageIndex;\n    imageData.forEach((image) => {\n      const progressiveImage = this.createMigImage(\n        this.renderer2,\n        image,\n        imageIndex++,\n        configurationParameters,\n      );\n\n      if (this.withImageClickEvents) {\n        progressiveImage.onClick$\n          .pipe(takeUntil(this.unsubscribe$))\n          // .subscribe(this.imageClicked);\n          .subscribe((imageData) =>\n            this.ngZone.run(() => this.imageClicked.next(imageData)),\n          );\n      }\n\n      progressiveImages.push(progressiveImage);\n    });\n\n    // at this point the images do not yet have an (absolute) position\n    return progressiveImages;\n  }\n\n  /**\n   * This computes the layout of the images in the given range, setting the height,\n   * width, translateX, translateY, and transition values for each ProgressiveImage\n   * `this.images`. These styles are set on the ProgressiveImage.style property,\n   * but are not set in the DOM.\n   *\n   * This separation of concerns (computing layout and DOM manipulation) is\n   * paramount to the performance of mat-image-grid. While we need to manipulate\n   * the DOM every time we scroll (adding or remove images, etc.), we only need\n   * to compute the layout of the mat-image-grid on loading new data and on resize.\n   * Therefore, this function will compute the layout of the images in the given\n   * range but will **not** manipulate the DOM at all.\n   *\n   * All DOM manipulation occurs in `showImagesInViewport`.\n   *\n   * This method handles positioning images at the start of the images list\n   * (images that have been deleted, when scrolling down).\n   * @param startIndex - index of the first image to position in grid\n   * @param endIndexExclusive - index of the first image beyond the positioned range\n   */\n  private computeLayoutAtStart(startIndex: number, endIndexExclusive: number) {\n    const wrapperWidth = this.containerWidth;\n    let row: ProgressiveImage<ServerData>[] = []; // The list of images in the current row.\n    let translateX = 0; // The current translateX value that we are at\n    let translateY = this.topOfImage(endIndexExclusive); // The last translateY value that we are at\n    let rowAspectRatio = 0; // The aspect ratio of the row we are building\n\n    // limit loop defining values to prevent accessing non existing images\n    const lowestIndex = Math.max(startIndex, 0);\n    const highestIndex = Math.min(endIndexExclusive, this.images.length);\n\n    // Loop through all our images in the given range, building them up into rows and computing\n    // the working rowAspectRatio.\n    for (let i = highestIndex - 1; i >= lowestIndex; i--) {\n      const image = this.images[i];\n      rowAspectRatio += image.aspectRatio;\n      row.unshift(image);\n\n      // When the rowAspectRatio exceeds the minimum acceptable aspect ratio\n      // or when we reached the first image, we say that we have all the images\n      // we need for this row, and compute the style values for each of these\n      // images.\n      if (rowAspectRatio >= (this.minAspectRatio ?? 0) || i - 1 < 0) {\n        // Make sure that the first row gets not too high, if we have\n        // not enough images to fill the row\n        rowAspectRatio = Math.max(rowAspectRatio, this.minAspectRatio ?? 0);\n\n        // Compute this row's height.\n        const totalDesiredWidthOfImages =\n          wrapperWidth - this.spaceBetweenImages * (row.length - 1);\n\n        // round height of images to integer (as height has unit px)\n        // round down to avoid horizontal scrollbar (rounding up, the image might be 1px too wide)\n        const rowHeight = Math.floor(\n          totalDesiredWidthOfImages / rowAspectRatio,\n        );\n\n        // fix position of row\n        translateY -= rowHeight + this.spaceBetweenImages;\n\n        // For each image in the row, compute the width, height, translateX,\n        // and translateY values, and set them (and the transition value we\n        // found above) on each image.\n        //\n        // NOTE: This does not manipulate the DOM, rather it just sets the\n        //       style values on the ProgressiveImage instance. The DOM nodes\n        //       will be updated in showImagesInViewport.\n        row.forEach((img) => {\n          const imageWidth = Math.floor(rowHeight * img.aspectRatio);\n\n          // This is NOT DOM manipulation.\n          img.style = {\n            width: imageWidth,\n            height: rowHeight,\n            translateX,\n            translateY,\n          };\n\n          // The next image is this.settings.spaceBetweenImages pixels to the\n          // right of this image.\n          translateX += imageWidth + this.spaceBetweenImages;\n        });\n\n        this.indexFirstPositionedImage = i;\n\n        // Reset our state variables for next row.\n        row = [];\n        rowAspectRatio = 0;\n        translateX = 0;\n      }\n    }\n  }\n\n  /**\n   * This computes the layout of the images in the given range, setting the height,\n   * width, translateX, translateY, and transition values for each ProgressiveImage\n   * `this.images`. These styles are set on the ProgressiveImage.style property,\n   * but are not set in the DOM.\n   *\n   * This separation of concerns (computing layout and DOM manipulation) is\n   * paramount to the performance of mat-image-grid. While we need to manipulate\n   * the DOM every time we scroll (adding or remove images, etc.), we only need\n   * to compute the layout of the mat-image-grid on loading new data and on resize.\n   * Therefore, this function will compute the layout of the images in the given\n   * range but will **not** manipulate the DOM at all.\n   *\n   * All DOM manipulation occurs in `showImagesInViewport`.\n   *\n   * This method handles positioning images at the end of the images list.\n   * @param startIndex - index of the first image to position in grid\n   * @param endIndexExclusive - index of the first image beyond the positioned range\n   * @returns true=image grid height must be adjusted, as average values have been changed\n   */\n  private computeLayoutAtEnd(startIndex: number, endIndexExclusive: number) {\n    const wrapperWidth = this.containerWidth;\n    let row: ProgressiveImage<ServerData>[] = []; // The list of images in the current row.\n    let rowAspectRatio = 0; // The aspect ratio of the row we are building\n    let translateX = 0; // The current translateX value that we are at\n    let translateY = this.bottomOfImage(startIndex - 1); // The bottom of the previous row\n    let adjustImageGridHeight = false;\n\n    // limit loop defining values to prevent accessing non existing images\n    const startindexLimited = Math.max(startIndex, 0);\n    const endIndexExclusiveLimited = Math.min(\n      endIndexExclusive,\n      this.images.length,\n    );\n\n    // Loop through all our images in the given range, building them up into rows and computing\n    // the working rowAspectRatio.\n    for (let i = startindexLimited; i < endIndexExclusiveLimited; i++) {\n      const image = this.images[i];\n      rowAspectRatio += image.aspectRatio;\n      row.push(image);\n\n      // When the rowAspectRatio exceeds the minimum acceptable aspect ratio\n      // or when we're out of images, we say that we have all the images we\n      // need for this row, and compute the style values for each of these\n      // images.\n      if (\n        rowAspectRatio >= (this.minAspectRatio ?? 0) ||\n        i + 1 >= this.serverDataTotals.totalFilteredElements\n      ) {\n        // Make sure that the last row also has a reasonable height\n        rowAspectRatio = Math.max(rowAspectRatio, this.minAspectRatio ?? 0);\n\n        // Compute this row's height.\n        const totalDesiredWidthOfImages =\n          wrapperWidth - this.spaceBetweenImages * (row.length - 1);\n\n        // round height of images to integer (as height has unit px)\n        // round down to avoid horizontal scrollbar (rounding up, the image might be 1px too wide)\n        const rowHeight = Math.floor(\n          totalDesiredWidthOfImages / rowAspectRatio,\n        );\n\n        // For each image in the row, compute the width, height, translateX,\n        // and translateY values, and set them (and the transition value we\n        // found above) on each image.\n        //\n        // NOTE: This does not manipulate the DOM, rather it just sets the\n        //       style values on the ProgressiveImage instance. The DOM nodes\n        //       will be updated in showImagesInViewport.\n        row.forEach((img) => {\n          const imageWidth = Math.floor(rowHeight * img.aspectRatio);\n\n          // This is NOT DOM manipulation.\n          img.style = {\n            width: imageWidth,\n            height: rowHeight,\n            translateX,\n            translateY,\n          };\n\n          // The next image is this.settings.spaceBetweenImages pixels to the\n          // right of this image.\n          translateX += imageWidth + this.spaceBetweenImages;\n        });\n\n        this.indexLastPositionedImage = i;\n\n        // if we did not yet call computeLayoutAtStart, then this is also the first positioned image\n        if (this.indexFirstPositionedImage < 0) {\n          this.indexFirstPositionedImage = startindexLimited;\n        }\n\n        translateY += rowHeight + this.spaceBetweenImages;\n        adjustImageGridHeight = this.addRowToAverage(\n          i,\n          row.length,\n          rowHeight,\n          translateY,\n        );\n\n        // Reset our state variables for next row.\n        row = [];\n        rowAspectRatio = 0;\n        translateX = 0;\n      }\n    }\n\n    return adjustImageGridHeight;\n  }\n\n  /**\n   * Add a row of images to the calculation of the average values.\n   * Average values are the height of a row and the number of images per row.\n   * The average values are used to estimate the required height of the image grid (even when not\n   * all images have already been loaded).\n   * @param indexLastImageInRow - index of the last image in the row\n   * @param imagesInRow - number of images in the row\n   * @param heightOfRow - height of the row\n   * @param yBottomRow - Y of bottom of the row\n   * @returns true=the average value has been changed\n   */\n  private addRowToAverage(\n    indexLastImageInRow: number,\n    imagesInRow: number,\n    heightOfRow: number,\n    yBottomRow: number,\n  ) {\n    let addedToAverage = false;\n\n    if (indexLastImageInRow > this.indexLastImageEverPositioned) {\n      // only consider row, when we never considered these images before\n      this.averageImagesPerRow.addEntry(imagesInRow);\n      this.averageHeightOfRow.addEntry(heightOfRow);\n      addedToAverage = true;\n    }\n\n    if (indexLastImageInRow > this.indexLastImageEverPositioned) {\n      this.indexLastImageEverPositioned = indexLastImageInRow;\n      this.yBottomLastImageEverPositioned = yBottomRow;\n    }\n    return addedToAverage;\n  }\n\n  /**\n   * Set y position where to start loading more images when scrolling down.\n   */\n  private setReloadTriggerScrollDown() {\n    const offsetToTriggerPointFromBottom = Math.floor(\n      this.containerHeight *\n        (1 +\n          this.PreViewportDomBufferMultiplier +\n          this.PreViewportTriggerLoadBufferMultiplier),\n    );\n\n    this.triggerPointLoadImages = Math.min(\n      this.latestViewportTop + offsetToTriggerPointFromBottom,\n      this.bottomLastPositionedRow,\n    );\n  }\n\n  /**\n   * Set y position where to start loading more images when scrolling up.\n   */\n  private setReloadTriggerScrollUp() {\n    const offsetToTriggerPointFromTop = Math.floor(\n      this.containerHeight *\n        (this.PreViewportDomBufferMultiplier +\n          this.PreViewportTriggerLoadBufferMultiplier),\n    );\n\n    this.triggerPointLoadImages = Math.max(\n      this.latestViewportTop - offsetToTriggerPointFromTop,\n      this.topFirstPositionedRow,\n    );\n  }\n\n  /**\n   * Set y position where to start loading more images for\n   * both scrolling directions.\n   */\n  private setReloadTrigger() {\n    if (this.scrollDirection === ScrollDirection.down) {\n      this.setReloadTriggerScrollDown();\n    } else {\n      this.setReloadTriggerScrollUp();\n    }\n  }\n\n  /**\n   * Update the DOM to reflect the style values of each image in 'images'\n   * field of this component, adding or removing images appropriately.\n   *\n   * Mat-image-grid ensures that there are not too many images loaded into the\n   * DOM at once by maintaining buffer regions around the viewport in which\n   * images are allowed, removing all images below and above. Because all of\n   * our layout is computed using CSS transforms, removing an image above the\n   * buffer will not cause the grid to reshuffle.\n   *\n   * The Pre-Buffers are the buffers in the direction the user is scrolling.\n   * (Below if they are scrolling down, above if they are scrolling up.) The\n   * size of this buffer determines the experience of scrolling down the page.\n   *\n   * The Post-Buffers are the buffers in the opposite direction of the users\n   * scrolling. The size of this buffer determines the experience of changing\n   * scroll directions. (Too small, and we have to reload a ton of images above\n   * the viewport if the user changes scroll directions.)\n   *\n   * While the layout of all loaded images have been computed, only images within\n   * the viewport, the PreViewportDomBuffer and the PostViewportDomBuffer will\n   * exist in the DOM.\n   */\n  private showImagesInViewport() {\n    if (this.indexFirstPositionedImage < 0) {\n      // nothing to show\n      return;\n    }\n\n    // This is the top of the DOM buffer (smallest Y value). If the bottom\n    // of an image is above this line, it will be removed from the DOM.\n    const minYInDom = Math.max(this.domBufferStart, 0);\n\n    // This is the bottom of the DOM buffer (highest Y value). If the\n    // top of an image is below this line, it will be removed from the DOM.\n    const maxYInDom = this.domBufferEnd;\n\n    for (\n      let i = this.indexFirstPositionedImage;\n      i <= this.indexLastPositionedImage;\n      ++i\n    ) {\n      // ignore 'holes' in sparse array\n      if (this.images[i] === undefined) {\n        continue;\n      }\n\n      const image = this.images[i];\n      const imageTranslateYAsNumber = image.style?.translateY ?? 0;\n      const imageHeightAsNumber = image.style?.height ?? 0;\n      const bottomOfImage = imageTranslateYAsNumber + imageHeightAsNumber;\n\n      if (\n        bottomOfImage < minYInDom ||\n        imageTranslateYAsNumber > maxYInDom ||\n        i > this.indexLastPositionedImage\n      ) {\n        image.hide();\n      } else {\n        image.load();\n      }\n    }\n  }\n\n  /**\n   * Event handler for images grid scroll event (triggered by cdkScrollable).\n   * When called in this.scrollable observable, this event handler runs outside\n   * the Angular zone.\n   */\n  private onContentScrolled() {\n    // Compute the scroll direction using the latestYOffset and the previousYOffset.\n    // Prevent scrolling below the bottom of the grid (would  inadvertently change scrolling direction)\n    const newYOffset = Math.min(\n      this.migContainerNative.scrollTop,\n      this.totalHeight,\n    );\n    const previousYOffset = this.latestViewportTop ?? newYOffset;\n    this.latestViewportTop = newYOffset;\n    const scrollTopChange = newYOffset - previousYOffset;\n\n    if (Math.abs(scrollTopChange) >= this.ScrollDirectionChangeThreshold) {\n      this.scrollDirection =\n        scrollTopChange >= 0 ? ScrollDirection.down : ScrollDirection.up;\n    }\n\n    // Show / hide images according to new scroll position\n    this.showImagesInViewport();\n\n    // load more images, if required\n    this.fillViewport();\n  }\n\n  /**\n   * Delete images from the start of the load cache ('this.images') when scrolling down.\n   */\n  private deleteImagesAtStart() {\n    // do nothing, if this.images is empty\n    if (this.indexFirstLoadedImage < 0) {\n      return;\n    }\n\n    // calculate Y of the top of the DOM buffer. If the bottom of an image\n    // is above this line, it will be removed from the DOM.\n    const heightDomBufferStart =\n      this.containerHeight * this.PostViewportDomBufferMultiplier;\n    const minYInDom = Math.max(\n      this.latestViewportTop - heightDomBufferStart,\n      0,\n    );\n\n    // calculate Y of the top of the load buffer. If the bottom of an image is above\n    // this line, it will be removed from the load buffer (this.images).\n    const heightLoadBufferStart =\n      this.containerHeight * this.PostViewportLoadBufferMultiplier;\n    const minYLoaded = Math.max(minYInDom - heightLoadBufferStart, 0);\n\n    // do not delete the last positioned image, as we need it to get the y-position\n    // of images added at the end of this.images\n    for (\n      let i = this.indexFirstLoadedImage;\n      i < this.indexLastPositionedImage;\n      i++\n    ) {\n      if (this.images[i].yBottom >= minYLoaded) {\n        break;\n      }\n\n      this.images[i].hide();\n      // eslint-disable-next-line @typescript-eslint/no-array-delete\n      delete this.images[i];\n      this.indexFirstLoadedImage = i + 1;\n\n      this.indexFirstPositionedImage = this.indexFirstLoadedImage;\n    }\n  }\n\n  /**\n   * Delete images from the end of the load cache ('this.images') when scrolling up.\n   */\n  private deleteImagesAtEnd() {\n    // calculate Y of the bottom of the DOM buffer. If the top of an image\n    // is below this line, it will be removed from the DOM.\n    const heightDomBufferEnd =\n      this.containerHeight * this.PostViewportDomBufferMultiplier;\n    const maxYInDom =\n      this.latestViewportTop + this.containerHeight + heightDomBufferEnd;\n\n    // calculate Y of the bottom of the load buffer. If the top of an image\n    // is below this line, it will be removed from the load buffer (this.images).\n    const heightLoadBufferEnd =\n      this.containerHeight * this.PostViewportLoadBufferMultiplier;\n    const maxYLoadBuffer = maxYInDom + heightLoadBufferEnd;\n\n    let indexOfFirstImageToDelete = this.indexLastPositionedImage + 1;\n\n    // do not delete the first positioned image, as we need it to get the y-position\n    // of images to be added at the start of this image\n    for (\n      let i = this.images.length - 1;\n      i > this.indexFirstPositionedImage;\n      i--\n    ) {\n      const image = this.images[i];\n      const yTop = image.yTop;\n      if (yTop <= maxYLoadBuffer) {\n        indexOfFirstImageToDelete = i + 1;\n        break;\n      }\n\n      image.hide();\n    }\n\n    // set this.bottomOfLastPositionedRow; calculate from image and space between images\n    if (indexOfFirstImageToDelete < this.images.length) {\n      this.indexLastPositionedImage = Math.max(\n        indexOfFirstImageToDelete - 1,\n        0,\n      );\n    }\n\n    // remove unneeded elements at end of cache\n    this.images.splice(indexOfFirstImageToDelete);\n  }\n\n  private onResized() {\n    this.containerHeight = this.migContainerNative.clientHeight;\n    this.containerWidth = this.migContainerNative.clientWidth;\n    this.minAspectRatio = this.getMinAspectRatio(this.containerWidth);\n    this.resetAverageValues();\n\n    // Reposition all loaded images\n    const indexOfFirstVisibleImage = this.indexOfScrollTop();\n    const adjustImageGridHeight = this.computeLayoutAtEnd(\n      indexOfFirstVisibleImage,\n      this.images.length,\n    );\n    this.computeLayoutAtStart(\n      this.indexFirstLoadedImage,\n      indexOfFirstVisibleImage,\n    );\n\n    if (adjustImageGridHeight) {\n      this.setImageGridHeight();\n    }\n    this.setReloadTrigger(); // as viewportTop may have changed when setting total grid height\n    this.showImagesInViewport();\n    this.fillViewport();\n  }\n\n  /**\n   * Get the index of the first image visible in viewport.\n   * @returns index of the first visible image or -1 (if no image is visible)\n   */\n  private indexOfScrollTop() {\n    const viewportTop = this.latestViewportTop;\n\n    for (\n      let i = this.indexFirstPositionedImage;\n      i <= this.indexLastPositionedImage;\n      i++\n    ) {\n      const image = this.images[i];\n      if (image && image.yTop >= viewportTop) {\n        return i;\n      }\n    }\n    return -1; // No image found in the viewport\n  }\n\n  /**\n   * Set the height of the images container based on the images already positioned\n   * and on an estimation about the height required by the remaining images.\n   * for the 'images already positioned' indexOfLastPositionedImage and\n   * bottomOfLastPositionedRow is used; i.e. images that were once positioned and\n   * then later removed while scrolling up are ignored.\n   */\n  private setImageGridHeight() {\n    if (this.serverDataTotals.totalFilteredElements > 0) {\n      const numberOfUnpositionedImages = Math.ceil(\n        this.serverDataTotals.totalFilteredElements -\n          (this.indexLastImageEverPositioned + 1),\n      );\n      this.totalHeight = Math.ceil(\n        this.yBottomLastImageEverPositioned +\n          (numberOfUnpositionedImages / this.averageImagesPerRow.average) *\n            (this.averageHeightOfRow.average + this.spaceBetweenImages),\n      );\n\n      if (numberOfUnpositionedImages <= 0) {\n        this.totalHeight -= this.spaceBetweenImages;\n      }\n    } else {\n      this.totalHeight = 0;\n    }\n\n    // Set the container height\n    this.renderer2.setStyle(\n      this.migGridNative,\n      'height',\n      `${this.totalHeight}px`,\n    );\n\n    // set this.latestViewportTop to current scrollTop, as scrollTop changes, when container height is reduced\n    this.latestViewportTop = this.migContainerNative.scrollTop;\n  }\n\n  /**\n   * Request images from the dataSource to fill the viewport, the Pre- and the Post-ViewportDomBuffer\n   * and the Pre- and the Post-ViewportLoadBuffer.\n   */\n  private fillViewport() {\n    if (this.containerHeight === 0) {\n      // get number of images on sever only\n      this.requestDataFromServer(0, 0);\n    } else {\n      if (this.scrollDirection === ScrollDirection.down) {\n        this.fillViewportScrollDown();\n      } else {\n        this.fillViewportScrollUp();\n      }\n    }\n  }\n\n  /**\n   * Request images from the dataSource to fill the viewport and the buffers\n   * when scrolling down.\n   */\n  private fillViewportScrollDown() {\n    const bottomOfDomBuffer =\n      this.latestViewportTop +\n      this.containerHeight * (1 + this.PreViewportDomBufferMultiplier);\n\n    if (\n      bottomOfDomBuffer >= this.triggerPointLoadImages ||\n      this.images.length === 0\n    ) {\n      // Calculate vertical space to fill starting from top of visible area\n      const viewRangeAlreadyPositioned =\n        this.bottomLastPositionedRow - this.latestViewportTop;\n\n      const viewRangeRequired =\n        this.containerHeight *\n        (1 +\n          this.PreViewportDomBufferMultiplier +\n          this.PreViewportLoadBufferMultiplier);\n\n      const rowsToRender = Math.ceil(\n        (viewRangeRequired - viewRangeAlreadyPositioned) /\n          this.averageHeightOfRow.average,\n      );\n      const imagesToRender = Math.ceil(\n        rowsToRender * this.averageImagesPerRow.average,\n      );\n      const indexOfFirstImageToLoad = this.images.length;\n\n      let indexOfLastImageToLoadExcl = Math.max(\n        indexOfFirstImageToLoad + imagesToRender,\n        0,\n      );\n      // limit last index to number of images on server, if available\n      if (this.serverDataTotals.totalFilteredElements !== 0) {\n        indexOfLastImageToLoadExcl = Math.min(\n          indexOfLastImageToLoadExcl,\n          this.serverDataTotals.totalFilteredElements,\n        );\n      }\n\n      if (indexOfLastImageToLoadExcl > indexOfFirstImageToLoad) {\n        this.requestDataFromServer(\n          indexOfFirstImageToLoad,\n          indexOfLastImageToLoadExcl,\n        );\n      }\n    }\n  }\n\n  /**\n   * Request images from the dataSource to fill the viewport and the buffers\n   * when scrolling up.\n   */\n  private fillViewportScrollUp() {\n    const topOfDomBuffer =\n      this.latestViewportTop -\n      this.containerHeight * this.PreViewportDomBufferMultiplier;\n\n    if (topOfDomBuffer <= this.triggerPointLoadImages) {\n      // Calculate vertical space to fill starting from top of visible area\n      const viewRangeAlreadyPositioned =\n        this.latestViewportTop - this.topFirstPositionedRow;\n\n      const viewRangeRequired =\n        this.containerHeight *\n        (this.PreViewportDomBufferMultiplier +\n          this.PreViewportLoadBufferMultiplier);\n\n      const rowsToRender = Math.ceil(\n        (viewRangeRequired - viewRangeAlreadyPositioned) /\n          this.averageHeightOfRow.average,\n      );\n      const imagesToRender = Math.ceil(\n        rowsToRender * this.averageImagesPerRow.average,\n      );\n      const indexOfLastImageToLoad = this.indexFirstLoadedImage - 1;\n      const indexOfFirstImageToLoad = Math.max(\n        indexOfLastImageToLoad - imagesToRender + 1,\n        0,\n      );\n      if (indexOfLastImageToLoad >= indexOfFirstImageToLoad) {\n        this.requestDataFromServer(\n          indexOfFirstImageToLoad,\n          indexOfLastImageToLoad + 1,\n        );\n      }\n    }\n  }\n\n  /**\n   * Request images data from server.\n   * @param indexStart - index of first image to load\n   * @param indexEndExclusive - index of last image to load + 1\n   */\n  private requestDataFromServer(indexStart: number, indexEndExclusive: number) {\n    // Send only requests that will return data\n    const imagesAvailable = this.serverDataTotals.totalFilteredElements;\n    if (\n      indexEndExclusive > indexStart &&\n      (indexStart < imagesAvailable || imagesAvailable === 0)\n    ) {\n      this.requestDataFromServer$.next({\n        start: indexStart,\n        end: indexEndExclusive,\n      });\n    } else {\n      if (indexStart === indexEndExclusive) {\n        // request number of images on server only\n        this.requestDataFromServer$.next({\n          start: 0,\n          end: 0,\n        });\n      }\n    }\n  }\n\n  /**\n   * Default implementation of the function that gets the URL for an image with the given data & dimensions.\n   * @param singleImageData - The properties of one image (e.g. containing the imageId).\n   * @param imageWidth - The width (in pixels) of the image.\n   * @param imageHeight - The height (in pixels) of the image.\n   * @returns The URL of the image with the given size.\n   */\n  private urlForImageDefault(\n    this: void,\n    singleImageData: ServerData,\n    imageWidth: number,\n    imageHeight: number,\n  ): string {\n    return `/${singleImageData.imageId}/${imageWidth.toString(10)}/${imageHeight.toString(10)}`;\n  }\n\n  /**\n   * Create a new instance of the MigImage class.\n   * The MigImage class represents 1 image in the image grid.\n   * @param renderer - Renderer to be injected into ProgressiveImage constructor.\n   * @param singleImageData - Data from the server describing the image.\n   * @param index - Index of the image in the list of all images (0..n-1).\n   * @param configuration - Configuration data for this image.\n   * @returns New instance of the MigImage class.\n   */\n  private createMigImageDefault(\n    this: void,\n    renderer: Renderer2,\n    singleImageData: ServerData,\n    index: number,\n    configuration: MigImageConfiguration,\n  ): MigImage {\n    return new ProgressiveImage(\n      renderer,\n      singleImageData,\n      index,\n      configuration,\n    ) as MigImage;\n  }\n\n  /**\n   * Default implementation to get the minimum required aspect ratio for a\n   * valid row of images. The perfect rows are maintained by building up a\n   * row of images by adding together their aspect ratios (the aspect ratio\n   * when they are placed next to each other) until that aspect ratio exceeds\n   * the value returned by this function. Responsive reordering is achieved\n   * through changes to what this function returns at different values of the\n   * passed parameter `lastWindowWidth`.\n   * @param lastWindowWidth - The last computed width of the browser window.\n   * @returns The minimum aspect ratio at this window width.\n   */\n  private getMinAspectRatioDefault(this: void, lastWindowWidth: number) {\n    if (lastWindowWidth <= 500) {\n      return 3.5;\n    } else if (lastWindowWidth <= 640) {\n      return 3.8;\n    } else if (lastWindowWidth <= 1280) {\n      return 4;\n    } else if (lastWindowWidth <= 1920) {\n      return 5;\n    }\n    return 6;\n  }\n\n  /**\n   * Default implementation to get the image size (height in pixels) to use\n   * for this window width.\n   * Responsive resizing of images is achieved through changes to what this\n   * function returns at different values of the passed parameter `lastWindowWidth`.\n   * @param lastWindowWidth - The last computed width of the images container.\n   * @returns The size (height in pixels) of the images to load.\n   */\n  private getImageSizeDefault(this: void, lastWindowWidth: number): number {\n    if (lastWindowWidth <= 640) {\n      return 100;\n    } else if (lastWindowWidth <= 1920) {\n      return 250;\n    }\n    return 500;\n  }\n}\n","<mat-progress-bar\n  [ngClass]=\"{\n    'mat-image-grid-loading-hide': (loading$ | async) === false,\n  }\"\n  class=\"mat-image-grid-loading-spinner\"\n  color=\"primary\"\n  mode=\"indeterminate\"\n>\n</mat-progress-bar>\n<div #migContainer class=\"images-container\" cdkScrollable migResizable>\n  <div #migGrid class=\"images-grid\"></div>\n</div>\n","import { Injectable } from '@angular/core';\nimport { Observable } from 'rxjs';\n\nimport {\n  FieldFilterDefinition,\n  FieldSortDefinition,\n  RequestImagesRange,\n  DataStoreAdapter,\n} from '../interfaces/datastore-adapter.interface';\nimport { MigImageData } from '../interfaces/mig-image-data.interface';\nimport { Page } from '../interfaces/page.interface';\n\n/**\n * Base class for the adapter that gets a list of image data\n * from the data store.\n * @template T - class derived from MigImageData\n */\n@Injectable()\nexport abstract class DatastoreAdapterServiceBase<\n  T extends MigImageData = MigImageData,\n> implements DataStoreAdapter<T>\n{\n  // eslint-disable-next-line jsdoc/require-returns-check\n  /**\n   * Get list of all available images for use in progressive image grid\n   * @param imagesRange - definition of the number of requested images\n   * @param sorts - sorting definition of the requested images\n   * @param filters - filter for selecting the requested images\n   * @returns list of images\n   */\n  public getPagedData(\n    /* eslint-disable @typescript-eslint/no-unused-vars */\n    imagesRange: RequestImagesRange,\n    sorts?: FieldSortDefinition<T>[],\n    filters?: FieldFilterDefinition<T>[],\n    /* eslint-enable @typescript-eslint/no-unused-vars */\n  ): Observable<Page<T>> {\n    throw new Error('Method \"getPagedData\" not implemented.');\n  }\n}\n","/*\n * Public API Surface of mat-image-grid library\n */\n\nexport * from './lib/mat-image-grid.component';\n\nexport * from './lib/classes/datastore-adapter.service.base';\nexport * from './lib/classes/progressive-image.class';\n\nexport * from './lib/interfaces/datastore-adapter.interface';\nexport * from './lib/interfaces/mig-image-configuration.interface';\nexport * from './lib/interfaces/mig-image-data.interface';\nexport * from './lib/interfaces/page.interface';\nexport * from './lib/interfaces/progressive-image.interface';\n\nexport * from './lib/interfaces/mig-common.types';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}