cloud-ide-layout 1.0.8 → 1.0.9

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.
Files changed (83) hide show
  1. package/README.md +34 -448
  2. package/fesm2022/{cloud-ide-layout-cloud-ide-layout-D3xzVSNA.mjs → cloud-ide-layout-cloud-ide-layout-DLceZY3Y.mjs} +335 -343
  3. package/fesm2022/{cloud-ide-layout-cloud-ide-layout-D3xzVSNA.mjs.map → cloud-ide-layout-cloud-ide-layout-DLceZY3Y.mjs.map} +1 -1
  4. package/fesm2022/{cloud-ide-layout-drawer-theme.component-BSUFE_o2.mjs → cloud-ide-layout-drawer-theme.component-Bn5--C_Q.mjs} +69 -67
  5. package/fesm2022/{cloud-ide-layout-drawer-theme.component-BSUFE_o2.mjs.map → cloud-ide-layout-drawer-theme.component-Bn5--C_Q.mjs.map} +1 -1
  6. package/fesm2022/{cloud-ide-layout-home-wrapper.component-Dr4MO4MB.mjs → cloud-ide-layout-home-wrapper.component-Bo-4LNLx.mjs} +56 -51
  7. package/fesm2022/{cloud-ide-layout-home-wrapper.component-Dr4MO4MB.mjs.map → cloud-ide-layout-home-wrapper.component-Bo-4LNLx.mjs.map} +1 -1
  8. package/fesm2022/{cloud-ide-layout-sidedrawer-notes.component-BWx03JYS.mjs → cloud-ide-layout-sidedrawer-notes.component-BmadMzdl.mjs} +28 -32
  9. package/fesm2022/{cloud-ide-layout-sidedrawer-notes.component-BWx03JYS.mjs.map → cloud-ide-layout-sidedrawer-notes.component-BmadMzdl.mjs.map} +1 -1
  10. package/fesm2022/cloud-ide-layout.mjs +1 -1
  11. package/index.d.ts +579 -3
  12. package/package.json +3 -5
  13. package/esm2022/cloud-ide-layout.mjs +0 -5
  14. package/esm2022/lib/cloud-ide-layout.component.mjs +0 -16
  15. package/esm2022/lib/cloud-ide-layout.routes.mjs +0 -28
  16. package/esm2022/lib/cloud-ide-layout.service.mjs +0 -14
  17. package/esm2022/lib/layout/console/console-wrapper/console-wrapper.component.mjs +0 -11
  18. package/esm2022/lib/layout/console/console.service.mjs +0 -28
  19. package/esm2022/lib/layout/footer/footer-wrapper/footer-wrapper.component.mjs +0 -20
  20. package/esm2022/lib/layout/footer/footer.service.mjs +0 -28
  21. package/esm2022/lib/layout/header/header-wrapper/header-wrapper.component.mjs +0 -84
  22. package/esm2022/lib/layout/header/header.service.mjs +0 -28
  23. package/esm2022/lib/layout/home/home-wrapper/home-wrapper.component.mjs +0 -198
  24. package/esm2022/lib/layout/layout/layout-wrapper/layout-wrapper.component.mjs +0 -28
  25. package/esm2022/lib/layout/request/request-wrapper/request-wrapper.component.mjs +0 -60
  26. package/esm2022/lib/layout/request/request.service.mjs +0 -235
  27. package/esm2022/lib/layout/request/tab-content/tab-content.component.mjs +0 -84
  28. package/esm2022/lib/layout/shared/shared-wrapper/shared-wrapper.component.mjs +0 -49
  29. package/esm2022/lib/layout/shared/shared.service.mjs +0 -508
  30. package/esm2022/lib/layout/sidebar/sidebar-wrapper/sidebar-wrapper.component.mjs +0 -488
  31. package/esm2022/lib/layout/sidebar/sidebar.service.mjs +0 -35
  32. package/esm2022/lib/layout/sidedrawer/cide-lyt-drawer-base.class.mjs +0 -40
  33. package/esm2022/lib/layout/sidedrawer/drawer-theme/drawer-theme.component.mjs +0 -296
  34. package/esm2022/lib/layout/sidedrawer/sidedrawer-notes/sidedrawer-notes.component.mjs +0 -175
  35. package/esm2022/lib/layout/sidedrawer/sidedrawer-notes/sidedrawer-notes.service.mjs +0 -51
  36. package/esm2022/lib/layout/sidedrawer/sidedrawer-wrapper/sidedrawer-wrapper.component.mjs +0 -257
  37. package/esm2022/lib/layout/sidedrawer/sidedrawer.service.mjs +0 -70
  38. package/esm2022/lib/services/app-state/app-state-helper.service.mjs +0 -222
  39. package/esm2022/lib/services/app-state/app-state.service.mjs +0 -256
  40. package/esm2022/lib/services/app-state/index.mjs +0 -3
  41. package/esm2022/lib/services/cache-manager/cache-manager.service.mjs +0 -112
  42. package/esm2022/lib/services/file-manager/file-manager.service.mjs +0 -21
  43. package/esm2022/lib/services/tab-state.service.mjs +0 -128
  44. package/esm2022/lib/services/theme/theme.service.mjs +0 -151
  45. package/esm2022/lib/services/user-status/user-status.service.mjs +0 -135
  46. package/esm2022/lib/utils/custom-route-reuse-strategy.mjs +0 -61
  47. package/esm2022/lib/utils/index.mjs +0 -2
  48. package/esm2022/public-api.mjs +0 -18
  49. package/lib/cloud-ide-layout.component.d.ts +0 -5
  50. package/lib/cloud-ide-layout.routes.d.ts +0 -3
  51. package/lib/cloud-ide-layout.service.d.ts +0 -6
  52. package/lib/layout/console/console-wrapper/console-wrapper.component.d.ts +0 -5
  53. package/lib/layout/console/console.service.d.ts +0 -9
  54. package/lib/layout/footer/footer-wrapper/footer-wrapper.component.d.ts +0 -9
  55. package/lib/layout/footer/footer.service.d.ts +0 -9
  56. package/lib/layout/header/header-wrapper/header-wrapper.component.d.ts +0 -25
  57. package/lib/layout/header/header.service.d.ts +0 -9
  58. package/lib/layout/home/home-wrapper/home-wrapper.component.d.ts +0 -94
  59. package/lib/layout/layout/layout-wrapper/layout-wrapper.component.d.ts +0 -5
  60. package/lib/layout/request/request-wrapper/request-wrapper.component.d.ts +0 -14
  61. package/lib/layout/request/request.service.d.ts +0 -60
  62. package/lib/layout/request/tab-content/tab-content.component.d.ts +0 -19
  63. package/lib/layout/shared/shared-wrapper/shared-wrapper.component.d.ts +0 -17
  64. package/lib/layout/shared/shared.service.d.ts +0 -114
  65. package/lib/layout/sidebar/sidebar-wrapper/sidebar-wrapper.component.d.ts +0 -140
  66. package/lib/layout/sidebar/sidebar.service.d.ts +0 -12
  67. package/lib/layout/sidedrawer/cide-lyt-drawer-base.class.d.ts +0 -16
  68. package/lib/layout/sidedrawer/drawer-theme/drawer-theme.component.d.ts +0 -71
  69. package/lib/layout/sidedrawer/sidedrawer-notes/sidedrawer-notes.component.d.ts +0 -48
  70. package/lib/layout/sidedrawer/sidedrawer-notes/sidedrawer-notes.service.d.ts +0 -13
  71. package/lib/layout/sidedrawer/sidedrawer-wrapper/sidedrawer-wrapper.component.d.ts +0 -30
  72. package/lib/layout/sidedrawer/sidedrawer.service.d.ts +0 -30
  73. package/lib/services/app-state/app-state-helper.service.d.ts +0 -150
  74. package/lib/services/app-state/app-state.service.d.ts +0 -85
  75. package/lib/services/app-state/index.d.ts +0 -3
  76. package/lib/services/cache-manager/cache-manager.service.d.ts +0 -64
  77. package/lib/services/file-manager/file-manager.service.d.ts +0 -9
  78. package/lib/services/tab-state.service.d.ts +0 -79
  79. package/lib/services/theme/theme.service.d.ts +0 -71
  80. package/lib/services/user-status/user-status.service.d.ts +0 -57
  81. package/lib/utils/custom-route-reuse-strategy.d.ts +0 -15
  82. package/lib/utils/index.d.ts +0 -1
  83. package/public-api.d.ts +0 -12
