UNPKG

@dhutaryan/ngx-mat-timepicker

Version:

Angular timepicker to add time which is based on material design and Angular material.

2,813 lines 182 kB
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, Directive, Component, ViewEncapsulation, ChangeDetectionStrategy, Attribute, Input, ContentChild, EventEmitter, Inject, Output, inject, LOCALE_ID, Optional, NgModule, HostListener, SkipSelf, ViewChild, booleanAttribute, forwardRef, TemplateRef, signal } from '@angular/core';
import * as i1$1 from '@angular/cdk/overlay';
import { Overlay, FlexibleConnectedPositionStrategy, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
import * as i3$1 from '@angular/cdk/portal';
import { PortalModule, ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
import { CdkScrollableModule } from '@angular/cdk/scrolling';
import * as i4$1 from '@angular/cdk/a11y';
import { A11yModule } from '@angular/cdk/a11y';
import * as i2 from '@angular/material/button';
import { MatButtonModule, MAT_FAB_DEFAULT_OPTIONS } from '@angular/material/button';
import * as i1 from '@angular/common';
import { CommonModule, DOCUMENT } from '@angular/common';
import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
import { Subject, Subscription, of, merge, fromEvent, debounceTime, take, BehaviorSubject, first, filter } from 'rxjs';
import { PlatformModule, _getFocusedElementPierceShadowDom } from '@angular/cdk/platform';
import { DOWN_ARROW, UP_ARROW, PAGE_UP, PAGE_DOWN, ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';
import { trigger, transition, animate, keyframes, style, state } from '@angular/animations';
import * as i2$1 from '@angular/material/divider';
import { MatDividerModule } from '@angular/material/divider';
import * as i3 from '@angular/material/core';
import { MatRippleModule } from '@angular/material/core';
import * as i4 from '@angular/material/form-field';
import { MatFormFieldModule, MAT_FORM_FIELD } from '@angular/material/form-field';
import * as i5 from '@angular/material/input';
import { MatInputModule, MAT_INPUT_VALUE_ACCESSOR } from '@angular/material/input';
import { NG_VALUE_ACCESSOR, NG_VALIDATORS, Validators } from '@angular/forms';

/** Injection token that determines the scroll handling while the timepicker is open. */
const MAT_TIMEPICKER_SCROLL_STRATEGY = new InjectionToken('mat-timepicker-scroll-strategy');
/** Timepicker scroll strategy factory. */
function MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY(overlay) {
    return () => overlay.scrollStrategies.reposition();
}
/** Timepicker scroll strategy provider. */
const MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER = {
    provide: MAT_TIMEPICKER_SCROLL_STRATEGY,
    deps: [Overlay],
    useFactory: MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY,
};

class MatTimepickerIntl {
    constructor() {
        /**
         * Stream that emits whenever the labels here are changed. Use this to notify
         * components if the labels have changed after initialization.
         */
        this.changes = new Subject();
        /** A label for inputs title. */
        this.inputsTitle = 'Enter time';
        /** A label for dials title. */
        this.dialsTitle = 'Select time';
        /** A label for hour input hint. */
        this.hourInputHint = 'Hour';
        /** A label for minute input hint. */
        this.minuteInputHint = 'Minute';
        /** Label for the button used to open the timepicker popup (used by screen readers). */
        this.openTimepickerLabel = 'Open timepicker';
        /** Label for the button used to close the timepicker popup (used by screen readers). */
        this.closeTimepickerLabel = 'Close timepicker';
        /** A label for OK button to apply time. */
        this.okButton = 'OK';
        /** A label for cancel button to close timepicker. */
        this.cancelButton = 'Cancel';
        /** A label for am text. */
        this.am = 'AM';
        /** A label for am text. */
        this.pm = 'PM';
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerIntl, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerIntl, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerIntl, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }] });

class MatTimepickerToggleIcon {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerToggleIcon, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerToggleIcon, isStandalone: true, selector: "[matTimepickerToggleIcon]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerToggleIcon, decorators: [{
            type: Directive,
            args: [{ selector: '[matTimepickerToggleIcon]', standalone: true }]
        }] });
class MatTimepickerToggle {
    /** Whether the toggle button is disabled. */
    get disabled() {
        if (this._disabled === undefined && this.timepicker) {
            return this.timepicker.disabled;
        }
        return !!this._disabled;
    }
    set disabled(value) {
        this._disabled = coerceBooleanProperty(value);
    }
    constructor(defaultTabIndex, _intl, _cdr) {
        this._intl = _intl;
        this._cdr = _cdr;
        this._stateChanges = Subscription.EMPTY;
        const parsedTabIndex = Number(defaultTabIndex);
        this.tabIndex =
            parsedTabIndex || parsedTabIndex === 0 ? parsedTabIndex : null;
    }
    ngOnChanges(changes) {
        if (changes['timepicker']) {
            this._watchStateChanges();
        }
    }
    ngOnDestroy() {
        this._stateChanges.unsubscribe();
    }
    /** Opens timepicker. */
    open(event) {
        if (this.timepicker && !this.disabled) {
            this.timepicker.open();
            event.stopPropagation();
        }
    }
    _watchStateChanges() {
        const timepickerStateChanged = this.timepicker
            ? this.timepicker.stateChanges
            : of();
        const inputStateChanged = this.timepicker && this.timepicker.timepickerInput
            ? this.timepicker.timepickerInput.stateChanges
            : of();
        const timepickerToggled = this.timepicker
            ? merge(this.timepicker.openedStream, this.timepicker.closedStream)
            : of();
        this._stateChanges.unsubscribe();
        this._stateChanges = merge(this._intl.changes, timepickerStateChanged, inputStateChanged, timepickerToggled).subscribe(() => this._cdr.markForCheck());
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerToggle, deps: [{ token: 'tabindex', attribute: true }, { token: MatTimepickerIntl }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: MatTimepickerToggle, isStandalone: true, selector: "mat-timepicker-toggle", inputs: { timepicker: ["for", "timepicker"], disabled: "disabled", disableRipple: "disableRipple", tabIndex: "tabIndex", ariaLabel: ["aria-label", "ariaLabel"] }, host: { listeners: { "click": "open($event)" }, properties: { "attr.tabindex": "null", "class.mat-timepicker-toggle-active": "timepicker && timepicker.opened", "class.mat-accent": "timepicker && timepicker.color === \"accent\"", "class.mat-warn": "timepicker && timepicker.color === \"warn\"" }, classAttribute: "mat-timepicker-toggle" }, queries: [{ propertyName: "customIcon", first: true, predicate: MatTimepickerToggleIcon, descendants: true }], exportAs: ["matTimepickerToggle"], usesOnChanges: true, ngImport: i0, template: "<button\n  type=\"button\"\n  #button\n  mat-icon-button\n  [attr.aria-haspopup]=\"timepicker ? 'dialog' : null\"\n  [attr.aria-label]=\"ariaLabel || _intl.openTimepickerLabel\"\n  [attr.tabindex]=\"disabled ? -1 : tabIndex\"\n  [disabled]=\"disabled\"\n  [disableRipple]=\"disableRipple\"\n>\n  @if (!customIcon) {\n    <svg\n      class=\"mat-timepicker-toggle-default-icon\"\n      viewBox=\"0 0 24 24\"\n      width=\"24\"\n      height=\"24\"\n      fill=\"currentColor\"\n      focusable=\"false\"\n    >\n      <path\n        d=\"M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M12,20c-4.41,0-8-3.59-8-8s3.59-8,8-8s8,3.59,8,8 S16.41,20,12,20z M12.5,7H11v6l5.2,3.2l0.8-1.3l-4.5-2.7V7z\"\n      />\n    </svg>\n  }\n\n  <ng-content select=\"[matTimepickerToggleIcon]\"></ng-content>\n</button>\n", styles: [".mat-form-field .mat-form-field-prefix .mat-timepicker-toggle-default-icon,.mat-form-field .mat-form-field-suffix .mat-timepicker-toggle-default-icon{display:block;width:1.5em;height:1.5em}.mat-form-field .mat-form-field-prefix .mat-icon-button .mat-timepicker-toggle-default-icon,.mat-form-field .mat-form-field-suffix .mat-icon-button .mat-timepicker-toggle-default-icon{margin:auto}.mat-timepicker-toggle{color:var(--mat-timepicker-toggle-color, var(--mat-sys-on-surface-variant))}.mat-timepicker-toggle.mat-timepicker-toggle-active button{color:var(--mat-timepicker-toggle-active-color, var(--mat-sys-primary))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerToggle, decorators: [{
            type: Component,
            args: [{ selector: 'mat-timepicker-toggle', standalone: true, imports: [CommonModule, MatButtonModule], exportAs: 'matTimepickerToggle', host: {
                        class: 'mat-timepicker-toggle',
                        '[attr.tabindex]': 'null',
                        '[class.mat-timepicker-toggle-active]': 'timepicker && timepicker.opened',
                        '[class.mat-accent]': 'timepicker && timepicker.color === "accent"',
                        '[class.mat-warn]': 'timepicker && timepicker.color === "warn"',
                        '(click)': 'open($event)',
                    }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n  type=\"button\"\n  #button\n  mat-icon-button\n  [attr.aria-haspopup]=\"timepicker ? 'dialog' : null\"\n  [attr.aria-label]=\"ariaLabel || _intl.openTimepickerLabel\"\n  [attr.tabindex]=\"disabled ? -1 : tabIndex\"\n  [disabled]=\"disabled\"\n  [disableRipple]=\"disableRipple\"\n>\n  @if (!customIcon) {\n    <svg\n      class=\"mat-timepicker-toggle-default-icon\"\n      viewBox=\"0 0 24 24\"\n      width=\"24\"\n      height=\"24\"\n      fill=\"currentColor\"\n      focusable=\"false\"\n    >\n      <path\n        d=\"M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M12,20c-4.41,0-8-3.59-8-8s3.59-8,8-8s8,3.59,8,8 S16.41,20,12,20z M12.5,7H11v6l5.2,3.2l0.8-1.3l-4.5-2.7V7z\"\n      />\n    </svg>\n  }\n\n  <ng-content select=\"[matTimepickerToggleIcon]\"></ng-content>\n</button>\n", styles: [".mat-form-field .mat-form-field-prefix .mat-timepicker-toggle-default-icon,.mat-form-field .mat-form-field-suffix .mat-timepicker-toggle-default-icon{display:block;width:1.5em;height:1.5em}.mat-form-field .mat-form-field-prefix .mat-icon-button .mat-timepicker-toggle-default-icon,.mat-form-field .mat-form-field-suffix .mat-icon-button .mat-timepicker-toggle-default-icon{margin:auto}.mat-timepicker-toggle{color:var(--mat-timepicker-toggle-color, var(--mat-sys-on-surface-variant))}.mat-timepicker-toggle.mat-timepicker-toggle-active button{color:var(--mat-timepicker-toggle-active-color, var(--mat-sys-primary))}\n"] }]
        }], ctorParameters: () => [{ type: undefined, decorators: [{
                    type: Attribute,
                    args: ['tabindex']
                }] }, { type: MatTimepickerIntl }, { type: i0.ChangeDetectorRef }], propDecorators: { timepicker: [{
                type: Input,
                args: ['for']
            }], disabled: [{
                type: Input
            }], disableRipple: [{
                type: Input
            }], tabIndex: [{
                type: Input
            }], customIcon: [{
                type: ContentChild,
                args: [MatTimepickerToggleIcon]
            }], ariaLabel: [{
                type: Input,
                args: ['aria-label']
            }] } });

/** Animations used by the timepicker. */
const matTimepickerAnimations = {
    /** Transforms the height of the timepicker's. */
    transformPanel: trigger('transformPanel', [
        transition('void => enter-dropdown', animate('120ms cubic-bezier(0, 0, 0.2, 1)', keyframes([
            style({ opacity: 0, transform: 'scale(1, 0.8)' }),
            style({ opacity: 1, transform: 'scale(1, 1)' }),
        ]))),
        transition('void => enter-dialog', animate('150ms cubic-bezier(0, 0, 0.2, 1)', keyframes([
            style({ opacity: 0, transform: 'scale(0.7)' }),
            style({ transform: 'none', opacity: 1 }),
        ]))),
        transition('* => void', animate('100ms linear', style({ opacity: 0 }))),
    ]),
    /** Fades in the content of the timepicker. */
    fadeInTimepicker: trigger('fadeInTimepicker', [
        state('void', style({ opacity: 0 })),
        state('enter', style({ opacity: 1 })),
    ]),
};

const TOUCH_UI_MULTIPLIER = 1.25;
const TOUCH_UI_TICK_MULTIPLIER = 1.5;
const CLOCK_RADIUS = 128;
const CLOCK_TICK_RADIUS = 16;
const CLOCK_OUTER_RADIUS = 100;
function getClockRadius(touchUi) {
    return touchUi ? CLOCK_RADIUS * TOUCH_UI_MULTIPLIER : CLOCK_RADIUS;
}
function getClockTickRadius(touchUi) {
    return touchUi
        ? CLOCK_TICK_RADIUS * TOUCH_UI_TICK_MULTIPLIER
        : CLOCK_TICK_RADIUS;
}
function getClockCorrectedRadius(touchUi) {
    return getClockRadius(touchUi) - getClockTickRadius(touchUi);
}
function getClockOuterRadius(touchUi) {
    return touchUi
        ? CLOCK_OUTER_RADIUS * TOUCH_UI_MULTIPLIER
        : CLOCK_OUTER_RADIUS;
}
function getClockInnerRadius(touchUi) {
    return getClockOuterRadius(touchUi) - getClockTickRadius(touchUi) * 2;
}

const ALL_MINUTES = Array(60)
    .fill(null)
    .map((_, i) => i);
