@libs-ui/components-table 0.2.78

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 (35) hide show
  1. package/README.md +3 -0
  2. package/esm2022/index.mjs +4 -0
  3. package/esm2022/interfaces/button-action-event.interface.mjs +3 -0
  4. package/esm2022/interfaces/button-bar-event.interface.mjs +3 -0
  5. package/esm2022/interfaces/function-control-event.interface.mjs +2 -0
  6. package/esm2022/interfaces/hover-button-action-event.interface.mjs +2 -0
  7. package/esm2022/interfaces/index.mjs +11 -0
  8. package/esm2022/interfaces/load-more-event.interface.mjs +2 -0
  9. package/esm2022/interfaces/no-data-config.interface.mjs +2 -0
  10. package/esm2022/interfaces/sort-event.interface.mjs +2 -0
  11. package/esm2022/interfaces/table-config.interface.mjs +2 -0
  12. package/esm2022/interfaces/table.type.mjs +2 -0
  13. package/esm2022/interfaces/template-config.interface.mjs +3 -0
  14. package/esm2022/libs-ui-components-table.mjs +5 -0
  15. package/esm2022/table.component.mjs +608 -0
  16. package/esm2022/templates/template.abstract.component.mjs +16 -0
  17. package/esm2022/templates/templates.component.mjs +111 -0
  18. package/fesm2022/libs-ui-components-table.mjs +735 -0
  19. package/fesm2022/libs-ui-components-table.mjs.map +1 -0
  20. package/index.d.ts +3 -0
  21. package/interfaces/button-action-event.interface.d.ts +12 -0
  22. package/interfaces/button-bar-event.interface.d.ts +7 -0
  23. package/interfaces/function-control-event.interface.d.ts +13 -0
  24. package/interfaces/hover-button-action-event.interface.d.ts +4 -0
  25. package/interfaces/index.d.ts +10 -0
  26. package/interfaces/load-more-event.interface.d.ts +4 -0
  27. package/interfaces/no-data-config.interface.d.ts +8 -0
  28. package/interfaces/sort-event.interface.d.ts +5 -0
  29. package/interfaces/table-config.interface.d.ts +88 -0
  30. package/interfaces/table.type.d.ts +12 -0
  31. package/interfaces/template-config.interface.d.ts +60 -0
  32. package/package.json +25 -0
  33. package/table.component.d.ts +137 -0
  34. package/templates/template.abstract.component.d.ts +7 -0
  35. package/templates/templates.component.d.ts +25 -0
