@bnsights/bbsf-controls 1.0.194-beta.9 → 1.2.1

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 (159) hide show
  1. package/README.md +1315 -1245
  2. package/fesm2022/bnsights-bbsf-controls.mjs +375 -345
  3. package/fesm2022/bnsights-bbsf-controls.mjs.map +1 -1
  4. package/lib/Shared/Models/DropdownOptions.d.ts +3 -0
  5. package/lib/Shared/Models/RepeaterOptions.d.ts +2 -0
  6. package/lib/controls/ConfirmationModal/ConfirmationModal.component.d.ts +0 -1
  7. package/lib/controls/MapAutoComplete/MapAutoComplete.component.d.ts +0 -1
  8. package/lib/controls/MultiLingualTextBox/MultiLingualTextBox.component.d.ts +1 -1
  9. package/lib/controls/Repeater/repeater/repeater.component.d.ts +7 -0
  10. package/lib/controls/Repeater/repeater-table/repeater-table.component.d.ts +7 -0
  11. package/lib/modules/bbsf-editors.module.d.ts +6 -7
  12. package/package.json +34 -37
  13. package/src/lib/assets/Style.scss +2 -0
  14. package/src/lib/assets/ace-builds/ace.js +1 -1
  15. package/src/lib/assets/ace-builds/mode-markdown.js +1 -1
  16. package/esm2022/bnsights-bbsf-controls.mjs +0 -5
  17. package/esm2022/lib/Shared/Components/app-base-component.mjs +0 -226
  18. package/esm2022/lib/Shared/Components/ng-tag-input.mjs +0 -336
  19. package/esm2022/lib/Shared/Directives/appPreventDoubleClick.directive.mjs +0 -39
  20. package/esm2022/lib/Shared/Directives/template-name.directive.mjs +0 -19
  21. package/esm2022/lib/Shared/Enums/CalendarView.mjs +0 -8
  22. package/esm2022/lib/Shared/Enums/ControlLayout.mjs +0 -6
  23. package/esm2022/lib/Shared/Enums/Countries.mjs +0 -247
  24. package/esm2022/lib/Shared/Enums/Enums.mjs +0 -36
  25. package/esm2022/lib/Shared/Enums/FileType.mjs +0 -29
  26. package/esm2022/lib/Shared/Enums/FilterType.mjs +0 -11
  27. package/esm2022/lib/Shared/Enums/FontSize.mjs +0 -7
  28. package/esm2022/lib/Shared/Enums/ForceDirection.mjs +0 -6
  29. package/esm2022/lib/Shared/Enums/IconPosition.mjs +0 -6
  30. package/esm2022/lib/Shared/Enums/ImageType.mjs +0 -10
  31. package/esm2022/lib/Shared/Enums/InputType.mjs +0 -10
  32. package/esm2022/lib/Shared/Enums/Insert.mjs +0 -9
  33. package/esm2022/lib/Shared/Enums/LanguageMode.mjs +0 -11
  34. package/esm2022/lib/Shared/Enums/LanguageValidation.mjs +0 -6
  35. package/esm2022/lib/Shared/Enums/Markdown.mjs +0 -20
  36. package/esm2022/lib/Shared/Enums/Misc.mjs +0 -7
  37. package/esm2022/lib/Shared/Enums/PagingActionMode.mjs +0 -6
  38. package/esm2022/lib/Shared/Enums/Para.mjs +0 -9
  39. package/esm2022/lib/Shared/Enums/PickerType.mjs +0 -7
  40. package/esm2022/lib/Shared/Enums/SelectMode.mjs +0 -6
  41. package/esm2022/lib/Shared/Enums/StartView.mjs +0 -7
  42. package/esm2022/lib/Shared/Enums/Style.mjs +0 -8
  43. package/esm2022/lib/Shared/Enums/StyleConfirmationMode.mjs +0 -7
  44. package/esm2022/lib/Shared/Enums/TagInputView.mjs +0 -7
  45. package/esm2022/lib/Shared/Enums/ToolbarButtons.mjs +0 -33
  46. package/esm2022/lib/Shared/Enums/map-enums.mjs +0 -15
  47. package/esm2022/lib/Shared/Enums/menu-list-enum.mjs +0 -6
  48. package/esm2022/lib/Shared/Models/Attribute.mjs +0 -3
  49. package/esm2022/lib/Shared/Models/AutocompleteDTO.mjs +0 -8
  50. package/esm2022/lib/Shared/Models/AutocompleteOptions.mjs +0 -39
  51. package/esm2022/lib/Shared/Models/CalendarDTO.mjs +0 -3
  52. package/esm2022/lib/Shared/Models/CalendarEventDTO.mjs +0 -3
  53. package/esm2022/lib/Shared/Models/CalendarOptions.mjs +0 -19
  54. package/esm2022/lib/Shared/Models/CancelDTO.mjs +0 -7
  55. package/esm2022/lib/Shared/Models/CaptchaStyle.mjs +0 -3
  56. package/esm2022/lib/Shared/Models/CheckBoxOptions.mjs +0 -11
  57. package/esm2022/lib/Shared/Models/ConfirmationModalOptions.mjs +0 -39
  58. package/esm2022/lib/Shared/Models/ControlOptionsBase.mjs +0 -17
  59. package/esm2022/lib/Shared/Models/CustomValidation.mjs +0 -14
  60. package/esm2022/lib/Shared/Models/DatePickerOptions.mjs +0 -40
  61. package/esm2022/lib/Shared/Models/DropdownListItem.mjs +0 -3
  62. package/esm2022/lib/Shared/Models/DropdownOptions.mjs +0 -38
  63. package/esm2022/lib/Shared/Models/EditPersonalImage.mjs +0 -7
  64. package/esm2022/lib/Shared/Models/EnglishArabicDTO.mjs +0 -10
  65. package/esm2022/lib/Shared/Models/FileDTO.mjs +0 -24
  66. package/esm2022/lib/Shared/Models/FileOptions.mjs +0 -15
  67. package/esm2022/lib/Shared/Models/FileUploadModel.mjs +0 -3
  68. package/esm2022/lib/Shared/Models/FileUploadOptions.mjs +0 -13
  69. package/esm2022/lib/Shared/Models/FilterItem.mjs +0 -8
  70. package/esm2022/lib/Shared/Models/FormOptions.mjs +0 -32
  71. package/esm2022/lib/Shared/Models/HtmlEditorOptions.mjs +0 -12
  72. package/esm2022/lib/Shared/Models/ImageUploadOptions.mjs +0 -14
  73. package/esm2022/lib/Shared/Models/MapAutoCompleteOptions.mjs +0 -12
  74. package/esm2022/lib/Shared/Models/MapAutocompleteDTO.mjs +0 -6
  75. package/esm2022/lib/Shared/Models/MarkdownEditorOptions.mjs +0 -24
  76. package/esm2022/lib/Shared/Models/MultiLingualHtmlEditorOptions.mjs +0 -9
  77. package/esm2022/lib/Shared/Models/MultiLingualTextAreaOptions.mjs +0 -9
  78. package/esm2022/lib/Shared/Models/MultiLingualTextBoxOptions.mjs +0 -17
  79. package/esm2022/lib/Shared/Models/MultilingualControlOptionsBase.mjs +0 -21
  80. package/esm2022/lib/Shared/Models/MultipleFileUploadModel.mjs +0 -9
  81. package/esm2022/lib/Shared/Models/PagingDTO.mjs +0 -13
  82. package/esm2022/lib/Shared/Models/PagingOptions.mjs +0 -49
  83. package/esm2022/lib/Shared/Models/PagingPayload.mjs +0 -3
  84. package/esm2022/lib/Shared/Models/PhoneOptions.mjs +0 -16
  85. package/esm2022/lib/Shared/Models/ProfileImageUploadOptions.mjs +0 -11
  86. package/esm2022/lib/Shared/Models/ProfilePictureDTO.mjs +0 -3
  87. package/esm2022/lib/Shared/Models/RadioButtonItem.mjs +0 -3
  88. package/esm2022/lib/Shared/Models/RadioButtonOptions.mjs +0 -7
  89. package/esm2022/lib/Shared/Models/RangeNumber.mjs +0 -3
  90. package/esm2022/lib/Shared/Models/Recaptcha.mjs +0 -6
  91. package/esm2022/lib/Shared/Models/RecaptchaOptions.mjs +0 -22
  92. package/esm2022/lib/Shared/Models/RepeaterField.mjs +0 -3
  93. package/esm2022/lib/Shared/Models/RepeaterOptions.mjs +0 -14
  94. package/esm2022/lib/Shared/Models/SaveDTO.mjs +0 -7
  95. package/esm2022/lib/Shared/Models/TagsInputDTO.mjs +0 -3
  96. package/esm2022/lib/Shared/Models/TagsInputOptions.mjs +0 -56
  97. package/esm2022/lib/Shared/Models/TextAreaOptions.mjs +0 -19
  98. package/esm2022/lib/Shared/Models/TextBoxOptions.mjs +0 -27
  99. package/esm2022/lib/Shared/Models/ToggleSlideOptions.mjs +0 -9
  100. package/esm2022/lib/Shared/Models/UploadPersonalImage.mjs +0 -7
  101. package/esm2022/lib/Shared/Models/bread-crumb.mjs +0 -8
  102. package/esm2022/lib/Shared/Models/control-filter-Item.mjs +0 -6
  103. package/esm2022/lib/Shared/Models/filter-options.mjs +0 -9
  104. package/esm2022/lib/Shared/Models/index.mjs +0 -58
  105. package/esm2022/lib/Shared/Models/page-header-options.mjs +0 -78
  106. package/esm2022/lib/Shared/Pipes/bbsf-date-time.pipe.mjs +0 -22
  107. package/esm2022/lib/Shared/Pipes/bbsf-date.pipe.mjs +0 -22
  108. package/esm2022/lib/Shared/config/environment.mjs +0 -12
  109. package/esm2022/lib/Shared/default_intl.mjs +0 -29
  110. package/esm2022/lib/Shared/services/ControlUtility.mjs +0 -162
  111. package/esm2022/lib/Shared/services/GlobalSettings.service.mjs +0 -30
  112. package/esm2022/lib/Shared/services/OnPagingFiltersChange.service.mjs +0 -24
  113. package/esm2022/lib/Shared/services/file-upload.service.mjs +0 -29
  114. package/esm2022/lib/Shared/services/index.mjs +0 -7
  115. package/esm2022/lib/Shared/services/render-component-service.service.mjs +0 -32
  116. package/esm2022/lib/Shared/services/validationErrorMassage.service.mjs +0 -125
  117. package/esm2022/lib/Shared/utils/date-formatter.mjs +0 -48
  118. package/esm2022/lib/controls/AutocompleteTextBox/AutocompleteTextBox.component.mjs +0 -299
  119. package/esm2022/lib/controls/Calendar/Calendar.component.mjs +0 -179
  120. package/esm2022/lib/controls/CheckBox/CheckBox.component.mjs +0 -121
  121. package/esm2022/lib/controls/ConfirmationModal/ConfirmationModal.component.mjs +0 -143
  122. package/esm2022/lib/controls/DateTimePicker/DateTimePicker.component.mjs +0 -240
  123. package/esm2022/lib/controls/DropdownList/DropdownList.component.mjs +0 -296
  124. package/esm2022/lib/controls/FileUpload/FileUpload.component.mjs +0 -741
  125. package/esm2022/lib/controls/Form/Form.component.mjs +0 -117
  126. package/esm2022/lib/controls/HtmlEditor/HtmlEditor.component.mjs +0 -185
  127. package/esm2022/lib/controls/ImageUpload/ImageUpload.component.mjs +0 -360
  128. package/esm2022/lib/controls/MapAutoComplete/MapAutoComplete.component.mjs +0 -502
  129. package/esm2022/lib/controls/MarkdownEditor/markdown-editor.component.mjs +0 -243
  130. package/esm2022/lib/controls/MultiLingualHtmlEditor/MultiLingualHtmlEditor.component.mjs +0 -456
  131. package/esm2022/lib/controls/MultiLingualTextArea/MultiLingualTextArea.component.mjs +0 -441
  132. package/esm2022/lib/controls/MultiLingualTextBox/MultiLingualTextBox.component.mjs +0 -500
  133. package/esm2022/lib/controls/Paging/JwPagination.component.mjs +0 -160
  134. package/esm2022/lib/controls/Paging/Paging.component.mjs +0 -626
  135. package/esm2022/lib/controls/Phone/Phone.component.mjs +0 -134
  136. package/esm2022/lib/controls/ProfileImageUploader/ProfileImageUploader.component.mjs +0 -390
  137. package/esm2022/lib/controls/RadioButton/RadioButton.component.mjs +0 -113
  138. package/esm2022/lib/controls/Recaptcha/Recaptcha.component.mjs +0 -134
  139. package/esm2022/lib/controls/Repeater/repeater/repeater.component.mjs +0 -135
  140. package/esm2022/lib/controls/Repeater/repeater-field-builder/repeater-field-builder.component.mjs +0 -1291
  141. package/esm2022/lib/controls/Repeater/repeater-item-field/repeater-item-field.component.mjs +0 -22
  142. package/esm2022/lib/controls/Repeater/repeater-table/repeater-table.component.mjs +0 -118
  143. package/esm2022/lib/controls/TagsInput/TagsInput.component.mjs +0 -308
  144. package/esm2022/lib/controls/TextArea/TextArea.component.mjs +0 -581
  145. package/esm2022/lib/controls/TextBox/TextBox.component.mjs +0 -357
  146. package/esm2022/lib/controls/Toggleslide/Toggleslide.component.mjs +0 -96
  147. package/esm2022/lib/controls/bbsf-controls.module.mjs +0 -92
  148. package/esm2022/lib/controls/page-header-component/page-header-component.component.mjs +0 -42
  149. package/esm2022/lib/modules/bbsf-core.module.mjs +0 -210
  150. package/esm2022/lib/modules/bbsf-datetime.module.mjs +0 -90
  151. package/esm2022/lib/modules/bbsf-dropdown.module.mjs +0 -57
  152. package/esm2022/lib/modules/bbsf-editors.module.mjs +0 -97
  153. package/esm2022/lib/modules/bbsf-forms-basic.module.mjs +0 -79
  154. package/esm2022/lib/modules/bbsf-multilingual.module.mjs +0 -60
  155. package/esm2022/lib/modules/bbsf-phone.module.mjs +0 -57
  156. package/esm2022/lib/modules/bbsf-specialized.module.mjs +0 -160
  157. package/esm2022/lib/modules/bbsf-uploads.module.mjs +0 -106
  158. package/esm2022/lib/modules/bbsf-utility.module.mjs +0 -103
  159. package/esm2022/public-api.mjs +0 -169
