ng-kinintel 0.0.397 → 20.0.2

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 (184) hide show
  1. package/fesm2022/ng-kinintel.mjs +11874 -0
  2. package/fesm2022/ng-kinintel.mjs.map +1 -0
  3. package/index.d.ts +2818 -5
  4. package/package.json +6 -14
  5. package/esm2020/lib/components/alert-groups/alert-groups.component.mjs +0 -76
  6. package/esm2020/lib/components/alert-groups/edit-alert-group/edit-alert-group.component.mjs +0 -83
  7. package/esm2020/lib/components/dashboard-editor/configure-item/configure-item.component.mjs +0 -853
  8. package/esm2020/lib/components/dashboard-editor/configure-item/edit-dashboard-alert/edit-dashboard-alert.component.mjs +0 -56
  9. package/esm2020/lib/components/dashboard-editor/configure-item/html-documentation/html-documentation.component.mjs +0 -114
  10. package/esm2020/lib/components/dashboard-editor/configure-item/table-cell-formatter/table-cell-formatter.component.mjs +0 -163
  11. package/esm2020/lib/components/dashboard-editor/configure-item/vis-network-options.json +0 -135
  12. package/esm2020/lib/components/dashboard-editor/dashboard-editor.component.mjs +0 -580
  13. package/esm2020/lib/components/dashboard-editor/dashboard-parameter/dashboard-parameter.component.mjs +0 -15
  14. package/esm2020/lib/components/dashboard-editor/dashboard-settings/dashboard-settings.component.mjs +0 -50
  15. package/esm2020/lib/components/dashboard-editor/item-component/item-component.component.mjs +0 -1226
  16. package/esm2020/lib/components/dashboard-editor/source-selector-dialog/source-selector-dialog.component.mjs +0 -111
  17. package/esm2020/lib/components/dashboards/dashboards.component.mjs +0 -163
  18. package/esm2020/lib/components/dashboards/view-dashboard/view-dashboard.component.mjs +0 -429
  19. package/esm2020/lib/components/data-explorer/change-source-warning/change-source-warning.component.mjs +0 -20
  20. package/esm2020/lib/components/data-explorer/data-explorer.component.mjs +0 -243
  21. package/esm2020/lib/components/data-explorer/export-data/export-data.component.mjs +0 -62
  22. package/esm2020/lib/components/data-explorer/snapshot-api-access/snapshot-api-access.component.mjs +0 -70
  23. package/esm2020/lib/components/data-explorer/snapshot-profile-dialog/snapshot-profile-dialog.component.mjs +0 -190
  24. package/esm2020/lib/components/data-picker/data-picker.component.mjs +0 -79
  25. package/esm2020/lib/components/data-search/data-search.component.mjs +0 -11
  26. package/esm2020/lib/components/data-sharing-invite/data-sharing-invite.component.mjs +0 -52
  27. package/esm2020/lib/components/dataset/create-dataset/create-dataset.component.mjs +0 -47
  28. package/esm2020/lib/components/dataset/dataset-editor/available-columns/available-columns.component.mjs +0 -28
  29. package/esm2020/lib/components/dataset/dataset-editor/dataset-add-join/dataset-add-join.component.mjs +0 -344
  30. package/esm2020/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-editor/dataset-column-editor.component.mjs +0 -80
  31. package/esm2020/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-settings.component.mjs +0 -54
  32. package/esm2020/lib/components/dataset/dataset-editor/dataset-create-formula/dataset-create-formula.component.mjs +0 -67
  33. package/esm2020/lib/components/dataset/dataset-editor/dataset-editor.component.mjs +0 -1134
  34. package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter/dataset-filter.component.mjs +0 -201
  35. package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-inclusion/dataset-filter-inclusion.component.mjs +0 -25
  36. package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-junction/dataset-filter-junction.component.mjs +0 -72
  37. package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filters.component.mjs +0 -62
  38. package/esm2020/lib/components/dataset/dataset-editor/dataset-name-dialog/dataset-name-dialog.component.mjs +0 -41
  39. package/esm2020/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-add-parameter/dataset-add-parameter.component.mjs +0 -78
  40. package/esm2020/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-type/dataset-parameter-type.component.mjs +0 -39
  41. package/esm2020/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-values.component.mjs +0 -75
  42. package/esm2020/lib/components/dataset/dataset-editor/dataset-summarise/dataset-summarise.component.mjs +0 -107
  43. package/esm2020/lib/components/dataset/dataset-editor/move-transformation-confirmation/move-transformation-confirmation.component.mjs +0 -20
  44. package/esm2020/lib/components/dataset/dataset-editor/remove-transformation-warning/remove-transformation-warning.component.mjs +0 -20
  45. package/esm2020/lib/components/dataset/dataset-editor/save-as-query/save-as-query.component.mjs +0 -58
  46. package/esm2020/lib/components/dataset/dataset-editor/share-query/share-query.component.mjs +0 -110
  47. package/esm2020/lib/components/dataset/dataset-editor/upstream-changes-confirmation/upstream-changes-confirmation.component.mjs +0 -20
  48. package/esm2020/lib/components/dataset/dataset.component.mjs +0 -294
  49. package/esm2020/lib/components/datasource/create-datasource/advanced-settings/advanced-settings.component.mjs +0 -130
  50. package/esm2020/lib/components/datasource/create-datasource/api-access/api-access.component.mjs +0 -132
  51. package/esm2020/lib/components/datasource/create-datasource/create-datasource.component.mjs +0 -729
  52. package/esm2020/lib/components/datasource/create-datasource/import-data/import-data.component.mjs +0 -146
  53. package/esm2020/lib/components/datasource/create-datasource/import-data/import-wizard/import-wizard.component.mjs +0 -165
  54. package/esm2020/lib/components/datasource/create-datasource/tabular-datasource/tabular-datasource.component.mjs +0 -145
  55. package/esm2020/lib/components/datasource/datasource.component.mjs +0 -162
  56. package/esm2020/lib/components/datasource/document-datasource/document-datasource.component.mjs +0 -297
  57. package/esm2020/lib/components/export-project/export-project.component.mjs +0 -29
  58. package/esm2020/lib/components/feeds/feed/feed.component.mjs +0 -92
  59. package/esm2020/lib/components/feeds/feeds.component.mjs +0 -145
  60. package/esm2020/lib/components/job-tasks/job-tasks.component.mjs +0 -25
  61. package/esm2020/lib/components/marketplace/marketplace.component.mjs +0 -65
  62. package/esm2020/lib/components/metadata/metadata.component.mjs +0 -65
  63. package/esm2020/lib/components/notification-groups/edit-notification-group/edit-notification-group.component.mjs +0 -113
  64. package/esm2020/lib/components/notification-groups/notification-groups.component.mjs +0 -86
  65. package/esm2020/lib/components/project-picker/project-picker.component.mjs +0 -118
  66. package/esm2020/lib/components/project-settings/project-link-selection/project-link-selection.component.mjs +0 -104
  67. package/esm2020/lib/components/project-settings/project-settings.component.mjs +0 -155
  68. package/esm2020/lib/components/query-caching/edit-query-cache/edit-query-cache.component.mjs +0 -51
  69. package/esm2020/lib/components/query-caching/query-cache-view/query-cache-view.component.mjs +0 -121
  70. package/esm2020/lib/components/query-caching/query-caching.component.mjs +0 -162
  71. package/esm2020/lib/components/shared-with-me/feed-api-modal/feed-api-modal.component.mjs +0 -45
  72. package/esm2020/lib/components/shared-with-me/shared-with-me.component.mjs +0 -174
  73. package/esm2020/lib/components/snapshots/snapshots.component.mjs +0 -244
  74. package/esm2020/lib/components/tag-picker/tag-picker.component.mjs +0 -74
  75. package/esm2020/lib/components/task-time-periods/task-time-periods.component.mjs +0 -55
  76. package/esm2020/lib/components/whitelisted-sql-functions/whitelisted-sql-functions.component.mjs +0 -40
  77. package/esm2020/lib/guards/dashboard-changes.guard.mjs +0 -22
  78. package/esm2020/lib/kinintel-config.mjs +0 -3
  79. package/esm2020/lib/ng-kinintel.module.mjs +0 -437
  80. package/esm2020/lib/objects/action-event.mjs +0 -16
  81. package/esm2020/lib/services/alert.service.mjs +0 -52
  82. package/esm2020/lib/services/dashboard.service.mjs +0 -75
  83. package/esm2020/lib/services/data-processor.service.mjs +0 -56
  84. package/esm2020/lib/services/data-search.service.mjs +0 -36
  85. package/esm2020/lib/services/dataset.service.mjs +0 -187
  86. package/esm2020/lib/services/datasource.service.mjs +0 -93
  87. package/esm2020/lib/services/external.service.mjs +0 -33
  88. package/esm2020/lib/services/feed.service.mjs +0 -50
  89. package/esm2020/lib/services/notification.service.mjs +0 -41
  90. package/esm2020/lib/services/project.service.mjs +0 -130
  91. package/esm2020/lib/services/tag.service.mjs +0 -63
  92. package/esm2020/ng-kinintel.mjs +0 -5
  93. package/esm2020/public-api.mjs +0 -43
  94. package/fesm2015/ng-kinintel.mjs +0 -12182
  95. package/fesm2015/ng-kinintel.mjs.map +0 -1
  96. package/fesm2020/ng-kinintel.mjs +0 -11872
  97. package/fesm2020/ng-kinintel.mjs.map +0 -1
  98. package/lib/components/alert-groups/alert-groups.component.d.ts +0 -30
  99. package/lib/components/alert-groups/edit-alert-group/edit-alert-group.component.d.ts +0 -28
  100. package/lib/components/dashboard-editor/configure-item/configure-item.component.d.ts +0 -256
  101. package/lib/components/dashboard-editor/configure-item/edit-dashboard-alert/edit-dashboard-alert.component.d.ts +0 -16
  102. package/lib/components/dashboard-editor/configure-item/html-documentation/html-documentation.component.d.ts +0 -59
  103. package/lib/components/dashboard-editor/configure-item/table-cell-formatter/table-cell-formatter.component.d.ts +0 -26
  104. package/lib/components/dashboard-editor/dashboard-editor.component.d.ts +0 -85
  105. package/lib/components/dashboard-editor/dashboard-parameter/dashboard-parameter.component.d.ts +0 -8
  106. package/lib/components/dashboard-editor/dashboard-settings/dashboard-settings.component.d.ts +0 -22
  107. package/lib/components/dashboard-editor/item-component/item-component.component.d.ts +0 -264
  108. package/lib/components/dashboard-editor/source-selector-dialog/source-selector-dialog.component.d.ts +0 -30
  109. package/lib/components/dashboards/dashboards.component.d.ts +0 -56
  110. package/lib/components/dashboards/view-dashboard/view-dashboard.component.d.ts +0 -81
  111. package/lib/components/data-explorer/change-source-warning/change-source-warning.component.d.ts +0 -11
  112. package/lib/components/data-explorer/data-explorer.component.d.ts +0 -61
  113. package/lib/components/data-explorer/export-data/export-data.component.d.ts +0 -17
  114. package/lib/components/data-explorer/snapshot-api-access/snapshot-api-access.component.d.ts +0 -25
  115. package/lib/components/data-explorer/snapshot-profile-dialog/snapshot-profile-dialog.component.d.ts +0 -44
  116. package/lib/components/data-picker/data-picker.component.d.ts +0 -32
  117. package/lib/components/data-search/data-search.component.d.ts +0 -5
  118. package/lib/components/data-sharing-invite/data-sharing-invite.component.d.ts +0 -21
  119. package/lib/components/dataset/create-dataset/create-dataset.component.d.ts +0 -17
  120. package/lib/components/dataset/dataset-editor/available-columns/available-columns.component.d.ts +0 -12
  121. package/lib/components/dataset/dataset-editor/dataset-add-join/dataset-add-join.component.d.ts +0 -61
  122. package/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-editor/dataset-column-editor.component.d.ts +0 -21
  123. package/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-settings.component.d.ts +0 -20
  124. package/lib/components/dataset/dataset-editor/dataset-create-formula/dataset-create-formula.component.d.ts +0 -19
  125. package/lib/components/dataset/dataset-editor/dataset-editor.component.d.ts +0 -131
  126. package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter/dataset-filter.component.d.ts +0 -63
  127. package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-inclusion/dataset-filter-inclusion.component.d.ts +0 -11
  128. package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-junction/dataset-filter-junction.component.d.ts +0 -20
  129. package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filters.component.d.ts +0 -16
  130. package/lib/components/dataset/dataset-editor/dataset-name-dialog/dataset-name-dialog.component.d.ts +0 -18
  131. package/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-add-parameter/dataset-add-parameter.component.d.ts +0 -23
  132. package/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-type/dataset-parameter-type.component.d.ts +0 -13
  133. package/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-values.component.d.ts +0 -22
  134. package/lib/components/dataset/dataset-editor/dataset-summarise/dataset-summarise.component.d.ts +0 -27
  135. package/lib/components/dataset/dataset-editor/move-transformation-confirmation/move-transformation-confirmation.component.d.ts +0 -11
  136. package/lib/components/dataset/dataset-editor/remove-transformation-warning/remove-transformation-warning.component.d.ts +0 -11
  137. package/lib/components/dataset/dataset-editor/save-as-query/save-as-query.component.d.ts +0 -25
  138. package/lib/components/dataset/dataset-editor/share-query/share-query.component.d.ts +0 -41
  139. package/lib/components/dataset/dataset-editor/upstream-changes-confirmation/upstream-changes-confirmation.component.d.ts +0 -11
  140. package/lib/components/dataset/dataset.component.d.ts +0 -74
  141. package/lib/components/datasource/create-datasource/advanced-settings/advanced-settings.component.d.ts +0 -26
  142. package/lib/components/datasource/create-datasource/api-access/api-access.component.d.ts +0 -31
  143. package/lib/components/datasource/create-datasource/create-datasource.component.d.ts +0 -112
  144. package/lib/components/datasource/create-datasource/import-data/import-data.component.d.ts +0 -28
  145. package/lib/components/datasource/create-datasource/import-data/import-wizard/import-wizard.component.d.ts +0 -40
  146. package/lib/components/datasource/create-datasource/tabular-datasource/tabular-datasource.component.d.ts +0 -34
  147. package/lib/components/datasource/datasource.component.d.ts +0 -46
  148. package/lib/components/datasource/document-datasource/document-datasource.component.d.ts +0 -64
  149. package/lib/components/export-project/export-project.component.d.ts +0 -9
  150. package/lib/components/feeds/feed/feed.component.d.ts +0 -30
  151. package/lib/components/feeds/feeds.component.d.ts +0 -47
  152. package/lib/components/job-tasks/job-tasks.component.d.ts +0 -11
  153. package/lib/components/marketplace/marketplace.component.d.ts +0 -42
  154. package/lib/components/metadata/metadata.component.d.ts +0 -24
  155. package/lib/components/notification-groups/edit-notification-group/edit-notification-group.component.d.ts +0 -37
  156. package/lib/components/notification-groups/notification-groups.component.d.ts +0 -28
  157. package/lib/components/project-picker/project-picker.component.d.ts +0 -37
  158. package/lib/components/project-settings/project-link-selection/project-link-selection.component.d.ts +0 -32
  159. package/lib/components/project-settings/project-settings.component.d.ts +0 -40
  160. package/lib/components/query-caching/edit-query-cache/edit-query-cache.component.d.ts +0 -17
  161. package/lib/components/query-caching/query-cache-view/query-cache-view.component.d.ts +0 -35
  162. package/lib/components/query-caching/query-caching.component.d.ts +0 -38
  163. package/lib/components/shared-with-me/feed-api-modal/feed-api-modal.component.d.ts +0 -21
  164. package/lib/components/shared-with-me/shared-with-me.component.d.ts +0 -43
  165. package/lib/components/snapshots/snapshots.component.d.ts +0 -52
  166. package/lib/components/tag-picker/tag-picker.component.d.ts +0 -27
  167. package/lib/components/task-time-periods/task-time-periods.component.d.ts +0 -20
  168. package/lib/components/whitelisted-sql-functions/whitelisted-sql-functions.component.d.ts +0 -17
  169. package/lib/guards/dashboard-changes.guard.d.ts +0 -11
  170. package/lib/kinintel-config.d.ts +0 -10
  171. package/lib/ng-kinintel.module.d.ts +0 -116
  172. package/lib/objects/action-event.d.ts +0 -12
  173. package/lib/services/alert.service.d.ts +0 -17
  174. package/lib/services/dashboard.service.d.ts +0 -25
  175. package/lib/services/data-processor.service.d.ts +0 -18
  176. package/lib/services/data-search.service.d.ts +0 -14
  177. package/lib/services/dataset.service.d.ts +0 -56
  178. package/lib/services/datasource.service.d.ts +0 -34
  179. package/lib/services/external.service.d.ts +0 -12
  180. package/lib/services/feed.service.d.ts +0 -19
  181. package/lib/services/notification.service.d.ts +0 -16
  182. package/lib/services/project.service.d.ts +0 -27
  183. package/lib/services/tag.service.d.ts +0 -19
  184. package/public-api.d.ts +0 -38