@@ -0,0 +1,16 @@
1
+ import { Component, input } from "@angular/core";
2
+ import * as i0 from "@angular/core";
3
+ export class LibsUiComponentsTableTemplateAbstractComponent {
4
+ item = input.required();
5
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsTableTemplateAbstractComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: LibsUiComponentsTableTemplateAbstractComponent, selector: "libs_ui-components-table-templates_abstract", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: ``, isInline: true });
7
+ }
8
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsTableTemplateAbstractComponent, decorators: [{
9
+ type: Component,
10
+ args: [{
11
+ // eslint-disable-next-line @angular-eslint/component-selector
12
+ selector: 'libs_ui-components-table-templates_abstract',
13
+ template: ``
14
+ }]
15
+ }] });
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGUuYWJzdHJhY3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL3RhYmxlL3NyYy90ZW1wbGF0ZXMvdGVtcGxhdGUuYWJzdHJhY3QuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQVFqRCxNQUFNLE9BQU8sOENBQThDO0lBQ2hELElBQUksR0FBRyxLQUFLLENBQUMsUUFBUSxFQUF3QixDQUFDO3dHQUQ1Qyw4Q0FBOEM7NEZBQTlDLDhDQUE4QyxtTkFGL0MsRUFBRTs7NEZBRUQsOENBQThDO2tCQUwxRCxTQUFTO21CQUFDO29CQUNULDhEQUE4RDtvQkFDOUQsUUFBUSxFQUFFLDZDQUE2QztvQkFDdkQsUUFBUSxFQUFFLEVBQUU7aUJBQ2IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGlucHV0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IFRZUEVfSVRFTV9EQVRBX1RBQkxFIH0gZnJvbSBcIi4uL2ludGVyZmFjZXNcIjtcblxuQENvbXBvbmVudCh7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvY29tcG9uZW50LXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnbGlic191aS1jb21wb25lbnRzLXRhYmxlLXRlbXBsYXRlc19hYnN0cmFjdCcsXG4gIHRlbXBsYXRlOiBgYFxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlDb21wb25lbnRzVGFibGVUZW1wbGF0ZUFic3RyYWN0Q29tcG9uZW50IHtcbiAgcmVhZG9ubHkgaXRlbSA9IGlucHV0LnJlcXVpcmVkPFRZUEVfSVRFTV9EQVRBX1RBQkxFPigpO1xufSJdfQ==
@@ -0,0 +1,111 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { AsyncPipe, NgClass, NgComponentOutlet, NgStyle } from '@angular/common';
3
+ import { ChangeDetectionStrategy, Component, input } from '@angular/core';
4
+ import { LibsUiComponentsAvatarComponent } from '@libs-ui/components-avatar';
5
+ import { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
6
+ import { LibsUiComponentsButtonsStatusComponent } from '@libs-ui/components-buttons-status';
7
+ import { LibsUiComponentsDropdownComponent } from '@libs-ui/components-dropdown';
8
+ import { LibsUiComponentsLineClampComponent } from '@libs-ui/components-line-clamp';
9
+ import { LibsUiComponentsPopoverComponent } from '@libs-ui/components-popover';
10
+ import { LibsUiComponentsSwitchComponent } from '@libs-ui/components-switch';
11
+ import { LibsUiPipesCallFunctionInTemplatePipe } from '@libs-ui/pipes-call-function-in-template';
12
+ import { LibsUiPipesCloneObjectPipe } from '@libs-ui/pipes-clone-object';
13
+ import { LibsUiPipesSecurityTrustPipe } from '@libs-ui/pipes-security-trust';
14
+ import { convertObjectToSignal } from '@libs-ui/utils';
15
+ import { TranslateModule } from '@ngx-translate/core';
16
+ import { LibsUiComponentsBadgeComponent } from '@libs-ui/components-badge';
17
+ import * as i0 from "@angular/core";
18
+ import * as i1 from "@ngx-translate/core";
19
+ export class LibsUiComponentsTableTemplatesComponent {
20
+ lockClick;
21
+ functionControls = new Map();
22
+ isImageError;
23
+ isHover = input();
24
+ configs = input();
25
+ templateCssWrapper = input();
26
+ item = input.required();
27
+ async handlerItemClick(event, config, dataField) {
28
+ if (event instanceof Event) {
29
+ event.preventDefault();
30
+ event.stopPropagation();
31
+ }
32
+ if (typeof event === 'string' && event !== 'click') {
33
+ return;
34
+ }
35
+ if (this.lockClick) {
36
+ return;
37
+ }
38
+ this.lockClick = true;
39
+ setTimeout(() => {
40
+ this.lockClick = false;
41
+ }, 250);
42
+ if (config && config.action) {
43
+ config.action(dataField, this.item());
44
+ }
45
+ }
46
+ async clickButtonAction(button) {
47
+ if (this.lockClick) {
48
+ return;
49
+ }
50
+ this.lockClick = true;
51
+ setTimeout(() => {
52
+ this.lockClick = false;
53
+ }, 250);
54
+ button.action?.({ item: this.item() });
55
+ }
56
+ async handlerSwitch(switchItem, config) {
57
+ if (this.lockClick) {
58
+ return;
59
+ }
60
+ this.lockClick = true;
61
+ setTimeout(() => {
62
+ this.lockClick = false;
63
+ }, 250);
64
+ config?.switchAction?.(switchItem, this.item());
65
+ }
66
+ async handlerSelectItemDropdown(fieldConfig, index, data) {
67
+ if (this.lockClick || !data) {
68
+ return;
69
+ }
70
+ this.lockClick = true;
71
+ setTimeout(() => {
72
+ this.lockClick = false;
73
+ }, 250);
74
+ fieldConfig?.action?.(data.key, data.item, this.item());
75
+ this.functionControls?.get(index)?.reset();
76
+ this.functionControls?.get(index)?.removeList();
77
+ }
78
+ async handlerSelectItemsDropdown(fieldConfig, index, data) {
79
+ if (this.lockClick || !data) {
80
+ return;
81
+ }
82
+ this.lockClick = true;
83
+ setTimeout(() => {
84
+ this.lockClick = false;
85
+ }, 250);
86
+ fieldConfig?.action?.(data.keys, convertObjectToSignal(data.mapKeys, false), this.item());
87
+ this.functionControls?.get(index)?.reset();
88
+ }
89
+ async handlerImageError(event) {
90
+ event.stopPropagation();
91
+ this.isImageError = true;
92
+ }
93
+ async handlerFunctionControl(event, index) {
94
+ this.functionControls.set(index, event);
95
+ }
96
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsTableTemplatesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
97
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: LibsUiComponentsTableTemplatesComponent, isStandalone: true, selector: "libs_ui-components-table-templates", inputs: { isHover: { classPropertyName: "isHover", publicName: "isHover", isSignal: true, isRequired: false, transformFunction: null }, configs: { classPropertyName: "configs", publicName: "configs", isSignal: true, isRequired: false, transformFunction: null }, templateCssWrapper: { classPropertyName: "templateCssWrapper", publicName: "templateCssWrapper", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@if (configs(); as configs) {\n @if (item(); as item) {\n <div class=\"mo-lib-table-template {{ templateCssWrapper() || '' }}\">\n @for (config of configs; track $index) {\n @if (config.fieldsConfig) {\n <div [class]=\"config.cssWrapper\">\n @for (fieldConfig of config.fieldsConfig; track index;let index = $index;) {\n\n @if (!fieldConfig.rows && !fieldConfig.getComponentOutlet) {\n @switch (fieldConfig.instance) {\n @case (\"tooltip\") {\n @if ((fieldConfig.tooltip || {}); as tooltip) {\n <span LibsUiComponentsPopoverDirective\n [type]=\"tooltip.type || 'text'\"\n [mode]=\"tooltip.mode || 'hover'\"\n [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [classInclude]=\"tooltip.classInclude || ' '\"\n [ignoreShowPopover]=\"tooltip.ignoreShowPopover || false\"\n [config]=\"(fieldConfig.getTooltipConfig ? (item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getTooltipConfig:item() | async) : (tooltip.config | LibsUiPipesCloneObjectPipe)) | translate\"\n [innerHTML]=\" (fieldConfig.field ? item()[fieldConfig.field] : tooltip.dataView) | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item() | async | translate\"\n (outEvent)=\"handlerItemClick($event,fieldConfig,item()[fieldConfig.field])\">\n </span>\n }\n }\n @case (\"image\") {\n @if (((item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getImageSrc:item():isImageError) | async); as linkImage) {\n @if (linkImage !== ' ') {\n <img [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [src]=\"linkImage\"\n (error)=\"handlerImageError($event)\"\n (click)=\"handlerItemClick($event,fieldConfig,item()[fieldConfig.field])\" />\n }\n }\n }\n\n @case (\"avatar\") {\n @if ((item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getAvatarConfig:item()) | async ; as avatarConfig) {\n <libs_ui-components-avatar [typeShape]=\"avatarConfig.typeShape || 'circle'\"\n [classInclude]=\"avatarConfig.classInclude\"\n [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [size]='avatarConfig.size || 32'\n [linkAvatar]=\"avatarConfig.linkAvatar\"\n [linkAvatarError]=\"avatarConfig.linkAvatarError\"\n [idGenColor]=\"avatarConfig.idGenColor\"\n [textAvatar]=\"avatarConfig.textAvatar\"\n [getLastTextAfterSpace]=\"avatarConfig.getLastTextAfterSpace\" />\n }\n }\n\n @case (\"buttons\") {\n @if ((fieldConfig.buttons && fieldConfig.buttons.length) || fieldConfig.getButtonsByItem) {\n <div [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [class.invisible]=\"!isHover() && fieldConfig.showButtonHoverMode\">\n @for (button of (fieldConfig.buttons || (item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getButtonsByItem:item() | async)); track $index) {\n\n <libs_ui-components-buttons-button [type]=\"button().type || 'button-primary'\"\n [sizeButton]=\"button().sizeButton || 'smaller'\"\n [disable]=\"button().disable ?? (item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getDisable:item())\"\n [label]=\"button().label || ' '\"\n [classIconLeft]=\"button().classIconLeft || ''\"\n [classIconRight]=\"button().classIconRight || ''\"\n [popover]=\"button().popover || {}\"\n [classInclude]=\"button().classInclude || ''\"\n [ignorePointerEvent]=\"button().ignorePointerEvent\"\n (outClick)=\"clickButtonAction(button())\" />\n }\n </div>\n }\n }\n\n @case (\"button-status\") {\n <libs_ui-components-buttons-status\n [config]=\"(item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item()) | async\"\n (click)=\"handlerItemClick($event,fieldConfig,item()[fieldConfig.field])\" />\n }\n\n @case (\"switch\") {\n <libs_ui-components-switch\n [active]=\"item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getActiveValueSwitch:item() | async\"\n [disable]=\"item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getDisableValueSwitch:item() | async\"\n (outSwitch)=\"handlerSwitch($event,fieldConfig)\" />\n }\n\n\n @case ((fieldConfig.instance === 'other-action-show-popup' || fieldConfig.instance === 'badge' || fieldConfig.instance === 'button-action-show-popup') ? fieldConfig.instance : '') {\n @if ((item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item() | async) !== ' ') {\n <div [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [class.ml-[8px]]=\"!fieldConfig.ignoreClassMarginLeft\">\n <libs_ui-components-dropdown [isNgContent]=\"true\"\n [popoverCustomConfig]=\"{\n widthByParent:false,\n ignoreArrow: fieldConfig.dropdownConfig?.ignoreArrow || false,\n maxHeight: fieldConfig.dropdownConfig?.maxHeight || 2048,\n paddingLeftItem:fieldConfig.dropdownConfig?.paddingLeftItem ?? true,\n classInclude:fieldConfig.dropdownConfig?.classIncludePopup || 'w-[250px]',\n position: fieldConfig.dropdownConfig?.position || {\n mode:'center',\n distance:0\n }\n }\"\n [zIndex]=\"fieldConfig.dropdownConfig?.zIndex\"\n [listConfig]=\"fieldConfig.dropdownConfig?.getListViewConfig ? ((item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.dropdownConfig?.getListViewConfig:item()) | async):fieldConfig.dropdownConfig?.listViewConfig\"\n [listBackgroundCustom]=\"fieldConfig.dropdownConfig?.listViewBackgroundListCustom\"\n [listMaxItemShow]=\"fieldConfig.dropdownConfig?.listViewMaxItemShow || 5\"\n [listKeysDisable]=\"fieldConfig.dropdownConfig?.listViewKeysDisableItem\"\n (outFunctionsControl)=\"handlerFunctionControl($event, index)\"\n (outSelectKey)=\"handlerSelectItemDropdown(fieldConfig, index,$event)\"\n (outSelectMultiKey)=\"handlerSelectItemsDropdown(fieldConfig, index,$event)\">\n @if (fieldConfig.instance === 'other-action-show-popup') {\n <div\n [innerHtml]=\"(item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item())| async | translate\">\n </div>\n }\n @if (fieldConfig.instance === 'badge' && (item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item() | async) > 0) {\n <libs_ui-components-badge [active]=\"true\"\n [ignoreMarginDefault]=\"true\"\n mode=\"+x\"\n [count]=\"item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item() | async\"\n [maxCount]=\"99\" />\n }\n @if (fieldConfig.instance === 'button-action-show-popup') {\n <libs_ui-components-buttons-button\n [type]=\"fieldConfig?.buttonDropDown()?.type || 'button-primary'\"\n [sizeButton]=\"fieldConfig?.buttonDropDown()?.sizeButton || 'smaller'\"\n [disable]=\"fieldConfig?.buttonDropDown()?.disable ?? (item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getDisable:item() | async)\"\n [label]=\"fieldConfig?.buttonDropDown()?.label || ' '\"\n [classIconLeft]=\"fieldConfig?.buttonDropDown()?.classIconLeft || ''\"\n [classIconRight]=\"fieldConfig?.buttonDropDown()?.classIconRight || ''\"\n [popover]=\"fieldConfig?.buttonDropDown()?.popover || {}\"\n [classInclude]=\"fieldConfig?.buttonDropDown()?.classInclude || ''\"\n [ignoreStopPropagationEvent]=\"true\" />\n }\n\n </libs_ui-components-dropdown>\n </div>\n }\n }\n\n @case (\"line-clamp\") {\n <div [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\">\n @if (fieldConfig.lineClampConfig; as lineClampConfig) {\n <libs_ui-components-line_clamp\n [ignoreShowButtonCollapseExpand]=\"lineClampConfig.ignoreShowButtonCollapseExpand ?? true\"\n [showTooltip]=\"lineClampConfig.showTooltip ?? true\"\n [maxHeight]=\"lineClampConfig.maxHeight || 36\"\n [maxWidthPopover]=\"lineClampConfig.maxWidthPopover || 200\"\n [maxHeightPopover]=\"lineClampConfig.maxHeightPopover || 100\"\n [ngClassObject]=\"lineClampConfig.ngClassObject ?? { 'libs-ui-line-clamp-content mo-lib-font-head-5': true }\"\n [isInnerText]=\"lineClampConfig.isInnerText || false\"\n [ignoreStopPropagationTooltipEvent]=\"true\"\n [content]=\"item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item() | async\"\n (click)=\"handlerItemClick($event,fieldConfig,item()[fieldConfig.field])\" />\n }\n </div>\n }\n\n @case (\"shape-style\") {\n <div [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [innerHTML]=\"(item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item())| async | translate | LibsUiPipesSecurityTrustPipe:'html':true | async\"\n (click)=\"handlerItemClick($event,fieldConfig,item()[fieldConfig.field])\">\n </div>\n }\n @default {\n @if (((item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item()) | async | translate); as value) {\n @if (value !==' ') {\n <div [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [innerHTML]=\"value | LibsUiPipesSecurityTrustPipe:'html':true|async\"\n (click)=\"handlerItemClick($event,fieldConfig,item()[fieldConfig.field])\">\n </div>\n }\n }\n }\n }\n } @else {\n @if (fieldConfig.rows) {\n <div class=\"w-full flex relative {{ fieldConfig.rowsTemplateCssWrapper }}\">\n <div class=\"w-full flex absolute {{ fieldConfig.rowsTemplateCssWrapper }}\">\n <libs_ui-components-table-templates class=\"flex w-full\"\n [item]=\"item\"\n [configs]=\"fieldConfig.rows\" />\n </div>\n </div>\n }\n @else {\n <ng-container\n *ngComponentOutlet=\"(item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getComponentOutlet) | async; inputs:{item}\" />\n }\n }\n\n }\n </div>\n }\n }\n </div>\n }\n}\n", styles: [":host{width:100%;height:100%}:host .mo-lib-table-template{color:#071631;font-size:12px;font-weight:400;width:100%;height:inherit}:host .mo-lib-table-template .mo-lib-table-template-buttons-container{visibility:hidden!important}:host .mo-lib-table-template [is-hover=true].mo-lib-table-template-buttons-container{visibility:visible!important}\n"], dependencies: [{ kind: "component", type: LibsUiComponentsTableTemplatesComponent, selector: "libs_ui-components-table-templates", inputs: ["isHover", "configs", "templateCssWrapper", "item"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "component", type: LibsUiComponentsAvatarComponent, selector: "libs_ui-components-avatar", inputs: ["getLastTextAfterSpace", "typeShape", "classInclude", "size", "linkAvatar", "linkAvatarError", "idGenColor", "textAvatar", "classImageInclude"], outputs: ["outAvatarError"] }, { kind: "pipe", type: LibsUiPipesCallFunctionInTemplatePipe, name: "LibsUiPipesCallFunctionInTemplatePipe" }, { kind: "pipe", type: LibsUiPipesSecurityTrustPipe, name: "LibsUiPipesSecurityTrustPipe" }, { kind: "component", type: LibsUiComponentsPopoverComponent, selector: "libs_ui-components-popover,[LibsUiComponentsPopoverDirective]", inputs: ["debugId", "flagMouse", "type", "mode", "config", "ignoreShowPopover", "elementRefCustom", "classInclude", "ignoreHiddenPopoverContentWhenMouseLeave", "ignoreStopPropagationEvent", "ignoreCursorPointerModeLikeClick", "isAddContentToParentDocument", "ignoreClickOutside"], outputs: ["outEvent", "outChangStageFlagMouse", "outEventPopoverContent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsButtonsStatusComponent, selector: "libs_ui-components-buttons-status", inputs: ["config"] }, { kind: "component", type: LibsUiComponentsSwitchComponent, selector: "libs_ui-components-switch", inputs: ["size", "disable", "active"], outputs: ["activeChange", "outSwitch"] }, { kind: "pipe", type: LibsUiPipesCloneObjectPipe, name: "LibsUiPipesCloneObjectPipe" }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsLineClampComponent, selector: "libs_ui-components-line_clamp", inputs: ["content", "lengthLimitDisplay", "maxHeight", "ignoreShowButtonCollapseExpand", "ignoreShowButtonCollapse", "showTooltip", "timeHidePopoverOnMouseout", "maxWidthPopover", "maxHeightPopover", "zIndexPopover", "isInnerText", "classClassLabelButtonCollapseExpand", "classClassIncludeButtonCollapseExpand", "ignoreStopPropagationTooltipEvent", "ngClassObject", "hasBackgroundGradient", "labelButtonViewMore", "labelButtonCollapse", "directionTooltip", "useXssFilter"], outputs: ["outDisplayLineClamp", "outAction", "outClick", "outFunctionControl"] }, { kind: "component", type: LibsUiComponentsDropdownComponent, selector: "libs_ui-components-dropdown", inputs: ["useXssFilter", "popoverElementRefCustom", "classInclude", "ignoreStopPropagationEvent", "flagMouse", "flagMouseContent", "popoverCustomConfig", "isNgContent", "zIndex", "convertItemSelected", "getPopoverItemSelected", "httpRequestDetailItemById", "lengthKeys", "textDisplayWhenNoSelect", "textDisplayWhenMultiSelect", "classIncludeTextDisplayWhenNoSelect", "fieldGetLabel", "labelPopoverConfig", "labelPopoverFullWidth", "hasContentUnitRight", "listSearchNoDataTemplateRef", "fieldGetImage", "imageSize", "typeShape", "fieldGetIcon", "fieldGetTextAvatar", "fieldGetColorAvatar", "classAvatarInclude", "getLastTextAfterSpace", "linkImageError", "showError", "showBorderError", "disable", "readonly", "labelConfig", "listSearchConfig", "isSearchOnline", "listHiddenInputSearch", "listSearchPadding", "listKeySearch", "listDividerClassInclude", "listConfig", "listButtonsOther", "listHasButtonUnSelectOption", "listClickExactly", "listBackgroundCustom", "listMaxItemShow", "listKeySelected", "listMultiKeySelected", "listKeysDisable", "listKeysHidden", "validRequired", "validMaxItemSelected", "changeValidUndefinedResetError", "allowSelectItemMultiple", "focusInputSearch", "onlyEmitDataWhenReset", "resetKeyWhenSelectAllKey", "listConfigHasDivider", "classIncludeIcon", "classIncludeContent", "listIgnoreClassDisableDefaultWhenUseKeysDisableItem", "tabKeyActive", "tabsConfig", "ignoreBorderBottom"], outputs: ["flagMouseChange", "flagMouseContentChange", "lengthKeysChange", "showBorderErrorChange", "listKeySelectedChange", "listMultiKeySelectedChange", "tabKeyActiveChange", "outSelectKey", "outSelectMultiKey", "outFunctionsControl", "outValidEvent", "outChangStageFlagMouse", "outDataChange", "outClickButtonOther", "outShowList", "outChangeTabKeyActive"] }, { kind: "component", type: LibsUiComponentsBadgeComponent, selector: "libs_ui-components-badge", inputs: ["popoverConfig", "active", "count", "mode", "maxCount", "ignoreMarginDefault", "classCircle", "ignoreStopPropagationEvent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
98
+ }
99
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsTableTemplatesComponent, decorators: [{
100
+ type: Component,
101
+ args: [{ selector: 'libs_ui-components-table-templates', standalone: true, imports: [
102
+ NgStyle, NgClass, TranslateModule, AsyncPipe, NgComponentOutlet,
103
+ LibsUiComponentsAvatarComponent, LibsUiPipesCallFunctionInTemplatePipe,
104
+ LibsUiPipesSecurityTrustPipe, LibsUiComponentsPopoverComponent,
105
+ LibsUiComponentsButtonsStatusComponent, LibsUiComponentsSwitchComponent,
106
+ LibsUiPipesCloneObjectPipe, LibsUiComponentsButtonsButtonComponent,
107
+ LibsUiComponentsLineClampComponent, LibsUiComponentsDropdownComponent,
108
+ LibsUiComponentsBadgeComponent
109
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (configs(); as configs) {\n @if (item(); as item) {\n <div class=\"mo-lib-table-template {{ templateCssWrapper() || '' }}\">\n @for (config of configs; track $index) {\n @if (config.fieldsConfig) {\n <div [class]=\"config.cssWrapper\">\n @for (fieldConfig of config.fieldsConfig; track index;let index = $index;) {\n\n @if (!fieldConfig.rows && !fieldConfig.getComponentOutlet) {\n @switch (fieldConfig.instance) {\n @case (\"tooltip\") {\n @if ((fieldConfig.tooltip || {}); as tooltip) {\n <span LibsUiComponentsPopoverDirective\n [type]=\"tooltip.type || 'text'\"\n [mode]=\"tooltip.mode || 'hover'\"\n [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [classInclude]=\"tooltip.classInclude || ' '\"\n [ignoreShowPopover]=\"tooltip.ignoreShowPopover || false\"\n [config]=\"(fieldConfig.getTooltipConfig ? (item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getTooltipConfig:item() | async) : (tooltip.config | LibsUiPipesCloneObjectPipe)) | translate\"\n [innerHTML]=\" (fieldConfig.field ? item()[fieldConfig.field] : tooltip.dataView) | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item() | async | translate\"\n (outEvent)=\"handlerItemClick($event,fieldConfig,item()[fieldConfig.field])\">\n </span>\n }\n }\n @case (\"image\") {\n @if (((item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getImageSrc:item():isImageError) | async); as linkImage) {\n @if (linkImage !== ' ') {\n <img [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [src]=\"linkImage\"\n (error)=\"handlerImageError($event)\"\n (click)=\"handlerItemClick($event,fieldConfig,item()[fieldConfig.field])\" />\n }\n }\n }\n\n @case (\"avatar\") {\n @if ((item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getAvatarConfig:item()) | async ; as avatarConfig) {\n <libs_ui-components-avatar [typeShape]=\"avatarConfig.typeShape || 'circle'\"\n [classInclude]=\"avatarConfig.classInclude\"\n [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [size]='avatarConfig.size || 32'\n [linkAvatar]=\"avatarConfig.linkAvatar\"\n [linkAvatarError]=\"avatarConfig.linkAvatarError\"\n [idGenColor]=\"avatarConfig.idGenColor\"\n [textAvatar]=\"avatarConfig.textAvatar\"\n [getLastTextAfterSpace]=\"avatarConfig.getLastTextAfterSpace\" />\n }\n }\n\n @case (\"buttons\") {\n @if ((fieldConfig.buttons && fieldConfig.buttons.length) || fieldConfig.getButtonsByItem) {\n <div [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [class.invisible]=\"!isHover() && fieldConfig.showButtonHoverMode\">\n @for (button of (fieldConfig.buttons || (item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getButtonsByItem:item() | async)); track $index) {\n\n <libs_ui-components-buttons-button [type]=\"button().type || 'button-primary'\"\n [sizeButton]=\"button().sizeButton || 'smaller'\"\n [disable]=\"button().disable ?? (item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getDisable:item())\"\n [label]=\"button().label || ' '\"\n [classIconLeft]=\"button().classIconLeft || ''\"\n [classIconRight]=\"button().classIconRight || ''\"\n [popover]=\"button().popover || {}\"\n [classInclude]=\"button().classInclude || ''\"\n [ignorePointerEvent]=\"button().ignorePointerEvent\"\n (outClick)=\"clickButtonAction(button())\" />\n }\n </div>\n }\n }\n\n @case (\"button-status\") {\n <libs_ui-components-buttons-status\n [config]=\"(item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item()) | async\"\n (click)=\"handlerItemClick($event,fieldConfig,item()[fieldConfig.field])\" />\n }\n\n @case (\"switch\") {\n <libs_ui-components-switch\n [active]=\"item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getActiveValueSwitch:item() | async\"\n [disable]=\"item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getDisableValueSwitch:item() | async\"\n (outSwitch)=\"handlerSwitch($event,fieldConfig)\" />\n }\n\n\n @case ((fieldConfig.instance === 'other-action-show-popup' || fieldConfig.instance === 'badge' || fieldConfig.instance === 'button-action-show-popup') ? fieldConfig.instance : '') {\n @if ((item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item() | async) !== ' ') {\n <div [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [class.ml-[8px]]=\"!fieldConfig.ignoreClassMarginLeft\">\n <libs_ui-components-dropdown [isNgContent]=\"true\"\n [popoverCustomConfig]=\"{\n widthByParent:false,\n ignoreArrow: fieldConfig.dropdownConfig?.ignoreArrow || false,\n maxHeight: fieldConfig.dropdownConfig?.maxHeight || 2048,\n paddingLeftItem:fieldConfig.dropdownConfig?.paddingLeftItem ?? true,\n classInclude:fieldConfig.dropdownConfig?.classIncludePopup || 'w-[250px]',\n position: fieldConfig.dropdownConfig?.position || {\n mode:'center',\n distance:0\n }\n }\"\n [zIndex]=\"fieldConfig.dropdownConfig?.zIndex\"\n [listConfig]=\"fieldConfig.dropdownConfig?.getListViewConfig ? ((item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.dropdownConfig?.getListViewConfig:item()) | async):fieldConfig.dropdownConfig?.listViewConfig\"\n [listBackgroundCustom]=\"fieldConfig.dropdownConfig?.listViewBackgroundListCustom\"\n [listMaxItemShow]=\"fieldConfig.dropdownConfig?.listViewMaxItemShow || 5\"\n [listKeysDisable]=\"fieldConfig.dropdownConfig?.listViewKeysDisableItem\"\n (outFunctionsControl)=\"handlerFunctionControl($event, index)\"\n (outSelectKey)=\"handlerSelectItemDropdown(fieldConfig, index,$event)\"\n (outSelectMultiKey)=\"handlerSelectItemsDropdown(fieldConfig, index,$event)\">\n @if (fieldConfig.instance === 'other-action-show-popup') {\n <div\n [innerHtml]=\"(item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item())| async | translate\">\n </div>\n }\n @if (fieldConfig.instance === 'badge' && (item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item() | async) > 0) {\n <libs_ui-components-badge [active]=\"true\"\n [ignoreMarginDefault]=\"true\"\n mode=\"+x\"\n [count]=\"item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item() | async\"\n [maxCount]=\"99\" />\n }\n @if (fieldConfig.instance === 'button-action-show-popup') {\n <libs_ui-components-buttons-button\n [type]=\"fieldConfig?.buttonDropDown()?.type || 'button-primary'\"\n [sizeButton]=\"fieldConfig?.buttonDropDown()?.sizeButton || 'smaller'\"\n [disable]=\"fieldConfig?.buttonDropDown()?.disable ?? (item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getDisable:item() | async)\"\n [label]=\"fieldConfig?.buttonDropDown()?.label || ' '\"\n [classIconLeft]=\"fieldConfig?.buttonDropDown()?.classIconLeft || ''\"\n [classIconRight]=\"fieldConfig?.buttonDropDown()?.classIconRight || ''\"\n [popover]=\"fieldConfig?.buttonDropDown()?.popover || {}\"\n [classInclude]=\"fieldConfig?.buttonDropDown()?.classInclude || ''\"\n [ignoreStopPropagationEvent]=\"true\" />\n }\n\n </libs_ui-components-dropdown>\n </div>\n }\n }\n\n @case (\"line-clamp\") {\n <div [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\">\n @if (fieldConfig.lineClampConfig; as lineClampConfig) {\n <libs_ui-components-line_clamp\n [ignoreShowButtonCollapseExpand]=\"lineClampConfig.ignoreShowButtonCollapseExpand ?? true\"\n [showTooltip]=\"lineClampConfig.showTooltip ?? true\"\n [maxHeight]=\"lineClampConfig.maxHeight || 36\"\n [maxWidthPopover]=\"lineClampConfig.maxWidthPopover || 200\"\n [maxHeightPopover]=\"lineClampConfig.maxHeightPopover || 100\"\n [ngClassObject]=\"lineClampConfig.ngClassObject ?? { 'libs-ui-line-clamp-content mo-lib-font-head-5': true }\"\n [isInnerText]=\"lineClampConfig.isInnerText || false\"\n [ignoreStopPropagationTooltipEvent]=\"true\"\n [content]=\"item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item() | async\"\n (click)=\"handlerItemClick($event,fieldConfig,item()[fieldConfig.field])\" />\n }\n </div>\n }\n\n @case (\"shape-style\") {\n <div [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [innerHTML]=\"(item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item())| async | translate | LibsUiPipesSecurityTrustPipe:'html':true | async\"\n (click)=\"handlerItemClick($event,fieldConfig,item()[fieldConfig.field])\">\n </div>\n }\n @default {\n @if (((item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.parseValue:item()) | async | translate); as value) {\n @if (value !==' ') {\n <div [ngStyle]=\"fieldConfig.ngStyle || {}\"\n [ngClass]=\"fieldConfig.ngClass || {}\"\n [innerHTML]=\"value | LibsUiPipesSecurityTrustPipe:'html':true|async\"\n (click)=\"handlerItemClick($event,fieldConfig,item()[fieldConfig.field])\">\n </div>\n }\n }\n }\n }\n } @else {\n @if (fieldConfig.rows) {\n <div class=\"w-full flex relative {{ fieldConfig.rowsTemplateCssWrapper }}\">\n <div class=\"w-full flex absolute {{ fieldConfig.rowsTemplateCssWrapper }}\">\n <libs_ui-components-table-templates class=\"flex w-full\"\n [item]=\"item\"\n [configs]=\"fieldConfig.rows\" />\n </div>\n </div>\n }\n @else {\n <ng-container\n *ngComponentOutlet=\"(item()[fieldConfig.field] | LibsUiPipesCallFunctionInTemplatePipe:fieldConfig.getComponentOutlet) | async; inputs:{item}\" />\n }\n }\n\n }\n </div>\n }\n }\n </div>\n }\n}\n", styles: [":host{width:100%;height:100%}:host .mo-lib-table-template{color:#071631;font-size:12px;font-weight:400;width:100%;height:inherit}:host .mo-lib-table-template .mo-lib-table-template-buttons-container{visibility:hidden!important}:host .mo-lib-table-template [is-hover=true].mo-lib-table-template-buttons-container{visibility:visible!important}\n"] }]
110
+ }] });
111
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGVzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy90YWJsZS9zcmMvdGVtcGxhdGVzL3RlbXBsYXRlcy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvdGFibGUvc3JjL3RlbXBsYXRlcy90ZW1wbGF0ZXMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsdURBQXVEO0FBQ3ZELE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2pGLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFFLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzdFLE9BQU8sRUFBVyxzQ0FBc0MsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3JHLE9BQU8sRUFBRSxzQ0FBc0MsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQzVGLE9BQU8sRUFBZ0UsaUNBQWlDLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMvSSxPQUFPLEVBQUUsa0NBQWtDLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRixPQUFPLEVBQUUsZ0NBQWdDLEVBQXNCLE1BQU0sNkJBQTZCLENBQUM7QUFDbkcsT0FBTyxFQUFnQiwrQkFBK0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzNGLE9BQU8sRUFBRSxxQ0FBcUMsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBQ2pHLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3pFLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGdC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ckZVLHVDQUF1Qzs0RkFBdkMsdUNBQXVDLHluQkNwQ3BELHd3YUE0TUEsaVpEeEthLHVDQUF1Qyw2SUFWaEQsT0FBTywyRUFBRSxPQUFPLG1GQUFFLGVBQWUsdUZBQUUsU0FBUyw4Q0FBRSxpQkFBaUIsb1BBQy9ELCtCQUErQix3UEFBRSxxQ0FBcUMseUVBQ3RFLDRCQUE0QixxRUFBRSxnQ0FBZ0MscWVBQzlELHNDQUFzQyxrR0FBRSwrQkFBK0IsZ0pBQ3ZFLDBCQUEwQixtRUFBRSxzQ0FBc0MsaWhCQUNsRSxrQ0FBa0MscW5CQUFFLGlDQUFpQyxtekRBQ3JFLDhCQUE4Qjs7NEZBSXJCLHVDQUF1QztrQkFqQm5ELFNBQVM7K0JBRUUsb0NBQW9DLGNBR2xDLElBQUksV0FDUDt3QkFDUCxPQUFPLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsaUJBQWlCO3dCQUMvRCwrQkFBK0IsRUFBRSxxQ0FBcUM7d0JBQ3RFLDRCQUE0QixFQUFFLGdDQUFnQzt3QkFDOUQsc0NBQXNDLEVBQUUsK0JBQStCO3dCQUN2RSwwQkFBMEIsRUFBRSxzQ0FBc0M7d0JBQ2xFLGtDQUFrQyxFQUFFLGlDQUFpQzt3QkFDckUsOEJBQThCO3FCQUMvQixtQkFDZ0IsdUJBQXVCLENBQUMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbmltcG9ydCB7IEFzeW5jUGlwZSwgTmdDbGFzcywgTmdDb21wb25lbnRPdXRsZXQsIE5nU3R5bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgaW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNBdmF0YXJDb21wb25lbnQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWF2YXRhcic7XG5pbXBvcnQgeyBJQnV0dG9uLCBMaWJzVWlDb21wb25lbnRzQnV0dG9uc0J1dHRvbkNvbXBvbmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtYnV0dG9ucy1idXR0b24nO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c0J1dHRvbnNTdGF0dXNDb21wb25lbnQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWJ1dHRvbnMtc3RhdHVzJztcbmltcG9ydCB7IElEcm9wZG93bkZ1bmN0aW9uQ29udHJvbEV2ZW50LCBJRW1pdE11bHRpS2V5LCBJRW1pdFNlbGVjdEtleSwgTGlic1VpQ29tcG9uZW50c0Ryb3Bkb3duQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1kcm9wZG93bic7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzTGluZUNsYW1wQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1saW5lLWNsYW1wJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNQb3BvdmVyQ29tcG9uZW50LCBUWVBFX1BPUE9WRVJfRVZFTlQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLXBvcG92ZXInO1xuaW1wb3J0IHsgSVN3aXRjaEV2ZW50LCBMaWJzVWlDb21wb25lbnRzU3dpdGNoQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1zd2l0Y2gnO1xuaW1wb3J0IHsgTGlic1VpUGlwZXNDYWxsRnVuY3Rpb25JblRlbXBsYXRlUGlwZSB9IGZyb20gJ0BsaWJzLXVpL3BpcGVzLWNhbGwtZnVuY3Rpb24taW4tdGVtcGxhdGUnO1xuaW1wb3J0IHsgTGlic1VpUGlwZXNDbG9uZU9iamVjdFBpcGUgfSBmcm9tICdAbGlicy11aS9waXBlcy1jbG9uZS1vYmplY3QnO1xuaW1wb3J0IHsgTGlic1VpUGlwZXNTZWN1cml0eVRydXN0UGlwZSB9IGZyb20gJ0BsaWJzLXVpL3BpcGVzLXNlY3VyaXR5LXRydXN0JztcbmltcG9ydCB7IGNvbnZlcnRPYmplY3RUb1NpZ25hbCB9IGZyb20gJ0BsaWJzLXVpL3V0aWxzJztcbmltcG9ydCB7IFRyYW5zbGF0ZU1vZHVsZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgVFlQRV9JVEVNX0RBVEFfVEFCTEUgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IElUYWJsZUZpZWxkVGVtcGxhdGVDb25maWcsIElUYWJsZVRlbXBsYXRlQ29uZmlnIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy90ZW1wbGF0ZS1jb25maWcuaW50ZXJmYWNlJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNCYWRnZUNvbXBvbmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtYmFkZ2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9jb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdsaWJzX3VpLWNvbXBvbmVudHMtdGFibGUtdGVtcGxhdGVzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3RlbXBsYXRlcy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3RlbXBsYXRlcy5jb21wb25lbnQuc2NzcyddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgTmdTdHlsZSwgTmdDbGFzcywgVHJhbnNsYXRlTW9kdWxlLCBBc3luY1BpcGUsIE5nQ29tcG9uZW50T3V0bGV0LFxuICAgIExpYnNVaUNvbXBvbmVudHNBdmF0YXJDb21wb25lbnQsIExpYnNVaVBpcGVzQ2FsbEZ1bmN0aW9uSW5UZW1wbGF0ZVBpcGUsXG4gICAgTGlic1VpUGlwZXNTZWN1cml0eVRydXN0UGlwZSwgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJDb21wb25lbnQsXG4gICAgTGlic1VpQ29tcG9uZW50c0J1dHRvbnNTdGF0dXNDb21wb25lbnQsIExpYnNVaUNvbXBvbmVudHNTd2l0Y2hDb21wb25lbnQsXG4gICAgTGlic1VpUGlwZXNDbG9uZU9iamVjdFBpcGUsIExpYnNVaUNvbXBvbmVudHNCdXR0b25zQnV0dG9uQ29tcG9uZW50LFxuICAgIExpYnNVaUNvbXBvbmVudHNMaW5lQ2xhbXBDb21wb25lbnQsIExpYnNVaUNvbXBvbmVudHNEcm9wZG93bkNvbXBvbmVudCxcbiAgICBMaWJzVWlDb21wb25lbnRzQmFkZ2VDb21wb25lbnRcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgTGlic1VpQ29tcG9uZW50c1RhYmxlVGVtcGxhdGVzQ29tcG9uZW50IHtcbiAgcHJpdmF0ZSBsb2NrQ2xpY2shOiBib29sZWFuO1xuICBwcml2YXRlIGZ1bmN0aW9uQ29udHJvbHMgPSBuZXcgTWFwPG51bWJlciwgSURyb3Bkb3duRnVuY3Rpb25Db250cm9sRXZlbnQ+KCk7XG4gIHByb3RlY3RlZCBpc0ltYWdlRXJyb3I6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgcmVhZG9ubHkgaXNIb3ZlciA9IGlucHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IGNvbmZpZ3MgPSBpbnB1dDxBcnJheTxJVGFibGVUZW1wbGF0ZUNvbmZpZz4+KCk7XG4gIHJlYWRvbmx5IHRlbXBsYXRlQ3NzV3JhcHBlciA9IGlucHV0PHN0cmluZz4oKTtcbiAgcmVhZG9ubHkgaXRlbSA9IGlucHV0LnJlcXVpcmVkPFRZUEVfSVRFTV9EQVRBX1RBQkxFPigpO1xuXG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJJdGVtQ2xpY2soZXZlbnQ6IEV2ZW50IHwgVFlQRV9QT1BPVkVSX0VWRU5UIHwgdW5kZWZpbmVkLCBjb25maWc6IElUYWJsZUZpZWxkVGVtcGxhdGVDb25maWcsIGRhdGFGaWVsZDogYW55KSB7XG4gICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgRXZlbnQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBldmVudCA9PT0gJ3N0cmluZycgJiYgZXZlbnQgIT09ICdjbGljaycpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMubG9ja0NsaWNrKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubG9ja0NsaWNrID0gdHJ1ZTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMubG9ja0NsaWNrID0gZmFsc2U7XG4gICAgfSwgMjUwKTtcbiAgICBpZiAoY29uZmlnICYmIGNvbmZpZy5hY3Rpb24pIHtcbiAgICAgIGNvbmZpZy5hY3Rpb24oZGF0YUZpZWxkLCB0aGlzLml0ZW0oKSk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGNsaWNrQnV0dG9uQWN0aW9uKGJ1dHRvbjogSUJ1dHRvbikge1xuICAgIGlmICh0aGlzLmxvY2tDbGljaykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmxvY2tDbGljayA9IHRydWU7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmxvY2tDbGljayA9IGZhbHNlO1xuICAgIH0sIDI1MCk7XG4gICAgYnV0dG9uLmFjdGlvbj8uKHsgaXRlbTogdGhpcy5pdGVtKCkgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaGFuZGxlclN3aXRjaChzd2l0Y2hJdGVtOiBJU3dpdGNoRXZlbnQsIGNvbmZpZzogSVRhYmxlRmllbGRUZW1wbGF0ZUNvbmZpZykge1xuICAgIGlmICh0aGlzLmxvY2tDbGljaykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmxvY2tDbGljayA9IHRydWU7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmxvY2tDbGljayA9IGZhbHNlO1xuICAgIH0sIDI1MCk7XG4gICAgY29uZmlnPy5zd2l0Y2hBY3Rpb24/Lihzd2l0Y2hJdGVtLCB0aGlzLml0ZW0oKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaGFuZGxlclNlbGVjdEl0ZW1Ecm9wZG93bihmaWVsZENvbmZpZzogSVRhYmxlRmllbGRUZW1wbGF0ZUNvbmZpZywgaW5kZXg6IG51bWJlciwgZGF0YT86IElFbWl0U2VsZWN0S2V5KSB7XG4gICAgaWYgKHRoaXMubG9ja0NsaWNrIHx8ICFkYXRhKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubG9ja0NsaWNrID0gdHJ1ZTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMubG9ja0NsaWNrID0gZmFsc2U7XG4gICAgfSwgMjUwKTtcbiAgICBmaWVsZENvbmZpZz8uYWN0aW9uPy4oZGF0YS5rZXksIGRhdGEuaXRlbSwgdGhpcy5pdGVtKCkpO1xuICAgICh0aGlzLmZ1bmN0aW9uQ29udHJvbHM/LmdldChpbmRleCkgYXMgSURyb3Bkb3duRnVuY3Rpb25Db250cm9sRXZlbnQpPy5yZXNldCgpO1xuICAgICh0aGlzLmZ1bmN0aW9uQ29udHJvbHM/LmdldChpbmRleCkgYXMgSURyb3Bkb3duRnVuY3Rpb25Db250cm9sRXZlbnQpPy5yZW1vdmVMaXN0KCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaGFuZGxlclNlbGVjdEl0ZW1zRHJvcGRvd24oZmllbGRDb25maWc6IElUYWJsZUZpZWxkVGVtcGxhdGVDb25maWcsIGluZGV4OiBudW1iZXIsIGRhdGE/OiBJRW1pdE11bHRpS2V5KSB7XG4gICAgaWYgKHRoaXMubG9ja0NsaWNrIHx8ICFkYXRhKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubG9ja0NsaWNrID0gdHJ1ZTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMubG9ja0NsaWNrID0gZmFsc2U7XG4gICAgfSwgMjUwKTtcbiAgICBmaWVsZENvbmZpZz8uYWN0aW9uPy4oZGF0YS5rZXlzLCBjb252ZXJ0T2JqZWN0VG9TaWduYWwoZGF0YS5tYXBLZXlzLCBmYWxzZSksIHRoaXMuaXRlbSgpKTtcbiAgICAodGhpcy5mdW5jdGlvbkNvbnRyb2xzPy5nZXQoaW5kZXgpIGFzIElEcm9wZG93bkZ1bmN0aW9uQ29udHJvbEV2ZW50KT8ucmVzZXQoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVySW1hZ2VFcnJvcihldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmlzSW1hZ2VFcnJvciA9IHRydWU7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaGFuZGxlckZ1bmN0aW9uQ29udHJvbChldmVudDogSURyb3Bkb3duRnVuY3Rpb25Db250cm9sRXZlbnQsIGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLmZ1bmN0aW9uQ29udHJvbHMuc2V0KGluZGV4LCBldmVudCk7XG4gIH1cblxufVxuIiwiQGlmIChjb25maWdzKCk7IGFzIGNvbmZpZ3MpIHtcbiAgQGlmIChpdGVtKCk7IGFzIGl0ZW0pIHtcbiAgICA8ZGl2IGNsYXNzPVwibW8tbGliLXRhYmxlLXRlbXBsYXRlIHt7IHRlbXBsYXRlQ3NzV3JhcHBlcigpIHx8ICcnIH19XCI+XG4gICAgICBAZm9yIChjb25maWcgb2YgY29uZmlnczsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgIEBpZiAoY29uZmlnLmZpZWxkc0NvbmZpZykge1xuICAgICAgICAgIDxkaXYgW2NsYXNzXT1cImNvbmZpZy5jc3NXcmFwcGVyXCI+XG4gICAgICAgICAgICBAZm9yIChmaWVsZENvbmZpZyBvZiBjb25maWcuZmllbGRzQ29uZmlnOyB0cmFjayBpbmRleDtsZXQgaW5kZXggPSAkaW5kZXg7KSB7XG5cbiAgICAgICAgICAgICAgQGlmICghZmllbGRDb25maWcucm93cyAmJiAhZmllbGRDb25maWcuZ2V0Q29tcG9uZW50T3V0bGV0KSB7XG4gICAgICAgICAgICAgICAgQHN3aXRjaCAoZmllbGRDb25maWcuaW5zdGFuY2UpIHtcbiAgICAgICAgICAgICAgICAgIEBjYXNlIChcInRvb2x0aXBcIikge1xuICAgICAgICAgICAgICAgICAgICBAaWYgKChmaWVsZENvbmZpZy50b29sdGlwIHx8IHt9KTsgYXMgdG9vbHRpcCkge1xuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJ0b29sdGlwLnR5cGUgfHwgJ3RleHQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFttb2RlXT1cInRvb2x0aXAubW9kZSB8fCAnaG92ZXInXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cImZpZWxkQ29uZmlnLm5nU3R5bGUgfHwge31cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiZmllbGRDb25maWcubmdDbGFzcyB8fCB7fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NJbmNsdWRlXT1cInRvb2x0aXAuY2xhc3NJbmNsdWRlIHx8ICcgJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaWdub3JlU2hvd1BvcG92ZXJdPVwidG9vbHRpcC5pZ25vcmVTaG93UG9wb3ZlciB8fCBmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY29uZmlnXT1cIihmaWVsZENvbmZpZy5nZXRUb29sdGlwQ29uZmlnID8gKGl0ZW0oKVtmaWVsZENvbmZpZy5maWVsZF0gfCBMaWJzVWlQaXBlc0NhbGxGdW5jdGlvbkluVGVtcGxhdGVQaXBlOmZpZWxkQ29uZmlnLmdldFRvb2x0aXBDb25maWc6aXRlbSgpIHwgYXN5bmMpIDogKHRvb2x0aXAuY29uZmlnIHwgTGlic1VpUGlwZXNDbG9uZU9iamVjdFBpcGUpKSB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJIVE1MXT1cIiAoZmllbGRDb25maWcuZmllbGQgPyBpdGVtKClbZmllbGRDb25maWcuZmllbGRdIDogdG9vbHRpcC5kYXRhVmlldykgfCBMaWJzVWlQaXBlc0NhbGxGdW5jdGlvbkluVGVtcGxhdGVQaXBlOmZpZWxkQ29uZmlnLnBhcnNlVmFsdWU6aXRlbSgpIHwgYXN5bmMgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG91dEV2ZW50KT1cImhhbmRsZXJJdGVtQ2xpY2soJGV2ZW50LGZpZWxkQ29uZmlnLGl0ZW0oKVtmaWVsZENvbmZpZy5maWVsZF0pXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBAY2FzZSAoXCJpbWFnZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoKChpdGVtKClbZmllbGRDb25maWcuZmllbGRdIHwgTGlic1VpUGlwZXNDYWxsRnVuY3Rpb25JblRlbXBsYXRlUGlwZTpmaWVsZENvbmZpZy5nZXRJbWFnZVNyYzppdGVtKCk6aXNJbWFnZUVycm9yKSB8IGFzeW5jKTsgYXMgbGlua0ltYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgQGlmIChsaW5rSW1hZ2UgIT09ICcgJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBbbmdTdHlsZV09XCJmaWVsZENvbmZpZy5uZ1N0eWxlIHx8IHt9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiZmllbGRDb25maWcubmdDbGFzcyB8fCB7fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwibGlua0ltYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yKT1cImhhbmRsZXJJbWFnZUVycm9yKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiaGFuZGxlckl0ZW1DbGljaygkZXZlbnQsZmllbGRDb25maWcsaXRlbSgpW2ZpZWxkQ29uZmlnLmZpZWxkXSlcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICBAY2FzZSAoXCJhdmF0YXJcIikge1xuICAgICAgICAgICAgICAgICAgICBAaWYgKChpdGVtKClbZmllbGRDb25maWcuZmllbGRdIHwgTGlic1VpUGlwZXNDYWxsRnVuY3Rpb25JblRlbXBsYXRlUGlwZTpmaWVsZENvbmZpZy5nZXRBdmF0YXJDb25maWc6aXRlbSgpKSB8IGFzeW5jIDsgYXMgYXZhdGFyQ29uZmlnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1hdmF0YXIgW3R5cGVTaGFwZV09XCJhdmF0YXJDb25maWcudHlwZVNoYXBlIHx8ICdjaXJjbGUnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc0luY2x1ZGVdPVwiYXZhdGFyQ29uZmlnLmNsYXNzSW5jbHVkZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJmaWVsZENvbmZpZy5uZ1N0eWxlIHx8IHt9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImZpZWxkQ29uZmlnLm5nQ2xhc3MgfHwge31cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3NpemVdPSdhdmF0YXJDb25maWcuc2l6ZSB8fCAzMidcbiAgICAgICAgICAgICAgICAgICAgICAgIFtsaW5rQXZhdGFyXT1cImF2YXRhckNvbmZpZy5saW5rQXZhdGFyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtsaW5rQXZhdGFyRXJyb3JdPVwiYXZhdGFyQ29uZmlnLmxpbmtBdmF0YXJFcnJvclwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaWRHZW5Db2xvcl09XCJhdmF0YXJDb25maWcuaWRHZW5Db2xvclwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdGV4dEF2YXRhcl09XCJhdmF0YXJDb25maWcudGV4dEF2YXRhclwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZ2V0TGFzdFRleHRBZnRlclNwYWNlXT1cImF2YXRhckNvbmZpZy5nZXRMYXN0VGV4dEFmdGVyU3BhY2VcIiAvPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIEBjYXNlIChcImJ1dHRvbnNcIikge1xuICAgICAgICAgICAgICAgICAgICBAaWYgKChmaWVsZENvbmZpZy5idXR0b25zICYmIGZpZWxkQ29uZmlnLmJ1dHRvbnMubGVuZ3RoKSB8fCBmaWVsZENvbmZpZy5nZXRCdXR0b25zQnlJdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBbbmdTdHlsZV09XCJmaWVsZENvbmZpZy5uZ1N0eWxlIHx8IHt9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImZpZWxkQ29uZmlnLm5nQ2xhc3MgfHwge31cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmludmlzaWJsZV09XCIhaXNIb3ZlcigpICYmIGZpZWxkQ29uZmlnLnNob3dCdXR0b25Ib3Zlck1vZGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKGJ1dHRvbiBvZiAoZmllbGRDb25maWcuYnV0dG9ucyB8fCAoaXRlbSgpW2ZpZWxkQ29uZmlnLmZpZWxkXSB8IExpYnNVaVBpcGVzQ2FsbEZ1bmN0aW9uSW5UZW1wbGF0ZVBpcGU6ZmllbGRDb25maWcuZ2V0QnV0dG9uc0J5SXRlbTppdGVtKCkgfCBhc3luYykpOyB0cmFjayAkaW5kZXgpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtYnV0dG9uIFt0eXBlXT1cImJ1dHRvbigpLnR5cGUgfHwgJ2J1dHRvbi1wcmltYXJ5J1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NpemVCdXR0b25dPVwiYnV0dG9uKCkuc2l6ZUJ1dHRvbiB8fCAnc21hbGxlcidcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlXT1cImJ1dHRvbigpLmRpc2FibGUgPz8gKGl0ZW0oKVtmaWVsZENvbmZpZy5maWVsZF0gfCBMaWJzVWlQaXBlc0NhbGxGdW5jdGlvbkluVGVtcGxhdGVQaXBlOmZpZWxkQ29uZmlnLmdldERpc2FibGU6aXRlbSgpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2xhYmVsXT1cImJ1dHRvbigpLmxhYmVsIHx8ICcgJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzSWNvbkxlZnRdPVwiYnV0dG9uKCkuY2xhc3NJY29uTGVmdCB8fCAnJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzSWNvblJpZ2h0XT1cImJ1dHRvbigpLmNsYXNzSWNvblJpZ2h0IHx8ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcG9wb3Zlcl09XCJidXR0b24oKS5wb3BvdmVyIHx8IHt9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NJbmNsdWRlXT1cImJ1dHRvbigpLmNsYXNzSW5jbHVkZSB8fCAnJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lnbm9yZVBvaW50ZXJFdmVudF09XCJidXR0b24oKS5pZ25vcmVQb2ludGVyRXZlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvdXRDbGljayk9XCJjbGlja0J1dHRvbkFjdGlvbihidXR0b24oKSlcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIEBjYXNlIChcImJ1dHRvbi1zdGF0dXNcIikge1xuICAgICAgICAgICAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtc3RhdHVzXG4gICAgICAgICAgICAgICAgICAgICAgW2NvbmZpZ109XCIoaXRlbSgpW2ZpZWxkQ29uZmlnLmZpZWxkXSB8IExpYnNVaVBpcGVzQ2FsbEZ1bmN0aW9uSW5UZW1wbGF0ZVBpcGU6ZmllbGRDb25maWcucGFyc2VWYWx1ZTppdGVtKCkpIHwgYXN5bmNcIlxuICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJoYW5kbGVySXRlbUNsaWNrKCRldmVudCxmaWVsZENvbmZpZyxpdGVtKClbZmllbGRDb25maWcuZmllbGRdKVwiIC8+XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIEBjYXNlIChcInN3aXRjaFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtc3dpdGNoXG4gICAgICAgICAgICAgICAgICAgICAgW2FjdGl2ZV09XCJpdGVtKClbZmllbGRDb25maWcuZmllbGRdIHwgTGlic1VpUGlwZXNDYWxsRnVuY3Rpb25JblRlbXBsYXRlUGlwZTpmaWVsZENvbmZpZy5nZXRBY3RpdmVWYWx1ZVN3aXRjaDppdGVtKCkgfCBhc3luY1wiXG4gICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVdPVwiaXRlbSgpW2ZpZWxkQ29uZmlnLmZpZWxkXSB8IExpYnNVaVBpcGVzQ2FsbEZ1bmN0aW9uSW5UZW1wbGF0ZVBpcGU6ZmllbGRDb25maWcuZ2V0RGlzYWJsZVZhbHVlU3dpdGNoOml0ZW0oKSB8IGFzeW5jXCJcbiAgICAgICAgICAgICAgICAgICAgICAob3V0U3dpdGNoKT1cImhhbmRsZXJTd2l0Y2goJGV2ZW50LGZpZWxkQ29uZmlnKVwiIC8+XG4gICAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgICAgQGNhc2UgKChmaWVsZENvbmZpZy5pbnN0YW5jZSA9PT0gJ290aGVyLWFjdGlvbi1zaG93LXBvcHVwJyB8fCBmaWVsZENvbmZpZy5pbnN0YW5jZSA9PT0gJ2JhZGdlJyB8fCBmaWVsZENvbmZpZy5pbnN0YW5jZSA9PT0gJ2J1dHRvbi1hY3Rpb24tc2hvdy1wb3B1cCcpID8gZmllbGRDb25maWcuaW5zdGFuY2UgOiAnJykge1xuICAgICAgICAgICAgICAgICAgICBAaWYgKChpdGVtKClbZmllbGRDb25maWcuZmllbGRdIHwgTGlic1VpUGlwZXNDYWxsRnVuY3Rpb25JblRlbXBsYXRlUGlwZTpmaWVsZENvbmZpZy5wYXJzZVZhbHVlOml0ZW0oKSB8IGFzeW5jKSAhPT0gJyAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBbbmdTdHlsZV09XCJmaWVsZENvbmZpZy5uZ1N0eWxlIHx8IHt9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImZpZWxkQ29uZmlnLm5nQ2xhc3MgfHwge31cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLm1sLVs4cHhdXT1cIiFmaWVsZENvbmZpZy5pZ25vcmVDbGFzc01hcmdpbkxlZnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtZHJvcGRvd24gW2lzTmdDb250ZW50XT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbcG9wb3ZlckN1c3RvbUNvbmZpZ109XCJ7XG4gICAgICAgICAgICAgICAgd2lkdGhCeVBhcmVudDpmYWxzZSxcbiAgICAgICAgICAgICAgICBpZ25vcmVBcnJvdzogZmllbGRDb25maWcuZHJvcGRvd25Db25maWc/Lmlnbm9yZUFycm93IHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1heEhlaWdodDogZmllbGRDb25maWcuZHJvcGRvd25Db25maWc/Lm1heEhlaWdodCB8fCAyMDQ4LFxuICAgICAgICAgICAgICAgIHBhZGRpbmdMZWZ0SXRlbTpmaWVsZENvbmZpZy5kcm9wZG93bkNvbmZpZz8ucGFkZGluZ0xlZnRJdGVtID8/IHRydWUsXG4gICAgICAgICAgICAgICAgY2xhc3NJbmNsdWRlOmZpZWxkQ29uZmlnLmRyb3Bkb3duQ29uZmlnPy5jbGFzc0luY2x1ZGVQb3B1cCB8fCAndy1bMjUwcHhdJyxcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogZmllbGRDb25maWcuZHJvcGRvd25Db25maWc/LnBvc2l0aW9uIHx8IHtcbiAgICAgICAgICAgICAgICAgIG1vZGU6J2NlbnRlcicsXG4gICAgICAgICAgICAgICAgICBkaXN0YW5jZTowXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW3pJbmRleF09XCJmaWVsZENvbmZpZy5kcm9wZG93bkNvbmZpZz8uekluZGV4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2xpc3RDb25maWddPVwiZmllbGRDb25maWcuZHJvcGRvd25Db25maWc/LmdldExpc3RWaWV3Q29uZmlnID8gKChpdGVtKClbZmllbGRDb25maWcuZmllbGRdIHwgTGlic1VpUGlwZXNDYWxsRnVuY3Rpb25JblRlbXBsYXRlUGlwZTpmaWVsZENvbmZpZy5kcm9wZG93bkNvbmZpZz8uZ2V0TGlzdFZpZXdDb25maWc6aXRlbSgpKSB8IGFzeW5jKTpmaWVsZENvbmZpZy5kcm9wZG93bkNvbmZpZz8ubGlzdFZpZXdDb25maWdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbGlzdEJhY2tncm91bmRDdXN0b21dPVwiZmllbGRDb25maWcuZHJvcGRvd25Db25maWc/Lmxpc3RWaWV3QmFja2dyb3VuZExpc3RDdXN0b21cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbGlzdE1heEl0ZW1TaG93XT1cImZpZWxkQ29uZmlnLmRyb3Bkb3duQ29uZmlnPy5saXN0Vmlld01heEl0ZW1TaG93IHx8IDVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbGlzdEtleXNEaXNhYmxlXT1cImZpZWxkQ29uZmlnLmRyb3Bkb3duQ29uZmlnPy5saXN0Vmlld0tleXNEaXNhYmxlSXRlbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChvdXRGdW5jdGlvbnNDb250cm9sKT1cImhhbmRsZXJGdW5jdGlvbkNvbnRyb2woJGV2ZW50LCBpbmRleClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAob3V0U2VsZWN0S2V5KT1cImhhbmRsZXJTZWxlY3RJdGVtRHJvcGRvd24oZmllbGRDb25maWcsIGluZGV4LCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAob3V0U2VsZWN0TXVsdGlLZXkpPVwiaGFuZGxlclNlbGVjdEl0ZW1zRHJvcGRvd24oZmllbGRDb25maWcsIGluZGV4LCRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChmaWVsZENvbmZpZy5pbnN0YW5jZSA9PT0gJ290aGVyLWFjdGlvbi1zaG93LXBvcHVwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbm5lckh0bWxdPVwiKGl0ZW0oKVtmaWVsZENvbmZpZy5maWVsZF0gfCBMaWJzVWlQaXBlc0NhbGxGdW5jdGlvbkluVGVtcGxhdGVQaXBlOmZpZWxkQ29uZmlnLnBhcnNlVmFsdWU6aXRlbSgpKXwgYXN5bmMgfCB0cmFuc2xhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGZpZWxkQ29uZmlnLmluc3RhbmNlID09PSAnYmFkZ2UnICYmIChpdGVtKClbZmllbGRDb25maWcuZmllbGRdIHwgTGlic1VpUGlwZXNDYWxsRnVuY3Rpb25JblRlbXBsYXRlUGlwZTpmaWVsZENvbmZpZy5wYXJzZVZhbHVlOml0ZW0oKSB8IGFzeW5jKSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWJhZGdlIFthY3RpdmVdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWdub3JlTWFyZ2luRGVmYXVsdF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGU9XCIreFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY291bnRdPVwiaXRlbSgpW2ZpZWxkQ29uZmlnLmZpZWxkXSB8IExpYnNVaVBpcGVzQ2FsbEZ1bmN0aW9uSW5UZW1wbGF0ZVBpcGU6ZmllbGRDb25maWcucGFyc2VWYWx1ZTppdGVtKCkgfCBhc3luY1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF4Q291bnRdPVwiOTlcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZmllbGRDb25maWcuaW5zdGFuY2UgPT09ICdidXR0b24tYWN0aW9uLXNob3ctcG9wdXAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1idXR0b25zLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3R5cGVdPVwiZmllbGRDb25maWc/LmJ1dHRvbkRyb3BEb3duKCk/LnR5cGUgfHwgJ2J1dHRvbi1wcmltYXJ5J1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2l6ZUJ1dHRvbl09XCJmaWVsZENvbmZpZz8uYnV0dG9uRHJvcERvd24oKT8uc2l6ZUJ1dHRvbiB8fCAnc21hbGxlcidcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVdPVwiZmllbGRDb25maWc/LmJ1dHRvbkRyb3BEb3duKCk/LmRpc2FibGUgPz8gKGl0ZW0oKVtmaWVsZENvbmZpZy5maWVsZF0gfCBMaWJzVWlQaXBlc0NhbGxGdW5jdGlvbkluVGVtcGxhdGVQaXBlOmZpZWxkQ29uZmlnLmdldERpc2FibGU6aXRlbSgpIHwgYXN5bmMpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsYWJlbF09XCJmaWVsZENvbmZpZz8uYnV0dG9uRHJvcERvd24oKT8ubGFiZWwgfHwgJyAnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc0ljb25MZWZ0XT1cImZpZWxkQ29uZmlnPy5idXR0b25Ecm9wRG93bigpPy5jbGFzc0ljb25MZWZ0IHx8ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc0ljb25SaWdodF09XCJmaWVsZENvbmZpZz8uYnV0dG9uRHJvcERvd24oKT8uY2xhc3NJY29uUmlnaHQgfHwgJydcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BvcG92ZXJdPVwiZmllbGRDb25maWc/LmJ1dHRvbkRyb3BEb3duKCk/LnBvcG92ZXIgfHwge31cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzSW5jbHVkZV09XCJmaWVsZENvbmZpZz8uYnV0dG9uRHJvcERvd24oKT8uY2xhc3NJbmNsdWRlIHx8ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpZ25vcmVTdG9wUHJvcGFnYXRpb25FdmVudF09XCJ0cnVlXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xpYnNfdWktY29tcG9uZW50cy1kcm9wZG93bj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICBAY2FzZSAoXCJsaW5lLWNsYW1wXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBbbmdTdHlsZV09XCJmaWVsZENvbmZpZy5uZ1N0eWxlIHx8IHt9XCJcbiAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJmaWVsZENvbmZpZy5uZ0NsYXNzIHx8IHt9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgQGlmIChmaWVsZENvbmZpZy5saW5lQ2xhbXBDb25maWc7IGFzIGxpbmVDbGFtcENvbmZpZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1saW5lX2NsYW1wXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtpZ25vcmVTaG93QnV0dG9uQ29sbGFwc2VFeHBhbmRdPVwibGluZUNsYW1wQ29uZmlnLmlnbm9yZVNob3dCdXR0b25Db2xsYXBzZUV4cGFuZCA/PyB0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dUb29sdGlwXT1cImxpbmVDbGFtcENvbmZpZy5zaG93VG9vbHRpcCA/PyB0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW21heEhlaWdodF09XCJsaW5lQ2xhbXBDb25maWcubWF4SGVpZ2h0IHx8IDM2XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW21heFdpZHRoUG9wb3Zlcl09XCJsaW5lQ2xhbXBDb25maWcubWF4V2lkdGhQb3BvdmVyIHx8IDIwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhIZWlnaHRQb3BvdmVyXT1cImxpbmVDbGFtcENvbmZpZy5tYXhIZWlnaHRQb3BvdmVyIHx8IDEwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzT2JqZWN0XT1cImxpbmVDbGFtcENvbmZpZy5uZ0NsYXNzT2JqZWN0ID8/IHsgJ2xpYnMtdWktbGluZS1jbGFtcC1jb250ZW50IG1vLWxpYi1mb250LWhlYWQtNSc6IHRydWUgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0lubmVyVGV4dF09XCJsaW5lQ2xhbXBDb25maWcuaXNJbm5lclRleHQgfHwgZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbaWdub3JlU3RvcFByb3BhZ2F0aW9uVG9vbHRpcEV2ZW50XT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY29udGVudF09XCJpdGVtKClbZmllbGRDb25maWcuZmllbGRdIHwgTGlic1VpUGlwZXNDYWxsRnVuY3Rpb25JblRlbXBsYXRlUGlwZTpmaWVsZENvbmZpZy5wYXJzZVZhbHVlOml0ZW0oKSB8IGFzeW5jXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImhhbmRsZXJJdGVtQ2xpY2soJGV2ZW50LGZpZWxkQ29uZmlnLGl0ZW0oKVtmaWVsZENvbmZpZy5maWVsZF0pXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICBAY2FzZSAoXCJzaGFwZS1zdHlsZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgW25nU3R5bGVdPVwiZmllbGRDb25maWcubmdTdHlsZSB8fCB7fVwiXG4gICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiZmllbGRDb25maWcubmdDbGFzcyB8fCB7fVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2lubmVySFRNTF09XCIoaXRlbSgpW2ZpZWxkQ29uZmlnLmZpZWxkXSB8IExpYnNVaVBpcGVzQ2FsbEZ1bmN0aW9uSW5UZW1wbGF0ZVBpcGU6ZmllbGRDb25maWcucGFyc2VWYWx1ZTppdGVtKCkpfCBhc3luYyB8IHRyYW5zbGF0ZSB8IExpYnNVaVBpcGVzU2VjdXJpdHlUcnVzdFBpcGU6J2h0bWwnOnRydWUgfCBhc3luY1wiXG4gICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImhhbmRsZXJJdGVtQ2xpY2soJGV2ZW50LGZpZWxkQ29uZmlnLGl0ZW0oKVtmaWVsZENvbmZpZy5maWVsZF0pXCI+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgQGRlZmF1bHQge1xuICAgICAgICAgICAgICAgICAgICBAaWYgKCgoaXRlbSgpW2ZpZWxkQ29uZmlnLmZpZWxkXSB8IExpYnNVaVBpcGVzQ2FsbEZ1bmN0aW9uSW5UZW1wbGF0ZVBpcGU6ZmllbGRDb25maWcucGFyc2VWYWx1ZTppdGVtKCkpIHwgYXN5bmMgfCB0cmFuc2xhdGUpOyBhcyB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgIEBpZiAodmFsdWUgIT09JyAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtuZ1N0eWxlXT1cImZpZWxkQ29uZmlnLm5nU3R5bGUgfHwge31cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJmaWVsZENvbmZpZy5uZ0NsYXNzIHx8IHt9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2lubmVySFRNTF09XCJ2YWx1ZSB8IExpYnNVaVBpcGVzU2VjdXJpdHlUcnVzdFBpcGU6J2h0bWwnOnRydWV8YXN5bmNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiaGFuZGxlckl0ZW1DbGljaygkZXZlbnQsZmllbGRDb25maWcsaXRlbSgpW2ZpZWxkQ29uZmlnLmZpZWxkXSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgQGlmIChmaWVsZENvbmZpZy5yb3dzKSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy1mdWxsIGZsZXggcmVsYXRpdmUge3sgZmllbGRDb25maWcucm93c1RlbXBsYXRlQ3NzV3JhcHBlciB9fVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy1mdWxsIGZsZXggYWJzb2x1dGUgIHt7IGZpZWxkQ29uZmlnLnJvd3NUZW1wbGF0ZUNzc1dyYXBwZXIgfX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLXRhYmxlLXRlbXBsYXRlcyBjbGFzcz1cImZsZXggdy1mdWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtpdGVtXT1cIml0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NvbmZpZ3NdPVwiZmllbGRDb25maWcucm93c1wiIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgKm5nQ29tcG9uZW50T3V0bGV0PVwiKGl0ZW0oKVtmaWVsZENvbmZpZy5maWVsZF0gfCBMaWJzVWlQaXBlc0NhbGxGdW5jdGlvbkluVGVtcGxhdGVQaXBlOmZpZWxkQ29uZmlnLmdldENvbXBvbmVudE91dGxldCkgfCBhc3luYzsgaW5wdXRzOntpdGVtfVwiIC8+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgfVxuICAgIDwvZGl2PlxuICB9XG59XG4iXX0=