class MatMinutesClockDial {
    /** Selected minute. */
    get selectedMinute() {
        return this._selectedMinute;
    }
    set selectedMinute(value) {
        this._selectedMinute = value;
    }
    /** Step over minutes. */
    get interval() {
        return this._interval;
    }
    set interval(value) {
        this._interval = coerceNumberProperty(value) || 1;
    }
    get availableMinutes() {
        return this._availableMinutes;
    }
    set availableMinutes(value) {
        this._availableMinutes = value;
        this._initMinutes();
    }
    /** Whether the timepicker UI is in touch mode. */
    get touchUi() {
        return this._touchUi;
    }
    set touchUi(value) {
        this._touchUi = value;
    }
    get disabled() {
        return !this.availableMinutes.includes(this.selectedMinute);
    }
    get isMinutePoint() {
        return !!this.minutes.find((hour) => hour.value === this.selectedMinute);
    }
    constructor(_element, _cdr, _document) {
        this._element = _element;
        this._cdr = _cdr;
        this._document = _document;
        this._selectedMinute = 0;
        this._interval = 1;
        this._availableMinutes = [];
        /** Emits selected minute. */
        this.selectedChange = new EventEmitter();
        this.minutes = [];
    }
    ngOnInit() {
        this._initMinutes();
    }
    /** Hand styles based on selected minute. */
    _handStyles() {
        const deg = Math.round(this._selectedMinute * (360 / 60));
        const height = getClockOuterRadius(this.touchUi);
        const marginTop = getClockRadius(this.touchUi) - getClockOuterRadius(this.touchUi);
        return {
            transform: `rotate(${deg}deg)`,
            height: `${height}px`,
            'margin-top': `${marginTop}px`,
        };
    }
    /** Handles mouse and touch events on dial and document. */
    _onUserAction(event) {
        if (event.cancelable) {
            event.preventDefault();
        }
        this._setMinute(event);
        const eventsSubscription = merge(fromEvent(this._document, 'mousemove'), fromEvent(this._document, 'touchmove'))
            .pipe(debounceTime(0))
            .subscribe({
            next: (event) => {
                event.preventDefault();
                this._setMinute(event);
            },
        });
        merge(fromEvent(this._document, 'mouseup'), fromEvent(this._document, 'touchend'))
            .pipe(take(1))
            .subscribe({
            next: () => {
                eventsSubscription.unsubscribe();
            },
        });
    }
    _isActiveCell(minute) {
        return this.selectedMinute === minute;
    }
    _setMinute(event) {
        const element = this._element.nativeElement;
        const window = this._getWindow();
        const elementRect = element.getBoundingClientRect();
        const width = element.offsetWidth;
        const height = element.offsetHeight;
        const pageX = event instanceof MouseEvent ? event.pageX : event.touches[0].pageX;
        const pageY = event instanceof MouseEvent ? event.pageY : event.touches[0].pageY;
        const x = width / 2 - (pageX - elementRect.left - window.scrollX);
        const y = height / 2 - (pageY - elementRect.top - window.scrollY);
        const unit = Math.PI / (30 / this.interval);
        const atan2 = Math.atan2(-x, y);
        const radian = atan2 < 0 ? Math.PI * 2 + atan2 : atan2;
        const initialValue = Math.round(radian / unit) * this.interval;
        const value = initialValue === 60 ? 0 : initialValue;
        if (this.availableMinutes.includes(value) && this.availableMinutes.includes(value)) {
            this.selectedMinute = value;
            this.selectedChange.emit(this.selectedMinute);
        }
        this._cdr.detectChanges();
    }
    /** Creates list of minutes. */
    _initMinutes() {
        this.minutes = ALL_MINUTES.filter((minute) => minute % 5 === 0).map((minute) => {
            const radian = (minute / 30) * Math.PI;
            const displayValue = minute === 0 ? '00' : String(minute);
            return {
                value: minute,
                displayValue,
                left: getClockCorrectedRadius(this.touchUi) +
                    Math.sin(radian) * getClockOuterRadius(this.touchUi),
                top: getClockCorrectedRadius(this.touchUi) -
                    Math.cos(radian) * getClockOuterRadius(this.touchUi),
                disabled: !this.availableMinutes.includes(minute),
            };
        });
    }
    /** Use defaultView of injected document if available or fallback to global window reference */
    _getWindow() {
        return this._document.defaultView || window;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatMinutesClockDial, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: MatMinutesClockDial, isStandalone: true, selector: "mat-minutes-clock-dial", inputs: { selectedMinute: "selectedMinute", interval: "interval", availableMinutes: "availableMinutes", color: "color", touchUi: "touchUi" }, outputs: { selectedChange: "selectedChange" }, host: { listeners: { "mousedown": "_onUserAction($event)", "touchstart": "_onUserAction($event)" }, classAttribute: "mat-clock-dial mat-clock-dial-minutes" }, exportAs: ["matMinutesClockDial"], ngImport: i0, template: "<div\n  class=\"mat-clock-dial-hand\"\n  [class.mat-clock-dial-hand-pointless]=\"isMinutePoint\"\n  [class.mat-clock-dial-hand-disabled]=\"disabled\"\n  [ngStyle]=\"_handStyles()\"\n>\n  <div class=\"mat-clock-dial-hand-point\" tabindex=\"0\"></div>\n</div>\n@for (minute of minutes; track minute.value) {\n  <button\n    class=\"mat-clock-dial-cell\"\n    mat-mini-fab\n    disableRipple\n    [tabIndex]=\"_isActiveCell(minute.value) ? 0 : -1\"\n    [style.left.px]=\"minute.left\"\n    [style.top.px]=\"minute.top\"\n    [class.mat-clock-dial-cell-active]=\"_isActiveCell(minute.value)\"\n    [class.mat-clock-dial-cell-disabled]=\"minute.disabled\"\n    [color]=\"_isActiveCell(minute.value) ? color : undefined\"\n    [attr.aria-disabled]=\"minute.disabled || null\"\n  >\n    {{ minute.displayValue }}\n  </button>\n}\n", styles: [".mat-clock-dial{position:relative;display:block;width:16rem;height:16rem;margin:0 auto;border-radius:50%;background-color:var(--mat-timepicker-clock-dial-background-color, var(--mat-sys-surface-container-highest))}.mat-clock-dial:before{position:absolute;top:50%;left:50%;width:.4375rem;height:.4375rem;border-radius:50%;transform:translate(-50%,-50%);content:\"\";background-color:var(--mat-timepicker-clock-dial-center-point-color, var(--mat-sys-primary))}[mat-mini-fab].mat-clock-dial-cell{position:absolute;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:50%;box-shadow:none}[mat-mini-fab].mat-clock-dial-cell:disabled{pointer-events:none}[mat-mini-fab].mat-clock-dial-cell:focus,[mat-mini-fab].mat-clock-dial-cell:hover,[mat-mini-fab].mat-clock-dial-cell:active,[mat-mini-fab].mat-clock-dial-cell:focus:active{box-shadow:none}[mat-mini-fab].mat-clock-dial-cell.mat-clock-dial-cell-disabled.mat-clock-dial-cell-active{background-color:var(--mat-timepicker-clock-dial-cell-active-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent));color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary))}.mat-clock-dial-cell:not(.mat-primary):not(.mat-accent):not(.mat-warn){background:var(--mat-timepicker-clock-dial-cell-unthemable-color, transparent)}.mat-clock-dial-cell.mat-clock-dial-cell-active{color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary));background-color:var(--mat-timepicker-clock-dial-cell-active-background-color, var(--mat-sys-primary))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled{color:var(--mat-timepicker-clock-dial-cell-disabled-text-color, color-mix(in srgb, var(--mat-sys-on-surface) 40%, transparent))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled .mat-mdc-button-persistent-ripple:before{background-color:var(--mat-timepicker-clock-dial-cell-disabled-background-color, transparent)}.mat-timepicker-content-touch .mat-clock-dial{width:20rem;height:20rem}.mat-timepicker-content-touch [mat-mini-fab].mat-clock-dial-cell{width:3rem;height:3rem;font-size:1.125rem}.mat-clock-dial-hand{position:absolute;inset:0;width:1px;margin:0 auto;transform-origin:bottom}.mat-clock-dial-hand:before{position:absolute;top:-.25rem;left:-.25rem;width:calc(.5rem + 1px);height:calc(.5rem + 1px);border-radius:50%;content:\"\"}.mat-clock-dial-hand.mat-clock-dial-hand-disabled{background-color:var(--mat-timepicker-clock-dial-hand-disabled-color, transparent)}.mat-clock-dial-hand.mat-clock-dial-hand-disabled:before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled){background-color:var(--mat-timepicker-clock-dial-hand-color, var(--mat-sys-primary))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled):before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-color, var(--mat-sys-primary))}.mat-clock-dial-hand.mat-clock-dial-hand-pointless:before{content:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab]", exportAs: ["matButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatMinutesClockDial, decorators: [{
            type: Component,
            args: [{ selector: 'mat-minutes-clock-dial', standalone: true, imports: [CommonModule, MatButtonModule], exportAs: 'matMinutesClockDial', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        class: 'mat-clock-dial mat-clock-dial-minutes',
                        '(mousedown)': '_onUserAction($event)',
                        '(touchstart)': '_onUserAction($event)',
                    }, template: "<div\n  class=\"mat-clock-dial-hand\"\n  [class.mat-clock-dial-hand-pointless]=\"isMinutePoint\"\n  [class.mat-clock-dial-hand-disabled]=\"disabled\"\n  [ngStyle]=\"_handStyles()\"\n>\n  <div class=\"mat-clock-dial-hand-point\" tabindex=\"0\"></div>\n</div>\n@for (minute of minutes; track minute.value) {\n  <button\n    class=\"mat-clock-dial-cell\"\n    mat-mini-fab\n    disableRipple\n    [tabIndex]=\"_isActiveCell(minute.value) ? 0 : -1\"\n    [style.left.px]=\"minute.left\"\n    [style.top.px]=\"minute.top\"\n    [class.mat-clock-dial-cell-active]=\"_isActiveCell(minute.value)\"\n    [class.mat-clock-dial-cell-disabled]=\"minute.disabled\"\n    [color]=\"_isActiveCell(minute.value) ? color : undefined\"\n    [attr.aria-disabled]=\"minute.disabled || null\"\n  >\n    {{ minute.displayValue }}\n  </button>\n}\n", styles: [".mat-clock-dial{position:relative;display:block;width:16rem;height:16rem;margin:0 auto;border-radius:50%;background-color:var(--mat-timepicker-clock-dial-background-color, var(--mat-sys-surface-container-highest))}.mat-clock-dial:before{position:absolute;top:50%;left:50%;width:.4375rem;height:.4375rem;border-radius:50%;transform:translate(-50%,-50%);content:\"\";background-color:var(--mat-timepicker-clock-dial-center-point-color, var(--mat-sys-primary))}[mat-mini-fab].mat-clock-dial-cell{position:absolute;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:50%;box-shadow:none}[mat-mini-fab].mat-clock-dial-cell:disabled{pointer-events:none}[mat-mini-fab].mat-clock-dial-cell:focus,[mat-mini-fab].mat-clock-dial-cell:hover,[mat-mini-fab].mat-clock-dial-cell:active,[mat-mini-fab].mat-clock-dial-cell:focus:active{box-shadow:none}[mat-mini-fab].mat-clock-dial-cell.mat-clock-dial-cell-disabled.mat-clock-dial-cell-active{background-color:var(--mat-timepicker-clock-dial-cell-active-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent));color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary))}.mat-clock-dial-cell:not(.mat-primary):not(.mat-accent):not(.mat-warn){background:var(--mat-timepicker-clock-dial-cell-unthemable-color, transparent)}.mat-clock-dial-cell.mat-clock-dial-cell-active{color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary));background-color:var(--mat-timepicker-clock-dial-cell-active-background-color, var(--mat-sys-primary))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled{color:var(--mat-timepicker-clock-dial-cell-disabled-text-color, color-mix(in srgb, var(--mat-sys-on-surface) 40%, transparent))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled .mat-mdc-button-persistent-ripple:before{background-color:var(--mat-timepicker-clock-dial-cell-disabled-background-color, transparent)}.mat-timepicker-content-touch .mat-clock-dial{width:20rem;height:20rem}.mat-timepicker-content-touch [mat-mini-fab].mat-clock-dial-cell{width:3rem;height:3rem;font-size:1.125rem}.mat-clock-dial-hand{position:absolute;inset:0;width:1px;margin:0 auto;transform-origin:bottom}.mat-clock-dial-hand:before{position:absolute;top:-.25rem;left:-.25rem;width:calc(.5rem + 1px);height:calc(.5rem + 1px);border-radius:50%;content:\"\"}.mat-clock-dial-hand.mat-clock-dial-hand-disabled{background-color:var(--mat-timepicker-clock-dial-hand-disabled-color, transparent)}.mat-clock-dial-hand.mat-clock-dial-hand-disabled:before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled){background-color:var(--mat-timepicker-clock-dial-hand-color, var(--mat-sys-primary))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled):before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-color, var(--mat-sys-primary))}.mat-clock-dial-hand.mat-clock-dial-hand-pointless:before{content:none}\n"] }]
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
                    type: Inject,
                    args: [DOCUMENT]
                }] }], propDecorators: { selectedMinute: [{
                type: Input
            }], interval: [{
                type: Input
            }], availableMinutes: [{
                type: Input
            }], color: [{
                type: Input
            }], touchUi: [{
                type: Input
            }], selectedChange: [{
                type: Output
            }] } });

const ALL_HOURS = Array(24)
    .fill(null)
    .map((_, i) => i);
class MatHoursClockDial {
    /** Selected hour. */
    get selectedHour() {
        return this._selectedHour;
    }
    set selectedHour(value) {
        this._selectedHour = value;
    }
    /** Whether the clock uses 12 hour format. */
    get isMeridiem() {
        return this._isMeridiem;
    }
    set isMeridiem(value) {
        this._isMeridiem = value;
    }
    get availableHours() {
        return this._availableHours;
    }
    set availableHours(value) {
        this._availableHours = value;
        this._initHours();
    }
    /** Whether the timepicker UI is in touch mode. */
    get touchUi() {
        return this._touchUi;
    }
    set touchUi(value) {
        this._touchUi = value;
        this._initHours();
    }
    get disabledHand() {
        return !this.availableHours.includes(this.selectedHour);
    }
    get isHour() {
        return !!this.hours.find((hour) => hour.value === this.selectedHour);
    }
    constructor(_element, _cdr, _document) {
        this._element = _element;
        this._cdr = _cdr;
        this._document = _document;
        this._availableHours = [];
        /** Emits selected hour. */
        this.selectedChange = new EventEmitter();
        this.hours = [];
    }
    ngOnInit() {
        this._initHours();
    }
    /** Hand styles based on selected hour. */
    _handStyles() {
        const deg = Math.round(this.selectedHour * (360 / (24 / 2)));
        const radius = this._getRadius(this.selectedHour);
        const height = radius;
        const marginTop = getClockRadius(this.touchUi) - radius;
        return {
            transform: `rotate(${deg}deg)`,
            height: `${height}px`,
            'margin-top': `${marginTop}px`,
        };
    }
    /** Handles mouse and touch events on dial and document. */
    _onUserAction(event) {
        if (event.cancelable) {
            event.preventDefault();
        }
        this._setHour(event);
        const eventsSubscription = merge(fromEvent(this._document, 'mousemove'), fromEvent(this._document, 'touchmove'))
            .pipe(debounceTime(0))
            .subscribe({
            next: (event) => {
                event.preventDefault();
                this._setHour(event);
            },
        });
        merge(fromEvent(this._document, 'mouseup'), fromEvent(this._document, 'touchend'))
            .pipe(take(1))
            .subscribe({
            next: () => {
                eventsSubscription.unsubscribe();
                this.selectedChange.emit({
                    hour: this.selectedHour,
                    changeView: true,
                });
            },
        });
    }
    _isActiveCell(hour) {
        return this.selectedHour === hour;
    }
    /** Changes selected hour based on coordinates. */
    _setHour(event) {
        const element = this._element.nativeElement;
        const window = this._getWindow();
        const elementRect = element.getBoundingClientRect();
        const width = element.offsetWidth;
        const height = element.offsetHeight;
        const pageX = event instanceof MouseEvent ? event.pageX : event.touches[0].pageX;
        const pageY = event instanceof MouseEvent ? event.pageY : event.touches[0].pageY;
        const x = width / 2 - (pageX - elementRect.left - window.scrollX);
        const y = height / 2 - (pageY - elementRect.top - window.scrollY);
        const unit = Math.PI / 6;
        const atan2 = Math.atan2(-x, y);
        const radian = atan2 < 0 ? Math.PI * 2 + atan2 : atan2;
        const initialValue = Math.round(radian / unit);
        const z = Math.sqrt(x * x + y * y);
        const outer = z > getClockOuterRadius(this.touchUi) - getClockTickRadius(this.touchUi);
        const value = this._getHourValue(initialValue, outer);
        if (this.availableHours.includes(value)) {
            this.selectedHour = value;
            this.selectedChange.emit({
                hour: this.selectedHour,
            });
        }
        this._cdr.detectChanges();
    }
    /** Return value of hour. */
    _getHourValue(value, outer) {
        const edgeValue = value === 0 || value === 12;
        if (this.isMeridiem) {
            return edgeValue ? 12 : value;
        }
        if (outer) {
            return edgeValue ? 0 : value;
        }
        return edgeValue ? 12 : value + 12;
    }
    /** Creates list of hours. */
    _initHours() {
        const initialHours = this.isMeridiem ? ALL_HOURS.slice(1, 13) : ALL_HOURS;
        this.hours = initialHours.map((hour) => {
            const radian = (hour / 6) * Math.PI;
            const radius = this._getRadius(hour);
            return {
                value: hour,
                displayValue: hour === 0 ? '00' : String(hour),
                left: getClockCorrectedRadius(this.touchUi) + Math.sin(radian) * radius,
                top: getClockCorrectedRadius(this.touchUi) - Math.cos(radian) * radius,
                disabled: !this.availableHours.includes(hour),
            };
        });
    }
    /** Returns radius based on hour */
    _getRadius(hour) {
        if (this.isMeridiem) {
            return getClockOuterRadius(this.touchUi);
        }
        const outer = hour >= 0 && hour < 12;
        const radius = outer ? getClockOuterRadius(this.touchUi) : getClockInnerRadius(this.touchUi);
        return radius;
    }
    /** Use defaultView of injected document if available or fallback to global window reference */
    _getWindow() {
        return this._document.defaultView || window;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatHoursClockDial, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: MatHoursClockDial, isStandalone: true, selector: "mat-hours-clock-dial", inputs: { selectedHour: "selectedHour", isMeridiem: "isMeridiem", availableHours: "availableHours", color: "color", touchUi: "touchUi" }, outputs: { selectedChange: "selectedChange" }, host: { listeners: { "mousedown": "_onUserAction($event)", "touchstart": "_onUserAction($event)" }, classAttribute: "mat-clock-dial mat-clock-dial-hours" }, exportAs: ["matHoursClockDial"], ngImport: i0, template: "<div\n  class=\"mat-clock-dial-hand\"\n  [class.mat-clock-dial-hand-pointless]=\"isHour\"\n  [class.mat-clock-dial-hand-disabled]=\"disabledHand\"\n  [ngStyle]=\"_handStyles()\"\n></div>\n@for (hour of hours; track hour.value) {\n  <button\n    class=\"mat-clock-dial-cell\"\n    mat-mini-fab\n    disableRipple\n    [tabIndex]=\"_isActiveCell(hour.value) ? 0 : -1\"\n    [style.left.px]=\"hour.left\"\n    [style.top.px]=\"hour.top\"\n    [class.mat-clock-dial-cell-active]=\"_isActiveCell(hour.value)\"\n    [class.mat-clock-dial-cell-disabled]=\"hour.disabled\"\n    [color]=\"_isActiveCell(hour.value) ? color : undefined\"\n    [attr.aria-disabled]=\"hour.disabled || null\"\n  >\n    {{ hour.displayValue }}\n  </button>\n}\n", styles: [".mat-clock-dial{position:relative;display:block;width:16rem;height:16rem;margin:0 auto;border-radius:50%;background-color:var(--mat-timepicker-clock-dial-background-color, var(--mat-sys-surface-container-highest))}.mat-clock-dial:before{position:absolute;top:50%;left:50%;width:.4375rem;height:.4375rem;border-radius:50%;transform:translate(-50%,-50%);content:\"\";background-color:var(--mat-timepicker-clock-dial-center-point-color, var(--mat-sys-primary))}[mat-mini-fab].mat-clock-dial-cell{position:absolute;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:50%;box-shadow:none}[mat-mini-fab].mat-clock-dial-cell:disabled{pointer-events:none}[mat-mini-fab].mat-clock-dial-cell:focus,[mat-mini-fab].mat-clock-dial-cell:hover,[mat-mini-fab].mat-clock-dial-cell:active,[mat-mini-fab].mat-clock-dial-cell:focus:active{box-shadow:none}[mat-mini-fab].mat-clock-dial-cell.mat-clock-dial-cell-disabled.mat-clock-dial-cell-active{background-color:var(--mat-timepicker-clock-dial-cell-active-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent));color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary))}.mat-clock-dial-cell:not(.mat-primary):not(.mat-accent):not(.mat-warn){background:var(--mat-timepicker-clock-dial-cell-unthemable-color, transparent)}.mat-clock-dial-cell.mat-clock-dial-cell-active{color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary));background-color:var(--mat-timepicker-clock-dial-cell-active-background-color, var(--mat-sys-primary))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled{color:var(--mat-timepicker-clock-dial-cell-disabled-text-color, color-mix(in srgb, var(--mat-sys-on-surface) 40%, transparent))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled .mat-mdc-button-persistent-ripple:before{background-color:var(--mat-timepicker-clock-dial-cell-disabled-background-color, transparent)}.mat-timepicker-content-touch .mat-clock-dial{width:20rem;height:20rem}.mat-timepicker-content-touch [mat-mini-fab].mat-clock-dial-cell{width:3rem;height:3rem;font-size:1.125rem}.mat-clock-dial-hand{position:absolute;inset:0;width:1px;margin:0 auto;transform-origin:bottom}.mat-clock-dial-hand:before{position:absolute;top:-.25rem;left:-.25rem;width:calc(.5rem + 1px);height:calc(.5rem + 1px);border-radius:50%;content:\"\"}.mat-clock-dial-hand.mat-clock-dial-hand-disabled{background-color:var(--mat-timepicker-clock-dial-hand-disabled-color, transparent)}.mat-clock-dial-hand.mat-clock-dial-hand-disabled:before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled){background-color:var(--mat-timepicker-clock-dial-hand-color, var(--mat-sys-primary))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled):before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-color, var(--mat-sys-primary))}.mat-clock-dial-hand.mat-clock-dial-hand-pointless:before{content:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab]", exportAs: ["matButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatHoursClockDial, decorators: [{
            type: Component,
            args: [{ selector: 'mat-hours-clock-dial', standalone: true, imports: [CommonModule, MatButtonModule], exportAs: 'matHoursClockDial', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        class: 'mat-clock-dial mat-clock-dial-hours',
                        '(mousedown)': '_onUserAction($event)',
                        '(touchstart)': '_onUserAction($event)',
                    }, template: "<div\n  class=\"mat-clock-dial-hand\"\n  [class.mat-clock-dial-hand-pointless]=\"isHour\"\n  [class.mat-clock-dial-hand-disabled]=\"disabledHand\"\n  [ngStyle]=\"_handStyles()\"\n></div>\n@for (hour of hours; track hour.value) {\n  <button\n    class=\"mat-clock-dial-cell\"\n    mat-mini-fab\n    disableRipple\n    [tabIndex]=\"_isActiveCell(hour.value) ? 0 : -1\"\n    [style.left.px]=\"hour.left\"\n    [style.top.px]=\"hour.top\"\n    [class.mat-clock-dial-cell-active]=\"_isActiveCell(hour.value)\"\n    [class.mat-clock-dial-cell-disabled]=\"hour.disabled\"\n    [color]=\"_isActiveCell(hour.value) ? color : undefined\"\n    [attr.aria-disabled]=\"hour.disabled || null\"\n  >\n    {{ hour.displayValue }}\n  </button>\n}\n", styles: [".mat-clock-dial{position:relative;display:block;width:16rem;height:16rem;margin:0 auto;border-radius:50%;background-color:var(--mat-timepicker-clock-dial-background-color, var(--mat-sys-surface-container-highest))}.mat-clock-dial:before{position:absolute;top:50%;left:50%;width:.4375rem;height:.4375rem;border-radius:50%;transform:translate(-50%,-50%);content:\"\";background-color:var(--mat-timepicker-clock-dial-center-point-color, var(--mat-sys-primary))}[mat-mini-fab].mat-clock-dial-cell{position:absolute;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:50%;box-shadow:none}[mat-mini-fab].mat-clock-dial-cell:disabled{pointer-events:none}[mat-mini-fab].mat-clock-dial-cell:focus,[mat-mini-fab].mat-clock-dial-cell:hover,[mat-mini-fab].mat-clock-dial-cell:active,[mat-mini-fab].mat-clock-dial-cell:focus:active{box-shadow:none}[mat-mini-fab].mat-clock-dial-cell.mat-clock-dial-cell-disabled.mat-clock-dial-cell-active{background-color:var(--mat-timepicker-clock-dial-cell-active-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent));color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary))}.mat-clock-dial-cell:not(.mat-primary):not(.mat-accent):not(.mat-warn){background:var(--mat-timepicker-clock-dial-cell-unthemable-color, transparent)}.mat-clock-dial-cell.mat-clock-dial-cell-active{color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary));background-color:var(--mat-timepicker-clock-dial-cell-active-background-color, var(--mat-sys-primary))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled{color:var(--mat-timepicker-clock-dial-cell-disabled-text-color, color-mix(in srgb, var(--mat-sys-on-surface) 40%, transparent))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled .mat-mdc-button-persistent-ripple:before{background-color:var(--mat-timepicker-clock-dial-cell-disabled-background-color, transparent)}.mat-timepicker-content-touch .mat-clock-dial{width:20rem;height:20rem}.mat-timepicker-content-touch [mat-mini-fab].mat-clock-dial-cell{width:3rem;height:3rem;font-size:1.125rem}.mat-clock-dial-hand{position:absolute;inset:0;width:1px;margin:0 auto;transform-origin:bottom}.mat-clock-dial-hand:before{position:absolute;top:-.25rem;left:-.25rem;width:calc(.5rem + 1px);height:calc(.5rem + 1px);border-radius:50%;content:\"\"}.mat-clock-dial-hand.mat-clock-dial-hand-disabled{background-color:var(--mat-timepicker-clock-dial-hand-disabled-color, transparent)}.mat-clock-dial-hand.mat-clock-dial-hand-disabled:before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled){background-color:var(--mat-timepicker-clock-dial-hand-color, var(--mat-sys-primary))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled):before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-color, var(--mat-sys-primary))}.mat-clock-dial-hand.mat-clock-dial-hand-pointless:before{content:none}\n"] }]
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
                    type: Inject,
                    args: [DOCUMENT]
                }] }], propDecorators: { selectedHour: [{
                type: Input
            }], isMeridiem: [{
                type: Input
            }], availableHours: [{
                type: Input
            }], color: [{
                type: Input
            }], touchUi: [{
                type: Input
            }], selectedChange: [{
                type: Output
            }] } });

