{"version":3,"sources":["node_modules/@angular/material/fesm2022/datepicker.mjs"],"sourcesContent":["import { CdkMonitorFocus, CdkTrapFocus, A11yModule } from '@angular/cdk/a11y';\nimport * as i4 from '@angular/cdk/overlay';\nimport { Overlay, FlexibleConnectedPositionStrategy, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';\nimport { ComponentPortal, CdkPortalOutlet, TemplatePortal, PortalModule } from '@angular/cdk/portal';\nimport { NgClass, DOCUMENT, CommonModule } from '@angular/common';\nimport * as i0 from '@angular/core';\nimport { Injectable, inject, EventEmitter, Component, ViewEncapsulation, ChangeDetectionStrategy, Input, Output, Optional, SkipSelf, InjectionToken, Inject, ViewChild, forwardRef, booleanAttribute, Directive, Attribute, ContentChild, Self, TemplateRef, NgModule } from '@angular/core';\nimport { MatButton, MatIconButton, MatButtonModule } from '@angular/material/button';\nimport { CdkScrollableModule } from '@angular/cdk/scrolling';\nimport * as i1 from '@angular/material/core';\nimport { DateAdapter, MAT_DATE_FORMATS, _ErrorStateTracker, MatCommonModule } from '@angular/material/core';\nimport { Subject, Subscription, merge, of } from 'rxjs';\nimport { ESCAPE, hasModifierKey, SPACE, ENTER, PAGE_DOWN, PAGE_UP, END, HOME, DOWN_ARROW, UP_ARROW, RIGHT_ARROW, LEFT_ARROW, BACKSPACE } from '@angular/cdk/keycodes';\nimport * as i2 from '@angular/cdk/bidi';\nimport { Directionality } from '@angular/cdk/bidi';\nimport { normalizePassiveListenerOptions, Platform, _getFocusedElementPierceShadowDom } from '@angular/cdk/platform';\nimport { take, startWith, filter } from 'rxjs/operators';\nimport { coerceStringArray } from '@angular/cdk/coercion';\nimport { trigger, transition, animate, keyframes, style, state } from '@angular/animations';\nimport * as i2$1 from '@angular/forms';\nimport { NG_VALUE_ACCESSOR, NG_VALIDATORS, Validators, NgControl } from '@angular/forms';\nimport { MAT_FORM_FIELD, MatFormFieldControl } from '@angular/material/form-field';\nimport { MAT_INPUT_VALUE_ACCESSOR } from '@angular/material/input';\n\n/** @docs-private */\nconst _c0 = [\"mat-calendar-body\", \"\"];\nfunction MatCalendarBody_Conditional_0_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"tr\", 0)(1, \"td\", 3);\n i0.ɵɵtext(2);\n i0.ɵɵelementEnd()();\n }\n if (rf & 2) {\n const ctx_r0 = i0.ɵɵnextContext();\n i0.ɵɵadvance();\n i0.ɵɵstyleProp(\"padding-top\", ctx_r0._cellPadding)(\"padding-bottom\", ctx_r0._cellPadding);\n i0.ɵɵattribute(\"colspan\", ctx_r0.numCols);\n i0.ɵɵadvance();\n i0.ɵɵtextInterpolate1(\" \", ctx_r0.label, \" \");\n }\n}\nfunction MatCalendarBody_For_2_Conditional_1_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"td\", 3);\n i0.ɵɵtext(1);\n i0.ɵɵelementEnd();\n }\n if (rf & 2) {\n const ctx_r0 = i0.ɵɵnextContext(2);\n i0.ɵɵstyleProp(\"padding-top\", ctx_r0._cellPadding)(\"padding-bottom\", ctx_r0._cellPadding);\n i0.ɵɵattribute(\"colspan\", ctx_r0._firstRowOffset);\n i0.ɵɵadvance();\n i0.ɵɵtextInterpolate1(\" \", ctx_r0._firstRowOffset >= ctx_r0.labelMinRequiredCells ? ctx_r0.label : \"\", \" \");\n }\n}\nfunction MatCalendarBody_For_2_For_3_Template(rf, ctx) {\n if (rf & 1) {\n const _r2 = i0.ɵɵgetCurrentView();\n i0.ɵɵelementStart(0, \"td\", 4)(1, \"button\", 5);\n i0.ɵɵlistener(\"click\", function MatCalendarBody_For_2_For_3_Template_button_click_1_listener($event) {\n const item_r3 = i0.ɵɵrestoreView(_r2).$implicit;\n const ctx_r0 = i0.ɵɵnextContext(2);\n return i0.ɵɵresetView(ctx_r0._cellClicked(item_r3, $event));\n })(\"focus\", function MatCalendarBody_For_2_For_3_Template_button_focus_1_listener($event) {\n const item_r3 = i0.ɵɵrestoreView(_r2).$implicit;\n const ctx_r0 = i0.ɵɵnextContext(2);\n return i0.ɵɵresetView(ctx_r0._emitActiveDateChange(item_r3, $event));\n });\n i0.ɵɵelementStart(2, \"span\", 6);\n i0.ɵɵtext(3);\n i0.ɵɵelementEnd();\n i0.ɵɵelement(4, \"span\", 7);\n i0.ɵɵelementEnd()();\n }\n if (rf & 2) {\n const item_r3 = ctx.$implicit;\n const colIndex_r4 = ctx.$index;\n const rowIndex_r5 = i0.ɵɵnextContext().$index;\n const ctx_r0 = i0.ɵɵnextContext();\n i0.ɵɵstyleProp(\"width\", ctx_r0._cellWidth)(\"padding-top\", ctx_r0._cellPadding)(\"padding-bottom\", ctx_r0._cellPadding);\n i0.ɵɵattribute(\"data-mat-row\", rowIndex_r5)(\"data-mat-col\", colIndex_r4);\n i0.ɵɵadvance();\n i0.ɵɵclassProp(\"mat-calendar-body-disabled\", !item_r3.enabled)(\"mat-calendar-body-active\", ctx_r0._isActiveCell(rowIndex_r5, colIndex_r4))(\"mat-calendar-body-range-start\", ctx_r0._isRangeStart(item_r3.compareValue))(\"mat-calendar-body-range-end\", ctx_r0._isRangeEnd(item_r3.compareValue))(\"mat-calendar-body-in-range\", ctx_r0._isInRange(item_r3.compareValue))(\"mat-calendar-body-comparison-bridge-start\", ctx_r0._isComparisonBridgeStart(item_r3.compareValue, rowIndex_r5, colIndex_r4))(\"mat-calendar-body-comparison-bridge-end\", ctx_r0._isComparisonBridgeEnd(item_r3.compareValue, rowIndex_r5, colIndex_r4))(\"mat-calendar-body-comparison-start\", ctx_r0._isComparisonStart(item_r3.compareValue))(\"mat-calendar-body-comparison-end\", ctx_r0._isComparisonEnd(item_r3.compareValue))(\"mat-calendar-body-in-comparison-range\", ctx_r0._isInComparisonRange(item_r3.compareValue))(\"mat-calendar-body-preview-start\", ctx_r0._isPreviewStart(item_r3.compareValue))(\"mat-calendar-body-preview-end\", ctx_r0._isPreviewEnd(item_r3.compareValue))(\"mat-calendar-body-in-preview\", ctx_r0._isInPreview(item_r3.compareValue));\n i0.ɵɵproperty(\"ngClass\", item_r3.cssClasses)(\"tabindex\", ctx_r0._isActiveCell(rowIndex_r5, colIndex_r4) ? 0 : -1);\n i0.ɵɵattribute(\"aria-label\", item_r3.ariaLabel)(\"aria-disabled\", !item_r3.enabled || null)(\"aria-pressed\", ctx_r0._isSelected(item_r3.compareValue))(\"aria-current\", ctx_r0.todayValue === item_r3.compareValue ? \"date\" : null)(\"aria-describedby\", ctx_r0._getDescribedby(item_r3.compareValue));\n i0.ɵɵadvance();\n i0.ɵɵclassProp(\"mat-calendar-body-selected\", ctx_r0._isSelected(item_r3.compareValue))(\"mat-calendar-body-comparison-identical\", ctx_r0._isComparisonIdentical(item_r3.compareValue))(\"mat-calendar-body-today\", ctx_r0.todayValue === item_r3.compareValue);\n i0.ɵɵadvance();\n i0.ɵɵtextInterpolate1(\" \", item_r3.displayValue, \" \");\n }\n}\nfunction MatCalendarBody_For_2_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"tr\", 1);\n i0.ɵɵtemplate(1, MatCalendarBody_For_2_Conditional_1_Template, 2, 6, \"td\", 3);\n i0.ɵɵrepeaterCreate(2, MatCalendarBody_For_2_For_3_Template, 5, 48, \"td\", 4, i0.ɵɵrepeaterTrackByIdentity);\n i0.ɵɵelementEnd();\n }\n if (rf & 2) {\n const row_r6 = ctx.$implicit;\n const rowIndex_r5 = ctx.$index;\n const ctx_r0 = i0.ɵɵnextContext();\n i0.ɵɵadvance();\n i0.ɵɵconditional(1, rowIndex_r5 === 0 && ctx_r0._firstRowOffset ? 1 : -1);\n i0.ɵɵadvance();\n i0.ɵɵrepeater(row_r6);\n }\n}\nfunction MatMonthView_For_4_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"th\", 2)(1, \"span\", 5);\n i0.ɵɵtext(2);\n i0.ɵɵelementEnd();\n i0.ɵɵelementStart(3, \"span\", 6);\n i0.ɵɵtext(4);\n i0.ɵɵelementEnd()();\n }\n if (rf & 2) {\n const day_r1 = ctx.$implicit;\n i0.ɵɵadvance(2);\n i0.ɵɵtextInterpolate(day_r1.long);\n i0.ɵɵadvance(2);\n i0.ɵɵtextInterpolate(day_r1.narrow);\n }\n}\nconst _c1 = [\"*\"];\nfunction MatCalendar_ng_template_0_Template(rf, ctx) {}\nfunction MatCalendar_Case_2_Template(rf, ctx) {\n if (rf & 1) {\n const _r1 = i0.ɵɵgetCurrentView();\n i0.ɵɵelementStart(0, \"mat-month-view\", 2);\n i0.ɵɵtwoWayListener(\"activeDateChange\", function MatCalendar_Case_2_Template_mat_month_view_activeDateChange_0_listener($event) {\n i0.ɵɵrestoreView(_r1);\n const ctx_r1 = i0.ɵɵnextContext();\n i0.ɵɵtwoWayBindingSet(ctx_r1.activeDate, $event) || (ctx_r1.activeDate = $event);\n return i0.ɵɵresetView($event);\n });\n i0.ɵɵlistener(\"_userSelection\", function MatCalendar_Case_2_Template_mat_month_view__userSelection_0_listener($event) {\n i0.ɵɵrestoreView(_r1);\n const ctx_r1 = i0.ɵɵnextContext();\n return i0.ɵɵresetView(ctx_r1._dateSelected($event));\n })(\"dragStarted\", function MatCalendar_Case_2_Template_mat_month_view_dragStarted_0_listener($event) {\n i0.ɵɵrestoreView(_r1);\n const ctx_r1 = i0.ɵɵnextContext();\n return i0.ɵɵresetView(ctx_r1._dragStarted($event));\n })(\"dragEnded\", function MatCalendar_Case_2_Template_mat_month_view_dragEnded_0_listener($event) {\n i0.ɵɵrestoreView(_r1);\n const ctx_r1 = i0.ɵɵnextContext();\n return i0.ɵɵresetView(ctx_r1._dragEnded($event));\n });\n i0.ɵɵelementEnd();\n }\n if (rf & 2) {\n const ctx_r1 = i0.ɵɵnextContext();\n i0.ɵɵtwoWayProperty(\"activeDate\", ctx_r1.activeDate);\n i0.ɵɵproperty(\"selected\", ctx_r1.selected)(\"dateFilter\", ctx_r1.dateFilter)(\"maxDate\", ctx_r1.maxDate)(\"minDate\", ctx_r1.minDate)(\"dateClass\", ctx_r1.dateClass)(\"comparisonStart\", ctx_r1.comparisonStart)(\"comparisonEnd\", ctx_r1.comparisonEnd)(\"startDateAccessibleName\", ctx_r1.startDateAccessibleName)(\"endDateAccessibleName\", ctx_r1.endDateAccessibleName)(\"activeDrag\", ctx_r1._activeDrag);\n }\n}\nfunction MatCalendar_Case_3_Template(rf, ctx) {\n if (rf & 1) {\n const _r3 = i0.ɵɵgetCurrentView();\n i0.ɵɵelementStart(0, \"mat-year-view\", 3);\n i0.ɵɵtwoWayListener(\"activeDateChange\", function MatCalendar_Case_3_Template_mat_year_view_activeDateChange_0_listener($event) {\n i0.ɵɵrestoreView(_r3);\n const ctx_r1 = i0.ɵɵnextContext();\n i0.ɵɵtwoWayBindingSet(ctx_r1.activeDate, $event) || (ctx_r1.activeDate = $event);\n return i0.ɵɵresetView($event);\n });\n i0.ɵɵlistener(\"monthSelected\", function MatCalendar_Case_3_Template_mat_year_view_monthSelected_0_listener($event) {\n i0.ɵɵrestoreView(_r3);\n const ctx_r1 = i0.ɵɵnextContext();\n return i0.ɵɵresetView(ctx_r1._monthSelectedInYearView($event));\n })(\"selectedChange\", function MatCalendar_Case_3_Template_mat_year_view_selectedChange_0_listener($event) {\n i0.ɵɵrestoreView(_r3);\n const ctx_r1 = i0.ɵɵnextContext();\n return i0.ɵɵresetView(ctx_r1._goToDateInView($event, \"month\"));\n });\n i0.ɵɵelementEnd();\n }\n if (rf & 2) {\n const ctx_r1 = i0.ɵɵnextContext();\n i0.ɵɵtwoWayProperty(\"activeDate\", ctx_r1.activeDate);\n i0.ɵɵproperty(\"selected\", ctx_r1.selected)(\"dateFilter\", ctx_r1.dateFilter)(\"maxDate\", ctx_r1.maxDate)(\"minDate\", ctx_r1.minDate)(\"dateClass\", ctx_r1.dateClass);\n }\n}\nfunction MatCalendar_Case_4_Template(rf, ctx) {\n if (rf & 1) {\n const _r4 = i0.ɵɵgetCurrentView();\n i0.ɵɵelementStart(0, \"mat-multi-year-view\", 4);\n i0.ɵɵtwoWayListener(\"activeDateChange\", function MatCalendar_Case_4_Template_mat_multi_year_view_activeDateChange_0_listener($event) {\n i0.ɵɵrestoreView(_r4);\n const ctx_r1 = i0.ɵɵnextContext();\n i0.ɵɵtwoWayBindingSet(ctx_r1.activeDate, $event) || (ctx_r1.activeDate = $event);\n return i0.ɵɵresetView($event);\n });\n i0.ɵɵlistener(\"yearSelected\", function MatCalendar_Case_4_Template_mat_multi_year_view_yearSelected_0_listener($event) {\n i0.ɵɵrestoreView(_r4);\n const ctx_r1 = i0.ɵɵnextContext();\n return i0.ɵɵresetView(ctx_r1._yearSelectedInMultiYearView($event));\n })(\"selectedChange\", function MatCalendar_Case_4_Template_mat_multi_year_view_selectedChange_0_listener($event) {\n i0.ɵɵrestoreView(_r4);\n const ctx_r1 = i0.ɵɵnextContext();\n return i0.ɵɵresetView(ctx_r1._goToDateInView($event, \"year\"));\n });\n i0.ɵɵelementEnd();\n }\n if (rf & 2) {\n const ctx_r1 = i0.ɵɵnextContext();\n i0.ɵɵtwoWayProperty(\"activeDate\", ctx_r1.activeDate);\n i0.ɵɵproperty(\"selected\", ctx_r1.selected)(\"dateFilter\", ctx_r1.dateFilter)(\"maxDate\", ctx_r1.maxDate)(\"minDate\", ctx_r1.minDate)(\"dateClass\", ctx_r1.dateClass);\n }\n}\nfunction MatDatepickerContent_ng_template_2_Template(rf, ctx) {}\nconst _c2 = [\"button\"];\nconst _c3 = [[[\"\", \"matDatepickerToggleIcon\", \"\"]]];\nconst _c4 = [\"[matDatepickerToggleIcon]\"];\nfunction MatDatepickerToggle_Conditional_2_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵnamespaceSVG();\n i0.ɵɵelementStart(0, \"svg\", 2);\n i0.ɵɵelement(1, \"path\", 3);\n i0.ɵɵelementEnd();\n }\n}\nconst _c5 = [[[\"input\", \"matStartDate\", \"\"]], [[\"input\", \"matEndDate\", \"\"]]];\nconst _c6 = [\"input[matStartDate]\", \"input[matEndDate]\"];\nfunction MatDatepickerActions_ng_template_0_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"div\", 0);\n i0.ɵɵprojection(1);\n i0.ɵɵelementEnd();\n }\n}\nfunction createMissingDateImplError(provider) {\n return Error(`MatDatepicker: No provider found for ${provider}. You must add one of the following ` + `to your app config: provideNativeDateAdapter, provideDateFnsAdapter, ` + `provideLuxonDateAdapter, provideMomentDateAdapter, or provide a custom implementation.`);\n}\n\n/** Datepicker data that requires internationalization. */\nlet MatDatepickerIntl = /*#__PURE__*/(() => {\n class MatDatepickerIntl {\n constructor() {\n /**\n * Stream that emits whenever the labels here are changed. Use this to notify\n * components if the labels have changed after initialization.\n */\n this.changes = new Subject();\n /** A label for the calendar popup (used by screen readers). */\n this.calendarLabel = 'Calendar';\n /** A label for the button used to open the calendar popup (used by screen readers). */\n this.openCalendarLabel = 'Open calendar';\n /** Label for the button used to close the calendar popup. */\n this.closeCalendarLabel = 'Close calendar';\n /** A label for the previous month button (used by screen readers). */\n this.prevMonthLabel = 'Previous month';\n /** A label for the next month button (used by screen readers). */\n this.nextMonthLabel = 'Next month';\n /** A label for the previous year button (used by screen readers). */\n this.prevYearLabel = 'Previous year';\n /** A label for the next year button (used by screen readers). */\n this.nextYearLabel = 'Next year';\n /** A label for the previous multi-year button (used by screen readers). */\n this.prevMultiYearLabel = 'Previous 24 years';\n /** A label for the next multi-year button (used by screen readers). */\n this.nextMultiYearLabel = 'Next 24 years';\n /** A label for the 'switch to month view' button (used by screen readers). */\n this.switchToMonthViewLabel = 'Choose date';\n /** A label for the 'switch to year view' button (used by screen readers). */\n this.switchToMultiYearViewLabel = 'Choose month and year';\n /**\n * A label for the first date of a range of dates (used by screen readers).\n * @deprecated Provide your own internationalization string.\n * @breaking-change 17.0.0\n */\n this.startDateLabel = 'Start date';\n /**\n * A label for the last date of a range of dates (used by screen readers).\n * @deprecated Provide your own internationalization string.\n * @breaking-change 17.0.0\n */\n this.endDateLabel = 'End date';\n }\n /** Formats a range of years (used for visuals). */\n formatYearRange(start, end) {\n return `${start} \\u2013 ${end}`;\n }\n /** Formats a label for a range of years (used by screen readers). */\n formatYearRangeLabel(start, end) {\n return `${start} to ${end}`;\n }\n static {\n this.ɵfac = function MatDatepickerIntl_Factory(t) {\n return new (t || MatDatepickerIntl)();\n };\n }\n static {\n this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: MatDatepickerIntl,\n factory: MatDatepickerIntl.ɵfac,\n providedIn: 'root'\n });\n }\n }\n return MatDatepickerIntl;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * An internal class that represents the data corresponding to a single calendar cell.\n * @docs-private\n */\nclass MatCalendarCell {\n constructor(value, displayValue, ariaLabel, enabled, cssClasses = {}, compareValue = value, rawValue) {\n this.value = value;\n this.displayValue = displayValue;\n this.ariaLabel = ariaLabel;\n this.enabled = enabled;\n this.cssClasses = cssClasses;\n this.compareValue = compareValue;\n this.rawValue = rawValue;\n }\n}\nlet calendarBodyId = 1;\n/** Event options that can be used to bind an active, capturing event. */\nconst activeCapturingEventOptions = /*#__PURE__*/normalizePassiveListenerOptions({\n passive: false,\n capture: true\n});\n/** Event options that can be used to bind a passive, capturing event. */\nconst passiveCapturingEventOptions = /*#__PURE__*/normalizePassiveListenerOptions({\n passive: true,\n capture: true\n});\n/** Event options that can be used to bind a passive, non-capturing event. */\nconst passiveEventOptions = /*#__PURE__*/normalizePassiveListenerOptions({\n passive: true\n});\n/**\n * An internal component used to display calendar data in a table.\n * @docs-private\n */\nlet MatCalendarBody = /*#__PURE__*/(() => {\n class MatCalendarBody {\n ngAfterViewChecked() {\n if (this._focusActiveCellAfterViewChecked) {\n this._focusActiveCell();\n this._focusActiveCellAfterViewChecked = false;\n }\n }\n constructor(_elementRef, _ngZone) {\n this._elementRef = _elementRef;\n this._ngZone = _ngZone;\n this._platform = inject(Platform);\n /**\n * Used to focus the active cell after change detection has run.\n */\n this._focusActiveCellAfterViewChecked = false;\n /** The number of columns in the table. */\n this.numCols = 7;\n /** The cell number of the active cell in the table. */\n this.activeCell = 0;\n /** Whether a range is being selected. */\n this.isRange = false;\n /**\n * The aspect ratio (width / height) to use for the cells in the table. This aspect ratio will be\n * maintained even as the table resizes.\n */\n this.cellAspectRatio = 1;\n /** Start of the preview range. */\n this.previewStart = null;\n /** End of the preview range. */\n this.previewEnd = null;\n /** Emits when a new value is selected. */\n this.selectedValueChange = new EventEmitter();\n /** Emits when the preview has changed as a result of a user action. */\n this.previewChange = new EventEmitter();\n this.activeDateChange = new EventEmitter();\n /** Emits the date at the possible start of a drag event. */\n this.dragStarted = new EventEmitter();\n /** Emits the date at the conclusion of a drag, or null if mouse was not released on a date. */\n this.dragEnded = new EventEmitter();\n this._didDragSinceMouseDown = false;\n /**\n * Event handler for when the user enters an element\n * inside the calendar body (e.g. by hovering in or focus).\n */\n this._enterHandler = event => {\n if (this._skipNextFocus && event.type === 'focus') {\n this._skipNextFocus = false;\n return;\n }\n // We only need to hit the zone when we're selecting a range.\n if (event.target && this.isRange) {\n const cell = this._getCellFromElement(event.target);\n if (cell) {\n this._ngZone.run(() => this.previewChange.emit({\n value: cell.enabled ? cell : null,\n event\n }));\n }\n }\n };\n this._touchmoveHandler = event => {\n if (!this.isRange) return;\n const target = getActualTouchTarget(event);\n const cell = target ? this._getCellFromElement(target) : null;\n if (target !== event.target) {\n this._didDragSinceMouseDown = true;\n }\n // If the initial target of the touch is a date cell, prevent default so\n // that the move is not handled as a scroll.\n if (getCellElement(event.target)) {\n event.preventDefault();\n }\n this._ngZone.run(() => this.previewChange.emit({\n value: cell?.enabled ? cell : null,\n event\n }));\n };\n /**\n * Event handler for when the user's pointer leaves an element\n * inside the calendar body (e.g. by hovering out or blurring).\n */\n this._leaveHandler = event => {\n // We only need to hit the zone when we're selecting a range.\n if (this.previewEnd !== null && this.isRange) {\n if (event.type !== 'blur') {\n this._didDragSinceMouseDown = true;\n }\n // Only reset the preview end value when leaving cells. This looks better, because\n // we have a gap between the cells and the rows and we don't want to remove the\n // range just for it to show up again when the user moves a few pixels to the side.\n if (event.target && this._getCellFromElement(event.target) && !(event.relatedTarget && this._getCellFromElement(event.relatedTarget))) {\n this._ngZone.run(() => this.previewChange.emit({\n value: null,\n event\n }));\n }\n }\n };\n /**\n * Triggered on mousedown or touchstart on a date cell.\n * Respsonsible for starting a drag sequence.\n */\n this._mousedownHandler = event => {\n if (!this.isRange) return;\n this._didDragSinceMouseDown = false;\n // Begin a drag if a cell within the current range was targeted.\n const cell = event.target && this._getCellFromElement(event.target);\n if (!cell || !this._isInRange(cell.compareValue)) {\n return;\n }\n this._ngZone.run(() => {\n this.dragStarted.emit({\n value: cell.rawValue,\n event\n });\n });\n };\n /** Triggered on mouseup anywhere. Respsonsible for ending a drag sequence. */\n this._mouseupHandler = event => {\n if (!this.isRange) return;\n const cellElement = getCellElement(event.target);\n if (!cellElement) {\n // Mouseup happened outside of datepicker. Cancel drag.\n this._ngZone.run(() => {\n this.dragEnded.emit({\n value: null,\n event\n });\n });\n return;\n }\n if (cellElement.closest('.mat-calendar-body') !== this._elementRef.nativeElement) {\n // Mouseup happened inside a different month instance.\n // Allow it to handle the event.\n return;\n }\n this._ngZone.run(() => {\n const cell = this._getCellFromElement(cellElement);\n this.dragEnded.emit({\n value: cell?.rawValue ?? null,\n event\n });\n });\n };\n /** Triggered on touchend anywhere. Respsonsible for ending a drag sequence. */\n this._touchendHandler = event => {\n const target = getActualTouchTarget(event);\n if (target) {\n this._mouseupHandler({\n target\n });\n }\n };\n this._id = `mat-calendar-body-${calendarBodyId++}`;\n this._startDateLabelId = `${this._id}-start-date`;\n this._endDateLabelId = `${this._id}-end-date`;\n _ngZone.runOutsideAngular(() => {\n const element = _elementRef.nativeElement;\n // `touchmove` is active since we need to call `preventDefault`.\n element.addEventListener('touchmove', this._touchmoveHandler, activeCapturingEventOptions);\n element.addEventListener('mouseenter', this._enterHandler, passiveCapturingEventOptions);\n element.addEventListener('focus', this._enterHandler, passiveCapturingEventOptions);\n element.addEventListener('mouseleave', this._leaveHandler, passiveCapturingEventOptions);\n element.addEventListener('blur', this._leaveHandler, passiveCapturingEventOptions);\n element.addEventListener('mousedown', this._mousedownHandler, passiveEventOptions);\n element.addEventListener('touchstart', this._mousedownHandler, passiveEventOptions);\n if (this._platform.isBrowser) {\n window.addEventListener('mouseup', this._mouseupHandler);\n window.addEventListener('touchend', this._touchendHandler);\n }\n });\n }\n /** Called when a cell is clicked. */\n _cellClicked(cell, event) {\n // Ignore \"clicks\" that are actually canceled drags (eg the user dragged\n // off and then went back to this cell to undo).\n if (this._didDragSinceMouseDown) {\n return;\n }\n if (cell.enabled) {\n this.selectedValueChange.emit({\n value: cell.value,\n event\n });\n }\n }\n _emitActiveDateChange(cell, event) {\n if (cell.enabled) {\n this.activeDateChange.emit({\n value: cell.value,\n event\n });\n }\n }\n /** Returns whether a cell should be marked as selected. */\n _isSelected(value) {\n return this.startValue === value || this.endValue === value;\n }\n ngOnChanges(changes) {\n const columnChanges = changes['numCols'];\n const {\n rows,\n numCols\n } = this;\n if (changes['rows'] || columnChanges) {\n this._firstRowOffset = rows && rows.length && rows[0].length ? numCols - rows[0].length : 0;\n }\n if (changes['cellAspectRatio'] || columnChanges || !this._cellPadding) {\n this._cellPadding = `${50 * this.cellAspectRatio / numCols}%`;\n }\n if (columnChanges || !this._cellWidth) {\n this._cellWidth = `${100 / numCols}%`;\n }\n }\n ngOnDestroy() {\n const element = this._elementRef.nativeElement;\n element.removeEventListener('touchmove', this._touchmoveHandler, activeCapturingEventOptions);\n element.removeEventListener('mouseenter', this._enterHandler, passiveCapturingEventOptions);\n element.removeEventListener('focus', this._enterHandler, passiveCapturingEventOptions);\n element.removeEventListener('mouseleave', this._leaveHandler, passiveCapturingEventOptions);\n element.removeEventListener('blur', this._leaveHandler, passiveCapturingEventOptions);\n element.removeEventListener('mousedown', this._mousedownHandler, passiveEventOptions);\n element.removeEventListener('touchstart', this._mousedownHandler, passiveEventOptions);\n if (this._platform.isBrowser) {\n window.removeEventListener('mouseup', this._mouseupHandler);\n window.removeEventListener('touchend', this._touchendHandler);\n }\n }\n /** Returns whether a cell is active. */\n _isActiveCell(rowIndex, colIndex) {\n let cellNumber = rowIndex * this.numCols + colIndex;\n // Account for the fact that the first row may not have as many cells.\n if (rowIndex) {\n cellNumber -= this._firstRowOffset;\n }\n return cellNumber == this.activeCell;\n }\n /**\n * Focuses the active cell after the microtask queue is empty.\n *\n * Adding a 0ms setTimeout seems to fix Voiceover losing focus when pressing PageUp/PageDown\n * (issue #24330).\n *\n * Determined a 0ms by gradually increasing duration from 0 and testing two use cases with screen\n * reader enabled:\n *\n * 1. Pressing PageUp/PageDown repeatedly with pausing between each key press.\n * 2. Pressing and holding the PageDown key with repeated keys enabled.\n *\n * Test 1 worked roughly 95-99% of the time with 0ms and got a little bit better as the duration\n * increased. Test 2 got slightly better until the duration was long enough to interfere with\n * repeated keys. If the repeated key speed was faster than the timeout duration, then pressing\n * and holding pagedown caused the entire page to scroll.\n *\n * Since repeated key speed can verify across machines, determined that any duration could\n * potentially interfere with repeated keys. 0ms would be best because it almost entirely\n * eliminates the focus being lost in Voiceover (#24330) without causing unintended side effects.\n * Adding delay also complicates writing tests.\n */\n _focusActiveCell(movePreview = true) {\n this._ngZone.runOutsideAngular(() => {\n this._ngZone.onStable.pipe(take(1)).subscribe(() => {\n setTimeout(() => {\n const activeCell = this._elementRef.nativeElement.querySelector('.mat-calendar-body-active');\n if (activeCell) {\n if (!movePreview) {\n this._skipNextFocus = true;\n }\n activeCell.focus();\n }\n });\n });\n });\n }\n /** Focuses the active cell after change detection has run and the microtask queue is empty. */\n _scheduleFocusActiveCellAfterViewChecked() {\n this._focusActiveCellAfterViewChecked = true;\n }\n /** Gets whether a value is the start of the main range. */\n _isRangeStart(value) {\n return isStart(value, this.startValue, this.endValue);\n }\n /** Gets whether a value is the end of the main range. */\n _isRangeEnd(value) {\n return isEnd(value, this.startValue, this.endValue);\n }\n /** Gets whether a value is within the currently-selected range. */\n _isInRange(value) {\n return isInRange(value, this.startValue, this.endValue, this.isRange);\n }\n /** Gets whether a value is the start of the comparison range. */\n _isComparisonStart(value) {\n return isStart(value, this.comparisonStart, this.comparisonEnd);\n }\n /** Whether the cell is a start bridge cell between the main and comparison ranges. */\n _isComparisonBridgeStart(value, rowIndex, colIndex) {\n if (!this._isComparisonStart(value) || this._isRangeStart(value) || !this._isInRange(value)) {\n return false;\n }\n let previousCell = this.rows[rowIndex][colIndex - 1];\n if (!previousCell) {\n const previousRow = this.rows[rowIndex - 1];\n previousCell = previousRow && previousRow[previousRow.length - 1];\n }\n return previousCell && !this._isRangeEnd(previousCell.compareValue);\n }\n /** Whether the cell is an end bridge cell between the main and comparison ranges. */\n _isComparisonBridgeEnd(value, rowIndex, colIndex) {\n if (!this._isComparisonEnd(value) || this._isRangeEnd(value) || !this._isInRange(value)) {\n return false;\n }\n let nextCell = this.rows[rowIndex][colIndex + 1];\n if (!nextCell) {\n const nextRow = this.rows[rowIndex + 1];\n nextCell = nextRow && nextRow[0];\n }\n return nextCell && !this._isRangeStart(nextCell.compareValue);\n }\n /** Gets whether a value is the end of the comparison range. */\n _isComparisonEnd(value) {\n return isEnd(value, this.comparisonStart, this.comparisonEnd);\n }\n /** Gets whether a value is within the current comparison range. */\n _isInComparisonRange(value) {\n return isInRange(value, this.comparisonStart, this.comparisonEnd, this.isRange);\n }\n /**\n * Gets whether a value is the same as the start and end of the comparison range.\n * For context, the functions that we use to determine whether something is the start/end of\n * a range don't allow for the start and end to be on the same day, because we'd have to use\n * much more specific CSS selectors to style them correctly in all scenarios. This is fine for\n * the regular range, because when it happens, the selected styles take over and still show where\n * the range would've been, however we don't have these selected styles for a comparison range.\n * This function is used to apply a class that serves the same purpose as the one for selected\n * dates, but it only applies in the context of a comparison range.\n */\n _isComparisonIdentical(value) {\n // Note that we don't need to null check the start/end\n // here, because the `value` will always be defined.\n return this.comparisonStart === this.comparisonEnd && value === this.comparisonStart;\n }\n /** Gets whether a value is the start of the preview range. */\n _isPreviewStart(value) {\n return isStart(value, this.previewStart, this.previewEnd);\n }\n /** Gets whether a value is the end of the preview range. */\n _isPreviewEnd(value) {\n return isEnd(value, this.previewStart, this.previewEnd);\n }\n /** Gets whether a value is inside the preview range. */\n _isInPreview(value) {\n return isInRange(value, this.previewStart, this.previewEnd, this.isRange);\n }\n /** Gets ids of aria descriptions for the start and end of a date range. */\n _getDescribedby(value) {\n if (!this.isRange) {\n return null;\n }\n if (this.startValue === value && this.endValue === value) {\n return `${this._startDateLabelId} ${this._endDateLabelId}`;\n } else if (this.startValue === value) {\n return this._startDateLabelId;\n } else if (this.endValue === value) {\n return this._endDateLabelId;\n }\n return null;\n }\n /** Finds the MatCalendarCell that corresponds to a DOM node. */\n _getCellFromElement(element) {\n const cell = getCellElement(element);\n if (cell) {\n const row = cell.getAttribute('data-mat-row');\n const col = cell.getAttribute('data-mat-col');\n if (row && col) {\n return this.rows[parseInt(row)][parseInt(col)];\n }\n }\n return null;\n }\n static {\n this.ɵfac = function MatCalendarBody_Factory(t) {\n return new (t || MatCalendarBody)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.NgZone));\n };\n }\n static {\n this.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatCalendarBody,\n selectors: [[\"\", \"mat-calendar-body\", \"\"]],\n hostAttrs: [1, \"mat-calendar-body\"],\n inputs: {\n label: \"label\",\n rows: \"rows\",\n todayValue: \"todayValue\",\n startValue: \"startValue\",\n endValue: \"endValue\",\n labelMinRequiredCells: \"labelMinRequiredCells\",\n numCols: \"numCols\",\n activeCell: \"activeCell\",\n isRange: \"isRange\",\n cellAspectRatio: \"cellAspectRatio\",\n comparisonStart: \"comparisonStart\",\n comparisonEnd: \"comparisonEnd\",\n previewStart: \"previewStart\",\n previewEnd: \"previewEnd\",\n startDateAccessibleName: \"startDateAccessibleName\",\n endDateAccessibleName: \"endDateAccessibleName\"\n },\n outputs: {\n selectedValueChange: \"selectedValueChange\",\n previewChange: \"previewChange\",\n activeDateChange: \"activeDateChange\",\n dragStarted: \"dragStarted\",\n dragEnded: \"dragEnded\"\n },\n exportAs: [\"matCalendarBody\"],\n standalone: true,\n features: [i0.ɵɵNgOnChangesFeature, i0.ɵɵStandaloneFeature],\n attrs: _c0,\n decls: 7,\n vars: 5,\n consts: [[\"aria-hidden\", \"true\"], [\"role\", \"row\"], [1, \"mat-calendar-body-hidden-label\", 3, \"id\"], [1, \"mat-calendar-body-label\"], [\"role\", \"gridcell\", 1, \"mat-calendar-body-cell-container\"], [\"type\", \"button\", 1, \"mat-calendar-body-cell\", 3, \"click\", \"focus\", \"ngClass\", \"tabindex\"], [1, \"mat-calendar-body-cell-content\", \"mat-focus-indicator\"], [\"aria-hidden\", \"true\", 1, \"mat-calendar-body-cell-preview\"]],\n template: function MatCalendarBody_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵtemplate(0, MatCalendarBody_Conditional_0_Template, 3, 6, \"tr\", 0);\n i0.ɵɵrepeaterCreate(1, MatCalendarBody_For_2_Template, 4, 1, \"tr\", 1, i0.ɵɵrepeaterTrackByIdentity);\n i0.ɵɵelementStart(3, \"label\", 2);\n i0.ɵɵtext(4);\n i0.ɵɵelementEnd();\n i0.ɵɵelementStart(5, \"label\", 2);\n i0.ɵɵtext(6);\n i0.ɵɵelementEnd();\n }\n if (rf & 2) {\n i0.ɵɵconditional(0, ctx._firstRowOffset < ctx.labelMinRequiredCells ? 0 : -1);\n i0.ɵɵadvance();\n i0.ɵɵrepeater(ctx.rows);\n i0.ɵɵadvance(2);\n i0.ɵɵproperty(\"id\", ctx._startDateLabelId);\n i0.ɵɵadvance();\n i0.ɵɵtextInterpolate1(\" \", ctx.startDateAccessibleName, \"\\n\");\n i0.ɵɵadvance();\n i0.ɵɵproperty(\"id\", ctx._endDateLabelId);\n i0.ɵɵadvance();\n i0.ɵɵtextInterpolate1(\" \", ctx.endDateAccessibleName, \"\\n\");\n }\n },\n dependencies: [NgClass],\n styles: [\".mat-calendar-body{min-width:224px}.mat-calendar-body-today:not(.mat-calendar-body-selected):not(.mat-calendar-body-comparison-identical){border-color:var(--mat-datepicker-calendar-date-today-outline-color)}.mat-calendar-body-label{height:0;line-height:0;text-align:start;padding-left:4.7142857143%;padding-right:4.7142857143%;font-size:var(--mat-datepicker-calendar-body-label-text-size);font-weight:var(--mat-datepicker-calendar-body-label-text-weight);color:var(--mat-datepicker-calendar-body-label-text-color)}.mat-calendar-body-hidden-label{display:none}.mat-calendar-body-cell-container{position:relative;height:0;line-height:0}.mat-calendar-body-cell{-webkit-user-select:none;user-select:none;cursor:pointer;outline:none;border:none;-webkit-tap-highlight-color:rgba(0,0,0,0);position:absolute;top:0;left:0;width:100%;height:100%;background:none;text-align:center;outline:none;font-family:inherit;margin:0}.mat-calendar-body-cell::-moz-focus-inner{border:0}.mat-calendar-body-cell::before,.mat-calendar-body-cell::after,.mat-calendar-body-cell-preview{content:\\\"\\\";position:absolute;top:5%;left:0;z-index:0;box-sizing:border-box;display:block;height:90%;width:100%}.mat-calendar-body-range-start:not(.mat-calendar-body-in-comparison-range)::before,.mat-calendar-body-range-start::after,.mat-calendar-body-comparison-start:not(.mat-calendar-body-comparison-bridge-start)::before,.mat-calendar-body-comparison-start::after,.mat-calendar-body-preview-start .mat-calendar-body-cell-preview{left:5%;width:95%;border-top-left-radius:999px;border-bottom-left-radius:999px}[dir=rtl] .mat-calendar-body-range-start:not(.mat-calendar-body-in-comparison-range)::before,[dir=rtl] .mat-calendar-body-range-start::after,[dir=rtl] .mat-calendar-body-comparison-start:not(.mat-calendar-body-comparison-bridge-start)::before,[dir=rtl] .mat-calendar-body-comparison-start::after,[dir=rtl] .mat-calendar-body-preview-start .mat-calendar-body-cell-preview{left:0;border-radius:0;border-top-right-radius:999px;border-bottom-right-radius:999px}.mat-calendar-body-range-end:not(.mat-calendar-body-in-comparison-range)::before,.mat-calendar-body-range-end::after,.mat-calendar-body-comparison-end:not(.mat-calendar-body-comparison-bridge-end)::before,.mat-calendar-body-comparison-end::after,.mat-calendar-body-preview-end .mat-calendar-body-cell-preview{width:95%;border-top-right-radius:999px;border-bottom-right-radius:999px}[dir=rtl] .mat-calendar-body-range-end:not(.mat-calendar-body-in-comparison-range)::before,[dir=rtl] .mat-calendar-body-range-end::after,[dir=rtl] .mat-calendar-body-comparison-end:not(.mat-calendar-body-comparison-bridge-end)::before,[dir=rtl] .mat-calendar-body-comparison-end::after,[dir=rtl] .mat-calendar-body-preview-end .mat-calendar-body-cell-preview{left:5%;border-radius:0;border-top-left-radius:999px;border-bottom-left-radius:999px}[dir=rtl] .mat-calendar-body-comparison-bridge-start.mat-calendar-body-range-end::after,[dir=rtl] .mat-calendar-body-comparison-bridge-end.mat-calendar-body-range-start::after{width:95%;border-top-right-radius:999px;border-bottom-right-radius:999px}.mat-calendar-body-comparison-start.mat-calendar-body-range-end::after,[dir=rtl] .mat-calendar-body-comparison-start.mat-calendar-body-range-end::after,.mat-calendar-body-comparison-end.mat-calendar-body-range-start::after,[dir=rtl] .mat-calendar-body-comparison-end.mat-calendar-body-range-start::after{width:90%}.mat-calendar-body-in-preview{color:var(--mat-datepicker-calendar-date-preview-state-outline-color)}.mat-calendar-body-in-preview .mat-calendar-body-cell-preview{border-top:dashed 1px;border-bottom:dashed 1px}.mat-calendar-body-preview-start .mat-calendar-body-cell-preview{border-left:dashed 1px}[dir=rtl] .mat-calendar-body-preview-start .mat-calendar-body-cell-preview{border-left:0;border-right:dashed 1px}.mat-calendar-body-preview-end .mat-calendar-body-cell-preview{border-right:dashed 1px}[dir=rtl] .mat-calendar-body-preview-end .mat-calendar-body-cell-preview{border-right:0;border-left:dashed 1px}.mat-calendar-body-disabled{cursor:default}.mat-calendar-body-disabled>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected):not(.mat-calendar-body-comparison-identical){color:var(--mat-datepicker-calendar-date-disabled-state-text-color)}.mat-calendar-body-disabled>.mat-calendar-body-today:not(.mat-calendar-body-selected):not(.mat-calendar-body-comparison-identical){border-color:var(--mat-datepicker-calendar-date-today-disabled-state-outline-color)}.cdk-high-contrast-active .mat-calendar-body-disabled{opacity:.5}.mat-calendar-body-cell-content{top:5%;left:5%;z-index:1;display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:90%;height:90%;line-height:1;border-width:1px;border-style:solid;border-radius:999px;color:var(--mat-datepicker-calendar-date-text-color);border-color:var(--mat-datepicker-calendar-date-outline-color)}.mat-calendar-body-cell-content.mat-focus-indicator{position:absolute}.cdk-high-contrast-active .mat-calendar-body-cell-content{border:none}.cdk-keyboard-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected):not(.mat-calendar-body-comparison-identical),.cdk-program-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected):not(.mat-calendar-body-comparison-identical){background-color:var(--mat-datepicker-calendar-date-focus-state-background-color)}@media(hover: hover){.mat-calendar-body-cell:not(.mat-calendar-body-disabled):hover>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected):not(.mat-calendar-body-comparison-identical){background-color:var(--mat-datepicker-calendar-date-hover-state-background-color)}}.mat-calendar-body-selected{background-color:var(--mat-datepicker-calendar-date-selected-state-background-color);color:var(--mat-datepicker-calendar-date-selected-state-text-color)}.mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:var(--mat-datepicker-calendar-date-selected-disabled-state-background-color)}.mat-calendar-body-selected.mat-calendar-body-today{box-shadow:inset 0 0 0 1px var(--mat-datepicker-calendar-date-today-selected-state-outline-color)}.mat-calendar-body-in-range::before{background:var(--mat-datepicker-calendar-date-in-range-state-background-color)}.mat-calendar-body-comparison-identical,.mat-calendar-body-in-comparison-range::before{background:var(--mat-datepicker-calendar-date-in-comparison-range-state-background-color)}.mat-calendar-body-comparison-identical,.mat-calendar-body-in-comparison-range::before{background:var(--mat-datepicker-calendar-date-in-comparison-range-state-background-color)}.mat-calendar-body-comparison-bridge-start::before,[dir=rtl] .mat-calendar-body-comparison-bridge-end::before{background:linear-gradient(to right, var(--mat-datepicker-calendar-date-in-range-state-background-color) 50%, var(--mat-datepicker-calendar-date-in-comparison-range-state-background-color) 50%)}.mat-calendar-body-comparison-bridge-end::before,[dir=rtl] .mat-calendar-body-comparison-bridge-start::before{background:linear-gradient(to left, var(--mat-datepicker-calendar-date-in-range-state-background-color) 50%, var(--mat-datepicker-calendar-date-in-comparison-range-state-background-color) 50%)}.mat-calendar-body-in-range>.mat-calendar-body-comparison-identical,.mat-calendar-body-in-comparison-range.mat-calendar-body-in-range::after{background:var(--mat-datepicker-calendar-date-in-overlap-range-state-background-color)}.mat-calendar-body-comparison-identical.mat-calendar-body-selected,.mat-calendar-body-in-comparison-range>.mat-calendar-body-selected{background:var(--mat-datepicker-calendar-date-in-overlap-range-selected-state-background-color)}.cdk-high-contrast-active .mat-datepicker-popup:not(:empty),.cdk-high-contrast-active .mat-calendar-body-cell:not(.mat-calendar-body-in-range) .mat-calendar-body-selected{outline:solid 1px}.cdk-high-contrast-active .mat-calendar-body-today{outline:dotted 1px}.cdk-high-contrast-active .mat-calendar-body-cell::before,.cdk-high-contrast-active .mat-calendar-body-cell::after,.cdk-high-contrast-active .mat-calendar-body-selected{background:none}.cdk-high-contrast-active .mat-calendar-body-in-range::before,.cdk-high-contrast-active .mat-calendar-body-comparison-bridge-start::before,.cdk-high-contrast-active .mat-calendar-body-comparison-bridge-end::before{border-top:solid 1px;border-bottom:solid 1px}.cdk-high-contrast-active .mat-calendar-body-range-start::before{border-left:solid 1px}[dir=rtl] .cdk-high-contrast-active .mat-calendar-body-range-start::before{border-left:0;border-right:solid 1px}.cdk-high-contrast-active .mat-calendar-body-range-end::before{border-right:solid 1px}[dir=rtl] .cdk-high-contrast-active .mat-calendar-body-range-end::before{border-right:0;border-left:solid 1px}.cdk-high-contrast-active .mat-calendar-body-in-comparison-range::before{border-top:dashed 1px;border-bottom:dashed 1px}.cdk-high-contrast-active .mat-calendar-body-comparison-start::before{border-left:dashed 1px}[dir=rtl] .cdk-high-contrast-active .mat-calendar-body-comparison-start::before{border-left:0;border-right:dashed 1px}.cdk-high-contrast-active .mat-calendar-body-comparison-end::before{border-right:dashed 1px}[dir=rtl] .cdk-high-contrast-active .mat-calendar-body-comparison-end::before{border-right:0;border-left:dashed 1px}\"],\n encapsulation: 2,\n changeDetection: 0\n });\n }\n }\n return MatCalendarBody;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** Checks whether a node is a table cell element. */\nfunction isTableCell(node) {\n return node?.nodeName === 'TD';\n}\n/**\n * Gets the date table cell element that is or contains the specified element.\n * Or returns null if element is not part of a date cell.\n */\nfunction getCellElement(element) {\n let cell;\n if (isTableCell(element)) {\n cell = element;\n } else if (isTableCell(element.parentNode)) {\n cell = element.parentNode;\n } else if (isTableCell(element.parentNode?.parentNode)) {\n cell = element.parentNode.parentNode;\n }\n return cell?.getAttribute('data-mat-row') != null ? cell : null;\n}\n/** Checks whether a value is the start of a range. */\nfunction isStart(value, start, end) {\n return end !== null && start !== end && value < end && value === start;\n}\n/** Checks whether a value is the end of a range. */\nfunction isEnd(value, start, end) {\n return start !== null && start !== end && value >= start && value === end;\n}\n/** Checks whether a value is inside of a range. */\nfunction isInRange(value, start, end, rangeEnabled) {\n return rangeEnabled && start !== null && end !== null && start !== end && value >= start && value <= end;\n}\n/**\n * Extracts the element that actually corresponds to a touch event's location\n * (rather than the element that initiated the sequence of touch events).\n */\nfunction getActualTouchTarget(event) {\n const touchLocation = event.changedTouches[0];\n return document.elementFromPoint(touchLocation.clientX, touchLocation.clientY);\n}\n\n/** A class representing a range of dates. */\nclass DateRange {\n constructor( /** The start date of the range. */\n start, /** The end date of the range. */\n end) {\n this.start = start;\n this.end = end;\n }\n}\n/**\n * A selection model containing a date selection.\n * @docs-private\n */\nlet MatDateSelectionModel = /*#__PURE__*/(() => {\n class MatDateSelectionModel {\n constructor( /** The current selection. */\n selection, _adapter) {\n this.selection = selection;\n this._adapter = _adapter;\n this._selectionChanged = new Subject();\n /** Emits when the selection has changed. */\n this.selectionChanged = this._selectionChanged;\n this.selection = selection;\n }\n /**\n * Updates the current selection in the model.\n * @param value New selection that should be assigned.\n * @param source Object that triggered the selection change.\n */\n updateSelection(value, source) {\n const oldValue = this.selection;\n this.selection = value;\n this._selectionChanged.next({\n selection: value,\n source,\n oldValue\n });\n }\n ngOnDestroy() {\n this._selectionChanged.complete();\n }\n _isValidDateInstance(date) {\n return this._adapter.isDateInstance(date) && this._adapter.isValid(date);\n }\n static {\n this.ɵfac = function MatDateSelectionModel_Factory(t) {\n i0.ɵɵinvalidFactory();\n };\n }\n static {\n this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: MatDateSelectionModel,\n factory: MatDateSelectionModel.ɵfac\n });\n }\n }\n return MatDateSelectionModel;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * A selection model that contains a single date.\n * @docs-private\n */\nlet MatSingleDateSelectionModel = /*#__PURE__*/(() => {\n class MatSingleDateSelectionModel extends MatDateSelectionModel {\n constructor(adapter) {\n super(null, adapter);\n }\n /**\n * Adds a date to the current selection. In the case of a single date selection, the added date\n * simply overwrites the previous selection\n */\n add(date) {\n super.updateSelection(date, this);\n }\n /** Checks whether the current selection is valid. */\n isValid() {\n return this.selection != null && this._isValidDateInstance(this.selection);\n }\n /**\n * Checks whether the current selection is complete. In the case of a single date selection, this\n * is true if the current selection is not null.\n */\n isComplete() {\n return this.selection != null;\n }\n /** Clones the selection model. */\n clone() {\n const clone = new MatSingleDateSelectionModel(this._adapter);\n clone.updateSelection(this.selection, this);\n return clone;\n }\n static {\n this.ɵfac = function MatSingleDateSelectionModel_Factory(t) {\n return new (t || MatSingleDateSelectionModel)(i0.ɵɵinject(i1.DateAdapter));\n };\n }\n static {\n this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: MatSingleDateSelectionModel,\n factory: MatSingleDateSelectionModel.ɵfac\n });\n }\n }\n return MatSingleDateSelectionModel;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * A selection model that contains a date range.\n * @docs-private\n */\nlet MatRangeDateSelectionModel = /*#__PURE__*/(() => {\n class MatRangeDateSelectionModel extends MatDateSelectionModel {\n constructor(adapter) {\n super(new DateRange(null, null), adapter);\n }\n /**\n * Adds a date to the current selection. In the case of a date range selection, the added date\n * fills in the next `null` value in the range. If both the start and the end already have a date,\n * the selection is reset so that the given date is the new `start` and the `end` is null.\n */\n add(date) {\n let {\n start,\n end\n } = this.selection;\n if (start == null) {\n start = date;\n } else if (end == null) {\n end = date;\n } else {\n start = date;\n end = null;\n }\n super.updateSelection(new DateRange(start, end), this);\n }\n /** Checks whether the current selection is valid. */\n isValid() {\n const {\n start,\n end\n } = this.selection;\n // Empty ranges are valid.\n if (start == null && end == null) {\n return true;\n }\n // Complete ranges are only valid if both dates are valid and the start is before the end.\n if (start != null && end != null) {\n return this._isValidDateInstance(start) && this._isValidDateInstance(end) && this._adapter.compareDate(start, end) <= 0;\n }\n // Partial ranges are valid if the start/end is valid.\n return (start == null || this._isValidDateInstance(start)) && (end == null || this._isValidDateInstance(end));\n }\n /**\n * Checks whether the current selection is complete. In the case of a date range selection, this\n * is true if the current selection has a non-null `start` and `end`.\n */\n isComplete() {\n return this.selection.start != null && this.selection.end != null;\n }\n /** Clones the selection model. */\n clone() {\n const clone = new MatRangeDateSelectionModel(this._adapter);\n clone.updateSelection(this.selection, this);\n return clone;\n }\n static {\n this.ɵfac = function MatRangeDateSelectionModel_Factory(t) {\n return new (t || MatRangeDateSelectionModel)(i0.ɵɵinject(i1.DateAdapter));\n };\n }\n static {\n this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: MatRangeDateSelectionModel,\n factory: MatRangeDateSelectionModel.ɵfac\n });\n }\n }\n return MatRangeDateSelectionModel;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** @docs-private */\nfunction MAT_SINGLE_DATE_SELECTION_MODEL_FACTORY(parent, adapter) {\n return parent || new MatSingleDateSelectionModel(adapter);\n}\n/**\n * Used to provide a single selection model to a component.\n * @docs-private\n */\nconst MAT_SINGLE_DATE_SELECTION_MODEL_PROVIDER = {\n provide: MatDateSelectionModel,\n deps: [[/*#__PURE__*/new Optional(), /*#__PURE__*/new SkipSelf(), MatDateSelectionModel], DateAdapter],\n useFactory: MAT_SINGLE_DATE_SELECTION_MODEL_FACTORY\n};\n/** @docs-private */\nfunction MAT_RANGE_DATE_SELECTION_MODEL_FACTORY(parent, adapter) {\n return parent || new MatRangeDateSelectionModel(adapter);\n}\n/**\n * Used to provide a range selection model to a component.\n * @docs-private\n */\nconst MAT_RANGE_DATE_SELECTION_MODEL_PROVIDER = {\n provide: MatDateSelectionModel,\n deps: [[/*#__PURE__*/new Optional(), /*#__PURE__*/new SkipSelf(), MatDateSelectionModel], DateAdapter],\n useFactory: MAT_RANGE_DATE_SELECTION_MODEL_FACTORY\n};\n\n/** Injection token used to customize the date range selection behavior. */\nconst MAT_DATE_RANGE_SELECTION_STRATEGY = /*#__PURE__*/new InjectionToken('MAT_DATE_RANGE_SELECTION_STRATEGY');\n/** Provides the default date range selection behavior. */\nlet DefaultMatCalendarRangeStrategy = /*#__PURE__*/(() => {\n class DefaultMatCalendarRangeStrategy {\n constructor(_dateAdapter) {\n this._dateAdapter = _dateAdapter;\n }\n selectionFinished(date, currentRange) {\n let {\n start,\n end\n } = currentRange;\n if (start == null) {\n start = date;\n } else if (end == null && date && this._dateAdapter.compareDate(date, start) >= 0) {\n end = date;\n } else {\n start = date;\n end = null;\n }\n return new DateRange(start, end);\n }\n createPreview(activeDate, currentRange) {\n let start = null;\n let end = null;\n if (currentRange.start && !currentRange.end && activeDate) {\n start = currentRange.start;\n end = activeDate;\n }\n return new DateRange(start, end);\n }\n createDrag(dragOrigin, originalRange, newDate) {\n let start = originalRange.start;\n let end = originalRange.end;\n if (!start || !end) {\n // Can't drag from an incomplete range.\n return null;\n }\n const adapter = this._dateAdapter;\n const isRange = adapter.compareDate(start, end) !== 0;\n const diffYears = adapter.getYear(newDate) - adapter.getYear(dragOrigin);\n const diffMonths = adapter.getMonth(newDate) - adapter.getMonth(dragOrigin);\n const diffDays = adapter.getDate(newDate) - adapter.getDate(dragOrigin);\n if (isRange && adapter.sameDate(dragOrigin, originalRange.start)) {\n start = newDate;\n if (adapter.compareDate(newDate, end) > 0) {\n end = adapter.addCalendarYears(end, diffYears);\n end = adapter.addCalendarMonths(end, diffMonths);\n end = adapter.addCalendarDays(end, diffDays);\n }\n } else if (isRange && adapter.sameDate(dragOrigin, originalRange.end)) {\n end = newDate;\n if (adapter.compareDate(newDate, start) < 0) {\n start = adapter.addCalendarYears(start, diffYears);\n start = adapter.addCalendarMonths(start, diffMonths);\n start = adapter.addCalendarDays(start, diffDays);\n }\n } else {\n start = adapter.addCalendarYears(start, diffYears);\n start = adapter.addCalendarMonths(start, diffMonths);\n start = adapter.addCalendarDays(start, diffDays);\n end = adapter.addCalendarYears(end, diffYears);\n end = adapter.addCalendarMonths(end, diffMonths);\n end = adapter.addCalendarDays(end, diffDays);\n }\n return new DateRange(start, end);\n }\n static {\n this.ɵfac = function DefaultMatCalendarRangeStrategy_Factory(t) {\n return new (t || DefaultMatCalendarRangeStrategy)(i0.ɵɵinject(i1.DateAdapter));\n };\n }\n static {\n this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: DefaultMatCalendarRangeStrategy,\n factory: DefaultMatCalendarRangeStrategy.ɵfac\n });\n }\n }\n return DefaultMatCalendarRangeStrategy;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** @docs-private */\nfunction MAT_CALENDAR_RANGE_STRATEGY_PROVIDER_FACTORY(parent, adapter) {\n return parent || new DefaultMatCalendarRangeStrategy(adapter);\n}\n/** @docs-private */\nconst MAT_CALENDAR_RANGE_STRATEGY_PROVIDER = {\n provide: MAT_DATE_RANGE_SELECTION_STRATEGY,\n deps: [[/*#__PURE__*/new Optional(), /*#__PURE__*/new SkipSelf(), MAT_DATE_RANGE_SELECTION_STRATEGY], DateAdapter],\n useFactory: MAT_CALENDAR_RANGE_STRATEGY_PROVIDER_FACTORY\n};\nconst DAYS_PER_WEEK = 7;\n/**\n * An internal component used to display a single month in the datepicker.\n * @docs-private\n */\nlet MatMonthView = /*#__PURE__*/(() => {\n class MatMonthView {\n /**\n * The date to display in this month view (everything other than the month and year is ignored).\n */\n get activeDate() {\n return this._activeDate;\n }\n set activeDate(value) {\n const oldActiveDate = this._activeDate;\n const validDate = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value)) || this._dateAdapter.today();\n this._activeDate = this._dateAdapter.clampDate(validDate, this.minDate, this.maxDate);\n if (!this._hasSameMonthAndYear(oldActiveDate, this._activeDate)) {\n this._init();\n }\n }\n /** The currently selected date. */\n get selected() {\n return this._selected;\n }\n set selected(value) {\n if (value instanceof DateRange) {\n this._selected = value;\n } else {\n this._selected = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n this._setRanges(this._selected);\n }\n /** The minimum selectable date. */\n get minDate() {\n return this._minDate;\n }\n set minDate(value) {\n this._minDate = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** The maximum selectable date. */\n get maxDate() {\n return this._maxDate;\n }\n set maxDate(value) {\n this._maxDate = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n constructor(_changeDetectorRef, _dateFormats, _dateAdapter, _dir, _rangeStrategy) {\n this._changeDetectorRef = _changeDetectorRef;\n this._dateFormats = _dateFormats;\n this._dateAdapter = _dateAdapter;\n this._dir = _dir;\n this._rangeStrategy = _rangeStrategy;\n this._rerenderSubscription = Subscription.EMPTY;\n /** Origin of active drag, or null when dragging is not active. */\n this.activeDrag = null;\n /** Emits when a new date is selected. */\n this.selectedChange = new EventEmitter();\n /** Emits when any date is selected. */\n this._userSelection = new EventEmitter();\n /** Emits when the user initiates a date range drag via mouse or touch. */\n this.dragStarted = new EventEmitter();\n /**\n * Emits when the user completes or cancels a date range drag.\n * Emits null when the drag was canceled or the newly selected date range if completed.\n */\n this.dragEnded = new EventEmitter();\n /** Emits when any date is activated. */\n this.activeDateChange = new EventEmitter();\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (!this._dateAdapter) {\n throw createMissingDateImplError('DateAdapter');\n }\n if (!this._dateFormats) {\n throw createMissingDateImplError('MAT_DATE_FORMATS');\n }\n }\n this._activeDate = this._dateAdapter.today();\n }\n ngAfterContentInit() {\n this._rerenderSubscription = this._dateAdapter.localeChanges.pipe(startWith(null)).subscribe(() => this._init());\n }\n ngOnChanges(changes) {\n const comparisonChange = changes['comparisonStart'] || changes['comparisonEnd'];\n if (comparisonChange && !comparisonChange.firstChange) {\n this._setRanges(this.selected);\n }\n if (changes['activeDrag'] && !this.activeDrag) {\n this._clearPreview();\n }\n }\n ngOnDestroy() {\n this._rerenderSubscription.unsubscribe();\n }\n /** Handles when a new date is selected. */\n _dateSelected(event) {\n const date = event.value;\n const selectedDate = this._getDateFromDayOfMonth(date);\n let rangeStartDate;\n let rangeEndDate;\n if (this._selected instanceof DateRange) {\n rangeStartDate = this._getDateInCurrentMonth(this._selected.start);\n rangeEndDate = this._getDateInCurrentMonth(this._selected.end);\n } else {\n rangeStartDate = rangeEndDate = this._getDateInCurrentMonth(this._selected);\n }\n if (rangeStartDate !== date || rangeEndDate !== date) {\n this.selectedChange.emit(selectedDate);\n }\n this._userSelection.emit({\n value: selectedDate,\n event: event.event\n });\n this._clearPreview();\n this._changeDetectorRef.markForCheck();\n }\n /**\n * Takes the index of a calendar body cell wrapped in an event as argument. For the date that\n * corresponds to the given cell, set `activeDate` to that date and fire `activeDateChange` with\n * that date.\n *\n * This function is used to match each component's model of the active date with the calendar\n * body cell that was focused. It updates its value of `activeDate` synchronously and updates the\n * parent's value asynchronously via the `activeDateChange` event. The child component receives an\n * updated value asynchronously via the `activeCell` Input.\n */\n _updateActiveDate(event) {\n const month = event.value;\n const oldActiveDate = this._activeDate;\n this.activeDate = this._getDateFromDayOfMonth(month);\n if (this._dateAdapter.compareDate(oldActiveDate, this.activeDate)) {\n this.activeDateChange.emit(this._activeDate);\n }\n }\n /** Handles keydown events on the calendar body when calendar is in month view. */\n _handleCalendarBodyKeydown(event) {\n // TODO(mmalerba): We currently allow keyboard navigation to disabled dates, but just prevent\n // disabled ones from being selected. This may not be ideal, we should look into whether\n // navigation should skip over disabled dates, and if so, how to implement that efficiently.\n const oldActiveDate = this._activeDate;\n const isRtl = this._isRtl();\n switch (event.keyCode) {\n case LEFT_ARROW:\n this.activeDate = this._dateAdapter.addCalendarDays(this._activeDate, isRtl ? 1 : -1);\n break;\n case RIGHT_ARROW:\n this.activeDate = this._dateAdapter.addCalendarDays(this._activeDate, isRtl ? -1 : 1);\n break;\n case UP_ARROW:\n this.activeDate = this._dateAdapter.addCalendarDays(this._activeDate, -7);\n break;\n case DOWN_ARROW:\n this.activeDate = this._dateAdapter.addCalendarDays(this._activeDate, 7);\n break;\n case HOME:\n this.activeDate = this._dateAdapter.addCalendarDays(this._activeDate, 1 - this._dateAdapter.getDate(this._activeDate));\n break;\n case END:\n this.activeDate = this._dateAdapter.addCalendarDays(this._activeDate, this._dateAdapter.getNumDaysInMonth(this._activeDate) - this._dateAdapter.getDate(this._activeDate));\n break;\n case PAGE_UP:\n this.activeDate = event.altKey ? this._dateAdapter.addCalendarYears(this._activeDate, -1) : this._dateAdapter.addCalendarMonths(this._activeDate, -1);\n break;\n case PAGE_DOWN:\n this.activeDate = event.altKey ? this._dateAdapter.addCalendarYears(this._activeDate, 1) : this._dateAdapter.addCalendarMonths(this._activeDate, 1);\n break;\n case ENTER:\n case SPACE:\n this._selectionKeyPressed = true;\n if (this._canSelect(this._activeDate)) {\n // Prevent unexpected default actions such as form submission.\n // Note that we only prevent the default action here while the selection happens in\n // `keyup` below. We can't do the selection here, because it can cause the calendar to\n // reopen if focus is restored immediately. We also can't call `preventDefault` on `keyup`\n // because it's too late (see #23305).\n event.preventDefault();\n }\n return;\n case ESCAPE:\n // Abort the current range selection if the user presses escape mid-selection.\n if (this._previewEnd != null && !hasModifierKey(event)) {\n this._clearPreview();\n // If a drag is in progress, cancel the drag without changing the\n // current selection.\n if (this.activeDrag) {\n this.dragEnded.emit({\n value: null,\n event\n });\n } else {\n this.selectedChange.emit(null);\n this._userSelection.emit({\n value: null,\n event\n });\n }\n event.preventDefault();\n event.stopPropagation(); // Prevents the overlay from closing.\n }\n return;\n default:\n // Don't prevent default or focus active cell on keys that we don't explicitly handle.\n return;\n }\n if (this._dateAdapter.compareDate(oldActiveDate, this.activeDate)) {\n this.activeDateChange.emit(this.activeDate);\n this._focusActiveCellAfterViewChecked();\n }\n // Prevent unexpected default actions such as form submission.\n event.preventDefault();\n }\n /** Handles keyup events on the calendar body when calendar is in month view. */\n _handleCalendarBodyKeyup(event) {\n if (event.keyCode === SPACE || event.keyCode === ENTER) {\n if (this._selectionKeyPressed && this._canSelect(this._activeDate)) {\n this._dateSelected({\n value: this._dateAdapter.getDate(this._activeDate),\n event\n });\n }\n this._selectionKeyPressed = false;\n }\n }\n /** Initializes this month view. */\n _init() {\n this._setRanges(this.selected);\n this._todayDate = this._getCellCompareValue(this._dateAdapter.today());\n this._monthLabel = this._dateFormats.display.monthLabel ? this._dateAdapter.format(this.activeDate, this._dateFormats.display.monthLabel) : this._dateAdapter.getMonthNames('short')[this._dateAdapter.getMonth(this.activeDate)].toLocaleUpperCase();\n let firstOfMonth = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), this._dateAdapter.getMonth(this.activeDate), 1);\n this._firstWeekOffset = (DAYS_PER_WEEK + this._dateAdapter.getDayOfWeek(firstOfMonth) - this._dateAdapter.getFirstDayOfWeek()) % DAYS_PER_WEEK;\n this._initWeekdays();\n this._createWeekCells();\n this._changeDetectorRef.markForCheck();\n }\n /** Focuses the active cell after the microtask queue is empty. */\n _focusActiveCell(movePreview) {\n this._matCalendarBody._focusActiveCell(movePreview);\n }\n /** Focuses the active cell after change detection has run and the microtask queue is empty. */\n _focusActiveCellAfterViewChecked() {\n this._matCalendarBody._scheduleFocusActiveCellAfterViewChecked();\n }\n /** Called when the user has activated a new cell and the preview needs to be updated. */\n _previewChanged({\n event,\n value: cell\n }) {\n if (this._rangeStrategy) {\n // We can assume that this will be a range, because preview\n // events aren't fired for single date selections.\n const value = cell ? cell.rawValue : null;\n const previewRange = this._rangeStrategy.createPreview(value, this.selected, event);\n this._previewStart = this._getCellCompareValue(previewRange.start);\n this._previewEnd = this._getCellCompareValue(previewRange.end);\n if (this.activeDrag && value) {\n const dragRange = this._rangeStrategy.createDrag?.(this.activeDrag.value, this.selected, value, event);\n if (dragRange) {\n this._previewStart = this._getCellCompareValue(dragRange.start);\n this._previewEnd = this._getCellCompareValue(dragRange.end);\n }\n }\n // Note that here we need to use `detectChanges`, rather than `markForCheck`, because\n // the way `_focusActiveCell` is set up at the moment makes it fire at the wrong time\n // when navigating one month back using the keyboard which will cause this handler\n // to throw a \"changed after checked\" error when updating the preview state.\n this._changeDetectorRef.detectChanges();\n }\n }\n /**\n * Called when the user has ended a drag. If the drag/drop was successful,\n * computes and emits the new range selection.\n */\n _dragEnded(event) {\n if (!this.activeDrag) return;\n if (event.value) {\n // Propagate drag effect\n const dragDropResult = this._rangeStrategy?.createDrag?.(this.activeDrag.value, this.selected, event.value, event.event);\n this.dragEnded.emit({\n value: dragDropResult ?? null,\n event: event.event\n });\n } else {\n this.dragEnded.emit({\n value: null,\n event: event.event\n });\n }\n }\n /**\n * Takes a day of the month and returns a new date in the same month and year as the currently\n * active date. The returned date will have the same day of the month as the argument date.\n */\n _getDateFromDayOfMonth(dayOfMonth) {\n return this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), this._dateAdapter.getMonth(this.activeDate), dayOfMonth);\n }\n /** Initializes the weekdays. */\n _initWeekdays() {\n const firstDayOfWeek = this._dateAdapter.getFirstDayOfWeek();\n const narrowWeekdays = this._dateAdapter.getDayOfWeekNames('narrow');\n const longWeekdays = this._dateAdapter.getDayOfWeekNames('long');\n // Rotate the labels for days of the week based on the configured first day of the week.\n let weekdays = longWeekdays.map((long, i) => {\n return {\n long,\n narrow: narrowWeekdays[i]\n };\n });\n this._weekdays = weekdays.slice(firstDayOfWeek).concat(weekdays.slice(0, firstDayOfWeek));\n }\n /** Creates MatCalendarCells for the dates in this month. */\n _createWeekCells() {\n const daysInMonth = this._dateAdapter.getNumDaysInMonth(this.activeDate);\n const dateNames = this._dateAdapter.getDateNames();\n this._weeks = [[]];\n for (let i = 0, cell = this._firstWeekOffset; i < daysInMonth; i++, cell++) {\n if (cell == DAYS_PER_WEEK) {\n this._weeks.push([]);\n cell = 0;\n }\n const date = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), this._dateAdapter.getMonth(this.activeDate), i + 1);\n const enabled = this._shouldEnableDate(date);\n const ariaLabel = this._dateAdapter.format(date, this._dateFormats.display.dateA11yLabel);\n const cellClasses = this.dateClass ? this.dateClass(date, 'month') : undefined;\n this._weeks[this._weeks.length - 1].push(new MatCalendarCell(i + 1, dateNames[i], ariaLabel, enabled, cellClasses, this._getCellCompareValue(date), date));\n }\n }\n /** Date filter for the month */\n _shouldEnableDate(date) {\n return !!date && (!this.minDate || this._dateAdapter.compareDate(date, this.minDate) >= 0) && (!this.maxDate || this._dateAdapter.compareDate(date, this.maxDate) <= 0) && (!this.dateFilter || this.dateFilter(date));\n }\n /**\n * Gets the date in this month that the given Date falls on.\n * Returns null if the given Date is in another month.\n */\n _getDateInCurrentMonth(date) {\n return date && this._hasSameMonthAndYear(date, this.activeDate) ? this._dateAdapter.getDate(date) : null;\n }\n /** Checks whether the 2 dates are non-null and fall within the same month of the same year. */\n _hasSameMonthAndYear(d1, d2) {\n return !!(d1 && d2 && this._dateAdapter.getMonth(d1) == this._dateAdapter.getMonth(d2) && this._dateAdapter.getYear(d1) == this._dateAdapter.getYear(d2));\n }\n /** Gets the value that will be used to one cell to another. */\n _getCellCompareValue(date) {\n if (date) {\n // We use the time since the Unix epoch to compare dates in this view, rather than the\n // cell values, because we need to support ranges that span across multiple months/years.\n const year = this._dateAdapter.getYear(date);\n const month = this._dateAdapter.getMonth(date);\n const day = this._dateAdapter.getDate(date);\n return new Date(year, month, day).getTime();\n }\n return null;\n }\n /** Determines whether the user has the RTL layout direction. */\n _isRtl() {\n return this._dir && this._dir.value === 'rtl';\n }\n /** Sets the current range based on a model value. */\n _setRanges(selectedValue) {\n if (selectedValue instanceof DateRange) {\n this._rangeStart = this._getCellCompareValue(selectedValue.start);\n this._rangeEnd = this._getCellCompareValue(selectedValue.end);\n this._isRange = true;\n } else {\n this._rangeStart = this._rangeEnd = this._getCellCompareValue(selectedValue);\n this._isRange = false;\n }\n this._comparisonRangeStart = this._getCellCompareValue(this.comparisonStart);\n this._comparisonRangeEnd = this._getCellCompareValue(this.comparisonEnd);\n }\n /** Gets whether a date can be selected in the month view. */\n _canSelect(date) {\n return !this.dateFilter || this.dateFilter(date);\n }\n /** Clears out preview state. */\n _clearPreview() {\n this._previewStart = this._previewEnd = null;\n }\n static {\n this.ɵfac = function MatMonthView_Factory(t) {\n return new (t || MatMonthView)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(MAT_DATE_FORMATS, 8), i0.ɵɵdirectiveInject(i1.DateAdapter, 8), i0.ɵɵdirectiveInject(i2.Directionality, 8), i0.ɵɵdirectiveInject(MAT_DATE_RANGE_SELECTION_STRATEGY, 8));\n };\n }\n static {\n this.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatMonthView,\n selectors: [[\"mat-month-view\"]],\n viewQuery: function MatMonthView_Query(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵviewQuery(MatCalendarBody, 5);\n }\n if (rf & 2) {\n let _t;\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx._matCalendarBody = _t.first);\n }\n },\n inputs: {\n activeDate: \"activeDate\",\n selected: \"selected\",\n minDate: \"minDate\",\n maxDate: \"maxDate\",\n dateFilter: \"dateFilter\",\n dateClass: \"dateClass\",\n comparisonStart: \"comparisonStart\",\n comparisonEnd: \"comparisonEnd\",\n startDateAccessibleName: \"startDateAccessibleName\",\n endDateAccessibleName: \"endDateAccessibleName\",\n activeDrag: \"activeDrag\"\n },\n outputs: {\n selectedChange: \"selectedChange\",\n _userSelection: \"_userSelection\",\n dragStarted: \"dragStarted\",\n dragEnded: \"dragEnded\",\n activeDateChange: \"activeDateChange\"\n },\n exportAs: [\"matMonthView\"],\n standalone: true,\n features: [i0.ɵɵNgOnChangesFeature, i0.ɵɵStandaloneFeature],\n decls: 8,\n vars: 14,\n consts: [[\"role\", \"grid\", 1, \"mat-calendar-table\"], [1, \"mat-calendar-table-header\"], [\"scope\", \"col\"], [\"aria-hidden\", \"true\", \"colspan\", \"7\", 1, \"mat-calendar-table-header-divider\"], [\"mat-calendar-body\", \"\", 3, \"selectedValueChange\", \"activeDateChange\", \"previewChange\", \"dragStarted\", \"dragEnded\", \"keyup\", \"keydown\", \"label\", \"rows\", \"todayValue\", \"startValue\", \"endValue\", \"comparisonStart\", \"comparisonEnd\", \"previewStart\", \"previewEnd\", \"isRange\", \"labelMinRequiredCells\", \"activeCell\", \"startDateAccessibleName\", \"endDateAccessibleName\"], [1, \"cdk-visually-hidden\"], [\"aria-hidden\", \"true\"]],\n template: function MatMonthView_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"table\", 0)(1, \"thead\", 1)(2, \"tr\");\n i0.ɵɵrepeaterCreate(3, MatMonthView_For_4_Template, 5, 2, \"th\", 2, i0.ɵɵrepeaterTrackByIdentity);\n i0.ɵɵelementEnd();\n i0.ɵɵelementStart(5, \"tr\");\n i0.ɵɵelement(6, \"th\", 3);\n i0.ɵɵelementEnd()();\n i0.ɵɵelementStart(7, \"tbody\", 4);\n i0.ɵɵlistener(\"selectedValueChange\", function MatMonthView_Template_tbody_selectedValueChange_7_listener($event) {\n return ctx._dateSelected($event);\n })(\"activeDateChange\", function MatMonthView_Template_tbody_activeDateChange_7_listener($event) {\n return ctx._updateActiveDate($event);\n })(\"previewChange\", function MatMonthView_Template_tbody_previewChange_7_listener($event) {\n return ctx._previewChanged($event);\n })(\"dragStarted\", function MatMonthView_Template_tbody_dragStarted_7_listener($event) {\n return ctx.dragStarted.emit($event);\n })(\"dragEnded\", function MatMonthView_Template_tbody_dragEnded_7_listener($event) {\n return ctx._dragEnded($event);\n })(\"keyup\", function MatMonthView_Template_tbody_keyup_7_listener($event) {\n return ctx._handleCalendarBodyKeyup($event);\n })(\"keydown\", function MatMonthView_Template_tbody_keydown_7_listener($event) {\n return ctx._handleCalendarBodyKeydown($event);\n });\n i0.ɵɵelementEnd()();\n }\n if (rf & 2) {\n i0.ɵɵadvance(3);\n i0.ɵɵrepeater(ctx._weekdays);\n i0.ɵɵadvance(4);\n i0.ɵɵproperty(\"label\", ctx._monthLabel)(\"rows\", ctx._weeks)(\"todayValue\", ctx._todayDate)(\"startValue\", ctx._rangeStart)(\"endValue\", ctx._rangeEnd)(\"comparisonStart\", ctx._comparisonRangeStart)(\"comparisonEnd\", ctx._comparisonRangeEnd)(\"previewStart\", ctx._previewStart)(\"previewEnd\", ctx._previewEnd)(\"isRange\", ctx._isRange)(\"labelMinRequiredCells\", 3)(\"activeCell\", ctx._dateAdapter.getDate(ctx.activeDate) - 1)(\"startDateAccessibleName\", ctx.startDateAccessibleName)(\"endDateAccessibleName\", ctx.endDateAccessibleName);\n }\n },\n dependencies: [MatCalendarBody],\n encapsulation: 2,\n changeDetection: 0\n });\n }\n }\n return MatMonthView;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nconst yearsPerPage = 24;\nconst yearsPerRow = 4;\n/**\n * An internal component used to display a year selector in the datepicker.\n * @docs-private\n */\nlet MatMultiYearView = /*#__PURE__*/(() => {\n class MatMultiYearView {\n /** The date to display in this multi-year view (everything other than the year is ignored). */\n get activeDate() {\n return this._activeDate;\n }\n set activeDate(value) {\n let oldActiveDate = this._activeDate;\n const validDate = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value)) || this._dateAdapter.today();\n this._activeDate = this._dateAdapter.clampDate(validDate, this.minDate, this.maxDate);\n if (!isSameMultiYearView(this._dateAdapter, oldActiveDate, this._activeDate, this.minDate, this.maxDate)) {\n this._init();\n }\n }\n /** The currently selected date. */\n get selected() {\n return this._selected;\n }\n set selected(value) {\n if (value instanceof DateRange) {\n this._selected = value;\n } else {\n this._selected = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n this._setSelectedYear(value);\n }\n /** The minimum selectable date. */\n get minDate() {\n return this._minDate;\n }\n set minDate(value) {\n this._minDate = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** The maximum selectable date. */\n get maxDate() {\n return this._maxDate;\n }\n set maxDate(value) {\n this._maxDate = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n constructor(_changeDetectorRef, _dateAdapter, _dir) {\n this._changeDetectorRef = _changeDetectorRef;\n this._dateAdapter = _dateAdapter;\n this._dir = _dir;\n this._rerenderSubscription = Subscription.EMPTY;\n /** Emits when a new year is selected. */\n this.selectedChange = new EventEmitter();\n /** Emits the selected year. This doesn't imply a change on the selected date */\n this.yearSelected = new EventEmitter();\n /** Emits when any date is activated. */\n this.activeDateChange = new EventEmitter();\n if (!this._dateAdapter && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw createMissingDateImplError('DateAdapter');\n }\n this._activeDate = this._dateAdapter.today();\n }\n ngAfterContentInit() {\n this._rerenderSubscription = this._dateAdapter.localeChanges.pipe(startWith(null)).subscribe(() => this._init());\n }\n ngOnDestroy() {\n this._rerenderSubscription.unsubscribe();\n }\n /** Initializes this multi-year view. */\n _init() {\n this._todayYear = this._dateAdapter.getYear(this._dateAdapter.today());\n // We want a range years such that we maximize the number of\n // enabled dates visible at once. This prevents issues where the minimum year\n // is the last item of a page OR the maximum year is the first item of a page.\n // The offset from the active year to the \"slot\" for the starting year is the\n // *actual* first rendered year in the multi-year view.\n const activeYear = this._dateAdapter.getYear(this._activeDate);\n const minYearOfPage = activeYear - getActiveOffset(this._dateAdapter, this.activeDate, this.minDate, this.maxDate);\n this._years = [];\n for (let i = 0, row = []; i < yearsPerPage; i++) {\n row.push(minYearOfPage + i);\n if (row.length == yearsPerRow) {\n this._years.push(row.map(year => this._createCellForYear(year)));\n row = [];\n }\n }\n this._changeDetectorRef.markForCheck();\n }\n /** Handles when a new year is selected. */\n _yearSelected(event) {\n const year = event.value;\n const selectedYear = this._dateAdapter.createDate(year, 0, 1);\n const selectedDate = this._getDateFromYear(year);\n this.yearSelected.emit(selectedYear);\n this.selectedChange.emit(selectedDate);\n }\n /**\n * Takes the index of a calendar body cell wrapped in an event as argument. For the date that\n * corresponds to the given cell, set `activeDate` to that date and fire `activeDateChange` with\n * that date.\n *\n * This function is used to match each component's model of the active date with the calendar\n * body cell that was focused. It updates its value of `activeDate` synchronously and updates the\n * parent's value asynchronously via the `activeDateChange` event. The child component receives an\n * updated value asynchronously via the `activeCell` Input.\n */\n _updateActiveDate(event) {\n const year = event.value;\n const oldActiveDate = this._activeDate;\n this.activeDate = this._getDateFromYear(year);\n if (this._dateAdapter.compareDate(oldActiveDate, this.activeDate)) {\n this.activeDateChange.emit(this.activeDate);\n }\n }\n /** Handles keydown events on the calendar body when calendar is in multi-year view. */\n _handleCalendarBodyKeydown(event) {\n const oldActiveDate = this._activeDate;\n const isRtl = this._isRtl();\n switch (event.keyCode) {\n case LEFT_ARROW:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, isRtl ? 1 : -1);\n break;\n case RIGHT_ARROW:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, isRtl ? -1 : 1);\n break;\n case UP_ARROW:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, -yearsPerRow);\n break;\n case DOWN_ARROW:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, yearsPerRow);\n break;\n case HOME:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, -getActiveOffset(this._dateAdapter, this.activeDate, this.minDate, this.maxDate));\n break;\n case END:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, yearsPerPage - getActiveOffset(this._dateAdapter, this.activeDate, this.minDate, this.maxDate) - 1);\n break;\n case PAGE_UP:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, event.altKey ? -yearsPerPage * 10 : -yearsPerPage);\n break;\n case PAGE_DOWN:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, event.altKey ? yearsPerPage * 10 : yearsPerPage);\n break;\n case ENTER:\n case SPACE:\n // Note that we only prevent the default action here while the selection happens in\n // `keyup` below. We can't do the selection here, because it can cause the calendar to\n // reopen if focus is restored immediately. We also can't call `preventDefault` on `keyup`\n // because it's too late (see #23305).\n this._selectionKeyPressed = true;\n break;\n default:\n // Don't prevent default or focus active cell on keys that we don't explicitly handle.\n return;\n }\n if (this._dateAdapter.compareDate(oldActiveDate, this.activeDate)) {\n this.activeDateChange.emit(this.activeDate);\n }\n this._focusActiveCellAfterViewChecked();\n // Prevent unexpected default actions such as form submission.\n event.preventDefault();\n }\n /** Handles keyup events on the calendar body when calendar is in multi-year view. */\n _handleCalendarBodyKeyup(event) {\n if (event.keyCode === SPACE || event.keyCode === ENTER) {\n if (this._selectionKeyPressed) {\n this._yearSelected({\n value: this._dateAdapter.getYear(this._activeDate),\n event\n });\n }\n this._selectionKeyPressed = false;\n }\n }\n _getActiveCell() {\n return getActiveOffset(this._dateAdapter, this.activeDate, this.minDate, this.maxDate);\n }\n /** Focuses the active cell after the microtask queue is empty. */\n _focusActiveCell() {\n this._matCalendarBody._focusActiveCell();\n }\n /** Focuses the active cell after change detection has run and the microtask queue is empty. */\n _focusActiveCellAfterViewChecked() {\n this._matCalendarBody._scheduleFocusActiveCellAfterViewChecked();\n }\n /**\n * Takes a year and returns a new date on the same day and month as the currently active date\n * The returned date will have the same year as the argument date.\n */\n _getDateFromYear(year) {\n const activeMonth = this._dateAdapter.getMonth(this.activeDate);\n const daysInMonth = this._dateAdapter.getNumDaysInMonth(this._dateAdapter.createDate(year, activeMonth, 1));\n const normalizedDate = this._dateAdapter.createDate(year, activeMonth, Math.min(this._dateAdapter.getDate(this.activeDate), daysInMonth));\n return normalizedDate;\n }\n /** Creates an MatCalendarCell for the given year. */\n _createCellForYear(year) {\n const date = this._dateAdapter.createDate(year, 0, 1);\n const yearName = this._dateAdapter.getYearName(date);\n const cellClasses = this.dateClass ? this.dateClass(date, 'multi-year') : undefined;\n return new MatCalendarCell(year, yearName, yearName, this._shouldEnableYear(year), cellClasses);\n }\n /** Whether the given year is enabled. */\n _shouldEnableYear(year) {\n // disable if the year is greater than maxDate lower than minDate\n if (year === undefined || year === null || this.maxDate && year > this._dateAdapter.getYear(this.maxDate) || this.minDate && year < this._dateAdapter.getYear(this.minDate)) {\n return false;\n }\n // enable if it reaches here and there's no filter defined\n if (!this.dateFilter) {\n return true;\n }\n const firstOfYear = this._dateAdapter.createDate(year, 0, 1);\n // If any date in the year is enabled count the year as enabled.\n for (let date = firstOfYear; this._dateAdapter.getYear(date) == year; date = this._dateAdapter.addCalendarDays(date, 1)) {\n if (this.dateFilter(date)) {\n return true;\n }\n }\n return false;\n }\n /** Determines whether the user has the RTL layout direction. */\n _isRtl() {\n return this._dir && this._dir.value === 'rtl';\n }\n /** Sets the currently-highlighted year based on a model value. */\n _setSelectedYear(value) {\n this._selectedYear = null;\n if (value instanceof DateRange) {\n const displayValue = value.start || value.end;\n if (displayValue) {\n this._selectedYear = this._dateAdapter.getYear(displayValue);\n }\n } else if (value) {\n this._selectedYear = this._dateAdapter.getYear(value);\n }\n }\n static {\n this.ɵfac = function MatMultiYearView_Factory(t) {\n return new (t || MatMultiYearView)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.DateAdapter, 8), i0.ɵɵdirectiveInject(i2.Directionality, 8));\n };\n }\n static {\n this.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatMultiYearView,\n selectors: [[\"mat-multi-year-view\"]],\n viewQuery: function MatMultiYearView_Query(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵviewQuery(MatCalendarBody, 5);\n }\n if (rf & 2) {\n let _t;\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx._matCalendarBody = _t.first);\n }\n },\n inputs: {\n activeDate: \"activeDate\",\n selected: \"selected\",\n minDate: \"minDate\",\n maxDate: \"maxDate\",\n dateFilter: \"dateFilter\",\n dateClass: \"dateClass\"\n },\n outputs: {\n selectedChange: \"selectedChange\",\n yearSelected: \"yearSelected\",\n activeDateChange: \"activeDateChange\"\n },\n exportAs: [\"matMultiYearView\"],\n standalone: true,\n features: [i0.ɵɵStandaloneFeature],\n decls: 5,\n vars: 7,\n consts: [[\"role\", \"grid\", 1, \"mat-calendar-table\"], [\"aria-hidden\", \"true\", 1, \"mat-calendar-table-header\"], [\"colspan\", \"4\", 1, \"mat-calendar-table-header-divider\"], [\"mat-calendar-body\", \"\", 3, \"selectedValueChange\", \"activeDateChange\", \"keyup\", \"keydown\", \"rows\", \"todayValue\", \"startValue\", \"endValue\", \"numCols\", \"cellAspectRatio\", \"activeCell\"]],\n template: function MatMultiYearView_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"table\", 0)(1, \"thead\", 1)(2, \"tr\");\n i0.ɵɵelement(3, \"th\", 2);\n i0.ɵɵelementEnd()();\n i0.ɵɵelementStart(4, \"tbody\", 3);\n i0.ɵɵlistener(\"selectedValueChange\", function MatMultiYearView_Template_tbody_selectedValueChange_4_listener($event) {\n return ctx._yearSelected($event);\n })(\"activeDateChange\", function MatMultiYearView_Template_tbody_activeDateChange_4_listener($event) {\n return ctx._updateActiveDate($event);\n })(\"keyup\", function MatMultiYearView_Template_tbody_keyup_4_listener($event) {\n return ctx._handleCalendarBodyKeyup($event);\n })(\"keydown\", function MatMultiYearView_Template_tbody_keydown_4_listener($event) {\n return ctx._handleCalendarBodyKeydown($event);\n });\n i0.ɵɵelementEnd()();\n }\n if (rf & 2) {\n i0.ɵɵadvance(4);\n i0.ɵɵproperty(\"rows\", ctx._years)(\"todayValue\", ctx._todayYear)(\"startValue\", ctx._selectedYear)(\"endValue\", ctx._selectedYear)(\"numCols\", 4)(\"cellAspectRatio\", 4 / 7)(\"activeCell\", ctx._getActiveCell());\n }\n },\n dependencies: [MatCalendarBody],\n encapsulation: 2,\n changeDetection: 0\n });\n }\n }\n return MatMultiYearView;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nfunction isSameMultiYearView(dateAdapter, date1, date2, minDate, maxDate) {\n const year1 = dateAdapter.getYear(date1);\n const year2 = dateAdapter.getYear(date2);\n const startingYear = getStartingYear(dateAdapter, minDate, maxDate);\n return Math.floor((year1 - startingYear) / yearsPerPage) === Math.floor((year2 - startingYear) / yearsPerPage);\n}\n/**\n * When the multi-year view is first opened, the active year will be in view.\n * So we compute how many years are between the active year and the *slot* where our\n * \"startingYear\" will render when paged into view.\n */\nfunction getActiveOffset(dateAdapter, activeDate, minDate, maxDate) {\n const activeYear = dateAdapter.getYear(activeDate);\n return euclideanModulo(activeYear - getStartingYear(dateAdapter, minDate, maxDate), yearsPerPage);\n}\n/**\n * We pick a \"starting\" year such that either the maximum year would be at the end\n * or the minimum year would be at the beginning of a page.\n */\nfunction getStartingYear(dateAdapter, minDate, maxDate) {\n let startingYear = 0;\n if (maxDate) {\n const maxYear = dateAdapter.getYear(maxDate);\n startingYear = maxYear - yearsPerPage + 1;\n } else if (minDate) {\n startingYear = dateAdapter.getYear(minDate);\n }\n return startingYear;\n}\n/** Gets remainder that is non-negative, even if first number is negative */\nfunction euclideanModulo(a, b) {\n return (a % b + b) % b;\n}\n\n/**\n * An internal component used to display a single year in the datepicker.\n * @docs-private\n */\nlet MatYearView = /*#__PURE__*/(() => {\n class MatYearView {\n /** The date to display in this year view (everything other than the year is ignored). */\n get activeDate() {\n return this._activeDate;\n }\n set activeDate(value) {\n let oldActiveDate = this._activeDate;\n const validDate = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value)) || this._dateAdapter.today();\n this._activeDate = this._dateAdapter.clampDate(validDate, this.minDate, this.maxDate);\n if (this._dateAdapter.getYear(oldActiveDate) !== this._dateAdapter.getYear(this._activeDate)) {\n this._init();\n }\n }\n /** The currently selected date. */\n get selected() {\n return this._selected;\n }\n set selected(value) {\n if (value instanceof DateRange) {\n this._selected = value;\n } else {\n this._selected = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n this._setSelectedMonth(value);\n }\n /** The minimum selectable date. */\n get minDate() {\n return this._minDate;\n }\n set minDate(value) {\n this._minDate = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** The maximum selectable date. */\n get maxDate() {\n return this._maxDate;\n }\n set maxDate(value) {\n this._maxDate = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n constructor(_changeDetectorRef, _dateFormats, _dateAdapter, _dir) {\n this._changeDetectorRef = _changeDetectorRef;\n this._dateFormats = _dateFormats;\n this._dateAdapter = _dateAdapter;\n this._dir = _dir;\n this._rerenderSubscription = Subscription.EMPTY;\n /** Emits when a new month is selected. */\n this.selectedChange = new EventEmitter();\n /** Emits the selected month. This doesn't imply a change on the selected date */\n this.monthSelected = new EventEmitter();\n /** Emits when any date is activated. */\n this.activeDateChange = new EventEmitter();\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (!this._dateAdapter) {\n throw createMissingDateImplError('DateAdapter');\n }\n if (!this._dateFormats) {\n throw createMissingDateImplError('MAT_DATE_FORMATS');\n }\n }\n this._activeDate = this._dateAdapter.today();\n }\n ngAfterContentInit() {\n this._rerenderSubscription = this._dateAdapter.localeChanges.pipe(startWith(null)).subscribe(() => this._init());\n }\n ngOnDestroy() {\n this._rerenderSubscription.unsubscribe();\n }\n /** Handles when a new month is selected. */\n _monthSelected(event) {\n const month = event.value;\n const selectedMonth = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), month, 1);\n this.monthSelected.emit(selectedMonth);\n const selectedDate = this._getDateFromMonth(month);\n this.selectedChange.emit(selectedDate);\n }\n /**\n * Takes the index of a calendar body cell wrapped in an event as argument. For the date that\n * corresponds to the given cell, set `activeDate` to that date and fire `activeDateChange` with\n * that date.\n *\n * This function is used to match each component's model of the active date with the calendar\n * body cell that was focused. It updates its value of `activeDate` synchronously and updates the\n * parent's value asynchronously via the `activeDateChange` event. The child component receives an\n * updated value asynchronously via the `activeCell` Input.\n */\n _updateActiveDate(event) {\n const month = event.value;\n const oldActiveDate = this._activeDate;\n this.activeDate = this._getDateFromMonth(month);\n if (this._dateAdapter.compareDate(oldActiveDate, this.activeDate)) {\n this.activeDateChange.emit(this.activeDate);\n }\n }\n /** Handles keydown events on the calendar body when calendar is in year view. */\n _handleCalendarBodyKeydown(event) {\n // TODO(mmalerba): We currently allow keyboard navigation to disabled dates, but just prevent\n // disabled ones from being selected. This may not be ideal, we should look into whether\n // navigation should skip over disabled dates, and if so, how to implement that efficiently.\n const oldActiveDate = this._activeDate;\n const isRtl = this._isRtl();\n switch (event.keyCode) {\n case LEFT_ARROW:\n this.activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, isRtl ? 1 : -1);\n break;\n case RIGHT_ARROW:\n this.activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, isRtl ? -1 : 1);\n break;\n case UP_ARROW:\n this.activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, -4);\n break;\n case DOWN_ARROW:\n this.activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, 4);\n break;\n case HOME:\n this.activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, -this._dateAdapter.getMonth(this._activeDate));\n break;\n case END:\n this.activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, 11 - this._dateAdapter.getMonth(this._activeDate));\n break;\n case PAGE_UP:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, event.altKey ? -10 : -1);\n break;\n case PAGE_DOWN:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, event.altKey ? 10 : 1);\n break;\n case ENTER:\n case SPACE:\n // Note that we only prevent the default action here while the selection happens in\n // `keyup` below. We can't do the selection here, because it can cause the calendar to\n // reopen if focus is restored immediately. We also can't call `preventDefault` on `keyup`\n // because it's too late (see #23305).\n this._selectionKeyPressed = true;\n break;\n default:\n // Don't prevent default or focus active cell on keys that we don't explicitly handle.\n return;\n }\n if (this._dateAdapter.compareDate(oldActiveDate, this.activeDate)) {\n this.activeDateChange.emit(this.activeDate);\n this._focusActiveCellAfterViewChecked();\n }\n // Prevent unexpected default actions such as form submission.\n event.preventDefault();\n }\n /** Handles keyup events on the calendar body when calendar is in year view. */\n _handleCalendarBodyKeyup(event) {\n if (event.keyCode === SPACE || event.keyCode === ENTER) {\n if (this._selectionKeyPressed) {\n this._monthSelected({\n value: this._dateAdapter.getMonth(this._activeDate),\n event\n });\n }\n this._selectionKeyPressed = false;\n }\n }\n /** Initializes this year view. */\n _init() {\n this._setSelectedMonth(this.selected);\n this._todayMonth = this._getMonthInCurrentYear(this._dateAdapter.today());\n this._yearLabel = this._dateAdapter.getYearName(this.activeDate);\n let monthNames = this._dateAdapter.getMonthNames('short');\n // First row of months only contains 5 elements so we can fit the year label on the same row.\n this._months = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]].map(row => row.map(month => this._createCellForMonth(month, monthNames[month])));\n this._changeDetectorRef.markForCheck();\n }\n /** Focuses the active cell after the microtask queue is empty. */\n _focusActiveCell() {\n this._matCalendarBody._focusActiveCell();\n }\n /** Schedules the matCalendarBody to focus the active cell after change detection has run */\n _focusActiveCellAfterViewChecked() {\n this._matCalendarBody._scheduleFocusActiveCellAfterViewChecked();\n }\n /**\n * Gets the month in this year that the given Date falls on.\n * Returns null if the given Date is in another year.\n */\n _getMonthInCurrentYear(date) {\n return date && this._dateAdapter.getYear(date) == this._dateAdapter.getYear(this.activeDate) ? this._dateAdapter.getMonth(date) : null;\n }\n /**\n * Takes a month and returns a new date in the same day and year as the currently active date.\n * The returned date will have the same month as the argument date.\n */\n _getDateFromMonth(month) {\n const normalizedDate = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), month, 1);\n const daysInMonth = this._dateAdapter.getNumDaysInMonth(normalizedDate);\n return this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), month, Math.min(this._dateAdapter.getDate(this.activeDate), daysInMonth));\n }\n /** Creates an MatCalendarCell for the given month. */\n _createCellForMonth(month, monthName) {\n const date = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), month, 1);\n const ariaLabel = this._dateAdapter.format(date, this._dateFormats.display.monthYearA11yLabel);\n const cellClasses = this.dateClass ? this.dateClass(date, 'year') : undefined;\n return new MatCalendarCell(month, monthName.toLocaleUpperCase(), ariaLabel, this._shouldEnableMonth(month), cellClasses);\n }\n /** Whether the given month is enabled. */\n _shouldEnableMonth(month) {\n const activeYear = this._dateAdapter.getYear(this.activeDate);\n if (month === undefined || month === null || this._isYearAndMonthAfterMaxDate(activeYear, month) || this._isYearAndMonthBeforeMinDate(activeYear, month)) {\n return false;\n }\n if (!this.dateFilter) {\n return true;\n }\n const firstOfMonth = this._dateAdapter.createDate(activeYear, month, 1);\n // If any date in the month is enabled count the month as enabled.\n for (let date = firstOfMonth; this._dateAdapter.getMonth(date) == month; date = this._dateAdapter.addCalendarDays(date, 1)) {\n if (this.dateFilter(date)) {\n return true;\n }\n }\n return false;\n }\n /**\n * Tests whether the combination month/year is after this.maxDate, considering\n * just the month and year of this.maxDate\n */\n _isYearAndMonthAfterMaxDate(year, month) {\n if (this.maxDate) {\n const maxYear = this._dateAdapter.getYear(this.maxDate);\n const maxMonth = this._dateAdapter.getMonth(this.maxDate);\n return year > maxYear || year === maxYear && month > maxMonth;\n }\n return false;\n }\n /**\n * Tests whether the combination month/year is before this.minDate, considering\n * just the month and year of this.minDate\n */\n _isYearAndMonthBeforeMinDate(year, month) {\n if (this.minDate) {\n const minYear = this._dateAdapter.getYear(this.minDate);\n const minMonth = this._dateAdapter.getMonth(this.minDate);\n return year < minYear || year === minYear && month < minMonth;\n }\n return false;\n }\n /** Determines whether the user has the RTL layout direction. */\n _isRtl() {\n return this._dir && this._dir.value === 'rtl';\n }\n /** Sets the currently-selected month based on a model value. */\n _setSelectedMonth(value) {\n if (value instanceof DateRange) {\n this._selectedMonth = this._getMonthInCurrentYear(value.start) || this._getMonthInCurrentYear(value.end);\n } else {\n this._selectedMonth = this._getMonthInCurrentYear(value);\n }\n }\n static {\n this.ɵfac = function MatYearView_Factory(t) {\n return new (t || MatYearView)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(MAT_DATE_FORMATS, 8), i0.ɵɵdirectiveInject(i1.DateAdapter, 8), i0.ɵɵdirectiveInject(i2.Directionality, 8));\n };\n }\n static {\n this.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatYearView,\n selectors: [[\"mat-year-view\"]],\n viewQuery: function MatYearView_Query(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵviewQuery(MatCalendarBody, 5);\n }\n if (rf & 2) {\n let _t;\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx._matCalendarBody = _t.first);\n }\n },\n inputs: {\n activeDate: \"activeDate\",\n selected: \"selected\",\n minDate: \"minDate\",\n maxDate: \"maxDate\",\n dateFilter: \"dateFilter\",\n dateClass: \"dateClass\"\n },\n outputs: {\n selectedChange: \"selectedChange\",\n monthSelected: \"monthSelected\",\n activeDateChange: \"activeDateChange\"\n },\n exportAs: [\"matYearView\"],\n standalone: true,\n features: [i0.ɵɵStandaloneFeature],\n decls: 5,\n vars: 9,\n consts: [[\"role\", \"grid\", 1, \"mat-calendar-table\"], [\"aria-hidden\", \"true\", 1, \"mat-calendar-table-header\"], [\"colspan\", \"4\", 1, \"mat-calendar-table-header-divider\"], [\"mat-calendar-body\", \"\", 3, \"selectedValueChange\", \"activeDateChange\", \"keyup\", \"keydown\", \"label\", \"rows\", \"todayValue\", \"startValue\", \"endValue\", \"labelMinRequiredCells\", \"numCols\", \"cellAspectRatio\", \"activeCell\"]],\n template: function MatYearView_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"table\", 0)(1, \"thead\", 1)(2, \"tr\");\n i0.ɵɵelement(3, \"th\", 2);\n i0.ɵɵelementEnd()();\n i0.ɵɵelementStart(4, \"tbody\", 3);\n i0.ɵɵlistener(\"selectedValueChange\", function MatYearView_Template_tbody_selectedValueChange_4_listener($event) {\n return ctx._monthSelected($event);\n })(\"activeDateChange\", function MatYearView_Template_tbody_activeDateChange_4_listener($event) {\n return ctx._updateActiveDate($event);\n })(\"keyup\", function MatYearView_Template_tbody_keyup_4_listener($event) {\n return ctx._handleCalendarBodyKeyup($event);\n })(\"keydown\", function MatYearView_Template_tbody_keydown_4_listener($event) {\n return ctx._handleCalendarBodyKeydown($event);\n });\n i0.ɵɵelementEnd()();\n }\n if (rf & 2) {\n i0.ɵɵadvance(4);\n i0.ɵɵproperty(\"label\", ctx._yearLabel)(\"rows\", ctx._months)(\"todayValue\", ctx._todayMonth)(\"startValue\", ctx._selectedMonth)(\"endValue\", ctx._selectedMonth)(\"labelMinRequiredCells\", 2)(\"numCols\", 4)(\"cellAspectRatio\", 4 / 7)(\"activeCell\", ctx._dateAdapter.getMonth(ctx.activeDate));\n }\n },\n dependencies: [MatCalendarBody],\n encapsulation: 2,\n changeDetection: 0\n });\n }\n }\n return MatYearView;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nlet calendarHeaderId = 1;\n/** Default header for MatCalendar */\nlet MatCalendarHeader = /*#__PURE__*/(() => {\n class MatCalendarHeader {\n constructor(_intl, calendar, _dateAdapter, _dateFormats, changeDetectorRef) {\n this._intl = _intl;\n this.calendar = calendar;\n this._dateAdapter = _dateAdapter;\n this._dateFormats = _dateFormats;\n this._id = `mat-calendar-header-${calendarHeaderId++}`;\n this._periodButtonLabelId = `${this._id}-period-label`;\n this.calendar.stateChanges.subscribe(() => changeDetectorRef.markForCheck());\n }\n /** The display text for the current calendar view. */\n get periodButtonText() {\n if (this.calendar.currentView == 'month') {\n return this._dateAdapter.format(this.calendar.activeDate, this._dateFormats.display.monthYearLabel).toLocaleUpperCase();\n }\n if (this.calendar.currentView == 'year') {\n return this._dateAdapter.getYearName(this.calendar.activeDate);\n }\n return this._intl.formatYearRange(...this._formatMinAndMaxYearLabels());\n }\n /** The aria description for the current calendar view. */\n get periodButtonDescription() {\n if (this.calendar.currentView == 'month') {\n return this._dateAdapter.format(this.calendar.activeDate, this._dateFormats.display.monthYearLabel).toLocaleUpperCase();\n }\n if (this.calendar.currentView == 'year') {\n return this._dateAdapter.getYearName(this.calendar.activeDate);\n }\n // Format a label for the window of years displayed in the multi-year calendar view. Use\n // `formatYearRangeLabel` because it is TTS friendly.\n return this._intl.formatYearRangeLabel(...this._formatMinAndMaxYearLabels());\n }\n /** The `aria-label` for changing the calendar view. */\n get periodButtonLabel() {\n return this.calendar.currentView == 'month' ? this._intl.switchToMultiYearViewLabel : this._intl.switchToMonthViewLabel;\n }\n /** The label for the previous button. */\n get prevButtonLabel() {\n return {\n 'month': this._intl.prevMonthLabel,\n 'year': this._intl.prevYearLabel,\n 'multi-year': this._intl.prevMultiYearLabel\n }[this.calendar.currentView];\n }\n /** The label for the next button. */\n get nextButtonLabel() {\n return {\n 'month': this._intl.nextMonthLabel,\n 'year': this._intl.nextYearLabel,\n 'multi-year': this._intl.nextMultiYearLabel\n }[this.calendar.currentView];\n }\n /** Handles user clicks on the period label. */\n currentPeriodClicked() {\n this.calendar.currentView = this.calendar.currentView == 'month' ? 'multi-year' : 'month';\n }\n /** Handles user clicks on the previous button. */\n previousClicked() {\n this.calendar.activeDate = this.calendar.currentView == 'month' ? this._dateAdapter.addCalendarMonths(this.calendar.activeDate, -1) : this._dateAdapter.addCalendarYears(this.calendar.activeDate, this.calendar.currentView == 'year' ? -1 : -yearsPerPage);\n }\n /** Handles user clicks on the next button. */\n nextClicked() {\n this.calendar.activeDate = this.calendar.currentView == 'month' ? this._dateAdapter.addCalendarMonths(this.calendar.activeDate, 1) : this._dateAdapter.addCalendarYears(this.calendar.activeDate, this.calendar.currentView == 'year' ? 1 : yearsPerPage);\n }\n /** Whether the previous period button is enabled. */\n previousEnabled() {\n if (!this.calendar.minDate) {\n return true;\n }\n return !this.calendar.minDate || !this._isSameView(this.calendar.activeDate, this.calendar.minDate);\n }\n /** Whether the next period button is enabled. */\n nextEnabled() {\n return !this.calendar.maxDate || !this._isSameView(this.calendar.activeDate, this.calendar.maxDate);\n }\n /** Whether the two dates represent the same view in the current view mode (month or year). */\n _isSameView(date1, date2) {\n if (this.calendar.currentView == 'month') {\n return this._dateAdapter.getYear(date1) == this._dateAdapter.getYear(date2) && this._dateAdapter.getMonth(date1) == this._dateAdapter.getMonth(date2);\n }\n if (this.calendar.currentView == 'year') {\n return this._dateAdapter.getYear(date1) == this._dateAdapter.getYear(date2);\n }\n // Otherwise we are in 'multi-year' view.\n return isSameMultiYearView(this._dateAdapter, date1, date2, this.calendar.minDate, this.calendar.maxDate);\n }\n /**\n * Format two individual labels for the minimum year and maximum year available in the multi-year\n * calendar view. Returns an array of two strings where the first string is the formatted label\n * for the minimum year, and the second string is the formatted label for the maximum year.\n */\n _formatMinAndMaxYearLabels() {\n // The offset from the active year to the \"slot\" for the starting year is the\n // *actual* first rendered year in the multi-year view, and the last year is\n // just yearsPerPage - 1 away.\n const activeYear = this._dateAdapter.getYear(this.calendar.activeDate);\n const minYearOfPage = activeYear - getActiveOffset(this._dateAdapter, this.calendar.activeDate, this.calendar.minDate, this.calendar.maxDate);\n const maxYearOfPage = minYearOfPage + yearsPerPage - 1;\n const minYearLabel = this._dateAdapter.getYearName(this._dateAdapter.createDate(minYearOfPage, 0, 1));\n const maxYearLabel = this._dateAdapter.getYearName(this._dateAdapter.createDate(maxYearOfPage, 0, 1));\n return [minYearLabel, maxYearLabel];\n }\n static {\n this.ɵfac = function MatCalendarHeader_Factory(t) {\n return new (t || MatCalendarHeader)(i0.ɵɵdirectiveInject(MatDatepickerIntl), i0.ɵɵdirectiveInject(forwardRef(() => MatCalendar)), i0.ɵɵdirectiveInject(i1.DateAdapter, 8), i0.ɵɵdirectiveInject(MAT_DATE_FORMATS, 8), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef));\n };\n }\n static {\n this.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatCalendarHeader,\n selectors: [[\"mat-calendar-header\"]],\n exportAs: [\"matCalendarHeader\"],\n standalone: true,\n features: [i0.ɵɵStandaloneFeature],\n ngContentSelectors: _c1,\n decls: 13,\n vars: 11,\n consts: [[1, \"mat-calendar-header\"], [1, \"mat-calendar-controls\"], [1, \"cdk-visually-hidden\", 3, \"id\"], [\"mat-button\", \"\", \"type\", \"button\", \"aria-live\", \"polite\", 1, \"mat-calendar-period-button\", 3, \"click\"], [\"aria-hidden\", \"true\"], [\"viewBox\", \"0 0 10 5\", \"focusable\", \"false\", \"aria-hidden\", \"true\", 1, \"mat-calendar-arrow\"], [\"points\", \"0,0 5,5 10,0\"], [1, \"mat-calendar-spacer\"], [\"mat-icon-button\", \"\", \"type\", \"button\", 1, \"mat-calendar-previous-button\", 3, \"click\", \"disabled\"], [\"mat-icon-button\", \"\", \"type\", \"button\", 1, \"mat-calendar-next-button\", 3, \"click\", \"disabled\"]],\n template: function MatCalendarHeader_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵprojectionDef();\n i0.ɵɵelementStart(0, \"div\", 0)(1, \"div\", 1)(2, \"label\", 2);\n i0.ɵɵtext(3);\n i0.ɵɵelementEnd();\n i0.ɵɵelementStart(4, \"button\", 3);\n i0.ɵɵlistener(\"click\", function MatCalendarHeader_Template_button_click_4_listener() {\n return ctx.currentPeriodClicked();\n });\n i0.ɵɵelementStart(5, \"span\", 4);\n i0.ɵɵtext(6);\n i0.ɵɵelementEnd();\n i0.ɵɵnamespaceSVG();\n i0.ɵɵelementStart(7, \"svg\", 5);\n i0.ɵɵelement(8, \"polygon\", 6);\n i0.ɵɵelementEnd()();\n i0.ɵɵnamespaceHTML();\n i0.ɵɵelement(9, \"div\", 7);\n i0.ɵɵprojection(10);\n i0.ɵɵelementStart(11, \"button\", 8);\n i0.ɵɵlistener(\"click\", function MatCalendarHeader_Template_button_click_11_listener() {\n return ctx.previousClicked();\n });\n i0.ɵɵelementEnd();\n i0.ɵɵelementStart(12, \"button\", 9);\n i0.ɵɵlistener(\"click\", function MatCalendarHeader_Template_button_click_12_listener() {\n return ctx.nextClicked();\n });\n i0.ɵɵelementEnd()()();\n }\n if (rf & 2) {\n i0.ɵɵadvance(2);\n i0.ɵɵproperty(\"id\", ctx._periodButtonLabelId);\n i0.ɵɵadvance();\n i0.ɵɵtextInterpolate(ctx.periodButtonDescription);\n i0.ɵɵadvance();\n i0.ɵɵattribute(\"aria-label\", ctx.periodButtonLabel)(\"aria-describedby\", ctx._periodButtonLabelId);\n i0.ɵɵadvance(2);\n i0.ɵɵtextInterpolate(ctx.periodButtonText);\n i0.ɵɵadvance();\n i0.ɵɵclassProp(\"mat-calendar-invert\", ctx.calendar.currentView !== \"month\");\n i0.ɵɵadvance(4);\n i0.ɵɵproperty(\"disabled\", !ctx.previousEnabled());\n i0.ɵɵattribute(\"aria-label\", ctx.prevButtonLabel);\n i0.ɵɵadvance();\n i0.ɵɵproperty(\"disabled\", !ctx.nextEnabled());\n i0.ɵɵattribute(\"aria-label\", ctx.nextButtonLabel);\n }\n },\n dependencies: [MatButton, MatIconButton],\n encapsulation: 2,\n changeDetection: 0\n });\n }\n }\n return MatCalendarHeader;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** A calendar that is used as part of the datepicker. */\nlet MatCalendar = /*#__PURE__*/(() => {\n class MatCalendar {\n /** A date representing the period (month or year) to start the calendar in. */\n get startAt() {\n return this._startAt;\n }\n set startAt(value) {\n this._startAt = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** The currently selected date. */\n get selected() {\n return this._selected;\n }\n set selected(value) {\n if (value instanceof DateRange) {\n this._selected = value;\n } else {\n this._selected = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n }\n /** The minimum selectable date. */\n get minDate() {\n return this._minDate;\n }\n set minDate(value) {\n this._minDate = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** The maximum selectable date. */\n get maxDate() {\n return this._maxDate;\n }\n set maxDate(value) {\n this._maxDate = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /**\n * The current active date. This determines which time period is shown and which date is\n * highlighted when using keyboard navigation.\n */\n get activeDate() {\n return this._clampedActiveDate;\n }\n set activeDate(value) {\n this._clampedActiveDate = this._dateAdapter.clampDate(value, this.minDate, this.maxDate);\n this.stateChanges.next();\n this._changeDetectorRef.markForCheck();\n }\n /** Whether the calendar is in month view. */\n get currentView() {\n return this._currentView;\n }\n set currentView(value) {\n const viewChangedResult = this._currentView !== value ? value : null;\n this._currentView = value;\n this._moveFocusOnNextTick = true;\n this._changeDetectorRef.markForCheck();\n if (viewChangedResult) {\n this.viewChanged.emit(viewChangedResult);\n }\n }\n constructor(_intl, _dateAdapter, _dateFormats, _changeDetectorRef) {\n this._dateAdapter = _dateAdapter;\n this._dateFormats = _dateFormats;\n this._changeDetectorRef = _changeDetectorRef;\n /**\n * Used for scheduling that focus should be moved to the active cell on the next tick.\n * We need to schedule it, rather than do it immediately, because we have to wait\n * for Angular to re-evaluate the view children.\n */\n this._moveFocusOnNextTick = false;\n /** Whether the calendar should be started in month or year view. */\n this.startView = 'month';\n /** Emits when the currently selected date changes. */\n this.selectedChange = new EventEmitter();\n /**\n * Emits the year chosen in multiyear view.\n * This doesn't imply a change on the selected date.\n */\n this.yearSelected = new EventEmitter();\n /**\n * Emits the month chosen in year view.\n * This doesn't imply a change on the selected date.\n */\n this.monthSelected = new EventEmitter();\n /**\n * Emits when the current view changes.\n */\n this.viewChanged = new EventEmitter(true);\n /** Emits when any date is selected. */\n this._userSelection = new EventEmitter();\n /** Emits a new date range value when the user completes a drag drop operation. */\n this._userDragDrop = new EventEmitter();\n /** Origin of active drag, or null when dragging is not active. */\n this._activeDrag = null;\n /**\n * Emits whenever there is a state change that the header may need to respond to.\n */\n this.stateChanges = new Subject();\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (!this._dateAdapter) {\n throw createMissingDateImplError('DateAdapter');\n }\n if (!this._dateFormats) {\n throw createMissingDateImplError('MAT_DATE_FORMATS');\n }\n }\n this._intlChanges = _intl.changes.subscribe(() => {\n _changeDetectorRef.markForCheck();\n this.stateChanges.next();\n });\n }\n ngAfterContentInit() {\n this._calendarHeaderPortal = new ComponentPortal(this.headerComponent || MatCalendarHeader);\n this.activeDate = this.startAt || this._dateAdapter.today();\n // Assign to the private property since we don't want to move focus on init.\n this._currentView = this.startView;\n }\n ngAfterViewChecked() {\n if (this._moveFocusOnNextTick) {\n this._moveFocusOnNextTick = false;\n this.focusActiveCell();\n }\n }\n ngOnDestroy() {\n this._intlChanges.unsubscribe();\n this.stateChanges.complete();\n }\n ngOnChanges(changes) {\n // Ignore date changes that are at a different time on the same day. This fixes issues where\n // the calendar re-renders when there is no meaningful change to [minDate] or [maxDate]\n // (#24435).\n const minDateChange = changes['minDate'] && !this._dateAdapter.sameDate(changes['minDate'].previousValue, changes['minDate'].currentValue) ? changes['minDate'] : undefined;\n const maxDateChange = changes['maxDate'] && !this._dateAdapter.sameDate(changes['maxDate'].previousValue, changes['maxDate'].currentValue) ? changes['maxDate'] : undefined;\n const change = minDateChange || maxDateChange || changes['dateFilter'];\n if (change && !change.firstChange) {\n const view = this._getCurrentViewComponent();\n if (view) {\n // We need to `detectChanges` manually here, because the `minDate`, `maxDate` etc. are\n // passed down to the view via data bindings which won't be up-to-date when we call `_init`.\n this._changeDetectorRef.detectChanges();\n view._init();\n }\n }\n this.stateChanges.next();\n }\n /** Focuses the active date. */\n focusActiveCell() {\n this._getCurrentViewComponent()._focusActiveCell(false);\n }\n /** Updates today's date after an update of the active date */\n updateTodaysDate() {\n this._getCurrentViewComponent()._init();\n }\n /** Handles date selection in the month view. */\n _dateSelected(event) {\n const date = event.value;\n if (this.selected instanceof DateRange || date && !this._dateAdapter.sameDate(date, this.selected)) {\n this.selectedChange.emit(date);\n }\n this._userSelection.emit(event);\n }\n /** Handles year selection in the multiyear view. */\n _yearSelectedInMultiYearView(normalizedYear) {\n this.yearSelected.emit(normalizedYear);\n }\n /** Handles month selection in the year view. */\n _monthSelectedInYearView(normalizedMonth) {\n this.monthSelected.emit(normalizedMonth);\n }\n /** Handles year/month selection in the multi-year/year views. */\n _goToDateInView(date, view) {\n this.activeDate = date;\n this.currentView = view;\n }\n /** Called when the user starts dragging to change a date range. */\n _dragStarted(event) {\n this._activeDrag = event;\n }\n /**\n * Called when a drag completes. It may end in cancelation or in the selection\n * of a new range.\n */\n _dragEnded(event) {\n if (!this._activeDrag) return;\n if (event.value) {\n this._userDragDrop.emit(event);\n }\n this._activeDrag = null;\n }\n /** Returns the component instance that corresponds to the current calendar view. */\n _getCurrentViewComponent() {\n // The return type is explicitly written as a union to ensure that the Closure compiler does\n // not optimize calls to _init(). Without the explicit return type, TypeScript narrows it to\n // only the first component type. See https://github.com/angular/components/issues/22996.\n return this.monthView || this.yearView || this.multiYearView;\n }\n static {\n this.ɵfac = function MatCalendar_Factory(t) {\n return new (t || MatCalendar)(i0.ɵɵdirectiveInject(MatDatepickerIntl), i0.ɵɵdirectiveInject(i1.DateAdapter, 8), i0.ɵɵdirectiveInject(MAT_DATE_FORMATS, 8), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef));\n };\n }\n static {\n this.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatCalendar,\n selectors: [[\"mat-calendar\"]],\n viewQuery: function MatCalendar_Query(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵviewQuery(MatMonthView, 5);\n i0.ɵɵviewQuery(MatYearView, 5);\n i0.ɵɵviewQuery(MatMultiYearView, 5);\n }\n if (rf & 2) {\n let _t;\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.monthView = _t.first);\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.yearView = _t.first);\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.multiYearView = _t.first);\n }\n },\n hostAttrs: [1, \"mat-calendar\"],\n inputs: {\n headerComponent: \"headerComponent\",\n startAt: \"startAt\",\n startView: \"startView\",\n selected: \"selected\",\n minDate: \"minDate\",\n maxDate: \"maxDate\",\n dateFilter: \"dateFilter\",\n dateClass: \"dateClass\",\n comparisonStart: \"comparisonStart\",\n comparisonEnd: \"comparisonEnd\",\n startDateAccessibleName: \"startDateAccessibleName\",\n endDateAccessibleName: \"endDateAccessibleName\"\n },\n outputs: {\n selectedChange: \"selectedChange\",\n yearSelected: \"yearSelected\",\n monthSelected: \"monthSelected\",\n viewChanged: \"viewChanged\",\n _userSelection: \"_userSelection\",\n _userDragDrop: \"_userDragDrop\"\n },\n exportAs: [\"matCalendar\"],\n standalone: true,\n features: [i0.ɵɵProvidersFeature([MAT_SINGLE_DATE_SELECTION_MODEL_PROVIDER]), i0.ɵɵNgOnChangesFeature, i0.ɵɵStandaloneFeature],\n decls: 5,\n vars: 2,\n consts: [[3, \"cdkPortalOutlet\"], [\"cdkMonitorSubtreeFocus\", \"\", \"tabindex\", \"-1\", 1, \"mat-calendar-content\"], [3, \"activeDateChange\", \"_userSelection\", \"dragStarted\", \"dragEnded\", \"activeDate\", \"selected\", \"dateFilter\", \"maxDate\", \"minDate\", \"dateClass\", \"comparisonStart\", \"comparisonEnd\", \"startDateAccessibleName\", \"endDateAccessibleName\", \"activeDrag\"], [3, \"activeDateChange\", \"monthSelected\", \"selectedChange\", \"activeDate\", \"selected\", \"dateFilter\", \"maxDate\", \"minDate\", \"dateClass\"], [3, \"activeDateChange\", \"yearSelected\", \"selectedChange\", \"activeDate\", \"selected\", \"dateFilter\", \"maxDate\", \"minDate\", \"dateClass\"]],\n template: function MatCalendar_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵtemplate(0, MatCalendar_ng_template_0_Template, 0, 0, \"ng-template\", 0);\n i0.ɵɵelementStart(1, \"div\", 1);\n i0.ɵɵtemplate(2, MatCalendar_Case_2_Template, 1, 11)(3, MatCalendar_Case_3_Template, 1, 6)(4, MatCalendar_Case_4_Template, 1, 6);\n i0.ɵɵelementEnd();\n }\n if (rf & 2) {\n let tmp_1_0;\n i0.ɵɵproperty(\"cdkPortalOutlet\", ctx._calendarHeaderPortal);\n i0.ɵɵadvance(2);\n i0.ɵɵconditional(2, (tmp_1_0 = ctx.currentView) === \"month\" ? 2 : tmp_1_0 === \"year\" ? 3 : tmp_1_0 === \"multi-year\" ? 4 : -1);\n }\n },\n dependencies: [CdkPortalOutlet, CdkMonitorFocus, MatMonthView, MatYearView, MatMultiYearView],\n styles: [\".mat-calendar{display:block;font-family:var(--mat-datepicker-calendar-text-font);font-size:var(--mat-datepicker-calendar-text-size)}.mat-calendar-header{padding:8px 8px 0 8px}.mat-calendar-content{padding:0 8px 8px 8px;outline:none}.mat-calendar-controls{display:flex;align-items:center;margin:5% calc(4.7142857143% - 16px)}.mat-calendar-spacer{flex:1 1 auto}.mat-calendar-period-button{min-width:0;margin:0 8px;font-size:var(--mat-datepicker-calendar-period-button-text-size);font-weight:var(--mat-datepicker-calendar-period-button-text-weight);--mdc-text-button-label-text-color:var(--mat-datepicker-calendar-period-button-text-color)}.mat-calendar-arrow{display:inline-block;width:10px;height:5px;margin:0 0 0 5px;vertical-align:middle;fill:var(--mat-datepicker-calendar-period-button-icon-color)}.mat-calendar-arrow.mat-calendar-invert{transform:rotate(180deg)}[dir=rtl] .mat-calendar-arrow{margin:0 5px 0 0}.cdk-high-contrast-active .mat-calendar-arrow{fill:CanvasText}.mat-calendar-previous-button,.mat-calendar-next-button{position:relative}.mat-datepicker-content .mat-calendar-previous-button:not(.mat-mdc-button-disabled),.mat-datepicker-content .mat-calendar-next-button:not(.mat-mdc-button-disabled){color:var(--mat-datepicker-calendar-navigation-button-icon-color)}.mat-calendar-previous-button::after,.mat-calendar-next-button::after{top:0;left:0;right:0;bottom:0;position:absolute;content:\\\"\\\";margin:15.5px;border:0 solid currentColor;border-top-width:2px}[dir=rtl] .mat-calendar-previous-button,[dir=rtl] .mat-calendar-next-button{transform:rotate(180deg)}.mat-calendar-previous-button::after{border-left-width:2px;transform:translateX(2px) rotate(-45deg)}.mat-calendar-next-button::after{border-right-width:2px;transform:translateX(-2px) rotate(45deg)}.mat-calendar-table{border-spacing:0;border-collapse:collapse;width:100%}.mat-calendar-table-header th{text-align:center;padding:0 0 8px 0;color:var(--mat-datepicker-calendar-header-text-color);font-size:var(--mat-datepicker-calendar-header-text-size);font-weight:var(--mat-datepicker-calendar-header-text-weight)}.mat-calendar-table-header-divider{position:relative;height:1px}.mat-calendar-table-header-divider::after{content:\\\"\\\";position:absolute;top:0;left:-8px;right:-8px;height:1px;background:var(--mat-datepicker-calendar-header-divider-color)}.mat-calendar-body-cell-content::before{margin:calc(calc(var(--mat-focus-indicator-border-width, 3px) + 3px)*-1)}.mat-calendar-body-cell:focus .mat-focus-indicator::before{content:\\\"\\\"}\"],\n encapsulation: 2,\n changeDetection: 0\n });\n }\n }\n return MatCalendar;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Animations used by the Material datepicker.\n * @docs-private\n */\nconst matDatepickerAnimations = {\n /** Transforms the height of the datepicker's calendar. */\n transformPanel: /*#__PURE__*/trigger('transformPanel', [/*#__PURE__*/transition('void => enter-dropdown', /*#__PURE__*/animate('120ms cubic-bezier(0, 0, 0.2, 1)', /*#__PURE__*/keyframes([/*#__PURE__*/style({\n opacity: 0,\n transform: 'scale(1, 0.8)'\n }), /*#__PURE__*/style({\n opacity: 1,\n transform: 'scale(1, 1)'\n })]))), /*#__PURE__*/transition('void => enter-dialog', /*#__PURE__*/animate('150ms cubic-bezier(0, 0, 0.2, 1)', /*#__PURE__*/keyframes([/*#__PURE__*/style({\n opacity: 0,\n transform: 'scale(0.7)'\n }), /*#__PURE__*/style({\n transform: 'none',\n opacity: 1\n })]))), /*#__PURE__*/transition('* => void', /*#__PURE__*/animate('100ms linear', /*#__PURE__*/style({\n opacity: 0\n })))]),\n /** Fades in the content of the calendar. */\n fadeInCalendar: /*#__PURE__*/trigger('fadeInCalendar', [/*#__PURE__*/state('void', /*#__PURE__*/style({\n opacity: 0\n })), /*#__PURE__*/state('enter', /*#__PURE__*/style({\n opacity: 1\n })),\n /*#__PURE__*/\n // TODO(crisbeto): this animation should be removed since it isn't quite on spec, but we\n // need to keep it until #12440 gets in, otherwise the exit animation will look glitchy.\n transition('void => *', /*#__PURE__*/animate('120ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)'))])\n};\n\n/** Used to generate a unique ID for each datepicker instance. */\nlet datepickerUid = 0;\n/** Injection token that determines the scroll handling while the calendar is open. */\nconst MAT_DATEPICKER_SCROLL_STRATEGY = /*#__PURE__*/new InjectionToken('mat-datepicker-scroll-strategy', {\n providedIn: 'root',\n factory: () => {\n const overlay = inject(Overlay);\n return () => overlay.scrollStrategies.reposition();\n }\n});\n/** @docs-private */\nfunction MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY(overlay) {\n return () => overlay.scrollStrategies.reposition();\n}\n/** @docs-private */\nconst MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER = {\n provide: MAT_DATEPICKER_SCROLL_STRATEGY,\n deps: [Overlay],\n useFactory: MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY\n};\n/**\n * Component used as the content for the datepicker overlay. We use this instead of using\n * MatCalendar directly as the content so we can control the initial focus. This also gives us a\n * place to put additional features of the overlay that are not part of the calendar itself in the\n * future. (e.g. confirmation buttons).\n * @docs-private\n */\nlet MatDatepickerContent = /*#__PURE__*/(() => {\n class MatDatepickerContent {\n constructor(_elementRef, _changeDetectorRef, _globalModel, _dateAdapter, _rangeSelectionStrategy, intl) {\n this._elementRef = _elementRef;\n this._changeDetectorRef = _changeDetectorRef;\n this._globalModel = _globalModel;\n this._dateAdapter = _dateAdapter;\n this._rangeSelectionStrategy = _rangeSelectionStrategy;\n this._subscriptions = new Subscription();\n /** Emits when an animation has finished. */\n this._animationDone = new Subject();\n /** Whether there is an in-progress animation. */\n this._isAnimating = false;\n /** Portal with projected action buttons. */\n this._actionsPortal = null;\n this._closeButtonText = intl.closeCalendarLabel;\n }\n ngOnInit() {\n this._animationState = this.datepicker.touchUi ? 'enter-dialog' : 'enter-dropdown';\n }\n ngAfterViewInit() {\n this._subscriptions.add(this.datepicker.stateChanges.subscribe(() => {\n this._changeDetectorRef.markForCheck();\n }));\n this._calendar.focusActiveCell();\n }\n ngOnDestroy() {\n this._subscriptions.unsubscribe();\n this._animationDone.complete();\n }\n _handleUserSelection(event) {\n const selection = this._model.selection;\n const value = event.value;\n const isRange = selection instanceof DateRange;\n // If we're selecting a range and we have a selection strategy, always pass the value through\n // there. Otherwise don't assign null values to the model, unless we're selecting a range.\n // A null value when picking a range means that the user cancelled the selection (e.g. by\n // pressing escape), whereas when selecting a single value it means that the value didn't\n // change. This isn't very intuitive, but it's here for backwards-compatibility.\n if (isRange && this._rangeSelectionStrategy) {\n const newSelection = this._rangeSelectionStrategy.selectionFinished(value, selection, event.event);\n this._model.updateSelection(newSelection, this);\n } else if (value && (isRange || !this._dateAdapter.sameDate(value, selection))) {\n this._model.add(value);\n }\n // Delegate closing the overlay to the actions.\n if ((!this._model || this._model.isComplete()) && !this._actionsPortal) {\n this.datepicker.close();\n }\n }\n _handleUserDragDrop(event) {\n this._model.updateSelection(event.value, this);\n }\n _startExitAnimation() {\n this._animationState = 'void';\n this._changeDetectorRef.markForCheck();\n }\n _handleAnimationEvent(event) {\n this._isAnimating = event.phaseName === 'start';\n if (!this._isAnimating) {\n this._animationDone.next();\n }\n }\n _getSelected() {\n return this._model.selection;\n }\n /** Applies the current pending selection to the global model. */\n _applyPendingSelection() {\n if (this._model !== this._globalModel) {\n this._globalModel.updateSelection(this._model.selection, this);\n }\n }\n /**\n * Assigns a new portal containing the datepicker actions.\n * @param portal Portal with the actions to be assigned.\n * @param forceRerender Whether a re-render of the portal should be triggered. This isn't\n * necessary if the portal is assigned during initialization, but it may be required if it's\n * added at a later point.\n */\n _assignActions(portal, forceRerender) {\n // If we have actions, clone the model so that we have the ability to cancel the selection,\n // otherwise update the global model directly. Note that we want to assign this as soon as\n // possible, but `_actionsPortal` isn't available in the constructor so we do it in `ngOnInit`.\n this._model = portal ? this._globalModel.clone() : this._globalModel;\n this._actionsPortal = portal;\n if (forceRerender) {\n this._changeDetectorRef.detectChanges();\n }\n }\n static {\n this.ɵfac = function MatDatepickerContent_Factory(t) {\n return new (t || MatDatepickerContent)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(MatDateSelectionModel), i0.ɵɵdirectiveInject(i1.DateAdapter), i0.ɵɵdirectiveInject(MAT_DATE_RANGE_SELECTION_STRATEGY, 8), i0.ɵɵdirectiveInject(MatDatepickerIntl));\n };\n }\n static {\n this.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatDatepickerContent,\n selectors: [[\"mat-datepicker-content\"]],\n viewQuery: function MatDatepickerContent_Query(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵviewQuery(MatCalendar, 5);\n }\n if (rf & 2) {\n let _t;\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx._calendar = _t.first);\n }\n },\n hostAttrs: [1, \"mat-datepicker-content\"],\n hostVars: 5,\n hostBindings: function MatDatepickerContent_HostBindings(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵsyntheticHostListener(\"@transformPanel.start\", function MatDatepickerContent_animation_transformPanel_start_HostBindingHandler($event) {\n return ctx._handleAnimationEvent($event);\n })(\"@transformPanel.done\", function MatDatepickerContent_animation_transformPanel_done_HostBindingHandler($event) {\n return ctx._handleAnimationEvent($event);\n });\n }\n if (rf & 2) {\n i0.ɵɵsyntheticHostProperty(\"@transformPanel\", ctx._animationState);\n i0.ɵɵclassMap(ctx.color ? \"mat-\" + ctx.color : \"\");\n i0.ɵɵclassProp(\"mat-datepicker-content-touch\", ctx.datepicker.touchUi);\n }\n },\n inputs: {\n color: \"color\"\n },\n exportAs: [\"matDatepickerContent\"],\n standalone: true,\n features: [i0.ɵɵStandaloneFeature],\n decls: 5,\n vars: 26,\n consts: [[\"cdkTrapFocus\", \"\", \"role\", \"dialog\", 1, \"mat-datepicker-content-container\"], [3, \"yearSelected\", \"monthSelected\", \"viewChanged\", \"_userSelection\", \"_userDragDrop\", \"id\", \"ngClass\", \"startAt\", \"startView\", \"minDate\", \"maxDate\", \"dateFilter\", \"headerComponent\", \"selected\", \"dateClass\", \"comparisonStart\", \"comparisonEnd\", \"startDateAccessibleName\", \"endDateAccessibleName\"], [3, \"cdkPortalOutlet\"], [\"type\", \"button\", \"mat-raised-button\", \"\", 1, \"mat-datepicker-close-button\", 3, \"focus\", \"blur\", \"click\", \"color\"]],\n template: function MatDatepickerContent_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"div\", 0)(1, \"mat-calendar\", 1);\n i0.ɵɵlistener(\"yearSelected\", function MatDatepickerContent_Template_mat_calendar_yearSelected_1_listener($event) {\n return ctx.datepicker._selectYear($event);\n })(\"monthSelected\", function MatDatepickerContent_Template_mat_calendar_monthSelected_1_listener($event) {\n return ctx.datepicker._selectMonth($event);\n })(\"viewChanged\", function MatDatepickerContent_Template_mat_calendar_viewChanged_1_listener($event) {\n return ctx.datepicker._viewChanged($event);\n })(\"_userSelection\", function MatDatepickerContent_Template_mat_calendar__userSelection_1_listener($event) {\n return ctx._handleUserSelection($event);\n })(\"_userDragDrop\", function MatDatepickerContent_Template_mat_calendar__userDragDrop_1_listener($event) {\n return ctx._handleUserDragDrop($event);\n });\n i0.ɵɵelementEnd();\n i0.ɵɵtemplate(2, MatDatepickerContent_ng_template_2_Template, 0, 0, \"ng-template\", 2);\n i0.ɵɵelementStart(3, \"button\", 3);\n i0.ɵɵlistener(\"focus\", function MatDatepickerContent_Template_button_focus_3_listener() {\n return ctx._closeButtonFocused = true;\n })(\"blur\", function MatDatepickerContent_Template_button_blur_3_listener() {\n return ctx._closeButtonFocused = false;\n })(\"click\", function MatDatepickerContent_Template_button_click_3_listener() {\n return ctx.datepicker.close();\n });\n i0.ɵɵtext(4);\n i0.ɵɵelementEnd()();\n }\n if (rf & 2) {\n let tmp_3_0;\n i0.ɵɵclassProp(\"mat-datepicker-content-container-with-custom-header\", ctx.datepicker.calendarHeaderComponent)(\"mat-datepicker-content-container-with-actions\", ctx._actionsPortal);\n i0.ɵɵattribute(\"aria-modal\", true)(\"aria-labelledby\", (tmp_3_0 = ctx._dialogLabelId) !== null && tmp_3_0 !== undefined ? tmp_3_0 : undefined);\n i0.ɵɵadvance();\n i0.ɵɵproperty(\"id\", ctx.datepicker.id)(\"ngClass\", ctx.datepicker.panelClass)(\"startAt\", ctx.datepicker.startAt)(\"startView\", ctx.datepicker.startView)(\"minDate\", ctx.datepicker._getMinDate())(\"maxDate\", ctx.datepicker._getMaxDate())(\"dateFilter\", ctx.datepicker._getDateFilter())(\"headerComponent\", ctx.datepicker.calendarHeaderComponent)(\"selected\", ctx._getSelected())(\"dateClass\", ctx.datepicker.dateClass)(\"comparisonStart\", ctx.comparisonStart)(\"comparisonEnd\", ctx.comparisonEnd)(\"@fadeInCalendar\", \"enter\")(\"startDateAccessibleName\", ctx.startDateAccessibleName)(\"endDateAccessibleName\", ctx.endDateAccessibleName);\n i0.ɵɵadvance();\n i0.ɵɵproperty(\"cdkPortalOutlet\", ctx._actionsPortal);\n i0.ɵɵadvance();\n i0.ɵɵclassProp(\"cdk-visually-hidden\", !ctx._closeButtonFocused);\n i0.ɵɵproperty(\"color\", ctx.color || \"primary\");\n i0.ɵɵadvance();\n i0.ɵɵtextInterpolate(ctx._closeButtonText);\n }\n },\n dependencies: [CdkTrapFocus, MatCalendar, NgClass, CdkPortalOutlet, MatButton],\n styles: [\".mat-datepicker-content{display:block;border-radius:4px;background-color:var(--mat-datepicker-calendar-container-background-color);color:var(--mat-datepicker-calendar-container-text-color);box-shadow:var(--mat-datepicker-calendar-container-elevation-shadow);border-radius:var(--mat-datepicker-calendar-container-shape)}.mat-datepicker-content .mat-calendar{width:296px;height:354px}.mat-datepicker-content .mat-datepicker-content-container-with-custom-header .mat-calendar{height:auto}.mat-datepicker-content .mat-datepicker-close-button{position:absolute;top:100%;left:0;margin-top:8px}.ng-animating .mat-datepicker-content .mat-datepicker-close-button{display:none}.mat-datepicker-content-container{display:flex;flex-direction:column;justify-content:space-between}.mat-datepicker-content-touch{display:block;max-height:80vh;box-shadow:var(--mat-datepicker-calendar-container-touch-elevation-shadow);border-radius:var(--mat-datepicker-calendar-container-touch-shape);position:relative;overflow:visible}.mat-datepicker-content-touch .mat-datepicker-content-container{min-height:312px;max-height:788px;min-width:250px;max-width:750px}.mat-datepicker-content-touch .mat-calendar{width:100%;height:auto}@media all and (orientation: landscape){.mat-datepicker-content-touch .mat-datepicker-content-container{width:64vh;height:80vh}}@media all and (orientation: portrait){.mat-datepicker-content-touch .mat-datepicker-content-container{width:80vw;height:100vw}.mat-datepicker-content-touch .mat-datepicker-content-container-with-actions{height:115vw}}\"],\n encapsulation: 2,\n data: {\n animation: [matDatepickerAnimations.transformPanel, matDatepickerAnimations.fadeInCalendar]\n },\n changeDetection: 0\n });\n }\n }\n return MatDatepickerContent;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** Base class for a datepicker. */\nlet MatDatepickerBase = /*#__PURE__*/(() => {\n class MatDatepickerBase {\n /** The date to open the calendar to initially. */\n get startAt() {\n // If an explicit startAt is set we start there, otherwise we start at whatever the currently\n // selected value is.\n return this._startAt || (this.datepickerInput ? this.datepickerInput.getStartValue() : null);\n }\n set startAt(value) {\n this._startAt = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** Color palette to use on the datepicker's calendar. */\n get color() {\n return this._color || (this.datepickerInput ? this.datepickerInput.getThemePalette() : undefined);\n }\n set color(value) {\n this._color = value;\n }\n /** Whether the datepicker pop-up should be disabled. */\n get disabled() {\n return this._disabled === undefined && this.datepickerInput ? this.datepickerInput.disabled : !!this._disabled;\n }\n set disabled(value) {\n if (value !== this._disabled) {\n this._disabled = value;\n this.stateChanges.next(undefined);\n }\n }\n /**\n * Classes to be passed to the date picker panel.\n * Supports string and string array values, similar to `ngClass`.\n */\n get panelClass() {\n return this._panelClass;\n }\n set panelClass(value) {\n this._panelClass = coerceStringArray(value);\n }\n /** Whether the calendar is open. */\n get opened() {\n return this._opened;\n }\n set opened(value) {\n if (value) {\n this.open();\n } else {\n this.close();\n }\n }\n /** The minimum selectable date. */\n _getMinDate() {\n return this.datepickerInput && this.datepickerInput.min;\n }\n /** The maximum selectable date. */\n _getMaxDate() {\n return this.datepickerInput && this.datepickerInput.max;\n }\n _getDateFilter() {\n return this.datepickerInput && this.datepickerInput.dateFilter;\n }\n constructor(_overlay, _ngZone, _viewContainerRef, scrollStrategy, _dateAdapter, _dir, _model) {\n this._overlay = _overlay;\n this._ngZone = _ngZone;\n this._viewContainerRef = _viewContainerRef;\n this._dateAdapter = _dateAdapter;\n this._dir = _dir;\n this._model = _model;\n this._inputStateChanges = Subscription.EMPTY;\n this._document = inject(DOCUMENT);\n /** The view that the calendar should start in. */\n this.startView = 'month';\n /**\n * Whether the calendar UI is in touch mode. In touch mode the calendar opens in a dialog rather\n * than a dropdown and elements have more padding to allow for bigger touch targets.\n */\n this.touchUi = false;\n /** Preferred position of the datepicker in the X axis. */\n this.xPosition = 'start';\n /** Preferred position of the datepicker in the Y axis. */\n this.yPosition = 'below';\n /**\n * Whether to restore focus to the previously-focused element when the calendar is closed.\n * Note that automatic focus restoration is an accessibility feature and it is recommended that\n * you provide your own equivalent, if you decide to turn it off.\n */\n this.restoreFocus = true;\n /**\n * Emits selected year in multiyear view.\n * This doesn't imply a change on the selected date.\n */\n this.yearSelected = new EventEmitter();\n /**\n * Emits selected month in year view.\n * This doesn't imply a change on the selected date.\n */\n this.monthSelected = new EventEmitter();\n /**\n * Emits when the current view changes.\n */\n this.viewChanged = new EventEmitter(true);\n /** Emits when the datepicker has been opened. */\n this.openedStream = new EventEmitter();\n /** Emits when the datepicker has been closed. */\n this.closedStream = new EventEmitter();\n this._opened = false;\n /** The id for the datepicker calendar. */\n this.id = `mat-datepicker-${datepickerUid++}`;\n /** The element that was focused before the datepicker was opened. */\n this._focusedElementBeforeOpen = null;\n /** Unique class that will be added to the backdrop so that the test harnesses can look it up. */\n this._backdropHarnessClass = `${this.id}-backdrop`;\n /** Emits when the datepicker's state changes. */\n this.stateChanges = new Subject();\n if (!this._dateAdapter && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw createMissingDateImplError('DateAdapter');\n }\n this._scrollStrategy = scrollStrategy;\n }\n ngOnChanges(changes) {\n const positionChange = changes['xPosition'] || changes['yPosition'];\n if (positionChange && !positionChange.firstChange && this._overlayRef) {\n const positionStrategy = this._overlayRef.getConfig().positionStrategy;\n if (positionStrategy instanceof FlexibleConnectedPositionStrategy) {\n this._setConnectedPositions(positionStrategy);\n if (this.opened) {\n this._overlayRef.updatePosition();\n }\n }\n }\n this.stateChanges.next(undefined);\n }\n ngOnDestroy() {\n this._destroyOverlay();\n this.close();\n this._inputStateChanges.unsubscribe();\n this.stateChanges.complete();\n }\n /** Selects the given date */\n select(date) {\n this._model.add(date);\n }\n /** Emits the selected year in multiyear view */\n _selectYear(normalizedYear) {\n this.yearSelected.emit(normalizedYear);\n }\n /** Emits selected month in year view */\n _selectMonth(normalizedMonth) {\n this.monthSelected.emit(normalizedMonth);\n }\n /** Emits changed view */\n _viewChanged(view) {\n this.viewChanged.emit(view);\n }\n /**\n * Register an input with this datepicker.\n * @param input The datepicker input to register with this datepicker.\n * @returns Selection model that the input should hook itself up to.\n */\n registerInput(input) {\n if (this.datepickerInput && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error('A MatDatepicker can only be associated with a single input.');\n }\n this._inputStateChanges.unsubscribe();\n this.datepickerInput = input;\n this._inputStateChanges = input.stateChanges.subscribe(() => this.stateChanges.next(undefined));\n return this._model;\n }\n /**\n * Registers a portal containing action buttons with the datepicker.\n * @param portal Portal to be registered.\n */\n registerActions(portal) {\n if (this._actionsPortal && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error('A MatDatepicker can only be associated with a single actions row.');\n }\n this._actionsPortal = portal;\n this._componentRef?.instance._assignActions(portal, true);\n }\n /**\n * Removes a portal containing action buttons from the datepicker.\n * @param portal Portal to be removed.\n */\n removeActions(portal) {\n if (portal === this._actionsPortal) {\n this._actionsPortal = null;\n this._componentRef?.instance._assignActions(null, true);\n }\n }\n /** Open the calendar. */\n open() {\n // Skip reopening if there's an in-progress animation to avoid overlapping\n // sequences which can cause \"changed after checked\" errors. See #25837.\n if (this._opened || this.disabled || this._componentRef?.instance._isAnimating) {\n return;\n }\n if (!this.datepickerInput && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error('Attempted to open an MatDatepicker with no associated input.');\n }\n this._focusedElementBeforeOpen = _getFocusedElementPierceShadowDom();\n this._openOverlay();\n this._opened = true;\n this.openedStream.emit();\n }\n /** Close the calendar. */\n close() {\n // Skip reopening if there's an in-progress animation to avoid overlapping\n // sequences which can cause \"changed after checked\" errors. See #25837.\n if (!this._opened || this._componentRef?.instance._isAnimating) {\n return;\n }\n const canRestoreFocus = this.restoreFocus && this._focusedElementBeforeOpen && typeof this._focusedElementBeforeOpen.focus === 'function';\n const completeClose = () => {\n // The `_opened` could've been reset already if\n // we got two events in quick succession.\n if (this._opened) {\n this._opened = false;\n this.closedStream.emit();\n }\n };\n if (this._componentRef) {\n const {\n instance,\n location\n } = this._componentRef;\n instance._startExitAnimation();\n instance._animationDone.pipe(take(1)).subscribe(() => {\n const activeElement = this._document.activeElement;\n // Since we restore focus after the exit animation, we have to check that\n // the user didn't move focus themselves inside the `close` handler.\n if (canRestoreFocus && (!activeElement || activeElement === this._document.activeElement || location.nativeElement.contains(activeElement))) {\n this._focusedElementBeforeOpen.focus();\n }\n this._focusedElementBeforeOpen = null;\n this._destroyOverlay();\n });\n }\n if (canRestoreFocus) {\n // Because IE moves focus asynchronously, we can't count on it being restored before we've\n // marked the datepicker as closed. If the event fires out of sequence and the element that\n // we're refocusing opens the datepicker on focus, the user could be stuck with not being\n // able to close the calendar at all. We work around it by making the logic, that marks\n // the datepicker as closed, async as well.\n setTimeout(completeClose);\n } else {\n completeClose();\n }\n }\n /** Applies the current pending selection on the overlay to the model. */\n _applyPendingSelection() {\n this._componentRef?.instance?._applyPendingSelection();\n }\n /** Forwards relevant values from the datepicker to the datepicker content inside the overlay. */\n _forwardContentValues(instance) {\n instance.datepicker = this;\n instance.color = this.color;\n instance._dialogLabelId = this.datepickerInput.getOverlayLabelId();\n instance._assignActions(this._actionsPortal, false);\n }\n /** Opens the overlay with the calendar. */\n _openOverlay() {\n this._destroyOverlay();\n const isDialog = this.touchUi;\n const portal = new ComponentPortal(MatDatepickerContent, this._viewContainerRef);\n const overlayRef = this._overlayRef = this._overlay.create(new OverlayConfig({\n positionStrategy: isDialog ? this._getDialogStrategy() : this._getDropdownStrategy(),\n hasBackdrop: true,\n backdropClass: [isDialog ? 'cdk-overlay-dark-backdrop' : 'mat-overlay-transparent-backdrop', this._backdropHarnessClass],\n direction: this._dir,\n scrollStrategy: isDialog ? this._overlay.scrollStrategies.block() : this._scrollStrategy(),\n panelClass: `mat-datepicker-${isDialog ? 'dialog' : 'popup'}`\n }));\n this._getCloseStream(overlayRef).subscribe(event => {\n if (event) {\n event.preventDefault();\n }\n this.close();\n });\n // The `preventDefault` call happens inside the calendar as well, however focus moves into\n // it inside a timeout which can give browsers a chance to fire off a keyboard event in-between\n // that can scroll the page (see #24969). Always block default actions of arrow keys for the\n // entire overlay so the page doesn't get scrolled by accident.\n overlayRef.keydownEvents().subscribe(event => {\n const keyCode = event.keyCode;\n if (keyCode === UP_ARROW || keyCode === DOWN_ARROW || keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW || keyCode === PAGE_UP || keyCode === PAGE_DOWN) {\n event.preventDefault();\n }\n });\n this._componentRef = overlayRef.attach(portal);\n this._forwardContentValues(this._componentRef.instance);\n // Update the position once the calendar has rendered. Only relevant in dropdown mode.\n if (!isDialog) {\n this._ngZone.onStable.pipe(take(1)).subscribe(() => overlayRef.updatePosition());\n }\n }\n /** Destroys the current overlay. */\n _destroyOverlay() {\n if (this._overlayRef) {\n this._overlayRef.dispose();\n this._overlayRef = this._componentRef = null;\n }\n }\n /** Gets a position strategy that will open the calendar as a dropdown. */\n _getDialogStrategy() {\n return this._overlay.position().global().centerHorizontally().centerVertically();\n }\n /** Gets a position strategy that will open the calendar as a dropdown. */\n _getDropdownStrategy() {\n const strategy = this._overlay.position().flexibleConnectedTo(this.datepickerInput.getConnectedOverlayOrigin()).withTransformOriginOn('.mat-datepicker-content').withFlexibleDimensions(false).withViewportMargin(8).withLockedPosition();\n return this._setConnectedPositions(strategy);\n }\n /** Sets the positions of the datepicker in dropdown mode based on the current configuration. */\n _setConnectedPositions(strategy) {\n const primaryX = this.xPosition === 'end' ? 'end' : 'start';\n const secondaryX = primaryX === 'start' ? 'end' : 'start';\n const primaryY = this.yPosition === 'above' ? 'bottom' : 'top';\n const secondaryY = primaryY === 'top' ? 'bottom' : 'top';\n return strategy.withPositions([{\n originX: primaryX,\n originY: secondaryY,\n overlayX: primaryX,\n overlayY: primaryY\n }, {\n originX: primaryX,\n originY: primaryY,\n overlayX: primaryX,\n overlayY: secondaryY\n }, {\n originX: secondaryX,\n originY: secondaryY,\n overlayX: secondaryX,\n overlayY: primaryY\n }, {\n originX: secondaryX,\n originY: primaryY,\n overlayX: secondaryX,\n overlayY: secondaryY\n }]);\n }\n /** Gets an observable that will emit when the overlay is supposed to be closed. */\n _getCloseStream(overlayRef) {\n const ctrlShiftMetaModifiers = ['ctrlKey', 'shiftKey', 'metaKey'];\n return merge(overlayRef.backdropClick(), overlayRef.detachments(), overlayRef.keydownEvents().pipe(filter(event => {\n // Closing on alt + up is only valid when there's an input associated with the datepicker.\n return event.keyCode === ESCAPE && !hasModifierKey(event) || this.datepickerInput && hasModifierKey(event, 'altKey') && event.keyCode === UP_ARROW && ctrlShiftMetaModifiers.every(modifier => !hasModifierKey(event, modifier));\n })));\n }\n static {\n this.ɵfac = function MatDatepickerBase_Factory(t) {\n return new (t || MatDatepickerBase)(i0.ɵɵdirectiveInject(i4.Overlay), i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(MAT_DATEPICKER_SCROLL_STRATEGY), i0.ɵɵdirectiveInject(i1.DateAdapter, 8), i0.ɵɵdirectiveInject(i2.Directionality, 8), i0.ɵɵdirectiveInject(MatDateSelectionModel));\n };\n }\n static {\n this.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatDatepickerBase,\n inputs: {\n calendarHeaderComponent: \"calendarHeaderComponent\",\n startAt: \"startAt\",\n startView: \"startView\",\n color: \"color\",\n touchUi: [i0.ɵɵInputFlags.HasDecoratorInputTransform, \"touchUi\", \"touchUi\", booleanAttribute],\n disabled: [i0.ɵɵInputFlags.HasDecoratorInputTransform, \"disabled\", \"disabled\", booleanAttribute],\n xPosition: \"xPosition\",\n yPosition: \"yPosition\",\n restoreFocus: [i0.ɵɵInputFlags.HasDecoratorInputTransform, \"restoreFocus\", \"restoreFocus\", booleanAttribute],\n dateClass: \"dateClass\",\n panelClass: \"panelClass\",\n opened: [i0.ɵɵInputFlags.HasDecoratorInputTransform, \"opened\", \"opened\", booleanAttribute]\n },\n outputs: {\n yearSelected: \"yearSelected\",\n monthSelected: \"monthSelected\",\n viewChanged: \"viewChanged\",\n openedStream: \"opened\",\n closedStream: \"closed\"\n },\n features: [i0.ɵɵInputTransformsFeature, i0.ɵɵNgOnChangesFeature]\n });\n }\n }\n return MatDatepickerBase;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n// TODO(mmalerba): We use a component instead of a directive here so the user can use implicit\n// template reference variables (e.g. #d vs #d=\"matDatepicker\"). We can change this to a directive\n// if angular adds support for `exportAs: '$implicit'` on directives.\n/** Component responsible for managing the datepicker popup/dialog. */\nlet MatDatepicker = /*#__PURE__*/(() => {\n class MatDatepicker extends MatDatepickerBase {\n static {\n this.ɵfac = /* @__PURE__ */(() => {\n let ɵMatDatepicker_BaseFactory;\n return function MatDatepicker_Factory(t) {\n return (ɵMatDatepicker_BaseFactory || (ɵMatDatepicker_BaseFactory = i0.ɵɵgetInheritedFactory(MatDatepicker)))(t || MatDatepicker);\n };\n })();\n }\n static {\n this.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatDatepicker,\n selectors: [[\"mat-datepicker\"]],\n exportAs: [\"matDatepicker\"],\n standalone: true,\n features: [i0.ɵɵProvidersFeature([MAT_SINGLE_DATE_SELECTION_MODEL_PROVIDER, {\n provide: MatDatepickerBase,\n useExisting: MatDatepicker\n }]), i0.ɵɵInheritDefinitionFeature, i0.ɵɵStandaloneFeature],\n decls: 0,\n vars: 0,\n template: function MatDatepicker_Template(rf, ctx) {},\n encapsulation: 2,\n changeDetection: 0\n });\n }\n }\n return MatDatepicker;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * An event used for datepicker input and change events. We don't always have access to a native\n * input or change event because the event may have been triggered by the user clicking on the\n * calendar popup. For consistency, we always use MatDatepickerInputEvent instead.\n */\nclass MatDatepickerInputEvent {\n constructor( /** Reference to the datepicker input component that emitted the event. */\n target, /** Reference to the native input element associated with the datepicker input. */\n targetElement) {\n this.target = target;\n this.targetElement = targetElement;\n this.value = this.target.value;\n }\n}\n/** Base class for datepicker inputs. */\nlet MatDatepickerInputBase = /*#__PURE__*/(() => {\n class MatDatepickerInputBase {\n /** The value of the input. */\n get value() {\n return this._model ? this._getValueFromModel(this._model.selection) : this._pendingValue;\n }\n set value(value) {\n this._assignValueProgrammatically(value);\n }\n /** Whether the datepicker-input is disabled. */\n get disabled() {\n return !!this._disabled || this._parentDisabled();\n }\n set disabled(value) {\n const newValue = value;\n const element = this._elementRef.nativeElement;\n if (this._disabled !== newValue) {\n this._disabled = newValue;\n this.stateChanges.next(undefined);\n }\n // We need to null check the `blur` method, because it's undefined during SSR.\n // In Ivy static bindings are invoked earlier, before the element is attached to the DOM.\n // This can cause an error to be thrown in some browsers (IE/Edge) which assert that the\n // element has been inserted.\n if (newValue && this._isInitialized && element.blur) {\n // Normally, native input elements automatically blur if they turn disabled. This behavior\n // is problematic, because it would mean that it triggers another change detection cycle,\n // which then causes a changed after checked error if the input element was focused before.\n element.blur();\n }\n }\n /** Gets the base validator functions. */\n _getValidators() {\n return [this._parseValidator, this._minValidator, this._maxValidator, this._filterValidator];\n }\n /** Registers a date selection model with the input. */\n _registerModel(model) {\n this._model = model;\n this._valueChangesSubscription.unsubscribe();\n if (this._pendingValue) {\n this._assignValue(this._pendingValue);\n }\n this._valueChangesSubscription = this._model.selectionChanged.subscribe(event => {\n if (this._shouldHandleChangeEvent(event)) {\n const value = this._getValueFromModel(event.selection);\n this._lastValueValid = this._isValidValue(value);\n this._cvaOnChange(value);\n this._onTouched();\n this._formatValue(value);\n this.dateInput.emit(new MatDatepickerInputEvent(this, this._elementRef.nativeElement));\n this.dateChange.emit(new MatDatepickerInputEvent(this, this._elementRef.nativeElement));\n }\n });\n }\n constructor(_elementRef, _dateAdapter, _dateFormats) {\n this._elementRef = _elementRef;\n this._dateAdapter = _dateAdapter;\n this._dateFormats = _dateFormats;\n /** Emits when a `change` event is fired on this ``. */\n this.dateChange = new EventEmitter();\n /** Emits when an `input` event is fired on this ``. */\n this.dateInput = new EventEmitter();\n /** Emits when the internal state has changed */\n this.stateChanges = new Subject();\n this._onTouched = () => {};\n this._validatorOnChange = () => {};\n this._cvaOnChange = () => {};\n this._valueChangesSubscription = Subscription.EMPTY;\n this._localeSubscription = Subscription.EMPTY;\n /** The form control validator for whether the input parses. */\n this._parseValidator = () => {\n return this._lastValueValid ? null : {\n 'matDatepickerParse': {\n 'text': this._elementRef.nativeElement.value\n }\n };\n };\n /** The form control validator for the date filter. */\n this._filterValidator = control => {\n const controlValue = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(control.value));\n return !controlValue || this._matchesFilter(controlValue) ? null : {\n 'matDatepickerFilter': true\n };\n };\n /** The form control validator for the min date. */\n this._minValidator = control => {\n const controlValue = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(control.value));\n const min = this._getMinDate();\n return !min || !controlValue || this._dateAdapter.compareDate(min, controlValue) <= 0 ? null : {\n 'matDatepickerMin': {\n 'min': min,\n 'actual': controlValue\n }\n };\n };\n /** The form control validator for the max date. */\n this._maxValidator = control => {\n const controlValue = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(control.value));\n const max = this._getMaxDate();\n return !max || !controlValue || this._dateAdapter.compareDate(max, controlValue) >= 0 ? null : {\n 'matDatepickerMax': {\n 'max': max,\n 'actual': controlValue\n }\n };\n };\n /** Whether the last value set on the input was valid. */\n this._lastValueValid = false;\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (!this._dateAdapter) {\n throw createMissingDateImplError('DateAdapter');\n }\n if (!this._dateFormats) {\n throw createMissingDateImplError('MAT_DATE_FORMATS');\n }\n }\n // Update the displayed date when the locale changes.\n this._localeSubscription = _dateAdapter.localeChanges.subscribe(() => {\n this._assignValueProgrammatically(this.value);\n });\n }\n ngAfterViewInit() {\n this._isInitialized = true;\n }\n ngOnChanges(changes) {\n if (dateInputsHaveChanged(changes, this._dateAdapter)) {\n this.stateChanges.next(undefined);\n }\n }\n ngOnDestroy() {\n this._valueChangesSubscription.unsubscribe();\n this._localeSubscription.unsubscribe();\n this.stateChanges.complete();\n }\n /** @docs-private */\n registerOnValidatorChange(fn) {\n this._validatorOnChange = fn;\n }\n /** @docs-private */\n validate(c) {\n return this._validator ? this._validator(c) : null;\n }\n // Implemented as part of ControlValueAccessor.\n writeValue(value) {\n this._assignValueProgrammatically(value);\n }\n // Implemented as part of ControlValueAccessor.\n registerOnChange(fn) {\n this._cvaOnChange = fn;\n }\n // Implemented as part of ControlValueAccessor.\n registerOnTouched(fn) {\n this._onTouched = fn;\n }\n // Implemented as part of ControlValueAccessor.\n setDisabledState(isDisabled) {\n this.disabled = isDisabled;\n }\n _onKeydown(event) {\n const ctrlShiftMetaModifiers = ['ctrlKey', 'shiftKey', 'metaKey'];\n const isAltDownArrow = hasModifierKey(event, 'altKey') && event.keyCode === DOWN_ARROW && ctrlShiftMetaModifiers.every(modifier => !hasModifierKey(event, modifier));\n if (isAltDownArrow && !this._elementRef.nativeElement.readOnly) {\n this._openPopup();\n event.preventDefault();\n }\n }\n _onInput(value) {\n const lastValueWasValid = this._lastValueValid;\n let date = this._dateAdapter.parse(value, this._dateFormats.parse.dateInput);\n this._lastValueValid = this._isValidValue(date);\n date = this._dateAdapter.getValidDateOrNull(date);\n const hasChanged = !this._dateAdapter.sameDate(date, this.value);\n // We need to fire the CVA change event for all\n // nulls, otherwise the validators won't run.\n if (!date || hasChanged) {\n this._cvaOnChange(date);\n } else {\n // Call the CVA change handler for invalid values\n // since this is what marks the control as dirty.\n if (value && !this.value) {\n this._cvaOnChange(date);\n }\n if (lastValueWasValid !== this._lastValueValid) {\n this._validatorOnChange();\n }\n }\n if (hasChanged) {\n this._assignValue(date);\n this.dateInput.emit(new MatDatepickerInputEvent(this, this._elementRef.nativeElement));\n }\n }\n _onChange() {\n this.dateChange.emit(new MatDatepickerInputEvent(this, this._elementRef.nativeElement));\n }\n /** Handles blur events on the input. */\n _onBlur() {\n // Reformat the input only if we have a valid value.\n if (this.value) {\n this._formatValue(this.value);\n }\n this._onTouched();\n }\n /** Formats a value and sets it on the input element. */\n _formatValue(value) {\n this._elementRef.nativeElement.value = value != null ? this._dateAdapter.format(value, this._dateFormats.display.dateInput) : '';\n }\n /** Assigns a value to the model. */\n _assignValue(value) {\n // We may get some incoming values before the model was\n // assigned. Save the value so that we can assign it later.\n if (this._model) {\n this._assignValueToModel(value);\n this._pendingValue = null;\n } else {\n this._pendingValue = value;\n }\n }\n /** Whether a value is considered valid. */\n _isValidValue(value) {\n return !value || this._dateAdapter.isValid(value);\n }\n /**\n * Checks whether a parent control is disabled. This is in place so that it can be overridden\n * by inputs extending this one which can be placed inside of a group that can be disabled.\n */\n _parentDisabled() {\n return false;\n }\n /** Programmatically assigns a value to the input. */\n _assignValueProgrammatically(value) {\n value = this._dateAdapter.deserialize(value);\n this._lastValueValid = this._isValidValue(value);\n value = this._dateAdapter.getValidDateOrNull(value);\n this._assignValue(value);\n this._formatValue(value);\n }\n /** Gets whether a value matches the current date filter. */\n _matchesFilter(value) {\n const filter = this._getDateFilter();\n return !filter || filter(value);\n }\n static {\n this.ɵfac = function MatDatepickerInputBase_Factory(t) {\n return new (t || MatDatepickerInputBase)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.DateAdapter, 8), i0.ɵɵdirectiveInject(MAT_DATE_FORMATS, 8));\n };\n }\n static {\n this.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatDatepickerInputBase,\n inputs: {\n value: \"value\",\n disabled: [i0.ɵɵInputFlags.HasDecoratorInputTransform, \"disabled\", \"disabled\", booleanAttribute]\n },\n outputs: {\n dateChange: \"dateChange\",\n dateInput: \"dateInput\"\n },\n standalone: true,\n features: [i0.ɵɵInputTransformsFeature, i0.ɵɵNgOnChangesFeature]\n });\n }\n }\n return MatDatepickerInputBase;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Checks whether the `SimpleChanges` object from an `ngOnChanges`\n * callback has any changes, accounting for date objects.\n */\nfunction dateInputsHaveChanged(changes, adapter) {\n const keys = Object.keys(changes);\n for (let key of keys) {\n const {\n previousValue,\n currentValue\n } = changes[key];\n if (adapter.isDateInstance(previousValue) && adapter.isDateInstance(currentValue)) {\n if (!adapter.sameDate(previousValue, currentValue)) {\n return true;\n }\n } else {\n return true;\n }\n }\n return false;\n}\n\n/** @docs-private */\nconst MAT_DATEPICKER_VALUE_ACCESSOR = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: /*#__PURE__*/forwardRef(() => MatDatepickerInput),\n multi: true\n};\n/** @docs-private */\nconst MAT_DATEPICKER_VALIDATORS = {\n provide: NG_VALIDATORS,\n useExisting: /*#__PURE__*/forwardRef(() => MatDatepickerInput),\n multi: true\n};\n/** Directive used to connect an input to a MatDatepicker. */\nlet MatDatepickerInput = /*#__PURE__*/(() => {\n class MatDatepickerInput extends MatDatepickerInputBase {\n /** The datepicker that this input is associated with. */\n set matDatepicker(datepicker) {\n if (datepicker) {\n this._datepicker = datepicker;\n this._closedSubscription = datepicker.closedStream.subscribe(() => this._onTouched());\n this._registerModel(datepicker.registerInput(this));\n }\n }\n /** The minimum valid date. */\n get min() {\n return this._min;\n }\n set min(value) {\n const validValue = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n if (!this._dateAdapter.sameDate(validValue, this._min)) {\n this._min = validValue;\n this._validatorOnChange();\n }\n }\n /** The maximum valid date. */\n get max() {\n return this._max;\n }\n set max(value) {\n const validValue = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(value));\n if (!this._dateAdapter.sameDate(validValue, this._max)) {\n this._max = validValue;\n this._validatorOnChange();\n }\n }\n /** Function that can be used to filter out dates within the datepicker. */\n get dateFilter() {\n return this._dateFilter;\n }\n set dateFilter(value) {\n const wasMatchingValue = this._matchesFilter(this.value);\n this._dateFilter = value;\n if (this._matchesFilter(this.value) !== wasMatchingValue) {\n this._validatorOnChange();\n }\n }\n constructor(elementRef, dateAdapter, dateFormats, _formField) {\n super(elementRef, dateAdapter, dateFormats);\n this._formField = _formField;\n this._closedSubscription = Subscription.EMPTY;\n this._validator = Validators.compose(super._getValidators());\n }\n /**\n * Gets the element that the datepicker popup should be connected to.\n * @return The element to connect the popup to.\n */\n getConnectedOverlayOrigin() {\n return this._formField ? this._formField.getConnectedOverlayOrigin() : this._elementRef;\n }\n /** Gets the ID of an element that should be used a description for the calendar overlay. */\n getOverlayLabelId() {\n if (this._formField) {\n return this._formField.getLabelId();\n }\n return this._elementRef.nativeElement.getAttribute('aria-labelledby');\n }\n /** Returns the palette used by the input's form field, if any. */\n getThemePalette() {\n return this._formField ? this._formField.color : undefined;\n }\n /** Gets the value at which the calendar should start. */\n getStartValue() {\n return this.value;\n }\n ngOnDestroy() {\n super.ngOnDestroy();\n this._closedSubscription.unsubscribe();\n }\n /** Opens the associated datepicker. */\n _openPopup() {\n if (this._datepicker) {\n this._datepicker.open();\n }\n }\n _getValueFromModel(modelValue) {\n return modelValue;\n }\n _assignValueToModel(value) {\n if (this._model) {\n this._model.updateSelection(value, this);\n }\n }\n /** Gets the input's minimum date. */\n _getMinDate() {\n return this._min;\n }\n /** Gets the input's maximum date. */\n _getMaxDate() {\n return this._max;\n }\n /** Gets the input's date filtering function. */\n _getDateFilter() {\n return this._dateFilter;\n }\n _shouldHandleChangeEvent(event) {\n return event.source !== this;\n }\n static {\n this.ɵfac = function MatDatepickerInput_Factory(t) {\n return new (t || MatDatepickerInput)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.DateAdapter, 8), i0.ɵɵdirectiveInject(MAT_DATE_FORMATS, 8), i0.ɵɵdirectiveInject(MAT_FORM_FIELD, 8));\n };\n }\n static {\n this.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatDatepickerInput,\n selectors: [[\"input\", \"matDatepicker\", \"\"]],\n hostAttrs: [1, \"mat-datepicker-input\"],\n hostVars: 6,\n hostBindings: function MatDatepickerInput_HostBindings(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵlistener(\"input\", function MatDatepickerInput_input_HostBindingHandler($event) {\n return ctx._onInput($event.target.value);\n })(\"change\", function MatDatepickerInput_change_HostBindingHandler() {\n return ctx._onChange();\n })(\"blur\", function MatDatepickerInput_blur_HostBindingHandler() {\n return ctx._onBlur();\n })(\"keydown\", function MatDatepickerInput_keydown_HostBindingHandler($event) {\n return ctx._onKeydown($event);\n });\n }\n if (rf & 2) {\n i0.ɵɵhostProperty(\"disabled\", ctx.disabled);\n i0.ɵɵattribute(\"aria-haspopup\", ctx._datepicker ? \"dialog\" : null)(\"aria-owns\", (ctx._datepicker == null ? null : ctx._datepicker.opened) && ctx._datepicker.id || null)(\"min\", ctx.min ? ctx._dateAdapter.toIso8601(ctx.min) : null)(\"max\", ctx.max ? ctx._dateAdapter.toIso8601(ctx.max) : null)(\"data-mat-calendar\", ctx._datepicker ? ctx._datepicker.id : null);\n }\n },\n inputs: {\n matDatepicker: \"matDatepicker\",\n min: \"min\",\n max: \"max\",\n dateFilter: [i0.ɵɵInputFlags.None, \"matDatepickerFilter\", \"dateFilter\"]\n },\n exportAs: [\"matDatepickerInput\"],\n standalone: true,\n features: [i0.ɵɵProvidersFeature([MAT_DATEPICKER_VALUE_ACCESSOR, MAT_DATEPICKER_VALIDATORS, {\n provide: MAT_INPUT_VALUE_ACCESSOR,\n useExisting: MatDatepickerInput\n }]), i0.ɵɵInheritDefinitionFeature]\n });\n }\n }\n return MatDatepickerInput;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/** Can be used to override the icon of a `matDatepickerToggle`. */\nlet MatDatepickerToggleIcon = /*#__PURE__*/(() => {\n class MatDatepickerToggleIcon {\n static {\n this.ɵfac = function MatDatepickerToggleIcon_Factory(t) {\n return new (t || MatDatepickerToggleIcon)();\n };\n }\n static {\n this.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatDatepickerToggleIcon,\n selectors: [[\"\", \"matDatepickerToggleIcon\", \"\"]],\n standalone: true\n });\n }\n }\n return MatDatepickerToggleIcon;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nlet MatDatepickerToggle = /*#__PURE__*/(() => {\n class MatDatepickerToggle {\n /** Whether the toggle button is disabled. */\n get disabled() {\n if (this._disabled === undefined && this.datepicker) {\n return this.datepicker.disabled;\n }\n return !!this._disabled;\n }\n set disabled(value) {\n this._disabled = value;\n }\n constructor(_intl, _changeDetectorRef, defaultTabIndex) {\n this._intl = _intl;\n this._changeDetectorRef = _changeDetectorRef;\n this._stateChanges = Subscription.EMPTY;\n const parsedTabIndex = Number(defaultTabIndex);\n this.tabIndex = parsedTabIndex || parsedTabIndex === 0 ? parsedTabIndex : null;\n }\n ngOnChanges(changes) {\n if (changes['datepicker']) {\n this._watchStateChanges();\n }\n }\n ngOnDestroy() {\n this._stateChanges.unsubscribe();\n }\n ngAfterContentInit() {\n this._watchStateChanges();\n }\n _open(event) {\n if (this.datepicker && !this.disabled) {\n this.datepicker.open();\n event.stopPropagation();\n }\n }\n _watchStateChanges() {\n const datepickerStateChanged = this.datepicker ? this.datepicker.stateChanges : of();\n const inputStateChanged = this.datepicker && this.datepicker.datepickerInput ? this.datepicker.datepickerInput.stateChanges : of();\n const datepickerToggled = this.datepicker ? merge(this.datepicker.openedStream, this.datepicker.closedStream) : of();\n this._stateChanges.unsubscribe();\n this._stateChanges = merge(this._intl.changes, datepickerStateChanged, inputStateChanged, datepickerToggled).subscribe(() => this._changeDetectorRef.markForCheck());\n }\n static {\n this.ɵfac = function MatDatepickerToggle_Factory(t) {\n return new (t || MatDatepickerToggle)(i0.ɵɵdirectiveInject(MatDatepickerIntl), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵinjectAttribute('tabindex'));\n };\n }\n static {\n this.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatDatepickerToggle,\n selectors: [[\"mat-datepicker-toggle\"]],\n contentQueries: function MatDatepickerToggle_ContentQueries(rf, ctx, dirIndex) {\n if (rf & 1) {\n i0.ɵɵcontentQuery(dirIndex, MatDatepickerToggleIcon, 5);\n }\n if (rf & 2) {\n let _t;\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx._customIcon = _t.first);\n }\n },\n viewQuery: function MatDatepickerToggle_Query(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵviewQuery(_c2, 5);\n }\n if (rf & 2) {\n let _t;\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx._button = _t.first);\n }\n },\n hostAttrs: [1, \"mat-datepicker-toggle\"],\n hostVars: 8,\n hostBindings: function MatDatepickerToggle_HostBindings(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵlistener(\"click\", function MatDatepickerToggle_click_HostBindingHandler($event) {\n return ctx._open($event);\n });\n }\n if (rf & 2) {\n i0.ɵɵattribute(\"tabindex\", null)(\"data-mat-calendar\", ctx.datepicker ? ctx.datepicker.id : null);\n i0.ɵɵclassProp(\"mat-datepicker-toggle-active\", ctx.datepicker && ctx.datepicker.opened)(\"mat-accent\", ctx.datepicker && ctx.datepicker.color === \"accent\")(\"mat-warn\", ctx.datepicker && ctx.datepicker.color === \"warn\");\n }\n },\n inputs: {\n datepicker: [i0.ɵɵInputFlags.None, \"for\", \"datepicker\"],\n tabIndex: \"tabIndex\",\n ariaLabel: [i0.ɵɵInputFlags.None, \"aria-label\", \"ariaLabel\"],\n disabled: [i0.ɵɵInputFlags.HasDecoratorInputTransform, \"disabled\", \"disabled\", booleanAttribute],\n disableRipple: \"disableRipple\"\n },\n exportAs: [\"matDatepickerToggle\"],\n standalone: true,\n features: [i0.ɵɵInputTransformsFeature, i0.ɵɵNgOnChangesFeature, i0.ɵɵStandaloneFeature],\n ngContentSelectors: _c4,\n decls: 4,\n vars: 6,\n consts: [[\"button\", \"\"], [\"mat-icon-button\", \"\", \"type\", \"button\", 3, \"disabled\", \"disableRipple\"], [\"viewBox\", \"0 0 24 24\", \"width\", \"24px\", \"height\", \"24px\", \"fill\", \"currentColor\", \"focusable\", \"false\", \"aria-hidden\", \"true\", 1, \"mat-datepicker-toggle-default-icon\"], [\"d\", \"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z\"]],\n template: function MatDatepickerToggle_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵprojectionDef(_c3);\n i0.ɵɵelementStart(0, \"button\", 1, 0);\n i0.ɵɵtemplate(2, MatDatepickerToggle_Conditional_2_Template, 2, 0, \":svg:svg\", 2);\n i0.ɵɵprojection(3);\n i0.ɵɵelementEnd();\n }\n if (rf & 2) {\n i0.ɵɵproperty(\"disabled\", ctx.disabled)(\"disableRipple\", ctx.disableRipple);\n i0.ɵɵattribute(\"aria-haspopup\", ctx.datepicker ? \"dialog\" : null)(\"aria-label\", ctx.ariaLabel || ctx._intl.openCalendarLabel)(\"tabindex\", ctx.disabled ? -1 : ctx.tabIndex);\n i0.ɵɵadvance(2);\n i0.ɵɵconditional(2, !ctx._customIcon ? 2 : -1);\n }\n },\n dependencies: [MatIconButton],\n styles: [\".mat-datepicker-toggle{pointer-events:auto;color:var(--mat-datepicker-toggle-icon-color)}.mat-datepicker-toggle-active{color:var(--mat-datepicker-toggle-active-state-icon-color)}.cdk-high-contrast-active .mat-datepicker-toggle-default-icon{color:CanvasText}\"],\n encapsulation: 2,\n changeDetection: 0\n });\n }\n }\n return MatDatepickerToggle;\n})();\n/*#__PURE__*/(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n// This file contains the `_computeAriaAccessibleName` function, which computes what the *expected*\n// ARIA accessible name would be for a given element. Implements a subset of ARIA specification\n// [Accessible Name and Description Computation 1.2](https://www.w3.org/TR/accname-1.2/).\n//\n// Specification accname-1.2 can be summarized by returning the result of the first method\n// available.\n//\n// 1. `aria-labelledby` attribute\n// ```\n// \n// \n// \n// ```\n// 2. `aria-label` attribute (e.g. ``)\n// 3. Label with `for`/`id`\n// ```\n// \n// \n// \n// ```\n// 4. `placeholder` attribute (e.g. ``)\n// 5. `title` attribute (e.g. ``)\n// 6. text content\n// ```\n// \n// \n// \n// ```\n/**\n * Computes the *expected* ARIA accessible name for argument element based on [accname-1.2\n * specification](https://www.w3.org/TR/accname-1.2/). Implements a subset of accname-1.2,\n * and should only be used for the Datepicker's specific use case.\n *\n * Intended use:\n * This is not a general use implementation. Only implements the parts of accname-1.2 that are\n * required for the Datepicker's specific use case. This function is not intended for any other\n * use.\n *\n * Limitations:\n * - Only covers the needs of `matStartDate` and `matEndDate`. Does not support other use cases.\n * - See NOTES's in implementation for specific details on what parts of the accname-1.2\n * specification are not implemented.\n *\n * @param element {HTMLInputElement} native <input/> element of `matStartDate` or\n * `matEndDate` component. Corresponds to the 'Root Element' from accname-1.2\n *\n * @return expected ARIA accessible name of argument <input/>\n */\nfunction _computeAriaAccessibleName(element) {\n return _computeAriaAccessibleNameInternal(element, true);\n}\n/**\n * Determine if argument node is an Element based on `nodeType` property. This function is safe to\n * use with server-side rendering.\n */\nfunction ssrSafeIsElement(node) {\n return node.nodeType === Node.ELEMENT_NODE;\n}\n/**\n * Determine if argument node is an HTMLInputElement based on `nodeName` property. This funciton is\n * safe to use with server-side rendering.\n */\nfunction ssrSafeIsHTMLInputElement(node) {\n return node.nodeName === 'INPUT';\n}\n/**\n * Determine if argument node is an HTMLTextAreaElement based on `nodeName` property. This\n * funciton is safe to use with server-side rendering.\n */\nfunction ssrSafeIsHTMLTextAreaElement(node) {\n return node.nodeName === 'TEXTAREA';\n}\n/**\n * Calculate the expected ARIA accessible name for given DOM Node. Given DOM Node may be either the\n * \"Root node\" passed to `_computeAriaAccessibleName` or \"Current node\" as result of recursion.\n *\n * @return the accessible name of argument DOM Node\n *\n * @param currentNode node to determine accessible name of\n * @param isDirectlyReferenced true if `currentNode` is the root node to calculate ARIA accessible\n * name of. False if it is a result of recursion.\n */\nfunction _computeAriaAccessibleNameInternal(currentNode, isDirectlyReferenced) {\n // NOTE: this differs from accname-1.2 specification.\n // - Does not implement Step 1. of accname-1.2: '''If `currentNode`'s role prohibits naming,\n // return the empty string (\"\")'''.\n // - Does not implement Step 2.A. of accname-1.2: '''if current node is hidden and not directly\n // referenced by aria-labelledby... return the empty string.'''\n // acc-name-1.2 Step 2.B.: aria-labelledby\n if (ssrSafeIsElement(currentNode) && isDirectlyReferenced) {\n const labelledbyIds = currentNode.getAttribute?.('aria-labelledby')?.split(/\\s+/g) || [];\n const validIdRefs = labelledbyIds.reduce((validIds, id) => {\n const elem = document.getElementById(id);\n if (elem) {\n validIds.push(elem);\n }\n return validIds;\n }, []);\n if (validIdRefs.length) {\n return validIdRefs.map(idRef => {\n return _computeAriaAccessibleNameInternal(idRef, false);\n }).join(' ');\n }\n }\n // acc-name-1.2 Step 2.C.: aria-label\n if (ssrSafeIsElement(currentNode)) {\n const ariaLabel = currentNode.getAttribute('aria-label')?.trim();\n if (ariaLabel) {\n return ariaLabel;\n }\n }\n // acc-name-1.2 Step 2.D. attribute or element that defines a text alternative\n //\n // NOTE: this differs from accname-1.2 specification.\n // Only implements Step 2.D. for `