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

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 +7 -0
  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 +33 -36
  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,741 +0,0 @@
1
- import { Component, Input, Optional, ViewChild, Output, EventEmitter, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { HttpEventType } from '@angular/common/http';
4
- import { FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
5
- import { FileUploader, FileUploadModule } from 'ng2-file-upload';
6
- import { NgxDropzoneModule } from 'ngx-dropzone';
7
- import { Subject } from 'rxjs';
8
- import { takeUntil } from 'rxjs/operators';
9
- import { FileUploadModel, MultipleFileUploadModel } from '../../Shared/Models';
10
- import * as i0 from "@angular/core";
11
- import * as i1 from "@angular/forms";
12
- import * as i2 from "../../Shared/services";
13
- import * as i3 from "@bnsights/bbsf-utilities/ui";
14
- import * as i4 from "@angular/common";
15
- import * as i5 from "ng2-file-upload";
16
- export class FileUploadComponent {
17
- static { this.controlContainerStatic = null; }
18
- constructor(controlContainer, MultipleFileUploadControlHost, controlUtility, UtilityService, controlValidationService, globalSettings, fileUploadService) {
19
- this.controlContainer = controlContainer;
20
- this.MultipleFileUploadControlHost = MultipleFileUploadControlHost;
21
- this.controlUtility = controlUtility;
22
- this.UtilityService = UtilityService;
23
- this.controlValidationService = controlValidationService;
24
- this.globalSettings = globalSettings;
25
- this.fileUploadService = fileUploadService;
26
- this.OnChange = new EventEmitter();
27
- this.isUploadComplete = new EventEmitter();
28
- this.validationMessage = '';
29
- this.validationCountMessage = '';
30
- this.acceptedType = '';
31
- this.acceptedTypeArray = [];
32
- this.toolTipTypeArray = [];
33
- this.markAllAsTouched = false;
34
- this.validationRules = [];
35
- this.validationRulesAsync = [];
36
- this.deletedFiles = [];
37
- this.destroy$ = new Subject();
38
- this.pendingValidationErrors = null;
39
- this.resetError = () => {
40
- this.controlValidationService.removeGlobalError();
41
- };
42
- //External Method
43
- this.removeRequiredValidation = () => {
44
- this.controlUtility.removeRequiredValidation(this.fileUploadFormControl, this.validationRules, this.options);
45
- };
46
- //External Method
47
- this.addRequiredValidation = () => {
48
- this.controlUtility.addRequiredValidation(this.fileUploadFormControl, this.validationRules, this.options);
49
- };
50
- //External Method
51
- this.removeCustomValidation = (customValidation) => {
52
- this.controlUtility.removeCustomValidation(this.fileUploadFormControl, this.validationRules, customValidation);
53
- };
54
- //External Method
55
- this.addCustomValidation = (customValidation) => {
56
- this.controlUtility.addCustomValidation(this.fileUploadFormControl, this.validationRules, customValidation);
57
- };
58
- //External Method
59
- this.isValid = () => {
60
- this.controlUtility.isValid(this.fileUploadFormControl);
61
- };
62
- FileUploadComponent.controlContainerStatic = this.controlContainer;
63
- // Initialize uploader with minimal options, URL will be set in ngOnInit only if needed
64
- this.uploader = new FileUploader({
65
- url: '',
66
- disableMultipart: false // 'DisableMultipart' must be 'true' for formatDataFunction to be called.
67
- });
68
- this.hasAnotherDropZoneOver = false;
69
- }
70
- ngOnInit() {
71
- this.fileUploadModel = new FileUploadModel();
72
- this.multipleFileUploadModel = new MultipleFileUploadModel();
73
- if (!this.options.viewType)
74
- this.options.viewType = this.globalSettings.viewType;
75
- // Configure uploader options - no URL needed since we handle uploads via FileUploadService
76
- // Note: allowedMimeType in ng2-file-upload doesn't work well with comma-separated enum values
77
- // We handle MIME type validation manually in onFileChange
78
- this.uploader.setOptions({
79
- url: '',
80
- disableMultipart: false,
81
- autoUpload: false // We manually control uploads
82
- // allowedMimeType removed - we handle validation manually for better control
83
- });
84
- if (this.options.value == null) {
85
- if (this.options.isMultipleFile == true) {
86
- //this.options.Value=this.multipleFileUploadModel
87
- }
88
- else {
89
- // this.options.Value=this.fileUploadModel
90
- }
91
- }
92
- else {
93
- if (this.options.isMultipleFile == true) {
94
- let files = [];
95
- this.multipleFileUploadModel.existingFiles = this.options.value.existingFiles;
96
- this.multipleFileUploadModel.uploadedFiles = [];
97
- for (let index = 0; index < this.options.value.existingFiles.length; index++) {
98
- const element = this.options.value.existingFiles[index];
99
- var bytes = new Uint8Array(element.bytes);
100
- var base64 = btoa(String.fromCharCode(...Array.from(bytes)));
101
- this.fileLikeObject = {
102
- name: element.nameWithExtension,
103
- type: element.mimeType,
104
- rawFile: base64
105
- };
106
- // let blob: any;
107
- // blob = new Blob(['']) as any;
108
- // blob.name = element.FileName;
109
- // blob.lastModifiedDate = null;
110
- // blob.webkitRelativePath = '';
111
- let file = this.fileLikeObject;
112
- file.url = element.fullFileURL;
113
- files.push(file);
114
- }
115
- this.uploader.addToQueue(files);
116
- console.log(this.uploader.queue);
117
- }
118
- else {
119
- const element = this.options.value.file ?? this.options.value;
120
- var bytes = new Uint8Array(element.bytes);
121
- var base64 = btoa(String.fromCharCode(...Array.from(bytes)));
122
- this.fileLikeObject = {
123
- name: element.nameWithExtension,
124
- type: element.mimeType,
125
- rawFile: base64
126
- };
127
- this.file = element;
128
- let file = this.fileLikeObject;
129
- file.url = element.fullFileURL;
130
- this.uploader.addToQueue([file]);
131
- if (!this.options.value.file) {
132
- this.fileUploadModel = new FileUploadModel();
133
- this.fileUploadModel.file = this.options.value;
134
- }
135
- else
136
- this.fileUploadModel = this.options.value;
137
- this.options.value = this.fileUploadModel;
138
- }
139
- this.uploader.queue.forEach((element) => {
140
- element.progress = 100;
141
- });
142
- }
143
- if (this.options.labelKey != null && this.options.labelKey != '')
144
- this.options.labelValue = this.UtilityService.getResourceValue(this.options.labelKey);
145
- if (this.options.fileUploadAcceptsTypes != null &&
146
- this.options.fileUploadAcceptsTypes.length > 0) {
147
- // Process FileType enum values which may contain comma-separated MIME types
148
- for (let index = 0; index < this.options.fileUploadAcceptsTypes.length; index++) {
149
- const Type = this.options.fileUploadAcceptsTypes[index];
150
- this.acceptedType = this.acceptedType + Type + ',';
151
- }
152
- this.acceptedTypeArray = this.acceptedType.split(',');
153
- this.acceptedTypeArray = this.acceptedTypeArray.filter((value) => value.trim() != '');
154
- // Rebuild acceptedType string for HTML accept attribute (properly formatted)
155
- this.acceptedType = this.acceptedTypeArray.join(',');
156
- // Process each accepted MIME type to build tooltip display names
157
- for (let index = 0; index < this.acceptedTypeArray.length; index++) {
158
- const element = this.acceptedTypeArray[index].trim();
159
- switch (element) {
160
- case 'application/pdf':
161
- if (!this.toolTipTypeArray.includes('PDF'))
162
- this.toolTipTypeArray.push('PDF');
163
- break;
164
- case 'application/msword':
165
- if (!this.toolTipTypeArray.includes('Word'))
166
- this.toolTipTypeArray.push('Word');
167
- break;
168
- case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
169
- if (!this.toolTipTypeArray.includes('Word'))
170
- this.toolTipTypeArray.push('Word');
171
- break;
172
- case 'application/vnd.ms-excel':
173
- if (!this.toolTipTypeArray.includes('Excel'))
174
- this.toolTipTypeArray.push('Excel');
175
- break;
176
- case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
177
- if (!this.toolTipTypeArray.includes('Excel'))
178
- this.toolTipTypeArray.push('Excel');
179
- break;
180
- case 'application/vnd.ms-powerpoint':
181
- if (!this.toolTipTypeArray.includes('PowerPoint'))
182
- this.toolTipTypeArray.push('PowerPoint');
183
- break;
184
- case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
185
- if (!this.toolTipTypeArray.includes('PowerPoint'))
186
- this.toolTipTypeArray.push('PowerPoint');
187
- break;
188
- case 'image/png':
189
- if (!this.toolTipTypeArray.includes('PNG'))
190
- this.toolTipTypeArray.push('PNG');
191
- break;
192
- case 'image/bmp':
193
- if (!this.toolTipTypeArray.includes('BMP'))
194
- this.toolTipTypeArray.push('BMP');
195
- break;
196
- case 'image/jpeg':
197
- if (!this.toolTipTypeArray.includes('JPEG'))
198
- this.toolTipTypeArray.push('JPEG');
199
- break;
200
- case 'application/zip':
201
- if (!this.toolTipTypeArray.includes('ZIP'))
202
- this.toolTipTypeArray.push('ZIP');
203
- break;
204
- case 'application/x-rar-compressed':
205
- if (!this.toolTipTypeArray.includes('RAR'))
206
- this.toolTipTypeArray.push('RAR');
207
- break;
208
- case 'video/mp4':
209
- if (!this.toolTipTypeArray.includes('MP4'))
210
- this.toolTipTypeArray.push('MP4');
211
- break;
212
- case 'video/avi':
213
- if (!this.toolTipTypeArray.includes('AVI'))
214
- this.toolTipTypeArray.push('AVI');
215
- break;
216
- case 'video/quicktime':
217
- if (!this.toolTipTypeArray.includes('MOV'))
218
- this.toolTipTypeArray.push('MOV');
219
- break;
220
- case 'video/mpeg':
221
- if (!this.toolTipTypeArray.includes('MPEG'))
222
- this.toolTipTypeArray.push('MPEG');
223
- break;
224
- case 'audio/mpeg':
225
- if (!this.toolTipTypeArray.includes('MP3'))
226
- this.toolTipTypeArray.push('MP3');
227
- break;
228
- case 'video/x-flv':
229
- if (!this.toolTipTypeArray.includes('FLV'))
230
- this.toolTipTypeArray.push('FLV');
231
- break;
232
- case 'video/x-ms-wmv':
233
- if (!this.toolTipTypeArray.includes('WMV'))
234
- this.toolTipTypeArray.push('WMV');
235
- break;
236
- case 'image/svg+xml':
237
- if (!this.toolTipTypeArray.includes('SVG'))
238
- this.toolTipTypeArray.push('SVG');
239
- break;
240
- case 'text/plain':
241
- if (!this.toolTipTypeArray.includes('Txt'))
242
- this.toolTipTypeArray.push('Txt');
243
- break;
244
- case 'application/BN':
245
- if (!this.toolTipTypeArray.includes('License'))
246
- this.toolTipTypeArray.push('License');
247
- break;
248
- default:
249
- break;
250
- }
251
- }
252
- this.validationMessage = this.validationMessage + `${this.UtilityService.getResourceValue('Extensions')} (${this.toolTipTypeArray}) `;
253
- }
254
- if (this.options.fileMaxSizeInMB > 0) {
255
- this.validationMessage = this.validationMessage + `<br /> ${this.UtilityService.getResourceValue('FileMaxSizeInMB') + this.options.fileMaxSizeInMB + ' ' + this.UtilityService.getResourceValue('MB')}`;
256
- }
257
- if (this.options.minNoOfFiles > 0) {
258
- this.validationMessage = this.validationMessage + `<br /> ${this.UtilityService.getResourceValue('MinFileCountValidationKey') + this.options.minNoOfFiles}`;
259
- }
260
- if (this.options.maxNoOfFiles > 0) {
261
- this.validationMessage = this.validationMessage + `<br /> ${this.UtilityService.getResourceValue('MaxFileCountValidationKey') + this.options.maxNoOfFiles}`;
262
- }
263
- this.group.addControl(this.options.name, new FormControl(''));
264
- this.fileUploadFormControl = this.group.controls[this.options.name];
265
- if (this.options.customValidation.length > 0) {
266
- let Validations = this.options.customValidation;
267
- for (let index = 0; index < Validations.length; index++) {
268
- const Validation = Validations[index];
269
- this.validationRules.push(Validation.functionBody);
270
- }
271
- }
272
- if (this.options.isMultipleFile && this.options.maxNoOfFiles > 0) {
273
- this.validationCountMessage = `${this.UtilityService.getResourceValue('MaxFilesCount')} : ${this.options.maxNoOfFiles}`;
274
- }
275
- if (this.options.isRequired) {
276
- this.validationRules.push(Validators.required);
277
- }
278
- this.fileUploadFormControl.setValidators(this.validationRules);
279
- this.fileUploadFormControl.setAsyncValidators(this.validationRulesAsync);
280
- if (this.options.isDisabled) {
281
- this.fileUploadFormControl.disable();
282
- }
283
- this.MultipleFileUploadControlHost.ngSubmit
284
- .pipe(takeUntil(this.destroy$))
285
- .subscribe((value) => {
286
- this.group.markAllAsTouched();
287
- this.markAllAsTouched = true;
288
- });
289
- this.fileUploadFormControl.setValue(this.options.value);
290
- }
291
- ngAfterViewInit() {
292
- if (this.options.attributeList != null) {
293
- var element = document.getElementById(this.options.name);
294
- for (let index = 0; index < this.options.attributeList.length; index++) {
295
- element.setAttribute(this.options.attributeList[index].key, this.options.attributeList[index].value);
296
- }
297
- }
298
- }
299
- showGlobalError() {
300
- this.controlUtility.showGlobalError();
301
- }
302
- getErrorValidation(ErrorList) {
303
- if (this.markAllAsTouched && this.group.invalid) {
304
- this.showGlobalError();
305
- this.markAllAsTouched = false;
306
- }
307
- return this.controlUtility.getErrorValidationMassage(ErrorList, this.group, this.options);
308
- }
309
- fileOverAnother(event) {
310
- this.hasAnotherDropZoneOver = event;
311
- }
312
- isHideInput() {
313
- if (this.options.isMultipleFile) {
314
- if (this.options.maxNoOfFiles != null &&
315
- this.options.maxNoOfFiles > 0 &&
316
- this.options.maxNoOfFiles == this.uploader.queue.length) {
317
- return true;
318
- }
319
- }
320
- else {
321
- if (this.uploader.queue.length > 0) {
322
- return true;
323
- }
324
- }
325
- return false;
326
- }
327
- onFileChange() {
328
- let FilesArray = [];
329
- // Clear any previous validation errors at the start of file change
330
- this.pendingValidationErrors = null;
331
- // Check for duplicate file names in the queue
332
- const duplicateFiles = this.findDuplicateFiles();
333
- if (duplicateFiles.length > 0) {
334
- // Remove only the newly added duplicate files from queue (keep existing files)
335
- this.removeDuplicateFilesFromQueue(duplicateFiles);
336
- // Set validation error for duplicate files
337
- const duplicateFileNames = duplicateFiles.map(f => f.file?.name).join(', ');
338
- const formControl = this.fileUploadFormControl;
339
- const resourceValue = this.UtilityService.getResourceValue('DuplicateFileError');
340
- // If resource value is the same as the key, it means the resource wasn't found
341
- const errorMessage = (resourceValue && resourceValue !== 'DuplicateFileError') ? resourceValue : 'File(s) already exist';
342
- const errorObj = {
343
- DuplicateFileError: `${errorMessage}: ${duplicateFileNames}`
344
- };
345
- this.pendingValidationErrors = errorObj;
346
- formControl.setErrors(errorObj);
347
- formControl.markAsTouched();
348
- // Auto-clear duplicate error after 5 seconds to allow form submission
349
- setTimeout(() => {
350
- // Only clear if the current error is still the duplicate error we set
351
- const currentErrors = formControl.errors;
352
- if (currentErrors && currentErrors.DuplicateFileError === errorObj.DuplicateFileError) {
353
- formControl.setErrors(null);
354
- this.pendingValidationErrors = null;
355
- }
356
- }, 5000);
357
- // If all files were duplicates, return early
358
- if (this.uploader.queue.filter(item => item['some'].lastModified != null).length === 0) {
359
- return;
360
- }
361
- }
362
- if (this.options.isMultipleFile && this.options.minNoOfFiles != null && this.options.minNoOfFiles > 0 && this.options.minNoOfFiles > this.uploader.queue.length) {
363
- const formControl = this.fileUploadFormControl;
364
- const existingErrors = formControl.errors || {};
365
- const newErrors = {
366
- ...existingErrors,
367
- MinFileCountValidationKey: this.options.minNoOfFiles
368
- };
369
- formControl.setErrors(newErrors);
370
- formControl.markAsTouched();
371
- this.uploader.queue = [];
372
- return;
373
- }
374
- if (this.options.isMultipleFile && this.options.maxNoOfFiles != null && this.options.maxNoOfFiles > 0 && this.options.maxNoOfFiles < this.uploader.queue.length) {
375
- const formControl = this.fileUploadFormControl;
376
- const existingErrors = formControl.errors || {};
377
- const newErrors = {
378
- ...existingErrors,
379
- MaxFileCountValidationKey: this.options.maxNoOfFiles
380
- };
381
- formControl.setErrors(newErrors);
382
- formControl.markAsTouched();
383
- this.uploader.queue = [];
384
- return;
385
- }
386
- if (this.options.isMultipleFile && this.options.maxSizeForAllFilesInMB != null && this.options.maxSizeForAllFilesInMB > 0) {
387
- let AllSizeFile = 0;
388
- for (let index = 0; index < this.uploader.queue.length; index++) {
389
- const element = this.uploader.queue[index];
390
- const file = element.file;
391
- AllSizeFile = AllSizeFile + file.size;
392
- }
393
- const MaxSizeForAllFiles = this.options.maxSizeForAllFilesInMB * 1000 * 1000;
394
- if (AllSizeFile > MaxSizeForAllFiles) {
395
- const formControl = this.fileUploadFormControl;
396
- const existingErrors = formControl.errors || {};
397
- const newErrors = {
398
- ...existingErrors,
399
- MaxSizeForAllFilesInMB: this.options.maxSizeForAllFilesInMB + ' ' + this.UtilityService.getResourceValue('MB')
400
- };
401
- formControl.setErrors(newErrors);
402
- formControl.markAsTouched();
403
- this.uploader.queue = [];
404
- return;
405
- }
406
- }
407
- if (!this.options.isMultipleFile && this.uploader.queue.length > 1) {
408
- const formControl = this.fileUploadFormControl;
409
- const newErrors = {
410
- MaxFileCountValidationKey: 1
411
- };
412
- formControl.setErrors(newErrors);
413
- formControl.markAsTouched();
414
- this.uploader.queue = [];
415
- return;
416
- }
417
- let AddedQueue = this.uploader.queue.filter((obj) => obj['some'].lastModified != null);
418
- let hasValidationError = false;
419
- let validationErrorType = '';
420
- let validationErrorValue = '';
421
- for (let index = 0; index < AddedQueue.length; index++) {
422
- const element = AddedQueue[index];
423
- const file = element.file;
424
- const maxFileSize = this.options.fileMaxSizeInMB * 1000 * 1000;
425
- if (file) {
426
- const fileType = file.type;
427
- if (file.size > maxFileSize) {
428
- // Remove only the file that violates the size limit
429
- this.uploader.queue = this.uploader.queue.filter(queueItem => queueItem.file.name !== file.name);
430
- hasValidationError = true;
431
- validationErrorType = 'FileMaxSizeInMB';
432
- validationErrorValue = this.options.fileMaxSizeInMB + ' ' + this.UtilityService.getResourceValue('MB');
433
- // Continue checking other files instead of returning immediately
434
- }
435
- if (this.options.fileUploadAcceptsTypes != null &&
436
- this.options.fileUploadAcceptsTypes.length > 0 &&
437
- !this.isFileTypeAccepted(fileType)) {
438
- // Remove only the file that violates the file type restriction
439
- this.uploader.queue = this.uploader.queue.filter(queueItem => queueItem.file.name !== file.name);
440
- hasValidationError = true;
441
- validationErrorType = 'ToolTipTypeError';
442
- validationErrorValue = this.toolTipTypeArray;
443
- // Continue checking other files instead of returning immediately
444
- }
445
- }
446
- }
447
- // Set validation error if any files were removed due to validation failures
448
- this.pendingValidationErrors = null;
449
- if (hasValidationError) {
450
- const formControl = this.fileUploadFormControl;
451
- const errorObj = {};
452
- errorObj[validationErrorType] = validationErrorValue;
453
- this.pendingValidationErrors = errorObj; // Store errors to reapply later
454
- formControl.setErrors(errorObj);
455
- formControl.markAsTouched();
456
- // Auto-clear FileMaxSizeInMB error after 5 seconds (similar to DuplicateFileError)
457
- if (validationErrorType === 'FileMaxSizeInMB') {
458
- setTimeout(() => {
459
- // Only clear if the current error is still the FileMaxSizeInMB error we set
460
- const currentErrors = formControl.errors;
461
- if (currentErrors && currentErrors['FileMaxSizeInMB'] === errorObj['FileMaxSizeInMB']) {
462
- formControl.setErrors(null);
463
- this.pendingValidationErrors = null;
464
- }
465
- }, 5000);
466
- }
467
- // Don't return here, continue processing valid files
468
- }
469
- // Re-filter the queue to get only valid files for processing
470
- AddedQueue = this.uploader.queue.filter((obj) => obj['some'].lastModified != null);
471
- for (let index = 0; index < AddedQueue.length; index++) {
472
- const element = AddedQueue[index];
473
- const file = element.file;
474
- if (file) {
475
- if (this.options.isUploadFileAsync && !element._file['iD_GUID']) {
476
- this.fileUploadService.uploadFile(element._file)
477
- .pipe(takeUntil(this.destroy$))
478
- .subscribe({
479
- next: (event) => {
480
- let queueIndex = this.uploader.queue.findIndex((file) => file == element);
481
- if (event.type === HttpEventType.UploadProgress) {
482
- let value = Math.round((100 * event.loaded) / event.total);
483
- this.uploader.queue[queueIndex].progress = value >= 95 ? 95 : value;
484
- }
485
- else if (event.type === HttpEventType.Response) {
486
- this.uploader.queue[queueIndex].progress = 100;
487
- let fileID = event.body.val;
488
- this.uploader.queue[queueIndex]._file['iD_GUID'] = fileID;
489
- this.uploader.queue[queueIndex]._file['isNew'] = true;
490
- let AddedFile = {
491
- iD_GUID: fileID,
492
- fileName: this.uploader.queue[queueIndex]._file['name'],
493
- fileType: this.uploader.queue[queueIndex]._file['type'],
494
- isNew: true
495
- };
496
- if (this.options.isMultipleFile == false) {
497
- this.fileUploadModel = new FileUploadModel();
498
- this.fileUploadModel.file = AddedFile;
499
- this.setValuePreservingErrors(this.fileUploadModel, this.pendingValidationErrors);
500
- }
501
- else {
502
- FilesArray.push(AddedFile);
503
- this.multipleFileUploadModel.uploadedFiles = FilesArray;
504
- if (this.options.value != null && this.options.value != undefined) {
505
- if (this.options.value.correlationID_GUID == null) {
506
- this.multipleFileUploadModel.removedFiles = [];
507
- }
508
- }
509
- this.multipleFileUploadModel.correlationID_GUID =
510
- this.options.value?.correlationID_GUID;
511
- this.setValuePreservingErrors(this.multipleFileUploadModel, this.pendingValidationErrors);
512
- this.isUploadComplete.emit(true);
513
- }
514
- }
515
- }
516
- });
517
- }
518
- else {
519
- let reader = new FileReader();
520
- let fileObject = file.rawFile;
521
- reader.readAsDataURL(fileObject);
522
- reader.onload = () => {
523
- let existingID_GUID = null;
524
- if (!this.options.isMultipleFile && this.file)
525
- existingID_GUID = this.file.NameWithExtension == file.name ? this.file.iD_GUID : null;
526
- let AddedFile = {
527
- fileName: file.name,
528
- fileType: file.type,
529
- fileBase64: reader.result.toString().split(',')[1],
530
- fileSizeInMB: file.size / 1000 / 1000,
531
- nameWithExtension: file.name,
532
- iD_GUID: existingID_GUID,
533
- isNew: true
534
- };
535
- if (this.options.isMultipleFile == false) {
536
- this.fileUploadModel = new FileUploadModel();
537
- this.fileUploadModel.file = AddedFile;
538
- this.setValuePreservingErrors(this.fileUploadModel, this.pendingValidationErrors);
539
- }
540
- else {
541
- FilesArray.push(AddedFile);
542
- this.multipleFileUploadModel.uploadedFiles = FilesArray;
543
- if (this.options.value != null && this.options.value != undefined) {
544
- if (this.options.value.correlationID_GUID == null) {
545
- this.multipleFileUploadModel.removedFiles = [];
546
- }
547
- }
548
- this.multipleFileUploadModel.correlationID_GUID =
549
- this.options.value?.correlationID_GUID;
550
- this.setValuePreservingErrors(this.multipleFileUploadModel, this.pendingValidationErrors);
551
- }
552
- };
553
- let originalValue = this.group.get(this.options.name).value;
554
- if (this.options.patchFunction &&
555
- this.options.patchPath &&
556
- this.group.get(this.options.name).valid) {
557
- this.controlUtility.patchControlValue(originalValue, this.options.patchFunction, this.options.patchPath);
558
- }
559
- this.OnChange.emit(originalValue);
560
- }
561
- }
562
- }
563
- }
564
- removeFromControlValue(item) {
565
- if (this.options.isUploadFileAsync && item.progress == 100 && item._file['isNew']) {
566
- this.fileUploadService.deleteFile(item._file['iD_GUID'])
567
- .pipe(takeUntil(this.destroy$))
568
- .subscribe((res) => { });
569
- }
570
- if (this.options.isMultipleFile == false) {
571
- this.fileUploadModel = null;
572
- if (this.options.isRequired == true) {
573
- this.fileUploadFormControl.markAsTouched();
574
- this.fileUploadFormControl.updateValueAndValidity(); // Trigger validation check
575
- }
576
- this.group.get(this.options.name).setValue(this.fileUploadModel);
577
- this.options.value = this.fileUploadModel;
578
- }
579
- else {
580
- if (this.options.value != null && this.options.value != undefined) {
581
- if (this.options.value.correlationID_GUID == null) {
582
- this.deletedFiles = [];
583
- this.multipleFileUploadModel.removedFiles = [];
584
- }
585
- else {
586
- if (this.multipleFileUploadModel.removedFiles.length == 0) {
587
- let FileObject = item.file.rawFile;
588
- let DeletedItem = this.multipleFileUploadModel.existingFiles.filter((obj) => obj.nameWithExtension == FileObject.name)[0];
589
- this.multipleFileUploadModel.existingFiles =
590
- this.multipleFileUploadModel.existingFiles.filter((obj) => obj.nameWithExtension != FileObject.name);
591
- this.deletedFiles.push(DeletedItem);
592
- this.multipleFileUploadModel.removedFiles.push(DeletedItem.iD_GUID);
593
- }
594
- else {
595
- let FileObject = item.file.rawFile;
596
- let deletedList = this.deletedFiles.filter((obj) => obj.nameWithExtension == FileObject.name);
597
- if (deletedList.length == 0 || deletedList == undefined) {
598
- let DeletedItem = this.multipleFileUploadModel.existingFiles.filter((obj) => obj.nameWithExtension == FileObject.name)[0];
599
- this.multipleFileUploadModel.existingFiles =
600
- this.multipleFileUploadModel.existingFiles.filter((obj) => obj.nameWithExtension != FileObject.name);
601
- this.deletedFiles.push(DeletedItem);
602
- this.multipleFileUploadModel.removedFiles.push(DeletedItem.iD_GUID);
603
- }
604
- }
605
- }
606
- }
607
- else {
608
- this.deletedFiles = [];
609
- this.multipleFileUploadModel.removedFiles = [];
610
- }
611
- this.multipleFileUploadModel.uploadedFiles =
612
- this.multipleFileUploadModel.uploadedFiles.filter((obj) => (obj.nameWithExtension && obj.nameWithExtension != item._file.name) ||
613
- obj.iD_GUID != item._file['iD_GUID']);
614
- if ((this.multipleFileUploadModel.uploadedFiles == null ||
615
- this.multipleFileUploadModel.uploadedFiles.length == 0) &&
616
- this.options.isRequired) {
617
- const formControl = this.fileUploadFormControl;
618
- formControl.setErrors({
619
- MinFileCountValidationKey: this.options.minNoOfFiles
620
- });
621
- this.fileUploadFormControl.markAsTouched();
622
- this.fileUploadFormControl.updateValueAndValidity(); // Trigger validation check
623
- }
624
- this.multipleFileUploadModel.correlationID_GUID = this.options.value?.correlationID_GUID;
625
- this.fileUploadFormControl.setValue(this.multipleFileUploadModel);
626
- this.group.get(this.options.name).setValue(this.multipleFileUploadModel);
627
- this.fileUploadFormControl.updateValueAndValidity();
628
- //Use this line to enable two way binding.
629
- this.options.value = this.multipleFileUploadModel;
630
- }
631
- }
632
- convertSizeToMB(size) {
633
- if (size === 0) {
634
- return 0;
635
- }
636
- // Convert size to megabytes
637
- const megabytes = size / (1024 * 1024);
638
- // Round to two decimal places
639
- const roundedMegabytes = Math.round(megabytes * 100) / 100;
640
- return roundedMegabytes;
641
- }
642
- ngOnDestroy() {
643
- // Complete all subscriptions to prevent memory leaks
644
- this.destroy$.next();
645
- this.destroy$.complete();
646
- // Clear uploader queue to free memory
647
- if (this.uploader) {
648
- this.uploader.clearQueue();
649
- }
650
- }
651
- sanitizeFileName(fileName) {
652
- // Remove potentially dangerous characters from file names
653
- return fileName.replace(/[<>:"/\\|?*]/g, '_').trim();
654
- }
655
- findDuplicateFiles() {
656
- const duplicateFiles = [];
657
- const existingFileNames = new Set();
658
- // First pass: collect names of existing files (already in queue before this upload)
659
- const existingFiles = this.uploader.queue.filter(item => item['some'].lastModified == null);
660
- for (const item of existingFiles) {
661
- const fileName = item.file.name.toLowerCase().trim();
662
- existingFileNames.add(fileName);
663
- }
664
- // Second pass: check newly added files against existing file names
665
- const newlyAddedFiles = this.uploader.queue.filter(item => item['some'].lastModified != null);
666
- for (const item of newlyAddedFiles) {
667
- const fileName = item.file.name.toLowerCase().trim();
668
- // If this new file name already exists in the queue, it's a duplicate
669
- if (existingFileNames.has(fileName)) {
670
- duplicateFiles.push(item);
671
- }
672
- else {
673
- // Add this new file name to the set so subsequent files with same name are also flagged
674
- existingFileNames.add(fileName);
675
- }
676
- }
677
- return duplicateFiles;
678
- }
679
- removeDuplicateFilesFromQueue(duplicateFiles) {
680
- for (const duplicateFile of duplicateFiles) {
681
- const index = this.uploader.queue.indexOf(duplicateFile);
682
- if (index > -1) {
683
- this.uploader.queue.splice(index, 1);
684
- }
685
- }
686
- }
687
- isFileTypeAccepted(fileType) {
688
- if (!this.acceptedTypeArray || this.acceptedTypeArray.length === 0) {
689
- return true; // No restrictions
690
- }
691
- // Normalize the file type for comparison
692
- const normalizedFileType = fileType.toLowerCase().trim();
693
- // Check against all accepted types (case-insensitive and trimmed)
694
- return this.acceptedTypeArray.some(acceptedType => {
695
- const normalizedAcceptedType = acceptedType.toLowerCase().trim();
696
- return normalizedAcceptedType === normalizedFileType;
697
- });
698
- }
699
- setValuePreservingErrors(value, preserveErrors) {
700
- // Capture current duplicate errors before setValue clears them
701
- const currentErrors = this.fileUploadFormControl.errors;
702
- const duplicateError = currentErrors?.DuplicateFileError ? { DuplicateFileError: currentErrors.DuplicateFileError } : null;
703
- // Set the form control value
704
- this.fileUploadFormControl.setValue(value);
705
- this.group.get(this.options.name).setValue(value);
706
- // Apply errors in priority order: preserveErrors > duplicateError > pendingValidationErrors
707
- const errorsToApply = preserveErrors || duplicateError || this.pendingValidationErrors;
708
- if (errorsToApply) {
709
- this.fileUploadFormControl.setErrors(errorsToApply);
710
- this.fileUploadFormControl.markAsTouched();
711
- }
712
- // Update the options value for two-way binding
713
- this.options.value = value;
714
- }
715
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FileUploadComponent, deps: [{ token: i1.ControlContainer, optional: true }, { token: i1.FormGroupDirective }, { token: i2.ControlUtility }, { token: i3.UtilityService }, { token: i3.ControlValidationService }, { token: i2.GlobalSettings }, { token: i2.FileUploadService }], target: i0.ɵɵFactoryTarget.Component }); }
716
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: FileUploadComponent, isStandalone: true, selector: "BBSF-FileUpload", inputs: { group: "group", options: "options" }, outputs: { OnChange: "OnChange", isUploadComplete: "isUploadComplete" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-file-upload\" [formGroup]=\"group\">\r\n <div [ngClass]=\"options.viewType == 1 ? 'bbsf-vertical' : 'bbsf-horizontal'\">\r\n <!--label-->\r\n <label [hidden]=\"options.hideLabel\" class=\"bbsf-label {{ options.labelExtraClasses }}\">\r\n {{ options.labelValue }}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk && options.isRequired) || options.isRequired) && !options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <!--Allow dropZone-->\r\n <div ng2FileDrop class=\"bbsf-input-container {{ options.extraClasses }}\"\r\n *ngIf=\"options.isDropZone && !(options.isMultipleFile == false && uploader.queue.length > 0) && !options.isReadonly\"\r\n [ngClass]=\"{ 'another-file-over-class': hasAnotherDropZoneOver }\" (onFileDrop)=\"onFileChange()\"\r\n (fileOver)=\"fileOverAnother($event)\" [uploader]=\"uploader\" [accept]=\"acceptedType\" id=\"{{ options.name }}\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" aria-invalid=\"true\" type=\"file\"\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\"\r\n (click)=\"fileInputDropZone.click()\">\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg validation-msg-header text-center\">\r\n {{ UtilityService.getResourceValue('DragAndDropHere') }}\r\n </div>\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n <div class=\"bbsf-validation-msg ng-star-inserted text-center text-danger\"\r\n *ngIf=\"validationCountMessage && options.isMultipleFile && options.maxNoOfFiles > 0\"\r\n [innerHTML]=\"validationCountMessage\"></div>\r\n </div>\r\n </div>\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" name=\"file\" type=\"file\" value=\"\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType == 1 ? '' : 'col-md-9'\" id=\"{{ options.name }}\"\r\n aria-invalid=\"true\" #fileInputDropZone\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!--Not allowed dropZone-->\r\n <div class=\"bbsf-input-container\" *ngIf=\"!options.isDropZone && !isHideInput() && !options.isReadonly\"\r\n (click)=\"fileInput.click()\">\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg text-center\">{{ UtilityService.getResourceValue('Upload') }}</div>\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n <div class=\"bbsf-validation-msg ng-star-inserted text-center text-danger\"\r\n *ngIf=\"validationCountMessage && options.isMultipleFile && options.maxNoOfFiles > 0\"\r\n [innerHTML]=\"validationCountMessage\"></div>\r\n </div>\r\n </div>\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" name=\"file\" type=\"file\" value=\"\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType == 1 ? '' : 'col-md-9'\" id=\"{{ options.name }}\"\r\n aria-invalid=\"true\" #fileInput\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!-- readonly -->\r\n <div *ngIf=\"options.isReadonly && !options.value\">\r\n <span class=\"readonly-view\">{{ UtilityService.getResourceValue('NA') }}</span>\r\n </div>\r\n </div>\r\n <!--items uploaded-->\r\n <div class=\"uploaded-items\">\r\n <div class=\"btn-group\" *ngFor=\"let item of uploader.queue\">\r\n <ng-container *ngIf=\"item?.progress == 100 && options.isUploadFileAsync\">\r\n <a *ngIf=\"item?.file?.rawFile['url']\" href=\"{{ item?.file?.rawFile['url'] }}\"\r\n class=\"btn-download-file btn-sm btn-progress-upload\" download>\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <a *ngIf=\"item?.file?.rawFile['url'] == null\" class=\"btn-download-file btn-sm btn-progress-upload\">\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <button *ngIf=\"!options.isReadonly\" class=\"btn btn-download-file btn-sm\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M9.33301 3.70584V3.26663C9.33301 2.65166 9.33301 2.34419 9.20587 2.1093C9.09405 1.9027 8.91555 1.73471 8.69604 1.62944C8.44647 1.50977 8.11977 1.50977 7.46638 1.50977H6.53305C5.87965 1.50977 5.55296 1.50977 5.30339 1.62944C5.08387 1.73471 4.90539 1.9027 4.79354 2.1093C4.66638 2.34419 4.66638 2.65166 4.66638 3.26663V3.70584\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M1.75 3.70605H12.25M11.0834 3.70605V9.8551C11.0834 10.7775 11.0834 11.2387 10.8926 11.591C10.7248 11.901 10.4571 12.1529 10.1278 12.3109C9.75345 12.4904 9.26345 12.4904 8.28334 12.4904H5.71666C4.73658 12.4904 4.24653 12.4904 3.87218 12.3109C3.5429 12.1529 3.27519 11.901 3.10741 11.591C2.91666 11.2387 2.91666 10.7775 2.91666 9.8551V3.70605\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!options.isUploadFileAsync\">\r\n <a href=\"{{ item?.file?.rawFile['url'] }}\" *ngIf=\"item?.file?.rawFile['url']\" class=\"btn btn-download-file btn-sm\" download>\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M21 22H3C2.4 22 2 21.6 2 21C2 20.4 2.4 20 3 20H21C21.6 20 22 20.4 22 21C22 21.6 21.6 22 21 22ZM13 13.4V3C13 2.4 12.6 2 12 2C11.4 2 11 2.4 11 3V13.4H13Z\"\r\n fill=\"currentColor\"></path>\r\n <path opacity=\"0.3\" d=\"M7 13.4H17L12.7 17.7C12.3 18.1 11.7 18.1 11.3 17.7L7 13.4Z\" fill=\"currentColor\">\r\n </path>\r\n </svg>\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <a *ngIf=\"item?.file?.rawFile['url'] == null\" class=\"btn-download-file btn-sm btn-progress-upload\">\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <button *ngIf=\"!options.isReadonly\" class=\"btn btn-download-file btn-sm btn-danger\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <i class=\"fa fa-times px-0\"></i>\r\n </button>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!--progress bar file upload-->\r\n <div *ngFor=\"let item of uploader.queue\">\r\n <div class=\"upload-items\" [ngClass]=\"{ 'mt-4': options.isMultipleFile == true }\"\r\n *ngIf=\"item?.progress < 100 && options.isUploadFileAsync\">\r\n <div class=\"upload-items-toolbar\">\r\n <h4>{{ item?.file?.name }}</h4>\r\n <span (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <g clip-path=\"url(#clip0_1324_13216)\">\r\n <path opacity=\"0.4\"\r\n d=\"M9 16.5C13.1421 16.5 16.5 13.1421 16.5 9C16.5 4.85786 13.1421 1.5 9 1.5C4.85786 1.5 1.5 4.85786 1.5 9C1.5 13.1421 4.85786 16.5 9 16.5Z\"\r\n stroke=\"#DBE1F0\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M11.25 6.75L6.75 11.25M6.75 6.75L11.25 11.25\" stroke=\"#DBE1F0\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </g>\r\n <defs>\r\n <clipPath id=\"clip0_1324_13216\">\r\n <rect width=\"18\" height=\"18\" fill=\"white\" />\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"progress\">\r\n <div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"70\" aria-valuemin=\"0\" aria-valuemax=\"100\"\r\n [class.file-uploaded]=\"item?.progress < 100\" [style.width.%]=\"item?.progress\" *ngIf=\"item?.progress > 0\">\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- required text-->\r\n <div class=\"bbsf-validation\" *ngIf=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\">\r\n {{ getErrorValidation(fileUploadFormControl.errors | keyvalue) }}\r\n </div>\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription != null\">{{ options.labelDescription }}</div>\r\n <div *ngIf=\"(group.valid && group.dirty && group.touched) || (group.untouched && group.invalid && group.dirty)\">\r\n {{ resetError() }}\r\n </div>\r\n </div>\r\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i4.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "directive", type: i5.FileDropDirective, selector: "[ng2FileDrop]", inputs: ["uploader"], outputs: ["fileOver", "onFileDrop"] }, { kind: "directive", type: i5.FileSelectDirective, selector: "[ng2FileSelect]", inputs: ["uploader"], outputs: ["onFileSelected"] }, { kind: "ngmodule", type: NgxDropzoneModule }] }); }
717
- }
718
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FileUploadComponent, decorators: [{
719
- type: Component,
720
- args: [{ selector: 'BBSF-FileUpload', standalone: true, imports: [
721
- CommonModule,
722
- FormsModule,
723
- ReactiveFormsModule,
724
- FileUploadModule,
725
- NgxDropzoneModule
726
- ], schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA], template: "<div class=\"form-group bbsf-control bbsf-file-upload\" [formGroup]=\"group\">\r\n <div [ngClass]=\"options.viewType == 1 ? 'bbsf-vertical' : 'bbsf-horizontal'\">\r\n <!--label-->\r\n <label [hidden]=\"options.hideLabel\" class=\"bbsf-label {{ options.labelExtraClasses }}\">\r\n {{ options.labelValue }}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk && options.isRequired) || options.isRequired) && !options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <!--Allow dropZone-->\r\n <div ng2FileDrop class=\"bbsf-input-container {{ options.extraClasses }}\"\r\n *ngIf=\"options.isDropZone && !(options.isMultipleFile == false && uploader.queue.length > 0) && !options.isReadonly\"\r\n [ngClass]=\"{ 'another-file-over-class': hasAnotherDropZoneOver }\" (onFileDrop)=\"onFileChange()\"\r\n (fileOver)=\"fileOverAnother($event)\" [uploader]=\"uploader\" [accept]=\"acceptedType\" id=\"{{ options.name }}\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" aria-invalid=\"true\" type=\"file\"\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\"\r\n (click)=\"fileInputDropZone.click()\">\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg validation-msg-header text-center\">\r\n {{ UtilityService.getResourceValue('DragAndDropHere') }}\r\n </div>\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n <div class=\"bbsf-validation-msg ng-star-inserted text-center text-danger\"\r\n *ngIf=\"validationCountMessage && options.isMultipleFile && options.maxNoOfFiles > 0\"\r\n [innerHTML]=\"validationCountMessage\"></div>\r\n </div>\r\n </div>\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" name=\"file\" type=\"file\" value=\"\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType == 1 ? '' : 'col-md-9'\" id=\"{{ options.name }}\"\r\n aria-invalid=\"true\" #fileInputDropZone\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!--Not allowed dropZone-->\r\n <div class=\"bbsf-input-container\" *ngIf=\"!options.isDropZone && !isHideInput() && !options.isReadonly\"\r\n (click)=\"fileInput.click()\">\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg text-center\">{{ UtilityService.getResourceValue('Upload') }}</div>\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n <div class=\"bbsf-validation-msg ng-star-inserted text-center text-danger\"\r\n *ngIf=\"validationCountMessage && options.isMultipleFile && options.maxNoOfFiles > 0\"\r\n [innerHTML]=\"validationCountMessage\"></div>\r\n </div>\r\n </div>\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" name=\"file\" type=\"file\" value=\"\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType == 1 ? '' : 'col-md-9'\" id=\"{{ options.name }}\"\r\n aria-invalid=\"true\" #fileInput\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!-- readonly -->\r\n <div *ngIf=\"options.isReadonly && !options.value\">\r\n <span class=\"readonly-view\">{{ UtilityService.getResourceValue('NA') }}</span>\r\n </div>\r\n </div>\r\n <!--items uploaded-->\r\n <div class=\"uploaded-items\">\r\n <div class=\"btn-group\" *ngFor=\"let item of uploader.queue\">\r\n <ng-container *ngIf=\"item?.progress == 100 && options.isUploadFileAsync\">\r\n <a *ngIf=\"item?.file?.rawFile['url']\" href=\"{{ item?.file?.rawFile['url'] }}\"\r\n class=\"btn-download-file btn-sm btn-progress-upload\" download>\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <a *ngIf=\"item?.file?.rawFile['url'] == null\" class=\"btn-download-file btn-sm btn-progress-upload\">\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <button *ngIf=\"!options.isReadonly\" class=\"btn btn-download-file btn-sm\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M9.33301 3.70584V3.26663C9.33301 2.65166 9.33301 2.34419 9.20587 2.1093C9.09405 1.9027 8.91555 1.73471 8.69604 1.62944C8.44647 1.50977 8.11977 1.50977 7.46638 1.50977H6.53305C5.87965 1.50977 5.55296 1.50977 5.30339 1.62944C5.08387 1.73471 4.90539 1.9027 4.79354 2.1093C4.66638 2.34419 4.66638 2.65166 4.66638 3.26663V3.70584\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M1.75 3.70605H12.25M11.0834 3.70605V9.8551C11.0834 10.7775 11.0834 11.2387 10.8926 11.591C10.7248 11.901 10.4571 12.1529 10.1278 12.3109C9.75345 12.4904 9.26345 12.4904 8.28334 12.4904H5.71666C4.73658 12.4904 4.24653 12.4904 3.87218 12.3109C3.5429 12.1529 3.27519 11.901 3.10741 11.591C2.91666 11.2387 2.91666 10.7775 2.91666 9.8551V3.70605\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!options.isUploadFileAsync\">\r\n <a href=\"{{ item?.file?.rawFile['url'] }}\" *ngIf=\"item?.file?.rawFile['url']\" class=\"btn btn-download-file btn-sm\" download>\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M21 22H3C2.4 22 2 21.6 2 21C2 20.4 2.4 20 3 20H21C21.6 20 22 20.4 22 21C22 21.6 21.6 22 21 22ZM13 13.4V3C13 2.4 12.6 2 12 2C11.4 2 11 2.4 11 3V13.4H13Z\"\r\n fill=\"currentColor\"></path>\r\n <path opacity=\"0.3\" d=\"M7 13.4H17L12.7 17.7C12.3 18.1 11.7 18.1 11.3 17.7L7 13.4Z\" fill=\"currentColor\">\r\n </path>\r\n </svg>\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <a *ngIf=\"item?.file?.rawFile['url'] == null\" class=\"btn-download-file btn-sm btn-progress-upload\">\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <button *ngIf=\"!options.isReadonly\" class=\"btn btn-download-file btn-sm btn-danger\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <i class=\"fa fa-times px-0\"></i>\r\n </button>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!--progress bar file upload-->\r\n <div *ngFor=\"let item of uploader.queue\">\r\n <div class=\"upload-items\" [ngClass]=\"{ 'mt-4': options.isMultipleFile == true }\"\r\n *ngIf=\"item?.progress < 100 && options.isUploadFileAsync\">\r\n <div class=\"upload-items-toolbar\">\r\n <h4>{{ item?.file?.name }}</h4>\r\n <span (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <g clip-path=\"url(#clip0_1324_13216)\">\r\n <path opacity=\"0.4\"\r\n d=\"M9 16.5C13.1421 16.5 16.5 13.1421 16.5 9C16.5 4.85786 13.1421 1.5 9 1.5C4.85786 1.5 1.5 4.85786 1.5 9C1.5 13.1421 4.85786 16.5 9 16.5Z\"\r\n stroke=\"#DBE1F0\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M11.25 6.75L6.75 11.25M6.75 6.75L11.25 11.25\" stroke=\"#DBE1F0\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </g>\r\n <defs>\r\n <clipPath id=\"clip0_1324_13216\">\r\n <rect width=\"18\" height=\"18\" fill=\"white\" />\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"progress\">\r\n <div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"70\" aria-valuemin=\"0\" aria-valuemax=\"100\"\r\n [class.file-uploaded]=\"item?.progress < 100\" [style.width.%]=\"item?.progress\" *ngIf=\"item?.progress > 0\">\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- required text-->\r\n <div class=\"bbsf-validation\" *ngIf=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\">\r\n {{ getErrorValidation(fileUploadFormControl.errors | keyvalue) }}\r\n </div>\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription != null\">{{ options.labelDescription }}</div>\r\n <div *ngIf=\"(group.valid && group.dirty && group.touched) || (group.untouched && group.invalid && group.dirty)\">\r\n {{ resetError() }}\r\n </div>\r\n </div>\r\n</div>" }]
727
- }], ctorParameters: () => [{ type: i1.ControlContainer, decorators: [{
728
- type: Optional
729
- }] }, { type: i1.FormGroupDirective }, { type: i2.ControlUtility }, { type: i3.UtilityService }, { type: i3.ControlValidationService }, { type: i2.GlobalSettings }, { type: i2.FileUploadService }], propDecorators: { fileInput: [{
730
- type: ViewChild,
731
- args: ['fileInput', { static: false }]
732
- }], group: [{
733
- type: Input
734
- }], options: [{
735
- type: Input
736
- }], OnChange: [{
737
- type: Output
738
- }], isUploadComplete: [{
739
- type: Output
740
- }] } });
741
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmlsZVVwbG9hZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9iYnNmLWNvbnRyb2xzL3NyYy9saWIvY29udHJvbHMvRmlsZVVwbG9hZC9GaWxlVXBsb2FkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Jic2YtY29udHJvbHMvc3JjL2xpYi9jb250cm9scy9GaWxlVXBsb2FkL0ZpbGVVcGxvYWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBeUIsS0FBSyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQWMsTUFBTSxFQUFFLFlBQVksRUFBRSxzQkFBc0IsRUFBRSxnQkFBZ0IsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUNwTCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFvRSxXQUFXLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3SixPQUFPLEVBQUUsWUFBWSxFQUFpRCxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2hILE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUVqRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQVcsZUFBZSxFQUFxQix1QkFBdUIsRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7Ozs7O0FBZ0IzRyxNQUFNLE9BQU8sbUJBQW1CO2FBQ3ZCLDJCQUFzQixHQUFHLElBQUksQUFBUCxDQUFRO0lBNkJyQyxZQUNzQixnQkFBa0MsRUFDL0MsNkJBQWlE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QUFpQixjQUVmLElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLFdBQVc7d0JBQ1gsbUJBQW1CO3dCQUNuQixnQkFBZ0I7d0JBQ2hCLGlCQUFpQjtxQkFDbEIsV0FDUSxDQUFDLHNCQUFzQixFQUFFLGdCQUFnQixDQUFDOzswQkFpQ2hELFFBQVE7d09BNUJnQyxTQUFTO3NCQUFuRCxTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Z0JBR2hDLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0ksUUFBUTtzQkFBakIsTUFBTTtnQkFDRyxnQkFBZ0I7c0JBQXpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgSW5wdXQsIE9wdGlvbmFsLCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBDVVNUT01fRUxFTUVOVFNfU0NIRU1BLCBOT19FUlJPUlNfU0NIRU1BLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgSHR0cEV2ZW50VHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgRm9ybUNvbnRyb2wsIFZhbGlkYXRvcnMsIEZvcm1Hcm91cCwgQWJzdHJhY3RDb250cm9sLCBDb250cm9sQ29udGFpbmVyLCBGb3JtR3JvdXBEaXJlY3RpdmUsIEZvcm1zTW9kdWxlLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBGaWxlVXBsb2FkZXIsIEZpbGVMaWtlT2JqZWN0LCBGaWxlVXBsb2FkZXJPcHRpb25zLCBGaWxlSXRlbSwgRmlsZVVwbG9hZE1vZHVsZSB9IGZyb20gJ25nMi1maWxlLXVwbG9hZCc7XHJcbmltcG9ydCB7IE5neERyb3B6b25lTW9kdWxlIH0gZnJvbSAnbmd4LWRyb3B6b25lJztcclxuaW1wb3J0IHsgQ29udHJvbFZhbGlkYXRpb25TZXJ2aWNlLCBVdGlsaXR5U2VydmljZSB9IGZyb20gJ0BibnNpZ2h0cy9iYnNmLXV0aWxpdGllcy91aSc7XHJcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyBGaWxlRFRPLCBGaWxlVXBsb2FkTW9kZWwsIEZpbGVVcGxvYWRPcHRpb25zLCBNdWx0aXBsZUZpbGVVcGxvYWRNb2RlbCB9IGZyb20gJy4uLy4uL1NoYXJlZC9Nb2RlbHMnO1xyXG5pbXBvcnQgeyBDb250cm9sVXRpbGl0eSwgRmlsZVVwbG9hZFNlcnZpY2UsIEdsb2JhbFNldHRpbmdzIH0gZnJvbSAnLi4vLi4vU2hhcmVkL3NlcnZpY2VzJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnQkJTRi1GaWxlVXBsb2FkJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vRmlsZVVwbG9hZC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbXHJcbiAgICBDb21tb25Nb2R1bGUsXHJcbiAgICBGb3Jtc01vZHVsZSxcclxuICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXHJcbiAgICBGaWxlVXBsb2FkTW9kdWxlLFxyXG4gICAgTmd4RHJvcHpvbmVNb2R1bGVcclxuICBdLFxyXG4gIHNjaGVtYXM6IFtDVVNUT01fRUxFTUVOVFNfU0NIRU1BLCBOT19FUlJPUlNfU0NIRU1BXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRmlsZVVwbG9hZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuICBzdGF0aWMgY29udHJvbENvbnRhaW5lclN0YXRpYyA9IG51bGw7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ2ZpbGVJbnB1dCcsIHsgc3RhdGljOiBmYWxzZSB9KSBmaWxlSW5wdXQ6IEVsZW1lbnRSZWY7XHJcblxyXG4gIGlzU3VibWl0dGVkOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIGdyb3VwOiBGb3JtR3JvdXA7XHJcbiAgQElucHV0KCkgb3B0aW9uczogRmlsZVVwbG9hZE9wdGlvbnM7XHJcbiAgQE91dHB1dCgpIE9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gIEBPdXRwdXQoKSBpc1VwbG9hZENvbXBsZXRlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG5cclxuICBmaWxlVXBsb2FkRm9ybUNvbnRyb2w6IEFic3RyYWN0Q29udHJvbDtcclxuICB2YWxpZGF0aW9uTWVzc2FnZSA9ICcnO1xyXG4gIHZhbGlkYXRpb25Db3VudE1lc3NhZ2UgPSAnJztcclxuICB1cGxvYWRlcjogRmlsZVVwbG9hZGVyO1xyXG4gIGhhc0Fub3RoZXJEcm9wWm9uZU92ZXI6IGJvb2xlYW47XHJcbiAgYWNjZXB0ZWRUeXBlOiBzdHJpbmcgPSAnJztcclxuICBhY2NlcHRlZFR5cGVBcnJheTogc3RyaW5nW10gPSBbXTtcclxuICB0b29sVGlwVHlwZUFycmF5OiBzdHJpbmdbXSA9IFtdO1xyXG4gIGZpbGVMaWtlT2JqZWN0OiBGaWxlTGlrZU9iamVjdDtcclxuICBtYXJrQWxsQXNUb3VjaGVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgdmFsaWRhdGlvblJ1bGVzID0gW107XHJcbiAgdmFsaWRhdGlvblJ1bGVzQXN5bmMgPSBbXTtcclxuICBmaWxlVXBsb2FkTW9kZWw6IEZpbGVVcGxvYWRNb2RlbDtcclxuICBtdWx0aXBsZUZpbGVVcGxvYWRNb2RlbDogTXVsdGlwbGVGaWxlVXBsb2FkTW9kZWw7XHJcbiAgZmlsZTogYW55O1xyXG4gIGRlbGV0ZWRGaWxlczogRmlsZURUT1tdID0gW107XHJcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcbiAgcHJpdmF0ZSBwZW5kaW5nVmFsaWRhdGlvbkVycm9yczogYW55ID0gbnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIGNvbnRyb2xDb250YWluZXI6IENvbnRyb2xDb250YWluZXIsXHJcbiAgICBwdWJsaWMgTXVsdGlwbGVGaWxlVXBsb2FkQ29udHJvbEhvc3Q6IEZvcm1Hcm91cERpcmVjdGl2ZSxcclxuICAgIHByaXZhdGUgY29udHJvbFV0aWxpdHk6IENvbnRyb2xVdGlsaXR5LFxyXG4gICAgcHVibGljIFV0aWxpdHlTZXJ2aWNlOiBVdGlsaXR5U2VydmljZSxcclxuICAgIHByaXZhdGUgY29udHJvbFZhbGlkYXRpb25TZXJ2aWNlOiBDb250cm9sVmFsaWRhdGlvblNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGdsb2JhbFNldHRpbmdzOiBHbG9iYWxTZXR0aW5ncyxcclxuICAgIHByaXZhdGUgZmlsZVVwbG9hZFNlcnZpY2U6IEZpbGVVcGxvYWRTZXJ2aWNlXHJcbiAgKSB7XHJcbiAgICBGaWxlVXBsb2FkQ29tcG9uZW50LmNvbnRyb2xDb250YWluZXJTdGF0aWMgPSB0aGlzLmNvbnRyb2xDb250YWluZXI7XHJcbiAgICAvLyBJbml0aWFsaXplIHVwbG9hZGVyIHdpdGggbWluaW1hbCBvcHRpb25zLCBVUkwgd2lsbCBiZSBzZXQgaW4gbmdPbkluaXQgb25seSBpZiBuZWVkZWRcclxuICAgIHRoaXMudXBsb2FkZXIgPSBuZXcgRmlsZVVwbG9hZGVyKHtcclxuICAgICAgdXJsOiAnJywgLy8gRW1wdHkgVVJMIGluaXRpYWxseSwgd2lsbCBiZSBzZXQgaW4gbmdPbkluaXQgb25seSBpZiBpc1VwbG9hZEZpbGVBc3luYyBpcyB0cnVlXHJcbiAgICAgIGRpc2FibGVNdWx0aXBhcnQ6IGZhbHNlIC8vICdEaXNhYmxlTXVsdGlwYXJ0JyBtdXN0IGJlICd0cnVlJyBmb3IgZm9ybWF0RGF0YUZ1bmN0aW9uIHRvIGJlIGNhbGxlZC5cclxuICAgIH0gYXMgRmlsZVVwbG9hZGVyT3B0aW9ucyk7XHJcbiAgICB0aGlzLmhhc0Fub3RoZXJEcm9wWm9uZU92ZXIgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgdGhpcy5maWxlVXBsb2FkTW9kZWwgPSBuZXcgRmlsZVVwbG9hZE1vZGVsKCk7XHJcbiAgICB0aGlzLm11bHRpcGxlRmlsZVVwbG9hZE1vZGVsID0gbmV3IE11bHRpcGxlRmlsZVVwbG9hZE1vZGVsKCk7XHJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy52aWV3VHlwZSkgdGhpcy5vcHRpb25zLnZpZXdUeXBlID0gdGhpcy5nbG9iYWxTZXR0aW5ncy52aWV3VHlwZTtcclxuXHJcbiAgICAvLyBDb25maWd1cmUgdXBsb2FkZXIgb3B0aW9ucyAtIG5vIFVSTCBuZWVkZWQgc2luY2Ugd2UgaGFuZGxlIHVwbG9hZHMgdmlhIEZpbGVVcGxvYWRTZXJ2aWNlXHJcbiAgICAvLyBOb3RlOiBhbGxvd2VkTWltZVR5cGUgaW4gbmcyLWZpbGUtdXBsb2FkIGRvZXNuJ3Qgd29yayB3ZWxsIHdpdGggY29tbWEtc2VwYXJhdGVkIGVudW0gdmFsdWVzXHJcbiAgICAvLyBXZSBoYW5kbGUgTUlNRSB0eXBlIHZhbGlkYXRpb24gbWFudWFsbHkgaW4gb25GaWxlQ2hhbmdlXHJcbiAgICB0aGlzLnVwbG9hZGVyLnNldE9wdGlvbnMoe1xyXG4gICAgICB1cmw6ICcnLCAvLyBOb3QgdXNlZCAtIHVwbG9hZHMgaGFuZGxlZCBieSBGaWxlVXBsb2FkU2VydmljZSB3aGVuIGlzVXBsb2FkRmlsZUFzeW5jIGlzIHRydWVcclxuICAgICAgZGlzYWJsZU11bHRpcGFydDogZmFsc2UsXHJcbiAgICAgIGF1dG9VcGxvYWQ6IGZhbHNlIC8vIFdlIG1hbnVhbGx5IGNvbnRyb2wgdXBsb2Fkc1xyXG4gICAgICAvLyBhbGxvd2VkTWltZVR5cGUgcmVtb3ZlZCAtIHdlIGhhbmRsZSB2YWxpZGF0aW9uIG1hbnVhbGx5IGZvciBiZXR0ZXIgY29udHJvbFxyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy52YWx1ZSA9PSBudWxsKSB7XHJcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuaXNNdWx0aXBsZUZpbGUgPT0gdHJ1ZSkge1xyXG4gICAgICAgIC8vdGhpcy5vcHRpb25zLlZhbHVlPXRoaXMubXVsdGlwbGVGaWxlVXBsb2FkTW9kZWxcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyB0aGlzLm9wdGlvbnMuVmFsdWU9dGhpcy5maWxlVXBsb2FkTW9kZWxcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKHRoaXMub3B0aW9ucy5pc011bHRpcGxlRmlsZSA9PSB0cnVlKSB7XHJcbiAgICAgICAgbGV0IGZpbGVzOiBhbnlbXSA9IFtdO1xyXG4gICAgICAgIHRoaXMubXVsdGlwbGVGaWxlVXBsb2FkTW9kZWwuZXhpc3RpbmdGaWxlcyA9IHRoaXMub3B0aW9ucy52YWx1ZS5leGlzdGluZ0ZpbGVzO1xyXG4gICAgICAgIHRoaXMubXVsdGlwbGVGaWxlVXBsb2FkTW9kZWwudXBsb2FkZWRGaWxlcyA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLm9wdGlvbnMudmFsdWUuZXhpc3RpbmdGaWxlcy5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLm9wdGlvbnMudmFsdWUuZXhpc3RpbmdGaWxlc1tpbmRleF07XHJcbiAgICAgICAgICB2YXIgYnl0ZXMgPSBuZXcgVWludDhBcnJheShlbGVtZW50LmJ5dGVzKTtcclxuICAgICAgICAgIHZhciBiYXNlNjQgPSBidG9hKFN0cmluZy5mcm9tQ2hhckNvZGUoLi4uQXJyYXkuZnJvbShieXRlcykpKTtcclxuICAgICAgICAgIHRoaXMuZmlsZUxpa2VPYmplY3QgPSA8RmlsZUxpa2VPYmplY3Q+e1xyXG4gICAgICAgICAgICBuYW1lOiBlbGVtZW50Lm5hbWVXaXRoRXh0ZW5zaW9uLFxyXG4gICAgICAgICAgICB0eXBlOiBlbGVtZW50Lm1pbWVUeXBlLFxyXG4gICAgICAgICAgICByYXdGaWxlOiA8YW55PmJhc2U2NFxyXG4gICAgICAgICAgfTtcclxuICAgICAgICAgIC8vIGxldCBibG9iOiBhbnk7XHJcbiAgICAgICAgICAvLyBibG9iID0gbmV3IEJsb2IoWycnXSkgYXMgYW55O1xyXG4gICAgICAgICAgLy8gYmxvYi5uYW1lID0gZWxlbWVudC5GaWxlTmFtZTtcclxuICAgICAgICAgIC8vIGJsb2IubGFzdE1vZGlmaWVkRGF0ZSA9IG51bGw7XHJcbiAgICAgICAgICAvLyBibG9iLndlYmtpdFJlbGF0aXZlUGF0aCA9ICcnO1xyXG4gICAgICAgICAgbGV0IGZpbGUgPSB0aGlzLmZpbGVMaWtlT2JqZWN0IGFzIGFueTtcclxuICAgICAgICAgIGZpbGUudXJsID0gZWxlbWVudC5mdWxsRmlsZVVSTDtcclxuICAgICAgICAgIGZpbGVzLnB1c2goZmlsZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMudXBsb2FkZXIuYWRkVG9RdWV1ZShmaWxlcyk7XHJcbiAgICAgICAgY29uc29sZS5sb2codGhpcy51cGxvYWRlci5xdWV1ZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMub3B0aW9ucy52YWx1ZS5maWxlID8/IHRoaXMub3B0aW9ucy52YWx1ZTtcclxuICAgICAgICB2YXIgYnl0ZXMgPSBuZXcgVWludDhBcnJheShlbGVtZW50LmJ5dGVzKTtcclxuICAgICAgICB2YXIgYmFzZTY0ID0gYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlKC4uLkFycmF5LmZyb20oYnl0ZXMpKSk7XHJcbiAgICAgICAgdGhpcy5maWxlTGlrZU9iamVjdCA9IDxGaWxlTGlrZU9iamVjdD57XHJcbiAgICAgICAgICBuYW1lOiBlbGVtZW50Lm5hbWVXaXRoRXh0ZW5zaW9uLFxyXG4gICAgICAgICAgdHlwZTogZWxlbWVudC5taW1lVHlwZSxcclxuICAgICAgICAgIHJhd0ZpbGU6IDxhbnk+YmFzZTY0XHJcbiAgICAgICAgfTtcclxuICAgICAgICB0aGlzLmZpbGUgPSBlbGVtZW50O1xyXG4gICAgICAgIGxldCBmaWxlID0gdGhpcy5maWxlTGlrZU9iamVjdCBhcyBhbnk7XHJcbiAgICAgICAgZmlsZS51cmwgPSBlbGVtZW50LmZ1bGxGaWxlVVJMO1xyXG4gICAgICAgIHRoaXMudXBsb2FkZXIuYWRkVG9RdWV1ZShbZmlsZV0pO1xyXG4gICAgICAgIGlmICghdGhpcy5vcHRpb25zLnZhbHVlLmZpbGUpIHtcclxuICAgICAgICAgIHRoaXMuZmlsZVVwbG9hZE1vZGVsID0gbmV3IEZpbGVVcGxvYWRNb2RlbCgpO1xyXG4gICAgICAgICAgdGhpcy5maWxlVXBsb2FkTW9kZWwuZmlsZSA9IHRoaXMub3B0aW9ucy52YWx1ZTtcclxuICAgICAgICB9IGVsc2UgdGhpcy5maWxlVXBsb2FkTW9kZWwgPSB0aGlzLm9wdGlvbnMudmFsdWU7XHJcbiAgICAgICAgdGhpcy5vcHRpb25zLnZhbHVlID0gdGhpcy5maWxlVXBsb2FkTW9kZWw7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy51cGxvYWRlci5xdWV1ZS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XHJcbiAgICAgICAgZWxlbWVudC5wcm9ncmVzcyA9IDEwMDtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5sYWJlbEtleSAhPSBudWxsICYmIHRoaXMub3B0aW9ucy5sYWJlbEtleSAhPSAnJylcclxuICAgICAgdGhpcy5vcHRpb25zLmxhYmVsVmFsdWUgPSB0aGlzLlV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUodGhpcy5vcHRpb25zLmxhYmVsS2V5KTtcclxuXHJcbiAgICBpZiAoXHJcbiAgICAgIHRoaXMub3B0aW9ucy5maWxlVXBsb2FkQWNjZXB0c1R5cGVzICE9IG51bGwgJiZcclxuICAgICAgdGhpcy5vcHRpb25zLmZpbGVVcGxvYWRBY2NlcHRzVHlwZXMubGVuZ3RoID4gMFxyXG4gICAgKSB7XHJcbiAgICAgIC8vIFByb2Nlc3MgRmlsZVR5cGUgZW51bSB2YWx1ZXMgd2hpY2ggbWF5IGNvbnRhaW4gY29tbWEtc2VwYXJhdGVkIE1JTUUgdHlwZXNcclxuICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMub3B0aW9ucy5maWxlVXBsb2FkQWNjZXB0c1R5cGVzLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICAgIGNvbnN0IFR5cGUgPSB0aGlzLm9wdGlvbnMuZmlsZVVwbG9hZEFjY2VwdHNUeXBlc1tpbmRleF07XHJcbiAgICAgICAgdGhpcy5hY2NlcHRlZFR5cGUgPSB0aGlzLmFjY2VwdGVkVHlwZSArIFR5cGUgKyAnLCc7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5hY2NlcHRlZFR5cGVBcnJheSA9IHRoaXMuYWNjZXB0ZWRUeXBlLnNwbGl0KCcsJyk7XHJcbiAgICAgIHRoaXMuYWNjZXB0ZWRUeXBlQXJyYXkgPSB0aGlzLmFjY2VwdGVkVHlwZUFycmF5LmZpbHRlcigodmFsdWUpID0+IHZhbHVlLnRyaW0oKSAhPSAnJyk7XHJcblxyXG4gICAgICAvLyBSZWJ1aWxkIGFjY2VwdGVkVHlwZSBzdHJpbmcgZm9yIEhUTUwgYWNjZXB0IGF0dHJpYnV0ZSAocHJvcGVybHkgZm9ybWF0dGVkKVxyXG4gICAgICB0aGlzLmFjY2VwdGVkVHlwZSA9IHRoaXMuYWNjZXB0ZWRUeXBlQXJyYXkuam9pbignLCcpO1xyXG4gICAgICAvLyBQcm9jZXNzIGVhY2ggYWNjZXB0ZWQgTUlNRSB0eXBlIHRvIGJ1aWxkIHRvb2x0aXAgZGlzcGxheSBuYW1lc1xyXG4gICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5hY2NlcHRlZFR5cGVBcnJheS5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5hY2NlcHRlZFR5cGVBcnJheVtpbmRleF0udHJpbSgpO1xyXG4gICAgICAgIHN3aXRjaCAoZWxlbWVudCkge1xyXG4gICAgICAgICAgY2FzZSAnYXBwbGljYXRpb24vcGRmJzpcclxuICAgICAgICAgICAgaWYgKCF0aGlzLnRvb2xUaXBUeXBlQXJyYXkuaW5jbHVkZXMoJ1BERicpKSB0aGlzLnRvb2xUaXBUeXBlQXJyYXkucHVzaCgnUERGJyk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAnYXBwbGljYXRpb24vbXN3b3JkJzpcclxuICAgICAgICAgICAgaWYgKCF0aGlzLnRvb2xUaXBUeXBlQXJyYXkuaW5jbHVkZXMoJ1dvcmQnKSkgdGhpcy50b29sVGlwVHlwZUFycmF5LnB1c2goJ1dvcmQnKTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlICdhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5kb2N1bWVudCc6XHJcbiAgICAgICAgICAgIGlmICghdGhpcy50b29sVGlwVHlwZUFycmF5LmluY2x1ZGVzKCdXb3JkJykpIHRoaXMudG9vbFRpcFR5cGVBcnJheS5wdXNoKCdXb3JkJyk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAnYXBwbGljYXRpb24vdm5kLm1zLWV4Y2VsJzpcclxuICAgICAgICAgICAgaWYgKCF0aGlzLnRvb2xUaXBUeXBlQXJyYXkuaW5jbHVkZXMoJ0V4Y2VsJykpIHRoaXMudG9vbFRpcFR5cGVBcnJheS5wdXNoKCdFeGNlbCcpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0JzpcclxuICAgICAgICAgICAgaWYgKCF0aGlzLnRvb2xUaXBUeXBlQXJyYXkuaW5jbHVkZXMoJ0V4Y2VsJykpIHRoaXMudG9vbFRpcFR5cGVBcnJheS5wdXNoKCdFeGNlbCcpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ2FwcGxpY2F0aW9uL3ZuZC5tcy1wb3dlcnBvaW50JzpcclxuICAgICAgICAgICAgaWYgKCF0aGlzLnRvb2xUaXBUeXBlQXJyYXkuaW5jbHVkZXMoJ1Bvd2VyUG9pbnQnKSlcclxuICAgICAgICAgICAgICB0aGlzLnRvb2xUaXBUeXBlQXJyYXkucHVzaCgnUG93ZXJQb2ludCcpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5wcmVzZW50YXRpb24nOlxyXG4gICAgICAgICAgICBpZiAoIXRoaXMudG9vbFRpcFR5cGVBcnJheS5pbmNsdWRlcygnUG93ZXJQb2ludCcpKVxyXG4gICAgICAgICAgICAgIHRoaXMudG9vbFRpcFR5cGVBcnJheS5wdXNoKCdQb3dlclBvaW50Jyk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAnaW1hZ2UvcG5nJzpcclxuICAgICAgICAgICAgaWYgKCF0aGlzLnRvb2xUaXBUeXBlQXJyYXkuaW5jbHVkZXMoJ1BORycpKSB0aGlzLnRvb2xUaXBUeXBlQXJyYXkucHVzaCgnUE5HJyk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAnaW1hZ2UvYm1wJzpcclxuICAgICAgICAgICAgaWYgKCF0aGlzLnRvb2xUaXBUeXBlQXJyYXkuaW5jbHVkZXMoJ0JNUCcpKSB0aGlzLnRvb2xUaXBUeXBlQXJyYXkucHVzaCgnQk1QJyk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAnaW1hZ2UvanBlZyc6XHJcbiAgICAgICAgICAgIGlmICghdGhpcy50b29sVGlwVHlwZUFycmF5LmluY2x1ZGVzKCdKUEVHJykpIHRoaXMudG9vbFRpcFR5cGVBcnJheS5wdXNoKCdKUEVHJyk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAnYXBwbGljYXRpb24vemlwJzpcclxuICAgICAgICAgICAgaWYgKCF0aGlzLnRvb2xUaXBUeXBlQXJyYXkuaW5jbHVkZXMoJ1pJUCcpKSB0aGlzLnRvb2xUaXBUeXBlQXJyYXkucHVzaCgnWklQJyk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAnYXBwbGljYXRpb24veC1yYXItY29tcHJlc3NlZCc6XHJcbiAgICAgICAgICAgIGlmICghdGhpcy50b29sVGlwVHlwZUFycmF5LmluY2x1ZGVzKCdSQVInKSkgdGhpcy50b29sVGlwVHlwZUFycmF5LnB1c2goJ1JBUicpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ3ZpZGVvL21wNCc6XHJcbiAgICAgICAgICAgIGlmICghdGhpcy50b29sVGlwVHlwZUFycmF5LmluY2x1ZGVzKCdNUDQnKSkgdGhpcy50b29sVGlwVHlwZUFycmF5LnB1c2goJ01QNCcpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ3ZpZGVvL2F2aSc6XHJcbiAgICAgICAgICAgIGlmICghdGhpcy50b29sVGlwVHlwZUFycmF5LmluY2x1ZGVzKCdBVkknKSkgdGhpcy50b29sVGlwVHlwZUFycmF5LnB1c2goJ0FWSScpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ3ZpZGVvL3F1aWNrdGltZSc6XHJcbiAgICAgICAgICAgIGlmICghdGhpcy50b29sVGlwVHlwZUFycmF5LmluY2x1ZGVzKCdNT1YnKSkgdGhpcy50b29sVGlwVHlwZUFycmF5LnB1c2goJ01PVicpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ3ZpZGVvL21wZWcnOlxyXG4gICAgICAgICAgICBpZiAoIXRoaXMudG9vbFRpcFR5cGVBcnJheS5pbmNsdWRlcygnTVBFRycpKSB0aGlzLnRvb2xUaXBUeXBlQXJyYXkucHVzaCgnTVBFRycpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ2F1ZGlvL21wZWcnOlxyXG4gICAgICAgICAgICBpZiAoIXRoaXMudG9vbFRpcFR5cGVBcnJheS5pbmNsdWRlcygnTVAzJykpIHRoaXMudG9vbFRpcFR5cGVBcnJheS5wdXNoKCdNUDMnKTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlICd2aWRlby94LWZsdic6XHJcbiAgICAgICAgICAgIGlmICghdGhpcy50b29sVGlwVHlwZUFycmF5LmluY2x1ZGVzKCdGTFYnKSkgdGhpcy50b29sVGlwVHlwZUFycmF5LnB1c2goJ0ZMVicpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ3ZpZGVvL3gtbXMtd212JzpcclxuICAgICAgICAgICAgaWYgKCF0aGlzLnRvb2xUaXBUeXBlQXJyYXkuaW5jbHVkZXMoJ1dNVicpKSB0aGlzLnRvb2xUaXBUeXBlQXJyYXkucHVzaCgnV01WJyk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAnaW1hZ2Uvc3ZnK3htbCc6XHJcbiAgICAgICAgICAgIGlmICghdGhpcy50b29sVGlwVHlwZUFycmF5LmluY2x1ZGVzKCdTVkcnKSkgdGhpcy50b29sVGlwVHlwZUFycmF5LnB1c2goJ1NWRycpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ3RleHQvcGxhaW4nOlxyXG4gICAgICAgICAgICBpZiAoIXRoaXMudG9vbFRpcFR5cGVBcnJheS5pbmNsdWRlcygnVHh0JykpIHRoaXMudG9vbFRpcFR5cGVBcnJheS5wdXNoKCdUeHQnKTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlICdhcHBsaWNhdGlvbi9CTic6XHJcbiAgICAgICAgICAgIGlmICghdGhpcy50b29sVGlwVHlwZUFycmF5LmluY2x1ZGVzKCdMaWNlbnNlJykpIHRoaXMudG9vbFRpcFR5cGVBcnJheS5wdXNoKCdMaWNlbnNlJyk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIHRoaXMudmFsaWRhdGlvbk1lc3NhZ2UgPSB0aGlzLnZhbGlkYXRpb25NZXNzYWdlICsgYCR7dGhpcy5VdGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKCdFeHRlbnNpb25zJyl9ICgke3RoaXMudG9vbFRpcFR5cGVBcnJheX0pIGA7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5maWxlTWF4U2l6ZUluTUIgPiAwKSB7XHJcbiAgICAgIHRoaXMudmFsaWRhdGlvbk1lc3NhZ2UgPSB0aGlzLnZhbGlkYXRpb25NZXNzYWdlICsgYDxiciAvPiAgJHt0aGlzLlV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ0ZpbGVNYXhTaXplSW5NQicpICsgdGhpcy5vcHRpb25zLmZpbGVNYXhTaXplSW5NQiArICcgJyArIHRoaXMuVXRpbGl0eVNlcnZpY2UuZ2V0UmVzb3VyY2VWYWx1ZSgnTUInKX1gO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMubWluTm9PZkZpbGVzID4gMCkge1xyXG4gICAgICB0aGlzLnZhbGlkYXRpb25NZXNzYWdlID0gdGhpcy52YWxpZGF0aW9uTWVzc2FnZSArIGA8YnIgLz4gJHt0aGlzLlV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ01pbkZpbGVDb3VudFZhbGlkYXRpb25LZXknKSArIHRoaXMub3B0aW9ucy5taW5Ob09mRmlsZXN9YDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5vcHRpb25zLm1heE5vT2ZGaWxlcyA+IDApIHtcclxuICAgICAgdGhpcy52YWxpZGF0aW9uTWVzc2FnZSA9IHRoaXMudmFsaWRhdGlvbk1lc3NhZ2UgKyBgPGJyIC8+ICR7dGhpcy5VdGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKCdNYXhGaWxlQ291bnRWYWxpZGF0aW9uS2V5JykgKyB0aGlzLm9wdGlvbnMubWF4Tm9PZkZpbGVzfWA7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5ncm91cC5hZGRDb250cm9sKHRoaXMub3B0aW9ucy5uYW1lLCBuZXcgRm9ybUNvbnRyb2woJycpKTtcclxuICAgIHRoaXMuZmlsZVVwbG9hZEZvcm1Db250cm9sID0gdGhpcy5ncm91cC5jb250cm9sc1t0aGlzLm9wdGlvbnMubmFtZV07XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5jdXN0b21WYWxpZGF0aW9uLmxlbmd0aCA+IDApIHtcclxuICAgICAgbGV0IFZhbGlkYXRpb25zID0gdGhpcy5vcHRpb25zLmN1c3RvbVZhbGlkYXRpb247XHJcbiAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBWYWxpZGF0aW9ucy5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICBjb25zdCBWYWxpZGF0aW9uID0gVmFsaWRhdGlvbnNbaW5kZXhdO1xyXG4gICAgICAgIHRoaXMudmFsaWRhdGlvblJ1bGVzLnB1c2goVmFsaWRhdGlvbi5mdW5jdGlvbkJvZHkpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pc011bHRpcGxlRmlsZSAmJiB0aGlzLm9wdGlvbnMubWF4Tm9PZkZpbGVzID4gMCkge1xyXG4gICAgICB0aGlzLnZhbGlkYXRpb25Db3VudE1lc3NhZ2UgPSBgJHt0aGlzLlV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ01heEZpbGVzQ291bnQnKX0gOiAke3RoaXMub3B0aW9ucy5tYXhOb09mRmlsZXN9YDtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuaXNSZXF1aXJlZCkge1xyXG4gICAgICB0aGlzLnZhbGlkYXRpb25SdWxlcy5wdXNoKFZhbGlkYXRvcnMucmVxdWlyZWQpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuZmlsZVVwbG9hZEZvcm1Db250cm9sLnNldFZhbGlkYXRvcnModGhpcy52YWxpZGF0aW9uUnVsZXMpO1xyXG4gICAgdGhpcy5maWxlVXBsb2FkRm9ybUNvbnRyb2wuc2V0QXN5bmNWYWxpZGF0b3JzKHRoaXMudmFsaWRhdGlvblJ1bGVzQXN5bmMpO1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pc0Rpc2FibGVkKSB7XHJcbiAgICAgIHRoaXMuZmlsZVVwbG9hZEZvcm1Db250cm9sLmRpc2FibGUoKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLk11bHRpcGxlRmlsZVVwbG9hZENvbnRyb2xIb3N0Lm5nU3VibWl0XHJcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcclxuICAgICAgLnN1YnNjcmliZSgodmFsdWUpID0+IHtcclxuICAgICAgICB0aGlzLmdyb3VwLm1hcmtBbGxBc1RvdWNoZWQoKTtcclxuICAgICAgICB0aGlzLm1hcmtBbGxBc1RvdWNoZWQgPSB0cnVlO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICB0aGlzLmZpbGVVcGxvYWRGb3JtQ29udHJvbC5zZXRWYWx1ZSh0aGlzLm9wdGlvbnMudmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5hdHRyaWJ1dGVMaXN0ICE9IG51bGwpIHtcclxuICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLm9wdGlvbnMubmFtZSk7XHJcbiAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLm9wdGlvbnMuYXR0cmlidXRlTGlzdC5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShcclxuICAgICAgICAgIHRoaXMub3B0aW9ucy5hdHRyaWJ1dGVMaXN0W2luZGV4XS5rZXksXHJcbiAgICAgICAgICB0aGlzLm9wdGlvbnMuYXR0cmlidXRlTGlzdFtpbmRleF0udmFsdWVcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXNldEVycm9yID0gKCkgPT4ge1xyXG4gICAgdGhpcy5jb250cm9sVmFsaWRhdGlvblNlcnZpY2UucmVtb3ZlR2xvYmFsRXJyb3IoKTtcclxuICB9O1xyXG5cclxuICBzaG93R2xvYmFsRXJyb3IoKSB7XHJcbiAgICB0aGlzLmNvbnRyb2xVdGlsaXR5LnNob3dHbG9iYWxFcnJvcigpO1xyXG4gIH1cclxuXHJcbiAgZ2V0RXJyb3JWYWxpZGF0aW9uKEVycm9yTGlzdCkge1xyXG4gICAgaWYgKHRoaXMubWFya0FsbEFzVG91Y2hlZCAmJiB0aGlzLmdyb3VwLmludmFsaWQpIHtcclxuICAgICAgdGhpcy5zaG93R2xvYmFsRXJyb3IoKTtcclxuICAgICAgdGhpcy5tYXJrQWxsQXNUb3VjaGVkID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuY29udHJvbFV0aWxpdHkuZ2V0RXJyb3JWYWxpZGF0aW9uTWFzc2FnZShFcnJvckxpc3QsIHRoaXMuZ3JvdXAsIHRoaXMub3B0aW9ucyk7XHJcbiAgfVxyXG5cclxuICBmaWxlT3ZlckFub3RoZXIoZXZlbnQ6IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5oYXNBbm90aGVyRHJvcFpvbmVPdmVyID0gZXZlbnQ7XHJcbiAgfVxyXG5cclxuICBpc0hpZGVJbnB1dCgpIHtcclxuICAgIGlmICh0aGlzLm9wdGlvbnMuaXNNdWx0aXBsZUZpbGUpIHtcclxuICAgICAgaWYgKFxyXG4gICAgICAgIHRoaXMub3B0aW9ucy5tYXhOb09mRmlsZXMgIT0gbnVsbCAmJlxyXG4gICAgICAgIHRoaXMub3B0aW9ucy5tYXhOb09mRmlsZXMgPiAwICYmXHJcbiAgICAgICAgdGhpcy5vcHRpb25zLm1heE5vT2ZGaWxlcyA9PSB0aGlzLnVwbG9hZGVyLnF1ZXVlLmxlbmd0aFxyXG4gICAgICApIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKHRoaXMudXBsb2FkZXIucXVldWUubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG5cclxuICBvbkZpbGVDaGFuZ2UoKSB7XHJcbiAgICBsZXQgRmlsZXNBcnJheTogRmlsZURUT1tdID0gW107XHJcbiAgICAvLyBDbGVhciBhbnkgcHJldmlvdXMgdmFsaWRhdGlvbiBlcnJvcnMgYXQgdGhlIHN0YXJ0IG9mIGZpbGUgY2hhbmdlXHJcbiAgICB0aGlzLnBlbmRpbmdWYWxpZGF0aW9uRXJyb3JzID0gbnVsbDtcclxuXHJcbiAgICAvLyBDaGVjayBmb3IgZHVwbGljYXRlIGZpbGUgbmFtZXMgaW4gdGhlIHF1ZXVlXHJcbiAgICBjb25zdCBkdXBsaWNhdGVGaWxlcyA9IHRoaXMuZmluZER1cGxpY2F0ZUZpbGVzKCk7XHJcbiAgICBpZiAoZHVwbGljYXRlRmlsZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAvLyBSZW1vdmUgb25seSB0aGUgbmV3bHkgYWRkZWQgZHVwbGljYXRlIGZpbGVzIGZyb20gcXVldWUgKGtlZXAgZXhpc3RpbmcgZmlsZXMpXHJcbiAgICAgIHRoaXMucmVtb3ZlRHVwbGljYXRlRmlsZXNGcm9tUXVldWUoZHVwbGljYXRlRmlsZXMpO1xyXG5cclxuICAgICAgLy8gU2V0IHZhbGlkYXRpb24gZXJyb3IgZm9yIGR1cGxpY2F0ZSBmaWxlc1xyXG4gICAgICBjb25zdCBkdXBsaWNhdGVGaWxlTmFtZXMgPSBkdXBsaWNhdGVGaWxlcy5tYXAoZiA9PiBmLmZpbGU/Lm5hbWUpLmpvaW4oJywgJyk7XHJcbiAgICAgIGNvbnN0IGZvcm1Db250cm9sID0gdGhpcy5maWxlVXBsb2FkRm9ybUNvbnRyb2w7XHJcbiAgICAgIGNvbnN0IHJlc291cmNlVmFsdWUgPSB0aGlzLlV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ0R1cGxpY2F0ZUZpbGVFcnJvcicpO1xyXG4gICAgICAvLyBJZiByZXNvdXJjZSB2YWx1ZSBpcyB0aGUgc2FtZSBhcyB0aGUga2V5LCBpdCBtZWFucyB0aGUgcmVzb3VyY2Ugd2Fzbid0IGZvdW5kXHJcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IChyZXNvdXJjZVZhbHVlICYmIHJlc291cmNlVmFsdWUgIT09ICdEdXBsaWNhdGVGaWxlRXJyb3InKSA/IHJlc291cmNlVmFsdWUgOiAnRmlsZShzKSBhbHJlYWR5IGV4aXN0JztcclxuICAgICAgY29uc3QgZXJyb3JPYmogPSB7XHJcbiAgICAgICAgRHVwbGljYXRlRmlsZUVycm9yOiBgJHtlcnJvck1lc3NhZ2V9OiAke2R1cGxpY2F0ZUZpbGVOYW1lc31gXHJcbiAgICAgIH07XHJcbiAgICAgIHRoaXMucGVuZGluZ1ZhbGlkYXRpb25FcnJvcnMgPSBlcnJvck9iajtcclxuICAgICAgZm9ybUNvbnRyb2wuc2V0RXJyb3JzKGVycm9yT2JqKTtcclxuICAgICAgZm9ybUNvbnRyb2wubWFya0FzVG91Y2hlZCgpO1xyXG5cclxuICAgICAgLy8gQXV0by1jbGVhciBkdXBsaWNhdGUgZXJyb3IgYWZ0ZXIgNSBzZWNvbmRzIHRvIGFsbG93IGZvcm0gc3VibWlzc2lvblxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAvLyBPbmx5IGNsZWFyIGlmIHRoZSBjdXJyZW50IGVycm9yIGlzIHN0aWxsIHRoZSBkdXBsaWNhdGUgZXJyb3Igd2Ugc2V0XHJcbiAgICAgICAgY29uc3QgY3VycmVudEVycm9ycyA9IGZvcm1Db250cm9sLmVycm9ycztcclxuICAgICAgICBpZiAoY3VycmVudEVycm9ycyAmJiBjdXJyZW50RXJyb3JzLkR1cGxpY2F0ZUZpbGVFcnJvciA9PT0gZXJyb3JPYmouRHVwbGljYXRlRmlsZUVycm9yKSB7XHJcbiAgICAgICAgICBmb3JtQ29udHJvbC5zZXRFcnJvcnMobnVsbCk7XHJcbiAgICAgICAgICB0aGlzLnBlbmRpbmdWYWxpZGF0aW9uRXJyb3JzID0gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgIH0sIDUwMDApO1xyXG5cclxuICAgICAgLy8gSWYgYWxsIGZpbGVzIHdlcmUgZHVwbGljYXRlcywgcmV0dXJuIGVhcmx5XHJcbiAgICAgIGlmICh0aGlzLnVwbG9hZGVyLnF1ZXVlLmZpbHRlcihpdGVtID0+IGl0ZW1bJ3NvbWUnXS5sYXN0TW9kaWZpZWQgIT0gbnVsbCkubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmlzTXVsdGlwbGVGaWxlICYmIHRoaXMub3B0aW9ucy5taW5Ob09mRmlsZXMgIT0gbnVsbCAmJiB0aGlzLm9wdGlvbnMubWluTm9PZkZpbGVzID4gMCAmJiB0aGlzLm9wdGlvbnMubWluTm9PZkZpbGVzID4gdGhpcy51cGxvYWRlci5xdWV1ZS5sZW5ndGgpIHtcclxuICAgICAgY29uc3QgZm9ybUNvbnRyb2wgPSB0aGlzLmZpbGVVcGxvYWRGb3JtQ29udHJvbDtcclxuICAgICAgY29uc3QgZXhpc3RpbmdFcnJvcnMgPSBmb3JtQ29udHJvbC5lcnJvcnMgfHwge307XHJcbiAgICAgIGNvbnN0IG5ld0Vycm9ycyA9IHtcclxuICAgICAgICAuLi5leGlzdGluZ0Vycm9ycyxcclxuICAgICAgICBNaW5GaWxlQ291bnRWYWxpZGF0aW9uS2V5OiB0aGlzLm9wdGlvbnMubWluTm9PZkZpbGVzXHJcbiAgICAgIH07XHJcbiAgICAgIGZvcm1Db250cm9sLnNldEVycm9ycyhuZXdFcnJvcnMpO1xyXG4gICAgICBmb3JtQ29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XHJcbiAgICAgIHRoaXMudXBsb2FkZXIucXVldWUgPSBbXTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuaXNNdWx0aXBsZUZpbGUgJiYgdGhpcy5vcHRpb25zLm1heE5vT2ZGaWxlcyAhPSBudWxsICYmIHRoaXMub3B0aW9ucy5tYXhOb09mRmlsZXMgPiAwICYmIHRoaXMub3B0aW9ucy5tYXhOb09mRmlsZXMgPCB0aGlzLnVwbG9hZGVyLnF1ZXVlLmxlbmd0aCkge1xyXG4gICAgICBjb25zdCBmb3JtQ29udHJvbCA9IHRoaXMuZmlsZVVwbG9hZEZvcm1Db250cm9sO1xyXG4gICAgICBjb25zdCBleGlzdGluZ0Vycm9ycyA9IGZvcm1Db250cm9sLmVycm9ycyB8fCB7fTtcclxuICAgICAgY29uc3QgbmV3RXJyb3JzID0ge1xyXG4gICAgICAgIC4uLmV4aXN0aW5nRXJyb3JzLFxyXG4gICAgICAgIE1heEZpbGVDb3VudFZhbGlkYXRpb25LZXk6IHRoaXMub3B0aW9ucy5tYXhOb09mRmlsZXNcclxuICAgICAgfTtcclxuICAgICAgZm9ybUNvbnRyb2wuc2V0RXJyb3JzKG5ld0Vycm9ycyk7XHJcbiAgICAgIGZvcm1Db250cm9sLm1hcmtBc1RvdWNoZWQoKTtcclxuICAgICAgdGhpcy51cGxvYWRlci5xdWV1ZSA9IFtdO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuaXNNdWx0aXBsZUZpbGUgJiYgdGhpcy5vcHRpb25zLm1heFNpemVGb3JBbGxGaWxlc0luTUIgIT0gbnVsbCAmJiB0aGlzLm9wdGlvbnMubWF4U2l6ZUZvckFsbEZpbGVzSW5NQiA+IDApIHtcclxuICAgICAgbGV0IEFsbFNpemVGaWxlID0gMDtcclxuICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMudXBsb2FkZXIucXVldWUubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMudXBsb2FkZXIucXVldWVbaW5kZXhdO1xyXG4gICAgICAgIGNvbnN0IGZpbGUgPSBlbGVtZW50LmZpbGU7XHJcbiAgICAgICAgQWxsU2l6ZUZpbGUgPSBBbGxTaXplRmlsZSArIGZpbGUuc2l6ZTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBNYXhTaXplRm9yQWxsRmlsZXMgPSB0aGlzLm9wdGlvbnMubWF4U2l6ZUZvckFsbEZpbGVzSW5NQiAqIDEwMDAgKiAxMDAwO1xyXG4gICAgICBpZiAoQWxsU2l6ZUZpbGUgPiBNYXhTaXplRm9yQWxsRmlsZXMpIHtcclxuICAgICAgICBjb25zdCBmb3JtQ29udHJvbCA9IHRoaXMuZmlsZVVwbG9hZEZvcm1Db250cm9sO1xyXG4gICAgICAgIGNvbnN0IGV4aXN0aW5nRXJyb3JzID0gZm9ybUNvbnRyb2wuZXJyb3JzIHx8IHt9O1xyXG4gICAgICAgIGNvbnN0IG5ld0Vycm9ycyA9IHtcclxuICAgICAgICAgIC4uLmV4aXN0aW5nRXJyb3JzLFxyXG4gICAgICAgICAgTWF4U2l6ZUZvckFsbEZpbGVzSW5NQjogdGhpcy5vcHRpb25zLm1heFNpemVGb3JBbGxGaWxlc0luTUIgKyAnICcgKyB0aGlzLlV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ01CJylcclxuICAgICAgICB9O1xyXG4gICAgICAgIGZvcm1Db250cm9sLnNldEVycm9ycyhuZXdFcnJvcnMpO1xyXG4gICAgICAgIGZvcm1Db250cm9sLm1hcmtBc1RvdWNoZWQoKTtcclxuICAgICAgICB0aGlzLnVwbG9hZGVyLnF1ZXVlID0gW107XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5pc011bHRpcGxlRmlsZSAmJiB0aGlzLnVwbG9hZGVyLnF1ZXVlLmxlbmd0aCA+IDEpIHtcclxuICAgICAgY29uc3QgZm9ybUNvbnRyb2wgPSB0aGlzLmZpbGVVcGxvYWRGb3JtQ29udHJvbDtcclxuICAgICAgY29uc3QgbmV3RXJyb3JzID0ge1xyXG4gICAgICAgIE1heEZpbGVDb3VudFZhbGlkYXRpb25LZXk6IDFcclxuICAgICAgfTtcclxuICAgICAgZm9ybUNvbnRyb2wuc2V0RXJyb3JzKG5ld0Vycm9ycyk7XHJcbiAgICAgIGZvcm1Db250cm9sLm1hcmtBc1RvdWNoZWQoKTtcclxuICAgICAgdGhpcy51cGxvYWRlci5xdWV1ZSA9IFtdO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBsZXQgQWRkZWRRdWV1ZSA9IHRoaXMudXBsb2FkZXIucXVldWUuZmlsdGVyKChvYmopID0+IG9ialsnc29tZSddLmxhc3RNb2RpZmllZCAhPSBudWxsKTtcclxuICAgIGxldCBoYXNWYWxpZGF0aW9uRXJyb3IgPSBmYWxzZTtcclxuICAgIGxldCB2YWxpZGF0aW9uRXJyb3JUeXBlID0gJyc7XHJcbiAgICBsZXQgdmFsaWRhdGlvbkVycm9yVmFsdWU6IGFueSA9ICcnO1xyXG5cclxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBBZGRlZFF1ZXVlLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICBjb25zdCBlbGVtZW50ID0gQWRkZWRRdWV1ZVtpbmRleF07XHJcbiAgICAgIGNvbnN0IGZpbGUgPSBlbGVtZW50LmZpbGU7XHJcbiAgICAgIGNvbnN0IG1heEZpbGVTaXplID0gdGhpcy5vcHRpb25zLmZpbGVNYXhTaXplSW5NQiAqIDEwMDAgKiAxMDAwO1xyXG4gICAgICBpZiAoZmlsZSkge1xyXG4gICAgICAgIGNvbnN0IGZpbGVUeXBlID0gZmlsZS50eXBlO1xyXG4gICAgICAgIGlmIChmaWxlLnNpemUgPiBtYXhGaWxlU2l6ZSkge1xyXG4gICAgICAgICAgLy8gUmVtb3ZlIG9ubHkgdGhlIGZpbGUgdGhhdCB2aW9sYXRlcyB0aGUgc2l6ZSBsaW1pdFxyXG4gICAgICAgICAgdGhpcy51cGxvYWRlci5xdWV1ZSA9IHRoaXMudXBsb2FkZXIucXVldWUuZmlsdGVyKHF1ZXVlSXRlbSA9PlxyXG4gICAgICAgICAgICBxdWV1ZUl0ZW0uZmlsZS5uYW1lICE9PSBmaWxlLm5hbWVcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICBoYXNWYWxpZGF0aW9uRXJyb3IgPSB0cnVlO1xyXG4gICAgICAgICAgdmFsaWRhdGlvbkVycm9yVHlwZSA9ICdGaWxlTWF4U2l6ZUluTUInO1xyXG4gICAgICAgICAgdmFsaWRhdGlvbkVycm9yVmFsdWUgPSB0aGlzLm9wdGlvbnMuZmlsZU1heFNpemVJbk1CICsgJyAnICsgdGhpcy5VdGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKCdNQicpO1xyXG4gICAgICAgICAgLy8gQ29udGludWUgY2hlY2tpbmcgb3RoZXIgZmlsZXMgaW5zdGVhZCBvZiByZXR1cm5pbmcgaW1tZWRpYXRlbHlcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgdGhpcy5vcHRpb25zLmZpbGVVcGxvYWRBY2NlcHRzVHlwZXMgIT0gbnVsbCAmJlxyXG4gICAgICAgICAgdGhpcy5vcHRpb25zLmZpbGVVcGxvYWRBY2NlcHRzVHlwZXMubGVuZ3RoID4gMCAmJlxyXG4gICAgICAgICAgIXRoaXMuaXNGaWxlVHlwZUFjY2VwdGVkKGZpbGVUeXBlKVxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgLy8gUmVtb3ZlIG9ubHkgdGhlIGZpbGUgdGhhdCB2aW9sYXRlcyB0aGUgZmlsZSB0eXBlIHJlc3RyaWN0aW9uXHJcbiAgICAgICAgICB0aGlzLnVwbG9hZGVyLnF1ZXVlID0gdGhpcy51cGxvYWRlci5xdWV1ZS5maWx0ZXIocXVldWVJdGVtID0+XHJcbiAgICAgICAgICAgIHF1ZXVlSXRlbS5maWxlLm5hbWUgIT09IGZpbGUubmFtZVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIGhhc1ZhbGlkYXRpb25FcnJvciA9IHRydWU7XHJcbiAgICAgICAgICB2YWxpZGF0aW9uRXJyb3JUeXBlID0gJ1Rvb2xUaXBUeXBlRXJyb3InO1xyXG4gICAgICAgICAgdmFsaWRhdGlvbkVycm9yVmFsdWUgPSB0aGlzLnRvb2xUaXBUeXBlQXJyYXk7XHJcbiAgICAgICAgICAvLyBDb250aW51ZSBjaGVja2luZyBvdGhlciBmaWxlcyBpbnN0ZWFkIG9mIHJldHVybmluZyBpbW1lZGlhdGVseVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIFNldCB2YWxpZGF0aW9uIGVycm9yIGlmIGFueSBmaWxlcyB3ZXJlIHJlbW92ZWQgZHVlIHRvIHZhbGlkYXRpb24gZmFpbHVyZXNcclxuICAgIHRoaXMucGVuZGluZ1ZhbGlkYXRpb25FcnJvcnMgPSBudWxsO1xyXG4gICAgaWYgKGhhc1ZhbGlkYXRpb25FcnJvcikge1xyXG4gICAgICBjb25zdCBmb3JtQ29udHJvbCA9IHRoaXMuZmlsZVVwbG9hZEZvcm1Db250cm9sO1xyXG4gICAgICBjb25zdCBlcnJvck9iaiA9IHt9O1xyXG4gICAgICBlcnJvck9ialt2YWxpZGF0aW9uRXJyb3JUeXBlXSA9IHZhbGlkYXRpb25FcnJvclZhbHVlO1xyXG4gICAgICB0aGlzLnBlbmRpbmdWYWxpZGF0aW9uRXJyb3JzID0gZXJyb3JPYmo7IC8vIFN0b3JlIGVycm9ycyB0byByZWFwcGx5IGxhdGVyXHJcbiAgICAgIGZvcm1Db250cm9sLnNldEVycm9ycyhlcnJvck9iaik7XHJcbiAgICAgIGZvcm1Db250cm9sLm1hcmtBc1RvdWNoZWQoKTtcclxuXHJcbiAgICAgIC8vIEF1dG8tY2xlYXIgRmlsZU1heFNpemVJbk1CIGVycm9yIGFmdGVyIDUgc2Vjb25kcyAoc2ltaWxhciB0byBEdXBsaWNhdGVGaWxlRXJyb3IpXHJcbiAgICAgIGlmICh2YWxpZGF0aW9uRXJyb3JUeXBlID09PSAnRmlsZU1heFNpemVJbk1CJykge1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgLy8gT25seSBjbGVhciBpZiB0aGUgY3VycmVudCBlcnJvciBpcyBzdGlsbCB0aGUgRmlsZU1heFNpemVJbk1CIGVycm9yIHdlIHNldFxyXG4gICAgICAgICAgY29uc3QgY3VycmVudEVycm9ycyA9IGZvcm1Db250cm9sLmVycm9ycztcclxuICAgICAgICAgIGlmIChjdXJyZW50RXJyb3JzICYmIGN1cnJlbnRFcnJvcnNbJ0ZpbGVNYXhTaXplSW5NQiddID09PSBlcnJvck9ialsnRmlsZU1heFNpemVJbk1CJ10pIHtcclxuICAgICAgICAgICAgZm9ybUNvbnRyb2wuc2V0RXJyb3JzKG51bGwpO1xyXG4gICAgICAgICAgICB0aGlzLnBlbmRpbmdWYWxpZGF0aW9uRXJyb3JzID0gbnVsbDtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LCA1MDAwKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gRG9uJ3QgcmV0dXJuIGhlcmUsIGNvbnRpbnVlIHByb2Nlc3NpbmcgdmFsaWQgZmlsZXNcclxuICAgIH1cclxuXHJcbiAgICAvLyBSZS1maWx0ZXIgdGhlIHF1ZXVlIHRvIGdldCBvbmx5IHZhbGlkIGZpbGVzIGZvciBwcm9jZXNzaW5nXHJcbiAgICBBZGRlZFF1ZXVlID0gdGhpcy51cGxvYWRlci5xdWV1ZS5maWx0ZXIoKG9iaikgPT4gb2JqWydzb21lJ10ubGFzdE1vZGlmaWVkICE9IG51bGwpO1xyXG5cclxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBBZGRlZFF1ZXVlLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICBjb25zdCBlbGVtZW50ID0gQWRkZWRRdWV1ZVtpbmRleF07XHJcbiAgICAgIGNvbnN0IGZpbGUgPSBlbGVtZW50LmZpbGU7XHJcbiAgICAgIGlmIChmaWxlKSB7XHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5pc1VwbG9hZEZpbGVBc3luYyAmJiAhZWxlbWVudC5fZmlsZVsnaURfR1VJRCddKSB7XHJcbiAgICAgICAgICB0aGlzLmZpbGVVcGxvYWRTZXJ2aWNlLnVwbG9hZEZpbGUoZWxlbWVudC5fZmlsZSlcclxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKHtcclxuICAgICAgICAgICAgICBuZXh0OiAoZXZlbnQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgbGV0IHF1ZXVlSW5kZXggPSB0aGlzLnVwbG9hZGVyLnF1ZXVlLmZpbmRJbmRleCgoZmlsZSkgPT4gZmlsZSA9PSBlbGVtZW50KTtcclxuICAgICAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSBIdHRwRXZlbnRUeXBlLlVwbG9hZFByb2dyZXNzKSB7XHJcbiAgICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IE1hdGgucm91bmQoKDEwMCAqIGV2ZW50LmxvYWRlZCkgLyBldmVudC50b3RhbCk7XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkZXIucXVldWVbcXVldWVJbmRleF0ucHJvZ3Jlc3MgPSB2YWx1ZSA+PSA5NSA/IDk1IDogdmFsdWU7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IEh0dHBFdmVudFR5cGUuUmVzcG9uc2UpIHtcclxuICAgICAgICAgICAgICAgICAgdGhpcy51cGxvYWRlci5xdWV1ZVtxdWV1ZUluZGV4XS5wcm9ncmVzcyA9IDEwMDtcclxuICAgICAgICAgICAgICAgICAgbGV0IGZpbGVJRCA9IGV2ZW50LmJvZHkudmFsIGFzIGFueTtcclxuICAgICAgICAgICAgICAgICAgdGhpcy51cGxvYWRlci5xdWV1ZVtxdWV1ZUluZGV4XS5fZmlsZVsnaURfR1VJRCddID0gZmlsZUlEO1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLnVwbG9hZGVyLnF1ZXVlW3F1ZXVlSW5kZXhdLl9maWxlWydpc05ldyddID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgbGV0IEFkZGVkRmlsZSA9IDxGaWxlRFRPPntcclxuICAgICAgICAgICAgICAgICAgICBpRF9HVUlEOiBmaWxlSUQsXHJcbiAgICAgICAgICAgICAgICAgICAgZmlsZU5hbWU6IHRoaXMudXBsb2FkZXIucXVldWVbcXVldWVJbmRleF0uX2ZpbGVbJ25hbWUnXSxcclxuICAgICAgICAgICAgICAgICAgICBmaWxlVHlwZTogdGhpcy51cGxvYWRlci5xdWV1ZVtxdWV1ZUluZGV4XS5fZmlsZVsndHlwZSddLFxyXG4gICAgICAgICAgICAgICAgICAgIGlzTmV3OiB0cnVlXHJcbiAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuaXNNdWx0aXBsZUZpbGUgPT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbGVVcGxvYWRNb2RlbCA9IG5ldyBGaWxlVXBsb2FkTW9kZWwoKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbGVVcGxvYWRNb2RlbC5maWxlID0gQWRkZWRGaWxlO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0VmFsdWVQcmVzZXJ2aW5nRXJyb3JzKHRoaXMuZmlsZVVwbG9hZE1vZGVsLCB0aGlzLnBlbmRpbmdWYWxpZGF0aW9uRXJyb3JzKTtcclxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBGaWxlc0FycmF5LnB1c2goQWRkZWRGaWxlKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm11bHRpcGxlRmlsZVVwbG9hZE1vZGVsLnVwbG9hZGVkRmlsZXMgPSBGaWxlc0FycmF5O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMudmFsdWUgIT0gbnVsbCAmJiB0aGlzLm9wdGlvbnMudmFsdWUgIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnZhbHVlLmNvcnJlbGF0aW9uSURfR1VJRCA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubXVsdGlwbGVGaWxlVXBsb2FkTW9kZWwucmVtb3ZlZEZpbGVzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubXVsdGlwbGVGaWxlVXBsb2FkTW9kZWwuY29ycmVsYXRpb25JRF9HVUlEID1cclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy52YWx1ZT8uY29ycmVsYXRpb25JRF9HVUlEO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0VmFsdWVQcmVzZXJ2aW5nRXJyb3JzKHRoaXMubXVsdGlwbGVGaWxlVXBsb2FkTW9kZWwsIHRoaXMucGVuZGluZ1ZhbGlkYXRpb25FcnJvcnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNVcGxvYWRDb21wbGV0ZS5lbWl0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgbGV0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICAgICAgICBsZXQgZmlsZU9iamVjdCA9IGZpbGUucmF3RmlsZSBhcyBhbnk7XHJcbiAgICAgICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlT2JqZWN0KTtcclxuICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgIGxldCBleGlzdGluZ0lEX0dVSUQgPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuaXNNdWx0aXBsZUZpbGUgJiYgdGhpcy5maWxlKVxyXG4gICAgICAgICAgICAgIGV4aXN0aW5nSURfR1VJRCA9IHRoaXMuZmlsZS5OYW1lV2l0aEV4dGVuc2lvbiA9PSBmaWxlLm5hbWUgPyB0aGlzLmZpbGUuaURfR1VJRCA6IG51bGw7XHJcblxyXG4gICAgICAgICAgICBsZXQgQWRkZWRGaWxlOiBGaWxlRFRPID0ge1xyXG4gICAgICAgICAgICAgIGZpbGVOYW1lOiBmaWxlLm5hbWUsXHJcbiAgICAgICAgICAgICAgZmlsZVR5cGU6IGZpbGUudHlwZSxcclxuICAgICAgICAgICAgICBmaWxlQmFzZTY0OiByZWFkZXIucmVzdWx0LnRvU3RyaW5nKCkuc3BsaXQoJywnKVsxXSxcclxuICAgICAgICAgICAgICBmaWxlU2l6ZUluTUI6IGZpbGUuc2l6ZSAvIDEwMDAgLyAxMDAwLFxyXG4gICAgICAgICAgICAgIG5hbWVXaXRoRXh0ZW5zaW9uOiBmaWxlLm5hbWUsXHJcbiAgICAgICAgICAgICAgaURfR1VJRDogZXhpc3RpbmdJRF9HVUlELFxyXG4gICAgICAgICAgICAgIGlzTmV3OiB0cnVlXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmlzTXVsdGlwbGVGaWxlID09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5maWxlVXBsb2FkTW9kZWwgPSBuZXcgRmlsZVVwbG9hZE1vZGVsKCk7XHJcbiAgICAgICAgICAgICAgdGhpcy5maWxlVXBsb2FkTW9kZWwuZmlsZSA9IEFkZGVkRmlsZTtcclxuICAgICAgICAgICAgICB0aGlzLnNldFZhbHVlUHJlc2VydmluZ0Vycm9ycyh0aGlzLmZpbGVVcGxvYWRNb2RlbCwgdGhpcy5wZW5kaW5nVmFsaWRhdGlvbkVycm9ycyk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgRmlsZXNBcnJheS5wdXNoKEFkZGVkRmlsZSk7XHJcbiAgICAgICAgICAgICAgdGhpcy5tdWx0aXBsZUZpbGVVcGxvYWRNb2RlbC51cGxvYWRlZEZpbGVzID0gRmlsZXNBcnJheTtcclxuICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnZhbHVlICE9IG51bGwgJiYgdGhpcy5vcHRpb25zLnZhbHVlICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy52YWx1ZS5jb3JyZWxhdGlvbklEX0dVSUQgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLm11bHRpcGxlRmlsZVVwbG9hZE1vZGVsLnJlbW92ZWRGaWxlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB0aGlzLm11bHRpcGxlRmlsZVVwbG9hZE1vZGVsLmNvcnJlbGF0aW9uSURfR1VJRCA9XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMudmFsdWU/LmNvcnJlbGF0aW9uSURfR1VJRDtcclxuICAgICAgICAgICAgICB0aGlzLnNldFZhbHVlUHJlc2VydmluZ0Vycm9ycyh0aGlzLm11bHRpcGxlRmlsZVVwbG9hZE1vZGVsLCB0aGlzLnBlbmRpbmdWYWxpZGF0aW9uRXJyb3JzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfTtcclxuICAgICAgICAgIGxldCBvcmlnaW5hbFZhbHVlID0gdGhpcy5ncm91cC5nZXQodGhpcy5vcHRpb25zLm5hbWUpLnZhbHVlO1xyXG4gICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMucGF0Y2hGdW5jdGlvbiAmJlxyXG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMucGF0Y2hQYXRoICYmXHJcbiAgICAgICAgICAgIHRoaXMuZ3JvdXAuZ2V0KHRoaXMub3B0aW9ucy5uYW1lKS52YWxpZFxyXG4gICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29udHJvbFV0aWxpdHkucGF0Y2hDb250cm9sVmFsdWUoXHJcbiAgICAgICAgICAgICAgb3JpZ2luYWxWYWx1ZSxcclxuICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMucGF0Y2hGdW5jdGlvbixcclxuICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMucGF0Y2hQYXRoXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICB0aGlzLk9uQ2hhbmdlLmVtaXQob3JpZ2luYWxWYWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZW1vdmVGcm9tQ29udHJvbFZhbHVlKGl0ZW06IEZpbGVJdGVtKSB7XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmlzVXBsb2FkRmlsZUFzeW5jICYmIGl0ZW0ucHJvZ3Jlc3MgPT0gMTAwICYmIGl0ZW0uX2ZpbGVbJ2lzTmV3J10pIHtcclxuICAgICAgdGhpcy5maWxlVXBsb2FkU2VydmljZS5kZWxldGVGaWxlKGl0ZW0uX2ZpbGVbJ2lEX0dVSUQnXSlcclxuICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXHJcbiAgICAgICAgLnN1YnNjcmliZSgocmVzKSA9PiB7IH0pO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pc011bHRpcGxlRmlsZSA9PSBmYWxzZSkge1xyXG4gICAgICB0aGlzLmZpbGVVcGxvYWRNb2RlbCA9IG51bGw7XHJcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuaXNSZXF1aXJlZCA9PSB0cnVlKSB7XHJcbiAgICAgICAgdGhpcy5maWxlVXBsb2FkRm9ybUNvbnRyb2wubWFya0FzVG91Y2hlZCgpO1xyXG4gICAgICAgIHRoaXMuZmlsZVVwbG9hZEZvcm1Db250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTsgLy8gVHJpZ2dlciB2YWxpZGF0aW9uIGNoZWNrXHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5ncm91cC5nZXQodGhpcy5vcHRpb25zLm5hbWUpLnNldFZhbHVlKHRoaXMuZmlsZVVwbG9hZE1vZGVsKTtcclxuICAgICAgdGhpcy5vcHRpb25zLnZhbHVlID0gdGhpcy5maWxlVXBsb2FkTW9kZWw7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLnZhbHVlICE9IG51bGwgJiYgdGhpcy5vcHRpb25zLnZhbHVlICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMudmFsdWUuY29ycmVsYXRpb25JRF9HVUlEID09IG51bGwpIHtcclxuICAgICAgICAgIHRoaXMuZGVsZXRlZEZpbGVzID0gW107XHJcbiAgICAgICAgICB0aGlzLm11bHRpcGxlRmlsZVVwbG9hZE1vZGVsLnJlbW92ZWRGaWxlcyA9IFtdO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBpZiAodGhpcy5tdWx0aXBsZUZpbGVVcGxvYWRNb2RlbC5yZW1vdmVkRmlsZXMubGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgbGV0IEZpbGVPYmplY3QgPSBpdGVtLmZpbGUucmF3RmlsZTtcclxuICAgICAgICAgICAgbGV0IERlbGV0ZWRJdGVtID0gdGhpcy5tdWx0aXBsZUZpbGVVcGxvYWRNb2RlbC5leGlzdGluZ0ZpbGVzLmZpbHRlcihcclxuICAgICAgICAgICAgICAob2JqKSA9PiBvYmoubmFtZVdpdGhFeHRlbnNpb24gPT0gRmlsZU9iamVjdC5uYW1lXHJcbiAgICAgICAgICAgIClbMF07XHJcbiAgICAgICAgICAgIHRoaXMubXVsdGlwbGVGaWxlVXBsb2FkTW9kZWwuZXhpc3RpbmdGaWxlcyA9XHJcbiAgICAgICAgICAgICAgdGhpcy5tdWx0aXBsZUZpbGVVcGxvYWRNb2RlbC5leGlzdGluZ0ZpbGVzLmZpbHRlcihcclxuICAgICAgICAgICAgICAgIChvYmopID0+IG9iai5uYW1lV2l0aEV4dGVuc2lvbiAhPSBGaWxlT2JqZWN0Lm5hbWVcclxuICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB0aGlzLmRlbGV0ZWRGaWxlcy5wdXNoKERlbGV0ZWRJdGVtKTtcclxuICAgICAgICAgICAgdGhpcy5tdWx0aXBsZUZpbGVVcGxvYWRNb2RlbC5yZW1vdmVkRmlsZXMucHVzaChEZWxldGVkSXRlbS5pRF9HVUlEKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGxldCBGaWxlT2JqZWN0ID0gaXRlbS5maWxlLnJhd0ZpbGU7XHJcbiAgICAgICAgICAgIGxldCBkZWxldGVkTGlzdCA9IHRoaXMuZGVsZXRlZEZpbGVzLmZpbHRlcihcclxuICAgICAgICAgICAgICAob2JqKSA9PiBvYmoubmFtZVdpdGhFeHRlbnNpb24gPT0gRmlsZU9iamVjdC5uYW1lXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIGlmIChkZWxldGVkTGlzdC5sZW5ndGggPT0gMCB8fCBkZWxldGVkTGlzdCA9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICBsZXQgRGVsZXRlZEl0ZW0gPSB0aGlzLm11bHRpcGxlRmlsZVVwbG9hZE1vZGVsLmV4aXN0aW5nRmlsZXMuZmlsdGVyKFxyXG4gICAgICAgICAgICAgICAgKG9iaikgPT4gb2JqLm5hbWVXaXRoRXh0ZW5zaW9uID09IEZpbGVPYmplY3QubmFtZVxyXG4gICAgICAgICAgICAgIClbMF07XHJcbiAgICAgICAgICAgICAgdGhpcy5tdWx0aXBsZUZpbGVVcGxvYWRNb2RlbC5leGlzdGluZ0ZpbGVzID1cclxuICAgICAgICAgICAgICAgIHRoaXMubXVsdGlwbGVGaWxlVXBsb2FkTW9kZWwuZXhpc3RpbmdGaWxlcy5maWx0ZXIoXHJcbiAgICAgICAgICAgICAgICAgIChvYmopID0+IG9iai5uYW1lV2l0aEV4dGVuc2lvbiAhPSBGaWxlT2JqZWN0Lm5hbWVcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgdGhpcy5kZWxldGVkRmlsZXMucHVzaChEZWxldGVkSXRlbSk7XHJcbiAgICAgICAgICAgICAgdGhpcy5tdWx0aXBsZUZpbGVVcGxvYWRNb2RlbC5yZW1vdmVkRmlsZXMucHVzaChEZWxldGVkSXRlbS5pRF9HVUlEKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmRlbGV0ZWRGaWxlcyA9IFtdO1xyXG4gICAgICAgIHRoaXMubXVsdGlwbGVGaWxlVXBsb2FkTW9kZWwucmVtb3ZlZEZpbGVzID0gW107XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5tdWx0aXBsZUZpbGVVcGxvYWRNb2RlbC51cGxvYWRlZEZpbGVzID1cclxuICAgICAgICB0aGlzLm11bHRpcGxlRmlsZVVwbG9hZE1vZGVsLnVwbG9hZGVkRmlsZXMuZmlsdGVyKFxyXG4gICAgICAgICAgKG9iaikgPT5cclxuICAgICAgICAgICAgKG9iai5uYW1lV2l0aEV4dGVuc2lvbiAmJiBvYmoubmFtZVdpdGhFeHRlbnNpb24gIT0gaXRlbS5fZmlsZS5uYW1lKSB8fFxyXG4gICAgICAgICAgICBvYmouaURfR1VJRCAhPSBpdGVtLl9maWxlWydpRF9HVUlEJ11cclxuICAgICAgICApO1xyXG5cclxuICAgICAgaWYgKFxyXG4gICAgICAgICh0aGlzLm11bHRpcGxlRmlsZVVwbG9hZE1vZGVsLnVwbG9hZGVkRmlsZXMgPT0gbnVsbCB8fFxyXG4gICAgICAgICAgdGhpcy5tdWx0aXBsZUZpbGVVcGxvYWRNb2RlbC51cGxvYWRlZEZpbGVzLmxlbmd0aCA9PSAwKSAmJlxyXG4gICAgICAgIHRoaXMub3B0aW9ucy5pc1JlcXVpcmVkXHJcbiAgICAgICkge1xyXG4gICAgICAgIGNvbnN0IGZvcm1Db250cm9sID0gdGhpcy5maWxlVXBsb2FkRm9ybUNvbnRyb2w7XHJcbiAgICAgICAgZm9ybUNvbnRyb2wuc2V0RXJyb3JzKHtcclxuICAgICAgICAgIE1pbkZpbGVDb3VudFZhbGlkYXRpb25LZXk6IHRoaXMub3B0aW9ucy5taW5Ob09mRmlsZXNcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLmZpbGVVcGxvYWRGb3JtQ29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XHJcbiAgICAgICAgdGhpcy5maWxlVXBsb2FkRm9ybUNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpOyAvLyBUcmlnZ2VyIHZhbGlkYXRpb24gY2hlY2tcclxuICAgICAgfVxyXG4gICAgICB0aGlzLm11bHRpcGxlRmlsZVVwbG9hZE1vZGVsLmNvcnJlbGF0aW9uSURfR1VJRCA9IHRoaXMub3B0aW9ucy52YWx1ZT8uY29ycmVsYXRpb25JRF9HVUlEO1xyXG4gICAgICB0aGlzLmZpbGVVcGxvYWRGb3JtQ29udHJvbC5zZXRWYWx1ZSh0aGlzLm11bHRpcGxlRmlsZVVwbG9hZE1vZGVsKTtcclxuICAgICAgdGhpcy5ncm91cC5nZXQodGhpcy5vcHRpb25zLm5hbWUpLnNldFZhbHVlKHRoaXMubXVsdGlwbGVGaWxlVXBsb2FkTW9kZWwpO1xyXG4gICAgICB0aGlzLmZpbGVVcGxvYWRGb3JtQ29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgIC8vVXNlIHRoaXMgbGluZSB0byBlbmFibGUgdHdvIHdheSBiaW5kaW5nLlxyXG4gICAgICB0aGlzLm9wdGlvbnMudmFsdWUgPSB0aGlzLm11bHRpcGxlRmlsZVVwbG9hZE1vZGVsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy9FeHRlcm5hbCBNZXRob2RcclxuICByZW1vdmVSZXF1aXJlZFZhbGlkYXRpb24gPSAoKSA9PiB7XHJcbiAgICB0aGlzLmNvbnRyb2xVdGlsaXR5LnJlbW92ZVJlcXVpcmVkVmFsaWRhdGlvbihcclxuICAgICAgdGhpcy5maWxlVXBsb2FkRm9ybUNvbnRyb2wsXHJcbiAgICAgIHRoaXMudmFsaWRhdGlvblJ1bGVzLFxyXG4gICAgICB0aGlzLm9wdGlvbnNcclxuICAgICk7XHJcbiAgfTtcclxuXHJcbiAgLy9FeHRlcm5hbCBNZXRob2RcclxuICBhZGRSZXF1aXJlZFZhbGlkYXRpb24gPSAoKSA9PiB7XHJcbiAgICB0aGlzLmNvbnRyb2xVdGlsaXR5LmFkZFJlcXVpcmVkVmFsaWRhdGlvbihcclxuICAgICAgdGhpcy5maWxlVXBsb2FkRm9ybUNvbnRyb2wsXHJcbiAgICAgIHRoaXMudmFsaWRhdGlvblJ1bGVzLFxyXG4gICAgICB0aGlzLm9wdGlvbnNcclxuICAgICk7XHJcbiAgfTtcclxuXHJcbiAgLy9FeHRlcm5hbCBNZXRob2RcclxuICByZW1vdmVDdXN0b21WYWxpZGF0aW9uID0gKGN1c3RvbVZhbGlkYXRpb24pID0+IHtcclxuICAgIHRoaXMuY29udHJvbFV0aWxpdHkucmVtb3ZlQ3VzdG9tVmFsaWRhdGlvbihcclxuICAgICAgdGhpcy5maWxlVXBsb2FkRm9ybUNvbnRyb2wsXHJcbiAgICAgIHRoaXMudmFsaWRhdGlvblJ1bGVzLFxyXG4gICAgICBjdXN0b21WYWxpZGF0aW9uXHJcbiAgICApO1xyXG4gIH07XHJcblxyXG4gIC8vRXh0ZXJuYWwgTWV0aG9kXHJcbiAgYWRkQ3VzdG9tVmFsaWRhdGlvbiA9IChjdXN0b21WYWxpZGF0aW9uKSA9PiB7XHJcbiAgICB0aGlzLmNvbnRyb2xVdGlsaXR5LmFkZEN1c3RvbVZhbGlkYXRpb24oXHJcbiAgICAgIHRoaXMuZmlsZVVwbG9hZEZvcm1Db250cm9sLFxyXG4gICAgICB0aGlzLnZhbGlkYXRpb25SdWxlcyxcclxuICAgICAgY3VzdG9tVmFsaWRhdGlvblxyXG4gICAgKTtcclxuICB9O1xyXG5cclxuICAvL0V4dGVybmFsIE1ldGhvZFxyXG4gIGlzVmFsaWQgPSAoKSA9PiB7XHJcbiAgICB0aGlzLmNvbnRyb2xVdGlsaXR5LmlzVmFsaWQodGhpcy5maWxlVXBsb2FkRm9ybUNvbnRyb2wpO1xyXG4gIH07XHJcblxyXG4gIGNvbnZlcnRTaXplVG9NQihzaXplOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgaWYgKHNpemUgPT09IDApIHtcclxuICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ29udmVydCBzaXplIHRvIG1lZ2FieXRlc1xyXG4gICAgY29uc3QgbWVnYWJ5dGVzID0gc2l6ZSAvICgxMDI0ICogMTAyNCk7XHJcblxyXG4gICAgLy8gUm91bmQgdG8gdHdvIGRlY2ltYWwgcGxhY2VzXHJcbiAgICBjb25zdCByb3VuZGVkTWVnYWJ5dGVzID0gTWF0aC5yb3VuZChtZWdhYnl0ZXMgKiAxMDApIC8gMTAwO1xyXG5cclxuICAgIHJldHVybiByb3VuZGVkTWVnYWJ5dGVzO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICAvLyBDb21wbGV0ZSBhbGwgc3Vic2NyaXB0aW9ucyB0byBwcmV2ZW50IG1lbW9yeSBsZWFrc1xyXG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XHJcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XHJcblxyXG4gICAgLy8gQ2xlYXIgdXBsb2FkZXIgcXVldWUgdG8gZnJlZSBtZW1vcnlcclxuICAgIGlmICh0aGlzLnVwbG9hZGVyKSB7XHJcbiAgICAgIHRoaXMudXBsb2FkZXIuY2xlYXJRdWV1ZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIHNhbml0aXplRmlsZU5hbWUoZmlsZU5hbWU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAvLyBSZW1vdmUgcG90ZW50aWFsbHkgZGFuZ2Vyb3VzIGNoYXJhY3RlcnMgZnJvbSBmaWxlIG5hbWVzXHJcbiAgICByZXR1cm4gZmlsZU5hbWUucmVwbGFjZSgvWzw+OlwiL1xcXFx8PypdL2csICdfJykudHJpbSgpO1xyXG4gIH1cclxuXHJcblxyXG4gIHByaXZhdGUgZmluZER1cGxpY2F0ZUZpbGVzKCk6IGFueVtdIHtcclxuICAgIGNvbnN0IGR1cGxpY2F0ZUZpbGVzOiBhbnlbXSA9IFtdO1xyXG4gICAgY29uc3QgZXhpc3RpbmdGaWxlTmFtZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcclxuXHJcbiAgICAvLyBGaXJzdCBwYXNzOiBjb2xsZWN0IG5hbWVzIG9mIGV4aXN0aW5nIGZpbGVzIChhbHJlYWR5IGluIHF1ZXVlIGJlZm9yZSB0aGlzIHVwbG9hZClcclxuICAgIGNvbnN0IGV4aXN0aW5nRmlsZXMgPSB0aGlzLnVwbG9hZGVyLnF1ZXVlLmZpbHRlcihpdGVtID0+IGl0ZW1bJ3NvbWUnXS5sYXN0TW9kaWZpZWQgPT0gbnVsbCk7XHJcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgZXhpc3RpbmdGaWxlcykge1xyXG4gICAgICBjb25zdCBmaWxlTmFtZSA9IGl0ZW0uZmlsZS5uYW1lLnRvTG93ZXJDYXNlKCkudHJpbSgpO1xyXG4gICAgICBleGlzdGluZ0ZpbGVOYW1lcy5hZGQoZmlsZU5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFNlY29uZCBwYXNzOiBjaGVjayBuZXdseSBhZGRlZCBmaWxlcyBhZ2FpbnN0IGV4aXN0aW5nIGZpbGUgbmFtZXNcclxuICAgIGNvbnN0IG5ld2x5QWRkZWRGaWxlcyA9IHRoaXMudXBsb2FkZXIucXVldWUuZmlsdGVyKGl0ZW0gPT4gaXRlbVsnc29tZSddLmxhc3RNb2RpZmllZCAhPSBudWxsKTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgbmV3bHlBZGRlZEZpbGVzKSB7XHJcbiAgICAgIGNvbnN0IGZpbGVOYW1lID0gaXRlbS5maWxlLm5hbWUudG9Mb3dlckNhc2UoKS50cmltKCk7XHJcblxyXG4gICAgICAvLyBJZiB0aGlzIG5ldyBmaWxlIG5hbWUgYWxyZWFkeSBleGlzdHMgaW4gdGhlIHF1ZXVlLCBpdCdzIGEgZHVwbGljYXRlXHJcbiAgICAgIGlmIChleGlzdGluZ0ZpbGVOYW1lcy5oYXMoZmlsZU5hbWUpKSB7XHJcbiAgICAgICAgZHVwbGljYXRlRmlsZXMucHVzaChpdGVtKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBBZGQgdGhpcyBuZXcgZmlsZSBuYW1lIHRvIHRoZSBzZXQgc28gc3Vic2VxdWVudCBmaWxlcyB3aXRoIHNhbWUgbmFtZSBhcmUgYWxzbyBmbGFnZ2VkXHJcbiAgICAgICAgZXhpc3RpbmdGaWxlTmFtZXMuYWRkKGZpbGVOYW1lKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBkdXBsaWNhdGVGaWxlcztcclxuICB9XHJcblxyXG5cclxuICBwcml2YXRlIHJlbW92ZUR1cGxpY2F0ZUZpbGVzRnJvbVF1ZXVlKGR1cGxpY2F0ZUZpbGVzOiBhbnlbXSk6IHZvaWQge1xyXG4gICAgZm9yIChjb25zdCBkdXBsaWNhdGVGaWxlIG9mIGR1cGxpY2F0ZUZpbGVzKSB7XHJcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy51cGxvYWRlci5xdWV1ZS5pbmRleE9mKGR1cGxpY2F0ZUZpbGUpO1xyXG4gICAgICBpZiAoaW5kZXggPiAtMSkge1xyXG4gICAgICAgIHRoaXMudXBsb2FkZXIucXVldWUuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpc0ZpbGVUeXBlQWNjZXB0ZWQoZmlsZVR5cGU6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKCF0aGlzLmFjY2VwdGVkVHlwZUFycmF5IHx8IHRoaXMuYWNjZXB0ZWRUeXBlQXJyYXkubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHJldHVybiB0cnVlOyAvLyBObyByZXN0cmljdGlvbnNcclxuICAgIH1cclxuXHJcbiAgICAvLyBOb3JtYWxpemUgdGhlIGZpbGUgdHlwZSBmb3IgY29tcGFyaXNvblxyXG4gICAgY29uc3Qgbm9ybWFsaXplZEZpbGVUeXBlID0gZmlsZVR5cGUudG9Mb3dlckNhc2UoKS50cmltKCk7XHJcblxyXG4gICAgLy8gQ2hlY2sgYWdhaW5zdCBhbGwgYWNjZXB0ZWQgdHlwZXMgKGNhc2UtaW5zZW5zaXRpdmUgYW5kIHRyaW1tZWQpXHJcbiAgICByZXR1cm4gdGhpcy5hY2NlcHRlZFR5cGVBcnJheS5zb21lKGFjY2VwdGVkVHlwZSA9PiB7XHJcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRBY2NlcHRlZFR5cGUgPSBhY2NlcHRlZFR5cGUudG9Mb3dlckNhc2UoKS50cmltKCk7XHJcbiAgICAgIHJldHVybiBub3JtYWxpemVkQWNjZXB0ZWRUeXBlID09PSBub3JtYWxpemVkRmlsZVR5cGU7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2V0VmFsdWVQcmVzZXJ2aW5nRXJyb3JzKHZhbHVlOiBhbnksIHByZXNlcnZlRXJyb3JzPzogYW55KTogdm9pZCB7XHJcbiAgICAvLyBDYXB0dXJlIGN1cnJlbnQgZHVwbGljYXRlIGVycm9ycyBiZWZvcmUgc2V0VmFsdWUgY2xlYXJzIHRoZW1cclxuICAgIGNvbnN0IGN1cnJlbnRFcnJvcnMgPSB0aGlzLmZpbGVVcGxvYWRGb3JtQ29udHJvbC5lcnJvcnM7XHJcbiAgICBjb25zdCBkdXBsaWNhdGVFcnJvciA9IGN1cnJlbnRFcnJvcnM/LkR1cGxpY2F0ZUZpbGVFcnJvciA/IHsgRHVwbGljYXRlRmlsZUVycm9yOiBjdXJyZW50RXJyb3JzLkR1cGxpY2F0ZUZpbGVFcnJvciB9IDogbnVsbDtcclxuXHJcbiAgICAvLyBTZXQgdGhlIGZvcm0gY29udHJvbCB2YWx1ZVxyXG4gICAgdGhpcy5maWxlVXBsb2FkRm9ybUNvbnRyb2wuc2V0VmFsdWUodmFsdWUpO1xyXG4gICAgdGhpcy5ncm91cC5nZXQodGhpcy5vcHRpb25zLm5hbWUpLnNldFZhbHVlKHZhbHVlKTtcclxuXHJcbiAgICAvLyBBcHBseSBlcnJvcnMgaW4gcHJpb3JpdHkgb3JkZXI6IHByZXNlcnZlRXJyb3JzID4gZHVwbGljYXRlRXJyb3IgPiBwZW5kaW5nVmFsaWRhdGlvbkVycm9yc1xyXG4gICAgY29uc3QgZXJyb3JzVG9BcHBseSA9IHByZXNlcnZlRXJyb3JzIHx8IGR1cGxpY2F0ZUVycm9yIHx8IHRoaXMucGVuZGluZ1ZhbGlkYXRpb25FcnJvcnM7XHJcbiAgICBpZiAoZXJyb3JzVG9BcHBseSkge1xyXG4gICAgICB0aGlzLmZpbGVVcGxvYWRGb3JtQ29udHJvbC5zZXRFcnJvcnMoZXJyb3JzVG9BcHBseSk7XHJcbiAgICAgIHRoaXMuZmlsZVVwbG9hZEZvcm1Db250cm9sLm1hcmtBc1RvdWNoZWQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBVcGRhdGUgdGhlIG9wdGlvbnMgdmFsdWUgZm9yIHR3by13YXkgYmluZGluZ1xyXG4gICAgdGhpcy5vcHRpb25zLnZhbHVlID0gdmFsdWU7XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIGJic2YtY29udHJvbCBiYnNmLWZpbGUtdXBsb2FkXCIgW2Zvcm1Hcm91cF09XCJncm91cFwiPlxyXG4gIDxkaXYgW25nQ2xhc3NdPVwib3B0aW9ucy52aWV3VHlwZSA9PSAxID8gJ2Jic2YtdmVydGljYWwnIDogJ2Jic2YtaG9yaXpvbnRhbCdcIj5cclxuICAgIDwhLS1sYWJlbC0tPlxyXG4gICAgPGxhYmVsIFtoaWRkZW5dPVwib3B0aW9ucy5oaWRlTGFiZWxcIiBjbGFzcz1cImJic2YtbGFiZWwge3sgb3B0aW9ucy5sYWJlbEV4dHJhQ2xhc3NlcyB9fVwiPlxyXG4gICAgICB7eyBvcHRpb25zLmxhYmVsVmFsdWUgfX1cclxuICAgICAgPCEtLUFzdGVyaXNrLS0+XHJcbiAgICAgIDxzcGFuICpuZ0lmPVwiKChvcHRpb25zLnNob3dBc3RlcmlzayAmJiBvcHRpb25zLmlzUmVxdWlyZWQpIHx8IG9wdGlvbnMuaXNSZXF1aXJlZCkgJiYgIW9wdGlvbnMuaXNSZWFkb25seVwiXHJcbiAgICAgICAgY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+XHJcbiAgICA8L2xhYmVsPlxyXG4gICAgPCEtLUFsbG93IGRyb3Bab25lLS0+XHJcbiAgICA8ZGl2IG5nMkZpbGVEcm9wIGNsYXNzPVwiYmJzZi1pbnB1dC1jb250YWluZXIge3sgb3B0aW9ucy5leHRyYUNsYXNzZXMgfX1cIlxyXG4gICAgICAqbmdJZj1cIm9wdGlvbnMuaXNEcm9wWm9uZSAmJiAhKG9wdGlvbnMuaXNNdWx0aXBsZUZpbGUgPT0gZmFsc2UgJiYgdXBsb2FkZXIucXVldWUubGVuZ3RoID4gMCkgJiYgIW9wdGlvbnMuaXNSZWFkb25seVwiXHJcbiAgICAgIFtuZ0NsYXNzXT1cInsgJ2Fub3RoZXItZmlsZS1vdmVyLWNsYXNzJzogaGFzQW5vdGhlckRyb3Bab25lT3ZlciB9XCIgKG9uRmlsZURyb3ApPVwib25GaWxlQ2hhbmdlKClcIlxyXG4gICAgICAoZmlsZU92ZXIpPVwiZmlsZU92ZXJBbm90aGVyKCRldmVudClcIiBbdXBsb2FkZXJdPVwidXBsb2FkZXJcIiBbYWNjZXB0XT1cImFjY2VwdGVkVHlwZVwiIGlkPVwie3sgb3B0aW9ucy5uYW1lIH19XCJcclxuICAgICAgbXVsdGlwbGU9XCJ7eyBvcHRpb25zLmlzTXVsdGlwbGVGaWxlID8gJ211bHRpcGxlJyA6ICcnIH19XCIgYXJpYS1pbnZhbGlkPVwidHJ1ZVwiIHR5cGU9XCJmaWxlXCJcclxuICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiZmlsZVVwbG9hZEZvcm1Db250cm9sLmludmFsaWQgJiYgZmlsZVVwbG9hZEZvcm1Db250cm9sLnRvdWNoZWRcIlxyXG4gICAgICAoY2xpY2spPVwiZmlsZUlucHV0RHJvcFpvbmUuY2xpY2soKVwiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiZHJvcHpvbmUtbGFiZWxcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwic3ZnLWFuZC12YWxpZGF0aW9uXCI+XHJcbiAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjcwXCIgaGVpZ2h0PVwiNzBcIiB2aWV3Qm94PVwiMCAwIDcwIDcwXCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgPHBhdGggb3BhY2l0eT1cIjAuNFwiXHJcbiAgICAgICAgICAgICAgZD1cIk01OC4zMzMgNDguODMzMkM2MS44OTU3IDQ1Ljg5MDggNjQuMTY2MyA0MS40Mzk3IDY0LjE2NjMgMzYuNDU4M0M2NC4xNjYzIDI3LjU5ODggNTYuOTg0MyAyMC40MTY3IDQ4LjEyNDcgMjAuNDE2N0M0Ny40ODc0IDIwLjQxNjcgNDYuODkxMiAyMC4wODQyIDQ2LjU2NzUgMTkuNTM1MUM0Mi43NjQxIDEzLjA4MDggMzUuNzQxNyA4Ljc1IDI3LjcwOCA4Ljc1QzE1LjYyNjggOC43NSA1LjgzMzAxIDE4LjU0MzggNS44MzMwMSAzMC42MjVDNS44MzMwMSAzNi42NTExIDguMjY5NzQgNDIuMTA4MiAxMi4yMTE2IDQ2LjA2NDRcIlxyXG4gICAgICAgICAgICAgIHN0cm9rZT1cIiM0QjU0ODlcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgPHBhdGggZD1cIk0yMy4zMzMgNDYuNjY2N0wzNC45OTk3IDM1TTM0Ljk5OTcgMzVMNDYuNjY2MyA0Ni42NjY3TTM0Ljk5OTcgMzVWNjEuMjVcIiBzdHJva2U9XCIjNEI1NDg5XCJcclxuICAgICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgPCEtLVZhbGlkYXRpb24gdGV4dC0tPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImJic2YtdmFsaWRhdGlvbi1tc2cgdmFsaWRhdGlvbi1tc2ctaGVhZGVyIHRleHQtY2VudGVyXCI+XHJcbiAgICAgICAgICAgIHt7IFV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ0RyYWdBbmREcm9wSGVyZScpIH19XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJiYnNmLXZhbGlkYXRpb24tbXNnIHRleHQtY2VudGVyXCIgKm5nSWY9XCJ2YWxpZGF0aW9uTWVzc2FnZVwiIFtpbm5lckhUTUxdPVwidmFsaWRhdGlvbk1lc3NhZ2VcIj48L2Rpdj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJiYnNmLXZhbGlkYXRpb24tbXNnIG5nLXN0YXItaW5zZXJ0ZWQgdGV4dC1jZW50ZXIgdGV4dC1kYW5nZXJcIlxyXG4gICAgICAgICAgICAqbmdJZj1cInZhbGlkYXRpb25Db3VudE1lc3NhZ2UgJiYgb3B0aW9ucy5pc011bHRpcGxlRmlsZSAmJiBvcHRpb25zLm1heE5vT2ZGaWxlcyA+IDBcIlxyXG4gICAgICAgICAgICBbaW5uZXJIVE1MXT1cInZhbGlkYXRpb25Db3VudE1lc3NhZ2VcIj48L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxpbnB1dCBuZzJGaWxlU2VsZWN0IFt1cGxvYWRlcl09XCJ1cGxvYWRlclwiIFthY2NlcHRdPVwiYWNjZXB0ZWRUeXBlXCJcclxuICAgICAgICBjbGFzcz1cImZpbGVTZWxlY3RvciBjdXN0b21GaWxlVXBsb2FkUGxhY21lbnQgaGlkZGVuIHYtcmVxdWlyZWQtbXVsdGlwbGVmaWxlcyBkLW5vbmVcIlxyXG4gICAgICAgIG11bHRpcGxlPVwie3sgb3B0aW9ucy5pc011bHRpcGxlRmlsZSA/ICdtdWx0aXBsZScgOiAnJyB9fVwiIG5hbWU9XCJmaWxlXCIgdHlwZT1cImZpbGVcIiB2YWx1ZT1cIlwiIGF1dG9jb21wbGV0ZT1cIm9mZlwiXHJcbiAgICAgICAgKGNoYW5nZSk9XCJvbkZpbGVDaGFuZ2UoKVwiIFtuZ0NsYXNzXT1cIm9wdGlvbnMudmlld1R5cGUgPT0gMSA/ICcnIDogJ2NvbC1tZC05J1wiIGlkPVwie3sgb3B0aW9ucy5uYW1lIH19XCJcclxuICAgICAgICBhcmlhLWludmFsaWQ9XCJ0cnVlXCIgI2ZpbGVJbnB1dERyb3Bab25lXHJcbiAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiZmlsZVVwbG9hZEZvcm1Db250cm9sLmludmFsaWQgJiYgZmlsZVVwbG9hZEZvcm1Db250cm9sLnRvdWNoZWRcIiAvPlxyXG4gICAgPC9kaXY+XHJcbiAgICA8IS0tTm90IGFsbG93ZWQgZHJvcFpvbmUtLT5cclxuICAgIDxkaXYgY2xhc3M9XCJiYnNmLWlucHV0LWNvbnRhaW5lclwiICpuZ0lmPVwiIW9wdGlvbnMuaXNEcm9wWm9uZSAmJiAhaXNIaWRlSW5wdXQoKSAmJiAhb3B0aW9ucy5pc1JlYWRvbmx5XCJcclxuICAgICAgKGNsaWNrKT1cImZpbGVJbnB1dC5jbGljaygpXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJkcm9wem9uZS1sYWJlbFwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzdmctYW5kLXZhbGlkYXRpb25cIj5cclxuICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiNzBcIiBoZWlnaHQ9XCI3MFwiIHZpZXdCb3g9XCIwIDAgNzAgNzBcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICA8cGF0aCBvcGFjaXR5PVwiMC40XCJcclxuICAgICAgICAgICAgICBkPVwiTTU4LjMzMyA0OC44MzMyQzYxLjg5NTcgNDUuODkwOCA2NC4xNjYzIDQxLjQzOTcgNjQuMTY2MyAzNi40NTgzQzY0LjE2NjMgMjcuNTk4OCA1Ni45ODQzIDIwLjQxNjcgNDguMTI0NyAyMC40MTY3QzQ3LjQ4NzQgMjAuNDE2NyA0Ni44OTEyIDIwLjA4NDIgNDYuNTY3NSAxOS41MzUxQzQyLjc2NDEgMTMuMDgwOCAzNS43NDE3IDguNzUgMjcuNzA4IDguNzVDMTUuNjI2OCA4Ljc1IDUuODMzMDEgMTguNTQzOCA1LjgzMzAxIDMwLjYyNUM1LjgzMzAxIDM2LjY1MTEgOC4yNjk3NCA0Mi4xMDgyIDEyLjIxMTYgNDYuMDY0NFwiXHJcbiAgICAgICAgICAgICAgc3Ryb2tlPVwiIzRCNTQ4OVwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICA8cGF0aCBkPVwiTTIzLjMzMyA0Ni42NjY3TDM0Ljk5OTcgMzVNMzQuOTk5NyAzNUw0Ni42NjYzIDQ2LjY2NjdNMzQuOTk5NyAzNVY2MS4yNVwiIHN0cm9rZT1cIiM0QjU0ODlcIlxyXG4gICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICA8IS0tVmFsaWRhdGlvbiB0ZXh0LS0+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmJzZi12YWxpZGF0aW9uLW1zZyB0ZXh0LWNlbnRlclwiPnt7IFV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ1VwbG9hZCcpIH19PC9kaXY+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmJzZi12YWxpZGF0aW9uLW1zZyB0ZXh0LWNlbnRlclwiICpuZ0lmPVwidmFsaWRhdGlvbk1lc3NhZ2VcIiBbaW5uZXJIVE1MXT1cInZhbGlkYXRpb25NZXNzYWdlXCI+PC9kaXY+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmJzZi12YWxpZGF0aW9uLW1zZyBuZy1zdGFyLWluc2VydGVkIHRleHQtY2VudGVyIHRleHQtZGFuZ2VyXCJcclxuICAgICAgICAgICAgKm5nSWY9XCJ2YWxpZGF0aW9uQ291bnRNZXNzYWdlICYmIG9wdGlvbnMuaXNNdWx0aXBsZUZpbGUgJiYgb3B0aW9ucy5tYXhOb09mRmlsZXMgPiAwXCJcclxuICAgICAgICAgICAgW2lubmVySFRNTF09XCJ2YWxpZGF0aW9uQ291bnRNZXNzYWdlXCI+PC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8aW5wdXQgbmcyRmlsZVNlbGVjdCBbdXBsb2FkZXJdPVwidXBsb2FkZXJcIiBbYWNjZXB0XT1cImFjY2VwdGVkVHlwZVwiXHJcbiAgICAgICAgY2xhc3M9XCJmaWxlU2VsZWN0b3IgY3VzdG9tRmlsZVVwbG9hZFBsYWNtZW50IGhpZGRlbiB2LXJlcXVpcmVkLW11bHRpcGxlZmlsZXMgZC1ub25lXCJcclxuICAgICAgICBtdWx0aXBsZT1cInt7IG9wdGlvbnMuaXNNdWx0aXBsZUZpbGUgPyAnbXVsdGlwbGUnIDogJycgfX1cIiBuYW1lPVwiZmlsZVwiIHR5cGU9XCJmaWxlXCIgdmFsdWU9XCJcIiBhdXRvY29tcGxldGU9XCJvZmZcIlxyXG4gICAgICAgIChjaGFuZ2UpPVwib25GaWxlQ2hhbmdlKClcIiBbbmdDbGFzc109XCJvcHRpb25zLnZpZXdUeXBlID09IDEgPyAnJyA6ICdjb2wtbWQtOSdcIiBpZD1cInt7IG9wdGlvbnMubmFtZSB9fVwiXHJcbiAgICAgICAgYXJpYS1pbnZhbGlkPVwidHJ1ZVwiICNmaWxlSW5wdXRcclxuICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJmaWxlVXBsb2FkRm9ybUNvbnRyb2wuaW52YWxpZCAmJiBmaWxlVXBsb2FkRm9ybUNvbnRyb2wudG91Y2hlZFwiIC8+XHJcbiAgICA8L2Rpdj5cclxuICAgIDwhLS0gcmVhZG9ubHkgLS0+XHJcbiAgICA8ZGl2ICpuZ0lmPVwib3B0aW9ucy5pc1JlYWRvbmx5ICYmICFvcHRpb25zLnZhbHVlXCI+XHJcbiAgICAgIDxzcGFuIGNsYXNzPVwicmVhZG9ubHktdmlld1wiPnt7IFV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ05BJykgfX08L3NwYW4+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuICA8IS0taXRlbXMgdXBsb2FkZWQtLT5cclxuICA8ZGl2IGNsYXNzPVwidXBsb2FkZWQtaXRlbXNcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXBcIiAqbmdGb3I9XCJsZXQgaXRlbSBvZiB1cGxvYWRlci5xdWV1ZVwiPlxyXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbT8ucHJvZ3Jlc3MgPT0gMTAwICYmIG9wdGlvbnMuaXNVcGxvYWRGaWxlQXN5bmNcIj5cclxuICAgICAgICA8YSAqbmdJZj1cIml0ZW0/LmZpbGU/LnJhd0ZpbGVbJ3VybCddXCIgaHJlZj1cInt7IGl0ZW0/LmZpbGU/LnJhd0ZpbGVbJ3VybCddIH19XCJcclxuICAgICAgICAgIGNsYXNzPVwiYnRuLWRvd25sb2FkLWZpbGUgYnRuLXNtIGJ0bi1wcm9ncmVzcy11cGxvYWRcIiBkb3dubG9hZD5cclxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZmlsZS1uYW1lXCI+e3sgc2FuaXRpemVGaWxlTmFtZShpdGVtPy5maWxlPy5uYW1lIHx8ICcnKSB9fTwvc3Bhbj5cclxuICAgICAgICA8L2E+XHJcbiAgICAgICAgPGEgKm5nSWY9XCJpdGVtPy5maWxlPy5yYXdGaWxlWyd1cmwnXSA9PSBudWxsXCIgY2xhc3M9XCJidG4tZG93bmxvYWQtZmlsZSBidG4tc20gYnRuLXByb2dyZXNzLXVwbG9hZFwiPlxyXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJmaWxlLW5hbWVcIj57eyBzYW5pdGl6ZUZpbGVOYW1lKGl0ZW0/LmZpbGU/Lm5hbWUgfHwgJycpIH19PC9zcGFuPlxyXG4gICAgICAgIDwvYT5cclxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiIW9wdGlvbnMuaXNSZWFkb25seVwiIGNsYXNzPVwiYnRuIGJ0bi1kb3dubG9hZC1maWxlIGJ0bi1zbVwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiaXRlbS5yZW1vdmUoKTsgcmVtb3ZlRnJvbUNvbnRyb2xWYWx1ZShpdGVtKVwiPlxyXG4gICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIxNFwiIGhlaWdodD1cIjE0XCIgdmlld0JveD1cIjAgMCAxNCAxNFwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgIDxwYXRoIG9wYWNpdHk9XCIwLjRcIlxyXG4gICAgICAgICAgICAgIGQ9XCJNOS4zMzMwMSAzLjcwNTg0VjMuMjY2NjNDOS4zMzMwMSAyLjY1MTY2IDkuMzMzMDEgMi4zNDQxOSA5LjIwNTg3IDIuMTA5M0M5LjA5NDA1IDEuOTAyNyA4LjkxNTU1IDEuNzM0NzEgOC42OTYwNCAxLjYyOTQ0QzguNDQ2NDcgMS41MDk3NyA4LjExOTc3IDEuNTA5NzcgNy40NjYzOCAxLjUwOTc3SDYuNTMzMDVDNS44Nzk2NSAxLjUwOTc3IDUuNTUyOTYgMS41MDk3NyA1LjMwMzM5IDEuNjI5NDRDNS4wODM4NyAxLjczNDcxIDQuOTA1MzkgMS45MDI3IDQuNzkzNTQgMi4xMDkzQzQuNjY2MzggMi4zNDQxOSA0LjY2NjM4IDIuNjUxNjYgNC42NjYzOCAzLjI2NjYzVjMuNzA1ODRcIlxyXG4gICAgICAgICAgICAgIHN0cm9rZT1cIiNEODM3MzFcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICA8cGF0aFxyXG4gICAgICAgICAgICAgIGQ9XCJNMS43NSAzLjcwNjA1SDEyLjI1TTExLjA4MzQgMy43MDYwNVY5Ljg1NTFDMTEuMDgzNCAxMC43Nzc1IDExLjA4MzQgMTEuMjM4NyAxMC44OTI2IDExLjU5MUMxMC43MjQ4IDExLjkwMSAxMC40NTcxIDEyLjE1MjkgMTAuMTI3OCAxMi4zMTA5QzkuNzUzNDUgMTIuNDkwNCA5LjI2MzQ1IDEyLjQ5MDQgOC4yODMzNCAxMi40OTA0SDUuNzE2NjZDNC43MzY1OCAxMi40OTA0IDQuMjQ2NTMgMTIuNDkwNCAzLjg3MjE4IDEyLjMxMDlDMy41NDI5IDEyLjE1MjkgMy4yNzUxOSAxMS45MDEgMy4xMDc0MSAxMS41OTFDMi45MTY2NiAxMS4yMzg3IDIuOTE2NjYgMTAuNzc3NSAyLjkxNjY2IDkuODU1MVYzLjcwNjA1XCJcclxuICAgICAgICAgICAgICBzdHJva2U9XCIjRDgzNzMxXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFvcHRpb25zLmlzVXBsb2FkRmlsZUFzeW5jXCI+XHJcbiAgICAgICAgPGEgaHJlZj1cInt7IGl0ZW0/LmZpbGU/LnJhd0ZpbGVbJ3VybCddIH19XCIgKm5nSWY9XCJpdGVtPy5maWxlPy5yYXdGaWxlWyd1cmwnXVwiIGNsYXNzPVwiYnRuIGJ0bi1kb3dubG9hZC1maWxlIGJ0bi1zbVwiIGRvd25sb2FkPlxyXG4gICAgICAgICAgPHN2ZyB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XHJcbiAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgZD1cIk0yMSAyMkgzQzIuNCAyMiAyIDIxLjYgMiAyMUMyIDIwLjQgMi40IDIwIDMgMjBIMjFDMjEuNiAyMCAyMiAyMC40IDIyIDIxQzIyIDIxLjYgMjEuNiAyMiAyMSAyMlpNMTMgMTMuNFYzQzEzIDIuNCAxMi42IDIgMTIgMkMxMS40IDIgMTEgMi40IDExIDNWMTMuNEgxM1pcIlxyXG4gICAgICAgICAgICAgIGZpbGw9XCJjdXJyZW50Q29sb3JcIj48L3BhdGg+XHJcbiAgICAgICAgICAgIDxwYXRoIG9wYWNpdHk9XCIwLjNcIiBkPVwiTTcgMTMuNEgxN0wxMi43IDE3LjdDMTIuMyAxOC4xIDExLjcgMTguMSAxMS4zIDE3LjdMNyAxMy40WlwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIj5cclxuICAgICAgICAgICAgPC9wYXRoPlxyXG4gICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImZpbGUtbmFtZVwiPnt7IHNhbml0aXplRmlsZU5hbWUoaXRlbT8uZmlsZT8ubmFtZSB8fCAnJykgfX08L3NwYW4+XHJcbiAgICAgICAgPC9hPlxyXG4gICAgICAgICA8YSAqbmdJZj1cIml0ZW0/LmZpbGU/LnJhd0ZpbGVbJ3VybCddID09IG51bGxcIiBjbGFzcz1cImJ0bi1kb3dubG9hZC1maWxlIGJ0bi1zbSBidG4tcHJvZ3Jlc3MtdXBsb2FkXCI+XHJcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImZpbGUtbmFtZVwiPnt7IHNhbml0aXplRmlsZU5hbWUoaXRlbT8uZmlsZT8ubmFtZSB8fCAnJykgfX08L3NwYW4+XHJcbiAgICAgICAgPC9hPlxyXG4gICAgICAgIDxidXR0b24gKm5nSWY9XCIhb3B0aW9ucy5pc1JlYWRvbmx5XCIgY2xhc3M9XCJidG4gYnRuLWRvd25sb2FkLWZpbGUgYnRuLXNtIGJ0bi1kYW5nZXJcIlxyXG4gICAgICAgICAgKGNsaWNrKT1cIml0ZW0ucmVtb3ZlKCk7IHJlbW92ZUZyb21Db250cm9sVmFsdWUoaXRlbSlcIj5cclxuICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtdGltZXMgcHgtMFwiPjwvaT5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuICA8IS0tcHJvZ3Jlc3MgYmFyIGZpbGUgdXBsb2FkLS0+XHJcbiAgPGRpdiAqbmdGb3I9XCJsZXQgaXRlbSBvZiB1cGxvYWRlci5xdWV1ZVwiPlxyXG4gICAgPGRpdiBjbGFzcz1cInVwbG9hZC1pdGVtc1wiIFtuZ0NsYXNzXT1cInsgJ210LTQnOiBvcHRpb25zLmlzTXVsdGlwbGVGaWxlID09IHRydWUgfVwiXHJcbiAgICAgICpuZ0lmPVwiaXRlbT8ucHJvZ3Jlc3MgPCAxMDAgJiYgb3B0aW9ucy5pc1VwbG9hZEZpbGVBc3luY1wiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwidXBsb2FkLWl0ZW1zLXRvb2xiYXJcIj5cclxuICAgICAgICA8aDQ+e3sgaXRlbT8uZmlsZT8ubmFtZSB9fTwvaDQ+XHJcbiAgICAgICAgPHNwYW4gKGNsaWNrKT1cIml0ZW0ucmVtb3ZlKCk7IHJlbW92ZUZyb21Db250cm9sVmFsdWUoaXRlbSlcIj5cclxuICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMThcIiBoZWlnaHQ9XCIxOFwiIHZpZXdCb3g9XCIwIDAgMTggMThcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICA8ZyBjbGlwLXBhdGg9XCJ1cmwoI2NsaXAwXzEzMjRfMTMyMTYpXCI+XHJcbiAgICAgICAgICAgICAgPHBhdGggb3BhY2l0eT1cIjAuNFwiXHJcbiAgICAgICAgICAgICAgICBkPVwiTTkgMTYuNUMxMy4xNDIxIDE2LjUgMTYuNSAxMy4xNDIxIDE2LjUgOUMxNi41IDQuODU3ODYgMTMuMTQyMSAxLjUgOSAxLjVDNC44NTc4NiAxLjUgMS41IDQuODU3ODYgMS41IDlDMS41IDEzLjE0MjEgNC44NTc4NiAxNi41IDkgMTYuNVpcIlxyXG4gICAgICAgICAgICAgICAgc3Ryb2tlPVwiI0RCRTFGMFwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTEuMjUgNi43NUw2Ljc1IDExLjI1TTYuNzUgNi43NUwxMS4yNSAxMS4yNVwiIHN0cm9rZT1cIiNEQkUxRjBcIiBzdHJva2Utd2lkdGg9XCIyXCJcclxuICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgIDwvZz5cclxuICAgICAgICAgICAgPGRlZnM+XHJcbiAgICAgICAgICAgICAgPGNsaXBQYXRoIGlkPVwiY2xpcDBfMTMyNF8xMzIxNlwiPlxyXG4gICAgICAgICAgICAgICAgPHJlY3Qgd2lkdGg9XCIxOFwiIGhlaWdodD1cIjE4XCIgZmlsbD1cIndoaXRlXCIgLz5cclxuICAgICAgICAgICAgICA8L2NsaXBQYXRoPlxyXG4gICAgICAgICAgICA8L2RlZnM+XHJcbiAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICA8L3NwYW4+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3NcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtYmFyXCIgcm9sZT1cInByb2dyZXNzYmFyXCIgYXJpYS12YWx1ZW5vdz1cIjcwXCIgYXJpYS12YWx1ZW1pbj1cIjBcIiBhcmlhLXZhbHVlbWF4PVwiMTAwXCJcclxuICAgICAgICAgIFtjbGFzcy5maWxlLXVwbG9hZGVkXT1cIml0ZW0/LnByb2dyZXNzIDwgMTAwXCIgW3N0eWxlLndpZHRoLiVdPVwiaXRlbT8ucHJvZ3Jlc3NcIiAqbmdJZj1cIml0ZW0/LnByb2dyZXNzID4gMFwiPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG5cclxuICA8ZGl2IGNsYXNzPVwic3VidGV4dC1jb250YWluZXJcIiAqbmdJZj1cIiFvcHRpb25zLmlzUmVhZG9ubHlcIj5cclxuICAgIDwhLS0gcmVxdWlyZWQgdGV4dC0tPlxyXG4gICAgPGRpdiBjbGFzcz1cImJic2YtdmFsaWRhdGlvblwiICpuZ0lmPVwiZmlsZVVwbG9hZEZvcm1Db250cm9sLmludmFsaWQgJiYgZmlsZVVwbG9hZEZvcm1Db250cm9sLnRvdWNoZWRcIj5cclxuICAgICAge3sgZ2V0RXJyb3JWYWxpZGF0aW9uKGZpbGVVcGxvYWRGb3JtQ29udHJvbC5lcnJvcnMgfCBrZXl2YWx1ZSkgfX1cclxuICAgIDwvZGl2PlxyXG4gICAgPCEtLSBMYWJlbERlc2NyaXB0aW9uLS0+XHJcbiAgICA8ZGl2IGNsYXNzPVwiYmJzZi1jb250cm9sLWRlc2NcIiAqbmdJZj1cIm9wdGlvbnMubGFiZWxEZXNjcmlwdGlvbiAhPSBudWxsXCI+e3sgb3B0aW9ucy5sYWJlbERlc2NyaXB0aW9uIH19PC9kaXY+XHJcbiAgICA8ZGl2ICpuZ0lmPVwiKGdyb3VwLnZhbGlkICYmIGdyb3VwLmRpcnR5ICYmIGdyb3VwLnRvdWNoZWQpIHx8IChncm91cC51bnRvdWNoZWQgJiYgZ3JvdXAuaW52YWxpZCAmJiBncm91cC5kaXJ0eSlcIj5cclxuICAgICAge3sgcmVzZXRFcnJvcigpIH19XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuPC9kaXY+Il19