/** InjectionToken for timepicker that can be used to override default locale code. */
const MAT_TIME_LOCALE = new InjectionToken('MAT_TIME_LOCALE', {
    providedIn: 'root',
    factory: MAT_DATE_TIME_LOCALE_FACTORY,
});
function MAT_DATE_TIME_LOCALE_FACTORY() {
    return inject(LOCALE_ID);
}
/**
 * No longer needed since MAT_TIME_LOCALE has been changed to a scoped injectable.
 * If you are importing and providing this in your code you can simply remove it.
 * @deprecated
 * @breaking-change 18.0.0
 */
const MAT_TIME_LOCALE_PROVIDER = {
    provide: MAT_TIME_LOCALE,
    useExisting: LOCALE_ID,
};
class TimeAdapter {
    /**
     * Given a potential time object, returns that same time object if it is
     * a valid time, or `null` if it's not a valid time.
     * @param obj The object to check.
     * @returns A time or `null`.
     */
    getValidTimeOrNull(obj) {
        return this.isTimeInstance(obj) && this.isValid(obj)
            ? obj
            : null;
    }
    /**
     * Attempts to deserialize a value to a valid time object. The `<mat-timepicker>` will call this
     * method on all of its `@Input()` properties that accept time. It is therefore possible to
     * support passing values from your backend directly to these properties by overriding this method
     * to also deserialize the format used by your backend.
     * @param value The value to be deserialized into a time object.
     * @returns The deserialized time object, either a valid time, null if the value can be
     *     deserialized into a null time (e.g. the empty string), or an invalid date.
     */
    deserialize(value) {
        if (value == null || (this.isTimeInstance(value) && this.isValid(value))) {
            return value;
        }
        return this.invalid();
    }
    /**
     * Sets the locale used for all time.
     * @param locale The new locale.
     */
    setLocale(locale) {
        this.locale = locale;
    }
    /**
     * Checks if two time are equal.
     * @param first The first time to check.
     * @param second The second time to check.
     * @returns Whether the two time are equal.
     *     Null time are considered equal to other null time.
     */
    sameTime(first, second) {
        if (first && second) {
            let firstValid = this.isValid(first);
            let secondValid = this.isValid(second);
            if (firstValid && secondValid) {
                return !this.compareTime(first, second);
            }
            return firstValid == secondValid;
        }
        return first == second;
    }
    /**
     * Clamp the given time between min and max time.
     * @param time The time to clamp.
     * @param min The minimum value to allow. If null or omitted no min is enforced.
     * @param max The maximum value to allow. If null or omitted no max is enforced.
     * @returns `min` if `time` is less than `min`, `max` if time is greater than `max`,
     *     otherwise `time`.
     */
    clampTime(time, min, max) {
        if (min && this.compareTime(time, min) < 0) {
            return min;
        }
        if (max && this.compareTime(time, max) > 0) {
            return max;
        }
        return time;
    }
}

/**
 * Matches strings that have the form of a valid RFC 3339 string
 * (https://tools.ietf.org/html/rfc3339). Note that the string may not actually be a valid date
 * because the regex will match strings an with out of bounds month, date, etc.
 */
const ISO_8601_REGEX = /^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|(?:(?:\+|-)\d{2}:\d{2}))?)?$/;
/** Adapts the native JS Date for components that work with time. */
class NativeDateTimeAdapter extends TimeAdapter {
    constructor(matTimeLocale) {
        super();
        this._matTimeLocale = inject(MAT_TIME_LOCALE, { optional: true });
        if (matTimeLocale !== undefined) {
            this._matTimeLocale = matTimeLocale;
        }
        super.setLocale(this._matTimeLocale);
    }
    now() {
        return new Date();
    }
    parse(value, parseFormat) {
        // We have no way using the native JS Date to set the parse format or locale, so we ignore these
        // parameters.
        if (typeof value == 'number') {
            return new Date(value);
        }
        const { hour, minute, meridiem } = this.parseTime(value);
        // hour should be in 24h format
        // so, if meridiem is 'pm' and hour is less than 12, add 12 to hour
        const correctedHour = meridiem === 'pm' && hour < 12 ? hour + 12 : hour;
        const date = new Date();
        date.setHours(correctedHour);
        date.setMinutes(minute);
        return value ? new Date(date) : null;
    }
    parseTime(value) {
        const time = value.replace(/(\sam|\spm|\sAM|\sPM|am|pm|AM|PM)/g, '');
        const meridiem = value.replace(time, '').trim().toLowerCase();
        const [hour, minute] = time.split(':');
        return { hour: Number(hour), minute: Number(minute), meridiem };
    }
    getHour(date) {
        return date.getHours();
    }
    getMinute(date) {
        return date.getMinutes();
    }
    updateHour(date, hour) {
        const copy = new Date(date.getTime());
        copy.setHours(hour);
        return copy;
    }
    updateMinute(date, minute) {
        const copy = new Date(date.getTime());
        copy.setMinutes(minute);
        return copy;
    }
    getPeriod(date) {
        return date.getHours() < 12 ? 'am' : 'pm';
    }
    format(date, displayFormat) {
        if (!this.isValid(date)) {
            throw Error('NativeDateTimeAdapter: Cannot format invalid date.');
        }
        const dtf = new Intl.DateTimeFormat(this.locale, {
            ...displayFormat,
            timeZone: 'utc',
        });
        return this._format(dtf, date);
    }
    /**
     * Returns the given value if given a valid Date or null. Deserializes valid ISO 8601 strings
     * (https://www.ietf.org/rfc/rfc3339.txt) into valid Dates and empty string into null. Returns an
     * invalid date for all other values.
     */
    deserialize(value) {
        if (typeof value === 'string') {
            if (!value) {
                return null;
            }
            // The `Date` constructor accepts formats other than ISO 8601, so we need to make sure the
            // string is the right format first.
            if (ISO_8601_REGEX.test(value)) {
                const date = new Date(value);
                if (this.isValid(date)) {
                    return date;
                }
            }
        }
        return super.deserialize(value);
    }
    isTimeInstance(obj) {
        return obj instanceof Date;
    }
    isValid(date) {
        return !isNaN(date.getTime());
    }
    invalid() {
        return new Date(NaN);
    }
    compareTime(first, second) {
        return (first.getHours() - second.getHours() ||
            first.getMinutes() - second.getMinutes());
    }
    /**
     * When converting Date object to string, javascript built-in functions may return wrong
     * results because it applies its internal DST rules. The DST rules around the world change
     * very frequently, and the current valid rule is not always valid in previous years though.
     * We work around this problem building a new Date object which has its internal UTC
     * representation with the local date and time.
     * @param dtf Intl.DateTimeFormat object, containing the desired string format. It must have
     *    timeZone set to 'utc' to work fine.
     * @param date Date from which we want to get the string representation according to dtf
     * @returns A Date object with its UTC representation based on the passed in date info
     */
    _format(dtf, date) {
        // Passing the year to the constructor causes year numbers <100 to be converted to 19xx.
        // To work around this we use `setUTCFullYear` and `setUTCHours` instead.
        const d = new Date();
        d.setUTCFullYear(date.getFullYear(), date.getMonth(), date.getDate());
        d.setUTCHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
        return dtf.format(d);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeAdapter, deps: [{ token: MAT_TIME_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeAdapter }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeAdapter, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [MAT_TIME_LOCALE]
                }] }] });

class NativeDateTimeModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeModule, imports: [PlatformModule] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeModule, providers: [{ provide: TimeAdapter, useClass: NativeDateTimeAdapter }], imports: [PlatformModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [PlatformModule],
                    providers: [{ provide: TimeAdapter, useClass: NativeDateTimeAdapter }],
                }]
        }] });
class MatNativeDateTimeModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatNativeDateTimeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.1", ngImport: i0, type: MatNativeDateTimeModule }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatNativeDateTimeModule, providers: [provideNativeDateTimeAdapter()] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatNativeDateTimeModule, decorators: [{
            type: NgModule,
            args: [{
                    providers: [provideNativeDateTimeAdapter()],
                }]
        }] });
function provideNativeDateTimeAdapter() {
    return { provide: TimeAdapter, useClass: NativeDateTimeAdapter };
}