@@ -1,35 +0,0 @@
1
- import { HttpClient } from '@angular/common/http';
2
- import { Injectable, inject } from '@angular/core';
3
- import { cidePath, coreRoutesUrl, hostManagerRoutesUrl } from 'cloud-ide-lms-model';
4
- import * as i0 from "@angular/core";
5
- export class CideLytSidebarService {
6
- constructor() {
7
- this.sidebarMenueVisible = false;
8
- this.http = inject(HttpClient);
9
- }
10
- // method to get sidebar menues
11
- getSidebarMenues(body) {
12
- return this.http?.post(cidePath?.join([hostManagerRoutesUrl?.cideSuiteHost, coreRoutesUrl?.module, coreRoutesUrl?.getSidebarMenues]), body);
13
- }
14
- // Hide Sidebar
15
- hideSidebar() {
16
- this.sidebarMenueVisible = false;
17
- document.querySelector(`#cide-lyt-sidebar-page`)?.classList.add('cide-lyt-sidebar-page-hide');
18
- document.querySelector(`body`)?.classList.remove('cide-lyt-sidebar-exist');
19
- }
20
- // Show Sidebar
21
- showSidebar() {
22
- this.sidebarMenueVisible = true;
23
- document.querySelector(`#cide-lyt-sidebar-page`)?.classList.remove('cide-lyt-sidebar-page-hide');
24
- document.querySelector(`body`)?.classList.add('cide-lyt-sidebar-exist');
25
- }
26
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideLytSidebarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
27
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideLytSidebarService, providedIn: 'root' }); }
28
- }
29
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideLytSidebarService, decorators: [{
30
- type: Injectable,
31
- args: [{
32
- providedIn: 'root'
33
- }]
34
- }] });
35
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lkZWJhci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xvdWQtaWRlLWxheW91dC9zcmMvbGliL2xheW91dC9zaWRlYmFyL3NpZGViYXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsb0JBQW9CLEVBQWlDLE1BQU0scUJBQXFCLENBQUM7O0FBTW5ILE1BQU0sT0FBTyxxQkFBcUI7SUFIbEM7UUFJUyx3QkFBbUIsR0FBWSxLQUFLLENBQUM7UUFDcEMsU0FBSSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztLQW9CbkM7SUFsQkMsK0JBQStCO0lBQy9CLGdCQUFnQixDQUFDLElBQVc7UUFDMUIsT0FBTyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUMsb0JBQW9CLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLGdCQUFnQixDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM5SSxDQUFDO0lBRUQsZUFBZTtJQUNmLFdBQVc7UUFDVCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDO1FBQ2pDLFFBQVEsQ0FBQyxhQUFhLENBQUMsd0JBQXdCLENBQUMsRUFBRSxTQUFTLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFDOUYsUUFBUSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDN0UsQ0FBQztJQUVELGVBQWU7SUFDZixXQUFXO1FBQ1QsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQztRQUNoQyxRQUFRLENBQUMsYUFBYSxDQUFDLHdCQUF3QixDQUFDLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO1FBQ2pHLFFBQVEsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsU0FBUyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQzFFLENBQUM7OEdBckJVLHFCQUFxQjtrSEFBckIscUJBQXFCLGNBRnBCLE1BQU07OzJGQUVQLHFCQUFxQjtrQkFIakMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBjaWRlUGF0aCwgY29yZVJvdXRlc1VybCwgaG9zdE1hbmFnZXJSb3V0ZXNVcmwsIG1lbnVDb250cm9sbGVyUmVzcG9uc2UsIE1NZW51IH0gZnJvbSAnY2xvdWQtaWRlLWxtcy1tb2RlbCc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIENpZGVMeXRTaWRlYmFyU2VydmljZSB7XG4gIHB1YmxpYyBzaWRlYmFyTWVudWVWaXNpYmxlOiBib29sZWFuID0gZmFsc2U7XG4gIHByaXZhdGUgaHR0cCA9IGluamVjdChIdHRwQ2xpZW50KTtcblxuICAvLyBtZXRob2QgdG8gZ2V0IHNpZGViYXIgbWVudWVzXG4gIGdldFNpZGViYXJNZW51ZXMoYm9keTogTU1lbnUpOiBPYnNlcnZhYmxlPG1lbnVDb250cm9sbGVyUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwPy5wb3N0KGNpZGVQYXRoPy5qb2luKFtob3N0TWFuYWdlclJvdXRlc1VybD8uY2lkZVN1aXRlSG9zdCwgY29yZVJvdXRlc1VybD8ubW9kdWxlLCBjb3JlUm91dGVzVXJsPy5nZXRTaWRlYmFyTWVudWVzXSksIGJvZHkpO1xuICB9XG5cbiAgLy8gSGlkZSBTaWRlYmFyXG4gIGhpZGVTaWRlYmFyKCkge1xuICAgIHRoaXMuc2lkZWJhck1lbnVlVmlzaWJsZSA9IGZhbHNlO1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYCNjaWRlLWx5dC1zaWRlYmFyLXBhZ2VgKT8uY2xhc3NMaXN0LmFkZCgnY2lkZS1seXQtc2lkZWJhci1wYWdlLWhpZGUnKTtcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBib2R5YCk/LmNsYXNzTGlzdC5yZW1vdmUoJ2NpZGUtbHl0LXNpZGViYXItZXhpc3QnKTtcbiAgfVxuXG4gIC8vIFNob3cgU2lkZWJhclxuICBzaG93U2lkZWJhcigpIHtcbiAgICB0aGlzLnNpZGViYXJNZW51ZVZpc2libGUgPSB0cnVlO1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYCNjaWRlLWx5dC1zaWRlYmFyLXBhZ2VgKT8uY2xhc3NMaXN0LnJlbW92ZSgnY2lkZS1seXQtc2lkZWJhci1wYWdlLWhpZGUnKTtcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBib2R5YCk/LmNsYXNzTGlzdC5hZGQoJ2NpZGUtbHl0LXNpZGViYXItZXhpc3QnKTtcbiAgfVxufVxuXG4vLyNmZjU3MDBcbiJdfQ==
@@ -1,40 +0,0 @@
1
- import { Directive, inject } from '@angular/core';
2
- import { CideLytSidedrawerService } from './sidedrawer.service';
3
- import * as i0 from "@angular/core";
4
- export class CideLytDrawerBase {
5
- constructor() {
6
- this._pageId = null;
7
- this._themeId = null;
8
- this.sidedrawerService = inject(CideLytSidedrawerService);
9
- }
10
- ngOnInit() {
11
- // Automatically initialize context from the service
12
- const pageId = this.sidedrawerService.pageId;
13
- const themeId = this.sidedrawerService.themeId;
14
- if (pageId && themeId) {
15
- this.setContext(pageId, themeId);
16
- }
17
- this.afterContextInit();
18
- }
19
- // Child classes can override this for additional setup
20
- afterContextInit() { }
21
- setContext(pageId, themeId) {
22
- this._pageId = pageId;
23
- this._themeId = themeId;
24
- }
25
- get pageId() {
26
- return this._pageId;
27
- }
28
- get themeId() {
29
- return this._themeId;
30
- }
31
- getStorageKey(suffix) {
32
- return `drawer_${suffix}_${this._pageId || 'unknown'}`;
33
- }
34
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideLytDrawerBase, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
35
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.7", type: CideLytDrawerBase, ngImport: i0 }); }
36
- }
37
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideLytDrawerBase, decorators: [{
38
- type: Directive
39
- }] });
40
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2lkZS1seXQtZHJhd2VyLWJhc2UuY2xhc3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jbG91ZC1pZGUtbGF5b3V0L3NyYy9saWIvbGF5b3V0L3NpZGVkcmF3ZXIvY2lkZS1seXQtZHJhd2VyLWJhc2UuY2xhc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDMUQsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sc0JBQXNCLENBQUM7O0FBR2hFLE1BQU0sT0FBZ0IsaUJBQWlCO0lBRHZDO1FBRVUsWUFBTyxHQUFrQixJQUFJLENBQUM7UUFDOUIsYUFBUSxHQUFrQixJQUFJLENBQUM7UUFDN0Isc0JBQWlCLEdBQUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7S0ErQmhFO0lBN0JDLFFBQVE7UUFDTixvREFBb0Q7UUFDcEQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQztRQUM3QyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDO1FBQy9DLElBQUksTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ25DLENBQUM7UUFDRCxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsdURBQXVEO0lBQzdDLGdCQUFnQixLQUFVLENBQUM7SUFFckMsVUFBVSxDQUFDLE1BQWMsRUFBRSxPQUFlO1FBQ3hDLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO0lBQzFCLENBQUM7SUFFRCxJQUFJLE1BQU07UUFDUixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDdEIsQ0FBQztJQUVELElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBRVMsYUFBYSxDQUFDLE1BQWM7UUFDcEMsT0FBTyxVQUFVLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLFNBQVMsRUFBRSxDQUFDO0lBQ3pELENBQUM7OEdBakNtQixpQkFBaUI7a0dBQWpCLGlCQUFpQjs7MkZBQWpCLGlCQUFpQjtrQkFEdEMsU0FBUyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgT25Jbml0LCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENpZGVMeXRTaWRlZHJhd2VyU2VydmljZSB9IGZyb20gJy4vc2lkZWRyYXdlci5zZXJ2aWNlJztcblxuQERpcmVjdGl2ZSgpXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQ2lkZUx5dERyYXdlckJhc2UgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIF9wYWdlSWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF90aGVtZUlkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJvdGVjdGVkIHNpZGVkcmF3ZXJTZXJ2aWNlID0gaW5qZWN0KENpZGVMeXRTaWRlZHJhd2VyU2VydmljZSk7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgLy8gQXV0b21hdGljYWxseSBpbml0aWFsaXplIGNvbnRleHQgZnJvbSB0aGUgc2VydmljZVxuICAgIGNvbnN0IHBhZ2VJZCA9IHRoaXMuc2lkZWRyYXdlclNlcnZpY2UucGFnZUlkO1xuICAgIGNvbnN0IHRoZW1lSWQgPSB0aGlzLnNpZGVkcmF3ZXJTZXJ2aWNlLnRoZW1lSWQ7XG4gICAgaWYgKHBhZ2VJZCAmJiB0aGVtZUlkKSB7XG4gICAgICB0aGlzLnNldENvbnRleHQocGFnZUlkLCB0aGVtZUlkKTtcbiAgICB9XG4gICAgdGhpcy5hZnRlckNvbnRleHRJbml0KCk7XG4gIH1cblxuICAvLyBDaGlsZCBjbGFzc2VzIGNhbiBvdmVycmlkZSB0aGlzIGZvciBhZGRpdGlvbmFsIHNldHVwXG4gIHByb3RlY3RlZCBhZnRlckNvbnRleHRJbml0KCk6IHZvaWQge31cblxuICBzZXRDb250ZXh0KHBhZ2VJZDogc3RyaW5nLCB0aGVtZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9wYWdlSWQgPSBwYWdlSWQ7XG4gICAgdGhpcy5fdGhlbWVJZCA9IHRoZW1lSWQ7XG4gIH1cblxuICBnZXQgcGFnZUlkKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9wYWdlSWQ7XG4gIH1cblxuICBnZXQgdGhlbWVJZCgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fdGhlbWVJZDtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRTdG9yYWdlS2V5KHN1ZmZpeDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYGRyYXdlcl8ke3N1ZmZpeH1fJHt0aGlzLl9wYWdlSWQgfHwgJ3Vua25vd24nfWA7XG4gIH1cbn0gIl19
@@ -1,296 +0,0 @@
1
- import { NgFor, NgIf } from '@angular/common';
2
- import { NgClass } from '@angular/common';
3
- import { Component, PLATFORM_ID, Inject, inject } from '@angular/core';
4
- import { FormsModule } from '@angular/forms';
5
- import { CideSelectComponent, CideEleButtonComponent } from 'cloud-ide-element';
6
- import { setCSSVariable } from '../../../services/theme/theme.service';
7
- import { isEqual, cloneDeep } from 'lodash';
8
- import _ from 'lodash';
9
- import { AppStateHelperService } from '../../../services/app-state';
10
- import * as i0 from "@angular/core";
11
- import * as i1 from "../../../services/theme/theme.service";
12
- import * as i2 from "@angular/forms";
13
- export class CideLytDrawerThemeComponent {
14
- constructor(themeService, platformId) {
15
- this.themeService = themeService;
16
- this.platformId = platformId;
17
- this.appState = inject(AppStateHelperService);
18
- // Preset themes
19
- this.presetThemes = [];
20
- this.selectedTheme = '';
21
- this.isLoadingThemes = false;
22
- this.themeLoadError = '';
23
- this.mergedTheme = {};
24
- this.isRTL = false;
25
- this.originalThemeGroupValues = [];
26
- this.originalApiThemeValues = {}; // Store original API values
27
- this.themeGroups = [
28
- {
29
- label: 'Brand Colors',
30
- items: [
31
- { label: 'Primary', varName: '--cide-theme-color-brand-primary', value: '#4f46e5', type: 'text' },
32
- { label: 'Accent', varName: '--cide-theme-color-brand-accent', value: '#4338ca', type: 'text' },
33
- { label: 'Separator', varName: '--cide-theme-color-brand-separator', value: '#e5e7eb', type: 'text' }
34
- ]
35
- },
36
- {
37
- label: 'Text Colors',
38
- items: [
39
- { label: 'Body Text', varName: '--cide-theme-color-text-body', value: '#374151', type: 'text' },
40
- { label: 'Heading Text', varName: '--cide-theme-color-text-heading', value: '#111827', type: 'text' },
41
- { label: 'Link Text', varName: '--cide-theme-color-text-link', value: '#3b82f6', type: 'text' },
42
- { label: 'Muted Text', varName: '--cide-theme-color-text-muted', value: '#6b7280', type: 'text' }
43
- ]
44
- },
45
- {
46
- label: 'Background Colors',
47
- items: [
48
- { label: 'Body Background', varName: '--cide-theme-color-background-body', value: '#ffffff', type: 'text' }
49
- ]
50
- },
51
- {
52
- label: 'Layout Dimensions',
53
- items: [
54
- { label: 'Stack Wrapper Width', varName: '--cide-lyt-stack-wrapper-width', value: '60', type: 'number', min: 20, max: 120 }
55
- ]
56
- },
57
- {
58
- label: 'Font Sizes',
59
- items: [
60
- { label: 'XXXL Font Size', varName: '--cide-theme-font-size-xxxl', value: '3.052', type: 'number', min: 1, max: 10 },
61
- { label: 'XXL Font Size', varName: '--cide-theme-font-size-xxl', value: '2.441', type: 'number', min: 1, max: 10 },
62
- { label: 'XL Font Size', varName: '--cide-theme-font-size-xl', value: '1.953', type: 'number', min: 1, max: 10 },
63
- { label: 'LG Font Size', varName: '--cide-theme-font-size-lg', value: '1.563', type: 'number', min: 1, max: 10 },
64
- { label: 'MD Font Size', varName: '--cide-theme-font-size-md', value: '1.25', type: 'number', min: 1, max: 10 },
65
- { label: 'Paragraph Font Size', varName: '--cide-theme-font-size-p', value: '1', type: 'number', min: 0.5, max: 5 },
66
- { label: 'SM Font Size', varName: '--cide-theme-font-size-sm', value: '0.9', type: 'number', min: 0.5, max: 5 },
67
- { label: 'XS Font Size', varName: '--cide-theme-font-size-xs', value: '0.8', type: 'number', min: 0.5, max: 5 }
68
- ]
69
- },
70
- {
71
- label: 'Line Heights',
72
- items: [
73
- { label: 'Body Line Height', varName: '--cide-theme-line-height-body', value: '1.6', type: 'number', min: 1, max: 3 },
74
- { label: 'Heading Line Height', varName: '--cide-theme-line-height-heading', value: '1.2', type: 'number', min: 1, max: 3 }
75
- ]
76
- }
77
- ];
78
- }
79
- ngOnInit() {
80
- // Modern Angular v20 pattern: Use Signals directly
81
- this.selectedTheme = this.themeService.selectedTheme();
82
- // fetch the system themes list
83
- this.isLoadingThemes = true;
84
- this.themeService.fetchSystemThemesList().subscribe({
85
- next: (res) => {
86
- const themes = res?.data?.core_system_themes || [];
87
- this.presetThemes = themes.map((theme) => ({
88
- value: theme._id || '',
89
- label: theme.syth_theme_name || theme.syth_theme_id || '',
90
- theme
91
- }));
92
- this.isLoadingThemes = false;
93
- // If user has no theme set, select and apply the default theme
94
- if (!this.selectedTheme) {
95
- const defaultTheme = this.presetThemes.find(t => t.theme.syth_is_default);
96
- if (defaultTheme) {
97
- this.selectedTheme = defaultTheme.value;
98
- // Apply the default theme as CSS variables
99
- if (defaultTheme.theme.syth_properties) {
100
- Object.entries(defaultTheme.theme.syth_properties).forEach(([varName, value]) => {
101
- this.updateVar(varName, value);
102
- });
103
- }
104
- }
105
- }
106
- },
107
- error: () => {
108
- this.themeLoadError = 'Failed to load themes';
109
- this.isLoadingThemes = false;
110
- }
111
- });
112
- this.loadAndApplyUserTheme();
113
- }
114
- loadAndApplyUserTheme() {
115
- this.themeService.loadTheme().subscribe({
116
- next: (res) => {
117
- const base = res?.data?.core_system_themes;
118
- const org = res?.data?.core_system_organization_themes;
119
- const user = res?.data?.core_system_theme_user_preferences;
120
- // Start with base theme properties
121
- let merged = { ...(base?.syth_properties || {}) };
122
- // Override with org overrides
123
- if (org?.syoth_overrides) {
124
- merged = { ...merged, ...org.syoth_overrides };
125
- }
126
- // Override with user overrides
127
- if (user?.syupth_overrides) {
128
- merged = { ...merged, ...user.syupth_overrides };
129
- }
130
- this.mergedTheme = merged;
131
- // Store original API values for reset functionality
132
- this.originalApiThemeValues = { ...merged };
133
- // Apply merged theme as CSS variables
134
- Object.entries(this.mergedTheme).forEach(([varName, value]) => {
135
- this.updateVar(varName, value);
136
- });
137
- for (const group of this.themeGroups) {
138
- for (const item of group.items) {
139
- const key = item.varName.replace(/-/g, '_');
140
- item.value = merged[item.varName] || merged[key] || item.value;
141
- if (key.includes('font_size') || key.includes('line_height')) {
142
- item.value = parseFloat(item.value);
143
- }
144
- }
145
- }
146
- // Store a deep copy of the current values for reset
147
- this.originalThemeGroupValues = cloneDeep(this.themeGroups);
148
- },
149
- error: () => {
150
- // handle error if needed
151
- }
152
- });
153
- }
154
- // Update CSS variable in real time
155
- updateVar(varName, value) {
156
- // You can use either the utility function directly or the service method
157
- setCSSVariable(varName, value, this.platformId);
158
- // Alternative: this.themeService.updateCSSVariable(varName, value);
159
- }
160
- onThemeChange(event) {
161
- this.selectedTheme = event.value;
162
- const selected = this.presetThemes.find(t => t.value === this.selectedTheme);
163
- if (selected && selected.theme && selected.theme.syth_properties) {
164
- // here we will check the theme selected by organization is same if yes then overide also for user preferences
165
- if (this.themeService.selectedTheme() === selected.theme._id) {
166
- this.loadAndApplyUserTheme();
167
- }
168
- else {
169
- // Store original API values for the selected theme
170
- this.originalApiThemeValues = _.cloneDeep(selected.theme.syth_properties);
171
- // Update all group values from the selected theme
172
- for (const group of this.themeGroups) {
173
- for (const item of group.items) {
174
- const key = item.varName.replace(/-/g, '_');
175
- item.value = selected.theme.syth_properties[item.varName] ||
176
- selected.theme.syth_properties[key] ||
177
- item.value;
178
- this.updateVar(item.varName, item.value);
179
- if (key.includes('font_size') || key.includes('line_height')) {
180
- item.value = parseFloat(item.value);
181
- }
182
- }
183
- }
184
- // Store a deep copy of the current values for reset
185
- this.originalThemeGroupValues = cloneDeep(this.themeGroups);
186
- }
187
- }
188
- }
189
- onReset() {
190
- // Restore all values from the original API values
191
- for (const group of this.themeGroups) {
192
- for (const item of group.items) {
193
- const key = item.varName.replace(/-/g, '_');
194
- // Get the original API value
195
- const originalValue = this.originalApiThemeValues[item.varName] ||
196
- this.originalApiThemeValues[key] ||
197
- item.value;
198
- // Update the item value
199
- item.value = originalValue;
200
- // Apply the CSS variable
201
- this.updateVar(item.varName, item.value);
202
- if (key.includes('font_size') || key.includes('line_height')) {
203
- item.value = parseFloat(item.value);
204
- }
205
- }
206
- }
207
- // Update the originalThemeGroupValues to reflect the reset state
208
- this.originalThemeGroupValues = cloneDeep(this.themeGroups);
209
- }
210
- onSave() {
211
- // Collect all current values
212
- const themeVars = {};
213
- for (const group of this.themeGroups) {
214
- for (const item of group.items) {
215
- themeVars[item.varName?.replaceAll('-', '_')] = item.value;
216
- }
217
- }
218
- const systemThemePreferences = {
219
- syupth_overrides: {
220
- ...themeVars
221
- },
222
- syupth_system_theme_id_syth: this.selectedTheme, // LATER: need to upadate LATER
223
- syupth_user_id_user: this.appState.currentUser()?._id || '', // LATER: need to get user id from user
224
- syupth_entity_id_syen: this.appState.getActiveEntityId() || '', // LATER: need to get entity id from user
225
- syth_theme_id: "" // need to upadate LATER
226
- };
227
- // TODO: Send themeVars to backend or emit event by designConfigRoutesUrl?.systemThemeUserPreferences
228
- this.themeService.saveSystemThemeUserPreferences(systemThemePreferences).subscribe({
229
- next: (res) => {
230
- console.log('Theme saved:', res);
231
- // Modern Angular v20 pattern: Update Signal through service method
232
- // Note: The theme service should provide a method to update the selected theme
233
- // For now, we'll just log the change since the service doesn't expose a setter
234
- console.log('Theme selected:', this.selectedTheme);
235
- },
236
- error: (error) => {
237
- console.error('Error saving theme:', error);
238
- }
239
- });
240
- }
241
- hasUnsavedChanges() {
242
- // chec selected theme is different
243
- if (this.themeService.selectedTheme() !== this.selectedTheme) {
244
- return true;
245
- }
246
- // check the theme groups are different
247
- return !isEqual(this.themeGroups, this.originalThemeGroupValues);
248
- }
249
- /**
250
- * Check if current values differ from the original API values
251
- * This is useful for determining if reset should be enabled
252
- */
253
- hasChangesFromOriginal() {
254
- for (const group of this.themeGroups) {
255
- for (const item of group.items) {
256
- const key = item.varName.replace(/-/g, '_');
257
- const originalValue = this.originalApiThemeValues[item.varName] ||
258
- this.originalApiThemeValues[key];
259
- if (originalValue !== undefined && item.value !== originalValue) {
260
- return true;
261
- }
262
- }
263
- }
264
- return false;
265
- }
266
- onColorChange(event, color) {
267
- const input = event.target;
268
- color.value = input.value;
269
- this.updateVar(color.varName, color.value);
270
- }
271
- onTypographyChange(event, setting) {
272
- const input = event.target;
273
- setting.value = input.value;
274
- this.updateVar(setting.varName, setting.type === 'number' ? setting.value : setting.value);
275
- }
276
- onLayoutChange(event, setting) {
277
- const input = event.target;
278
- setting.value = input.value;
279
- // For layout dimensions, append 'px' unit to the value
280
- this.updateVar(setting.varName, setting.value + 'px');
281
- }
282
- onDirectionToggle(event) {
283
- this.isRTL = event.target.checked;
284
- document.documentElement.dir = this.isRTL ? 'rtl' : 'ltr';
285
- }
286
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideLytDrawerThemeComponent, deps: [{ token: i1.CideLytThemeService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component }); }
287
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: CideLytDrawerThemeComponent, isStandalone: true, selector: "cide-lyt-drawer-theme", ngImport: i0, template: "<div class=\"tw-relative tw-h-full tw-bg-white tw-overflow-hidden tw-flex tw-flex-col\">\n <!-- STICKY HEADER SECTION -->\n <div class=\"tw-bg-white tw-sticky tw-top-0 tw-border-b tw-border-gray-200 tw-z-10 tw-flex-shrink-0\">\n <!-- DYNAMIC HEADING -->\n <div class=\"tw-flex tw-justify-between tw-items-center tw-p-2 tw-bg-white tw-border-b tw-border-gray-200\">\n <h6 class=\"tw-font-semibold tw-text-gray-800\">Preset Theme</h6>\n </div>\n </div>\n\n <!-- SCROLLABLE CONTENT AREA -->\n <div class=\"tw-flex-1 tw-overflow-y-auto tw-scroll-smooth tw-p-2 tw-flex tw-flex-col tw-gap-5 tw-text-sm tw-pb-3 theme-scroll-container\">\n <!-- Preset Theme -->\n <section>\n <cide-ele-select id=\"theme-selector\" [(ngModel)]=\"selectedTheme\" (change)=\"onThemeChange($event)\"\n [options]=\"presetThemes\" [size]=\"'sm'\"></cide-ele-select>\n </section>\n\n <!-- Direction Toggle -->\n <section>\n <div class=\"tw-flex tw-justify-between tw-items-center tw-mb-2\">\n <h2 class=\"tw-text-md tw-font-semibold tw-text-gray-800\">Text Direction</h2>\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <span class=\"tw-text-xs tw-text-gray-500\">LTR</span>\n <label for=\"direction-toggle\" class=\"tw-relative tw-inline-block tw-w-9 tw-h-5\">\n <input type=\"checkbox\" id=\"direction-toggle\" class=\"tw-opacity-0 tw-w-0 tw-h-0\" [(ngModel)]=\"isRTL\"\n (change)=\"onDirectionToggle($event)\">\n <span\n class=\"tw-absolute tw-cursor-pointer tw-top-0 tw-left-0 tw-right-0 tw-bottom-0 tw-bg-gray-300 tw-rounded-full tw-transition-colors checked:tw-bg-blue-500 before:tw-absolute before:tw-content-[''] before:tw-h-4 before:tw-w-4 before:tw-left-0.5 before:tw-bottom-0.5 before:tw-bg-white before:tw-rounded-full before:tw-transition-transform checked:before:tw-translate-x-4\"></span>\n </label>\n <span class=\"tw-text-xs tw-text-gray-500\">RTL</span>\n </div>\n </div>\n </section>\n\n <!-- Theme Property Groups (Brand, Text, Background, Font Sizes, Line Heights) -->\n <section *ngFor=\"let group of themeGroups\" class=\"theme-section\">\n <h2 class=\"tw-text-md tw-font-semibold tw-mb-2 tw-text-gray-800\">{{ group.label }}</h2>\n <div class=\"tw-grid tw-grid-cols-2 tw-gap-2 tw-gap-x-4\">\n <div *ngFor=\"let item of group.items\"\n class=\"tw-flex tw-items-center tw-gap-2 tw-p-1 tw-rounded-lg tw-bg-gray-50\"\n [ngClass]=\"{'tw-flex-col tw-items-stretch': (group.label === 'Font Sizes' || group.label === 'Line Heights' || group.label === 'Layout Dimensions')}\">\n <!-- Font Sizes: label on top, input in middle, unit at bottom -->\n <ng-container *ngIf=\"group.label === 'Font Sizes'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"0.001\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">rem</span>\n </div>\n </ng-container>\n <!-- Line Heights: label on top, input and unit on same line -->\n <ng-container *ngIf=\"group.label === 'Line Heights'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"0.1\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">unitless</span>\n </div>\n </ng-container>\n <!-- Layout Dimensions: label on top, input in middle, px unit at bottom -->\n <ng-container *ngIf=\"group.label === 'Layout Dimensions'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"1\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onLayoutChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">px</span>\n </div>\n </ng-container>\n <!-- Other groups: keep previous layout -->\n <ng-container *ngIf=\"group.label !== 'Font Sizes' && group.label !== 'Line Heights' && group.label !== 'Layout Dimensions'\">\n <!-- Color input for color variables -->\n <ng-container *ngIf=\"item.varName.includes('color')\">\n <input [id]=\"item.varName\" [attr.data-variable]=\"item.varName\" type=\"color\" [(ngModel)]=\"item.value\"\n (input)=\"onColorChange($event, item)\"\n class=\"tw-appearance-none tw-border-2 tw-border-gray-200 tw-rounded tw-w-8 tw-h-8 tw-p-0 tw-bg-none tw-shadow-none tw-cursor-pointer tw-transition-colors focus:tw-border-blue-500 color-input\">\n </ng-container>\n <!-- Number input for line heights -->\n <ng-container\n *ngIf=\"!item.varName.includes('color') && item.type === 'number' && group.label !== 'Font Sizes'\">\n <input [id]=\"item.varName\" type=\"number\" [step]=\"item.varName.includes('line-height') ? 0.1 : 0.001\"\n [min]=\"item.min ?? null\" [max]=\"item.max ?? null\" [(ngModel)]=\"item.value\"\n (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-16 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\" *ngIf=\"!item.varName.includes('line-height')\">rem</span>\n </ng-container>\n <!-- Text input fallback (if needed) -->\n <ng-container *ngIf=\"!item.varName.includes('color') && item.type !== 'number'\">\n <input [id]=\"item.varName\" type=\"text\" [(ngModel)]=\"item.value\" (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-24 tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n </ng-container>\n <div class=\"tw-flex tw-flex-col tw-gap-0.5\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700\">{{ item.label }}</label>\n <span class=\"tw-text-xs tw-text-gray-500 tw-font-mono\">{{ item.value }}</span>\n </div>\n </ng-container>\n </div>\n </div>\n </section>\n </div>\n\n <!-- STICKY ACTION BUTTONS SECTION -->\n <div class=\"tw-bg-white tw-sticky tw-bottom-0 tw-border-t tw-border-gray-200 tw-z-10 tw-flex-shrink-0 tw-p-3 tw-shadow-lg sticky-action-buttons\">\n <div class=\"tw-flex tw-gap-2 tw-justify-end\">\n <button cideEleButton \n variant=\"outline\" \n size=\"sm\" \n (btnClick)=\"onReset()\" \n [disabled]=\"!hasChangesFromOriginal()\"\n class=\"tw-transition-all tw-duration-200 hover:tw-scale-105 action-button\">\n Reset to Original\n </button>\n <button cideEleButton \n variant=\"primary\" \n size=\"sm\" \n (btnClick)=\"onSave()\" \n [disabled]=\"!hasUnsavedChanges()\"\n class=\"tw-transition-all tw-duration-200 hover:tw-scale-105 action-button\">\n Save Changes\n </button>\n </div>\n </div>\n</div>", styles: [".theme-scroll-container{scroll-behavior:smooth;-webkit-overflow-scrolling:touch}.theme-scroll-container::-webkit-scrollbar{width:6px}.theme-scroll-container::-webkit-scrollbar-track{background:#f8fafc;border-radius:3px}.theme-scroll-container::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px;transition:background-color .2s ease}.theme-scroll-container::-webkit-scrollbar-thumb:hover{background:#94a3b8}.sticky-action-buttons{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background-color:#fffffff2;border-top:1px solid #e2e8f0;box-shadow:0 -4px 6px -1px #0000001a}.action-button{transition:all .2s ease-in-out}.action-button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 8px #00000026}.action-button:active:not(:disabled){transform:translateY(0)}.action-button:disabled{opacity:.5;cursor:not-allowed;transform:none!important;box-shadow:none!important}.theme-input:focus{transform:scale(1.02);transition:transform .2s ease-in-out}.color-input{transition:all .2s ease-in-out}.color-input:hover{transform:scale(1.1);box-shadow:0 4px 8px #0003}.theme-section{transition:all .3s ease-in-out}.theme-section:hover{background-color:#f8fafc;border-radius:8px;padding:8px;margin:-8px}@media (max-width: 640px){.sticky-action-buttons{padding:12px}.action-button{font-size:14px;padding:8px 12px}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i2.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: CideSelectComponent, selector: "cide-ele-select", inputs: ["label", "labelHide", "placeholder", "helperText", "errorText", "required", "disabled", "id", "ngModel", "size", "fill", "labelPlacement", "labelDir", "leadingIcon", "trailingIcon", "clearInput", "options", "multiple", "searchable", "showSearchInput", "loading"], outputs: ["ngModelChange", "change", "searchChange"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton]", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }] }); }
288
- }
289
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideLytDrawerThemeComponent, decorators: [{
290
- type: Component,
291
- args: [{ selector: 'cide-lyt-drawer-theme', standalone: true, imports: [FormsModule, NgFor, NgIf, NgClass, CideSelectComponent, CideEleButtonComponent], template: "<div class=\"tw-relative tw-h-full tw-bg-white tw-overflow-hidden tw-flex tw-flex-col\">\n <!-- STICKY HEADER SECTION -->\n <div class=\"tw-bg-white tw-sticky tw-top-0 tw-border-b tw-border-gray-200 tw-z-10 tw-flex-shrink-0\">\n <!-- DYNAMIC HEADING -->\n <div class=\"tw-flex tw-justify-between tw-items-center tw-p-2 tw-bg-white tw-border-b tw-border-gray-200\">\n <h6 class=\"tw-font-semibold tw-text-gray-800\">Preset Theme</h6>\n </div>\n </div>\n\n <!-- SCROLLABLE CONTENT AREA -->\n <div class=\"tw-flex-1 tw-overflow-y-auto tw-scroll-smooth tw-p-2 tw-flex tw-flex-col tw-gap-5 tw-text-sm tw-pb-3 theme-scroll-container\">\n <!-- Preset Theme -->\n <section>\n <cide-ele-select id=\"theme-selector\" [(ngModel)]=\"selectedTheme\" (change)=\"onThemeChange($event)\"\n [options]=\"presetThemes\" [size]=\"'sm'\"></cide-ele-select>\n </section>\n\n <!-- Direction Toggle -->\n <section>\n <div class=\"tw-flex tw-justify-between tw-items-center tw-mb-2\">\n <h2 class=\"tw-text-md tw-font-semibold tw-text-gray-800\">Text Direction</h2>\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <span class=\"tw-text-xs tw-text-gray-500\">LTR</span>\n <label for=\"direction-toggle\" class=\"tw-relative tw-inline-block tw-w-9 tw-h-5\">\n <input type=\"checkbox\" id=\"direction-toggle\" class=\"tw-opacity-0 tw-w-0 tw-h-0\" [(ngModel)]=\"isRTL\"\n (change)=\"onDirectionToggle($event)\">\n <span\n class=\"tw-absolute tw-cursor-pointer tw-top-0 tw-left-0 tw-right-0 tw-bottom-0 tw-bg-gray-300 tw-rounded-full tw-transition-colors checked:tw-bg-blue-500 before:tw-absolute before:tw-content-[''] before:tw-h-4 before:tw-w-4 before:tw-left-0.5 before:tw-bottom-0.5 before:tw-bg-white before:tw-rounded-full before:tw-transition-transform checked:before:tw-translate-x-4\"></span>\n </label>\n <span class=\"tw-text-xs tw-text-gray-500\">RTL</span>\n </div>\n </div>\n </section>\n\n <!-- Theme Property Groups (Brand, Text, Background, Font Sizes, Line Heights) -->\n <section *ngFor=\"let group of themeGroups\" class=\"theme-section\">\n <h2 class=\"tw-text-md tw-font-semibold tw-mb-2 tw-text-gray-800\">{{ group.label }}</h2>\n <div class=\"tw-grid tw-grid-cols-2 tw-gap-2 tw-gap-x-4\">\n <div *ngFor=\"let item of group.items\"\n class=\"tw-flex tw-items-center tw-gap-2 tw-p-1 tw-rounded-lg tw-bg-gray-50\"\n [ngClass]=\"{'tw-flex-col tw-items-stretch': (group.label === 'Font Sizes' || group.label === 'Line Heights' || group.label === 'Layout Dimensions')}\">\n <!-- Font Sizes: label on top, input in middle, unit at bottom -->\n <ng-container *ngIf=\"group.label === 'Font Sizes'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"0.001\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">rem</span>\n </div>\n </ng-container>\n <!-- Line Heights: label on top, input and unit on same line -->\n <ng-container *ngIf=\"group.label === 'Line Heights'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"0.1\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">unitless</span>\n </div>\n </ng-container>\n <!-- Layout Dimensions: label on top, input in middle, px unit at bottom -->\n <ng-container *ngIf=\"group.label === 'Layout Dimensions'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"1\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onLayoutChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">px</span>\n </div>\n </ng-container>\n <!-- Other groups: keep previous layout -->\n <ng-container *ngIf=\"group.label !== 'Font Sizes' && group.label !== 'Line Heights' && group.label !== 'Layout Dimensions'\">\n <!-- Color input for color variables -->\n <ng-container *ngIf=\"item.varName.includes('color')\">\n <input [id]=\"item.varName\" [attr.data-variable]=\"item.varName\" type=\"color\" [(ngModel)]=\"item.value\"\n (input)=\"onColorChange($event, item)\"\n class=\"tw-appearance-none tw-border-2 tw-border-gray-200 tw-rounded tw-w-8 tw-h-8 tw-p-0 tw-bg-none tw-shadow-none tw-cursor-pointer tw-transition-colors focus:tw-border-blue-500 color-input\">\n </ng-container>\n <!-- Number input for line heights -->\n <ng-container\n *ngIf=\"!item.varName.includes('color') && item.type === 'number' && group.label !== 'Font Sizes'\">\n <input [id]=\"item.varName\" type=\"number\" [step]=\"item.varName.includes('line-height') ? 0.1 : 0.001\"\n [min]=\"item.min ?? null\" [max]=\"item.max ?? null\" [(ngModel)]=\"item.value\"\n (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-16 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\" *ngIf=\"!item.varName.includes('line-height')\">rem</span>\n </ng-container>\n <!-- Text input fallback (if needed) -->\n <ng-container *ngIf=\"!item.varName.includes('color') && item.type !== 'number'\">\n <input [id]=\"item.varName\" type=\"text\" [(ngModel)]=\"item.value\" (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-24 tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n </ng-container>\n <div class=\"tw-flex tw-flex-col tw-gap-0.5\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700\">{{ item.label }}</label>\n <span class=\"tw-text-xs tw-text-gray-500 tw-font-mono\">{{ item.value }}</span>\n </div>\n </ng-container>\n </div>\n </div>\n </section>\n </div>\n\n <!-- STICKY ACTION BUTTONS SECTION -->\n <div class=\"tw-bg-white tw-sticky tw-bottom-0 tw-border-t tw-border-gray-200 tw-z-10 tw-flex-shrink-0 tw-p-3 tw-shadow-lg sticky-action-buttons\">\n <div class=\"tw-flex tw-gap-2 tw-justify-end\">\n <button cideEleButton \n variant=\"outline\" \n size=\"sm\" \n (btnClick)=\"onReset()\" \n [disabled]=\"!hasChangesFromOriginal()\"\n class=\"tw-transition-all tw-duration-200 hover:tw-scale-105 action-button\">\n Reset to Original\n </button>\n <button cideEleButton \n variant=\"primary\" \n size=\"sm\" \n (btnClick)=\"onSave()\" \n [disabled]=\"!hasUnsavedChanges()\"\n class=\"tw-transition-all tw-duration-200 hover:tw-scale-105 action-button\">\n Save Changes\n </button>\n </div>\n </div>\n</div>", styles: [".theme-scroll-container{scroll-behavior:smooth;-webkit-overflow-scrolling:touch}.theme-scroll-container::-webkit-scrollbar{width:6px}.theme-scroll-container::-webkit-scrollbar-track{background:#f8fafc;border-radius:3px}.theme-scroll-container::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px;transition:background-color .2s ease}.theme-scroll-container::-webkit-scrollbar-thumb:hover{background:#94a3b8}.sticky-action-buttons{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background-color:#fffffff2;border-top:1px solid #e2e8f0;box-shadow:0 -4px 6px -1px #0000001a}.action-button{transition:all .2s ease-in-out}.action-button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 8px #00000026}.action-button:active:not(:disabled){transform:translateY(0)}.action-button:disabled{opacity:.5;cursor:not-allowed;transform:none!important;box-shadow:none!important}.theme-input:focus{transform:scale(1.02);transition:transform .2s ease-in-out}.color-input{transition:all .2s ease-in-out}.color-input:hover{transform:scale(1.1);box-shadow:0 4px 8px #0003}.theme-section{transition:all .3s ease-in-out}.theme-section:hover{background-color:#f8fafc;border-radius:8px;padding:8px;margin:-8px}@media (max-width: 640px){.sticky-action-buttons{padding:12px}.action-button{font-size:14px;padding:8px 12px}}\n"] }]
292
- }], ctorParameters: () => [{ type: i1.CideLytThemeService }, { type: undefined, decorators: [{
293
- type: Inject,
294
- args: [PLATFORM_ID]
295
- }] }] });
296
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhd2VyLXRoZW1lLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Nsb3VkLWlkZS1sYXlvdXQvc3JjL2xpYi9sYXlvdXQvc2lkZWRyYXdlci9kcmF3ZXItdGhlbWUvZHJhd2VyLXRoZW1lLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Nsb3VkLWlkZS1sYXlvdXQvc3JjL2xpYi9sYXlvdXQvc2lkZWRyYXdlci9kcmF3ZXItdGhlbWUvZHJhd2VyLXRoZW1lLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDOUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQVUsV0FBVyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0UsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxtQkFBbUIsRUFBZ0Isc0JBQXNCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM5RixPQUFPLEVBQThCLGNBQWMsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBSW5HLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQzVDLE9BQU8sQ0FBQyxNQUFNLFFBQVEsQ0FBQztBQUN2QixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7OztBQW9DcEUsTUFBTSxPQUFPLDJCQUEyQjtJQWdFdEMsWUFDVSxZQUFpQyxFQUNaLFVBQWtCO1FBRHZDLGlCQUFZLEdBQVosWUFBWSxDQUFxQjtRQUNaLGVBQVUsR0FBVixVQUFVLENBQVE7UUFqRWhDLGFBQVEsR0FBRyxNQUFNLENB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Y0FBYyxDQUFDLEtBQVksRUFBRSxPQUEwQjtRQUNyRCxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBMEIsQ0FBQztRQUMvQyxPQUFPLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDNUIsdURBQXVEO1FBQ3ZELElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxLQUFZO1FBQzVCLElBQUksQ0FBQyxLQUFLLEdBQUksS0FBSyxDQUFDLE1BQTJCLENBQUMsT0FBTyxDQUFDO1FBQ3hELFFBQVEsQ0FBQyxlQUFlLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0lBQzVELENBQUM7OEdBOVNVLDJCQUEyQixxREFrRTVCLFdBQVc7a0dBbEVWLDJCQUEyQixpRkMvQ3hDLHdnUkErSE0sODJDRHBGTSxXQUFXLHd6Q0FBRSxLQUFLLG1IQUFFLElBQUksNkZBQUUsT0FBTyxvRkFBRSxtQkFBbUIsbVlBQUUsc0JBQXNCOzsyRkFJN0UsMkJBQTJCO2tCQVB2QyxTQUFTOytCQUNFLHVCQUF1QixjQUNyQixJQUFJLFdBQ1AsQ0FBQyxXQUFXLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsc0JBQXNCLENBQUM7OzBCQXNFdEYsTUFBTTsyQkFBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdGb3IsIE5nSWYgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTmdDbGFzcyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgUExBVEZPUk1fSUQsIEluamVjdCwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IENpZGVTZWxlY3RDb21wb25lbnQsIFNlbGVjdE9wdGlvbiwgQ2lkZUVsZUJ1dHRvbkNvbXBvbmVudCB9IGZyb20gJ2Nsb3VkLWlkZS1lbGVtZW50JztcbmltcG9ydCB7IENpZGVMeXRUaGVtZVNlcnZpY2UsIFRoZW1lLCBzZXRDU1NWYXJpYWJsZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL3RoZW1lL3RoZW1lLnNlcnZpY2UnO1xuaW1wb3J0IHR5cGUgeyBNU3lzdGVtVGhlbWVVc2VyUHJlZmVyZW5jZXNSZXF1ZXN0LCBTeXN0ZW1UaGVtZXNMaXN0Q29udHJvbGxlclJlc3Bvb25zZSwgU3lzdGVtVGhlbWVVc2VyUHJlZmVyZW5jZXNDb250cm9sbGVyUmVzcG9vbnNlIH0gZnJvbSAnY2xvdWQtaWRlLWxtcy1tb2RlbCc7XG5pbXBvcnQgdHlwZSB7IFN5c3RlbVRoZW1lQ29udHJvbGxlclJlc3Bvb25zZSB9IGZyb20gJ2Nsb3VkLWlkZS1sbXMtbW9kZWwnO1xuaW1wb3J0IHR5cGUgeyBJQ29yZVN5dGgsIElDb3JlU3lvdGgsIElDb3JlU3l1cHRoIH0gZnJvbSAnY2xvdWQtaWRlLWxtcy1tb2RlbCc7XG5pbXBvcnQgeyBpc0VxdWFsLCBjbG9uZURlZXAgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IEFwcFN0YXRlSGVscGVyU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2FwcC1zdGF0ZSc7XG5cbmludGVyZmFjZSBUaGVtZUNvbG9yIHtcbiAgbGFiZWw6IHN0cmluZztcbiAgdmFyTmFtZTogc3RyaW5nO1xuICB2YWx1ZTogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgVHlwb2dyYXBoeVNldHRpbmcge1xuICBsYWJlbDogc3RyaW5nO1xuICB2YXJOYW1lOiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmc7XG4gIHR5cGU6ICdudW1iZXInIHwgJ3RleHQnO1xuICBtaW4/OiBudW1iZXI7XG4gIG1heD86IG51bWJlcjtcbn1cblxudHlwZSBUaGVtZUdyb3VwID0ge1xuICBsYWJlbDogc3RyaW5nO1xuICBpdGVtczogQXJyYXk8e1xuICAgIGxhYmVsOiBzdHJpbmc7XG4gICAgdmFyTmFtZTogc3RyaW5nO1xuICAgIHZhbHVlOiBzdHJpbmc7XG4gICAgdHlwZTogJ251bWJlcicgfCAndGV4dCc7XG4gICAgbWluPzogbnVtYmVyO1xuICAgIG1heD86IG51bWJlcjtcbiAgfT47XG59O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjaWRlLWx5dC1kcmF3ZXItdGhlbWUnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbRm9ybXNNb2R1bGUsIE5nRm9yLCBOZ0lmLCBOZ0NsYXNzLCBDaWRlU2VsZWN0Q29tcG9uZW50LCBDaWRlRWxlQnV0dG9uQ29tcG9uZW50XSxcbiAgdGVtcGxhdGVVcmw6ICcuL2RyYXdlci10aGVtZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9kcmF3ZXItdGhlbWUuY29tcG9uZW50LnNjc3MnXG59KVxuZXhwb3J0IGNsYXNzIENpZGVMeXREcmF3ZXJUaGVtZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXBwU3RhdGUgPSBpbmplY3QoQXBwU3RhdGVIZWxwZXJTZXJ2aWNlKTtcbiAgLy8gUHJlc2V0IHRoZW1lc1xuICBwcmVzZXRUaGVtZXM6IHsgdmFsdWU6IHN0cmluZywgbGFiZWw6IHN0cmluZywgdGhlbWU6IElDb3JlU3l0aCB9W10gPSBbXTtcbiAgc2VsZWN0ZWRUaGVtZSA9ICcnO1xuICBpc0xvYWRpbmdUaGVtZXMgPSBmYWxzZTtcbiAgdGhlbWVMb2FkRXJyb3IgPSAnJztcbiAgbWVyZ2VkVGhlbWU6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgaXNSVEwgPSBmYWxzZTtcbiAgb3JpZ2luYWxUaGVtZUdyb3VwVmFsdWVzOiBUaGVtZUdyb3VwW10gPSBbXTtcbiAgb3JpZ2luYWxBcGlUaGVtZVZhbHVlczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9OyAvLyBTdG9yZSBvcmlnaW5hbCBBUEkgdmFsdWVzXG5cbiAgdGhlbWVHcm91cHM6IFRoZW1lR3JvdXBbXSA9IFtcbiAgICB7XG4gICAgICBsYWJlbDogJ0JyYW5kIENvbG9ycycsXG4gICAgICBpdGVtczogW1xuICAgICAgICB7IGxhYmVsOiAnUHJpbWFyeScsIHZhck5hbWU6ICctLWNpZGUtdGhlbWUtY29sb3ItYnJhbmQtcHJpbWFyeScsIHZhbHVlOiAnIzRmNDZlNScsIHR5cGU6ICd0ZXh0JyB9LFxuICAgICAgICB7IGxhYmVsOiAnQWNjZW50JywgdmFyTmFtZTogJy0tY2lkZS10aGVtZS1jb2xvci1icmFuZC1hY2NlbnQnLCB2YWx1ZTogJyM0MzM4Y2EnLCB0eXBlOiAndGV4dCcgfSxcbiAgICAgICAgeyBsYWJlbDogJ1NlcGFyYXRvcicsIHZhck5hbWU6ICctLWNpZGUtdGhlbWUtY29sb3ItYnJhbmQtc2VwYXJhdG9yJywgdmFsdWU6ICcjZTVlN2ViJywgdHlwZTogJ3RleHQnIH1cbiAgICAgIF1cbiAgICB9LFxuICAgIHtcbiAgICAgIGxhYmVsOiAnVGV4dCBDb2xvcnMnLFxuICAgICAgaXRlbXM6IFtcbiAgICAgICAgeyBsYWJlbDogJ0JvZHkgVGV4dCcsIHZhck5hbWU6ICctLWNpZGUtdGhlbWUtY29sb3ItdGV4dC1ib2R5JywgdmFsdWU6ICcjMzc0MTUxJywgdHlwZTogJ3RleHQnIH0sXG4gICAgICAgIHsgbGFiZWw6ICdIZWFkaW5nIFRleHQnLCB2YXJOYW1lOiAnLS1jaWRlLXRoZW1lLWNvbG9yLXRleHQtaGVhZGluZycsIHZhbHVlOiAnIzExMTgyNycsIHR5cGU6ICd0ZXh0JyB9LFxuICAgICAgICB7IGxhYmVsOiAnTGluayBUZXh0JywgdmFyTmFtZTogJy0tY2lkZS10aGVtZS1jb2xvci10ZXh0LWxpbmsnLCB2YWx1ZTogJyMzYjgyZjYnLCB0eXBlOiAndGV4dCcgfSxcbiAgICAgICAgeyBsYWJlbDogJ011dGVkIFRleHQnLCB2YXJOYW1lOiAnLS1jaWRlLXRoZW1lLWNvbG9yLXRleHQtbXV0ZWQnLCB2YWx1ZTogJyM2YjcyODAnLCB0eXBlOiAndGV4dCcgfVxuICAgICAgXVxuICAgIH0sXG4gICAge1xuICAgICAgbGFiZWw6ICdCYWNrZ3JvdW5kIENvbG9ycycsXG4gICAgICBpdGVtczogW1xuICAgICAgICB7IGxhYmVsOiAnQm9keSBCYWNrZ3JvdW5kJywgdmFyTmFtZTogJy0tY2lkZS10aGVtZS1jb2xvci1iYWNrZ3JvdW5kLWJvZHknLCB2YWx1ZTogJyNmZmZmZmYnLCB0eXBlOiAndGV4dCcgfVxuICAgICAgXVxuICAgIH0sXG4gICAge1xuICAgICAgbGFiZWw6ICdMYXlvdXQgRGltZW5zaW9ucycsXG4gICAgICBpdGVtczogW1xuICAgICAgICB7IGxhYmVsOiAnU3RhY2sgV3JhcHBlciBXaWR0aCcsIHZhck5hbWU6ICctLWNpZGUtbHl0LXN0YWNrLXdyYXBwZXItd2lkdGgnLCB2YWx1ZTogJzYwJywgdHlwZTogJ251bWJlcicsIG1pbjogMjAsIG1heDogMTIwIH1cbiAgICAgIF1cbiAgICB9LFxuICAgIHtcbiAgICAgIGxhYmVsOiAnRm9udCBTaXplcycsXG4gICAgICBpdGVtczogW1xuICAgICAgICB7IGxhYmVsOiAnWFhYTCBGb250IFNpemUnLCB2YXJOYW1lOiAnLS1jaWRlLXRoZW1lLWZvbnQtc2l6ZS14eHhsJywgdmFsdWU6ICczLjA1MicsIHR5cGU6ICdudW1iZXInLCBtaW46IDEsIG1heDogMTAgfSxcbiAgICAgICAgeyBsYWJlbDogJ1hYTCBGb250IFNpemUnLCB2YXJOYW1lOiAnLS1jaWRlLXRoZW1lLWZvbnQtc2l6ZS14eGwnLCB2YWx1ZTogJzIuNDQxJywgdHlwZTogJ251bWJlcicsIG1pbjogMSwgbWF4OiAxMCB9LFxuICAgICAgICB7IGxhYmVsOiAnWEwgRm9udCBTaXplJywgdmFyTmFtZTogJy0tY2lkZS10aGVtZS1mb250LXNpemUteGwnLCB2YWx1ZTogJzEuOTUzJywgdHlwZTogJ251bWJlcicsIG1pbjogMSwgbWF4OiAxMCB9LFxuICAgICAgICB7IGxhYmVsOiAnTEcgRm9udCBTaXplJywgdmFyTmFtZTogJy0tY2lkZS10aGVtZS1mb250LXNpemUtbGcnLCB2YWx1ZTogJzEuNTYzJywgdHlwZTogJ251bWJlcicsIG1pbjogMSwgbWF4OiAxMCB9LFxuICAgICAgICB7IGxhYmVsOiAnTUQgRm9udCBTaXplJywgdmFyTmFtZTogJy0tY2lkZS10aGVtZS1mb250LXNpemUtbWQnLCB2YWx1ZTogJzEuMjUnLCB0eXBlOiAnbnVtYmVyJywgbWluOiAxLCBtYXg6IDEwIH0sXG4gICAgICAgIHsgbGFiZWw6ICdQYXJhZ3JhcGggRm9udCBTaXplJywgdmFyTmFtZTogJy0tY2lkZS10aGVtZS1mb250LXNpemUtcCcsIHZhbHVlOiAnMScsIHR5cGU6ICdudW1iZXInLCBtaW46IDAuNSwgbWF4OiA1IH0sXG4gICAgICAgIHsgbGFiZWw6ICdTTSBGb250IFNpemUnLCB2YXJOYW1lOiAnLS1jaWRlLXRoZW1lLWZvbnQtc2l6ZS1zbScsIHZhbHVlOiAnMC45JywgdHlwZTogJ251bWJlcicsIG1pbjogMC41LCBtYXg6IDUgfSxcbiAgICAgICAgeyBsYWJlbDogJ1hTIEZvbnQgU2l6ZScsIHZhck5hbWU6ICctLWNpZGUtdGhlbWUtZm9udC1zaXplLXhzJywgdmFsdWU6ICcwLjgnLCB0eXBlOiAnbnVtYmVyJywgbWluOiAwLjUsIG1heDogNSB9XG4gICAgICBdXG4gICAgfSxcbiAgICB7XG4gICAgICBsYWJlbDogJ0xpbmUgSGVpZ2h0cycsXG4gICAgICBpdGVtczogW1xuICAgICAgICB7IGxhYmVsOiAnQm9keSBMaW5lIEhlaWdodCcsIHZhck5hbWU6ICctLWNpZGUtdGhlbWUtbGluZS1oZWlnaHQtYm9keScsIHZhbHVlOiAnMS42JywgdHlwZTogJ251bWJlcicsIG1pbjogMSwgbWF4OiAzIH0sXG4gICAgICAgIHsgbGFiZWw6ICdIZWFkaW5nIExpbmUgSGVpZ2h0JywgdmFyTmFtZTogJy0tY2lkZS10aGVtZS1saW5lLWhlaWdodC1oZWFkaW5nJywgdmFsdWU6ICcxLjInLCB0eXBlOiAnbnVtYmVyJywgbWluOiAxLCBtYXg6IDMgfVxuICAgICAgXVxuICAgIH1cbiAgXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHRoZW1lU2VydmljZTogQ2lkZUx5dFRoZW1lU2VydmljZSxcbiAgICBASW5qZWN0KFBMQVRGT1JNX0lEKSBwcml2YXRlIHBsYXRmb3JtSWQ6IG9iamVjdFxuICApIHsgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIE1vZGVybiBBbmd1bGFyIHYyMCBwYXR0ZXJuOiBVc2UgU2lnbmFscyBkaXJlY3RseVxuICAgIHRoaXMuc2VsZWN0ZWRUaGVtZSA9IHRoaXMudGhlbWVTZXJ2aWNlLnNlbGVjdGVkVGhlbWUoKTtcblxuICAgIC8vIGZldGNoIHRoZSBzeXN0ZW0gdGhlbWVzIGxpc3RcbiAgICB0aGlzLmlzTG9hZGluZ1RoZW1lcyA9IHRydWU7XG4gICAgdGhpcy50aGVtZVNlcnZpY2UuZmV0Y2hTeXN0ZW1UaGVtZXNMaXN0KCkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IFN5c3RlbVRoZW1lc0xpc3RDb250cm9sbGVyUmVzcG9vbnNlKSA9PiB7XG4gICAgICAgIGNvbnN0IHRoZW1lczogSUNvcmVTeXRoW10gPSByZXM/LmRhdGE/LmNvcmVfc3lzdGVtX3RoZW1lcyB8fCBbXTtcbiAgICAgICAgdGhpcy5wcmVzZXRUaGVtZXMgPSB0aGVtZXMubWFwKCh0aGVtZTogSUNvcmVTeXRoKSA9PiAoe1xuICAgICAgICAgIHZhbHVlOiB0aGVtZS5faWQgfHwgJycsXG4gICAgICAgICAgbGFiZWw6IHRoZW1lLnN5dGhfdGhlbWVfbmFtZSB8fCB0aGVtZS5zeXRoX3RoZW1lX2lkIHx8ICcnLFxuICAgICAgICAgIHRoZW1lXG4gICAgICAgIH0pKTtcbiAgICAgICAgdGhpcy5pc0xvYWRpbmdUaGVtZXMgPSBmYWxzZTtcbiAgICAgICAgLy8gSWYgdXNlciBoYXMgbm8gdGhlbWUgc2V0LCBzZWxlY3QgYW5kIGFwcGx5IHRoZSBkZWZhdWx0IHRoZW1lXG4gICAgICAgIGlmICghdGhpcy5zZWxlY3RlZFRoZW1lKSB7XG4gICAgICAgICAgY29uc3QgZGVmYXVsdFRoZW1lID0gdGhpcy5wcmVzZXRUaGVtZXMuZmluZCh0ID0+IHQudGhlbWUuc3l0aF9pc19kZWZhdWx0KTtcbiAgICAgICAgICBpZiAoZGVmYXVsdFRoZW1lKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkVGhlbWUgPSBkZWZhdWx0VGhlbWUudmFsdWU7XG4gICAgICAgICAgICAvLyBBcHBseSB0aGUgZGVmYXVsdCB0aGVtZSBhcyBDU1MgdmFyaWFibGVzXG4gICAgICAgICAgICBpZiAoZGVmYXVsdFRoZW1lLnRoZW1lLnN5dGhfcHJvcGVydGllcykge1xuICAgICAgICAgICAgICBPYmplY3QuZW50cmllcyhkZWZhdWx0VGhlbWUudGhlbWUuc3l0aF9wcm9wZXJ0aWVzKS5mb3JFYWNoKChbdmFyTmFtZSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVWYXIodmFyTmFtZSwgdmFsdWUgYXMgc3RyaW5nKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgdGhpcy50aGVtZUxvYWRFcnJvciA9ICdGYWlsZWQgdG8gbG9hZCB0aGVtZXMnO1xuICAgICAgICB0aGlzLmlzTG9hZGluZ1RoZW1lcyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMubG9hZEFuZEFwcGx5VXNlclRoZW1lKCk7XG4gIH1cblxuICBsb2FkQW5kQXBwbHlVc2VyVGhlbWUoKTogdm9pZCB7XG4gICAgdGhpcy50aGVtZVNlcnZpY2UubG9hZFRoZW1lKCkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IFN5c3RlbVRoZW1lQ29udHJvbGxlclJlc3Bvb25zZSkgPT4ge1xuICAgICAgICBjb25zdCBiYXNlOiBJQ29yZVN5dGggfCB1bmRlZmluZWQgPSByZXM/LmRhdGE/LmNvcmVfc3lzdGVtX3RoZW1lcztcbiAgICAgICAgY29uc3Qgb3JnOiBJQ29yZVN5b3RoIHwgdW5kZWZpbmVkID0gcmVzPy5kYXRhPy5jb3JlX3N5c3RlbV9vcmdhbml6YXRpb25fdGhlbWVzO1xuICAgICAgICBjb25zdCB1c2VyOiBJQ29yZVN5dXB0aCB8IHVuZGVmaW5lZCA9IHJlcz8uZGF0YT8uY29yZV9zeXN0ZW1fdGhlbWVfdXNlcl9wcmVmZXJlbmNlcztcbiAgICAgICAgLy8gU3RhcnQgd2l0aCBiYXNlIHRoZW1lIHByb3BlcnRpZXNcbiAgICAgICAgbGV0IG1lcmdlZCA9IHsgLi4uKGJhc2U/LnN5dGhfcHJvcGVydGllcyB8fCB7fSkgfTtcbiAgICAgICAgLy8gT3ZlcnJpZGUgd2l0aCBvcmcgb3ZlcnJpZGVzXG4gICAgICAgIGlmIChvcmc/LnN5b3RoX292ZXJyaWRlcykge1xuICAgICAgICAgIG1lcmdlZCA9IHsgLi4ubWVyZ2VkLCAuLi5vcmcuc3lvdGhfb3ZlcnJpZGVzIH07XG4gICAgICAgIH1cbiAgICAgICAgLy8gT3ZlcnJpZGUgd2l0aCB1c2VyIG92ZXJyaWRlc1xuICAgICAgICBpZiAodXNlcj8uc3l1cHRoX292ZXJyaWRlcykge1xuICAgICAgICAgIG1lcmdlZCA9IHsgLi4ubWVyZ2VkLCAuLi51c2VyLnN5dXB0aF9vdmVycmlkZXMgfTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm1lcmdlZFRoZW1lID0gbWVyZ2VkO1xuXG4gICAgICAgIC8vIFN0b3JlIG9yaWdpbmFsIEFQSSB2YWx1ZXMgZm9yIHJlc2V0IGZ1bmN0aW9uYWxpdHlcbiAgICAgICAgdGhpcy5vcmlnaW5hbEFwaVRoZW1lVmFsdWVzID0geyAuLi5tZXJnZWQgfTtcblxuICAgICAgICAvLyBBcHBseSBtZXJnZWQgdGhlbWUgYXMgQ1NTIHZhcmlhYmxlc1xuICAgICAgICBPYmplY3QuZW50cmllcyh0aGlzLm1lcmdlZFRoZW1lKS5mb3JFYWNoKChbdmFyTmFtZSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgdGhpcy51cGRhdGVWYXIodmFyTmFtZSwgdmFsdWUgYXMgc3RyaW5nKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZm9yIChjb25zdCBncm91cCBvZiB0aGlzLnRoZW1lR3JvdXBzKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGdyb3VwLml0ZW1zKSB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBpdGVtLnZhck5hbWUucmVwbGFjZSgvLS9nLCAnXycpO1xuICAgICAgICAgICAgaXRlbS52YWx1ZSA9IG1lcmdlZFtpdGVtLnZhck5hbWVdIHx8IG1lcmdlZFtrZXldIHx8IGl0ZW0udmFsdWU7XG5cbiAgICAgICAgICAgIGlmIChrZXkuaW5jbHVkZXMoJ2ZvbnRfc2l6ZScpIHx8IGtleS5pbmNsdWRlcygnbGluZV9oZWlnaHQnKSkge1xuICAgICAgICAgICAgICBpdGVtLnZhbHVlID0gcGFyc2VGbG9hdChpdGVtLnZhbHVlKSBhcyB1bmtub3duIGFzIHN0cmluZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gU3RvcmUgYSBkZWVwIGNvcHkgb2YgdGhlIGN1cnJlbnQgdmFsdWVzIGZvciByZXNldFxuICAgICAgICB0aGlzLm9yaWdpbmFsVGhlbWVHcm91cFZhbHVlcyA9IGNsb25lRGVlcCh0aGlzLnRoZW1lR3JvdXBzKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICAvLyBoYW5kbGUgZXJyb3IgaWYgbmVlZGVkXG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBVcGRhdGUgQ1NTIHZhcmlhYmxlIGluIHJlYWwgdGltZVxuICB1cGRhdGVWYXIodmFyTmFtZTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKSB7XG4gICAgLy8gWW91IGNhbiB1c2UgZWl0aGVyIHRoZSB1dGlsaXR5IGZ1bmN0aW9uIGRpcmVjdGx5IG9yIHRoZSBzZXJ2aWNlIG1ldGhvZFxuICAgIHNldENTU1ZhcmlhYmxlKHZhck5hbWUsIHZhbHVlLCB0aGlzLnBsYXRmb3JtSWQpO1xuICAgIC8vIEFsdGVybmF0aXZlOiB0aGlzLnRoZW1lU2VydmljZS51cGRhdGVDU1NWYXJpYWJsZSh2YXJOYW1lLCB2YWx1ZSk7XG4gIH1cblxuICBvblRoZW1lQ2hhbmdlKGV2ZW50OiBTZWxlY3RPcHRpb24pIHtcbiAgICB0aGlzLnNlbGVjdGVkVGhlbWUgPSBldmVudC52YWx1ZSBhcyBzdHJpbmc7XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLnByZXNldFRoZW1lcy5maW5kKHQgPT4gdC52YWx1ZSA9PT0gdGhpcy5zZWxlY3RlZFRoZW1lKTtcbiAgICBpZiAoc2VsZWN0ZWQgJiYgc2VsZWN0ZWQudGhlbWUgJiYgc2VsZWN0ZWQudGhlbWUuc3l0aF9wcm9wZXJ0aWVzKSB7XG4gICAgICAvLyBoZXJlIHdlIHdpbGwgY2hlY2sgdGhlIHRoZW1lIHNlbGVjdGVkIGJ5IG9yZ2FuaXphdGlvbiBpcyBzYW1lIGlmIHllcyB0aGVuIG92ZXJpZGUgYWxzbyBmb3IgdXNlciBwcmVmZXJlbmNlc1xuICAgICAgaWYgKHRoaXMudGhlbWVTZXJ2aWNlLnNlbGVjdGVkVGhlbWUoKSA9PT0gc2VsZWN0ZWQudGhlbWUuX2lkKSB7XG4gICAgICAgIHRoaXMubG9hZEFuZEFwcGx5VXNlclRoZW1lKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBTdG9yZSBvcmlnaW5hbCBBUEkgdmFsdWVzIGZvciB0aGUgc2VsZWN0ZWQgdGhlbWVcbiAgICAgICAgdGhpcy5vcmlnaW5hbEFwaVRoZW1lVmFsdWVzID0gXy5jbG9uZURlZXAoc2VsZWN0ZWQudGhlbWUuc3l0aF9wcm9wZXJ0aWVzKTtcblxuICAgICAgICAvLyBVcGRhdGUgYWxsIGdyb3VwIHZhbHVlcyBmcm9tIHRoZSBzZWxlY3RlZCB0aGVtZVxuICAgICAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIHRoaXMudGhlbWVHcm91cHMpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgZ3JvdXAuaXRlbXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IGl0ZW0udmFyTmFtZS5yZXBsYWNlKC8tL2csICdfJyk7XG4gICAgICAgICAgICBpdGVtLnZhbHVlID0gc2VsZWN0ZWQudGhlbWUuc3l0aF9wcm9wZXJ0aWVzW2l0ZW0udmFyTmFtZV0gfHxcbiAgICAgICAgICAgICAgc2VsZWN0ZWQudGhlbWUuc3l0aF9wcm9wZXJ0aWVzW2tleV0gfHxcbiAgICAgICAgICAgICAgaXRlbS52YWx1ZTtcblxuICAgICAgICAgICAgdGhpcy51cGRhdGVWYXIoaXRlbS52YXJOYW1lLCBpdGVtLnZhbHVlKTtcblxuICAgICAgICAgICAgaWYgKGtleS5pbmNsdWRlcygnZm9udF9zaXplJykgfHwga2V5LmluY2x1ZGVzKCdsaW5lX2hlaWdodCcpKSB7XG4gICAgICAgICAgICAgIGl0ZW0udmFsdWUgPSBwYXJzZUZsb2F0KGl0ZW0udmFsdWUpIGFzIHVua25vd24gYXMgc3RyaW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBTdG9yZSBhIGRlZXAgY29weSBvZiB0aGUgY3VycmVudCB2YWx1ZXMgZm9yIHJlc2V0XG4gICAgICAgIHRoaXMub3JpZ2luYWxUaGVtZUdyb3VwVmFsdWVzID0gY2xvbmVEZWVwKHRoaXMudGhlbWVHcm91cHMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uUmVzZXQoKSB7XG4gICAgLy8gUmVzdG9yZSBhbGwgdmFsdWVzIGZyb20gdGhlIG9yaWdpbmFsIEFQSSB2YWx1ZXNcbiAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIHRoaXMudGhlbWVHcm91cHMpIHtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBncm91cC5pdGVtcykge1xuICAgICAgICBjb25zdCBrZXkgPSBpdGVtLnZhck5hbWUucmVwbGFjZSgvLS9nLCAnXycpO1xuICAgICAgICAvLyBHZXQgdGhlIG9yaWdpbmFsIEFQSSB2YWx1ZVxuICAgICAgICBjb25zdCBvcmlnaW5hbFZhbHVlID0gdGhpcy5vcmlnaW5hbEFwaVRoZW1lVmFsdWVzW2l0ZW0udmFyTmFtZV0gfHxcbiAgICAgICAgICB0aGlzLm9yaWdpbmFsQXBpVGhlbWVWYWx1ZXNba2V5XSB8fFxuICAgICAgICAgIGl0ZW0udmFsdWU7XG5cbiAgICAgICAgLy8gVXBkYXRlIHRoZSBpdGVtIHZhbHVlXG4gICAgICAgIGl0ZW0udmFsdWUgPSBvcmlnaW5hbFZhbHVlO1xuXG4gICAgICAgIC8vIEFwcGx5IHRoZSBDU1MgdmFyaWFibGVcbiAgICAgICAgdGhpcy51cGRhdGVWYXIoaXRlbS52YXJOYW1lLCBpdGVtLnZhbHVlKTtcblxuICAgICAgICBpZiAoa2V5LmluY2x1ZGVzKCdmb250X3NpemUnKSB8fCBrZXkuaW5jbHVkZXMoJ2xpbmVfaGVpZ2h0JykpIHtcbiAgICAgICAgICBpdGVtLnZhbHVlID0gcGFyc2VGbG9hdChpdGVtLnZhbHVlKSBhcyB1bmtub3duIGFzIHN0cmluZztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFVwZGF0ZSB0aGUgb3JpZ2luYWxUaGVtZUdyb3VwVmFsdWVzIHRvIHJlZmxlY3QgdGhlIHJlc2V0IHN0YXRlXG4gICAgdGhpcy5vcmlnaW5hbFRoZW1lR3JvdXBWYWx1ZXMgPSBjbG9uZURlZXAodGhpcy50aGVtZUdyb3Vwcyk7XG4gIH1cblxuICBvblNhdmUoKSB7XG4gICAgLy8gQ29sbGVjdCBhbGwgY3VycmVudCB2YWx1ZXNcbiAgICBjb25zdCB0aGVtZVZhcnM6IFRoZW1lID0ge1xuXG4gICAgfTtcbiAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIHRoaXMudGhlbWVHcm91cHMpIHtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBncm91cC5pdGVtcykge1xuICAgICAgICB0aGVtZVZhcnNbaXRlbS52YXJOYW1lPy5yZXBsYWNlQWxsKCctJywgJ18nKV0gPSBpdGVtLnZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN5c3RlbVRoZW1lUHJlZmVyZW5jZXM6IE1TeXN0ZW1UaGVtZVVzZXJQcmVmZXJlbmNlc1JlcXVlc3QgPSB7XG4gICAgICBzeXVwdGhfb3ZlcnJpZGVzOiB7XG4gICAgICAgIC4uLnRoZW1lVmFyc1xuICAgICAgfSxcbiAgICAgIHN5dXB0aF9zeXN0ZW1fdGhlbWVfaWRfc3l0aDogdGhpcy5zZWxlY3RlZFRoZW1lLCAvLyBMQVRFUjogbmVlZCB0byB1cGFkYXRlIExBVEVSXG4gICAgICBzeXVwdGhfdXNlcl9pZF91c2VyOiB0aGlzLmFwcFN0YXRlLmN1cnJlbnRVc2VyKCk/Ll9pZCB8fCAnJywgLy8gTEFURVI6IG5lZWQgdG8gZ2V0IHVzZXIgaWQgZnJvbSB1c2VyXG4gICAgICBzeXVwdGhfZW50aXR5X2lkX3N5ZW46IHRoaXMuYXBwU3RhdGUuZ2V0QWN0aXZlRW50aXR5SWQoKSB8fCAnJywgLy8gTEFURVI6IG5lZWQgdG8gZ2V0IGVudGl0eSBpZCBmcm9tIHVzZXJcbiAgICAgIHN5dGhfdGhlbWVfaWQ6IFwiXCIgLy8gbmVlZCB0byB1cGFkYXRlIExBVEVSXG4gICAgfTtcblxuICAgIC8vIFRPRE86IFNlbmQgdGhlbWVWYXJzIHRvIGJhY2tlbmQgb3IgZW1pdCBldmVudCBieSBkZXNpZ25Db25maWdSb3V0ZXNVcmw/LnN5c3RlbVRoZW1lVXNlclByZWZlcmVuY2VzXG4gICAgdGhpcy50aGVtZVNlcnZpY2Uuc2F2ZVN5c3RlbVRoZW1lVXNlclByZWZlcmVuY2VzKHN5c3RlbVRoZW1lUHJlZmVyZW5jZXMpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBTeXN0ZW1UaGVtZVVzZXJQcmVmZXJlbmNlc0NvbnRyb2xsZXJSZXNwb29uc2UpID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coJ1RoZW1lIHNhdmVkOicsIHJlcyk7XG4gICAgICAgIC8vIE1vZGVybiBBbmd1bGFyIHYyMCBwYXR0ZXJuOiBVcGRhdGUgU2lnbmFsIHRocm91Z2ggc2VydmljZSBtZXRob2RcbiAgICAgICAgLy8gTm90ZTogVGhlIHRoZW1lIHNlcnZpY2Ugc2hvdWxkIHByb3ZpZGUgYSBtZXRob2QgdG8gdXBkYXRlIHRoZSBzZWxlY3RlZCB0aGVtZVxuICAgICAgICAvLyBGb3Igbm93LCB3ZSdsbCBqdXN0IGxvZyB0aGUgY2hhbmdlIHNpbmNlIHRoZSBzZXJ2aWNlIGRvZXNuJ3QgZXhwb3NlIGEgc2V0dGVyXG4gICAgICAgIGNvbnNvbGUubG9nKCdUaGVtZSBzZWxlY3RlZDonLCB0aGlzLnNlbGVjdGVkVGhlbWUpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3Igc2F2aW5nIHRoZW1lOicsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGhhc1Vuc2F2ZWRDaGFuZ2VzKCk6IGJvb2xlYW4ge1xuICAgIC8vIGNoZWMgc2VsZWN0ZWQgdGhlbWUgaXMgZGlmZmVyZW50XG4gICAgaWYgKHRoaXMudGhlbWVTZXJ2aWNlLnNlbGVjdGVkVGhlbWUoKSAhPT0gdGhpcy5zZWxlY3RlZFRoZW1lKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLy8gY2hlY2sgdGhlIHRoZW1lIGdyb3VwcyBhcmUgZGlmZmVyZW50XG4gICAgcmV0dXJuICFpc0VxdWFsKHRoaXMudGhlbWVHcm91cHMsIHRoaXMub3JpZ2luYWxUaGVtZUdyb3VwVmFsdWVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBjdXJyZW50IHZhbHVlcyBkaWZmZXIgZnJvbSB0aGUgb3JpZ2luYWwgQVBJIHZhbHVlc1xuICAgKiBUaGlzIGlzIHVzZWZ1bCBmb3IgZGV0ZXJtaW5pbmcgaWYgcmVzZXQgc2hvdWxkIGJlIGVuYWJsZWRcbiAgICovXG4gIGhhc0NoYW5nZXNGcm9tT3JpZ2luYWwoKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBncm91cCBvZiB0aGlzLnRoZW1lR3JvdXBzKSB7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgZ3JvdXAuaXRlbXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gaXRlbS52YXJOYW1lLnJlcGxhY2UoLy0vZywgJ18nKTtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxWYWx1ZSA9IHRoaXMub3JpZ2luYWxBcGlUaGVtZVZhbHVlc1tpdGVtLnZhck5hbWVdIHx8XG4gICAgICAgICAgdGhpcy5vcmlnaW5hbEFwaVRoZW1lVmFsdWVzW2tleV07XG5cbiAgICAgICAgaWYgKG9yaWdpbmFsVmFsdWUgIT09IHVuZGVmaW5lZCAmJiBpdGVtLnZhbHVlICE9PSBvcmlnaW5hbFZhbHVlKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgb25Db2xvckNoYW5nZShldmVudDogRXZlbnQsIGNvbG9yOiBUaGVtZUNvbG9yKSB7XG4gICAgY29uc3QgaW5wdXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICBjb2xvci52YWx1ZSA9IGlucHV0LnZhbHVlO1xuICAgIHRoaXMudXBkYXRlVmFyKGNvbG9yLnZhck5hbWUsIGNvbG9yLnZhbHVlKTtcbiAgfVxuXG4gIG9uVHlwb2dyYXBoeUNoYW5nZShldmVudDogRXZlbnQsIHNldHRpbmc6IFR5cG9ncmFwaHlTZXR0aW5nKSB7XG4gICAgY29uc3QgaW5wdXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICBzZXR0aW5nLnZhbHVlID0gaW5wdXQudmFsdWU7XG4gICAgdGhpcy51cGRhdGVWYXIoc2V0dGluZy52YXJOYW1lLCBzZXR0aW5nLnR5cGUgPT09ICdudW1iZXInID8gc2V0dGluZy52YWx1ZSA6IHNldHRpbmcudmFsdWUpO1xuICB9XG5cbiAgb25MYXlvdXRDaGFuZ2UoZXZlbnQ6IEV2ZW50LCBzZXR0aW5nOiBUeXBvZ3JhcGh5U2V0dGluZykge1xuICAgIGNvbnN0IGlucHV0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgc2V0dGluZy52YWx1ZSA9IGlucHV0LnZhbHVlO1xuICAgIC8vIEZvciBsYXlvdXQgZGltZW5zaW9ucywgYXBwZW5kICdweCcgdW5pdCB0byB0aGUgdmFsdWVcbiAgICB0aGlzLnVwZGF0ZVZhcihzZXR0aW5nLnZhck5hbWUsIHNldHRpbmcudmFsdWUgKyAncHgnKTtcbiAgfVxuXG4gIG9uRGlyZWN0aW9uVG9nZ2xlKGV2ZW50OiBFdmVudCkge1xuICAgIHRoaXMuaXNSVEwgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLmNoZWNrZWQ7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmRpciA9IHRoaXMuaXNSVEwgPyAncnRsJyA6ICdsdHInO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwidHctcmVsYXRpdmUgdHctaC1mdWxsIHR3LWJnLXdoaXRlIHR3LW92ZXJmbG93LWhpZGRlbiB0dy1mbGV4IHR3LWZsZXgtY29sXCI+XG4gIDwhLS0gU1RJQ0tZIEhFQURFUiBTRUNUSU9OIC0tPlxuICA8ZGl2IGNsYXNzPVwidHctYmctd2hpdGUgdHctc3RpY2t5IHR3LXRvcC0wIHR3LWJvcmRlci1iIHR3LWJvcmRlci1ncmF5LTIwMCB0dy16LTEwIHR3LWZsZXgtc2hyaW5rLTBcIj5cbiAgICA8IS0tIERZTkFNSUMgSEVBRElORyAtLT5cbiAgICA8ZGl2IGNsYXNzPVwidHctZmxleCB0dy1qdXN0aWZ5LWJldHdlZW4gdHctaXRlbXMtY2VudGVyIHR3LXAtMiB0dy1iZy13aGl0ZSB0dy1ib3JkZXItYiB0dy1ib3JkZXItZ3JheS0yMDBcIj5cbiAgICAgIDxoNiBjbGFzcz1cInR3LWZvbnQtc2VtaWJvbGQgdHctdGV4dC1ncmF5LTgwMFwiPlByZXNldCBUaGVtZTwvaDY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDwhLS0gU0NST0xMQUJMRSBDT05URU5UIEFSRUEgLS0+XG4gIDxkaXYgY2xhc3M9XCJ0dy1mbGV4LTEgdHctb3ZlcmZsb3cteS1hdXRvIHR3LXNjcm9sbC1zbW9vdGggdHctcC0yIHR3LWZsZXggdHctZmxleC1jb2wgdHctZ2FwLTUgdHctdGV4dC1zbSB0dy1wYi0zIHRoZW1lLXNjcm9sbC1jb250YWluZXJcIj5cbiAgICA8IS0tIFByZXNldCBUaGVtZSAtLT5cbiAgICA8c2VjdGlvbj5cbiAgICAgIDxjaWRlLWVsZS1zZWxlY3QgaWQ9XCJ0aGVtZS1zZWxlY3RvclwiIFsobmdNb2RlbCldPVwic2VsZWN0ZWRUaGVtZVwiIChjaGFuZ2UpPVwib25UaGVtZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgW29wdGlvbnNdPVwicHJlc2V0VGhlbWVzXCIgW3NpemVdPVwiJ3NtJ1wiPjwvY2lkZS1lbGUtc2VsZWN0PlxuICAgIDwvc2VjdGlvbj5cblxuICAgIDwhLS0gRGlyZWN0aW9uIFRvZ2dsZSAtLT5cbiAgICA8c2VjdGlvbj5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0dy1mbGV4IHR3LWp1c3RpZnktYmV0d2VlbiB0dy1pdGVtcy1jZW50ZXIgdHctbWItMlwiPlxuICAgICAgICA8aDIgY2xhc3M9XCJ0dy10ZXh0LW1kIHR3LWZvbnQtc2VtaWJvbGQgdHctdGV4dC1ncmF5LTgwMFwiPlRleHQgRGlyZWN0aW9uPC9oMj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInR3LWZsZXggdHctaXRlbXMtY2VudGVyIHR3LWdhcC0xXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0dy10ZXh0LXhzIHR3LXRleHQtZ3JheS01MDBcIj5MVFI8L3NwYW4+XG4gICAgICAgICAgPGxhYmVsIGZvcj1cImRpcmVjdGlvbi10b2dnbGVcIiBjbGFzcz1cInR3LXJlbGF0aXZlIHR3LWlubGluZS1ibG9jayB0dy13LTkgdHctaC01XCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJkaXJlY3Rpb24tdG9nZ2xlXCIgY2xhc3M9XCJ0dy1vcGFjaXR5LTAgdHctdy0wIHR3LWgtMFwiIFsobmdNb2RlbCldPVwiaXNSVExcIlxuICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uRGlyZWN0aW9uVG9nZ2xlKCRldmVudClcIj5cbiAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgIGNsYXNzPVwidHctYWJzb2x1dGUgdHctY3Vyc29yLXBvaW50ZXIgdHctdG9wLTAgdHctbGVmdC0wIHR3LXJpZ2h0LTAgdHctYm90dG9tLTAgdHctYmctZ3JheS0zMDAgdHctcm91bmRlZC1mdWxsIHR3LXRyYW5zaXRpb24tY29sb3JzIGNoZWNrZWQ6dHctYmctYmx1ZS01MDAgYmVmb3JlOnR3LWFic29sdXRlIGJlZm9yZTp0dy1jb250ZW50LVsnJ10gYmVmb3JlOnR3LWgtNCBiZWZvcmU6dHctdy00IGJlZm9yZTp0dy1sZWZ0LTAuNSBiZWZvcmU6dHctYm90dG9tLTAuNSBiZWZvcmU6dHctYmctd2hpdGUgYmVmb3JlOnR3LXJvdW5kZWQtZnVsbCBiZWZvcmU6dHctdHJhbnNpdGlvbi10cmFuc2Zvcm0gY2hlY2tlZDpiZWZvcmU6dHctdHJhbnNsYXRlLXgtNFwiPjwvc3Bhbj5cbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidHctdGV4dC14cyB0dy10ZXh0LWdyYXktNTAwXCI+UlRMPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvc2VjdGlvbj5cblxuICAgIDwhLS0gVGhlbWUgUHJvcGVydHkgR3JvdXBzIChCcmFuZCwgVGV4dCwgQmFja2dyb3VuZCwgRm9udCBTaXplcywgTGluZSBIZWlnaHRzKSAtLT5cbiAgICA8c2VjdGlvbiAqbmdGb3I9XCJsZXQgZ3JvdXAgb2YgdGhlbWVHcm91cHNcIiBjbGFzcz1cInRoZW1lLXNlY3Rpb25cIj5cbiAgICAgIDxoMiBjbGFzcz1cInR3LXRleHQtbWQgdHctZm9udC1zZW1pYm9sZCB0dy1tYi0yIHR3LXRleHQtZ3JheS04MDBcIj57eyBncm91cC5sYWJlbCB9fTwvaDI+XG4gICAgICA8ZGl2IGNsYXNzPVwidHctZ3JpZCB0dy1ncmlkLWNvbHMtMiB0dy1nYXAtMiB0dy1nYXAteC00XCI+XG4gICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGl0ZW0gb2YgZ3JvdXAuaXRlbXNcIlxuICAgICAgICAgIGNsYXNzPVwidHctZmxleCB0dy1pdGVtcy1jZW50ZXIgdHctZ2FwLTIgdHctcC0xIHR3LXJvdW5kZWQtbGcgdHctYmctZ3JheS01MFwiXG4gICAgICAgICAgW25nQ2xhc3NdPVwieyd0dy1mbGV4LWNvbCB0dy1pdGVtcy1zdHJldGNoJzogKGdyb3VwLmxhYmVsID09PSAnRm9udCBTaXplcycgfHwgZ3JvdXAubGFiZWwgPT09ICdMaW5lIEhlaWdodHMnIHx8IGdyb3VwLmxhYmVsID09PSAnTGF5b3V0IERpbWVuc2lvbnMnKX1cIj5cbiAgICAgICAgICA8IS0tIEZvbnQgU2l6ZXM6IGxhYmVsIG9uIHRvcCwgaW5wdXQgaW4gbWlkZGxlLCB1bml0IGF0IGJvdHRvbSAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ3JvdXAubGFiZWwgPT09ICdGb250IFNpemVzJ1wiPlxuICAgICAgICAgICAgPGxhYmVsIFtmb3JdPVwiaXRlbS52YXJOYW1lXCIgY2xhc3M9XCJ0dy10ZXh0LXNtIHR3LWZvbnQtbWVkaXVtIHR3LXRleHQtZ3JheS03MDAgdHctdGV4dC1sZWZ0XCI+e3sgaXRlbS5sYWJlbFxuICAgICAgICAgICAgICB9fTwvbGFiZWw+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHctZmxleCB0dy1pdGVtcy1zdGFydFwiPlxuICAgICAgICAgICAgICA8aW5wdXQgW2lkXT1cIml0ZW0udmFyTmFtZVwiIHR5cGU9XCJudW1iZXJcIiBzdGVwPVwiMC4wMDFcIiBbbWluXT1cIml0ZW0ubWluID8/IG51bGxcIiBbbWF4XT1cIml0ZW0ubWF4ID8/IG51bGxcIlxuICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaXRlbS52YWx1ZVwiIChpbnB1dCk9XCJvblR5cG9ncmFwaHlDaGFuZ2UoJGV2ZW50LCBpdGVtKVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ0dy13LTE4IHR3LXRleHQtcmlnaHQgdHctdGV4dC1zbSB0dy1ib3JkZXIgdHctYm9yZGVyLWdyYXktMzAwIHR3LXJvdW5kZWQgdHctcHgtMiB0dy1weS0xIGZvY3VzOnR3LW91dGxpbmUtbm9uZSBmb2N1czp0dy1yaW5nLTIgZm9jdXM6dHctcmluZy1ibHVlLTUwMCBmb2N1czp0dy1ib3JkZXItdHJhbnNwYXJlbnQgdGhlbWUtaW5wdXRcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0dy10ZXh0LXhzIHR3LXRleHQtZ3JheS00MDBcIj5yZW08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8IS0tIExpbmUgSGVpZ2h0czogbGFiZWwgb24gdG9wLCBpbnB1dCBhbmQgdW5pdCBvbiBzYW1lIGxpbmUgLS0+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdyb3VwLmxhYmVsID09PSAnTGluZSBIZWlnaHRzJ1wiPlxuICAgICAgICAgICAgPGxhYmVsIFtmb3JdPVwiaXRlbS52YXJOYW1lXCIgY2xhc3M9XCJ0dy10ZXh0LXNtIHR3LWZvbnQtbWVkaXVtIHR3LXRleHQtZ3JheS03MDAgdHctdGV4dC1sZWZ0XCI+e3sgaXRlbS5sYWJlbFxuICAgICAgICAgICAgICB9fTwvbGFiZWw+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHctZmxleCB0dy1pdGVtcy1zdGFydFwiPlxuICAgICAgICAgICAgICA8aW5wdXQgW2lkXT1cIml0ZW0udmFyTmFtZVwiIHR5cGU9XCJudW1iZXJcIiBzdGVwPVwiMC4xXCIgW21pbl09XCJpdGVtLm1pbiA/PyBudWxsXCIgW21heF09XCJpdGVtLm1heCA/PyBudWxsXCJcbiAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIml0ZW0udmFsdWVcIiAoaW5wdXQpPVwib25UeXBvZ3JhcGh5Q2hhbmdlKCRldmVudCwgaXRlbSlcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwidHctdy0xOCB0dy10ZXh0LXJpZ2h0IHR3LXRleHQtc20gdHctYm9yZGVyIHR3LWJvcmRlci1ncmF5LTMwMCB0dy1yb3VuZGVkIHR3LXB4LTIgdHctcHktMSBmb2N1czp0dy1vdXRsaW5lLW5vbmUgZm9jdXM6dHctcmluZy0yIGZvY3VzOnR3LXJpbmctYmx1ZS01MDAgZm9jdXM6dHctYm9yZGVyLXRyYW5zcGFyZW50IHRoZW1lLWlucHV0XCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidHctdGV4dC14cyB0dy10ZXh0LWdyYXktNDAwXCI+dW5pdGxlc3M8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8IS0tIExheW91dCBEaW1lbnNpb25zOiBsYWJlbCBvbiB0b3AsIGlucHV0IGluIG1pZGRsZSwgcHggdW5pdCBhdCBib3R0b20gLS0+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdyb3VwLmxhYmVsID09PSAnTGF5b3V0IERpbWVuc2lvbnMnXCI+XG4gICAgICAgICAgICA8bGFiZWwgW2Zvcl09XCJpdGVtLnZhck5hbWVcIiBjbGFzcz1cInR3LXRleHQtc20gdHctZm9udC1tZWRpdW0gdHctdGV4dC1ncmF5LTcwMCB0dy10ZXh0LWxlZnRcIj57eyBpdGVtLmxhYmVsXG4gICAgICAgICAgICAgIH19PC9sYWJlbD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0dy1mbGV4IHR3LWl0ZW1zLXN0YXJ0XCI+XG4gICAgICAgICAgICAgIDxpbnB1dCBbaWRdPVwiaXRlbS52YXJOYW1lXCIgdHlwZT1cIm51bWJlclwiIHN0ZXA9XCIxXCIgW21pbl09XCJpdGVtLm1pbiA/PyBudWxsXCIgW21heF09XCJpdGVtLm1heCA/PyBudWxsXCJcbiAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIml0ZW0udmFsdWVcIiAoaW5wdXQpPVwib25MYXlvdXRDaGFuZ2UoJGV2ZW50LCBpdGVtKVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ0dy13LTE4IHR3LXRleHQtcmlnaHQgdHctdGV4dC1zbSB0dy1ib3JkZXIgdHctYm9yZGVyLWdyYXktMzAwIHR3LXJvdW5kZWQgdHctcHgtMiB0dy1weS0xIGZvY3VzOnR3LW91dGxpbmUtbm9uZSBmb2N1czp0dy1yaW5nLTIgZm9jdXM6dHctcmluZy1ibHVlLTUwMCBmb2N1czp0dy1ib3JkZXItdHJhbnNwYXJlbnQgdGhlbWUtaW5wdXRcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0dy10ZXh0LXhzIHR3LXRleHQtZ3JheS00MDBcIj5weDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwhLS0gT3RoZXIgZ3JvdXBzOiBrZWVwIHByZXZpb3VzIGxheW91dCAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ3JvdXAubGFiZWwgIT09ICdGb250IFNpemVzJyAmJiBncm91cC5sYWJlbCAhPT0gJ0xpbmUgSGVpZ2h0cycgJiYgZ3JvdXAubGFiZWwgIT09ICdMYXlvdXQgRGltZW5zaW9ucydcIj5cbiAgICAgICAgICAgIDwhLS0gQ29sb3IgaW5wdXQgZm9yIGNvbG9yIHZhcmlhYmxlcyAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLnZhck5hbWUuaW5jbHVkZXMoJ2NvbG9yJylcIj5cbiAgICAgICAgICAgICAgPGlucHV0IFtpZF09XCJpdGVtLnZhck5hbWVcIiBbYXR0ci5kYXRhLXZhcmlhYmxlXT1cIml0ZW0udmFyTmFtZVwiIHR5cGU9XCJjb2xvclwiIFsobmdNb2RlbCldPVwiaXRlbS52YWx1ZVwiXG4gICAgICAgICAgICAgICAgKGlucHV0KT1cIm9uQ29sb3JDaGFuZ2UoJGV2ZW50LCBpdGVtKVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ0dy1hcHBlYXJhbmNlLW5vbmUgdHctYm9yZGVyLTIgdHctYm9yZGVyLWdyYXktMjAwIHR3LXJvdW5kZWQgdHctdy04IHR3LWgtOCB0dy1wLTAgdHctYmctbm9uZSB0dy1zaGFkb3ctbm9uZSB0dy1jdXJzb3ItcG9pbnRlciB0dy10cmFuc2l0aW9uLWNvbG9ycyBmb2N1czp0dy1ib3JkZXItYmx1ZS01MDAgY29sb3ItaW5wdXRcIj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPCEtLSBOdW1iZXIgaW5wdXQgZm9yIGxpbmUgaGVpZ2h0cyAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgKm5nSWY9XCIhaXRlbS52YXJOYW1lLmluY2x1ZGVzKCdjb2xvcicpICYmIGl0ZW0udHlwZSA9PT0gJ251bWJlcicgJiYgZ3JvdXAubGFiZWwgIT09ICdGb250IFNpemVzJ1wiPlxuICAgICAgICAgICAgICA8aW5wdXQgW2lkXT1cIml0ZW0udmFyTmFtZVwiIHR5cGU9XCJudW1iZXJcIiBbc3RlcF09XCJpdGVtLnZhck5hbWUuaW5jbHVkZXMoJ2xpbmUtaGVpZ2h0JykgPyAwLjEgOiAwLjAwMVwiXG4gICAgICAgICAgICAgICAgW21pbl09XCJpdGVtLm1pbiA/PyBudWxsXCIgW21heF09XCJpdGVtLm1heCA/PyBudWxsXCIgWyhuZ01vZGVsKV09XCJpdGVtLnZhbHVlXCJcbiAgICAgICAgICAgICAgICAoaW5wdXQpPVwib25UeXBvZ3JhcGh5Q2hhbmdlKCRldmVudCwgaXRlbSlcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwidHctdy0xNiB0dy10ZXh0LXJpZ2h0IHR3LXRleHQtc20gdHctYm9yZGVyIHR3LWJvcmRlci1ncmF5LTMwMCB0dy1yb3VuZGVkIHR3LXB4LTIgdHctcHktMSBmb2N1czp0dy1vdXRsaW5lLW5vbmUgZm9jdXM6dHctcmluZy0yIGZvY3VzOnR3LXJpbmctYmx1ZS01MDAgZm9jdXM6dHctYm9yZGVyLXRyYW5zcGFyZW50IHRoZW1lLWlucHV0XCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidHctdGV4dC14cyB0dy10ZXh0LWdyYXktNDAwXCIgKm5nSWY9XCIhaXRlbS52YXJOYW1lLmluY2x1ZGVzKCdsaW5lLWhlaWdodCcpXCI+cmVtPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8IS0tIFRleHQgaW5wdXQgZmFsbGJhY2sgKGlmIG5lZWRlZCkgLS0+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWl0ZW0udmFyTmFtZS5pbmNsdWRlcygnY29sb3InKSAmJiBpdGVtLnR5cGUgIT09ICdudW1iZXInXCI+XG4gICAgICAgICAgICAgIDxpbnB1dCBbaWRdPVwiaXRlbS52YXJOYW1lXCIgdHlwZT1cInRleHRcIiBbKG5nTW9kZWwpXT1cIml0ZW0udmFsdWVcIiAoaW5wdXQpPVwib25UeXBvZ3JhcGh5Q2hhbmdlKCRldmVudCwgaXRlbSlcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwidHctdy0yNCB0dy10ZXh0LXNtIHR3LWJvcmRlciB0dy1ib3JkZXItZ3JheS0zMDAgdHctcm91bmRlZCB0dy1weC0yIHR3LXB5LTEgZm9jdXM6dHctb3V0bGluZS1ub25lIGZvY3VzOnR3LXJpbmctMiBmb2N1czp0dy1yaW5nLWJsdWUtNTAwIGZvY3VzOnR3LWJvcmRlci10cmFuc3BhcmVudCB0aGVtZS1pbnB1dFwiPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHctZmxleCB0dy1mbGV4LWNvbCB0dy1nYXAtMC41XCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBbZm9yXT1cIml0ZW0udmFyTmFtZVwiIGNsYXNzPVwidHctdGV4dC1zbSB0dy1mb250LW1lZGl1bSB0dy10ZXh0LWdyYXktNzAwXCI+e3sgaXRlbS5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidHctdGV4dC14cyB0dy10ZXh0LWdyYXktNTAwIHR3LWZvbnQtbW9ub1wiPnt7IGl0ZW0udmFsdWUgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L3NlY3Rpb24+XG4gIDwvZGl2PlxuXG4gIDwhLS0gU1RJQ0tZIEFDVElPTiBCVVRUT05TIFNFQ1RJT04gLS0+XG4gIDxkaXYgY2xhc3M9XCJ0dy1iZy13aGl0ZSB0dy1zdGlja3kgdHctYm90dG9tLTAgdHctYm9yZGVyLXQgdHctYm9yZGVyLWdyYXktMjAwIHR3LXotMTAgdHctZmxleC1zaHJpbmstMCB0dy1wLTMgdHctc2hhZG93LWxnIHN0aWNreS1hY3Rpb24tYnV0dG9uc1wiPlxuICAgIDxkaXYgY2xhc3M9XCJ0dy1mbGV4IHR3LWdhcC0yIHR3LWp1c3RpZnktZW5kXCI+XG4gICAgICA8YnV0dG9uIGNpZGVFbGVCdXR0b24gXG4gICAgICAgIHZhcmlhbnQ9XCJvdXRsaW5lXCIgXG4gICAgICAgIHNpemU9XCJzbVwiIFxuICAgICAgICAoYnRuQ2xpY2spPVwib25SZXNldCgpXCIgXG4gICAgICAgIFtkaXNhYmxlZF09XCIhaGFzQ2hhbmdlc0Zyb21PcmlnaW5hbCgpXCJcbiAgICAgICAgY2xhc3M9XCJ0dy10cmFuc2l0aW9uLWFsbCB0dy1kdXJhdGlvbi0yMDAgaG92ZXI6dHctc2NhbGUtMTA1IGFjdGlvbi1idXR0b25cIj5cbiAgICAgICAgUmVzZXQgdG8gT3JpZ2luYWxcbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvbiBjaWRlRWxlQnV0dG9uIFxuICAgICAgICB2YXJpYW50PVwicHJpbWFyeVwiIFxuICAgICAgICBzaXplPVwic21cIiBcbiAgICAgICAgKGJ0bkNsaWNrKT1cIm9uU2F2ZSgpXCIgXG4gICAgICAgIFtkaXNhYmxlZF09XCIhaGFzVW5zYXZlZENoYW5nZXMoKVwiXG4gICAgICAgIGNsYXNzPVwidHctdHJhbnNpdGlvbi1hbGwgdHctZHVyYXRpb24tMjAwIGhvdmVyOnR3LXNjYWxlLTEwNSBhY3Rpb24tYnV0dG9uXCI+XG4gICAgICAgIFNhdmUgQ2hhbmdlc1xuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+Il19