UNPKG

@ngx-telly/player

Version:

Telly - Angular frame-accurate HTML player

1 lines 78.6 kB
{"version":3,"file":"ngx-telly-player.mjs","sources":["../../../../libs/player/src/lib/components/player/player.component.ts","../../../../libs/player/src/lib/components/player/player.component.html","../../../../libs/player/src/lib/components/buffering/buffering.component.ts","../../../../libs/player/src/lib/components/buffering/buffering.component.html","../../../../libs/player/src/lib/components/message-outlet/message-outlet.component.ts","../../../../libs/player/src/lib/components/message-outlet/message-outlet.component.html","../../../../libs/player/src/lib/components/controls/controls.component.ts","../../../../libs/player/src/lib/components/controls/controls.component.html","../../../../libs/player/src/lib/components/controls/forward/forward.component.ts","../../../../libs/player/src/lib/components/controls/forward/forward.component.html","../../../../libs/player/src/lib/components/controls/fullscreen/fullscreen.component.ts","../../../../libs/player/src/lib/components/controls/fullscreen/fullscreen.component.html","../../../../libs/player/src/lib/components/controls/play/play.component.ts","../../../../libs/player/src/lib/components/controls/play/play.component.html","../../../../libs/player/src/lib/components/controls/rewind/rewind.component.ts","../../../../libs/player/src/lib/components/controls/rewind/rewind.component.html","../../../../libs/player/src/lib/components/controls/time/time.component.ts","../../../../libs/player/src/lib/components/controls/time/time.component.html","../../../../libs/player/src/lib/components/controls/scrub-bar/scrub-bar.component.ts","../../../../libs/player/src/lib/components/controls/scrub-bar/scrub-bar.component.html","../../../../libs/player/src/lib/components/controls/scrub-bar-current-time/scrub-bar-current-time.component.ts","../../../../libs/player/src/lib/components/controls/scrub-bar-current-time/scrub-bar-current-time.component.html","../../../../libs/player/src/lib/components/controls/scrub-bar-buffered/scrub-bar-buffered.component.ts","../../../../libs/player/src/lib/components/controls/scrub-bar-buffered/scrub-bar-buffered.component.html","../../../../libs/player/src/lib/components/controls/scrub-bar-time/scrub-bar-time.component.ts","../../../../libs/player/src/lib/components/controls/scrub-bar-time/scrub-bar-time.component.html","../../../../libs/player/src/lib/components/controls/spacer/spacer.component.ts","../../../../libs/player/src/lib/components/controls/volume/volume-button/volume-icon.pipe.ts","../../../../libs/player/src/lib/components/controls/volume/volume-button/volume-button.component.ts","../../../../libs/player/src/lib/components/controls/volume/volume-button/volume-button.component.html","../../../../libs/player/src/lib/components/controls/volume/volume-slider/volume-slider.component.ts","../../../../libs/player/src/lib/components/controls/volume/volume-slider/volume-slider.component.html","../../../../libs/player/src/lib/components/controls/volume/volume.component.ts","../../../../libs/player/src/lib/components/controls/volume/volume.component.html","../../../../libs/player/src/lib/components/controls/jump-forward/jump-forward-icon.pipe.ts","../../../../libs/player/src/lib/components/controls/jump-forward/jump-forward.component.ts","../../../../libs/player/src/lib/components/controls/jump-forward/jump-forward.component.html","../../../../libs/player/src/lib/components/controls/jump-back/jump-back-icon.pipe.ts","../../../../libs/player/src/lib/components/controls/jump-back/jump-back.component.ts","../../../../libs/player/src/lib/components/controls/jump-back/jump-back.component.html","../../../../libs/player/src/ngx-telly-player.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n HostBinding,\n HostListener,\n inject,\n input,\n OnChanges,\n OnDestroy,\n OnInit,\n output,\n SimpleChanges,\n ViewChild,\n} from '@angular/core';\nimport { CrossOriginAttr, debounceMove, PreloadAttr, tellyConfigToken, TellyMedia } from '@ngx-telly/player/core';\nimport {\n TellyDurationCapperService,\n TellyEventsService,\n TellyMediaService,\n TellyPluginOrchestratorService,\n} from '@ngx-telly/player/services';\nimport { fromEvent, merge, Observable, takeUntil, tap, timer } from 'rxjs';\n\n@Component({\n selector: 'telly-player',\n templateUrl: './player.component.html',\n styleUrls: ['./player.component.scss'],\n providers: [TellyDurationCapperService],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PlayerComponent implements OnInit, OnDestroy, OnChanges {\n id = input.required<string>();\n src = input<string>();\n poster = input<string>();\n controlsList = input<string>();\n showId = input<boolean>(false);\n autoHide = input<boolean>(true);\n autoPlay = input<boolean>(false);\n autoPip = input<boolean>(false);\n disablePip = input<boolean>(false);\n controls = input<boolean>(true);\n loop = input<boolean>(false);\n muted = input<boolean>(false);\n disableRemotePlayback = input<boolean>(false);\n height = input<number>();\n width = input<number>();\n capToDuration = input<number>(0);\n updateInterval = input<number>(1000);\n hideDelay = input<number>(3000);\n startFrom = input<number>(0);\n timeOffset = input<number>(0);\n crossOrigin = input<CrossOriginAttr>();\n preload = input<PreloadAttr>();\n clickable = input<boolean>(true);\n\n created = output<TellyMedia>();\n\n @ViewChild('video', { static: true })\n video!: ElementRef<HTMLVideoElement>;\n\n @HostBinding('class.hide')\n private hide = false;\n\n config = inject(tellyConfigToken);\n media!: TellyMedia;\n element = inject(ElementRef).nativeElement;\n mediaService = inject(TellyMediaService);\n events = inject(TellyEventsService);\n capper = inject(TellyDurationCapperService);\n orchestrator = inject(TellyPluginOrchestratorService);\n\n @HostListener('pointerup')\n onClick() {\n this.events.click$.next();\n }\n\n ngOnInit(): void {\n this.setTimer();\n this.setEvents();\n\n this.events.activity$\n .pipe(\n debounceMove(3000, this.events.destroy$, (hide) => (this.hide = hide)),\n tap((hide) => this.events.hide$.next(hide))\n )\n .subscribe();\n\n this.orchestrator.registerMediaFactory();\n\n this.media = this.create();\n this.created.emit(this.media);\n\n if (this.capToDuration()) this.capper.set(this.capToDuration(), this.media);\n }\n\n ngOnChanges(changes: SimpleChanges) {\n if (changes['capToDuration']?.currentValue && !changes['capToDuration'].firstChange) {\n this.events.reconfigure$.next();\n this.capper.set(changes['capToDuration'].currentValue, this.media);\n }\n }\n\n onContainerClick() {\n if (this.clickable()) {\n this.media.toggle();\n }\n }\n\n create(): TellyMedia {\n const media = new TellyMedia(this.id(), this.video.nativeElement, this.config);\n this.mediaService.register(media);\n return this.mediaService.get(this.id()) as TellyMedia;\n }\n\n setTimer(): void {\n this.events.timer$ = timer(0, this.updateInterval());\n }\n\n setEvents(): void {\n this.events.activity$ = merge(\n fromEvent(this.element, 'mousemove'),\n fromEvent(this.element, 'touchmove'),\n fromEvent(this.element, 'touchend'),\n fromEvent(this.element, 'scroll'),\n fromEvent(this.element, 'wheel'),\n fromEvent(this.element, 'click')\n ) as Observable<Event>;\n\n fromEvent(this.video.nativeElement, 'click')\n .pipe(takeUntil(this.events.destroy$))\n .subscribe(() => this.events.click$.next);\n }\n\n ngOnDestroy(): void {\n this.events.destroy$.next();\n if (this.media?.id) this.mediaService.deregister(this.media.id);\n }\n}\n","<div class=\"telly-container\" (click)=\"onContainerClick()\">\n <div class=\"telly-overlay\">\n <video\n #video\n playsinline\n [src]=\"src()\"\n [autoplay]=\"autoPlay()\"\n [controls]=\"controls()\"\n [loop]=\"loop()\"\n [muted]=\"muted()\"\n [disableRemotePlayback]=\"disableRemotePlayback()\"\n [crossOrigin]=\"crossOrigin()\"\n [attr.preload]=\"preload()\"\n [attr.poster]=\"poster()\"\n [attr.height]=\"height()\"\n [attr.width]=\"width()\"\n >\n </video>\n <ng-content select=\"[overlay]\"></ng-content>\n </div>\n\n @if (media) {\n <ng-content></ng-content>\n }\n</div>\n\n<svg style=\"position: absolute\">\n <linearGradient\n id=\"telly-gradient\"\n gradientTransform=\"rotate(65)\"\n >\n <stop\n offset=\"0%\"\n stop-color=\"#F24C13\"\n />\n <stop\n offset=\"50%\"\n stop-color=\"#f36c15\"\n />\n <stop\n offset=\"100%\"\n stop-color=\"#F48616\"\n />\n </linearGradient>\n</svg>\n","import { ChangeDetectionStrategy, Component, HostBinding, inject, OnInit } from '@angular/core';\nimport { Browser, BROWSER, eventType, VideoEvent } from \"@ngx-telly/player/core\";\nimport { TellyEventsService } from \"@ngx-telly/player/services\";\nimport { debounceTime, map, merge, Subject, tap } from \"rxjs\";\nimport { PlayerComponent } from \"../player/player.component\";\n\n@Component({\n selector: 'telly-buffering',\n templateUrl: './buffering.component.html',\n styleUrls: [ './buffering.component.scss' ],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class BufferingComponent implements OnInit {\n player = inject(PlayerComponent);\n events = inject(TellyEventsService);\n platform = inject(BROWSER);\n play = false;\n suspend$ = new Subject<Event>();\n\n @HostBinding('class.hide') hide = false;\n\n ngOnInit() {\n const watcher = this.getWatcher();\n\n merge(this.player.media?.events, this.suspend$.pipe(debounceTime(4000)))\n .pipe(\n eventType([\n VideoEvent.Playing,\n VideoEvent.Pause,\n VideoEvent.Progress,\n VideoEvent.Stalled,\n VideoEvent.Suspend,\n VideoEvent.Seeked,\n VideoEvent.Seeking,\n VideoEvent.Waiting\n ]),\n tap((ev) => {\n switch (ev.type) {\n case VideoEvent.Playing:\n this.play = true;\n break;\n case VideoEvent.Pause:\n this.play = false;\n break;\n }\n }),\n tap((ev) => {\n if (ev.type === VideoEvent.Progress) {\n this.suspend$.next(new Event(VideoEvent.Suspend));\n }\n }),\n map((ev) => {\n return watcher(ev);\n })\n )\n .subscribe((buffering) => {\n if (typeof buffering !== 'boolean') return;\n this.hide = !buffering;\n });\n }\n\n getWatcher(): (ev: Event) => boolean | undefined {\n switch (this.platform) {\n case Browser.Chromium:\n return this.chromiumWatcher;\n case Browser.Webkit:\n return this.webkitWatcher;\n case Browser.Firefox:\n return this.firefoxWatcher;\n case Browser.Ios:\n return this.webkitWatcher;\n default:\n return this.chromiumWatcher;\n }\n }\n\n chromiumWatcher = (ev: Event): boolean | undefined => {\n if (ev.type === VideoEvent.Playing) {\n return false;\n }\n\n if (ev.type === VideoEvent.Waiting) {\n return true;\n }\n\n if (ev.type === VideoEvent.Ended) {\n return false;\n }\n\n if (ev.type === VideoEvent.Suspend) {\n return false;\n }\n\n return;\n };\n\n webkitWatcher = (ev: Event): boolean | undefined => {\n return this.chromiumWatcher(ev);\n };\n\n firefoxWatcher = (ev: Event): boolean | undefined => {\n return this.chromiumWatcher(ev);\n };\n}\n","<svg\n width=\"135\"\n height=\"140\"\n viewBox=\"0 0 135 140\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"#fff\"\n>\n <rect\n y=\"10\"\n width=\"15\"\n height=\"120\"\n rx=\"6\"\n >\n <animate\n attributeName=\"height\"\n begin=\"0.5s\"\n dur=\"1s\"\n values=\"120;110;100;90;80;70;60;50;40;140;120\"\n calcMode=\"linear\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"y\"\n begin=\"0.5s\"\n dur=\"1s\"\n values=\"10;15;20;25;30;35;40;45;50;0;10\"\n calcMode=\"linear\"\n repeatCount=\"indefinite\"\n />\n </rect>\n <rect\n x=\"30\"\n y=\"10\"\n width=\"15\"\n height=\"120\"\n rx=\"6\"\n >\n <animate\n attributeName=\"height\"\n begin=\"0.25s\"\n dur=\"1s\"\n values=\"120;110;100;90;80;70;60;50;40;140;120\"\n calcMode=\"linear\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"y\"\n begin=\"0.25s\"\n dur=\"1s\"\n values=\"10;15;20;25;30;35;40;45;50;0;10\"\n calcMode=\"linear\"\n repeatCount=\"indefinite\"\n />\n </rect>\n <rect\n x=\"60\"\n width=\"15\"\n height=\"140\"\n rx=\"6\"\n >\n <animate\n attributeName=\"height\"\n begin=\"0s\"\n dur=\"1s\"\n values=\"120;110;100;90;80;70;60;50;40;140;120\"\n calcMode=\"linear\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"y\"\n begin=\"0s\"\n dur=\"1s\"\n values=\"10;15;20;25;30;35;40;45;50;0;10\"\n calcMode=\"linear\"\n repeatCount=\"indefinite\"\n />\n </rect>\n <rect\n x=\"90\"\n y=\"10\"\n width=\"15\"\n height=\"120\"\n rx=\"6\"\n >\n <animate\n attributeName=\"height\"\n begin=\"0.25s\"\n dur=\"1s\"\n values=\"120;110;100;90;80;70;60;50;40;140;120\"\n calcMode=\"linear\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"y\"\n begin=\"0.25s\"\n dur=\"1s\"\n values=\"10;15;20;25;30;35;40;45;50;0;10\"\n calcMode=\"linear\"\n repeatCount=\"indefinite\"\n />\n </rect>\n <rect\n x=\"120\"\n y=\"10\"\n width=\"15\"\n height=\"120\"\n rx=\"6\"\n >\n <animate\n attributeName=\"height\"\n begin=\"0.5s\"\n dur=\"1s\"\n values=\"120;110;100;90;80;70;60;50;40;140;120\"\n calcMode=\"linear\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"y\"\n begin=\"0.5s\"\n dur=\"1s\"\n values=\"10;15;20;25;30;35;40;45;50;0;10\"\n calcMode=\"linear\"\n repeatCount=\"indefinite\"\n />\n </rect>\n</svg>\n","import { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit } from '@angular/core';\nimport { TellyEventsService } from '@ngx-telly/player/services';\nimport { debounceTime, takeUntil, tap } from 'rxjs';\nimport { PlayerComponent } from '../player/player.component';\n\n@Component({\n selector: 'telly-message-outlet',\n templateUrl: './message-outlet.component.html',\n styleUrls: ['./message-outlet.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [AsyncPipe]\n})\nexport class MessageOutletComponent implements OnInit {\n player = inject(PlayerComponent);\n events = inject(TellyEventsService);\n cdr = inject(ChangeDetectorRef);\n\n show = false;\n\n ngOnInit() {\n this.player.media?.messages\n .pipe(\n takeUntil(this.events.destroy$),\n tap(() => {\n this.show = true;\n this.cdr.markForCheck();\n }),\n debounceTime(1500)\n )\n .subscribe(() => {\n this.show = false;\n this.cdr.markForCheck();\n });\n }\n}\n","<span class=\"indicator\" [style.opacity]=\"show ? 1 : 0\">{{ player.media.internalEvents$ | async }}</span>\n","\nimport { ChangeDetectionStrategy, Component, HostBinding, HostListener, inject, Input, OnInit, DOCUMENT } from '@angular/core';\nimport { debounceMove } from '@ngx-telly/player/core';\nimport { TellyEventsService } from '@ngx-telly/player/services';\nimport { PlayerComponent } from '../player/player.component';\nimport { fromEvent, takeUntil } from 'rxjs';\n\n@Component({\n selector: 'telly-controls',\n templateUrl: './controls.component.html',\n styleUrls: ['./controls.component.scss'],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ControlsComponent implements OnInit {\n @Input() @HostBinding('class') class = 'telly-element';\n\n @HostBinding('class.hide')\n hide = false;\n\n private events = inject(TellyEventsService);\n private player = inject(PlayerComponent);\n private doc = inject(DOCUMENT);\n\n @HostListener('click', ['$event'])\n public onClick(event: MouseEvent): void {\n event.stopPropagation();\n }\n\n ngOnInit(): void {\n this.events.activity$\n .pipe(\n debounceMove(this.player.hideDelay(), this.events.destroy$, (hide) => {\n if (this.doc.fullscreenElement || this.player.autoHide()) {\n this.hide = hide;\n }\n })\n )\n .subscribe();\n\n fromEvent(this.player.element, 'fullscreenchange')\n .pipe(takeUntil(this.events.destroy$))\n .subscribe(() => {\n const fullscreen = !!this.doc.fullscreenElement;\n if (!fullscreen) {\n this.hide = false;\n }\n });\n }\n}\n","<ng-content></ng-content>\n","import { ChangeDetectionStrategy, Component, HostBinding, HostListener, inject, input } from '@angular/core';\nimport { fastForward } from '@ngx-telly/player/core';\nimport { PlayerComponent } from '../../player/player.component';\n\n@Component({\n selector: 'telly-forward',\n templateUrl: './forward.component.html',\n styleUrls: ['./forward.component.scss'],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ForwardComponent {\n icon = input(fastForward);\n size = input('1.6rem');\n\n player = inject(PlayerComponent);\n\n playing = false;\n handle = false;\n\n @HostBinding('attr.tip') title = 'Forward';\n\n @HostListener('pointerdown')\n onPointerDown(): void {\n this.playing = this.player.media.playing;\n this.handle = true;\n this.player.media.setRate(4);\n }\n\n @HostListener('pointerup')\n @HostListener('pointerleave')\n onPointerUpOrLeave(): void {\n if (this.handle) {\n this.player.media.setRate(1);\n this.playing ? this.player.media.play() : this.player.media.pause();\n this.handle = false;\n }\n }\n}\n","<svg\n viewBox=\"0 0 24 24\"\n [style.width]=\"size()\"\n>\n <path\n fill=\"white\"\n [attr.d]=\"icon()\"\n />\n</svg>\n","\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n effect,\n HostBinding,\n HostListener,\n inject,\n input,\n OnInit,\n DOCUMENT\n} from '@angular/core';\nimport { fullScreen, smallScreen } from '@ngx-telly/player/core';\nimport { TellyEventsService, TellyFullscreenService } from '@ngx-telly/player/services';\nimport { fromEvent, takeUntil } from 'rxjs';\nimport { PlayerComponent } from '../../player/player.component';\n\n@Component({\n selector: 'telly-fullscreen',\n templateUrl: './fullscreen.component.html',\n styleUrls: ['./fullscreen.component.scss'],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FullscreenComponent implements OnInit {\n icon = input(fullScreen);\n alternativeIcon = input(smallScreen);\n size = input('1.6rem');\n\n player = inject(PlayerComponent);\n events = inject(TellyEventsService);\n cdr = inject(ChangeDetectorRef);\n doc = inject(DOCUMENT);\n service = inject(TellyFullscreenService);\n\n @HostBinding('attr.tip') title = 'Big';\n\n constructor() {\n effect(() => {\n if (this.service.fullscreen()) {\n this.player.element.requestFullscreen();\n } else {\n this.doc.fullscreenElement != null && this.doc?.exitFullscreen();\n }\n });\n }\n\n ngOnInit() {\n fromEvent(this.player.element, 'fullscreenchange')\n .pipe(takeUntil(this.events.destroy$))\n .subscribe(() => {\n this.service.fullscreen.set(!!this.doc.fullscreenElement);\n this.title = this.service.fullscreen() ? 'Small' : 'Big';\n this.cdr.markForCheck();\n });\n }\n\n @HostListener('click')\n onClick(): void {\n this.service.toggle();\n }\n}\n","<svg\n viewBox=\"0 0 24 24\"\n [style.width]=\"size()\"\n>\n <path\n fill=\"white\"\n [attr.d]=\"service.fullscreen() ? alternativeIcon() : icon()\"\n />\n</svg>\n","import { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, HostBinding, HostListener, inject, input, OnInit } from '@angular/core';\nimport { eventType, pause, play, VideoEvent } from '@ngx-telly/player/core';\nimport { map, Observable, startWith } from 'rxjs';\nimport { PlayerComponent } from '../../player/player.component';\n\n@Component({\n selector: 'telly-play',\n templateUrl: './play.component.html',\n styleUrls: ['./play.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [AsyncPipe]\n})\nexport class PlayComponent implements OnInit {\n playIcon = input(play);\n pauseIcon = input(pause);\n size = input('1.2rem');\n\n player = inject(PlayerComponent);\n status$!: Observable<string>;\n\n @HostBinding('attr.tip') title = 'Toggle';\n\n @HostListener('pointerdown')\n onClick(): void {\n this.player.media?.toggle();\n }\n\n ngOnInit(): void {\n this.status$ = this.player.media.events.pipe(\n startWith(new Event(VideoEvent.Pause)),\n eventType([VideoEvent.Play, VideoEvent.Pause, VideoEvent.Ended]),\n map(({ type }) => (type === VideoEvent.Play ? this.pauseIcon() : this.playIcon()))\n );\n }\n}\n","<svg\n viewBox=\"0 0 24 24\"\n [style.width]=\"'1.6rem'\"\n>\n <path\n fill=\"white\"\n [attr.d]=\"status$ | async\"\n />\n</svg>\n","import { ChangeDetectionStrategy, Component, HostBinding, HostListener, inject, input } from '@angular/core';\nimport { rewind } from '@ngx-telly/player/core';\nimport { PlayerComponent } from '../../player/player.component';\n\n@Component({\n selector: 'telly-rewind',\n templateUrl: './rewind.component.html',\n styleUrls: ['./rewind.component.scss'],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class RewindComponent {\n icon = input(rewind);\n size = input('1.6rem');\n\n player = inject(PlayerComponent);\n\n playing = false;\n handle = false;\n\n @HostBinding('attr.tip') title = 'Rewind';\n\n @HostListener('pointerdown')\n onPointerDown(): void {\n this.handle = true;\n this.playing = this.player.media.playing;\n this.player.media.setRate(-4);\n }\n\n @HostListener('pointerup')\n @HostListener('pointerleave')\n onPointerUpOrLeave(): void {\n if (this.handle) {\n this.player.media.setRate(1);\n this.playing ? this.player.media.play() : this.player.media.pause();\n this.handle = false;\n }\n }\n}\n","<svg\n viewBox=\"0 0 24 24\"\n [style.width]=\"size()\"\n>\n <path\n fill=\"white\"\n [attr.d]=\"icon()\"\n />\n</svg>\n","import { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, inject, OnInit } from '@angular/core';\nimport { getTime } from '@ngx-telly/player/core';\nimport { TellyEventsService } from '@ngx-telly/player/services';\nimport { distinctUntilChanged, map, Observable } from 'rxjs';\nimport { PlayerComponent } from '../../player/player.component';\n\n@Component({\n selector: 'telly-time',\n templateUrl: './time.component.html',\n styleUrls: ['./time.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [AsyncPipe]\n})\nexport class TimeComponent implements OnInit {\n player = inject(PlayerComponent);\n events = inject(TellyEventsService);\n time$!: Observable<string>;\n\n ngOnInit(): void {\n const { media, timeOffset } = this.player;\n this.time$ = this.events.timer$.pipe(\n map(() => Math.floor(media.time + timeOffset())),\n distinctUntilChanged(),\n map((sec) => getTime(sec))\n );\n }\n}\n","<p>{{ time$ | async }}</p>\n","import { ChangeDetectionStrategy, Component, ElementRef, HostListener, inject } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { PlayerComponent } from '../../player/player.component';\n\n@Component({\n selector: 'telly-scrub-bar',\n templateUrl: './scrub-bar.component.html',\n styleUrls: ['./scrub-bar.component.scss'],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ScrubBarComponent {\n player = inject(PlayerComponent);\n ref = inject(ElementRef<HTMLElement>);\n\n offset$ = new BehaviorSubject<number>(0);\n time$ = new BehaviorSubject<number>(0);\n hover$ = new BehaviorSubject<boolean>(false);\n\n handle = false;\n\n @HostListener('pointerup')\n onPointerUp(): void {\n this.handle = false;\n }\n\n @HostListener('pointerenter')\n onPointerEnter(): void {\n this.hover$.next(true);\n }\n\n @HostListener('pointerleave')\n onPointerLeave(): void {\n this.handle = false;\n this.hover$.next(false);\n }\n\n @HostListener('pointerdown', ['$event'])\n onPointerDown(e: PointerEvent): void {\n this.handle = true;\n\n if (e.pointerType === 'mouse' && e.button != 0) {\n return;\n }\n\n const offset = e.offsetX / this.ref.nativeElement.clientWidth;\n this.player.media?.seek(this.player.media.duration * offset);\n }\n\n @HostListener('pointermove', ['$event'])\n onPointerMove(e: PointerEvent): void {\n this.offset$.next(e.offsetX);\n this.time$.next(this.player.media.duration * (e.offsetX / this.ref.nativeElement.clientWidth));\n\n if (this.handle) {\n const offset = e.offsetX / this.ref.nativeElement.clientWidth;\n this.player.media?.seek(this.player.media.duration * offset);\n }\n }\n}\n","<ng-content select=\"[out]\"></ng-content>\n<div class=\"outlet\">\n <ng-content select=\"[in]\"></ng-content>\n</div>\n","import { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, inject, OnInit } from '@angular/core';\nimport { TellyEventsService } from '@ngx-telly/player/services';\nimport { distinctUntilChanged, map, Observable } from 'rxjs';\nimport { PlayerComponent } from '../../player/player.component';\n\n@Component({\n selector: 'telly-scrub-bar-current-time',\n templateUrl: './scrub-bar-current-time.component.html',\n styleUrls: ['./scrub-bar-current-time.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [AsyncPipe]\n})\nexport class ScrubBarCurrentTimeComponent implements OnInit {\n player = inject(PlayerComponent);\n events = inject(TellyEventsService);\n\n progress$!: Observable<number>;\n\n ngOnInit(): void {\n this.progress$ = this.events.timer$.pipe(\n map(() => this.getPercentage()),\n distinctUntilChanged()\n );\n }\n\n getPercentage(): number {\n return (this.player.media.windowTime / this.player.media.duration) * 100;\n }\n}\n","<div\n class=\"current\"\n [style.width.%]=\"(progress$ | async)\"\n></div>\n","import { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, inject, OnInit } from '@angular/core';\nimport { TellyEventsService } from '@ngx-telly/player/services';\nimport { distinctUntilChanged, map, Observable } from 'rxjs';\nimport { PlayerComponent } from '../../player/player.component';\n\n@Component({\n selector: 'telly-scrub-bar-buffered',\n templateUrl: './scrub-bar-buffered.component.html',\n styleUrls: ['./scrub-bar-buffered.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [AsyncPipe]\n})\nexport class ScrubBarBufferedComponent implements OnInit {\n player = inject(PlayerComponent);\n events = inject(TellyEventsService);\n\n buffered$!: Observable<{ width: number; offset: number }[]>;\n\n ngOnInit(): void {\n this.buffered$ = this.events.timer$.pipe(\n map(() => {\n const { buffered, drift, duration } = this.player.media;\n return [...Array(buffered.length)].map((_, idx) => ({\n width: ((buffered.end(idx) - buffered.start(idx)) / duration) * 100,\n offset: ((buffered.start(idx) - drift) / duration) * 100,\n }));\n }),\n distinctUntilChanged((previous, current) => JSON.stringify(previous) === JSON.stringify(current))\n );\n }\n}\n","@if (buffered$ | async; as buffered) {\n @for (buffer of buffered; track buffer) {\n <div\n class=\"buffer\"\n [style.width.%]=\"buffer.width\"\n [style.margin-left.%]=\"buffer.offset\"\n ></div>\n }\n}\n","import { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, ElementRef, HostBinding, inject, ViewChild } from '@angular/core';\nimport { getTime } from '@ngx-telly/player/core';\nimport { map } from 'rxjs';\nimport { PlayerComponent } from '../../player/player.component';\nimport { ScrubBarComponent } from '../scrub-bar/scrub-bar.component';\n\n@Component({\n selector: 'telly-scrub-bar-time',\n templateUrl: './scrub-bar-time.component.html',\n styleUrls: ['./scrub-bar-time.component.scss'],\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [AsyncPipe]\n})\nexport class ScrubBarTimeComponent {\n @ViewChild('outlet', { static: true }) outlet?: ElementRef<HTMLDivElement>;\n\n scrubBar = inject(ScrubBarComponent);\n player = inject(PlayerComponent);\n element = inject(ElementRef<HTMLElement>);\n\n @HostBinding('style.left.px') left = 0;\n\n offset$ = this.scrubBar.offset$.subscribe((x) => {\n this.left = Math.max(x - (this.element.nativeElement.clientWidth - 26) / 2);\n });\n\n time$ = this.scrubBar.offset$.pipe(\n map((x) => {\n const { media, timeOffset } = this.player;\n const percentage = x / this.scrubBar.ref.nativeElement.clientWidth;\n return getTime(timeOffset() + media.duration * percentage);\n })\n );\n}\n","<div class=\"telly-element wrapper\" [style.display]=\"(scrubBar.hover$ | async) ? 'flex' : 'none'\">\n <div class=\"outlet\" #outlet>\n <ng-content></ng-content>\n </div>\n</div>\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'telly-spacer',\n template: '',\n styles: [':host { flex-grow: 1 }'],\n standalone: true,\n})\nexport class SpacerComponent {}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { mute, volumeHigh, volumeLow, volumeMedium } from '@ngx-telly/player/core';\n\n@Pipe({\n name: 'volumeIcon',\n standalone: true,\n})\nexport class VolumeIconPipe implements PipeTransform {\n transform(volume: number): unknown {\n if (volume === 0) {\n return mute;\n } else if (volume < 0.3) {\n return volumeLow;\n } else if (volume < 0.6) {\n return volumeMedium;\n } else {\n return volumeHigh;\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, HostListener, inject, input } from '@angular/core';\nimport { mute, volumeHigh, volumeLow, volumeMedium } from '@ngx-telly/player/core';\nimport { PlayerComponent } from '../../../player/player.component';\nimport { VolumeIconPipe } from './volume-icon.pipe';\n\n@Component({\n selector: 'telly-volume-button',\n templateUrl: './volume-button.component.html',\n styleUrls: ['./volume-button.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [VolumeIconPipe]\n})\nexport class VolumeButtonComponent {\n iconMute = input(mute);\n iconLow = input(volumeLow);\n iconMedium = input(volumeMedium);\n iconHigh = input(volumeHigh);\n size = input('1.4rem');\n volume = input(1);\n\n player = inject(PlayerComponent);\n lastVolume?: number;\n\n @HostListener('pointerup')\n onClick() {\n if (this.volume() > 0) {\n this.lastVolume = this.volume();\n this.player.media.volume = 0;\n } else {\n this.player.media.volume = this.lastVolume ?? 1;\n }\n }\n}\n","<svg\n viewBox=\"0 0 24 24\"\n [style.width]=\"size()\"\n>\n <path\n fill=\"white\"\n [attr.d]=\"volume() | volumeIcon\"\n />\n</svg>\n","import { ChangeDetectionStrategy, Component, ElementRef, HostListener, inject, input } from '@angular/core';\nimport { PlayerComponent } from '../../../player/player.component';\n\n@Component({\n selector: 'telly-volume-slider',\n templateUrl: './volume-slider.component.html',\n styleUrls: ['./volume-slider.component.scss'],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class VolumeSliderComponent {\n volume = input(1);\n\n ref = inject(ElementRef<HTMLElement>);\n player = inject(PlayerComponent);\n handle = false;\n\n @HostListener('pointerdown', ['$event'])\n onPointerDown(e: PointerEvent) {\n this.handle = true;\n const rawVolume = Math.round((e.offsetX / this.ref.nativeElement.clientWidth) * 10) / 10;\n this.player.media.volume = Math.max(0, Math.min(1, rawVolume));\n }\n\n @HostListener('pointermove', ['$event'])\n onPointerMove(e: PointerEvent) {\n if (this.handle) {\n const rawVolume = Math.round((e.offsetX / this.ref.nativeElement.clientWidth) * 10) / 10;\n this.player.media.volume = Math.max(0, Math.min(1, rawVolume));\n }\n }\n\n @HostListener('pointerleave')\n @HostListener('pointerup')\n onPointerLeave() {\n this.handle = false;\n }\n}\n","<div class=\"outlet\">\n <div\n class=\"current\"\n [style.width.%]=\"volume() * 100\"\n ></div>\n</div>\n","import { ChangeDetectionStrategy, Component, HostBinding, HostListener, inject, OnInit } from '@angular/core';\nimport { VideoEvent } from '@ngx-telly/player/core';\nimport { TellyEventsService } from '@ngx-telly/player/services';\nimport { takeUntil } from 'rxjs';\nimport { PlayerComponent } from '../../player/player.component';\nimport { VolumeButtonComponent } from './volume-button/volume-button.component';\nimport { VolumeSliderComponent } from './volume-slider/volume-slider.component';\n\n@Component({\n selector: 'telly-volume',\n templateUrl: './volume.component.html',\n styleUrls: ['./volume.component.scss'],\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [VolumeButtonComponent, VolumeSliderComponent],\n})\nexport class VolumeComponent implements OnInit {\n player = inject(PlayerComponent);\n events = inject(TellyEventsService);\n volume = 1;\n open = false;\n\n @HostBinding('style.width') width = '24px';\n @HostBinding('attr.tip') title = 'Volume';\n\n @HostListener('contextmenu', ['$event'])\n onContextMenu(e: PointerEvent): void {\n e.preventDefault();\n this.open ? this.hide() : this.show();\n }\n\n @HostListener('pointerover', ['$event'])\n onMouseOver(e: PointerEvent): void {\n if (e.pointerType === 'touch') return;\n this.show();\n }\n\n @HostListener('pointerleave', ['$event'])\n onPointerLeave(e: PointerEvent): void {\n if (e.pointerType === 'touch') return;\n this.hide();\n }\n\n ngOnInit() {\n this.volume = this.player.media.loadVolume();\n\n this.player.media\n .event(VideoEvent.VolumeChange)\n .pipe(takeUntil(this.events.destroy$))\n .subscribe(() => (this.volume = this.player.media.volume));\n }\n\n show(): void {\n this.open = true;\n this.width = '100px';\n }\n\n hide(): void {\n this.open = false;\n this.width = '24px';\n }\n}\n","<telly-volume-slider [volume]=\"volume\"></telly-volume-slider>\n<telly-volume-button [volume]=\"volume\"></telly-volume-button>\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { fwd10, fwd15, fwd30, fwd45, fwd5, fwd60 } from '@ngx-telly/player/core';\n\n@Pipe({\n name: 'jumpForwardIcon',\n standalone: true,\n})\nexport class JumpForwardIconPipe implements PipeTransform {\n map: Record<number, string> = {\n 5: fwd5,\n 10: fwd10,\n 15: fwd15,\n 30: fwd30,\n 45: fwd45,\n 60: fwd60,\n };\n\n transform(jump: number): string {\n return this.map[jump];\n }\n}\n","import { ChangeDetectionStrategy, Component, HostBinding, HostListener, inject, input } from '@angular/core';\nimport { fwd10, fwd15, fwd30, fwd45, fwd5, fwd60 } from '@ngx-telly/player/core';\nimport { PlayerComponent } from '../../player/player.component';\nimport { JumpForwardIconPipe } from './jump-forward-icon.pipe';\n\n@Component({\n selector: 'telly-jump-forward',\n templateUrl: './jump-forward.component.html',\n styleUrls: ['./jump-forward.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [JumpForwardIconPipe]\n})\nexport class JumpForwardComponent {\n jump = input(5);\n icon5 = input(fwd5);\n icon10 = input(fwd10);\n icon15 = input(fwd15);\n icon30 = input(fwd30);\n icon45 = input(fwd45);\n icon60 = input(fwd60);\n size = input('1.2rem');\n\n player = inject(PlayerComponent);\n\n @HostBinding('attr.tip') title = 'Jump';\n\n @HostListener('pointerdown')\n onClick() {\n this.player.media.seek(this.player.media.windowTime + this.jump());\n this.player.media.indicate(`${this.jump()}s forward`);\n }\n}\n","<svg\n viewBox=\"0 0 24 24\"\n [style.width]=\"size()\"\n>\n <path\n fill=\"white\"\n [attr.d]=\"jump()| jumpForwardIcon\"\n />\n</svg>\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { rwd10, rwd15, rwd30, rwd45, rwd5, rwd60 } from '@ngx-telly/player/core';\n\n@Pipe({\n name: 'jumpBackIcon',\n standalone: true,\n})\nexport class JumpBackIconPipe implements PipeTransform {\n map: Record<number, string> = {\n 5: rwd5,\n 10: rwd10,\n 15: rwd15,\n 30: rwd30,\n 45: rwd45,\n 60: rwd60,\n };\n\n transform(jump: number): string {\n return this.map[jump];\n }\n}\n","import { ChangeDetectionStrategy, Component, HostBinding, HostListener, inject, input } from '@angular/core';\nimport { rwd10, rwd15, rwd30, rwd45, rwd5, rwd60 } from '@ngx-telly/player/core';\nimport { PlayerComponent } from '../../player/player.component';\nimport { JumpBackIconPipe } from './jump-back-icon.pipe';\n\n@Component({\n selector: 'telly-jump-back',\n templateUrl: './jump-back.component.html',\n styleUrls: ['./jump-back.component.scss'],\n imports: [JumpBackIconPipe],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class JumpBackComponent {\n jump = input(5);\n icon5 = input(rwd5);\n icon10 = input(rwd10);\n icon15 = input(rwd15);\n icon30 = input(rwd30);\n icon45 = input(rwd45);\n icon60 = input(rwd60);\n size = '1.2rem';\n\n player = inject(PlayerComponent);\n\n @HostBinding('attr.tip') title = 'Jump';\n\n @HostListener('pointerdown')\n onClick() {\n this.player.media.seek(this.player.media.windowTime - this.jump());\n this.player.media.indicate(`${this.jump()}s back`);\n }\n}\n","<svg\n viewBox=\"0 0 24 24\"\n [style.width]=\"size\"\n>\n <path\n fill=\"white\"\n [attr.d]=\"jump() | jumpBackIcon\"\n />\n</svg>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;MAgCa,eAAe,CAAA;AAR5B,IAAA,WAAA,GAAA;AASE,QAAA,IAAA,CAAA,EAAE,GAAG,KAAK,CAAC,QAAQ,6CAAU;QAC7B,IAAA,CAAA,GAAG,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,KAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAU;QACrB,IAAA,CAAA,MAAM,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,QAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAU;QACxB,IAAA,CAAA,YAAY,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,cAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAU;AAC9B,QAAA,IAAA,CAAA,MAAM,GAAG,KAAK,CAAU,KAAK,kDAAC;AAC9B,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAU,IAAI,oDAAC;AAC/B,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAU,KAAK,oDAAC;AAChC,QAAA,IAAA,CAAA,OAAO,GAAG,KAAK,CAAU,KAAK,mDAAC;AAC/B,QAAA,IAAA,CAAA,UAAU,GAAG,KAAK,CAAU,KAAK,sDAAC;AAClC,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAU,IAAI,oDAAC;AAC/B,QAAA,IAAA,CAAA,IAAI,GAAG,KAAK,CAAU,KAAK,gDAAC;AAC5B,QAAA,IAAA,CAAA,KAAK,GAAG,KAAK,CAAU,KAAK,iDAAC;AAC7B,QAAA,IAAA,CAAA,qBAAqB,GAAG,KAAK,CAAU,KAAK,iEAAC;QAC7C,IAAA,CAAA,MAAM,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,QAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAU;QACxB,IAAA,CAAA,KAAK,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,OAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAU;AACvB,QAAA,IAAA,CAAA,aAAa,GAAG,KAAK,CAAS,CAAC,yDAAC;AAChC,QAAA,IAAA,CAAA,cAAc,GAAG,KAAK,CAAS,IAAI,0DAAC;AACpC,QAAA,IAAA,CAAA,SAAS,GAAG,KAAK,CAAS,IAAI,qDAAC;AAC/B,QAAA,IAAA,CAAA,SAAS,GAAG,KAAK,CAAS,CAAC,qDAAC;AAC5B,QAAA,IAAA,CAAA,UAAU,GAAG,KAAK,CAAS,CAAC,sDAAC;QAC7B,IAAA,CAAA,WAAW,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,aAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAmB;QACtC,IAAA,CAAA,OAAO,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,SAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAe;AAC9B,QAAA,IAAA,CAAA,SAAS,GAAG,KAAK,CAAU,IAAI,qDAAC;QAEhC,IAAA,CAAA,OAAO,GAAG,MAAM,EAAc;QAMtB,IAAA,CAAA,IAAI,GAAG,KAAK;AAEpB,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAEjC,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,aAAa;AAC1C,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,iBAAiB,CAAC;AACxC,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,kBAAkB,CAAC;AACnC,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,0BAA0B,CAAC;AAC3C,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,8BAA8B,CAAC;AAoEtD,IAAA;IAjEC,OAAO,GAAA;AACL,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;IAC3B;IAEA,QAAQ,GAAA;QACN,IAAI,CAAC,QAAQ,EAAE;QACf,IAAI,CAAC,SAAS,EAAE;QAEhB,IAAI,CAAC,MAAM,CAAC;AACT,aAAA,IAAI,CACH,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,EACtE,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAE5C,aAAA,SAAS,EAAE;AAEd,QAAA,IAAI,CAAC,YAAY,CAAC,oBAAoB,EAAE;AAExC,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE;QAC1B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QAE7B,IAAI,IAAI,CAAC,aAAa,EAAE;AAAE,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC;IAC7E;AAEA,IAAA,WAAW,CAAC,OAAsB,EAAA;AAChC,QAAA,IAAI,OAAO,CAAC,eAAe,CAAC,EAAE,YAAY,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,WAAW,EAAE;AACnF,YAAA,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE;AAC/B,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC;QACpE;IACF;IAEA,gBAAgB,GAAA;AACd,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE;AACpB,YAAA,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;QACrB;IACF;IAEA,MAAM,GAAA;QACJ,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC;AAC9E,QAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC;QACjC,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAe;IACvD;IAEA,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC;IACtD;IAEA,SAAS,GAAA;AACP,QAAA,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,KAAK,CAC3B,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,EACpC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,EACpC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,EACnC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,EACjC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,EAChC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CACZ;QAEtB,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,OAAO;aACxC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;AACpC,aAAA,SAAS,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;IAC7C;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;AAC3B,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE;YAAE,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;IACjE;+GA1GW,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAf,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,eAAe,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,EAAA,EAAA,EAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,qBAAA,EAAA,EAAA,iBAAA,EAAA,uBAAA,EAAA,UAAA,EAAA,uBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,OAAA,EAAA,SAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,WAAA,EAAA,WAAA,EAAA,EAAA,UAAA,EAAA,EAAA,YAAA,EAAA,WAAA,EAAA,EAAA,EAAA,SAAA,EAJf,CAAC,0BAA0B,CAAC,6JC5BzC,ojCA6CA,EAAA,MAAA,EAAA,CAAA,ucAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FDba,eAAe,EAAA,UAAA,EAAA,CAAA;kBAR3B,SAAS;+BACE,cAAc,EAAA,SAAA,EAGb,CAAC,0BAA0B,CAAC,cAC3B,IAAI,EAAA,eAAA,EACC,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,ojCAAA,EAAA,MAAA,EAAA,CAAA,ucAAA,CAAA,EAAA;;sBA6B9C,SAAS;AAAC,gBAAA,IAAA,EAAA,CAAA,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;;sBAGnC,WAAW;uBAAC,YAAY;;sBAWxB,YAAY;uBAAC,WAAW;;;ME5Dd,kBAAkB,CAAA;AAP/B,IAAA,WAAA,GAAA;AAQE,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC;AAChC,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,kBAAkB,CAAC;AACnC,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC;QAC1B,IAAA,CAAA,IAAI,GAAG,KAAK;AACZ,QAAA,IAAA,CAAA,QAAQ,GAAG,IAAI,OAAO,EAAS;QAEJ,IAAA,CAAA,IAAI,GAAG,KAAK;AAyDvC,QAAA,IAAA,CAAA,eAAe,GAAG,CAAC,EAAS,KAAyB;YACnD,IAAI,EAAE,CAAC,IAAI,KAAK,UAAU,CAAC,OAAO,EAAE;AAClC,gBAAA,OAAO,KAAK;YACd;YAEA,IAAI,EAAE,CAAC,IAAI,KAAK,UAAU,CAAC,OAAO,EAAE;AAClC,gBAAA,OAAO,IAAI;YACb;YAEA,IAAI,EAAE,CAAC,IAAI,KAAK,UAAU,CAAC,KAAK,EAAE;AAChC,gBAAA,OAAO,KAAK;YACd;YAEA,IAAI,EAAE,CAAC,IAAI,KAAK,UAAU,CAAC,OAAO,EAAE;AAClC,gBAAA,OAAO,KAAK;YACd;YAEA;AACF,QAAA,CAAC;AAED,QAAA,IAAA,CAAA,aAAa,GAAG,CAAC,EAAS,KAAyB;AACjD,YAAA,OAAO,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;AACjC,QAAA,CAAC;AAED,QAAA,IAAA,CAAA,cAAc,GAAG,CAAC,EAAS,KAAyB;AAClD,YAAA,OAAO,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;AACjC,QAAA,CAAC;AACF,IAAA;IAlFC,QAAQ,GAAA;AACN,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE;QAEjC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;aAClE,IAAI,CACD,SAAS,CAAC;AACR,YAAA,UAAU,CAAC,OAAO;AAClB,YAAA,UAAU,CAAC,KAAK;AAChB,YAAA,UAAU,CAAC,QAAQ;AACnB,YAAA,UAAU,CAAC,OAAO;AAClB,YAAA,UAAU,CAAC,OAAO;AAClB,YAAA,UAAU,CAAC,MAAM;AACjB,YAAA,UAAU,CAAC,OAAO;AAClB,YAAA,UAAU,CAAC;AACZ,SAAA,CAAC,EACF,GAAG,CAAC,CAAC,EAAE,KAAI;AACT,YAAA,QAAQ,EAAE,CAAC,IAAI;gBACb,KAAK,UAAU,CAAC,OAAO;AACrB,oBAAA,IAAI,CAAC,IAAI,GAAG,IAAI;oBAChB;gBACF,KAAK,UAAU,CAAC,KAAK;AACnB,oBAAA,IAAI,CAAC,IAAI,GAAG,KAAK;oBACjB;;AAEN,QAAA,CAAC,CAAC,EACF,GAAG,CAAC,CAAC,EAAE,KAAI;YACT,IAAI,EAAE,CAAC,IAAI,KAAK,UAAU,CAAC,QAAQ,EAAE;AACnC,gBAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACnD;AACF,QAAA,CAAC,CAAC,EACF,GAAG,CAAC,CAAC,EAAE,KAAI;AACT,YAAA,OAAO,OAAO,CAAC,EAAE,CAAC;AACpB,QAAA,CAAC,CAAC;AAEL,aAAA,SAAS,CAAC,CAAC,SAAS,KAAI;YACvB,IAAI,OAAO,SAAS,KAAK,SAAS;gBAAE;AACpC,YAAA,IAAI,CAAC,IAAI,GAAG,CAAC,SAAS;AACxB,QAAA,CAAC,CAAC;IACR;IAEA,UAAU,GAAA;AACR,QAAA,QAAQ,IAAI,CAAC,QAAQ;YACnB,KAAK,OAAO,CAAC,QAAQ;gBACnB,OAAO,IAAI,CAAC,eAAe;YAC7B,KAAK,OAAO,CAAC,MAAM;gBACjB,OAAO,IAAI,CAAC,aAAa;YAC3B,KAAK,OAAO,CAAC,OAAO;gBAClB,OAAO,IAAI,CAAC,cAAc;YAC5B,KAAK,OAAO,CAAC,GAAG;gBACd,OAAO,IAAI,CAAC,aAAa;AAC3B,YAAA;gBACE,OAAO,IAAI,CAAC,eAAe;;IAEjC;+GA9DW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAlB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,kBAAkB,gICb/B,mzFA8HA,EAAA,MAAA,EAAA,CAAA,wcAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FDjHa,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAP9B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iBAAiB,EAAA,UAAA,EAGf,IAAI,EAAA,eAAA,EACC,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,mzFAAA,EAAA,MAAA,EAAA,CAAA,wcAAA,CAAA,EAAA;;sBAS9C,WAAW;uBAAC,YAAY;;;MEPd,sBAAsB,CAAA;AAPnC,IAAA,WAAA,GAAA;AAQE,QAA