import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { inject, ElementRef, input, output, viewChild, signal, computed, effect, afterNextRender, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
import * as i1 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { TranslatePipe } from '@ngx-translate/core';
import { ZButtonComponent } from '@shival99/z-ui/components/z-button';
import { ZIconComponent } from '@shival99/z-ui/components/z-icon';
import { ZPopoverDirective } from '@shival99/z-ui/components/z-popover';
import { zMergeClasses } from '@shival99/z-ui/utils';
import { cva } from 'class-variance-authority';

const zMediaPlayerVariants = cva('relative overflow-hidden bg-black select-none transition-all duration-300 w-full flex flex-col justify-center items-center group/player outline-none', {
    variants: {
        zLayout: {
            default: 'aspect-video rounded-md shadow-md max-w-5xl mx-auto',
            theater: 'w-full aspect-[21/9] max-w-full',
            fullscreen: 'fixed inset-0 w-screen h-screen z-[9999] rounded-none max-w-full aspect-none',
        },
    },
    defaultVariants: {
        zLayout: 'default',
    },
});

class ZMediaPlayerComponent {
    _elementRef = inject((ElementRef));
    // Inputs
    class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
    zSrc = input.required(...(ngDevMode ? [{ debugName: "zSrc" }] : []));
    zSources = input([], ...(ngDevMode ? [{ debugName: "zSources" }] : []));
    zPoster = input('', ...(ngDevMode ? [{ debugName: "zPoster" }] : []));
    zAutoplay = input(false, ...(ngDevMode ? [{ debugName: "zAutoplay" }] : []));
    zLoop = input(false, ...(ngDevMode ? [{ debugName: "zLoop" }] : []));
    zMuted = input(false, ...(ngDevMode ? [{ debugName: "zMuted" }] : []));
    zVolume = input(1.0, ...(ngDevMode ? [{ debugName: "zVolume" }] : []));
    zSubtitles = input([], ...(ngDevMode ? [{ debugName: "zSubtitles" }] : []));
    // Outputs
    zPlay = output();
    zTimeUpdate = output();
    zVolumeChange = output();
    zFullscreenChange = output();
    zTheaterModeChange = output();
    zMiniplayerChange = output();
    zQualityChange = output();
    // Element Refs sử dụng signal viewChild thay vì decorator
    videoElement = viewChild('videoElement', ...(ngDevMode ? [{ debugName: "videoElement" }] : []));
    timelineContainer = viewChild('timelineContainer', ...(ngDevMode ? [{ debugName: "timelineContainer" }] : []));
    // Component Signals trạng thái trình phát
    isPlaying = signal(false, ...(ngDevMode ? [{ debugName: "isPlaying" }] : []));
    currentTime = signal(0, ...(ngDevMode ? [{ debugName: "currentTime" }] : []));
    duration = signal(0, ...(ngDevMode ? [{ debugName: "duration" }] : []));
    volume = signal(1.0, ...(ngDevMode ? [{ debugName: "volume" }] : []));
    isMuted = signal(false, ...(ngDevMode ? [{ debugName: "isMuted" }] : []));
    playbackSpeed = signal(1.0, ...(ngDevMode ? [{ debugName: "playbackSpeed" }] : []));
    activeSourceSrc = signal(null, ...(ngDevMode ? [{ debugName: "activeSourceSrc" }] : []));
    showControls = signal(true, ...(ngDevMode ? [{ debugName: "showControls" }] : []));
    isBuffering = signal(false, ...(ngDevMode ? [{ debugName: "isBuffering" }] : []));
    captionsEnabled = signal(false, ...(ngDevMode ? [{ debugName: "captionsEnabled" }] : []));
    isTheaterMode = signal(false, ...(ngDevMode ? [{ debugName: "isTheaterMode" }] : []));
    isFullscreen = signal(false, ...(ngDevMode ? [{ debugName: "isFullscreen" }] : []));
    isMiniplayer = signal(false, ...(ngDevMode ? [{ debugName: "isMiniplayer" }] : []));
    showSettings = signal(false, ...(ngDevMode ? [{ debugName: "showSettings" }] : []));
    settingsPanel = signal('main', ...(ngDevMode ? [{ debugName: "settingsPanel" }] : []));
    isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
    // Tiến trình đệm và phát
    bufferedProgress = signal(0, ...(ngDevMode ? [{ debugName: "bufferedProgress" }] : []));
    progress = computed(() => {
        const dur = this.duration();
        if (dur === 0) {
            return 0;
        }
        return (this.currentTime() / dur) * 100;
    }, ...(ngDevMode ? [{ debugName: "progress" }] : []));
    // Trạng thái visual hiển thị
    playPauseFlash = signal(null, ...(ngDevMode ? [{ debugName: "playPauseFlash" }] : []));
    hoverTimeLabel = signal(null, ...(ngDevMode ? [{ debugName: "hoverTimeLabel" }] : []));
    hoverX = signal(0, ...(ngDevMode ? [{ debugName: "hoverX" }] : []));
    // Lớp phủ tua nhanh nhảy số cộng dồn kiểu YouTube
    skipOverlayDirection = signal(null, ...(ngDevMode ? [{ debugName: "skipOverlayDirection" }] : []));
    skipOverlayValue = signal(0, ...(ngDevMode ? [{ debugName: "skipOverlayValue" }] : []));
    skipOverlayPulse = signal(0, ...(ngDevMode ? [{ debugName: "skipOverlayPulse" }] : []));
    // Kiểm tra trình duyệt hỗ trợ Picture-in-Picture
    isPiPSupported = computed(() => {
        if (typeof document === 'undefined') {
            return false;
        }
        const doc = document;
        const hasPiP = doc.pictureInPictureEnabled;
        const hasRequestPiP = typeof HTMLVideoElement !== 'undefined' && 'requestPictureInPicture' in HTMLVideoElement.prototype;
        if (hasPiP && hasRequestPiP) {
            return true;
        }
        const video = this.videoElement()?.nativeElement;
        if (video) {
            const hasWebkit = 'webkitSupportsPresentationMode' in video &&
                typeof video.webkitSupportsPresentationMode === 'function' &&
                video.webkitSupportsPresentationMode('picture-in-picture');
            return !!hasWebkit;
        }
        const hasWebkitProto = typeof HTMLVideoElement !== 'undefined' &&
            'webkitSupportsPresentationMode' in HTMLVideoElement.prototype &&
            'webkitSetPresentationMode' in HTMLVideoElement.prototype;
        return hasWebkitProto;
    }, ...(ngDevMode ? [{ debugName: "isPiPSupported" }] : []));
    // Danh sách các tốc độ phát video
    playbackSpeeds = [
        { label: '0.25x', value: 0.25 },
        { label: '0.5x', value: 0.5 },
        { label: '0.75x', value: 0.75 },
        { label: 'i18n_z_ui_media_player_normal', value: 1.0 },
        { label: '1.25x', value: 1.25 },
        { label: '1.5x', value: 1.5 },
        { label: '2.0x', value: 2.0 },
    ];
    // Lưu trữ Timer ẩn thanh điều khiển và điều hướng
    _controlsTimeout = null;
    _flashTimeout = null;
    _skipOverlayTimeout = null;
    _clickTimeout = null;
    _accumulatedSkip = 0;
    // Cập nhật CVA class dựa trên các trạng thái giao diện
    zClasses = computed(() => {
        let layout = 'default';
        if (this.isTheaterMode()) {
            layout = 'theater';
        }
        if (this.isFullscreen()) {
            layout = 'fullscreen';
        }
        return zMergeClasses(zMediaPlayerVariants({ zLayout: layout }), this.class());
    }, ...(ngDevMode ? [{ debugName: "zClasses" }] : []));
    // Nhãn thời gian hiển thị computed signals
    currentTimeLabel = computed(() => this._formatTime(this.currentTime()), ...(ngDevMode ? [{ debugName: "currentTimeLabel" }] : []));
    durationLabel = computed(() => this._formatTime(this.duration()), ...(ngDevMode ? [{ debugName: "durationLabel" }] : []));
    effectiveSrc = computed(() => this.activeSourceSrc() ?? this.zSrc(), ...(ngDevMode ? [{ debugName: "effectiveSrc" }] : []));
    qualitySources = computed(() => this.zSources().filter(source => !!source.src), ...(ngDevMode ? [{ debugName: "qualitySources" }] : []));
    activeQualityLabel = computed(() => {
        const activeSrc = this.effectiveSrc();
        return this.qualitySources().find(source => source.src === activeSrc)?.label ?? 'Auto';
    }, ...(ngDevMode ? [{ debugName: "activeQualityLabel" }] : []));
    constructor() {
        effect(() => {
            const fallbackSrc = this.zSrc();
            const sources = this.qualitySources();
            const currentSrc = this.activeSourceSrc();
            if (currentSrc && (currentSrc === fallbackSrc || sources.some(source => source.src === currentSrc))) {
                return;
            }
            this.activeSourceSrc.set(sources[0]?.src ?? fallbackSrc);
        });
        effect(() => {
            const src = this.effectiveSrc();
            const video = this.videoElement()?.nativeElement;
            if (video) {
                if (video.src !== src) {
                    video.src = src;
                }
                video.load();
            }
        });
        afterNextRender(() => {
            this._initializeVideoState();
        });
    }
    ngOnDestroy() {
        if (this._controlsTimeout) {
            clearTimeout(this._controlsTimeout);
        }
        if (this._flashTimeout) {
            clearTimeout(this._flashTimeout);
        }
        if (this._skipOverlayTimeout) {
            clearTimeout(this._skipOverlayTimeout);
        }
        if (this._clickTimeout) {
            clearTimeout(this._clickTimeout);
        }
    }
    // Khởi tạo trạng thái âm lượng và tắt tiếng khi bắt đầu render
    _initializeVideoState() {
        const video = this.videoElement()?.nativeElement;
        if (!video) {
            return;
        }
        video.volume = this.zVolume();
        this.volume.set(this.zVolume());
        video.muted = this.zMuted();
        this.isMuted.set(this.zMuted());
        this._resetControlsTimer();
    }
    // Thay đổi trạng thái Phát / Tạm dừng
    togglePlay() {
        const video = this.videoElement()?.nativeElement;
        if (!video) {
            return;
        }
        if (video.paused) {
            video.play().catch(console.error);
            this._triggerFlashIcon('play');
            return;
        }
        video.pause();
        this._triggerFlashIcon('pause');
    }
    // Kích hoạt flash icon giữa màn hình
    _triggerFlashIcon(type) {
        if (this._flashTimeout) {
            clearTimeout(this._flashTimeout);
        }
        this.playPauseFlash.set(type);
        this._flashTimeout = setTimeout(() => {
            this.playPauseFlash.set(null);
        }, 500);
    }
    // Bật / tắt tiếng (Mute)
    toggleMute() {
        const video = this.videoElement()?.nativeElement;
        if (!video) {
            return;
        }
        const nextMuted = !video.muted;
        video.muted = nextMuted;
        this.isMuted.set(nextMuted);
        this.zVolumeChange.emit(nextMuted ? 0 : this.volume());
    }
    // Điều chỉnh mức âm lượng từ slider
    onVolumeChange(val) {
        const video = this.videoElement()?.nativeElement;
        if (!video) {
            return;
        }
        video.volume = val;
        this.volume.set(val);
        const isSilent = val === 0;
        video.muted = isSilent;
        this.isMuted.set(isSilent);
        this.zVolumeChange.emit(val);
    }
    // Đặt tốc độ phát video
    setPlaybackSpeed(speed) {
        const video = this.videoElement()?.nativeElement;
        if (!video) {
            return;
        }
        video.playbackRate = speed;
        this.playbackSpeed.set(speed);
        this.closeSettingsPanel();
    }
    openSettingsPanel(panel) {
        this.settingsPanel.set(panel);
    }
    closeSettingsPanel() {
        this.settingsPanel.set('main');
    }
    onSettingsHidden() {
        this.showSettings.set(false);
        this.closeSettingsPanel();
        this.onMouseMove();
    }
    setQualitySource(source) {
        if (source.src === this.effectiveSrc()) {
            this.closeSettingsPanel();
            return;
        }
        const video = this.videoElement()?.nativeElement;
        const current = video?.currentTime ?? this.currentTime();
        const shouldResume = !!video && !video.paused;
        const playbackRate = video?.playbackRate ?? this.playbackSpeed();
        if (video) {
            let didResume = false;
            const restorePosition = () => {
                const safeTime = Number.isFinite(video.duration) ? Math.min(current, video.duration) : current;
                video.playbackRate = playbackRate;
                video.currentTime = safeTime;
                this.currentTime.set(safeTime);
                if (shouldResume && !didResume) {
                    didResume = true;
                    video.play().catch(console.error);
                }
            };
            video.addEventListener('loadedmetadata', restorePosition, { once: true });
            video.addEventListener('loadeddata', restorePosition, { once: true });
        }
        this.activeSourceSrc.set(source.src);
        this.bufferedProgress.set(0);
        this.zQualityChange.emit(source);
        this.closeSettingsPanel();
    }
    // Tua đến mốc thời gian chỉ định
    seekTo(time) {
        const video = this.videoElement()?.nativeElement;
        if (!video) {
            return;
        }
        video.currentTime = time;
        this.currentTime.set(time);
    }
    // Bật/tắt chế độ rạp phim (Theater Mode)
    toggleTheaterMode() {
        if (this.isFullscreen()) {
            return;
        }
        const nextState = !this.isTheaterMode();
        this.isTheaterMode.set(nextState);
        this.zTheaterModeChange.emit(nextState);
    }
    // Bật/tắt chế độ toàn màn hình
    toggleFullscreen() {
        const wrapper = this._elementRef.nativeElement;
        if (!wrapper) {
            return;
        }
        if (document.fullscreenElement) {
            document.exitFullscreen().catch(console.error);
            return;
        }
        wrapper.requestFullscreen().catch(console.error);
    }
    // Lắng nghe sự kiện thay đổi fullscreen (liên kết qua host property của component)
    onFullscreenStateChange() {
        const isFull = !!document.fullscreenElement;
        this.isFullscreen.set(isFull);
        this.zFullscreenChange.emit(isFull);
    }
    // Trình phát thu nhỏ (Picture-in-Picture)
    async toggleMiniplayer() {
        const video = this.videoElement()?.nativeElement;
        if (!video) {
            return;
        }
        try {
            const doc = document;
            if (doc.pictureInPictureEnabled && typeof video.requestPictureInPicture === 'function') {
                if (doc.pictureInPictureElement) {
                    await doc.exitPictureInPicture();
                    this.isMiniplayer.set(false);
                    this.zMiniplayerChange.emit(false);
                    return;
                }
                await video.requestPictureInPicture();
                this.isMiniplayer.set(true);
                this.zMiniplayerChange.emit(true);
                return;
            }
            const webkitVideo = video;
            if ('webkitSupportsPresentationMode' in webkitVideo &&
                typeof webkitVideo.webkitSupportsPresentationMode === 'function' &&
                webkitVideo.webkitSupportsPresentationMode('picture-in-picture')) {
                const currentMode = webkitVideo.webkitPresentationMode;
                const targetMode = currentMode === 'picture-in-picture' ? 'inline' : 'picture-in-picture';
                webkitVideo.webkitSetPresentationMode(targetMode);
                const isPiP = targetMode === 'picture-in-picture';
                this.isMiniplayer.set(isPiP);
                this.zMiniplayerChange.emit(isPiP);
            }
        }
        catch (err) {
            console.warn('Picture-in-Picture API error: ', err);
        }
    }
    onEnterPiP() {
        this.isMiniplayer.set(true);
        this.zMiniplayerChange.emit(true);
    }
    onLeavePiP() {
        this.isMiniplayer.set(false);
        this.zMiniplayerChange.emit(false);
    }
    onWebkitPresentationModeChanged() {
        const video = this.videoElement()?.nativeElement;
        if (video) {
            const isPiP = video.webkitPresentationMode === 'picture-in-picture';
            this.isMiniplayer.set(isPiP);
            this.zMiniplayerChange.emit(isPiP);
        }
    }
    // Bật/tắt hiển thị phụ đề (CC)
    toggleSubtitles() {
        const video = this.videoElement()?.nativeElement;
        if (!video) {
            return;
        }
        const tracks = video.textTracks;
        const currentEnabled = this.captionsEnabled();
        const targetState = !currentEnabled;
        this.captionsEnabled.set(targetState);
        let i = 0;
        while (i < tracks.length) {
            tracks[i].mode = targetState ? 'showing' : 'disabled';
            i++;
        }
    }
    // Cập nhật trạng thái khi video phát/dừng
    onPlayStateChange(playing) {
        this.isPlaying.set(playing);
        this.zPlay.emit(playing);
        this._resetControlsTimer();
    }
    // Cập nhật mốc thời gian phát
    onTimeUpdate() {
        const video = this.videoElement()?.nativeElement;
        if (!video || this.isDragging()) {
            return;
        }
        this.currentTime.set(video.currentTime);
        this.zTimeUpdate.emit(video.currentTime);
        this.updateBufferedProgress();
    }
    onDurationChange() {
        const video = this.videoElement()?.nativeElement;
        if (!video) {
            return;
        }
        this.duration.set(video.duration);
    }
    onSeeking(seeking) {
        this.isBuffering.set(seeking);
    }
    updateBufferedProgress() {
        const video = this.videoElement()?.nativeElement;
        if (!video || video.buffered.length === 0 || this.duration() === 0) {
            return;
        }
        const end = video.buffered.end(video.buffered.length - 1);
        this.bufferedProgress.set((end / this.duration()) * 100);
    }
    // Bắt đầu kéo thanh timeline phát
    onTimelineDragStart(event) {
        event.preventDefault();
        this.isDragging.set(true);
        this._updateTimeFromCoords(event);
        const moveHandler = (moveEvent) => {
            this._updateTimeFromCoords(moveEvent);
        };
        const upHandler = () => {
            this.isDragging.set(false);
            document.removeEventListener('mousemove', moveHandler);
            document.removeEventListener('mouseup', upHandler);
            this._resetControlsTimer();
        };
        document.addEventListener('mousemove', moveHandler);
        document.addEventListener('mouseup', upHandler);
    }
    onTimelineHover(event) {
        const container = this.timelineContainer()?.nativeElement;
        if (!container) {
            return;
        }
        const rect = container.getBoundingClientRect();
        const offsetX = event.clientX - rect.left;
        this.hoverX.set(offsetX);
        const ratio = Math.max(0, Math.min(1, offsetX / rect.width));
        const hoverTime = ratio * this.duration();
        this.hoverTimeLabel.set(this._formatTime(hoverTime));
    }
    onTimelineHoverEnd() {
        this.hoverTimeLabel.set(null);
    }
    _updateTimeFromCoords(event) {
        const container = this.timelineContainer()?.nativeElement;
        if (!container) {
            return;
        }
        const rect = container.getBoundingClientRect();
        const offsetX = event.clientX - rect.left;
        const { width } = rect;
        let ratio = offsetX / width;
        if (ratio < 0) {
            ratio = 0;
        }
        if (ratio > 1) {
            ratio = 1;
        }
        const targetTime = ratio * this.duration();
        const video = this.videoElement()?.nativeElement;
        if (video) {
            video.currentTime = targetTime;
            this.currentTime.set(targetTime);
        }
    }
    // Tải lại bộ đếm thời gian ẩn controls
    onMouseMove() {
        this._resetControlsTimer();
    }
    onMouseLeave() {
        const video = this.videoElement()?.nativeElement;
        if (video && !video.paused && !this.isDragging() && !this.showSettings()) {
            this.showControls.set(false);
        }
    }
    _resetControlsTimer() {
        this.showControls.set(true);
        if (this._controlsTimeout) {
            clearTimeout(this._controlsTimeout);
        }
        const video = this.videoElement()?.nativeElement;
        if (video && !video.paused && !this.showSettings() && !this.isDragging()) {
            this._controlsTimeout = setTimeout(() => {
                this.showControls.set(false);
            }, 3000);
        }
    }
    // Xử lý sự kiện click phân biệt Single-click và Double-click
    onVideoClick(event) {
        if (this._clickTimeout) {
            clearTimeout(this._clickTimeout);
            this._clickTimeout = null;
            this._handleVideoDoubleClick(event);
            return;
        }
        this._clickTimeout = setTimeout(() => {
            this._clickTimeout = null;
            this.togglePlay();
        }, 250);
    }
    _handleVideoDoubleClick(event) {
        const video = this.videoElement()?.nativeElement;
        if (!video) {
            return;
        }
        const rect = video.getBoundingClientRect();
        const clickX = event.clientX - rect.left;
        const isLeftHalf = clickX < rect.width / 2;
        if (isLeftHalf) {
            this.seekTo(Math.max(0, video.currentTime - 10));
            this._triggerSkipOverlay(10, 'left');
            return;
        }
        this.seekTo(Math.min(this.duration(), video.currentTime + 10));
        this._triggerSkipOverlay(10, 'right');
    }
    // Kích hoạt overlay tua nhanh cộng dồn
    triggerSkip(seconds, direction) {
        const video = this.videoElement()?.nativeElement;
        if (!video) {
            return;
        }
        if (direction === 'left') {
            this.seekTo(Math.max(0, video.currentTime - seconds));
        }
        if (direction === 'right') {
            this.seekTo(Math.min(this.duration(), video.currentTime + seconds));
        }
        this._triggerSkipOverlay(seconds, direction);
    }
    _triggerSkipOverlay(seconds, direction) {
        if (this._skipOverlayTimeout) {
            clearTimeout(this._skipOverlayTimeout);
        }
        this._accumulatedSkip += Math.abs(seconds);
        this.skipOverlayDirection.set(direction);
        this.skipOverlayValue.set(this._accumulatedSkip);
        this.skipOverlayPulse.update(value => value + 1);
        this._skipOverlayTimeout = setTimeout(() => {
            this.skipOverlayDirection.set(null);
            this.skipOverlayValue.set(0);
            this._accumulatedSkip = 0;
        }, 800);
    }
    // Bắt sự kiện phím tắt điều khiển
    onKeyDown(event) {
        const activeEl = document.activeElement;
        if (activeEl &&
            (activeEl.tagName === 'INPUT' || activeEl.tagName === 'TEXTAREA' || activeEl.hasAttribute('contenteditable'))) {
            return;
        }
        const video = this.videoElement()?.nativeElement;
        if (!video) {
            return;
        }
        const key = event.key.toLowerCase();
        if (key === ' ' || key === 'arrowup' || key === 'arrowdown' || key === 'arrowleft' || key === 'arrowright') {
            event.preventDefault();
        }
        if (key === ' ' || key === 'k') {
            this.togglePlay();
            return;
        }
        if (key === 'm') {
            this.toggleMute();
            return;
        }
        if (key === 'f') {
            this.toggleFullscreen();
            return;
        }
        if (key === 't') {
            this.toggleTheaterMode();
            return;
        }
        if (key === 'i') {
            void this.toggleMiniplayer();
            return;
        }
        if (key === 'arrowleft' || key === 'j') {
            const skipSec = key === 'j' ? 10 : 5;
            this.triggerSkip(skipSec, 'left');
            return;
        }
        if (key === 'arrowright' || key === 'l') {
            const skipSec = key === 'l' ? 10 : 5;
            this.triggerSkip(skipSec, 'right');
            return;
        }
        if (key === 'arrowup') {
            this.onVolumeChange(Math.min(1.0, this.volume() + 0.05));
            return;
        }
        if (key === 'arrowdown') {
            this.onVolumeChange(Math.max(0, this.volume() - 0.05));
            return;
        }
        if (event.key >= '0' && event.key <= '9') {
            const numPercent = Number(event.key) * 10;
            this.seekTo((numPercent / 100) * this.duration());
            return;
        }
    }
    toggleSettings() {
        this.showSettings.set(!this.showSettings());
    }
    // Định dạng hiển thị m:ss / h:mm:ss
    _formatTime(time) {
        if (Number.isNaN(time) || time === Infinity || time < 0) {
            return '0:00';
        }
        const hours = Math.floor(time / 3600);
        const minutes = Math.floor((time % 3600) / 60);
        const seconds = Math.floor(time % 60);
        const formattedSeconds = seconds < 10 ? `0${seconds}` : seconds;
        if (hours > 0) {
            const formattedMinutes = minutes < 10 ? `0${minutes}` : minutes;
            return `${hours}:${formattedMinutes}:${formattedSeconds}`;
        }
        return `${minutes}:${formattedSeconds}`;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZMediaPlayerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: ZMediaPlayerComponent, isStandalone: true, selector: "z-media-player", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zSrc: { classPropertyName: "zSrc", publicName: "zSrc", isSignal: true, isRequired: true, transformFunction: null }, zSources: { classPropertyName: "zSources", publicName: "zSources", isSignal: true, isRequired: false, transformFunction: null }, zPoster: { classPropertyName: "zPoster", publicName: "zPoster", isSignal: true, isRequired: false, transformFunction: null }, zAutoplay: { classPropertyName: "zAutoplay", publicName: "zAutoplay", isSignal: true, isRequired: false, transformFunction: null }, zLoop: { classPropertyName: "zLoop", publicName: "zLoop", isSignal: true, isRequired: false, transformFunction: null }, zMuted: { classPropertyName: "zMuted", publicName: "zMuted", isSignal: true, isRequired: false, transformFunction: null }, zVolume: { classPropertyName: "zVolume", publicName: "zVolume", isSignal: true, isRequired: false, transformFunction: null }, zSubtitles: { classPropertyName: "zSubtitles", publicName: "zSubtitles", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zPlay: "zPlay", zTimeUpdate: "zTimeUpdate", zVolumeChange: "zVolumeChange", zFullscreenChange: "zFullscreenChange", zTheaterModeChange: "zTheaterModeChange", zMiniplayerChange: "zMiniplayerChange", zQualityChange: "zQualityChange" }, host: { listeners: { "keydown": "onKeyDown($event)", "mousemove": "onMouseMove()", "mouseleave": "onMouseLeave()", "document:fullscreenchange": "onFullscreenStateChange()" }, properties: { "class": "zClasses()", "attr.tabindex": "0" } }, viewQueries: [{ propertyName: "videoElement", first: true, predicate: ["videoElement"], descendants: true, isSignal: true }, { propertyName: "timelineContainer", first: true, predicate: ["timelineContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Th\u1EBB video ch\u00EDnh ph\u00E1t ngu\u1ED3n zSrc -->\n<video\n  #videoElement\n  class=\"h-full w-full cursor-pointer object-contain\"\n  [src]=\"effectiveSrc()\"\n  [poster]=\"zPoster()\"\n  [loop]=\"zLoop()\"\n  [autoplay]=\"zAutoplay()\"\n  playsinline\n  webkit-playsinline\n  (click)=\"onVideoClick($event)\"\n  (play)=\"onPlayStateChange(true)\"\n  (pause)=\"onPlayStateChange(false)\"\n  (timeupdate)=\"onTimeUpdate()\"\n  (durationchange)=\"onDurationChange()\"\n  (seeking)=\"onSeeking(true)\"\n  (seeked)=\"onSeeking(false)\"\n  (waiting)=\"onSeeking(true)\"\n  (playing)=\"onSeeking(false)\"\n  (enterpictureinpicture)=\"onEnterPiP()\"\n  (leavepictureinpicture)=\"onLeavePiP()\"\n  (webkitpresentationmodechanged)=\"onWebkitPresentationModeChanged()\">\n  @for (sub of zSubtitles(); track sub.src) {\n    <track\n      [src]=\"sub.src\"\n      kind=\"subtitles\"\n      [srclang]=\"sub.srclang\"\n      [label]=\"sub.label\"\n      [default]=\"sub.default || false\" />\n  }\n</video>\n\n<!-- L\u1EDBp ph\u1EE7 v\u00F2ng xoay loading khi video \u0111ang buffer -->\n@if (isBuffering()) {\n  <div class=\"pointer-events-none absolute inset-0 z-[10] flex items-center justify-center bg-black/20\">\n    <div class=\"size-14 animate-spin rounded-full border-4 border-white/20 border-t-red-600\"></div>\n  </div>\n}\n\n<!-- Hi\u1EC7u \u1EE9ng nh\u1EA5p nh\u00E1y Play/Pause l\u1EDBn gi\u1EEFa m\u00E0n h\u00ECnh t\u01B0\u01A1ng t\u1EF1 YouTube -->\n@if (playPauseFlash()) {\n  <div class=\"pointer-events-none absolute inset-0 z-[11] flex items-center justify-center\">\n    <div\n      class=\"z-flash-animation flex size-14 items-center justify-center rounded-full bg-black/60 text-white sm:size-20\">\n      <z-icon [zType]=\"playPauseFlash() === 'play' ? 'lucidePlay' : 'lucidePause'\" zSize=\"24\" [zStrokeWidth]=\"2\" />\n    </div>\n  </div>\n}\n\n<!-- L\u1EDBp ph\u1EE7 tua nhanh nh\u1EA3y s\u1ED1 c\u1ED9ng d\u1ED3n Tr\u00E1i (YouTube style) -->\n@if (skipOverlayValue() > 0 && skipOverlayDirection() === 'left') {\n  <div class=\"z-double-tap-ripple-left\" [class.z-skip-pulse-alt]=\"skipOverlayPulse() % 2 === 1\">\n    <div class=\"z-skip-overlay-content\">\n      <span class=\"z-skip-overlay-number\">- {{ skipOverlayValue() }}</span>\n      <span class=\"z-skip-overlay-arrows z-chevron-slide-left\">\n        <z-icon zType=\"lucideChevronsLeft\" zSize=\"26\" [zStrokeWidth]=\"2.4\" />\n      </span>\n    </div>\n  </div>\n}\n\n<!-- L\u1EDBp ph\u1EE7 tua nhanh nh\u1EA3y s\u1ED1 c\u1ED9ng d\u1ED3n Ph\u1EA3i (YouTube style) -->\n@if (skipOverlayValue() > 0 && skipOverlayDirection() === 'right') {\n  <div class=\"z-double-tap-ripple-right\" [class.z-skip-pulse-alt]=\"skipOverlayPulse() % 2 === 1\">\n    <div class=\"z-skip-overlay-content\">\n      <span class=\"z-skip-overlay-arrows z-chevron-slide-right\">\n        <z-icon zType=\"lucideChevronsRight\" zSize=\"26\" [zStrokeWidth]=\"2.4\" />\n      </span>\n      <span class=\"z-skip-overlay-number\">+ {{ skipOverlayValue() }}</span>\n    </div>\n  </div>\n}\n\n<!-- L\u1EDBp ph\u1EE7 ch\u1EE9a thanh \u0111i\u1EC1u khi\u1EC3n (Bottom controls panel) -->\n<div\n  class=\"pointer-events-none absolute inset-x-0 bottom-0 z-[12] flex flex-col bg-gradient-to-t from-black/85 via-black/40 to-transparent p-3 pt-12 transition-opacity duration-300 select-none\"\n  [class.opacity-0]=\"!showControls()\"\n  [class.invisible]=\"!showControls()\">\n  <!-- Thanh Timeline (Progress Bar) t\u00F9y ch\u1EC9nh ki\u1EC3u YouTube -->\n  <div\n    #timelineContainer\n    id=\"z_media_player_timeline\"\n    class=\"group/timeline pointer-events-auto relative mb-3 flex h-1 w-full cursor-pointer items-center transition-all hover:h-1.5\"\n    (mousedown)=\"onTimelineDragStart($event)\"\n    (mousemove)=\"onTimelineHover($event)\"\n    (mouseleave)=\"onTimelineHoverEnd()\">\n    <!-- Thanh n\u1EC1n x\u00E1m c\u1EE7a thanh timeline -->\n    <div\n      class=\"absolute inset-x-0 h-1 overflow-hidden rounded-full bg-white/25 transition-all group-hover/timeline:h-1.5\">\n      <!-- Ti\u1EBFn tr\u00ECnh t\u1EA3i buffer c\u1EE7a video -->\n      <div class=\"absolute top-0 left-0 h-full rounded-full bg-white/30\" [style.width.%]=\"bufferedProgress()\"></div>\n      <!-- Ti\u1EBFn tr\u00ECnh ph\u00E1t hi\u1EC7n t\u1EA1i c\u1EE7a video -->\n      <div class=\"absolute top-0 left-0 h-full rounded-full bg-red-600\" [style.width.%]=\"progress()\"></div>\n    </div>\n\n    <!-- \u0110\u1EA7u k\u00E9o timeline (Thumb) \u0111\u1ECF ch\u1EC9 hi\u1EC3n th\u1ECB khi hover ho\u1EB7c k\u00E9o -->\n    <div\n      class=\"bg-red-650 pointer-events-none absolute size-3.5 -translate-x-1/2 scale-0 transform rounded-full opacity-0 transition-opacity duration-150 group-hover/timeline:scale-100 group-hover/timeline:opacity-100\"\n      [style.left.%]=\"progress()\"></div>\n\n    <!-- Tooltip hi\u1EC3n th\u1ECB m\u1ED1c th\u1EDDi gian khi hover -->\n    @if (hoverTimeLabel()) {\n      <div\n        class=\"pointer-events-none absolute bottom-4 z-[20] -translate-x-1/2 rounded-xs bg-zinc-950/70 px-2 py-1 font-mono text-[11px] leading-none whitespace-nowrap text-zinc-100 shadow-[0_12px_24px_-10px_rgba(0,0,0,0.85)] backdrop-blur-2xl\"\n        [style.left.px]=\"hoverX()\">\n        {{ hoverTimeLabel() }}\n      </div>\n    }\n  </div>\n\n  <!-- H\u00E0ng ch\u1EE9a c\u00E1c n\u00FAt b\u1EA5m \u0111i\u1EC1u khi\u1EC3n ch\u1EE9c n\u0103ng -->\n  <div class=\"pointer-events-auto flex items-center justify-between text-sm text-white\">\n    <!-- C\u00E1c n\u00FAt \u0111i\u1EC1u khi\u1EC3n ph\u00EDa b\u00EAn tr\u00E1i -->\n    <div class=\"flex items-center gap-2\">\n      <!-- N\u00FAt Ph\u00E1t / T\u1EA1m d\u1EEBng -->\n      <button\n        z-button\n        zType=\"ghost\"\n        zSize=\"sm\"\n        zShape=\"default\"\n        [zWave]=\"false\"\n        type=\"button\"\n        id=\"z_media_player_play_btn\"\n        class=\"mr-1 flex size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none\"\n        [title]=\"(isPlaying() ? 'i18n_z_ui_media_player_pause' : 'i18n_z_ui_media_player_play') | translate\"\n        (click)=\"togglePlay()\">\n        <z-icon [zType]=\"isPlaying() ? 'lucidePause' : 'lucidePlay'\" zSize=\"20\" [zStrokeWidth]=\"2\" />\n      </button>\n\n      <!-- N\u00FAt Tua l\u00F9i 5s -->\n      <button\n        z-button\n        zType=\"ghost\"\n        zSize=\"sm\"\n        zShape=\"default\"\n        [zWave]=\"false\"\n        type=\"button\"\n        id=\"z_media_player_rewind_5_btn\"\n        class=\"hidden size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none sm:flex\"\n        title=\"Tua l\u00F9i 5 gi\u00E2y (Arrow Left)\"\n        (click)=\"triggerSkip(5, 'left')\">\n        <div class=\"relative flex items-center justify-center\">\n          <z-icon zType=\"lucideRotateCcw\" zSize=\"18\" [zStrokeWidth]=\"2\" />\n          <span class=\"pointer-events-none absolute mt-[1px] scale-75 text-[8px] font-bold text-white select-none\">\n            5\n          </span>\n        </div>\n      </button>\n\n      <!-- N\u00FAt Tua ti\u1EBFn 5s -->\n      <button\n        z-button\n        zType=\"ghost\"\n        zSize=\"sm\"\n        zShape=\"default\"\n        [zWave]=\"false\"\n        type=\"button\"\n        id=\"z_media_player_forward_5_btn\"\n        class=\"mr-1 hidden size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none sm:flex\"\n        title=\"Tua ti\u1EBFn 5 gi\u00E2y (Arrow Right)\"\n        (click)=\"triggerSkip(5, 'right')\">\n        <div class=\"relative flex items-center justify-center\">\n          <z-icon zType=\"lucideRotateCw\" zSize=\"18\" [zStrokeWidth]=\"2\" />\n          <span class=\"pointer-events-none absolute mt-[1px] scale-75 text-[8px] font-bold text-white select-none\">\n            5\n          </span>\n        </div>\n      </button>\n\n      <!-- T\u1ED5 h\u1EE3p n\u00FAt Mute v\u00E0 Slider \u00E2m l\u01B0\u1EE3ng tr\u01B0\u1EE3t ngang -->\n      <div class=\"group/volume hidden items-center gap-1.5 sm:flex\">\n        <button\n          z-button\n          zType=\"ghost\"\n          zSize=\"sm\"\n          zShape=\"default\"\n          [zWave]=\"false\"\n          type=\"button\"\n          id=\"z_media_player_mute_btn\"\n          class=\"flex size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none\"\n          [title]=\"(isMuted() ? 'i18n_z_ui_media_player_unmute' : 'i18n_z_ui_media_player_mute') | translate\"\n          (click)=\"toggleMute()\">\n          <z-icon\n            [zType]=\"isMuted() ? 'lucideVolumeX' : volume() < 0.5 ? 'lucideVolume1' : 'lucideVolume2'\"\n            zSize=\"20\"\n            [zStrokeWidth]=\"2\" />\n        </button>\n        <!-- Thanh tr\u01B0\u1EE3t \u00E2m l\u01B0\u1EE3ng tr\u01B0\u1EE3t ngang m\u1EDF r\u1ED9ng khi hover -->\n        <input\n          type=\"range\"\n          id=\"z_media_player_volume_slider\"\n          min=\"0\"\n          max=\"1\"\n          step=\"0.05\"\n          [ngModel]=\"volume()\"\n          (ngModelChange)=\"onVolumeChange($event)\"\n          class=\"accent-red-650 h-1 w-0 cursor-pointer rounded-lg bg-white/20 opacity-0 transition-all duration-200 outline-none group-hover/volume:w-16 group-hover/volume:opacity-100 focus-visible:w-16 focus-visible:opacity-100\" />\n      </div>\n\n      <!-- Hi\u1EC3n th\u1ECB th\u1EDDi gian ph\u00E1t (currentTime / duration) -->\n      <div class=\"pl-1 font-mono text-xs text-white/90 select-none\">\n        <span>{{ currentTimeLabel() }}</span>\n        <span class=\"mx-1 text-white/40\">/</span>\n        <span class=\"text-white/60\">{{ durationLabel() }}</span>\n      </div>\n    </div>\n\n    <!-- C\u00E1c n\u00FAt \u0111i\u1EC1u khi\u1EC3n ph\u00EDa b\u00EAn ph\u1EA3i -->\n    <div class=\"flex items-center gap-1.5\">\n      <!-- N\u00FAt m\u1EDF tr\u00ECnh \u0111\u01A1n C\u00E0i \u0111\u1EB7t b\u1EB1ng ZPopoverDirective -->\n      <button\n        z-button\n        zType=\"ghost\"\n        zSize=\"sm\"\n        zShape=\"default\"\n        [zWave]=\"false\"\n        type=\"button\"\n        id=\"z_media_player_settings_btn\"\n        class=\"flex size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none\"\n        [title]=\"'i18n_z_ui_media_player_settings' | translate\"\n        z-popover\n        [zPopoverContent]=\"speedMenuTemplate\"\n        zPosition=\"top-right\"\n        zTrigger=\"click\"\n        [zOffset]=\"6\"\n        zClass=\"z-media-player-popover\"\n        (zShow)=\"showSettings.set(true); onMouseMove()\"\n        (zHide)=\"onSettingsHidden()\">\n        <z-icon zType=\"lucideSettings\" zSize=\"20\" [zStrokeWidth]=\"2\" />\n      </button>\n\n      <!-- N\u00FAt Miniplayer (Picture-in-Picture) - \u1EA8n ho\u1EB7c disable n\u1EBFu browser ko h\u1ED7 tr\u1EE3 -->\n      @if (isPiPSupported()) {\n        <button\n          z-button\n          zType=\"ghost\"\n          zSize=\"sm\"\n          zShape=\"default\"\n          [zWave]=\"false\"\n          type=\"button\"\n          id=\"z_media_player_mini_btn\"\n          class=\"hidden size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none sm:flex\"\n          [title]=\"'i18n_z_ui_media_player_miniplayer' | translate\"\n          (click)=\"toggleMiniplayer()\">\n          <z-icon zType=\"lucideTv\" zSize=\"20\" [zStrokeWidth]=\"2\" />\n        </button>\n      }\n\n      <!-- N\u00FAt b\u1EADt/t\u1EAFt ch\u1EBF \u0111\u1ED9 r\u1EA1p chi\u1EBFu phim (Theater Mode) -->\n      <button\n        z-button\n        zType=\"ghost\"\n        zSize=\"sm\"\n        zShape=\"default\"\n        [zWave]=\"false\"\n        id=\"z_media_player_theater_btn\"\n        class=\"flex hidden size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none md:flex\"\n        [title]=\"\n          (isTheaterMode() ? 'i18n_z_ui_media_player_default_mode' : 'i18n_z_ui_media_player_theater_mode') | translate\n        \"\n        (click)=\"toggleTheaterMode()\">\n        <z-icon\n          [zType]=\"isTheaterMode() ? 'lucideSquare' : 'lucideRectangleHorizontal'\"\n          zSize=\"20\"\n          [zStrokeWidth]=\"2\" />\n      </button>\n\n      <!-- N\u00FAt b\u1EADt/t\u1EAFt ch\u1EBF \u0111\u1ED9 to\u00E0n m\u00E0n h\u00ECnh (Fullscreen) -->\n      <button\n        z-button\n        zType=\"ghost\"\n        zSize=\"sm\"\n        zShape=\"default\"\n        [zWave]=\"false\"\n        type=\"button\"\n        id=\"z_media_player_full_btn\"\n        class=\"flex size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none\"\n        [title]=\"\n          (isFullscreen() ? 'i18n_z_ui_media_player_exit_fullscreen' : 'i18n_z_ui_media_player_fullscreen') | translate\n        \"\n        (click)=\"toggleFullscreen()\">\n        <z-icon [zType]=\"isFullscreen() ? 'lucideMinimize' : 'lucideMaximize'\" zSize=\"20\" [zStrokeWidth]=\"2\" />\n      </button>\n    </div>\n  </div>\n</div>\n\n<!-- Template c\u1EA5u h\u00ECnh Popover c\u00E0i \u0111\u1EB7t s\u1EED d\u1EE5ng ng-template -->\n<ng-template #speedMenuTemplate>\n  <div\n    class=\"z-media-player-settings flex w-44 flex-col px-1 py-[4px] text-zinc-200\"\n    [class.z-main-panel]=\"settingsPanel() === 'main'\"\n    [class.z-sub-panel]=\"settingsPanel() !== 'main'\">\n    @if (settingsPanel() === 'main') {\n      <div class=\"z-media-player-settings-panel flex flex-col\">\n        @if (qualitySources().length > 1) {\n          <button type=\"button\" class=\"z-media-player-settings-item\" (click)=\"openSettingsPanel('quality')\">\n            <span class=\"min-w-0 flex-1 truncate whitespace-nowrap\">\n              {{ 'i18n_z_ui_media_player_quality' | translate }}\n            </span>\n            <span class=\"flex max-w-[5.5rem] min-w-0 items-center gap-1.5 text-zinc-400\">\n              <span class=\"min-w-0 truncate whitespace-nowrap\">{{ activeQualityLabel() }}</span>\n              <z-icon zType=\"lucideChevronRight\" zSize=\"13\" class=\"shrink-0\" />\n            </span>\n          </button>\n        }\n        <button type=\"button\" class=\"z-media-player-settings-item\" (click)=\"openSettingsPanel('speed')\">\n          <span class=\"min-w-0 flex-1 truncate whitespace-nowrap\">\n            {{ 'i18n_z_ui_media_player_speed' | translate }}\n          </span>\n          <span class=\"flex max-w-[5.5rem] min-w-0 items-center gap-1.5 text-zinc-400\">\n            <span class=\"min-w-0 truncate whitespace-nowrap\">\n              {{ playbackSpeed() === 1 ? ('i18n_z_ui_media_player_normal' | translate) : playbackSpeed() + 'x' }}\n            </span>\n            <z-icon zType=\"lucideChevronRight\" zSize=\"13\" class=\"shrink-0\" />\n          </span>\n        </button>\n      </div>\n    }\n\n    @if (settingsPanel() === 'quality') {\n      <div class=\"z-media-player-settings-panel flex flex-col\">\n        <button\n          type=\"button\"\n          [title]=\"'i18n_z_ui_media_player_back' | translate\"\n          class=\"z-media-player-settings-back\"\n          (click)=\"closeSettingsPanel()\">\n          <z-icon zType=\"lucideChevronLeft\" zSize=\"13\" class=\"shrink-0\" />\n          <span class=\"min-w-0 truncate whitespace-nowrap\">{{ 'i18n_z_ui_media_player_quality' | translate }}</span>\n        </button>\n        @for (source of qualitySources(); track source.src) {\n          <button\n            type=\"button\"\n            [id]=\"'z_media_player_quality_btn_' + source.label\"\n            class=\"z-media-player-settings-item\"\n            [class.z-active]=\"effectiveSrc() === source.src\"\n            (click)=\"setQualitySource(source)\">\n            <span class=\"min-w-0 truncate whitespace-nowrap\">{{ source.label }}</span>\n          </button>\n        }\n      </div>\n    }\n\n    @if (settingsPanel() === 'speed') {\n      <div class=\"z-media-player-settings-panel flex flex-col\">\n        <button\n          type=\"button\"\n          [title]=\"'i18n_z_ui_media_player_back' | translate\"\n          class=\"z-media-player-settings-back\"\n          (click)=\"closeSettingsPanel()\">\n          <z-icon zType=\"lucideChevronLeft\" zSize=\"13\" class=\"shrink-0\" />\n          <span class=\"min-w-0 truncate whitespace-nowrap\">{{ 'i18n_z_ui_media_player_speed' | translate }}</span>\n        </button>\n        @for (speed of playbackSpeeds; track speed.value) {\n          <button\n            type=\"button\"\n            [id]=\"'z_media_player_speed_btn_' + speed.value\"\n            class=\"z-media-player-settings-item\"\n            [class.z-active]=\"playbackSpeed() === speed.value\"\n            (click)=\"setPlaybackSpeed(speed.value)\">\n            <span class=\"min-w-0 truncate whitespace-nowrap\">{{ speed.label | translate }}</span>\n          </button>\n        }\n      </div>\n    }\n  </div>\n</ng-template>\n", styles: ["z-media-player{display:block;width:100%;outline:none}z-media-player:focus,z-media-player:focus-visible{outline:none}z-media-player video::cue{background-color:#080808d9;color:#fff;font-family:inherit;font-size:16px;text-shadow:0 1px 2px rgba(0,0,0,.9);padding:4px 8px;border-radius:4px}z-media-player .z-flash-animation{animation:zUiFlashIcon .72s cubic-bezier(.2,.85,.25,1) forwards;will-change:opacity,transform,filter}z-media-player .z-flash-animation z-icon{width:24px!important;height:24px!important}@media(min-width:640px){z-media-player .z-flash-animation z-icon{width:32px!important;height:32px!important}}@keyframes zUiFlashIcon{0%{filter:blur(2px);opacity:0;transform:scale(.72)}18%{filter:blur(0);opacity:.95;transform:scale(1)}58%{opacity:.9;transform:scale(1.04)}to{filter:blur(0);opacity:0;transform:scale(1.18)}}z-media-player .animate-fade-in{animation:zUiFadeIn .2s cubic-bezier(.16,1,.3,1)}@keyframes zUiFadeIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}z-media-player .z-double-tap-ripple-left,z-media-player .z-double-tap-ripple-right{position:absolute;top:0;bottom:0;width:35%;display:flex;align-items:center;z-index:11;pointer-events:none}z-media-player .z-double-tap-ripple-left:before,z-media-player .z-double-tap-ripple-right:before{position:absolute;inset:0;content:\"\";opacity:0;animation-duration:.72s;animation-fill-mode:forwards;animation-timing-function:cubic-bezier(.25,1,.5,1)}z-media-player .z-double-tap-ripple-left{left:0;justify-content:flex-start;padding-left:5%}z-media-player .z-double-tap-ripple-left:before{background:radial-gradient(circle at 0% 50%,#ffffff21,#fff0 70%);border-top-right-radius:100% 50%;border-bottom-right-radius:100% 50%;animation-name:zUiDoubleTapRippleLeft;transform-origin:left center}z-media-player .z-double-tap-ripple-left.z-skip-pulse-alt:before{animation-name:zUiDoubleTapRippleLeftAlt}z-media-player .z-double-tap-ripple-right{right:0;justify-content:flex-end;padding-right:5%}z-media-player .z-double-tap-ripple-right:before{background:radial-gradient(circle at 100% 50%,#ffffff21,#fff0 70%);border-top-left-radius:100% 50%;border-bottom-left-radius:100% 50%;animation-name:zUiDoubleTapRippleRight;transform-origin:right center}z-media-player .z-double-tap-ripple-right.z-skip-pulse-alt:before{animation-name:zUiDoubleTapRippleRightAlt}z-media-player .z-skip-overlay-content{position:relative;display:flex;align-items:center;justify-content:center;gap:6px;min-width:92px;color:#fff;font-family:inherit;font-size:18px;font-weight:700;line-height:1;text-shadow:0 2px 8px rgba(0,0,0,.75);-webkit-user-select:none;user-select:none}z-media-player .z-skip-overlay-number{min-width:42px;animation:zUiSkipNumberBump .22s cubic-bezier(.2,.85,.25,1) forwards;text-align:center;transform-origin:center}z-media-player .z-skip-pulse-alt .z-skip-overlay-number{animation-name:zUiSkipNumberBumpAlt}z-media-player .z-skip-overlay-arrows{display:inline-flex;align-items:center;color:#fffffff2;filter:drop-shadow(0 2px 6px rgba(0,0,0,.7))}@keyframes zUiDoubleTapRippleLeft{0%{opacity:0;transform:scaleX(.5);transform-origin:left center}15%{opacity:1}80%{opacity:1}to{opacity:0;transform:scaleX(1);transform-origin:left center}}@keyframes zUiDoubleTapRippleLeftAlt{0%{opacity:0;transform:scaleX(.5);transform-origin:left center}15%{opacity:1}80%{opacity:1}to{opacity:0;transform:scaleX(1);transform-origin:left center}}@keyframes zUiDoubleTapRippleRight{0%{opacity:0;transform:scaleX(.5);transform-origin:right center}15%{opacity:1}80%{opacity:1}to{opacity:0;transform:scaleX(1);transform-origin:right center}}@keyframes zUiDoubleTapRippleRightAlt{0%{opacity:0;transform:scaleX(.5);transform-origin:right center}15%{opacity:1}80%{opacity:1}to{opacity:0;transform:scaleX(1);transform-origin:right center}}z-media-player .z-chevron-slide-left{animation:zUiChevronSlideLeft .72s cubic-bezier(.25,1,.5,1) forwards}z-media-player .z-chevron-slide-right{animation:zUiChevronSlideRight .72s cubic-bezier(.25,1,.5,1) forwards}z-media-player .z-skip-pulse-alt .z-chevron-slide-left{animation-name:zUiChevronSlideLeftAlt}z-media-player .z-skip-pulse-alt .z-chevron-slide-right{animation-name:zUiChevronSlideRightAlt}@keyframes zUiSkipNumberBump{0%{opacity:.78;transform:scale(.92)}55%{opacity:1;transform:scale(1.12)}to{opacity:1;transform:scale(1)}}@keyframes zUiSkipNumberBumpAlt{0%{opacity:.78;transform:scale(.92)}55%{opacity:1;transform:scale(1.12)}to{opacity:1;transform:scale(1)}}@keyframes zUiChevronSlideLeft{0%{opacity:0;transform:translate(8px)}28%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-12px)}}@keyframes zUiChevronSlideRight{0%{opacity:0;transform:translate(-8px)}28%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(12px)}}@keyframes zUiChevronSlideLeftAlt{0%{opacity:0;transform:translate(8px)}28%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-12px)}}@keyframes zUiChevronSlideRightAlt{0%{opacity:0;transform:translate(-8px)}28%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(12px)}}z-media-player #z_media_player_volume_slider{-webkit-appearance:none;appearance:none;background:transparent}z-media-player #z_media_player_volume_slider::-webkit-slider-runnable-track{background:#ffffff40;height:3px;border-radius:9999px}z-media-player #z_media_player_volume_slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background:#fff;height:10px;width:10px;border-radius:9999px;margin-top:-3.5px;transition:transform .15s ease}z-media-player #z_media_player_volume_slider:hover::-webkit-slider-thumb,z-media-player #z_media_player_volume_slider:focus-visible::-webkit-slider-thumb{transform:scale(1.3)}z-media-player #z_media_player_volume_slider::-moz-range-track{background:#ffffff40;height:3px;border-radius:9999px}z-media-player #z_media_player_volume_slider::-moz-range-thumb{background:#fff;height:10px;width:10px;border-radius:9999px;border:none;transition:transform .15s ease}z-media-player #z_media_player_volume_slider:hover::-moz-range-thumb,z-media-player #z_media_player_volume_slider:focus-visible::-moz-range-thumb{transform:scale(1.3)}.z-media-player-popover{backdrop-filter:blur(24px)!important;-webkit-backdrop-filter:blur(24px)!important;background-color:#0f0f0f99!important;border:1px solid rgba(255,255,255,.08)!important;box-shadow:0 15px 30px -10px #000c!important;border-radius:8px!important;padding:0!important;transform-origin:bottom right}.z-media-player-popover[data-state=open]{animation:zUiMediaSettingsPopoverIn .16s cubic-bezier(.2,.85,.25,1) forwards}.z-media-player-popover[data-state=closed]{animation:zUiMediaSettingsPopoverOut .16s cubic-bezier(.4,0,.2,1) forwards!important}.z-media-player-popover .bg-popover{background-color:transparent!important;color:#e4e4e7!important}.z-media-player-popover .z-media-player-settings{overflow:hidden;transform-origin:bottom right;animation:zUiMediaSettingsPanelIn .16s cubic-bezier(.2,.85,.25,1)}.z-media-player-popover .z-media-player-settings-panel{gap:4px;transform-origin:top right;animation:zUiMediaSettingsPanelIn .14s cubic-bezier(.2,.85,.25,1);will-change:opacity,transform}.z-media-player-popover .z-media-player-settings.z-main-panel .z-media-player-settings-panel{animation-name:zUiMediaSettingsPanelFromLeft}.z-media-player-popover .z-media-player-settings.z-sub-panel .z-media-player-settings-panel{animation-name:zUiMediaSettingsPanelFromRight}.z-media-player-popover .z-media-player-settings-item,.z-media-player-popover .z-media-player-settings-back{position:relative;display:flex;width:100%;min-width:0;height:32px;min-height:32px;cursor:pointer;align-items:center;border:0;border-radius:4px;background-color:transparent;padding:0 8px;color:#e4e4e7;font-size:12px;font-weight:500;line-height:1;outline:none;transition:background-color .12s ease,color .12s ease}.z-media-player-popover .z-media-player-settings-item{justify-content:space-between;gap:12px;text-align:left}.z-media-player-popover .z-media-player-settings-item:before{position:absolute;top:7px;bottom:7px;left:0;width:2px;border-radius:9999px;background-color:#fff;content:\"\";opacity:0;transform:scaleY(.5);transition:opacity .12s ease,transform .12s ease}.z-media-player-popover .z-media-player-settings-item.z-active{background-color:#ffffff14;color:#fff;font-weight:600}.z-media-player-popover .z-media-player-settings-item.z-active:before{opacity:1;transform:scaleY(1)}.z-media-player-popover .z-media-player-settings-back{justify-content:flex-start;gap:8px;color:#f4f4f5;font-weight:600}.z-media-player-popover .z-media-player-settings-item:hover,.z-media-player-popover .z-media-player-settings-back:hover,.z-media-player-popover .z-media-player-settings-item:focus-visible,.z-media-player-popover .z-media-player-settings-back:focus-visible{background-color:#ffffff1a}@keyframes zUiMediaSettingsPopoverIn{0%{opacity:0;transform:translateY(6px) scale(.94)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes zUiMediaSettingsPopoverOut{0%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(4px) scale(.96)}}@keyframes zUiMediaSettingsPanelIn{0%{opacity:0;transform:translateY(3px)}to{opacity:1;transform:translateY(0)}}@keyframes zUiMediaSettingsPanelFromRight{0%{opacity:0;transform:translate(8px)}to{opacity:1;transform:translate(0)}}@keyframes zUiMediaSettingsPanelFromLeft{0%{opacity:0;transform:translate(-5px)}to{opacity:1;transform:translate(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zAnimatedType", "zAnimate", "zAnimationTrigger", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zPopoverTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zTriggerRef", "zManualClose", "zOutsideClickClose", "zScrollClose", "zShowArrow"], outputs: ["zShow", "zHide", "zHideStart", "zControl", "zPositionChange", "zOutsideClick"], exportAs: ["zPopover"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zAnimatedTypeIcon", "zAnimateIcon", "zAnimationTriggerIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZMediaPlayerComponent, decorators: [{
            type: Component,
            args: [{ selector: 'z-media-player', imports: [CommonModule, FormsModule, ZIconComponent, ZPopoverDirective, TranslatePipe, ZButtonComponent], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        '[class]': 'zClasses()',
                        '[attr.tabindex]': '0',
                        '(keydown)': 'onKeyDown($event)',
                        '(mousemove)': 'onMouseMove()',
                        '(mouseleave)': 'onMouseLeave()',
                        '(document:fullscreenchange)': 'onFullscreenStateChange()',
                    }, template: "<!-- Th\u1EBB video ch\u00EDnh ph\u00E1t ngu\u1ED3n zSrc -->\n<video\n  #videoElement\n  class=\"h-full w-full cursor-pointer object-contain\"\n  [src]=\"effectiveSrc()\"\n  [poster]=\"zPoster()\"\n  [loop]=\"zLoop()\"\n  [autoplay]=\"zAutoplay()\"\n  playsinline\n  webkit-playsinline\n  (click)=\"onVideoClick($event)\"\n  (play)=\"onPlayStateChange(true)\"\n  (pause)=\"onPlayStateChange(false)\"\n  (timeupdate)=\"onTimeUpdate()\"\n  (durationchange)=\"onDurationChange()\"\n  (seeking)=\"onSeeking(true)\"\n  (seeked)=\"onSeeking(false)\"\n  (waiting)=\"onSeeking(true)\"\n  (playing)=\"onSeeking(false)\"\n  (enterpictureinpicture)=\"onEnterPiP()\"\n  (leavepictureinpicture)=\"onLeavePiP()\"\n  (webkitpresentationmodechanged)=\"onWebkitPresentationModeChanged()\">\n  @for (sub of zSubtitles(); track sub.src) {\n    <track\n      [src]=\"sub.src\"\n      kind=\"subtitles\"\n      [srclang]=\"sub.srclang\"\n      [label]=\"sub.label\"\n      [default]=\"sub.default || false\" />\n  }\n</video>\n\n<!-- L\u1EDBp ph\u1EE7 v\u00F2ng xoay loading khi video \u0111ang buffer -->\n@if (isBuffering()) {\n  <div class=\"pointer-events-none absolute inset-0 z-[10] flex items-center justify-center bg-black/20\">\n    <div class=\"size-14 animate-spin rounded-full border-4 border-white/20 border-t-red-600\"></div>\n  </div>\n}\n\n<!-- Hi\u1EC7u \u1EE9ng nh\u1EA5p nh\u00E1y Play/Pause l\u1EDBn gi\u1EEFa m\u00E0n h\u00ECnh t\u01B0\u01A1ng t\u1EF1 YouTube -->\n@if (playPauseFlash()) {\n  <div class=\"pointer-events-none absolute inset-0 z-[11] flex items-center justify-center\">\n    <div\n      class=\"z-flash-animation flex size-14 items-center justify-center rounded-full bg-black/60 text-white sm:size-20\">\n      <z-icon [zType]=\"playPauseFlash() === 'play' ? 'lucidePlay' : 'lucidePause'\" zSize=\"24\" [zStrokeWidth]=\"2\" />\n    </div>\n  </div>\n}\n\n<!-- L\u1EDBp ph\u1EE7 tua nhanh nh\u1EA3y s\u1ED1 c\u1ED9ng d\u1ED3n Tr\u00E1i (YouTube style) -->\n@if (skipOverlayValue() > 0 && skipOverlayDirection() === 'left') {\n  <div class=\"z-double-tap-ripple-left\" [class.z-skip-pulse-alt]=\"skipOverlayPulse() % 2 === 1\">\n    <div class=\"z-skip-overlay-content\">\n      <span class=\"z-skip-overlay-number\">- {{ skipOverlayValue() }}</span>\n      <span class=\"z-skip-overlay-arrows z-chevron-slide-left\">\n        <z-icon zType=\"lucideChevronsLeft\" zSize=\"26\" [zStrokeWidth]=\"2.4\" />\n      </span>\n    </div>\n  </div>\n}\n\n<!-- L\u1EDBp ph\u1EE7 tua nhanh nh\u1EA3y s\u1ED1 c\u1ED9ng d\u1ED3n Ph\u1EA3i (YouTube style) -->\n@if (skipOverlayValue() > 0 && skipOverlayDirection() === 'right') {\n  <div class=\"z-double-tap-ripple-right\" [class.z-skip-pulse-alt]=\"skipOverlayPulse() % 2 === 1\">\n    <div class=\"z-skip-overlay-content\">\n      <span class=\"z-skip-overlay-arrows z-chevron-slide-right\">\n        <z-icon zType=\"lucideChevronsRight\" zSize=\"26\" [zStrokeWidth]=\"2.4\" />\n      </span>\n      <span class=\"z-skip-overlay-number\">+ {{ skipOverlayValue() }}</span>\n    </div>\n  </div>\n}\n\n<!-- L\u1EDBp ph\u1EE7 ch\u1EE9a thanh \u0111i\u1EC1u khi\u1EC3n (Bottom controls panel) -->\n<div\n  class=\"pointer-events-none absolute inset-x-0 bottom-0 z-[12] flex flex-col bg-gradient-to-t from-black/85 via-black/40 to-transparent p-3 pt-12 transition-opacity duration-300 select-none\"\n  [class.opacity-0]=\"!showControls()\"\n  [class.invisible]=\"!showControls()\">\n  <!-- Thanh Timeline (Progress Bar) t\u00F9y ch\u1EC9nh ki\u1EC3u YouTube -->\n  <div\n    #timelineContainer\n    id=\"z_media_player_timeline\"\n    class=\"group/timeline pointer-events-auto relative mb-3 flex h-1 w-full cursor-pointer items-center transition-all hover:h-1.5\"\n    (mousedown)=\"onTimelineDragStart($event)\"\n    (mousemove)=\"onTimelineHover($event)\"\n    (mouseleave)=\"onTimelineHoverEnd()\">\n    <!-- Thanh n\u1EC1n x\u00E1m c\u1EE7a thanh timeline -->\n    <div\n      class=\"absolute inset-x-0 h-1 overflow-hidden rounded-full bg-white/25 transition-all group-hover/timeline:h-1.5\">\n      <!-- Ti\u1EBFn tr\u00ECnh t\u1EA3i buffer c\u1EE7a video -->\n      <div class=\"absolute top-0 left-0 h-full rounded-full bg-white/30\" [style.width.%]=\"bufferedProgress()\"></div>\n      <!-- Ti\u1EBFn tr\u00ECnh ph\u00E1t hi\u1EC7n t\u1EA1i c\u1EE7a video -->\n      <div class=\"absolute top-0 left-0 h-full rounded-full bg-red-600\" [style.width.%]=\"progress()\"></div>\n    </div>\n\n    <!-- \u0110\u1EA7u k\u00E9o timeline (Thumb) \u0111\u1ECF ch\u1EC9 hi\u1EC3n th\u1ECB khi hover ho\u1EB7c k\u00E9o -->\n    <div\n      class=\"bg-red-650 pointer-events-none absolute size-3.5 -translate-x-1/2 scale-0 transform rounded-full opacity-0 transition-opacity duration-150 group-hover/timeline:scale-100 group-hover/timeline:opacity-100\"\n      [style.left.%]=\"progress()\"></div>\n\n    <!-- Tooltip hi\u1EC3n th\u1ECB m\u1ED1c th\u1EDDi gian khi hover -->\n    @if (hoverTimeLabel()) {\n      <div\n        class=\"pointer-events-none absolute bottom-4 z-[20] -translate-x-1/2 rounded-xs bg-zinc-950/70 px-2 py-1 font-mono text-[11px] leading-none whitespace-nowrap text-zinc-100 shadow-[0_12px_24px_-10px_rgba(0,0,0,0.85)] backdrop-blur-2xl\"\n        [style.left.px]=\"hoverX()\">\n        {{ hoverTimeLabel() }}\n      </div>\n    }\n  </div>\n\n  <!-- H\u00E0ng ch\u1EE9a c\u00E1c n\u00FAt b\u1EA5m \u0111i\u1EC1u khi\u1EC3n ch\u1EE9c n\u0103ng -->\n  <div class=\"pointer-events-auto flex items-center justify-between text-sm text-white\">\n    <!-- C\u00E1c n\u00FAt \u0111i\u1EC1u khi\u1EC3n ph\u00EDa b\u00EAn tr\u00E1i -->\n    <div class=\"flex items-center gap-2\">\n      <!-- N\u00FAt Ph\u00E1t / T\u1EA1m d\u1EEBng -->\n      <button\n        z-button\n        zType=\"ghost\"\n        zSize=\"sm\"\n        zShape=\"default\"\n        [zWave]=\"false\"\n        type=\"button\"\n        id=\"z_media_player_play_btn\"\n        class=\"mr-1 flex size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none\"\n        [title]=\"(isPlaying() ? 'i18n_z_ui_media_player_pause' : 'i18n_z_ui_media_player_play') | translate\"\n        (click)=\"togglePlay()\">\n        <z-icon [zType]=\"isPlaying() ? 'lucidePause' : 'lucidePlay'\" zSize=\"20\" [zStrokeWidth]=\"2\" />\n      </button>\n\n      <!-- N\u00FAt Tua l\u00F9i 5s -->\n      <button\n        z-button\n        zType=\"ghost\"\n        zSize=\"sm\"\n        zShape=\"default\"\n        [zWave]=\"false\"\n        type=\"button\"\n        id=\"z_media_player_rewind_5_btn\"\n        class=\"hidden size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none sm:flex\"\n        title=\"Tua l\u00F9i 5 gi\u00E2y (Arrow Left)\"\n        (click)=\"triggerSkip(5, 'left')\">\n        <div class=\"relative flex items-center justify-center\">\n          <z-icon zType=\"lucideRotateCcw\" zSize=\"18\" [zStrokeWidth]=\"2\" />\n          <span class=\"pointer-events-none absolute mt-[1px] scale-75 text-[8px] font-bold text-white select-none\">\n            5\n          </span>\n        </div>\n      </button>\n\n      <!-- N\u00FAt Tua ti\u1EBFn 5s -->\n      <button\n        z-button\n        zType=\"ghost\"\n        zSize=\"sm\"\n        zShape=\"default\"\n        [zWave]=\"false\"\n        type=\"button\"\n        id=\"z_media_player_forward_5_btn\"\n        class=\"mr-1 hidden size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none sm:flex\"\n        title=\"Tua ti\u1EBFn 5 gi\u00E2y (Arrow Right)\"\n        (click)=\"triggerSkip(5, 'right')\">\n        <div class=\"relative flex items-center justify-center\">\n          <z-icon zType=\"lucideRotateCw\" zSize=\"18\" [zStrokeWidth]=\"2\" />\n          <span class=\"pointer-events-none absolute mt-[1px] scale-75 text-[8px] font-bold text-white select-none\">\n            5\n          </span>\n        </div>\n      </button>\n\n      <!-- T\u1ED5 h\u1EE3p n\u00FAt Mute v\u00E0 Slider \u00E2m l\u01B0\u1EE3ng tr\u01B0\u1EE3t ngang -->\n      <div class=\"group/volume hidden items-center gap-1.5 sm:flex\">\n        <button\n          z-button\n          zType=\"ghost\"\n          zSize=\"sm\"\n          zShape=\"default\"\n          [zWave]=\"false\"\n          type=\"button\"\n          id=\"z_media_player_mute_btn\"\n          class=\"flex size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none\"\n          [title]=\"(isMuted() ? 'i18n_z_ui_media_player_unmute' : 'i18n_z_ui_media_player_mute') | translate\"\n          (click)=\"toggleMute()\">\n          <z-icon\n            [zType]=\"isMuted() ? 'lucideVolumeX' : volume() < 0.5 ? 'lucideVolume1' : 'lucideVolume2'\"\n            zSize=\"20\"\n            [zStrokeWidth]=\"2\" />\n        </button>\n        <!-- Thanh tr\u01B0\u1EE3t \u00E2m l\u01B0\u1EE3ng tr\u01B0\u1EE3t ngang m\u1EDF r\u1ED9ng khi hover -->\n        <input\n          type=\"range\"\n          id=\"z_media_player_volume_slider\"\n          min=\"0\"\n          max=\"1\"\n          step=\"0.05\"\n          [ngModel]=\"volume()\"\n          (ngModelChange)=\"onVolumeChange($event)\"\n          class=\"accent-red-650 h-1 w-0 cursor-pointer rounded-lg bg-white/20 opacity-0 transition-all duration-200 outline-none group-hover/volume:w-16 group-hover/volume:opacity-100 focus-visible:w-16 focus-visible:opacity-100\" />\n      </div>\n\n      <!-- Hi\u1EC3n th\u1ECB th\u1EDDi gian ph\u00E1t (currentTime / duration) -->\n      <div class=\"pl-1 font-mono text-xs text-white/90 select-none\">\n        <span>{{ currentTimeLabel() }}</span>\n        <span class=\"mx-1 text-white/40\">/</span>\n        <span class=\"text-white/60\">{{ durationLabel() }}</span>\n      </div>\n    </div>\n\n    <!-- C\u00E1c n\u00FAt \u0111i\u1EC1u khi\u1EC3n ph\u00EDa b\u00EAn ph\u1EA3i -->\n    <div class=\"flex items-center gap-1.5\">\n      <!-- N\u00FAt m\u1EDF tr\u00ECnh \u0111\u01A1n C\u00E0i \u0111\u1EB7t b\u1EB1ng ZPopoverDirective -->\n      <button\n        z-button\n        zType=\"ghost\"\n        zSize=\"sm\"\n        zShape=\"default\"\n        [zWave]=\"false\"\n        type=\"button\"\n        id=\"z_media_player_settings_btn\"\n        class=\"flex size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none\"\n        [title]=\"'i18n_z_ui_media_player_settings' | translate\"\n        z-popover\n        [zPopoverContent]=\"speedMenuTemplate\"\n        zPosition=\"top-right\"\n        zTrigger=\"click\"\n        [zOffset]=\"6\"\n        zClass=\"z-media-player-popover\"\n        (zShow)=\"showSettings.set(true); onMouseMove()\"\n        (zHide)=\"onSettingsHidden()\">\n        <z-icon zType=\"lucideSettings\" zSize=\"20\" [zStrokeWidth]=\"2\" />\n      </button>\n\n      <!-- N\u00FAt Miniplayer (Picture-in-Picture) - \u1EA8n ho\u1EB7c disable n\u1EBFu browser ko h\u1ED7 tr\u1EE3 -->\n      @if (isPiPSupported()) {\n        <button\n          z-button\n          zType=\"ghost\"\n          zSize=\"sm\"\n          zShape=\"default\"\n          [zWave]=\"false\"\n          type=\"button\"\n          id=\"z_media_player_mini_btn\"\n          class=\"hidden size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none sm:flex\"\n          [title]=\"'i18n_z_ui_media_player_miniplayer' | translate\"\n          (click)=\"toggleMiniplayer()\">\n          <z-icon zType=\"lucideTv\" zSize=\"20\" [zStrokeWidth]=\"2\" />\n        </button>\n      }\n\n      <!-- N\u00FAt b\u1EADt/t\u1EAFt ch\u1EBF \u0111\u1ED9 r\u1EA1p chi\u1EBFu phim (Theater Mode) -->\n      <button\n        z-button\n        zType=\"ghost\"\n        zSize=\"sm\"\n        zShape=\"default\"\n        [zWave]=\"false\"\n        id=\"z_media_player_theater_btn\"\n        class=\"flex hidden size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none md:flex\"\n        [title]=\"\n          (isTheaterMode() ? 'i18n_z_ui_media_player_default_mode' : 'i18n_z_ui_media_player_theater_mode') | translate\n        \"\n        (click)=\"toggleTheaterMode()\">\n        <z-icon\n          [zType]=\"isTheaterMode() ? 'lucideSquare' : 'lucideRectangleHorizontal'\"\n          zSize=\"20\"\n          [zStrokeWidth]=\"2\" />\n      </button>\n\n      <!-- N\u00FAt b\u1EADt/t\u1EAFt ch\u1EBF \u0111\u1ED9 to\u00E0n m\u00E0n h\u00ECnh (Fullscreen) -->\n      <button\n        z-button\n        zType=\"ghost\"\n        zSize=\"sm\"\n        zShape=\"default\"\n        [zWave]=\"false\"\n        type=\"button\"\n        id=\"z_media_player_full_btn\"\n        class=\"flex size-8 cursor-pointer items-center justify-center rounded-xs border-0 border-none bg-transparent p-0 text-white shadow-none transition-colors outline-none hover:bg-white/15 hover:text-white focus:outline-none focus-visible:outline-none\"\n        [title]=\"\n          (isFullscreen() ? 'i18n_z_ui_media_player_exit_fullscreen' : 'i18n_z_ui_media_player_fullscreen') | translate\n        \"\n        (click)=\"toggleFullscreen()\">\n        <z-icon [zType]=\"isFullscreen() ? 'lucideMinimize' : 'lucideMaximize'\" zSize=\"20\" [zStrokeWidth]=\"2\" />\n      </button>\n    </div>\n  </div>\n</div>\n\n<!-- Template c\u1EA5u h\u00ECnh Popover c\u00E0i \u0111\u1EB7t s\u1EED d\u1EE5ng ng-template -->\n<ng-template #speedMenuTemplate>\n  <div\n    class=\"z-media-player-settings flex w-44 flex-col px-1 py-[4px] text-zinc-200\"\n    [class.z-main-panel]=\"settingsPanel() === 'main'\"\n    [class.z-sub-panel]=\"settingsPanel() !== 'main'\">\n    @if (settingsPanel() === 'main') {\n      <div class=\"z-media-player-settings-panel flex flex-col\">\n        @if (qualitySources().length > 1) {\n          <button type=\"button\" class=\"z-media-player-settings-item\" (click)=\"openSettingsPanel('quality')\">\n            <span class=\"min-w-0 flex-1 truncate whitespace-nowrap\">\n              {{ 'i18n_z_ui_media_player_quality' | translate }}\n            </span>\n            <span class=\"flex max-w-[5.5rem] min-w-0 items-center gap-1.5 text-zinc-400\">\n              <span class=\"min-w-0 truncate whitespace-nowrap\">{{ activeQualityLabel() }}</span>\n              <z-icon zType=\"lucideChevronRight\" zSize=\"13\" class=\"shrink-0\" />\n            </span>\n          </button>\n        }\n        <button type=\"button\" class=\"z-media-player-settings-item\" (click)=\"openSettingsPanel('speed')\">\n          <span class=\"min-w-0 flex-1 truncate whitespace-nowrap\">\n            {{ 'i18n_z_ui_media_player_speed' | translate }}\n          </span>\n          <span class=\"flex max-w-[5.5rem] min-w-0 items-center gap-1.5 text-zinc-400\">\n            <span class=\"min-w-0 truncate whitespace-nowrap\">\n              {{ playbackSpeed() === 1 ? ('i18n_z_ui_media_player_normal' | translate) : playbackSpeed() + 'x' }}\n            </span>\n            <z-icon zType=\"lucideChevronRight\" zSize=\"13\" class=\"shrink-0\" />\n          </span>\n        </button>\n      </div>\n    }\n\n    @if (settingsPanel() === 'quality') {\n      <div class=\"z-media-player-settings-panel flex flex-col\">\n        <button\n          type=\"button\"\n          [title]=\"'i18n_z_ui_media_player_back' | translate\"\n          class=\"z-media-player-settings-back\"\n          (click)=\"closeSettingsPanel()\">\n          <z-icon zType=\"lucideChevronLeft\" zSize=\"13\" class=\"shrink-0\" />\n          <span class=\"min-w-0 truncate whitespace-nowrap\">{{ 'i18n_z_ui_media_player_quality' | translate }}</span>\n        </button>\n        @for (source of qualitySources(); track source.src) {\n          <button\n            type=\"button\"\n            [id]=\"'z_media_player_quality_btn_' + source.label\"\n            class=\"z-media-player-settings-item\"\n            [class.z-active]=\"effectiveSrc() === source.src\"\n            (click)=\"setQualitySource(source)\">\n            <span class=\"min-w-0 truncate whitespace-nowrap\">{{ source.label }}</span>\n          </button>\n        }\n      </div>\n    }\n\n    @if (settingsPanel() === 'speed') {\n      <div class=\"z-media-player-settings-panel flex flex-col\">\n        <button\n          type=\"button\"\n          [title]=\"'i18n_z_ui_media_player_back' | translate\"\n          class=\"z-media-player-settings-back\"\n          (click)=\"closeSettingsPanel()\">\n          <z-icon zType=\"lucideChevronLeft\" zSize=\"13\" class=\"shrink-0\" />\n          <span class=\"min-w-0 truncate whitespace-nowrap\">{{ 'i18n_z_ui_media_player_speed' | translate }}</span>\n        </button>\n        @for (speed of playbackSpeeds; track speed.value) {\n          <button\n            type=\"button\"\n            [id]=\"'z_media_player_speed_btn_' + speed.value\"\n            class=\"z-media-player-settings-item\"\n            [class.z-active]=\"playbackSpeed() === speed.value\"\n            (click)=\"setPlaybackSpeed(speed.value)\">\n            <span class=\"min-w-0 truncate whitespace-nowrap\">{{ speed.label | translate }}</span>\n          </button>\n        }\n      </div>\n    }\n  </div>\n</ng-template>\n", styles: ["z-media-player{display:block;width:100%;outline:none}z-media-player:focus,z-media-player:focus-visible{outline:none}z-media-player video::cue{background-color:#080808d9;color:#fff;font-family:inherit;font-size:16px;text-shadow:0 1px 2px rgba(0,0,0,.9);padding:4px 8px;border-radius:4px}z-media-player .z-flash-animation{animation:zUiFlashIcon .72s cubic-bezier(.2,.85,.25,1) forwards;will-change:opacity,transform,filter}z-media-player .z-flash-animation z-icon{width:24px!important;height:24px!important}@media(min-width:640px){z-media-player .z-flash-animation z-icon{width:32px!important;height:32px!important}}@keyframes zUiFlashIcon{0%{filter:blur(2px);opacity:0;transform:scale(.72)}18%{filter:blur(0);opacity:.95;transform:scale(1)}58%{opacity:.9;transform:scale(1.04)}to{filter:blur(0);opacity:0;transform:scale(1.18)}}z-media-player .animate-fade-in{animation:zUiFadeIn .2s cubic-bezier(.16,1,.3,1)}@keyframes zUiFadeIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}z-media-player .z-double-tap-ripple-left,z-media-player .z-double-tap-ripple-right{position:absolute;top:0;bottom:0;width:35%;display:flex;align-items:center;z-index:11;pointer-events:none}z-media-player .z-double-tap-ripple-left:before,z-media-player .z-double-tap-ripple-right:before{position:absolute;inset:0;content:\"\";opacity:0;animation-duration:.72s;animation-fill-mode:forwards;animation-timing-function:cubic-bezier(.25,1,.5,1)}z-media-player .z-double-tap-ripple-left{left:0;justify-content:flex-start;padding-left:5%}z-media-player .z-double-tap-ripple-left:before{background:radial-gradient(circle at 0% 50%,#ffffff21,#fff0 70%);border-top-right-radius:100% 50%;border-bottom-right-radius:100% 50%;animation-name:zUiDoubleTapRippleLeft;transform-origin:left center}z-media-player .z-double-tap-ripple-left.z-skip-pulse-alt:before{animation-name:zUiDoubleTapRippleLeftAlt}z-media-player .z-double-tap-ripple-right{right:0;justify-content:flex-end;padding-right:5%}z-media-player .z-double-tap-ripple-right:before{background:radial-gradient(circle at 100% 50%,#ffffff21,#fff0 70%);border-top-left-radius:100% 50%;border-bottom-left-radius:100% 50%;animation-name:zUiDoubleTapRippleRight;transform-origin:right center}z-media-player .z-double-tap-ripple-right.z-skip-pulse-alt:before{animation-name:zUiDoubleTapRippleRightAlt}z-media-player .z-skip-overlay-content{position:relative;display:flex;align-items:center;justify-content:center;gap:6px;min-width:92px;color:#fff;font-family:inherit;font-size:18px;font-weight:700;line-height:1;text-shadow:0 2px 8px rgba(0,0,0,.75);-webkit-user-select:none;user-select:none}z-media-player .z-skip-overlay-number{min-width:42px;animation:zUiSkipNumberBump .22s cubic-bezier(.2,.85,.25,1) forwards;text-align:center;transform-origin:center}z-media-player .z-skip-pulse-alt .z-skip-overlay-number{animation-name:zUiSkipNumberBumpAlt}z-media-player .z-skip-overlay-arrows{display:inline-flex;align-items:center;color:#fffffff2;filter:drop-shadow(0 2px 6px rgba(0,0,0,.7))}@keyframes zUiDoubleTapRippleLeft{0%{opacity:0;transform:scaleX(.5);transform-origin:left center}15%{opacity:1}80%{opacity:1}to{opacity:0;transform:scaleX(1);transform-origin:left center}}@keyframes zUiDoubleTapRippleLeftAlt{0%{opacity:0;transform:scaleX(.5);transform-origin:left center}15%{opacity:1}80%{opacity:1}to{opacity:0;transform:scaleX(1);transform-origin:left center}}@keyframes zUiDoubleTapRippleRight{0%{opacity:0;transform:scaleX(.5);transform-origin:right center}15%{opacity:1}80%{opacity:1}to{opacity:0;transform:scaleX(1);transform-origin:right center}}@keyframes zUiDoubleTapRippleRightAlt{0%{opacity:0;transform:scaleX(.5);transform-origin:right center}15%{opacity:1}80%{opacity:1}to{opacity:0;transform:scaleX(1);transform-origin:right center}}z-media-player .z-chevron-slide-left{animation:zUiChevronSlideLeft .72s cubic-bezier(.25,1,.5,1) forwards}z-media-player .z-chevron-slide-right{animation:zUiChevronSlideRight .72s cubic-bezier(.25,1,.5,1) forwards}z-media-player .z-skip-pulse-alt .z-chevron-slide-left{animation-name:zUiChevronSlideLeftAlt}z-media-player .z-skip-pulse-alt .z-chevron-slide-right{animation-name:zUiChevronSlideRightAlt}@keyframes zUiSkipNumberBump{0%{opacity:.78;transform:scale(.92)}55%{opacity:1;transform:scale(1.12)}to{opacity:1;transform:scale(1)}}@keyframes zUiSkipNumberBumpAlt{0%{opacity:.78;transform:scale(.92)}55%{opacity:1;transform:scale(1.12)}to{opacity:1;transform:scale(1)}}@keyframes zUiChevronSlideLeft{0%{opacity:0;transform:translate(8px)}28%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-12px)}}@keyframes zUiChevronSlideRight{0%{opacity:0;transform:translate(-8px)}28%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(12px)}}@keyframes zUiChevronSlideLeftAlt{0%{opacity:0;transform:translate(8px)}28%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-12px)}}@keyframes zUiChevronSlideRightAlt{0%{opacity:0;transform:translate(-8px)}28%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(12px)}}z-media-player #z_media_player_volume_slider{-webkit-appearance:none;appearance:none;background:transparent}z-media-player #z_media_player_volume_slider::-webkit-slider-runnable-track{background:#ffffff40;height:3px;border-radius:9999px}z-media-player #z_media_player_volume_slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background:#fff;height:10px;width:10px;border-radius:9999px;margin-top:-3.5px;transition:transform .15s ease}z-media-player #z_media_player_volume_slider:hover::-webkit-slider-thumb,z-media-player #z_media_player_volume_slider:focus-visible::-webkit-slider-thumb{transform:scale(1.3)}z-media-player #z_media_player_volume_slider::-moz-range-track{background:#ffffff40;height:3px;border-radius:9999px}z-media-player #z_media_player_volume_slider::-moz-range-thumb{background:#fff;height:10px;width:10px;border-radius:9999px;border:none;transition:transform .15s ease}z-media-player #z_media_player_volume_slider:hover::-moz-range-thumb,z-media-player #z_media_player_volume_slider:focus-visible::-moz-range-thumb{transform:scale(1.3)}.z-media-player-popover{backdrop-filter:blur(24px)!important;-webkit-backdrop-filter:blur(24px)!important;background-color:#0f0f0f99!important;border:1px solid rgba(255,255,255,.08)!important;box-shadow:0 15px 30px -10px #000c!important;border-radius:8px!important;padding:0!important;transform-origin:bottom right}.z-media-player-popover[data-state=open]{animation:zUiMediaSettingsPopoverIn .16s cubic-bezier(.2,.85,.25,1) forwards}.z-media-player-popover[data-state=closed]{animation:zUiMediaSettingsPopoverOut .16s cubic-bezier(.4,0,.2,1) forwards!important}.z-media-player-popover .bg-popover{background-color:transparent!important;color:#e4e4e7!important}.z-media-player-popover .z-media-player-settings{overflow:hidden;transform-origin:bottom right;animation:zUiMediaSettingsPanelIn .16s cubic-bezier(.2,.85,.25,1)}.z-media-player-popover .z-media-player-settings-panel{gap:4px;transform-origin:top right;animation:zUiMediaSettingsPanelIn .14s cubic-bezier(.2,.85,.25,1);will-change:opacity,transform}.z-media-player-popover .z-media-player-settings.z-main-panel .z-media-player-settings-panel{animation-name:zUiMediaSettingsPanelFromLeft}.z-media-player-popover .z-media-player-settings.z-sub-panel .z-media-player-settings-panel{animation-name:zUiMediaSettingsPanelFromRight}.z-media-player-popover .z-media-player-settings-item,.z-media-player-popover .z-media-player-settings-back{position:relative;display:flex;width:100%;min-width:0;height:32px;min-height:32px;cursor:pointer;align-items:center;border:0;border-radius:4px;background-color:transparent;padding:0 8px;color:#e4e4e7;font-size:12px;font-weight:500;line-height:1;outline:none;transition:background-color .12s ease,color .12s ease}.z-media-player-popover .z-media-player-settings-item{justify-content:space-between;gap:12px;text-align:left}.z-media-player-popover .z-media-player-settings-item:before{position:absolute;top:7px;bottom:7px;left:0;width:2px;border-radius:9999px;background-color:#fff;content:\"\";opacity:0;transform:scaleY(.5);transition:opacity .12s ease,transform .12s ease}.z-media-player-popover .z-media-player-settings-item.z-active{background-color:#ffffff14;color:#fff;font-weight:600}.z-media-player-popover .z-media-player-settings-item.z-active:before{opacity:1;transform:scaleY(1)}.z-media-player-popover .z-media-player-settings-back{justify-content:flex-start;gap:8px;color:#f4f4f5;font-weight:600}.z-media-player-popover .z-media-player-settings-item:hover,.z-media-player-popover .z-media-player-settings-back:hover,.z-media-player-popover .z-media-player-settings-item:focus-visible,.z-media-player-popover .z-media-player-settings-back:focus-visible{background-color:#ffffff1a}@keyframes zUiMediaSettingsPopoverIn{0%{opacity:0;transform:translateY(6px) scale(.94)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes zUiMediaSettingsPopoverOut{0%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(4px) scale(.96)}}@keyframes zUiMediaSettingsPanelIn{0%{opacity:0;transform:translateY(3px)}to{opacity:1;transform:translateY(0)}}@keyframes zUiMediaSettingsPanelFromRight{0%{opacity:0;transform:translate(8px)}to{opacity:1;transform:translate(0)}}@keyframes zUiMediaSettingsPanelFromLeft{0%{opacity:0;transform:translate(-5px)}to{opacity:1;transform:translate(0)}}\n"] }]
        }], ctorParameters: () => [], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], zSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSrc", required: true }] }], zSources: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSources", required: false }] }], zPoster: [{ type: i0.Input, args: [{ isSignal: true, alias: "zPoster", required: false }] }], zAutoplay: [{ type: i0.Input, args: [{ isSignal: true, alias: "zAutoplay", required: false }] }], zLoop: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLoop", required: false }] }], zMuted: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMuted", required: false }] }], zVolume: [{ type: i0.Input, args: [{ isSignal: true, alias: "zVolume", required: false }] }], zSubtitles: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSubtitles", required: false }] }], zPlay: [{ type: i0.Output, args: ["zPlay"] }], zTimeUpdate: [{ type: i0.Output, args: ["zTimeUpdate"] }], zVolumeChange: [{ type: i0.Output, args: ["zVolumeChange"] }], zFullscreenChange: [{ type: i0.Output, args: ["zFullscreenChange"] }], zTheaterModeChange: [{ type: i0.Output, args: ["zTheaterModeChange"] }], zMiniplayerChange: [{ type: i0.Output, args: ["zMiniplayerChange"] }], zQualityChange: [{ type: i0.Output, args: ["zQualityChange"] }], videoElement: [{ type: i0.ViewChild, args: ['videoElement', { isSignal: true }] }], timelineContainer: [{ type: i0.ViewChild, args: ['timelineContainer', { isSignal: true }] }] } });

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

export { ZMediaPlayerComponent };
//# sourceMappingURL=shival99-z-ui-components-z-media-player.mjs.map