class MatTimeFaceBase {
    /** The currently selected time. */
    get selected() {
        return this._selected;
    }
    set selected(value) {
        this._selected = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(value));
        if (!this._selected) {
            return;
        }
        const hour = this._timeAdapter.getHour(this._selected);
        this.selectedHour = hour > 12 && this.isMeridiem ? hour - 12 : hour;
        if (hour === 0 && this.isMeridiem) {
            this.selectedHour = 12;
        }
        this.selectedMinute = this._timeAdapter.getMinute(this._selected);
        this.availableHours = ALL_HOURS;
        if (this.isMeridiem) {
            this.period = this._timeAdapter.getPeriod(this._selected);
        }
        this.availableMinutes = ALL_MINUTES;
        this._setMinHour();
        this._setMaxHour();
        this._setMinMinute();
        this._setMaxMinute();
        this._moveFocusOnNextTick = this.isMeridiem;
    }
    /** The minimum selectable time. */
    get minTime() {
        return this._minTime;
    }
    set minTime(value) {
        this._minTime = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(value));
        if (value) {
            this._setMinHour();
            this._setMinMinute();
            this._setDisabledPeriod();
        }
    }
    /** The maximum selectable time. */
    get maxTime() {
        return this._maxTime;
    }
    set maxTime(value) {
        this._maxTime = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(value));
        if (value) {
            this._setMaxHour();
            this._setMaxMinute();
            this._setDisabledPeriod();
        }
    }
    /** Step over minutes. */
    get minuteInterval() {
        return this._minuteInterval;
    }
    set minuteInterval(value) {
        this._minuteInterval = coerceNumberProperty(value) || 1;
    }
    constructor(_timeAdapter) {
        this._timeAdapter = _timeAdapter;
        this._minuteInterval = 1;
        /** Color palette. */
        this.color = 'primary';
        /** Emits when any hour, minute or period is selected. */
        this._userSelection = new EventEmitter();
        this.selectedChange = new EventEmitter();
        this.selectedHour = 0;
        this.selectedMinute = 0;
        this.disabledPeriod = null;
        this.availableMinutes = ALL_MINUTES;
        this.availableHours = ALL_HOURS;
        /**
         * Used for scheduling that focus should be moved to the active cell on the next tick.
         * We need to schedule it, rather than do it immediately, because we have to wait
         * for Angular to re-evaluate the view children.
         */
        this._moveFocusOnNextTick = false;
    }
    ngAfterContentInit() {
        if (!this.selected) {
            this.selected = this._timeAdapter.clampTime(this._timeAdapter.now(), this.minTime, this.maxTime);
            this._userSelection.emit(this.selected);
        }
    }
    ngAfterViewChecked() {
        if (this._moveFocusOnNextTick) {
            this._moveFocusOnNextTick = false;
            this.focusActiveCell();
        }
    }
    /** Handles hour selection. */
    _onHourSelected(hour) {
        this.selectedHour = hour;
        const selected = this._timeAdapter.updateHour(this.selected, this._getHourBasedOnPeriod(hour));
        this._timeSelected(selected);
    }
    /** Handles minute selection. */
    _onMinuteSelected(minute) {
        this.selectedMinute = minute;
        const selected = this._timeAdapter.updateMinute(this.selected, minute);
        this._timeSelected(selected);
    }
    /** Handles period changing. */
    _onPeriodChanged(period) {
        this.period = period;
        const selected = this._timeAdapter.updateHour(this.selected, this._getHourBasedOnPeriod(this.selectedHour));
        this._timeSelected(selected);
    }
    _getAvailableHours() {
        if (this.isMeridiem) {
            return this.availableHours
                .filter((h) => {
                if (this.period === 'am') {
                    return h < 12;
                }
                if (this.period === 'pm') {
                    return h >= 12;
                }
                return h;
            })
                .map((h) => {
                if (h > 12) {
                    return h - 12;
                }
                if (h === 0) {
                    return 12;
                }
                return h;
            });
        }
        return this.availableHours;
    }
    _onKeydown(event, view) {
        switch (view) {
            case 'hour':
                this._handleHourKeydown(event);
                break;
            case 'minute':
                this._handleMinuteKeydown(event);
                break;
        }
    }
    _handleHourKeydown(event) {
        const hours = this._getAvailableHours();
        const selectedHourIndex = hours.findIndex((hour) => hour === this.selectedHour);
        if (!hours.length) {
            return;
        }
        switch (event.keyCode) {
            case UP_ARROW:
                if (selectedHourIndex + 1 >= hours.length || selectedHourIndex < 0) {
                    this._onHourSelected(hours[0]);
                }
                else {
                    this._onHourSelected(hours[selectedHourIndex + 1]);
                }
                break;
            case DOWN_ARROW:
                if (selectedHourIndex - 1 < 0 || selectedHourIndex < 0) {
                    this._onHourSelected(hours[hours.length - 1]);
                }
                else {
                    this._onHourSelected(hours[selectedHourIndex - 1]);
                }
                break;
            default:
                break;
        }
    }
    _handleMinuteKeydown(event) {
        const minutes = this.availableMinutes;
        const selectedMinuteIndex = minutes.findIndex((minute) => minute === this.selectedMinute);
        if (!minutes.length) {
            return;
        }
        switch (event.keyCode) {
            case UP_ARROW:
                if (selectedMinuteIndex + this.minuteInterval >= minutes.length ||
                    selectedMinuteIndex < 0) {
                    const difference = 60 - this.selectedMinute + Math.min(...this.availableMinutes);
                    const count = Math.ceil(difference / this.minuteInterval);
                    const differenceForValid = count * this.minuteInterval;
                    const nextValidValue = this.selectedMinute + differenceForValid;
                    const correctIndex = minutes.findIndex((minute) => minute === nextValidValue - 60 // amount of mins
                    );
                    this._onMinuteSelected(minutes[correctIndex]);
                }
                else {
                    this._onMinuteSelected(minutes[selectedMinuteIndex + this.minuteInterval]);
                }
                break;
            case DOWN_ARROW:
                if (selectedMinuteIndex - this.minuteInterval < 0 ||
                    selectedMinuteIndex < 0) {
                    const difference = 60 + this.selectedMinute - Math.max(...this.availableMinutes);
                    const count = Math.ceil(difference / this.minuteInterval);
                    const differenceForValid = count * this.minuteInterval;
                    const nextValidValue = this.selectedMinute - differenceForValid;
                    const correctIndex = minutes.findIndex((minute) => minute === nextValidValue + 60 // amount of mins
                    );
                    this._onMinuteSelected(minutes[correctIndex]);
                }
                else {
                    this._onMinuteSelected(minutes[selectedMinuteIndex - this.minuteInterval]);
                }
                break;
            default:
                break;
        }
    }
    /** Gets a correct hours based on meridiem and period. */
    _getHourBasedOnPeriod(hour) {
        const afterNoon = this.isMeridiem && this.period === 'pm';
        const beforeNoon = this.isMeridiem && this.period === 'am';
        if (afterNoon) {
            return hour === 12 ? hour : hour + 12;
        }
        if (beforeNoon) {
            return hour === 12 ? 0 : hour;
        }
        return hour;
    }
    _timeSelected(value) {
        if (value && !this._timeAdapter.sameTime(value, this.selected)) {
            this.selectedChange.emit(value);
        }
        this._userSelection.emit(value);
    }
    /** Sets min hour. */
    _setMinHour() {
        if (!this.minTime) {
            return;
        }
        const minHour = this._timeAdapter.getHour(this.minTime);
        this.availableHours = this.availableHours.filter((h) => h >= minHour);
    }
    /** Sets max hour. */
    _setMaxHour() {
        if (!this.maxTime) {
            return;
        }
        const maxHour = this._timeAdapter.getHour(this.maxTime);
        this.availableHours = this.availableHours.filter((h) => h <= maxHour);
    }
    /** Sets min minute. */
    _setMinMinute() {
        if (!this.selected || !this.minTime) {
            return;
        }
        const selectedHour = this._timeAdapter.getHour(this.selected);
        const minHour = this._timeAdapter.getHour(this.minTime);
        const minMinute = selectedHour > minHour ? 0 : this._timeAdapter.getMinute(this.minTime);
        this.availableMinutes = this.availableMinutes.filter((minute) => minute >= minMinute);
        if (selectedHour < minHour) {
            this.availableMinutes = [];
        }
    }
    /** Sets max minute. */
    _setMaxMinute() {
        if (!this.selected || !this.maxTime) {
            return;
        }
        const selectedHour = this._timeAdapter.getHour(this.selected);
        const maxHour = this._timeAdapter.getHour(this.maxTime);
        const maxMinute = selectedHour < maxHour ? 59 : this._timeAdapter.getMinute(this.maxTime);
        this.availableMinutes = this.availableMinutes.filter((minute) => minute <= maxMinute);
        if (selectedHour > maxHour) {
            this.availableMinutes = [];
        }
    }
    /** Sets disabled period. */
    _setDisabledPeriod() {
        if (this.minTime) {
            const minHour = this._timeAdapter.getHour(this.minTime);
            if (minHour >= 12) {
                this.disabledPeriod = 'am';
            }
        }
        if (this.maxTime) {
            const maxHour = this._timeAdapter.getHour(this.maxTime);
            const maxMinute = this._timeAdapter.getHour(this.maxTime);
            if (maxHour < 12 || (maxHour === 12 && maxMinute === 0)) {
                this.disabledPeriod = 'pm';
            }
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeFaceBase, deps: [{ token: TimeAdapter, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimeFaceBase, isStandalone: true, inputs: { selected: "selected", minTime: "minTime", maxTime: "maxTime", minuteInterval: "minuteInterval", isMeridiem: "isMeridiem", color: "color" }, outputs: { _userSelection: "_userSelection", selectedChange: "selectedChange" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeFaceBase, decorators: [{
            type: Directive
        }], ctorParameters: () => [{ type: TimeAdapter, decorators: [{
                    type: Optional
                }] }], propDecorators: { selected: [{
                type: Input
            }], minTime: [{
                type: Input
            }], maxTime: [{
                type: Input
            }], minuteInterval: [{
                type: Input
            }], isMeridiem: [{
                type: Input
            }], color: [{
                type: Input
            }], _userSelection: [{
                type: Output
            }], selectedChange: [{
                type: Output
            }] } });

function withZeroPrefix(value) {
    return value < 10 ? `0${value}` : `${value}`;
}
function withZeroPrefixMeridiem(value, isMeridiem) {
    const newValue = isMeridiem && value === 0 ? 12 : value;
    return withZeroPrefix(newValue);
}
const DIGIT_KEYS = Array.from({ length: 10 }, (_, i) => `${i}`);
const SPECIAL_KEYS = ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab'];
class MatTimeInputBase {
    get value() {
        return this._value;
    }
    set value(value) {
        this._value = value;
        if (!this.hasFocus) {
            this.setInputValue(this._value);
        }
        // we need timeout here to set placeholder first time
        setTimeout(() => {
            this.setInputPlaceholder(this._value);
        }, 0);
    }
    _keydown(event) {
        const isAllow = (DIGIT_KEYS.includes(event.key) && !event.shiftKey) ||
            SPECIAL_KEYS.includes(event.code);
        if (!isAllow) {
            event.preventDefault();
        }
    }
    get inputElement() {
        return this.element.nativeElement;
    }
    get hasFocus() {
        return this.element?.nativeElement === this._document.activeElement;
    }
    constructor(element, _cdr, _document) {
        this.element = element;
        this._cdr = _cdr;
        this._document = _document;
        this.timeChanged = new EventEmitter();
    }
    focus() {
        this.setInputValue(null);
    }
    blur() {
        const isNumber = !isNaN(Number(this.inputElement.value));
        const value = this._formatValue(isNumber ? Number(this.inputElement.value || this._value) : this.value);
        this.setInputValue(value);
        this.setInputPlaceholder(value);
        this.timeChanged.emit(value);
    }
    setInputValue(value) {
        if (value !== null) {
            this.inputElement.value = this._withZeroPrefix(value);
        }
        else {
            this.inputElement.value = '';
        }
        this._cdr.markForCheck();
    }
    setInputPlaceholder(value) {
        this.inputElement.placeholder = this._withZeroPrefix(value);
        this._cdr.markForCheck();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeInputBase, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimeInputBase, isStandalone: true, inputs: { value: "value" }, outputs: { timeChanged: "timeChanged" }, host: { listeners: { "keydown": "_keydown($event)" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeInputBase, decorators: [{
            type: Directive
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
                    type: Inject,
                    args: [DOCUMENT]
                }] }], propDecorators: { value: [{
                type: Input
            }], timeChanged: [{
                type: Output
            }], _keydown: [{
                type: HostListener,
                args: ['keydown', ['$event']]
            }] } });

const visible = { transform: 'scale(1)', opacity: 1, visibility: 'visible' };
const hidden = { transform: 'scale(1.05)', opacity: 0, visibility: 'hidden' };
const enterLeaveAnimation = trigger('enterLeaveAnimation', [
    transition(':enter', [
        style(hidden),
        animate('0.1s ease-out', style(visible)),
    ]),
    transition(':leave', [style(visible), animate('0s ease-in', style(hidden))]),
]);

class MatTimepickerContentLayout {
    constructor() {
        /** Layout orientation. */
        this.orientation = 'vertical';
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerContentLayout, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerContentLayout, isStandalone: true, selector: "mat-timepicker-content-layout", inputs: { title: "title", orientation: "orientation" }, host: { properties: { "class.mat-timepicker-content-layout-horizontal": "orientation === \"horizontal\"", "class.mat-timepicker-content-layout-vertical": "orientation === \"vertical\"" }, classAttribute: "mat-timepicker-content-layout" }, exportAs: ["matTimepickerContent"], ngImport: i0, template: "<h6 class=\"mat-timepicker-content-layout-title\">{{ title }}</h6>\n\n<div class=\"mat-timepicker-content-layout-container\">\n  <div class=\"mat-timepicker-content-layout-values\">\n    <div class=\"mat-timepicker-content-layout-hours\">\n      <ng-content select=\"[hours]\"></ng-content>\n    </div>\n    <span class=\"mat-timepicker-content-layout-separator\">&#58;</span>\n    <div class=\"mat-timepicker-content-layout-minutes\">\n      <ng-content select=\"[minutes]\"></ng-content>\n    </div>\n\n    <ng-content select=\"[mat-time-period]\"></ng-content>\n  </div>\n\n  <ng-content></ng-content>\n</div>\n", styles: [".mat-timepicker-content-layout-title{color:var(--mat-timepicker-content-layout-title-color, var(--mat-sys-on-surface-variant));font-size:var(--mat-timepicker-content-layout-title-font-size, 12px);font-weight:var(--mat-timepicker-content-layout-title-font-weight, var(--mat-sys-title-medium-weight))}h6.mat-timepicker-content-layout-title{margin-top:0rem;margin-bottom:1.25rem;letter-spacing:.05rem}.mat-timepicker-content-layout-values{display:flex;justify-content:center}.mat-time-period{margin-left:.75rem}.mat-timepicker-content-layout-horizontal h6.mat-timepicker-content-layout-title{margin-bottom:0}.mat-timepicker-content-layout-horizontal .mat-timepicker-content-layout-container{display:flex;gap:4rem;align-items:center}.mat-timepicker-content-layout-horizontal .mat-timepicker-content-layout-values{flex-wrap:wrap}.mat-timepicker-content-layout-horizontal .mat-time-period{margin-top:.75rem;margin-left:0}.mat-timepicker-content-layout-hours,.mat-timepicker-content-layout-minutes{width:6rem}.mat-timepicker-content-layout-separator{display:flex;justify-content:center;align-self:center;width:1.5rem;height:1.75rem;font-weight:500;font-size:var(--mat-timepicker-content-layout-separator-font-size, 3rem);content-layout-separator-line-height:var(--mat-timepicker-content-layout-title-color, 1.25rem)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerContentLayout, decorators: [{
            type: Component,
            args: [{ selector: 'mat-timepicker-content-layout', standalone: true, exportAs: 'matTimepickerContent', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        class: 'mat-timepicker-content-layout',
                        '[class.mat-timepicker-content-layout-horizontal]': 'orientation === "horizontal"',
                        '[class.mat-timepicker-content-layout-vertical]': 'orientation === "vertical"',
                    }, template: "<h6 class=\"mat-timepicker-content-layout-title\">{{ title }}</h6>\n\n<div class=\"mat-timepicker-content-layout-container\">\n  <div class=\"mat-timepicker-content-layout-values\">\n    <div class=\"mat-timepicker-content-layout-hours\">\n      <ng-content select=\"[hours]\"></ng-content>\n    </div>\n    <span class=\"mat-timepicker-content-layout-separator\">&#58;</span>\n    <div class=\"mat-timepicker-content-layout-minutes\">\n      <ng-content select=\"[minutes]\"></ng-content>\n    </div>\n\n    <ng-content select=\"[mat-time-period]\"></ng-content>\n  </div>\n\n  <ng-content></ng-content>\n</div>\n", styles: [".mat-timepicker-content-layout-title{color:var(--mat-timepicker-content-layout-title-color, var(--mat-sys-on-surface-variant));font-size:var(--mat-timepicker-content-layout-title-font-size, 12px);font-weight:var(--mat-timepicker-content-layout-title-font-weight, var(--mat-sys-title-medium-weight))}h6.mat-timepicker-content-layout-title{margin-top:0rem;margin-bottom:1.25rem;letter-spacing:.05rem}.mat-timepicker-content-layout-values{display:flex;justify-content:center}.mat-time-period{margin-left:.75rem}.mat-timepicker-content-layout-horizontal h6.mat-timepicker-content-layout-title{margin-bottom:0}.mat-timepicker-content-layout-horizontal .mat-timepicker-content-layout-container{display:flex;gap:4rem;align-items:center}.mat-timepicker-content-layout-horizontal .mat-timepicker-content-layout-values{flex-wrap:wrap}.mat-timepicker-content-layout-horizontal .mat-time-period{margin-top:.75rem;margin-left:0}.mat-timepicker-content-layout-hours,.mat-timepicker-content-layout-minutes{width:6rem}.mat-timepicker-content-layout-separator{display:flex;justify-content:center;align-self:center;width:1.5rem;height:1.75rem;font-weight:500;font-size:var(--mat-timepicker-content-layout-separator-font-size, 3rem);content-layout-separator-line-height:var(--mat-timepicker-content-layout-title-color, 1.25rem)}\n"] }]
        }], propDecorators: { title: [{
                type: Input
            }], orientation: [{
                type: Input
            }] } });

class MatTimePeriod {
    /** Whether the time period is vertically aligned. */
    get vertical() {
        return this._vertical;
    }
    set vertical(value) {
        this._vertical = coerceBooleanProperty(value);
    }
    get period() {
        return this._period;
    }
    set period(value) {
        this._period = value || 'am';
    }
    get disabledPeriod() {
        return this._disabledPeriod;
    }
    set disabledPeriod(value) {
        this._disabledPeriod = value;
    }
    constructor(_intl) {
        this._intl = _intl;
        this._vertical = true;
        this._period = 'am';
        this._disabledPeriod = null;
        this.periodChanged = new EventEmitter();
    }
    setPeriod(event, period) {
        event.preventDefault();
        this.period = period;
        this.periodChanged.emit(period);
    }
    _isPeriodDisabled(period) {
        if (!this.disabledPeriod) {
            return false;
        }
        return this.disabledPeriod === period;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimePeriod, deps: [{ token: MatTimepickerIntl }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: MatTimePeriod, isStandalone: true, selector: "mat-time-period", inputs: { vertical: "vertical", period: "period", disabledPeriod: "disabledPeriod" }, outputs: { periodChanged: "periodChanged" }, host: { properties: { "class.mat-time-period-vertical": "vertical", "class.mat-time-period-horizontal": "!vertical", "attr.aria-orientation": "vertical ? \"vertical\" : \"horizontal\"" }, classAttribute: "mat-time-period" }, ngImport: i0, template: "<div\n  tabindex=\"0\"\n  class=\"mat-time-period-item\"\n  matRipple\n  [class.mat-time-period-item-active]=\"period === 'am'\"\n  [class.mat-time-period-item-disabled]=\"_isPeriodDisabled('am')\"\n  (click)=\"setPeriod($event, 'am')\"\n  (keydown.space)=\"setPeriod($event, 'am')\"\n>\n  {{ _intl.am }}\n</div>\n<mat-divider [vertical]=\"!vertical\"></mat-divider>\n<div\n  tabindex=\"0\"\n  class=\"mat-time-period-item\"\n  matRipple\n  [class.mat-time-period-item-active]=\"period === 'pm'\"\n  [class.mat-time-period-item-disabled]=\"_isPeriodDisabled('pm')\"\n  (click)=\"setPeriod($event, 'pm')\"\n  (keydown.space)=\"setPeriod($event, 'pm')\"\n>\n  {{ _intl.pm }}\n</div>\n", styles: [".mat-time-period{display:flex;text-align:center;border-width:1px;border-style:solid;border-radius:.25rem;box-sizing:border-box;border-color:var(--mat-timepicker-time-period-border-color, var(--mat-sys-outline))}.mat-time-period-vertical{flex-direction:column;width:3.25rem;height:4.5rem}.mat-time-period-vertical .mat-time-period-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.mat-time-period-vertical .mat-time-period-item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.mat-time-period-horizontal{flex-direction:row;max-width:13.5rem;width:100%;height:2.5rem}.mat-time-period-horizontal .mat-time-period-item:first-child{border-top-left-radius:inherit;border-bottom-left-radius:inherit}.mat-time-period-horizontal .mat-time-period-item:last-child{border-top-right-radius:inherit;border-bottom-right-radius:inherit}.mat-time-period-item{display:flex;flex-direction:column;justify-content:center;flex-grow:1;height:100%;font-size:.875rem;font-weight:500;cursor:pointer}.mat-time-period-item-active{color:var(--mat-timepicker-time-period-active-text-color, var(--mat-sys-on-tertiary-container));background-color:var(--mat-timepicker-time-period-active-background-color, var(--mat-sys-tertiary-container))}.mat-time-period-item-disabled{pointer-events:none;color:var(--mat-timepicker-time-period-disabled-text-color, var(--mat-sys-on-surface-variant));background-color:var(--mat-timepicker-time-period-disabled-background-color, color-mix(in srgb, var(--mat-sys-on-surface) 20%, transparent))}\n"], dependencies: [{ kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i2$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i3.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimePeriod, decorators: [{
            type: Component,
            args: [{ selector: 'mat-time-period', standalone: true, imports: [MatDividerModule, MatRippleModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        class: 'mat-time-period',
                        '[class.mat-time-period-vertical]': 'vertical',
                        '[class.mat-time-period-horizontal]': '!vertical',
                        '[attr.aria-orientation]': 'vertical ? "vertical" : "horizontal"',
                    }, template: "<div\n  tabindex=\"0\"\n  class=\"mat-time-period-item\"\n  matRipple\n  [class.mat-time-period-item-active]=\"period === 'am'\"\n  [class.mat-time-period-item-disabled]=\"_isPeriodDisabled('am')\"\n  (click)=\"setPeriod($event, 'am')\"\n  (keydown.space)=\"setPeriod($event, 'am')\"\n>\n  {{ _intl.am }}\n</div>\n<mat-divider [vertical]=\"!vertical\"></mat-divider>\n<div\n  tabindex=\"0\"\n  class=\"mat-time-period-item\"\n  matRipple\n  [class.mat-time-period-item-active]=\"period === 'pm'\"\n  [class.mat-time-period-item-disabled]=\"_isPeriodDisabled('pm')\"\n  (click)=\"setPeriod($event, 'pm')\"\n  (keydown.space)=\"setPeriod($event, 'pm')\"\n>\n  {{ _intl.pm }}\n</div>\n", styles: [".mat-time-period{display:flex;text-align:center;border-width:1px;border-style:solid;border-radius:.25rem;box-sizing:border-box;border-color:var(--mat-timepicker-time-period-border-color, var(--mat-sys-outline))}.mat-time-period-vertical{flex-direction:column;width:3.25rem;height:4.5rem}.mat-time-period-vertical .mat-time-period-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.mat-time-period-vertical .mat-time-period-item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.mat-time-period-horizontal{flex-direction:row;max-width:13.5rem;width:100%;height:2.5rem}.mat-time-period-horizontal .mat-time-period-item:first-child{border-top-left-radius:inherit;border-bottom-left-radius:inherit}.mat-time-period-horizontal .mat-time-period-item:last-child{border-top-right-radius:inherit;border-bottom-right-radius:inherit}.mat-time-period-item{display:flex;flex-direction:column;justify-content:center;flex-grow:1;height:100%;font-size:.875rem;font-weight:500;cursor:pointer}.mat-time-period-item-active{color:var(--mat-timepicker-time-period-active-text-color, var(--mat-sys-on-tertiary-container));background-color:var(--mat-timepicker-time-period-active-background-color, var(--mat-sys-tertiary-container))}.mat-time-period-item-disabled{pointer-events:none;color:var(--mat-timepicker-time-period-disabled-text-color, var(--mat-sys-on-surface-variant));background-color:var(--mat-timepicker-time-period-disabled-background-color, color-mix(in srgb, var(--mat-sys-on-surface) 20%, transparent))}\n"] }]
        }], ctorParameters: () => [{ type: MatTimepickerIntl }], propDecorators: { vertical: [{
                type: Input
            }], period: [{
                type: Input
            }], disabledPeriod: [{
                type: Input
            }], periodChanged: [{
                type: Output
            }] } });

class MatClockDials extends MatTimeFaceBase {
    constructor(_intl, _timeAdapter, _ngZone, _elementRef, _cdr) {
        super(_timeAdapter);
        this._intl = _intl;
        this._ngZone = _ngZone;
        this._elementRef = _elementRef;
        this._cdr = _cdr;
        this.isHoursView = true;
        /** Specifies the view of clock dial. */
        this._view = new BehaviorSubject('hours');
        this._viewSubscription = Subscription.EMPTY;
    }
    ngOnInit() {
        this._viewSubscription = this._view.subscribe((view) => (this.isHoursView = view === 'hours'));
    }
    ngOnDestroy() {
        this._viewSubscription?.unsubscribe();
        this._viewSubscription = null;
    }
    /** Changes clock dial view. */
    onViewChange(event, view) {
        event.preventDefault();
        this._view.next(view);
    }
    focusActiveCell() {
        this._ngZone.runOutsideAngular(() => {
            this._ngZone.onStable.pipe(take(1)).subscribe(() => {
                const activeCell = this._elementRef.nativeElement.querySelector('.mat-timepicker-content .mat-clock-dial-cell-active');
                if (activeCell) {
                    activeCell.focus();
                    return;
                }
                const activePoint = this._elementRef.nativeElement.querySelector('.mat-timepicker-content .mat-clock-dial-hand-point');
                if (activePoint) {
                    // if no active cell we need to focus a small dot
                    activePoint.focus();
                }
            });
        });
    }
    _withZeroPrefix(value) {
        if (value === 0) {
            return '00';
        }
        return withZeroPrefixMeridiem(value, this.isMeridiem);
    }
    _onMinuteSelected(minute) {
        super._onMinuteSelected(minute);
        this._cdr.detectChanges();
    }
    /** Handles hour selection. */
    _onHourChanged({ hour, changeView = false, }) {
        if (changeView) {
            this._view.next('minutes');
        }
        this._onHourSelected(hour);
        this._cdr.detectChanges();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatClockDials, deps: [{ token: MatTimepickerIntl }, { token: TimeAdapter, optional: true }, { token: i0.NgZone }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: MatClockDials, isStandalone: true, selector: "mat-clock-dials", inputs: { orientation: "orientation", touchUi: "touchUi" }, host: { attributes: { "role": "dial" }, classAttribute: "mat-clock-dials" }, exportAs: ["matClockDials"], usesInheritance: true, ngImport: i0, template: "<mat-timepicker-content-layout [title]=\"_intl.dialsTitle\" [orientation]=\"orientation\">\n  <div\n    tabindex=\"0\"\n    class=\"mat-clock-dial-value\"\n    hours\n    [class.mat-clock-dial-value-active]=\"isHoursView\"\n    (click)=\"onViewChange($event, 'hours')\"\n    (keydown.space)=\"onViewChange($event, 'hours')\"\n  >\n    {{ _withZeroPrefix(selectedHour) }}\n  </div>\n  <div\n    tabindex=\"0\"\n    class=\"mat-clock-dial-value\"\n    minutes\n    [class.mat-clock-dial-value-active]=\"!isHoursView\"\n    (click)=\"onViewChange($event, 'minutes')\"\n    (keydown.space)=\"onViewChange($event, 'minutes')\"\n  >\n    {{ _withZeroPrefix(selectedMinute) }}\n  </div>\n\n  <ng-template mat-time-period [ngIf]=\"isMeridiem\">\n    <mat-time-period\n      [period]=\"period\"\n      [disabledPeriod]=\"disabledPeriod\"\n      [vertical]=\"orientation === 'vertical'\"\n      (periodChanged)=\"_onPeriodChanged($event)\"\n    ></mat-time-period>\n  </ng-template>\n\n  <div\n    class=\"mat-clock-dial-faces\"\n    [class.mat-clock-dial-faces-horizontal]=\"orientation === 'horizontal'\"\n  >\n    @if (isHoursView) {\n      <mat-hours-clock-dial\n        [@enterLeaveAnimation]\n        [color]=\"color\"\n        [selectedHour]=\"selectedHour\"\n        [isMeridiem]=\"isMeridiem\"\n        [availableHours]=\"_getAvailableHours()\"\n        [touchUi]=\"touchUi\"\n        (selectedChange)=\"_onHourChanged($event)\"\n        (keydown)=\"_onKeydown($event, 'hour')\"\n      ></mat-hours-clock-dial>\n    }\n\n    @if (!isHoursView) {\n      <mat-minutes-clock-dial\n        [@enterLeaveAnimation]\n        [color]=\"color\"\n        [selectedMinute]=\"selectedMinute\"\n        [interval]=\"minuteInterval\"\n        [availableMinutes]=\"availableMinutes\"\n        [touchUi]=\"touchUi\"\n        (selectedChange)=\"_onMinuteSelected($event)\"\n        (keydown)=\"_onKeydown($event, 'minute')\"\n      ></mat-minutes-clock-dial>\n    }\n  </div>\n</mat-timepicker-content-layout>\n", styles: [".mat-clock-dial-values{display:flex;width:100%}.mat-clock-dial-value{display:flex;align-items:center;justify-content:center;height:4.5rem;border-radius:.25rem;cursor:pointer;background-color:var(--mat-timepicker-clock-dial-value-background-color, var(--mat-sys-surface-container-highest));font-family:var(--mat-timepicker-clock-dial-value-font-family, var(--mat-sys-body-medium-font));font-size:var(--mat-timepicker-clock-dial-value-font-size, 2rem);letter-spacing:var(--mat-timepicker-clock-dial-value-letter-spacing, .5px)}.mat-clock-dial-value.mat-clock-dial-value-active{color:var(--mat-timepicker-clock-dial-value-active-text-color, var(--mat-sys-on-surface-variant));background-color:var(--mat-timepicker-clock-dial-value-active-background-color, var(--mat-sys-primary-container))}.mat-clock-dial-faces{margin-top:2.25rem}.mat-clock-dial-faces.mat-clock-dial-faces-horizontal{margin-top:0}.mat-clock-dial-cell.mat-clock-dial-cell-disabled:hover{cursor:default}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: MatTimepickerContentLayout, selector: "mat-timepicker-content-layout", inputs: ["title", "orientation"], exportAs: ["matTimepickerContent"] }, { kind: "component", type: MatHoursClockDial, selector: "mat-hours-clock-dial", inputs: ["selectedHour", "isMeridiem", "availableHours", "color", "touchUi"], outputs: ["selectedChange"], exportAs: ["matHoursClockDial"] }, { kind: "component", type: MatMinutesClockDial, selector: "mat-minutes-clock-dial", inputs: ["selectedMinute", "interval", "availableMinutes", "color", "touchUi"], outputs: ["selectedChange"], exportAs: ["matMinutesClockDial"] }, { kind: "component", type: MatTimePeriod, selector: "mat-time-period", inputs: ["vertical", "period", "disabledPeriod"], outputs: ["periodChanged"] }], animations: [enterLeaveAnimation], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatClockDials, decorators: [{
            type: Component,
            args: [{ selector: 'mat-clock-dials', standalone: true, imports: [
                        CommonModule,
                        MatTimepickerContentLayout,
                        MatHoursClockDial,
                        MatMinutesClockDial,
                        MatTimePeriod,
                    ], exportAs: 'matClockDials', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        role: 'dial',
                        class: 'mat-clock-dials',
                    }, animations: [enterLeaveAnimation], template: "<mat-timepicker-content-layout [title]=\"_intl.dialsTitle\" [orientation]=\"orientation\">\n  <div\n    tabindex=\"0\"\n    class=\"mat-clock-dial-value\"\n    hours\n    [class.mat-clock-dial-value-active]=\"isHoursView\"\n    (click)=\"onViewChange($event, 'hours')\"\n    (keydown.space)=\"onViewChange($event, 'hours')\"\n  >\n    {{ _withZeroPrefix(selectedHour) }}\n  </div>\n  <div\n    tabindex=\"0\"\n    class=\"mat-clock-dial-value\"\n    minutes\n    [class.mat-clock-dial-value-active]=\"!isHoursView\"\n    (click)=\"onViewChange($event, 'minutes')\"\n    (keydown.space)=\"onViewChange($event, 'minutes')\"\n  >\n    {{ _withZeroPrefix(selectedMinute) }}\n  </div>\n\n  <ng-template mat-time-period [ngIf]=\"isMeridiem\">\n    <mat-time-period\n      [period]=\"period\"\n      [disabledPeriod]=\"disabledPeriod\"\n      [vertical]=\"orientation === 'vertical'\"\n      (periodChanged)=\"_onPeriodChanged($event)\"\n    ></mat-time-period>\n  </ng-template>\n\n  <div\n    class=\"mat-clock-dial-faces\"\n    [class.mat-clock-dial-faces-horizontal]=\"orientation === 'horizontal'\"\n  >\n    @if (isHoursView) {\n      <mat-hours-clock-dial\n        [@enterLeaveAnimation]\n        [color]=\"color\"\n        [selectedHour]=\"selectedHour\"\n        [isMeridiem]=\"isMeridiem\"\n        [availableHours]=\"_getAvailableHours()\"\n        [touchUi]=\"touchUi\"\n        (selectedChange)=\"_onHourChanged($event)\"\n        (keydown)=\"_onKeydown($event, 'hour')\"\n      ></mat-hours-clock-dial>\n    }\n\n    @if (!isHoursView) {\n      <mat-minutes-clock-dial\n        [@enterLeaveAnimation]\n        [color]=\"color\"\n        [selectedMinute]=\"selectedMinute\"\n        [interval]=\"minuteInterval\"\n        [availableMinutes]=\"availableMinutes\"\n        [touchUi]=\"touchUi\"\n        (selectedChange)=\"_onMinuteSelected($event)\"\n        (keydown)=\"_onKeydown($event, 'minute')\"\n      ></mat-minutes-clock-dial>\n    }\n  </div>\n</mat-timepicker-content-layout>\n", styles: [".mat-clock-dial-values{display:flex;width:100%}.mat-clock-dial-value{display:flex;align-items:center;justify-content:center;height:4.5rem;border-radius:.25rem;cursor:pointer;background-color:var(--mat-timepicker-clock-dial-value-background-color, var(--mat-sys-surface-container-highest));font-family:var(--mat-timepicker-clock-dial-value-font-family, var(--mat-sys-body-medium-font));font-size:var(--mat-timepicker-clock-dial-value-font-size, 2rem);letter-spacing:var(--mat-timepicker-clock-dial-value-letter-spacing, .5px)}.mat-clock-dial-value.mat-clock-dial-value-active{color:var(--mat-timepicker-clock-dial-value-active-text-color, var(--mat-sys-on-surface-variant));background-color:var(--mat-timepicker-clock-dial-value-active-background-color, var(--mat-sys-primary-container))}.mat-clock-dial-faces{margin-top:2.25rem}.mat-clock-dial-faces.mat-clock-dial-faces-horizontal{margin-top:0}.mat-clock-dial-cell.mat-clock-dial-cell-disabled:hover{cursor:default}\n"] }]
        }], ctorParameters: () => [{ type: MatTimepickerIntl }, { type: TimeAdapter, decorators: [{
                    type: Optional
                }] }, { type: i0.NgZone }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { orientation: [{
                type: Input
            }], touchUi: [{
                type: Input
            }] } });

class MatHourInput extends MatTimeInputBase {
    get availableHours() {
        return this._availableHours;
    }
    set availableHours(value) {
        this._availableHours = value;
    }
    constructor(element, _cdr, _document) {
        super(element, _cdr, _document);
        this._availableHours = [];
    }
    _withZeroPrefix(value) {
        return withZeroPrefixMeridiem(value, this.isMeridiem);
    }
    _formatValue(hour) {
        const getValue = () => {
            if (this.isMeridiem) {
                if (hour === 0 || hour === 24) {
                    return 12;
                }
            }
            if (hour === 24) {
                return 0;
            }
            return this.isMeridiem && hour > 12 ? hour - 12 : hour;
        };
        const value = getValue();
        if (this.isMeridiem) {
            if (!this.availableHours.length) {
                return this.value;
            }
            if (value === 12 && this.availableHours.includes(12)) {
                return 12;
            }
            if (value === 12 && !this.availableHours.includes(12)) {
                return Math.min(...this.availableHours);
            }
            if (value >= 1 && value < 12) {
                // the last item is max becuase 12 at the beginning is kinda "min"
                const maxHour = this.availableHours[this.availableHours.length - 1];
                return Math.min(Math.max(value, Math.min(...this.availableHours)), maxHour);
            }
        }
        return Math.min(Math.max(value, Math.min(...this.availableHours)), Math.max(...this.availableHours));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatHourInput, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatHourInput, isStandalone: true, selector: "input[matHourInput]", inputs: { availableHours: "availableHours", isMeridiem: "isMeridiem" }, host: { listeners: { "focus": "focus($event)", "blur": "blur($event)" }, classAttribute: "mat-time-input" }, exportAs: ["matTimeInput"], usesInheritance: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatHourInput, decorators: [{
            type: Directive,
            args: [{
                    selector: 'input[matHourInput]',
                    standalone: true,
                    exportAs: 'matTimeInput',
                    host: {
                        class: 'mat-time-input',
                        '(focus)': 'focus($event)',
                        '(blur)': 'blur($event)',
                    },
                }]
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
                    type: Inject,
                    args: [DOCUMENT]
                }] }], propDecorators: { availableHours: [{
                type: Input
            }], isMeridiem: [{
                type: Input
            }] } });
class MatMinuteInput extends MatTimeInputBase {
    /** Step over minutes. */
    get interval() {
        return this._interval;
    }
    set interval(value) {
        this._interval = coerceNumberProperty(value) || 1;
    }
    get availableMinutes() {
        return this._availableMinutes;
    }
    set availableMinutes(value) {
        this._availableMinutes = value;
    }
    constructor(element, _cdr, _document) {
        super(element, _cdr, _document);
        this._interval = 1;
        this._availableMinutes = [];
    }
    _withZeroPrefix(value) {
        return withZeroPrefix(value);
    }
    _formatValue(value) {
        if (!this.availableMinutes.length) {
            return this.value;
        }
        const roundedValue = Math.round(value / this.interval) * this.interval;
        return Math.min(Math.max(roundedValue, Math.min(...this.availableMinutes)), Math.max(...this.availableMinutes));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatMinuteInput, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatMinuteInput, isStandalone: true, selector: "input[matMinuteInput]", inputs: { interval: "interval", availableMinutes: "availableMinutes" }, host: { listeners: { "focus": "focus($event)", "blur": "blur($event)" }, classAttribute: "mat-time-input" }, exportAs: ["matTimeInput"], usesInheritance: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatMinuteInput, decorators: [{
            type: Directive,
            args: [{
                    selector: 'input[matMinuteInput]',
                    standalone: true,
                    exportAs: 'matTimeInput',
                    host: {
                        class: 'mat-time-input',
                        '(focus)': 'focus($event)',
                        '(blur)': 'blur($event)',
                    },
                }]
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
                    type: Inject,
                    args: [DOCUMENT]
                }] }], propDecorators: { interval: [{
                type: Input
            }], availableMinutes: [{
                type: Input
            }] } });