@@ -1,297 +0,0 @@
1
- import { Component, Input } from '@angular/core';
2
- import { BehaviorSubject } from 'rxjs';
3
- import { debounceTime, map, switchMap } from 'rxjs/operators';
4
- import { DatasetEditorPopupComponent } from '../../dataset/dataset-editor/dataset-editor.component';
5
- import * as lodash from 'lodash';
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "@angular/router";
8
- import * as i2 from "../../../services/datasource.service";
9
- import * as i3 from "../../../services/dataset.service";
10
- import * as i4 from "@angular/material/legacy-dialog";
11
- import * as i5 from "@angular/common";
12
- import * as i6 from "@angular/material/legacy-button";
13
- import * as i7 from "@angular/material/icon";
14
- import * as i8 from "@angular/material/legacy-input";
15
- import * as i9 from "@angular/forms";
16
- import * as i10 from "@angular/material/legacy-core";
17
- import * as i11 from "@angular/material/legacy-checkbox";
18
- import * as i12 from "@angular/material/legacy-autocomplete";
19
- import * as i13 from "@angular/material/legacy-progress-bar";
20
- const _ = lodash.default;
21
- export class DocumentDatasourceComponent {
22
- constructor(route, datasourceService, datasetService, dialog) {
23
- this.route = route;
24
- this.datasourceService = datasourceService;
25
- this.datasetService = datasetService;
26
- this.dialog = dialog;
27
- this.searchText = new BehaviorSubject('');
28
- this.searchParser = new BehaviorSubject('');
29
- this.datasources = [];
30
- this.documentParsers = [];
31
- this.datasource = { config: { stopWords: [] } };
32
- this.showSettings = true;
33
- this.showUpload = false;
34
- this.String = String;
35
- this.files = null;
36
- this._ = _;
37
- this.builtInStopWords = {
38
- builtIn: false
39
- };
40
- this.failedResults = [];
41
- this.uploading = false;
42
- this.page = 1;
43
- this.endOfResults = false;
44
- this.limit = 25;
45
- this.offset = 0;
46
- }
47
- async ngOnInit() {
48
- this.route.params.subscribe(async (param) => {
49
- this.datasourceKey = param.key;
50
- if (this.datasourceKey) {
51
- this.showSettings = false;
52
- this.datasource = await this.datasourceService.getDatasource(this.datasourceKey);
53
- this.evaluateDatasource();
54
- if (this.datasource.config.stopWords && this.datasource.config.stopWords.length) {
55
- for (const stopWord of this.datasource.config.stopWords) {
56
- if (stopWord.custom) {
57
- stopWord.datasource = await this.datasourceService.getDatasource(stopWord.datasourceKey);
58
- this.updateDatasource(stopWord, stopWord.datasource);
59
- }
60
- if (stopWord.builtIn) {
61
- this.builtInStopWords = stopWord;
62
- }
63
- }
64
- }
65
- }
66
- });
67
- this.searchText
68
- .pipe(debounceTime(300),
69
- // distinctUntilChanged(),
70
- switchMap(() => this.getDatasources())).subscribe((datasources) => {
71
- this.datasources = datasources;
72
- });
73
- this.searchParser
74
- .pipe(debounceTime(300),
75
- // distinctUntilChanged(),
76
- switchMap(() => this.getDocumentParsers())).subscribe((parsers) => {
77
- this.documentParsers = parsers;
78
- });
79
- }
80
- increaseOffset() {
81
- this.page = this.page + 1;
82
- this.offset = (this.limit * this.page) - this.limit;
83
- this.evaluateDatasource();
84
- }
85
- decreaseOffset() {
86
- this.page = this.page <= 1 ? 1 : this.page - 1;
87
- this.offset = (this.limit * this.page) - this.limit;
88
- this.evaluateDatasource();
89
- }
90
- pageSizeChange(value) {
91
- this.limit = value;
92
- this.evaluateDatasource(true);
93
- }
94
- viewFullItemData(data, columnName) {
95
- this.dialog.open(DatasetEditorPopupComponent, {
96
- width: '800px',
97
- height: '400px',
98
- data: {
99
- fullData: data,
100
- columnName
101
- }
102
- });
103
- }
104
- indexDocumentChange(change) {
105
- if (change) {
106
- if (!this.datasource.config.minPhraseLength) {
107
- this.datasource.config.minPhraseLength = 1;
108
- }
109
- if (!this.datasource.config.maxPhraseLength) {
110
- this.datasource.config.maxPhraseLength = 1;
111
- }
112
- }
113
- }
114
- chunkContentChange(change) {
115
- if (change) {
116
- if (!this.datasource.config.chunkContent) {
117
- this.datasource.config.indexChunksByAI = false;
118
- }
119
- }
120
- }
121
- updateBuiltInStopWordConfig(value) {
122
- _.remove(this.datasource.config.stopWords, stopWord => {
123
- return stopWord.builtIn !== undefined;
124
- });
125
- if (!this.datasource.config.stopWords) {
126
- this.datasource.config.stopWords = [];
127
- }
128
- this.datasource.config.stopWords.push(this.builtInStopWords);
129
- }
130
- removeCustomStopWord(index) {
131
- this.datasource.config.stopWords.splice(index, 1);
132
- }
133
- humanFileSize(size) {
134
- const i = size === 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));
135
- return Number((size / Math.pow(1024, i)).toFixed(2)) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
136
- }
137
- displayFn(dataset) {
138
- return dataset && dataset.title ? dataset.title : '';
139
- }
140
- dragOverHandler(ev) {
141
- // Prevent default behavior (Prevent file from being opened)
142
- ev.preventDefault();
143
- }
144
- dropHandler(ev) {
145
- // Prevent default behavior (Prevent file from being opened)
146
- ev.preventDefault();
147
- this.files = [];
148
- if (ev.dataTransfer.items) {
149
- // Use DataTransferItemList interface to access the file(s)
150
- for (let i = 0; i < ev.dataTransfer.items.length; i++) {
151
- // If dropped items aren't files, reject them
152
- if (ev.dataTransfer.items[i].kind === 'file') {
153
- const file = ev.dataTransfer.items[i].getAsFile();
154
- this.files.push(file);
155
- }
156
- }
157
- }
158
- else {
159
- // Use DataTransfer interface to access the file(s)
160
- for (let i = 0; i < ev.dataTransfer.files.length; i++) {
161
- const file = ev.dataTransfer.files[i];
162
- this.files.push(file);
163
- }
164
- }
165
- }
166
- fileUpload(event) {
167
- this.files = Array.from(event.target.files);
168
- }
169
- removeFile(index) {
170
- this.files.splice(index, 1);
171
- }
172
- downloadDoc(url) {
173
- window.open(url);
174
- }
175
- async uploadFiles() {
176
- const formData = new FormData();
177
- for (const file of this.files) {
178
- formData.append(file.name, file);
179
- }
180
- await this.uploadDatasourceDocuments(formData);
181
- this.evaluateDatasource();
182
- }
183
- async updateDatasource(stopWord, datasource) {
184
- stopWord.datasourceKey = datasource.key;
185
- stopWord.datasource = datasource;
186
- const datasetInstanceSummary = {
187
- datasetInstanceId: null,
188
- datasourceInstanceKey: datasource.key,
189
- transformationInstances: [],
190
- parameterValues: {},
191
- parameters: [],
192
- originDataItemTitle: datasource.title
193
- };
194
- stopWord.selectedDatasource = await this.datasetService.evaluateDataset(datasetInstanceSummary, '0', '1');
195
- }
196
- updateCustomParser(value) {
197
- this.datasource.config.customDocumentParser = value;
198
- }
199
- async save() {
200
- if (!this.datasourceKey) {
201
- this.datasourceKey = await this.datasourceService.createDocumentDatasource(this.datasource);
202
- if (this.files && this.files.length) {
203
- await this.uploadFiles();
204
- this.evaluateDatasource();
205
- }
206
- window.location.href = window.location.href + '/' + this.datasourceKey;
207
- }
208
- else {
209
- await this.datasourceService.updateDatasourceInstance(this.datasourceKey, this.datasource);
210
- this.evaluateDatasource();
211
- }
212
- }
213
- getDatasources() {
214
- return this.datasourceService.getDatasources(this.searchText.getValue() || '', '10', '0').pipe(map((datasources) => {
215
- return datasources;
216
- }));
217
- }
218
- getDocumentParsers() {
219
- return this.datasourceService.getDatasources(this.searchText.getValue() || '', '10', '0').pipe(map((datasources) => {
220
- return [
221
- {
222
- title: 'Plenipot Bucharest 22',
223
- value: 'plenipotBucharest22'
224
- },
225
- {
226
- title: 'ITU Study Group',
227
- value: 'itustudygroup'
228
- },
229
- {
230
- title: 'IETF Internet Drafts',
231
- value: 'ietfinternetdrafts'
232
- },
233
- {
234
- title: 'WTSA',
235
- value: 'wtsa'
236
- },
237
- {
238
- title: 'WTDC',
239
- value: 'wtdc'
240
- }
241
- ];
242
- }));
243
- }
244
- async uploadDatasourceDocuments(formData) {
245
- this.uploading = true;
246
- const trackingKey = Date.now() + (Math.random() + 1).toString(36).substr(2, 5);
247
- this.datasourceService.uploadDatasourceDocuments(this.datasourceKey, formData, trackingKey).catch(err => {
248
- // Ignore - we have set off a long-running task which we are tracking below
249
- });
250
- this.files = null;
251
- return new Promise((resolve, reject) => {
252
- setTimeout(() => {
253
- const resultSub = this.datasourceService.getDataTrackingResults(trackingKey).subscribe((res) => {
254
- this.uploadResults = res;
255
- if (res && res.status === 'COMPLETED') {
256
- this.uploading = false;
257
- resultSub.unsubscribe();
258
- this.failedResults = res.progressData.failed || [];
259
- resolve(true);
260
- setTimeout(() => {
261
- this.uploadResults = null;
262
- this.failedResults = [];
263
- }, 5000);
264
- }
265
- });
266
- }, 100);
267
- });
268
- }
269
- async evaluateDatasource(resetPager = false) {
270
- if (resetPager) {
271
- this.offset = 0;
272
- this.page = 1;
273
- }
274
- this.datasource.limit = this.limit;
275
- this.datasource.offset = this.offset;
276
- this.evaluatedDatasource = await this.datasourceService.evaluateDatasource(this.datasource);
277
- this.evaluatedDatasource.allData.map(data => {
278
- if (data.file_size) {
279
- data.file_size = this.humanFileSize(data.file_size);
280
- }
281
- if (data.file_type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
282
- data.file_type = 'application/docx';
283
- }
284
- return data;
285
- });
286
- this.endOfResults = this.evaluatedDatasource.allData.length < this.limit;
287
- }
288
- }
289
- DocumentDatasourceComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DocumentDatasourceComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.DatasourceService }, { token: i3.DatasetService }, { token: i4.MatLegacyDialog }], target: i0.ɵɵFactoryTarget.Component });
290
- DocumentDatasourceComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: DocumentDatasourceComponent, selector: "ki-document-datasource", inputs: { showCustomParser: "showCustomParser" }, ngImport: i0, template: "<div class=\"p-6 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-2xl font-bold text-gray-900\">\n {{!datasourceKey ? 'Document Datasource' : (datasource.title || 'Document Datasource')}}\n </h1>\n <p class=\"text-sm font-medium text-gray-500\">\n <ng-template [ngIf]=\"!datasourceKey\">\n Upload your documents using the form below.\n </ng-template>\n <ng-template [ngIf]=\"datasourceKey\">\n View your existing documents below and adjust any document settings here.\n </ng-template>\n </p>\n </div>\n </div>\n <div class=\"mt-6 flex flex-col-reverse justify-stretch\" *ngIf=\"datasourceKey\">\n <button type=\"button\" (click)=\"showUpload = !showUpload\"\n class=\"inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary focus:outline-none\">\n Upload Additional Documents\n </button>\n </div>\n </div>\n</div>\n\n<div class=\"bg-blue-50 p-4\" *ngIf=\"uploading\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/information-circle -->\n <svg class=\"h-5 w-5 text-primary\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3 w-full\">\n <p class=\"text-sm text-primary font-medium\">Progress</p>\n <ng-template [ngIf]=\"uploadResults && uploadResults.progressData\">\n <div class=\"text-primary my-2\">Uploaded {{uploadResults.progressData.completed}}\n /{{uploadResults.progressData.total}}</div>\n <mat-progress-bar class=\"w-full my-4\" mode=\"determinate\"\n [value]=\"(uploadResults.progressData.completed/uploadResults.progressData.total) * 100\"></mat-progress-bar>\n </ng-template>\n <ng-template [ngIf]=\"!uploadResults || !uploadResults.progressData\">\n <div class=\"text-primary my-2\">Preparing Upload...</div>\n <mat-progress-bar class=\"w-full my-4\" mode=\"buffer\"></mat-progress-bar>\n </ng-template>\n </div>\n </div>\n</div>\n\n<div class=\"bg-green-50 p-4\" *ngIf=\"!failedResults.length && uploadResults && !uploading\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/check-circle -->\n <svg class=\"h-5 w-5 text-green-400\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3\">\n <h3 class=\"text-sm font-medium text-green-800\">Upload completed</h3>\n <div class=\"mt-2 text-sm text-green-700\">\n <p><b>{{uploadResults.progressData.completed}}</b> files were processed successfully out of\n <b>{{uploadResults.progressData.total}}</b> uploaded items.</p>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"bg-red-50 p-4\" *ngIf=\"failedResults.length && uploadResults\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/x-circle -->\n <svg class=\"h-5 w-5 text-red-400\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3\">\n <h3 class=\"text-sm font-medium text-red-800\">There were {{failedResults.length}} errors with your\n submission</h3>\n <div class=\"mt-2 text-sm text-red-700\">\n <ul role=\"list\" class=\"list-disc pl-5 space-y-1\">\n <li *ngFor=\"let failedResult of failedResults\">\n {{failedResult.message}}\n </li>\n </ul>\n </div>\n </div>\n </div>\n</div>\n\n<div *ngIf=\"showUpload\"\n class=\"space-y-8 p-6 bg-gray-50 border-b\">\n <div class=\"space-y-8 sm:space-y-5\">\n <div>\n <div class=\"space-y-6 sm:space-y-5\">\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start\">\n <label class=\"block text-sm font-medium text-gray-700\">\n Upload Documents\n <div class=\"text-xs font-normal text-gray-500\">\n Additional documents to be processed.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <div *ngIf=\"!files || !files.length\"\n (drop)=\"dropHandler($event)\" (dragover)=\"dragOverHandler($event)\"\n class=\"w-full flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md\">\n <div class=\"space-y-1 text-center\">\n <svg class=\"mx-auto h-12 w-12 text-gray-400\" stroke=\"currentColor\" fill=\"none\"\n viewBox=\"0 0 48 48\" aria-hidden=\"true\">\n <path\n d=\"M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <div class=\"flex text-sm text-gray-600\">\n <label\n class=\"relative cursor-pointer rounded-md font-medium text-secondary focus-within:outline-none\">\n <span>Select file(s) to upload</span>\n <input name=\"additionalUpload\" multiple type=\"file\" class=\"sr-only\"\n (change)=\"fileUpload($event)\">\n </label>\n <p class=\"pl-1 mb-0\">or drag and drop</p>\n </div>\n <p class=\"text-xs text-gray-500\">.docx, .txt, .pfd, .zip</p>\n </div>\n </div>\n <div *ngIf=\"files && files.length\"\n class=\"overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg\">\n <table class=\"min-w-full divide-y divide-gray-300 block overflow-y-auto max-h-48\">\n <thead class=\"bg-gray-50\">\n <tr>\n <th scope=\"col\" colspan=\"2\"\n class=\"sticky top-0 z-10 bg-gray-100 py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6\">\n Selected File Preview\n <span class=\"text-xs text-gray-500 lowercase ml-4 font-normal\">\n click <span class=\"font-medium\">'Upload Files'</span> to upload the selected files.</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr *ngFor=\"let file of files; let i = index\">\n <td class=\"whitespace-nowrap py-2 pl-4 pr-3 text-xs font-medium text-gray-900 sm:pl-6\">\n {{file.name}}\n </td>\n <td class=\"relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium sm:pr-6\">\n <a (click)=\"removeFile(i)\" class=\"text-danger\">Remove</a>\n </td>\n </tr>\n\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n </div>\n </div>\n\n </div>\n\n <div class=\"\">\n <div class=\"flex justify-end\">\n <button type=\"button\" (click)=\"showUpload = false;files = null\"\n class=\"bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none\">\n Cancel\n </button>\n\n <button type=\"submit\" [disabled]=\"!files\"\n class=\"disabled:opacity-50 ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-secondary focus:outline-none\"\n (click)=\"uploadFiles()\">Upload Files\n </button>\n </div>\n </div>\n</div>\n\n<div class=\"transformation-listing py-2 bg-gray-50 cursor-pointer\"\n (click)=\"showSettings = !showSettings\" [ngClass]=\"{'border-b': !showSettings}\">\n <a class=\"list-title flex items-center\">\n Settings&nbsp;\n <mat-icon *ngIf=\"!showSettings\">expand_more</mat-icon>\n <mat-icon *ngIf=\"showSettings\">expand_less</mat-icon>\n </a>\n <div class=\"ml-6 text-xs text-gray-500\">\n Adjust the rules around how the uploaded documents will\n be processed.\n </div>\n</div>\n\n<div *ngIf=\"showSettings\" [ngClass]=\"{'border-b': showSettings}\"\n class=\"space-y-8 divide-y divide-gray-200 p-6 bg-gray-50\">\n <div class=\"space-y-8 divide-y divide-gray-200 sm:space-y-5\">\n <div>\n <div class=\"space-y-6 sm:space-y-5\">\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Title\n <div class=\"text-xs font-normal text-gray-500\">Enter the name to identify this data source</div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <input type=\"text\" [(ngModel)]=\"datasource.title\"\n class=\"max-w-lg block w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:max-w-xs sm:text-sm border-gray-300 rounded-md\">\n\n </div>\n </div>\n\n <div *ngIf=\"!datasourceKey\"\n class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Upload Documents\n <div class=\"text-xs font-normal text-gray-500\">\n The documents to be processed.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <div *ngIf=\"!files || !files.length\"\n (drop)=\"dropHandler($event)\" (dragover)=\"dragOverHandler($event)\"\n class=\"w-full flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md\">\n <div class=\"space-y-1 text-center\">\n <svg class=\"mx-auto h-12 w-12 text-gray-400\" stroke=\"currentColor\" fill=\"none\"\n viewBox=\"0 0 48 48\" aria-hidden=\"true\">\n <path\n d=\"M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <div class=\"flex text-sm text-gray-600\">\n <label\n class=\"relative cursor-pointer rounded-md font-medium text-secondary focus-within:outline-none\">\n <span>Select file(s) to upload</span>\n <input name=\"additionalUpload\" multiple type=\"file\" class=\"sr-only\"\n (change)=\"fileUpload($event)\">\n </label>\n <p class=\"pl-1 mb-0\">or drag and drop</p>\n </div>\n <p class=\"text-xs text-gray-500\">.docx, .txt, .pfd, .zip</p>\n </div>\n </div>\n <div *ngIf=\"files\"\n class=\"overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg\">\n <table class=\"min-w-full divide-y divide-gray-300 block overflow-y-auto max-h-48\">\n <thead class=\"bg-gray-50\">\n <tr>\n <th scope=\"col\" colspan=\"2\"\n class=\"sticky top-0 z-10 bg-gray-100 py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6\">\n Selected File Preview\n <span class=\"text-xs text-gray-500 lowercase ml-4 font-normal\">\n click <span class=\"font-medium\">'Upload Files'</span> to upload the selected files.</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr *ngFor=\"let file of files; let i = index\">\n <td class=\"whitespace-nowrap py-2 pl-4 pr-3 text-xs font-medium text-gray-900 sm:pl-6\">\n {{file.name}}\n </td>\n <td class=\"relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium sm:pr-6\">\n <a (click)=\"removeFile(i)\" class=\"text-danger\">Remove</a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <ng-template [ngIf]=\"showCustomParser\">\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Custom Document Parser\n <div class=\"text-xs font-normal text-gray-500\">\n Use a custom document parser to process the documents.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <label class=\"mb-4 text-sm\">\n Select Custom Document Parser\n <input type=\"text\" [matAutocomplete]=\"autoParsers\"\n [(ngModel)]=\"datasource.config.customDocumentParser\"\n (keyup)=\"searchParser.next($event.target.value)\"\n placeholder=\"Search for a custom parser\">\n <mat-autocomplete #autoParsers=\"matAutocomplete\">\n <mat-option *ngFor=\"let parser of documentParsers\" [value]=\"parser.value\">\n {{parser.title}}\n </mat-option>\n </mat-autocomplete>\n <small class=\"font-normal\">Start typing name to view available parsers</small>\n </label>\n </div>\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"!datasource.config.customDocumentParser\">\n\n\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Indexing\n <div class=\"text-xs font-normal text-gray-500\">\n Set whether you want the content of the documents to be indexed\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-4\" [(ngModel)]=\"datasource.config.indexContent\"\n (ngModelChange)=\"indexDocumentChange($event)\">Index Document\n Content\n </mat-checkbox>\n <ng-template [ngIf]=\"datasource.config.indexContent\">\n <div class=\"max-w-lg flex rounded-md shadow-sm mb-2\">\n <span\n class=\"inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500 sm:text-sm\"> Min phrase length (words) </span>\n <input type=\"number\" name=\"minPhrase\" [min]=\"1\"\n [(ngModel)]=\"datasource.config.minPhraseLength\"\n class=\"flex-1 block w-full min-w-0 rounded-none rounded-r-md sm:text-sm border-gray-300\">\n </div>\n <div class=\"max-w-lg flex rounded-md shadow-sm\">\n <span\n class=\"inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500 sm:text-sm\"> Max phrase length (words) </span>\n <input type=\"number\" name=\"maxPhrase\" [min]=\"1\"\n [(ngModel)]=\"datasource.config.maxPhraseLength\"\n class=\"flex-1 block w-full min-w-0 rounded-none rounded-r-md sm:text-sm border-gray-300\">\n </div>\n </ng-template>\n </div>\n </div>\n\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Chunking\n <div class=\"text-xs font-normal text-gray-500\">\n Set whether you want to split the documents into chunks for analysis\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-4\" [(ngModel)]=\"datasource.config.chunkContent\" (ngModelChange)=\"chunkContentChange($event)\"> Chunk Document Content\n </mat-checkbox>\n <ng-template [ngIf]=\"datasource.config.chunkContent\">\n <mat-checkbox class=\"block mb-4\" [(ngModel)]=\"datasource.config.indexChunksByAI\">Index Chunks by AI\n </mat-checkbox>\n </ng-template>\n </div>\n\n </div>\n\n <div *ngIf=\"datasource.config.indexContent\"\n class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Stop Words\n <div class=\"text-xs font-normal text-gray-500\">\n A list of words to exclude from being indexed.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-2\" [(ngModel)]=\"builtInStopWords.builtIn\"\n (ngModelChange)=\"updateBuiltInStopWordConfig($event)\">Use Built In\n </mat-checkbox>\n\n <ng-template [ngIf]=\"builtInStopWords.builtIn && datasource.config.maxPhraseLength > 1\">\n <label class=\"mb-4\">\n Min phrase length for including stop words\n <input type=\"number\" [min]=\"2\"\n [(ngModel)]=\"builtInStopWords.minPhraseLength\">\n <small class=\"font-normal\">The built it stop words will be included when the phrase\n length is greater than or equal to this value.</small>\n </label>\n </ng-template>\n\n <hr class=\"my-4\" *ngIf=\"_.filter(datasource.config.stopWords, 'custom').length\">\n\n <ng-template ngFor let-stopWord [ngForOf]=\"_.filter(datasource.config.stopWords, 'custom')\"\n let-i=index>\n <div class=\"flex items-center justify-between\">\n <div>\n <label class=\"mb-4 text-sm\">\n Datasource\n <input type=\"text\" [matAutocomplete]=\"autoDatasets\"\n [value]=\"stopWord.datasource ? stopWord.datasource.title : ''\"\n (keyup)=\"searchText.next($event.target.value)\"\n placeholder=\"Search for a datasource\">\n <mat-autocomplete #autoDatasets=\"matAutocomplete\" [displayWith]=\"displayFn\">\n <mat-option *ngFor=\"let datasource of datasources\" [value]=\"datasource\"\n (onSelectionChange)=\"updateDatasource(stopWord, $event.source.value)\">\n {{datasource.title}}\n </mat-option>\n </mat-autocomplete>\n <small class=\"font-normal\">Start typing name to view available\n datasources</small>\n </label>\n\n\n <div *ngIf=\"stopWord.selectedDatasource && stopWord.selectedDatasource.columns\">\n <label class=\"mb-4\">\n Stop Words Column\n <select matNativeControl [(ngModel)]=\"stopWord.datasourceColumn\">\n <option *ngFor=\"let column of stopWord.selectedDatasource.columns\"\n [ngValue]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n <small class=\"font-normal\">Select the column to use for the stop\n words</small>\n </label>\n\n <label class=\"mb-4\" *ngIf=\"datasource.config.maxPhraseLength > 1\">\n Min phrase length for including stop words\n <input type=\"number\" [min]=\"2\"\n [(ngModel)]=\"stopWord.minPhraseLength\">\n <small\n class=\"font-normal\">The {{stopWord.datasource ? stopWord.datasource.title : ''}}\n stop words will be included when the\n phrase length is greater than or equal to this value.</small>\n </label>\n </div>\n </div>\n\n <button mat-icon-button color=\"warn\" (click)=\"removeCustomStopWord(i)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n\n <hr class=\"my-4\">\n </ng-template>\n\n <button mat-button color=\"primary\"\n (click)=\"datasource.config.stopWords.push({custom: true})\">\n <mat-icon>add</mat-icon>\n Add Custom Stop Words\n </button>\n\n </div>\n </div>\n\n </ng-template>\n\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Storage Options\n <div class=\"text-xs font-normal text-gray-500\">\n Securely save an original copy of the document and/or its original text.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-2\" [(ngModel)]=\"datasource.config.storeOriginal\">Store\n Original File\n </mat-checkbox>\n <mat-checkbox class=\"block mb-2\" [(ngModel)]=\"datasource.config.storeText\">Store Document\n Text\n </mat-checkbox>\n </div>\n </div>\n\n </div>\n </div>\n\n </div>\n\n <div class=\"pt-5\">\n <div class=\"flex justify-end\">\n <button type=\"button\"\n class=\"bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none\">\n Cancel\n </button>\n <button type=\"submit\" [disabled]=\"!datasource.title\"\n class=\"disabled:opacity-50 ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-secondary focus:outline-none\"\n (click)=\"save()\">\n <ng-template [ngIf]=\"!datasourceKey\">\n Create Datasource\n </ng-template>\n <ng-template [ngIf]=\"datasourceKey\">\n Update Settings\n </ng-template>\n </button>\n </div>\n </div>\n</div>\n\n<ng-template [ngIf]=\"evaluatedDatasource\">\n\n\n <div class=\"overflow-scroll\">\n <table class=\"min-w-full border-separate bg-white\" style=\"border-spacing: 0\">\n <thead class=\"bg-gray-100\">\n <tr>\n <th *ngFor=\"let column of evaluatedDatasource.columns\" scope=\"col\"\n class=\"sticky top-0 z-10 border-b border-gray-300 bg-gray-50 bg-opacity-75 py-3.5 px-4 text-left text-xs font-semibold text-gray-900 backdrop-blur backdrop-filter\">\n {{column.title}}\n </th>\n </tr>\n </thead>\n <tbody class=\"bg-white\">\n <tr *ngFor=\"let data of evaluatedDatasource.allData\">\n <td *ngFor=\"let column of evaluatedDatasource.columns; let i = index\"\n [ngClass]=\"{'font-medium': i === 0}\"\n class=\"border-b border-gray-200 py-2 px-4 text-sm text-gray-900\">\n <ng-template [ngIf]=\"column.name === 'original_link'\">\n <a class=\"flex items-center text-cta hover:underline\" (click)=\"downloadDoc(data[column.name])\">\n {{data[column.name]}}\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"ml-1 h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\"/>\n </svg>\n </a>\n </ng-template>\n <ng-template [ngIf]=\"column.name !== 'original_link'\">\n <ng-template [ngIf]=\"data[column.name] && String(data[column.name]).length <= 100\">\n {{data[column.name]}}\n </ng-template>\n <ng-template [ngIf]=\"data[column.name] && String(data[column.name]).length > 100\">\n <div>{{data[column.name].substring(0, 100) + '...'}}</div>\n <a (click)=\"viewFullItemData(data[column.name], column.name)\"\n class=\"flex items-center text-sm text-cta hover:underline\">\n view more\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"ml-1 h-4 w-4\" fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\n </svg>\n </a>\n </ng-template>\n <ng-template [ngIf]=\"!data[column.name]\">\n {{data[column.name]}}\n </ng-template>\n </ng-template>\n </td>\n </tr>\n </tbody>\n\n </table>\n\n </div>\n <div class=\"bg-white p-4 flex align-center justify-end\">\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\" class=\"mr-8\">\n <option [value]=\"1\">1</option>\n <option [value]=\"5\">5</option>\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n\n</ng-template>\n", styles: [":host{display:block;background-color:#fff}.cell-header{width:100%;display:flex;align-items:center;justify-content:space-between}.cell-header.end{justify-content:flex-end}.transformation-listing{display:flex;align-items:center;flex-wrap:wrap;width:100%;border-bottom-color:#ddd;min-height:47px}.transformation-listing .list-title{text-transform:uppercase;font-size:.75rem;padding:0 1rem;border-right:2px solid #ddd;color:#4c4c4c;font-weight:500;letter-spacing:1px}.transformation-listing .badge-item{display:flex;align-items:center;margin-left:1rem;padding-left:1rem;border-radius:20px;background-color:#fff;border:1px solid #ddd;height:30px}.transformation-listing .badge-item.exclude{opacity:.8}.transformation-listing .badge-item:hover{background-color:#fcfcfc}.transformation-listing .badge-item span{margin-right:.5rem;color:#0000008a}.transformation-listing .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.transformation-listing .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}table{position:relative;border-collapse:collapse}table.sticky th{position:sticky;top:0;background-color:#f5f5f5;border-top:none!important;border-bottom:none!important;box-shadow:inset 0 -1px #ddd}table th.settings{padding:0}table td{max-width:400px;word-wrap:break-word;padding-top:.5rem;padding-bottom:.5rem;padding-right:1rem;min-width:100px;width:1%}table td.settings{max-width:25px;min-width:25px}table::-webkit-scrollbar{width:.75em;background:transparent}table::-webkit-scrollbar-thumb{background:#d2d2d2}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatLegacyButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatLegacyInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", exportAs: ["matInput"] }, { kind: "directive", type: i9.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i9.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i9.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i9.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i10.MatLegacyOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i11.MatLegacyCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i12.MatLegacyAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i12.MatLegacyAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i13.MatLegacyProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }] });
291
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DocumentDatasourceComponent, decorators: [{
292
- type: Component,
293
- args: [{ selector: 'ki-document-datasource', template: "<div class=\"p-6 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-2xl font-bold text-gray-900\">\n {{!datasourceKey ? 'Document Datasource' : (datasource.title || 'Document Datasource')}}\n </h1>\n <p class=\"text-sm font-medium text-gray-500\">\n <ng-template [ngIf]=\"!datasourceKey\">\n Upload your documents using the form below.\n </ng-template>\n <ng-template [ngIf]=\"datasourceKey\">\n View your existing documents below and adjust any document settings here.\n </ng-template>\n </p>\n </div>\n </div>\n <div class=\"mt-6 flex flex-col-reverse justify-stretch\" *ngIf=\"datasourceKey\">\n <button type=\"button\" (click)=\"showUpload = !showUpload\"\n class=\"inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary focus:outline-none\">\n Upload Additional Documents\n </button>\n </div>\n </div>\n</div>\n\n<div class=\"bg-blue-50 p-4\" *ngIf=\"uploading\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/information-circle -->\n <svg class=\"h-5 w-5 text-primary\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3 w-full\">\n <p class=\"text-sm text-primary font-medium\">Progress</p>\n <ng-template [ngIf]=\"uploadResults && uploadResults.progressData\">\n <div class=\"text-primary my-2\">Uploaded {{uploadResults.progressData.completed}}\n /{{uploadResults.progressData.total}}</div>\n <mat-progress-bar class=\"w-full my-4\" mode=\"determinate\"\n [value]=\"(uploadResults.progressData.completed/uploadResults.progressData.total) * 100\"></mat-progress-bar>\n </ng-template>\n <ng-template [ngIf]=\"!uploadResults || !uploadResults.progressData\">\n <div class=\"text-primary my-2\">Preparing Upload...</div>\n <mat-progress-bar class=\"w-full my-4\" mode=\"buffer\"></mat-progress-bar>\n </ng-template>\n </div>\n </div>\n</div>\n\n<div class=\"bg-green-50 p-4\" *ngIf=\"!failedResults.length && uploadResults && !uploading\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/check-circle -->\n <svg class=\"h-5 w-5 text-green-400\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3\">\n <h3 class=\"text-sm font-medium text-green-800\">Upload completed</h3>\n <div class=\"mt-2 text-sm text-green-700\">\n <p><b>{{uploadResults.progressData.completed}}</b> files were processed successfully out of\n <b>{{uploadResults.progressData.total}}</b> uploaded items.</p>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"bg-red-50 p-4\" *ngIf=\"failedResults.length && uploadResults\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/x-circle -->\n <svg class=\"h-5 w-5 text-red-400\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3\">\n <h3 class=\"text-sm font-medium text-red-800\">There were {{failedResults.length}} errors with your\n submission</h3>\n <div class=\"mt-2 text-sm text-red-700\">\n <ul role=\"list\" class=\"list-disc pl-5 space-y-1\">\n <li *ngFor=\"let failedResult of failedResults\">\n {{failedResult.message}}\n </li>\n </ul>\n </div>\n </div>\n </div>\n</div>\n\n<div *ngIf=\"showUpload\"\n class=\"space-y-8 p-6 bg-gray-50 border-b\">\n <div class=\"space-y-8 sm:space-y-5\">\n <div>\n <div class=\"space-y-6 sm:space-y-5\">\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start\">\n <label class=\"block text-sm font-medium text-gray-700\">\n Upload Documents\n <div class=\"text-xs font-normal text-gray-500\">\n Additional documents to be processed.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <div *ngIf=\"!files || !files.length\"\n (drop)=\"dropHandler($event)\" (dragover)=\"dragOverHandler($event)\"\n class=\"w-full flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md\">\n <div class=\"space-y-1 text-center\">\n <svg class=\"mx-auto h-12 w-12 text-gray-400\" stroke=\"currentColor\" fill=\"none\"\n viewBox=\"0 0 48 48\" aria-hidden=\"true\">\n <path\n d=\"M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <div class=\"flex text-sm text-gray-600\">\n <label\n class=\"relative cursor-pointer rounded-md font-medium text-secondary focus-within:outline-none\">\n <span>Select file(s) to upload</span>\n <input name=\"additionalUpload\" multiple type=\"file\" class=\"sr-only\"\n (change)=\"fileUpload($event)\">\n </label>\n <p class=\"pl-1 mb-0\">or drag and drop</p>\n </div>\n <p class=\"text-xs text-gray-500\">.docx, .txt, .pfd, .zip</p>\n </div>\n </div>\n <div *ngIf=\"files && files.length\"\n class=\"overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg\">\n <table class=\"min-w-full divide-y divide-gray-300 block overflow-y-auto max-h-48\">\n <thead class=\"bg-gray-50\">\n <tr>\n <th scope=\"col\" colspan=\"2\"\n class=\"sticky top-0 z-10 bg-gray-100 py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6\">\n Selected File Preview\n <span class=\"text-xs text-gray-500 lowercase ml-4 font-normal\">\n click <span class=\"font-medium\">'Upload Files'</span> to upload the selected files.</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr *ngFor=\"let file of files; let i = index\">\n <td class=\"whitespace-nowrap py-2 pl-4 pr-3 text-xs font-medium text-gray-900 sm:pl-6\">\n {{file.name}}\n </td>\n <td class=\"relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium sm:pr-6\">\n <a (click)=\"removeFile(i)\" class=\"text-danger\">Remove</a>\n </td>\n </tr>\n\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n </div>\n </div>\n\n </div>\n\n <div class=\"\">\n <div class=\"flex justify-end\">\n <button type=\"button\" (click)=\"showUpload = false;files = null\"\n class=\"bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none\">\n Cancel\n </button>\n\n <button type=\"submit\" [disabled]=\"!files\"\n class=\"disabled:opacity-50 ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-secondary focus:outline-none\"\n (click)=\"uploadFiles()\">Upload Files\n </button>\n </div>\n </div>\n</div>\n\n<div class=\"transformation-listing py-2 bg-gray-50 cursor-pointer\"\n (click)=\"showSettings = !showSettings\" [ngClass]=\"{'border-b': !showSettings}\">\n <a class=\"list-title flex items-center\">\n Settings&nbsp;\n <mat-icon *ngIf=\"!showSettings\">expand_more</mat-icon>\n <mat-icon *ngIf=\"showSettings\">expand_less</mat-icon>\n </a>\n <div class=\"ml-6 text-xs text-gray-500\">\n Adjust the rules around how the uploaded documents will\n be processed.\n </div>\n</div>\n\n<div *ngIf=\"showSettings\" [ngClass]=\"{'border-b': showSettings}\"\n class=\"space-y-8 divide-y divide-gray-200 p-6 bg-gray-50\">\n <div class=\"space-y-8 divide-y divide-gray-200 sm:space-y-5\">\n <div>\n <div class=\"space-y-6 sm:space-y-5\">\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Title\n <div class=\"text-xs font-normal text-gray-500\">Enter the name to identify this data source</div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <input type=\"text\" [(ngModel)]=\"datasource.title\"\n class=\"max-w-lg block w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:max-w-xs sm:text-sm border-gray-300 rounded-md\">\n\n </div>\n </div>\n\n <div *ngIf=\"!datasourceKey\"\n class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Upload Documents\n <div class=\"text-xs font-normal text-gray-500\">\n The documents to be processed.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <div *ngIf=\"!files || !files.length\"\n (drop)=\"dropHandler($event)\" (dragover)=\"dragOverHandler($event)\"\n class=\"w-full flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md\">\n <div class=\"space-y-1 text-center\">\n <svg class=\"mx-auto h-12 w-12 text-gray-400\" stroke=\"currentColor\" fill=\"none\"\n viewBox=\"0 0 48 48\" aria-hidden=\"true\">\n <path\n d=\"M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <div class=\"flex text-sm text-gray-600\">\n <label\n class=\"relative cursor-pointer rounded-md font-medium text-secondary focus-within:outline-none\">\n <span>Select file(s) to upload</span>\n <input name=\"additionalUpload\" multiple type=\"file\" class=\"sr-only\"\n (change)=\"fileUpload($event)\">\n </label>\n <p class=\"pl-1 mb-0\">or drag and drop</p>\n </div>\n <p class=\"text-xs text-gray-500\">.docx, .txt, .pfd, .zip</p>\n </div>\n </div>\n <div *ngIf=\"files\"\n class=\"overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg\">\n <table class=\"min-w-full divide-y divide-gray-300 block overflow-y-auto max-h-48\">\n <thead class=\"bg-gray-50\">\n <tr>\n <th scope=\"col\" colspan=\"2\"\n class=\"sticky top-0 z-10 bg-gray-100 py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6\">\n Selected File Preview\n <span class=\"text-xs text-gray-500 lowercase ml-4 font-normal\">\n click <span class=\"font-medium\">'Upload Files'</span> to upload the selected files.</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr *ngFor=\"let file of files; let i = index\">\n <td class=\"whitespace-nowrap py-2 pl-4 pr-3 text-xs font-medium text-gray-900 sm:pl-6\">\n {{file.name}}\n </td>\n <td class=\"relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium sm:pr-6\">\n <a (click)=\"removeFile(i)\" class=\"text-danger\">Remove</a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <ng-template [ngIf]=\"showCustomParser\">\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Custom Document Parser\n <div class=\"text-xs font-normal text-gray-500\">\n Use a custom document parser to process the documents.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <label class=\"mb-4 text-sm\">\n Select Custom Document Parser\n <input type=\"text\" [matAutocomplete]=\"autoParsers\"\n [(ngModel)]=\"datasource.config.customDocumentParser\"\n (keyup)=\"searchParser.next($event.target.value)\"\n placeholder=\"Search for a custom parser\">\n <mat-autocomplete #autoParsers=\"matAutocomplete\">\n <mat-option *ngFor=\"let parser of documentParsers\" [value]=\"parser.value\">\n {{parser.title}}\n </mat-option>\n </mat-autocomplete>\n <small class=\"font-normal\">Start typing name to view available parsers</small>\n </label>\n </div>\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"!datasource.config.customDocumentParser\">\n\n\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Indexing\n <div class=\"text-xs font-normal text-gray-500\">\n Set whether you want the content of the documents to be indexed\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-4\" [(ngModel)]=\"datasource.config.indexContent\"\n (ngModelChange)=\"indexDocumentChange($event)\">Index Document\n Content\n </mat-checkbox>\n <ng-template [ngIf]=\"datasource.config.indexContent\">\n <div class=\"max-w-lg flex rounded-md shadow-sm mb-2\">\n <span\n class=\"inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500 sm:text-sm\"> Min phrase length (words) </span>\n <input type=\"number\" name=\"minPhrase\" [min]=\"1\"\n [(ngModel)]=\"datasource.config.minPhraseLength\"\n class=\"flex-1 block w-full min-w-0 rounded-none rounded-r-md sm:text-sm border-gray-300\">\n </div>\n <div class=\"max-w-lg flex rounded-md shadow-sm\">\n <span\n class=\"inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500 sm:text-sm\"> Max phrase length (words) </span>\n <input type=\"number\" name=\"maxPhrase\" [min]=\"1\"\n [(ngModel)]=\"datasource.config.maxPhraseLength\"\n class=\"flex-1 block w-full min-w-0 rounded-none rounded-r-md sm:text-sm border-gray-300\">\n </div>\n </ng-template>\n </div>\n </div>\n\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Chunking\n <div class=\"text-xs font-normal text-gray-500\">\n Set whether you want to split the documents into chunks for analysis\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-4\" [(ngModel)]=\"datasource.config.chunkContent\" (ngModelChange)=\"chunkContentChange($event)\"> Chunk Document Content\n </mat-checkbox>\n <ng-template [ngIf]=\"datasource.config.chunkContent\">\n <mat-checkbox class=\"block mb-4\" [(ngModel)]=\"datasource.config.indexChunksByAI\">Index Chunks by AI\n </mat-checkbox>\n </ng-template>\n </div>\n\n </div>\n\n <div *ngIf=\"datasource.config.indexContent\"\n class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Stop Words\n <div class=\"text-xs font-normal text-gray-500\">\n A list of words to exclude from being indexed.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-2\" [(ngModel)]=\"builtInStopWords.builtIn\"\n (ngModelChange)=\"updateBuiltInStopWordConfig($event)\">Use Built In\n </mat-checkbox>\n\n <ng-template [ngIf]=\"builtInStopWords.builtIn && datasource.config.maxPhraseLength > 1\">\n <label class=\"mb-4\">\n Min phrase length for including stop words\n <input type=\"number\" [min]=\"2\"\n [(ngModel)]=\"builtInStopWords.minPhraseLength\">\n <small class=\"font-normal\">The built it stop words will be included when the phrase\n length is greater than or equal to this value.</small>\n </label>\n </ng-template>\n\n <hr class=\"my-4\" *ngIf=\"_.filter(datasource.config.stopWords, 'custom').length\">\n\n <ng-template ngFor let-stopWord [ngForOf]=\"_.filter(datasource.config.stopWords, 'custom')\"\n let-i=index>\n <div class=\"flex items-center justify-between\">\n <div>\n <label class=\"mb-4 text-sm\">\n Datasource\n <input type=\"text\" [matAutocomplete]=\"autoDatasets\"\n [value]=\"stopWord.datasource ? stopWord.datasource.title : ''\"\n (keyup)=\"searchText.next($event.target.value)\"\n placeholder=\"Search for a datasource\">\n <mat-autocomplete #autoDatasets=\"matAutocomplete\" [displayWith]=\"displayFn\">\n <mat-option *ngFor=\"let datasource of datasources\" [value]=\"datasource\"\n (onSelectionChange)=\"updateDatasource(stopWord, $event.source.value)\">\n {{datasource.title}}\n </mat-option>\n </mat-autocomplete>\n <small class=\"font-normal\">Start typing name to view available\n datasources</small>\n </label>\n\n\n <div *ngIf=\"stopWord.selectedDatasource && stopWord.selectedDatasource.columns\">\n <label class=\"mb-4\">\n Stop Words Column\n <select matNativeControl [(ngModel)]=\"stopWord.datasourceColumn\">\n <option *ngFor=\"let column of stopWord.selectedDatasource.columns\"\n [ngValue]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n <small class=\"font-normal\">Select the column to use for the stop\n words</small>\n </label>\n\n <label class=\"mb-4\" *ngIf=\"datasource.config.maxPhraseLength > 1\">\n Min phrase length for including stop words\n <input type=\"number\" [min]=\"2\"\n [(ngModel)]=\"stopWord.minPhraseLength\">\n <small\n class=\"font-normal\">The {{stopWord.datasource ? stopWord.datasource.title : ''}}\n stop words will be included when the\n phrase length is greater than or equal to this value.</small>\n </label>\n </div>\n </div>\n\n <button mat-icon-button color=\"warn\" (click)=\"removeCustomStopWord(i)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n\n <hr class=\"my-4\">\n </ng-template>\n\n <button mat-button color=\"primary\"\n (click)=\"datasource.config.stopWords.push({custom: true})\">\n <mat-icon>add</mat-icon>\n Add Custom Stop Words\n </button>\n\n </div>\n </div>\n\n </ng-template>\n\n <div class=\"sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5\">\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Storage Options\n <div class=\"text-xs font-normal text-gray-500\">\n Securely save an original copy of the document and/or its original text.\n </div>\n </label>\n <div class=\"mt-1 sm:mt-0 sm:col-span-2\">\n <mat-checkbox class=\"block mb-2\" [(ngModel)]=\"datasource.config.storeOriginal\">Store\n Original File\n </mat-checkbox>\n <mat-checkbox class=\"block mb-2\" [(ngModel)]=\"datasource.config.storeText\">Store Document\n Text\n </mat-checkbox>\n </div>\n </div>\n\n </div>\n </div>\n\n </div>\n\n <div class=\"pt-5\">\n <div class=\"flex justify-end\">\n <button type=\"button\"\n class=\"bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none\">\n Cancel\n </button>\n <button type=\"submit\" [disabled]=\"!datasource.title\"\n class=\"disabled:opacity-50 ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-secondary focus:outline-none\"\n (click)=\"save()\">\n <ng-template [ngIf]=\"!datasourceKey\">\n Create Datasource\n </ng-template>\n <ng-template [ngIf]=\"datasourceKey\">\n Update Settings\n </ng-template>\n </button>\n </div>\n </div>\n</div>\n\n<ng-template [ngIf]=\"evaluatedDatasource\">\n\n\n <div class=\"overflow-scroll\">\n <table class=\"min-w-full border-separate bg-white\" style=\"border-spacing: 0\">\n <thead class=\"bg-gray-100\">\n <tr>\n <th *ngFor=\"let column of evaluatedDatasource.columns\" scope=\"col\"\n class=\"sticky top-0 z-10 border-b border-gray-300 bg-gray-50 bg-opacity-75 py-3.5 px-4 text-left text-xs font-semibold text-gray-900 backdrop-blur backdrop-filter\">\n {{column.title}}\n </th>\n </tr>\n </thead>\n <tbody class=\"bg-white\">\n <tr *ngFor=\"let data of evaluatedDatasource.allData\">\n <td *ngFor=\"let column of evaluatedDatasource.columns; let i = index\"\n [ngClass]=\"{'font-medium': i === 0}\"\n class=\"border-b border-gray-200 py-2 px-4 text-sm text-gray-900\">\n <ng-template [ngIf]=\"column.name === 'original_link'\">\n <a class=\"flex items-center text-cta hover:underline\" (click)=\"downloadDoc(data[column.name])\">\n {{data[column.name]}}\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"ml-1 h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\"/>\n </svg>\n </a>\n </ng-template>\n <ng-template [ngIf]=\"column.name !== 'original_link'\">\n <ng-template [ngIf]=\"data[column.name] && String(data[column.name]).length <= 100\">\n {{data[column.name]}}\n </ng-template>\n <ng-template [ngIf]=\"data[column.name] && String(data[column.name]).length > 100\">\n <div>{{data[column.name].substring(0, 100) + '...'}}</div>\n <a (click)=\"viewFullItemData(data[column.name], column.name)\"\n class=\"flex items-center text-sm text-cta hover:underline\">\n view more\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"ml-1 h-4 w-4\" fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\n </svg>\n </a>\n </ng-template>\n <ng-template [ngIf]=\"!data[column.name]\">\n {{data[column.name]}}\n </ng-template>\n </ng-template>\n </td>\n </tr>\n </tbody>\n\n </table>\n\n </div>\n <div class=\"bg-white p-4 flex align-center justify-end\">\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\" class=\"mr-8\">\n <option [value]=\"1\">1</option>\n <option [value]=\"5\">5</option>\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n\n</ng-template>\n", styles: [":host{display:block;background-color:#fff}.cell-header{width:100%;display:flex;align-items:center;justify-content:space-between}.cell-header.end{justify-content:flex-end}.transformation-listing{display:flex;align-items:center;flex-wrap:wrap;width:100%;border-bottom-color:#ddd;min-height:47px}.transformation-listing .list-title{text-transform:uppercase;font-size:.75rem;padding:0 1rem;border-right:2px solid #ddd;color:#4c4c4c;font-weight:500;letter-spacing:1px}.transformation-listing .badge-item{display:flex;align-items:center;margin-left:1rem;padding-left:1rem;border-radius:20px;background-color:#fff;border:1px solid #ddd;height:30px}.transformation-listing .badge-item.exclude{opacity:.8}.transformation-listing .badge-item:hover{background-color:#fcfcfc}.transformation-listing .badge-item span{margin-right:.5rem;color:#0000008a}.transformation-listing .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.transformation-listing .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}table{position:relative;border-collapse:collapse}table.sticky th{position:sticky;top:0;background-color:#f5f5f5;border-top:none!important;border-bottom:none!important;box-shadow:inset 0 -1px #ddd}table th.settings{padding:0}table td{max-width:400px;word-wrap:break-word;padding-top:.5rem;padding-bottom:.5rem;padding-right:1rem;min-width:100px;width:1%}table td.settings{max-width:25px;min-width:25px}table::-webkit-scrollbar{width:.75em;background:transparent}table::-webkit-scrollbar-thumb{background:#d2d2d2}\n"] }]
294
- }], ctorParameters: function () { return [{ type: i1.ActivatedRoute }, { type: i2.DatasourceService }, { type: i3.DatasetService }, { type: i4.MatLegacyDialog }]; }, propDecorators: { showCustomParser: [{
295
- type: Input
296
- }] } });
297
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9jdW1lbnQtZGF0YXNvdXJjZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1raW5pbnRlbC9zcmMvbGliL2NvbXBvbmVudHMvZGF0YXNvdXJjZS9kb2N1bWVudC1kYXRhc291cmNlL2RvY3VtZW50LWRhdGFzb3VyY2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcta2luaW50ZWwvc3JjL2xpYi9jb21wb25lbnRzL2RhdGFzb3VyY2UvZG9jdW1lbnQtZGF0YXNvdXJjZS9kb2N1bWVudC1kYXRhc291cmNlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQUUsS0FBSyxFQUFTLE1BQU0sZUFBZSxDQUFDO0FBRXZELE9BQU8sRUFBQyxlQUFlLEVBQVEsTUFBTSxNQUFNLENBQUM7QUFDNUMsT0FBTyxFQUFDLFlBQVksRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFHNUQsT0FBTyxFQUNILDJCQUEyQixFQUM5QixNQUFNLHVEQUF1RCxDQUFDO0FBRS9ELE9BQU8sS0FBSyxNQUFNLE1BQU0sUUFBUSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7QUFFakMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztBQU96QixNQUFNLE9BQU8sMkJBQTJCO0lBNkJwQyxZQUFvQixLQUFxQixFQUNyQixpQkFBb0MsRUFDcEMsY0FBOEIsRUFDOUIsTUFBaUI7UUFIakIsVUFBSyxHQUFMLEtBQUssQ0FBZ0I7UUFDckIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQUNwQyxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsV0FBTSxHQUFOLE1BQU0sQ0FBVztRQTNCOUIsZUFBVSxHQUFHLElBQUksZUFBZSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3JDLGlC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MkIsZ0hDbkJ4Qyx3NWlDQThpQkE7NEZEM2hCYSwyQkFBMkI7a0JBTHZDLFNBQVM7K0JBQ0ksd0JBQXdCO2dNQU16QixnQkFBZ0I7c0JBQXhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgSW5wdXQsIE9uSW5pdH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0FjdGl2YXRlZFJvdXRlfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHtCZWhhdmlvclN1YmplY3QsIG1lcmdlfSBmcm9tICdyeGpzJztcbmltcG9ydCB7ZGVib3VuY2VUaW1lLCBtYXAsIHN3aXRjaE1hcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtEYXRhc291cmNlU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvZGF0YXNvdXJjZS5zZXJ2aWNlJztcbmltcG9ydCB7RGF0YXNldFNlcnZpY2V9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2RhdGFzZXQuc2VydmljZSc7XG5pbXBvcnQge1xuICAgIERhdGFzZXRFZGl0b3JQb3B1cENvbXBvbmVudFxufSBmcm9tICcuLi8uLi9kYXRhc2V0L2RhdGFzZXQtZWRpdG9yL2RhdGFzZXQtZWRpdG9yLmNvbXBvbmVudCc7XG5pbXBvcnQge01hdExlZ2FjeURpYWxvZyBhcyBNYXREaWFsb2d9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2xlZ2FjeS1kaWFsb2cnO1xuaW1wb3J0ICogYXMgbG9kYXNoIGZyb20gJ2xvZGFzaCc7XG5cbmNvbnN0IF8gPSBsb2Rhc2guZGVmYXVsdDtcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdraS1kb2N1bWVudC1kYXRhc291cmNlJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vZG9jdW1lbnQtZGF0YXNvdXJjZS5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vZG9jdW1lbnQtZGF0YXNvdXJjZS5jb21wb25lbnQuc2FzcyddXG59KVxuZXhwb3J0IGNsYXNzIERvY3VtZW50RGF0YXNvdXJjZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgICBASW5wdXQoKSBzaG93Q3VzdG9tUGFyc2VyOiBib29sZWFuO1xuXG4gICAgcHVibGljIGRhdGFzb3VyY2VLZXk6IGFueTtcbiAgICBwdWJsaWMgc2VhcmNoVGV4dCA9IG5ldyBCZWhhdmlvclN1YmplY3QoJycpO1xuICAgIHB1YmxpYyBzZWFyY2hQYXJzZXIgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KCcnKTtcbiAgICBwdWJsaWMgZGF0YXNvdXJjZXM6IGFueSA9IFtdO1xuICAgIHB1YmxpYyBkb2N1bWVudFBhcnNlcnM6IGFueSA9IFtdO1xuICAgIHB1YmxpYyBzZWxlY3RlZERhdGFzb3VyY2U6IGFueTtcbiAgICBwdWJsaWMgZGF0YXNvdXJjZTogYW55ID0ge2NvbmZpZzoge3N0b3BXb3JkczogW119fTtcbiAgICBwdWJsaWMgZXZhbHVhdGVkRGF0YXNvdXJjZTogYW55O1xuICAgIHB1YmxpYyBzaG93U2V0dGluZ3MgPSB0cnVlO1xuICAgIHB1YmxpYyBzaG93VXBsb2FkID0gZmFsc2U7XG4gICAgcHVibGljIFN0cmluZyA9IFN0cmluZztcbiAgICBwdWJsaWMgZmlsZXM6IGFueSA9IG51bGw7XG4gICAgcHVibGljIF8gPSBfO1xuICAgIHB1YmxpYyBidWlsdEluU3RvcFdvcmRzID0ge1xuICAgICAgICBidWlsdEluOiBmYWxzZVxuICAgIH07XG4gICAgcHVibGljIHVwbG9hZFJlc3VsdHM6IGFueTtcbiAgICBwdWJsaWMgZmFpbGVkUmVzdWx0czogYW55ID0gW107XG4gICAgcHVibGljIHVwbG9hZGluZyA9IGZhbHNlO1xuICAgIHB1YmxpYyBwYWdlID0gMTtcbiAgICBwdWJsaWMgZW5kT2ZSZXN1bHRzID0gZmFsc2U7XG4gICAgcHVibGljIGxpbWl0ID0gMjU7XG5cbiAgICBwcml2YXRlIG9mZnNldCA9IDA7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIGRhdGFzb3VyY2VTZXJ2aWNlOiBEYXRhc291cmNlU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIGRhdGFzZXRTZXJ2aWNlOiBEYXRhc2V0U2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIGRpYWxvZzogTWF0RGlhbG9nKSB7XG4gICAgfVxuXG4gICAgYXN5bmMgbmdPbkluaXQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgdGhpcy5yb3V0ZS5wYXJhbXMuc3Vic2NyaWJlKGFzeW5jIHBhcmFtID0+IHtcbiAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZUtleSA9IHBhcmFtLmtleTtcbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGFzb3VyY2VLZXkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dTZXR0aW5ncyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZSA9IGF3YWl0IHRoaXMuZGF0YXNvdXJjZVNlcnZpY2UuZ2V0RGF0YXNvdXJjZSh0aGlzLmRhdGFzb3VyY2VLZXkpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5ldmFsdWF0ZURhdGFzb3VyY2UoKTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRhdGFzb3VyY2UuY29uZmlnLnN0b3BXb3JkcyAmJiB0aGlzLmRhdGFzb3VyY2UuY29uZmlnLnN0b3BXb3Jkcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzdG9wV29yZCBvZiB0aGlzLmRhdGFzb3VyY2UuY29uZmlnLnN0b3BXb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0b3BXb3JkLmN1c3RvbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3BXb3JkLmRhdGFzb3VyY2UgPSBhd2FpdCB0aGlzLmRhdGFzb3VyY2VTZXJ2aWNlLmdldERhdGFzb3VyY2Uoc3RvcFdvcmQuZGF0YXNvdXJjZUtleSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVEYXRhc291cmNlKHN0b3BXb3JkLCBzdG9wV29yZC5kYXRhc291cmNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdG9wV29yZC5idWlsdEluKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5idWlsdEluU3RvcFdvcmRzID0gc3RvcFdvcmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuc2VhcmNoVGV4dFxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgZGVib3VuY2VUaW1lKDMwMCksXG4gICAgICAgICAgICAgICAgLy8gZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXREYXRhc291cmNlcygpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKS5zdWJzY3JpYmUoKGRhdGFzb3VyY2VzOiBhbnkpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZXMgPSBkYXRhc291cmNlcztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zZWFyY2hQYXJzZXJcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIGRlYm91bmNlVGltZSgzMDApLFxuICAgICAgICAgICAgICAgIC8vIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0RG9jdW1lbnRQYXJzZXJzKClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApLnN1YnNjcmliZSgocGFyc2VyczogYW55KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50UGFyc2VycyA9IHBhcnNlcnM7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbmNyZWFzZU9mZnNldCgpIHtcbiAgICAgICAgdGhpcy5wYWdlID0gdGhpcy5wYWdlICsgMTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAodGhpcy5saW1pdCAqIHRoaXMucGFnZSkgLSB0aGlzLmxpbWl0O1xuICAgICAgICB0aGlzLmV2YWx1YXRlRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkZWNyZWFzZU9mZnNldCgpIHtcbiAgICAgICAgdGhpcy5wYWdlID0gdGhpcy5wYWdlIDw9IDEgPyAxIDogdGhpcy5wYWdlIC0gMTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAodGhpcy5saW1pdCAqIHRoaXMucGFnZSkgLSB0aGlzLmxpbWl0O1xuICAgICAgICB0aGlzLmV2YWx1YXRlRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBwYWdlU2l6ZUNoYW5nZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLmxpbWl0ID0gdmFsdWU7XG4gICAgICAgIHRoaXMuZXZhbHVhdGVEYXRhc291cmNlKHRydWUpO1xuICAgIH1cblxuICAgIHB1YmxpYyB2aWV3RnVsbEl0ZW1EYXRhKGRhdGEsIGNvbHVtbk5hbWUpIHtcbiAgICAgICAgdGhpcy5kaWFsb2cub3BlbihEYXRhc2V0RWRpdG9yUG9wdXBDb21wb25lbnQsIHtcbiAgICAgICAgICAgIHdpZHRoOiAnODAwcHgnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnNDAwcHgnLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIGZ1bGxEYXRhOiBkYXRhLFxuICAgICAgICAgICAgICAgIGNvbHVtbk5hbWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGluZGV4RG9jdW1lbnRDaGFuZ2UoY2hhbmdlKSB7XG4gICAgICAgIGlmIChjaGFuZ2UpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5kYXRhc291cmNlLmNvbmZpZy5taW5QaHJhc2VMZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2UuY29uZmlnLm1pblBocmFzZUxlbmd0aCA9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGF0YXNvdXJjZS5jb25maWcubWF4UGhyYXNlTGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhc291cmNlLmNvbmZpZy5tYXhQaHJhc2VMZW5ndGggPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGNodW5rQ29udGVudENoYW5nZShjaGFuZ2UpIHtcbiAgICAgICAgaWYgKGNoYW5nZSl7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGF0YXNvdXJjZS5jb25maWcuY2h1bmtDb250ZW50KXtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2UuY29uZmlnLmluZGV4Q2h1bmtzQnlBSSA9IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgdXBkYXRlQnVpbHRJblN0b3BXb3JkQ29uZmlnKHZhbHVlKSB7XG4gICAgICAgIF8ucmVtb3ZlKHRoaXMuZGF0YXNvdXJjZS5jb25maWcuc3RvcFdvcmRzLCBzdG9wV29yZCA9PiB7XG4gICAgICAgICAgICByZXR1cm4gc3RvcFdvcmQuYnVpbHRJbiAhPT0gdW5kZWZpbmVkO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCF0aGlzLmRhdGFzb3VyY2UuY29uZmlnLnN0b3BXb3Jkcykge1xuICAgICAgICAgICAgdGhpcy5kYXRhc291cmNlLmNvbmZpZy5zdG9wV29yZHMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRhdGFzb3VyY2UuY29uZmlnLnN0b3BXb3Jkcy5wdXNoKHRoaXMuYnVpbHRJblN0b3BXb3Jkcyk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlbW92ZUN1c3RvbVN0b3BXb3JkKGluZGV4KSB7XG4gICAgICAgIHRoaXMuZGF0YXNvdXJjZS5jb25maWcuc3RvcFdvcmRzLnNwbGljZShpbmRleCwgMSk7XG4gICAgfVxuXG4gICAgcHVibGljIGh1bWFuRmlsZVNpemUoc2l6ZTogYW55KSB7XG4gICAgICAgIGNvbnN0IGkgPSBzaXplID09PSAwID8gMCA6IE1hdGguZmxvb3IoTWF0aC5sb2coc2l6ZSkgLyBNYXRoLmxvZygxMDI0KSk7XG4gICAgICAgIHJldHVybiBOdW1iZXIoKHNpemUgLyBNYXRoLnBvdygxMDI0LCBpKSkudG9GaXhlZCgyKSkgKiAxICsgJyAnICsgWydCJywgJ2tCJywgJ01CJywgJ0dCJywgJ1RCJ11baV07XG4gICAgfVxuXG4gICAgcHVibGljIGRpc3BsYXlGbihkYXRhc2V0KTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIGRhdGFzZXQgJiYgZGF0YXNldC50aXRsZSA/IGRhdGFzZXQudGl0bGUgOiAnJztcbiAgICB9XG5cbiAgICBwdWJsaWMgZHJhZ092ZXJIYW5kbGVyKGV2KSB7XG4gICAgICAgIC8vIFByZXZlbnQgZGVmYXVsdCBiZWhhdmlvciAoUHJldmVudCBmaWxlIGZyb20gYmVpbmcgb3BlbmVkKVxuICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkcm9wSGFuZGxlcihldikge1xuICAgICAgICAvLyBQcmV2ZW50IGRlZmF1bHQgYmVoYXZpb3IgKFByZXZlbnQgZmlsZSBmcm9tIGJlaW5nIG9wZW5lZClcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICB0aGlzLmZpbGVzID0gW107XG5cbiAgICAgICAgaWYgKGV2LmRhdGFUcmFuc2Zlci5pdGVtcykge1xuICAgICAgICAgICAgLy8gVXNlIERhdGFUcmFuc2Zlckl0ZW1MaXN0IGludGVyZmFjZSB0byBhY2Nlc3MgdGhlIGZpbGUocylcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXYuZGF0YVRyYW5zZmVyLml0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgZHJvcHBlZCBpdGVtcyBhcmVuJ3QgZmlsZXMsIHJlamVjdCB0aGVtXG4gICAgICAgICAgICAgICAgaWYgKGV2LmRhdGFUcmFuc2Zlci5pdGVtc1tpXS5raW5kID09PSAnZmlsZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlsZSA9IGV2LmRhdGFUcmFuc2Zlci5pdGVtc1tpXS5nZXRBc0ZpbGUoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maWxlcy5wdXNoKGZpbGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFVzZSBEYXRhVHJhbnNmZXIgaW50ZXJmYWNlIHRvIGFjY2VzcyB0aGUgZmlsZShzKVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBldi5kYXRhVHJhbnNmZXIuZmlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWxlID0gZXYuZGF0YVRyYW5zZmVyLmZpbGVzW2ldO1xuICAgICAgICAgICAgICAgIHRoaXMuZmlsZXMucHVzaChmaWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBmaWxlVXBsb2FkKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuZmlsZXMgPSBBcnJheS5mcm9tKGV2ZW50LnRhcmdldC5maWxlcyk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlbW92ZUZpbGUoaW5kZXgpIHtcbiAgICAgICAgdGhpcy5maWxlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkb3dubG9hZERvYyh1cmwpIHtcbiAgICAgICAgd2luZG93Lm9wZW4odXJsKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgdXBsb2FkRmlsZXMoKSB7XG4gICAgICAgIGNvbnN0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG5cbiAgICAgICAgZm9yIChjb25zdCBmaWxlIG9mIHRoaXMuZmlsZXMpIHtcblxuICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKGZpbGUubmFtZSwgZmlsZSk7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLnVwbG9hZERhdGFzb3VyY2VEb2N1bWVudHMoZm9ybURhdGEpO1xuICAgICAgICB0aGlzLmV2YWx1YXRlRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyB1cGRhdGVEYXRhc291cmNlKHN0b3BXb3JkLCBkYXRhc291cmNlKSB7XG4gICAgICAgIHN0b3BXb3JkLmRhdGFzb3VyY2VLZXkgPSBkYXRhc291cmNlLmtleTtcbiAgICAgICAgc3RvcFdvcmQuZGF0YXNvdXJjZSA9IGRhdGFzb3VyY2U7XG5cbiAgICAgICAgY29uc3QgZGF0YXNldEluc3RhbmNlU3VtbWFyeSA9IHtcbiAgICAgICAgICAgIGRhdGFzZXRJbnN0YW5jZUlkOiBudWxsLFxuICAgICAgICAgICAgZGF0YXNvdXJjZUluc3RhbmNlS2V5OiBkYXRhc291cmNlLmtleSxcbiAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzOiBbXSxcbiAgICAgICAgICAgIHBhcmFtZXRlclZhbHVlczoge30sXG4gICAgICAgICAgICBwYXJhbWV0ZXJzOiBbXSxcbiAgICAgICAgICAgIG9yaWdpbkRhdGFJdGVtVGl0bGU6IGRhdGFzb3VyY2UudGl0bGVcbiAgICAgICAgfTtcblxuICAgICAgICBzdG9wV29yZC5zZWxlY3RlZERhdGFzb3VyY2UgPSBhd2FpdCB0aGlzLmRhdGFzZXRTZXJ2aWNlLmV2YWx1YXRlRGF0YXNldChkYXRhc2V0SW5zdGFuY2VTdW1tYXJ5LCAnMCcsICcxJyk7XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZUN1c3RvbVBhcnNlcih2YWx1ZSkge1xuICAgICAgICB0aGlzLmRhdGFzb3VyY2UuY29uZmlnLmN1c3RvbURvY3VtZW50UGFyc2VyID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNhdmUoKSB7XG4gICAgICAgIGlmICghdGhpcy5kYXRhc291cmNlS2V5KSB7XG4gICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2VLZXkgPSBhd2FpdCB0aGlzLmRhdGFzb3VyY2VTZXJ2aWNlLmNyZWF0ZURvY3VtZW50RGF0YXNvdXJjZSh0aGlzLmRhdGFzb3VyY2UpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5maWxlcyAmJiB0aGlzLmZpbGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMudXBsb2FkRmlsZXMoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmV2YWx1YXRlRGF0YXNvdXJjZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmICsgJy8nICsgdGhpcy5kYXRhc291cmNlS2V5O1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmRhdGFzb3VyY2VTZXJ2aWNlLnVwZGF0ZURhdGFzb3VyY2VJbnN0YW5jZSh0aGlzLmRhdGFzb3VyY2VLZXksIHRoaXMuZGF0YXNvdXJjZSk7XG5cbiAgICAgICAgICAgIHRoaXMuZXZhbHVhdGVEYXRhc291cmNlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERhdGFzb3VyY2VzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRhc291cmNlU2VydmljZS5nZXREYXRhc291cmNlcyhcbiAgICAgICAgICAgIHRoaXMuc2VhcmNoVGV4dC5nZXRWYWx1ZSgpIHx8ICcnLFxuICAgICAgICAgICAgJzEwJyxcbiAgICAgICAgICAgICcwJ1xuICAgICAgICApLnBpcGUobWFwKChkYXRhc291cmNlczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGFzb3VyY2VzO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERvY3VtZW50UGFyc2VycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YXNvdXJjZVNlcnZpY2UuZ2V0RGF0YXNvdXJjZXMoXG4gICAgICAgICAgICB0aGlzLnNlYXJjaFRleHQuZ2V0VmFsdWUoKSB8fCAnJyxcbiAgICAgICAgICAgICcxMCcsXG4gICAgICAgICAgICAnMCdcbiAgICAgICAgKS5waXBlKG1hcCgoZGF0YXNvdXJjZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnUGxlbmlwb3QgQnVjaGFyZXN0IDIyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiAncGxlbmlwb3RCdWNoYXJlc3QyMidcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdJVFUgU3R1ZHkgR3JvdXAnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6ICdpdHVzdHVkeWdyb3VwJ1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ0lFVEYgSW50ZXJuZXQgRHJhZnRzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiAnaWV0ZmludGVybmV0ZHJhZnRzJ1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ1dUU0EnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6ICd3dHNhJ1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ1dUREMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6ICd3dGRjJ1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyB1cGxvYWREYXRhc291cmNlRG9jdW1lbnRzKGZvcm1EYXRhKSB7XG4gICAgICAgIHRoaXMudXBsb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgdHJhY2tpbmdLZXkgPSBEYXRlLm5vdygpICsgKE1hdGgucmFuZG9tKCkgKyAxKS50b1N0cmluZygzNikuc3Vic3RyKDIsIDUpO1xuXG4gICAgICAgIHRoaXMuZGF0YXNvdXJjZVNlcnZpY2UudXBsb2FkRGF0YXNvdXJjZURvY3VtZW50cyh0aGlzLmRhdGFzb3VyY2VLZXksIGZvcm1EYXRhLCB0cmFja2luZ0tleSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgIC8vIElnbm9yZSAtIHdlIGhhdmUgc2V0IG9mZiBhIGxvbmctcnVubmluZyB0YXNrIHdoaWNoIHdlIGFyZSB0cmFja2luZyBiZWxvd1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmZpbGVzID0gbnVsbDtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0U3ViID0gdGhpcy5kYXRhc291cmNlU2VydmljZS5nZXREYXRhVHJhY2tpbmdSZXN1bHRzKHRyYWNraW5nS2V5KS5zdWJzY3JpYmUoKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkUmVzdWx0cyA9IHJlcztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlcyAmJiByZXMuc3RhdHVzID09PSAnQ09NUExFVEVEJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mYWlsZWRSZXN1bHRzID0gcmVzLnByb2dyZXNzRGF0YS5mYWlsZWQgfHwgW107XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGxvYWRSZXN1bHRzID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZhaWxlZFJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDUwMDApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCAxMDApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGV2YWx1YXRlRGF0YXNvdXJjZShyZXNldFBhZ2VyID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKHJlc2V0UGFnZXIpIHtcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgICAgICAgICAgIHRoaXMucGFnZSA9IDE7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRhdGFzb3VyY2UubGltaXQgPSB0aGlzLmxpbWl0O1xuICAgICAgICB0aGlzLmRhdGFzb3VyY2Uub2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIHRoaXMuZXZhbHVhdGVkRGF0YXNvdXJjZSA9IGF3YWl0IHRoaXMuZGF0YXNvdXJjZVNlcnZpY2UuZXZhbHVhdGVEYXRhc291cmNlKHRoaXMuZGF0YXNvdXJjZSk7XG4gICAgICAgIHRoaXMuZXZhbHVhdGVkRGF0YXNvdXJjZS5hbGxEYXRhLm1hcChkYXRhID0+IHtcbiAgICAgICAgICAgIGlmIChkYXRhLmZpbGVfc2l6ZSkge1xuICAgICAgICAgICAgICAgIGRhdGEuZmlsZV9zaXplID0gdGhpcy5odW1hbkZpbGVTaXplKGRhdGEuZmlsZV9zaXplKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRhLmZpbGVfdHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmRvY3VtZW50Jykge1xuICAgICAgICAgICAgICAgIGRhdGEuZmlsZV90eXBlID0gJ2FwcGxpY2F0aW9uL2RvY3gnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuZW5kT2ZSZXN1bHRzID0gdGhpcy5ldmFsdWF0ZWREYXRhc291cmNlLmFsbERhdGEubGVuZ3RoIDwgdGhpcy5saW1pdDtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwicC02IGJnLXdoaXRlIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMFwiPlxuICAgIDxkaXYgY2xhc3M9XCJtZDpmbGV4IG1kOml0ZW1zLWNlbnRlciBtZDpqdXN0aWZ5LWJldHdlZW4gbWQ6c3BhY2UteC01XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0IGZsZXgtMVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB0LTEuNVwiPlxuICAgICAgICAgICAgICAgIDxoMSBjbGFzcz1cInRleHQtMnhsIGZvbnQtYm9sZCB0ZXh0LWdyYXktOTAwXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IWRhdGFzb3VyY2VLZXkgPyAnRG9jdW1lbnQgRGF0YXNvdXJjZScgOiAoZGF0YXNvdXJjZS50aXRsZSB8fCAnRG9jdW1lbnQgRGF0YXNvdXJjZScpfX1cbiAgICAgICAgICAgICAgICA8L2gxPlxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCIhZGF0YXNvdXJjZUtleVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgVXBsb2FkIHlvdXIgZG9jdW1lbnRzIHVzaW5nIHRoZSBmb3JtIGJlbG93LlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZGF0YXNvdXJjZUtleVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgVmlldyB5b3VyIGV4aXN0aW5nIGRvY3VtZW50cyBiZWxvdyBhbmQgYWRqdXN0IGFueSBkb2N1bWVudCBzZXR0aW5ncyBoZXJlLlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm10LTYgZmxleCBmbGV4LWNvbC1yZXZlcnNlIGp1c3RpZnktc3RyZXRjaFwiICpuZ0lmPVwiZGF0YXNvdXJjZUtleVwiPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cInNob3dVcGxvYWQgPSAhc2hvd1VwbG9hZFwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW5saW5lLWZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHB4LTQgcHktMiBib3JkZXIgYm9yZGVyLXRyYW5zcGFyZW50IHRleHQtc20gZm9udC1tZWRpdW0gcm91bmRlZC1tZCBzaGFkb3ctc20gdGV4dC13aGl0ZSBiZy1wcmltYXJ5IGZvY3VzOm91dGxpbmUtbm9uZVwiPlxuICAgICAgICAgICAgICAgIFVwbG9hZCBBZGRpdGlvbmFsIERvY3VtZW50c1xuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+XG5cbjxkaXYgY2xhc3M9XCJiZy1ibHVlLTUwIHAtNFwiICpuZ0lmPVwidXBsb2FkaW5nXCI+XG4gICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtc2hyaW5rLTBcIj5cbiAgICAgICAgICAgIDwhLS0gSGVyb2ljb24gbmFtZTogc29saWQvaW5mb3JtYXRpb24tY2lyY2xlIC0tPlxuICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImgtNSB3LTUgdGV4dC1wcmltYXJ5XCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjAgMjBcIlxuICAgICAgICAgICAgICAgICBmaWxsPVwiY3VycmVudENvbG9yXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiXG4gICAgICAgICAgICAgICAgICAgICAgZD1cIk0xOCAxMGE4IDggMCAxMS0xNiAwIDggOCAwIDAxMTYgMHptLTctNGExIDEgMCAxMS0yIDAgMSAxIDAgMDEyIDB6TTkgOWExIDEgMCAwMDAgMnYzYTEgMSAwIDAwMSAxaDFhMSAxIDAgMTAwLTJ2LTNhMSAxIDAgMDAtMS0xSDl6XCJcbiAgICAgICAgICAgICAgICAgICAgICBjbGlwLXJ1bGU9XCJldmVub2RkXCIvPlxuICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwibWwtMyB3LWZ1bGxcIj5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC1zbSB0ZXh0LXByaW1hcnkgZm9udC1tZWRpdW1cIj5Qcm9ncmVzczwvcD5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJ1cGxvYWRSZXN1bHRzICYmIHVwbG9hZFJlc3VsdHMucHJvZ3Jlc3NEYXRhXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtcHJpbWFyeSBteS0yXCI+VXBsb2FkZWQge3t1cGxvYWRSZXN1bHRzLnByb2dyZXNzRGF0YS5jb21wbGV0ZWR9fVxuICAgICAgICAgICAgICAgICAgICAve3t1cGxvYWRSZXN1bHRzLnByb2dyZXNzRGF0YS50b3RhbH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPG1hdC1wcm9ncmVzcy1iYXIgY2xhc3M9XCJ3LWZ1bGwgbXktNFwiIG1vZGU9XCJkZXRlcm1pbmF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cIih1cGxvYWRSZXN1bHRzLnByb2dyZXNzRGF0YS5jb21wbGV0ZWQvdXBsb2FkUmVzdWx0cy5wcm9ncmVzc0RhdGEudG90YWwpICogMTAwXCI+PC9tYXQtcHJvZ3Jlc3MtYmFyPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCIhdXBsb2FkUmVzdWx0cyB8fCAhdXBsb2FkUmVzdWx0cy5wcm9ncmVzc0RhdGFcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1wcmltYXJ5IG15LTJcIj5QcmVwYXJpbmcgVXBsb2FkLi4uPC9kaXY+XG4gICAgICAgICAgICAgICAgPG1hdC1wcm9ncmVzcy1iYXIgY2xhc3M9XCJ3LWZ1bGwgbXktNFwiIG1vZGU9XCJidWZmZXJcIj48L21hdC1wcm9ncmVzcy1iYXI+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuXG48ZGl2IGNsYXNzPVwiYmctZ3JlZW4tNTAgcC00XCIgKm5nSWY9XCIhZmFpbGVkUmVzdWx0cy5sZW5ndGggJiYgdXBsb2FkUmVzdWx0cyAmJiAhdXBsb2FkaW5nXCI+XG4gICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtc2hyaW5rLTBcIj5cbiAgICAgICAgICAgIDwhLS0gSGVyb2ljb24gbmFtZTogc29saWQvY2hlY2stY2lyY2xlIC0tPlxuICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImgtNSB3LTUgdGV4dC1ncmVlbi00MDBcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiXG4gICAgICAgICAgICAgICAgIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCJcbiAgICAgICAgICAgICAgICAgICAgICBkPVwiTTEwIDE4YTggOCAwIDEwMC0xNiA4IDggMCAwMDAgMTZ6bTMuNzA3LTkuMjkzYTEgMSAwIDAwLTEuNDE0LTEuNDE0TDkgMTAuNTg2IDcuNzA3IDkuMjkzYTEgMSAwIDAwLTEuNDE0IDEuNDE0bDIgMmExIDEgMCAwMDEuNDE0IDBsNC00elwiXG4gICAgICAgICAgICAgICAgICAgICAgY2xpcC1ydWxlPVwiZXZlbm9kZFwiLz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1sLTNcIj5cbiAgICAgICAgICAgIDxoMyBjbGFzcz1cInRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmVlbi04MDBcIj5VcGxvYWQgY29tcGxldGVkPC9oMz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0yIHRleHQtc20gdGV4dC1ncmVlbi03MDBcIj5cbiAgICAgICAgICAgICAgICA8cD48Yj57e3VwbG9hZFJlc3VsdHMucHJvZ3Jlc3NEYXRhLmNvbXBsZXRlZH19PC9iPiBmaWxlcyB3ZXJlIHByb2Nlc3NlZCBzdWNjZXNzZnVsbHkgb3V0IG9mXG4gICAgICAgICAgICAgICAgICAgIDxiPnt7dXBsb2FkUmVzdWx0cy5wcm9ncmVzc0RhdGEudG90YWx9fTwvYj4gdXBsb2FkZWQgaXRlbXMuPC9wPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+XG5cbjxkaXYgY2xhc3M9XCJiZy1yZWQtNTAgcC00XCIgKm5nSWY9XCJmYWlsZWRSZXN1bHRzLmxlbmd0aCAmJiB1cGxvYWRSZXN1bHRzXCI+XG4gICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtc2hyaW5rLTBcIj5cbiAgICAgICAgICAgIDwhLS0gSGVyb2ljb24gbmFtZTogc29saWQveC1jaXJjbGUgLS0+XG4gICAgICAgICAgICA8c3ZnIGNsYXNzPVwiaC01IHctNSB0ZXh0LXJlZC00MDBcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIlxuICAgICAgICAgICAgICAgICBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCJcbiAgICAgICAgICAgICAgICAgICAgICBkPVwiTTEwIDE4YTggOCAwIDEwMC0xNiA4IDggMCAwMDAgMTZ6TTguNzA3IDcuMjkzYTEgMSAwIDAwLTEuNDE0IDEuNDE0TDguNTg2IDEwbC0xLjI5MyAxLjI5M2ExIDEgMCAxMDEuNDE0IDEuNDE0TDEwIDExLjQxNGwxLjI5MyAxLjI5M2ExIDEgMCAwMDEuNDE0LTEuNDE0TDExLjQxNCAxMGwxLjI5My0xLjI5M2ExIDEgMCAwMC0xLjQxNC0xLjQxNEwxMCA4LjU4NiA4LjcwNyA3LjI5M3pcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsaXAtcnVsZT1cImV2ZW5vZGRcIi8+XG4gICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtbC0zXCI+XG4gICAgICAgICAgICA8aDMgY2xhc3M9XCJ0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtcmVkLTgwMFwiPlRoZXJlIHdlcmUge3tmYWlsZWRSZXN1bHRzLmxlbmd0aH19IGVycm9ycyB3aXRoIHlvdXJcbiAgICAgICAgICAgICAgICBzdWJtaXNzaW9uPC9oMz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0yIHRleHQtc20gdGV4dC1yZWQtNzAwXCI+XG4gICAgICAgICAgICAgICAgPHVsIHJvbGU9XCJsaXN0XCIgY2xhc3M9XCJsaXN0LWRpc2MgcGwtNSBzcGFjZS15LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxpICpuZ0Zvcj1cImxldCBmYWlsZWRSZXN1bHQgb2YgZmFpbGVkUmVzdWx0c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3tmYWlsZWRSZXN1bHQubWVzc2FnZX19XG4gICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuXG48ZGl2ICpuZ0lmPVwic2hvd1VwbG9hZFwiXG4gICAgIGNsYXNzPVwic3BhY2UteS04IHAtNiBiZy1ncmF5LTUwIGJvcmRlci1iXCI+XG4gICAgPGRpdiBjbGFzcz1cInNwYWNlLXktOCBzbTpzcGFjZS15LTVcIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcGFjZS15LTYgc206c3BhY2UteS01XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNtOmdyaWQgc206Z3JpZC1jb2xzLTMgc206Z2FwLTQgc206aXRlbXMtc3RhcnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBVcGxvYWQgRG9jdW1lbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkaXRpb25hbCBkb2N1bWVudHMgdG8gYmUgcHJvY2Vzc2VkLlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xIHNtOm10LTAgc206Y29sLXNwYW4tMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFmaWxlcyB8fCAhZmlsZXMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRyb3ApPVwiZHJvcEhhbmRsZXIoJGV2ZW50KVwiIChkcmFnb3Zlcik9XCJkcmFnT3ZlckhhbmRsZXIoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy1mdWxsIGZsZXgganVzdGlmeS1jZW50ZXIgcHgtNiBwdC01IHBiLTYgYm9yZGVyLTIgYm9yZGVyLWdyYXktMzAwIGJvcmRlci1kYXNoZWQgcm91bmRlZC1tZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcGFjZS15LTEgdGV4dC1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyBjbGFzcz1cIm14LWF1dG8gaC0xMiB3LTEyIHRleHQtZ3JheS00MDBcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBmaWxsPVwibm9uZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld0JveD1cIjAgMCA0OCA0OFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTI4IDhIMTJhNCA0IDAgMDAtNCA0djIwbTMyLTEydjhtMCAwdjhhNCA0IDAgMDEtNCA0SDEyYTQgNCAwIDAxLTQtNHYtNG0zMi00bC0zLjE3Mi0zLjE3MmE0IDQgMCAwMC01LjY1NiAwTDI4IDI4TTggMzJsOS4xNzItOS4xNzJhNCA0IDAgMDE1LjY1NiAwTDI4IDI4bTAgMGw0IDRtNC0yNGg4bS00LTR2OG0tMTIgNGguMDJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCB0ZXh0LXNtIHRleHQtZ3JheS02MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicmVsYXRpdmUgY3Vyc29yLXBvaW50ZXIgcm91bmRlZC1tZCBmb250LW1lZGl1bSB0ZXh0LXNlY29uZGFyeSBmb2N1cy13aXRoaW46b3V0bGluZS1ub25lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+U2VsZWN0IGZpbGUocykgdG8gdXBsb2FkPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBuYW1lPVwiYWRkaXRpb25hbFVwbG9hZFwiIG11bHRpcGxlIHR5cGU9XCJmaWxlXCIgY2xhc3M9XCJzci1vbmx5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJmaWxlVXBsb2FkKCRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInBsLTEgbWItMFwiPm9yIGRyYWcgYW5kIGRyb3A8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQteHMgdGV4dC1ncmF5LTUwMFwiPi5kb2N4LCAudHh0LCAucGZkLCAuemlwPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZmlsZXMgJiYgZmlsZXMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJvdmVyZmxvdy1oaWRkZW4gc2hhZG93IHJpbmctMSByaW5nLWJsYWNrIHJpbmctb3BhY2l0eS01IG1kOnJvdW5kZWQtbGdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJtaW4tdy1mdWxsIGRpdmlkZS15IGRpdmlkZS1ncmF5LTMwMCBibG9jayBvdmVyZmxvdy15LWF1dG8gbWF4LWgtNDhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoZWFkIGNsYXNzPVwiYmctZ3JheS01MFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIiBjb2xzcGFuPVwiMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzdGlja3kgdG9wLTAgei0xMCBiZy1ncmF5LTEwMCBweS0yIHBsLTQgcHItMyB0ZXh0LWxlZnQgdGV4dC1zbSBmb250LXNlbWlib2xkIHRleHQtZ3JheS05MDAgc206cGwtNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdGVkIEZpbGUgUHJldmlld1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC14cyB0ZXh0LWdyYXktNTAwIGxvd2VyY2FzZSBtbC00IGZvbnQtbm9ybWFsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWNrIDxzcGFuIGNsYXNzPVwiZm9udC1tZWRpdW1cIj4nVXBsb2FkIEZpbGVzJzwvc3Bhbj4gdG8gdXBsb2FkIHRoZSBzZWxlY3RlZCBmaWxlcy48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJkaXZpZGUteSBkaXZpZGUtZ3JheS0yMDAgYmctd2hpdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBmaWxlIG9mIGZpbGVzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aGl0ZXNwYWNlLW5vd3JhcCBweS0yIHBsLTQgcHItMyB0ZXh0LXhzIGZvbnQtbWVkaXVtIHRleHQtZ3JheS05MDAgc206cGwtNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZmlsZS5uYW1lfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJyZWxhdGl2ZSB3aGl0ZXNwYWNlLW5vd3JhcCBweS0yIHBsLTMgcHItNCB0ZXh0LXJpZ2h0IHRleHQtc20gZm9udC1tZWRpdW0gc206cHItNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIChjbGljayk9XCJyZW1vdmVGaWxlKGkpXCIgY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPlJlbW92ZTwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgganVzdGlmeS1lbmRcIj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJzaG93VXBsb2FkID0gZmFsc2U7ZmlsZXMgPSBudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJiZy13aGl0ZSBweS0yIHB4LTQgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCByb3VuZGVkLW1kIHNoYWRvdy1zbSB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS03MDAgaG92ZXI6YmctZ3JheS01MCBmb2N1czpvdXRsaW5lLW5vbmVcIj5cbiAgICAgICAgICAgICAgICBDYW5jZWxcbiAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiBbZGlzYWJsZWRdPVwiIWZpbGVzXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkaXNhYmxlZDpvcGFjaXR5LTUwIG1sLTMgaW5saW5lLWZsZXgganVzdGlmeS1jZW50ZXIgcHktMiBweC00IGJvcmRlciBib3JkZXItdHJhbnNwYXJlbnQgc2hhZG93LXNtIHRleHQtc20gZm9udC1tZWRpdW0gcm91bmRlZC1tZCB0ZXh0LXdoaXRlIGJnLXNlY29uZGFyeSBmb2N1czpvdXRsaW5lLW5vbmVcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwidXBsb2FkRmlsZXMoKVwiPlVwbG9hZCBGaWxlc1xuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+XG5cbjxkaXYgY2xhc3M9XCJ0cmFuc2Zvcm1hdGlvbi1saXN0aW5nIHB5LTIgYmctZ3JheS01MCBjdXJzb3ItcG9pbnRlclwiXG4gICAgIChjbGljayk9XCJzaG93U2V0dGluZ3MgPSAhc2hvd1NldHRpbmdzXCIgW25nQ2xhc3NdPVwieydib3JkZXItYic6ICFzaG93U2V0dGluZ3N9XCI+XG4gICAgPGEgY2xhc3M9XCJsaXN0LXRpdGxlIGZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgIFNldHRpbmdzJm5ic3A7XG4gICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFzaG93U2V0dGluZ3NcIj5leHBhbmRfbW9yZTwvbWF0LWljb24+XG4gICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cInNob3dTZXR0aW5nc1wiPmV4cGFuZF9sZXNzPC9tYXQtaWNvbj5cbiAgICA8L2E+XG4gICAgPGRpdiBjbGFzcz1cIm1sLTYgdGV4dC14cyB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgIEFkanVzdCB0aGUgcnVsZXMgYXJvdW5kIGhvdyB0aGUgdXBsb2FkZWQgZG9jdW1lbnRzIHdpbGxcbiAgICAgICAgYmUgcHJvY2Vzc2VkLlxuICAgIDwvZGl2PlxuPC9kaXY+XG5cbjxkaXYgKm5nSWY9XCJzaG93U2V0dGluZ3NcIiBbbmdDbGFzc109XCJ7J2JvcmRlci1iJzogc2hvd1NldHRpbmdzfVwiXG4gICAgIGNsYXNzPVwic3BhY2UteS04IGRpdmlkZS15IGRpdmlkZS1ncmF5LTIwMCBwLTYgYmctZ3JheS01MFwiPlxuICAgIDxkaXYgY2xhc3M9XCJzcGFjZS15LTggZGl2aWRlLXkgZGl2aWRlLWdyYXktMjAwIHNtOnNwYWNlLXktNVwiPlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwYWNlLXktNiBzbTpzcGFjZS15LTVcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic206Z3JpZCBzbTpncmlkLWNvbHMtMyBzbTpnYXAtNCBzbTppdGVtcy1zdGFydFwiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJibG9jayB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS03MDAgc206bXQtcHggc206cHQtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgVGl0bGVcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj5FbnRlciB0aGUgbmFtZSB0byBpZGVudGlmeSB0aGlzIGRhdGEgc291cmNlPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xIHNtOm10LTAgc206Y29sLXNwYW4tMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJkYXRhc291cmNlLnRpdGxlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1heC13LWxnIGJsb2NrIHctZnVsbCBzaGFkb3ctc20gZm9jdXM6cmluZy1pbmRpZ28tNTAwIGZvY3VzOmJvcmRlci1pbmRpZ28tNTAwIHNtOm1heC13LXhzIHNtOnRleHQtc20gYm9yZGVyLWdyYXktMzAwIHJvdW5kZWQtbWRcIj5cblxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhZGF0YXNvdXJjZUtleVwiXG4gICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNtOmdyaWQgc206Z3JpZC1jb2xzLTMgc206Z2FwLTQgc206aXRlbXMtc3RhcnQgc206Ym9yZGVyLXQgc206Ym9yZGVyLWdyYXktMjAwIHNtOnB0LTVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwIHNtOm10LXB4IHNtOnB0LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIFVwbG9hZCBEb2N1bWVudHNcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGUgZG9jdW1lbnRzIHRvIGJlIHByb2Nlc3NlZC5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMSBzbTptdC0wIHNtOmNvbC1zcGFuLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhZmlsZXMgfHwgIWZpbGVzLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkcm9wKT1cImRyb3BIYW5kbGVyKCRldmVudClcIiAoZHJhZ292ZXIpPVwiZHJhZ092ZXJIYW5kbGVyKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInctZnVsbCBmbGV4IGp1c3RpZnktY2VudGVyIHB4LTYgcHQtNSBwYi02IGJvcmRlci0yIGJvcmRlci1ncmF5LTMwMCBib3JkZXItZGFzaGVkIHJvdW5kZWQtbWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3BhY2UteS0xIHRleHQtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJteC1hdXRvIGgtMTIgdy0xMiB0ZXh0LWdyYXktNDAwXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgNDggNDhcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0yOCA4SDEyYTQgNCAwIDAwLTQgNHYyMG0zMi0xMnY4bTAgMHY4YTQgNCAwIDAxLTQgNEgxMmE0IDQgMCAwMS00LTR2LTRtMzItNGwtMy4xNzItMy4xNzJhNCA0IDAgMDAtNS42NTYgMEwyOCAyOE04IDMybDkuMTcyLTkuMTcyYTQgNCAwIDAxNS42NTYgMEwyOCAyOG0wIDBsNCA0bTQtMjRoOG0tNC00djhtLTEyIDRoLjAyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggdGV4dC1zbSB0ZXh0LWdyYXktNjAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInJlbGF0aXZlIGN1cnNvci1wb2ludGVyIHJvdW5kZWQtbWQgZm9udC1tZWRpdW0gdGV4dC1zZWNvbmRhcnkgZm9jdXMtd2l0aGluOm91dGxpbmUtbm9uZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPlNlbGVjdCBmaWxlKHMpIHRvIHVwbG9hZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbmFtZT1cImFkZGl0aW9uYWxVcGxvYWRcIiBtdWx0aXBsZSB0eXBlPVwiZmlsZVwiIGNsYXNzPVwic3Itb25seVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwiZmlsZVVwbG9hZCgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJwbC0xIG1iLTBcIj5vciBkcmFnIGFuZCBkcm9wPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXhzIHRleHQtZ3JheS01MDBcIj4uZG9jeCwgLnR4dCwgLnBmZCwgLnppcDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImZpbGVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJvdmVyZmxvdy1oaWRkZW4gc2hhZG93IHJpbmctMSByaW5nLWJsYWNrIHJpbmctb3BhY2l0eS01IG1kOnJvdW5kZWQtbGdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJtaW4tdy1mdWxsIGRpdmlkZS15IGRpdmlkZS1ncmF5LTMwMCBibG9jayBvdmVyZmxvdy15LWF1dG8gbWF4LWgtNDhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoZWFkIGNsYXNzPVwiYmctZ3JheS01MFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIiBjb2xzcGFuPVwiMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzdGlja3kgdG9wLTAgei0xMCBiZy1ncmF5LTEwMCBweS0yIHBsLTQgcHItMyB0ZXh0LWxlZnQgdGV4dC1zbSBmb250LXNlbWlib2xkIHRleHQtZ3JheS05MDAgc206cGwtNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdGVkIEZpbGUgUHJldmlld1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC14cyB0ZXh0LWdyYXktNTAwIGxvd2VyY2FzZSBtbC00IGZvbnQtbm9ybWFsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWNrIDxzcGFuIGNsYXNzPVwiZm9udC1tZWRpdW1cIj4nVXBsb2FkIEZpbGVzJzwvc3Bhbj4gdG8gdXBsb2FkIHRoZSBzZWxlY3RlZCBmaWxlcy48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJkaXZpZGUteSBkaXZpZGUtZ3JheS0yMDAgYmctd2hpdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBmaWxlIG9mIGZpbGVzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aGl0ZXNwYWNlLW5vd3JhcCBweS0yIHBsLTQgcHItMyB0ZXh0LXhzIGZvbnQtbWVkaXVtIHRleHQtZ3JheS05MDAgc206cGwtNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZmlsZS5uYW1lfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJyZWxhdGl2ZSB3aGl0ZXNwYWNlLW5vd3JhcCBweS0yIHBsLTMgcHItNCB0ZXh0LXJpZ2h0IHRleHQtc20gZm9udC1tZWRpdW0gc206cHItNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIChjbGljayk9XCJyZW1vdmVGaWxlKGkpXCIgY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPlJlbW92ZTwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJzaG93Q3VzdG9tUGFyc2VyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzbTpncmlkIHNtOmdyaWQtY29scy0zIHNtOmdhcC00IHNtOml0ZW1zLXN0YXJ0IHNtOmJvcmRlci10IHNtOmJvcmRlci1ncmF5LTIwMCBzbTpwdC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJibG9jayB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS03MDAgc206bXQtcHggc206cHQtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEN1c3RvbSBEb2N1bWVudCBQYXJzZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZSBhIGN1c3RvbSBkb2N1bWVudCBwYXJzZXIgdG8gcHJvY2VzcyB0aGUgZG9jdW1lbnRzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xIHNtOm10LTAgc206Y29sLXNwYW4tMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTQgdGV4dC1zbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3QgQ3VzdG9tIERvY3VtZW50IFBhcnNlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbbWF0QXV0b2NvbXBsZXRlXT1cImF1dG9QYXJzZXJzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiZGF0YXNvdXJjZS5jb25maWcuY3VzdG9tRG9jdW1lbnRQYXJzZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleXVwKT1cInNlYXJjaFBhcnNlci5uZXh0KCRldmVudC50YXJnZXQudmFsdWUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGZvciBhIGN1c3RvbSBwYXJzZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1hdXRvY29tcGxldGUgI2F1dG9QYXJzZXJzPVwibWF0QXV0b2NvbXBsZXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgcGFyc2VyIG9mIGRvY3VtZW50UGFyc2Vyc1wiIFt2YWx1ZV09XCJwYXJzZXIudmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3BhcnNlci50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWF1dG9jb21wbGV0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNtYWxsIGNsYXNzPVwiZm9udC1ub3JtYWxcIj5TdGFydCB0eXBpbmcgbmFtZSB0byB2aWV3IGF2YWlsYWJsZSBwYXJzZXJzPC9zbWFsbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIWRhdGFzb3VyY2UuY29uZmlnLmN1c3RvbURvY3VtZW50UGFyc2VyXCI+XG5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic206Z3JpZCBzbTpncmlkLWNvbHMtMyBzbTpnYXAtNCBzbTppdGVtcy1zdGFydCBzbTpib3JkZXItdCBzbTpib3JkZXItZ3JheS0yMDAgc206cHQtNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwIHNtOm10LXB4IHNtOnB0LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRleGluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0IHdoZXRoZXIgeW91IHdhbnQgdGhlIGNvbnRlbnQgb2YgdGhlIGRvY3VtZW50cyB0byBiZSBpbmRleGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTEgc206bXQtMCBzbTpjb2wtc3Bhbi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBjbGFzcz1cImJsb2NrIG1iLTRcIiBbKG5nTW9kZWwpXT1cImRhdGFzb3VyY2UuY29uZmlnLmluZGV4Q29udGVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJpbmRleERvY3VtZW50Q2hhbmdlKCRldmVudClcIj5JbmRleCBEb2N1bWVudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhdGFzb3VyY2UuY29uZmlnLmluZGV4Q29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWF4LXctbGcgZmxleCByb3VuZGVkLW1kIHNoYWRvdy1zbSBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImlubGluZS1mbGV4IGl0ZW1zLWNlbnRlciBweC0zIHJvdW5kZWQtbC1tZCBib3JkZXIgYm9yZGVyLXItMCBib3JkZXItZ3JheS0zMDAgYmctZ3JheS01MCB0ZXh0LWdyYXktNTAwIHNtOnRleHQtc21cIj4gTWluIHBocmFzZSBsZW5ndGggKHdvcmRzKSA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIG5hbWU9XCJtaW5QaHJhc2VcIiBbbWluXT1cIjFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiZGF0YXNvdXJjZS5jb25maWcubWluUGhyYXNlTGVuZ3RoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXgtMSBibG9jayB3LWZ1bGwgbWluLXctMCByb3VuZGVkLW5vbmUgcm91bmRlZC1yLW1kIHNtOnRleHQtc20gYm9yZGVyLWdyYXktMzAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWF4LXctbGcgZmxleCByb3VuZGVkLW1kIHNoYWRvdy1zbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbmxpbmUtZmxleCBpdGVtcy1jZW50ZXIgcHgtMyByb3VuZGVkLWwtbWQgYm9yZGVyIGJvcmRlci1yLTAgYm9yZGVyLWdyYXktMzAwIGJnLWdyYXktNTAgdGV4dC1ncmF5LTUwMCBzbTp0ZXh0LXNtXCI+IE1heCBwaHJhc2UgbGVuZ3RoICh3b3JkcykgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBuYW1lPVwibWF4UGhyYXNlXCIgW21pbl09XCIxXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImRhdGFzb3VyY2UuY29uZmlnLm1heFBocmFzZUxlbmd0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbGV4LTEgYmxvY2sgdy1mdWxsIG1pbi13LTAgcm91bmRlZC1ub25lIHJvdW5kZWQtci1tZCBzbTp0ZXh0LXNtIGJvcmRlci1ncmF5LTMwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzbTpncmlkIHNtOmdyaWQtY29scy0zIHNtOmdhcC00IHNtOml0ZW1zLXN0YXJ0IHNtOmJvcmRlci10IHNtOmJvcmRlci1ncmF5LTIwMCBzbTpwdC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJibG9jayB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS03MDAgc206bXQtcHggc206cHQtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENodW5raW5nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXQgd2hldGhlciB5b3Ugd2FudCB0byBzcGxpdCB0aGUgZG9jdW1lbnRzIGludG8gY2h1bmtzIGZvciBhbmFseXNpc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xIHNtOm10LTAgc206Y29sLXNwYW4tMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggY2xhc3M9XCJibG9jayBtYi00XCIgWyhuZ01vZGVsKV09XCJkYXRhc291cmNlLmNvbmZpZy5jaHVua0NvbnRlbnRcIiAobmdNb2RlbENoYW5nZSk9XCJjaHVua0NvbnRlbnRDaGFuZ2UoJGV2ZW50KVwiPiBDaHVuayBEb2N1bWVudCBDb250ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhdGFzb3VyY2UuY29uZmlnLmNodW5rQ29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IGNsYXNzPVwiYmxvY2sgbWItNFwiIFsobmdNb2RlbCldPVwiZGF0YXNvdXJjZS5jb25maWcuaW5kZXhDaHVua3NCeUFJXCI+SW5kZXggQ2h1bmtzIGJ5IEFJXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZGF0YXNvdXJjZS5jb25maWcuaW5kZXhDb250ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNtOmdyaWQgc206Z3JpZC1jb2xzLTMgc206Z2FwLTQgc206aXRlbXMtc3RhcnQgc206Ym9yZGVyLXQgc206Ym9yZGVyLWdyYXktMjAwIHNtOnB0LTVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImJsb2NrIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTcwMCBzbTptdC1weCBzbTpwdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RvcCBXb3Jkc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQSBsaXN0IG9mIHdvcmRzIHRvIGV4Y2x1ZGUgZnJvbSBiZWluZyBpbmRleGVkLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xIHNtOm10LTAgc206Y29sLXNwYW4tMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggY2xhc3M9XCJibG9jayBtYi0yXCIgWyhuZ01vZGVsKV09XCJidWlsdEluU3RvcFdvcmRzLmJ1aWx0SW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlQnVpbHRJblN0b3BXb3JkQ29uZmlnKCRldmVudClcIj5Vc2UgQnVpbHQgSW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1jaGVja2JveD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJidWlsdEluU3RvcFdvcmRzLmJ1aWx0SW4gJiYgZGF0YXNvdXJjZS5jb25maWcubWF4UGhyYXNlTGVuZ3RoID4gMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNaW4gcGhyYXNlIGxlbmd0aCBmb3IgaW5jbHVkaW5nIHN0b3Agd29yZHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgW21pbl09XCIyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImJ1aWx0SW5TdG9wV29yZHMubWluUGhyYXNlTGVuZ3RoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJmb250LW5vcm1hbFwiPlRoZSBidWlsdCBpdCBzdG9wIHdvcmRzIHdpbGwgYmUgaW5jbHVkZWQgd2hlbiB0aGUgcGhyYXNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGlzIHZhbHVlLjwvc21hbGw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxociBjbGFzcz1cIm15LTRcIiAqbmdJZj1cIl8uZmlsdGVyKGRhdGFzb3VyY2UuY29uZmlnLnN0b3BXb3JkcywgJ2N1c3RvbScpLmxlbmd0aFwiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1zdG9wV29yZCBbbmdGb3JPZl09XCJfLmZpbHRlcihkYXRhc291cmNlLmNvbmZpZy5zdG9wV29yZHMsICdjdXN0b20nKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldC1pPWluZGV4PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTQgdGV4dC1zbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhc291cmNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFttYXRBdXRvY29tcGxldGVdPVwiYXV0b0RhdGFzZXRzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJzdG9wV29yZC5kYXRhc291cmNlID8gc3RvcFdvcmQuZGF0YXNvdXJjZS50aXRsZSA6ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXl1cCk9XCJzZWFyY2hUZXh0Lm5leHQoJGV2ZW50LnRhcmdldC52YWx1ZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2ggZm9yIGEgZGF0YXNvdXJjZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWF1dG9jb21wbGV0ZSAjYXV0b0RhdGFzZXRzPVwibWF0QXV0b2NvbXBsZXRlXCIgW2Rpc3BsYXlXaXRoXT1cImRpc3BsYXlGblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGRhdGFzb3VyY2Ugb2YgZGF0YXNvdXJjZXNcIiBbdmFsdWVdPVwiZGF0YXNvdXJjZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25TZWxlY3Rpb25DaGFuZ2UpPVwidXBkYXRlRGF0YXNvdXJjZShzdG9wV29yZCwgJGV2ZW50LnNvdXJjZS52YWx1ZSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2RhdGFzb3VyY2UudGl0bGV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1hdXRvY29tcGxldGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cImZvbnQtbm9ybWFsXCI+U3RhcnQgdHlwaW5nIG5hbWUgdG8gdmlldyBhdmFpbGFibGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFzb3VyY2VzPC9zbWFsbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwic3RvcFdvcmQuc2VsZWN0ZWREYXRhc291cmNlICYmIHN0b3BXb3JkLnNlbGVjdGVkRGF0YXNvdXJjZS5jb2x1bW5zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0b3AgV29yZHMgQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJzdG9wV29yZC5kYXRhc291cmNlQ29sdW1uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIHN0b3BXb3JkLnNlbGVjdGVkRGF0YXNvdXJjZS5jb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1ZhbHVlXT1cImNvbHVtbi5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Y29sdW1uLnRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNtYWxsIGNsYXNzPVwiZm9udC1ub3JtYWxcIj5TZWxlY3QgdGhlIGNvbHVtbiB0byB1c2UgZm9yIHRoZSBzdG9wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29yZHM8L3NtYWxsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTRcIiAqbmdJZj1cImRhdGFzb3VyY2UuY29uZmlnLm1heFBocmFzZUxlbmd0aCA+IDFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1pbiBwaHJhc2UgbGVuZ3RoIGZvciBpbmNsdWRpbmcgc3RvcCB3b3Jkc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBbbWluXT1cIjJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic3RvcFdvcmQubWluUGhyYXNlTGVuZ3RoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c21hbGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvbnQtbm9ybWFsXCI+VGhlIHt7c3RvcFdvcmQuZGF0YXNvdXJjZSA/IHN0b3BXb3JkLmRhdGFzb3VyY2UudGl0bGUgOiAnJ319XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcCB3b3JkcyB3aWxsIGJlIGluY2x1ZGVkIHdoZW4gdGhlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGhyYXNlIGxlbmd0aCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhpcyB2YWx1ZS48L3NtYWxsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGNvbG9yPVwid2FyblwiIChjbGljayk9XCJyZW1vdmVDdXN0b21TdG9wV29yZChpKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jbGVhcjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGhyIGNsYXNzPVwibXktNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJkYXRhc291cmNlLmNvbmZpZy5zdG9wV29yZHMucHVzaCh7Y3VzdG9tOiB0cnVlfSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFkZCBDdXN0b20gU3RvcCBXb3Jkc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNtOmdyaWQgc206Z3JpZC1jb2xzLTMgc206Z2FwLTQgc206aXRlbXMtc3RhcnQgc206Ym9yZGVyLXQgc206Ym9yZGVyLWdyYXktMjAwIHNtOnB0LTVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwIHNtOm10LXB4IHNtOnB0LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIFN0b3JhZ2UgT3B0aW9uc1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlY3VyZWx5IHNhdmUgYW4gb3JpZ2luYWwgY29weSBvZiB0aGUgZG9jdW1lbnQgYW5kL29yIGl0cyBvcmlnaW5hbCB0ZXh0LlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xIHNtOm10LTAgc206Y29sLXNwYW4tMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBjbGFzcz1cImJsb2NrIG1iLTJcIiBbKG5nTW9kZWwpXT1cImRhdGFzb3VyY2UuY29uZmlnLnN0b3JlT3JpZ2luYWxcIj5TdG9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9yaWdpbmFsIEZpbGVcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBjbGFzcz1cImJsb2NrIG1iLTJcIiBbKG5nTW9kZWwpXT1cImRhdGFzb3VyY2UuY29uZmlnLnN0b3JlVGV4dFwiPlN0b3JlIERvY3VtZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4dFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJwdC01XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktZW5kXCI+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJnLXdoaXRlIHB5LTIgcHgtNCBib3JkZXIgYm9yZGVyLWdyYXktMzAwIHJvdW5kZWQtbWQgc2hhZG93LXNtIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTcwMCBob3ZlcjpiZy1ncmF5LTUwIGZvY3VzOm91dGxpbmUtbm9uZVwiPlxuICAgICAgICAgICAgICAgIENhbmNlbFxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiBbZGlzYWJsZWRdPVwiIWRhdGFzb3VyY2UudGl0bGVcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImRpc2FibGVkOm9wYWNpdHktNTAgbWwtMyBpbmxpbmUtZmxleCBqdXN0aWZ5LWNlbnRlciBweS0yIHB4LTQgYm9yZGVyIGJvcmRlci10cmFuc3BhcmVudCBzaGFkb3ctc20gdGV4dC1zbSBmb250LW1lZGl1bSByb3VuZGVkLW1kIHRleHQtd2hpdGUgYmctc2Vjb25kYXJ5IGZvY3VzOm91dGxpbmUtbm9uZVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzYXZlKClcIj5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIWRhdGFzb3VyY2VLZXlcIj5cbiAgICAgICAgICAgICAgICAgICAgQ3JlYXRlIERhdGFzb3VyY2VcbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXRhc291cmNlS2V5XCI+XG4gICAgICAgICAgICAgICAgICAgIFVwZGF0ZSBTZXR0aW5nc1xuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L2Rpdj5cblxuPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImV2YWx1YXRlZERhdGFzb3VyY2VcIj5cblxuXG4gICAgPGRpdiBjbGFzcz1cIm92ZXJmbG93LXNjcm9sbFwiPlxuICAgICAgICA8dGFibGUgY2xhc3M9XCJtaW4tdy1mdWxsIGJvcmRlci1zZXBhcmF0ZSBiZy13aGl0ZVwiIHN0eWxlPVwiYm9yZGVyLXNwYWNpbmc6IDBcIj5cbiAgICAgICAgICAgIDx0aGVhZCBjbGFzcz1cImJnLWdyYXktMTAwXCI+XG4gICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZXZhbHVhdGVkRGF0YXNvdXJjZS5jb2x1bW5zXCIgc2NvcGU9XCJjb2xcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInN0aWNreSB0b3AtMCB6LTEwIGJvcmRlci1iIGJvcmRlci1ncmF5LTMwMCBiZy1ncmF5LTUwIGJnLW9wYWNpdHktNzUgcHktMy41IHB4LTQgdGV4dC1sZWZ0IHRleHQteHMgZm9udC1zZW1pYm9sZCB0ZXh0LWdyYXktOTAwIGJhY2tkcm9wLWJsdXIgYmFja2Ryb3AtZmlsdGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7Y29sdW1uLnRpdGxlfX1cbiAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJiZy13aGl0ZVwiPlxuICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBkYXRhIG9mIGV2YWx1YXRlZERhdGFzb3VyY2UuYWxsRGF0YVwiPlxuICAgICAgICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGV2YWx1YXRlZERhdGFzb3VyY2UuY29sdW1uczsgbGV0IGkgPSBpbmRleFwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZm9udC1tZWRpdW0nOiBpID09PSAwfVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwIHB5LTIgcHgtNCB0ZXh0LXNtIHRleHQtZ3JheS05MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImNvbHVtbi5uYW1lID09PSAnb3JpZ2luYWxfbGluaydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgdGV4dC1jdGEgaG92ZXI6dW5kZXJsaW5lXCIgKGNsaWNrKT1cImRvd25sb2FkRG9jKGRhdGFbY29sdW1uLm5hbWVdKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZGF0YVtjb2x1bW4ubmFtZV19fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGNsYXNzPVwibWwtMSBoLTQgdy00XCIgZmlsbD1cIm5vbmVcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk00IDE2djFhMyAzIDAgMDAzIDNoMTBhMyAzIDAgMDAzLTN2LTFtLTQtNGwtNCA0bTAgMGwtNC00bTQgNFY0XCIvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiY29sdW1uLm5hbWUgIT09ICdvcmlnaW5hbF9saW5rJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhdGFbY29sdW1uLm5hbWVdICYmIFN0cmluZyhkYXRhW2NvbHVtbi5uYW1lXSkubGVuZ3RoIDw9IDEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZGF0YVtjb2x1bW4ubmFtZV19fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXRhW2NvbHVtbi5uYW1lXSAmJiBTdHJpbmcoZGF0YVtjb2x1bW4ubmFtZV0pLmxlbmd0aCA+IDEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+e3tkYXRhW2NvbHVtbi5uYW1lXS5zdWJzdHJpbmcoMCwgMTAwKSArICcuLi4nfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSAoY2xpY2spPVwidmlld0Z1bGxJdGVtRGF0YShkYXRhW2NvbHVtbi5uYW1lXSwgY29sdW1uLm5hbWUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHRleHQtc20gdGV4dC1jdGEgaG92ZXI6dW5kZXJsaW5lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXcgbW9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBjbGFzcz1cIm1sLTEgaC00IHctNFwiIGZpbGw9XCJub25lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDI0IDI0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIHN0cm9rZS13aWR0aD1cIjJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xMCA2SDZhMiAyIDAgMDAtMiAydjEwYTIgMiAwIDAwMiAyaDEwYTIgMiAwIDAwMi0ydi00TTE0IDRoNm0wIDB2Nm0wLTZMMTAgMTRcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIWRhdGFbY29sdW1uLm5hbWVdXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3tkYXRhW2NvbHVtbi5uYW1lXX19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPC90Ym9keT5cblxuICAgICAgICA8L3RhYmxlPlxuXG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImJnLXdoaXRlIHAtNCBmbGV4IGFsaWduLWNlbnRlciBqdXN0aWZ5LWVuZFwiPlxuICAgICAgICA8c2VsZWN0IFt2YWx1ZV09XCJsaW1pdFwiIChjaGFuZ2UpPVwicGFnZVNpemVDaGFuZ2UoJGV2ZW50LnRhcmdldC52YWx1ZSlcIiBjbGFzcz1cIm1yLThcIj5cbiAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIjFcIj4xPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCI1XCI+NTwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiMTBcIj4xMDwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiMjVcIj4yNTwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiNTBcIj41MDwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiMTAwXCI+MTAwPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCIyNTBcIj4yNTA8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIjEwMDBcIj4xMDAwPC9vcHRpb24+XG4gICAgICAgIDwvc2VsZWN0PlxuICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjbGFzcz1cIm1yLTRcIiAoY2xpY2spPVwiZGVjcmVhc2VPZmZzZXQoKVwiIFtkaXNhYmxlZF09XCJwYWdlIDw9IDFcIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbj5jaGV2cm9uX2xlZnQ8L21hdC1pY29uPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gKGNsaWNrKT1cImluY3JlYXNlT2Zmc2V0KClcIiBbZGlzYWJsZWRdPVwiZW5kT2ZSZXN1bHRzXCI+XG4gICAgICAgICAgICA8bWF0LWljb24+Y2hldnJvbl9yaWdodDwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG48L25nLXRlbXBsYXRlPlxuIl19