ngx-bimplus-components 0.0.160 → 0.0.162

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 (162) hide show
  1. package/assets/images/default/Attachment_18_gray.svg +1 -0
  2. package/assets/images/default/Attachment_18_maincolor.svg +3 -0
  3. package/assets/images/default/Attachmentlink_18_gray.svg +7 -0
  4. package/assets/images/default/Attachmentlink_18_maincolor.svg +7 -0
  5. package/assets/images/default/Calendar_18.svg +4 -0
  6. package/assets/images/default/Calendar_18_disabled.svg +1 -0
  7. package/assets/images/default/Calendar_18_gray.svg +1 -0
  8. package/assets/images/default/Comments_18_gray.svg +1 -0
  9. package/assets/images/default/Comments_18_maincolor.svg +4 -0
  10. package/assets/images/default/Links_18_gray.svg +1 -0
  11. package/assets/images/default/Links_18_maincolor.svg +4 -0
  12. package/assets/images/default/Refresh_18_gray.svg +1 -0
  13. package/assets/images/default/bimplus_WebIcons_Cross_Disabled.svg +1 -0
  14. package/assets/images/default/ic_models.svg +3 -0
  15. package/assets/images/default/ic_models_maincolor.svg +3 -0
  16. package/assets/images/default/icn_grid_attachments.png +0 -0
  17. package/assets/images/default/icn_grid_hyperlinks.png +0 -0
  18. package/assets/images/default/progress-spinner.svg +1 -0
  19. package/esm2022/lib/components/bimplus-attachments/bimplus-attachments.component.mjs +114 -0
  20. package/esm2022/lib/components/bimplus-attachments/bimplus-attachments.interface.mjs +38 -0
  21. package/esm2022/lib/components/bimplus-attachments/components/bimplus-attachment-item/bimplus-attachment-item.component.mjs +95 -0
  22. package/esm2022/lib/components/bimplus-attachments/services/bimplus-attachments.service.mjs +32 -0
  23. package/esm2022/lib/components/bimplus-buttons-row/bimplus-buttons-row.component.mjs +40 -5
  24. package/esm2022/lib/components/bimplus-buttons-row/bimplus-buttons-row.interface.mjs +5 -2
  25. package/esm2022/lib/components/bimplus-comment/IComment.mjs +2 -0
  26. package/esm2022/lib/components/bimplus-comment/bimplus-comment.component.mjs +118 -0
  27. package/esm2022/lib/components/bimplus-connection-designer/bimplus-connection-designer.component.mjs +5 -5
  28. package/esm2022/lib/components/bimplus-connection-designer-results/bimplus-connection-designer-results.component.mjs +3 -3
  29. package/esm2022/lib/components/bimplus-flat-tree/bimplus-flat-tree.component.mjs +115 -7
  30. package/esm2022/lib/components/bimplus-flat-tree/bimplus-flat-tree.interface.mjs +1 -1
  31. package/esm2022/lib/components/bimplus-floating-bar-header-logo/bimplus-floating-bar-header-logo.component.mjs +1 -1
  32. package/esm2022/lib/components/bimplus-general-overlay-dialog/bimplus-general-dialog-config-settings.mjs +1 -1
  33. package/esm2022/lib/components/bimplus-general-overlay-dialog/bimplus-general-overlay-dialog.component.mjs +3 -3
  34. package/esm2022/lib/components/bimplus-input-checkbox/bimplus-input-checkbox.component.mjs +64 -0
  35. package/esm2022/lib/components/bimplus-input-combobox/bimplus-input-combobox.component.mjs +161 -0
  36. package/esm2022/lib/components/bimplus-input-date/bimplus-input-date.component.mjs +271 -0
  37. package/esm2022/lib/components/bimplus-input-number/bimplus-input-number.component.mjs +85 -0
  38. package/esm2022/lib/components/bimplus-input-text-field/bimplus-input-text-field.component.mjs +92 -0
  39. package/esm2022/lib/components/bimplus-link-tooltip-message/bimplus-link-tooltip-message.component.mjs +78 -0
  40. package/esm2022/lib/components/bimplus-object-comments-list/bimplus-object-comments-list.component.mjs +388 -0
  41. package/esm2022/lib/components/bimplus-object-comments-list/bimplus-object-comments-list.interface.mjs +3 -0
  42. package/esm2022/lib/components/bimplus-object-comments-list/bimplus-object-comments-list.service.mjs +104 -0
  43. package/esm2022/lib/components/bimplus-object-comments-list/bimplusObjectCommentsI.mjs +2 -0
  44. package/esm2022/lib/components/bimplus-object-complex-properties/bimplus-object-complex-properties.component.mjs +3 -3
  45. package/esm2022/lib/components/bimplus-object-navigator/bimplus-object-navigator.component.mjs +6 -3
  46. package/esm2022/lib/components/bimplus-object-navigator/criteria-select-object-properties/criteria-select-object-properties.component.mjs +3 -3
  47. package/esm2022/lib/components/bimplus-object-navigator/criteria-select-object-properties/criteria-select-object-properties.interface.mjs +1 -1
  48. package/esm2022/lib/components/bimplus-object-navigator/object-filter-result/object-filter-result.component.mjs +3 -3
  49. package/esm2022/lib/components/bimplus-object-structure/bimplus-object-structure.component.mjs +42 -4
  50. package/esm2022/lib/components/bimplus-object-structure/bimplus-object-structure.interface.mjs +4 -2
  51. package/esm2022/lib/components/bimplus-overlay-dialog-confirm/bimplus-overlay-dialog-confirm.component.mjs +77 -0
  52. package/esm2022/lib/components/bimplus-overlay-dialog-delete/bimplus-overlay-dialog-delete.component.mjs +83 -0
  53. package/esm2022/lib/components/bimplus-overlay-dialog-error/bimplus-overlay-dialog-error.component.mjs +31 -8
  54. package/esm2022/lib/components/bimplus-overlay-dialog-warning/bimplus-overlay-dialog-warning.component.mjs +34 -8
  55. package/esm2022/lib/components/bimplus-scrollable-container/bimplus-scrollable-container.component.mjs +1 -1
  56. package/esm2022/lib/components/bimplus-status-bar/bimplus-status-bar.component.mjs +35 -0
  57. package/esm2022/lib/components/bimplus-status-bar/bimplus-status-bar.service.mjs +35 -0
  58. package/esm2022/lib/components/bimplus-status-bar/statusBar.mjs +2 -0
  59. package/esm2022/lib/components/bimplus-tabs-switcher/bimplus-tabs-switcher.component.mjs +38 -0
  60. package/esm2022/lib/components/bimplus-tabs-switcher/bimplus-tabs-switcher.interface.mjs +10 -0
  61. package/esm2022/lib/components/bimplus-tabs-switcher/components/bimplus-tab/bimplus-tab.component.mjs +89 -0
  62. package/esm2022/lib/components/bimplus-tabs-switcher/services/bimplus-tabs-switcher.service.mjs +33 -0
  63. package/esm2022/lib/components/bimplus-textarea/autoResizeTextarea.directive.mjs +83 -0
  64. package/esm2022/lib/components/bimplus-textarea/bimplus-textarea.component.mjs +128 -0
  65. package/esm2022/lib/components/links-to-documents/links-to-documents.component.mjs +376 -0
  66. package/esm2022/lib/components/object-hyperlinks/object-hyperlinks.component.mjs +145 -0
  67. package/esm2022/lib/components/object-hyperlinks-item/object-hyperlinks-item.component.mjs +36 -0
  68. package/esm2022/lib/components/object-preview/object-preview.component.mjs +284 -0
  69. package/esm2022/lib/components/object-preview/object-preview.interface.mjs +2 -0
  70. package/esm2022/lib/components/object-properties/object-properties.component.mjs +545 -0
  71. package/esm2022/lib/components/object-properties/object-properties.interface.mjs +2 -0
  72. package/esm2022/lib/components/object-properties/object-properties.service.mjs +26 -0
  73. package/esm2022/lib/components/object-properties-group/object-properties-group.component.mjs +129 -0
  74. package/esm2022/lib/components/object-properties-group/object-property-value/object-property-value.component.mjs +55 -0
  75. package/esm2022/lib/components/object-properties-header/object-properties-header.component.mjs +48 -6
  76. package/esm2022/lib/components/object-properties-header/object-properties-header.interface.mjs +1 -1
  77. package/esm2022/lib/components/resizable-panel/resizable-panel.component.mjs +54 -10
  78. package/esm2022/lib/pipes/bit-converter.pipe.mjs +46 -0
  79. package/esm2022/lib/pipes/get-attribute-value-as-string.pipe.mjs +173 -0
  80. package/esm2022/lib/pipes/get-attribute-value.pipe.mjs +156 -0
  81. package/esm2022/lib/pipes/round.pipe.mjs +20 -0
  82. package/esm2022/lib/services/decorators.service.mjs +65 -0
  83. package/esm2022/lib/utils/objectProperties.mjs +9 -0
  84. package/esm2022/lib/validators/double-enum.validator.mjs +20 -0
  85. package/esm2022/lib/validators/double.validator.mjs +23 -0
  86. package/esm2022/lib/validators/guid-enum.validator.mjs +20 -0
  87. package/esm2022/lib/validators/guid.validator.mjs +14 -0
  88. package/esm2022/lib/validators/integer.validator.mjs +23 -0
  89. package/esm2022/lib/validators/string-combobox.validator.mjs +20 -0
  90. package/esm2022/lib/validators/string-enum.validator.mjs +20 -0
  91. package/esm2022/public-api.mjs +22 -1
  92. package/fesm2022/ngx-bimplus-components.mjs +4618 -80
  93. package/fesm2022/ngx-bimplus-components.mjs.map +1 -1
  94. package/lib/components/bimplus-attachments/bimplus-attachments.component.d.ts +39 -0
  95. package/lib/components/bimplus-attachments/bimplus-attachments.interface.d.ts +33 -0
  96. package/lib/components/bimplus-attachments/components/bimplus-attachment-item/bimplus-attachment-item.component.d.ts +30 -0
  97. package/lib/components/bimplus-attachments/services/bimplus-attachments.service.d.ts +8 -0
  98. package/lib/components/bimplus-buttons-row/bimplus-buttons-row.component.d.ts +14 -3
  99. package/lib/components/bimplus-buttons-row/bimplus-buttons-row.interface.d.ts +7 -1
  100. package/lib/components/bimplus-comment/IComment.d.ts +4 -0
  101. package/lib/components/bimplus-comment/bimplus-comment.component.d.ts +39 -0
  102. package/lib/components/bimplus-flat-tree/bimplus-flat-tree.component.d.ts +16 -3
  103. package/lib/components/bimplus-flat-tree/bimplus-flat-tree.interface.d.ts +4 -0
  104. package/lib/components/bimplus-floating-bar-header-logo/bimplus-floating-bar-header-logo.component.d.ts +1 -1
  105. package/lib/components/bimplus-general-overlay-dialog/bimplus-general-dialog-config-settings.d.ts +3 -3
  106. package/lib/components/bimplus-input-checkbox/bimplus-input-checkbox.component.d.ts +18 -0
  107. package/lib/components/bimplus-input-combobox/bimplus-input-combobox.component.d.ts +41 -0
  108. package/lib/components/bimplus-input-date/bimplus-input-date.component.d.ts +46 -0
  109. package/lib/components/bimplus-input-number/bimplus-input-number.component.d.ts +26 -0
  110. package/lib/components/bimplus-input-text-field/bimplus-input-text-field.component.d.ts +28 -0
  111. package/lib/components/bimplus-link-tooltip-message/bimplus-link-tooltip-message.component.d.ts +22 -0
  112. package/lib/components/bimplus-object-comments-list/bimplus-object-comments-list.component.d.ts +88 -0
  113. package/lib/components/bimplus-object-comments-list/bimplus-object-comments-list.interface.d.ts +10 -0
  114. package/lib/components/bimplus-object-comments-list/bimplus-object-comments-list.service.d.ts +20 -0
  115. package/lib/components/bimplus-object-comments-list/bimplusObjectCommentsI.d.ts +11 -0
  116. package/lib/components/bimplus-object-navigator/bimplus-object-navigator.component.d.ts +2 -1
  117. package/lib/components/bimplus-object-navigator/criteria-select-object-properties/criteria-select-object-properties.component.d.ts +12 -12
  118. package/lib/components/bimplus-object-navigator/criteria-select-object-properties/criteria-select-object-properties.interface.d.ts +3 -3
  119. package/lib/components/bimplus-object-structure/bimplus-object-structure.component.d.ts +5 -1
  120. package/lib/components/bimplus-object-structure/bimplus-object-structure.interface.d.ts +2 -0
  121. package/lib/components/bimplus-overlay-dialog-confirm/bimplus-overlay-dialog-confirm.component.d.ts +29 -0
  122. package/lib/components/bimplus-overlay-dialog-delete/bimplus-overlay-dialog-delete.component.d.ts +24 -0
  123. package/lib/components/bimplus-overlay-dialog-error/bimplus-overlay-dialog-error.component.d.ts +8 -1
  124. package/lib/components/bimplus-overlay-dialog-warning/bimplus-overlay-dialog-warning.component.d.ts +11 -1
  125. package/lib/components/bimplus-scrollable-container/bimplus-scrollable-container.component.d.ts +1 -1
  126. package/lib/components/bimplus-status-bar/bimplus-status-bar.component.d.ts +14 -0
  127. package/lib/components/bimplus-status-bar/bimplus-status-bar.service.d.ts +14 -0
  128. package/lib/components/bimplus-status-bar/statusBar.d.ts +4 -0
  129. package/lib/components/bimplus-tabs-switcher/bimplus-tabs-switcher.component.d.ts +16 -0
  130. package/lib/components/bimplus-tabs-switcher/bimplus-tabs-switcher.interface.d.ts +18 -0
  131. package/lib/components/bimplus-tabs-switcher/components/bimplus-tab/bimplus-tab.component.d.ts +36 -0
  132. package/lib/components/bimplus-tabs-switcher/services/bimplus-tabs-switcher.service.d.ts +15 -0
  133. package/lib/components/bimplus-textarea/autoResizeTextarea.directive.d.ts +24 -0
  134. package/lib/components/bimplus-textarea/bimplus-textarea.component.d.ts +42 -0
  135. package/lib/components/links-to-documents/links-to-documents.component.d.ts +69 -0
  136. package/lib/components/object-hyperlinks/object-hyperlinks.component.d.ts +32 -0
  137. package/lib/components/object-hyperlinks-item/object-hyperlinks-item.component.d.ts +15 -0
  138. package/lib/components/object-preview/object-preview.component.d.ts +45 -0
  139. package/lib/components/object-preview/object-preview.interface.d.ts +5 -0
  140. package/lib/components/object-properties/object-properties.component.d.ts +79 -0
  141. package/lib/components/object-properties/object-properties.interface.d.ts +22 -0
  142. package/lib/components/object-properties/object-properties.service.d.ts +12 -0
  143. package/lib/components/object-properties-group/object-properties-group.component.d.ts +30 -0
  144. package/lib/components/object-properties-group/object-property-value/object-property-value.component.d.ts +14 -0
  145. package/lib/components/object-properties-header/object-properties-header.component.d.ts +13 -4
  146. package/lib/components/object-properties-header/object-properties-header.interface.d.ts +8 -0
  147. package/lib/components/resizable-panel/resizable-panel.component.d.ts +12 -3
  148. package/lib/pipes/bit-converter.pipe.d.ts +17 -0
  149. package/lib/pipes/get-attribute-value-as-string.pipe.d.ts +35 -0
  150. package/lib/pipes/get-attribute-value.pipe.d.ts +35 -0
  151. package/lib/pipes/round.pipe.d.ts +7 -0
  152. package/lib/services/decorators.service.d.ts +12 -0
  153. package/lib/utils/objectProperties.d.ts +2 -0
  154. package/lib/validators/double-enum.validator.d.ts +2 -0
  155. package/lib/validators/double.validator.d.ts +2 -0
  156. package/lib/validators/guid-enum.validator.d.ts +2 -0
  157. package/lib/validators/guid.validator.d.ts +2 -0
  158. package/lib/validators/integer.validator.d.ts +2 -0
  159. package/lib/validators/string-combobox.validator.d.ts +2 -0
  160. package/lib/validators/string-enum.validator.d.ts +2 -0
  161. package/package.json +14 -4
  162. package/public-api.d.ts +21 -0