class MatTimeInputs extends MatTimeFaceBase {
    constructor(_intl, _timeAdapter, _ngZone, _elementRef) {
        super(_timeAdapter);
        this._intl = _intl;
        this._ngZone = _ngZone;
        this._elementRef = _elementRef;
        /**
         * Using for skipping that focus shouldn't be moved to the active cell on the next tick.
         * We need to use it to avoid focusing input for input mode.
         */
        this._skipNextTickFocus = false;
    }
    focusActiveCell() {
        this._ngZone.runOutsideAngular(() => {
            this._ngZone.onStable.pipe(take(1)).subscribe(() => {
                const activeCell = this._elementRef.nativeElement.querySelector('.mat-timepicker-content input');
                if (activeCell && !this._skipNextTickFocus) {
                    activeCell.focus();
                    this._skipNextTickFocus = true;
                }
            });
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeInputs, deps: [{ token: MatTimepickerIntl }, { token: TimeAdapter, optional: true }, { token: i0.NgZone }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: MatTimeInputs, isStandalone: true, selector: "mat-time-inputs", host: { classAttribute: "mat-time-inputs" }, usesInheritance: true, ngImport: i0, template: "<mat-timepicker-content-layout [title]=\"_intl.inputsTitle\">\n  <mat-form-field\n    class=\"mat-time-inputs-field\"\n    appearance=\"outline\"\n    hours\n    [color]=\"color\"\n  >\n    <input\n      type=\"text\"\n      inputmode=\"numeric\"\n      maxlength=\"2\"\n      matInput\n      matHourInput\n      [isMeridiem]=\"isMeridiem\"\n      [value]=\"selectedHour\"\n      [availableHours]=\"_getAvailableHours()\"\n      (timeChanged)=\"_onHourSelected($event)\"\n      (keydown)=\"_onKeydown($event, 'hour')\"\n    />\n    <mat-hint>{{_intl.hourInputHint}}</mat-hint>\n  </mat-form-field>\n  <mat-form-field\n    class=\"mat-time-inputs-field\"\n    appearance=\"outline\"\n    minutes\n    [color]=\"color\"\n  >\n    <input\n      type=\"text\"\n      inputmode=\"numeric\"\n      maxlength=\"2\"\n      matInput\n      matMinuteInput\n      [value]=\"selectedMinute\"\n      [interval]=\"minuteInterval\"\n      [availableMinutes]=\"availableMinutes\"\n      (timeChanged)=\"_onMinuteSelected($event)\"\n      (keydown)=\"_onKeydown($event, 'minute')\"\n    />\n    <mat-hint>{{_intl.minuteInputHint}}</mat-hint>\n  </mat-form-field>\n\n  <ng-template mat-time-period [ngIf]=\"isMeridiem\">\n    <mat-time-period\n      [period]=\"period\"\n      [disabledPeriod]=\"disabledPeriod\"\n      (periodChanged)=\"_onPeriodChanged($event)\"\n    ></mat-time-period>\n  </ng-template>\n</mat-timepicker-content-layout>\n", styles: [".mat-time-inputs{display:block}.mat-time-inputs .mat-timepicker-content-layout-separator{margin-top:-1.5rem}.mat-time-inputs-field{display:block}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-form-field-flex{margin:0}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-text-field-wrapper{top:0;margin:0;background-color:var(--mat-timepicker-time-inputs-field-background-color, var(--mat-sys-surface-container-highest))}.mat-time-inputs-field.mat-form-field-appearance-outline:not(.mat-focused) .mdc-notched-outline__leading,.mat-time-inputs-field.mat-form-field-appearance-outline:not(.mat-focused) .mdc-notched-outline__notch,.mat-time-inputs-field.mat-form-field-appearance-outline:not(.mat-focused) .mdc-notched-outline__trailing{border-style:none}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-form-field-subscript-wrapper{margin-top:.75rem;line-height:1;letter-spacing:.05rem}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-form-field-subscript-wrapper .mat-mdc-form-field-hint-wrapper{padding-left:0}.mat-time-inputs-field.mat-form-field-appearance-outline input.mat-mdc-input-element{font-size:var(--mat-timepicker-time-inputs-field-font-size, 2rem);line-height:var(--mat-timepicker-time-inputs-field-line-height, 1.25)}.mat-time-inputs-field .mat-mdc-form-field-bottom-align:before{height:0}.mat-time-inputs-field .mat-mdc-form-field-infix{border-top:none;text-align:center}.mat-time-inputs-field input.mat-mdc-input-element{margin-top:0;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl],      input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: MatTimepickerContentLayout, selector: "mat-timepicker-content-layout", inputs: ["title", "orientation"], exportAs: ["matTimepickerContent"] }, { kind: "directive", type: MatHourInput, selector: "input[matHourInput]", inputs: ["availableHours", "isMeridiem"], exportAs: ["matTimeInput"] }, { kind: "directive", type: MatMinuteInput, selector: "input[matMinuteInput]", inputs: ["interval", "availableMinutes"], exportAs: ["matTimeInput"] }, { kind: "component", type: MatTimePeriod, selector: "mat-time-period", inputs: ["vertical", "period", "disabledPeriod"], outputs: ["periodChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeInputs, decorators: [{
            type: Component,
            args: [{ selector: 'mat-time-inputs', standalone: true, imports: [
                        CommonModule,
                        MatFormFieldModule,
                        MatInputModule,
                        MatTimepickerContentLayout,
                        MatHourInput,
                        MatMinuteInput,
                        MatTimePeriod,
                    ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        class: 'mat-time-inputs',
                    }, template: "<mat-timepicker-content-layout [title]=\"_intl.inputsTitle\">\n  <mat-form-field\n    class=\"mat-time-inputs-field\"\n    appearance=\"outline\"\n    hours\n    [color]=\"color\"\n  >\n    <input\n      type=\"text\"\n      inputmode=\"numeric\"\n      maxlength=\"2\"\n      matInput\n      matHourInput\n      [isMeridiem]=\"isMeridiem\"\n      [value]=\"selectedHour\"\n      [availableHours]=\"_getAvailableHours()\"\n      (timeChanged)=\"_onHourSelected($event)\"\n      (keydown)=\"_onKeydown($event, 'hour')\"\n    />\n    <mat-hint>{{_intl.hourInputHint}}</mat-hint>\n  </mat-form-field>\n  <mat-form-field\n    class=\"mat-time-inputs-field\"\n    appearance=\"outline\"\n    minutes\n    [color]=\"color\"\n  >\n    <input\n      type=\"text\"\n      inputmode=\"numeric\"\n      maxlength=\"2\"\n      matInput\n      matMinuteInput\n      [value]=\"selectedMinute\"\n      [interval]=\"minuteInterval\"\n      [availableMinutes]=\"availableMinutes\"\n      (timeChanged)=\"_onMinuteSelected($event)\"\n      (keydown)=\"_onKeydown($event, 'minute')\"\n    />\n    <mat-hint>{{_intl.minuteInputHint}}</mat-hint>\n  </mat-form-field>\n\n  <ng-template mat-time-period [ngIf]=\"isMeridiem\">\n    <mat-time-period\n      [period]=\"period\"\n      [disabledPeriod]=\"disabledPeriod\"\n      (periodChanged)=\"_onPeriodChanged($event)\"\n    ></mat-time-period>\n  </ng-template>\n</mat-timepicker-content-layout>\n", styles: [".mat-time-inputs{display:block}.mat-time-inputs .mat-timepicker-content-layout-separator{margin-top:-1.5rem}.mat-time-inputs-field{display:block}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-form-field-flex{margin:0}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-text-field-wrapper{top:0;margin:0;background-color:var(--mat-timepicker-time-inputs-field-background-color, var(--mat-sys-surface-container-highest))}.mat-time-inputs-field.mat-form-field-appearance-outline:not(.mat-focused) .mdc-notched-outline__leading,.mat-time-inputs-field.mat-form-field-appearance-outline:not(.mat-focused) .mdc-notched-outline__notch,.mat-time-inputs-field.mat-form-field-appearance-outline:not(.mat-focused) .mdc-notched-outline__trailing{border-style:none}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-form-field-subscript-wrapper{margin-top:.75rem;line-height:1;letter-spacing:.05rem}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-form-field-subscript-wrapper .mat-mdc-form-field-hint-wrapper{padding-left:0}.mat-time-inputs-field.mat-form-field-appearance-outline input.mat-mdc-input-element{font-size:var(--mat-timepicker-time-inputs-field-font-size, 2rem);line-height:var(--mat-timepicker-time-inputs-field-line-height, 1.25)}.mat-time-inputs-field .mat-mdc-form-field-bottom-align:before{height:0}.mat-time-inputs-field .mat-mdc-form-field-infix{border-top:none;text-align:center}.mat-time-inputs-field input.mat-mdc-input-element{margin-top:0;text-align:center}\n"] }]
        }], ctorParameters: () => [{ type: MatTimepickerIntl }, { type: TimeAdapter, decorators: [{
                    type: Optional
                }] }, { type: i0.NgZone }, { type: i0.ElementRef }] });

/**
 * A selection model containing a time selection.
 */
class MatTimeSelectionModel {
    /**
     * Updates the current selection in the model.
     * @param value New selection that should be assigned.
     * @param source Object that triggered the selection change.
     */
    updateSelection(value, source) {
        const oldValue = this.selection;
        this.selection = value;
        this._selectionChanged.next({ selection: value, source, oldValue });
    }
    constructor(_adapter) {
        this._adapter = _adapter;
        this._selectionChanged = new Subject();
        /** Emits when the selection has changed. */
        this.selectionChanged = this._selectionChanged;
        // this.selection = selection;
    }
    ngOnDestroy() {
        this._selectionChanged.complete();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeSelectionModel, deps: [{ token: TimeAdapter }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeSelectionModel }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeSelectionModel, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: TimeAdapter }] });
/**
 * A selection model that contains a single time.
 */
class MatSingleTimeSelectionModel extends MatTimeSelectionModel {
    constructor(adapter) {
        super(adapter);
    }
    /**
     * Adds a time to the current selection. In the case of a single time selection, the added time
     * simply overwrites the previous selection
     */
    add(time) {
        super.updateSelection(time, this);
    }
    /** Clones the selection model. */
    clone() {
        const clone = new MatSingleTimeSelectionModel(this._adapter);
        clone.updateSelection(this.selection, this);
        return clone;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatSingleTimeSelectionModel, deps: [{ token: TimeAdapter }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatSingleTimeSelectionModel }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatSingleTimeSelectionModel, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: TimeAdapter }] });
