@libs-ui/components-audio 0.2.189 → 0.2.190

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,109 @@
1
- # audio
1
+ # Component Audio
2
2
 
3
- This library was generated with [Nx](https://nx.dev).
3
+ ## Tính năng
4
+
5
+ - Control play/pause âm thanh
6
+ - Control âm lượng với chức năng mute
7
+ - Hiển thị thời gian theo định dạng HH:MM:SS
8
+ - Progress bar với chức năng seek
9
+ - Khả năng download audio với permission control
10
+ - Thiết kế responsive sử dụng Tailwind CSS
11
+ - Source audio có thể cấu hình
12
+
13
+ ## Cài đặt
14
+
15
+ ```bash
16
+ npm install @libs-ui/components-audio
17
+ ```
18
+
19
+ ## Cách sử dụng cơ bản
20
+
21
+ Import component vào module hoặc standalone component của bạn:
22
+
23
+ ```typescript
24
+ import { LibsUiComponentsAudioComponent } from '@libs-ui/components-audio';
25
+
26
+ @Component({
27
+ selector: 'your-component',
28
+ standalone: true,
29
+ imports: [LibsUiComponentsAudioComponent],
30
+ template: `
31
+ <libs_ui-components-audio
32
+ fileAudio="https://example.com/audio.mp3"
33
+ [checkPermissionDownloadAudio]="checkDownloadPermission"
34
+ />
35
+ `
36
+ })
37
+ export class YourComponent {
38
+ checkDownloadPermission(): Promise<boolean> {
39
+ // Your logic to determine if download is allowed
40
+ return Promise.resolve(true);
41
+ }
42
+ }
43
+ ```
44
+
45
+ ## Inputs
46
+
47
+ | Input | Type | Required | Description |
48
+ |-------|------|----------|-------------|
49
+ | `fileAudio` | `string` | Yes | URL của file audio cần phát |
50
+ | `checkPermissionDownloadAudio` | `() => Promise<boolean>` | Yes | Function trả về promise với kết quả boolean cho biết nếu được phép download |
51
+
52
+ ## UI Features
53
+
54
+ ### Audio Controls
55
+ - Button play/pause
56
+ - Hiển thị current time và duration (định dạng HH:MM:SS)
57
+ - Progress bar với chức năng seek
58
+
59
+ ### Volume Controls
60
+ - Button mute/unmute
61
+ - Volume slider (hiển thị khi hover)
62
+
63
+ ### Download
64
+ - Button download cần kiểm tra permission
65
+
66
+ ## CSS Classes
67
+
68
+ Component sử dụng các class của Tailwind và các custom icon classes:
69
+
70
+ - `.libs-ui-disable` - Áp dụng cho player bị disabled
71
+ - `.pointer-events-none` - Áp dụng khi player bị disabled
72
+ - `.libs-ui-font-h5r` - Áp dụng cho time display
73
+ - `.libs-ui-icon-play-solid` - Icon play
74
+ - `.libs-ui-icon-pause-solid` - Icon pause
75
+ - `.libs-ui-icon-speaker-on-solid` - Icon speaker (volume on)
76
+ - `.libs-ui-icon-speaker-off-solid` - Icon speaker (volume off/mute)
77
+ - `.libs-ui-icon-download-solid` - Icon download
78
+
79
+ ## Dependencies
80
+
81
+ - Angular 16+
82
+ - RxJS
83
+ - @libs-ui/components-inputs-range-slider
84
+
85
+ ## Example Implementation
86
+
87
+ ```typescript
88
+ @Component({
89
+ selector: 'app-audio-player',
90
+ standalone: true,
91
+ imports: [LibsUiComponentsAudioComponent],
92
+ template: `
93
+ <libs_ui-components-audio
94
+ fileAudio="https://example.com/audio.mp3"
95
+ [checkPermissionDownloadAudio]="checkDownloadPermission"
96
+ />
97
+ `
98
+ })
99
+ export class AudioPlayerComponent {
100
+ checkDownloadPermission(): Promise<boolean> {
101
+ // Example implementation - can be replaced with actual permission logic
102
+ return new Promise(resolve => {
103
+ // Check user permissions, authentication, or any other business logic
104
+ const isAllowed = true;
105
+ resolve(isAllowed);
106
+ });
107
+ }
108
+ }
109
+ ```
@@ -12,7 +12,7 @@ export declare class LibsUiComponentsAudioComponent implements AfterViewInit, On
12
12
  protected showFullControlVolume: import("@angular/core").WritableSignal<boolean>;
13
13
  private onDestroy;
14
14
  readonly fileAudio: import("@angular/core").InputSignal<string>;
15
- checkPermissionDownloadAudio?: () => Promise<boolean>;
15
+ readonly checkPermissionDownloadAudio: import("@angular/core").InputSignal<() => Promise<boolean>>;
16
16
  readonly audioRef: import("@angular/core").Signal<ElementRef<any>>;
17
17
  readonly volumeControlRef: import("@angular/core").Signal<ElementRef<any>>;
18
18
  ngAfterViewInit(): void;
@@ -29,5 +29,5 @@ export declare class LibsUiComponentsAudioComponent implements AfterViewInit, On
29
29
  protected handlerDownload(e: Event): Promise<void>;
30
30
  ngOnDestroy(): void;
31
31
  static ɵfac: i0.ɵɵFactoryDeclaration<LibsUiComponentsAudioComponent, never>;
32
- static ɵcmp: i0.ɵɵComponentDeclaration<LibsUiComponentsAudioComponent, "libs_ui-components-audio", never, { "fileAudio": { "alias": "fileAudio"; "required": true; "isSignal": true; }; "checkPermissionDownloadAudio": { "alias": "checkPermissionDownloadAudio"; "required": true; }; }, {}, never, never, true, never>;
32
+ static ɵcmp: i0.ɵɵComponentDeclaration<LibsUiComponentsAudioComponent, "libs_ui-components-audio", never, { "fileAudio": { "alias": "fileAudio"; "required": true; "isSignal": true; }; "checkPermissionDownloadAudio": { "alias": "checkPermissionDownloadAudio"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
33
33
  }
@@ -0,0 +1,20 @@
1
+ import * as i0 from "@angular/core";
2
+ /**
3
+ * Demo component hiển thị các ví dụ khác nhau của Audio component
4
+ */
5
+ export declare class LibsUiComponentsAudioDemoComponent {
6
+ /**
7
+ * Permission function luôn allow download
8
+ */
9
+ basicPermissionCheck(): Promise<boolean>;
10
+ /**
11
+ * Permission function không cho phép download
12
+ */
13
+ denyPermissionCheck(): Promise<boolean>;
14
+ /**
15
+ * Permission function có delay để mô phỏng API call
16
+ */
17
+ delayedPermissionCheck(): Promise<boolean>;
18
+ static ɵfac: i0.ɵɵFactoryDeclaration<LibsUiComponentsAudioDemoComponent, never>;
19
+ static ɵcmp: i0.ɵɵComponentDeclaration<LibsUiComponentsAudioDemoComponent, "lib-audio-demo", never, {}, {}, never, never, true, never>;
20
+ }
@@ -1,4 +1,4 @@
1
- import { ChangeDetectionStrategy, Component, input, Input, signal, viewChild } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, input, signal, viewChild } from '@angular/core';
2
2
  import { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';
3
3
  import { fromEvent, merge, Subject, takeUntil, tap } from 'rxjs';
4
4
  import * as i0 from "@angular/core";
@@ -16,7 +16,7 @@ export class LibsUiComponentsAudioComponent {
16
16
  onDestroy = new Subject();
17
17
  // #region INPUT
18
18
  fileAudio = input.required();
19
- checkPermissionDownloadAudio;
19
+ checkPermissionDownloadAudio = input.required();
20
20
  /* VIEW CHILD */
21
21
  audioRef = viewChild.required('audioRef');
22
22
  volumeControlRef = viewChild.required('volumeControlRef');
@@ -111,7 +111,7 @@ export class LibsUiComponentsAudioComponent {
111
111
  this.isPlay.set(false);
112
112
  }
113
113
  async handlerDownload(e) {
114
- if (!this.checkPermissionDownloadAudio || !await this.checkPermissionDownloadAudio()) {
114
+ if (!this.checkPermissionDownloadAudio() || !await this.checkPermissionDownloadAudio()()) {
115
115
  return;
116
116
  }
117
117
  e.stopPropagation();
@@ -125,15 +125,12 @@ export class LibsUiComponentsAudioComponent {
125
125
  this.onDestroy.complete();
126
126
  }
127
127
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
128
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.13", type: LibsUiComponentsAudioComponent, isStandalone: true, selector: "libs_ui-components-audio", inputs: { fileAudio: { classPropertyName: "fileAudio", publicName: "fileAudio", isSignal: true, isRequired: true, transformFunction: null }, checkPermissionDownloadAudio: { classPropertyName: "checkPermissionDownloadAudio", publicName: "checkPermissionDownloadAudio", isSignal: false, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "audioRef", first: true, predicate: ["audioRef"], descendants: true, isSignal: true }, { propertyName: "volumeControlRef", first: true, predicate: ["volumeControlRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n", dependencies: [{ kind: "component", type: LibsUiComponentsInputsRangeSliderComponent, selector: "libs_ui-components-inputs-range_slider", inputs: ["mode", "min", "max", "value", "classInclude", "disable", "unit", "step", "hideProgressingValue", "formatNumber"], outputs: ["valueChange", "outChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
128
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.13", type: LibsUiComponentsAudioComponent, isStandalone: true, selector: "libs_ui-components-audio", inputs: { fileAudio: { classPropertyName: "fileAudio", publicName: "fileAudio", isSignal: true, isRequired: true, transformFunction: null }, checkPermissionDownloadAudio: { classPropertyName: "checkPermissionDownloadAudio", publicName: "checkPermissionDownloadAudio", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "audioRef", first: true, predicate: ["audioRef"], descendants: true, isSignal: true }, { propertyName: "volumeControlRef", first: true, predicate: ["volumeControlRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n", dependencies: [{ kind: "component", type: LibsUiComponentsInputsRangeSliderComponent, selector: "libs_ui-components-inputs-range_slider", inputs: ["mode", "min", "max", "value", "classInclude", "disable", "unit", "step", "hideProgressingValue", "formatNumber"], outputs: ["valueChange", "outChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
129
129
  }
130
130
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioComponent, decorators: [{
131
131
  type: Component,
132
132
  args: [{ selector: 'libs_ui-components-audio', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
133
133
  LibsUiComponentsInputsRangeSliderComponent
134
134
  ], template: "<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n" }]
135
- }], propDecorators: { checkPermissionDownloadAudio: [{
136
- type: Input,
137
- args: [{ required: true }]
138
- }] } });
139
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaW8uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL2F1ZGlvL3NyYy9hdWRpby5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvYXVkaW8vc3JjL2F1ZGlvLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBaUIsdUJBQXVCLEVBQUUsU0FBUyxFQUFjLEtBQUssRUFBRSxLQUFLLEVBQWEsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxSSxPQUFPLEVBQUUsMENBQTBDLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNyRyxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBYyxPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7QUFZN0UsTUFBTSxPQUFPLDhCQUE4QjtJQUN6QyxtQkFBbUI7SUFDVCxlQUFlLEdBQUcsTUFBTSxDQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ3BDLGdCQUFnQixHQUFHLE1BQU0sQ0FBUyxHQUFHLENBQUMsQ0FBQztJQUN2QyxNQUFNLEdBQUcsTUFBTSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLE1BQU0sR0FBRyxNQUFNLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDaEMsa0JBQWtCLEdBQUcsTUFBTSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBQzVDLFNBQVMsR0FBRyxNQUFNLENBQVUsSUFBSSxDQUFDLENBQUM7SUFDbEMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFTLE9BQU8sQ0FBQyxDQUFDO0lBQzNDLGlCQUFpQixHQUFHLE1BQU0sQ0FBUyxPQUFPLENBQUMsQ0FBQztJQUM1QyxxQkFBcUIsR0FBRyxNQUFNLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDakQsU0FBUyxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7SUFFeEMsZ0JBQWdCO0lBQ1AsU0FBUyxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQVUsQ0FBQztJQUNuQiw0QkFBNEIsQ0FBMEI7SUFFakYsZ0JBQWdCO0lBQ1AsUUFBUSxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQWEsVUFBVSxDQUFDLENBQUM7SUFDdEQsZ0JBQWdCLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBYSxrQkFBa0IsQ0FBQyxDQUFDO0lBRS9FLGVBQWU7UUFDYixLQUFLLENBQ0gsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDOUgsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FDaEksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ2hELENBQUM7SUFDRCxlQUFlO0lBQ1AsY0FBYyxDQUFDLEVBQWUsRUFBRSxTQUFpQjtRQUN2RCxPQUFPLFNBQVMsQ0FBYSxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUM5QyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsZUFBZSxFQUFFLENBQUMsRUFDN0IsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FDMUIsQ0FBQztJQUNKLENBQUM7SUFFUyxLQUFLLENBQUMsb0JBQW9CO1FBQ2xDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVTLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxLQUFZO1FBQ2hELEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ2pELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztZQUM1QyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBRTlCLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7SUFDN0MsQ0FBQztJQUVTLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxLQUFZO1FBQ2hELEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDO1FBQ25ELElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDekIsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3ZCLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEIsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLHNCQUFzQixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQy9DLENBQUM7SUFDSCxDQUFDO0lBRVMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEtBQVk7UUFDNUMsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3hCLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0RyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxLQUFZO1FBQzVDLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ25DLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RHLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEdBQUcsQ0FBQztZQUU5SCxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDbkksQ0FBQztJQUVPLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBWTtRQUNqQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQztRQUN0QyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDekQsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBRXZELE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQyxHQUFXLEVBQUUsRUFBRTtZQUNoQyxPQUFPLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsR0FBRyxFQUFFLENBQUM7UUFDeEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztJQUN4RSxDQUFDO0lBRVMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEtBQWE7UUFDOUMsSUFBSSxLQUFLLEtBQUssSUFBSSxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUM7WUFDckMsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFdBQVcsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDO1FBQ2pHLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVTLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxLQUFhO1FBQy9DLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLEtBQUssR0FBRyxHQUFHLENBQUM7UUFFbkQsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3pDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztZQUM1QyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUV2QixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUMzQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4QixDQUFDO0lBRVMsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFZO1FBQ3ZDLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRVMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFRO1FBQ3RDLElBQUksQ0FBQyxJQUFJLENBQUMsNEJBQTRCLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxFQUFFLENBQUM7WUFDckYsT0FBTztRQUNULENBQUM7UUFDRCxDQUFDLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDO1lBQ3RCLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDNUIsQ0FBQzt3R0FuSlUsOEJBQThCOzRGQUE5Qiw4QkFBOEIsNm9CQ2QzQyxzaEVBb0RBLDRDRHpDSSwwQ0FBMEM7OzRGQUdqQyw4QkFBOEI7a0JBVjFDLFNBQVM7K0JBRUUsMEJBQTBCLGNBRXhCLElBQUksbUJBQ0MsdUJBQXVCLENBQUMsTUFBTSxXQUN0Qzt3QkFDUCwwQ0FBMEM7cUJBQzNDOzhCQWlCMEIsNEJBQTRCO3NCQUF0RCxLQUFLO3VCQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyVmlld0luaXQsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIGlucHV0LCBJbnB1dCwgT25EZXN0cm95LCBzaWduYWwsIHZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c0lucHV0c1JhbmdlU2xpZGVyQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1pbnB1dHMtcmFuZ2Utc2xpZGVyJztcbmltcG9ydCB7IGZyb21FdmVudCwgbWVyZ2UsIE9ic2VydmFibGUsIFN1YmplY3QsIHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcyc7XG5cbkBDb21wb25lbnQoe1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2NvbXBvbmVudC1zZWxlY3RvclxuICBzZWxlY3RvcjogJ2xpYnNfdWktY29tcG9uZW50cy1hdWRpbycsXG4gIHRlbXBsYXRlVXJsOiAnLi9hdWRpby5jb21wb25lbnQuaHRtbCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBpbXBvcnRzOiBbXG4gICAgTGlic1VpQ29tcG9uZW50c0lucHV0c1JhbmdlU2xpZGVyQ29tcG9uZW50XG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgTGlic1VpQ29tcG9uZW50c0F1ZGlvQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgLy8gI3JlZ2lvbiBQUk9QRVJUWVxuICBwcm90ZWN0ZWQgYXVkaW9SYXRpb1ZhbHVlID0gc2lnbmFsPG51bWJlcj4oMCk7XG4gIHByb3RlY3RlZCB2b2x1bWVSYXRpb1ZhbHVlID0gc2lnbmFsPG51bWJlcj4oMTAwKTtcbiAgcHJvdGVjdGVkIGlzUGxheSA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHByb3RlY3RlZCBpc011dGUgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcm90ZWN0ZWQgaXNTbGlkZXJBdWRpb1ByZXNzID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJvdGVjdGVkIGlzRGlzYWJsZSA9IHNpZ25hbDxib29sZWFuPih0cnVlKTtcbiAgcHJvdGVjdGVkIGF1ZGlvVGltZUN1cnJlbnQgPSBzaWduYWw8c3RyaW5nPignXzpfOl8nKTtcbiAgcHJvdGVjdGVkIGF1ZGlvVGltZUR1cmF0aW9uID0gc2lnbmFsPHN0cmluZz4oJ186XzpfJyk7XG4gIHByb3RlY3RlZCBzaG93RnVsbENvbnRyb2xWb2x1bWUgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIG9uRGVzdHJveSA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLy8gI3JlZ2lvbiBJTlBVVFxuICByZWFkb25seSBmaWxlQXVkaW8gPSBpbnB1dC5yZXF1aXJlZDxzdHJpbmc+KCk7XG4gIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pIGNoZWNrUGVybWlzc2lvbkRvd25sb2FkQXVkaW8/OiAoKSA9PiBQcm9taXNlPGJvb2xlYW4+O1xuXG4gIC8qIFZJRVcgQ0hJTEQgKi9cbiAgcmVhZG9ubHkgYXVkaW9SZWYgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ2F1ZGlvUmVmJyk7XG4gIHJlYWRvbmx5IHZvbHVtZUNvbnRyb2xSZWYgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ3ZvbHVtZUNvbnRyb2xSZWYnKTtcblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgbWVyZ2UoXG4gICAgICB0aGlzLmluaXRPYnNlcnZhYmxlKHRoaXMudm9sdW1lQ29udHJvbFJlZigpLm5hdGl2ZUVsZW1lbnQsICdtb3VzZWVudGVyJykucGlwZSh0YXAoKCkgPT4gdGhpcy5zaG93RnVsbENvbnRyb2xWb2x1bWUuc2V0KHRydWUpKSksXG4gICAgICB0aGlzLmluaXRPYnNlcnZhYmxlKHRoaXMudm9sdW1lQ29udHJvbFJlZigpLm5hdGl2ZUVsZW1lbnQsICdtb3VzZWxlYXZlJykucGlwZSh0YXAoKCkgPT4gdGhpcy5zaG93RnVsbENvbnRyb2xWb2x1bWUuc2V0KGZhbHNlKSkpXG4gICAgKS5waXBlKHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSkpLnN1YnNjcmliZSgpO1xuICB9XG4gIC8qIEZVTkNUSU9OUyAqL1xuICBwcml2YXRlIGluaXRPYnNlcnZhYmxlKGVsOiBIVE1MRWxlbWVudCwgZXZlbnROYW1lOiBzdHJpbmcpOiBPYnNlcnZhYmxlPE1vdXNlRXZlbnQ+IHtcbiAgICByZXR1cm4gZnJvbUV2ZW50PE1vdXNlRXZlbnQ+KGVsLCBldmVudE5hbWUpLnBpcGUoXG4gICAgICB0YXAoZSA9PiBlLnN0b3BQcm9wYWdhdGlvbigpKSxcbiAgICAgIHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSlcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJLZXlQcmVzc0F1ZGlvKCkge1xuICAgIHRoaXMuaXNTbGlkZXJBdWRpb1ByZXNzLnNldCh0cnVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyQXVkaW9NdXRlTXV0ZWQoZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50Lm11dGVkID09PSB0cnVlKSB7XG4gICAgICB0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5tdXRlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5pc011dGUuc2V0KGZhbHNlKTtcbiAgICAgIHRoaXMudm9sdW1lUmF0aW9WYWx1ZS5zZXQoNTApO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudm9sdW1lUmF0aW9WYWx1ZS5zZXQoMCk7XG4gICAgdGhpcy5pc011dGUuc2V0KHRydWUpO1xuICAgIHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50Lm11dGVkID0gdHJ1ZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyQXVkaW9QYXVzZVBsYXkoZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgYXVkaW9FbGVtZW50ID0gdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFhdWRpb0VsZW1lbnQucGF1c2VkKSB7XG4gICAgICBhdWRpb0VsZW1lbnQucGF1c2UoKTtcbiAgICAgIHRoaXMuaXNQbGF5LnNldChmYWxzZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGF1ZGlvRWxlbWVudC5wbGF5KCk7XG4gICAgICB0aGlzLmlzUGxheS5zZXQodHJ1ZSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHBsYXlpbmcgYXVkaW86JywgZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyTG9hZGVkRGF0YShldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIHRoaXMuYXVkaW9UaW1lRHVyYXRpb24uc2V0KGF3YWl0IHRoaXMudG9ISE1NU1MoTWF0aC5mbG9vcih0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5kdXJhdGlvbikpKTtcbiAgICAgIHRoaXMuYXVkaW9UaW1lQ3VycmVudC5zZXQoYXdhaXQgdGhpcy50b0hITU1TUyhNYXRoLmZsb29yKHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LmN1cnJlbnRUaW1lKSkpO1xuICAgICAgdGhpcy5pc0Rpc2FibGUuc2V0KGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaGFuZGxlclRpbWVVcGRhdGUoZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKCF0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmF1ZGlvVGltZUR1cmF0aW9uLnNldChhd2FpdCB0aGlzLnRvSEhNTVNTKE1hdGguZmxvb3IodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuZHVyYXRpb24pKSk7XG4gICAgdGhpcy5hdWRpb1RpbWVDdXJyZW50LnNldChhd2FpdCB0aGlzLnRvSEhNTVNTKE1hdGguZmxvb3IodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuY3VycmVudFRpbWUpKSk7XG4gICAgaWYgKHRoaXMuaXNTbGlkZXJBdWRpb1ByZXNzKCkpIHtcbiAgICAgIHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LmN1cnJlbnRUaW1lID0gdGhpcy5hdWRpb1JhdGlvVmFsdWUoKSAqIE1hdGguZmxvb3IodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuZHVyYXRpb24pIC8gMTAwO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYXVkaW9SYXRpb1ZhbHVlLnNldChNYXRoLmZsb29yKCh0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5jdXJyZW50VGltZSAvIHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LmR1cmF0aW9uKSAqIDEwMCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB0b0hITU1TUyh0aW1lOiBudW1iZXIpIHtcbiAgICBjb25zdCBob3VycyA9IE1hdGguZmxvb3IodGltZSAvIDM2MDApO1xuICAgIGNvbnN0IG1pbnV0ZXMgPSBNYXRoLmZsb29yKCh0aW1lIC0gKGhvdXJzICogMzYwMCkpIC8gNjApO1xuICAgIGNvbnN0IHNlY29uZHMgPSB0aW1lIC0gKGhvdXJzICogMzYwMCkgLSAobWludXRlcyAqIDYwKTtcblxuICAgIGNvbnN0IGdldExhYmVsID0gKCh2YWw6IG51bWJlcikgPT4ge1xuICAgICAgcmV0dXJuIGAke3ZhbCA8IDEwID8gJzAnIDogJyd9JHt2YWx9YDtcbiAgICB9KTtcblxuICAgIHJldHVybiBgJHtnZXRMYWJlbChob3Vycyl9OiR7Z2V0TGFiZWwobWludXRlcyl9OiR7Z2V0TGFiZWwoc2Vjb25kcyl9YDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyQ2hhbmdlQXVkaW8odmFsdWU6IG51bWJlcikge1xuICAgIGlmICh2YWx1ZSA9PT0gdGhpcy5hdWRpb1JhdGlvVmFsdWUoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5jdXJyZW50VGltZSA9IHZhbHVlICogdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuZHVyYXRpb24gLyAxMDA7XG4gICAgdGhpcy5hdWRpb1JhdGlvVmFsdWUuc2V0KHZhbHVlKTtcbiAgICB0aGlzLmlzU2xpZGVyQXVkaW9QcmVzcy5zZXQoZmFsc2UpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJDaGFuZ2VWb2x1bWUodmFsdWU6IG51bWJlcikge1xuICAgIHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LnZvbHVtZSA9IHZhbHVlIC8gMTAwO1xuXG4gICAgaWYgKHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LnZvbHVtZSkge1xuICAgICAgdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQubXV0ZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuaXNNdXRlLnNldChmYWxzZSk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQubXV0ZWQgPSB0cnVlO1xuICAgIHRoaXMuaXNNdXRlLnNldCh0cnVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyRW5kZWQoZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5pc1BsYXkuc2V0KGZhbHNlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyRG93bmxvYWQoZTogRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuY2hlY2tQZXJtaXNzaW9uRG93bmxvYWRBdWRpbyB8fCAhYXdhaXQgdGhpcy5jaGVja1Blcm1pc3Npb25Eb3dubG9hZEF1ZGlvKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoIXRoaXMuZmlsZUF1ZGlvKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgd2luZG93Lm9wZW4odGhpcy5maWxlQXVkaW8oKSwgYF9ibGFua2ApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5vbkRlc3Ryb3kubmV4dCgpO1xuICAgIHRoaXMub25EZXN0cm95LmNvbXBsZXRlKCk7XG4gIH1cbn1cbiIsIjxhdWRpbyBjb250cm9sc1xuICAjYXVkaW9SZWZcbiAgY2xhc3M9XCJoaWRkZW5cIlxuICAodGltZXVwZGF0ZSk9XCJoYW5kbGVyVGltZVVwZGF0ZSgkZXZlbnQpXCJcbiAgKGxvYWRlZGRhdGEpPVwiaGFuZGxlckxvYWRlZERhdGEoJGV2ZW50KVwiXG4gIChlbmRlZCk9XCJoYW5kbGVyRW5kZWQoJGV2ZW50KVwiPlxuICA8c291cmNlIFtzcmNdPVwiZmlsZUF1ZGlvKClcIlxuICAgIHR5cGU9XCJhdWRpby9tcGVnXCI+XG48L2F1ZGlvPlxuPGRpdiBbY2xhc3MubGlicy11aS1kaXNhYmxlXT1cImlzRGlzYWJsZSgpXCJcbiAgW2NsYXNzLnBvaW50ZXItZXZlbnRzLW5vbmVdPVwiaXNEaXNhYmxlKClcIj5cbiAgPGRpdiBjbGFzcz1cImZsZXgganVzdGlmeS1iZXR3ZWVuIGl0ZW1zLWNlbnRlclwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3LVs3MCVdIGZsZXggcC0wIGl0ZW1zLWNlbnRlciBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IG1yLVsxNnB4XSBjdXJzb3ItcG9pbnRlclwiXG4gICAgICAgIChjbGljayk9XCJoYW5kbGVyQXVkaW9QYXVzZVBsYXkoJGV2ZW50KVwiPlxuICAgICAgICA8aSBjbGFzcz1cInRleHQtWzE2cHhdXCJcbiAgICAgICAgICBbY2xhc3MubGlicy11aS1pY29uLXBsYXktc29saWRdPVwiIWlzUGxheSgpXCJcbiAgICAgICAgICBbY2xhc3MubGlicy11aS1pY29uLXBhdXNlLXNvbGlkXT1cImlzUGxheSgpXCI+XG4gICAgICAgIDwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImxpYnMtdWktZm9udC1oNXIgbXItWzE2cHhdXCI+e3sgYXVkaW9UaW1lQ3VycmVudCgpIH19IC97eyBhdWRpb1RpbWVEdXJhdGlvbigpIH19PC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInctWzMwJV0gZmxleCBwLTAgaXRlbXMtY2VudGVyIGp1c3RpZnktZW5kXCI+XG4gICAgICA8ZGl2ICN2b2x1bWVDb250cm9sUmVmXG4gICAgICAgIGNsYXNzPVwiZmxleCBweS1bM3B4XSBpdGVtcy1jZW50ZXIgcm91bmRlZC1bMTJweF0gaC1bMjhweF1cIlxuICAgICAgICBbY2xhc3MuYmctWyNlNmU3ZWFdXT0nc2hvd0Z1bGxDb250cm9sVm9sdW1lKCknXG4gICAgICAgIFtjbGFzcy5weC1bMTJweF1dPSdzaG93RnVsbENvbnRyb2xWb2x1bWUoKSc+XG4gICAgICAgIDxpIGNsYXNzPVwidGV4dC1bMTZweF0gY3Vyc29yLXBvaW50ZXJcIlxuICAgICAgICAgIFtjbGFzcy5saWJzLXVpLWljb24tc3BlYWtlci1vbi1zb2xpZF09XCIhaXNNdXRlKClcIlxuICAgICAgICAgIFtjbGFzcy5saWJzLXVpLWljb24tc3BlYWtlci1vZmYtc29saWRdPVwiaXNNdXRlKClcIlxuICAgICAgICAgIChjbGljayk9XCJoYW5kbGVyQXVkaW9NdXRlTXV0ZWQoJGV2ZW50KVwiPlxuICAgICAgICA8L2k+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtaW5wdXRzLXJhbmdlX3NsaWRlciBbY2xhc3MuaGlkZGVuXT1cIiFzaG93RnVsbENvbnRyb2xWb2x1bWUoKVwiXG4gICAgICAgICAgW21vZGVdPVwiJ2F1ZGlvJ1wiXG4gICAgICAgICAgY2xhc3NJbmNsdWRlPVwiZmxleCBpdGVtcy1jZW50ZXIgIXctWzU0cHhdIGN1cnNvci1wb2ludGVyIG1sLVs4cHhdXCJcbiAgICAgICAgICBbdmFsdWVdPVwidm9sdW1lUmF0aW9WYWx1ZSgpXCJcbiAgICAgICAgICAob3V0Q2hhbmdlKT1cImhhbmRsZXJDaGFuZ2VWb2x1bWUoJGV2ZW50KVwiIC8+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGkgY2xhc3M9XCJsaWJzLXVpLWljb24tZG93bmxvYWQtc29saWQgbWwtWzE2cHhdIGN1cnNvci1wb2ludGVyXCJcbiAgICAgICAgKGNsaWNrKT1cImhhbmRsZXJEb3dubG9hZCgkZXZlbnQpXCI+XG4gICAgICA8L2k+XG4gICAgPC9kaXY+XG5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJoLVsyNHB4XVwiPlxuICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtaW5wdXRzLXJhbmdlX3NsaWRlciBbbW9kZV09XCInYXVkaW8nXCJcbiAgICAgIFt2YWx1ZV09XCJhdWRpb1JhdGlvVmFsdWUoKVwiXG4gICAgICBbZGlzYWJsZV09J2lzRGlzYWJsZSgpJ1xuICAgICAgKG91dENoYW5nZSk9XCJoYW5kbGVyQ2hhbmdlQXVkaW8oJGV2ZW50KVwiIC8+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=
135
+ }] });
136
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaW8uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL2F1ZGlvL3NyYy9hdWRpby5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvYXVkaW8vc3JjL2F1ZGlvLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBaUIsdUJBQXVCLEVBQUUsU0FBUyxFQUFjLEtBQUssRUFBYSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25JLE9BQU8sRUFBRSwwQ0FBMEMsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQ3JHLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFjLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQVk3RSxNQUFNLE9BQU8sOEJBQThCO0lBQ3pDLG1CQUFtQjtJQUNULGVBQWUsR0FBRyxNQUFNLENBQVMsQ0FBQyxDQUFDLENBQUM7SUFDcEMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZDLE1BQU0sR0FBRyxNQUFNLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDaEMsTUFBTSxHQUFHLE1BQU0sQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUNoQyxrQkFBa0IsR0FBRyxNQUFNLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDNUMsU0FBUyxHQUFHLE1BQU0sQ0FBVSxJQUFJLENBQUMsQ0FBQztJQUNsQyxnQkFBZ0IsR0FBRyxNQUFNLENBQVMsT0FBTyxDQUFDLENBQUM7SUFDM0MsaUJBQWlCLEdBQUcsTUFBTSxDQUFTLE9BQU8sQ0FBQyxDQUFDO0lBQzVDLHFCQUFxQixHQUFHLE1BQU0sQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUNqRCxTQUFTLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztJQUV4QyxnQkFBZ0I7SUFD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QztJQUN4QixDQUFDO0lBRVMsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFZO1FBQ3ZDLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRVMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFRO1FBQ3RDLElBQUksQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLDRCQUE0QixFQUFFLEVBQUUsRUFBRSxDQUFDO1lBQ3pGLE9BQU87UUFDVCxDQUFDO1FBQ0QsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQztZQUN0QixPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzVCLENBQUM7d0dBbkpVLDhCQUE4Qjs0RkFBOUIsOEJBQThCLDRvQkNkM0Msc2hFQW9EQSw0Q0R6Q0ksMENBQTBDOzs0RkFHakMsOEJBQThCO2tCQVYxQyxTQUFTOytCQUVFLDBCQUEwQixjQUV4QixJQUFJLG1CQUNDLHVCQUF1QixDQUFDLE1BQU0sV0FDdEM7d0JBQ1AsMENBQTBDO3FCQUMzQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyVmlld0luaXQsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIGlucHV0LCBPbkRlc3Ryb3ksIHNpZ25hbCwgdmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzSW5wdXRzUmFuZ2VTbGlkZXJDb21wb25lbnQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWlucHV0cy1yYW5nZS1zbGlkZXInO1xuaW1wb3J0IHsgZnJvbUV2ZW50LCBtZXJnZSwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzJztcblxuQENvbXBvbmVudCh7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvY29tcG9uZW50LXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnbGlic191aS1jb21wb25lbnRzLWF1ZGlvJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2F1ZGlvLmNvbXBvbmVudC5odG1sJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGltcG9ydHM6IFtcbiAgICBMaWJzVWlDb21wb25lbnRzSW5wdXRzUmFuZ2VTbGlkZXJDb21wb25lbnRcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlDb21wb25lbnRzQXVkaW9Db21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICAvLyAjcmVnaW9uIFBST1BFUlRZXG4gIHByb3RlY3RlZCBhdWRpb1JhdGlvVmFsdWUgPSBzaWduYWw8bnVtYmVyPigwKTtcbiAgcHJvdGVjdGVkIHZvbHVtZVJhdGlvVmFsdWUgPSBzaWduYWw8bnVtYmVyPigxMDApO1xuICBwcm90ZWN0ZWQgaXNQbGF5ID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJvdGVjdGVkIGlzTXV0ZSA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHByb3RlY3RlZCBpc1NsaWRlckF1ZGlvUHJlc3MgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcm90ZWN0ZWQgaXNEaXNhYmxlID0gc2lnbmFsPGJvb2xlYW4+KHRydWUpO1xuICBwcm90ZWN0ZWQgYXVkaW9UaW1lQ3VycmVudCA9IHNpZ25hbDxzdHJpbmc+KCdfOl86XycpO1xuICBwcm90ZWN0ZWQgYXVkaW9UaW1lRHVyYXRpb24gPSBzaWduYWw8c3RyaW5nPignXzpfOl8nKTtcbiAgcHJvdGVjdGVkIHNob3dGdWxsQ29udHJvbFZvbHVtZSA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHByaXZhdGUgb25EZXN0cm95ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAvLyAjcmVnaW9uIElOUFVUXG4gIHJlYWRvbmx5IGZpbGVBdWRpbyA9IGlucHV0LnJlcXVpcmVkPHN0cmluZz4oKTtcbiAgcmVhZG9ubHkgY2hlY2tQZXJtaXNzaW9uRG93bmxvYWRBdWRpbyA9IGlucHV0LnJlcXVpcmVkPCgpID0+IFByb21pc2U8Ym9vbGVhbj4+KCk7XG5cbiAgLyogVklFVyBDSElMRCAqL1xuICByZWFkb25seSBhdWRpb1JlZiA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPignYXVkaW9SZWYnKTtcbiAgcmVhZG9ubHkgdm9sdW1lQ29udHJvbFJlZiA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPigndm9sdW1lQ29udHJvbFJlZicpO1xuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBtZXJnZShcbiAgICAgIHRoaXMuaW5pdE9ic2VydmFibGUodGhpcy52b2x1bWVDb250cm9sUmVmKCkubmF0aXZlRWxlbWVudCwgJ21vdXNlZW50ZXInKS5waXBlKHRhcCgoKSA9PiB0aGlzLnNob3dGdWxsQ29udHJvbFZvbHVtZS5zZXQodHJ1ZSkpKSxcbiAgICAgIHRoaXMuaW5pdE9ic2VydmFibGUodGhpcy52b2x1bWVDb250cm9sUmVmKCkubmF0aXZlRWxlbWVudCwgJ21vdXNlbGVhdmUnKS5waXBlKHRhcCgoKSA9PiB0aGlzLnNob3dGdWxsQ29udHJvbFZvbHVtZS5zZXQoZmFsc2UpKSlcbiAgICApLnBpcGUodGFrZVVudGlsKHRoaXMub25EZXN0cm95KSkuc3Vic2NyaWJlKCk7XG4gIH1cbiAgLyogRlVOQ1RJT05TICovXG4gIHByaXZhdGUgaW5pdE9ic2VydmFibGUoZWw6IEhUTUxFbGVtZW50LCBldmVudE5hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8TW91c2VFdmVudD4ge1xuICAgIHJldHVybiBmcm9tRXZlbnQ8TW91c2VFdmVudD4oZWwsIGV2ZW50TmFtZSkucGlwZShcbiAgICAgIHRhcChlID0+IGUuc3RvcFByb3BhZ2F0aW9uKCkpLFxuICAgICAgdGFrZVVudGlsKHRoaXMub25EZXN0cm95KVxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaGFuZGxlcktleVByZXNzQXVkaW8oKSB7XG4gICAgdGhpcy5pc1NsaWRlckF1ZGlvUHJlc3Muc2V0KHRydWUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJBdWRpb011dGVNdXRlZChldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQubXV0ZWQgPT09IHRydWUpIHtcbiAgICAgIHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50Lm11dGVkID0gZmFsc2U7XG4gICAgICB0aGlzLmlzTXV0ZS5zZXQoZmFsc2UpO1xuICAgICAgdGhpcy52b2x1bWVSYXRpb1ZhbHVlLnNldCg1MCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy52b2x1bWVSYXRpb1ZhbHVlLnNldCgwKTtcbiAgICB0aGlzLmlzTXV0ZS5zZXQodHJ1ZSk7XG4gICAgdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQubXV0ZWQgPSB0cnVlO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJBdWRpb1BhdXNlUGxheShldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBjb25zdCBhdWRpb0VsZW1lbnQgPSB0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIWF1ZGlvRWxlbWVudC5wYXVzZWQpIHtcbiAgICAgIGF1ZGlvRWxlbWVudC5wYXVzZSgpO1xuICAgICAgdGhpcy5pc1BsYXkuc2V0KGZhbHNlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgYXVkaW9FbGVtZW50LnBsYXkoKTtcbiAgICAgIHRoaXMuaXNQbGF5LnNldCh0cnVlKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgcGxheWluZyBhdWRpbzonLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJMb2FkZWREYXRhKGV2ZW50OiBFdmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmICh0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudCkge1xuICAgICAgdGhpcy5hdWRpb1RpbWVEdXJhdGlvbi5zZXQoYXdhaXQgdGhpcy50b0hITU1TUyhNYXRoLmZsb29yKHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LmR1cmF0aW9uKSkpO1xuICAgICAgdGhpcy5hdWRpb1RpbWVDdXJyZW50LnNldChhd2FpdCB0aGlzLnRvSEhNTVNTKE1hdGguZmxvb3IodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuY3VycmVudFRpbWUpKSk7XG4gICAgICB0aGlzLmlzRGlzYWJsZS5zZXQoZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyVGltZVVwZGF0ZShldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoIXRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYXVkaW9UaW1lRHVyYXRpb24uc2V0KGF3YWl0IHRoaXMudG9ISE1NU1MoTWF0aC5mbG9vcih0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5kdXJhdGlvbikpKTtcbiAgICB0aGlzLmF1ZGlvVGltZUN1cnJlbnQuc2V0KGF3YWl0IHRoaXMudG9ISE1NU1MoTWF0aC5mbG9vcih0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5jdXJyZW50VGltZSkpKTtcbiAgICBpZiAodGhpcy5pc1NsaWRlckF1ZGlvUHJlc3MoKSkge1xuICAgICAgdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuY3VycmVudFRpbWUgPSB0aGlzLmF1ZGlvUmF0aW9WYWx1ZSgpICogTWF0aC5mbG9vcih0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5kdXJhdGlvbikgLyAxMDA7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5hdWRpb1JhdGlvVmFsdWUuc2V0KE1hdGguZmxvb3IoKHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LmN1cnJlbnRUaW1lIC8gdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuZHVyYXRpb24pICogMTAwKSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHRvSEhNTVNTKHRpbWU6IG51bWJlcikge1xuICAgIGNvbnN0IGhvdXJzID0gTWF0aC5mbG9vcih0aW1lIC8gMzYwMCk7XG4gICAgY29uc3QgbWludXRlcyA9IE1hdGguZmxvb3IoKHRpbWUgLSAoaG91cnMgKiAzNjAwKSkgLyA2MCk7XG4gICAgY29uc3Qgc2Vjb25kcyA9IHRpbWUgLSAoaG91cnMgKiAzNjAwKSAtIChtaW51dGVzICogNjApO1xuXG4gICAgY29uc3QgZ2V0TGFiZWwgPSAoKHZhbDogbnVtYmVyKSA9PiB7XG4gICAgICByZXR1cm4gYCR7dmFsIDwgMTAgPyAnMCcgOiAnJ30ke3ZhbH1gO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGAke2dldExhYmVsKGhvdXJzKX06JHtnZXRMYWJlbChtaW51dGVzKX06JHtnZXRMYWJlbChzZWNvbmRzKX1gO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJDaGFuZ2VBdWRpbyh2YWx1ZTogbnVtYmVyKSB7XG4gICAgaWYgKHZhbHVlID09PSB0aGlzLmF1ZGlvUmF0aW9WYWx1ZSgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LmN1cnJlbnRUaW1lID0gdmFsdWUgKiB0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5kdXJhdGlvbiAvIDEwMDtcbiAgICB0aGlzLmF1ZGlvUmF0aW9WYWx1ZS5zZXQodmFsdWUpO1xuICAgIHRoaXMuaXNTbGlkZXJBdWRpb1ByZXNzLnNldChmYWxzZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaGFuZGxlckNoYW5nZVZvbHVtZSh2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQudm9sdW1lID0gdmFsdWUgLyAxMDA7XG5cbiAgICBpZiAodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQudm9sdW1lKSB7XG4gICAgICB0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5tdXRlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5pc011dGUuc2V0KGZhbHNlKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5tdXRlZCA9IHRydWU7XG4gICAgdGhpcy5pc011dGUuc2V0KHRydWUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJFbmRlZChldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmlzUGxheS5zZXQoZmFsc2UpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJEb3dubG9hZChlOiBFdmVudCkge1xuICAgIGlmICghdGhpcy5jaGVja1Blcm1pc3Npb25Eb3dubG9hZEF1ZGlvKCkgfHwgIWF3YWl0IHRoaXMuY2hlY2tQZXJtaXNzaW9uRG93bmxvYWRBdWRpbygpKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoIXRoaXMuZmlsZUF1ZGlvKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgd2luZG93Lm9wZW4odGhpcy5maWxlQXVkaW8oKSwgYF9ibGFua2ApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5vbkRlc3Ryb3kubmV4dCgpO1xuICAgIHRoaXMub25EZXN0cm95LmNvbXBsZXRlKCk7XG4gIH1cbn1cbiIsIjxhdWRpbyBjb250cm9sc1xuICAjYXVkaW9SZWZcbiAgY2xhc3M9XCJoaWRkZW5cIlxuICAodGltZXVwZGF0ZSk9XCJoYW5kbGVyVGltZVVwZGF0ZSgkZXZlbnQpXCJcbiAgKGxvYWRlZGRhdGEpPVwiaGFuZGxlckxvYWRlZERhdGEoJGV2ZW50KVwiXG4gIChlbmRlZCk9XCJoYW5kbGVyRW5kZWQoJGV2ZW50KVwiPlxuICA8c291cmNlIFtzcmNdPVwiZmlsZUF1ZGlvKClcIlxuICAgIHR5cGU9XCJhdWRpby9tcGVnXCI+XG48L2F1ZGlvPlxuPGRpdiBbY2xhc3MubGlicy11aS1kaXNhYmxlXT1cImlzRGlzYWJsZSgpXCJcbiAgW2NsYXNzLnBvaW50ZXItZXZlbnRzLW5vbmVdPVwiaXNEaXNhYmxlKClcIj5cbiAgPGRpdiBjbGFzcz1cImZsZXgganVzdGlmeS1iZXR3ZWVuIGl0ZW1zLWNlbnRlclwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3LVs3MCVdIGZsZXggcC0wIGl0ZW1zLWNlbnRlciBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IG1yLVsxNnB4XSBjdXJzb3ItcG9pbnRlclwiXG4gICAgICAgIChjbGljayk9XCJoYW5kbGVyQXVkaW9QYXVzZVBsYXkoJGV2ZW50KVwiPlxuICAgICAgICA8aSBjbGFzcz1cInRleHQtWzE2cHhdXCJcbiAgICAgICAgICBbY2xhc3MubGlicy11aS1pY29uLXBsYXktc29saWRdPVwiIWlzUGxheSgpXCJcbiAgICAgICAgICBbY2xhc3MubGlicy11aS1pY29uLXBhdXNlLXNvbGlkXT1cImlzUGxheSgpXCI+XG4gICAgICAgIDwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImxpYnMtdWktZm9udC1oNXIgbXItWzE2cHhdXCI+e3sgYXVkaW9UaW1lQ3VycmVudCgpIH19IC97eyBhdWRpb1RpbWVEdXJhdGlvbigpIH19PC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInctWzMwJV0gZmxleCBwLTAgaXRlbXMtY2VudGVyIGp1c3RpZnktZW5kXCI+XG4gICAgICA8ZGl2ICN2b2x1bWVDb250cm9sUmVmXG4gICAgICAgIGNsYXNzPVwiZmxleCBweS1bM3B4XSBpdGVtcy1jZW50ZXIgcm91bmRlZC1bMTJweF0gaC1bMjhweF1cIlxuICAgICAgICBbY2xhc3MuYmctWyNlNmU3ZWFdXT0nc2hvd0Z1bGxDb250cm9sVm9sdW1lKCknXG4gICAgICAgIFtjbGFzcy5weC1bMTJweF1dPSdzaG93RnVsbENvbnRyb2xWb2x1bWUoKSc+XG4gICAgICAgIDxpIGNsYXNzPVwidGV4dC1bMTZweF0gY3Vyc29yLXBvaW50ZXJcIlxuICAgICAgICAgIFtjbGFzcy5saWJzLXVpLWljb24tc3BlYWtlci1vbi1zb2xpZF09XCIhaXNNdXRlKClcIlxuICAgICAgICAgIFtjbGFzcy5saWJzLXVpLWljb24tc3BlYWtlci1vZmYtc29saWRdPVwiaXNNdXRlKClcIlxuICAgICAgICAgIChjbGljayk9XCJoYW5kbGVyQXVkaW9NdXRlTXV0ZWQoJGV2ZW50KVwiPlxuICAgICAgICA8L2k+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtaW5wdXRzLXJhbmdlX3NsaWRlciBbY2xhc3MuaGlkZGVuXT1cIiFzaG93RnVsbENvbnRyb2xWb2x1bWUoKVwiXG4gICAgICAgICAgW21vZGVdPVwiJ2F1ZGlvJ1wiXG4gICAgICAgICAgY2xhc3NJbmNsdWRlPVwiZmxleCBpdGVtcy1jZW50ZXIgIXctWzU0cHhdIGN1cnNvci1wb2ludGVyIG1sLVs4cHhdXCJcbiAgICAgICAgICBbdmFsdWVdPVwidm9sdW1lUmF0aW9WYWx1ZSgpXCJcbiAgICAgICAgICAob3V0Q2hhbmdlKT1cImhhbmRsZXJDaGFuZ2VWb2x1bWUoJGV2ZW50KVwiIC8+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGkgY2xhc3M9XCJsaWJzLXVpLWljb24tZG93bmxvYWQtc29saWQgbWwtWzE2cHhdIGN1cnNvci1wb2ludGVyXCJcbiAgICAgICAgKGNsaWNrKT1cImhhbmRsZXJEb3dubG9hZCgkZXZlbnQpXCI+XG4gICAgICA8L2k+XG4gICAgPC9kaXY+XG5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJoLVsyNHB4XVwiPlxuICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtaW5wdXRzLXJhbmdlX3NsaWRlciBbbW9kZV09XCInYXVkaW8nXCJcbiAgICAgIFt2YWx1ZV09XCJhdWRpb1JhdGlvVmFsdWUoKVwiXG4gICAgICBbZGlzYWJsZV09J2lzRGlzYWJsZSgpJ1xuICAgICAgKG91dENoYW5nZSk9XCJoYW5kbGVyQ2hhbmdlQXVkaW8oJGV2ZW50KVwiIC8+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=
@@ -0,0 +1,128 @@
1
+ import { Component } from '@angular/core';
2
+ import { LibsUiComponentsAudioComponent } from './audio.component';
3
+ import { CommonModule } from '@angular/common';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * Demo component hiển thị các ví dụ khác nhau của Audio component
7
+ */
8
+ export class LibsUiComponentsAudioDemoComponent {
9
+ /**
10
+ * Permission function luôn allow download
11
+ */
12
+ basicPermissionCheck() {
13
+ return Promise.resolve(true);
14
+ }
15
+ /**
16
+ * Permission function không cho phép download
17
+ */
18
+ denyPermissionCheck() {
19
+ return Promise.resolve(false);
20
+ }
21
+ /**
22
+ * Permission function có delay để mô phỏng API call
23
+ */
24
+ delayedPermissionCheck() {
25
+ return new Promise(resolve => {
26
+ setTimeout(() => {
27
+ resolve(true);
28
+ }, 1500);
29
+ });
30
+ }
31
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
32
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: LibsUiComponentsAudioDemoComponent, isStandalone: true, selector: "lib-audio-demo", ngImport: i0, template: `
33
+ <div class="p-4">
34
+ <h1 class="text-2xl font-bold mb-4">Audio Component Demo</h1>
35
+
36
+ <p class="mb-4">
37
+ Audio Component là một trình phát âm thanh tùy chỉnh với các controls đầy đủ như play/pause,
38
+ volume control, progress bar và download button.
39
+ </p>
40
+
41
+ <div class="demo-section">
42
+ <div class="demo-title">Basic Usage</div>
43
+ <p class="demo-description">Simple audio player với default settings</p>
44
+ <libs_ui-components-audio
45
+ fileAudio="https://nhacchuong123.com/nhac-chuong/abcdefgh/nhac-chuong-nguoi-ay-dau-co-dang-akira-phan-nguyen-van-chung.mp3"
46
+ [checkPermissionDownloadAudio]="basicPermissionCheck"
47
+ />
48
+ </div>
49
+
50
+ <div class="demo-section">
51
+ <div class="demo-title">Disabled Download</div>
52
+ <p class="demo-description">Audio player không cho phép download</p>
53
+ <libs_ui-components-audio
54
+ fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
55
+ [checkPermissionDownloadAudio]="denyPermissionCheck"
56
+ />
57
+ </div>
58
+
59
+ <div class="demo-section">
60
+ <div class="demo-title">Long Audio File</div>
61
+ <p class="demo-description">Audio player với track có duration dài hơn</p>
62
+ <libs_ui-components-audio
63
+ fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"
64
+ [checkPermissionDownloadAudio]="basicPermissionCheck"
65
+ />
66
+ </div>
67
+
68
+ <div class="demo-section">
69
+ <div class="demo-title">Delayed Permission Check</div>
70
+ <p class="demo-description">Mô phỏng permission check có delay, simulate API call</p>
71
+ <libs_ui-components-audio
72
+ fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3"
73
+ [checkPermissionDownloadAudio]="delayedPermissionCheck"
74
+ />
75
+ </div>
76
+ </div>
77
+ `, isInline: true, styles: [".demo-section{margin-bottom:2rem;padding:1rem;border:1px solid #e5e7eb;border-radius:.5rem}.demo-title{font-size:1.25rem;font-weight:600;margin-bottom:1rem}.demo-description{margin-bottom:1rem;color:#4b5563}\n"], dependencies: [{ kind: "component", type: LibsUiComponentsAudioComponent, selector: "libs_ui-components-audio", inputs: ["fileAudio", "checkPermissionDownloadAudio"] }, { kind: "ngmodule", type: CommonModule }] });
78
+ }
79
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioDemoComponent, decorators: [{
80
+ type: Component,
81
+ args: [{ selector: 'lib-audio-demo', standalone: true, imports: [LibsUiComponentsAudioComponent, CommonModule], template: `
82
+ <div class="p-4">
83
+ <h1 class="text-2xl font-bold mb-4">Audio Component Demo</h1>
84
+
85
+ <p class="mb-4">
86
+ Audio Component là một trình phát âm thanh tùy chỉnh với các controls đầy đủ như play/pause,
87
+ volume control, progress bar và download button.
88
+ </p>
89
+
90
+ <div class="demo-section">
91
+ <div class="demo-title">Basic Usage</div>
92
+ <p class="demo-description">Simple audio player với default settings</p>
93
+ <libs_ui-components-audio
94
+ fileAudio="https://nhacchuong123.com/nhac-chuong/abcdefgh/nhac-chuong-nguoi-ay-dau-co-dang-akira-phan-nguyen-van-chung.mp3"
95
+ [checkPermissionDownloadAudio]="basicPermissionCheck"
96
+ />
97
+ </div>
98
+
99
+ <div class="demo-section">
100
+ <div class="demo-title">Disabled Download</div>
101
+ <p class="demo-description">Audio player không cho phép download</p>
102
+ <libs_ui-components-audio
103
+ fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
104
+ [checkPermissionDownloadAudio]="denyPermissionCheck"
105
+ />
106
+ </div>
107
+
108
+ <div class="demo-section">
109
+ <div class="demo-title">Long Audio File</div>
110
+ <p class="demo-description">Audio player với track có duration dài hơn</p>
111
+ <libs_ui-components-audio
112
+ fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"
113
+ [checkPermissionDownloadAudio]="basicPermissionCheck"
114
+ />
115
+ </div>
116
+
117
+ <div class="demo-section">
118
+ <div class="demo-title">Delayed Permission Check</div>
119
+ <p class="demo-description">Mô phỏng permission check có delay, simulate API call</p>
120
+ <libs_ui-components-audio
121
+ fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3"
122
+ [checkPermissionDownloadAudio]="delayedPermissionCheck"
123
+ />
124
+ </div>
125
+ </div>
126
+ `, styles: [".demo-section{margin-bottom:2rem;padding:1rem;border:1px solid #e5e7eb;border-radius:.5rem}.demo-title{font-size:1.25rem;font-weight:600;margin-bottom:1rem}.demo-description{margin-bottom:1rem;color:#4b5563}\n"] }]
127
+ }] });
128
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVtby5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvYXVkaW8vc3JjL2RlbW8uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDMUMsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDOztBQUUvQzs7R0FFRztBQXVFSCxNQUFNLE9BQU8sa0NBQWtDO0lBQzdDOztPQUVHO0lBQ0gsb0JBQW9CO1FBQ2xCLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxtQkFBbUI7UUFDakIsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7T0FFRztJQUNILHNCQUFzQjtRQUNwQixPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzNCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2QsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2hCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNYLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzt3R0F4QlUsa0NBQWtDOzRGQUFsQyxrQ0FBa0MsMEVBL0NuQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNkNULDJSQWpFUyw4QkFBOEIsMkhBQUUsWUFBWTs7NEZBbUUzQyxrQ0FBa0M7a0JBdEU5QyxTQUFTOytCQUNFLGdCQUFnQixjQUNkLElBQUksV0FDUCxDQUFDLDhCQUE4QixFQUFFLFlBQVksQ0FBQyxZQW9CN0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZDVCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c0F1ZGlvQ29tcG9uZW50IH0gZnJvbSAnLi9hdWRpby5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuLyoqXG4gKiBEZW1vIGNvbXBvbmVudCBoaeG7g24gdGjhu4sgY8OhYyB2w60gZOG7pSBraMOhYyBuaGF1IGPhu6dhIEF1ZGlvIGNvbXBvbmVudFxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdsaWItYXVkaW8tZGVtbycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtMaWJzVWlDb21wb25lbnRzQXVkaW9Db21wb25lbnQsIENvbW1vbk1vZHVsZV0sXG4gIHN0eWxlczogW2BcbiAgICAuZGVtby1zZWN0aW9uIHtcbiAgICAgIG1hcmdpbi1ib3R0b206IDJyZW07XG4gICAgICBwYWRkaW5nOiAxcmVtO1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgI2U1ZTdlYjtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDAuNXJlbTtcbiAgICB9XG4gICAgXG4gICAgLmRlbW8tdGl0bGUge1xuICAgICAgZm9udC1zaXplOiAxLjI1cmVtO1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgIG1hcmdpbi1ib3R0b206IDFyZW07XG4gICAgfVxuICAgIFxuICAgIC5kZW1vLWRlc2NyaXB0aW9uIHtcbiAgICAgIG1hcmdpbi1ib3R0b206IDFyZW07XG4gICAgICBjb2xvcjogIzRiNTU2MztcbiAgICB9XG4gIGBdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJwLTRcIj5cbiAgICAgIDxoMSBjbGFzcz1cInRleHQtMnhsIGZvbnQtYm9sZCBtYi00XCI+QXVkaW8gQ29tcG9uZW50IERlbW88L2gxPlxuICAgICAgXG4gICAgICA8cCBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgQXVkaW8gQ29tcG9uZW50IGzDoCBt4buZdCB0csOsbmggcGjDoXQgw6JtIHRoYW5oIHTDuXkgY2jhu4luaCB24bubaSBjw6FjIGNvbnRyb2xzIMSR4bqneSDEkeG7pyBuaMawIHBsYXkvcGF1c2UsIFxuICAgICAgICB2b2x1bWUgY29udHJvbCwgcHJvZ3Jlc3MgYmFyIHbDoCBkb3dubG9hZCBidXR0b24uXG4gICAgICA8L3A+XG4gICAgICBcbiAgICAgIDxkaXYgY2xhc3M9XCJkZW1vLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRlbW8tdGl0bGVcIj5CYXNpYyBVc2FnZTwvZGl2PlxuICAgICAgICA8cCBjbGFzcz1cImRlbW8tZGVzY3JpcHRpb25cIj5TaW1wbGUgYXVkaW8gcGxheWVyIHbhu5tpIGRlZmF1bHQgc2V0dGluZ3M8L3A+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtYXVkaW9cbiAgICAgICAgICBmaWxlQXVkaW89XCJodHRwczovL25oYWNjaHVvbmcxMjMuY29tL25oYWMtY2h1b25nL2FiY2RlZmdoL25oYWMtY2h1b25nLW5ndW9pLWF5LWRhdS1jby1kYW5nLWFraXJhLXBoYW4tbmd1eWVuLXZhbi1jaHVuZy5tcDNcIlxuICAgICAgICAgIFtjaGVja1Blcm1pc3Npb25Eb3dubG9hZEF1ZGlvXT1cImJhc2ljUGVybWlzc2lvbkNoZWNrXCJcbiAgICAgICAgLz5cbiAgICAgIDwvZGl2PlxuICAgICAgXG4gICAgICA8ZGl2IGNsYXNzPVwiZGVtby1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkZW1vLXRpdGxlXCI+RGlzYWJsZWQgRG93bmxvYWQ8L2Rpdj5cbiAgICAgICAgPHAgY2xhc3M9XCJkZW1vLWRlc2NyaXB0aW9uXCI+QXVkaW8gcGxheWVyIGtow7RuZyBjaG8gcGjDqXAgZG93bmxvYWQ8L3A+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtYXVkaW9cbiAgICAgICAgICBmaWxlQXVkaW89XCJodHRwczovL3d3dy5zb3VuZGhlbGl4LmNvbS9leGFtcGxlcy9tcDMvU291bmRIZWxpeC1Tb25nLTEubXAzXCJcbiAgICAgICAgICBbY2hlY2tQZXJtaXNzaW9uRG93bmxvYWRBdWRpb109XCJkZW55UGVybWlzc2lvbkNoZWNrXCJcbiAgICAgICAgLz5cbiAgICAgIDwvZGl2PlxuICAgICAgXG4gICAgICA8ZGl2IGNsYXNzPVwiZGVtby1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkZW1vLXRpdGxlXCI+TG9uZyBBdWRpbyBGaWxlPC9kaXY+XG4gICAgICAgIDxwIGNsYXNzPVwiZGVtby1kZXNjcmlwdGlvblwiPkF1ZGlvIHBsYXllciB24bubaSB0cmFjayBjw7MgZHVyYXRpb24gZMOgaSBoxqFuPC9wPlxuICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWF1ZGlvXG4gICAgICAgICAgZmlsZUF1ZGlvPVwiaHR0cHM6Ly93d3cuc291bmRoZWxpeC5jb20vZXhhbXBsZXMvbXAzL1NvdW5kSGVsaXgtU29uZy0yLm1wM1wiXG4gICAgICAgICAgW2NoZWNrUGVybWlzc2lvbkRvd25sb2FkQXVkaW9dPVwiYmFzaWNQZXJtaXNzaW9uQ2hlY2tcIlxuICAgICAgICAvPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJkZW1vLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRlbW8tdGl0bGVcIj5EZWxheWVkIFBlcm1pc3Npb24gQ2hlY2s8L2Rpdj5cbiAgICAgICAgPHAgY2xhc3M9XCJkZW1vLWRlc2NyaXB0aW9uXCI+TcO0IHBo4buPbmcgcGVybWlzc2lvbiBjaGVjayBjw7MgZGVsYXksIHNpbXVsYXRlIEFQSSBjYWxsPC9wPlxuICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWF1ZGlvXG4gICAgICAgICAgZmlsZUF1ZGlvPVwiaHR0cHM6Ly93d3cuc291bmRoZWxpeC5jb20vZXhhbXBsZXMvbXAzL1NvdW5kSGVsaXgtU29uZy0zLm1wM1wiXG4gICAgICAgICAgW2NoZWNrUGVybWlzc2lvbkRvd25sb2FkQXVkaW9dPVwiZGVsYXllZFBlcm1pc3Npb25DaGVja1wiXG4gICAgICAgIC8+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYFxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlDb21wb25lbnRzQXVkaW9EZW1vQ29tcG9uZW50IHtcbiAgLyoqXG4gICAqIFBlcm1pc3Npb24gZnVuY3Rpb24gbHXDtG4gYWxsb3cgZG93bmxvYWRcbiAgICovXG4gIGJhc2ljUGVybWlzc2lvbkNoZWNrKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodHJ1ZSk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBQZXJtaXNzaW9uIGZ1bmN0aW9uIGtow7RuZyBjaG8gcGjDqXAgZG93bmxvYWRcbiAgICovXG4gIGRlbnlQZXJtaXNzaW9uQ2hlY2soKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogUGVybWlzc2lvbiBmdW5jdGlvbiBjw7MgZGVsYXkgxJHhu4MgbcO0IHBo4buPbmcgQVBJIGNhbGxcbiAgICovXG4gIGRlbGF5ZWRQZXJtaXNzaW9uQ2hlY2soKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICB9LCAxNTAwKTtcbiAgICB9KTtcbiAgfVxufSAiXX0=
package/esm2022/index.mjs CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './audio.component';
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvYXVkaW8vc3JjL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsbUJBQW1CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2F1ZGlvLmNvbXBvbmVudCc7XG4iXX0=
2
+ export * from './demo.component';
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvYXVkaW8vc3JjL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyxrQkFBa0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vYXVkaW8uY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vZGVtby5jb21wb25lbnQnO1xuIl19
@@ -1,7 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, input, viewChild, Input, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { signal, input, viewChild, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';
4
4
  import { Subject, merge, tap, takeUntil, fromEvent } from 'rxjs';
5
+ import { CommonModule } from '@angular/common';
5
6
 
6
7
  class LibsUiComponentsAudioComponent {
7
8
  // #region PROPERTY
@@ -17,7 +18,7 @@ class LibsUiComponentsAudioComponent {
17
18
  onDestroy = new Subject();
18
19
  // #region INPUT
19
20
  fileAudio = input.required();
20
- checkPermissionDownloadAudio;
21
+ checkPermissionDownloadAudio = input.required();
21
22
  /* VIEW CHILD */
22
23
  audioRef = viewChild.required('audioRef');
23
24
  volumeControlRef = viewChild.required('volumeControlRef');
@@ -112,7 +113,7 @@ class LibsUiComponentsAudioComponent {
112
113
  this.isPlay.set(false);
113
114
  }
114
115
  async handlerDownload(e) {
115
- if (!this.checkPermissionDownloadAudio || !await this.checkPermissionDownloadAudio()) {
116
+ if (!this.checkPermissionDownloadAudio() || !await this.checkPermissionDownloadAudio()()) {
116
117
  return;
117
118
  }
118
119
  e.stopPropagation();
@@ -126,21 +127,142 @@ class LibsUiComponentsAudioComponent {
126
127
  this.onDestroy.complete();
127
128
  }
128
129
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
129
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.13", type: LibsUiComponentsAudioComponent, isStandalone: true, selector: "libs_ui-components-audio", inputs: { fileAudio: { classPropertyName: "fileAudio", publicName: "fileAudio", isSignal: true, isRequired: true, transformFunction: null }, checkPermissionDownloadAudio: { classPropertyName: "checkPermissionDownloadAudio", publicName: "checkPermissionDownloadAudio", isSignal: false, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "audioRef", first: true, predicate: ["audioRef"], descendants: true, isSignal: true }, { propertyName: "volumeControlRef", first: true, predicate: ["volumeControlRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n", dependencies: [{ kind: "component", type: LibsUiComponentsInputsRangeSliderComponent, selector: "libs_ui-components-inputs-range_slider", inputs: ["mode", "min", "max", "value", "classInclude", "disable", "unit", "step", "hideProgressingValue", "formatNumber"], outputs: ["valueChange", "outChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
130
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.13", type: LibsUiComponentsAudioComponent, isStandalone: true, selector: "libs_ui-components-audio", inputs: { fileAudio: { classPropertyName: "fileAudio", publicName: "fileAudio", isSignal: true, isRequired: true, transformFunction: null }, checkPermissionDownloadAudio: { classPropertyName: "checkPermissionDownloadAudio", publicName: "checkPermissionDownloadAudio", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "audioRef", first: true, predicate: ["audioRef"], descendants: true, isSignal: true }, { propertyName: "volumeControlRef", first: true, predicate: ["volumeControlRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n", dependencies: [{ kind: "component", type: LibsUiComponentsInputsRangeSliderComponent, selector: "libs_ui-components-inputs-range_slider", inputs: ["mode", "min", "max", "value", "classInclude", "disable", "unit", "step", "hideProgressingValue", "formatNumber"], outputs: ["valueChange", "outChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
130
131
  }
131
132
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioComponent, decorators: [{
132
133
  type: Component,
133
134
  args: [{ selector: 'libs_ui-components-audio', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
134
135
  LibsUiComponentsInputsRangeSliderComponent
135
136
  ], template: "<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n" }]
136
- }], propDecorators: { checkPermissionDownloadAudio: [{
137
- type: Input,
138
- args: [{ required: true }]
139
- }] } });
137
+ }] });
138
+
139
+ /**
140
+ * Demo component hiển thị các ví dụ khác nhau của Audio component
141
+ */
142
+ class LibsUiComponentsAudioDemoComponent {
143
+ /**
144
+ * Permission function luôn allow download
145
+ */
146
+ basicPermissionCheck() {
147
+ return Promise.resolve(true);
148
+ }
149
+ /**
150
+ * Permission function không cho phép download
151
+ */
152
+ denyPermissionCheck() {
153
+ return Promise.resolve(false);
154
+ }
155
+ /**
156
+ * Permission function có delay để mô phỏng API call
157
+ */
158
+ delayedPermissionCheck() {
159
+ return new Promise(resolve => {
160
+ setTimeout(() => {
161
+ resolve(true);
162
+ }, 1500);
163
+ });
164
+ }
165
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
166
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: LibsUiComponentsAudioDemoComponent, isStandalone: true, selector: "lib-audio-demo", ngImport: i0, template: `
167
+ <div class="p-4">
168
+ <h1 class="text-2xl font-bold mb-4">Audio Component Demo</h1>
169
+
170
+ <p class="mb-4">
171
+ Audio Component là một trình phát âm thanh tùy chỉnh với các controls đầy đủ như play/pause,
172
+ volume control, progress bar và download button.
173
+ </p>
174
+
175
+ <div class="demo-section">
176
+ <div class="demo-title">Basic Usage</div>
177
+ <p class="demo-description">Simple audio player với default settings</p>
178
+ <libs_ui-components-audio
179
+ fileAudio="https://nhacchuong123.com/nhac-chuong/abcdefgh/nhac-chuong-nguoi-ay-dau-co-dang-akira-phan-nguyen-van-chung.mp3"
180
+ [checkPermissionDownloadAudio]="basicPermissionCheck"
181
+ />
182
+ </div>
183
+
184
+ <div class="demo-section">
185
+ <div class="demo-title">Disabled Download</div>
186
+ <p class="demo-description">Audio player không cho phép download</p>
187
+ <libs_ui-components-audio
188
+ fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
189
+ [checkPermissionDownloadAudio]="denyPermissionCheck"
190
+ />
191
+ </div>
192
+
193
+ <div class="demo-section">
194
+ <div class="demo-title">Long Audio File</div>
195
+ <p class="demo-description">Audio player với track có duration dài hơn</p>
196
+ <libs_ui-components-audio
197
+ fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"
198
+ [checkPermissionDownloadAudio]="basicPermissionCheck"
199
+ />
200
+ </div>
201
+
202
+ <div class="demo-section">
203
+ <div class="demo-title">Delayed Permission Check</div>
204
+ <p class="demo-description">Mô phỏng permission check có delay, simulate API call</p>
205
+ <libs_ui-components-audio
206
+ fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3"
207
+ [checkPermissionDownloadAudio]="delayedPermissionCheck"
208
+ />
209
+ </div>
210
+ </div>
211
+ `, isInline: true, styles: [".demo-section{margin-bottom:2rem;padding:1rem;border:1px solid #e5e7eb;border-radius:.5rem}.demo-title{font-size:1.25rem;font-weight:600;margin-bottom:1rem}.demo-description{margin-bottom:1rem;color:#4b5563}\n"], dependencies: [{ kind: "component", type: LibsUiComponentsAudioComponent, selector: "libs_ui-components-audio", inputs: ["fileAudio", "checkPermissionDownloadAudio"] }, { kind: "ngmodule", type: CommonModule }] });
212
+ }
213
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioDemoComponent, decorators: [{
214
+ type: Component,
215
+ args: [{ selector: 'lib-audio-demo', standalone: true, imports: [LibsUiComponentsAudioComponent, CommonModule], template: `
216
+ <div class="p-4">
217
+ <h1 class="text-2xl font-bold mb-4">Audio Component Demo</h1>
218
+
219
+ <p class="mb-4">
220
+ Audio Component là một trình phát âm thanh tùy chỉnh với các controls đầy đủ như play/pause,
221
+ volume control, progress bar và download button.
222
+ </p>
223
+
224
+ <div class="demo-section">
225
+ <div class="demo-title">Basic Usage</div>
226
+ <p class="demo-description">Simple audio player với default settings</p>
227
+ <libs_ui-components-audio
228
+ fileAudio="https://nhacchuong123.com/nhac-chuong/abcdefgh/nhac-chuong-nguoi-ay-dau-co-dang-akira-phan-nguyen-van-chung.mp3"
229
+ [checkPermissionDownloadAudio]="basicPermissionCheck"
230
+ />
231
+ </div>
232
+
233
+ <div class="demo-section">
234
+ <div class="demo-title">Disabled Download</div>
235
+ <p class="demo-description">Audio player không cho phép download</p>
236
+ <libs_ui-components-audio
237
+ fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
238
+ [checkPermissionDownloadAudio]="denyPermissionCheck"
239
+ />
240
+ </div>
241
+
242
+ <div class="demo-section">
243
+ <div class="demo-title">Long Audio File</div>
244
+ <p class="demo-description">Audio player với track có duration dài hơn</p>
245
+ <libs_ui-components-audio
246
+ fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"
247
+ [checkPermissionDownloadAudio]="basicPermissionCheck"
248
+ />
249
+ </div>
250
+
251
+ <div class="demo-section">
252
+ <div class="demo-title">Delayed Permission Check</div>
253
+ <p class="demo-description">Mô phỏng permission check có delay, simulate API call</p>
254
+ <libs_ui-components-audio
255
+ fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3"
256
+ [checkPermissionDownloadAudio]="delayedPermissionCheck"
257
+ />
258
+ </div>
259
+ </div>
260
+ `, styles: [".demo-section{margin-bottom:2rem;padding:1rem;border:1px solid #e5e7eb;border-radius:.5rem}.demo-title{font-size:1.25rem;font-weight:600;margin-bottom:1rem}.demo-description{margin-bottom:1rem;color:#4b5563}\n"] }]
261
+ }] });
140
262
 