@@ -0,0 +1,545 @@
1
+ import { Component, ViewEncapsulation, Input, signal, EventEmitter, Output } from '@angular/core';
2
+ import { ExpansionPanelComponent } from '../expansion-panel/expansion-panel.component';
3
+ import { ExpansionPanelHeaderComponent } from '../expansion-panel-header/expansion-panel-header.component';
4
+ import { BimplusLocalizedWidgetComponent } from '../bimplus-localized-widget/bimplus-localized-widget.component';
5
+ import { TranslateModule } from '@ngx-translate/core';
6
+ import { ObjectStructureNodeBuilder, } from '../bimplus-object-structure/bimplus-object-structure.interface';
7
+ import { from, BehaviorSubject } from 'rxjs';
8
+ import { BimplusObjectStructureComponent } from '../bimplus-object-structure/bimplus-object-structure.component';
9
+ import { ComplexPropertiesNodeBuilder, } from '../bimplus-object-complex-properties/bimplus-object-complex-properties.interface';
10
+ import { BimplusObjectComplexPropertiesComponent } from '../bimplus-object-complex-properties/bimplus-object-complex-properties.component';
11
+ import { BimplusButtonsRowComponent } from '../bimplus-buttons-row/bimplus-buttons-row.component';
12
+ import { BimplusScrollableContainerComponent } from '../bimplus-scrollable-container/bimplus-scrollable-container.component';
13
+ import { ObjectPropertiesGroupComponent } from '../object-properties-group/object-properties-group.component';
14
+ import { isObjectPropertyValueBlank } from '../../utils/objectProperties';
15
+ import { FormGroup, ReactiveFormsModule, FormControl, Validators } from '@angular/forms';
16
+ import { GetAttributeValue } from '../../pipes/get-attribute-value.pipe';
17
+ import { doubleValidator } from '../../validators/double.validator';
18
+ import { integerValidator } from '../../validators/integer.validator';
19
+ import { guidValidator } from '../../validators/guid.validator';
20
+ import { doubleEnumValidator } from '../../validators/double-enum.validator';
21
+ import { ObjectPreviewComponent } from "../object-preview/object-preview.component";
22
+ import { guidEnumValidator } from '../../validators/guid-enum.validator';
23
+ import { stringEnumValidator } from '../../validators/string-enum.validator';
24
+ import { stringComboboxValidator } from '../../validators/string-combobox.validator';
25
+ import * as i0 from "@angular/core";
26
+ import * as i1 from "@ngx-translate/core";
27
+ import * as i2 from "@angular/forms";
28
+ import * as i3 from "./object-properties.service";
29
+ export class ObjectPropertiesComponent extends BimplusLocalizedWidgetComponent {
30
+ _objectPropertiesGroupForm(group_name) {
31
+ const _groupForm = this._objectPropertiesForm;
32
+ return _groupForm.controls[group_name];
33
+ }
34
+ constructor(translateService, formBuilder, cdr, objectPropertiesService) {
35
+ super(translateService);
36
+ this.formBuilder = formBuilder;
37
+ this.cdr = cdr;
38
+ this.objectPropertiesService = objectPropertiesService;
39
+ this._objectPropertiesForm = new FormGroup({});
40
+ this._editMode = signal(false);
41
+ this._objectStructure = null;
42
+ this._complexProperties = null;
43
+ this.api = null;
44
+ this.revision = undefined;
45
+ this._canUpdateObject = signal(false);
46
+ this._rootObjectId = "";
47
+ this.isSaveButtonDisabled$ = new BehaviorSubject(true);
48
+ this.visibleNodeSignal = signal({ id: "", visible: false, opaque: false });
49
+ this.opaqueNodeSignal = signal({ id: "", visible: false, opaque: false });
50
+ this._currentObjectId$ = new BehaviorSubject("");
51
+ this._currentPropertiesObjectId$ = new BehaviorSubject("");
52
+ this.buttonRowItems = [];
53
+ this.configEditProperties = [];
54
+ this.configEditedProperties = [];
55
+ this.updatedObjectProperties = new EventEmitter();
56
+ this.objectAttributeGroups = signal([]);
57
+ this.initialFormValues = "";
58
+ }
59
+ get objectStructure() {
60
+ return this._objectStructure;
61
+ }
62
+ get complexProperties() {
63
+ return this._complexProperties;
64
+ }
65
+ set canUpdateObject(canUpdateObject) {
66
+ this._canUpdateObject.set(canUpdateObject);
67
+ }
68
+ set rootObjectId(id) {
69
+ if (this._rootObjectId === id) {
70
+ return;
71
+ }
72
+ this._cancelEditingProperties();
73
+ this._currentObjectId$.next(id);
74
+ this._createObjectStructure(id, this.revision);
75
+ this._rootObjectId = id;
76
+ }
77
+ get rootObjectId() {
78
+ return this._rootObjectId;
79
+ }
80
+ _editPropertiesButtonsConfiguration() {
81
+ this.configEditProperties.push({
82
+ id: 'edit-properties',
83
+ title: this.translateService.instant('_Edit_properties'),
84
+ tooltip: this.translateService.instant('_Edit_properties'),
85
+ disabled: !this._canUpdateObject(),
86
+ buttonStyle: 'primary',
87
+ });
88
+ }
89
+ _editedPropertiesButtonsConfiguration() {
90
+ this.configEditedProperties.push({
91
+ id: 'save-changed-properties',
92
+ title: this.translateService.instant('_Save'),
93
+ tooltip: this.translateService.instant('_Save'),
94
+ disabled: this.isSaveButtonDisabled$,
95
+ buttonStyle: 'primary',
96
+ });
97
+ this.configEditedProperties.push({
98
+ id: 'cancel-editing-properties',
99
+ title: this.translateService.instant('_Cancel'),
100
+ tooltip: this.translateService.instant('_Cancel'),
101
+ disabled: false,
102
+ buttonStyle: 'secondary',
103
+ });
104
+ }
105
+ ngOnInit() {
106
+ this._editPropertiesButtonsConfiguration();
107
+ this._editedPropertiesButtonsConfiguration();
108
+ this.buttonRowItems = this.configEditProperties;
109
+ this.subscribeProperties();
110
+ }
111
+ subscribeProperties() {
112
+ this._currentPropertiesObjectId$.subscribe({
113
+ next: (id) => {
114
+ if (id) {
115
+ this._createObjectProperties(id, this.revision);
116
+ }
117
+ },
118
+ });
119
+ this._currentObjectId$.subscribe({
120
+ next: (id) => {
121
+ this._currentPropertiesObjectId$.next(id);
122
+ this._createComplexPropertiestructure(id, this.revision);
123
+ },
124
+ });
125
+ }
126
+ handleObjectStructureNodeSelected(node) {
127
+ console.log(node);
128
+ this._currentObjectId$.next(node.id);
129
+ }
130
+ handleObjectStructureNodeVisible(node) {
131
+ const objNode = {
132
+ id: node.id,
133
+ visible: node.visible,
134
+ opaque: node.opaque
135
+ };
136
+ this.visibleNodeSignal.set(objNode); // Update the signal
137
+ }
138
+ handleObjectStructureNodeOpaque(node) {
139
+ const objNode = {
140
+ id: node.id,
141
+ visible: node.visible,
142
+ opaque: node.opaque
143
+ };
144
+ this.opaqueNodeSignal.set(objNode); // Update the signal
145
+ }
146
+ handleComplexPropertyNodeSelected(node) {
147
+ console.log(node);
148
+ this._currentPropertiesObjectId$.next(node.id);
149
+ }
150
+ _loadObjectStructure(objectId, revision) {
151
+ if (!this.api) {
152
+ return;
153
+ }
154
+ if (!objectId) {
155
+ return;
156
+ }
157
+ return from(this.api.objects.getTopology(objectId, revision, false, false, undefined));
158
+ }
159
+ _createObjectStructure(objectId, revision) {
160
+ this._loadObjectStructure(objectId, revision)?.subscribe({
161
+ next: (structureData) => {
162
+ if (structureData) {
163
+ this._objectStructure =
164
+ ObjectStructureNodeBuilder.createFromResponse(structureData);
165
+ }
166
+ },
167
+ });
168
+ }
169
+ _loadObjectComplexPropertiesStructure(objectId, revision) {
170
+ if (!this.api) {
171
+ return;
172
+ }
173
+ if (!objectId) {
174
+ return;
175
+ }
176
+ return from(this.api.objects.getComplexPropertiesTopology(objectId, revision));
177
+ }
178
+ _createComplexPropertiestructure(objectId, revision) {
179
+ this._loadObjectComplexPropertiesStructure(objectId, revision)?.subscribe({
180
+ next: (structureData) => {
181
+ if (structureData) {
182
+ const complexProps = ComplexPropertiesNodeBuilder.createFromResponse(structureData);
183
+ if (complexProps?.children?.length) {
184
+ this._complexProperties = complexProps;
185
+ }
186
+ else {
187
+ this._complexProperties = null;
188
+ }
189
+ }
190
+ },
191
+ });
192
+ }
193
+ _loadObjectProperties(objectId, revision) {
194
+ if (!this.api) {
195
+ return;
196
+ }
197
+ if (!objectId) {
198
+ return;
199
+ }
200
+ return from(this.api.objects.get(objectId, revision, '8', undefined, false, undefined));
201
+ }
202
+ _createObjectProperties(objectId, revision) {
203
+ this._loadObjectProperties(objectId, revision)?.subscribe({
204
+ // properties response is badly structured, nearly impossible to create class structure from it. Therefore using shortcut
205
+ // any for json response
206
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
207
+ next: (propertiesData) => {
208
+ this.objectPropertiesService.setModel(propertiesData);
209
+ this.objectAttributeGroups.set(this._createAttributeGroupsFromResponse(propertiesData));
210
+ },
211
+ error: () => {
212
+ this.objectAttributeGroups.set([]);
213
+ },
214
+ });
215
+ }
216
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
217
+ _tooltip(attrib) {
218
+ const nameTitle = this.translateService.instant('_Name');
219
+ const name = attrib.name ? attrib.name : '';
220
+ const descriptionTitle = this.translateService.instant('description');
221
+ const description = attrib.description;
222
+ const uuidTitle = this.translateService.instant('_UUID');
223
+ const uuid = attrib.id;
224
+ if (description === null ||
225
+ description === undefined ||
226
+ description === '') {
227
+ return `${nameTitle}: ${name}\n${uuidTitle}: ${uuid}`;
228
+ }
229
+ return `${nameTitle}: ${name}\n${descriptionTitle}: ${description}\n${uuidTitle}: ${uuid}`;
230
+ }
231
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
232
+ _createAttributeGroupsFromResponse(propertiesData) {
233
+ const groups = [];
234
+ let localizedAttribGroups = null;
235
+ if (propertiesData.localizedAttributeGroups) {
236
+ localizedAttribGroups = propertiesData.localizedAttributeGroups;
237
+ }
238
+ if (!propertiesData.attributes) {
239
+ return groups;
240
+ }
241
+ const attribGroups = propertiesData.attributes;
242
+ for (const [groupName, attribsObject] of Object.entries(attribGroups)) {
243
+ const newGroup = {
244
+ name: groupName,
245
+ expanded: false,
246
+ attributes: [],
247
+ };
248
+ if (localizedAttribGroups?.[groupName]) {
249
+ newGroup.name = localizedAttribGroups[groupName];
250
+ }
251
+ if (!attribsObject) {
252
+ continue;
253
+ }
254
+ for (const attrib of Object.values(attribsObject)) {
255
+ const newAttrib = {
256
+ id: attrib.id,
257
+ name: attrib.name,
258
+ description: attrib.description,
259
+ value: attrib.value,
260
+ group: attrib.group,
261
+ type: attrib.type,
262
+ unit: attrib.unit,
263
+ decimal: attrib.decimal,
264
+ control: attrib.control,
265
+ enumdefinition: attrib.enumdefinition,
266
+ isChangeable: attrib.isChangeable,
267
+ tooltip: this._tooltip(attrib),
268
+ minValue: attrib.minValue,
269
+ maxValue: attrib.maxValue,
270
+ };
271
+ newGroup.attributes.push(newAttrib);
272
+ }
273
+ groups.push(newGroup);
274
+ }
275
+ return groups;
276
+ }
277
+ _deleteForm() {
278
+ this._objectPropertiesForm = new FormGroup({});
279
+ }
280
+ _createForm() {
281
+ const _getAttributeValue = new GetAttributeValue();
282
+ const _form = {};
283
+ this.objectAttributeGroups().forEach(groupAttributes => {
284
+ const _form_group = {};
285
+ groupAttributes.attributes.forEach(attribute => {
286
+ if ((typeof attribute.type === 'string' && /^boolean$/i.test(attribute.type)) && !attribute.control) {
287
+ _form_group[attribute.id] = this.formBuilder.control(_getAttributeValue.transform(attribute), attribute.isChangeable ? [Validators.pattern(/^(false|true|0|1)$/i)] : []);
288
+ return;
289
+ }
290
+ if ((typeof attribute.type === 'string' && /^boolean$/i.test(attribute.type))
291
+ && (typeof attribute.control === 'string' && /^checkbox$/i.test(attribute.control))) {
292
+ _form_group[attribute.id] = this.formBuilder.control(_getAttributeValue.transform(attribute));
293
+ return;
294
+ }
295
+ if ((typeof attribute.type === 'string' && /^string$/i.test(attribute.type)) && !attribute.control) {
296
+ _form_group[attribute.id] = this.formBuilder.control(_getAttributeValue.transform(attribute));
297
+ return;
298
+ }
299
+ if ((typeof attribute.type === 'string' && /^double$/i.test(attribute.type)) && !attribute.control) {
300
+ _form_group[attribute.id] = this.formBuilder.control(_getAttributeValue.transform(attribute), attribute.isChangeable ? [doubleValidator(attribute.minValue, attribute.maxValue)] : []);
301
+ return;
302
+ }
303
+ if ((typeof attribute.type === 'string' && /^int(32)?$/i.test(attribute.type)) && !attribute.control) {
304
+ _form_group[attribute.id] = this.formBuilder.control(_getAttributeValue.transform(attribute), attribute.isChangeable ? [integerValidator(attribute.minValue, attribute.maxValue)] : []);
305
+ return;
306
+ }
307
+ if ((typeof attribute.type === 'string' && /^guid$/i.test(attribute.type)) && !attribute.control) {
308
+ _form_group[attribute.id] = this.formBuilder.control(_getAttributeValue.transform(attribute), attribute.isChangeable ? [guidValidator()] : []);
309
+ return;
310
+ }
311
+ if ((typeof attribute.type === 'string' && /^double$/i.test(attribute.type))
312
+ && (typeof attribute.control === 'string' && /^enumeration$/i.test(attribute.control))) {
313
+ _form_group[attribute.id] = this.formBuilder.control(_getAttributeValue.transform(attribute), attribute.isChangeable ? [doubleEnumValidator(attribute.enumdefinition)] : []);
314
+ return;
315
+ }
316
+ if ((typeof attribute.type === 'string' && /^guid$/i.test(attribute.type))
317
+ && (typeof attribute.control === 'string' && /^enumeration$/i.test(attribute.control))) {
318
+ _form_group[attribute.id] = this.formBuilder.control(_getAttributeValue.transform(attribute), attribute.isChangeable ? [guidEnumValidator(attribute.enumdefinition)] : []);
319
+ return;
320
+ }
321
+ if ((typeof attribute.type === 'string' && /^int(32)?$/i.test(attribute.type))
322
+ && (typeof attribute.control === 'string' && /^enumeration$/i.test(attribute.control))) {
323
+ _form_group[attribute.id] = this.formBuilder.control(_getAttributeValue.transform(attribute), attribute.isChangeable ? [doubleEnumValidator(attribute.enumdefinition)] : []);
324
+ return;
325
+ }
326
+ if ((typeof attribute.type === 'string' && /^string$/i.test(attribute.type))
327
+ && (typeof attribute.control === 'string' && /^enumeration$/i.test(attribute.control))) {
328
+ _form_group[attribute.id] = this.formBuilder.control(_getAttributeValue.transform(attribute), attribute.isChangeable ? [stringEnumValidator(attribute.enumdefinition)] : []);
329
+ return;
330
+ }
331
+ if ((typeof attribute.type === 'string' && /^string$/i.test(attribute.type))
332
+ && (typeof attribute.control === 'string' && /^combobox$/i.test(attribute.control))) {
333
+ _form_group[attribute.id] = this.formBuilder.control(_getAttributeValue.transform(attribute), attribute.isChangeable ? [stringComboboxValidator(attribute.enumdefinition)] : []);
334
+ return;
335
+ }
336
+ if ((typeof attribute.type === 'string' && /^datetime$/i.test(attribute.type)) && !attribute.control) {
337
+ _form_group[attribute.id] = this.formBuilder.control(_getAttributeValue.transform(attribute), attribute.isChangeable ? [] : []);
338
+ return;
339
+ }
340
+ });
341
+ _form[groupAttributes.name] = this.formBuilder.group(_form_group);
342
+ });
343
+ this._objectPropertiesForm = this.formBuilder.group(_form);
344
+ this.initialFormValues = JSON.stringify(this._objectPropertiesForm.value);
345
+ this._objectPropertiesForm.valueChanges.subscribe({
346
+ next: (value) => {
347
+ const changed = JSON.stringify(value) !== this.initialFormValues;
348
+ this.isSaveButtonDisabled$.next(!(this._objectPropertiesForm.valid && changed));
349
+ }
350
+ });
351
+ }
352
+ _getPropertyName(uuid) {
353
+ const attrGroups = this.objectAttributeGroups();
354
+ for (const attrGroup of attrGroups) {
355
+ for (const attr of attrGroup.attributes) {
356
+ if (attr.id === uuid) {
357
+ return attr.name;
358
+ }
359
+ }
360
+ }
361
+ return '';
362
+ }
363
+ _getPropertyType(uuid) {
364
+ const attrGroups = this.objectAttributeGroups();
365
+ for (const attrGroup of attrGroups) {
366
+ for (const attr of attrGroup.attributes) {
367
+ if (attr.id === uuid) {
368
+ return attr.type;
369
+ }
370
+ }
371
+ }
372
+ return '';
373
+ }
374
+ _getPropertyControl(uuid) {
375
+ const attrGroups = this.objectAttributeGroups();
376
+ for (const attrGroup of attrGroups) {
377
+ for (const attr of attrGroup.attributes) {
378
+ if (attr.id === uuid) {
379
+ return attr.control;
380
+ }
381
+ }
382
+ }
383
+ return '';
384
+ }
385
+ _convertValueToBoolean(value) {
386
+ return /^true$/i.test(value) || /^1$/i.test(value);
387
+ }
388
+ _convertValueToDouble(value) {
389
+ return parseFloat(value);
390
+ }
391
+ _hasBeenValueChanged(uuid, value) {
392
+ const attrGroups = this.objectAttributeGroups();
393
+ for (const attrGroup of attrGroups) {
394
+ for (const attr of attrGroup.attributes) {
395
+ if (attr.id === uuid) {
396
+ return value !== attr.value;
397
+ }
398
+ }
399
+ }
400
+ return false;
401
+ }
402
+ _getChangedData(formGroup) {
403
+ const changedData = {};
404
+ Object.keys(formGroup.controls).forEach(key => {
405
+ const control = formGroup.get(key);
406
+ if (control instanceof FormControl) {
407
+ // If it's a FormControl and it's dirty, capture the changed value
408
+ if (control.dirty) {
409
+ const propName = this._getPropertyName(key);
410
+ const propType = this._getPropertyType(key);
411
+ // const propControl: string = this._getPropertyControl(key);
412
+ if (propName === '') {
413
+ const _newValue = {
414
+ id: key,
415
+ value: control.value
416
+ };
417
+ changedData[key] = _newValue;
418
+ }
419
+ else {
420
+ if (/^boolean$/i.test(propType)) {
421
+ const _val = this._convertValueToBoolean(control.value);
422
+ if (this._hasBeenValueChanged(key, _val)) {
423
+ const _newValue = {
424
+ id: key,
425
+ value: _val
426
+ };
427
+ changedData[propName] = _newValue;
428
+ }
429
+ }
430
+ else if (/^double$/i.test(propType)) {
431
+ const _val = this._convertValueToDouble(control.value);
432
+ if (this._hasBeenValueChanged(key, _val)) {
433
+ const _newValue = {
434
+ id: key,
435
+ value: _val
436
+ };
437
+ changedData[propName] = _newValue;
438
+ }
439
+ }
440
+ else {
441
+ const _val = control.value;
442
+ if (this._hasBeenValueChanged(key, control.value)) {
443
+ const _newValue = {
444
+ id: key,
445
+ value: _val
446
+ };
447
+ changedData[propName] = _newValue;
448
+ }
449
+ }
450
+ }
451
+ }
452
+ }
453
+ else if (control instanceof FormGroup) {
454
+ if (control.dirty) {
455
+ // Recursively get changed data from nested FormGroup
456
+ const nestedChanges = this._getChangedData(control);
457
+ if (Object.keys(nestedChanges).length > 0) {
458
+ changedData[key] = nestedChanges;
459
+ }
460
+ }
461
+ }
462
+ });
463
+ return changedData;
464
+ }
465
+ _saveObjectProperties() {
466
+ const saveData = {};
467
+ saveData['id'] = this._currentObjectId$.value;
468
+ saveData['unsaved'] = true;
469
+ saveData['attributes'] = this._getChangedData(this._objectPropertiesForm);
470
+ this.saveObjectProperties(saveData);
471
+ }
472
+ _cancelEditingProperties() {
473
+ this._editMode.set(false);
474
+ this._deleteForm();
475
+ this.buttonRowItems = this.configEditProperties;
476
+ }
477
+ buttonClicked($event) {
478
+ if ($event.id === 'edit-properties') {
479
+ this._editMode.set(true);
480
+ this._createForm();
481
+ console.log('Edit properties clicked');
482
+ this.buttonRowItems = this.configEditedProperties;
483
+ }
484
+ if ($event.id === 'save-changed-properties') {
485
+ this._saveObjectProperties();
486
+ this._cancelEditingProperties();
487
+ console.log('Save changed properties clicked');
488
+ }
489
+ if ($event.id === 'cancel-editing-properties') {
490
+ this._cancelEditingProperties();
491
+ console.log('Cancel edit properties clicked');
492
+ }
493
+ }
494
+ hasSetAnyAttribute(objectAttributeGroup) {
495
+ return objectAttributeGroup.attributes.some((attrib) => {
496
+ return !isObjectPropertyValueBlank(attrib);
497
+ });
498
+ }
499
+ saveObjectProperties(data) {
500
+ const selectedObjectId = this._currentPropertiesObjectId$.value;
501
+ if (!data || !selectedObjectId) {
502
+ return;
503
+ }
504
+ if (!this.api) {
505
+ return;
506
+ }
507
+ from(this.api.objects.put(selectedObjectId, JSON.stringify(data))).subscribe({
508
+ next: (response) => {
509
+ this._createObjectProperties(selectedObjectId, this.revision);
510
+ this._createObjectStructure(selectedObjectId, this.revision);
511
+ this.updatedObjectProperties.emit({ id: selectedObjectId, request: data, response });
512
+ },
513
+ });
514
+ }
515
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ObjectPropertiesComponent, deps: [{ token: i1.TranslateService }, { token: i2.FormBuilder }, { token: i0.ChangeDetectorRef }, { token: i3.ObjectPropertiesService }], target: i0.ɵɵFactoryTarget.Component }); }
516
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: ObjectPropertiesComponent, isStandalone: true, selector: "lib-object-properties", inputs: { api: "api", revision: "revision", canUpdateObject: "canUpdateObject", rootObjectId: "rootObjectId" }, outputs: { updatedObjectProperties: "updatedObjectProperties" }, usesInheritance: true, ngImport: i0, template: "<lib-bimplus-buttons-row\r\n [items]=\"buttonRowItems\"\r\n (buttonClicked)=\"buttonClicked($event)\"\r\n/>\r\n\r\n<div class=\"object-properties\">\r\n\r\n <lib-bimplus-scrollable-container>\r\n <lib-expansion-panel class=\"object-properties-preview-panel\">\r\n <lib-expansion-panel-header>\r\n <span class=\"object-structure-header\">{{\"_3D preview\" | translate}}</span>\r\n </lib-expansion-panel-header>\r\n <lib-object-preview \r\n [api]=\"api\" \r\n [revision]=\"revision\" \r\n [objectId]=\"rootObjectId\"\r\n [visibleNode]=\"visibleNodeSignal()\"\t\r\n [opaqueNode]=\"opaqueNodeSignal()\"\r\n />\r\n </lib-expansion-panel>\r\n <!-- Object structure-->\r\n <lib-expansion-panel class=\"object-properties-object-structure-panel\">\r\n <lib-expansion-panel-header>\r\n <span class=\"object-structure-header\">{{\"_Object structure\" | translate}}</span>\r\n </lib-expansion-panel-header>\r\n @if (objectStructure) {\r\n <lib-bimplus-object-structure\r\n [objectStructure]=\"objectStructure\"\r\n (nodeSelected)=\"handleObjectStructureNodeSelected($event)\"\r\n (nodeVisible)= \"handleObjectStructureNodeVisible($event)\"\r\n (nodeOpaque)= \"handleObjectStructureNodeOpaque($event)\" \r\n />\r\n }\r\n </lib-expansion-panel>\r\n <!-- End Object structure-->\r\n\r\n <!-- Complex properties-->\r\n @if(complexProperties){\r\n <lib-expansion-panel>\r\n <lib-expansion-panel-header>\r\n <span class=\"object-properties-header\"> {{\"_Object multiproperties tree\" | translate}}</span>\r\n </lib-expansion-panel-header>\r\n <lib-bimplus-object-complex-properties\r\n [complexProperties]=\"complexProperties\"\r\n (nodeSelected)=\"handleComplexPropertyNodeSelected($event)\"\r\n />\r\n </lib-expansion-panel>\r\n }\r\n <!-- End Complex properties-->\r\n\r\n @if(objectAttributeGroups().length > 0){\r\n <lib-expansion-panel>\r\n <lib-expansion-panel-header>\r\n <span class=\"object-properties-header\">{{\"_Object properties\" | translate}}</span>\r\n </lib-expansion-panel-header>\r\n <form [formGroup]=\"_objectPropertiesForm\" class=\"input-form\">\r\n @for (attribGroup of objectAttributeGroups(); track attribGroup) {\r\n @if(_editMode() || hasSetAnyAttribute(attribGroup)){\r\n <lib-expansion-panel [expanded]=\"attribGroup.expanded\">\r\n <lib-expansion-panel-header>\r\n <span class=\"object-properties-group-header\"> {{attribGroup.name}}</span>\r\n </lib-expansion-panel-header>\r\n <lib-object-properties-group\r\n [attributesGroup]=\"attribGroup\"\r\n [editMode]=\"_editMode()\"\r\n [canUpdateObject]=\"_canUpdateObject()\"\r\n [objectPropertiesForm]=\"_objectPropertiesGroupForm(attribGroup.name)\"\r\n />\r\n </lib-expansion-panel>\r\n }\r\n }\r\n </form>\r\n </lib-expansion-panel>\r\n }\r\n </lib-bimplus-scrollable-container>\r\n</div>\r\n", styles: [":host{height:100%;display:flex;flex-direction:column;flex:1}lib-bimplus-buttons-row{flex:0;--button-row-margin-right: .8rem}.object-properties{margin-left:.8rem;position:relative;flex:1}.object-properties .object-structure-header,.object-properties .object-properties-header{font-weight:700;text-transform:uppercase;font-size:1.4rem}.object-properties .object-properties-group-header{line-height:2.4rem}.object-properties lib-bimplus-object-structure{--bimplus-object-structure-background-color: var(--object-properties-background-color, var(--flat-tree-container-background-color-enabled))}.object-properties lib-bimplus-object-complex-properties{--bimplus-object-complex-properties-background-color: var(--object-properties-background-color, var(--flat-tree-container-background-color-enabled))}.object-properties lib-bimplus-scrollable-container{position:absolute;top:0;bottom:0;flex:1;width:100%}.object-properties .object-properties-object-structure-panel .expansion-panel,.object-properties lib-object-preview{margin-top:.8rem}\n"], dependencies: [{ kind: "component", type: ExpansionPanelComponent, selector: "lib-expansion-panel", inputs: ["expanded"] }, { kind: "component", type: ExpansionPanelHeaderComponent, selector: "lib-expansion-panel-header" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "component", type: BimplusObjectStructureComponent, selector: "lib-bimplus-object-structure", inputs: ["objectStructure"], outputs: ["nodeSelected", "nodeVisible", "nodeOpaque"] }, { kind: "component", type: BimplusObjectComplexPropertiesComponent, selector: "lib-bimplus-object-complex-properties", inputs: ["complexProperties"], outputs: ["nodeSelected"] }, { kind: "component", type: BimplusButtonsRowComponent, selector: "lib-bimplus-buttons-row", inputs: ["items", "isMultiple", "canUpdateObject"], outputs: ["fileChanged", "buttonClicked"] }, { kind: "component", type: BimplusScrollableContainerComponent, selector: "lib-bimplus-scrollable-container" }, { kind: "component", type: ObjectPropertiesGroupComponent, selector: "lib-object-properties-group", inputs: ["editMode", "objectPropertiesForm", "canUpdateObject", "attributesGroup"] }, { kind: "component", type: ObjectPreviewComponent, selector: "lib-object-preview", inputs: ["api", "objectId", "revision", "visibleNode", "opaqueNode"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }], encapsulation: i0.ViewEncapsulation.ShadowDom }); }
517
+ }
518
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ObjectPropertiesComponent, decorators: [{
519
+ type: Component,
520
+ args: [{ selector: 'lib-object-properties', standalone: true, imports: [
521
+ ExpansionPanelComponent,
522
+ ExpansionPanelHeaderComponent,
523
+ TranslateModule,
524
+ BimplusObjectStructureComponent,
525
+ BimplusObjectComplexPropertiesComponent,
526
+ BimplusButtonsRowComponent,
527
+ BimplusScrollableContainerComponent,
528
+ ObjectPropertiesGroupComponent,
529
+ ObjectPropertiesGroupComponent,
530
+ ObjectPreviewComponent,
531
+ ReactiveFormsModule,
532
+ GetAttributeValue
533
+ ], encapsulation: ViewEncapsulation.ShadowDom, template: "<lib-bimplus-buttons-row\r\n [items]=\"buttonRowItems\"\r\n (buttonClicked)=\"buttonClicked($event)\"\r\n/>\r\n\r\n<div class=\"object-properties\">\r\n\r\n <lib-bimplus-scrollable-container>\r\n <lib-expansion-panel class=\"object-properties-preview-panel\">\r\n <lib-expansion-panel-header>\r\n <span class=\"object-structure-header\">{{\"_3D preview\" | translate}}</span>\r\n </lib-expansion-panel-header>\r\n <lib-object-preview \r\n [api]=\"api\" \r\n [revision]=\"revision\" \r\n [objectId]=\"rootObjectId\"\r\n [visibleNode]=\"visibleNodeSignal()\"\t\r\n [opaqueNode]=\"opaqueNodeSignal()\"\r\n />\r\n </lib-expansion-panel>\r\n <!-- Object structure-->\r\n <lib-expansion-panel class=\"object-properties-object-structure-panel\">\r\n <lib-expansion-panel-header>\r\n <span class=\"object-structure-header\">{{\"_Object structure\" | translate}}</span>\r\n </lib-expansion-panel-header>\r\n @if (objectStructure) {\r\n <lib-bimplus-object-structure\r\n [objectStructure]=\"objectStructure\"\r\n (nodeSelected)=\"handleObjectStructureNodeSelected($event)\"\r\n (nodeVisible)= \"handleObjectStructureNodeVisible($event)\"\r\n (nodeOpaque)= \"handleObjectStructureNodeOpaque($event)\" \r\n />\r\n }\r\n </lib-expansion-panel>\r\n <!-- End Object structure-->\r\n\r\n <!-- Complex properties-->\r\n @if(complexProperties){\r\n <lib-expansion-panel>\r\n <lib-expansion-panel-header>\r\n <span class=\"object-properties-header\"> {{\"_Object multiproperties tree\" | translate}}</span>\r\n </lib-expansion-panel-header>\r\n <lib-bimplus-object-complex-properties\r\n [complexProperties]=\"complexProperties\"\r\n (nodeSelected)=\"handleComplexPropertyNodeSelected($event)\"\r\n />\r\n </lib-expansion-panel>\r\n }\r\n <!-- End Complex properties-->\r\n\r\n @if(objectAttributeGroups().length > 0){\r\n <lib-expansion-panel>\r\n <lib-expansion-panel-header>\r\n <span class=\"object-properties-header\">{{\"_Object properties\" | translate}}</span>\r\n </lib-expansion-panel-header>\r\n <form [formGroup]=\"_objectPropertiesForm\" class=\"input-form\">\r\n @for (attribGroup of objectAttributeGroups(); track attribGroup) {\r\n @if(_editMode() || hasSetAnyAttribute(attribGroup)){\r\n <lib-expansion-panel [expanded]=\"attribGroup.expanded\">\r\n <lib-expansion-panel-header>\r\n <span class=\"object-properties-group-header\"> {{attribGroup.name}}</span>\r\n </lib-expansion-panel-header>\r\n <lib-object-properties-group\r\n [attributesGroup]=\"attribGroup\"\r\n [editMode]=\"_editMode()\"\r\n [canUpdateObject]=\"_canUpdateObject()\"\r\n [objectPropertiesForm]=\"_objectPropertiesGroupForm(attribGroup.name)\"\r\n />\r\n </lib-expansion-panel>\r\n }\r\n }\r\n </form>\r\n </lib-expansion-panel>\r\n }\r\n </lib-bimplus-scrollable-container>\r\n</div>\r\n", styles: [":host{height:100%;display:flex;flex-direction:column;flex:1}lib-bimplus-buttons-row{flex:0;--button-row-margin-right: .8rem}.object-properties{margin-left:.8rem;position:relative;flex:1}.object-properties .object-structure-header,.object-properties .object-properties-header{font-weight:700;text-transform:uppercase;font-size:1.4rem}.object-properties .object-properties-group-header{line-height:2.4rem}.object-properties lib-bimplus-object-structure{--bimplus-object-structure-background-color: var(--object-properties-background-color, var(--flat-tree-container-background-color-enabled))}.object-properties lib-bimplus-object-complex-properties{--bimplus-object-complex-properties-background-color: var(--object-properties-background-color, var(--flat-tree-container-background-color-enabled))}.object-properties lib-bimplus-scrollable-container{position:absolute;top:0;bottom:0;flex:1;width:100%}.object-properties .object-properties-object-structure-panel .expansion-panel,.object-properties lib-object-preview{margin-top:.8rem}\n"] }]
534
+ }], ctorParameters: () => [{ type: i1.TranslateService }, { type: i2.FormBuilder }, { type: i0.ChangeDetectorRef }, { type: i3.ObjectPropertiesService }], propDecorators: { api: [{
535
+ type: Input
536
+ }], revision: [{
537
+ type: Input
538
+ }], canUpdateObject: [{
539
+ type: Input
540
+ }], rootObjectId: [{
541
+ type: Input
542
+ }], updatedObjectProperties: [{
543
+ type: Output
544
+ }] } });
545
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JqZWN0LXByb3BlcnRpZXMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWJpbXBsdXMtY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvb2JqZWN0LXByb3BlcnRpZXMvb2JqZWN0LXByb3BlcnRpZXMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWJpbXBsdXMtY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvb2JqZWN0LXByb3BlcnRpZXMvb2JqZWN0LXByb3BlcnRpZXMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDUCxpQkFBaUIsRUFDakIsS0FBSyxFQUVMLE1BQU0sRUFHUixZQUFZLEVBQ1osTUFBTSxFQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQ3ZGLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLDREQUE0RCxDQUFDO0FBQzNHLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLGdFQUFnRSxDQUFDO0FBQ2pILE9BQU8sRUFDTCxlQUFlLEVBRWhCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUVMLDBCQUEwQixHQUMzQixNQUFNLGdFQUFnRSxDQUFDO0FBR3hFLE9BQU8sRUFDTCxJQUFJLEVBQ0YsZUFBZSxFQUNsQixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLGdFQUFnRSxDQUFDO0FBQ2pILE9BQU8sRUFFTCw0QkFBNEIsR0FDN0IsTUFBTSxrRkFBa0YsQ0FBQztBQUMxRixPQUFPLEVBQUUsdUNBQXVDLEVBQUUsTUFBTSxrRkFBa0YsQ0FBQztBQUszSSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxzREFBc0QsQ0FBQztBQUts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LEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZGLENBQUM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDOytHQS9tQlUseUJBQXlCO21HQUF6Qix5QkFBeUIseVJDdEZ0Qyx3c0dBNEVBLHFrQ0RSSSx1QkFBdUIsc0ZBQ3ZCLDZCQUE2QixzRUFDN0IsZUFBZSw0RkFDZiwrQkFBK0IsOEpBQy9CLHVDQUF1Qyw0SUFDdkMsMEJBQTBCLG1LQUMxQixtQ0FBbUMsNkVBQ25DLDhCQUE4Qiw0SkFFOUIsc0JBQXNCLG9JQUN0QixtQkFBbUI7OzRGQVFWLHlCQUF5QjtrQkF0QnJDLFNBQVM7K0JBQ0UsdUJBQXVCLGNBQ3JCLElBQUksV0FDUDt3QkFDUCx1QkFBdUI7d0JBQ3ZCLDZCQUE2Qjt3QkFDN0IsZUFBZTt3QkFDZiwrQkFBK0I7d0JBQy9CLHVDQUF1Qzt3QkFDdkMsMEJBQTBCO3dCQUMxQixtQ0FBbUM7d0JBQ25DLDhCQUE4Qjt3QkFDOUIsOEJBQThCO3dCQUM5QixzQkFBc0I7d0JBQ3RCLG1CQUFtQjt3QkFDbkIsaUJBQWlCO3FCQUNsQixpQkFHYyxpQkFBaUIsQ0FBQyxTQUFTO3FMQW1DakMsR0FBRztzQkFBWCxLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBR08sZUFBZTtzQkFBM0IsS0FBSztnQkFLTyxZQUFZO3NCQUF4QixLQUFLO2dCQTBCSSx1QkFBdUI7c0JBQWhDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudFxyXG4gICwgVmlld0VuY2Fwc3VsYXRpb25cclxuICAsIElucHV0XHJcbiAgLCBPbkluaXRcclxuICAsIHNpZ25hbFxyXG4gICwgV3JpdGFibGVTaWduYWxcclxuICAsIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBPdXRwdXRcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRXhwYW5zaW9uUGFuZWxDb21wb25lbnQgfSBmcm9tICcuLi9leHBhbnNpb24tcGFuZWwvZXhwYW5zaW9uLXBhbmVsLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEV4cGFuc2lvblBhbmVsSGVhZGVyQ29tcG9uZW50IH0gZnJvbSAnLi4vZXhwYW5zaW9uLXBhbmVsLWhlYWRlci9leHBhbnNpb24tcGFuZWwtaGVhZGVyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEJpbXBsdXNMb2NhbGl6ZWRXaWRnZXRDb21wb25lbnQgfSBmcm9tICcuLi9iaW1wbHVzLWxvY2FsaXplZC13aWRnZXQvYmltcGx1cy1sb2NhbGl6ZWQtd2lkZ2V0LmNvbXBvbmVudCc7XHJcbmltcG9ydCB7XHJcbiAgVHJhbnNsYXRlTW9kdWxlXHJcbiAgLCBUcmFuc2xhdGVTZXJ2aWNlXHJcbn0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgT2JqZWN0U3RydWN0dXJlTm9kZSxcclxuICBPYmplY3RTdHJ1Y3R1cmVOb2RlQnVpbGRlcixcclxufSBmcm9tICcuLi9iaW1wbHVzLW9iamVjdC1zdHJ1Y3R1cmUvYmltcGx1cy1vYmplY3Qtc3RydWN0dXJlLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IFByZXZpZXdPYmplY3QgfSBmcm9tICcuLi9vYmplY3QtcHJldmlldy9vYmplY3QtcHJldmlldy5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgKiBhcyBXZWJTZGsgZnJvbSAnYmltcGx1cy13ZWJzZGsnO1xyXG5pbXBvcnQge1xyXG4gIGZyb21cclxuICAsIEJlaGF2aW9yU3ViamVjdFxyXG59IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBCaW1wbHVzT2JqZWN0U3RydWN0dXJlQ29tcG9uZW50IH0gZnJvbSAnLi4vYmltcGx1cy1vYmplY3Qtc3RydWN0dXJlL2JpbXBsdXMtb2JqZWN0LXN0cnVjdHVyZS5jb21wb25lbnQnO1xyXG5pbXBvcnQge1xyXG4gIENvbXBsZXhQcm9wZXJ0aWVzTm9kZSxcclxuICBDb21wbGV4UHJvcGVydGllc05vZGVCdWlsZGVyLFxyXG59IGZyb20gJy4uL2JpbXBsdXMtb2JqZWN0LWNvbXBsZXgtcHJvcGVydGllcy9iaW1wbHVzLW9iamVjdC1jb21wbGV4LXByb3BlcnRpZXMuaW50ZXJmYWNlJztcclxuaW1wb3J0IHsgQmltcGx1c09iamVjdENvbXBsZXhQcm9wZXJ0aWVzQ29tcG9uZW50IH0gZnJvbSAnLi4vYmltcGx1cy1vYmplY3QtY29tcGxleC1wcm9wZXJ0aWVzL2JpbXBsdXMtb2JqZWN0LWNvbXBsZXgtcHJvcGVydGllcy5jb21wb25lbnQnO1xyXG5pbXBvcnQge1xyXG4gIE9iamVjdEF0dHJpYnV0ZSxcclxuICBPYmplY3RBdHRyaWJ1dGVHcm91cCxcclxufSBmcm9tICcuL29iamVjdC1wcm9wZXJ0aWVzLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IEJpbXBsdXNCdXR0b25zUm93Q29tcG9uZW50IH0gZnJvbSAnLi4vYmltcGx1cy1idXR0b25zLXJvdy9iaW1wbHVzLWJ1dHRvbnMtcm93LmNvbXBvbmVudCc7XHJcbmltcG9ydCB7XHJcbiAgQmltcGx1c0J1dHRvblJvd0l0ZW0sXHJcbiAgQmltcGx1c0J1dHRvbkNsaWNrRXZlbnQsXHJcbn0gZnJvbSAnLi4vYmltcGx1cy1idXR0b25zLXJvdy9iaW1wbHVzLWJ1dHRvbnMtcm93LmludGVyZmFjZSc7XHJcbmltcG9ydCB7IEJpbXBsdXNTY3JvbGxhYmxlQ29udGFpbmVyQ29tcG9uZW50IH0gZnJvbSAnLi4vYmltcGx1cy1zY3JvbGxhYmxlLWNvbnRhaW5lci9iaW1wbHVzLXNjcm9sbGFibGUtY29udGFpbmVyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IE9iamVjdFByb3BlcnRpZXNHcm91cENvbXBvbmVudCB9IGZyb20gJy4uL29iamVjdC1wcm9wZXJ0aWVzLWdyb3VwL29iamVjdC1wcm9wZXJ0aWVzLWdyb3VwLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IGlzT2JqZWN0UHJvcGVydHlWYWx1ZUJsYW5rIH0gZnJvbSAnLi4vLi4vdXRpbHMvb2JqZWN0UHJvcGVydGllcyc7XHJcbmltcG9ydCB7XHJcbiAgRm9ybUdyb3VwXHJcbiAgLCBSZWFjdGl2ZUZvcm1zTW9kdWxlXHJcbiAgLCBGb3JtQnVpbGRlclxyXG4gICwgRm9ybUNvbnRyb2xcclxuICAsIFZhbGlkYXRvcnNcclxufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IEdldEF0dHJpYnV0ZVZhbHVlIH0gZnJvbSAnLi4vLi4vcGlwZXMvZ2V0LWF0dHJpYnV0ZS12YWx1ZS5waXBlJztcclxuaW1wb3J0IHsgZG91YmxlVmFsaWRhdG9yIH0gZnJvbSAnLi4vLi4vdmFsaWRhdG9ycy9kb3VibGUudmFsaWRhdG9yJztcclxuaW1wb3J0IHsgaW50ZWdlclZhbGlkYXRvciB9IGZyb20gJy4uLy4uL3ZhbGlkYXRvcnMvaW50ZWdlci52YWxpZGF0b3InO1xyXG5pbXBvcnQgeyBndWlkVmFsaWRhdG9yIH0gZnJvbSAnLi4vLi4vdmFsaWRhdG9ycy9ndWlkLnZhbGlkYXRvcic7XHJcbmltcG9ydCB7IGRvdWJsZUVudW1WYWxpZGF0b3IgfSBmcm9tICcuLi8uLi92YWxpZGF0b3JzL2RvdWJsZS1lbnVtLnZhbGlkYXRvcic7XHJcbmltcG9ydCB7IE9iamVjdFByZXZpZXdDb21wb25lbnQgfSBmcm9tIFwiLi4vb2JqZWN0LXByZXZpZXcvb2JqZWN0LXByZXZpZXcuY29tcG9uZW50XCI7XHJcbmltcG9ydCB7IE9iamVjdFByb3BlcnRpZXNTZXJ2aWNlIH0gZnJvbSAnLi9vYmplY3QtcHJvcGVydGllcy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgZ3VpZEVudW1WYWxpZGF0b3IgfSBmcm9tICcuLi8uLi92YWxpZGF0b3JzL2d1aWQtZW51bS52YWxpZGF0b3InO1xyXG5pbXBvcnQgeyBzdHJpbmdFbnVtVmFsaWRhdG9yIH0gZnJvbSAnLi4vLi4vdmFsaWRhdG9ycy9zdHJpbmctZW51bS52YWxpZGF0b3InO1xyXG5pbXBvcnQgeyBzdHJpbmdDb21ib2JveFZhbGlkYXRvciB9IGZyb20gJy4uLy4uL3ZhbGlkYXRvcnMvc3RyaW5nLWNvbWJvYm94LnZhbGlkYXRvcic7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2xpYi1vYmplY3QtcHJvcGVydGllcycsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbXHJcbiAgICBFeHBhbnNpb25QYW5lbENvbXBvbmVudCxcclxuICAgIEV4cGFuc2lvblBhbmVsSGVhZGVyQ29tcG9uZW50LFxyXG4gICAgVHJhbnNsYXRlTW9kdWxlLFxyXG4gICAgQmltcGx1c09iamVjdFN0cnVjdHVyZUNvbXBvbmVudCxcclxuICAgIEJpbXBsdXNPYmplY3RDb21wbGV4UHJvcGVydGllc0NvbXBvbmVudCxcclxuICAgIEJpbXBsdXNCdXR0b25zUm93Q29tcG9uZW50LFxyXG4gICAgQmltcGx1c1Njcm9sbGFibGVDb250YWluZXJDb21wb25lbnQsXHJcbiAgICBPYmplY3RQcm9wZXJ0aWVzR3JvdXBDb21wb25lbnQsXHJcbiAgICBPYmplY3RQcm9wZXJ0aWVzR3JvdXBDb21wb25lbnQsXHJcbiAgICBPYmplY3RQcmV2aWV3Q29tcG9uZW50LFxyXG4gICAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcclxuICAgIEdldEF0dHJpYnV0ZVZhbHVlXHJcbiAgXSxcclxuICB0ZW1wbGF0ZVVybDogJy4vb2JqZWN0LXByb3BlcnRpZXMuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL29iamVjdC1wcm9wZXJ0aWVzLmNvbXBvbmVudC5sZXNzJ10sXHJcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uU2hhZG93RG9tLFxyXG59KVxyXG5cclxuZXhwb3J0IGNsYXNzIE9iamVjdFByb3BlcnRpZXNDb21wb25lbnRcclxuICBleHRlbmRzIEJpbXBsdXNMb2NhbGl6ZWRXaWRnZXRDb21wb25lbnRcclxuICBpbXBsZW1lbnRzIE9uSW5pdFxyXG57XHJcbiAgcHJvdGVjdGVkIF9vYmplY3RQcm9wZXJ0aWVzRm9ybSAgPSBuZXcgRm9ybUdyb3VwKHt9KTtcclxuXHJcbiAgcHJvdGVjdGVkIF9vYmplY3RQcm9wZXJ0aWVzR3JvdXBGb3JtKGdyb3VwX25hbWU6IHN0cmluZyk6IEZvcm1Hcm91cCB7XHJcbiAgICBjb25zdCBfZ3JvdXBGb3JtOiBGb3JtR3JvdXAgPSB0aGlzLl9vYmplY3RQcm9wZXJ0aWVzRm9ybTtcclxuICAgIHJldHVybiBfZ3JvdXBGb3JtLmNvbnRyb2xzW2dyb3VwX25hbWVdIGFzIEZvcm1Hcm91cDtcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKHRyYW5zbGF0ZVNlcnZpY2U6IFRyYW5zbGF0ZVNlcnZpY2VcclxuICAgICwgcHJpdmF0ZSByZWFkb25seSBmb3JtQnVpbGRlcjogRm9ybUJ1aWxkZXJcclxuICAgICwgcHJpdmF0ZSByZWFkb25seSBjZHI6IENoYW5nZURldGVjdG9yUmVmXHJcbiAgICAsIHByaXZhdGUgcmVhZG9ubHkgb2JqZWN0UHJvcGVydGllc1NlcnZpY2U6IE9iamVjdFByb3BlcnRpZXNTZXJ2aWNlIClcclxuICB7XHJcbiAgICBzdXBlcih0cmFuc2xhdGVTZXJ2aWNlKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBfZWRpdE1vZGUgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIHByaXZhdGUgX29iamVjdFN0cnVjdHVyZTogT2JqZWN0U3RydWN0dXJlTm9kZSB8IG51bGwgPSBudWxsO1xyXG5cclxuICBnZXQgb2JqZWN0U3RydWN0dXJlKCk6IE9iamVjdFN0cnVjdHVyZU5vZGUgfCBudWxsIHtcclxuICAgIHJldHVybiB0aGlzLl9vYmplY3RTdHJ1Y3R1cmU7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9jb21wbGV4UHJvcGVydGllczogQ29tcGxleFByb3BlcnRpZXNOb2RlIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIGdldCBjb21wbGV4UHJvcGVydGllcygpOiBDb21wbGV4UHJvcGVydGllc05vZGUgfCBudWxsIHtcclxuICAgIHJldHVybiB0aGlzLl9jb21wbGV4UHJvcGVydGllcztcclxuICB9XHJcblxyXG4gIEBJbnB1dCgpIGFwaTogV2ViU2RrLkFwaSB8IG51bGwgPSBudWxsO1xyXG4gIEBJbnB1dCgpIHJldmlzaW9uOiBudW1iZXIgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XHJcblxyXG4gIHByb3RlY3RlZCBfY2FuVXBkYXRlT2JqZWN0ID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcclxuICBASW5wdXQoKSBzZXQgY2FuVXBkYXRlT2JqZWN0KGNhblVwZGF0ZU9iamVjdDogYm9vbGVhbikge1xyXG4gICAgdGhpcy5fY2FuVXBkYXRlT2JqZWN0LnNldChjYW5VcGRhdGVPYmplY3QpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfcm9vdE9iamVjdElkIDogc3RyaW5nID0gXCJcIjtcclxuICBASW5wdXQoKSBzZXQgcm9vdE9iamVjdElkKGlkOiBzdHJpbmcpIHtcclxuICAgIGlmKHRoaXMuX3Jvb3RPYmplY3RJZCA9PT0gaWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5fY2FuY2VsRWRpdGluZ1Byb3BlcnRpZXMoKTtcclxuXHJcbiAgICB0aGlzLl9jdXJyZW50T2JqZWN0SWQkLm5leHQoaWQpO1xyXG4gICAgdGhpcy5fY3JlYXRlT2JqZWN0U3RydWN0dXJlKGlkLCB0aGlzLnJldmlzaW9uKTtcclxuICAgIHRoaXMuX3Jvb3RPYmplY3RJZCA9IGlkO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHJvb3RPYmplY3RJZCgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuX3Jvb3RPYmplY3RJZDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgaXNTYXZlQnV0dG9uRGlzYWJsZWQkOiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KHRydWUpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSB2aXNpYmxlTm9kZVNpZ25hbDpXcml0YWJsZVNpZ25hbDxQcmV2aWV3T2JqZWN0PiA9IHNpZ25hbCh7aWQ6XCJcIix2aXNpYmxlOmZhbHNlLG9wYXF1ZTpmYWxzZX0pO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSBvcGFxdWVOb2RlU2lnbmFsOldyaXRhYmxlU2lnbmFsPFByZXZpZXdPYmplY3Q+ID0gc2lnbmFsKHtpZDpcIlwiLHZpc2libGU6ZmFsc2Usb3BhcXVlOmZhbHNlfSk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgX2N1cnJlbnRPYmplY3RJZCQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4gKFwiXCIpO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgX2N1cnJlbnRQcm9wZXJ0aWVzT2JqZWN0SWQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+IChcIlwiKTtcclxuXHJcbiAgYnV0dG9uUm93SXRlbXM6IEFycmF5PEJpbXBsdXNCdXR0b25Sb3dJdGVtPiA9IFtdO1xyXG4gIGNvbmZpZ0VkaXRQcm9wZXJ0aWVzOiBBcnJheTxCaW1wbHVzQnV0dG9uUm93SXRlbT4gPSBbXTtcclxuICBjb25maWdFZGl0ZWRQcm9wZXJ0aWVzOiBBcnJheTxCaW1wbHVzQnV0dG9uUm93SXRlbT4gPSBbXTtcclxuXHJcbiAgQE91dHB1dCgpIHVwZGF0ZWRPYmplY3RQcm9wZXJ0aWVzID0gbmV3IEV2ZW50RW1pdHRlcjx7IFtrZXk6IHN0cmluZ106IHVua25vd24gfT4oKTtcclxuXHJcbiAgX2VkaXRQcm9wZXJ0aWVzQnV0dG9uc0NvbmZpZ3VyYXRpb24oKSB7XHJcbiAgICB0aGlzLmNvbmZpZ0VkaXRQcm9wZXJ0aWVzLnB1c2goe1xyXG4gICAgICBpZDogJ2VkaXQtcHJvcGVydGllcycsXHJcbiAgICAgIHRpdGxlOiB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudCgnX0VkaXRfcHJvcGVydGllcycpLFxyXG4gICAgICB0b29sdGlwOiB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudCgnX0VkaXRfcHJvcGVydGllcycpLFxyXG4gICAgICBkaXNhYmxlZDogIXRoaXMuX2NhblVwZGF0ZU9iamVjdCgpLFxyXG4gICAgICBidXR0b25TdHlsZTogJ3ByaW1hcnknLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBfZWRpdGVkUHJvcGVydGllc0J1dHRvbnNDb25maWd1cmF0aW9uKCkge1xyXG4gICAgdGhpcy5jb25maWdFZGl0ZWRQcm9wZXJ0aWVzLnB1c2goe1xyXG4gICAgICBpZDogJ3NhdmUtY2hhbmdlZC1wcm9wZXJ0aWVzJyxcclxuICAgICAgdGl0bGU6IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KCdfU2F2ZScpLFxyXG4gICAgICB0b29sdGlwOiB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudCgnX1NhdmUnKSxcclxuICAgICAgZGlzYWJsZWQ6IHRoaXMuaXNTYXZlQnV0dG9uRGlzYWJsZWQkLFxyXG4gICAgICBidXR0b25TdHlsZTogJ3ByaW1hcnknLFxyXG4gICAgfSk7XHJcbiAgICB0aGlzLmNvbmZpZ0VkaXRlZFByb3BlcnRpZXMucHVzaCh7XHJcbiAgICAgIGlkOiAnY2FuY2VsLWVkaXRpbmctcHJvcGVydGllcycsXHJcbiAgICAgIHRpdGxlOiB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudCgnX0NhbmNlbCcpLFxyXG4gICAgICB0b29sdGlwOiB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudCgnX0NhbmNlbCcpLFxyXG4gICAgICBkaXNhYmxlZDogZmFsc2UsXHJcbiAgICAgIGJ1dHRvblN0eWxlOiAnc2Vjb25kYXJ5JyxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICB0aGlzLl9lZGl0UHJvcGVydGllc0J1dHRvbnNDb25maWd1cmF0aW9uKCk7XHJcbiAgICB0aGlzLl9lZGl0ZWRQcm9wZXJ0aWVzQnV0dG9uc0NvbmZpZ3VyYXRpb24oKTtcclxuXHJcbiAgICB0aGlzLmJ1dHRvblJvd0l0ZW1zID0gdGhpcy5jb25maWdFZGl0UHJvcGVydGllcztcclxuXHJcbiAgICB0aGlzLnN1YnNjcmliZVByb3BlcnRpZXMoKTsgIFxyXG4gIH1cclxuXHJcbiAgc3Vic2NyaWJlUHJvcGVydGllcygpIHtcclxuICAgIHRoaXMuX2N1cnJlbnRQcm9wZXJ0aWVzT2JqZWN0SWQkLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6IChpZCkgPT4ge1xyXG4gICAgICAgIGlmIChpZCkge1xyXG4gICAgICAgICAgdGhpcy5fY3JlYXRlT2JqZWN0UHJvcGVydGllcyhpZCwgdGhpcy5yZXZpc2lvbik7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5fY3VycmVudE9iamVjdElkJC5zdWJzY3JpYmUoe1xyXG4gICAgICBuZXh0OiAoaWQpID0+IHtcclxuICAgICAgICB0aGlzLl9jdXJyZW50UHJvcGVydGllc09iamVjdElkJC5uZXh0KGlkKTtcclxuICAgICAgICB0aGlzLl9jcmVhdGVDb21wbGV4UHJvcGVydGllc3RydWN0dXJlKGlkLCB0aGlzLnJldmlzaW9uKTtcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaGFuZGxlT2JqZWN0U3RydWN0dXJlTm9kZVNlbGVjdGVkKG5vZGU6IE9iamVjdFN0cnVjdHVyZU5vZGUpIHtcclxuICAgIGNvbnNvbGUubG9nKG5vZGUpO1xyXG4gICAgdGhpcy5fY3VycmVudE9iamVjdElkJC5uZXh0KG5vZGUuaWQpO1xyXG4gIH1cclxuXHJcbiAgaGFuZGxlT2JqZWN0U3RydWN0dXJlTm9kZVZpc2libGUobm9kZSA6IE9iamVjdFN0cnVjdHVyZU5vZGUpe1xyXG4gICAgY29uc3Qgb2JqTm9kZTogUHJldmlld09iamVjdCA9IHtcclxuICAgICAgaWQ6bm9kZS5pZCxcclxuICAgICAgdmlzaWJsZTogbm9kZS52aXNpYmxlLFxyXG4gICAgICBvcGFxdWU6IG5vZGUub3BhcXVlfTtcclxuICAgIHRoaXMudmlzaWJsZU5vZGVTaWduYWwuc2V0KG9iak5vZGUpOyAvLyBVcGRhdGUgdGhlIHNpZ25hbFxyXG4gIH1cclxuXHJcbiAgaGFuZGxlT2JqZWN0U3RydWN0dXJlTm9kZU9wYXF1ZShub2RlIDogT2JqZWN0U3RydWN0dXJlTm9kZSl7XHJcbiAgICBjb25zdCBvYmpOb2RlOiBQcmV2aWV3T2JqZWN0ID0ge1xyXG4gICAgICBpZDpub2RlLmlkLFxyXG4gICAgICB2aXNpYmxlOiBub2RlLnZpc2libGUsXHJcbiAgICAgIG9wYXF1ZTogbm9kZS5vcGFxdWV9O1xyXG4gICAgdGhpcy5vcGFxdWVOb2RlU2lnbmFsLnNldChvYmpOb2RlKTsgLy8gVXBkYXRlIHRoZSBzaWduYWxcclxuICB9XHJcbiAgXHJcblxyXG4gIGhhbmRsZUNvbXBsZXhQcm9wZXJ0eU5vZGVTZWxlY3RlZChub2RlIDogQ29tcGxleFByb3BlcnRpZXNOb2RlKXtcclxuICAgIGNvbnNvbGUubG9nKG5vZGUpO1xyXG4gICAgdGhpcy5fY3VycmVudFByb3BlcnRpZXNPYmplY3RJZCQubmV4dChub2RlLmlkKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2xvYWRPYmplY3RTdHJ1Y3R1cmUob2JqZWN0SWQ6IHN0cmluZywgcmV2aXNpb246IG51bWJlciB8IHVuZGVmaW5lZCkge1xyXG4gICAgaWYgKCF0aGlzLmFwaSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFvYmplY3RJZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGZyb20oXHJcbiAgICAgIHRoaXMuYXBpLm9iamVjdHMuZ2V0VG9wb2xvZ3kob2JqZWN0SWQsIHJldmlzaW9uLCBmYWxzZSwgZmFsc2UsIHVuZGVmaW5lZClcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9jcmVhdGVPYmplY3RTdHJ1Y3R1cmUoXHJcbiAgICBvYmplY3RJZDogc3RyaW5nLFxyXG4gICAgcmV2aXNpb246IG51bWJlciB8IHVuZGVmaW5lZFxyXG4gICkge1xyXG4gICAgdGhpcy5fbG9hZE9iamVjdFN0cnVjdHVyZShvYmplY3RJZCwgcmV2aXNpb24pPy5zdWJzY3JpYmUoe1xyXG4gICAgICBuZXh0OiAoc3RydWN0dXJlRGF0YSkgPT4ge1xyXG4gICAgICAgIGlmIChzdHJ1Y3R1cmVEYXRhKSB7XHJcbiAgICAgICAgICB0aGlzLl9vYmplY3RTdHJ1Y3R1cmUgPVxyXG4gICAgICAgICAgICBPYmplY3RTdHJ1Y3R1cmVOb2RlQnVpbGRlci5jcmVhdGVGcm9tUmVzcG9uc2Uoc3RydWN0dXJlRGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9sb2FkT2JqZWN0Q29tcGxleFByb3BlcnRpZXNTdHJ1Y3R1cmUoXHJcbiAgICBvYmplY3RJZDogc3RyaW5nLFxyXG4gICAgcmV2aXNpb246IG51bWJlciB8IHVuZGVmaW5lZFxyXG4gICkge1xyXG4gICAgaWYgKCF0aGlzLmFwaSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFvYmplY3RJZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGZyb20oXHJcbiAgICAgIHRoaXMuYXBpLm9iamVjdHMuZ2V0Q29tcGxleFByb3BlcnRpZXNUb3BvbG9neShvYmplY3RJZCwgcmV2aXNpb24pXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY3JlYXRlQ29tcGxleFByb3BlcnRpZXN0cnVjdHVyZShcclxuICAgIG9iamVjdElkOiBzdHJpbmcsXHJcbiAgICByZXZpc2lvbjogbnVtYmVyIHwgdW5kZWZpbmVkXHJcbiAgKSB7XHJcbiAgICB0aGlzLl9sb2FkT2JqZWN0Q29tcGxleFByb3BlcnRpZXNTdHJ1Y3R1cmUob2JqZWN0SWQsIHJldmlzaW9uKT8uc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHN0cnVjdHVyZURhdGEpID0+IHtcclxuICAgICAgICBpZiAoc3RydWN0dXJlRGF0YSkge1xyXG4gICAgICAgICAgY29uc3QgY29tcGxleFByb3BzID1cclxuICAgICAgICAgICAgQ29tcGxleFByb3BlcnRpZXNOb2RlQnVpbGRlci5jcmVhdGVGcm9tUmVzcG9uc2Uoc3RydWN0dXJlRGF0YSk7XHJcbiAgICAgICAgICBpZiAoY29tcGxleFByb3BzPy5jaGlsZHJlbj8ubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbXBsZXhQcm9wZXJ0aWVzID0gY29tcGxleFByb3BzO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fY29tcGxleFByb3BlcnRpZXMgPSBudWxsO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIG9iamVjdEF0dHJpYnV0ZUdyb3VwcyA9IHNpZ25hbDxPYmplY3RBdHRyaWJ1dGVHcm91cFtdPihbXSk7XHJcblxyXG4gIHByaXZhdGUgX2xvYWRPYmplY3RQcm9wZXJ0aWVzKFxyXG4gICAgb2JqZWN0SWQ6IHN0cmluZyxcclxuICAgIHJldmlzaW9uOiBudW1iZXIgfCB1bmRlZmluZWRcclxuICApIHtcclxuICAgIGlmICghdGhpcy5hcGkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghb2JqZWN0SWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmcm9tKFxyXG4gICAgICB0aGlzLmFwaS5vYmplY3RzLmdldChvYmplY3RJZCwgcmV2aXNpb24sICc4JywgdW5kZWZpbmVkLCBmYWxzZSwgdW5kZWZpbmVkKVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NyZWF0ZU9iamVjdFByb3BlcnRpZXMoXHJcbiAgICBvYmplY3RJZDogc3RyaW5nLFxyXG4gICAgcmV2aXNpb246IG51bWJlciB8IHVuZGVmaW5lZFxyXG4gICkge1xyXG4gICAgdGhpcy5fbG9hZE9iamVjdFByb3BlcnRpZXMob2JqZWN0SWQsIHJldmlzaW9uKT8uc3Vic2NyaWJlKHtcclxuICAgICAgLy8gcHJvcGVydGllcyByZXNwb25zZSBpcyBiYWRseSBzdHJ1Y3R1cmVkLCBuZWFybHkgaW1wb3NzaWJsZSB0byBjcmVhdGUgY2xhc3Mgc3RydWN0dXJlIGZyb20gaXQuIFRoZXJlZm9yZSB1c2luZyBzaG9ydGN1dFxyXG4gICAgICAvLyBhbnkgZm9yIGpzb24gcmVzcG9uc2VcclxuXHJcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSAgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxyXG4gICAgICBuZXh0OiAocHJvcGVydGllc0RhdGE6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMub2JqZWN0UHJvcGVydGllc1NlcnZpY2Uuc2V0TW9kZWwocHJvcGVydGllc0RhdGEpO1xyXG4gICAgICAgIHRoaXMub2JqZWN0QXR0cmlidXRlR3JvdXBzLnNldCh0aGlzLl9jcmVhdGVBdHRyaWJ1dGVHcm91cHNGcm9tUmVzcG9uc2UocHJvcGVydGllc0RhdGEpKTtcclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6ICgpID0+IHtcclxuICAgICAgICB0aGlzLm9iamVjdEF0dHJpYnV0ZUdyb3Vwcy5zZXQoW10pO1xyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcclxuICBwcml2YXRlIF90b29sdGlwKGF0dHJpYjogYW55KTogc3RyaW5nIHtcclxuICAgIGNvbnN0IG5hbWVUaXRsZTogc3RyaW5nID0gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoJ19OYW1lJyk7XHJcbiAgICBjb25zdCBuYW1lOiBzdHJpbmcgPSBhdHRyaWIubmFtZSA/IGF0dHJpYi5uYW1lIDogJyc7XHJcbiAgICBjb25zdCBkZXNjcmlwdGlvblRpdGxlOiBzdHJpbmcgPVxyXG4gICAgICB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudCgnZGVzY3JpcHRpb24nKTtcclxuICAgIGNvbnN0IGRlc2NyaXB0aW9uOiBzdHJpbmcgPSBhdHRyaWIuZGVzY3JpcHRpb247XHJcbiAgICBjb25zdCB1dWlkVGl0bGU6IHN0cmluZyA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KCdfVVVJRCcpO1xyXG4gICAgY29uc3QgdXVpZDogc3RyaW5nID0gYXR0cmliLmlkO1xyXG4gICAgaWYgKFxyXG4gICAgICBkZXNjcmlwdGlvbiA9PT0gbnVsbCB8fFxyXG4gICAgICBkZXNjcmlwdGlvbiA9PT0gdW5kZWZpbmVkIHx8XHJcbiAgICAgIGRlc2NyaXB0aW9uID09PSAnJ1xyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiBgJHtuYW1lVGl0bGV9OiAke25hbWV9XFxuJHt1dWlkVGl0bGV9OiAke3V1aWR9YDtcclxuICAgIH1cclxuICAgIHJldHVybiBgJHtuYW1lVGl0bGV9OiAke25hbWV9XFxuJHtkZXNjcmlwdGlvblRpdGxlfTogJHtkZXNjcmlwdGlvbn1cXG4ke3V1aWRUaXRsZX06ICR7dXVpZH1gO1xyXG4gIH1cclxuXHJcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lICBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XHJcbiAgcHJpdmF0ZSBfY3JlYXRlQXR0cmlidXRlR3JvdXBzRnJvbVJlc3BvbnNlKHByb3BlcnRpZXNEYXRhOiBhbnkpIHtcclxuICAgIGNvbnN0IGdyb3VwczogQXJyYXk8T2JqZWN0QXR0cmlidXRlR3JvdXA+ID0gW107XHJcbiAgICBsZXQgbG9jYWxpemVkQXR0cmliR3JvdXBzID0gbnVsbDtcclxuICAgIGlmIChwcm9wZXJ0aWVzRGF0YS5sb2NhbGl6ZWRBdHRyaWJ1dGVHcm91cHMpIHtcclxuICAgICAgbG9jYWxpemVkQXR0cmliR3JvdXBzID0gcHJvcGVydGllc0RhdGEubG9jYWxpemVkQXR0cmlidXRlR3JvdXBzO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghcHJvcGVydGllc0RhdGEuYXR0cmlidXRlcykge1xyXG4gICAgICByZXR1cm4gZ3JvdXBzO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGF0dHJpYkdyb3VwcyA9IHByb3BlcnRpZXNEYXRhLmF0dHJpYnV0ZXM7XHJcbiAgICBmb3IgKGNvbnN0IFtncm91cE5hbWUsIGF0dHJpYnNPYmplY3RdIG9mIE9iamVjdC5lbnRyaWVzKGF0dHJpYkdyb3VwcykpIHtcclxuICAgICAgY29uc3QgbmV3R3JvdXA6IE9iamVjdEF0dHJpYnV0ZUdyb3VwID0ge1xyXG4gICAgICAgIG5hbWU6IGdyb3VwTmFtZSxcclxuICAgICAgICBleHBhbmRlZDogZmFsc2UsXHJcbiAgICAgICAgYXR0cmlidXRlczogW10sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBpZiAobG9jYWxpemVkQXR0cmliR3JvdXBzPy5bZ3JvdXBOYW1lXSkge1xyXG4gICAgICAgIG5ld0dyb3VwLm5hbWUgPSBsb2NhbGl6ZWRBdHRyaWJHcm91cHNbZ3JvdXBOYW1lXTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFhdHRyaWJzT2JqZWN0KSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGZvciAoY29uc3QgYXR0cmliIG9mIE9iamVjdC52YWx1ZXMoYXR0cmlic09iamVjdCkpIHtcclxuICAgICAgICBjb25zdCBuZXdBdHRyaWI6IE9iamVjdEF0dHJpYnV0ZSA9IHtcclxuICAgICAgICAgIGlkOiBhdHRyaWIuaWQsXHJcbiAgICAgICAgICBuYW1lOiBhdHRyaWIubmFtZSxcclxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBhdHRyaWIuZGVzY3JpcHRpb24sXHJcbiAgICAgICAgICB2YWx1ZTogYXR0cmliLnZhbHVlLFxyXG4gICAgICAgICAgZ3JvdXA6IGF0dHJpYi5ncm91cCxcclxuICAgICAgICAgIHR5cGU6IGF0dHJpYi50eXBlLFxyXG4gICAgICAgICAgdW5pdDogYXR0cmliLnVuaXQsXHJcbiAgICAgICAgICBkZWNpbWFsOiBhdHRyaWIuZGVjaW1hbCxcclxuICAgICAgICAgIGNvbnRyb2w6IGF0dHJpYi5jb250cm9sLFxyXG4gICAgICAgICAgZW51bWRlZmluaXRpb246IGF0dHJpYi5lbnVtZGVmaW5pdGlvbixcclxuICAgICAgICAgIGlzQ2hhbmdlYWJsZTogYXR0cmliLmlzQ2hhbmdlYWJsZSxcclxuICAgICAgICAgIHRvb2x0aXA6IHRoaXMuX3Rvb2x0aXAoYXR0cmliKSxcclxuICAgICAgICAgIG1pblZhbHVlOiBhdHRyaWIubWluVmFsdWUsXHJcbiAgICAgICAgICBtYXhWYWx1ZTogYXR0cmliLm1heFZhbHVlLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIG5ld0dyb3VwLmF0dHJpYnV0ZXMucHVzaChuZXdBdHRyaWIpO1xyXG4gICAgICB9XHJcbiAgICAgIGdyb3Vwcy5wdXNoKG5ld0dyb3VwKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZ3JvdXBzO1xyXG4gIH1cclxuXHJcbiAgX2RlbGV0ZUZvcm0oKSB7XHJcbiAgICB0aGlzLl9vYmplY3RQcm9wZXJ0aWVzRm9ybSA9IG5ldyBGb3JtR3JvdXAoe30pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpbml0aWFsRm9ybVZhbHVlczogc3RyaW5nID0gXCJcIjtcclxuICBfY3JlYXRlRm9ybSgpIHtcclxuICAgIGNvbnN0IF9nZXRBdHRyaWJ1dGVWYWx1ZSA9IG5ldyBHZXRBdHRyaWJ1dGVWYWx1ZSgpO1xyXG4gICAgY29uc3QgX2Zvcm06IHsgW2tleTogc3RyaW5nXTogRm9ybUdyb3VwIH0gPSB7fTtcclxuICAgIHRoaXMub2JqZWN0QXR0cmlidXRlR3JvdXBzKCkuZm9yRWFjaChncm91cEF0dHJpYnV0ZXMgPT4ge1xyXG4gICAgICBjb25zdCBfZm9ybV9ncm91cDogeyBba2V5OiBzdHJpbmddOiBGb3JtQ29udHJvbCB8IG51bGwgfSA9IHt9O1xyXG4gICAgICBncm91cEF0dHJpYnV0ZXMuYXR0cmlidXRlcy5mb3JFYWNoKGF0dHJpYnV0ZSA9PiB7XHJcbiAgICAgICAgaWYoKHR5cGVvZiBhdHRyaWJ1dGUudHlwZSA9PT0gJ3N0cmluZycgJiYgL15ib29sZWFuJC9pLnRlc3QoYXR0cmlidXRlLnR5cGUpKSAmJiAhYXR0cmlidXRlLmNvbnRyb2wpIHtcclxuICAgICAgICAgIF9mb3JtX2dyb3VwW2F0dHJpYnV0ZS5pZF0gPSB0aGlzLmZvcm1CdWlsZGVyLmNvbnRyb2woXHJcbiAgICAgICAgICAgIF9nZXRBdHRyaWJ1dGVWYWx1ZS50cmFuc2Zvcm0oYXR0cmlidXRlKVxyXG4gICAgICAgICAgICAsIGF0dHJpYnV0ZS5pc0NoYW5nZWFibGUgPyBbVmFsaWRhdG9ycy5wYXR0ZXJuKC9eKGZhbHNlfHRydWV8MHwxKSQvaSldIDogW11cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKCh0eXBlb2YgYXR0cmlidXRlLnR5cGUgPT09ICdzdHJpbmcnICYmIC9eYm9vbGVhbiQvaS50ZXN0KGF0dHJpYnV0ZS50eXBlKSlcclxuICAgICAgICAgICAgJiYgKHR5cGVvZiBhdHRyaWJ1dGUuY29udHJvbCA9PT0gJ3N0cmluZycgJiYgL15jaGVja2JveCQvaS50ZXN0KGF0dHJpYnV0ZS5jb250cm9sKSlcclxuICAgICAgICAgIClcclxuICAgICAgICB7XHJcbiAgICAgICAgICBfZm9ybV9ncm91cFthdHRyaWJ1dGUuaWRdID0gdGhpcy5mb3JtQnVpbGRlci5jb250cm9sKFxyXG4gICAgICAgICAgICBfZ2V0QXR0cmlidXRlVmFsdWUudHJhbnNmb3JtKGF0dHJpYnV0ZSlcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKCh0eXBlb2YgYXR0cmlidXRlLnR5cGUgPT09ICdzdHJpbmcnICYmIC9ec3RyaW5nJC9pLnRlc3QoYXR0cmlidXRlLnR5cGUpKSAmJiAhYXR0cmlidXRlLmNvbnRyb2wpIHtcclxuICAgICAgICAgIF9mb3JtX2dyb3VwW2F0dHJpYnV0ZS5pZF0gPSB0aGlzLmZvcm1CdWlsZGVyLmNvbnRyb2woXHJcbiAgICAgICAgICAgIF9nZXRBdHRyaWJ1dGVWYWx1ZS50cmFuc2Zvcm0oYXR0cmlidXRlKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYoKHR5cGVvZiBhdHRyaWJ1dGUudHlwZSA9PT0gJ3N0cmluZycgJiYgL15kb3VibGUkL2kudGVzdChhdHRyaWJ1dGUudHlwZSkpICYmICFhdHRyaWJ1dGUuY29udHJvbCkge1xyXG4gICAgICAgICAgX2Zvcm1fZ3JvdXBbYXR0cmlidXRlLmlkXSA9IHRoaXMuZm9ybUJ1aWxkZXIuY29udHJvbChcclxuICAgICAgICAgICAgX2dldEF0dHJpYnV0ZVZhbHVlLnRyYW5zZm9ybShhdHRyaWJ1dGUpXHJcbiAgICAgICAgICAgICwgYXR0cmlidXRlLmlzQ2hhbmdlYWJsZSA/IFtkb3VibGVWYWxpZGF0b3IoYXR0cmlidXRlLm1pblZhbHVlLCBhdHRyaWJ1dGUubWF4VmFsdWUpXSA6IFtdXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZigodHlwZW9mIGF0dHJpYnV0ZS50eXBlID09PSAnc3RyaW5nJyAmJiAvXmludCgzMik/JC9pLnRlc3QoYXR0cmlidXRlLnR5cGUpKSAmJiAhYXR0cmlidXRlLmNvbnRyb2wpIHtcclxuICAgICAgICAgIF9mb3JtX2dyb3VwW2F0dHJpYnV0ZS5pZF0gPSB0aGlzLmZvcm1CdWlsZGVyLmNvbnRyb2woXHJcbiAgICAgICAgICAgIF9nZXRBdHRyaWJ1dGVWYWx1ZS50cmFuc2Zvcm0oYXR0cmlidXRlKVxyXG4gICAgICAgICAgICAsIGF0dHJpYnV0ZS5pc0NoYW5nZWFibGUgPyBbaW50ZWdlclZhbGlkYXRvcihhdHRyaWJ1dGUubWluVmFsdWUsIGF0dHJpYnV0ZS5tYXhWYWx1ZSldIDogW11cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKCh0eXBlb2YgYXR0cmlidXRlLnR5cGUgPT09ICdzdHJpbmcnICYmIC9eZ3VpZCQvaS50ZXN0KGF0dHJpYnV0ZS50eXBlKSkgJiYgIWF0dHJpYnV0ZS5jb250cm9sKSB7XHJcbiAgICAgICAgICBfZm9ybV9ncm91cFthdHRyaWJ1dGUuaWRdID0gdGhpcy5mb3JtQnVpbGRlci5jb250cm9sKFxyXG4gICAgICAgICAgICBfZ2V0QXR0cmlidXRlVmFsdWUudHJhbnNmb3JtKGF0dHJpYnV0ZSlcclxuICAgICAgICAgICAgLCBhdHRyaWJ1dGUuaXNDaGFuZ2VhYmxlID8gW2d1aWRWYWxpZGF0b3IoKV0gOiBbXVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYoKHR5cGVvZiBhdHRyaWJ1dGUudHlwZSA9PT0gJ3N0cmluZycgJiYgL15kb3VibGUkL2kudGVzdChhdHRyaWJ1dGUudHlwZSkpXHJcbiAgICAgICAgICAmJiAodHlwZW9mIGF0dHJpYnV0ZS5jb250cm9sID09PSAnc3RyaW5nJyAmJiAvXmVudW1lcmF0aW9uJC9pLnRlc3QoYXR0cmlidXRlLmNvbnRyb2wpKVxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgX2Zvcm1fZ3JvdXBbYXR0cmlidXRlLmlkXSA9IHRoaXMuZm9ybUJ1aWxkZXIuY29udHJvbChcclxuICAgICAgICAgICAgX2dldEF0dHJpYnV0ZVZhbHVlLnRyYW5zZm9ybShhdHRyaWJ1dGUpXHJcbiAgICAgICAgICAgICwgYXR0cmlidXRlLmlzQ2hhbmdlYWJsZSA/IFtkb3VibGVFbnVtVmFsaWRhdG9yKGF0dHJpYnV0ZS5lbnVtZGVmaW5pdGlvbildIDogW11cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKCh0eXBlb2YgYXR0cmlidXRlLnR5cGUgPT09ICdzdHJpbmcnICYmIC9eZ3VpZCQvaS50ZXN0KGF0dHJpYnV0ZS50eXBlKSlcclxuICAgICAgICAgICYmICh0eXBlb2YgYXR0cmlidXRlLmNvbnRyb2wgPT09ICdzdHJpbmcnICYmIC9eZW51bWVyYXRpb24kL2kudGVzdChhdHRyaWJ1dGUuY29udHJvbCkpXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICBfZm9ybV9ncm91cFthdHRyaWJ1dGUuaWRdID0gdGhpcy5mb3JtQnVpbGRlci5jb250cm9sKFxyXG4gICAgICAgICAgICBfZ2V0QXR0cmlidXRlVmFsdWUudHJhbnNmb3JtKGF0dHJpYnV0ZSlcclxuICAgICAgICAgICAgLCBhdHRyaWJ1dGUuaXNDaGFuZ2VhYmxlID8gW2d1aWRFbnVtVmFsaWRhdG9yKGF0dHJpYnV0ZS5lbnVtZGVmaW5pdGlvbildIDogW11cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKCh0eXBlb2YgYXR0cmlidXRlLnR5cGUgPT09ICdzdHJpbmcnICYmIC9eaW50KDMyKT8kL2kudGVzdChhdHRyaWJ1dGUudHlwZSkpXHJcbiAgICAgICAgICAmJiAodHlwZW9mIGF0dHJpYnV0ZS5jb250cm9sID09PSAnc3RyaW5nJyAmJiAvXmVudW1lcmF0aW9uJC9pLnRlc3QoYXR0cmlidXRlLmNvbnRyb2wpKVxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgX2Zvcm1fZ3JvdXBbYXR0cmlidXRlLmlkXSA9IHRoaXMuZm9ybUJ1aWxkZXIuY29udHJvbChcclxuICAgICAgICAgICAgX2dldEF0dHJpYnV0ZVZhbHVlLnRyYW5zZm9ybShhdHRyaWJ1dGUpXHJcbiAgICAgICAgICAgICwgYXR0cmlidXRlLmlzQ2hhbmdlYWJsZSA/IFtkb3VibGVFbnVtVmFsaWRhdG9yKGF0dHJpYnV0ZS5lbnVtZGVmaW5pdGlvbildIDogW11cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKCh0eXBlb2YgYXR0cmlidXRlLnR5cGUgPT09ICdzdHJpbmcnICYmIC9ec3RyaW5nJC9pLnRlc3QoYXR0cmlidXRlLnR5cGUpKVxyXG4gICAgICAgICAgJiYgKHR5cGVvZiBhdHRyaWJ1dGUuY29udHJvbCA9PT0gJ3N0cmluZycgJiYgL15lbnVtZXJhdGlvbiQvaS50ZXN0KGF0dHJpYnV0ZS5jb250cm9sKSlcclxuICAgICAgICApIHtcclxuICAgICAgICAgIF9mb3JtX2dyb3VwW2F0dHJpYnV0ZS5pZF0gPSB0aGlzLmZvcm1CdWlsZGVyLmNvbnRyb2woXHJcbiAgICAgICAgICAgIF9nZXRBdHRyaWJ1dGVWYWx1ZS50cmFuc2Zvcm0oYXR0cmlidXRlKVxyXG4gICAgICAgICAgICAsIGF0dHJpYnV0ZS5pc0NoYW5nZWFibGUgPyBbc3RyaW5nRW51bVZhbGlkYXRvcihhdHRyaWJ1dGUuZW51bWRlZmluaXRpb24pXSA6IFtdXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZigodHlwZW9mIGF0dHJpYnV0ZS50eXBlID09PSAnc3RyaW5nJyAmJiAvXnN0cmluZyQvaS50ZXN0KGF0dHJpYnV0ZS50eXBlKSlcclxuICAgICAgICAgICYmICh0eXBlb2YgYXR0cmlidXRlLmNvbnRyb2wgPT09ICdzdHJpbmcnICYmIC9eY29tYm9ib3gkL2kudGVzdChhdHRyaWJ1dGUuY29udHJvbCkpXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICBfZm9ybV9ncm91cFthdHRyaWJ1dGUuaWRdID0gdGhpcy5mb3JtQnVpbGRlci5jb250cm9sKFxyXG4gICAgICAgICAgICBfZ2V0QXR0cmlidXRlVmFsdWUudHJhbnNmb3JtKGF0dHJpYnV0ZSlcclxuICAgICAgICAgICAgLCBhdHRyaWJ1dGUuaXNDaGFuZ2VhYmxlID8gW3N0cmluZ0NvbWJvYm94VmFsaWRhdG9yKGF0dHJpYnV0ZS5lbnVtZGVmaW5pdGlvbildIDogW11cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKCh0eXBlb2YgYXR0cmlidXRlLnR5cGUgPT09ICdzdHJpbmcnICYmIC9eZGF0ZXRpbWUkL2kudGVzdChhdHRyaWJ1dGUudHlwZSkpICYmICFhdHRyaWJ1dGUuY29udHJvbCkge1xyXG4gICAgICAgICAgX2Zvcm1fZ3JvdXBbYXR0cmlidXRlLmlkXSA9IHRoaXMuZm9ybUJ1aWxkZXIuY29udHJvbChcclxuICAgICAgICAgICAgX2dldEF0dHJpYnV0ZVZhbHVlLnRyYW5zZm9ybShhdHRyaWJ1dGUpXHJcbiAgICAgICAgICAgICwgYXR0cmlidXRlLmlzQ2hhbmdlYWJsZSA/IFtdIDogW11cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICAgIF9mb3JtW2dyb3VwQXR0cmlidXRlcy5uYW1lXSA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoX2Zvcm1fZ3JvdXApO1xyXG4gICAgfSk7XHJcbiAgICB0aGlzLl9vYmplY3RQcm9wZXJ0aWVzRm9ybSA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoX2Zvcm0pO1xyXG5cclxuICAgIHRoaXMuaW5pdGlhbEZvcm1WYWx1ZXMgPSBKU09OLnN0cmluZ2lmeSh0aGlzLl9vYmplY3RQcm9wZXJ0aWVzRm9ybS52YWx1ZSk7XHJcbiAgICB0aGlzLl9vYmplY3RQcm9wZXJ0aWVzRm9ybS52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHZhbHVlKSA9PiB7XHJcbiAgICAgICAgY29uc3QgY2hhbmdlZDogYm9vbGVhbiA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKSAhPT0gdGhpcy5pbml0aWFsRm9ybVZhbHVlcztcclxuICAgICAgICB0aGlzLmlzU2F2ZUJ1dHRvbkRpc2FibGVkJC5uZXh0KCEodGhpcy5fb2JqZWN0UHJvcGVydGllc0Zvcm0udmFsaWQgJiYgY2hhbmdlZCkpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2dldFByb3BlcnR5TmFtZSh1dWlkOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgYXR0ckdyb3VwczogT2JqZWN0QXR0cmlidXRlR3JvdXBbXSA9IHRoaXMub2JqZWN0QXR0cmlidXRlR3JvdXBzKCk7XHJcbiAgICBmb3IgKGNvbnN0IGF0dHJHcm91cCBvZiBhdHRyR3JvdXBzKSB7XHJcbiAgICAgIGZvciAoY29uc3QgYXR0ciBvZiBhdHRyR3JvdXAuYXR0cmlidXRlcykge1xyXG4gICAgICAgIGlmIChhdHRyLmlkID09PSB1dWlkKSB7XHJcbiAgICAgICAgICByZXR1cm4gYXR0ci5uYW1lO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuICcnO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfZ2V0UHJvcGVydHlUeXBlKHV1aWQ6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBhdHRyR3JvdXBzOiBPYmplY3RBdHRyaWJ1dGVHcm91cFtdID0gdGhpcy5vYmplY3RBdHRyaWJ1dGVHcm91cHMoKTtcclxuICAgIGZvciAoY29uc3QgYXR0ckdyb3VwIG9mIGF0dHJHcm91cHMpIHtcclxuICAgICAgZm9yIChjb25zdCBhdHRyIG9mIGF0dHJHcm91cC5hdHRyaWJ1dGVzKSB7XHJcbiAgICAgICAgaWYgKGF0dHIuaWQgPT09IHV1aWQpIHtcclxuICAgICAgICAgIHJldHVybiBhdHRyLnR5cGU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gJyc7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9nZXRQcm9wZXJ0eUNvbnRyb2wodXVpZDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcclxuICAgIGNvbnN0IGF0dHJHcm91cHM6IE9iamVjdEF0dHJpYnV0ZUdyb3VwW10gPSB0aGlzLm9iamVjdEF0dHJpYnV0ZUdyb3VwcygpO1xyXG4gICAgZm9yIChjb25zdCBhdHRyR3JvdXAgb2YgYXR0ckdyb3Vwcykge1xyXG4gICAgICBmb3IgKGNvbnN0IGF0dHIgb2YgYXR0ckdyb3VwLmF0dHJpYnV0ZXMpIHtcclxuICAgICAgICBpZiAoYXR0ci5pZCA9PT0gdXVpZCkge1xyXG4gICAgICAgICAgcmV0dXJuIGF0dHIuY29udHJvbDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiAnJztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NvbnZlcnRWYWx1ZVRvQm9vbGVhbih2YWx1ZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gL150cnVlJC9pLnRlc3QodmFsdWUpIHx8IC9eMSQvaS50ZXN0KHZhbHVlKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NvbnZlcnRWYWx1ZVRvRG91YmxlKHZhbHVlOiBzdHJpbmcpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHBhcnNlRmxvYXQodmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaGFzQmVlblZhbHVlQ2hhbmdlZCh1dWlkOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBhdHRyR3JvdXBzOiBPYmplY3RBdHRyaWJ1dGVHcm91cFtdID0gdGhpcy5vYmplY3RBdHRyaWJ1dGVHcm91cHMoKTtcclxuICAgIGZvciAoY29uc3QgYXR0ckdyb3VwIG9mIGF0dHJHcm91cHMpIHtcclxuICAgICAgZm9yIChjb25zdCBhdHRyIG9mIGF0dHJHcm91cC5hdHRyaWJ1dGVzKSB7XHJcbiAgICAgICAgaWYgKGF0dHIuaWQgPT09IHV1aWQpIHtcclxuICAgICAgICAgIHJldHVybiB2YWx1ZSAhPT0gYXR0ci52YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2dldENoYW5nZWREYXRhKGZvcm1Hcm91cDogRm9ybUdyb3VwKTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0ge1xyXG4gICAgY29uc3QgY2hhbmdlZERhdGE6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0ge307XHJcblxyXG4gICAgT2JqZWN0LmtleXMoZm9ybUdyb3VwLmNvbnRyb2xzKS5mb3JFYWNoKGtleSA9PiB7XHJcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtR3JvdXAuZ2V0KGtleSk7XHJcblxyXG4gICAgICBpZiAoY29udHJvbCBpbnN0YW5jZW9mIEZvcm1Db250cm9sKSB7XHJcbiAgICAgICAgLy8gSWYgaXQncyBhIEZvcm1Db250cm9sIGFuZCBpdCdzIGRpcnR5LCBjYXB0dXJlIHRoZSBjaGFuZ2VkIHZhbHVlXHJcbiAgICAgICAgaWYgKGNvbnRyb2wuZGlydHkpIHtcclxuICAgICAgICAgIGNvbnN0IHByb3BOYW1lOiBzdHJpbmcgPSB0aGlzLl9nZXRQcm9wZXJ0eU5hbWUoa2V5KTtcclxuICAgICAgICAgIGNvbnN0IHByb3BUeXBlOiBzdHJpbmcgPSB0aGlzLl9nZXRQcm9wZXJ0eVR5cGUoa2V5KTtcclxuICAgICAgICAgIC8vIGNvbnN0IHByb3BDb250cm9sOiBzdHJpbmcgPSB0aGlzLl9nZXRQcm9wZXJ0eUNvbnRyb2woa2V5KTtcclxuICAgICAgICAgIGlmKHByb3BOYW1lID09PSAnJykge1xyXG4gICAgICAgICAgICBjb25zdCBfbmV3VmFsdWUgPSB7XHJcbiAgICAgICAgICAgICAgaWQ6IGtleSxcclxuICAgICAgICAgICAgICB2YWx1ZTogY29udHJvbC52YWx1ZVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBjaGFuZ2VkRGF0YVtrZXldID0gX25ld1ZhbHVlO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYoL15ib29sZWFuJC9pLnRlc3QocHJvcFR5cGUpKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgX3ZhbDogYm9vbGVhbiA9IHRoaXMuX2NvbnZlcnRWYWx1ZVRvQm9vbGVhbihjb250cm9sLnZhbHVlKTtcclxuICAgICAgICAgICAgICBpZih0aGlzLl9oYXNCZWVuVmFsdWVDaGFuZ2VkKGtleSwgX3ZhbCkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IF9uZXdWYWx1ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgaWQ6IGtleSxcclxuICAgICAgICAgICAgICAgICAgdmFsdWU6IF92YWxcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICBjaGFuZ2VkRGF0YVtwcm9wTmFtZV0gPSBfbmV3VmFsdWU7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYoL15kb3VibGUkL2kudGVzdChwcm9wVHlwZSkpIHtcclxuICAgICAgICAgICAgICBjb25zdCBfdmFsOiBudW1iZXIgPSB0aGlzLl9jb252ZXJ0VmFsdWVUb0RvdWJsZShjb250cm9sLnZhbHVlKTtcclxuICAgICAgICAgICAgICBpZih0aGlzLl9oYXNCZWVuVmFsdWVDaGFuZ2VkKGtleSwgX3ZhbCkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IF9uZXdWYWx1ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgaWQ6IGtleSxcclxuICAgICAgICAgICAgICAgICAgdmFsdWU6IF92YWxcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICBjaGFuZ2VkRGF0YVtwcm9wTmFtZV0gPSBfbmV3VmFsdWU7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgIGNvbnN0IF92YWw6IHN0cmluZyA9IGNvbnRyb2wudmFsdWU7XHJcblxyXG4gICAgICAgICAgICAgIGlmKHRoaXMuX2hhc0JlZW5WYWx1ZUNoYW5nZWQoa2V5LCBjb250cm9sLnZhbHVlKSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgX25ld1ZhbHVlID0ge1xyXG4gICAgICAgICAgICAgICAgICBpZDoga2V5LFxyXG4gICAgICAgICAgICAgICAgICB2YWx1ZTogX3ZhbFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIGNoYW5nZWREYXRhW3Byb3BOYW1lXSA9IF9uZXdWYWx1ZTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSBpZiAoY29udHJvbCBpbnN0YW5jZW9mIEZvcm1Hcm91cCkge1xyXG4gICAgICAgIGlmKGNvbnRyb2wuZGlydHkpIHtcclxuICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGdldCBjaGFuZ2VkIGRhdGEgZnJvbSBuZXN0ZWQgRm9ybUdyb3VwXHJcbiAgICAgICAgICBjb25zdCBuZXN0ZWRDaGFuZ2VzID0gdGhpcy5fZ2V0Q2hhbmdlZERhdGEoY29udHJvbCk7XHJcbiAgICAgICAgICBpZiAoT2JqZWN0LmtleXMobmVzdGVkQ2hhbmdlcykubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBjaGFuZ2VkRGF0YVtrZXldID0gbmVzdGVkQ2hhbmdlcztcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiBjaGFuZ2VkRGF0YTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3NhdmVPYmplY3RQcm9wZXJ0aWVzKCkge1xyXG4gICAgY29uc3Qgc2F2ZURhdGE6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0ge307XHJcbiAgICBzYXZlRGF0YVsnaWQnXSA9IHRoaXMuX2N1cnJlbnRPYmplY3RJZCQudmFsdWU7XHJcbiAgICBzYXZlRGF0YVsndW5zYXZlZCddID0gdHJ1ZTtcclxuICAgIHNhdmVEYXRhWydhdHRyaWJ1dGVzJ10gPSB0aGlzLl9nZXRDaGFuZ2VkRGF0YSh0aGlzLl9vYmplY3RQcm9wZXJ0aWVzRm9ybSk7XHJcbiAgICB0aGlzLnNhdmVPYmplY3RQcm9wZXJ0aWVzKHNhdmVEYXRhKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NhbmNlbEVkaXRpbmdQcm9wZXJ0aWVzKCkge1xyXG4gICAgdGhpcy5fZWRpdE1vZGUuc2V0KGZhbHNlKTtcclxuICAgIHRoaXMuX2RlbGV0ZUZvcm0oKTtcclxuICAgIHRoaXMuYnV0dG9uUm93SXRlbXMgPSB0aGlzLmNvbmZpZ0VkaXRQcm9wZXJ0aWVzXHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgYnV0dG9uQ2xpY2tlZCgkZXZlbnQ6IEJpbXBsdXNCdXR0b25DbGlja0V2ZW50KSB7XHJcbiAgICBpZiAoJGV2ZW50LmlkID09PSAnZWRpdC1wcm9wZXJ0aWVzJykge1xyXG4gICAgICB0aGlzLl9lZGl0TW9kZS5zZXQodHJ1ZSk7XHJcbiAgICAgIHRoaXMuX2NyZWF0ZUZvcm0oKTtcclxuICAgICAgY29uc29sZS5sb2coJ0VkaXQgcHJvcGVydGllcyBjbGlja2VkJyk7XHJcbiAgICAgIHRoaXMuYnV0dG9uUm93SXRlbXMgPSB0aGlzLmNvbmZpZ0VkaXRlZFByb3BlcnRpZXM7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCRldmVudC5pZCA9PT0gJ3NhdmUtY2hhbmdlZC1wcm9wZXJ0aWVzJykge1xyXG4gICAgICB0aGlzLl9zYXZlT2JqZWN0UHJvcGVydGllcygpO1xyXG4gICAgICB0aGlzLl9jYW5jZWxFZGl0aW5nUHJvcGVydGllcygpO1xyXG4gICAgICBjb25zb2xlLmxvZygnU2F2ZSBjaGFuZ2VkIHByb3BlcnRpZXMgY2xpY2tlZCcpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICgkZXZlbnQuaWQgPT09ICdjYW5jZWwtZWRpdGluZy1wcm9wZXJ0aWVzJykge1xyXG4gICAgICB0aGlzLl9jYW5jZWxFZGl0aW5nUHJvcGVydGllcygpO1xyXG4gICAgICBjb25zb2xlLmxvZygnQ2FuY2VsIGVkaXQgcHJvcGVydGllcyBjbGlja2VkJyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBoYXNTZXRBbnlBdHRyaWJ1dGUob2JqZWN0QXR0cmlidXRlR3JvdXA6IE9iamVjdEF0dHJpYnV0ZUdyb3VwKSB7XHJcbiAgICByZXR1cm4gb2JqZWN0QXR0cmlidXRlR3JvdXAuYXR0cmlidXRlcy5zb21lKChhdHRyaWIpID0+IHtcclxuICAgICAgcmV0dXJuICFpc09iamVjdFByb3BlcnR5VmFsdWVCbGFuayhhdHRyaWIpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgc2F2ZU9iamVjdFByb3BlcnRpZXMoZGF0YTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0pOiB2b2lkIHtcclxuICAgIGNvbnN0IHNlbGVjdGVkT2JqZWN0SWQgPSB0aGlzLl9jdXJyZW50UHJvcGVydGllc09iamVjdElkJC52YWx1ZTtcclxuICAgIGlmICghZGF0YSB8fCAhc2VsZWN0ZWRPYmplY3RJZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCF0aGlzLmFwaSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgZnJvbSh0aGlzLmFwaS5vYmplY3RzLnB1dChzZWxlY3RlZE9iamVjdElkLCBKU09OLnN0cmluZ2lmeShkYXRhKSkpLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6IChyZXNwb25zZTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0pID0+IHtcclxuICAgICAgICB0aGlzLl9jcmVhdGVPYmplY3RQcm9wZXJ0aWVzKHNlbGVjdGVkT2JqZWN0SWQsIHRoaXMucmV2aXNpb24pO1xyXG4gICAgICAgIHRoaXMuX2NyZWF0ZU9iamVjdFN0cnVjdHVyZShzZWxlY3RlZE9iamVjdElkLCB0aGlzLnJldmlzaW9uKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZWRPYmplY3RQcm9wZXJ0aWVzLmVtaXQoeyBpZDogc2VsZWN0ZWRPYmplY3RJZCwgcmVxdWVzdDogZGF0YSwgcmVzcG9uc2UgfSk7XHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuIiwiPGxpYi1iaW1wbHVzLWJ1dHRvbnMtcm93XHJcbiAgW2l0ZW1zXT1cImJ1dHRvblJvd0l0ZW1zXCJcclxuICAoYnV0dG9uQ2xpY2tlZCk9XCJidXR0b25DbGlja2VkKCRldmVudClcIlxyXG4vPlxyXG5cclxuPGRpdiBjbGFzcz1cIm9iamVjdC1wcm9wZXJ0aWVzXCI+XHJcblxyXG4gIDxsaWItYmltcGx1cy1zY3JvbGxhYmxlLWNvbnRhaW5lcj5cclxuICAgIDxsaWItZXhwYW5zaW9uLXBhbmVsIGNsYXNzPVwib2JqZWN0LXByb3BlcnRpZXMtcHJldmlldy1wYW5lbFwiPlxyXG4gICAgICA8bGliLWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJvYmplY3Qtc3RydWN0dXJlLWhlYWRlclwiPnt7XCJfM0QgcHJldmlld1wiIHwgdHJhbnNsYXRlfX08L3NwYW4+XHJcbiAgICAgIDwvbGliLWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XHJcbiAgICAgIDxsaWItb2JqZWN0LXByZXZpZXcgXHJcbiAgICAgICAgW2FwaV09XCJhcGlcIiBcclxuICAgICAgICBbcmV2aXNpb25dPVwicmV2aXNpb25cIiBcclxuICAgICAgICBbb2JqZWN0SWRdPVwicm9vdE9iamVjdElkXCJcclxuICAgICAgICBbdmlzaWJsZU5vZGVdPVwidmlzaWJsZU5vZGVTaWduYWwoKVwiXHRcclxuICAgICAgICBbb3BhcXVlTm9kZV09XCJvcGFxdWVOb2RlU2lnbmFsKClcIlxyXG4gICAgICAvPlxyXG4gICAgPC9saWItZXhwYW5zaW9uLXBhbmVsPlxyXG4gICAgPCEtLSBPYmplY3Qgc3RydWN0dXJlLS0+XHJcbiAgICA8bGliLWV4cGFuc2lvbi1wYW5lbCBjbGFzcz1cIm9iamVjdC1wcm9wZXJ0aWVzLW9iamVjdC1zdHJ1Y3R1cmUtcGFuZWxcIj5cclxuICAgICAgPGxpYi1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwib2JqZWN0LXN0cnVjdHVyZS1oZWFkZXJcIj57e1wiX09iamVjdCBzdHJ1Y3R1cmVcIiB8IHRyYW5zbGF0ZX19PC9zcGFuPlxyXG4gICAgICA8L2xpYi1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxyXG4gICAgICBAaWYgKG9iamVjdFN0cnVjdHVyZSkge1xyXG4gICAgICAgIDxsaWItYmltcGx1cy1vYmplY3Qtc3RydWN0dXJlXHJcbiAgICAgICAgICBbb2JqZWN0U3RydWN0dXJlXT1cIm9iamVjdFN0cnVjdHVyZVwiXHJcbiAgICAgICAgICAobm9kZVNlbGVjdGVkKT1cImhhbmRsZU9iamVjdFN0cnVjdHVyZU5vZGVTZWxlY3RlZCgkZXZlbnQpXCJcclxuICAgICAgICAgIChub2RlVmlzaWJsZSk9IFwiaGFuZGxlT2JqZWN0U3RydWN0dXJlTm9kZVZpc2libGUoJGV2ZW50KVwiXHJcbiAgICAgICAgICAobm9kZU9wYXF1ZSk9ICBcImhhbmRsZU9iamVjdFN0cnVjdHVyZU5vZGVPcGFxdWUoJGV2ZW50KVwiICAgICAgICAgIFxyXG4gICAgICAgIC8+XHJcbiAgICAgIH1cclxuICAgIDwvbGliLWV4cGFuc2lvbi1wYW5lbD5cclxuICAgIDwhLS0gRW5kIE9iamVjdCBzdHJ1Y3R1cmUtLT5cclxuXHJcbiAgICA8IS0tIENvbXBsZXggcHJvcGVydGllcy0tPlxyXG4gICAgQGlmKGNvbXBsZXhQcm9wZXJ0aWVzKXtcclxuICAgICAgPGxpYi1leHBhbnNpb24tcGFuZWw+XHJcbiAgICAgICAgPGxpYi1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxyXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJvYmplY3QtcHJvcGVydGllcy1oZWFkZXJcIj4ge3tcIl9PYmplY3QgbXVsdGlwcm9wZXJ0aWVzIHRyZWVcIiB8IHRyYW5zbGF0ZX19PC9zcGFuPlxyXG4gICAgICAgIDwvbGliLWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XHJcbiAgICAgICAgPGxpYi1iaW1wbHVzLW9iamVjdC1jb21wbGV4LXByb3BlcnRpZXNcclxuICAgICAgICAgIFtjb21wbGV4UHJvcGVydGllc109XCJjb21wbGV4UHJvcGVydGllc1wiXHJcbiAgICAgICAgICAobm9kZVNlbGVjdGVkKT1cImhhbmRsZUNvbXBsZXhQcm9wZXJ0eU5vZGVTZWxlY3RlZCgkZXZlbnQpXCJcclxuICAgICAgICAvPlxyXG4gICAgICA8L2xpYi1leHBhbnNpb24tcGFuZWw+XHJcbiAgICB9XHJcbiAgICA8IS0tIEVuZCBDb21wbGV4IHByb3BlcnRpZXMtLT5cclxuXHJcbiAgICBAaWYob2JqZWN0QXR0cmlidXRlR3JvdXBzKCkubGVuZ3RoID4gMCl7XHJcbiAgICAgIDxsaWItZXhwYW5zaW9uLXBhbmVsPlxyXG4gICAgICAgIDxsaWItZXhwYW5zaW9uLXBhbmVsLWhlYWRlcj5cclxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwib2JqZWN0LXByb3BlcnRpZXMtaGVhZGVyXCI+e3tcIl9PYmplY3QgcHJvcGVydGllc1wiIHwgdHJhbnNsYXRlfX08L3NwYW4+XHJcbiAgICAgICAgPC9saWItZXhwYW5zaW9uLXBhbmVsLWhlYWRlcj5cclxuICAgICAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cIl9vYmplY3RQcm9wZXJ0aWVzRm9ybVwiIGNsYXNzPVwiaW5wdXQtZm9ybVwiPlxyXG4gICAgICAgICAgQGZvciAoYXR0cmliR3JvdXAgb2Ygb2JqZWN0QXR0cmlidXRlR3JvdXBzKCk7IHRyYWNrIGF0dHJpYkdyb3VwKSB7XHJcbiAgICAgICAgICAgIEBpZihfZWRpdE1vZGUoKSB8fCBoYXNTZXRBbnlBdHRyaWJ1dGUoYXR0cmliR3JvdXApKXtcclxuICAgICAgICAgICAgICA8bGliLWV4cGFuc2lvbi1wYW5lbCBbZXhwYW5kZWRdPVwiYXR0cmliR3JvdXAuZXhwYW5kZWRcIj5cclxuICAgICAgICAgICAgICAgIDxsaWItZXhwYW5zaW9uLXBhbmVsLWhlYWRlcj5cclxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJvYmplY3QtcHJvcGVydGllcy1ncm91cC1oZWFkZXJcIj4ge3thdHRyaWJHcm91cC5uYW1lfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICA8L2xpYi1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxyXG4gICAgICAgICAgICAgICAgPGxpYi1vYmplY3QtcHJvcGVydGllcy1ncm91cFxyXG4gICAgICAgICAgICAgICAgICBbYXR0cmlidXRlc0dyb3VwXT1cImF0dHJpYkdyb3VwXCJcclxuICAgICAgICAgICAgICAgICAgW2VkaXRNb2RlXT1cIl9lZGl0TW9kZSgpXCJcclxuICAgICAgICAgICAgICAgICAgW2NhblVwZGF0ZU9iamVjdF09XCJfY2FuVXBkYXRlT2JqZWN0KClcIlxyXG4gICAgICAgICAgICAgICAgICBbb2JqZWN0UHJvcGVydGllc0Zvcm1dPVwiX29iamVjdFByb3BlcnRpZXNHcm91cEZvcm0oYXR0cmliR3JvdXAubmFtZSlcIlxyXG4gICAgICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgICA8L2xpYi1leHBhbnNpb24tcGFuZWw+XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICA8L2Zvcm0+XHJcbiAgICAgIDwvbGliLWV4cGFuc2lvbi1wYW5lbD5cclxuICAgIH1cclxuICA8L2xpYi1iaW1wbHVzLXNjcm9sbGFibGUtY29udGFpbmVyPlxyXG48L2Rpdj5cclxuIl19