function MAT_SINGLE_TIME_SELECTION_MODEL_FACTORY(parent, adapter) {
    return parent || new MatSingleTimeSelectionModel(adapter);
}
/**
 * Used to provide a single selection model to a component.
 */
const MAT_SINGLE_TIME_SELECTION_MODEL_PROVIDER = {
    provide: MatTimeSelectionModel,
    deps: [
        [new Optional(), new SkipSelf(), MatSingleTimeSelectionModel],
        TimeAdapter,
    ],
    useFactory: MAT_SINGLE_TIME_SELECTION_MODEL_FACTORY,
};

class MatTimepickerContent {
    constructor(intl, _globalModel, _changeDetectorRef) {
        this._globalModel = _globalModel;
        this._changeDetectorRef = _changeDetectorRef;
        /** Portal with projected action buttons. */
        this._actionsPortal = null;
        /** Whether there is an in-progress animation. */
        this._isAnimating = false;
        /** Emits when an animation has finished. */
        this._animationDone = new Subject();
        this._subscriptions = new Subscription();
        this._closeButtonText = intl.closeTimepickerLabel;
    }
    ngOnInit() {
        this._animationState =
            this.timepicker.openAs === 'dialog' ? 'enter-dialog' : 'enter-dropdown';
    }
    ngAfterViewInit() {
        this._subscriptions.add(this.timepicker.stateChanges.subscribe(() => {
            this._changeDetectorRef.markForCheck();
        }));
        (this._dials || this._inputs)?.focusActiveCell();
    }
    ngOnDestroy() {
        this._subscriptions.unsubscribe();
        this._animationDone.complete();
    }
    /** Changes animation state while closing timepicker content. */
    _startExitAnimation() {
        this._animationState = 'void';
        this._changeDetectorRef.markForCheck();
    }
    _handleAnimationEvent(event) {
        this._isAnimating = event.phaseName === 'start';
        if (!this._isAnimating) {
            this._animationDone.next();
        }
    }
    onToggleMode(mode) {
        this.mode = mode;
    }
    _getSelected() {
        return this._model?.selection;
    }
    /** Applies the current pending selection to the global model. */
    _applyPendingSelection() {
        if (this._model !== this._globalModel) {
            this._globalModel.updateSelection(this._model.selection, this);
        }
    }
    /**
     * Assigns a new portal containing the timepicker actions.
     * @param portal Portal with the actions to be assigned.
     * @param forceRerender Whether a re-render of the portal should be triggered. This isn't
     * necessary if the portal is assigned during initialization, but it may be required if it's
     * added at a later point.
     */
    _assignActions(portal, forceRerender) {
        // As we have actions, clone the model so that we have the ability to cancel the selection.
        // Note that we want to assign this as soon as possible,
        // but `_actionsPortal` isn't available in the constructor so we do it in `ngOnInit`.
        this._model = this._globalModel.clone();
        this._actionsPortal = portal;
        if (forceRerender) {
            this._changeDetectorRef.detectChanges();
        }
    }
    _handleUserSelection(event) {
        const value = event;
        this._model.add(value);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerContent, deps: [{ token: MatTimepickerIntl }, { token: MatTimeSelectionModel }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: MatTimepickerContent, isStandalone: true, selector: "mat-timepicker-content", host: { listeners: { "@transformPanel.start": "_handleAnimationEvent($event)", "@transformPanel.done": "_handleAnimationEvent($event)" }, properties: { "class": "color ? \"mat-\" + color : \"\"", "@transformPanel": "_animationState", "class.mat-timepicker-content-touch": "timepicker.touchUi" }, classAttribute: "mat-timepicker-content" }, viewQueries: [{ propertyName: "_dials", first: true, predicate: MatClockDials, descendants: true }, { propertyName: "_inputs", first: true, predicate: MatTimeInputs, descendants: true }], exportAs: ["matTimepickerContent"], ngImport: i0, template: "<div\n  cdkTrapFocus\n  role=\"dialog\"\n  class=\"mat-timepicker-content-container\"\n  [attr.aria-modal]=\"true\"\n  [attr.aria-labelledby]=\"_dialogLabelId ?? undefined\"\n>\n  @switch (mode) {\n    @case ('input') {\n      <mat-time-inputs\n        [id]=\"timepicker.id\"\n        [color]=\"color\"\n        [isMeridiem]=\"isMeridiem\"\n        [selected]=\"_getSelected()\"\n        [minTime]=\"timepicker._getMinTime()\"\n        [maxTime]=\"timepicker._getMaxTime()\"\n        [minuteInterval]=\"minuteInterval\"\n        (_userSelection)=\"_handleUserSelection($event)\"\n      ></mat-time-inputs>\n\n      <div class=\"mat-timepicker-content-actions\">\n        @if (showToggleModeButton) {\n          <button\n            class=\"mat-time-toggle-mode-button\"\n            mat-icon-button\n            (click)=\"onToggleMode('dial')\"\n          >\n            <svg\n              xmlns=\"http://www.w3.org/2000/svg\"\n              height=\"24\"\n              width=\"24\"\n              viewBox=\"0 0 24 24\"\n            >\n              <path\n                d=\"m15.175 16.625 1.475-1.45-3.6-3.6V7.1h-2.075v5.3ZM12 21.95q-2.075 0-3.887-.787-1.813-.788-3.15-2.125-1.338-1.338-2.125-3.151Q2.05 14.075 2.05 12t.788-3.887q.787-1.813 2.125-3.15Q6.3 3.625 8.113 2.837 9.925 2.05 12 2.05t3.887.787q1.813.788 3.151 2.126 1.337 1.337 2.125 3.15.787 1.812.787 3.887t-.787 3.887q-.788 1.813-2.125 3.151-1.338 1.337-3.151 2.125-1.812.787-3.887.787ZM12 12Zm0 7.8q3.225 0 5.513-2.275Q19.8 15.25 19.8 12q0-3.25-2.287-5.525Q15.225 4.2 12 4.2T6.488 6.475Q4.2 8.75 4.2 12q0 3.25 2.288 5.525Q8.775 19.8 12 19.8Z\"\n              />\n            </svg>\n          </button>\n        }\n\n        <ng-template [cdkPortalOutlet]=\"_actionsPortal\"></ng-template>\n      </div>\n    }\n\n    @case ('dial') {\n      <mat-clock-dials\n        [id]=\"timepicker.id\"\n        [color]=\"color\"\n        [isMeridiem]=\"isMeridiem\"\n        [selected]=\"_getSelected()\"\n        [minTime]=\"timepicker._getMinTime()\"\n        [maxTime]=\"timepicker._getMaxTime()\"\n        [minuteInterval]=\"minuteInterval\"\n        [orientation]=\"orientation\"\n        [touchUi]=\"timepicker.touchUi\"\n        (_userSelection)=\"_handleUserSelection($event)\"\n      ></mat-clock-dials>\n\n      <div class=\"mat-timepicker-content-actions\">\n        @if (showToggleModeButton) {\n          <button\n            class=\"mat-time-toggle-mode-button\"\n            mat-icon-button\n            (click)=\"onToggleMode('input')\"\n          >\n            <svg\n              xmlns=\"http://www.w3.org/2000/svg\"\n              height=\"24\"\n              width=\"24\"\n              viewBox=\"0 0 24 24\"\n            >\n              <path\n                d=\"M4 19q-.825 0-1.412-.587Q2 17.825 2 17V7q0-.825.588-1.412Q3.175 5 4 5h16q.825 0 1.413.588Q22 6.175 22 7v10q0 .825-.587 1.413Q20.825 19 20 19Zm0-2h16V7H4v10Zm4-1h8v-2H8Zm-3-3h2v-2H5Zm3 0h2v-2H8Zm3 0h2v-2h-2Zm3 0h2v-2h-2Zm3 0h2v-2h-2ZM5 10h2V8H5Zm3 0h2V8H8Zm3 0h2V8h-2Zm3 0h2V8h-2Zm3 0h2V8h-2ZM4 17V7v10Z\"\n              />\n            </svg>\n          </button>\n        }\n\n        <ng-template [cdkPortalOutlet]=\"_actionsPortal\"></ng-template>\n      </div>\n    }\n  }\n\n  <!-- Invisible close button for screen reader users. -->\n  <button\n    type=\"button\"\n    class=\"mat-timepicker-close-button\"\n    mat-raised-button\n    [color]=\"color || 'primary'\"\n    [class.cdk-visually-hidden]=\"!_closeButtonFocused\"\n    (focus)=\"_closeButtonFocused = true\"\n    (blur)=\"_closeButtonFocused = false\"\n    (click)=\"timepicker.close()\"\n  >\n    {{ _closeButtonText }}\n  </button>\n</div>\n", styles: [".mat-timepicker-content{color:var(--mat-timepicker-content-text-color, var(--mat-sys-on-surface));background-color:var(--mat-timepicker-content-background-color, var(--mat-sys-surface-container-high));border-radius:var(--mat-timepicker-content-border-radius, var(--mat-sys-corner-large))}.mat-timepicker-content-container{position:relative;display:flex;flex-direction:column;padding:1rem 1.5rem}.mat-timepicker-content-actions{display:flex;justify-content:space-between;margin-right:-1rem;margin-top:1.5rem}.mat-time-toggle-mode-button{display:flex;align-items:center;justify-content:center;width:3.25rem;height:3.25rem;margin-left:-.75rem;margin-bottom:-.25rem}.mat-time-toggle-mode-button svg{fill:var(--mat-timepicker-toggle-mode-button-color, var(--mat-sys-on-surface-variant))}button.mat-timepicker-close-button{position:absolute;top:100%;left:0;margin-top:.5rem}.ng-animating button.mat-timepicker-close-button{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i3$1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i4$1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: MatTimeInputs, selector: "mat-time-inputs" }, { kind: "component", type: MatClockDials, selector: "mat-clock-dials", inputs: ["orientation", "touchUi"], exportAs: ["matClockDials"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: "    button[mat-button], button[mat-raised-button], button[mat-flat-button],    button[mat-stroked-button]  ", exportAs: ["matButton"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }], animations: [
            matTimepickerAnimations.transformPanel,
            matTimepickerAnimations.fadeInTimepicker,
        ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerContent, decorators: [{
            type: Component,
            args: [{ selector: 'mat-timepicker-content', standalone: true, imports: [
                        CommonModule,
                        PortalModule,
                        A11yModule,
                        MatTimeInputs,
                        MatClockDials,
                        MatButtonModule,
                    ], exportAs: 'matTimepickerContent', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        class: 'mat-timepicker-content',
                        '[class]': 'color ? "mat-" + color : ""',
                        '[@transformPanel]': '_animationState',
                        '(@transformPanel.start)': '_handleAnimationEvent($event)',
                        '(@transformPanel.done)': '_handleAnimationEvent($event)',
                        '[class.mat-timepicker-content-touch]': 'timepicker.touchUi',
                    }, animations: [
                        matTimepickerAnimations.transformPanel,
                        matTimepickerAnimations.fadeInTimepicker,
                    ], template: "<div\n  cdkTrapFocus\n  role=\"dialog\"\n  class=\"mat-timepicker-content-container\"\n  [attr.aria-modal]=\"true\"\n  [attr.aria-labelledby]=\"_dialogLabelId ?? undefined\"\n>\n  @switch (mode) {\n    @case ('input') {\n      <mat-time-inputs\n        [id]=\"timepicker.id\"\n        [color]=\"color\"\n        [isMeridiem]=\"isMeridiem\"\n        [selected]=\"_getSelected()\"\n        [minTime]=\"timepicker._getMinTime()\"\n        [maxTime]=\"timepicker._getMaxTime()\"\n        [minuteInterval]=\"minuteInterval\"\n        (_userSelection)=\"_handleUserSelection($event)\"\n      ></mat-time-inputs>\n\n      <div class=\"mat-timepicker-content-actions\">\n        @if (showToggleModeButton) {\n          <button\n            class=\"mat-time-toggle-mode-button\"\n            mat-icon-button\n            (click)=\"onToggleMode('dial')\"\n          >\n            <svg\n              xmlns=\"http://www.w3.org/2000/svg\"\n              height=\"24\"\n              width=\"24\"\n              viewBox=\"0 0 24 24\"\n            >\n              <path\n                d=\"m15.175 16.625 1.475-1.45-3.6-3.6V7.1h-2.075v5.3ZM12 21.95q-2.075 0-3.887-.787-1.813-.788-3.15-2.125-1.338-1.338-2.125-3.151Q2.05 14.075 2.05 12t.788-3.887q.787-1.813 2.125-3.15Q6.3 3.625 8.113 2.837 9.925 2.05 12 2.05t3.887.787q1.813.788 3.151 2.126 1.337 1.337 2.125 3.15.787 1.812.787 3.887t-.787 3.887q-.788 1.813-2.125 3.151-1.338 1.337-3.151 2.125-1.812.787-3.887.787ZM12 12Zm0 7.8q3.225 0 5.513-2.275Q19.8 15.25 19.8 12q0-3.25-2.287-5.525Q15.225 4.2 12 4.2T6.488 6.475Q4.2 8.75 4.2 12q0 3.25 2.288 5.525Q8.775 19.8 12 19.8Z\"\n              />\n            </svg>\n          </button>\n        }\n\n        <ng-template [cdkPortalOutlet]=\"_actionsPortal\"></ng-template>\n      </div>\n    }\n\n    @case ('dial') {\n      <mat-clock-dials\n        [id]=\"timepicker.id\"\n        [color]=\"color\"\n        [isMeridiem]=\"isMeridiem\"\n        [selected]=\"_getSelected()\"\n        [minTime]=\"timepicker._getMinTime()\"\n        [maxTime]=\"timepicker._getMaxTime()\"\n        [minuteInterval]=\"minuteInterval\"\n        [orientation]=\"orientation\"\n        [touchUi]=\"timepicker.touchUi\"\n        (_userSelection)=\"_handleUserSelection($event)\"\n      ></mat-clock-dials>\n\n      <div class=\"mat-timepicker-content-actions\">\n        @if (showToggleModeButton) {\n          <button\n            class=\"mat-time-toggle-mode-button\"\n            mat-icon-button\n            (click)=\"onToggleMode('input')\"\n          >\n            <svg\n              xmlns=\"http://www.w3.org/2000/svg\"\n              height=\"24\"\n              width=\"24\"\n              viewBox=\"0 0 24 24\"\n            >\n              <path\n                d=\"M4 19q-.825 0-1.412-.587Q2 17.825 2 17V7q0-.825.588-1.412Q3.175 5 4 5h16q.825 0 1.413.588Q22 6.175 22 7v10q0 .825-.587 1.413Q20.825 19 20 19Zm0-2h16V7H4v10Zm4-1h8v-2H8Zm-3-3h2v-2H5Zm3 0h2v-2H8Zm3 0h2v-2h-2Zm3 0h2v-2h-2Zm3 0h2v-2h-2ZM5 10h2V8H5Zm3 0h2V8H8Zm3 0h2V8h-2Zm3 0h2V8h-2Zm3 0h2V8h-2ZM4 17V7v10Z\"\n              />\n            </svg>\n          </button>\n        }\n\n        <ng-template [cdkPortalOutlet]=\"_actionsPortal\"></ng-template>\n      </div>\n    }\n  }\n\n  <!-- Invisible close button for screen reader users. -->\n  <button\n    type=\"button\"\n    class=\"mat-timepicker-close-button\"\n    mat-raised-button\n    [color]=\"color || 'primary'\"\n    [class.cdk-visually-hidden]=\"!_closeButtonFocused\"\n    (focus)=\"_closeButtonFocused = true\"\n    (blur)=\"_closeButtonFocused = false\"\n    (click)=\"timepicker.close()\"\n  >\n    {{ _closeButtonText }}\n  </button>\n</div>\n", styles: [".mat-timepicker-content{color:var(--mat-timepicker-content-text-color, var(--mat-sys-on-surface));background-color:var(--mat-timepicker-content-background-color, var(--mat-sys-surface-container-high));border-radius:var(--mat-timepicker-content-border-radius, var(--mat-sys-corner-large))}.mat-timepicker-content-container{position:relative;display:flex;flex-direction:column;padding:1rem 1.5rem}.mat-timepicker-content-actions{display:flex;justify-content:space-between;margin-right:-1rem;margin-top:1.5rem}.mat-time-toggle-mode-button{display:flex;align-items:center;justify-content:center;width:3.25rem;height:3.25rem;margin-left:-.75rem;margin-bottom:-.25rem}.mat-time-toggle-mode-button svg{fill:var(--mat-timepicker-toggle-mode-button-color, var(--mat-sys-on-surface-variant))}button.mat-timepicker-close-button{position:absolute;top:100%;left:0;margin-top:.5rem}.ng-animating button.mat-timepicker-close-button{display:none}\n"] }]
        }], ctorParameters: () => [{ type: MatTimepickerIntl }, { type: MatTimeSelectionModel }, { type: i0.ChangeDetectorRef }], propDecorators: { _dials: [{
                type: ViewChild,
                args: [MatClockDials]
            }], _inputs: [{
                type: ViewChild,
                args: [MatTimeInputs]
            }] } });

const MAT_DEFAULT_ACITONS = new InjectionToken('MAT_DEFAULT_ACITONS');

/**
 * Injection token that can be used to configure the
 * default options for all timepickers within an app.
 */
const MAT_TIMEPICKER_DEFAULT_OPTIONS = new InjectionToken('MAT_TIMEPICKER_DEFAULT_OPTIONS');
/** Default open as used by the timepicker. */
const DEFAULT_OPEN_AS = 'popup';
/** Default mode used by the timepicker. */
const DEFAULT_MODE = 'dial';
/** Default format used by the timepicker. */
const DEFAULT_FORMAT = '12h';
/** Used to generate a unique ID for each timepicker instance. */
let timepickerUid = 0;
class MatTimepickerBase {
    /** Whether the timepicker pop-up should be disabled. */
    get disabled() {
        return this._disabled === undefined && this.timepickerInput
            ? this.timepickerInput.disabled
            : !!this._disabled;
    }
    set disabled(value) {
        const newValue = coerceBooleanProperty(value);
        if (newValue !== this._disabled) {
            this._disabled = newValue;
            this.stateChanges.next(undefined);
        }
    }
    /** Whether the timepicker is open. */
    get opened() {
        return this._opened;
    }
    set opened(value) {
        coerceBooleanProperty(value) ? this.open() : this.close();
    }
    /** Whether the timepicker mode which determines what the timepicker will be opened as. */
    get openAs() {
        return this._openAs || this._defaults?.openAs || DEFAULT_OPEN_AS;
    }
    set openAs(value) {
        this._openAs = value;
    }
    /** Color palette to use on the timepicker's content. */
    get color() {
        return (this._color ||
            this._defaults?.color ||
            (this.timepickerInput
                ? this.timepickerInput.getThemePalette()
                : undefined));
    }
    set color(value) {
        this._color = value;
    }
    /** Timepicker display mode. */
    get mode() {
        return this._mode || this._defaults?.mode || DEFAULT_MODE;
    }
    set mode(value) {
        this._mode = value;
    }
    /** Timepicker period format. */
    get format() {
        return this._format || this._defaults?.format || DEFAULT_FORMAT;
    }
    set format(value) {
        this._format = value;
    }
    /** Show or hide toggle button between dial and input. */
    get showToggleModeButton() {
        return this._showToggleModeButton;
    }
    set showToggleModeButton(value) {
        this._showToggleModeButton = value;
    }
    /** Step for minutes. */
    get minuteInterval() {
        return this._minuteInterval || this._defaults?.minuteInterval || 1;
    }
    set minuteInterval(value) {
        this._minuteInterval = coerceNumberProperty(value);
    }
    /** Orientation for dial mode. */
    get orientation() {
        return this._orientation || this._defaults?.orientation || 'vertical';
    }
    set orientation(value) {
        this._orientation = value;
    }
    /**
     * Whether the timepicker UI is in touch mode. In touch mode elements are larger for bigger touch targets.
     */
    get touchUi() {
        return this._touchUi;
    }
    set touchUi(value) {
        this._touchUi = coerceBooleanProperty(value);
        if (value) {
            this.openAs = 'dialog';
        }
    }
    /** The minimum selectable time. */
    _getMinTime() {
        return this.timepickerInput && this.timepickerInput.min;
    }
    /** The maximum selectable time. */
    _getMaxTime() {
        return this.timepickerInput && this.timepickerInput.max;
    }
    constructor(_viewContainerRef, _overlay, _ngZone, scrollStrategy, _defaultActionsComponent, _model, _defaults) {
        this._viewContainerRef = _viewContainerRef;
        this._overlay = _overlay;
        this._ngZone = _ngZone;
        this._defaultActionsComponent = _defaultActionsComponent;
        this._model = _model;
        this._defaults = _defaults;
        this._opened = false;
        this._showToggleModeButton = true;
        this._touchUi = false;
        /** Preferred position of the timepicker in the X axis. */
        this.xPosition = 'start';
        /** Preferred position of the timepicker in the Y axis. */
        this.yPosition = 'below';
        /**
         * Whether to restore focus to the previously-focused element when the timepicker is closed.
         * Note that automatic focus restoration is an accessibility feature and it is recommended that
         * you provide your own equivalent, if you decide to turn it off.
         */
        this.restoreFocus = true;
        /** Emits when the timepicker has been opened. */
        this.openedStream = new EventEmitter();
        /** Emits when the timepicker has been closed. */
        this.closedStream = new EventEmitter();
        /** The id for the timepicker. */
        this.id = `mat-timepicker-${timepickerUid++}`;
        /** Portal with projected action buttons. */
        this._actionsPortal = null;
        /** Emits when the timepicker's state changes. */
        this.stateChanges = new Subject();
        /** Unique class that will be added to the backdrop so that the test harnesses can look it up. */
        this._backdropHarnessClass = `${this.id}-backdrop`;
        /** The element that was focused before the timepicker was opened. */
        this._focusedElementBeforeOpen = null;
        this._document = inject(DOCUMENT);
        this._scrollStrategy = scrollStrategy;
        if (_defaults) {
            this.showToggleModeButton =
                _defaults.showToggleModeButton !== undefined
                    ? _defaults.showToggleModeButton
                    : true;
        }
    }
    ngOnChanges(changes) {
        const positionChange = changes['xPosition'] || changes['yPosition'];
        if (positionChange && !positionChange.firstChange && this._overlayRef) {
            const positionStrategy = this._overlayRef.getConfig().positionStrategy;
            if (positionStrategy instanceof FlexibleConnectedPositionStrategy) {
                this._setConnectedPositions(positionStrategy);
                if (this.opened) {
                    this._overlayRef.updatePosition();
                }
            }
        }
        this.stateChanges.next(undefined);
    }
    ngOnDestroy() {
        this._destroyOverlay();
        this.close();
        this.stateChanges.complete();
    }
    /** Opens the timepicker. */
    open() {
        if (this._opened ||
            this.disabled ||
            this._componentRef?.instance._isAnimating) {
            return;
        }
        if (!this.timepickerInput) {
            throw Error('Attempted to open an MatTimepicker with no associated input.');
        }
        this._focusedElementBeforeOpen = _getFocusedElementPierceShadowDom();
        this._openOverlay();
        this._opened = true;
        this.openedStream.emit();
    }
    /** Closes the timepicker. */
    close() {
        if (!this._opened || this._componentRef?.instance._isAnimating) {
            return;
        }
        const canRestoreFocus = this.restoreFocus &&
            this._focusedElementBeforeOpen &&
            typeof this._focusedElementBeforeOpen.focus === 'function';
        const completeClose = () => {
            // The `_opened` could've been reset already if
            // we got two events in quick succession.
            if (this._opened) {
                this._opened = false;
                this.closedStream.emit();
            }
        };
        if (this._componentRef) {
            const { instance, location } = this._componentRef;
            instance._startExitAnimation();
            instance._animationDone.pipe(take(1)).subscribe(() => {
                const activeElement = this._document.activeElement;
                // Since we restore focus after the exit animation, we have to check that
                // the user didn't move focus themselves inside the `close` handler.
                if (canRestoreFocus &&
                    (!activeElement ||
                        activeElement === this._document.activeElement ||
                        location.nativeElement.contains(activeElement))) {
                    this._focusedElementBeforeOpen.focus();
                }
                this._focusedElementBeforeOpen = null;
                this._destroyOverlay();
            });
            if (canRestoreFocus) {
                setTimeout(completeClose);
            }
            else {
                completeClose();
            }
        }
    }
    /**
     * Register an input with this timepicker.
     * @param input The timepicker input to register with this timepicker.
     * @returns Selection model that the input should hook itself up to.
     */
    registerInput(input) {
        if (this.timepickerInput) {
            throw Error('A MatTimepicker can only be associated with a single input.');
        }
        this.timepickerInput = input;
        return this._model;
    }
    /**
     * Registers a portal containing action buttons with the timepicker.
     * @param portal Portal to be registered.
     */
    registerActions(portal) {
        if (this._actionsPortal) {
            throw Error('A MatTimepicker can only be associated with a single actions row.');
        }
        this._actionsPortal = portal;
        this._componentRef?.instance._assignActions(portal, true);
    }
    /**
     * Removes a portal containing action buttons from the timepicker.
     * @param portal Portal to be removed.
     */
    removeActions(portal) {
        if (portal === this._actionsPortal) {
            this._actionsPortal = null;
            this._componentRef?.instance._assignActions(null, true);
        }
    }
    /** Applies the current pending selection on the overlay to the model. */
    _applyPendingSelection() {
        this._componentRef?.instance?._applyPendingSelection();
    }
    /** Forwards relevant values from the timepicker to the timepicker content inside the overlay. */
    _forwardContentValues(instance) {
        const defaultPortal = new ComponentPortal(this._defaultActionsComponent);
        instance.timepicker = this;
        instance.color = this.color;
        instance.mode = this.mode;
        instance.isMeridiem = this.format === '12h';
        instance.showToggleModeButton = this.showToggleModeButton;
        instance.minuteInterval = this.minuteInterval;
        instance.orientation = this.orientation;
        instance._dialogLabelId = this.timepickerInput.getOverlayLabelId();
        instance._assignActions(this._actionsPortal || defaultPortal, false);
    }
    /** Opens the overlay with the timepicker. */
    _openOverlay() {
        this._destroyOverlay();
        const isDialog = this.openAs === 'dialog';
        const portal = new ComponentPortal(MatTimepickerContent, this._viewContainerRef);
        const overlayRef = (this._overlayRef = this._overlay.create(new OverlayConfig({
            positionStrategy: isDialog
                ? this._getDialogStrategy()
                : this._getDropdownStrategy(),
            hasBackdrop: true,
            backdropClass: [
                isDialog
                    ? 'cdk-overlay-dark-backdrop'
                    : 'mat-overlay-transparent-backdrop',
                this._backdropHarnessClass,
            ],
            direction: 'ltr',
            scrollStrategy: isDialog
                ? this._overlay.scrollStrategies.block()
                : this._scrollStrategy(),
            panelClass: `mat-timepicker-${this.openAs}`,
        })));
        this._getCloseStream(overlayRef).subscribe((event) => {
            if (event) {
                event.preventDefault();
            }
            this.close();
        });
        // The `preventDefault` call happens inside the timepicker as well, however focus moves into
        // it inside a timeout which can give browsers a chance to fire off a keyboard event in-between
        // that can scroll the page. Always block default actions of arrow keys for the
        // entire overlay so the page doesn't get scrolled by accident.
        overlayRef.keydownEvents().subscribe((event) => {
            const keyCode = event.keyCode;
            if (keyCode === UP_ARROW ||
                keyCode === DOWN_ARROW ||
                keyCode === PAGE_UP ||
                keyCode === PAGE_DOWN) {
                event.preventDefault();
            }
        });
        this._componentRef = overlayRef.attach(portal);
        this._forwardContentValues(this._componentRef.instance);
        // Update the position once the timepicker has rendered. Only relevant in dropdown mode.
        if (!isDialog) {
            this._ngZone.onStable
                .pipe(first())
                .subscribe(() => overlayRef.updatePosition());
        }
    }
    /** Destroys the current overlay. */
    _destroyOverlay() {
        if (this._overlayRef) {
            this._overlayRef.dispose();
            this._overlayRef = this._componentRef = null;
        }
    }
    /** Gets a position strategy that will open the timepicker as a dropdown. */
    _getDialogStrategy() {
        return this._overlay
            .position()
            .global()
            .centerHorizontally()
            .centerVertically();
    }
    /** Gets a position strategy that will open the timepicker as a dropdown. */
    _getDropdownStrategy() {
        const strategy = this._overlay
            .position()
            .flexibleConnectedTo(this.timepickerInput.getConnectedOverlayOrigin())
            .withTransformOriginOn('.mat-timepicker-content')
            .withFlexibleDimensions(false)
            .withViewportMargin(8)
            .withLockedPosition();
        return this._setConnectedPositions(strategy);
    }
    /** Sets the positions of the timepicker in dropdown mode based on the current configuration. */
    _setConnectedPositions(strategy) {
        const primaryX = this.xPosition === 'end' ? 'end' : 'start';
        const secondaryX = primaryX === 'start' ? 'end' : 'start';
        const primaryY = this.yPosition === 'above' ? 'bottom' : 'top';
        const secondaryY = primaryY === 'top' ? 'bottom' : 'top';
        return strategy.withPositions([
            {
                originX: primaryX,
                originY: secondaryY,
                overlayX: primaryX,
                overlayY: primaryY,
            },
            {
                originX: primaryX,
                originY: primaryY,
                overlayX: primaryX,
                overlayY: secondaryY,
            },
            {
                originX: secondaryX,
                originY: secondaryY,
                overlayX: secondaryX,
                overlayY: primaryY,
            },
            {
                originX: secondaryX,
                originY: primaryY,
                overlayX: secondaryX,
                overlayY: secondaryY,
            },
        ]);
    }
    /** Gets an observable that will emit when the overlay is supposed to be closed. */
    _getCloseStream(overlayRef) {
        return merge(overlayRef.backdropClick(), overlayRef.detachments(), overlayRef.keydownEvents().pipe(filter((event) => {
            // Closing on alt + up is only valid when there's an input associated with the timepicker.
            return ((event.keyCode === ESCAPE && !hasModifierKey(event)) ||
                (this.timepickerInput &&
                    hasModifierKey(event, 'altKey') &&
                    event.keyCode === UP_ARROW));
        })));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerBase, deps: [{ token: i0.ViewContainerRef }, { token: i1$1.Overlay }, { token: i0.NgZone }, { token: MAT_TIMEPICKER_SCROLL_STRATEGY }, { token: MAT_DEFAULT_ACITONS }, { token: MatTimeSelectionModel }, { token: MAT_TIMEPICKER_DEFAULT_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.0.1", type: MatTimepickerBase, isStandalone: true, inputs: { disabled: "disabled", opened: "opened", openAs: "openAs", color: "color", mode: "mode", format: "format", showToggleModeButton: "showToggleModeButton", minuteInterval: "minuteInterval", orientation: "orientation", touchUi: ["touchUi", "touchUi", booleanAttribute], xPosition: "xPosition", yPosition: "yPosition", restoreFocus: ["restoreFocus", "restoreFocus", booleanAttribute] }, outputs: { openedStream: "opened", closedStream: "closed" }, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerBase, decorators: [{
            type: Directive
        }], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i1$1.Overlay }, { type: i0.NgZone }, { type: undefined, decorators: [{
                    type: Inject,
                    args: [MAT_TIMEPICKER_SCROLL_STRATEGY]
                }] }, { type: undefined, decorators: [{
                    type: Inject,
                    args: [MAT_DEFAULT_ACITONS]
                }] }, { type: MatTimeSelectionModel }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [MAT_TIMEPICKER_DEFAULT_OPTIONS]
                }] }], propDecorators: { disabled: [{
                type: Input
            }], opened: [{
                type: Input
            }], openAs: [{
                type: Input
            }], color: [{
                type: Input
            }], mode: [{
                type: Input
            }], format: [{
                type: Input
            }], showToggleModeButton: [{
                type: Input
            }], minuteInterval: [{
                type: Input
            }], orientation: [{
                type: Input
            }], touchUi: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], xPosition: [{
                type: Input
            }], yPosition: [{
                type: Input
            }], restoreFocus: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], openedStream: [{
                type: Output,
                args: ['opened']
            }], closedStream: [{
                type: Output,
                args: ['closed']
            }] } });