141
263
  /**
142
264
  * Generated bundle index. Do not edit.
143
265
  */
144
266
 
145
- export { LibsUiComponentsAudioComponent };
267
+ export { LibsUiComponentsAudioComponent, LibsUiComponentsAudioDemoComponent };
146
268
  //# sourceMappingURL=libs-ui-components-audio.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"libs-ui-components-audio.mjs","sources":["../../../../../libs-ui/components/audio/src/audio.component.ts","../../../../../libs-ui/components/audio/src/audio.component.html","../../../../../libs-ui/components/audio/src/libs-ui-components-audio.ts"],"sourcesContent":["import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, input, Input, OnDestroy, signal, viewChild } from '@angular/core';\nimport { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';\nimport { fromEvent, merge, Observable, Subject, takeUntil, tap } from 'rxjs';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-audio',\n templateUrl: './audio.component.html',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n LibsUiComponentsInputsRangeSliderComponent\n ]\n})\nexport class LibsUiComponentsAudioComponent implements AfterViewInit, OnDestroy {\n // #region PROPERTY\n protected audioRatioValue = signal<number>(0);\n protected volumeRatioValue = signal<number>(100);\n protected isPlay = signal<boolean>(false);\n protected isMute = signal<boolean>(false);\n protected isSliderAudioPress = signal<boolean>(false);\n protected isDisable = signal<boolean>(true);\n protected audioTimeCurrent = signal<string>('_:_:_');\n protected audioTimeDuration = signal<string>('_:_:_');\n protected showFullControlVolume = signal<boolean>(false);\n private onDestroy = new Subject<void>();\n\n // #region INPUT\n readonly fileAudio = input.required<string>();\n @Input({ required: true }) checkPermissionDownloadAudio?: () => Promise<boolean>;\n\n /* VIEW CHILD */\n readonly audioRef = viewChild.required<ElementRef>('audioRef');\n readonly volumeControlRef = viewChild.required<ElementRef>('volumeControlRef');\n\n ngAfterViewInit() {\n merge(\n this.initObservable(this.volumeControlRef().nativeElement, 'mouseenter').pipe(tap(() => this.showFullControlVolume.set(true))),\n this.initObservable(this.volumeControlRef().nativeElement, 'mouseleave').pipe(tap(() => this.showFullControlVolume.set(false)))\n ).pipe(takeUntil(this.onDestroy)).subscribe();\n }\n /* FUNCTIONS */\n private initObservable(el: HTMLElement, eventName: string): Observable<MouseEvent> {\n return fromEvent<MouseEvent>(el, eventName).pipe(\n tap(e => e.stopPropagation()),\n takeUntil(this.onDestroy)\n );\n }\n\n protected async handlerKeyPressAudio() {\n this.isSliderAudioPress.set(true);\n }\n\n protected async handlerAudioMuteMuted(event: Event) {\n event.stopPropagation();\n if (this.audioRef().nativeElement.muted === true) {\n this.audioRef().nativeElement.muted = false;\n this.isMute.set(false);\n this.volumeRatioValue.set(50);\n\n return;\n }\n this.volumeRatioValue.set(0);\n this.isMute.set(true);\n this.audioRef().nativeElement.muted = true;\n }\n\n protected async handlerAudioPausePlay(event: Event) {\n event.stopPropagation();\n const audioElement = this.audioRef().nativeElement;\n if (!audioElement.paused) {\n audioElement.pause();\n this.isPlay.set(false);\n return;\n }\n\n try {\n await audioElement.play();\n this.isPlay.set(true);\n } catch (error) {\n console.error('Error playing audio:', error);\n }\n }\n\n protected async handlerLoadedData(event: Event) {\n event.stopPropagation();\n if (this.audioRef().nativeElement) {\n this.audioTimeDuration.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.duration)));\n this.audioTimeCurrent.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.currentTime)));\n this.isDisable.set(false);\n }\n }\n\n protected async handlerTimeUpdate(event: Event) {\n event.stopPropagation();\n if (!this.audioRef().nativeElement) {\n return;\n }\n this.audioTimeDuration.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.duration)));\n this.audioTimeCurrent.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.currentTime)));\n if (this.isSliderAudioPress()) {\n this.audioRef().nativeElement.currentTime = this.audioRatioValue() * Math.floor(this.audioRef().nativeElement.duration) / 100;\n\n return;\n }\n this.audioRatioValue.set(Math.floor((this.audioRef().nativeElement.currentTime / this.audioRef().nativeElement.duration) * 100));\n }\n\n private async toHHMMSS(time: number) {\n const hours = Math.floor(time / 3600);\n const minutes = Math.floor((time - (hours * 3600)) / 60);\n const seconds = time - (hours * 3600) - (minutes * 60);\n\n const getLabel = ((val: number) => {\n return `${val < 10 ? '0' : ''}${val}`;\n });\n\n return `${getLabel(hours)}:${getLabel(minutes)}:${getLabel(seconds)}`;\n }\n\n protected async handlerChangeAudio(value: number) {\n if (value === this.audioRatioValue()) {\n return;\n }\n this.audioRef().nativeElement.currentTime = value * this.audioRef().nativeElement.duration / 100;\n this.audioRatioValue.set(value);\n this.isSliderAudioPress.set(false);\n }\n\n protected async handlerChangeVolume(value: number) {\n this.audioRef().nativeElement.volume = value / 100;\n\n if (this.audioRef().nativeElement.volume) {\n this.audioRef().nativeElement.muted = false;\n this.isMute.set(false);\n\n return;\n }\n this.audioRef().nativeElement.muted = true;\n this.isMute.set(true);\n }\n\n protected async handlerEnded(event: Event) {\n event.stopPropagation();\n this.isPlay.set(false);\n }\n\n protected async handlerDownload(e: Event) {\n if (!this.checkPermissionDownloadAudio || !await this.checkPermissionDownloadAudio()) {\n return;\n }\n e.stopPropagation();\n if (!this.fileAudio()) {\n return;\n }\n window.open(this.fileAudio(), `_blank`);\n }\n\n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n}\n","<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"libs-ui-components-audio.mjs","sources":["../../../../../libs-ui/components/audio/src/audio.component.ts","../../../../../libs-ui/components/audio/src/audio.component.html","../../../../../libs-ui/components/audio/src/demo.component.ts","../../../../../libs-ui/components/audio/src/libs-ui-components-audio.ts"],"sourcesContent":["import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, input, OnDestroy, signal, viewChild } from '@angular/core';\nimport { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';\nimport { fromEvent, merge, Observable, Subject, takeUntil, tap } from 'rxjs';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-audio',\n templateUrl: './audio.component.html',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n LibsUiComponentsInputsRangeSliderComponent\n ]\n})\nexport class LibsUiComponentsAudioComponent implements AfterViewInit, OnDestroy {\n // #region PROPERTY\n protected audioRatioValue = signal<number>(0);\n protected volumeRatioValue = signal<number>(100);\n protected isPlay = signal<boolean>(false);\n protected isMute = signal<boolean>(false);\n protected isSliderAudioPress = signal<boolean>(false);\n protected isDisable = signal<boolean>(true);\n protected audioTimeCurrent = signal<string>('_:_:_');\n protected audioTimeDuration = signal<string>('_:_:_');\n protected showFullControlVolume = signal<boolean>(false);\n private onDestroy = new Subject<void>();\n\n // #region INPUT\n readonly fileAudio = input.required<string>();\n readonly checkPermissionDownloadAudio = input.required<() => Promise<boolean>>();\n\n /* VIEW CHILD */\n readonly audioRef = viewChild.required<ElementRef>('audioRef');\n readonly volumeControlRef = viewChild.required<ElementRef>('volumeControlRef');\n\n ngAfterViewInit() {\n merge(\n this.initObservable(this.volumeControlRef().nativeElement, 'mouseenter').pipe(tap(() => this.showFullControlVolume.set(true))),\n this.initObservable(this.volumeControlRef().nativeElement, 'mouseleave').pipe(tap(() => this.showFullControlVolume.set(false)))\n ).pipe(takeUntil(this.onDestroy)).subscribe();\n }\n /* FUNCTIONS */\n private initObservable(el: HTMLElement, eventName: string): Observable<MouseEvent> {\n return fromEvent<MouseEvent>(el, eventName).pipe(\n tap(e => e.stopPropagation()),\n takeUntil(this.onDestroy)\n );\n }\n\n protected async handlerKeyPressAudio() {\n this.isSliderAudioPress.set(true);\n }\n\n protected async handlerAudioMuteMuted(event: Event) {\n event.stopPropagation();\n if (this.audioRef().nativeElement.muted === true) {\n this.audioRef().nativeElement.muted = false;\n this.isMute.set(false);\n this.volumeRatioValue.set(50);\n\n return;\n }\n this.volumeRatioValue.set(0);\n this.isMute.set(true);\n this.audioRef().nativeElement.muted = true;\n }\n\n protected async handlerAudioPausePlay(event: Event) {\n event.stopPropagation();\n const audioElement = this.audioRef().nativeElement;\n if (!audioElement.paused) {\n audioElement.pause();\n this.isPlay.set(false);\n return;\n }\n\n try {\n await audioElement.play();\n this.isPlay.set(true);\n } catch (error) {\n console.error('Error playing audio:', error);\n }\n }\n\n protected async handlerLoadedData(event: Event) {\n event.stopPropagation();\n if (this.audioRef().nativeElement) {\n this.audioTimeDuration.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.duration)));\n this.audioTimeCurrent.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.currentTime)));\n this.isDisable.set(false);\n }\n }\n\n protected async handlerTimeUpdate(event: Event) {\n event.stopPropagation();\n if (!this.audioRef().nativeElement) {\n return;\n }\n this.audioTimeDuration.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.duration)));\n this.audioTimeCurrent.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.currentTime)));\n if (this.isSliderAudioPress()) {\n this.audioRef().nativeElement.currentTime = this.audioRatioValue() * Math.floor(this.audioRef().nativeElement.duration) / 100;\n\n return;\n }\n this.audioRatioValue.set(Math.floor((this.audioRef().nativeElement.currentTime / this.audioRef().nativeElement.duration) * 100));\n }\n\n private async toHHMMSS(time: number) {\n const hours = Math.floor(time / 3600);\n const minutes = Math.floor((time - (hours * 3600)) / 60);\n const seconds = time - (hours * 3600) - (minutes * 60);\n\n const getLabel = ((val: number) => {\n return `${val < 10 ? '0' : ''}${val}`;\n });\n\n return `${getLabel(hours)}:${getLabel(minutes)}:${getLabel(seconds)}`;\n }\n\n protected async handlerChangeAudio(value: number) {\n if (value === this.audioRatioValue()) {\n return;\n }\n this.audioRef().nativeElement.currentTime = value * this.audioRef().nativeElement.duration / 100;\n this.audioRatioValue.set(value);\n this.isSliderAudioPress.set(false);\n }\n\n protected async handlerChangeVolume(value: number) {\n this.audioRef().nativeElement.volume = value / 100;\n\n if (this.audioRef().nativeElement.volume) {\n this.audioRef().nativeElement.muted = false;\n this.isMute.set(false);\n\n return;\n }\n this.audioRef().nativeElement.muted = true;\n this.isMute.set(true);\n }\n\n protected async handlerEnded(event: Event) {\n event.stopPropagation();\n this.isPlay.set(false);\n }\n\n protected async handlerDownload(e: Event) {\n if (!this.checkPermissionDownloadAudio() || !await this.checkPermissionDownloadAudio()()) {\n return;\n }\n e.stopPropagation();\n if (!this.fileAudio()) {\n return;\n }\n window.open(this.fileAudio(), `_blank`);\n }\n\n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n}\n","<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n","import { Component } from '@angular/core';\nimport { LibsUiComponentsAudioComponent } from './audio.component';\nimport { CommonModule } from '@angular/common';\n\n/**\n * Demo component hiển thị các ví dụ khác nhau của Audio component\n */\n@Component({\n selector: 'lib-audio-demo',\n standalone: true,\n imports: [LibsUiComponentsAudioComponent, CommonModule],\n styles: [`\n .demo-section {\n margin-bottom: 2rem;\n padding: 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 0.5rem;\n }\n \n .demo-title {\n font-size: 1.25rem;\n font-weight: 600;\n margin-bottom: 1rem;\n }\n \n .demo-description {\n margin-bottom: 1rem;\n color: #4b5563;\n }\n `],\n template: `\n <div class=\"p-4\">\n <h1 class=\"text-2xl font-bold mb-4\">Audio Component Demo</h1>\n \n <p class=\"mb-4\">\n Audio Component là một trình phát âm thanh tùy chỉnh với các controls đầy đủ như play/pause, \n volume control, progress bar và download button.\n </p>\n \n <div class=\"demo-section\">\n <div class=\"demo-title\">Basic Usage</div>\n <p class=\"demo-description\">Simple audio player với default settings</p>\n <libs_ui-components-audio\n fileAudio=\"https://nhacchuong123.com/nhac-chuong/abcdefgh/nhac-chuong-nguoi-ay-dau-co-dang-akira-phan-nguyen-van-chung.mp3\"\n [checkPermissionDownloadAudio]=\"basicPermissionCheck\"\n />\n </div>\n \n <div class=\"demo-section\">\n <div class=\"demo-title\">Disabled Download</div>\n <p class=\"demo-description\">Audio player không cho phép download</p>\n <libs_ui-components-audio\n fileAudio=\"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3\"\n [checkPermissionDownloadAudio]=\"denyPermissionCheck\"\n />\n </div>\n \n <div class=\"demo-section\">\n <div class=\"demo-title\">Long Audio File</div>\n <p class=\"demo-description\">Audio player với track có duration dài hơn</p>\n <libs_ui-components-audio\n fileAudio=\"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3\"\n [checkPermissionDownloadAudio]=\"basicPermissionCheck\"\n />\n </div>\n\n <div class=\"demo-section\">\n <div class=\"demo-title\">Delayed Permission Check</div>\n <p class=\"demo-description\">Mô phỏng permission check có delay, simulate API call</p>\n <libs_ui-components-audio\n fileAudio=\"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3\"\n [checkPermissionDownloadAudio]=\"delayedPermissionCheck\"\n />\n </div>\n </div>\n `\n})\nexport class LibsUiComponentsAudioDemoComponent {\n /**\n * Permission function luôn allow download\n */\n basicPermissionCheck(): Promise<boolean> {\n return Promise.resolve(true);\n }\n \n /**\n * Permission function không cho phép download\n */\n denyPermissionCheck(): Promise<boolean> {\n return Promise.resolve(false);\n }\n\n /**\n * Permission function có delay để mô phỏng API call\n */\n delayedPermissionCheck(): Promise<boolean> {\n return new Promise(resolve => {\n setTimeout(() => {\n resolve(true);\n }, 1500);\n });\n }\n} ","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from './audio.component';
2
+ export * from './demo.component';
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@libs-ui/components-audio",
3
- "version": "0.2.189",
3
+ "version": "0.2.190",
4
4
  "peerDependencies": {
5
5
  "@angular/core": "^18.2.0",
6
- "@libs-ui/components-inputs-range-slider": "^0.2.189",
6
+ "@libs-ui/components-inputs-range-slider": "^0.2.190",
7
7
  "rxjs": "~7.8.0"
8
8
  },
9
9
  "sideEffects": false,