text: import { isObservable, of, Subject } from 'rxjs';
  import { ɵɵdefineInjectable, Injectable, InjectionToken } from '@angular/core';
  
  /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  import * as ɵngcc0 from '@angular/core';
  class DataSource {
  }
  /** Checks whether an object is a data source. */
  function isDataSource(value) {
      // Check if the value is a DataSource by observing if it has a connect function. Cannot
      // be checked as an `instanceof DataSource` since people could create their own sources
      // that match the interface, but don't extend DataSource.
      return value && typeof value.connect === 'function';
  }
  
  /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  /** DataSource wrapper for a native array. */
  class ArrayDataSource extends DataSource {
      constructor(_data) {
          super();
          this._data = _data;
      }
      connect() {
          return isObservable(this._data) ? this._data : of(this._data);
      }
      disconnect() { }
  }
  
  /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  
  /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  /**
   * A repeater that destroys views when they are removed from a
   * {@link ViewContainerRef}. When new items are inserted into the container,
   * the repeater will always construct a new embedded view for each item.
   *
   * @template T The type for the embedded view's $implicit property.
   * @template R The type for the item in each IterableDiffer change record.
   * @template C The type for the context passed to each embedded view.
   */
  class _DisposeViewRepeaterStrategy {
      applyChanges(changes, viewContainerRef, itemContextFactory, itemValueResolver, itemViewChanged) {
          changes.forEachOperation((record, adjustedPreviousIndex, currentIndex) => {
              let view;
              let operation;
              if (record.previousIndex == null) {
                  const insertContext = itemContextFactory(record, adjustedPreviousIndex, currentIndex);
                  view = viewContainerRef.createEmbeddedView(insertContext.templateRef, insertContext.context, insertContext.index);
                  operation = 1 /* INSERTED */;
              }
              else if (currentIndex == null) {
                  viewContainerRef.remove(adjustedPreviousIndex);
                  operation = 3 /* REMOVED */;
              }
              else {
                  view = viewContainerRef.get(adjustedPreviousIndex);
                  viewContainerRef.move(view, currentIndex);
                  operation = 2 /* MOVED */;
              }
              if (itemViewChanged) {
                  itemViewChanged({
                      context: view === null || view === void 0 ? void 0 : view.context,
                      operation,
                      record,
                  });
              }
          });
      }
      detach() {
      }
  }
  
  /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  /**
   * A repeater that caches views when they are removed from a
   * {@link ViewContainerRef}. When new items are inserted into the container,
   * the repeater will reuse one of the cached views instead of creating a new
   * embedded view. Recycling cached views reduces the quantity of expensive DOM
   * inserts.
   *
   * @template T The type for the embedded view's $implicit property.
   * @template R The type for the item in each IterableDiffer change record.
   * @template C The type for the context passed to each embedded view.
   */
  class _RecycleViewRepeaterStrategy {
      constructor() {
          /**
           * The size of the cache used to store unused views.
           * Setting the cache size to `0` will disable caching. Defaults to 20 views.
           */
          this.viewCacheSize = 20;
          /**
           * View cache that stores embedded view instances that have been previously stamped out,
           * but don't are not currently rendered. The view repeater will reuse these views rather than
           * creating brand new ones.
           *
           * TODO(michaeljamesparsons) Investigate whether using a linked list would improve performance.
           */
          this._viewCache = [];
      }
      /** Apply changes to the DOM. */
      applyChanges(changes, viewContainerRef, itemContextFactory, itemValueResolver, itemViewChanged) {
          // Rearrange the views to put them in the right location.
          changes.forEachOperation((record, adjustedPreviousIndex, currentIndex) => {
              let view;
              let operation;
              if (record.previousIndex == null) { // Item added.
                  const viewArgsFactory = () => itemContextFactory(record, adjustedPreviousIndex, currentIndex);
                  view = this._insertView(viewArgsFactory, currentIndex, viewContainerRef, itemValueResolver(record));
                  operation = view ? 1 /* INSERTED */ : 0 /* REPLACED */;
              }
              else if (currentIndex == null) { // Item removed.
                  this._detachAndCacheView(adjustedPreviousIndex, viewContainerRef);
                  operation = 3 /* REMOVED */;
              }
              else { // Item moved.
                  view = this._moveView(adjustedPreviousIndex, currentIndex, viewContainerRef, itemValueResolver(record));
                  operation = 2 /* MOVED */;
              }
              if (itemViewChanged) {
                  itemViewChanged({
                      context: view === null || view === void 0 ? void 0 : view.context,
                      operation,
                      record,
                  });
              }
          });
      }
      detach() {
          for (const view of this._viewCache) {
              view.destroy();
          }
      }
      /**
       * Inserts a view for a new item, either from the cache or by creating a new
       * one. Returns `undefined` if the item was inserted into a cached view.
       */
      _insertView(viewArgsFactory, currentIndex, viewContainerRef, value) {
          let cachedView = this._insertViewFromCache(currentIndex, viewContainerRef);
          if (cachedView) {
              cachedView.context.$implicit = value;
              return undefined;
          }
          const viewArgs = viewArgsFactory();
          return viewContainerRef.createEmbeddedView(viewArgs.templateRef, viewArgs.context, viewArgs.index);
      }
      /** Detaches the view at the given index and inserts into the view cache. */
      _detachAndCacheView(index, viewContainerRef) {
          const detachedView = this._detachView(index, viewContainerRef);
          this._maybeCacheView(detachedView, viewContainerRef);
      }
      /** Moves view at the previous index to the current index. */
      _moveView(adjustedPreviousIndex, currentIndex, viewContainerRef, value) {
          const view = viewContainerRef.get(adjustedPreviousIndex);
          viewContainerRef.move(view, currentIndex);
          view.context.$implicit = value;
          return view;
      }
      /**
       * Cache the given detached view. If the cache is full, the view will be
       * destroyed.
       */
      _maybeCacheView(view, viewContainerRef) {
          if (this._viewCache.length < this.viewCacheSize) {
              this._viewCache.push(view);
          }
          else {
              const index = viewContainerRef.indexOf(view);
              // The host component could remove views from the container outside of
              // the view repeater. It's unlikely this will occur, but just in case,
              // destroy the view on its own, otherwise destroy it through the
              // container to ensure that all the references are removed.
              if (index === -1) {
                  view.destroy();
              }
              else {
                  viewContainerRef.remove(index);
              }
          }
      }
      /** Inserts a recycled view from the cache at the given index. */
      _insertViewFromCache(index, viewContainerRef) {
          const cachedView = this._viewCache.pop();
          if (cachedView) {
              viewContainerRef.insert(cachedView, index);
          }
          return cachedView || null;
      }
      /** Detaches the embedded view at the given index. */
      _detachView(index, viewContainerRef) {
          return viewContainerRef.detach(index);
      }
  }
  
  /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  /**
   * Class to be used to power selecting one or more options from a list.
   */
  class SelectionModel {
      constructor(_multiple = false, initiallySelectedValues, _emitChanges = true) {
          this._multiple = _multiple;
          this._emitChanges = _emitChanges;
          /** Currently-selected values. */
          this._selection = new Set();
          /** Keeps track of the deselected options that haven't been emitted by the change event. */
          this._deselectedToEmit = [];
          /** Keeps track of the selected options that haven't been emitted by the change event. */
          this._selectedToEmit = [];
          /** Event emitted when the value has changed. */
          this.changed = new Subject();
          if (initiallySelectedValues && initiallySelectedValues.length) {
              if (_multiple) {
                  initiallySelectedValues.forEach(value => this._markSelected(value));
              }
              else {
                  this._markSelected(initiallySelectedValues[0]);
              }
              // Clear the array in order to avoid firing the change event for preselected values.
              this._selectedToEmit.length = 0;
          }
      }
      /** Selected values. */
      get selected() {
          if (!this._selected) {
              this._selected = Array.from(this._selection.values());
          }
          return this._selected;
      }
      /**
       * Selects a value or an array of values.
       */
      select(...values) {
          this._verifyValueAssignment(values);
          values.forEach(value => this._markSelected(value));
          this._emitChangeEvent();
      }
      /**
       * Deselects a value or an array of values.
       */
      deselect(...values) {
          this._verifyValueAssignment(values);
          values.forEach(value => this._unmarkSelected(value));
          this._emitChangeEvent();
      }
      /**
       * Toggles a value between selected and deselected.
       */
      toggle(value) {
          this.isSelected(value) ? this.deselect(value) : this.select(value);
      }
      /**
       * Clears all of the selected values.
       */
      clear() {
          this._unmarkAll();
          this._emitChangeEvent();
      }
      /**
       * Determines whether a value is selected.
       */
      isSelected(value) {
          return this._selection.has(value);
      }
      /**
       * Determines whether the model does not have a value.
       */
      isEmpty() {
          return this._selection.size === 0;
      }
      /**
       * Determines whether the model has a value.
       */
      hasValue() {
          return !this.isEmpty();
      }
      /**
       * Sorts the selected values based on a predicate function.
       */
      sort(predicate) {
          if (this._multiple && this.selected) {
              this._selected.sort(predicate);
          }
      }
      /**
       * Gets whether multiple values can be selected.
       */
      isMultipleSelection() {
          return this._multiple;
      }
      /** Emits a change event and clears the records of selected and deselected values. */
      _emitChangeEvent() {
          // Clear the selected values so they can be re-cached.
          this._selected = null;
          if (this._selectedToEmit.length || this._deselectedToEmit.length) {
              this.changed.next({
                  source: this,
                  added: this._selectedToEmit,
                  removed: this._deselectedToEmit
              });
              this._deselectedToEmit = [];
              this._selectedToEmit = [];
          }
      }
      /** Selects a value. */
      _markSelected(value) {
          if (!this.isSelected(value)) {
              if (!this._multiple) {
                  this._unmarkAll();
              }
              this._selection.add(value);
              if (this._emitChanges) {
                  this._selectedToEmit.push(value);
              }
          }
      }
      /** Deselects a value. */
      _unmarkSelected(value) {
          if (this.isSelected(value)) {
              this._selection.delete(value);
              if (this._emitChanges) {
                  this._deselectedToEmit.push(value);
              }
          }
      }
      /** Clears out the selected values. */
      _unmarkAll() {
          if (!this.isEmpty()) {
              this._selection.forEach(value => this._unmarkSelected(value));
          }
      }
      /**
       * Verifies the value assignment and throws an error if the specified value array is
       * including multiple values while the selection model is not supporting multiple values.
       */
      _verifyValueAssignment(values) {
          if (values.length > 1 && !this._multiple && (typeof ngDevMode === 'undefined' || ngDevMode)) {
              throw getMultipleValuesInSingleSelectionError();
          }
      }
  }
  /**
   * Returns an error that reports that multiple values are passed into a selection model
   * with a single value.
   * @docs-private
   */
  function getMultipleValuesInSingleSelectionError() {
      return Error('Cannot pass multiple values into SelectionModel with single-value mode.');
  }
  
  /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  /**
   * Class to coordinate unique selection based on name.
   * Intended to be consumed as an Angular service.
   * This service is needed because native radio change events are only fired on the item currently
   * being selected, and we still need to uncheck the previous selection.
   *
   * This service does not *store* any IDs and names because they may change at any time, so it is
   * less error-prone if they are simply passed through when the events occur.
   */
  class UniqueSelectionDispatcher {
      constructor() {
          this._listeners = [];
      }
      /**
       * Notify other items that selection for the given name has been set.
       * @param id ID of the item.
       * @param name Name of the item.
       */
      notify(id, name) {
          for (let listener of this._listeners) {
              listener(id, name);
          }
      }
      /**
       * Listen for future changes to item selection.
       * @return Function used to deregister listener
       */
      listen(listener) {
          this._listeners.push(listener);
          return () => {
              this._listeners = this._listeners.filter((registered) => {
                  return listener !== registered;
              });
          };
      }
      ngOnDestroy() {
          this._listeners = [];
      }
  }
  UniqueSelectionDispatcher.ɵfac = function UniqueSelectionDispatcher_Factory(t) { return new (t || UniqueSelectionDispatcher)(); };
  UniqueSelectionDispatcher.ɵprov = ɵɵdefineInjectable({ factory: function UniqueSelectionDispatcher_Factory() { return new UniqueSelectionDispatcher(); }, token: UniqueSelectionDispatcher, providedIn: "root" });
  /*@__PURE__*/ (function () { ɵngcc0.ɵsetClassMetadata(UniqueSelectionDispatcher, [{
          type: Injectable,
          args: [{ providedIn: 'root' }]
      }], function () { return []; }, null); })();
  
  /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  
  /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  /**
   * Injection token for {@link _ViewRepeater}.
   *
   * INTERNAL ONLY - not for public consumption.
   * @docs-private
   */
  const _VIEW_REPEATER_STRATEGY = new InjectionToken('_ViewRepeater');
  
  /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  
  /**
   * Generated bundle index. Do not edit.
   */
  
  export { ArrayDataSource, DataSource, SelectionModel, UniqueSelectionDispatcher, _DisposeViewRepeaterStrategy, _RecycleViewRepeaterStrategy, _VIEW_REPEATER_STRATEGY, getMultipleValuesInSingleSelectionError, isDataSource };
  
  //# sourceMappingURL=collections.js.map