class MatTimepicker extends MatTimepickerBase {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepicker, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepicker, isStandalone: true, selector: "mat-timepicker", host: { properties: { "class.mat-primary": "color !== \"accent\" && color !== \"warn\"", "class.mat-accent": "color === \"accent\"", "class.mat-warn": "color === \"warn\"" }, classAttribute: "mat-timepicker" }, providers: [
            MAT_SINGLE_TIME_SELECTION_MODEL_PROVIDER,
            { provide: MatTimepickerBase, useExisting: MatTimepicker },
        ], exportAs: ["matTimepicker"], usesInheritance: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepicker, decorators: [{
            type: Component,
            args: [{
                    selector: 'mat-timepicker',
                    standalone: true,
                    template: '',
                    exportAs: 'matTimepicker',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    encapsulation: ViewEncapsulation.None,
                    host: {
                        class: 'mat-timepicker',
                        '[class.mat-primary]': 'color !== "accent" && color !== "warn"',
                        '[class.mat-accent]': 'color === "accent"',
                        '[class.mat-warn]': 'color === "warn"',
                    },
                    providers: [
                        MAT_SINGLE_TIME_SELECTION_MODEL_PROVIDER,
                        { provide: MatTimepickerBase, useExisting: MatTimepicker },
                    ],
                }]
        }] });

/**
 * An event used for timepicker input and change events. We don't always have access to a native
 * input or change event because the event may have been triggered by the user clicking on the
 * clock popup. For consistency, we always use MatTimepickerInputEvent instead.
 */
