text: import { ɵɵdefineInjectable, Injectable, EventEmitter, Component, Renderer2, ElementRef, Directive, ViewContainerRef, Input, Output, forwardRef, Host, ChangeDetectorRef, ViewChild, ChangeDetectionStrategy, NgModule } from '@angular/core';
  import { filter, map, take, takeUntil, distinctUntilChanged } from 'rxjs/operators';
  import { isFirstDayOfWeek, getDay, shiftDate, isBefore, endOf, isAfter, startOf, isArray, isSame, getFirstDayOfMonth, formatDate, getLocale, isSameMonth, isSameDay, isDisabledDay, isSameYear, isDateValid, setFullDate, getMonth, getFullYear, isDate, parseDate, utcAsLocal } from 'ngx-bootstrap/chronos';
  import { PositioningService } from 'ngx-bootstrap/positioning';
  import { trigger, state, style, transition, animate } from '@angular/animations';
  import { Subscription, BehaviorSubject, combineLatest, Subject } from 'rxjs';
  import { MiniStore, MiniState } from 'ngx-bootstrap/mini-ngrx';
  import { ComponentLoaderFactory } from 'ngx-bootstrap/component-loader';
  import { NG_VALUE_ACCESSOR, NG_VALIDATORS, FormsModule } from '@angular/forms';
  import { isBs3 } from 'ngx-bootstrap/utils';
  import { CommonModule } from '@angular/common';
  import { TooltipModule } from 'ngx-bootstrap/tooltip';
  
  /**
   * For date range picker there are `BsDaterangepickerConfig` which inherits all properties,
   * except `displayMonths`, for range picker it default to `2`
   */
  class BsDatepickerConfig {
      constructor() {
          /** sets use adaptive position */
          this.adaptivePosition = false;
          /** sets use UTC date time format */
          this.useUtc = false;
          /** turn on/off animation */
          this.isAnimated = false;
          /**
           * The view that the datepicker should start in
           */
          this.startView = 'day';
          /**
           * If true, returns focus to the datepicker / daterangepicker input after date selection
           */
          this.returnFocusToInput = false;
          /** CSS class which will be applied to datepicker container,
           * usually used to set color theme
           */
          this.containerClass = 'theme-green';
          // DatepickerRenderOptions
          this.displayMonths = 1;
          /**
           * Allows to hide week numbers in datepicker
           */
          this.showWeekNumbers = true;
          this.dateInputFormat = 'L';
          // range picker
          this.rangeSeparator = ' - ';
          /**
           * Date format for date range input field
           */
          this.rangeInputFormat = 'L';
          // DatepickerFormatOptions
          this.monthTitle = 'MMMM';
          this.yearTitle = 'YYYY';
          this.dayLabel = 'D';
          this.monthLabel = 'MMMM';
          this.yearLabel = 'YYYY';
          this.weekNumbers = 'w';
          /**
           * Shows 'today' button
           */
          this.showTodayButton = false;
          /**
           * Shows clear button
           */
          this.showClearButton = false;
          /**
           * Positioning of 'today' button
           */
          this.todayPosition = 'center';
          /**
           * Positioning of 'clear' button
           */
          this.clearPosition = 'right';
          /**
           * Label for 'today' button
           */
          this.todayButtonLabel = 'Today';
          /**
           * Label for 'clear' button
           */
          this.clearButtonLabel = 'Clear';
          /**
           * Label for 'custom range' button
           */
          this.customRangeButtonLabel = 'Custom Range';
      }
  }
  BsDatepickerConfig.ɵprov = ɵɵdefineInjectable({ factory: function BsDatepickerConfig_Factory() { return new BsDatepickerConfig(); }, token: BsDatepickerConfig, providedIn: "root" });
  BsDatepickerConfig.decorators = [
      { type: Injectable, args: [{
                  providedIn: 'root'
              },] }
  ];
  
  const DATEPICKER_ANIMATION_TIMING = '220ms cubic-bezier(0, 0, 0.2, 1)';
  const datepickerAnimation = trigger('datepickerAnimation', [
      state('animated-down', style({ height: '*', overflow: 'hidden' })),
      transition('* => animated-down', [
          style({ height: 0, overflow: 'hidden' }),
          animate(DATEPICKER_ANIMATION_TIMING)
      ]),
      state('animated-up', style({ height: '*', overflow: 'hidden' })),
      transition('* => animated-up', [
          style({ height: '*', overflow: 'hidden' }),
          animate(DATEPICKER_ANIMATION_TIMING)
      ]),
      transition('* => unanimated', animate('0s'))
  ]);
  
  class BsDatepickerAbstractComponent {
      constructor() {
          this.containerClass = '';
          this.customRanges = [];
          this.chosenRange = [];
          this._daysCalendarSub = new Subscription();
      }
      set minDate(value) {
          var _a;
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setMinDate(value);
      }
      set maxDate(value) {
          var _a;
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setMaxDate(value);
      }
      set daysDisabled(value) {
          var _a;
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setDaysDisabled(value);
      }
      set datesDisabled(value) {
          var _a;
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setDatesDisabled(value);
      }
      set datesEnabled(value) {
          var _a;
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setDatesEnabled(value);
      }
      set isDisabled(value) {
          var _a;
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setDisabled(value);
      }
      set dateCustomClasses(value) {
          var _a;
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setDateCustomClasses(value);
      }
      set dateTooltipTexts(value) {
          var _a;
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setDateTooltipTexts(value);
      }
      set daysCalendar$(value) {
          this._daysCalendar$ = value;
          this._daysCalendarSub.unsubscribe();
          this._daysCalendarSub.add(this._daysCalendar$.subscribe(value => {
              this.multipleCalendars = !!value && value.length > 1;
          }));
      }
      get daysCalendar$() {
          return this._daysCalendar$;
      }
      // todo: valorkin fix
      // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function
      setViewMode(event) { }
      // eslint-disable-next-line
      navigateTo(event) { }
      // eslint-disable-next-line
      dayHoverHandler(event) { }
      // eslint-disable-next-line
      weekHoverHandler(event) { }
      // eslint-disable-next-line
      monthHoverHandler(event) { }
      // eslint-disable-next-line
      yearHoverHandler(event) { }
      // eslint-disable-next-line
      daySelectHandler(day) { }
      // eslint-disable-next-line
      monthSelectHandler(event) { }
      // eslint-disable-next-line
      yearSelectHandler(event) { }
      // eslint-disable-next-line
      setRangeOnCalendar(dates) { }
      // eslint-disable-next-line
      setToday() { }
      // eslint-disable-next-line
      clearDate() { }
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      _stopPropagation(event) {
          event.stopPropagation();
      }
  }
  
  class BsDatepickerActions {
      calculate() {
          return { type: BsDatepickerActions.CALCULATE };
      }
      format() {
          return { type: BsDatepickerActions.FORMAT };
      }
      flag() {
          return { type: BsDatepickerActions.FLAG };
      }
      select(date) {
          return {
              type: BsDatepickerActions.SELECT,
              payload: date
          };
      }
      changeViewMode(event) {
          return {
              type: BsDatepickerActions.CHANGE_VIEWMODE,
              payload: event
          };
      }
      navigateTo(event) {
          return {
              type: BsDatepickerActions.NAVIGATE_TO,
              payload: event
          };
      }
      navigateStep(step) {
          return {
              type: BsDatepickerActions.NAVIGATE_OFFSET,
              payload: step
          };
      }
      setOptions(options) {
          return {
              type: BsDatepickerActions.SET_OPTIONS,
              payload: options
          };
      }
      // date range picker
      selectRange(value) {
          return {
              type: BsDatepickerActions.SELECT_RANGE,
              payload: value
          };
      }
      hoverDay(event) {
          return {
              type: BsDatepickerActions.HOVER,
              payload: event.isHovered ? event.cell.date : null
          };
      }
      minDate(date) {
          return {
              type: BsDatepickerActions.SET_MIN_DATE,
              payload: date
          };
      }
      maxDate(date) {
          return {
              type: BsDatepickerActions.SET_MAX_DATE,
              payload: date
          };
      }
      daysDisabled(days) {
          return {
              type: BsDatepickerActions.SET_DAYSDISABLED,
              payload: days
          };
      }
      datesDisabled(dates) {
          return {
              type: BsDatepickerActions.SET_DATESDISABLED,
              payload: dates
          };
      }
      datesEnabled(dates) {
          return {
              type: BsDatepickerActions.SET_DATESENABLED,
              payload: dates
          };
      }
      isDisabled(value) {
          return {
              type: BsDatepickerActions.SET_IS_DISABLED,
              payload: value
          };
      }
      setDateCustomClasses(value) {
          return {
              type: BsDatepickerActions.SET_DATE_CUSTOM_CLASSES,
              payload: value
          };
      }
      setDateTooltipTexts(value) {
          return {
              type: BsDatepickerActions.SET_DATE_TOOLTIP_TEXTS,
              payload: value
          };
      }
      setLocale(locale) {
          return {
              type: BsDatepickerActions.SET_LOCALE,
              payload: locale
          };
      }
  }
  BsDatepickerActions.CALCULATE = '[datepicker] calculate dates matrix';
  BsDatepickerActions.FORMAT = '[datepicker] format datepicker values';
  BsDatepickerActions.FLAG = '[datepicker] set flags';
  BsDatepickerActions.SELECT = '[datepicker] select date';
  BsDatepickerActions.NAVIGATE_OFFSET = '[datepicker] shift view date';
  BsDatepickerActions.NAVIGATE_TO = '[datepicker] change view date';
  BsDatepickerActions.SET_OPTIONS = '[datepicker] update render options';
  BsDatepickerActions.HOVER = '[datepicker] hover date';
  BsDatepickerActions.CHANGE_VIEWMODE = '[datepicker] switch view mode';
  BsDatepickerActions.SET_MIN_DATE = '[datepicker] set min date';
  BsDatepickerActions.SET_MAX_DATE = '[datepicker] set max date';
  BsDatepickerActions.SET_DAYSDISABLED = '[datepicker] set days disabled';
  BsDatepickerActions.SET_DATESDISABLED = '[datepicker] set dates disabled';
  BsDatepickerActions.SET_DATESENABLED = '[datepicker] set dates enabled';
  BsDatepickerActions.SET_IS_DISABLED = '[datepicker] set is disabled';
  BsDatepickerActions.SET_DATE_CUSTOM_CLASSES = '[datepicker] set date custom classes';
  BsDatepickerActions.SET_DATE_TOOLTIP_TEXTS = '[datepicker] set date tooltip texts';
  BsDatepickerActions.SET_LOCALE = '[datepicker] set datepicker locale';
  BsDatepickerActions.SELECT_RANGE = '[daterangepicker] select dates range';
  BsDatepickerActions.decorators = [
      { type: Injectable }
  ];
  
  class BsLocaleService {
      constructor() {
          this._defaultLocale = 'en';
          this._locale = new BehaviorSubject(this._defaultLocale);
          this._localeChange = this._locale.asObservable();
      }
      get locale() {
          return this._locale;
      }
      get localeChange() {
          return this._localeChange;
      }
      get currentLocale() {
          return this._locale.getValue();
      }
      use(locale) {
          if (locale === this.currentLocale) {
              return;
          }
          this._locale.next(locale);
      }
  }
  BsLocaleService.decorators = [
      { type: Injectable }
  ];
  
  class BsDatepickerEffects {
      constructor(_actions, _localeService) {
          this._actions = _actions;
          this._localeService = _localeService;
          this._subs = [];
      }
      init(_bsDatepickerStore) {
          this._store = _bsDatepickerStore;
          return this;
      }
      /** setters */
      setValue(value) {
          var _a;
          (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.select(value));
      }
      setRangeValue(value) {
          var _a;
          (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.selectRange(value));
      }
      setMinDate(value) {
          var _a;
          (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.minDate(value));
          return this;
      }
      setMaxDate(value) {
          var _a;
          (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.maxDate(value));
          return this;
      }
      setDaysDisabled(value) {
          var _a;
          (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.daysDisabled(value));
          return this;
      }
      setDatesDisabled(value) {
          var _a;
          (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.datesDisabled(value));
          return this;
      }
      setDatesEnabled(value) {
          var _a;
          (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.datesEnabled(value));
          return this;
      }
      setDisabled(value) {
          var _a;
          (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.isDisabled(value));
          return this;
      }
      setDateCustomClasses(value) {
          var _a;
          (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.setDateCustomClasses(value));
          return this;
      }
      setDateTooltipTexts(value) {
          var _a;
          (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.setDateTooltipTexts(value));
          return this;
      }
      /* Set rendering options */
      setOptions(_config) {
          var _a;
          const _options = Object.assign({ locale: this._localeService.currentLocale }, _config);
          (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.setOptions(_options));
          return this;
      }
      /** view to mode bindings */
      setBindings(container) {
          if (!this._store) {
              return this;
          }
          container.daysCalendar$ = this._store.select(state => state.flaggedMonths)
              .pipe(filter(months => !!months));
          // month calendar
          container.monthsCalendar = this._store.select(state => state.flaggedMonthsCalendar)
              .pipe(filter(months => !!months));
          // year calendar
          container.yearsCalendar = this._store.select(state => state.yearsCalendarFlagged)
              .pipe(filter(years => !!years));
          container.viewMode = this._store.select(state => { var _a; return (_a = state.view) === null || _a === void 0 ? void 0 : _a.mode; });
          container.options$ = combineLatest([
              this._store.select(state => state.showWeekNumbers),
              this._store.select(state => state.displayMonths)
          ])
              .pipe(map((latest) => ({
              showWeekNumbers: latest[0],
              displayMonths: latest[1]
          })));
          return this;
      }
      /** event handlers */
      setEventHandlers(container) {
          container.setViewMode = (event) => {
              var _a;
              (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.changeViewMode(event));
          };
          container.navigateTo = (event) => {
              var _a;
              (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.navigateStep(event.step));
          };
          container.dayHoverHandler = (event) => {
              var _a;
              const _cell = event.cell;
              if (_cell.isOtherMonth || _cell.isDisabled) {
                  return;
              }
              (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.hoverDay(event));
              _cell.isHovered = event.isHovered;
          };
          container.monthHoverHandler = (event) => {
              event.cell.isHovered = event.isHovered;
          };
          container.yearHoverHandler = (event) => {
              event.cell.isHovered = event.isHovered;
          };
          return this;
      }
      registerDatepickerSideEffects() {
          if (!this._store) {
              return this;
          }
          this._subs.push(this._store.select(state => state.view).subscribe(() => {
              var _a;
              (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.calculate());
          }));
          // format calendar values on month model change
          this._subs.push(this._store
              .select(state => state.monthsModel)
              .pipe(filter(monthModel => !!monthModel))
              .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.format()); }));
          // flag day values
          this._subs.push(this._store
              .select(state => state.formattedMonths)
              .pipe(filter(month => !!month))
              .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
          // flag day values
          this._subs.push(this._store
              .select(state => state.selectedDate)
              .pipe(filter(selectedDate => !!selectedDate))
              .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
          // flag for date range picker
          this._subs.push(this._store
              .select(state => state.selectedRange)
              .pipe(filter(selectedRange => !!selectedRange))
              .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
          // monthsCalendar
          this._subs.push(this._store
              .select(state => state.monthsCalendar)
              .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
          // years calendar
          this._subs.push(this._store
              .select(state => state.yearsCalendarModel)
              .pipe(filter(state => !!state))
              .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
          // on hover
          this._subs.push(this._store
              .select(state => state.hoveredDate)
              .pipe(filter(hoveredDate => !!hoveredDate))
              .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
          // date custom classes
          this._subs.push(this._store
              .select(state => state.dateCustomClasses)
              .pipe(filter(dateCustomClasses => !!dateCustomClasses))
              .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
          // date tooltip texts
          this._subs.push(this._store
              .select(state => state.dateTooltipTexts)
              .pipe(filter(dateTooltipTexts => !!dateTooltipTexts))
              .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
          // on locale change
          this._subs.push(this._localeService.localeChange
              .subscribe(locale => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.setLocale(locale)); }));
          return this;
      }
      destroy() {
          for (const sub of this._subs) {
              sub.unsubscribe();
          }
      }
  }
  BsDatepickerEffects.decorators = [
      { type: Injectable }
  ];
  BsDatepickerEffects.ctorParameters = () => [
      { type: BsDatepickerActions },
      { type: BsLocaleService }
  ];
  
  const defaultMonthOptions = {
      width: 7,
      height: 6
  };
  const dayInMilliseconds = 24 * 60 * 60 * 1000;
  
  class BsDatepickerState {
      constructor() {
          // DatepickerRenderOptions
          this.showWeekNumbers = true;
          this.displayMonths = 1;
      }
  }
  const _initialView = { date: new Date(), mode: 'day' };
  const initialDatepickerState = Object.assign(new BsDatepickerConfig(), {
      locale: 'en',
      view: _initialView,
      selectedRange: [],
      monthViewOptions: defaultMonthOptions
  });
  
  function getStartingDayOfCalendar(date, options) {
      if (isFirstDayOfWeek(date, options.firstDayOfWeek)) {
          return date;
      }
      const weekDay = getDay(date);
      const offset = calculateDateOffset(weekDay, options.firstDayOfWeek);
      return shiftDate(date, { day: -offset });
  }
  function calculateDateOffset(weekday, startingDayOffset) {
      const _startingDayOffset = Number(startingDayOffset);
      if (isNaN(_startingDayOffset)) {
          return 0;
      }
      if (_startingDayOffset === 0) {
          return weekday;
      }
      const offset = weekday - _startingDayOffset % 7;
      return offset < 0 ? offset + 7 : offset;
  }
  function isMonthDisabled(date, min, max) {
      const minBound = min && isBefore(endOf(date, 'month'), min, 'day');
      const maxBound = max && isAfter(startOf(date, 'month'), max, 'day');
      return minBound || maxBound || false;
  }
  function isYearDisabled(date, min, max) {
      const minBound = min && isBefore(endOf(date, 'year'), min, 'day');
      const maxBound = max && isAfter(startOf(date, 'year'), max, 'day');
      return minBound || maxBound || false;
  }
  function isDisabledDate(date, datesDisabled) {
      if (!datesDisabled || !isArray(datesDisabled) || !datesDisabled.length) {
          return false;
      }
      return datesDisabled.some((dateDisabled) => isSame(date, dateDisabled, 'date'));
  }
  function isEnabledDate(date, datesEnabled) {
      if (!datesEnabled || !isArray(datesEnabled) || !datesEnabled.length) {
          return false;
      }
      return !datesEnabled.some((enabledDate) => isSame(date, enabledDate, 'date'));
  }
  function getYearsCalendarInitialDate(state, calendarIndex = 0) {
      const model = state && state.yearsCalendarModel && state.yearsCalendarModel[calendarIndex];
      return (model === null || model === void 0 ? void 0 : model.years[0]) && model.years[0][0] && model.years[0][0].date;
  }
  function checkRangesWithMaxDate(ranges, maxDate) {
      if (!ranges)
          return ranges;
      if (!maxDate)
          return ranges;
      if (!ranges.length && !ranges[0].value)
          return ranges;
      ranges.forEach((item) => {
          if (!item || !item.value)
              return ranges;
          if (item.value instanceof Date)
              return ranges;
          if (!(item.value instanceof Array && item.value.length))
              return ranges;
          item.value = compareDateWithMaxDateHelper(item.value, maxDate);
          return ranges;
      });
      return ranges;
  }
  function checkBsValue(date, maxDate) {
      if (!date)
          return date;
      if (!maxDate)
          return date;
      if (date instanceof Array && !date.length)
          return date;
      if (date instanceof Date)
          return date;
      return compareDateWithMaxDateHelper(date, maxDate);
  }
  function compareDateWithMaxDateHelper(date, maxDate) {
      if (date instanceof Array) {
          const editedValues = date.map(item => {
              if (!item)
                  return item;
              if (isAfter(item, maxDate, 'date'))
                  item = maxDate;
              return item;
          });
          return editedValues;
      }
      return date;
  }
  
  function createMatrix(options, fn) {
      let prevValue = options.initialDate;
      const matrix = new Array(options.height);
      for (let i = 0; i < options.height; i++) {
          matrix[i] = new Array(options.width);
          for (let j = 0; j < options.width; j++) {
              matrix[i][j] = fn(prevValue);
              prevValue = shiftDate(prevValue, options.shift);
          }
      }
      return matrix;
  }
  
  // user and model input should handle parsing and validating input values
  function calcDaysCalendar(startingDate, options) {
      const firstDay = getFirstDayOfMonth(startingDate);
      const initialDate = getStartingDayOfCalendar(firstDay, options);
      // todo test
      const matrixOptions = {
          width: options.width || 0,
          height: options.height || 0,
          initialDate,
          shift: { day: 1 }
      };
      const daysMatrix = createMatrix(matrixOptions, date => date);
      return {
          daysMatrix,
          month: firstDay
      };
  }
  
  function formatDaysCalendar(daysCalendar, formatOptions, monthIndex) {
      return {
          month: daysCalendar.month,
          monthTitle: formatDate(daysCalendar.month, formatOptions.monthTitle, formatOptions.locale),
          yearTitle: formatDate(daysCalendar.month, formatOptions.yearTitle, formatOptions.locale),
          weekNumbers: getWeekNumbers(daysCalendar.daysMatrix, formatOptions.weekNumbers, formatOptions.locale),
          weekdays: getShiftedWeekdays(formatOptions.locale),
          weeks: daysCalendar.daysMatrix.map((week, weekIndex) => ({
              days: week.map((date, dayIndex) => ({
                  date,
                  label: formatDate(date, formatOptions.dayLabel, formatOptions.locale),
                  monthIndex,
                  weekIndex,
                  dayIndex
              }))
          })),
          hideLeftArrow: false,
          hideRightArrow: false,
          disableLeftArrow: false,
          disableRightArrow: false
      };
  }
  function getWeekNumbers(daysMatrix, format, locale) {
      return daysMatrix.map((days) => (days[0] ? formatDate(days[0], format, locale) : ''));
  }
  function getShiftedWeekdays(locale) {
      const _locale = getLocale(locale);
      const weekdays = _locale.weekdaysShort();
      const firstDayOfWeek = _locale.firstDayOfWeek();
      return [...weekdays.slice(firstDayOfWeek), ...weekdays.slice(0, firstDayOfWeek)];
  }
  
  function flagDaysCalendar(formattedMonth, options) {
      formattedMonth.weeks.forEach((week) => {
          week.days.forEach((day, dayIndex) => {
              // datepicker
              const isOtherMonth = !isSameMonth(day.date, formattedMonth.month);
              const isHovered = !isOtherMonth && isSameDay(day.date, options.hoveredDate);
              // date range picker
              const isSelectionStart = !isOtherMonth &&
                  options.selectedRange &&
                  isSameDay(day.date, options.selectedRange[0]);
              const isSelectionEnd = !isOtherMonth &&
                  options.selectedRange &&
                  isSameDay(day.date, options.selectedRange[1]);
              const isSelected = (!isOtherMonth && isSameDay(day.date, options.selectedDate)) ||
                  isSelectionStart ||
                  isSelectionEnd;
              const isInRange = !isOtherMonth &&
                  options.selectedRange &&
                  isDateInRange(day.date, options.selectedRange, options.hoveredDate);
              const isDisabled = options.isDisabled ||
                  isBefore(day.date, options.minDate, 'day') ||
                  isAfter(day.date, options.maxDate, 'day') ||
                  isDisabledDay(day.date, options.daysDisabled) ||
                  isDisabledDate(day.date, options.datesDisabled) ||
                  isEnabledDate(day.date, options.datesEnabled);
              const currentDate = new Date();
              const isToday = !isOtherMonth && isSameDay(day.date, currentDate);
              const customClasses = options.dateCustomClasses && options.dateCustomClasses
                  .map(dcc => isSameDay(day.date, dcc.date) ? dcc.classes : [])
                  .reduce((previousValue, currentValue) => previousValue.concat(currentValue), [])
                  .join(' ')
                  || '';
              const tooltipText = options.dateTooltipTexts && options.dateTooltipTexts
                  .map(tt => isSameDay(day.date, tt.date) ? tt.tooltipText : '')
                  .reduce((previousValue, currentValue) => {
                  previousValue.push(currentValue);
                  return previousValue;
              }, [])
                  .join(' ')
                  || '';
              // decide update or not
              const newDay = Object.assign({}, day, {
                  isOtherMonth,
                  isHovered,
                  isSelected,
                  isSelectionStart,
                  isSelectionEnd,
                  isInRange,
                  isDisabled,
                  isToday,
                  customClasses,
                  tooltipText
              });
              if (day.isOtherMonth !== newDay.isOtherMonth ||
                  day.isHovered !== newDay.isHovered ||
                  day.isSelected !== newDay.isSelected ||
                  day.isSelectionStart !== newDay.isSelectionStart ||
                  day.isSelectionEnd !== newDay.isSelectionEnd ||
                  day.isDisabled !== newDay.isDisabled ||
                  day.isInRange !== newDay.isInRange ||
                  day.customClasses !== newDay.customClasses ||
                  day.tooltipText !== newDay.tooltipText) {
                  week.days[dayIndex] = newDay;
              }
          });
      });
      // todo: add check for linked calendars
      formattedMonth.hideLeftArrow =
          options.isDisabled ||
              (!!options.monthIndex && options.monthIndex > 0 && options.monthIndex !== options.displayMonths);
      formattedMonth.hideRightArrow =
          options.isDisabled ||
              ((!!options.monthIndex || options.monthIndex === 0) && !!options.displayMonths && options.monthIndex < options.displayMonths &&
                  options.monthIndex + 1 !== options.displayMonths);
      formattedMonth.disableLeftArrow = isMonthDisabled(shiftDate(formattedMonth.month, { month: -1 }), options.minDate, options.maxDate);
      formattedMonth.disableRightArrow = isMonthDisabled(shiftDate(formattedMonth.month, { month: 1 }), options.minDate, options.maxDate);
      return formattedMonth;
  }
  function isDateInRange(date, selectedRange, hoveredDate) {
      if (!date || !selectedRange || !selectedRange[0]) {
          return false;
      }
      if (selectedRange[1]) {
          return date > selectedRange[0] && date <= selectedRange[1];
      }
      if (hoveredDate) {
          return date > selectedRange[0] && date <= hoveredDate;
      }
      return false;
  }
  
  function canSwitchMode(mode, minMode) {
      return minMode ? mode >= minMode : true;
  }
  
  const height = 4;
  const width = 3;
  const shift = { month: 1 };
  function formatMonthsCalendar(viewDate, formatOptions) {
      const initialDate = startOf(viewDate, 'year');
      const matrixOptions = { width, height, initialDate, shift };
      const monthMatrix = createMatrix(matrixOptions, date => ({
          date,
          label: formatDate(date, formatOptions.monthLabel, formatOptions.locale)
      }));
      return {
          months: monthMatrix,
          monthTitle: '',
          yearTitle: formatDate(viewDate, formatOptions.yearTitle, formatOptions.locale),
          hideRightArrow: false,
          hideLeftArrow: false,
          disableRightArrow: false,
          disableLeftArrow: false
      };
  }
  
  function flagMonthsCalendar(monthCalendar, options) {
      monthCalendar.months.forEach((months, rowIndex) => {
          months.forEach((month, monthIndex) => {
              let isSelected;
              const isHovered = isSameMonth(month.date, options.hoveredMonth);
              const isDisabled = options.isDisabled ||
                  isMonthDisabled(month.date, options.minDate, options.maxDate);
              if (!options.selectedDate && options.selectedRange) {
                  isSelected = isSameMonth(month.date, options.selectedRange[0]);
                  if (!isSelected) {
                      isSelected = isSameMonth(month.date, options.selectedRange[1]);
                  }
              }
              else {
                  isSelected = isSameMonth(month.date, options.selectedDate);
              }
              const newMonth = Object.assign(/*{},*/ month, {
                  isHovered,
                  isDisabled,
                  isSelected
              });
              if (month.isHovered !== newMonth.isHovered ||
                  month.isDisabled !== newMonth.isDisabled ||
                  month.isSelected !== newMonth.isSelected) {
                  monthCalendar.months[rowIndex][monthIndex] = newMonth;
              }
          });
      });
      // todo: add check for linked calendars
      monthCalendar.hideLeftArrow =
          !!options.monthIndex && options.monthIndex > 0 && options.monthIndex !== options.displayMonths;
      monthCalendar.hideRightArrow =
          (!!options.monthIndex || options.monthIndex === 0)
              && (!!options.displayMonths || options.displayMonths === 0)
              && options.monthIndex < options.displayMonths
              && options.monthIndex + 1 !== options.displayMonths;
      monthCalendar.disableLeftArrow = isYearDisabled(shiftDate(monthCalendar.months[0][0].date, { year: -1 }), options.minDate, options.maxDate);
      monthCalendar.disableRightArrow = isYearDisabled(shiftDate(monthCalendar.months[0][0].date, { year: 1 }), options.minDate, options.maxDate);
      return monthCalendar;
  }
  
  const height$1 = 4;
  const width$1 = 4;
  const yearsPerCalendar = height$1 * width$1;
  const initialYearShift = (Math.floor(yearsPerCalendar / 2) - 1) * -1;
  const shift$1 = { year: 1 };
  function formatYearsCalendar(viewDate, formatOptions, previousInitialDate) {
      const initialDate = calculateInitialDate(viewDate, previousInitialDate);
      const matrixOptions = { width: width$1, height: height$1, initialDate, shift: shift$1 };
      const yearsMatrix = createMatrix(matrixOptions, date => ({
          date,
          label: formatDate(date, formatOptions.yearLabel, formatOptions.locale)
      }));
      const yearTitle = formatYearRangeTitle(yearsMatrix, formatOptions);
      return {
          years: yearsMatrix,
          monthTitle: '',
          yearTitle,
          hideLeftArrow: false,
          hideRightArrow: false,
          disableLeftArrow: false,
          disableRightArrow: false
      };
  }
  function calculateInitialDate(viewDate, previousInitialDate) {
      if (previousInitialDate
          && viewDate.getFullYear() >= previousInitialDate.getFullYear()
          && viewDate.getFullYear() < previousInitialDate.getFullYear() + yearsPerCalendar) {
          return previousInitialDate;
      }
      return shiftDate(viewDate, { year: initialYearShift });
  }
  function formatYearRangeTitle(yearsMatrix, formatOptions) {
      const from = formatDate(yearsMatrix[0][0].date, formatOptions.yearTitle, formatOptions.locale);
      const to = formatDate(yearsMatrix[height$1 - 1][width$1 - 1].date, formatOptions.yearTitle, formatOptions.locale);
      return `${from} - ${to}`;
  }
  
  function flagYearsCalendar(yearsCalendar, options) {
      yearsCalendar.years.forEach((years, rowIndex) => {
          years.forEach((year, yearIndex) => {
              let isSelected;
              const isHovered = isSameYear(year.date, options.hoveredYear);
              const isDisabled = options.isDisabled ||
                  isYearDisabled(year.date, options.minDate, options.maxDate);
              if (!options.selectedDate && options.selectedRange) {
                  isSelected = isSameYear(year.date, options.selectedRange[0]);
                  if (!isSelected) {
                      isSelected = isSameYear(year.date, options.selectedRange[1]);
                  }
              }
              else {
                  isSelected = isSameYear(year.date, options.selectedDate);
              }
              const newMonth = Object.assign(/*{},*/ year, { isHovered, isDisabled, isSelected });
              if (year.isHovered !== newMonth.isHovered ||
                  year.isDisabled !== newMonth.isDisabled ||
                  year.isSelected !== newMonth.isSelected) {
                  yearsCalendar.years[rowIndex][yearIndex] = newMonth;
              }
          });
      });
      // todo: add check for linked calendars
      yearsCalendar.hideLeftArrow =
          !!options.yearIndex && options.yearIndex > 0 && options.yearIndex !== options.displayMonths;
      yearsCalendar.hideRightArrow =
          !!options.yearIndex && !!options.displayMonths &&
              options.yearIndex < options.displayMonths &&
              options.yearIndex + 1 !== options.displayMonths;
      yearsCalendar.disableLeftArrow = isYearDisabled(shiftDate(yearsCalendar.years[0][0].date, { year: -1 }), options.minDate, options.maxDate);
      const i = yearsCalendar.years.length - 1;
      const j = yearsCalendar.years[i].length - 1;
      yearsCalendar.disableRightArrow = isYearDisabled(shiftDate(yearsCalendar.years[i][j].date, { year: 1 }), options.minDate, options.maxDate);
      return yearsCalendar;
  }
  
  function bsDatepickerReducer(state = initialDatepickerState, action) {
      switch (action.type) {
          case BsDatepickerActions.CALCULATE: {
              return calculateReducer(state);
          }
          case BsDatepickerActions.FORMAT: {
              return formatReducer(state);
          }
          case BsDatepickerActions.FLAG: {
              return flagReducer(state);
          }
          case BsDatepickerActions.NAVIGATE_OFFSET: {
              return navigateOffsetReducer(state, action);
          }
          case BsDatepickerActions.NAVIGATE_TO: {
              const payload = action.payload;
              if (!state.view || !payload.unit) {
                  return state;
              }
              const date = setFullDate(state.view.date, payload.unit);
              let newState;
              let mode;
              if (canSwitchMode(payload.viewMode, state.minMode)) {
                  mode = payload.viewMode;
                  newState = { view: { date, mode } };
              }
              else {
                  mode = state.view.mode;
                  newState = { selectedDate: date, view: { date, mode } };
              }
              return Object.assign({}, state, newState);
          }
          case BsDatepickerActions.CHANGE_VIEWMODE: {
              if (!canSwitchMode(action.payload, state.minMode) || !state.view) {
                  return state;
              }
              const date = state.view.date;
              const mode = action.payload;
              const newState = { view: { date, mode } };
              return Object.assign({}, state, newState);
          }
          case BsDatepickerActions.HOVER: {
              return Object.assign({}, state, { hoveredDate: action.payload });
          }
          case BsDatepickerActions.SELECT: {
              if (!state.view) {
                  return state;
              }
              const newState = {
                  selectedDate: action.payload,
                  view: state.view
              };
              const mode = state.view.mode;
              const _date = action.payload || state.view.date;
              const date = getViewDate(_date, state.minDate, state.maxDate);
              newState.view = { mode, date };
              return Object.assign({}, state, newState);
          }
          case BsDatepickerActions.SET_OPTIONS: {
              if (!state.view) {
                  return state;
              }
              const newState = action.payload;
              // preserve view mode
              const mode = newState.minMode ? newState.minMode : state.view.mode;
              const _viewDate = isDateValid(newState.value) && newState.value
                  || isArray(newState.value) && isDateValid(newState.value[0]) && newState.value[0]
                  || state.view.date;
              const date = getViewDate(_viewDate, newState.minDate, newState.maxDate);
              newState.view = { mode, date };
              // update selected value
              if (newState.value) {
                  // if new value is array we work with date range
                  if (isArray(newState.value)) {
                      newState.selectedRange = newState.value;
                  }
                  // if new value is a date -> datepicker
                  if (newState.value instanceof Date) {
                      newState.selectedDate = newState.value;
                  }
                  // provided value is not supported :)
                  // need to report it somehow
              }
              return Object.assign({}, state, newState);
          }
          // date range picker
          case BsDatepickerActions.SELECT_RANGE: {
              if (!state.view) {
                  return state;
              }
              const newState = {
                  selectedRange: action.payload,
                  view: state.view
              };
              const mode = state.view.mode;
              const _date = action.payload && action.payload[0] || state.view.date;
              const date = getViewDate(_date, state.minDate, state.maxDate);
              newState.view = { mode, date };
              return Object.assign({}, state, newState);
          }
          case BsDatepickerActions.SET_MIN_DATE: {
              return Object.assign({}, state, {
                  minDate: action.payload
              });
          }
          case BsDatepickerActions.SET_MAX_DATE: {
              return Object.assign({}, state, {
                  maxDate: action.payload
              });
          }
          case BsDatepickerActions.SET_IS_DISABLED: {
              return Object.assign({}, state, {
                  isDisabled: action.payload
              });
          }
          case BsDatepickerActions.SET_DATE_CUSTOM_CLASSES: {
              return Object.assign({}, state, {
                  dateCustomClasses: action.payload
              });
          }
          case BsDatepickerActions.SET_DATE_TOOLTIP_TEXTS: {
              return Object.assign({}, state, {
                  dateTooltipTexts: action.payload
              });
          }
          default:
              return state;
      }
  }
  function calculateReducer(state) {
      if (!state.view) {
          return state;
      }
      // how many calendars
      let displayMonths;
      if (state.displayOneMonthRange &&
          isDisplayOneMonth(state.view.date, state.minDate, state.maxDate)) {
          displayMonths = 1;
      }
      else {
          displayMonths = state.displayMonths || 1;
      }
      // use selected date on initial rendering if set
      let viewDate = state.view.date;
      if (state.view.mode === 'day' && state.monthViewOptions) {
          if (state.showPreviousMonth && state.selectedRange && state.selectedRange.length === 0) {
              viewDate = shiftDate(viewDate, { month: -1 });
          }
          state.monthViewOptions.firstDayOfWeek = getLocale(state.locale).firstDayOfWeek();
          let monthsModel = new Array(displayMonths);
          for (let monthIndex = 0; monthIndex < displayMonths; monthIndex++) {
              // todo: for unlinked calendars it will be harder
              monthsModel[monthIndex] = calcDaysCalendar(viewDate, state.monthViewOptions);
              viewDate = shiftDate(viewDate, { month: 1 });
          }
          // Check if parameter enabled and check if it's not months navigation event
          if (state.preventChangeToNextMonth && state.flaggedMonths && state.hoveredDate) {
              const viewMonth = calcDaysCalendar(state.view.date, state.monthViewOptions);
              // Check if viewed right month same as in flaggedMonths state, then override months model with flaggedMonths
              if (state.flaggedMonths.length && state.flaggedMonths[1].month.getMonth() === viewMonth.month.getMonth()) {
                  monthsModel = state.flaggedMonths
                      .map(item => {
                      if (state.monthViewOptions) {
                          return calcDaysCalendar(item.month, state.monthViewOptions);
                      }
                      return null;
                  })
                      .filter(item => item !== null);
              }
          }
          return Object.assign({}, state, { monthsModel });
      }
      if (state.view.mode === 'month') {
          const monthsCalendar = new Array(displayMonths);
          for (let calendarIndex = 0; calendarIndex < displayMonths; calendarIndex++) {
              // todo: for unlinked calendars it will be harder
              monthsCalendar[calendarIndex] = formatMonthsCalendar(viewDate, getFormatOptions(state));
              viewDate = shiftDate(viewDate, { year: 1 });
          }
          return Object.assign({}, state, { monthsCalendar });
      }
      if (state.view.mode === 'year') {
          const yearsCalendarModel = new Array(displayMonths);
          for (let calendarIndex = 0; calendarIndex < displayMonths; calendarIndex++) {
              // todo: for unlinked calendars it will be harder
              yearsCalendarModel[calendarIndex] = formatYearsCalendar(viewDate, getFormatOptions(state), state.minMode === 'year' ? getYearsCalendarInitialDate(state, calendarIndex) : undefined);
              viewDate = shiftDate(viewDate, { year: yearsPerCalendar });
          }
          return Object.assign({}, state, { yearsCalendarModel });
      }
      return state;
  }
  function formatReducer(state) {
      if (!state.view) {
          return state;
      }
      if (state.view.mode === 'day' && state.monthsModel) {
          const formattedMonths = state.monthsModel.map((month, monthIndex) => formatDaysCalendar(month, getFormatOptions(state), monthIndex));
          return Object.assign({}, state, { formattedMonths });
      }
      // how many calendars
      const displayMonths = state.displayMonths || 1;
      // check initial rendering
      // use selected date on initial rendering if set
      let viewDate = state.view.date;
      if (state.view.mode === 'month') {
          const monthsCalendar = new Array(displayMonths);
          for (let calendarIndex = 0; calendarIndex < displayMonths; calendarIndex++) {
              // todo: for unlinked calendars it will be harder
              monthsCalendar[calendarIndex] = formatMonthsCalendar(viewDate, getFormatOptions(state));
              viewDate = shiftDate(viewDate, { year: 1 });
          }
          return Object.assign({}, state, { monthsCalendar });
      }
      if (state.view.mode === 'year') {
          const yearsCalendarModel = new Array(displayMonths);
          for (let calendarIndex = 0; calendarIndex < displayMonths; calendarIndex++) {
              // todo: for unlinked calendars it will be harder
              yearsCalendarModel[calendarIndex] = formatYearsCalendar(viewDate, getFormatOptions(state));
              viewDate = shiftDate(viewDate, { year: 16 });
          }
          return Object.assign({}, state, { yearsCalendarModel });
      }
      return state;
  }
  function flagReducer(state) {
      if (!state.view) {
          return state;
      }
      const displayMonths = isDisplayOneMonth(state.view.date, state.minDate, state.maxDate) ? 1 : state.displayMonths;
      if (state.formattedMonths && state.view.mode === 'day') {
          const flaggedMonths = state.formattedMonths.map((formattedMonth, monthIndex) => flagDaysCalendar(formattedMonth, {
              isDisabled: state.isDisabled,
              minDate: state.minDate,
              maxDate: state.maxDate,
              daysDisabled: state.daysDisabled,
              datesDisabled: state.datesDisabled,
              datesEnabled: state.datesEnabled,
              hoveredDate: state.hoveredDate,
              selectedDate: state.selectedDate,
              selectedRange: state.selectedRange,
              displayMonths,
              dateCustomClasses: state.dateCustomClasses,
              dateTooltipTexts: state.dateTooltipTexts,
              monthIndex
          }));
          return Object.assign({}, state, { flaggedMonths });
      }
      if (state.view.mode === 'month' && state.monthsCalendar) {
          const flaggedMonthsCalendar = state.monthsCalendar.map((formattedMonth, monthIndex) => flagMonthsCalendar(formattedMonth, {
              isDisabled: state.isDisabled,
              minDate: state.minDate,
              maxDate: state.maxDate,
              hoveredMonth: state.hoveredMonth,
              selectedDate: state.selectedDate,
              selectedRange: state.selectedRange,
              displayMonths,
              monthIndex
          }));
          return Object.assign({}, state, { flaggedMonthsCalendar });
      }
      if (state.view.mode === 'year' && state.yearsCalendarModel) {
          const yearsCalendarFlagged = state.yearsCalendarModel.map((formattedMonth, yearIndex) => flagYearsCalendar(formattedMonth, {
              isDisabled: state.isDisabled,
              minDate: state.minDate,
              maxDate: state.maxDate,
              hoveredYear: state.hoveredYear,
              selectedDate: state.selectedDate,
              selectedRange: state.selectedRange,
              displayMonths,
              yearIndex
          }));
          return Object.assign({}, state, { yearsCalendarFlagged });
      }
      return state;
  }
  function navigateOffsetReducer(state, action) {
      if (!state.view) {
          return state;
      }
      const date = shiftViewDate(state, action);
      if (!date) {
          return state;
      }
      const newState = {
          view: {
              mode: state.view.mode,
              date
          }
      };
      return Object.assign({}, state, newState);
  }
  function shiftViewDate(state, action) {
      if (!state.view) {
          return undefined;
      }
      if (state.view.mode === 'year' && state.minMode === 'year') {
          const initialDate = getYearsCalendarInitialDate(state, 0);
          if (initialDate) {
              const middleDate = shiftDate(initialDate, { year: -initialYearShift });
              return shiftDate(middleDate, action.payload);
          }
      }
      return shiftDate(startOf(state.view.date, 'month'), action.payload);
  }
  function getFormatOptions(state) {
      return {
          locale: state.locale,
          monthTitle: state.monthTitle,
          yearTitle: state.yearTitle,
          dayLabel: state.dayLabel,
          monthLabel: state.monthLabel,
          yearLabel: state.yearLabel,
          weekNumbers: state.weekNumbers
      };
  }
  /**
   * if view date is provided (bsValue|ngModel) it should be shown
   * if view date is not provider:
   * if minDate>currentDate (default view value), show minDate
   * if maxDate<currentDate(default view value) show maxDate
   */
  function getViewDate(viewDate, minDate, maxDate) {
      const _date = Array.isArray(viewDate) ? viewDate[0] : viewDate;
      if (minDate && isAfter(minDate, _date, 'day')) {
          return minDate;
      }
      if (maxDate && isBefore(maxDate, _date, 'day')) {
          return maxDate;
      }
      return _date;
  }
  function isDisplayOneMonth(viewDate, minDate, maxDate) {
      if (maxDate && isSame(maxDate, viewDate, 'day')) {
          return true;
      }
      return minDate && maxDate && minDate.getMonth() === maxDate.getMonth();
  }
  
  class BsDatepickerStore extends MiniStore {
      constructor() {
          const _dispatcher = new BehaviorSubject({
              type: '[datepicker] dispatcher init'
          });
          const state = new MiniState(initialDatepickerState, _dispatcher, bsDatepickerReducer);
          super(_dispatcher, bsDatepickerReducer, state);
      }
  }
  BsDatepickerStore.decorators = [
      { type: Injectable }
  ];
  BsDatepickerStore.ctorParameters = () => [];
  
  class BsDatepickerContainerComponent extends BsDatepickerAbstractComponent {
      constructor(_renderer, _config, _store, _element, _actions, _effects, _positionService) {
          super();
          this._config = _config;
          this._store = _store;
          this._element = _element;
          this._actions = _actions;
          this._positionService = _positionService;
          this.valueChange = new EventEmitter();
          this.animationState = 'void';
          this._subs = [];
          this._effects = _effects;
          _renderer.setStyle(_element.nativeElement, 'display', 'block');
          _renderer.setStyle(_element.nativeElement, 'position', 'absolute');
      }
      set value(value) {
          var _a;
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setValue(value);
      }
      ngOnInit() {
          var _a, _b;
          this._positionService.setOptions({
              modifiers: { flip: { enabled: this._config.adaptivePosition } },
              allowedPositions: ['top', 'bottom']
          });
          (_a = this._positionService.event$) === null || _a === void 0 ? void 0 : _a.pipe(take(1)).subscribe(() => {
              this._positionService.disable();
              if (this._config.isAnimated) {
                  this.animationState = this.isTopPosition ? 'animated-up' : 'animated-down';
                  return;
              }
              this.animationState = 'unanimated';
          });
          this.isOtherMonthsActive = this._config.selectFromOtherMonth;
          this.containerClass = this._config.containerClass;
          this.showTodayBtn = this._config.showTodayButton;
          this.todayBtnLbl = this._config.todayButtonLabel;
          this.todayPos = this._config.todayPosition;
          this.showClearBtn = this._config.showClearButton;
          this.clearBtnLbl = this._config.clearButtonLabel;
          this.clearPos = this._config.clearPosition;
          this.customRangeBtnLbl = this._config.customRangeButtonLabel;
          (_b = this._effects) === null || _b === void 0 ? void 0 : _b.init(this._store).setOptions(this._config).setBindings(this).setEventHandlers(this).registerDatepickerSideEffects();
          // todo: move it somewhere else
          // on selected date change
          this._subs.push(this._store
              // eslint-disable-next-line @typescript-eslint/no-explicit-any
              .select((state) => state.selectedDate)
              // eslint-disable-next-line @typescript-eslint/no-explicit-any
              .subscribe((date) => this.valueChange.emit(date)));
          this._store.dispatch(this._actions.changeViewMode(this._config.startView));
      }
      get isTopPosition() {
          return this._element.nativeElement.classList.contains('top');
      }
      positionServiceEnable() {
          this._positionService.enable();
      }
      daySelectHandler(day) {
          if (!day) {
              return;
          }
          const isDisabled = this.isOtherMonthsActive ? day.isDisabled : (day.isOtherMonth || day.isDisabled);
          if (isDisabled) {
              return;
          }
          this._store.dispatch(this._actions.select(day.date));
      }
      monthSelectHandler(day) {
          if (!day || day.isDisabled) {
              return;
          }
          this._store.dispatch(this._actions.navigateTo({
              unit: {
                  month: getMonth(day.date),
                  year: getFullYear(day.date)
              },
              viewMode: 'day'
          }));
      }
      yearSelectHandler(day) {
          if (!day || day.isDisabled) {
              return;
          }
          this._store.dispatch(this._actions.navigateTo({
              unit: {
                  year: getFullYear(day.date)
              },
              viewMode: 'month'
          }));
      }
      setToday() {
          this._store.dispatch(this._actions.select(new Date()));
      }
      clearDate() {
          this._store.dispatch(this._actions.select(undefined));
      }
      ngOnDestroy() {
          var _a;
          for (const sub of this._subs) {
              sub.unsubscribe();
          }
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.destroy();
      }
  }
  BsDatepickerContainerComponent.decorators = [
      { type: Component, args: [{
                  selector: 'bs-datepicker-container',
                  providers: [BsDatepickerStore, BsDatepickerEffects],
                  template: "<!-- days calendar view mode -->\n<div class=\"bs-datepicker\" [ngClass]=\"containerClass\" *ngIf=\"viewMode | async\">\n  <div class=\"bs-datepicker-container\"\n    [@datepickerAnimation]=\"animationState\"\n    (@datepickerAnimation.done)=\"positionServiceEnable()\">\n    <!--calendars-->\n    <div class=\"bs-calendar-container\" [ngSwitch]=\"viewMode | async\" role=\"application\">\n      <!--days calendar-->\n      <div *ngSwitchCase=\"'day'\" class=\"bs-media-container\">\n        <bs-days-calendar-view\n          *ngFor=\"let calendar of daysCalendar$ | async\"\n          [class.bs-datepicker-multiple]=\"multipleCalendars\"\n          [calendar]=\"calendar\"\n          [options]=\"options$ | async\"\n          (onNavigate)=\"navigateTo($event)\"\n          (onViewMode)=\"setViewMode($event)\"\n          (onHover)=\"dayHoverHandler($event)\"\n          (onHoverWeek)=\"weekHoverHandler($event)\"\n          (onSelect)=\"daySelectHandler($event)\">\n        </bs-days-calendar-view>\n      </div>\n\n      <!--months calendar-->\n      <div *ngSwitchCase=\"'month'\" class=\"bs-media-container\">\n        <bs-month-calendar-view\n          *ngFor=\"let calendar of monthsCalendar | async\"\n          [class.bs-datepicker-multiple]=\"multipleCalendars\"\n          [calendar]=\"calendar\"\n          (onNavigate)=\"navigateTo($event)\"\n          (onViewMode)=\"setViewMode($event)\"\n          (onHover)=\"monthHoverHandler($event)\"\n          (onSelect)=\"monthSelectHandler($event)\">\n        </bs-month-calendar-view>\n      </div>\n\n      <!--years calendar-->\n      <div *ngSwitchCase=\"'year'\" class=\"bs-media-container\">\n        <bs-years-calendar-view\n          *ngFor=\"let calendar of yearsCalendar | async\"\n          [class.bs-datepicker-multiple]=\"multipleCalendars\"\n          [calendar]=\"calendar\"\n          (onNavigate)=\"navigateTo($event)\"\n          (onViewMode)=\"setViewMode($event)\"\n          (onHover)=\"yearHoverHandler($event)\"\n          (onSelect)=\"yearSelectHandler($event)\">\n        </bs-years-calendar-view>\n      </div>\n    </div>\n\n    <!--applycancel buttons-->\n    <div class=\"bs-datepicker-buttons\" *ngIf=\"false\">\n      <button class=\"btn btn-success\" type=\"button\">Apply</button>\n      <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n    </div>\n\n    <div class=\"bs-datepicker-buttons\" *ngIf=\"showTodayBtn || showClearBtn\">\n      <div class=\"btn-today-wrapper\"\n           [class.today-left]=\"todayPos === 'left'\"\n           [class.today-right]=\"todayPos === 'right'\"\n           [class.today-center]=\"todayPos === 'center'\"\n           *ngIf=\"showTodayBtn\">\n        <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n      </div>\n\n        <div class=\"btn-clear-wrapper\"\n        [class.clear-left]=\"clearPos === 'left'\"\n        [class.clear-right]=\"clearPos === 'right'\"\n        [class.clear-center]=\"clearPos === 'center'\"\n        *ngIf=\"showClearBtn\">\n          <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n        </div>\n    </div>\n\n  </div>\n\n  <!--custom dates or date ranges picker-->\n  <div class=\"bs-datepicker-custom-range\" *ngIf=\"customRanges && customRanges.length > 0\">\n    <bs-custom-date-view\n      [selectedRange]=\"chosenRange\"\n      [ranges]=\"customRanges\"\n      [customRangeLabel]=\"customRangeBtnLbl\"\n      (onSelect)=\"setRangeOnCalendar($event)\">\n    </bs-custom-date-view>\n  </div>\n</div>\n",
                  host: {
                      class: 'bottom',
                      '(click)': '_stopPropagation($event)',
                      role: 'dialog',
                      'aria-label': 'calendar'
                  },
                  animations: [datepickerAnimation]
              },] }
  ];
  BsDatepickerContainerComponent.ctorParameters = () => [
      { type: Renderer2 },
      { type: BsDatepickerConfig },
      { type: BsDatepickerStore },
      { type: ElementRef },
      { type: BsDatepickerActions },
      { type: BsDatepickerEffects },
      { type: PositioningService }
  ];
  
  class BsDatepickerDirective {
      constructor(_config, _elementRef, _renderer, _viewContainerRef, cis) {
          this._config = _config;
          this._elementRef = _elementRef;
          this._renderer = _renderer;
          /**
           * Placement of a datepicker. Accepts: "top", "bottom", "left", "right"
           */
          this.placement = 'bottom';
          /**
           * Specifies events that should trigger. Supports a space separated list of
           * event names.
           */
          this.triggers = 'click';
          /**
           * Close datepicker on outside click
           */
          this.outsideClick = true;
          /**
           * A selector specifying the element the datepicker should be appended to.
           */
          this.container = 'body';
          this.outsideEsc = true;
          this.isDestroy$ = new Subject();
          /**
           * Indicates whether datepicker's content is enabled or not
           */
          this.isDisabled = false;
          /**
           * Emits when datepicker value has been changed
           */
          this.bsValueChange = new EventEmitter();
          this._subs = [];
          this._dateInputFormat$ = new Subject();
          // todo: assign only subset of fields
          Object.assign(this, this._config);
          this._datepicker = cis.createLoader(_elementRef, _viewContainerRef, _renderer);
          this.onShown = this._datepicker.onShown;
          this.onHidden = this._datepicker.onHidden;
          this.isOpen$ = new BehaviorSubject(this.isOpen);
      }
      /**
       * Returns whether or not the datepicker is currently being shown
       */
      get isOpen() {
          return this._datepicker.isShown;
      }
      set isOpen(value) {
          this.isOpen$.next(value);
      }
      /**
       * Initial value of datepicker
       */
      set bsValue(value) {
          if (this._bsValue && value && this._bsValue.getTime() === value.getTime()) {
              return;
          }
          if (!this._bsValue && value) {
              const now = new Date();
              value.setMilliseconds(now.getMilliseconds());
              value.setSeconds(now.getSeconds());
              value.setMinutes(now.getMinutes());
              value.setHours(now.getHours());
          }
          this._bsValue = value;
          this.bsValueChange.emit(value);
      }
      get dateInputFormat$() {
          return this._dateInputFormat$;
      }
      get bsConfig() {
          return this._bsConfig;
      }
      /**
       * Config object for datepicker
       */
      set bsConfig(bsConfig) {
          this._bsConfig = bsConfig;
          this.setConfig();
          this._dateInputFormat$.next(bsConfig && bsConfig.dateInputFormat);
      }
      ngOnInit() {
          this._datepicker.listen({
              outsideClick: this.outsideClick,
              outsideEsc: this.outsideEsc,
              triggers: this.triggers,
              show: () => this.show()
          });
          this.setConfig();
      }
      ngOnChanges(changes) {
          if (!this._datepickerRef || !this._datepickerRef.instance) {
              return;
          }
          if (changes.minDate) {
              this._datepickerRef.instance.minDate = this.minDate;
          }
          if (changes.maxDate) {
              this._datepickerRef.instance.maxDate = this.maxDate;
          }
          if (changes.daysDisabled) {
              this._datepickerRef.instance.daysDisabled = this.daysDisabled;
          }
          if (changes.datesDisabled) {
              this._datepickerRef.instance.datesDisabled = this.datesDisabled;
          }
          if (changes.datesEnabled) {
              this._datepickerRef.instance.datesEnabled = this.datesEnabled;
          }
          if (changes.isDisabled) {
              this._datepickerRef.instance.isDisabled = this.isDisabled;
          }
          if (changes.dateCustomClasses) {
              this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
          }
          if (changes.dateTooltipTexts) {
              this._datepickerRef.instance.dateTooltipTexts = this.dateTooltipTexts;
          }
      }
      ngAfterViewInit() {
          this.isOpen$.pipe(filter(isOpen => isOpen !== this.isOpen), takeUntil(this.isDestroy$))
              .subscribe(() => this.toggle());
      }
      /**
       * Opens an element’s datepicker. This is considered a “manual” triggering of
       * the datepicker.
       */
      show() {
          if (this._datepicker.isShown) {
              return;
          }
          this.setConfig();
          this._datepickerRef = this._datepicker
              .provide({ provide: BsDatepickerConfig, useValue: this._config })
              .attach(BsDatepickerContainerComponent)
              .to(this.container)
              .position({ attachment: this.placement })
              .show({ placement: this.placement });
          // if date changes from external source (model -> view)
          this._subs.push(this.bsValueChange.subscribe((value) => {
              if (this._datepickerRef) {
                  this._datepickerRef.instance.value = value;
              }
          }));
          // if date changes from picker (view -> model)
          if (this._datepickerRef) {
              this._subs.push(this._datepickerRef.instance.valueChange.subscribe((value) => {
                  this.bsValue = value;
                  this.hide();
              }));
          }
      }
      /**
       * Closes an element’s datepicker. This is considered a “manual” triggering of
       * the datepicker.
       */
      hide() {
          if (this.isOpen) {
              this._datepicker.hide();
          }
          for (const sub of this._subs) {
              sub.unsubscribe();
          }
          if (this._config.returnFocusToInput) {
              this._renderer.selectRootElement(this._elementRef.nativeElement).focus();
          }
      }
      /**
       * Toggles an element’s datepicker. This is considered a “manual” triggering
       * of the datepicker.
       */
      toggle() {
          if (this.isOpen) {
              return this.hide();
          }
          this.show();
      }
      /**
       * Set config for datepicker
       */
      setConfig() {
          this._config = Object.assign({}, this._config, this.bsConfig, {
              value: checkBsValue(this._bsValue, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
              isDisabled: this.isDisabled,
              minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
              maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
              daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
              dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
              dateTooltipTexts: this.dateTooltipTexts || this.bsConfig && this.bsConfig.dateTooltipTexts,
              datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
              datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
              minMode: this.minMode || this.bsConfig && this.bsConfig.minMode
          });
      }
      ngOnDestroy() {
          this._datepicker.dispose();
          this.isOpen$.next(false);
          if (this.isDestroy$) {
              this.isDestroy$.next();
              this.isDestroy$.complete();
          }
      }
  }
  BsDatepickerDirective.decorators = [
      { type: Directive, args: [{
                  selector: '[bsDatepicker]',
                  exportAs: 'bsDatepicker'
              },] }
  ];
  BsDatepickerDirective.ctorParameters = () => [
      { type: BsDatepickerConfig },
      { type: ElementRef },
      { type: Renderer2 },
      { type: ViewContainerRef },
      { type: ComponentLoaderFactory }
  ];
  BsDatepickerDirective.propDecorators = {
      placement: [{ type: Input }],
      triggers: [{ type: Input }],
      outsideClick: [{ type: Input }],
      container: [{ type: Input }],
      outsideEsc: [{ type: Input }],
      onShown: [{ type: Output }],
      onHidden: [{ type: Output }],
      isDisabled: [{ type: Input }],
      minDate: [{ type: Input }],
      maxDate: [{ type: Input }],
      minMode: [{ type: Input }],
      daysDisabled: [{ type: Input }],
      datesDisabled: [{ type: Input }],
      datesEnabled: [{ type: Input }],
      dateCustomClasses: [{ type: Input }],
      dateTooltipTexts: [{ type: Input }],
      bsValueChange: [{ type: Output }],
      isOpen: [{ type: Input }],
      bsValue: [{ type: Input }],
      bsConfig: [{ type: Input }]
  };
  
  class BsDatepickerInlineConfig extends BsDatepickerConfig {
  }
  BsDatepickerInlineConfig.ɵprov = ɵɵdefineInjectable({ factory: function BsDatepickerInlineConfig_Factory() { return new BsDatepickerInlineConfig(); }, token: BsDatepickerInlineConfig, providedIn: "root" });
  BsDatepickerInlineConfig.decorators = [
      { type: Injectable, args: [{
                  providedIn: 'root'
              },] }
  ];
  
  class BsDatepickerInlineContainerComponent extends BsDatepickerContainerComponent {
      constructor(_renderer, _config, _store, _element, _actions, _effects, _positioningService) {
          super(_renderer, _config, _store, _element, _actions, _effects, _positioningService);
          _renderer.setStyle(_element.nativeElement, 'display', 'inline-block');
          _renderer.setStyle(_element.nativeElement, 'position', 'static');
      }
  }
  BsDatepickerInlineContainerComponent.decorators = [
      { type: Component, args: [{
                  selector: 'bs-datepicker-inline-container',
                  providers: [BsDatepickerStore, BsDatepickerEffects],
                  template: "<!-- days calendar view mode -->\n<div class=\"bs-datepicker\" [ngClass]=\"containerClass\" *ngIf=\"viewMode | async\">\n  <div class=\"bs-datepicker-container\"\n    [@datepickerAnimation]=\"animationState\"\n    (@datepickerAnimation.done)=\"positionServiceEnable()\">\n    <!--calendars-->\n    <div class=\"bs-calendar-container\" [ngSwitch]=\"viewMode | async\" role=\"application\">\n      <!--days calendar-->\n      <div *ngSwitchCase=\"'day'\" class=\"bs-media-container\">\n        <bs-days-calendar-view\n          *ngFor=\"let calendar of daysCalendar$ | async\"\n          [class.bs-datepicker-multiple]=\"multipleCalendars\"\n          [calendar]=\"calendar\"\n          [options]=\"options$ | async\"\n          (onNavigate)=\"navigateTo($event)\"\n          (onViewMode)=\"setViewMode($event)\"\n          (onHover)=\"dayHoverHandler($event)\"\n          (onHoverWeek)=\"weekHoverHandler($event)\"\n          (onSelect)=\"daySelectHandler($event)\">\n        </bs-days-calendar-view>\n      </div>\n\n      <!--months calendar-->\n      <div *ngSwitchCase=\"'month'\" class=\"bs-media-container\">\n        <bs-month-calendar-view\n          *ngFor=\"let calendar of monthsCalendar | async\"\n          [class.bs-datepicker-multiple]=\"multipleCalendars\"\n          [calendar]=\"calendar\"\n          (onNavigate)=\"navigateTo($event)\"\n          (onViewMode)=\"setViewMode($event)\"\n          (onHover)=\"monthHoverHandler($event)\"\n          (onSelect)=\"monthSelectHandler($event)\">\n        </bs-month-calendar-view>\n      </div>\n\n      <!--years calendar-->\n      <div *ngSwitchCase=\"'year'\" class=\"bs-media-container\">\n        <bs-years-calendar-view\n          *ngFor=\"let calendar of yearsCalendar | async\"\n          [class.bs-datepicker-multiple]=\"multipleCalendars\"\n          [calendar]=\"calendar\"\n          (onNavigate)=\"navigateTo($event)\"\n          (onViewMode)=\"setViewMode($event)\"\n          (onHover)=\"yearHoverHandler($event)\"\n          (onSelect)=\"yearSelectHandler($event)\">\n        </bs-years-calendar-view>\n      </div>\n    </div>\n\n    <!--applycancel buttons-->\n    <div class=\"bs-datepicker-buttons\" *ngIf=\"false\">\n      <button class=\"btn btn-success\" type=\"button\">Apply</button>\n      <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n    </div>\n\n    <div class=\"bs-datepicker-buttons\" *ngIf=\"showTodayBtn || showClearBtn\">\n      <div class=\"btn-today-wrapper\"\n           [class.today-left]=\"todayPos === 'left'\"\n           [class.today-right]=\"todayPos === 'right'\"\n           [class.today-center]=\"todayPos === 'center'\"\n           *ngIf=\"showTodayBtn\">\n        <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n      </div>\n\n        <div class=\"btn-clear-wrapper\"\n        [class.clear-left]=\"clearPos === 'left'\"\n        [class.clear-right]=\"clearPos === 'right'\"\n        [class.clear-center]=\"clearPos === 'center'\"\n        *ngIf=\"showClearBtn\">\n          <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n        </div>\n    </div>\n\n  </div>\n\n  <!--custom dates or date ranges picker-->\n  <div class=\"bs-datepicker-custom-range\" *ngIf=\"customRanges && customRanges.length > 0\">\n    <bs-custom-date-view\n      [selectedRange]=\"chosenRange\"\n      [ranges]=\"customRanges\"\n      [customRangeLabel]=\"customRangeBtnLbl\"\n      (onSelect)=\"setRangeOnCalendar($event)\">\n    </bs-custom-date-view>\n  </div>\n</div>\n",
                  host: {
                      '(click)': '_stopPropagation($event)'
                  },
                  animations: [datepickerAnimation]
              },] }
  ];
  BsDatepickerInlineContainerComponent.ctorParameters = () => [
      { type: Renderer2 },
      { type: BsDatepickerConfig },
      { type: BsDatepickerStore },
      { type: ElementRef },
      { type: BsDatepickerActions },
      { type: BsDatepickerEffects },
      { type: PositioningService }
  ];
  
  class BsDatepickerInlineDirective {
      constructor(_config, _elementRef, _renderer, _viewContainerRef, cis) {
          this._config = _config;
          this._elementRef = _elementRef;
          /**
           * Indicates whether datepicker is enabled or not
           */
          this.isDisabled = false;
          /**
           * Emits when datepicker value has been changed
           */
          this.bsValueChange = new EventEmitter();
          this._subs = [];
          // todo: assign only subset of fields
          Object.assign(this, this._config);
          this._datepicker = cis.createLoader(_elementRef, _viewContainerRef, _renderer);
      }
      /**
       * Initial value of datepicker
       */
      set bsValue(value) {
          if (this._bsValue === value) {
              return;
          }
          if (!this._bsValue && value) {
              const now = new Date();
              value.setMilliseconds(now.getMilliseconds());
              value.setSeconds(now.getSeconds());
              value.setMinutes(now.getMinutes());
              value.setHours(now.getHours());
          }
          this._bsValue = value;
          this.bsValueChange.emit(value);
      }
      ngOnInit() {
          this.setConfig();
          // if date changes from external source (model -> view)
          this._subs.push(this.bsValueChange.subscribe((value) => {
              if (this._datepickerRef) {
                  this._datepickerRef.instance.value = value;
              }
          }));
          // if date changes from picker (view -> model)
          if (this._datepickerRef) {
              this._subs.push(this._datepickerRef.instance.valueChange.subscribe((value) => {
                  this.bsValue = value;
              }));
          }
      }
      ngOnChanges(changes) {
          if (!this._datepickerRef || !this._datepickerRef.instance) {
              return;
          }
          if (changes.minDate) {
              this._datepickerRef.instance.minDate = this.minDate;
              this.setConfig();
          }
          if (changes.maxDate) {
              this._datepickerRef.instance.maxDate = this.maxDate;
              this.setConfig();
          }
          if (changes.datesDisabled) {
              this._datepickerRef.instance.datesDisabled = this.datesDisabled;
              this.setConfig();
          }
          if (changes.datesEnabled) {
              this._datepickerRef.instance.datesEnabled = this.datesEnabled;
              this._datepickerRef.instance.value = this._bsValue;
          }
          if (changes.isDisabled) {
              this._datepickerRef.instance.isDisabled = this.isDisabled;
              this.setConfig();
          }
          if (changes.dateCustomClasses) {
              this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
              this.setConfig();
          }
          if (changes.dateTooltipTexts) {
              this._datepickerRef.instance.dateTooltipTexts = this.dateTooltipTexts;
              this.setConfig();
          }
      }
      /**
       * Set config for datepicker
       */
      setConfig() {
          if (this._datepicker) {
              this._datepicker.hide();
          }
          this._config = Object.assign({}, this._config, this.bsConfig, {
              value: checkBsValue(this._bsValue, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
              isDisabled: this.isDisabled,
              minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
              maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
              dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
              dateTooltipTexts: this.dateTooltipTexts || this.bsConfig && this.bsConfig.dateTooltipTexts,
              datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
              datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled
          });
          this._datepickerRef = this._datepicker
              .provide({ provide: BsDatepickerConfig, useValue: this._config })
              .attach(BsDatepickerInlineContainerComponent)
              .to(this._elementRef)
              .show();
      }
      ngOnDestroy() {
          this._datepicker.dispose();
      }
  }
  BsDatepickerInlineDirective.decorators = [
      { type: Directive, args: [{
                  selector: 'bs-datepicker-inline',
                  exportAs: 'bsDatepickerInline'
              },] }
  ];
  BsDatepickerInlineDirective.ctorParameters = () => [
      { type: BsDatepickerInlineConfig },
      { type: ElementRef },
      { type: Renderer2 },
      { type: ViewContainerRef },
      { type: ComponentLoaderFactory }
  ];
  BsDatepickerInlineDirective.propDecorators = {
      bsConfig: [{ type: Input }],
      isDisabled: [{ type: Input }],
      minDate: [{ type: Input }],
      maxDate: [{ type: Input }],
      dateCustomClasses: [{ type: Input }],
      dateTooltipTexts: [{ type: Input }],
      datesEnabled: [{ type: Input }],
      datesDisabled: [{ type: Input }],
      bsValueChange: [{ type: Output }],
      bsValue: [{ type: Input }]
  };
  
  class BsDaterangepickerInlineConfig extends BsDatepickerConfig {
      constructor() {
          super(...arguments);
          // DatepickerRenderOptions
          this.displayMonths = 2;
          /** turn on/off animation */
          this.isAnimated = false;
      }
  }
  BsDaterangepickerInlineConfig.ɵprov = ɵɵdefineInjectable({ factory: function BsDaterangepickerInlineConfig_Factory() { return new BsDaterangepickerInlineConfig(); }, token: BsDaterangepickerInlineConfig, providedIn: "root" });
  BsDaterangepickerInlineConfig.decorators = [
      { type: Injectable, args: [{
                  providedIn: 'root'
              },] }
  ];
  
  class BsDaterangepickerContainerComponent extends BsDatepickerAbstractComponent {
      constructor(_renderer, _config, _store, _element, _actions, _effects, _positionService) {
          super();
          this._config = _config;
          this._store = _store;
          this._element = _element;
          this._actions = _actions;
          this._positionService = _positionService;
          this.valueChange = new EventEmitter();
          this.animationState = 'void';
          this._rangeStack = [];
          this.chosenRange = [];
          this._subs = [];
          this._effects = _effects;
          this.customRanges = this._config.ranges || [];
          this.customRangeBtnLbl = this._config.customRangeButtonLabel;
          _renderer.setStyle(_element.nativeElement, 'display', 'block');
          _renderer.setStyle(_element.nativeElement, 'position', 'absolute');
      }
      set value(value) {
          var _a;
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setRangeValue(value);
      }
      ngOnInit() {
          var _a, _b;
          this._positionService.setOptions({
              modifiers: { flip: { enabled: this._config.adaptivePosition } },
              allowedPositions: ['top', 'bottom']
          });
          (_a = this._positionService.event$) === null || _a === void 0 ? void 0 : _a.pipe(take(1)).subscribe(() => {
              this._positionService.disable();
              if (this._config.isAnimated) {
                  this.animationState = this.isTopPosition ? 'animated-up' : 'animated-down';
                  return;
              }
              this.animationState = 'unanimated';
          });
          this.containerClass = this._config.containerClass;
          this.isOtherMonthsActive = this._config.selectFromOtherMonth;
          (_b = this._effects) === null || _b === void 0 ? void 0 : _b.init(this._store).setOptions(this._config).setBindings(this).setEventHandlers(this).registerDatepickerSideEffects();
          // todo: move it somewhere else
          // on selected date change
          this._subs.push(this._store
              .select(state => state.selectedRange)
              .subscribe(dateRange => {
              this.valueChange.emit(dateRange);
              this.chosenRange = dateRange || [];
          }));
      }
      get isTopPosition() {
          return this._element.nativeElement.classList.contains('top');
      }
      positionServiceEnable() {
          this._positionService.enable();
      }
      daySelectHandler(day) {
          if (!day) {
              return;
          }
          const isDisabled = this.isOtherMonthsActive ? day.isDisabled : (day.isOtherMonth || day.isDisabled);
          if (isDisabled) {
              return;
          }
          this.rangesProcessing(day);
      }
      monthSelectHandler(day) {
          if (!day || day.isDisabled) {
              return;
          }
          day.isSelected = true;
          if (this._config.minMode !== 'month') {
              if (day.isDisabled) {
                  return;
              }
              this._store.dispatch(this._actions.navigateTo({
                  unit: {
                      month: getMonth(day.date),
                      year: getFullYear(day.date)
                  },
                  viewMode: 'day'
              }));
              return;
          }
          this.rangesProcessing(day);
      }
      yearSelectHandler(day) {
          if (!day || day.isDisabled) {
              return;
          }
          day.isSelected = true;
          if (this._config.minMode !== 'year') {
              if (day.isDisabled) {
                  return;
              }
              this._store.dispatch(this._actions.navigateTo({
                  unit: {
                      year: getFullYear(day.date)
                  },
                  viewMode: 'month'
              }));
              return;
          }
          this.rangesProcessing(day);
      }
      rangesProcessing(day) {
          // if only one date is already selected
          // and user clicks on previous date
          // start selection from new date
          // but if new date is after initial one
          // than finish selection
          if (this._rangeStack.length === 1) {
              this._rangeStack =
                  day.date >= this._rangeStack[0]
                      ? [this._rangeStack[0], day.date]
                      : [day.date];
          }
          if (this._config.maxDateRange) {
              this.setMaxDateRangeOnCalendar(day.date);
          }
          if (this._rangeStack.length === 0) {
              this._rangeStack = [day.date];
              if (this._config.maxDateRange) {
                  this.setMaxDateRangeOnCalendar(day.date);
              }
          }
          this._store.dispatch(this._actions.selectRange(this._rangeStack));
          if (this._rangeStack.length === 2) {
              this._rangeStack = [];
          }
      }
      ngOnDestroy() {
          var _a;
          for (const sub of this._subs) {
              sub.unsubscribe();
          }
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.destroy();
      }
      setRangeOnCalendar(dates) {
          if (dates) {
              this._rangeStack = dates.value instanceof Date ? [dates.value] : dates.value;
          }
          this._store.dispatch(this._actions.selectRange(this._rangeStack));
      }
      setMaxDateRangeOnCalendar(currentSelection) {
          var _a;
          let maxDateRange = new Date(currentSelection);
          if (this._config.maxDate) {
              const maxDateValueInMilliseconds = this._config.maxDate.getTime();
              const maxDateRangeInMilliseconds = currentSelection.getTime() + ((this._config.maxDateRange || 0) * dayInMilliseconds);
              maxDateRange = maxDateRangeInMilliseconds > maxDateValueInMilliseconds ?
                  new Date(this._config.maxDate) :
                  new Date(maxDateRangeInMilliseconds);
          }
          else {
              maxDateRange.setDate(currentSelection.getDate() + (this._config.maxDateRange || 0));
          }
          (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setMaxDate(maxDateRange);
      }
  }
  BsDaterangepickerContainerComponent.decorators = [
      { type: Component, args: [{
                  selector: 'bs-daterangepicker-container',
                  providers: [BsDatepickerStore, BsDatepickerEffects],
                  template: "<!-- days calendar view mode -->\n<div class=\"bs-datepicker\" [ngClass]=\"containerClass\" *ngIf=\"viewMode | async\">\n  <div class=\"bs-datepicker-container\"\n    [@datepickerAnimation]=\"animationState\"\n    (@datepickerAnimation.done)=\"positionServiceEnable()\">\n    <!--calendars-->\n    <div class=\"bs-calendar-container\" [ngSwitch]=\"viewMode | async\" role=\"application\">\n      <!--days calendar-->\n      <div *ngSwitchCase=\"'day'\" class=\"bs-media-container\">\n        <bs-days-calendar-view\n          *ngFor=\"let calendar of daysCalendar$ | async\"\n          [class.bs-datepicker-multiple]=\"multipleCalendars\"\n          [calendar]=\"calendar\"\n          [options]=\"options$ | async\"\n          (onNavigate)=\"navigateTo($event)\"\n          (onViewMode)=\"setViewMode($event)\"\n          (onHover)=\"dayHoverHandler($event)\"\n          (onHoverWeek)=\"weekHoverHandler($event)\"\n          (onSelect)=\"daySelectHandler($event)\">\n        </bs-days-calendar-view>\n      </div>\n\n      <!--months calendar-->\n      <div *ngSwitchCase=\"'month'\" class=\"bs-media-container\">\n        <bs-month-calendar-view\n          *ngFor=\"let calendar of monthsCalendar | async\"\n          [class.bs-datepicker-multiple]=\"multipleCalendars\"\n          [calendar]=\"calendar\"\n          (onNavigate)=\"navigateTo($event)\"\n          (onViewMode)=\"setViewMode($event)\"\n          (onHover)=\"monthHoverHandler($event)\"\n          (onSelect)=\"monthSelectHandler($event)\">\n        </bs-month-calendar-view>\n      </div>\n\n      <!--years calendar-->\n      <div *ngSwitchCase=\"'year'\" class=\"bs-media-container\">\n        <bs-years-calendar-view\n          *ngFor=\"let calendar of yearsCalendar | async\"\n          [class.bs-datepicker-multiple]=\"multipleCalendars\"\n          [calendar]=\"calendar\"\n          (onNavigate)=\"navigateTo($event)\"\n          (onViewMode)=\"setViewMode($event)\"\n          (onHover)=\"yearHoverHandler($event)\"\n          (onSelect)=\"yearSelectHandler($event)\">\n        </bs-years-calendar-view>\n      </div>\n    </div>\n\n    <!--applycancel buttons-->\n    <div class=\"bs-datepicker-buttons\" *ngIf=\"false\">\n      <button class=\"btn btn-success\" type=\"button\">Apply</button>\n      <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n    </div>\n\n    <div class=\"bs-datepicker-buttons\" *ngIf=\"showTodayBtn || showClearBtn\">\n      <div class=\"btn-today-wrapper\"\n           [class.today-left]=\"todayPos === 'left'\"\n           [class.today-right]=\"todayPos === 'right'\"\n           [class.today-center]=\"todayPos === 'center'\"\n           *ngIf=\"showTodayBtn\">\n        <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n      </div>\n\n        <div class=\"btn-clear-wrapper\"\n        [class.clear-left]=\"clearPos === 'left'\"\n        [class.clear-right]=\"clearPos === 'right'\"\n        [class.clear-center]=\"clearPos === 'center'\"\n        *ngIf=\"showClearBtn\">\n          <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n        </div>\n    </div>\n\n  </div>\n\n  <!--custom dates or date ranges picker-->\n  <div class=\"bs-datepicker-custom-range\" *ngIf=\"customRanges && customRanges.length > 0\">\n    <bs-custom-date-view\n      [selectedRange]=\"chosenRange\"\n      [ranges]=\"customRanges\"\n      [customRangeLabel]=\"customRangeBtnLbl\"\n      (onSelect)=\"setRangeOnCalendar($event)\">\n    </bs-custom-date-view>\n  </div>\n</div>\n",
                  host: {
                      class: 'bottom',
                      '(click)': '_stopPropagation($event)',
                      role: 'dialog',
                      'aria-label': 'calendar'
                  },
                  animations: [datepickerAnimation]
              },] }
  ];
  BsDaterangepickerContainerComponent.ctorParameters = () => [
      { type: Renderer2 },
      { type: BsDatepickerConfig },
      { type: BsDatepickerStore },
      { type: ElementRef },
      { type: BsDatepickerActions },
      { type: BsDatepickerEffects },
      { type: PositioningService }
  ];
  
  class BsDaterangepickerInlineContainerComponent extends BsDaterangepickerContainerComponent {
      constructor(_renderer, _config, _store, _element, _actions, _effects, _positioningService) {
          super(_renderer, _config, _store, _element, _actions, _effects, _positioningService);
          _renderer.setStyle(_element.nativeElement, 'display', 'inline-block');
          _renderer.setStyle(_element.nativeElement, 'position', 'static');
      }
  }
  BsDaterangepickerInlineContainerComponent.decorators = [
      { type: Component, args: [{
                  selector: 'bs-daterangepicker-inline-container',
                  providers: [BsDatepickerStore, BsDatepickerEffects],
                  template: "<!-- days calendar view mode -->\n<div class=\"bs-datepicker\" [ngClass]=\"containerClass\" *ngIf=\"viewMode | async\">\n  <div class=\"bs-datepicker-container\"\n    [@datepickerAnimation]=\"animationState\"\n    (@datepickerAnimation.done)=\"positionServiceEnable()\">\n    <!--calendars-->\n    <div class=\"bs-calendar-container\" [ngSwitch]=\"viewMode | async\" role=\"application\">\n      <!--days calendar-->\n      <div *ngSwitchCase=\"'day'\" class=\"bs-media-container\">\n        <bs-days-calendar-view\n          *ngFor=\"let calendar of daysCalendar$ | async\"\n          [class.bs-datepicker-multiple]=\"multipleCalendars\"\n          [calendar]=\"calendar\"\n          [options]=\"options$ | async\"\n          (onNavigate)=\"navigateTo($event)\"\n          (onViewMode)=\"setViewMode($event)\"\n          (onHover)=\"dayHoverHandler($event)\"\n          (onHoverWeek)=\"weekHoverHandler($event)\"\n          (onSelect)=\"daySelectHandler($event)\">\n        </bs-days-calendar-view>\n      </div>\n\n      <!--months calendar-->\n      <div *ngSwitchCase=\"'month'\" class=\"bs-media-container\">\n        <bs-month-calendar-view\n          *ngFor=\"let calendar of monthsCalendar | async\"\n          [class.bs-datepicker-multiple]=\"multipleCalendars\"\n          [calendar]=\"calendar\"\n          (onNavigate)=\"navigateTo($event)\"\n          (onViewMode)=\"setViewMode($event)\"\n          (onHover)=\"monthHoverHandler($event)\"\n          (onSelect)=\"monthSelectHandler($event)\">\n        </bs-month-calendar-view>\n      </div>\n\n      <!--years calendar-->\n      <div *ngSwitchCase=\"'year'\" class=\"bs-media-container\">\n        <bs-years-calendar-view\n          *ngFor=\"let calendar of yearsCalendar | async\"\n          [class.bs-datepicker-multiple]=\"multipleCalendars\"\n          [calendar]=\"calendar\"\n          (onNavigate)=\"navigateTo($event)\"\n          (onViewMode)=\"setViewMode($event)\"\n          (onHover)=\"yearHoverHandler($event)\"\n          (onSelect)=\"yearSelectHandler($event)\">\n        </bs-years-calendar-view>\n      </div>\n    </div>\n\n    <!--applycancel buttons-->\n    <div class=\"bs-datepicker-buttons\" *ngIf=\"false\">\n      <button class=\"btn btn-success\" type=\"button\">Apply</button>\n      <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n    </div>\n\n    <div class=\"bs-datepicker-buttons\" *ngIf=\"showTodayBtn || showClearBtn\">\n      <div class=\"btn-today-wrapper\"\n           [class.today-left]=\"todayPos === 'left'\"\n           [class.today-right]=\"todayPos === 'right'\"\n           [class.today-center]=\"todayPos === 'center'\"\n           *ngIf=\"showTodayBtn\">\n        <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n      </div>\n\n        <div class=\"btn-clear-wrapper\"\n        [class.clear-left]=\"clearPos === 'left'\"\n        [class.clear-right]=\"clearPos === 'right'\"\n        [class.clear-center]=\"clearPos === 'center'\"\n        *ngIf=\"showClearBtn\">\n          <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n        </div>\n    </div>\n\n  </div>\n\n  <!--custom dates or date ranges picker-->\n  <div class=\"bs-datepicker-custom-range\" *ngIf=\"customRanges && customRanges.length > 0\">\n    <bs-custom-date-view\n      [selectedRange]=\"chosenRange\"\n      [ranges]=\"customRanges\"\n      [customRangeLabel]=\"customRangeBtnLbl\"\n      (onSelect)=\"setRangeOnCalendar($event)\">\n    </bs-custom-date-view>\n  </div>\n</div>\n",
                  host: {
                      '(click)': '_stopPropagation($event)'
                  },
                  animations: [datepickerAnimation]
              },] }
  ];
  BsDaterangepickerInlineContainerComponent.ctorParameters = () => [
      { type: Renderer2 },
      { type: BsDatepickerConfig },
      { type: BsDatepickerStore },
      { type: ElementRef },
      { type: BsDatepickerActions },
      { type: BsDatepickerEffects },
      { type: PositioningService }
  ];
  
  class BsDaterangepickerInlineDirective {
      constructor(_config, _elementRef, _renderer, _viewContainerRef, cis) {
          this._config = _config;
          this._elementRef = _elementRef;
          /**
           * Indicates whether datepicker is enabled or not
           */
          this.isDisabled = false;
          /**
           * Emits when daterangepicker value has been changed
           */
          this.bsValueChange = new EventEmitter();
          this._subs = [];
          // todo: assign only subset of fields
          Object.assign(this, this._config);
          this._datepicker = cis.createLoader(_elementRef, _viewContainerRef, _renderer);
      }
      /**
       * Initial value of datepicker
       */
      set bsValue(value) {
          if (this._bsValue === value) {
              return;
          }
          this._bsValue = value;
          this.bsValueChange.emit(value);
      }
      ngOnInit() {
          this.setConfig();
          // if date changes from external source (model -> view)
          this._subs.push(this.bsValueChange.subscribe((value) => {
              if (this._datepickerRef) {
                  this._datepickerRef.instance.value = value;
              }
          }));
          // if date changes from picker (view -> model)
          if (this._datepickerRef) {
              this._subs.push(this._datepickerRef.instance.valueChange
                  .pipe(filter((range) => range && range[0] && !!range[1]))
                  .subscribe((value) => {
                  this.bsValue = value;
              }));
          }
      }
      ngOnChanges(changes) {
          if (!this._datepickerRef || !this._datepickerRef.instance) {
              return;
          }
          if (changes.minDate) {
              this._datepickerRef.instance.minDate = this.minDate;
              this.setConfig();
          }
          if (changes.maxDate) {
              this._datepickerRef.instance.maxDate = this.maxDate;
              this.setConfig();
          }
          if (changes.datesEnabled) {
              this._datepickerRef.instance.datesEnabled = this.datesEnabled;
          }
          if (changes.datesDisabled) {
              this._datepickerRef.instance.datesDisabled = this.datesDisabled;
              this.setConfig();
          }
          if (changes.daysDisabled) {
              this._datepickerRef.instance.daysDisabled = this.daysDisabled;
              this.setConfig();
          }
          if (changes.isDisabled) {
              this._datepickerRef.instance.isDisabled = this.isDisabled;
              this.setConfig();
          }
          if (changes.dateCustomClasses) {
              this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
              this.setConfig();
          }
      }
      /**
       * Set config for datepicker
       */
      setConfig() {
          if (this._datepicker) {
              this._datepicker.hide();
          }
          this._config = Object.assign({}, this._config, this.bsConfig, {
              value: checkBsValue(this._bsValue, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
              isDisabled: this.isDisabled,
              minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
              maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
              daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
              dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
              datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
              datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
              ranges: checkRangesWithMaxDate(this.bsConfig && this.bsConfig.ranges, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
              maxDateRange: this.bsConfig && this.bsConfig.maxDateRange
          });
          this._datepickerRef = this._datepicker
              .provide({ provide: BsDatepickerConfig, useValue: this._config })
              .attach(BsDaterangepickerInlineContainerComponent)
              .to(this._elementRef)
              .show();
      }
      ngOnDestroy() {
          this._datepicker.dispose();
      }
  }
  BsDaterangepickerInlineDirective.decorators = [
      { type: Directive, args: [{
                  selector: 'bs-daterangepicker-inline',
                  exportAs: 'bsDaterangepickerInline'
              },] }
  ];
  BsDaterangepickerInlineDirective.ctorParameters = () => [
      { type: BsDaterangepickerInlineConfig },
      { type: ElementRef },
      { type: Renderer2 },
      { type: ViewContainerRef },
      { type: ComponentLoaderFactory }
  ];
  BsDaterangepickerInlineDirective.propDecorators = {
      bsValue: [{ type: Input }],
      bsConfig: [{ type: Input }],
      isDisabled: [{ type: Input }],
      minDate: [{ type: Input }],
      maxDate: [{ type: Input }],
      dateCustomClasses: [{ type: Input }],
      daysDisabled: [{ type: Input }],
      datesDisabled: [{ type: Input }],
      datesEnabled: [{ type: Input }],
      bsValueChange: [{ type: Output }]
  };
  
  const BS_DATEPICKER_VALUE_ACCESSOR = {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => BsDatepickerInputDirective),
      multi: true
  };
  const BS_DATEPICKER_VALIDATOR = {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => BsDatepickerInputDirective),
      multi: true
  };
  class BsDatepickerInputDirective {
      constructor(_picker, _localeService, _renderer, _elRef, changeDetection) {
          this._picker = _picker;
          this._localeService = _localeService;
          this._renderer = _renderer;
          this._elRef = _elRef;
          this.changeDetection = changeDetection;
          this._onChange = Function.prototype;
          this._onTouched = Function.prototype;
          this._validatorChange = Function.prototype;
          this._subs = new Subscription();
      }
      ngOnInit() {
          const setBsValue = (value) => {
              this._setInputValue(value);
              if (this._value !== value) {
                  this._value = value;
                  this._onChange(value);
                  this._onTouched();
              }
              this.changeDetection.markForCheck();
          };
          // if value set via [bsValue] it will not get into value change
          if (this._picker._bsValue) {
              setBsValue(this._picker._bsValue);
          }
          // update input value on datepicker value update
          this._subs.add(this._picker.bsValueChange.subscribe(setBsValue));
          // update input value on locale change
          this._subs.add(this._localeService.localeChange.subscribe(() => {
              this._setInputValue(this._value);
          }));
          this._subs.add(this._picker.dateInputFormat$.pipe(distinctUntilChanged()).subscribe(() => {
              this._setInputValue(this._value);
          }));
      }
      ngOnDestroy() {
          this._subs.unsubscribe();
      }
      onKeydownEvent(event) {
          if (event.keyCode === 13 || event.code === 'Enter') {
              this.hide();
          }
      }
      _setInputValue(value) {
          const initialDate = !value ? ''
              : formatDate(value, this._picker._config.dateInputFormat, this._localeService.currentLocale);
          this._renderer.setProperty(this._elRef.nativeElement, 'value', initialDate);
      }
      onChange(event) {
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          this.writeValue(event.target.value);
          this._onChange(this._value);
          if (this._picker._config.returnFocusToInput) {
              this._renderer.selectRootElement(this._elRef.nativeElement).focus();
          }
          this._onTouched();
      }
      validate(c) {
          const _value = c.value;
          if (_value === null || _value === undefined || _value === '') {
              return null;
          }
          if (isDate(_value)) {
              const _isDateValid = isDateValid(_value);
              if (!_isDateValid) {
                  return { bsDate: { invalid: _value } };
              }
              if (this._picker && this._picker.minDate && isBefore(_value, this._picker.minDate, 'date')) {
                  this.writeValue(this._picker.minDate);
                  return { bsDate: { minDate: this._picker.minDate } };
              }
              if (this._picker && this._picker.maxDate && isAfter(_value, this._picker.maxDate, 'date')) {
                  this.writeValue(this._picker.maxDate);
                  return { bsDate: { maxDate: this._picker.maxDate } };
              }
          }
          return null;
      }
      registerOnValidatorChange(fn) {
          this._validatorChange = fn;
      }
      writeValue(value) {
          if (!value) {
              this._value = void 0;
          }
          else {
              const _localeKey = this._localeService.currentLocale;
              const _locale = getLocale(_localeKey);
              if (!_locale) {
                  throw new Error(`Locale "${_localeKey}" is not defined, please add it with "defineLocale(...)"`);
              }
              this._value = parseDate(value, this._picker._config.dateInputFormat, this._localeService.currentLocale);
              if (this._picker._config.useUtc) {
                  this._value = utcAsLocal(this._value);
              }
          }
          this._picker.bsValue = this._value;
      }
      setDisabledState(isDisabled) {
          this._picker.isDisabled = isDisabled;
          if (isDisabled) {
              this._renderer.setAttribute(this._elRef.nativeElement, 'disabled', 'disabled');
              return;
          }
          this._renderer.removeAttribute(this._elRef.nativeElement, 'disabled');
      }
      registerOnChange(fn) {
          this._onChange = fn;
      }
      registerOnTouched(fn) {
          this._onTouched = fn;
      }
      onBlur() {
          this._onTouched();
      }
      hide() {
          this._picker.hide();
          this._renderer.selectRootElement(this._elRef.nativeElement).blur();
          if (this._picker._config.returnFocusToInput) {
              this._renderer.selectRootElement(this._elRef.nativeElement).focus();
          }
      }
  }
  BsDatepickerInputDirective.decorators = [
      { type: Directive, args: [{
                  selector: `input[bsDatepicker]`,
                  // eslint-disable-next-line @angular-eslint/no-host-metadata-property
                  host: {
                      '(change)': 'onChange($event)',
                      '(keyup.esc)': 'hide()',
                      '(keydown)': 'onKeydownEvent($event)',
                      '(blur)': 'onBlur()'
                  },
                  providers: [BS_DATEPICKER_VALUE_ACCESSOR, BS_DATEPICKER_VALIDATOR]
              },] }
  ];
  BsDatepickerInputDirective.ctorParameters = () => [
      { type: BsDatepickerDirective, decorators: [{ type: Host }] },
      { type: BsLocaleService },
      { type: Renderer2 },
      { type: ElementRef },
      { type: ChangeDetectorRef }
  ];
  
  class BsDaterangepickerConfig extends BsDatepickerConfig {
      constructor() {
          super(...arguments);
          // DatepickerRenderOptions
          this.displayMonths = 2;
      }
  }
  BsDaterangepickerConfig.ɵprov = ɵɵdefineInjectable({ factory: function BsDaterangepickerConfig_Factory() { return new BsDaterangepickerConfig(); }, token: BsDaterangepickerConfig, providedIn: "root" });
  BsDaterangepickerConfig.decorators = [
      { type: Injectable, args: [{
                  providedIn: 'root'
              },] }
  ];
  
  class BsDaterangepickerDirective {
      constructor(_config, _elementRef, _renderer, _viewContainerRef, cis) {
          this._config = _config;
          this._elementRef = _elementRef;
          this._renderer = _renderer;
          /**
           * Placement of a daterangepicker. Accepts: "top", "bottom", "left", "right"
           */
          this.placement = 'bottom';
          /**
           * Specifies events that should trigger. Supports a space separated list of
           * event names.
           */
          this.triggers = 'click';
          /**
           * Close daterangepicker on outside click
           */
          this.outsideClick = true;
          /**
           * A selector specifying the element the daterangepicker should be appended to.
           */
          this.container = 'body';
          this.outsideEsc = true;
          this.isDestroy$ = new Subject();
          /**
           * Indicates whether daterangepicker's content is enabled or not
           */
          this.isDisabled = false;
          /**
           * Emits when daterangepicker value has been changed
           */
          this.bsValueChange = new EventEmitter();
          this._subs = [];
          this._rangeInputFormat$ = new Subject();
          this._datepicker = cis.createLoader(_elementRef, _viewContainerRef, _renderer);
          Object.assign(this, _config);
          this.onShown = this._datepicker.onShown;
          this.onHidden = this._datepicker.onHidden;
          this.isOpen$ = new BehaviorSubject(this.isOpen);
      }
      /**
       * Returns whether or not the daterangepicker is currently being shown
       */
      get isOpen() {
          return this._datepicker.isShown;
      }
      set isOpen(value) {
          this.isOpen$.next(value);
      }
      /**
       * Initial value of daterangepicker
       */
      set bsValue(value) {
          if (this._bsValue === value) {
              return;
          }
          this._bsValue = value;
          this.bsValueChange.emit(value);
      }
      /**
       * Config object for daterangepicker
       */
      set bsConfig(bsConfig) {
          this._bsConfig = bsConfig;
          this.setConfig();
          this._rangeInputFormat$.next(bsConfig && bsConfig.rangeInputFormat);
      }
      get bsConfig() {
          return this._bsConfig;
      }
      get rangeInputFormat$() {
          return this._rangeInputFormat$;
      }
      ngOnInit() {
          this.isDestroy$ = new Subject();
          this._datepicker.listen({
              outsideClick: this.outsideClick,
              outsideEsc: this.outsideEsc,
              triggers: this.triggers,
              show: () => this.show()
          });
          this.setConfig();
      }
      ngOnChanges(changes) {
          if (!this._datepickerRef || !this._datepickerRef.instance) {
              return;
          }
          if (changes.minDate) {
              this._datepickerRef.instance.minDate = this.minDate;
          }
          if (changes.maxDate) {
              this._datepickerRef.instance.maxDate = this.maxDate;
          }
          if (changes.datesDisabled) {
              this._datepickerRef.instance.datesDisabled = this.datesDisabled;
          }
          if (changes.datesEnabled) {
              this._datepickerRef.instance.datesEnabled = this.datesEnabled;
          }
          if (changes.daysDisabled) {
              this._datepickerRef.instance.daysDisabled = this.daysDisabled;
          }
          if (changes.isDisabled) {
              this._datepickerRef.instance.isDisabled = this.isDisabled;
          }
          if (changes.dateCustomClasses) {
              this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
          }
      }
      ngAfterViewInit() {
          this.isOpen$.pipe(filter(isOpen => isOpen !== this.isOpen), takeUntil(this.isDestroy$))
              .subscribe(() => this.toggle());
      }
      /**
       * Opens an element’s datepicker. This is considered a “manual” triggering of
       * the datepicker.
       */
      show() {
          if (this._datepicker.isShown) {
              return;
          }
          this.setConfig();
          this._datepickerRef = this._datepicker
              .provide({ provide: BsDatepickerConfig, useValue: this._config })
              .attach(BsDaterangepickerContainerComponent)
              .to(this.container)
              .position({ attachment: this.placement })
              .show({ placement: this.placement });
          // if date changes from external source (model -> view)
          this._subs.push(this.bsValueChange.subscribe((value) => {
              if (this._datepickerRef) {
                  this._datepickerRef.instance.value = value;
              }
          }));
          // if date changes from picker (view -> model)
          if (this._datepickerRef) {
              this._subs.push(this._datepickerRef.instance.valueChange
                  .pipe(filter((range) => range && range[0] && !!range[1]))
                  .subscribe((value) => {
                  this.bsValue = value;
                  this.hide();
              }));
          }
      }
      /**
       * Set config for daterangepicker
       */
      setConfig() {
          this._config = Object.assign({}, this._config, this.bsConfig, {
              value: checkBsValue(this._bsValue, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
              isDisabled: this.isDisabled,
              minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
              maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
              daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
              dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
              datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
              datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
              ranges: checkRangesWithMaxDate(this.bsConfig && this.bsConfig.ranges, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
              maxDateRange: this.bsConfig && this.bsConfig.maxDateRange
          });
      }
      /**
       * Closes an element’s datepicker. This is considered a “manual” triggering of
       * the datepicker.
       */
      hide() {
          if (this.isOpen) {
              this._datepicker.hide();
          }
          for (const sub of this._subs) {
              sub.unsubscribe();
          }
          if (this._config.returnFocusToInput) {
              this._renderer.selectRootElement(this._elementRef.nativeElement).focus();
          }
      }
      /**
       * Toggles an element’s datepicker. This is considered a “manual” triggering
       * of the datepicker.
       */
      toggle() {
          if (this.isOpen) {
              return this.hide();
          }
          this.show();
      }
      ngOnDestroy() {
          this._datepicker.dispose();
          this.isOpen$.next(false);
          if (this.isDestroy$) {
              this.isDestroy$.next();
              this.isDestroy$.complete();
          }
      }
  }
  BsDaterangepickerDirective.decorators = [
      { type: Directive, args: [{
                  selector: '[bsDaterangepicker]',
                  exportAs: 'bsDaterangepicker'
              },] }
  ];
  BsDaterangepickerDirective.ctorParameters = () => [
      { type: BsDaterangepickerConfig },
      { type: ElementRef },
      { type: Renderer2 },
      { type: ViewContainerRef },
      { type: ComponentLoaderFactory }
  ];
  BsDaterangepickerDirective.propDecorators = {
      placement: [{ type: Input }],
      triggers: [{ type: Input }],
      outsideClick: [{ type: Input }],
      container: [{ type: Input }],
      outsideEsc: [{ type: Input }],
      isOpen: [{ type: Input }],
      onShown: [{ type: Output }],
      onHidden: [{ type: Output }],
      bsValue: [{ type: Input }],
      bsConfig: [{ type: Input }],
      isDisabled: [{ type: Input }],
      minDate: [{ type: Input }],
      maxDate: [{ type: Input }],
      dateCustomClasses: [{ type: Input }],
      daysDisabled: [{ type: Input }],
      datesDisabled: [{ type: Input }],
      datesEnabled: [{ type: Input }],
      bsValueChange: [{ type: Output }]
  };
  
  const BS_DATERANGEPICKER_VALUE_ACCESSOR = {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => BsDaterangepickerInputDirective),
      multi: true
  };
  const BS_DATERANGEPICKER_VALIDATOR = {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => BsDaterangepickerInputDirective),
      multi: true
  };
  class BsDaterangepickerInputDirective {
      constructor(_picker, _localeService, _renderer, _elRef, changeDetection) {
          this._picker = _picker;
          this._localeService = _localeService;
          this._renderer = _renderer;
          this._elRef = _elRef;
          this.changeDetection = changeDetection;
          this._onChange = Function.prototype;
          this._onTouched = Function.prototype;
          this._validatorChange = Function.prototype;
          this._subs = new Subscription();
      }
      ngOnInit() {
          const setBsValue = (value) => {
              this._setInputValue(value);
              if (this._value !== value) {
                  this._value = value;
                  this._onChange(value);
                  this._onTouched();
              }
              this.changeDetection.markForCheck();
          };
          // if value set via [bsValue] it will not get into value change
          if (this._picker._bsValue) {
              setBsValue(this._picker._bsValue);
          }
          // update input value on datepicker value update
          this._subs.add(this._picker.bsValueChange.subscribe((value) => {
              this._setInputValue(value);
              if (this._value !== value) {
                  this._value = value;
                  this._onChange(value);
                  this._onTouched();
              }
              this.changeDetection.markForCheck();
          }));
          // update input value on locale change
          this._subs.add(this._localeService.localeChange.subscribe(() => {
              this._setInputValue(this._value);
          }));
          this._subs.add(
          // update input value on format change
          this._picker.rangeInputFormat$.pipe(distinctUntilChanged()).subscribe(() => {
              this._setInputValue(this._value);
          }));
      }
      ngOnDestroy() {
          this._subs.unsubscribe();
      }
      onKeydownEvent(event) {
          if (event.keyCode === 13 || event.code === 'Enter') {
              this.hide();
          }
      }
      _setInputValue(date) {
          let range = '';
          if (date) {
              const start = !date[0] ? ''
                  : formatDate(date[0], this._picker._config.rangeInputFormat, this._localeService.currentLocale);
              const end = !date[1] ? ''
                  : formatDate(date[1], this._picker._config.rangeInputFormat, this._localeService.currentLocale);
              range = (start && end) ? start + this._picker._config.rangeSeparator + end : '';
          }
          this._renderer.setProperty(this._elRef.nativeElement, 'value', range);
      }
      onChange(event) {
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          this.writeValue(event.target.value);
          this._onChange(this._value);
          if (this._picker._config.returnFocusToInput) {
              this._renderer.selectRootElement(this._elRef.nativeElement).focus();
          }
          this._onTouched();
      }
      validate(c) {
          let _value = c.value;
          const errors = [];
          if (_value === null || _value === undefined || !isArray(_value)) {
              return null;
          }
          _value = _value.slice().sort((a, b) => a.getTime() - b.getTime());
          const _isFirstDateValid = isDateValid(_value[0]);
          const _isSecondDateValid = isDateValid(_value[1]);
          if (!_isFirstDateValid) {
              return { bsDate: { invalid: _value[0] } };
          }
          if (!_isSecondDateValid) {
              return { bsDate: { invalid: _value[1] } };
          }
          if (this._picker && this._picker.minDate && isBefore(_value[0], this._picker.minDate, 'date')) {
              _value[0] = this._picker.minDate;
              errors.push({ bsDate: { minDate: this._picker.minDate } });
          }
          if (this._picker && this._picker.maxDate && isAfter(_value[1], this._picker.maxDate, 'date')) {
              _value[1] = this._picker.maxDate;
              errors.push({ bsDate: { maxDate: this._picker.maxDate } });
          }
          if (errors.length > 0) {
              this.writeValue(_value);
              return errors;
          }
          return null;
      }
      registerOnValidatorChange(fn) {
          this._validatorChange = fn;
      }
      writeValue(value) {
          if (!value) {
              this._value = void 0;
          }
          else {
              const _localeKey = this._localeService.currentLocale;
              const _locale = getLocale(_localeKey);
              if (!_locale) {
                  throw new Error(`Locale "${_localeKey}" is not defined, please add it with "defineLocale(...)"`);
              }
              let _input = [];
              if (typeof value === 'string') {
                  const trimmedSeparator = this._picker._config.rangeSeparator.trim();
                  _input = value
                      .split(trimmedSeparator.length > 0 ? trimmedSeparator : this._picker._config.rangeSeparator)
                      .map(_val => _val.trim());
              }
              if (Array.isArray(value)) {
                  _input = value;
              }
              this._value = _input
                  .map((_val) => {
                  if (this._picker._config.useUtc) {
                      return utcAsLocal(parseDate(_val, this._picker._config.rangeInputFormat, this._localeService.currentLocale));
                  }
                  return parseDate(_val, this._picker._config.rangeInputFormat, this._localeService.currentLocale);
              })
                  .map((date) => (isNaN(date.valueOf()) ? void 0 : date));
          }
          this._picker.bsValue = this._value;
      }
      setDisabledState(isDisabled) {
          this._picker.isDisabled = isDisabled;
          if (isDisabled) {
              this._renderer.setAttribute(this._elRef.nativeElement, 'disabled', 'disabled');
              return;
          }
          this._renderer.removeAttribute(this._elRef.nativeElement, 'disabled');
      }
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      registerOnChange(fn) {
          this._onChange = fn;
      }
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      registerOnTouched(fn) {
          this._onTouched = fn;
      }
      onBlur() {
          this._onTouched();
      }
      hide() {
          this._picker.hide();
          this._renderer.selectRootElement(this._elRef.nativeElement).blur();
          if (this._picker._config.returnFocusToInput) {
              this._renderer.selectRootElement(this._elRef.nativeElement).focus();
          }
      }
  }
  BsDaterangepickerInputDirective.decorators = [
      { type: Directive, args: [{
                  selector: `input[bsDaterangepicker]`,
                  // eslint-disable-next-line @angular-eslint/no-host-metadata-property
                  host: {
                      '(change)': 'onChange($event)',
                      '(keyup.esc)': 'hide()',
                      '(keydown)': 'onKeydownEvent($event)',
                      '(blur)': 'onBlur()'
                  },
                  providers: [BS_DATERANGEPICKER_VALUE_ACCESSOR, BS_DATERANGEPICKER_VALIDATOR]
              },] }
  ];
  BsDaterangepickerInputDirective.ctorParameters = () => [
      { type: BsDaterangepickerDirective, decorators: [{ type: Host }] },
      { type: BsLocaleService },
      { type: Renderer2 },
      { type: ElementRef },
      { type: ChangeDetectorRef }
  ];
  
  class DateFormatter {
      format(date, format, locale) {
          return formatDate(date, format, locale);
      }
  }
  
  class DatePickerInnerComponent {
      constructor() {
          this.monthColLimit = 0;
          this.yearColLimit = 0;
          this.selectionDone = new EventEmitter(undefined);
          this.update = new EventEmitter(false);
          this.activeDateChange = new EventEmitter(undefined);
          this.stepDay = {};
          this.stepMonth = {};
          this.stepYear = {};
          this.modes = ['day', 'month', 'year'];
          this.dateFormatter = new DateFormatter();
      }
      get activeDate() {
          return this._activeDate;
      }
      set activeDate(value) {
          this._activeDate = value;
      }
      // todo: add formatter value to Date object
      ngOnInit() {
          // todo: use date for unique value
          this.uniqueId = `datepicker--${Math.floor(Math.random() * 10000)}`;
          if (this.initDate) {
              this.activeDate = this.initDate;
              this.selectedDate = new Date(this.activeDate.valueOf());
              this.update.emit(this.activeDate);
          }
          else if (this.activeDate === undefined) {
              this.activeDate = new Date();
          }
      }
      // this.refreshView should be called here to reflect the changes on the fly
      ngOnChanges(changes) {
          this.refreshView();
          this.checkIfActiveDateGotUpdated(changes.activeDate);
      }
      // Check if activeDate has been update and then emit the activeDateChange with the new date
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      checkIfActiveDateGotUpdated(activeDate) {
          if (activeDate && !activeDate.firstChange) {
              const previousValue = activeDate.previousValue;
              if (previousValue &&
                  previousValue instanceof Date &&
                  previousValue.getTime() !== activeDate.currentValue.getTime()) {
                  this.activeDateChange.emit(this.activeDate);
              }
          }
      }
      setCompareHandler(handler, type) {
          if (type === 'day') {
              this.compareHandlerDay = handler;
          }
          if (type === 'month') {
              this.compareHandlerMonth = handler;
          }
          if (type === 'year') {
              this.compareHandlerYear = handler;
          }
      }
      compare(date1, date2) {
          if (date1 === undefined || date2 === undefined) {
              return undefined;
          }
          if (this.datepickerMode === 'day' && this.compareHandlerDay) {
              return this.compareHandlerDay(date1, date2);
          }
          if (this.datepickerMode === 'month' && this.compareHandlerMonth) {
              return this.compareHandlerMonth(date1, date2);
          }
          if (this.datepickerMode === 'year' && this.compareHandlerYear) {
              return this.compareHandlerYear(date1, date2);
          }
          return void 0;
      }
      setRefreshViewHandler(handler, type) {
          if (type === 'day') {
              this.refreshViewHandlerDay = handler;
          }
          if (type === 'month') {
              this.refreshViewHandlerMonth = handler;
          }
          if (type === 'year') {
              this.refreshViewHandlerYear = handler;
          }
      }
      refreshView() {
          if (this.datepickerMode === 'day' && this.refreshViewHandlerDay) {
              this.refreshViewHandlerDay();
          }
          if (this.datepickerMode === 'month' && this.refreshViewHandlerMonth) {
              this.refreshViewHandlerMonth();
          }
          if (this.datepickerMode === 'year' && this.refreshViewHandlerYear) {
              this.refreshViewHandlerYear();
          }
      }
      dateFilter(date, format) {
          return this.dateFormatter.format(date, format, this.locale);
      }
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      isActive(dateObject) {
          if (this.compare(dateObject.date, this.activeDate) === 0) {
              this.activeDateId = dateObject.uid;
              return true;
          }
          return false;
      }
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      createDateObject(date, format) {
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          const dateObject = {};
          dateObject.date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
          dateObject.date = this.fixTimeZone(dateObject.date);
          dateObject.label = this.dateFilter(date, format);
          dateObject.selected = this.compare(date, this.selectedDate) === 0;
          dateObject.disabled = this.isDisabled(date);
          dateObject.current = this.compare(date, new Date()) === 0;
          dateObject.customClass = this.getCustomClassForDate(dateObject.date);
          return dateObject;
      }
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      split(arr, size) {
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          const arrays = [];
          while (arr.length > 0) {
              arrays.push(arr.splice(0, size));
          }
          return arrays;
      }
      // Fix a hard-reproducible bug with timezones
      // The bug depends on OS, browser, current timezone and current date
      // i.e.
      // var date = new Date(2014, 0, 1);
      // console.log(date.getFullYear(), date.getMonth(), date.getDate(),
      // date.getHours()); can result in "2013 11 31 23" because of the bug.
      fixTimeZone(date) {
          const hours = date.getHours();
          return new Date(date.getFullYear(), date.getMonth(), date.getDate(), hours === 23 ? hours + 2 : 0);
      }
      select(date, isManual = true) {
          if (this.datepickerMode === this.minMode) {
              if (!this.activeDate) {
                  this.activeDate = new Date(0, 0, 0, 0, 0, 0, 0);
              }
              this.activeDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
              this.activeDate = this.fixTimeZone(this.activeDate);
              if (isManual) {
                  this.selectionDone.emit(this.activeDate);
              }
          }
          else {
              this.activeDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
              this.activeDate = this.fixTimeZone(this.activeDate);
              if (isManual && this.datepickerMode) {
                  this.datepickerMode = this.modes[this.modes.indexOf(this.datepickerMode) - 1];
              }
          }
          this.selectedDate = new Date(this.activeDate.valueOf());
          this.update.emit(this.activeDate);
          this.refreshView();
      }
      move(direction) {
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          let expectedStep;
          if (this.datepickerMode === 'day') {
              expectedStep = this.stepDay;
          }
          if (this.datepickerMode === 'month') {
              expectedStep = this.stepMonth;
          }
          if (this.datepickerMode === 'year') {
              expectedStep = this.stepYear;
          }
          if (expectedStep && this.activeDate) {
              const year = this.activeDate.getFullYear() + direction * (expectedStep.years || 0);
              const month = this.activeDate.getMonth() + direction * (expectedStep.months || 0);
              this.activeDate = new Date(year, month, 1);
              this.refreshView();
              this.activeDateChange.emit(this.activeDate);
          }
      }
      toggleMode(_direction) {
          const direction = _direction || 1;
          if ((this.datepickerMode === this.maxMode && direction === 1) ||
              (this.datepickerMode === this.minMode && direction === -1)) {
              return;
          }
          if (this.datepickerMode) {
              this.datepickerMode = this.modes[this.modes.indexOf(this.datepickerMode) + direction];
          }
          this.refreshView();
      }
      getCustomClassForDate(date) {
          if (!this.customClass) {
              return '';
          }
          // todo: build a hash of custom classes, it will work faster
          const customClassObject = this.customClass.find((customClass) => {
              return (customClass.date.valueOf() === date.valueOf() &&
                  customClass.mode === this.datepickerMode);
          }, this);
          return customClassObject === undefined ? '' : customClassObject.clazz;
      }
      compareDateDisabled(date1Disabled, date2) {
          if (date1Disabled === undefined || date2 === undefined) {
              return undefined;
          }
          if (date1Disabled.mode === 'day' && this.compareHandlerDay) {
              return this.compareHandlerDay(date1Disabled.date, date2);
          }
          if (date1Disabled.mode === 'month' && this.compareHandlerMonth) {
              return this.compareHandlerMonth(date1Disabled.date, date2);
          }
          if (date1Disabled.mode === 'year' && this.compareHandlerYear) {
              return this.compareHandlerYear(date1Disabled.date, date2);
          }
          return undefined;
      }
      isDisabled(date) {
          let isDateDisabled = false;
          if (this.dateDisabled) {
              this.dateDisabled.forEach((disabledDate) => {
                  if (this.compareDateDisabled(disabledDate, date) === 0) {
                      isDateDisabled = true;
                  }
              });
          }
          if (this.dayDisabled) {
              isDateDisabled =
                  isDateDisabled ||
                      this.dayDisabled.indexOf(date.getDay()) > -1;
          }
          if (isDateDisabled) {
              return isDateDisabled;
          }
          const minDate = Number(this.minDate && this.compare(date, this.minDate));
          if (!isNaN(minDate)) {
              return minDate < 0;
          }
          const maxDate = Number(this.maxDate && this.compare(date, this.maxDate));
          if (!isNaN(maxDate)) {
              return maxDate > 0;
          }
          return false;
      }
  }
  DatePickerInnerComponent.decorators = [
      { type: Component, args: [{
                  selector: 'datepicker-inner',
                  template: `
      <!--&lt;!&ndash;ng-keydown="keydown($event)"&ndash;&gt;-->
      <div *ngIf='datepickerMode' class='well well-sm bg-faded p-a card' role='application'>
        <ng-content></ng-content>
      </div>
    `
              },] }
  ];
  DatePickerInnerComponent.propDecorators = {
      locale: [{ type: Input }],
      datepickerMode: [{ type: Input }],
      startingDay: [{ type: Input }],
      yearRange: [{ type: Input }],
      minDate: [{ type: Input }],
      maxDate: [{ type: Input }],
      minMode: [{ type: Input }],
      maxMode: [{ type: Input }],
      showWeeks: [{ type: Input }],
      formatDay: [{ type: Input }],
      formatMonth: [{ type: Input }],
      formatYear: [{ type: Input }],
      formatDayHeader: [{ type: Input }],
      formatDayTitle: [{ type: Input }],
      formatMonthTitle: [{ type: Input }],
      onlyCurrentMonth: [{ type: Input }],
      shortcutPropagation: [{ type: Input }],
      customClass: [{ type: Input }],
      monthColLimit: [{ type: Input }],
      yearColLimit: [{ type: Input }],
      dateDisabled: [{ type: Input }],
      dayDisabled: [{ type: Input }],
      initDate: [{ type: Input }],
      selectionDone: [{ type: Output }],
      update: [{ type: Output }],
      activeDateChange: [{ type: Output }],
      activeDate: [{ type: Input }]
  };
  
  class DatepickerConfig {
      constructor() {
          this.locale = 'en';
          this.datepickerMode = 'day';
          this.startingDay = 0;
          this.yearRange = 20;
          this.minMode = 'day';
          this.maxMode = 'year';
          this.showWeeks = true;
          this.formatDay = 'DD';
          this.formatMonth = 'MMMM';
          this.formatYear = 'YYYY';
          this.formatDayHeader = 'dd';
          this.formatDayTitle = 'MMMM YYYY';
          this.formatMonthTitle = 'YYYY';
          this.onlyCurrentMonth = false;
          this.monthColLimit = 3;
          this.yearColLimit = 5;
          this.shortcutPropagation = false;
      }
  }
  DatepickerConfig.ɵprov = ɵɵdefineInjectable({ factory: function DatepickerConfig_Factory() { return new DatepickerConfig(); }, token: DatepickerConfig, providedIn: "root" });
  DatepickerConfig.decorators = [
      { type: Injectable, args: [{
                  providedIn: 'root'
              },] }
  ];
  
  const DATEPICKER_CONTROL_VALUE_ACCESSOR = {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => DatePickerComponent),
      multi: true
  };
  class DatePickerComponent {
      constructor(config) {
          /** sets datepicker mode, supports: `day`, `month`, `year` */
          this.datepickerMode = 'day';
          /** if false week numbers will be hidden */
          this.showWeeks = true;
          /** number of months displayed in a single row of month picker */
          this.monthColLimit = 3;
          /** number of years displayed in a single row of year picker */
          this.yearColLimit = 5;
          this.selectionDone = new EventEmitter(undefined);
          /** callback to invoke when the activeDate is changed. */
          this.activeDateChange = new EventEmitter(undefined);
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          this.onChange = Function.prototype;
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          this.onTouched = Function.prototype;
          this._now = new Date();
          this.config = config;
          this.configureOptions();
      }
      /** currently active date */
      get activeDate() {
          return this._activeDate || this._now;
      }
      set activeDate(value) {
          this._activeDate = value;
      }
      configureOptions() {
          Object.assign(this, this.config);
      }
      onUpdate(event) {
          this.activeDate = event;
          this.onChange(event);
      }
      onSelectionDone(event) {
          this.selectionDone.emit(event);
      }
      onActiveDateChange(event) {
          this.activeDateChange.emit(event);
      }
      // todo: support null value
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      writeValue(value) {
          var _a, _b;
          if (((_a = this._datePicker) === null || _a === void 0 ? void 0 : _a.compare(value, this._activeDate)) === 0) {
              return;
          }
          if (value && value instanceof Date) {
              this.activeDate = value;
              (_b = this._datePicker) === null || _b === void 0 ? void 0 : _b.select(value, false);
              return;
          }
          this.activeDate = value ? new Date(value) : void 0;
      }
      registerOnChange(fn) {
          this.onChange = fn;
      }
      registerOnTouched(fn) {
          this.onTouched = fn;
      }
  }
  DatePickerComponent.decorators = [
      { type: Component, args: [{
                  selector: 'datepicker',
                  template: `
      <datepicker-inner [activeDate]="activeDate"
                        (update)="onUpdate($event)"
                        [locale]="config.locale"
                        [datepickerMode]="datepickerMode"
                        [initDate]="initDate"
                        [minDate]="minDate"
                        [maxDate]="maxDate"
                        [minMode]="minMode"
                        [maxMode]="maxMode"
                        [showWeeks]="showWeeks"
                        [formatDay]="formatDay"
                        [formatMonth]="formatMonth"
                        [formatYear]="formatYear"
                        [formatDayHeader]="formatDayHeader"
                        [formatDayTitle]="formatDayTitle"
                        [formatMonthTitle]="formatMonthTitle"
                        [startingDay]="startingDay"
                        [yearRange]="yearRange"
                        [customClass]="customClass"
                        [dateDisabled]="dateDisabled"
                        [dayDisabled]="dayDisabled"
                        [onlyCurrentMonth]="onlyCurrentMonth"
                        [shortcutPropagation]="shortcutPropagation"
                        [monthColLimit]="monthColLimit"
                        [yearColLimit]="yearColLimit"
                        (selectionDone)="onSelectionDone($event)"
                        (activeDateChange)="onActiveDateChange($event)">
        <daypicker tabindex="0"></daypicker>
        <monthpicker tabindex="0"></monthpicker>
        <yearpicker tabindex="0"></yearpicker>
      </datepicker-inner>
      `,
                  providers: [DATEPICKER_CONTROL_VALUE_ACCESSOR]
              },] }
  ];
  DatePickerComponent.ctorParameters = () => [
      { type: DatepickerConfig }
  ];
  DatePickerComponent.propDecorators = {
      datepickerMode: [{ type: Input }],
      initDate: [{ type: Input }],
      minDate: [{ type: Input }],
      maxDate: [{ type: Input }],
      minMode: [{ type: Input }],
      maxMode: [{ type: Input }],
      showWeeks: [{ type: Input }],
      formatDay: [{ type: Input }],
      formatMonth: [{ type: Input }],
      formatYear: [{ type: Input }],
      formatDayHeader: [{ type: Input }],
      formatDayTitle: [{ type: Input }],
      formatMonthTitle: [{ type: Input }],
      startingDay: [{ type: Input }],
      yearRange: [{ type: Input }],
      onlyCurrentMonth: [{ type: Input }],
      shortcutPropagation: [{ type: Input }],
      monthColLimit: [{ type: Input }],
      yearColLimit: [{ type: Input }],
      customClass: [{ type: Input }],
      dateDisabled: [{ type: Input }],
      dayDisabled: [{ type: Input }],
      activeDate: [{ type: Input }],
      selectionDone: [{ type: Output }],
      activeDateChange: [{ type: Output }],
      _datePicker: [{ type: ViewChild, args: [DatePickerInnerComponent, { static: true },] }]
  };
  
  // @deprecated
  class DayPickerComponent {
      constructor(datePicker) {
          this.labels = [];
          // eslint-disable-next-line @typescript-eslint/ban-ts-comment
          // @ts-ignore
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          this.rows = [];
          this.weekNumbers = [];
          this.datePicker = datePicker;
      }
      get isBs4() {
          return !isBs3();
      }
      /*protected getDaysInMonth(year:number, month:number) {
       return ((month === 1) && (year % 4 === 0) &&
       ((year % 100 !== 0) || (year % 400 === 0))) ? 29 : DAYS_IN_MONTH[month];
       }*/
      ngOnInit() {
          // eslint-disable-next-line @typescript-eslint/no-this-alias
          const self = this;
          this.datePicker.stepDay = { months: 1 };
          // todo valorkin fix
          this.datePicker.setRefreshViewHandler(function () {
              // eslint-disable-next-line @typescript-eslint/ban-ts-comment
              // @ts-ignore
              // eslint-disable-next-line @typescript-eslint/no-this-alias
              const that = this;
              const year = that.activeDate.getFullYear();
              const month = that.activeDate.getMonth();
              const firstDayOfMonth = new Date(year, month, 1);
              const difference = that.startingDay - firstDayOfMonth.getDay();
              const numDisplayedFromPreviousMonth = difference > 0 ? 7 - difference : -difference;
              const firstDate = new Date(firstDayOfMonth.getTime());
              if (numDisplayedFromPreviousMonth > 0) {
                  firstDate.setDate(-numDisplayedFromPreviousMonth + 1);
              }
              // 42 is the number of days on a six-week calendar
              const _days = self.getDates(firstDate, 42);
              const days = [];
              for (let i = 0; i < 42; i++) {
                  const _dateObject = that.createDateObject(_days[i], that.formatDay);
                  _dateObject.secondary = _days[i].getMonth() !== month;
                  _dateObject.uid = that.uniqueId + '-' + i;
                  days[i] = _dateObject;
              }
              self.labels = [];
              for (let j = 0; j < 7; j++) {
                  self.labels[j] = {};
                  self.labels[j].abbr = that.dateFilter(days[j].date, that.formatDayHeader);
                  self.labels[j].full = that.dateFilter(days[j].date, 'EEEE');
              }
              self.title = that.dateFilter(that.activeDate, that.formatDayTitle);
              self.rows = that.split(days, 7);
              if (that.showWeeks) {
                  self.weekNumbers = [];
                  const thursdayIndex = (4 + 7 - that.startingDay) % 7;
                  const numWeeks = self.rows.length;
                  for (let curWeek = 0; curWeek < numWeeks; curWeek++) {
                      const _date = self.rows[curWeek][thursdayIndex].date;
                      if (_date) {
                          self.weekNumbers.push(self.getISO8601WeekNumber(_date));
                      }
                  }
              }
          }, 'day');
          this.datePicker.setCompareHandler(function (date1, date2) {
              const d1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate());
              const d2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
              return d1.getTime() - d2.getTime();
          }, 'day');
          this.datePicker.refreshView();
      }
      getDates(startDate, n) {
          const dates = new Array(n);
          let current = new Date(startDate.getTime());
          let i = 0;
          let date;
          while (i < n) {
              date = new Date(current.getTime());
              date = this.datePicker.fixTimeZone(date);
              dates[i++] = date;
              current = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);
          }
          return dates;
      }
      getISO8601WeekNumber(date) {
          const checkDate = new Date(date.getTime());
          // Thursday
          checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
          const time = checkDate.getTime();
          // Compare with Jan 1
          checkDate.setMonth(0);
          checkDate.setDate(1);
          return (Math.floor(Math.round((time - checkDate.getTime()) / 86400000) / 7) + 1);
      }
  }
  DayPickerComponent.decorators = [
      { type: Component, args: [{
                  selector: 'daypicker',
                  template: `
  <table *ngIf="datePicker.datepickerMode === 'day'" role="grid" [attr.aria-labelledby]="datePicker.uniqueId + '-title'" aria-activedescendant="activeDateId">
    <thead>
      <tr>
        <th>
          <button *ngIf="!isBs4"
                  type="button"
                  class="btn btn-default btn-secondary btn-sm pull-left float-left"
                  (click)="datePicker.move(-1)"
                  tabindex="-1">‹</button>
          <button *ngIf="isBs4"
                  type="button"
                  class="btn btn-default btn-secondary btn-sm pull-left float-left"
                  (click)="datePicker.move(-1)"
                  tabindex="-1">&lt;</button>
        </th>
        <th [attr.colspan]="5 + (datePicker.showWeeks ? 1 : 0)">
          <button [id]="datePicker.uniqueId + '-title'"
                  type="button" class="btn btn-default btn-secondary btn-sm"
                  (click)="datePicker.toggleMode(0)"
                  [disabled]="datePicker.datepickerMode === datePicker.maxMode"
                  [ngClass]="{disabled: datePicker.datepickerMode === datePicker.maxMode}" tabindex="-1" style="width:100%;">
            <strong>{{ title }}</strong>
          </button>
        </th>
        <th>
          <button *ngIf="!isBs4"
                  type="button"
                  class="btn btn-default btn-secondary btn-sm pull-right float-right"
                  (click)="datePicker.move(1)"
                  tabindex="-1">›</button>
          <button *ngIf="isBs4"
                  type="button"
                  class="btn btn-default btn-secondary btn-sm pull-right float-right"
                  (click)="datePicker.move(1)"
                  tabindex="-1">&gt;
          </button>
        </th>
      </tr>
      <tr>
        <th *ngIf="datePicker.showWeeks"></th>
        <th *ngFor="let labelz of labels" class="text-center">
          <small aria-label="labelz.full"><b>{{ labelz.abbr }}</b></small>
        </th>
      </tr>
    </thead>
    <tbody>
      <ng-template ngFor [ngForOf]="rows" let-rowz="$implicit" let-index="index">
        <tr *ngIf="!(datePicker.onlyCurrentMonth && rowz[0].secondary && rowz[6].secondary)">
          <td *ngIf="datePicker.showWeeks" class="h6" class="text-center">
            <em>{{ weekNumbers[index] }}</em>
          </td>
          <td *ngFor="let dtz of rowz" class="text-center" role="gridcell" [id]="dtz.uid">
            <button type="button" style="min-width:100%;" class="btn btn-sm {{dtz.customClass}}"
                    *ngIf="!(datePicker.onlyCurrentMonth && dtz.secondary)"
                    [ngClass]="{'btn-secondary': isBs4 && !dtz.selected && !datePicker.isActive(dtz), 'btn-info': dtz.selected, disabled: dtz.disabled, active: !isBs4 && datePicker.isActive(dtz), 'btn-default': !isBs4}"
                    [disabled]="dtz.disabled"
                    (click)="datePicker.select(dtz.date)" tabindex="-1">
              <span [ngClass]="{'text-muted': dtz.secondary || dtz.current, 'text-info': !isBs4 && dtz.current}">{{ dtz.label }}</span>
            </button>
          </td>
        </tr>
      </ng-template>
    </tbody>
  </table>
    `,
                  styles: [`
      :host .btn-secondary {
        color: #292b2c;
        background-color: #fff;
        border-color: #ccc;
      }
      :host .btn-info .text-muted {
        color: #292b2c !important;
      }
    `]
              },] }
  ];
  DayPickerComponent.ctorParameters = () => [
      { type: DatePickerInnerComponent }
  ];
  
  // @deprecated
  class MonthPickerComponent {
      constructor(datePicker) {
          this.rows = [];
          this.datePicker = datePicker;
      }
      get isBs4() {
          return !isBs3();
      }
      ngOnInit() {
          // eslint-disable-next-line @typescript-eslint/no-this-alias
          const self = this;
          this.datePicker.stepMonth = { years: 1 };
          this.datePicker.setRefreshViewHandler(function () {
              // eslint-disable-next-line @typescript-eslint/ban-ts-comment
              // @ts-ignore
              // eslint-disable-next-line @typescript-eslint/no-this-alias
              const that = this;
              const months = new Array(12);
              const year = that.activeDate.getFullYear();
              let date;
              for (let i = 0; i < 12; i++) {
                  date = new Date(year, i, 1);
                  date = that.fixTimeZone(date);
                  months[i] = that.createDateObject(date, that.formatMonth);
                  months[i].uid = that.uniqueId + '-' + i;
              }
              self.title = that.dateFilter(that.activeDate, that.formatMonthTitle);
              self.rows = that.split(months, self.datePicker.monthColLimit);
          }, 'month');
          this.datePicker.setCompareHandler(function (date1, date2) {
              const d1 = new Date(date1.getFullYear(), date1.getMonth());
              const d2 = new Date(date2.getFullYear(), date2.getMonth());
              return d1.getTime() - d2.getTime();
          }, 'month');
          this.datePicker.refreshView();
      }
  }
  MonthPickerComponent.decorators = [
      { type: Component, args: [{
                  selector: 'monthpicker',
                  template: `
  <table *ngIf="datePicker.datepickerMode==='month'" role="grid">
    <thead>
      <tr>
        <th>
          <button type="button" class="btn btn-default btn-sm pull-left float-left"
                  (click)="datePicker.move(-1)" tabindex="-1">‹</button></th>
        <th [attr.colspan]="((datePicker.monthColLimit - 2) <= 0) ? 1 : datePicker.monthColLimit - 2">
          <button [id]="datePicker.uniqueId + '-title'"
                  type="button" class="btn btn-default btn-sm"
                  (click)="datePicker.toggleMode(0)"
                  [disabled]="datePicker.datepickerMode === maxMode"
                  [ngClass]="{disabled: datePicker.datepickerMode === maxMode}" tabindex="-1" style="width:100%;">
            <strong>{{ title }}</strong>
          </button>
        </th>
        <th>
          <button type="button" class="btn btn-default btn-sm pull-right float-right"
                  (click)="datePicker.move(1)" tabindex="-1">›</button>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let rowz of rows">
        <td *ngFor="let dtz of rowz" class="text-center" role="gridcell" [attr.id]="dtz.uid" [ngClass]="dtz.customClass">
          <button type="button" style="min-width:100%;" class="btn btn-default"
                  [ngClass]="{'btn-link': isBs4 && !dtz.selected && !datePicker.isActive(dtz), 'btn-info': dtz.selected || (isBs4 && !dtz.selected && datePicker.isActive(dtz)), disabled: dtz.disabled, active: !isBs4 && datePicker.isActive(dtz)}"
                  [disabled]="dtz.disabled"
                  (click)="datePicker.select(dtz.date)" tabindex="-1">
            <span [ngClass]="{'text-success': isBs4 && dtz.current, 'text-info': !isBs4 && dtz.current}">{{ dtz.label }}</span>
          </button>
        </td>
      </tr>
    </tbody>
  </table>
    `,
                  styles: [`
      :host .btn-info .text-success {
        color: #fff !important;
      }
    `]
              },] }
  ];
  MonthPickerComponent.ctorParameters = () => [
      { type: DatePickerInnerComponent }
  ];
  
  // @deprecated
  class YearPickerComponent {
      constructor(datePicker) {
          this.rows = [];
          this.datePicker = datePicker;
      }
      get isBs4() {
          return !isBs3();
      }
      ngOnInit() {
          // eslint-disable-next-line @typescript-eslint/no-this-alias
          const self = this;
          this.datePicker.stepYear = { years: this.datePicker.yearRange };
          this.datePicker.setRefreshViewHandler(function () {
              // eslint-disable-next-line @typescript-eslint/ban-ts-comment
              // @ts-ignore
              // eslint-disable-next-line @typescript-eslint/no-this-alias
              const that = this;
              const years = new Array(that.yearRange);
              let date;
              const start = self.getStartingYear(that.activeDate.getFullYear()) || 0;
              for (let i = 0; i < that.yearRange; i++) {
                  date = new Date(start + i, 0, 1);
                  date = that.fixTimeZone(date);
                  years[i] = that.createDateObject(date, that.formatYear);
                  years[i].uid = that.uniqueId + '-' + i;
              }
              self.title = [years[0].label, years[that.yearRange - 1].label].join(' - ');
              self.rows = that.split(years, self.datePicker.yearColLimit);
          }, 'year');
          this.datePicker.setCompareHandler(function (date1, date2) {
              return date1.getFullYear() - date2.getFullYear();
          }, 'year');
          this.datePicker.refreshView();
      }
      getStartingYear(year) {
          // todo: parseInt
          if (this.datePicker && this.datePicker.yearRange) {
              return ((year - 1) / this.datePicker.yearRange * this.datePicker.yearRange + 1);
          }
          return undefined;
      }
  }
  YearPickerComponent.decorators = [
      { type: Component, args: [{
                  selector: 'yearpicker',
                  template: `
      <table *ngIf="datePicker.datepickerMode==='year'" role='grid'>
        <thead>
        <tr>
          <th>
            <button type='button' class='btn btn-default btn-sm pull-left float-left'
                    (click)='datePicker.move(-1)' tabindex='-1'>‹
            </button>
          </th>
          <th [attr.colspan]='((datePicker.yearColLimit - 2) <= 0) ? 1 : datePicker.yearColLimit - 2'>
            <button [id]="datePicker.uniqueId + '-title'" role='heading'
                    type='button' class='btn btn-default btn-sm'
                    (click)='datePicker.toggleMode(0)'
                    [disabled]='datePicker.datepickerMode === datePicker.maxMode'
                    [ngClass]='{disabled: datePicker.datepickerMode === datePicker.maxMode}' tabindex='-1'
                    style='width:100%;'>
              <strong>{{ title }}</strong>
            </button>
          </th>
          <th>
            <button type='button' class='btn btn-default btn-sm pull-right float-right'
                    (click)='datePicker.move(1)' tabindex='-1'>›
            </button>
          </th>
        </tr>
        </thead>
        <tbody>
        <tr *ngFor='let rowz of rows'>
          <td *ngFor='let dtz of rowz' class='text-center' role='gridcell' [attr.id]='dtz.uid'>
            <button type='button' style='min-width:100%;' class='btn btn-default'
                    [ngClass]="{'btn-link': isBs4 && !dtz.selected && !datePicker.isActive(dtz), 'btn-info': dtz.selected || (isBs4 && !dtz.selected && datePicker.isActive(dtz)), disabled: dtz.disabled, active: !isBs4 && datePicker.isActive(dtz)}"
                    [disabled]='dtz.disabled'
                    (click)='datePicker.select(dtz.date)' tabindex='-1'>
              <span
                [ngClass]="{'text-success': isBs4 && dtz.current, 'text-info': !isBs4 && dtz.current}">{{ dtz.label }}</span>
            </button>
          </td>
        </tr>
        </tbody>
      </table>
    `,
                  styles: [`
        :host .btn-info .text-success {
          color: #fff !important;
        }
      `]
              },] }
  ];
  YearPickerComponent.ctorParameters = () => [
      { type: DatePickerInnerComponent }
  ];
  
  class BsCalendarLayoutComponent {
  }
  BsCalendarLayoutComponent.decorators = [
      { type: Component, args: [{
                  selector: 'bs-calendar-layout',
                  template: `
      <!-- current date, will be added in nearest releases -->
      <bs-current-date title="hey there" *ngIf="false"></bs-current-date>
  
      <!--navigation-->
      <div class="bs-datepicker-head">
        <ng-content select="bs-datepicker-navigation-view"></ng-content>
      </div>
  
      <div class="bs-datepicker-body">
        <ng-content></ng-content>
      </div>
  
      <!--timepicker-->
      <bs-timepicker *ngIf="false"></bs-timepicker>
    `
              },] }
  ];
  
  class BsCurrentDateViewComponent {
  }
  BsCurrentDateViewComponent.decorators = [
      { type: Component, args: [{
                  selector: 'bs-current-date',
                  template: `<div class="current-timedate"><span>{{ title }}</span></div>`
              },] }
  ];
  BsCurrentDateViewComponent.propDecorators = {
      title: [{ type: Input }]
  };
  
  class BsCustomDatesViewComponent {
      constructor() {
          this.onSelect = new EventEmitter();
      }
      selectFromRanges(range) {
          this.onSelect.emit(range);
      }
  }
  BsCustomDatesViewComponent.decorators = [
      { type: Component, args: [{
                  selector: 'bs-custom-date-view',
                  template: `
      <div class="bs-datepicker-predefined-btns">
        <button *ngFor="let range of ranges"
          type="button"
          class="btn"
          (click)="selectFromRanges(range)"
          [class.selected]="range.value === selectedRange">
          {{ range.label }}
        </button>
      </div>
    `,
                  changeDetection: ChangeDetectionStrategy.OnPush
              },] }
  ];
  BsCustomDatesViewComponent.propDecorators = {
      ranges: [{ type: Input }],
      selectedRange: [{ type: Input }],
      customRangeLabel: [{ type: Input }],
      onSelect: [{ type: Output }]
  };
  
  class BsDatepickerDayDecoratorComponent {
      constructor(_config, _elRef, _renderer) {
          this._config = _config;
          this._elRef = _elRef;
          this._renderer = _renderer;
          this.day = { date: new Date(), label: '' };
      }
      ngOnInit() {
          var _a, _b, _c;
          if (((_a = this.day) === null || _a === void 0 ? void 0 : _a.isToday) && this._config && this._config.customTodayClass) {
              this._renderer.addClass(this._elRef.nativeElement, this._config.customTodayClass);
          }
          if (typeof ((_b = this.day) === null || _b === void 0 ? void 0 : _b.customClasses) === 'string') {
              (_c = this.day) === null || _c === void 0 ? void 0 : _c.customClasses.split(' ').filter((className) => className).forEach((className) => {
                  this._renderer.addClass(this._elRef.nativeElement, className);
              });
          }
      }
  }
  BsDatepickerDayDecoratorComponent.decorators = [
      { type: Component, args: [{
                  selector: '[bsDatepickerDayDecorator]',
                  changeDetection: ChangeDetectionStrategy.OnPush,
                  host: {
                      '[class.disabled]': 'day.isDisabled',
                      '[class.is-highlighted]': 'day.isHovered',
                      '[class.is-other-month]': 'day.isOtherMonth',
                      '[class.is-active-other-month]': 'day.isOtherMonthHovered',
                      '[class.in-range]': 'day.isInRange',
                      '[class.select-start]': 'day.isSelectionStart',
                      '[class.select-end]': 'day.isSelectionEnd',
                      '[class.selected]': 'day.isSelected'
                  },
                  template: `{{ day && day.label || '' }}`
              },] }
  ];
  BsDatepickerDayDecoratorComponent.ctorParameters = () => [
      { type: BsDatepickerConfig },
      { type: ElementRef },
      { type: Renderer2 }
  ];
  BsDatepickerDayDecoratorComponent.propDecorators = {
      day: [{ type: Input }]
  };
  
  /** *************** */
  // events
  /** *************** */
  var BsNavigationDirection;
  (function (BsNavigationDirection) {
      BsNavigationDirection[BsNavigationDirection["UP"] = 0] = "UP";
      BsNavigationDirection[BsNavigationDirection["DOWN"] = 1] = "DOWN";
  })(BsNavigationDirection || (BsNavigationDirection = {}));
  
  class BsDatepickerNavigationViewComponent {
      constructor() {
          this.onNavigate = new EventEmitter();
          this.onViewMode = new EventEmitter();
      }
      navTo(down) {
          this.onNavigate.emit(down ? BsNavigationDirection.DOWN : BsNavigationDirection.UP);
      }
      view(viewMode) {
          this.onViewMode.emit(viewMode);
      }
  }
  BsDatepickerNavigationViewComponent.decorators = [
      { type: Component, args: [{
                  selector: 'bs-datepicker-navigation-view',
                  changeDetection: ChangeDetectionStrategy.OnPush,
                  template: `
      <button class="previous"
              [disabled]="calendar.disableLeftArrow"
              [style.visibility]="calendar.hideLeftArrow ? 'hidden' : 'visible'"
              type="button"
              (click)="navTo(true)">
        <span>&lsaquo;</span>
      </button>
  
      <ng-container *ngIf="calendar && calendar.monthTitle">
        &#8203;  <!-- zero-width space needed for correct alignment
                    with preserveWhitespaces: false in Angular -->
  
        <button class="current"
              type="button"
              (click)="view('month')"
        ><span>{{ calendar.monthTitle }}</span>
        </button>
      </ng-container>
  
      &#8203;  <!-- zero-width space needed for correct alignment
                    with preserveWhitespaces: false in Angular -->
  
      <button class="current" (click)="view('year')" type="button">
        <span>{{ calendar.yearTitle }}</span>
      </button>
  
      &#8203;  <!-- zero-width space needed for correct alignment
                    with preserveWhitespaces: false in Angular -->
  
      <button class="next"
              [disabled]="calendar.disableRightArrow"
              [style.visibility]="calendar.hideRightArrow ? 'hidden' : 'visible'"
              type="button"
              (click)="navTo(false)"><span>&rsaquo;</span>
      </button>
    `
              },] }
  ];
  BsDatepickerNavigationViewComponent.propDecorators = {
      calendar: [{ type: Input }],
      onNavigate: [{ type: Output }],
      onViewMode: [{ type: Output }]
  };
  
  class BsDaysCalendarViewComponent {
      constructor(_config) {
          this._config = _config;
          this.onNavigate = new EventEmitter();
          this.onViewMode = new EventEmitter();
          this.onSelect = new EventEmitter();
          this.onHover = new EventEmitter();
          this.onHoverWeek = new EventEmitter();
          this.isiOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
              (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1));
          if (this._config.dateTooltipTexts && this._config.dateTooltipTexts.length > 0) {
              this.isShowTooltip = true;
          }
      }
      navigateTo(event) {
          const step = BsNavigationDirection.DOWN === event ? -1 : 1;
          this.onNavigate.emit({ step: { month: step } });
      }
      changeViewMode(event) {
          this.onViewMode.emit(event);
      }
      selectDay(event) {
          this.onSelect.emit(event);
      }
      selectWeek(week) {
          if (!this._config.selectWeek && !this._config.selectWeekDateRange) {
              return;
          }
          if (week.days.length === 0) {
              return;
          }
          if (this._config.selectWeek && week.days[0]
              && !week.days[0].isDisabled
              && this._config.selectFromOtherMonth) {
              this.onSelect.emit(week.days[0]);
              return;
          }
          const selectedDay = week.days.find((day) => {
              return this._config.selectFromOtherMonth
                  ? !day.isDisabled
                  : !day.isOtherMonth && !day.isDisabled;
          });
          this.onSelect.emit(selectedDay);
          if (this._config.selectWeekDateRange) {
              const days = week.days.slice(0);
              const lastDayOfRange = days.reverse().find((day) => {
                  return this._config.selectFromOtherMonth
                      ? !day.isDisabled
                      : !day.isOtherMonth && !day.isDisabled;
              });
              this.onSelect.emit(lastDayOfRange);
          }
      }
      weekHoverHandler(cell, isHovered) {
          if (!this._config.selectWeek && !this._config.selectWeekDateRange) {
              return;
          }
          const hasActiveDays = cell.days.find((day) => {
              return this._config.selectFromOtherMonth
                  ? !day.isDisabled
                  : !day.isOtherMonth && !day.isDisabled;
          });
          if (hasActiveDays) {
              cell.isHovered = isHovered;
              this.isWeekHovered = isHovered;
              this.onHoverWeek.emit(cell);
          }
      }
      hoverDay(cell, isHovered) {
          if (this._config.selectFromOtherMonth && cell.isOtherMonth) {
              cell.isOtherMonthHovered = isHovered;
          }
          if (this._config.dateTooltipTexts) {
              cell.tooltipText = '';
              this._config.dateTooltipTexts.forEach((dateData) => {
                  if (isSameDay(dateData.date, cell.date)) {
                      cell.tooltipText = dateData.tooltipText;
                      return;
                  }
              });
          }
          this.onHover.emit({ cell, isHovered });
      }
  }
  BsDaysCalendarViewComponent.decorators = [
      { type: Component, args: [{
                  selector: 'bs-days-calendar-view',
                  // changeDetection: ChangeDetectionStrategy.OnPush,
                  template: `
      <bs-calendar-layout>
        <bs-datepicker-navigation-view
          [calendar]="calendar"
          (onNavigate)="navigateTo($event)"
          (onViewMode)="changeViewMode($event)"
        ></bs-datepicker-navigation-view>
        <!--days matrix-->
        <table role="grid" class="days weeks">
          <thead>
          <tr>
            <!--if show weeks-->
            <th *ngIf="options && options.showWeekNumbers"></th>
            <th *ngFor="let weekday of calendar.weekdays; let i = index"
                aria-label="weekday">{{ calendar.weekdays[i] }}
            </th>
          </tr>
          </thead>
          <tbody>
          <tr *ngFor="let week of calendar.weeks; let i = index">
            <td class="week" [class.active-week]="isWeekHovered"  *ngIf="options && options.showWeekNumbers">
              <span *ngIf="isiOS" (click)="selectWeek(week)">{{ calendar.weekNumbers[i] }}</span>
              <span *ngIf="!isiOS"
                  (click)="selectWeek(week)"
                  (mouseenter)="weekHoverHandler(week, true)"
                  (mouseleave)="weekHoverHandler(week, false)">{{ calendar.weekNumbers[i] }}</span>
            </td>
            <td *ngFor="let day of week.days" role="gridcell">
  
              <!-- When we want to show tooltips for dates -->
              <span *ngIf="!isiOS && isShowTooltip" bsDatepickerDayDecorator
                  [day]="day"
                  (click)="selectDay(day)"
                  tooltip="{{day.tooltipText}}"
                  (mouseenter)="hoverDay(day, true)"
                  (mouseleave)="hoverDay(day, false)">{{ day.label }} 3</span>
              <!-- When tooltips for dates are disabled -->
              <span *ngIf="!isiOS && !isShowTooltip" bsDatepickerDayDecorator
                    [day]="day"
                    (click)="selectDay(day)"
                    (mouseenter)="hoverDay(day, true)"
                    (mouseleave)="hoverDay(day, false)">{{ day.label }} 2</span>
  
              <!-- For mobile iOS view, tooltips are not needed -->
              <span *ngIf="isiOS" bsDatepickerDayDecorator
                    [day]="day"
                    (click)="selectDay(day)">{{ day.label }} 1</span>
            </td>
          </tr>
          </tbody>
        </table>
  
      </bs-calendar-layout>
    `
              },] }
  ];
  BsDaysCalendarViewComponent.ctorParameters = () => [
      { type: BsDatepickerConfig }
  ];
  BsDaysCalendarViewComponent.propDecorators = {
      calendar: [{ type: Input }],
      options: [{ type: Input }],
      onNavigate: [{ type: Output }],
      onViewMode: [{ type: Output }],
      onSelect: [{ type: Output }],
      onHover: [{ type: Output }],
      onHoverWeek: [{ type: Output }]
  };
  
  class BsMonthCalendarViewComponent {
      constructor() {
          this.onNavigate = new EventEmitter();
          this.onViewMode = new EventEmitter();
          this.onSelect = new EventEmitter();
          this.onHover = new EventEmitter();
      }
      navigateTo(event) {
          const step = BsNavigationDirection.DOWN === event ? -1 : 1;
          this.onNavigate.emit({ step: { year: step } });
      }
      viewMonth(month) {
          this.onSelect.emit(month);
      }
      hoverMonth(cell, isHovered) {
          this.onHover.emit({ cell, isHovered });
      }
      changeViewMode(event) {
          this.onViewMode.emit(event);
      }
  }
  BsMonthCalendarViewComponent.decorators = [
      { type: Component, args: [{
                  selector: 'bs-month-calendar-view',
                  template: `
      <bs-calendar-layout>
        <bs-datepicker-navigation-view
          [calendar]="calendar"
          (onNavigate)="navigateTo($event)"
          (onViewMode)="changeViewMode($event)"
        ></bs-datepicker-navigation-view>
  
        <table role="grid" class="months">
          <tbody>
          <tr *ngFor="let row of calendar?.months">
            <td *ngFor="let month of row" role="gridcell"
                (click)="viewMonth(month)"
                (mouseenter)="hoverMonth(month, true)"
                (mouseleave)="hoverMonth(month, false)"
                [class.disabled]="month.isDisabled"
                [class.is-highlighted]="month.isHovered">
              <span [class.selected]="month.isSelected">{{ month.label }}</span>
            </td>
          </tr>
          </tbody>
        </table>
      </bs-calendar-layout>
    `
              },] }
  ];
  BsMonthCalendarViewComponent.propDecorators = {
      calendar: [{ type: Input }],
      onNavigate: [{ type: Output }],
      onViewMode: [{ type: Output }],
      onSelect: [{ type: Output }],
      onHover: [{ type: Output }]
  };
  
  class BsTimepickerViewComponent {
      constructor() {
          this.ampm = 'ok';
          this.hours = 0;
          this.minutes = 0;
      }
  }
  BsTimepickerViewComponent.decorators = [
      { type: Component, args: [{
                  selector: 'bs-timepicker',
                  template: `
      <div class="bs-timepicker-container">
        <div class="bs-timepicker-controls">
          <button class="bs-decrease" type="button">-</button>
          <input type="text" [value]="hours" placeholder="00">
          <button class="bs-increase" type="button">+</button>
        </div>
        <div class="bs-timepicker-controls">
          <button class="bs-decrease" type="button">-</button>
          <input type="text" [value]="minutes" placeholder="00">
          <button class="bs-increase" type="button">+</button>
        </div>
        <button class="switch-time-format" type="button">{{ ampm }}
          <img
            src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAABi8KSDAAABSElEQVQYV3XQPUvDUBQG4HNuagtVqc6KgouCv6GIuIntYBLB9hcIQpLStCAIV7DYmpTcRWcXqZio3Vwc/UCc/QEqfgyKGbr0I7nS1EiHeqYzPO/h5SD0jaxUZjmSLCB+OFb+UFINFwASAEAdpu9gaGXVyAHHFQBkHpKHc6a9dzECvADyY9sqlAMsK9W0jzxDXqeytr3mhQckxSji27TJJ5/rPmIpwJJq3HrtduriYOurv1a4i1p5HnhkG9OFymi0ReoO05cGwb+ayv4dysVygjeFmsP05f8wpZQ8fsdvfmuY9zjWSNqUtgYFVnOVReILYoBFzdQI5/GGFzNHhGbeZnopDGU29sZbscgldmC99w35VOATTycIMMcBXIfpSVGzZhA6C8hh00conln6VQ9TGgV32OEAKQC4DrBq7CJwd0ggR7Vq/rPrfgB+C3sGypY5DAAAAABJRU5ErkJggg=="
            alt="">
        </button>
      </div>
    `
              },] }
  ];
  
  class BsYearsCalendarViewComponent {
      constructor() {
          this.onNavigate = new EventEmitter();
          this.onViewMode = new EventEmitter();
          this.onSelect = new EventEmitter();
          this.onHover = new EventEmitter();
      }
      navigateTo(event) {
          const step = BsNavigationDirection.DOWN === event ? -1 : 1;
          this.onNavigate.emit({ step: { year: step * yearsPerCalendar } });
      }
      viewYear(year) {
          this.onSelect.emit(year);
      }
      hoverYear(cell, isHovered) {
          this.onHover.emit({ cell, isHovered });
      }
      changeViewMode(event) {
          this.onViewMode.emit(event);
      }
  }
  BsYearsCalendarViewComponent.decorators = [
      { type: Component, args: [{
                  selector: 'bs-years-calendar-view',
                  template: `
      <bs-calendar-layout>
        <bs-datepicker-navigation-view
          [calendar]="calendar"
          (onNavigate)="navigateTo($event)"
          (onViewMode)="changeViewMode($event)"
        ></bs-datepicker-navigation-view>
  
        <table role="grid" class="years">
          <tbody>
          <tr *ngFor="let row of calendar?.years">
            <td *ngFor="let year of row" role="gridcell"
                (click)="viewYear(year)"
                (mouseenter)="hoverYear(year, true)"
                (mouseleave)="hoverYear(year, false)"
                [class.disabled]="year.isDisabled"
                [class.is-highlighted]="year.isHovered">
              <span [class.selected]="year.isSelected">{{ year.label }}</span>
            </td>
          </tr>
          </tbody>
        </table>
      </bs-calendar-layout>
    `
              },] }
  ];
  BsYearsCalendarViewComponent.propDecorators = {
      calendar: [{ type: Input }],
      onNavigate: [{ type: Output }],
      onViewMode: [{ type: Output }],
      onSelect: [{ type: Output }],
      onHover: [{ type: Output }]
  };
  
  class BsDatepickerModule {
      static forRoot() {
          return {
              ngModule: BsDatepickerModule,
              providers: [
                  ComponentLoaderFactory,
                  PositioningService,
                  BsDatepickerStore,
                  BsDatepickerActions,
                  BsDatepickerEffects,
                  BsLocaleService
              ]
          };
      }
  }
  BsDatepickerModule.decorators = [
      { type: NgModule, args: [{
                  imports: [CommonModule, TooltipModule],
                  declarations: [
                      BsCalendarLayoutComponent,
                      BsCurrentDateViewComponent,
                      BsCustomDatesViewComponent,
                      BsDatepickerDayDecoratorComponent,
                      BsDatepickerNavigationViewComponent,
                      BsDaysCalendarViewComponent,
                      BsMonthCalendarViewComponent,
                      BsTimepickerViewComponent,
                      BsYearsCalendarViewComponent,
                      BsDatepickerContainerComponent,
                      BsDatepickerDirective,
                      BsDatepickerInlineContainerComponent,
                      BsDatepickerInlineDirective,
                      BsDatepickerInputDirective,
                      BsDaterangepickerContainerComponent,
                      BsDaterangepickerDirective,
                      BsDaterangepickerInlineContainerComponent,
                      BsDaterangepickerInlineDirective,
                      BsDaterangepickerInputDirective
                  ],
                  entryComponents: [
                      BsDatepickerContainerComponent,
                      BsDaterangepickerContainerComponent,
                      BsDatepickerInlineContainerComponent,
                      BsDaterangepickerInlineContainerComponent
                  ],
                  exports: [
                      BsDatepickerContainerComponent,
                      BsDatepickerDirective,
                      BsDatepickerInlineContainerComponent,
                      BsDatepickerInlineDirective,
                      BsDatepickerInputDirective,
                      BsDaterangepickerContainerComponent,
                      BsDaterangepickerDirective,
                      BsDaterangepickerInlineContainerComponent,
                      BsDaterangepickerInlineDirective,
                      BsDaterangepickerInputDirective
                  ]
              },] }
  ];
  
  class DatepickerModule {
      static forRoot() {
          return { ngModule: DatepickerModule, providers: [DatepickerConfig] };
      }
  }
  DatepickerModule.decorators = [
      { type: NgModule, args: [{
                  imports: [CommonModule, FormsModule],
                  declarations: [
                      DatePickerComponent,
                      DatePickerInnerComponent,
                      DayPickerComponent,
                      MonthPickerComponent,
                      YearPickerComponent
                  ],
                  exports: [
                      DatePickerComponent,
                      DatePickerInnerComponent,
                      DayPickerComponent,
                      MonthPickerComponent,
                      YearPickerComponent
                  ],
                  entryComponents: [DatePickerComponent]
              },] }
  ];
  
  /**
   * Generated bundle index. Do not edit.
   */
  
  export { BsDatepickerConfig, BsDatepickerContainerComponent, BsDatepickerDirective, BsDatepickerInlineConfig, BsDatepickerInlineContainerComponent, BsDatepickerInlineDirective, BsDatepickerInputDirective, BsDatepickerModule, BsDaterangepickerConfig, BsDaterangepickerContainerComponent, BsDaterangepickerDirective, BsDaterangepickerInlineConfig, BsDaterangepickerInlineContainerComponent, BsDaterangepickerInlineDirective, BsDaterangepickerInputDirective, BsLocaleService, DateFormatter, DatePickerComponent, DatePickerInnerComponent, DatepickerConfig, DatepickerModule, DayPickerComponent, MonthPickerComponent, YearPickerComponent, DATEPICKER_CONTROL_VALUE_ACCESSOR as ɵa, BsDatepickerAbstractComponent as ɵb, BsDatepickerStore as ɵc, BsDatepickerEffects as ɵd, BsDatepickerActions as ɵe, datepickerAnimation as ɵf, BsCalendarLayoutComponent as ɵg, BsCurrentDateViewComponent as ɵh, BsCustomDatesViewComponent as ɵi, BsDatepickerDayDecoratorComponent as ɵj, BsDatepickerNavigationViewComponent as ɵk, BsDaysCalendarViewComponent as ɵl, BsMonthCalendarViewComponent as ɵm, BsTimepickerViewComponent as ɵn, BsYearsCalendarViewComponent as ɵo };
  //# sourceMappingURL=ngx-bootstrap-datepicker.js.map
  