@@ -1,626 +0,0 @@
1
- import { Component, Output, EventEmitter, Input, HostListener, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { FormsModule, ReactiveFormsModule } from '@angular/forms';
4
- import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap';
5
- import { BlockUIModule } from 'ng-block-ui';
6
- import { InlineSVGModule } from 'ng-inline-svg-2';
7
- import { PagingDTO } from '../../Shared/Models/PagingDTO';
8
- import { Subscription } from 'rxjs';
9
- import { FilterType } from '../../Shared/Enums/FilterType';
10
- import { RequestOptionsModel } from '@bnsights/bbsf-utilities/http';
11
- import { plainToClass } from 'class-transformer';
12
- import { JwPaginationComponent } from './JwPagination.component';
13
- import * as i0 from "@angular/core";
14
- import * as i1 from "@bnsights/bbsf-utilities/ui";
15
- import * as i2 from "@angular/common/http";
16
- import * as i3 from "@angular/router";
17
- import * as i4 from "@angular/common";
18
- import * as i5 from "../../Shared/services/OnPagingFiltersChange.service";
19
- import * as i6 from "@bnsights/bbsf-utilities/http";
20
- import * as i7 from "@angular/forms";
21
- export class PagingComponent {
22
- constructor(utilityService, http, router, route, location, onChangeService, requestHandlerService, cdr, renderer, elementRef) {
23
- this.utilityService = utilityService;
24
- this.http = http;
25
- this.router = router;
26
- this.route = route;
27
- this.location = location;
28
- this.onChangeService = onChangeService;
29
- this.requestHandlerService = requestHandlerService;
30
- this.cdr = cdr;
31
- this.renderer = renderer;
32
- this.elementRef = elementRef;
33
- this.items = [];
34
- this.result = [];
35
- this.pagerConfig = null;
36
- this.totalRow = 0;
37
- this.pageSize = 10;
38
- this.Pages = 0;
39
- this.currentPage = 1;
40
- this.showPageSizeOption = true;
41
- this.showFirstAndLast = true;
42
- this.hidePaginationWhenPageSizeEqualOne = true;
43
- this.sum = 0;
44
- this.throttle = 300;
45
- this.scrollDistance = 1;
46
- this.scrollUpDistance = 2;
47
- this.direction = '';
48
- this.isFirstCall = true;
49
- this.previousFilters = {};
50
- this.Items = new EventEmitter();
51
- this.pageStateRestored = new EventEmitter();
52
- this.subscriptions = new Subscription();
53
- // Browser navigation support
54
- this.isNavigatingBack = false;
55
- this.isRestoringFilters = false;
56
- this.pageHistory = [];
57
- this.currentHistoryIndex = -1;
58
- this.reinitializePaging = () => {
59
- this.isFirstCall = true;
60
- this.currentPage = 1;
61
- this.clearHistoryState();
62
- this.getItemList(1, true);
63
- };
64
- this.updatePaging = () => {
65
- //this.IsFirstCall=true;
66
- this.getItemList(this.currentPage);
67
- };
68
- }
69
- ngOnDestroy() {
70
- this.subscriptions.unsubscribe();
71
- }
72
- ngOnInit() {
73
- // Initialize browser navigation support if enabled
74
- if (this.options.enableBrowserNavigation) {
75
- this.initializeBrowserNavigation();
76
- }
77
- if (this.options.isLoadMoreControl)
78
- this.sum = this.options.pageSize;
79
- if (this.options.dropdownFiltersControlNames != null && this.options.dropdownFiltersControlNames.length > 0) {
80
- const DropdownFiltersControlNames = this.options.dropdownFiltersControlNames;
81
- this.subscriptions.add(this.onChangeService.GetValue().subscribe((value) => {
82
- let result = this.options.dropdownFiltersControlNames.filter((item) => item == value);
83
- if (result.length > 0) {
84
- this.isFirstCall = true;
85
- this.currentPage = 1;
86
- this.updateHistoryState();
87
- this.getItemList(this.currentPage, true);
88
- }
89
- }));
90
- }
91
- if (this.options.bootstrapDatePickersFiltersControlNames != null && this.options.bootstrapDatePickersFiltersControlNames.length > 0) {
92
- const BootstrapDatePickersFiltersControlNames = this.options.bootstrapDatePickersFiltersControlNames;
93
- this.subscriptions.add(this.onChangeService.GetValue().subscribe((value) => {
94
- let result = this.options.bootstrapDatePickersFiltersControlNames.filter((item) => item == value);
95
- if (result.length > 0) {
96
- this.isFirstCall = true;
97
- this.currentPage = 1;
98
- this.updateHistoryState();
99
- this.getItemList(this.currentPage, true);
100
- }
101
- }));
102
- }
103
- this.isFirstCall = true;
104
- this.getItemList(this.currentPage, true);
105
- }
106
- /**
107
- * Initialize browser navigation support
108
- */
109
- initializeBrowserNavigation() {
110
- // Try to restore state from browser history on initial load
111
- this.restoreStateFromBrowserHistory();
112
- }
113
- /**
114
- * Restore state from browser history on initial load
115
- */
116
- restoreStateFromBrowserHistory() {
117
- try {
118
- // Get the current history state
119
- const currentState = history.state;
120
- if (currentState && currentState.pagingState) {
121
- const savedState = currentState.pagingState;
122
- // Check if the saved state has valid data
123
- if (savedState.page && savedState.pageSize && savedState.filters) {
124
- // Restore filter values to form controls
125
- this.restoreFilterValues(savedState.filters);
126
- // Get current filters after restoration
127
- const currentFilters = this.getFiltersValue();
128
- // Only restore if filters match (same search context)
129
- if (JSON.stringify(savedState.filters) === JSON.stringify(currentFilters)) {
130
- let pageChanged = false;
131
- let pageSizeChanged = false;
132
- if (savedState.page !== this.currentPage) {
133
- this.currentPage = savedState.page;
134
- pageChanged = true;
135
- }
136
- if (savedState.pageSize !== this.options.pageSize) {
137
- this.options.pageSize = savedState.pageSize;
138
- pageSizeChanged = true;
139
- }
140
- // If page or page size changed, reload data
141
- if (pageChanged || pageSizeChanged) {
142
- this.getItemList(this.currentPage, pageSizeChanged);
143
- }
144
- // Add the restored state to our local history
145
- this.pageHistory.push(savedState);
146
- this.currentHistoryIndex = this.pageHistory.length - 1;
147
- // Emit event to notify that page state was restored
148
- this.pageStateRestored.emit({
149
- page: this.currentPage,
150
- pageSize: this.options.pageSize
151
- });
152
- // Force change detection to update the UI
153
- this.cdr.detectChanges();
154
- console.log(`Initial page state restored: Page ${this.currentPage}, PageSize ${this.options.pageSize}, Filters restored`);
155
- }
156
- }
157
- }
158
- }
159
- catch (error) {
160
- console.warn('Failed to restore browser history state:', error);
161
- }
162
- }
163
- /**
164
- * Listen to browser back/forward navigation
165
- */
166
- onPopState(event) {
167
- if (!this.options.enableBrowserNavigation) {
168
- return;
169
- }
170
- console.log('Browser back/forward navigation detected');
171
- this.isNavigatingBack = true;
172
- this.restorePageStateFromHistory();
173
- this.isNavigatingBack = false;
174
- }
175
- /**
176
- * Restore page state from browser history
177
- */
178
- restorePageStateFromHistory() {
179
- try {
180
- // Get the current history state from browser
181
- const currentState = history.state;
182
- if (currentState && currentState.pagingState) {
183
- const savedState = currentState.pagingState;
184
- // Check if the saved state has valid data
185
- if (savedState.page && savedState.pageSize && savedState.filters) {
186
- // Restore filter values to form controls
187
- this.restoreFilterValues(savedState.filters);
188
- // Get current filters after restoration
189
- const currentFilters = this.getFiltersValue();
190
- // Only restore if filters match (same search context)
191
- if (JSON.stringify(savedState.filters) === JSON.stringify(currentFilters)) {
192
- let pageChanged = false;
193
- let pageSizeChanged = false;
194
- if (savedState.page !== this.currentPage) {
195
- this.currentPage = savedState.page;
196
- pageChanged = true;
197
- }
198
- if (savedState.pageSize !== this.options.pageSize) {
199
- this.options.pageSize = savedState.pageSize;
200
- pageSizeChanged = true;
201
- }
202
- // If page or page size changed, reload data
203
- if (pageChanged || pageSizeChanged) {
204
- this.getItemList(this.currentPage, pageSizeChanged);
205
- }
206
- // Update our local history index to match the browser state
207
- this.updateLocalHistoryIndex(savedState);
208
- // Emit event to notify that page state was restored
209
- this.pageStateRestored.emit({
210
- page: this.currentPage,
211
- pageSize: this.options.pageSize
212
- });
213
- // Force change detection to update the UI
214
- this.cdr.detectChanges();
215
- console.log(`Page state restored from browser navigation: Page ${this.currentPage}, PageSize ${this.options.pageSize}, Filters restored`);
216
- }
217
- }
218
- }
219
- }
220
- catch (error) {
221
- console.warn('Failed to restore page state from history:', error);
222
- }
223
- }
224
- /**
225
- * Update local history index to match browser state
226
- */
227
- updateLocalHistoryIndex(savedState) {
228
- // Find the matching state in our local history
229
- const index = this.pageHistory.findIndex(state => state.page === savedState.page &&
230
- state.pageSize === savedState.pageSize &&
231
- JSON.stringify(state.filters) === JSON.stringify(savedState.filters));
232
- if (index !== -1) {
233
- this.currentHistoryIndex = index;
234
- }
235
- else {
236
- // If not found, add it to our history
237
- this.pageHistory.push(savedState);
238
- this.currentHistoryIndex = this.pageHistory.length - 1;
239
- }
240
- }
241
- /**
242
- * Update browser history state with current page and page size
243
- */
244
- updateHistoryState() {
245
- if (!this.options.enableBrowserNavigation) {
246
- return;
247
- }
248
- const currentFilters = this.getFiltersValue();
249
- const currentState = {
250
- page: this.currentPage,
251
- pageSize: this.options.pageSize,
252
- filters: currentFilters
253
- };
254
- // Only update history if we're not already navigating back
255
- if (!this.isNavigatingBack) {
256
- // Add current state to local history
257
- this.pageHistory.push(currentState);
258
- this.currentHistoryIndex = this.pageHistory.length - 1;
259
- // Limit history size to prevent memory issues
260
- if (this.pageHistory.length > 50) {
261
- this.pageHistory.shift();
262
- this.currentHistoryIndex--;
263
- }
264
- // Update browser history state
265
- const historyState = {
266
- pagingState: currentState,
267
- timestamp: Date.now()
268
- };
269
- try {
270
- // Use history.pushState to add a new history entry
271
- // This allows proper back/forward navigation
272
- history.pushState(historyState, '', this.location.path());
273
- }
274
- catch (error) {
275
- console.warn('Failed to update browser history state:', error);
276
- // Fallback to replaceState if pushState fails
277
- this.location.replaceState(this.location.path(), '', JSON.stringify(historyState));
278
- }
279
- }
280
- }
281
- ngAfterViewInit() {
282
- if (this.options.onClickFiltersControlNames != null && this.options.onClickFiltersControlNames.length > 0) {
283
- const OnClickFiltersControlNames = this.options.onClickFiltersControlNames;
284
- for (let index = 0; index < OnClickFiltersControlNames.length; index++) {
285
- const OnClickFiltersControlName = OnClickFiltersControlNames[index];
286
- document.getElementById(OnClickFiltersControlName).addEventListener("click", () => {
287
- this.currentPage = 1;
288
- this.isFirstCall = true;
289
- this.updateHistoryState();
290
- this.getItemList(this.currentPage, true);
291
- }, false);
292
- }
293
- }
294
- if (this.options.onKeyPressFiltersControlNames != null && this.options.onKeyPressFiltersControlNames.length > 0) {
295
- const OnKeyPressFiltersControlNames = this.options.onKeyPressFiltersControlNames;
296
- // Use Renderer2 to listen to document keypress event
297
- // This works with elements in parent component
298
- const keypressListener = this.renderer.listen('document', 'keypress', (event) => {
299
- if (event.key === "Enter") {
300
- const target = event.target;
301
- const formControlName = target.getAttribute('id');
302
- if (formControlName && OnKeyPressFiltersControlNames.includes(formControlName)) {
303
- event.preventDefault();
304
- event.stopPropagation();
305
- this.currentPage = 1;
306
- this.isFirstCall = true;
307
- this.updateHistoryState();
308
- this.getItemList(this.currentPage, true);
309
- return false;
310
- }
311
- }
312
- });
313
- // Store the unsubscribe function
314
- this.subscriptions.add({ unsubscribe: keypressListener });
315
- }
316
- //Add click event on Reset Filter button
317
- if (this.options.resetFilterButtonName != null) {
318
- const button = document.getElementsByName(this.options.resetFilterButtonName)[0];
319
- if (button != undefined) {
320
- let element = button;
321
- element.addEventListener("click", (e) => {
322
- this.clearFilters();
323
- }, false);
324
- }
325
- }
326
- if (this.options.typeaheadSearchControlNames != null && this.options.typeaheadSearchControlNames.length > 0) {
327
- const TypeaheadSearchControlNames = this.options.typeaheadSearchControlNames;
328
- for (let index = 0; index < TypeaheadSearchControlNames.length; index++) {
329
- const TypeaheadSearchControlName = TypeaheadSearchControlNames[index];
330
- document.getElementById(TypeaheadSearchControlName).addEventListener("keypress", (e) => {
331
- if (e.key == "Enter") {
332
- this.currentPage = 1;
333
- this.isFirstCall = true;
334
- this.updateHistoryState();
335
- this.getItemList(this.currentPage, true);
336
- }
337
- }, false);
338
- }
339
- }
340
- }
341
- onDropDownChange(result) {
342
- if (result) {
343
- this.currentPage = 1;
344
- this.isFirstCall = true;
345
- this.updateHistoryState();
346
- this.getItemList(this.currentPage, true);
347
- }
348
- }
349
- onChangePage(Page) {
350
- if (Page == 0)
351
- return;
352
- if (Page > 0) {
353
- if (this.isFirstCall) {
354
- this.isFirstCall = false;
355
- return;
356
- }
357
- this.currentPage = Page;
358
- this.updateHistoryState();
359
- this.getItemList(Page);
360
- }
361
- }
362
- changePageSize(e) {
363
- this.options.pageSize = e.target.value;
364
- this.currentPage = 1;
365
- this.isFirstCall = true;
366
- this.updateHistoryState();
367
- this.getItemList(this.currentPage, true);
368
- }
369
- onScrollDown() {
370
- this.sum += this.options.pageSize;
371
- this.currentPage = 1;
372
- this.isFirstCall = true;
373
- this.direction = 'down';
374
- this.getItemList(this.currentPage, true);
375
- }
376
- getItemList(page, IsFilterUpdated = false) {
377
- if (this.options.startPagingCallback)
378
- this.options.startPagingCallback.call(null);
379
- let filters = {};
380
- filters = this.getFiltersValue();
381
- // Skip filter change detection if we're restoring filters from browser history
382
- if (!this.isRestoringFilters && !IsFilterUpdated && Object.keys(this.previousFilters).length != 0 && JSON.stringify(this.previousFilters) != JSON.stringify(filters)) {
383
- //Reinitialize if filters changed
384
- page = 1;
385
- IsFilterUpdated = true;
386
- }
387
- this.previousFilters = filters;
388
- let pagingDTO = new PagingDTO();
389
- let size = Number.parseInt(this.options.pageSize.toString());
390
- if (this.options.isLoadMoreControl)
391
- pagingDTO.PageCount = this.sum;
392
- else
393
- pagingDTO.PageCount = size;
394
- pagingDTO.CurrentPageNumber = page;
395
- pagingDTO.TotalCount = this.totalRow;
396
- pagingDTO.IsFilterUpdated = IsFilterUpdated;
397
- //Set Filters object that sent to action URL
398
- let filtersDTO = {
399
- PagingDTO: pagingDTO,
400
- Filters: filters
401
- };
402
- let requestOptions = new RequestOptionsModel();
403
- requestOptions.disableBlockUI = this.options.disableBlockUI;
404
- this.requestHandlerService.post(this.options.actionPostURL, this.options.filters && this.options.filters.length > 0 ? filtersDTO : pagingDTO, null, null, requestOptions)
405
- .subscribe((responseData) => {
406
- this.options.totalCount = responseData.totalCount;
407
- this.result = responseData.items; //this.castItems(responseData.items);
408
- let castedResult = plainToClass(this.options.TypeOfResponse, this.result, { excludeExtraneousValues: true });
409
- this.Items.emit(castedResult);
410
- this.totalRow = responseData.totalCount;
411
- if (IsFilterUpdated) {
412
- this.items = [];
413
- this.Pages = Math.ceil((this.totalRow / this.options.pageSize));
414
- this.items = Array(this.totalRow);
415
- this.setText(this.Pages, this.totalRow);
416
- }
417
- }, (error) => {
418
- if (error.status == 401)
419
- this.router.navigate(["/Admin/account/login"]);
420
- });
421
- }
422
- /**
423
- * Force update the current page (useful for external components)
424
- */
425
- setCurrentPage(page) {
426
- if (page > 0 && page !== this.currentPage) {
427
- this.currentPage = page;
428
- this.updateHistoryState();
429
- this.getItemList(page);
430
- this.cdr.detectChanges();
431
- }
432
- }
433
- /**
434
- * Get the current page number
435
- */
436
- getCurrentPage() {
437
- return this.currentPage;
438
- }
439
- /**
440
- * Restore filter values to form controls
441
- */
442
- restoreFilterValues(savedFilters) {
443
- if (!this.options.filters || !this.group) {
444
- return;
445
- }
446
- this.isRestoringFilters = true;
447
- try {
448
- for (let index = 0; index < this.options.filters.length; index++) {
449
- const filter = this.options.filters[index];
450
- if (filter.formControlName && filter.formControlName !== "") {
451
- const formControlName = filter.formControlName;
452
- const actionParameterName = filter.actionParameterName;
453
- // Check if we have a saved value for this filter
454
- if (savedFilters.hasOwnProperty(actionParameterName)) {
455
- const savedValue = savedFilters[actionParameterName];
456
- // Only restore if the value is not null/undefined/empty
457
- if (savedValue !== null && savedValue !== undefined && savedValue !== "") {
458
- // Set the value to the form control
459
- this.group.controls[formControlName].setValue(savedValue);
460
- console.log(`Restored filter ${formControlName} with value:`, savedValue);
461
- }
462
- }
463
- }
464
- else if (filter.jQuerySelector) {
465
- // Handle jQuery selector based filters
466
- const actionParameterName = filter.actionParameterName;
467
- if (savedFilters.hasOwnProperty(actionParameterName)) {
468
- const savedValue = savedFilters[actionParameterName];
469
- if (savedValue !== null && savedValue !== undefined && savedValue !== "") {
470
- const element = document.querySelector(filter.jQuerySelector);
471
- if (element) {
472
- element.value = savedValue;
473
- console.log(`Restored jQuery filter ${filter.jQuerySelector} with value:`, savedValue);
474
- }
475
- }
476
- }
477
- }
478
- }
479
- }
480
- catch (error) {
481
- console.warn('Failed to restore filter values:', error);
482
- }
483
- finally {
484
- // Reset the flag after a short delay to allow form controls to update
485
- setTimeout(() => {
486
- this.isRestoringFilters = false;
487
- }, 100);
488
- }
489
- }
490
- castItems(objectArr) {
491
- let originalArray = [];
492
- for (let index = 0; index < objectArr.length; index++) {
493
- const element = objectArr[index];
494
- let key, keys = Object.keys(element);
495
- let n = keys.length;
496
- let newObject = {};
497
- while (n--) {
498
- key = keys[n];
499
- let Okey = key;
500
- newObject[key.charAt(0).toUpperCase() + Okey.slice(1)] = element[key];
501
- }
502
- let finalObject = newObject;
503
- originalArray.push(finalObject);
504
- }
505
- return originalArray;
506
- }
507
- setText(pagesNumber, itemsNumber) {
508
- if (this.utilityService.isCurrentLanguageArabic()) {
509
- //Set pages text
510
- if (pagesNumber < 3 || pagesNumber > 10)
511
- this.pagesText = this.utilityService.getResourceValue("Page");
512
- else
513
- this.pagesText = this.utilityService.getResourceValue("Pages");
514
- //Set items text
515
- if (itemsNumber < 3 || itemsNumber > 10)
516
- this.itemsText = this.utilityService.getResourceValue("Item");
517
- else
518
- this.itemsText = this.utilityService.getResourceValue("Items");
519
- }
520
- else {
521
- //Set pages text
522
- if (pagesNumber > 1)
523
- this.pagesText = this.utilityService.getResourceValue("Pages");
524
- else
525
- this.pagesText = this.utilityService.getResourceValue("Page");
526
- //Set items text
527
- if (itemsNumber > 1)
528
- this.itemsText = this.utilityService.getResourceValue("Items");
529
- else
530
- this.itemsText = this.utilityService.getResourceValue("Item");
531
- }
532
- }
533
- clearFilters() {
534
- if (this.options.filters != null) {
535
- for (let index = 0; index < this.options.filters.length; index++) {
536
- if (this.options.filters[index].formControlName != null && this.options.filters[index].formControlName != "") {
537
- const FormControlName = this.options.filters[index].formControlName;
538
- this.group.controls[FormControlName].setValue(null);
539
- }
540
- }
541
- // Clear history state when filters are reset
542
- this.clearHistoryState();
543
- this.reinitializePaging();
544
- }
545
- }
546
- /**
547
- * Clear page history state
548
- */
549
- clearHistoryState() {
550
- if (!this.options.enableBrowserNavigation) {
551
- return;
552
- }
553
- // Clear the page history
554
- this.pageHistory = [];
555
- this.currentHistoryIndex = -1;
556
- }
557
- getFiltersValue() {
558
- let filters = {};
559
- if (this.options.filters != null) {
560
- for (let index = 0; index < this.options.filters.length; index++) {
561
- if (this.options.filters[index].formControlName != null && this.options.filters[index].formControlName != "") {
562
- const FormControlName = this.options.filters[index].formControlName;
563
- let ControlValue = this.group.controls[FormControlName].value;
564
- if (ControlValue != undefined && ControlValue != null && ControlValue != "") {
565
- if (this.options.filters[index].filterType == FilterType.DatePicker) {
566
- //if (Array.isArray(ControlValue)) {
567
- // for (let element = 0; element < ControlValue.length; element++) {
568
- // const value = ControlValue[element];
569
- // filters[this.options.Filters[index].ActionParameterName] = value;
570
- // }
571
- //}
572
- //else {
573
- filters[this.options.filters[index].actionParameterName] = ControlValue;
574
- //}
575
- }
576
- else {
577
- if (this.options.filters[index].filterType == FilterType.AutocompleteTextBox)
578
- ControlValue = ControlValue;
579
- if (this.options.filters[index].filterType == FilterType.TagInput)
580
- ControlValue = ControlValue;
581
- filters[this.options.filters[index].actionParameterName] = ControlValue;
582
- }
583
- }
584
- else {
585
- filters[this.options.filters[index].actionParameterName] = null;
586
- }
587
- }
588
- else {
589
- const ElementjQuerySelector = this.options.filters[index].jQuerySelector;
590
- let ElementValue = document.querySelector(ElementjQuerySelector).value;
591
- if (ElementValue != undefined && ElementValue != null)
592
- filters[this.options.filters[index].actionParameterName] = ElementValue;
593
- else
594
- filters[this.options.filters[index].actionParameterName] = null;
595
- }
596
- }
597
- }
598
- return filters;
599
- }
600
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PagingComponent, deps: [{ token: i1.UtilityService }, { token: i2.HttpClient }, { token: i3.Router }, { token: i3.ActivatedRoute }, { token: i4.Location }, { token: i5.OnPagingFiltersChangeService }, { token: i6.RequestHandlerService }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
601
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: PagingComponent, isStandalone: true, selector: "BBSF-Paging", inputs: { options: "options", group: "group" }, outputs: { Items: "Items", pageStateRestored: "pageStateRestored" }, host: { listeners: { "window:popstate": "onPopState($event)" } }, ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-paging\" *ngIf=\"(result.length > 0)\" role=\"navigation\" [attr.aria-label]=\"utilityService.getResourceValue('Pagination')\">\r\n <!--paging container-->\r\n <div class=\"bbsf-paging-container\" *ngIf=\"!options.isLoadMoreControl\">\r\n <!--items-->\r\n <div class=\"bbsf-pagination\">\r\n <jw-pagination [items]=\"items\" *ngIf=\"!((Pages==1)&&options.hidePaginationWhenPageSizeEqualOne)\"\r\n (changePage)=\"onChangePage($event)\" [pageSize]=\"options.pageSize\" [ShowFirstAndLast]=\"options.showFirstAndLast\"\r\n [initialPage]=\"currentPage\" [maxPages]=\"10\"></jw-pagination>\r\n </div>\r\n <!--page count-->\r\n <div class=\"bbsf-pages\" *ngIf=\"!((Pages==1)&&options.hidePaginationWhenPageSizeEqualOne)\">\r\n <select (change)=\"changePageSize($event)\" *ngIf=\"options.showPageSizeOption\" \r\n [attr.aria-label]=\"utilityService.getResourceValue('SelectPageSize')\" \r\n [ngbTooltip]=\"utilityService.getResourceValue('SelectPageSize')\">\r\n <option>10</option>\r\n <option>20</option>\r\n <option>50</option>\r\n <option>100</option>\r\n <option>200</option>\r\n </select>\r\n <div class=\"bssf-items\" [attr.aria-label]=\"utilityService.getResourceValue('PageInfo')\">\r\n <strong>{{totalRow}}</strong> {{itemsText}} {{utilityService.getResourceValue(\"In\")}} <strong>\r\n {{Pages}}</strong> {{pagesText}}\r\n </div>\r\n </div>\r\n </div>\r\n <!--load more-->\r\n <div class=\"bbsf-loadmore\" *ngIf=\"options.isLoadMoreControl\">\r\n <div class=\"search-results\" infinite-scroll [infiniteScrollDistance]=\"scrollDistance\"\r\n [infiniteScrollUpDistance]=\"scrollUpDistance\" [infiniteScrollThrottle]=\"throttle\"\r\n (scrolled)=\"options.isInfiniteScroll==true?onScrollDown():null\" [scrollWindow]=\"options.scrollWindow\"\r\n [infiniteScrollContainer]=\"options.infiniteScrollContainer\">\r\n </div>\r\n <button class=\"btn btn-sm btn-primary\" (click)=\"onScrollDown()\"\r\n *ngIf=\"!(result.length==totalRow)\"\r\n [attr.aria-label]=\"utilityService.getResourceValue('LoadMore')\"\r\n [ngbTooltip]=\"utilityService.getResourceValue('LoadMore')\">{{utilityService.getResourceValue(\"LoadMore\")}}</button>\r\n </div>\r\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "ngmodule", type: BlockUIModule }, { kind: "ngmodule", type: InlineSVGModule }, { kind: "component", type: JwPaginationComponent, selector: "jw-pagination", inputs: ["items", "initialPage", "pageSize", "maxPages", "ShowFirstAndLast"], outputs: ["changePage"] }] }); }
602
- }
603
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PagingComponent, decorators: [{
604
- type: Component,
605
- args: [{ selector: 'BBSF-Paging', standalone: true, imports: [
606
- CommonModule,
607
- FormsModule,
608
- ReactiveFormsModule,
609
- NgbTooltip,
610
- BlockUIModule,
611
- InlineSVGModule,
612
- JwPaginationComponent
613
- ], schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA], template: "<div class=\"form-group bbsf-control bbsf-paging\" *ngIf=\"(result.length > 0)\" role=\"navigation\" [attr.aria-label]=\"utilityService.getResourceValue('Pagination')\">\r\n <!--paging container-->\r\n <div class=\"bbsf-paging-container\" *ngIf=\"!options.isLoadMoreControl\">\r\n <!--items-->\r\n <div class=\"bbsf-pagination\">\r\n <jw-pagination [items]=\"items\" *ngIf=\"!((Pages==1)&&options.hidePaginationWhenPageSizeEqualOne)\"\r\n (changePage)=\"onChangePage($event)\" [pageSize]=\"options.pageSize\" [ShowFirstAndLast]=\"options.showFirstAndLast\"\r\n [initialPage]=\"currentPage\" [maxPages]=\"10\"></jw-pagination>\r\n </div>\r\n <!--page count-->\r\n <div class=\"bbsf-pages\" *ngIf=\"!((Pages==1)&&options.hidePaginationWhenPageSizeEqualOne)\">\r\n <select (change)=\"changePageSize($event)\" *ngIf=\"options.showPageSizeOption\" \r\n [attr.aria-label]=\"utilityService.getResourceValue('SelectPageSize')\" \r\n [ngbTooltip]=\"utilityService.getResourceValue('SelectPageSize')\">\r\n <option>10</option>\r\n <option>20</option>\r\n <option>50</option>\r\n <option>100</option>\r\n <option>200</option>\r\n </select>\r\n <div class=\"bssf-items\" [attr.aria-label]=\"utilityService.getResourceValue('PageInfo')\">\r\n <strong>{{totalRow}}</strong> {{itemsText}} {{utilityService.getResourceValue(\"In\")}} <strong>\r\n {{Pages}}</strong> {{pagesText}}\r\n </div>\r\n </div>\r\n </div>\r\n <!--load more-->\r\n <div class=\"bbsf-loadmore\" *ngIf=\"options.isLoadMoreControl\">\r\n <div class=\"search-results\" infinite-scroll [infiniteScrollDistance]=\"scrollDistance\"\r\n [infiniteScrollUpDistance]=\"scrollUpDistance\" [infiniteScrollThrottle]=\"throttle\"\r\n (scrolled)=\"options.isInfiniteScroll==true?onScrollDown():null\" [scrollWindow]=\"options.scrollWindow\"\r\n [infiniteScrollContainer]=\"options.infiniteScrollContainer\">\r\n </div>\r\n <button class=\"btn btn-sm btn-primary\" (click)=\"onScrollDown()\"\r\n *ngIf=\"!(result.length==totalRow)\"\r\n [attr.aria-label]=\"utilityService.getResourceValue('LoadMore')\"\r\n [ngbTooltip]=\"utilityService.getResourceValue('LoadMore')\">{{utilityService.getResourceValue(\"LoadMore\")}}</button>\r\n </div>\r\n</div>" }]
614
- }], ctorParameters: () => [{ type: i1.UtilityService }, { type: i2.HttpClient }, { type: i3.Router }, { type: i3.ActivatedRoute }, { type: i4.Location }, { type: i5.OnPagingFiltersChangeService }, { type: i6.RequestHandlerService }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: i0.ElementRef }], propDecorators: { Items: [{
615
- type: Output
616
- }], pageStateRestored: [{
617
- type: Output
618
- }], options: [{
619
- type: Input
620
- }], group: [{
621
- type: Input
622
- }], onPopState: [{
623
- type: HostListener,
624
- args: ['window:popstate', ['$event']]
625
- }] } });
626
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGFnaW5nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Jic2YtY29udHJvbHMvc3JjL2xpYi9jb250cm9scy9QYWdpbmcvUGFnaW5nLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Jic2YtY29udHJvbHMvc3JjL2xpYi9jb250cm9scy9QYWdpbmcvUGFnaW5nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQWEsWUFBWSxFQUFxQixzQkFBc0IsRUFBRSxnQkFBZ0IsRUFBeUIsTUFBTSxlQUFlLENBQUM7QUFDNUwsT0FBTyxFQUFFLFlBQVksRUFBWSxNQUFNLGlCQUFpQixDQUFDO0FBR3pELE9BQU8sRUFBYSxXQUFXLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDeEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM1QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTFELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFcEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzNELE9BQU8sRUFBeUIsbUJBQW1CLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUzRixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFakQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7Ozs7OztBQWlCakUsTUFBTSxPQUFPLGVBQWU7SUFtQzFCLFlB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USxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25EZXN0cm95LCBIb3N0TGlzdGVuZXIsIENoYW5nZURldGVjdG9yUmVmLCBDVVNUT01fRUxFTUVOVFNfU0NIRU1BLCBOT19FUlJPUlNfU0NIRU1BLCBSZW5kZXJlcjIsIEVsZW1lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlLCBMb2NhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IFJvdXRlciwgQWN0aXZhdGVkUm91dGUgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5pbXBvcnQgeyBIdHRwQ2xpZW50LCBIdHRwRXJyb3JSZXNwb25zZSwgSHR0cEhlYWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7IEZvcm1Hcm91cCwgRm9ybXNNb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IE5nYlRvb2x0aXAgfSBmcm9tICdAbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcCc7XHJcbmltcG9ydCB7IEJsb2NrVUlNb2R1bGUgfSBmcm9tICduZy1ibG9jay11aSc7XHJcbmltcG9ydCB7IElubGluZVNWR01vZHVsZSB9IGZyb20gJ25nLWlubGluZS1zdmctMic7XHJcbmltcG9ydCB7IFBhZ2luZ0RUTyB9IGZyb20gJy4uLy4uL1NoYXJlZC9Nb2RlbHMvUGFnaW5nRFRPJztcclxuaW1wb3J0IHsgUGFnaW5nT3B0aW9ucyB9IGZyb20gJy4uLy4uL1NoYXJlZC9Nb2RlbHMvUGFnaW5nT3B0aW9ucyc7XHJcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBPblBhZ2luZ0ZpbHRlcnNDaGFuZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vU2hhcmVkL3NlcnZpY2VzL09uUGFnaW5nRmlsdGVyc0NoYW5nZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRmlsdGVyVHlwZSB9IGZyb20gJy4uLy4uL1NoYXJlZC9FbnVtcy9GaWx0ZXJUeXBlJztcclxuaW1wb3J0IHsgUmVxdWVzdEhhbmRsZXJTZXJ2aWNlLCBSZXF1ZXN0T3B0aW9uc01vZGVsIH0gZnJvbSAnQGJuc2lnaHRzL2Jic2YtdXRpbGl0aWVzL2h0dHAnO1xyXG5pbXBvcnQgeyBVdGlsaXR5U2VydmljZSB9IGZyb20gJ0BibnNpZ2h0cy9iYnNmLXV0aWxpdGllcy91aSc7XHJcbmltcG9ydCB7IHBsYWluVG9DbGFzcyB9IGZyb20gJ2NsYXNzLXRyYW5zZm9ybWVyJztcclxuaW1wb3J0IHsgUGFnaW5nUGF5bG9hZCB9IGZyb20gJy4uLy4uL1NoYXJlZC9Nb2RlbHMvUGFnaW5nUGF5bG9hZCc7XHJcbmltcG9ydCB7IEp3UGFnaW5hdGlvbkNvbXBvbmVudCB9IGZyb20gJy4vSndQYWdpbmF0aW9uLmNvbXBvbmVudCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ0JCU0YtUGFnaW5nJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vUGFnaW5nLmNvbXBvbmVudC5odG1sJyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtcclxuICAgIENvbW1vbk1vZHVsZSxcclxuICAgIEZvcm1zTW9kdWxlLFxyXG4gICAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcclxuICAgIE5nYlRvb2x0aXAsXHJcbiAgICBCbG9ja1VJTW9kdWxlLFxyXG4gICAgSW5saW5lU1ZHTW9kdWxlLFxyXG4gICAgSndQYWdpbmF0aW9uQ29tcG9uZW50XHJcbiAgXSxcclxuICBzY2hlbWFzOiBbQ1VTVE9NX0VMRU1FTlRTX1NDSEVNQSwgTk9fRVJST1JTX1NDSEVNQV1cclxufSlcclxuZXhwb3J0IGNsYXNzIFBhZ2luZ0NvbXBvbmVudDxUPiBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuXHJcbiAgaXRlbXMgPSBbXTtcclxuICBwYWdlT2ZJdGVtczogQXJyYXk8YW55PjtcclxuICByZXN1bHQ6IFRbXSA9IFtdO1xyXG4gIHBhZ2VyQ29uZmlnOiBhbnkgPSBudWxsO1xyXG4gIHRvdGFsUm93OiBhbnkgPSAwO1xyXG4gIHBhZ2VTaXplOiBhbnkgPSAxMDtcclxuICBQYWdlczogYW55ID0gMDtcclxuICBwYWdlc1RleHQ6IHN0cmluZztcclxuICBpdGVtc1RleHQ6IHN0cmluZztcclxuICBjdXJyZW50UGFnZTogYW55ID0gMTtcclxuICBzaG93UGFnZVNpemVPcHRpb24gPSB0cnVlO1xyXG4gIHNob3dGaXJzdEFuZExhc3QgPSB0cnVlO1xyXG4gIGhpZGVQYWdpbmF0aW9uV2hlblBhZ2VTaXplRXF1YWxPbmUgPSB0cnVlO1xyXG4gIHN1bSA9IDA7XHJcbiAgdGhyb3R0bGUgPSAzMDA7XHJcbiAgc2Nyb2xsRGlzdGFuY2UgPSAxO1xyXG4gIHNjcm9sbFVwRGlzdGFuY2UgPSAyO1xyXG4gIGRpcmVjdGlvbiA9ICcnO1xyXG4gIGhlYWRlcnM6IEh0dHBIZWFkZXJzO1xyXG4gIGlzRmlyc3RDYWxsOiBib29sZWFuID0gdHJ1ZTtcclxuICBwcmV2aW91c0ZpbHRlcnM6IGFueSA9IHt9O1xyXG4gIEBPdXRwdXQoKSBJdGVtczogRXZlbnRFbWl0dGVyPFRbXT4gPSBuZXcgRXZlbnRFbWl0dGVyPFRbXT4oKTtcclxuICBAT3V0cHV0KCkgcGFnZVN0YXRlUmVzdG9yZWQ6IEV2ZW50RW1pdHRlcjx7IHBhZ2U6IG51bWJlciwgcGFnZVNpemU6IG51bWJlcjsgfT4gPSBuZXcgRXZlbnRFbWl0dGVyPHsgcGFnZTogbnVtYmVyLCBwYWdlU2l6ZTogbnVtYmVyOyB9PigpO1xyXG4gIEBJbnB1dCgpIG9wdGlvbnM6IFBhZ2luZ09wdGlvbnM7XHJcbiAgQElucHV0KCkgZ3JvdXA6IEZvcm1Hcm91cDtcclxuICBzdWJzY3JpcHRpb25zID0gbmV3IFN1YnNjcmlwdGlvbigpO1xyXG5cclxuICAvLyBCcm93c2VyIG5hdmlnYXRpb24gc3VwcG9ydFxyXG4gIHByaXZhdGUgaXNOYXZpZ2F0aW5nQmFjayA9IGZhbHNlO1xyXG4gIHByaXZhdGUgaXNSZXN0b3JpbmdGaWx0ZXJzID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBwYWdlSGlzdG9yeTogQXJyYXk8eyBwYWdlOiBudW1iZXIsIHBhZ2VTaXplOiBudW1iZXIsIGZpbHRlcnM6IGFueTsgfT4gPSBbXTtcclxuICBwcml2YXRlIGN1cnJlbnRIaXN0b3J5SW5kZXggPSAtMTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwdWJsaWMgdXRpbGl0eVNlcnZpY2U6IFV0aWxpdHlTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxyXG4gICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcclxuICAgIHByaXZhdGUgcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxyXG4gICAgcHJpdmF0ZSBsb2NhdGlvbjogTG9jYXRpb24sXHJcbiAgICBwcml2YXRlIG9uQ2hhbmdlU2VydmljZTogT25QYWdpbmdGaWx0ZXJzQ2hhbmdlU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVxdWVzdEhhbmRsZXJTZXJ2aWNlOiBSZXF1ZXN0SGFuZGxlclNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXHJcbiAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWZcclxuICApIHtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIC8vIEluaXRpYWxpemUgYnJvd3NlciBuYXZpZ2F0aW9uIHN1cHBvcnQgaWYgZW5hYmxlZFxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5lbmFibGVCcm93c2VyTmF2aWdhdGlvbikge1xyXG4gICAgICB0aGlzLmluaXRpYWxpemVCcm93c2VyTmF2aWdhdGlvbigpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuaXNMb2FkTW9yZUNvbnRyb2wpXHJcbiAgICAgIHRoaXMuc3VtID0gdGhpcy5vcHRpb25zLnBhZ2VTaXplO1xyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuZHJvcGRvd25GaWx0ZXJzQ29udHJvbE5hbWVzICE9IG51bGwgJiYgdGhpcy5vcHRpb25zLmRyb3Bkb3duRmlsdGVyc0NvbnRyb2xOYW1lcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGNvbnN0IERyb3Bkb3duRmlsdGVyc0NvbnRyb2xOYW1lcyA9IHRoaXMub3B0aW9ucy5kcm9wZG93bkZpbHRlcnNDb250cm9sTmFtZXM7XHJcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXHJcbiAgICAgICAgdGhpcy5vbkNoYW5nZVNlcnZpY2UuR2V0VmFsdWUoKS5zdWJzY3JpYmUoKHZhbHVlKSA9PiB7XHJcbiAgICAgICAgICBsZXQgcmVzdWx0ID0gdGhpcy5vcHRpb25zLmRyb3Bkb3duRmlsdGVyc0NvbnRyb2xOYW1lcy5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0gPT0gdmFsdWUpO1xyXG4gICAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaXNGaXJzdENhbGwgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRQYWdlID0gMTtcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVIaXN0b3J5U3RhdGUoKTtcclxuICAgICAgICAgICAgdGhpcy5nZXRJdGVtTGlzdCh0aGlzLmN1cnJlbnRQYWdlLCB0cnVlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5ib290c3RyYXBEYXRlUGlja2Vyc0ZpbHRlcnNDb250cm9sTmFtZXMgIT0gbnVsbCAmJiB0aGlzLm9wdGlvbnMuYm9vdHN0cmFwRGF0ZVBpY2tlcnNGaWx0ZXJzQ29udHJvbE5hbWVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgY29uc3QgQm9vdHN0cmFwRGF0ZVBpY2tlcnNGaWx0ZXJzQ29udHJvbE5hbWVzID0gdGhpcy5vcHRpb25zLmJvb3RzdHJhcERhdGVQaWNrZXJzRmlsdGVyc0NvbnRyb2xOYW1lcztcclxuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLm9uQ2hhbmdlU2VydmljZS5HZXRWYWx1ZSgpLnN1YnNjcmliZSgodmFsdWUpID0+IHtcclxuICAgICAgICBsZXQgcmVzdWx0ID0gdGhpcy5vcHRpb25zLmJvb3RzdHJhcERhdGVQaWNrZXJzRmlsdGVyc0NvbnRyb2xOYW1lcy5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0gPT0gdmFsdWUpO1xyXG4gICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgdGhpcy5pc0ZpcnN0Q2FsbCA9IHRydWU7XHJcbiAgICAgICAgICB0aGlzLmN1cnJlbnRQYWdlID0gMTtcclxuICAgICAgICAgIHRoaXMudXBkYXRlSGlzdG9yeVN0YXRlKCk7XHJcbiAgICAgICAgICB0aGlzLmdldEl0ZW1MaXN0KHRoaXMuY3VycmVudFBhZ2UsIHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuaXNGaXJzdENhbGwgPSB0cnVlO1xyXG4gICAgdGhpcy5nZXRJdGVtTGlzdCh0aGlzLmN1cnJlbnRQYWdlLCB0cnVlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemUgYnJvd3NlciBuYXZpZ2F0aW9uIHN1cHBvcnRcclxuICAgKi9cclxuICBwcml2YXRlIGluaXRpYWxpemVCcm93c2VyTmF2aWdhdGlvbigpOiB2b2lkIHtcclxuICAgIC8vIFRyeSB0byByZXN0b3JlIHN0YXRlIGZyb20gYnJvd3NlciBoaXN0b3J5IG9uIGluaXRpYWwgbG9hZFxyXG4gICAgdGhpcy5yZXN0b3JlU3RhdGVGcm9tQnJvd3Nlckhpc3RvcnkoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlc3RvcmUgc3RhdGUgZnJvbSBicm93c2VyIGhpc3Rvcnkgb24gaW5pdGlhbCBsb2FkXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZXN0b3JlU3RhdGVGcm9tQnJvd3Nlckhpc3RvcnkoKTogdm9pZCB7XHJcbiAgICB0cnkge1xyXG4gICAgICAvLyBHZXQgdGhlIGN1cnJlbnQgaGlzdG9yeSBzdGF0ZVxyXG4gICAgICBjb25zdCBjdXJyZW50U3RhdGUgPSBoaXN0b3J5LnN0YXRlO1xyXG5cclxuICAgICAgaWYgKGN1cnJlbnRTdGF0ZSAmJiBjdXJyZW50U3RhdGUucGFnaW5nU3RhdGUpIHtcclxuICAgICAgICBjb25zdCBzYXZlZFN0YXRlID0gY3VycmVudFN0YXRlLnBhZ2luZ1N0YXRlO1xyXG5cclxuICAgICAgICAvLyBDaGVjayBpZiB0aGUgc2F2ZWQgc3RhdGUgaGFzIHZhbGlkIGRhdGFcclxuICAgICAgICBpZiAoc2F2ZWRTdGF0ZS5wYWdlICYmIHNhdmVkU3RhdGUucGFnZVNpemUgJiYgc2F2ZWRTdGF0ZS5maWx0ZXJzKSB7XHJcbiAgICAgICAgICAvLyBSZXN0b3JlIGZpbHRlciB2YWx1ZXMgdG8gZm9ybSBjb250cm9sc1xyXG4gICAgICAgICAgdGhpcy5yZXN0b3JlRmlsdGVyVmFsdWVzKHNhdmVkU3RhdGUuZmlsdGVycyk7XHJcblxyXG4gICAgICAgICAgLy8gR2V0IGN1cnJlbnQgZmlsdGVycyBhZnRlciByZXN0b3JhdGlvblxyXG4gICAgICAgICAgY29uc3QgY3VycmVudEZpbHRlcnMgPSB0aGlzLmdldEZpbHRlcnNWYWx1ZSgpO1xyXG5cclxuICAgICAgICAgIC8vIE9ubHkgcmVzdG9yZSBpZiBmaWx0ZXJzIG1hdGNoIChzYW1lIHNlYXJjaCBjb250ZXh0KVxyXG4gICAgICAgICAgaWYgKEpTT04uc3RyaW5naWZ5KHNhdmVkU3RhdGUuZmlsdGVycykgPT09IEpTT04uc3RyaW5naWZ5KGN1cnJlbnRGaWx0ZXJzKSkge1xyXG4gICAgICAgICAgICBsZXQgcGFnZUNoYW5nZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgbGV0IHBhZ2VTaXplQ2hhbmdlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgaWYgKHNhdmVkU3RhdGUucGFnZSAhPT0gdGhpcy5jdXJyZW50UGFnZSkge1xyXG4gICAgICAgICAgICAgIHRoaXMuY3VycmVudFBhZ2UgPSBzYXZlZFN0YXRlLnBhZ2U7XHJcbiAgICAgICAgICAgICAgcGFnZUNoYW5nZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoc2F2ZWRTdGF0ZS5wYWdlU2l6ZSAhPT0gdGhpcy5vcHRpb25zLnBhZ2VTaXplKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLnBhZ2VTaXplID0gc2F2ZWRTdGF0ZS5wYWdlU2l6ZTtcclxuICAgICAgICAgICAgICBwYWdlU2l6ZUNoYW5nZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBJZiBwYWdlIG9yIHBhZ2Ugc2l6ZSBjaGFuZ2VkLCByZWxvYWQgZGF0YVxyXG4gICAgICAgICAgICBpZiAocGFnZUNoYW5nZWQgfHwgcGFnZVNpemVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5nZXRJdGVtTGlzdCh0aGlzLmN1cnJlbnRQYWdlLCBwYWdlU2l6ZUNoYW5nZWQpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBBZGQgdGhlIHJlc3RvcmVkIHN0YXRlIHRvIG91ciBsb2NhbCBoaXN0b3J5XHJcbiAgICAgICAgICAgIHRoaXMucGFnZUhpc3RvcnkucHVzaChzYXZlZFN0YXRlKTtcclxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SGlzdG9yeUluZGV4ID0gdGhpcy5wYWdlSGlzdG9yeS5sZW5ndGggLSAxO1xyXG5cclxuICAgICAgICAgICAgLy8gRW1pdCBldmVudCB0byBub3RpZnkgdGhhdCBwYWdlIHN0YXRlIHdhcyByZXN0b3JlZFxyXG4gICAgICAgICAgICB0aGlzLnBhZ2VTdGF0ZVJlc3RvcmVkLmVtaXQoe1xyXG4gICAgICAgICAgICAgIHBhZ2U6IHRoaXMuY3VycmVudFBhZ2UsXHJcbiAgICAgICAgICAgICAgcGFnZVNpemU6IHRoaXMub3B0aW9ucy5wYWdlU2l6ZVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIC8vIEZvcmNlIGNoYW5nZSBkZXRlY3Rpb24gdG8gdXBkYXRlIHRoZSBVSVxyXG4gICAgICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XHJcblxyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgSW5pdGlhbCBwYWdlIHN0YXRlIHJlc3RvcmVkOiBQYWdlICR7dGhpcy5jdXJyZW50UGFnZX0sIFBhZ2VTaXplICR7dGhpcy5vcHRpb25zLnBhZ2VTaXplfSwgRmlsdGVycyByZXN0b3JlZGApO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc29sZS53YXJuKCdGYWlsZWQgdG8gcmVzdG9yZSBicm93c2VyIGhpc3Rvcnkgc3RhdGU6JywgZXJyb3IpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTGlzdGVuIHRvIGJyb3dzZXIgYmFjay9mb3J3YXJkIG5hdmlnYXRpb25cclxuICAgKi9cclxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cG9wc3RhdGUnLCBbJyRldmVudCddKVxyXG4gIG9uUG9wU3RhdGUoZXZlbnQ6IFBvcFN0YXRlRXZlbnQpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5vcHRpb25zLmVuYWJsZUJyb3dzZXJOYXZpZ2F0aW9uKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zb2xlLmxvZygnQnJvd3NlciBiYWNrL2ZvcndhcmQgbmF2aWdhdGlvbiBkZXRlY3RlZCcpO1xyXG4gICAgdGhpcy5pc05hdmlnYXRpbmdCYWNrID0gdHJ1ZTtcclxuICAgIHRoaXMucmVzdG9yZVBhZ2VTdGF0ZUZyb21IaXN0b3J5KCk7XHJcbiAgICB0aGlzLmlzTmF2aWdhdGluZ0JhY2sgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlc3RvcmUgcGFnZSBzdGF0ZSBmcm9tIGJyb3dzZXIgaGlzdG9yeVxyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVzdG9yZVBhZ2VTdGF0ZUZyb21IaXN0b3J5KCk6IHZvaWQge1xyXG4gICAgdHJ5IHtcclxuICAgICAgLy8gR2V0IHRoZSBjdXJyZW50IGhpc3Rvcnkgc3RhdGUgZnJvbSBicm93c2VyXHJcbiAgICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IGhpc3Rvcnkuc3RhdGU7XHJcblxyXG4gICAgICBpZiAoY3VycmVudFN0YXRlICYmIGN1cnJlbnRTdGF0ZS5wYWdpbmdTdGF0ZSkge1xyXG4gICAgICAgIGNvbnN0IHNhdmVkU3RhdGUgPSBjdXJyZW50U3RhdGUucGFnaW5nU3RhdGU7XHJcblxyXG4gICAgICAgIC8vIENoZWNrIGlmIHRoZSBzYXZlZCBzdGF0ZSBoYXMgdmFsaWQgZGF0YVxyXG4gICAgICAgIGlmIChzYXZlZFN0YXRlLnBhZ2UgJiYgc2F2ZWRTdGF0ZS5wYWdlU2l6ZSAmJiBzYXZlZFN0YXRlLmZpbHRlcnMpIHtcclxuICAgICAgICAgIC8vIFJlc3RvcmUgZmlsdGVyIHZhbHVlcyB0byBmb3JtIGNvbnRyb2xzXHJcbiAgICAgICAgICB0aGlzLnJlc3RvcmVGaWx0ZXJWYWx1ZXMoc2F2ZWRTdGF0ZS5maWx0ZXJzKTtcclxuXHJcbiAgICAgICAgICAvLyBHZXQgY3VycmVudCBmaWx0ZXJzIGFmdGVyIHJlc3RvcmF0aW9uXHJcbiAgICAgICAgICBjb25zdCBjdXJyZW50RmlsdGVycyA9IHRoaXMuZ2V0RmlsdGVyc1ZhbHVlKCk7XHJcblxyXG4gICAgICAgICAgLy8gT25seSByZXN0b3JlIGlmIGZpbHRlcnMgbWF0Y2ggKHNhbWUgc2VhcmNoIGNvbnRleHQpXHJcbiAgICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkoc2F2ZWRTdGF0ZS5maWx0ZXJzKSA9PT0gSlNPTi5zdHJpbmdpZnkoY3VycmVudEZpbHRlcnMpKSB7XHJcbiAgICAgICAgICAgIGxldCBwYWdlQ2hhbmdlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBsZXQgcGFnZVNpemVDaGFuZ2VkID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICBpZiAoc2F2ZWRTdGF0ZS5wYWdlICE9PSB0aGlzLmN1cnJlbnRQYWdlKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5jdXJyZW50UGFnZSA9IHNhdmVkU3RhdGUucGFnZTtcclxuICAgICAgICAgICAgICBwYWdlQ2hhbmdlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChzYXZlZFN0YXRlLnBhZ2VTaXplICE9PSB0aGlzLm9wdGlvbnMucGFnZVNpemUpIHtcclxuICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMucGFnZVNpemUgPSBzYXZlZFN0YXRlLnBhZ2VTaXplO1xyXG4gICAgICAgICAgICAgIHBhZ2VTaXplQ2hhbmdlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIElmIHBhZ2Ugb3IgcGFnZSBzaXplIGNoYW5nZWQsIHJlbG9hZCBkYXRhXHJcbiAgICAgICAgICAgIGlmIChwYWdlQ2hhbmdlZCB8fCBwYWdlU2l6ZUNoYW5nZWQpIHtcclxuICAgICAgICAgICAgICB0aGlzLmdldEl0ZW1MaXN0KHRoaXMuY3VycmVudFBhZ2UsIHBhZ2VTaXplQ2hhbmdlZCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIFVwZGF0ZSBvdXIgbG9jYWwgaGlzdG9yeSBpbmRleCB0byBtYXRjaCB0aGUgYnJvd3NlciBzdGF0ZVxyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUxvY2FsSGlzdG9yeUluZGV4KHNhdmVkU3RhdGUpO1xyXG5cclxuICAgICAgICAgICAgLy8gRW1pdCBldmVudCB0byBub3RpZnkgdGhhdCBwYWdlIHN0YXRlIHdhcyByZXN0b3JlZFxyXG4gICAgICAgICAgICB0aGlzLnBhZ2VTdGF0ZVJlc3RvcmVkLmVtaXQoe1xyXG4gICAgICAgICAgICAgIHBhZ2U6IHRoaXMuY3VycmVudFBhZ2UsXHJcbiAgICAgICAgICAgICAgcGFnZVNpemU6IHRoaXMub3B0aW9ucy5wYWdlU2l6ZVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIC8vIEZvcmNlIGNoYW5nZSBkZXRlY3Rpb24gdG8gdXBkYXRlIHRoZSBVSVxyXG4gICAgICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XHJcblxyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgUGFnZSBzdGF0ZSByZXN0b3JlZCBmcm9tIGJyb3dzZXIgbmF2aWdhdGlvbjogUGFnZSAke3RoaXMuY3VycmVudFBhZ2V9LCBQYWdlU2l6ZSAke3RoaXMub3B0aW9ucy5wYWdlU2l6ZX0sIEZpbHRlcnMgcmVzdG9yZWRgKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybignRmFpbGVkIHRvIHJlc3RvcmUgcGFnZSBzdGF0ZSBmcm9tIGhpc3Rvcnk6JywgZXJyb3IpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVXBkYXRlIGxvY2FsIGhpc3RvcnkgaW5kZXggdG8gbWF0Y2ggYnJvd3NlciBzdGF0ZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgdXBkYXRlTG9jYWxIaXN0b3J5SW5kZXgoc2F2ZWRTdGF0ZTogYW55KTogdm9pZCB7XHJcbiAgICAvLyBGaW5kIHRoZSBtYXRjaGluZyBzdGF0ZSBpbiBvdXIgbG9jYWwgaGlzdG9yeVxyXG4gICAgY29uc3QgaW5kZXggPSB0aGlzLnBhZ2VIaXN0b3J5LmZpbmRJbmRleChzdGF0ZSA9PlxyXG4gICAgICBzdGF0ZS5wYWdlID09PSBzYXZlZFN0YXRlLnBhZ2UgJiZcclxuICAgICAgc3RhdGUucGFnZVNpemUgPT09IHNhdmVkU3RhdGUucGFnZVNpemUgJiZcclxuICAgICAgSlNPTi5zdHJpbmdpZnkoc3RhdGUuZmlsdGVycykgPT09IEpTT04uc3RyaW5naWZ5KHNhdmVkU3RhdGUuZmlsdGVycylcclxuICAgICk7XHJcblxyXG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xyXG4gICAgICB0aGlzLmN1cnJlbnRIaXN0b3J5SW5kZXggPSBpbmRleDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIElmIG5vdCBmb3VuZCwgYWRkIGl0IHRvIG91ciBoaXN0b3J5XHJcbiAgICAgIHRoaXMucGFnZUhpc3RvcnkucHVzaChzYXZlZFN0YXRlKTtcclxuICAgICAgdGhpcy5jdXJyZW50SGlzdG9yeUluZGV4ID0gdGhpcy5wYWdlSGlzdG9yeS5sZW5ndGggLSAxO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVXBkYXRlIGJyb3dzZXIgaGlzdG9yeSBzdGF0ZSB3aXRoIGN1cnJlbnQgcGFnZSBhbmQgcGFnZSBzaXplXHJcbiAgICovXHJcbiAgcHJpdmF0ZSB1cGRhdGVIaXN0b3J5U3RhdGUoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5lbmFibGVCcm93c2VyTmF2aWdhdGlvbikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY3VycmVudEZpbHRlcnMgPSB0aGlzLmdldEZpbHRlcnNWYWx1ZSgpO1xyXG4gICAgY29uc3QgY3VycmVudFN0YXRlID0ge1xyXG4gICAgICBwYWdlOiB0aGlzLmN1cnJlbnRQYWdlLFxyXG4gICAgICBwYWdlU2l6ZTogdGhpcy5vcHRpb25zLnBhZ2VTaXplLFxyXG4gICAgICBmaWx0ZXJzOiBjdXJyZW50RmlsdGVyc1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBPbmx5IHVwZGF0ZSBoaXN0b3J5IGlmIHdlJ3JlIG5vdCBhbHJlYWR5IG5hdmlnYXRpbmcgYmFja1xyXG4gICAgaWYgKCF0aGlzLmlzTmF2aWdhdGluZ0JhY2spIHtcclxuICAgICAgLy8gQWRkIGN1cnJlbnQgc3RhdGUgdG8gbG9jYWwgaGlzdG9yeVxyXG4gICAgICB0aGlzLnBhZ2VIaXN0b3J5LnB1c2goY3VycmVudFN0YXRlKTtcclxuICAgICAgdGhpcy5jdXJyZW50SGlzdG9yeUluZGV4ID0gdGhpcy5wYWdlSGlzdG9yeS5sZW5ndGggLSAxO1xyXG5cclxuICAgICAgLy8gTGltaXQgaGlzdG9yeSBzaXplIHRvIHByZXZlbnQgbWVtb3J5IGlzc3Vlc1xyXG4gICAgICBpZiAodGhpcy5wYWdlSGlzdG9yeS5sZW5ndGggPiA1MCkge1xyXG4gICAgICAgIHRoaXMucGFnZUhpc3Rvcnkuc2hpZnQoKTtcclxuICAgICAgICB0aGlzLmN1cnJlbnRIaXN0b3J5SW5kZXgtLTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gVXBkYXRlIGJyb3dzZXIgaGlzdG9yeSBzdGF0ZVxyXG4gICAgICBjb25zdCBoaXN0b3J5U3RhdGUgPSB7XHJcbiAgICAgICAgcGFnaW5nU3RhdGU6IGN1cnJlbnRTdGF0ZSxcclxuICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KClcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgLy8gVXNlIGhpc3RvcnkucHVzaFN0YXRlIHRvIGFkZCBhIG5ldyBoaXN0b3J5IGVudHJ5XHJcbiAgICAgICAgLy8gVGhpcyBhbGxvd3MgcHJvcGVyIGJhY2svZm9yd2FyZCBuYXZpZ2F0aW9uXHJcbiAgICAgICAgaGlzdG9yeS5wdXNoU3RhdGUoaGlzdG9yeVN0YXRlLCAnJywgdGhpcy5sb2NhdGlvbi5wYXRoKCkpO1xyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIGNvbnNvbGUud2FybignRmFpbGVkIHRvIHVwZGF0ZSBicm93c2VyIGhpc3Rvcnkgc3RhdGU6JywgZXJyb3IpO1xyXG4gICAgICAgIC8vIEZhbGxiYWNrIHRvIHJlcGxhY2VTdGF0ZSBpZiBwdXNoU3RhdGUgZmFpbHNcclxuICAgICAgICB0aGlzLmxvY2F0aW9uLnJlcGxhY2VTdGF0ZSh0aGlzLmxvY2F0aW9uLnBhdGgoKSwgJycsIEpTT04uc3RyaW5naWZ5KGhpc3RvcnlTdGF0ZSkpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5vbkNsaWNrRmlsdGVyc0NvbnRyb2xOYW1lcyAhPSBudWxsICYmIHRoaXMub3B0aW9ucy5vbkNsaWNrRmlsdGVyc0NvbnRyb2xOYW1lcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGNvbnN0IE9uQ2xpY2tGaWx0ZXJzQ29udHJvbE5hbWVzID0gdGhpcy5vcHRpb25zLm9uQ2xpY2tGaWx0ZXJzQ29udHJvbE5hbWVzO1xyXG4gICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgT25DbGlja0ZpbHRlcnNDb250cm9sTmFtZXMubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgICAgY29uc3QgT25DbGlja0ZpbHRlcnNDb250cm9sTmFtZSA9IE9uQ2xpY2tGaWx0ZXJzQ29udHJvbE5hbWVzW2luZGV4XTtcclxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChPbkNsaWNrRmlsdGVyc0NvbnRyb2xOYW1lKS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKCkgPT4ge1xyXG4gICAgICAgICAgdGhpcy5jdXJyZW50UGFnZSA9IDE7XHJcbiAgICAgICAgICB0aGlzLmlzRmlyc3RDYWxsID0gdHJ1ZTtcclxuICAgICAgICAgIHRoaXMudXBkYXRlSGlzdG9yeVN0YXRlKCk7XHJcbiAgICAgICAgICB0aGlzLmdldEl0ZW1MaXN0KHRoaXMuY3VycmVudFBhZ2UsIHRydWUpO1xyXG4gICAgICAgIH0sIGZhbHNlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5vbktleVByZXNzRmlsdGVyc0NvbnRyb2xOYW1lcyAhPSBudWxsICYmIHRoaXMub3B0aW9ucy5vbktleVByZXNzRmlsdGVyc0NvbnRyb2xOYW1lcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGNvbnN0IE9uS2V5UHJlc3NGaWx0ZXJzQ29udHJvbE5hbWVzID0gdGhpcy5vcHRpb25zLm9uS2V5UHJlc3NGaWx0ZXJzQ29udHJvbE5hbWVzO1xyXG4gICAgICAvLyBVc2UgUmVuZGVyZXIyIHRvIGxpc3RlbiB0byBkb2N1bWVudCBrZXlwcmVzcyBldmVudFxyXG4gICAgICAvLyBUaGlzIHdvcmtzIHdpdGggZWxlbWVudHMgaW4gcGFyZW50IGNvbXBvbmVudFxyXG4gICAgICBjb25zdCBrZXlwcmVzc0xpc3RlbmVyID0gdGhpcy5yZW5kZXJlci5saXN0ZW4oJ2RvY3VtZW50JywgJ2tleXByZXNzJywgKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XHJcbiAgICAgICAgaWYgKGV2ZW50LmtleSA9PT0gXCJFbnRlclwiKSB7XHJcbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgICBjb25zdCBmb3JtQ29udHJvbE5hbWUgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdpZCcpO1xyXG4gICAgICAgICAgaWYgKGZvcm1Db250cm9sTmFtZSAmJiBPbktleVByZXNzRmlsdGVyc0NvbnRyb2xOYW1lcy5pbmNsdWRlcyhmb3JtQ29udHJvbE5hbWUpKSB7XHJcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRQYWdlID0gMTtcclxuICAgICAgICAgICAgdGhpcy5pc0ZpcnN0Q2FsbCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlSGlzdG9yeVN0YXRlKCk7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0SXRlbUxpc3QodGhpcy5jdXJyZW50UGFnZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8gU3RvcmUgdGhlIHVuc3Vic2NyaWJlIGZ1bmN0aW9uXHJcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoeyB1bnN1YnNjcmliZToga2V5cHJlc3NMaXN0ZW5lciB9KTtcclxuICAgIH1cclxuICAgIC8vQWRkIGNsaWNrIGV2ZW50IG9uIFJlc2V0IEZpbHRlciBidXR0b25cclxuICAgIGlmICh0aGlzLm9wdGlvbnMucmVzZXRGaWx0ZXJCdXR0b25OYW1lICE9IG51bGwpIHtcclxuICAgICAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeU5hbWUodGhpcy5vcHRpb25zLnJlc2V0RmlsdGVyQnV0dG9uTmFtZSlbMF07XHJcbiAgICAgIGlmIChidXR0b24gIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgbGV0IGVsZW1lbnQgPSBidXR0b24gYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcclxuICAgICAgICAgIHRoaXMuY2xlYXJGaWx0ZXJzKCk7XHJcbiAgICAgICAgfSwgZmFsc2UpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLnR5cGVhaGVhZFNlYXJjaENvbnRyb2xOYW1lcyAhPSBudWxsICYmIHRoaXMub3B0aW9ucy50eXBlYWhlYWRTZWFyY2hDb250cm9sTmFtZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICBjb25zdCBUeXBlYWhlYWRTZWFyY2hDb250cm9sTmFtZXMgPSB0aGlzLm9wdGlvbnMudHlwZWFoZWFkU2VhcmNoQ29udHJvbE5hbWVzO1xyXG4gICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgVHlwZWFoZWFkU2VhcmNoQ29udHJvbE5hbWVzLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICAgIGNvbnN0IFR5cGVhaGVhZFNlYXJjaENvbnRyb2xOYW1lID0gVHlwZWFoZWFkU2VhcmNoQ29udHJvbE5hbWVzW2luZGV4XTtcclxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChUeXBlYWhlYWRTZWFyY2hDb250cm9sTmFtZSkuYWRkRXZlbnRMaXN0ZW5lcihcImtleXByZXNzXCIsIChlKSA9PiB7XHJcbiAgICAgICAgICBpZiAoZS5rZXkgPT0gXCJFbnRlclwiKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFBhZ2UgPSAxO1xyXG4gICAgICAgICAgICB0aGlzLmlzRmlyc3RDYWxsID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVIaXN0b3J5U3RhdGUoKTtcclxuICAgICAgICAgICAgdGhpcy5nZXRJdGVtTGlzdCh0aGlzLmN1cnJlbnRQYWdlLCB0cnVlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LCBmYWxzZSk7XHJcblxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gIH1cclxuXHJcbiAgb25Ecm9wRG93bkNoYW5nZShyZXN1bHQpIHtcclxuICAgIGlmIChyZXN1bHQpIHtcclxuICAgICAgdGhpcy5jdXJyZW50UGFnZSA9IDE7XHJcbiAgICAgIHRoaXMuaXNGaXJzdENhbGwgPSB0cnVlO1xyXG4gICAgICB0aGlzLnVwZGF0ZUhpc3RvcnlTdGF0ZSgpO1xyXG4gICAgICB0aGlzLmdldEl0ZW1MaXN0KHRoaXMuY3VycmVudFBhZ2UsIHRydWUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgb25DaGFuZ2VQYWdlKFBhZ2UpIHtcclxuICAgIGlmIChQYWdlID09IDApXHJcbiAgICAgIHJldHVybjtcclxuICAgIGlmIChQYWdlID4gMCkge1xyXG4gICAgICBpZiAodGhpcy5pc0ZpcnN0Q2FsbCkge1xyXG4gICAgICAgIHRoaXMuaXNGaXJzdENhbGwgPSBmYWxzZTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5jdXJyZW50UGFnZSA9IFBhZ2U7XHJcbiAgICAgIHRoaXMudXBkYXRlSGlzdG9yeVN0YXRlKCk7XHJcbiAgICAgIHRoaXMuZ2V0SXRlbUxpc3QoUGFnZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjaGFuZ2VQYWdlU2l6ZShlKSB7XHJcbiAgICB0aGlzLm9wdGlvbnMucGFnZVNpemUgPSBlLnRhcmdldC52YWx1ZTtcclxuICAgIHRoaXMuY3VycmVudFBhZ2UgPSAxO1xyXG4gICAgdGhpcy5pc0ZpcnN0Q2FsbCA9IHRydWU7XHJcbiAgICB0aGlzLnVwZGF0ZUhpc3RvcnlTdGF0ZSgpO1xyXG4gICAgdGhpcy5nZXRJdGVtTGlzdCh0aGlzLmN1cnJlbnRQYWdlLCB0cnVlKTtcclxuICB9XHJcblxyXG4gIG9uU2Nyb2xsRG93bigpIHtcclxuICAgIHRoaXMuc3VtICs9IHRoaXMub3B0aW9ucy5wYWdlU2l6ZTtcclxuICAgIHRoaXMuY3VycmVudFBhZ2UgPSAxO1xyXG4gICAgdGhpcy5pc0ZpcnN0Q2FsbCA9IHRydWU7XHJcbiAgICB0aGlzLmRpcmVjdGlvbiA9ICdkb3duJztcclxuICAgIHRoaXMuZ2V0SXRlbUxpc3QodGhpcy5jdXJyZW50UGFnZSwgdHJ1ZSk7XHJcbiAgfVxyXG5cclxuICBnZXRJdGVtTGlzdChwYWdlLCBJc0ZpbHRlclVwZGF0ZWQgPSBmYWxzZSkge1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5zdGFydFBhZ2luZ0NhbGxiYWNrKVxyXG4gICAgICB0aGlzLm9wdGlvbnMuc3RhcnRQYWdpbmdDYWxsYmFjay5jYWxsKG51bGwpO1xyXG5cclxuICAgIGxldCBmaWx0ZXJzID0ge307XHJcbiAgICBmaWx0ZXJzID0gdGhpcy5nZXRGaWx0ZXJzVmFsdWUoKTtcclxuXHJcbiAgICAvLyBTa2lwIGZpbHRlciBjaGFuZ2UgZGV0ZWN0aW9uIGlmIHdlJ3JlIHJlc3RvcmluZyBmaWx0ZXJzIGZyb20gYnJvd3NlciBoaXN0b3J5XHJcbiAgICBpZiAoIXRoaXMuaXNSZXN0b3JpbmdGaWx0ZXJzICYmICFJc0ZpbHRlclVwZGF0ZWQgJiYgT2JqZWN0LmtleXModGhpcy5wcmV2aW91c0ZpbHRlcnMpLmxlbmd0aCAhPSAwICYmIEpTT04uc3RyaW5naWZ5KHRoaXMucHJldmlvdXNGaWx0ZXJzKSAhPSBKU09OLnN0cmluZ2lmeShmaWx0ZXJzKSkge1xyXG4gICAgICAvL1JlaW5pdGlhbGl6ZSBpZiBmaWx0ZXJzIGNoYW5nZWRcclxuICAgICAgcGFnZSA9IDE7XHJcbiAgICAgIElzRmlsdGVyVXBkYXRlZCA9IHRydWU7XHJcbiAgICB9XHJcbiAgICB0aGlzLnByZXZpb3VzRmlsdGVycyA9IGZpbHRlcnM7XHJcbiAgICBsZXQgcGFnaW5nRFRPID0gbmV3IFBhZ2luZ0RUTygpO1xyXG4gICAgbGV0IHNpemUgPSBOdW1iZXIucGFyc2VJbnQodGhpcy5vcHRpb25zLnBhZ2VTaXplLnRvU3RyaW5nKCkpO1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pc0xvYWRNb3JlQ29udHJvbClcclxuICAgICAgcGFnaW5nRFRPLlBhZ2VDb3VudCA9IHRoaXMuc3VtO1xyXG4gICAgZWxzZVxyXG4gICAgICBwYWdpbmdEVE8uUGFnZUNvdW50ID0gc2l6ZTtcclxuXHJcbiAgICBwYWdpbmdEVE8uQ3VycmVudFBhZ2VOdW1iZXIgPSBwYWdlO1xyXG4gICAgcGFnaW5nRFRPLlRvdGFsQ291bnQgPSB0aGlzLnRvdGFsUm93O1xyXG4gICAgcGFnaW5nRFRPLklzRmlsdGVyVXBkYXRlZCA9IElzRmlsdGVyVXBkYXRlZDtcclxuXHJcbiAgICAvL1NldCBGaWx0ZXJzIG9iamVjdCB0aGF0IHNlbnQgdG8gYWN0aW9uIFVSTFxyXG4gICAgbGV0IGZpbHRlcnNEVE86IFBhZ2luZ1BheWxvYWQgPSB7XHJcbiAgICAgIFBhZ2luZ0RUTzogcGFnaW5nRFRPLFxyXG4gICAgICBGaWx0ZXJzOiBmaWx0ZXJzXHJcbiAgICB9O1xyXG5cclxuICAgIGxldCByZXF1ZXN0T3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9uc01vZGVsKCk7XHJcbiAgICByZXF1ZXN0T3B0aW9ucy5kaXNhYmxlQmxvY2tVSSA9IHRoaXMub3B0aW9ucy5kaXNhYmxlQmxvY2tVSTtcclxuICAgIHRoaXMucmVxdWVzdEhhbmRsZXJTZXJ2aWNlLnBvc3QodGhpcy5vcHRpb25zLmFjdGlvblBvc3RVUkwsIHRoaXMub3B0aW9ucy5maWx0ZXJzICYmIHRoaXMub3B0aW9ucy5maWx0ZXJzLmxlbmd0aCA+IDAgPyBmaWx0ZXJzRFRPIDogcGFnaW5nRFRPLCBudWxsLCBudWxsLCByZXF1ZXN0T3B0aW9ucylcclxuICAgICAgLnN1YnNjcmliZSgocmVzcG9uc2VEYXRhOiBhbnkpID0+IHtcclxuICAgICAgICB0aGlzLm9wdGlvbnMudG90YWxDb3VudCA9IHJlc3BvbnNlRGF0YS50b3RhbENvdW50O1xyXG4gICAgICAgIHRoaXMucmVzdWx0ID0gcmVzcG9uc2VEYXRhLml0ZW1zOyAvL3RoaXMuY2FzdEl0ZW1zKHJlc3BvbnNlRGF0YS5pdGVtcyk7XHJcbiAgICAgICAgbGV0IGNhc3RlZFJlc3VsdCA9IHBsYWluVG9DbGFzcyh0aGlzLm9wdGlvbnMuVHlwZU9mUmVzcG9uc2UsIHRoaXMucmVzdWx0LCB7IGV4Y2x1ZGVFeHRyYW5lb3VzVmFsdWVzOiB0cnVlIH0pO1xyXG4gICAgICAgIHRoaXMuSXRlbXMuZW1pdChjYXN0ZWRSZXN1bHQpO1xyXG4gICAgICAgIHRoaXMudG90YWxSb3cgPSByZXNwb25zZURhdGEudG90YWxDb3VudDtcclxuXHJcbiAgICAgICAgaWYgKElzRmlsdGVyVXBkYXRlZCkge1xyXG4gICAgICAgICAgdGhpcy5pdGVtcyA9IFtdO1xyXG4gICAgICAgICAgdGhpcy5QYWdlcyA9IE1hdGguY2VpbCgodGhpcy50b3RhbFJvdyAvIHRoaXMub3B0aW9ucy5wYWdlU2l6ZSkpO1xyXG4gICAgICAgICAgdGhpcy5pdGVtcyA9IEFycmF5KHRoaXMudG90YWxSb3cpO1xyXG5cclxuICAgICAgICAgIHRoaXMuc2V0VGV4dCh0aGlzLlBhZ2VzLCB0aGlzLnRvdGFsUm93KTtcclxuXHJcbiAgICAgICAgfVxyXG4gICAgICB9LCAoZXJyb3I6IEh0dHBFcnJvclJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgaWYgKGVycm9yLnN0YXR1cyA9PSA0MDEpXHJcbiAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbXCIvQWRtaW4vYWNjb3VudC9sb2dpblwiXSk7XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcmVpbml0aWFsaXplUGFnaW5nID0gKCkgPT4ge1xyXG4gICAgdGhpcy5pc0ZpcnN0Q2FsbCA9IHRydWU7XHJcbiAgICB0aGlzLmN1cnJlbnRQYWdlID0gMTtcclxuICAgIHRoaXMuY2xlYXJIaXN0b3J5U3RhdGUoKTtcclxuICAgIHRoaXMuZ2V0SXRlbUxpc3QoMSwgdHJ1ZSk7XHJcbiAgfTtcclxuXHJcbiAgdXBkYXRlUGFnaW5nID0gKCkgPT4ge1xyXG4gICAgLy90aGlzLklzRmlyc3RDYWxsPXRydWU7XHJcbiAgICB0aGlzLmdldEl0ZW1MaXN0KHRoaXMuY3VycmVudFBhZ2UpO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIEZvcmNlIHVwZGF0ZSB0aGUgY3VycmVudCBwYWdlICh1c2VmdWwgZm9yIGV4dGVybmFsIGNvbXBvbmVudHMpXHJcbiAgICovXHJcbiAgc2V0Q3VycmVudFBhZ2UocGFnZTogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBpZiAocGFnZSA+IDAgJiYgcGFnZSAhPT0gdGhpcy5jdXJyZW50UGFnZSkge1xyXG4gICAgICB0aGlzLmN1cnJlbnRQYWdlID0gcGFnZTtcclxuICAgICAgdGhpcy51cGRhdGVIaXN0b3J5U3RhdGUoKTtcclxuICAgICAgdGhpcy5nZXRJdGVtTGlzdChwYWdlKTtcclxuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBjdXJyZW50IHBhZ2UgbnVtYmVyXHJcbiAgICovXHJcbiAgZ2V0Q3VycmVudFBhZ2UoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLmN1cnJlbnRQYWdlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVzdG9yZSBmaWx0ZXIgdmFsdWVzIHRvIGZvcm0gY29udHJvbHNcclxuICAgKi9cclxuICBwcml2YXRlIHJlc3RvcmVGaWx0ZXJWYWx1ZXMoc2F2ZWRGaWx0ZXJzOiBhbnkpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5vcHRpb25zLmZpbHRlcnMgfHwgIXRoaXMuZ3JvdXApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuaXNSZXN0b3JpbmdGaWx0ZXJzID0gdHJ1ZTtcclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5vcHRpb25zLmZpbHRlcnMubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgICAgY29uc3QgZmlsdGVyID0gdGhpcy5vcHRpb25zLmZpbHRlcnNbaW5kZXhdO1xyXG5cclxuICAgICAgICBpZiAoZmlsdGVyLmZvcm1Db250cm9sTmFtZSAmJiBmaWx0ZXIuZm9ybUNvbnRyb2xOYW1lICE9PSBcIlwiKSB7XHJcbiAgICAgICAgICBjb25zdCBmb3JtQ29udHJvbE5hbWUgPSBmaWx0ZXIuZm9ybUNvbnRyb2xOYW1lO1xyXG4gICAgICAgICAgY29uc3QgYWN0aW9uUGFyYW1ldGVyTmFtZSA9IGZpbHRlci5hY3Rpb25QYXJhbWV0ZXJOYW1lO1xyXG5cclxuICAgICAgICAgIC8vIENoZWNrIGlmIHdlIGhhdmUgYSBzYXZlZCB2YWx1ZSBmb3IgdGhpcyBmaWx0ZXJcclxuICAgICAgICAgIGlmIChzYXZlZEZpbHRlcnMuaGFzT3duUHJvcGVydHkoYWN0aW9uUGFyYW1ldGVyTmFtZSkpIHtcclxuICAgICAgICAgICAgY29uc3Qgc2F2ZWRWYWx1ZSA9IHNhdmVkRmlsdGVyc1thY3Rpb25QYXJhbWV0ZXJOYW1lXTtcclxuXHJcbiAgICAgICAgICAgIC8vIE9ubHkgcmVzdG9yZSBpZiB0aGUgdmFsdWUgaXMgbm90IG51bGwvdW5kZWZpbmVkL2VtcHR5XHJcbiAgICAgICAgICAgIGlmIChzYXZlZFZhbHVlICE9PSBudWxsICYmIHNhdmVkVmFsdWUgIT09IHVuZGVmaW5lZCAmJiBzYXZlZFZhbHVlICE9PSBcIlwiKSB7XHJcbiAgICAgICAgICAgICAgLy8gU2V0IHRoZSB2YWx1ZSB0byB0aGUgZm9ybSBjb250cm9sXHJcbiAgICAgICAgICAgICAgdGhpcy5ncm91cC5jb250cm9sc1tmb3JtQ29udHJvbE5hbWVdLnNldFZhbHVlKHNhdmVkVmFsdWUpO1xyXG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBSZXN0b3JlZCBmaWx0ZXIgJHtmb3JtQ29udHJvbE5hbWV9IHdpdGggdmFsdWU6YCwgc2F2ZWRWYWx1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKGZpbHRlci5qUXVlcnlTZWxlY3Rvcikge1xyXG4gICAgICAgICAgLy8gSGFuZGxlIGpRdWVyeSBzZWxlY3RvciBiYXNlZCBmaWx0ZXJzXHJcbiAgICAgICAgICBjb25zdCBhY3Rpb25QYXJhbWV0ZXJOYW1lID0gZmlsdGVyLmFjdGlvblBhcmFtZXRlck5hbWU7XHJcblxyXG4gICAgICAgICAgaWYgKHNhdmVkRmlsdGVycy5oYXNPd25Qcm9wZXJ0eShhY3Rpb25QYXJhbWV0ZXJOYW1lKSkge1xyXG4gICAgICAgICAgICBjb25zdCBzYXZlZFZhbHVlID0gc2F2ZWRGaWx0ZXJzW2FjdGlvblBhcmFtZXRlck5hbWVdO1xyXG5cclxuICAgICAgICAgICAgaWYgKHNhdmVkVmFsdWUgIT09IG51bGwgJiYgc2F2ZWRWYWx1ZSAhPT0gdW5kZWZpbmVkICYmIHNhdmVkVmFsdWUgIT09IFwiXCIpIHtcclxuICAgICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihmaWx0ZXIualF1ZXJ5U2VsZWN0b3IpIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgaWYgKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQudmFsdWUgPSBzYXZlZFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFJlc3RvcmVkIGpRdWVyeSBmaWx0ZXIgJHtmaWx0ZXIualF1ZXJ5U2VsZWN0b3J9IHdpdGggdmFsdWU6YCwgc2F2ZWRWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byByZXN0b3JlIGZpbHRlciB2YWx1ZXM6JywgZXJyb3IpO1xyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgLy8gUmVzZXQgdGhlIGZsYWcgYWZ0ZXIgYSBzaG9ydCBkZWxheSB0byBhbGxvdyBmb3JtIGNvbnRyb2xzIHRvIHVwZGF0ZVxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICB0aGlzLmlzUmVzdG9yaW5nRmlsdGVycyA9IGZhbHNlO1xyXG4gICAgICB9LCAxMDApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY2FzdEl0ZW1zKG9iamVjdEFycjogYW55W10pOiBUW10ge1xyXG4gICAgbGV0IG9yaWdpbmFsQXJyYXk6IFRbXSA9IFtdO1xyXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IG9iamVjdEFyci5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgY29uc3QgZWxlbWVudCA9IG9iamVjdEFycltpbmRleF07XHJcbiAgICAgIGxldCBrZXksIGtleXMgPSBPYmplY3Qua2V5cyhlbGVtZW50KTtcclxuICAgICAgbGV0IG4gPSBrZXlzLmxlbmd0aDtcclxuICAgICAgbGV0IG5ld09iamVjdCA9IHt9O1xyXG4gICAgICB3aGlsZSAobi0tKSB7XHJcbiAgICAgICAga2V5ID0ga2V5c1tuXTtcclxuICAgICAgICBsZXQgT2tleSA9IGtleTtcclxuICAgICAgICBuZXdPYmplY3Rba2V5LmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgT2tleS5zbGljZSgxKV0gPSBlbGVtZW50W2tleV07XHJcbiAgICAgIH1cclxuICAgICAgbGV0IGZpbmFsT2JqZWN0ID0gbmV3T2JqZWN0IGFzIFQ7XHJcbiAgICAgIG9yaWdpbmFsQXJyYXkucHVzaChmaW5hbE9iamVjdCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG9yaWdpbmFsQXJyYXk7XHJcbiAgfVxyXG5cclxuICBzZXRUZXh0KHBhZ2VzTnVtYmVyOiBudW1iZXIsIGl0ZW1zTnVtYmVyOiBudW1iZXIpIHtcclxuICAgIGlmICh0aGlzLnV0aWxpdHlTZXJ2aWNlLmlzQ3VycmVudExhbmd1YWdlQXJhYmljKCkpIHtcclxuICAgICAgLy9TZXQgcGFnZXMgdGV4dFxyXG4gICAgICBpZiAocGFnZXNOdW1iZXIgPCAzIHx8IHBhZ2VzTnVtYmVyID4gMTApXHJcbiAgICAgICAgdGhpcy5wYWdlc1RleHQgPSB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoXCJQYWdlXCIpO1xyXG4gICAgICBlbHNlXHJcbiAgICAgICAgdGhpcy5wYWdlc1RleHQgPSB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoXCJQYWdlc1wiKTtcclxuICAgICAgLy9TZXQgaXRlbXMgdGV4dFxyXG4gICAgICBpZiAoaXRlbXNOdW1iZXIgPCAzIHx8IGl0ZW1zTnVtYmVyID4gMTApXHJcbiAgICAgICAgdGhpcy5pdGVtc1RleHQgPSB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoXCJJdGVtXCIpO1xyXG4gICAgICBlbHNlXHJcbiAgICAgICAgdGhpcy5pdGVtc1RleHQgPSB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoXCJJdGVtc1wiKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAvL1NldCBwYWdlcyB0ZXh0XHJcbiAgICAgIGlmIChwYWdlc051bWJlciA+IDEpXHJcbiAgICAgICAgdGhpcy5wYWdlc1RleHQgPSB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoXCJQYWdlc1wiKTtcclxuICAgICAgZWxzZVxyXG4gICAgICAgIHRoaXMucGFnZXNUZXh0ID0gdGhpcy51dGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKFwiUGFnZVwiKTtcclxuICAgICAgLy9TZXQgaXRlbXMgdGV4dFxyXG4gICAgICBpZiAoaXRlbXNOdW1iZXIgPiAxKVxyXG4gICAgICAgIHRoaXMuaXRlbXNUZXh0ID0gdGhpcy51dGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKFwiSXRlbXNcIik7XHJcbiAgICAgIGVsc2VcclxuICAgICAgICB0aGlzLml0ZW1zVGV4dCA9IHRoaXMudXRpbGl0eVNlcnZpY2UuZ2V0UmVzb3VyY2VWYWx1ZShcIkl0ZW1cIik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjbGVhckZpbHRlcnMoKSB7XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmZpbHRlcnMgIT0gbnVsbCkge1xyXG4gICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5vcHRpb25zLmZpbHRlcnMubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5maWx0ZXJzW2luZGV4XS5mb3JtQ29udHJvbE5hbWUgIT0gbnVsbCAmJiB0aGlzLm9wdGlvbnMuZmlsdGVyc1tpbmRleF0uZm9ybUNvbnRyb2xOYW1lICE9IFwiXCIpIHtcclxuICAgICAgICAgIGNvbnN0IEZvcm1Db250cm9sTmFtZSA9IHRoaXMub3B0aW9ucy5maWx0ZXJzW2luZGV4XS5mb3JtQ29udHJvbE5hbWU7XHJcbiAgICAgICAgICB0aGlzLmdyb3VwLmNvbnRyb2xzW0Zvcm1Db250cm9sTmFtZV0uc2V0VmFsdWUobnVsbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIC8vIENsZWFyIGhpc3Rvcnkgc3RhdGUgd2hlbiBmaWx0ZXJzIGFyZSByZXNldFxyXG4gICAgICB0aGlzLmNsZWFySGlzdG9yeVN0YXRlKCk7XHJcbiAgICAgIHRoaXMucmVpbml0aWFsaXplUGFnaW5nKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDbGVhciBwYWdlIGhpc3Rvcnkgc3RhdGVcclxuICAgKi9cclxuICBwcml2YXRlIGNsZWFySGlzdG9yeVN0YXRlKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLm9wdGlvbnMuZW5hYmxlQnJvd3Nlck5hdmlnYXRpb24pIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENsZWFyIHRoZSBwYWdlIGhpc3RvcnlcclxuICAgIHRoaXMucGFnZUhpc3RvcnkgPSBbXTtcclxuICAgIHRoaXMuY3VycmVudEhpc3RvcnlJbmRleCA9IC0xO1xyXG4gIH1cclxuXHJcbiAgZ2V0RmlsdGVyc1ZhbHVlKCkge1xyXG4gICAgbGV0IGZpbHRlcnMgPSB7fTtcclxuICAgIGlmICh0aGlzLm9wdGlvbnMuZmlsdGVycyAhPSBudWxsKSB7XHJcbiAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLm9wdGlvbnMuZmlsdGVycy5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmZpbHRlcnNbaW5kZXhdLmZvcm1Db250cm9sTmFtZSAhPSBudWxsICYmIHRoaXMub3B0aW9ucy5maWx0ZXJzW2luZGV4XS5mb3JtQ29udHJvbE5hbWUgIT0gXCJcIikge1xyXG4gICAgICAgICAgY29uc3QgRm9ybUNvbnRyb2xOYW1lID0gdGhpcy5vcHRpb25zLmZpbHRlcnNbaW5kZXhdLmZvcm1Db250cm9sTmFtZTtcclxuICAgICAgICAgIGxldCBDb250cm9sVmFsdWUgPSB0aGlzLmdyb3VwLmNvbnRyb2xzW0Zvcm1Db250cm9sTmFtZV0udmFsdWU7XHJcbiAgICAgICAgICBpZiAoQ29udHJvbFZhbHVlICE9IHVuZGVmaW5lZCAmJiBDb250cm9sVmFsdWUgIT0gbnVsbCAmJiBDb250cm9sVmFsdWUgIT0gXCJcIikge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmZpbHRlcnNbaW5kZXhdLmZpbHRlclR5cGUgPT0gRmlsdGVyVHlwZS5EYXRlUGlja2VyKSB7XHJcbiAgICAgICAgICAgICAgLy9pZiAoQXJyYXkuaXNBcnJheShDb250cm9sVmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgLy8gIGZvciAobGV0IGVsZW1lbnQgPSAwOyBlbGVtZW50IDwgQ29udHJvbFZhbHVlLmxlbmd0aDsgZWxlbWVudCsrKSB7XHJcbiAgICAgICAgICAgICAgLy8gICAgY29uc3QgdmFsdWUgPSBDb250cm9sVmFsdWVbZWxlbWVudF07XHJcbiAgICAgICAgICAgICAgLy8gICAgZmlsdGVyc1t0aGlzLm9wdGlvbnMuRmlsdGVyc1tpbmRleF0uQWN0aW9uUGFyYW1ldGVyTmFtZV0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAvLyAgfVxyXG4gICAgICAgICAgICAgIC8vfVxyXG4gICAgICAgICAgICAgIC8vZWxzZSB7XHJcbiAgICAgICAgICAgICAgZmlsdGVyc1t0aGlzLm9wdGlvbnMuZmlsdGVyc1tpbmRleF0uYWN0aW9uUGFyYW1ldGVyTmFtZV0gPSBDb250cm9sVmFsdWU7XHJcbiAgICAgICAgICAgICAgLy99XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5maWx0ZXJzW2luZGV4XS5maWx0ZXJUeXBlID09IEZpbHRlclR5cGUuQXV0b2NvbXBsZXRlVGV4dEJveClcclxuICAgICAgICAgICAgICAgIENvbnRyb2xWYWx1ZSA9IENvbnRyb2xWYWx1ZTtcclxuICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmZpbHRlcnNbaW5kZXhdLmZpbHRlclR5cGUgPT0gRmlsdGVyVHlwZS5UYWdJbnB1dClcclxuICAgICAgICAgICAgICAgIENvbnRyb2xWYWx1ZSA9IENvbnRyb2xWYWx1ZTtcclxuXHJcbiAgICAgICAgICAgICAgZmlsdGVyc1t0aGlzLm9wdGlvbnMuZmlsdGVyc1tpbmRleF0uYWN0aW9uUGFyYW1ldGVyTmFtZV0gPSBDb250cm9sVmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBmaWx0ZXJzW3RoaXMub3B0aW9ucy5maWx0ZXJzW2luZGV4XS5hY3Rpb25QYXJhbWV0ZXJOYW1lXSA9IG51bGw7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgY29uc3QgRWxlbWVudGpRdWVyeVNlbGVjdG9yID0gdGhpcy5vcHRpb25zLmZpbHRlcnNbaW5kZXhdLmpRdWVyeVNlbGVjdG9yO1xyXG4gICAgICAgICAgbGV0IEVsZW1lbnRWYWx1ZSA9IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKEVsZW1lbnRqUXVlcnlTZWxlY3RvcikgYXMgSFRNTElucHV0RWxlbWVudCkudmFsdWU7XHJcbiAgICAgICAgICBpZiAoRWxlbWVudFZhbHVlICE9IHVuZGVmaW5lZCAmJiBFbGVtZW50VmFsdWUgIT0gbnVsbClcclxuICAgICAgICAgICAgZmlsdGVyc1t0aGlzLm9wdGlvbnMuZmlsdGVyc1tpbmRleF0uYWN0aW9uUGFyYW1ldGVyTmFtZV0gPSBFbGVtZW50VmFsdWU7XHJcbiAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIGZpbHRlcnNbdGhpcy5vcHRpb25zLmZpbHRlcnNbaW5kZXhdLmFjdGlvblBhcmFtZXRlck5hbWVdID0gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBmaWx0ZXJzO1xyXG4gIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBiYnNmLWNvbnRyb2wgYmJzZi1wYWdpbmdcIiAqbmdJZj1cIihyZXN1bHQubGVuZ3RoID4gMClcIiByb2xlPVwibmF2aWdhdGlvblwiIFthdHRyLmFyaWEtbGFiZWxdPVwidXRpbGl0eVNlcnZpY2UuZ2V0UmVzb3VyY2VWYWx1ZSgnUGFnaW5hdGlvbicpXCI+XHJcbiAgPCEtLXBhZ2luZyBjb250YWluZXItLT5cclxuICA8ZGl2IGNsYXNzPVwiYmJzZi1wYWdpbmctY29udGFpbmVyXCIgKm5nSWY9XCIhb3B0aW9ucy5pc0xvYWRNb3JlQ29udHJvbFwiPlxyXG4gICAgPCEtLWl0ZW1zLS0+XHJcbiAgICA8ZGl2IGNsYXNzPVwiYmJzZi1wYWdpbmF0aW9uXCI+XHJcbiAgICAgIDxqdy1wYWdpbmF0aW9uIFtpdGVtc109XCJpdGVtc1wiICpuZ0lmPVwiISgoUGFnZXM9PTEpJiZvcHRpb25zLmhpZGVQYWdpbmF0aW9uV2hlblBhZ2VTaXplRXF1YWxPbmUpXCJcclxuICAgICAgICAoY2hhbmdlUGFnZSk9XCJvbkNoYW5nZVBhZ2UoJGV2ZW50KVwiIFtwYWdlU2l6ZV09XCJvcHRpb25zLnBhZ2VTaXplXCIgW1Nob3dGaXJzdEFuZExhc3RdPVwib3B0aW9ucy5zaG93Rmlyc3RBbmRMYXN0XCJcclxuICAgICAgICBbaW5pdGlhbFBhZ2VdPVwiY3VycmVudFBhZ2VcIiBbbWF4UGFnZXNdPVwiMTBcIj48L2p3LXBhZ2luYXRpb24+XHJcbiAgICA8L2Rpdj5cclxuICAgIDwhLS1wYWdlIGNvdW50LS0+XHJcbiAgICA8ZGl2IGNsYXNzPVwiYmJzZi1wYWdlc1wiICpuZ0lmPVwiISgoUGFnZXM9PTEpJiZvcHRpb25zLmhpZGVQYWdpbmF0aW9uV2hlblBhZ2VTaXplRXF1YWxPbmUpXCI+XHJcbiAgICAgIDxzZWxlY3QgKGNoYW5nZSk9XCJjaGFuZ2VQYWdlU2l6ZSgkZXZlbnQpXCIgKm5nSWY9XCJvcHRpb25zLnNob3dQYWdlU2l6ZU9wdGlvblwiIFxyXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwidXRpbGl0eVNlcnZpY2UuZ2V0UmVzb3VyY2VWYWx1ZSgnU2VsZWN0UGFnZVNpemUnKVwiIFxyXG4gICAgICAgIFtuZ2JUb29sdGlwXT1cInV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ1NlbGVjdFBhZ2VTaXplJylcIj5cclxuICAgICAgICA8b3B0aW9uPjEwPC9vcHRpb24+XHJcbiAgICAgICAgPG9wdGlvbj4yMDwvb3B0aW9uPlxyXG4gICAgICAgIDxvcHRpb24+NTA8L29wdGlvbj5cclxuICAgICAgICA8b3B0aW9uPjEwMDwvb3B0aW9uPlxyXG4gICAgICAgIDxvcHRpb24+MjAwPC9vcHRpb24+XHJcbiAgICAgIDwvc2VsZWN0PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiYnNzZi1pdGVtc1wiIFthdHRyLmFyaWEtbGFiZWxdPVwidXRpbGl0eVNlcnZpY2UuZ2V0UmVzb3VyY2VWYWx1ZSgnUGFnZUluZm8nKVwiPlxyXG4gICAgICAgIDxzdHJvbmc+e3t0b3RhbFJvd319PC9zdHJvbmc+IHt7aXRlbXNUZXh0fX0ge3t1dGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKFwiSW5cIil9fSA8c3Ryb25nPlxyXG4gICAgICAgICAge3tQYWdlc319PC9zdHJvbmc+IHt7cGFnZXNUZXh0fX1cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuICA8IS0tbG9hZCBtb3JlLS0+XHJcbiAgPGRpdiBjbGFzcz1cImJic2YtbG9hZG1vcmVcIiAqbmdJZj1cIm9wdGlvbnMuaXNMb2FkTW9yZUNvbnRyb2xcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJzZWFyY2gtcmVzdWx0c1wiIGluZmluaXRlLXNjcm9sbCBbaW5maW5pdGVTY3JvbGxEaXN0YW5jZV09XCJzY3JvbGxEaXN0YW5jZVwiXHJcbiAgICAgIFtpbmZpbml0ZVNjcm9sbFVwRGlzdGFuY2VdPVwic2Nyb2xsVXBEaXN0YW5jZVwiIFtpbmZpbml0ZVNjcm9sbFRocm90dGxlXT1cInRocm90dGxlXCJcclxuICAgICAgKHNjcm9sbGVkKT1cIm9wdGlvbnMuaXNJbmZpbml0ZVNjcm9sbD09dHJ1ZT9vblNjcm9sbERvd24oKTpudWxsXCIgW3Njcm9sbFdpbmRvd109XCJvcHRpb25zLnNjcm9sbFdpbmRvd1wiXHJcbiAgICAgIFtpbmZpbml0ZVNjcm9sbENvbnRhaW5lcl09XCJvcHRpb25zLmluZmluaXRlU2Nyb2xsQ29udGFpbmVyXCI+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1wcmltYXJ5XCIgKGNsaWNrKT1cIm9uU2Nyb2xsRG93bigpXCJcclxuICAgICAgKm5nSWY9XCIhKHJlc3VsdC5sZW5ndGg9PXRvdGFsUm93KVwiXHJcbiAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwidXRpbGl0eVNlcnZpY2UuZ2V0UmVzb3VyY2VWYWx1ZSgnTG9hZE1vcmUnKVwiXHJcbiAgICAgIFtuZ2JUb29sdGlwXT1cInV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ0xvYWRNb3JlJylcIj57e3V0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoXCJMb2FkTW9yZVwiKX19PC9idXR0b24+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PiJdfQ==