class MatTimepickerInputEvent {
    constructor(
    /** Reference to the timepicker input component that emitted the event. */
    target, 
    /** Reference to the native input element associated with the timepicker input. */
    targetElement) {
        this.target = target;
        this.targetElement = targetElement;
        this.value = this.target.value;
    }
}
const TIME_FORMATS = { hour: '2-digit', minute: '2-digit' };
class MatTimepickerInputBase {
    /** The value of the input. */
    get value() {
        return this._model
            ? this._getValueFromModel(this._model.selection)
            : this._pendingValue;
    }
    set value(value) {
        this._assignValueProgrammatically(value);
    }
    /** Whether the timepicker-input is disabled. */
    get disabled() {
        return !!this._disabled;
    }
    set disabled(value) {
        const newValue = coerceBooleanProperty(value);
        const element = this._elementRef.nativeElement;
        if (this._disabled !== newValue) {
            this._disabled = newValue;
            this.stateChanges.next(undefined);
        }
        // We need to null check the `blur` method, because it's undefined during SSR.
        // In Ivy static bindings are invoked earlier, before the element is attached to the DOM.
        // This can cause an error to be thrown in some browsers (IE/Edge) which assert that the
        // element has been inserted.
        if (newValue && this._isInitialized && element.blur) {
            // Normally, native input elements automatically blur if they turn disabled. This behavior
            // is problematic, because it would mean that it triggers another change detection cycle,
            // which then causes a changed after checked error if the input element was focused before.
            element.blur();
        }
    }
    constructor(_elementRef, _timeAdapter) {
        this._elementRef = _elementRef;
        this._timeAdapter = _timeAdapter;
        /** Emits when a change event is fired on this <input>. */
        this.timeChange = new EventEmitter();
        /** Emits when an input event is fired on this <input>. */
        this.timeInput = new EventEmitter();
        /** Emits when the internal state has changed */
        this.stateChanges = new Subject();
        this._onTouched = () => { };
        this._validatorOnChange = () => { };
        this._cvaOnChange = () => { };
        this._valueChangesSubscription = Subscription.EMPTY;
        /** Whether the last value set on the input was valid. */
        this._lastValueValid = false;
        /** The form control validator for whether the input parses. */
        this._parseValidator = () => {
            return this._lastValueValid
                ? null
                : { matTimepickerParse: { text: this._elementRef.nativeElement.value } };
        };
        /** The form control validator for the min time. */
        this._minValidator = (control) => {
            const controlValue = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(control.value));
            const min = this._getMinTime();
            return !min ||
                !controlValue ||
                this._timeAdapter.compareTime(min, controlValue) <= 0
                ? null
                : { matTimepickerMin: { min, actual: controlValue } };
        };
        /** The form control validator for the max time. */
        this._maxValidator = (control) => {
            const controlValue = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(control.value));
            const max = this._getMaxTime();
            return !max ||
                !controlValue ||
                this._timeAdapter.compareTime(max, controlValue) >= 0
                ? null
                : { matTimepickerMax: { max, actual: controlValue } };
        };
    }
    ngOnChanges(changes) {
        if (timeInputsHaveChanged(changes, this._timeAdapter)) {
            this.stateChanges.next(undefined);
        }
    }
    ngOnDestroy() {
        this._valueChangesSubscription.unsubscribe();
        this.stateChanges.complete();
    }
    /** Registers a time selection model with the input. */
    _registerModel(model) {
        this._model = model;
        this._valueChangesSubscription.unsubscribe();
        if (this._pendingValue) {
            this._assignValue(this._pendingValue);
        }
        this._valueChangesSubscription = this._model.selectionChanged.subscribe((event) => {
            if (this._shouldHandleChangeEvent(event)) {
                const value = this._getValueFromModel(event.selection);
                this._lastValueValid = this._isValidValue(value);
                this._cvaOnChange(value);
                this._onTouched();
                this._formatValue(value);
                this.timeInput.emit(new MatTimepickerInputEvent(this, this._elementRef.nativeElement));
                this.timeChange.emit(new MatTimepickerInputEvent(this, this._elementRef.nativeElement));
            }
        });
    }
    _onInput(value) {
        const lastValueWasValid = this._lastValueValid;
        let time = this._timeAdapter.parse(value, TIME_FORMATS);
        this._lastValueValid = this._isValidValue(time);
        time = this._timeAdapter.getValidTimeOrNull(time);
        const hasChanged = !this._timeAdapter.sameTime(time, this.value);
        // We need to fire the CVA change event for all
        // nulls, otherwise the validators won't run.
        if (!time || hasChanged) {
            this._cvaOnChange(time);
        }
        else {
            // Call the CVA change handler for invalid values
            // since this is what marks the control as dirty.
            if (value && !this.value) {
                this._cvaOnChange(time);
            }
            if (lastValueWasValid !== this._lastValueValid) {
                this._validatorOnChange();
            }
        }
        if (hasChanged) {
            this._assignValue(time);
            this.timeInput.emit(new MatTimepickerInputEvent(this, this._elementRef.nativeElement));
        }
    }
    /** Handles change event on the input. */
    _onChange() {
        this.timeChange.emit(new MatTimepickerInputEvent(this, this._elementRef.nativeElement));
    }
    /** Handles blur event on the input. */
    _onBlur() {
        // Reformat the input only if we have a valid value.
        if (this.value) {
            this._formatValue(this.value);
        }
        this._onTouched();
    }
    /** Implemented as part of ControlValueAccessor.  */
    writeValue(value) {
        this.value = value;
    }
    /** Implemented as part of ControlValueAccessor.  */
    registerOnChange(fn) {
        this._cvaOnChange = fn;
    }
    /** Implemented as part of ControlValueAccessor.  */
    registerOnTouched(fn) {
        this._onTouched = fn;
    }
    /** Implemented as part of ControlValueAccessor.  */
    setDisabledState(isDisabled) {
        this.disabled = isDisabled;
    }
    registerOnValidatorChange(fn) {
        this._validatorOnChange = fn;
    }
    validate(c) {
        return this._validator ? this._validator(c) : null;
    }
    /** Programmatically assigns a value to the input. */
    _assignValueProgrammatically(value) {
        value = this._timeAdapter.deserialize(value);
        this._lastValueValid = this._isValidValue(value);
        value = this._timeAdapter.getValidTimeOrNull(value);
        this._assignValue(value);
        this._formatValue(value);
    }
    /** Formats a value and sets it on the input element. */
    _formatValue(value) {
        this._elementRef.nativeElement.value =
            value != null ? this._timeAdapter.format(value, TIME_FORMATS) : '';
    }
    /** Gets the base validator functions. */
    _getValidators() {
        return [this._parseValidator, this._minValidator, this._maxValidator];
    }
    /** Whether a value is considered valid. */
    _isValidValue(value) {
        return !value || this._timeAdapter.isValid(value);
    }
    /** Assigns a value to the model. */
    _assignValue(value) {
        // We may get some incoming values before the model was
        // assigned. Save the value so that we can assign it later.
        if (this._model) {
            this._assignValueToModel(value);
            this._pendingValue = null;
        }
        else {
            this._pendingValue = value;
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerInputBase, deps: [{ token: i0.ElementRef }, { token: TimeAdapter, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerInputBase, isStandalone: true, inputs: { value: "value", disabled: "disabled" }, outputs: { timeChange: "timeChange", timeInput: "timeInput" }, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerInputBase, decorators: [{
            type: Directive
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: TimeAdapter, decorators: [{
                    type: Optional
                }] }], propDecorators: { value: [{
                type: Input
            }], disabled: [{
                type: Input
            }], timeChange: [{
                type: Output
            }], timeInput: [{
                type: Output
            }] } });
/**
 * Checks whether the `SimpleChanges` object from an `ngOnChanges`
 * callback has any changes, accounting for time objects.
 */
function timeInputsHaveChanged(changes, adapter) {
    const keys = Object.keys(changes);
    for (const key of keys) {
        const { previousValue, currentValue } = changes[key];
        if (adapter.isTimeInstance(previousValue) &&
            adapter.isTimeInstance(currentValue)) {
            if (!adapter.sameTime(previousValue, currentValue)) {
                return true;
            }
        }
        else {
            return true;
        }
    }
    return false;
}

const MAT_TIMEPICKER_VALUE_ACCESSOR = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => MatTimepickerInput),
    multi: true,
};
const MAT_TIMEPICKER_VALIDATORS = {
    provide: NG_VALIDATORS,
    useExisting: forwardRef(() => MatTimepickerInput),
    multi: true,
};
/** Directive used to connect an input to a MatTimepicker. */
class MatTimepickerInput extends MatTimepickerInputBase {
    /** The timepicker that this input is associated with. */
    set matTimepicker(timepicker) {
        if (timepicker) {
            this._timepicker = timepicker;
            this._registerModel(timepicker.registerInput(this));
        }
    }
    /** The minimum valid date. */
    get min() {
        return this._min;
    }
    set min(value) {
        const validValue = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(value));
        if (!this._timeAdapter.sameTime(validValue, this._min)) {
            this._min = validValue;
            this._validatorOnChange();
        }
    }
    /** The maximum valid date. */
    get max() {
        return this._max;
    }
    set max(value) {
        const validValue = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(value));
        if (!this._timeAdapter.sameTime(validValue, this._max)) {
            this._max = validValue;
            this._validatorOnChange();
        }
    }
    constructor(elementRef, timeAdapter, _formField) {
        super(elementRef, timeAdapter);
        this._formField = _formField;
        this._validator = Validators.compose(super._getValidators());
    }
    /**
     * Gets the element that the timepicker popup should be connected to.
     * @return The element to connect the popup to.
     */
    getConnectedOverlayOrigin() {
        return this._formField ? this._formField.getConnectedOverlayOrigin() : this._elementRef;
    }
    /** Returns the palette used by the input's form field, if any. */
    getThemePalette() {
        return this._formField ? this._formField.color : undefined;
    }
    /** Gets the ID of an element that should be used a description for the timepicker overlay. */
    getOverlayLabelId() {
        if (this._formField) {
            return this._formField.getLabelId();
        }
        return this._elementRef.nativeElement.getAttribute('aria-labelledby');
    }
    /** Gets the input's minimum time. */
    _getMinTime() {
        return this._min;
    }
    /** Gets the input's maximum time. */
    _getMaxTime() {
        return this._max;
    }
    _assignValueToModel(value) {
        if (this._model) {
            this._model.updateSelection(value, this);
        }
    }
    _getValueFromModel(modelValue) {
        return modelValue;
    }
    _shouldHandleChangeEvent(event) {
        return event.source !== this;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerInput, deps: [{ token: i0.ElementRef }, { token: TimeAdapter, optional: true }, { token: MAT_FORM_FIELD, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerInput, isStandalone: true, selector: "input[matTimepicker]", inputs: { matTimepicker: "matTimepicker", min: "min", max: "max" }, host: { listeners: { "input": "_onInput($event.target.value)", "change": "_onChange()", "blur": "_onBlur()" }, properties: { "attr.aria-haspopup": "_timepicker ? \"dialog\" : null", "attr.aria-owns": "(_timepicker?.opened && _timepicker.id) || null", "attr.min": "min || null", "attr.max": "max || null", "disabled": "disabled" }, classAttribute: "mat-timepicker-input" }, providers: [
            MAT_TIMEPICKER_VALUE_ACCESSOR,
            MAT_TIMEPICKER_VALIDATORS,
            { provide: MAT_INPUT_VALUE_ACCESSOR, useExisting: MatTimepickerInput },
        ], exportAs: ["matTimepickerInput"], usesInheritance: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerInput, decorators: [{
            type: Directive,
            args: [{
                    selector: 'input[matTimepicker]',
                    standalone: true,
                    exportAs: 'matTimepickerInput',
                    providers: [
                        MAT_TIMEPICKER_VALUE_ACCESSOR,
                        MAT_TIMEPICKER_VALIDATORS,
                        { provide: MAT_INPUT_VALUE_ACCESSOR, useExisting: MatTimepickerInput },
                    ],
                    host: {
                        class: 'mat-timepicker-input',
                        '[attr.aria-haspopup]': '_timepicker ? "dialog" : null',
                        '[attr.aria-owns]': '(_timepicker?.opened && _timepicker.id) || null',
                        '[attr.min]': 'min || null',
                        '[attr.max]': 'max || null',
                        '[disabled]': 'disabled',
                        '(input)': '_onInput($event.target.value)',
                        '(change)': '_onChange()',
                        '(blur)': '_onBlur()',
                    },
                }]
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: TimeAdapter, decorators: [{
                    type: Optional
                }] }, { type: i4.MatFormField, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [MAT_FORM_FIELD]
                }] }], propDecorators: { matTimepicker: [{
                type: Input
            }], min: [{
                type: Input
            }], max: [{
                type: Input
            }] } });

/** Button that will close the timepicker and assign the current selection to the data model. */
class MatTimepickerApply {
    constructor(_timepicker) {
        this._timepicker = _timepicker;
    }
    _applySelection() {
        this._timepicker._applyPendingSelection();
        this._timepicker.close();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerApply, deps: [{ token: MatTimepickerBase }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerApply, isStandalone: true, selector: "[matTimepickerApply]", host: { listeners: { "click": "_applySelection()" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerApply, decorators: [{
            type: Directive,
            args: [{
                    selector: '[matTimepickerApply]',
                    standalone: true,
                    host: {
                        '(click)': '_applySelection()',
                    },
                }]
        }], ctorParameters: () => [{ type: MatTimepickerBase }] });
/** Button that will close the timepicker and discard the current selection. */
class MatTimepickerCancel {
    constructor(_timepicker) {
        this._timepicker = _timepicker;
    }
    close() {
        this._timepicker.close();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerCancel, deps: [{ token: MatTimepickerBase }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerCancel, isStandalone: true, selector: "[matTimepickerCancel]", host: { listeners: { "click": "close()" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerCancel, decorators: [{
            type: Directive,
            args: [{
                    selector: '[matTimepickerCancel]',
                    standalone: true,
                    host: {
                        '(click)': 'close()',
                    },
                }]
        }], ctorParameters: () => [{ type: MatTimepickerBase }] });
/**
 * Container that can be used to project a row of action buttons
 * to the bottom of a timepicker.
 */
class MatTimepickerActions {
    constructor(_timepicker, _viewContainerRef) {
        this._timepicker = _timepicker;
        this._viewContainerRef = _viewContainerRef;
    }
    ngAfterViewInit() {
        this._portal = new TemplatePortal(this._template, this._viewContainerRef);
        this._timepicker.registerActions(this._portal);
    }
    ngOnDestroy() {
        this._timepicker.removeActions(this._portal);
        // Needs to be null checked since we initialize it in `ngAfterViewInit`.
        if (this._portal && this._portal.isAttached) {
            this._portal?.detach();
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerActions, deps: [{ token: MatTimepickerBase }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerActions, isStandalone: true, selector: "mat-timepicker-actions", host: { classAttribute: "mat-timepicker-actions-container" }, viewQueries: [{ propertyName: "_template", first: true, predicate: TemplateRef, descendants: true }], ngImport: i0, template: `
    <ng-template>
      <div class="mat-timepicker-actions">
        <ng-content></ng-content>
      </div>
    </ng-template>
  `, isInline: true, styles: [".mat-timepicker-actions-container{margin-left:auto}.mat-timepicker-actions{display:flex;gap:.5rem;align-items:center;margin-top:.5rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerActions, decorators: [{
            type: Component,
            args: [{ selector: 'mat-timepicker-actions', standalone: true, template: `
    <ng-template>
      <div class="mat-timepicker-actions">
        <ng-content></ng-content>
      </div>
    </ng-template>
  `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        class: 'mat-timepicker-actions-container',
                    }, styles: [".mat-timepicker-actions-container{margin-left:auto}.mat-timepicker-actions{display:flex;gap:.5rem;align-items:center;margin-top:.5rem}\n"] }]
        }], ctorParameters: () => [{ type: MatTimepickerBase }, { type: i0.ViewContainerRef }], propDecorators: { _template: [{
                type: ViewChild,
                args: [TemplateRef]
            }] } });
/**
 * Default action buttons to the bottom of a timepicker.
 */
class MatTimepickerDefaultActions {
    constructor(_timepicker, _intl) {
        this._timepicker = _timepicker;
        this._intl = _intl;
        this.color = signal(undefined);
    }
    ngOnInit() {
        this.color.set(this._timepicker.color);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerDefaultActions, deps: [{ token: MatTimepickerBase }, { token: MatTimepickerIntl }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerDefaultActions, isStandalone: true, selector: "mat-timepicker-default-actions", host: { classAttribute: "mat-timepicker-actions-container" }, ngImport: i0, template: `
    <div class="mat-timepicker-actions">
      <ng-content></ng-content>
      <button [color]="color()" mat-button matTimepickerCancel>
        {{ _intl.cancelButton }}
      </button>
      <button [color]="color()" mat-button matTimepickerApply>
        {{ _intl.okButton }}
      </button>
    </div>
  `, isInline: true, styles: [".mat-timepicker-actions-container{margin-left:auto}.mat-timepicker-actions{display:flex;gap:.5rem;align-items:center;margin-top:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: "    button[mat-button], button[mat-raised-button], button[mat-flat-button],    button[mat-stroked-button]  ", exportAs: ["matButton"] }, { kind: "directive", type: MatTimepickerApply, selector: "[matTimepickerApply]" }, { kind: "directive", type: MatTimepickerCancel, selector: "[matTimepickerCancel]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerDefaultActions, decorators: [{
            type: Component,
            args: [{ selector: 'mat-timepicker-default-actions', standalone: true, imports: [MatButtonModule, MatTimepickerApply, MatTimepickerCancel], template: `
    <div class="mat-timepicker-actions">
      <ng-content></ng-content>
      <button [color]="color()" mat-button matTimepickerCancel>
        {{ _intl.cancelButton }}
      </button>
      <button [color]="color()" mat-button matTimepickerApply>
        {{ _intl.okButton }}
      </button>
    </div>
  `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        class: 'mat-timepicker-actions-container',
                    }, styles: [".mat-timepicker-actions-container{margin-left:auto}.mat-timepicker-actions{display:flex;gap:.5rem;align-items:center;margin-top:.5rem}\n"] }]
        }], ctorParameters: () => [{ type: MatTimepickerBase }, { type: MatTimepickerIntl }] });

class MatTimepickerModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerModule, imports: [OverlayModule,
            PortalModule,
            A11yModule,
            MatTimepicker,
            MatTimepickerToggle,
            MatTimepickerToggleIcon,
            MatTimepickerContent,
            MatTimepickerContentLayout,
            MatTimepickerInput,
            MatTimeInputs,
            MatHourInput,
            MatMinuteInput,
            MatClockDials,
            MatHoursClockDial,
            MatMinutesClockDial,
            MatTimePeriod,
            MatTimepickerActions,
            MatTimepickerDefaultActions,
            MatTimepickerApply,
            MatTimepickerCancel], exports: [CdkScrollableModule,
            MatTimepicker,
            MatTimepickerToggle,
            MatTimepickerToggleIcon,
            MatTimepickerContent,
            MatTimepickerContentLayout,
            MatTimepickerInput,
            MatTimeInputs,
            MatHourInput,
            MatMinuteInput,
            MatClockDials,
            MatHoursClockDial,
            MatMinutesClockDial,
            MatTimePeriod,
            MatTimepickerActions,
            MatTimepickerDefaultActions,
            MatTimepickerApply,
            MatTimepickerCancel] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerModule, providers: [
            MatTimepickerIntl,
            MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER,
            { provide: MAT_DEFAULT_ACITONS, useValue: MatTimepickerDefaultActions },
            {
                provide: MAT_FAB_DEFAULT_OPTIONS,
                useValue: { color: 'unthemed' },
            },
        ], imports: [OverlayModule,
            PortalModule,
            A11yModule,
            MatTimepickerToggle,
            MatTimepickerContent,
            MatTimeInputs,
            MatClockDials,
            MatHoursClockDial,
            MatMinutesClockDial,
            MatTimePeriod,
            MatTimepickerDefaultActions, CdkScrollableModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [],
                    imports: [
                        OverlayModule,
                        PortalModule,
                        A11yModule,
                        MatTimepicker,
                        MatTimepickerToggle,
                        MatTimepickerToggleIcon,
                        MatTimepickerContent,
                        MatTimepickerContentLayout,
                        MatTimepickerInput,
                        MatTimeInputs,
                        MatHourInput,
                        MatMinuteInput,
                        MatClockDials,
                        MatHoursClockDial,
                        MatMinutesClockDial,
                        MatTimePeriod,
                        MatTimepickerActions,
                        MatTimepickerDefaultActions,
                        MatTimepickerApply,
                        MatTimepickerCancel,
                    ],
                    exports: [
                        CdkScrollableModule,
                        MatTimepicker,
                        MatTimepickerToggle,
                        MatTimepickerToggleIcon,
                        MatTimepickerContent,
                        MatTimepickerContentLayout,
                        MatTimepickerInput,
                        MatTimeInputs,
                        MatHourInput,
                        MatMinuteInput,
                        MatClockDials,
                        MatHoursClockDial,
                        MatMinutesClockDial,
                        MatTimePeriod,
                        MatTimepickerActions,
                        MatTimepickerDefaultActions,
                        MatTimepickerApply,
                        MatTimepickerCancel,
                    ],
                    providers: [
                        MatTimepickerIntl,
                        MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER,
                        { provide: MAT_DEFAULT_ACITONS, useValue: MatTimepickerDefaultActions },
                        {
                            provide: MAT_FAB_DEFAULT_OPTIONS,
                            useValue: { color: 'unthemed' },
                        },
                    ],
                }]
        }] });

/*
 * Public API Surface of mat-timepicker
 */

/**
 * Generated bundle index. Do not edit.
 */

export { ALL_HOURS, ALL_MINUTES, MAT_DATE_TIME_LOCALE_FACTORY, MAT_DEFAULT_ACITONS, MAT_TIMEPICKER_DEFAULT_OPTIONS, MAT_TIMEPICKER_SCROLL_STRATEGY, MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY, MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER, MAT_TIMEPICKER_VALIDATORS, MAT_TIMEPICKER_VALUE_ACCESSOR, MAT_TIME_LOCALE, MAT_TIME_LOCALE_PROVIDER, MatClockDials, MatHourInput, MatHoursClockDial, MatMinuteInput, MatMinutesClockDial, MatNativeDateTimeModule, MatTimeInputs, MatTimePeriod, MatTimepicker, MatTimepickerActions, MatTimepickerApply, MatTimepickerBase, MatTimepickerCancel, MatTimepickerContent, MatTimepickerContentLayout, MatTimepickerDefaultActions, MatTimepickerInput, MatTimepickerInputBase, MatTimepickerInputEvent, MatTimepickerIntl, MatTimepickerModule, MatTimepickerToggle, MatTimepickerToggleIcon, NativeDateTimeAdapter, NativeDateTimeModule, TimeAdapter, provideNativeDateTimeAdapter, timeInputsHaveChanged };
//# sourceMappingURL=dhutaryan-ngx-mat-timepicker.mjs.map