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,344 +0,0 @@
1
- import { Component, Inject, ViewChild } from '@angular/core';
2
- import { BehaviorSubject, merge, Subject } from 'rxjs';
3
- import { debounceTime, distinctUntilChanged, map, switchMap } from 'rxjs/operators';
4
- import { MAT_LEGACY_DIALOG_DATA as MAT_DIALOG_DATA } from '@angular/material/legacy-dialog';
5
- import * as lodash from 'lodash';
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "../../../../services/dataset.service";
8
- import * as i2 from "../../../../services/datasource.service";
9
- import * as i3 from "../../../../services/project.service";
10
- import * as i4 from "../../../../services/tag.service";
11
- import * as i5 from "@angular/material/legacy-dialog";
12
- import * as i6 from "../../../../services/data-processor.service";
13
- import * as i7 from "@angular/common";
14
- import * as i8 from "@angular/material/legacy-button";
15
- import * as i9 from "@angular/material/icon";
16
- import * as i10 from "@angular/cdk/drag-drop";
17
- import * as i11 from "@angular/forms";
18
- import * as i12 from "@angular/material/stepper";
19
- import * as i13 from "@angular/material/legacy-checkbox";
20
- import * as i14 from "../dataset-filters/dataset-filters.component";
21
- import * as i15 from "../dataset-parameter-values/dataset-parameter-values.component";
22
- import * as i16 from "../../../whitelisted-sql-functions/whitelisted-sql-functions.component";
23
- import * as i17 from "../../../data-picker/data-picker.component";
24
- const _ = lodash.default;
25
- export class DatasetAddJoinComponent {
26
- constructor(datasetService, datasourceService, projectService, tagService, dialogRef, data, dataProcessorService) {
27
- this.datasetService = datasetService;
28
- this.datasourceService = datasourceService;
29
- this.projectService = projectService;
30
- this.tagService = tagService;
31
- this.dialogRef = dialogRef;
32
- this.data = data;
33
- this.dataProcessorService = dataProcessorService;
34
- this.Object = Object;
35
- this.environment = {};
36
- this.datasources = [];
37
- this.datasets = [];
38
- this.snapshots = [];
39
- this.sharedDatasets = [];
40
- this.searchText = new BehaviorSubject('');
41
- this.joinColumns = [];
42
- this.joinTransformation = {
43
- type: 'join',
44
- config: {
45
- joinFilters: [],
46
- joinColumns: [],
47
- joinParameterMappings: [],
48
- strictJoin: false
49
- }
50
- };
51
- this.allColumns = true;
52
- this.updateParams = new Subject();
53
- this.openSide = new BehaviorSubject(false);
54
- this.tableData = {
55
- datasources: {
56
- data: [],
57
- limit: 5,
58
- offset: 0,
59
- page: 1,
60
- endOfResults: false,
61
- shared: false,
62
- reload: new Subject(),
63
- title: 'My Data',
64
- type: 'datasource'
65
- },
66
- datasets: {
67
- data: [],
68
- limit: 5,
69
- offset: 0,
70
- page: 1,
71
- endOfResults: false,
72
- shared: false,
73
- reload: new Subject(),
74
- title: 'Stored Queries',
75
- type: 'dataset'
76
- }
77
- };
78
- this._ = _;
79
- }
80
- ngOnInit() {
81
- this.admin = !!this.data.admin;
82
- this.environment = this.data.environment || {};
83
- this.filterFields = this.data.filterFields;
84
- this.parameterValues = this.data.parameterValues;
85
- this.datasetEditor = this.data.datasetEditor;
86
- if (!this.admin) {
87
- this.tableData.shared = {
88
- data: [],
89
- limit: 5,
90
- offset: 0,
91
- page: 1,
92
- endOfResults: false,
93
- shared: false,
94
- reload: new Subject(),
95
- title: 'Data Feeds',
96
- type: 'dataset'
97
- };
98
- }
99
- this.tableData.snapshots = {
100
- data: [],
101
- limit: 5,
102
- offset: 0,
103
- page: 1,
104
- endOfResults: false,
105
- shared: false,
106
- reload: new Subject(),
107
- title: 'Snapshots',
108
- type: 'snapshot'
109
- };
110
- this.activeProject = this.projectService.activeProject.getValue();
111
- this.activeTag = this.tagService.activeTag.getValue();
112
- merge(this.searchText, this.tableData.datasets.reload)
113
- .pipe(debounceTime(300), distinctUntilChanged(), switchMap(() => this.getDatasets(false, this.tableData.datasets.limit, this.tableData.datasets.offset))).subscribe((datasets) => {
114
- this.tableData.datasets.endOfResults = datasets.length < this.tableData.datasets.limit;
115
- this.tableData.datasets.data = datasets;
116
- });
117
- merge(this.searchText, this.tableData.snapshots.reload)
118
- .pipe(debounceTime(300), distinctUntilChanged(), switchMap(() => this.getSnapshots(this.tableData.snapshots.limit, this.tableData.snapshots.offset))).subscribe((snapshots) => {
119
- this.tableData.snapshots.endOfResults = snapshots.length < this.tableData.snapshots.limit;
120
- this.tableData.snapshots.data = snapshots;
121
- });
122
- merge(this.searchText, this.tableData.datasources.reload)
123
- .pipe(debounceTime(300), distinctUntilChanged(), switchMap(() => this.getDatasources(this.tableData.datasources.limit, this.tableData.datasources.offset))).subscribe((datasources) => {
124
- this.tableData.datasources.endOfResults = datasources.length < this.tableData.datasources.limit;
125
- this.tableData.datasources.data = datasources;
126
- });
127
- if (!this.admin) {
128
- merge(this.searchText, this.tableData.shared.reload)
129
- .pipe(debounceTime(300), distinctUntilChanged(), switchMap(() => this.getDatasets(true, this.tableData.shared.limit, this.tableData.shared.offset))).subscribe((shared) => {
130
- this.tableData.shared.endOfResults = shared.length < this.tableData.shared.limit;
131
- this.tableData.shared.data = shared;
132
- });
133
- }
134
- if (this.data.joinTransformation) {
135
- this.joinTransformation = this.data.joinTransformation;
136
- const action = {
137
- datasourceKey: this.joinTransformation.config.joinedDataSourceInstanceKey,
138
- datasetId: this.joinTransformation.config.joinedDataSetInstanceId
139
- };
140
- setTimeout(() => {
141
- this.select(action, this.matStepper, false);
142
- }, 200);
143
- }
144
- }
145
- increaseOffset(dataItem) {
146
- dataItem.page = dataItem.page + 1;
147
- dataItem.offset = (dataItem.limit * dataItem.page) - dataItem.limit;
148
- dataItem.reload.next(Date.now());
149
- }
150
- decreaseOffset(dataItem) {
151
- dataItem.page = dataItem.page <= 1 ? 1 : dataItem.page - 1;
152
- dataItem.offset = (dataItem.limit * dataItem.page) - dataItem.limit;
153
- dataItem.reload.next(Date.now());
154
- }
155
- pageSizeChange(value, dataItem) {
156
- dataItem.page = 1;
157
- dataItem.offset = 0;
158
- dataItem.limit = value;
159
- dataItem.reload.next(Date.now());
160
- }
161
- async select(action, step, reset = true) {
162
- this.joinFilterFields = null;
163
- // Reset if we are selecting an item again, not loading initially.
164
- if (reset) {
165
- this.joinTransformation = {
166
- type: 'join',
167
- config: {
168
- joinFilters: [],
169
- joinColumns: [],
170
- joinParameterMappings: [],
171
- strictJoin: false
172
- }
173
- };
174
- }
175
- let requiredParams = [];
176
- if (action.datasourceKey) {
177
- this.selectedSource = {
178
- datasetInstanceId: null,
179
- datasourceInstanceKey: action.datasourceKey,
180
- transformationInstances: [],
181
- parameterValues: {},
182
- parameters: []
183
- };
184
- this.joinTransformation.config.joinedDataSourceInstanceKey = action.datasourceKey;
185
- requiredParams = await this.datasourceService.getEvaluatedParameters({
186
- key: action.datasourceKey
187
- });
188
- }
189
- else if (action.datasetId) {
190
- this.selectedSource = await this.datasetService.getDataset(action.datasetId);
191
- this.joinTransformation.config.joinedDataSetInstanceId = action.datasetId;
192
- requiredParams = await this.datasetService.getEvaluatedParameters(this.selectedSource);
193
- }
194
- const existingJoinedParameters = this.joinTransformation.config.joinParameterMappings || [];
195
- this.createParameterStructure(requiredParams, existingJoinedParameters);
196
- if (!this.requiredParameters || !this.requiredParameters.length) {
197
- this.getJoinColumns(reset);
198
- }
199
- setTimeout(() => {
200
- step.next();
201
- }, 0);
202
- }
203
- toggleAllColumns(event) {
204
- this.joinColumns.map(column => {
205
- column.selected = event.checked;
206
- return column;
207
- });
208
- }
209
- allSelected() {
210
- this.allColumns = _.every(this.joinColumns, 'selected');
211
- }
212
- async getParameterValues(step) {
213
- this.updateParams.next(Date.now());
214
- await this.getJoinColumns(true);
215
- setTimeout(() => {
216
- step.next();
217
- }, 0);
218
- }
219
- setEvaluatedParameters(requiredParameters, step) {
220
- const parameterMappings = [];
221
- requiredParameters.forEach(param => {
222
- const mapping = { parameterName: param.name };
223
- if (param.selectedType === 'Column') {
224
- mapping.sourceColumnName = param.value;
225
- }
226
- else if (param.selectedType === 'Parameter') {
227
- mapping.sourceParameterName = param.value;
228
- }
229
- parameterMappings.push(mapping);
230
- });
231
- this.joinTransformation.config.joinParameterMappings = parameterMappings;
232
- }
233
- join() {
234
- const filters = this.joinTransformation.config.joinFilters;
235
- const selectedColumns = _.filter(this.joinColumns, 'selected');
236
- this.joinTransformation.config.joinColumns = selectedColumns.map(column => {
237
- return { name: column.name, title: column.title };
238
- });
239
- this.dialogRef.close(this.joinTransformation);
240
- }
241
- createParameterStructure(requiredParameters, existingValue = []) {
242
- this.requiredParameters = requiredParameters.map(param => {
243
- param.type = 'join';
244
- param.selectedType = 'Column';
245
- const existing = _.find(existingValue, { parameterName: param.name });
246
- if (existing) {
247
- if (existing.sourceColumnName) {
248
- param.value = existing.sourceColumnName;
249
- }
250
- if (existing.sourceParameterName) {
251
- param.selectedType = 'Parameter';
252
- param.value = existing.sourceParameterName;
253
- }
254
- }
255
- param.values = [
256
- {
257
- label: 'Column',
258
- values: this.filterFields
259
- },
260
- {
261
- label: 'Parameter',
262
- values: _.map(this.parameterValues, (value) => {
263
- return {
264
- title: value.title + ' (' + value.currentValue + ')',
265
- name: value.name
266
- };
267
- })
268
- }
269
- ];
270
- return param;
271
- });
272
- }
273
- async getJoinColumns(reset = true) {
274
- if (reset) {
275
- this.joinTransformation.config.joinFilters = {
276
- logic: 'AND',
277
- filters: [{
278
- lhsExpression: '',
279
- rhsExpression: '',
280
- filterType: 'eq'
281
- }],
282
- filterJunctions: []
283
- };
284
- }
285
- // If we have join parameter mappings then we need to add the parameter value to the evaluate to get column data
286
- if (this.joinTransformation.config.joinParameterMappings &&
287
- this.joinTransformation.config.joinParameterMappings.length) {
288
- const firstDataRow = this.datasetEditor.dataset.allData[0];
289
- const parameterValues = {};
290
- this.joinTransformation.config.joinParameterMappings.forEach(param => {
291
- parameterValues[param.parameterName] = firstDataRow[param.sourceColumnName];
292
- });
293
- this.selectedSource.parameterValues = parameterValues;
294
- }
295
- const data = await this.datasetService.evaluateDataset(this.selectedSource, '0', '1');
296
- if (data.columns) {
297
- this.joinFilterFields = [];
298
- this.joinColumns = [];
299
- data.columns.forEach(column => {
300
- this.joinFilterFields.push({
301
- title: column.title,
302
- name: column.name
303
- });
304
- const duplicate = !!_.find(this.filterFields, { name: column.name, title: column.title });
305
- this.joinColumns.push({
306
- selected: !duplicate,
307
- name: column.name,
308
- title: column.title,
309
- duplicate
310
- });
311
- });
312
- }
313
- }
314
- getDatasets(shared, limit, offset) {
315
- return this.datasetService.getDatasets(this.searchText.getValue() || '', limit.toString(), offset.toString(), shared ? null : '').pipe(map((datasets) => {
316
- return datasets;
317
- }));
318
- }
319
- getDatasources(limit, offset) {
320
- return this.datasourceService.getDatasources(this.searchText.getValue() || '', limit.toString(), offset.toString()).pipe(map((sources) => {
321
- return sources;
322
- }));
323
- }
324
- getSnapshots(limit, offset) {
325
- return this.dataProcessorService.filterProcessorsByType('snapshot', this.searchText.getValue() || '', limit.toString(), offset.toString()).pipe(map((snapshots) => {
326
- return _.filter(snapshots, snapshot => {
327
- return snapshot.taskStatus !== 'PENDING';
328
- });
329
- }));
330
- }
331
- }
332
- DatasetAddJoinComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DatasetAddJoinComponent, deps: [{ token: i1.DatasetService }, { token: i2.DatasourceService }, { token: i3.ProjectService }, { token: i4.TagService }, { token: i5.MatLegacyDialogRef }, { token: MAT_DIALOG_DATA }, { token: i6.DataProcessorService }], target: i0.ɵɵFactoryTarget.Component });
333
- DatasetAddJoinComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: DatasetAddJoinComponent, selector: "ki-dataset-add-join", host: { classAttribute: "dialog-wrapper" }, viewQueries: [{ propertyName: "matStepper", first: true, predicate: ["stepper"], descendants: true }], ngImport: i0, template: "<div class=\"dialog\" cdkDrag cdkDragRootElement=\".cdk-overlay-pane\">\n\n <div class=\"dialog-title\" cdkDragHandle>\n <h2 mat-dialog-title>Join Data</h2>\n\n <button mat-icon-button mat-dialog-close>\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n\n <div class=\"dialog-content p-0\">\n\n <div class=\"border-t bg-blue-50 p-4\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: mini/information-circle -->\n <svg class=\"h-5 w-5 text-blue-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=\"M19 10.5a8.5 8.5 0 11-17 0 8.5 8.5 0 0117 0zM8.25 9.75A.75.75 0 019 9h.253a1.75 1.75 0 011.709 2.13l-.46 2.066a.25.25 0 00.245.304H11a.75.75 0 010 1.5h-.253a1.75 1.75 0 01-1.709-2.13l.46-2.066a.25.25 0 00-.245-.304H9a.75.75 0 01-.75-.75zM10 7a1 1 0 100-2 1 1 0 000 2z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3 flex-1 md:flex md:justify-between\">\n <p class=\"text-sm text-blue-700 mb-0\">\n Join Data functionality allows you to merge data from another Data Feed, or Stored Query\n into this data feed. <b>Select</b> the data to merge and follow the on screen prompts to\n complete\n the join.\n </p>\n\n </div>\n </div>\n </div>\n\n <mat-horizontal-stepper [linear]=\"true\" #stepper [animationDuration]=\"0\">\n <mat-step [completed]=\"selectedSource\" label=\"Select data\">\n\n <ki-data-picker class=\"block\" style=\"height: 547px\" [admin]=\"admin\"\n (selected)=\"select($event, stepper)\"></ki-data-picker>\n\n </mat-step>\n <mat-step *ngIf=\"requiredParameters && requiredParameters.length\"\n [completed]=\"joinTransformation.config.joinParameterMappings.length >= 1\"\n label=\"Required parameters\">\n <div class=\"mx-4\">\n <ng-template [ngIf]=\"!selectedSource\">\n <p>Please select either a Datasource or Dataset to join to.</p>\n </ng-template>\n\n <ng-template [ngIf]=\"selectedSource\">\n <p class=\"mb-4\">\n <b *ngIf=\"!joinTransformation.config.joinedDataItemTitle\">Selected\n source: {{ selectedSource.title || selectedSource.name }}</b>\n <b *ngIf=\"joinTransformation.config.joinedDataItemTitle\">Selected\n source: {{ joinTransformation.config.joinedDataItemTitle }}</b>\n </p>\n\n <div class=\"mb-4\" *ngIf=\"requiredParameters && requiredParameters.length\">\n <ki-dataset-parameter-values [parameterValues]=\"requiredParameters\" [hideNew]=\"true\"\n [update]=\"updateParams\"\n (changed)=\"setEvaluatedParameters($event, stepper)\"></ki-dataset-parameter-values>\n </div>\n\n <div class=\"rounded-md bg-blue-50 p-4\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/information-circle -->\n <svg class=\"h-5 w-5 text-blue-400\" xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\" 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 flex-1 md:flex md:justify-between\">\n <p class=\"text-sm text-blue-600 mb-0\">\n The selected source requires a parameter to be set in order for the data\n to be retrieved. Please choose the relevant column to use as the parameter or\n choose an existing parameter value already defined in this query.\n </p>\n </div>\n </div>\n </div>\n\n </ng-template>\n </div>\n </mat-step>\n <mat-step *ngIf=\"!requiredParameters || !requiredParameters.length\"\n [completed]=\"(!joinFilterFields || !joinFilterFields.length) ||\n (_.every(joinTransformation.config.joinFilters.filters, 'lhsExpression') &&\n _.every(joinTransformation.config.joinFilters.filters, 'rhsExpression'))\"\n label=\"Join criteria\">\n <div class=\"mx-4\">\n <ng-template [ngIf]=\"!selectedSource\">\n <p>Please select either a Datasource or Dataset to join to.</p>\n </ng-template>\n\n <ng-template [ngIf]=\"selectedSource\">\n <p class=\"mb-4\">\n <b *ngIf=\"!joinTransformation.config.joinedDataItemTitle\">Selected\n source: {{ selectedSource.title || selectedSource.name }}</b>\n <b *ngIf=\"joinTransformation.config.joinedDataItemTitle\">Selected\n source: {{ joinTransformation.config.joinedDataItemTitle }}</b>\n </p>\n <div class=\"my-4\">\n <mat-checkbox [(ngModel)]=\"joinTransformation.config.strictJoin\">Strict Join?</mat-checkbox>\n <p><small>If turned on, data will be pruned to only return rows that match.</small></p>\n </div>\n\n <ki-dataset-filters *ngIf=\"joinFilterFields\" [filterFields]=\"filterFields\"\n [joinFilterFields]=\"joinFilterFields\" [openSide]=\"openSide\"\n [joinFieldsName]=\"selectedSource.title || selectedSource.name\"\n [filterJunction]=\"joinTransformation.config.joinFilters\"></ki-dataset-filters>\n\n <ng-template [ngIf]=\"openSide.getValue()\">\n <ki-whitelisted-sql-functions [fields]=\"filterFields\"></ki-whitelisted-sql-functions>\n </ng-template>\n\n </ng-template>\n </div>\n </mat-step>\n\n <mat-step [completed]=\"false\" label=\"Column definition\">\n <div class=\"mx-4\">\n <ng-template [ngIf]=\"!selectedSource\">\n <p>Please select either a Datasource or Dataset to join to.</p>\n </ng-template>\n\n <ng-template [ngIf]=\"selectedSource\">\n <p class=\"mb-4\">\n <b *ngIf=\"!joinTransformation.config.joinedDataItemTitle\">Selected\n source: {{ selectedSource.title || selectedSource.name }}</b>\n <b *ngIf=\"joinTransformation.config.joinedDataItemTitle\">Selected\n source: {{ joinTransformation.config.joinedDataItemTitle }}</b>\n </p>\n\n <p>Select the columns you would like to view, and set a new column name if required.</p>\n\n <div class=\"column-definition align-center\">\n <mat-checkbox [(ngModel)]=\"allColumns\" (change)=\"toggleAllColumns($event)\"></mat-checkbox>\n <label class=\"mw\">Column Name</label>\n <label class=\"mw\">New Column Title</label>\n </div>\n\n <div class=\"column-definition align-center\" *ngFor=\"let column of joinColumns\">\n <mat-checkbox [(ngModel)]=\"column.selected\" (ngModelChange)=\"allSelected()\"></mat-checkbox>\n <label>\n <input type=\"text\" [(ngModel)]=\"column.name\" disabled>\n </label>\n <label>\n <input type=\"text\" [(ngModel)]=\"column.title\">\n </label>\n <span *ngIf=\"column.duplicate\" class=\"primary\">Duplicate column name</span>\n </div>\n </ng-template>\n </div>\n </mat-step>\n\n </mat-horizontal-stepper>\n\n </div>\n\n <div class=\"dialog-footer\">\n\n <!-- BACK/CANCEL BUTTONS-->\n <button *ngIf=\"stepper.selectedIndex === 0\" mat-stroked-button color=\"primary\" mat-dialog-close>Cancel</button>\n <button *ngIf=\"stepper.selectedIndex > 0\" mat-stroked-button color=\"primary\" (click)=\"stepper.previous()\">Back\n </button>\n\n <!-- MIDDLE NEXT BUTTONS -->\n <ng-template [ngIf]=\"stepper.selectedIndex === 1\">\n <ng-template [ngIf]=\"!requiredParameters || !requiredParameters.length\">\n <button mat-flat-button color=\"primary\" (click)=\"stepper.next()\"\n [disabled]=\"(joinFilterFields && joinFilterFields.length) &&\n !(_.every(joinTransformation.config.joinFilters.filters, 'lhsExpression') &&\n _.every(joinTransformation.config.joinFilters.filters, 'rhsExpression'))\">\n Next\n </button>\n </ng-template>\n\n <ng-template [ngIf]=\"requiredParameters && requiredParameters.length\">\n <button mat-flat-button color=\"primary\" (click)=\"getParameterValues(stepper)\">\n Next\n </button>\n </ng-template>\n </ng-template>\n <!-- FINAL BUTTON -->\n <button mat-flat-button color=\"primary\" *ngIf=\"stepper.selectedIndex === 2\" (click)=\"join()\">\n Create Join\n </button>\n </div>\n\n</div>\n\n\n", styles: ["table th{background-color:#f5f5f5}.column-definition{border-bottom:1px solid whitesmoke;padding:.5rem;margin-bottom:.5rem}.column-definition label{margin-left:1rem}.column-definition label.mw,.column-definition label input{width:300px}.column-definition span{margin:0 0 1rem 2rem;align-self:flex-end}\n"], dependencies: [{ kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i8.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: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5.MatLegacyDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i5.MatLegacyDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i10.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i10.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i11.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: i11.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i11.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i12.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "component", type: i12.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["selectedIndex", "disableRipple", "color", "labelPosition", "headerPosition", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "component", type: i13.MatLegacyCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i14.DatasetFiltersComponent, selector: "ki-dataset-filters", inputs: ["filterJunction", "filterFields", "joinFilterFields", "joinFieldsName", "openSide", "parameterValues"] }, { kind: "component", type: i15.DatasetParameterValuesComponent, selector: "ki-dataset-parameter-values", inputs: ["parameterValues", "focusParameters", "evaluatedDatasource", "showNewOnOpen", "hideNew", "update"], outputs: ["changed", "evaluatedDatasourceChange"] }, { kind: "component", type: i16.WhitelistedSqlFunctionsComponent, selector: "ki-whitelisted-sql-functions", inputs: ["search", "fields"] }, { kind: "component", type: i17.DataPickerComponent, selector: "ki-data-picker", inputs: ["admin", "typeMapping"], outputs: ["selected"] }] });
334
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DatasetAddJoinComponent, decorators: [{
335
- type: Component,
336
- args: [{ selector: 'ki-dataset-add-join', host: { class: 'dialog-wrapper' }, template: "<div class=\"dialog\" cdkDrag cdkDragRootElement=\".cdk-overlay-pane\">\n\n <div class=\"dialog-title\" cdkDragHandle>\n <h2 mat-dialog-title>Join Data</h2>\n\n <button mat-icon-button mat-dialog-close>\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n\n <div class=\"dialog-content p-0\">\n\n <div class=\"border-t bg-blue-50 p-4\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: mini/information-circle -->\n <svg class=\"h-5 w-5 text-blue-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=\"M19 10.5a8.5 8.5 0 11-17 0 8.5 8.5 0 0117 0zM8.25 9.75A.75.75 0 019 9h.253a1.75 1.75 0 011.709 2.13l-.46 2.066a.25.25 0 00.245.304H11a.75.75 0 010 1.5h-.253a1.75 1.75 0 01-1.709-2.13l.46-2.066a.25.25 0 00-.245-.304H9a.75.75 0 01-.75-.75zM10 7a1 1 0 100-2 1 1 0 000 2z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3 flex-1 md:flex md:justify-between\">\n <p class=\"text-sm text-blue-700 mb-0\">\n Join Data functionality allows you to merge data from another Data Feed, or Stored Query\n into this data feed. <b>Select</b> the data to merge and follow the on screen prompts to\n complete\n the join.\n </p>\n\n </div>\n </div>\n </div>\n\n <mat-horizontal-stepper [linear]=\"true\" #stepper [animationDuration]=\"0\">\n <mat-step [completed]=\"selectedSource\" label=\"Select data\">\n\n <ki-data-picker class=\"block\" style=\"height: 547px\" [admin]=\"admin\"\n (selected)=\"select($event, stepper)\"></ki-data-picker>\n\n </mat-step>\n <mat-step *ngIf=\"requiredParameters && requiredParameters.length\"\n [completed]=\"joinTransformation.config.joinParameterMappings.length >= 1\"\n label=\"Required parameters\">\n <div class=\"mx-4\">\n <ng-template [ngIf]=\"!selectedSource\">\n <p>Please select either a Datasource or Dataset to join to.</p>\n </ng-template>\n\n <ng-template [ngIf]=\"selectedSource\">\n <p class=\"mb-4\">\n <b *ngIf=\"!joinTransformation.config.joinedDataItemTitle\">Selected\n source: {{ selectedSource.title || selectedSource.name }}</b>\n <b *ngIf=\"joinTransformation.config.joinedDataItemTitle\">Selected\n source: {{ joinTransformation.config.joinedDataItemTitle }}</b>\n </p>\n\n <div class=\"mb-4\" *ngIf=\"requiredParameters && requiredParameters.length\">\n <ki-dataset-parameter-values [parameterValues]=\"requiredParameters\" [hideNew]=\"true\"\n [update]=\"updateParams\"\n (changed)=\"setEvaluatedParameters($event, stepper)\"></ki-dataset-parameter-values>\n </div>\n\n <div class=\"rounded-md bg-blue-50 p-4\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <!-- Heroicon name: solid/information-circle -->\n <svg class=\"h-5 w-5 text-blue-400\" xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\" 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 flex-1 md:flex md:justify-between\">\n <p class=\"text-sm text-blue-600 mb-0\">\n The selected source requires a parameter to be set in order for the data\n to be retrieved. Please choose the relevant column to use as the parameter or\n choose an existing parameter value already defined in this query.\n </p>\n </div>\n </div>\n </div>\n\n </ng-template>\n </div>\n </mat-step>\n <mat-step *ngIf=\"!requiredParameters || !requiredParameters.length\"\n [completed]=\"(!joinFilterFields || !joinFilterFields.length) ||\n (_.every(joinTransformation.config.joinFilters.filters, 'lhsExpression') &&\n _.every(joinTransformation.config.joinFilters.filters, 'rhsExpression'))\"\n label=\"Join criteria\">\n <div class=\"mx-4\">\n <ng-template [ngIf]=\"!selectedSource\">\n <p>Please select either a Datasource or Dataset to join to.</p>\n </ng-template>\n\n <ng-template [ngIf]=\"selectedSource\">\n <p class=\"mb-4\">\n <b *ngIf=\"!joinTransformation.config.joinedDataItemTitle\">Selected\n source: {{ selectedSource.title || selectedSource.name }}</b>\n <b *ngIf=\"joinTransformation.config.joinedDataItemTitle\">Selected\n source: {{ joinTransformation.config.joinedDataItemTitle }}</b>\n </p>\n <div class=\"my-4\">\n <mat-checkbox [(ngModel)]=\"joinTransformation.config.strictJoin\">Strict Join?</mat-checkbox>\n <p><small>If turned on, data will be pruned to only return rows that match.</small></p>\n </div>\n\n <ki-dataset-filters *ngIf=\"joinFilterFields\" [filterFields]=\"filterFields\"\n [joinFilterFields]=\"joinFilterFields\" [openSide]=\"openSide\"\n [joinFieldsName]=\"selectedSource.title || selectedSource.name\"\n [filterJunction]=\"joinTransformation.config.joinFilters\"></ki-dataset-filters>\n\n <ng-template [ngIf]=\"openSide.getValue()\">\n <ki-whitelisted-sql-functions [fields]=\"filterFields\"></ki-whitelisted-sql-functions>\n </ng-template>\n\n </ng-template>\n </div>\n </mat-step>\n\n <mat-step [completed]=\"false\" label=\"Column definition\">\n <div class=\"mx-4\">\n <ng-template [ngIf]=\"!selectedSource\">\n <p>Please select either a Datasource or Dataset to join to.</p>\n </ng-template>\n\n <ng-template [ngIf]=\"selectedSource\">\n <p class=\"mb-4\">\n <b *ngIf=\"!joinTransformation.config.joinedDataItemTitle\">Selected\n source: {{ selectedSource.title || selectedSource.name }}</b>\n <b *ngIf=\"joinTransformation.config.joinedDataItemTitle\">Selected\n source: {{ joinTransformation.config.joinedDataItemTitle }}</b>\n </p>\n\n <p>Select the columns you would like to view, and set a new column name if required.</p>\n\n <div class=\"column-definition align-center\">\n <mat-checkbox [(ngModel)]=\"allColumns\" (change)=\"toggleAllColumns($event)\"></mat-checkbox>\n <label class=\"mw\">Column Name</label>\n <label class=\"mw\">New Column Title</label>\n </div>\n\n <div class=\"column-definition align-center\" *ngFor=\"let column of joinColumns\">\n <mat-checkbox [(ngModel)]=\"column.selected\" (ngModelChange)=\"allSelected()\"></mat-checkbox>\n <label>\n <input type=\"text\" [(ngModel)]=\"column.name\" disabled>\n </label>\n <label>\n <input type=\"text\" [(ngModel)]=\"column.title\">\n </label>\n <span *ngIf=\"column.duplicate\" class=\"primary\">Duplicate column name</span>\n </div>\n </ng-template>\n </div>\n </mat-step>\n\n </mat-horizontal-stepper>\n\n </div>\n\n <div class=\"dialog-footer\">\n\n <!-- BACK/CANCEL BUTTONS-->\n <button *ngIf=\"stepper.selectedIndex === 0\" mat-stroked-button color=\"primary\" mat-dialog-close>Cancel</button>\n <button *ngIf=\"stepper.selectedIndex > 0\" mat-stroked-button color=\"primary\" (click)=\"stepper.previous()\">Back\n </button>\n\n <!-- MIDDLE NEXT BUTTONS -->\n <ng-template [ngIf]=\"stepper.selectedIndex === 1\">\n <ng-template [ngIf]=\"!requiredParameters || !requiredParameters.length\">\n <button mat-flat-button color=\"primary\" (click)=\"stepper.next()\"\n [disabled]=\"(joinFilterFields && joinFilterFields.length) &&\n !(_.every(joinTransformation.config.joinFilters.filters, 'lhsExpression') &&\n _.every(joinTransformation.config.joinFilters.filters, 'rhsExpression'))\">\n Next\n </button>\n </ng-template>\n\n <ng-template [ngIf]=\"requiredParameters && requiredParameters.length\">\n <button mat-flat-button color=\"primary\" (click)=\"getParameterValues(stepper)\">\n Next\n </button>\n </ng-template>\n </ng-template>\n <!-- FINAL BUTTON -->\n <button mat-flat-button color=\"primary\" *ngIf=\"stepper.selectedIndex === 2\" (click)=\"join()\">\n Create Join\n </button>\n </div>\n\n</div>\n\n\n", styles: ["table th{background-color:#f5f5f5}.column-definition{border-bottom:1px solid whitesmoke;padding:.5rem;margin-bottom:.5rem}.column-definition label{margin-left:1rem}.column-definition label.mw,.column-definition label input{width:300px}.column-definition span{margin:0 0 1rem 2rem;align-self:flex-end}\n"] }]
337
- }], ctorParameters: function () { return [{ type: i1.DatasetService }, { type: i2.DatasourceService }, { type: i3.ProjectService }, { type: i4.TagService }, { type: i5.MatLegacyDialogRef }, { type: undefined, decorators: [{
338
- type: Inject,
339
- args: [MAT_DIALOG_DATA]
340
- }] }, { type: i6.DataProcessorService }]; }, propDecorators: { matStepper: [{
341
- type: ViewChild,
342
- args: ['stepper']
343
- }] } });
344
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXNldC1hZGQtam9pbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1raW5pbnRlbC9zcmMvbGliL2NvbXBvbmVudHMvZGF0YXNldC9kYXRhc2V0LWVkaXRvci9kYXRhc2V0LWFkZC1qb2luL2RhdGFzZXQtYWRkLWpvaW4uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcta2luaW50ZWwvc3JjL2xpYi9jb21wb25lbnRzL2RhdGFzZXQvZGF0YXNldC1lZGl0b3IvZGF0YXNldC1hZGQtam9pbi9kYXRhc2V0LWFkZC1qb2luLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQUUsTUFBTSxFQUFpQixTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDMUUsT0FBTyxFQUFDLGVBQWUsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ3JELE9BQU8sRUFBQyxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBS2xGLE9BQU8sRUFBQyxzQkFBc0IsSUFBSSxlQUFlLEVBQXFDLE1BQU0saUNBQWlDLENBQUM7QUFDOUgsT0FBTyxLQUFLLE1BQU0sTUFBTSxRQUFRLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDakMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztBQVV6QixNQUFNLE9BQU8sdUJBQXVCO0lBNkRoQyxZQUFvQixjQUE4QixFQUM5QixpQkFBb0MsRUFDcEMsY0FBOEIsRUFDOUIsVUFBc0IsRUFDdkIsU0FBZ0QsRUFDdkIsSUFBUyxFQUNqQyxvQkFBMEM7UUFOMUMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7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LGNBQWMsQ0FDeEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLEVBQ2hDLEtBQUssQ0FBQyxRQUFRLEVBQUUsRUFDaEIsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUNwQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFZLEVBQUUsRUFBRTtZQUNwQixPQUFPLE9BQU8sQ0FBQztRQUNuQixDQUFDLENBQUMsQ0FDTCxDQUFDO0lBQ04sQ0FBQztJQUVPLFlBQVksQ0FBQyxLQUFLLEVBQUUsTUFBTTtRQUM5QixPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxzQkFBc0IsQ0FDbkQsVUFBVSxFQUNWLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxFQUNoQyxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQ2hCLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FDcEIsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBYyxFQUFFLEVBQUU7WUFDdEIsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsRUFBRTtnQkFDbEMsT0FBTyxRQUFRLENBQUMsVUFBVSxLQUFLLFNBQVMsQ0FBQztZQUM3QyxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUNMLENBQUM7SUFDTixDQUFDOztxSEFoWlEsdUJBQXVCLDJLQWtFWixlQUFlO3lHQWxFMUIsdUJBQXVCLDhNQ25CcEMsZzNWQW9NQTs0RkRqTGEsdUJBQXVCO2tCQU5uQyxTQUFTOytCQUNJLHFCQUFxQixRQUd6QixFQUFDLEtBQUssRUFBRSxnQkFBZ0IsRUFBQzs7MEJBb0VsQixNQUFNOzJCQUFDLGVBQWU7K0VBaEViLFVBQVU7c0JBQS9CLFNBQVM7dUJBQUMsU0FBUyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29tcG9uZW50LCBJbmplY3QsIElucHV0LCBPbkluaXQsIFZpZXdDaGlsZH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0JlaGF2aW9yU3ViamVjdCwgbWVyZ2UsIFN1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtkZWJvdW5jZVRpbWUsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBtYXAsIHN3aXRjaE1hcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtEYXRhc2V0U2VydmljZX0gZnJvbSAnLi4vLi4vLi4vLi4vc2VydmljZXMvZGF0YXNldC5zZXJ2aWNlJztcbmltcG9ydCB7RGF0YXNvdXJjZVNlcnZpY2V9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL2RhdGFzb3VyY2Uuc2VydmljZSc7XG5pbXBvcnQge1Byb2plY3RTZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy9wcm9qZWN0LnNlcnZpY2UnO1xuaW1wb3J0IHtUYWdTZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy90YWcuc2VydmljZSc7XG5pbXBvcnQge01BVF9MRUdBQ1lfRElBTE9HX0RBVEEgYXMgTUFUX0RJQUxPR19EQVRBLCBNYXRMZWdhY3lEaWFsb2dSZWYgYXMgTWF0RGlhbG9nUmVmfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9sZWdhY3ktZGlhbG9nJztcbmltcG9ydCAqIGFzIGxvZGFzaCBmcm9tICdsb2Rhc2gnO1xuY29uc3QgXyA9IGxvZGFzaC5kZWZhdWx0O1xuaW1wb3J0IHtNYXRTdGVwcGVyfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zdGVwcGVyJztcbmltcG9ydCB7RGF0YVByb2Nlc3NvclNlcnZpY2V9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL2RhdGEtcHJvY2Vzc29yLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2tpLWRhdGFzZXQtYWRkLWpvaW4nLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9kYXRhc2V0LWFkZC1qb2luLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9kYXRhc2V0LWFkZC1qb2luLmNvbXBvbmVudC5zYXNzJ10sXG4gICAgaG9zdDoge2NsYXNzOiAnZGlhbG9nLXdyYXBwZXInfVxufSlcbmV4cG9ydCBjbGFzcyBEYXRhc2V0QWRkSm9pbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgICBAVmlld0NoaWxkKCdzdGVwcGVyJykgbWF0U3RlcHBlcjogTWF0U3RlcHBlcjtcblxuICAgIHB1YmxpYyBPYmplY3QgPSBPYmplY3Q7XG4gICAgcHVibGljIGVudmlyb25tZW50OiBhbnkgPSB7fTtcbiAgICBwdWJsaWMgZGF0YXNvdXJjZXM6IGFueSA9IFtdO1xuICAgIHB1YmxpYyBkYXRhc2V0czogYW55ID0gW107XG4gICAgcHVibGljIHNuYXBzaG90czogYW55ID0gW107XG4gICAgcHVibGljIHNoYXJlZERhdGFzZXRzOiBhbnkgPSBbXTtcbiAgICBwdWJsaWMgc2VhcmNoVGV4dCA9IG5ldyBCZWhhdmlvclN1YmplY3QoJycpO1xuICAgIHB1YmxpYyBzZWxlY3RlZFNvdXJjZTogYW55O1xuICAgIHB1YmxpYyBmaWx0ZXJGaWVsZHM6IGFueTtcbiAgICBwdWJsaWMgam9pbkZpbHRlckZpZWxkczogYW55O1xuICAgIHB1YmxpYyBqb2luQ29sdW1uczogYW55ID0gW107XG4gICAgcHVibGljIGpvaW5UcmFuc2Zvcm1hdGlvbjogYW55ID0ge1xuICAgICAgICB0eXBlOiAnam9pbicsXG4gICAgICAgIGNvbmZpZzoge1xuICAgICAgICAgICAgam9pbkZpbHRlcnM6IFtdLFxuICAgICAgICAgICAgam9pbkNvbHVtbnM6IFtdLFxuICAgICAgICAgICAgam9pblBhcmFtZXRlck1hcHBpbmdzOiBbXSxcbiAgICAgICAgICAgIHN0cmljdEpvaW46IGZhbHNlXG4gICAgICAgIH1cbiAgICB9O1xuICAgIHB1YmxpYyBhZG1pbjogYm9vbGVhbjtcbiAgICBwdWJsaWMgYWxsQ29sdW1ucyA9IHRydWU7XG4gICAgcHVibGljIGFjdGl2ZVByb2plY3Q6IGFueTtcbiAgICBwdWJsaWMgYWN0aXZlVGFnOiBhbnk7XG4gICAgcHVibGljIHJlcXVpcmVkUGFyYW1ldGVyczogYW55O1xuICAgIHB1YmxpYyBwYXJhbWV0ZXJWYWx1ZXM6IGFueTtcbiAgICBwdWJsaWMgdXBkYXRlUGFyYW1zID0gbmV3IFN1YmplY3QoKTtcbiAgICBwdWJsaWMgb3BlblNpZGUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KGZhbHNlKTtcbiAgICBwdWJsaWMgdGFibGVEYXRhOiBhbnkgPSB7XG4gICAgICAgIGRhdGFzb3VyY2VzOiB7XG4gICAgICAgICAgICBkYXRhOiBbXSxcbiAgICAgICAgICAgIGxpbWl0OiA1LFxuICAgICAgICAgICAgb2Zmc2V0OiAwLFxuICAgICAgICAgICAgcGFnZTogMSxcbiAgICAgICAgICAgIGVuZE9mUmVzdWx0czogZmFsc2UsXG4gICAgICAgICAgICBzaGFyZWQ6IGZhbHNlLFxuICAgICAgICAgICAgcmVsb2FkOiBuZXcgU3ViamVjdCgpLFxuICAgICAgICAgICAgdGl0bGU6ICdNeSBEYXRhJyxcbiAgICAgICAgICAgIHR5cGU6ICdkYXRhc291cmNlJ1xuICAgICAgICB9LFxuICAgICAgICBkYXRhc2V0czoge1xuICAgICAgICAgICAgZGF0YTogW10sXG4gICAgICAgICAgICBsaW1pdDogNSxcbiAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgIHBhZ2U6IDEsXG4gICAgICAgICAgICBlbmRPZlJlc3VsdHM6IGZhbHNlLFxuICAgICAgICAgICAgc2hhcmVkOiBmYWxzZSxcbiAgICAgICAgICAgIHJlbG9hZDogbmV3IFN1YmplY3QoKSxcbiAgICAgICAgICAgIHRpdGxlOiAnU3RvcmVkIFF1ZXJpZXMnLFxuICAgICAgICAgICAgdHlwZTogJ2RhdGFzZXQnXG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHVibGljIF8gPSBfO1xuXG4gICAgcHJpdmF0ZSBkYXRhc2V0RWRpdG9yOiBhbnk7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRhdGFzZXRTZXJ2aWNlOiBEYXRhc2V0U2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIGRhdGFzb3VyY2VTZXJ2aWNlOiBEYXRhc291cmNlU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIHByb2plY3RTZXJ2aWNlOiBQcm9qZWN0U2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIHRhZ1NlcnZpY2U6IFRhZ1NlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHVibGljIGRpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPERhdGFzZXRBZGRKb2luQ29tcG9uZW50PixcbiAgICAgICAgICAgICAgICBASW5qZWN0KE1BVF9ESUFMT0dfREFUQSkgcHVibGljIGRhdGE6IGFueSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIGRhdGFQcm9jZXNzb3JTZXJ2aWNlOiBEYXRhUHJvY2Vzc29yU2VydmljZSkge1xuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmFkbWluID0gISF0aGlzLmRhdGEuYWRtaW47XG4gICAgICAgIHRoaXMuZW52aXJvbm1lbnQgPSB0aGlzLmRhdGEuZW52aXJvbm1lbnQgfHwge307XG4gICAgICAgIHRoaXMuZmlsdGVyRmllbGRzID0gdGhpcy5kYXRhLmZpbHRlckZpZWxkcztcbiAgICAgICAgdGhpcy5wYXJhbWV0ZXJWYWx1ZXMgPSB0aGlzLmRhdGEucGFyYW1ldGVyVmFsdWVzO1xuICAgICAgICB0aGlzLmRhdGFzZXRFZGl0b3IgPSB0aGlzLmRhdGEuZGF0YXNldEVkaXRvcjtcblxuICAgICAgICBpZiAoIXRoaXMuYWRtaW4pIHtcbiAgICAgICAgICAgIHRoaXMudGFibGVEYXRhLnNoYXJlZCA9IHtcbiAgICAgICAgICAgICAgICBkYXRhOiBbXSxcbiAgICAgICAgICAgICAgICBsaW1pdDogNSxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IDAsXG4gICAgICAgICAgICAgICAgcGFnZTogMSxcbiAgICAgICAgICAgICAgICBlbmRPZlJlc3VsdHM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNoYXJlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgcmVsb2FkOiBuZXcgU3ViamVjdCgpLFxuICAgICAgICAgICAgICAgIHRpdGxlOiAnRGF0YSBGZWVkcycsXG4gICAgICAgICAgICAgICAgdHlwZTogJ2RhdGFzZXQnXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy50YWJsZURhdGEuc25hcHNob3RzID0ge1xuICAgICAgICAgICAgZGF0YTogW10sXG4gICAgICAgICAgICBsaW1pdDogNSxcbiAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgIHBhZ2U6IDEsXG4gICAgICAgICAgICBlbmRPZlJlc3VsdHM6IGZhbHNlLFxuICAgICAgICAgICAgc2hhcmVkOiBmYWxzZSxcbiAgICAgICAgICAgIHJlbG9hZDogbmV3IFN1YmplY3QoKSxcbiAgICAgICAgICAgIHRpdGxlOiAnU25hcHNob3RzJyxcbiAgICAgICAgICAgIHR5cGU6ICdzbmFwc2hvdCdcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLmFjdGl2ZVByb2plY3QgPSB0aGlzLnByb2plY3RTZXJ2aWNlLmFjdGl2ZVByb2plY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgdGhpcy5hY3RpdmVUYWcgPSB0aGlzLnRhZ1NlcnZpY2UuYWN0aXZlVGFnLmdldFZhbHVlKCk7XG5cbiAgICAgICAgbWVyZ2UodGhpcy5zZWFyY2hUZXh0LCB0aGlzLnRhYmxlRGF0YS5kYXRhc2V0cy5yZWxvYWQpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBkZWJvdW5jZVRpbWUoMzAwKSxcbiAgICAgICAgICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdldERhdGFzZXRzKGZhbHNlLCB0aGlzLnRhYmxlRGF0YS5kYXRhc2V0cy5saW1pdCwgdGhpcy50YWJsZURhdGEuZGF0YXNldHMub2Zmc2V0KVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICkuc3Vic2NyaWJlKChkYXRhc2V0czogYW55KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRhYmxlRGF0YS5kYXRhc2V0cy5lbmRPZlJlc3VsdHMgPSBkYXRhc2V0cy5sZW5ndGggPCB0aGlzLnRhYmxlRGF0YS5kYXRhc2V0cy5saW1pdDtcbiAgICAgICAgICAgIHRoaXMudGFibGVEYXRhLmRhdGFzZXRzLmRhdGEgPSBkYXRhc2V0cztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbWVyZ2UodGhpcy5zZWFyY2hUZXh0LCB0aGlzLnRhYmxlRGF0YS5zbmFwc2hvdHMucmVsb2FkKVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgZGVib3VuY2VUaW1lKDMwMCksXG4gICAgICAgICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRTbmFwc2hvdHModGhpcy50YWJsZURhdGEuc25hcHNob3RzLmxpbWl0LCB0aGlzLnRhYmxlRGF0YS5zbmFwc2hvdHMub2Zmc2V0KVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICkuc3Vic2NyaWJlKChzbmFwc2hvdHM6IGFueSkgPT4ge1xuICAgICAgICAgICAgdGhpcy50YWJsZURhdGEuc25hcHNob3RzLmVuZE9mUmVzdWx0cyA9IHNuYXBzaG90cy5sZW5ndGggPCB0aGlzLnRhYmxlRGF0YS5zbmFwc2hvdHMubGltaXQ7XG4gICAgICAgICAgICB0aGlzLnRhYmxlRGF0YS5zbmFwc2hvdHMuZGF0YSA9IHNuYXBzaG90cztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbWVyZ2UodGhpcy5zZWFyY2hUZXh0LCB0aGlzLnRhYmxlRGF0YS5kYXRhc291cmNlcy5yZWxvYWQpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBkZWJvdW5jZVRpbWUoMzAwKSxcbiAgICAgICAgICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdldERhdGFzb3VyY2VzKHRoaXMudGFibGVEYXRhLmRhdGFzb3VyY2VzLmxpbWl0LCB0aGlzLnRhYmxlRGF0YS5kYXRhc291cmNlcy5vZmZzZXQpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKS5zdWJzY3JpYmUoKGRhdGFzb3VyY2VzOiBhbnkpID0+IHtcbiAgICAgICAgICAgIHRoaXMudGFibGVEYXRhLmRhdGFzb3VyY2VzLmVuZE9mUmVzdWx0cyA9IGRhdGFzb3VyY2VzLmxlbmd0aCA8IHRoaXMudGFibGVEYXRhLmRhdGFzb3VyY2VzLmxpbWl0O1xuICAgICAgICAgICAgdGhpcy50YWJsZURhdGEuZGF0YXNvdXJjZXMuZGF0YSA9IGRhdGFzb3VyY2VzO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIXRoaXMuYWRtaW4pIHtcbiAgICAgICAgICAgIG1lcmdlKHRoaXMuc2VhcmNoVGV4dCwgdGhpcy50YWJsZURhdGEuc2hhcmVkLnJlbG9hZClcbiAgICAgICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICAgICAgZGVib3VuY2VUaW1lKDMwMCksXG4gICAgICAgICAgICAgICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXREYXRhc2V0cyh0cnVlLCB0aGlzLnRhYmxlRGF0YS5zaGFyZWQubGltaXQsIHRoaXMudGFibGVEYXRhLnNoYXJlZC5vZmZzZXQpXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApLnN1YnNjcmliZSgoc2hhcmVkOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnRhYmxlRGF0YS5zaGFyZWQuZW5kT2ZSZXN1bHRzID0gc2hhcmVkLmxlbmd0aCA8IHRoaXMudGFibGVEYXRhLnNoYXJlZC5saW1pdDtcbiAgICAgICAgICAgICAgICB0aGlzLnRhYmxlRGF0YS5zaGFyZWQuZGF0YSA9IHNoYXJlZDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZGF0YS5qb2luVHJhbnNmb3JtYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuam9pblRyYW5zZm9ybWF0aW9uID0gdGhpcy5kYXRhLmpvaW5UcmFuc2Zvcm1hdGlvbjtcbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBkYXRhc291cmNlS2V5OiB0aGlzLmpvaW5UcmFuc2Zvcm1hdGlvbi5jb25maWcuam9pbmVkRGF0YVNvdXJjZUluc3RhbmNlS2V5LFxuICAgICAgICAgICAgICAgIGRhdGFzZXRJZDogdGhpcy5qb2luVHJhbnNmb3JtYXRpb24uY29uZmlnLmpvaW5lZERhdGFTZXRJbnN0YW5jZUlkXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdChhY3Rpb24sIHRoaXMubWF0U3RlcHBlciwgZmFsc2UpO1xuICAgICAgICAgICAgfSwgMjAwKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBpbmNyZWFzZU9mZnNldChkYXRhSXRlbSkge1xuICAgICAgICBkYXRhSXRlbS5wYWdlID0gZGF0YUl0ZW0ucGFnZSArIDE7XG4gICAgICAgIGRhdGFJdGVtLm9mZnNldCA9IChkYXRhSXRlbS5saW1pdCAqIGRhdGFJdGVtLnBhZ2UpIC0gZGF0YUl0ZW0ubGltaXQ7XG4gICAgICAgIGRhdGFJdGVtLnJlbG9hZC5uZXh0KERhdGUubm93KCkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkZWNyZWFzZU9mZnNldChkYXRhSXRlbSkge1xuICAgICAgICBkYXRhSXRlbS5wYWdlID0gZGF0YUl0ZW0ucGFnZSA8PSAxID8gMSA6IGRhdGFJdGVtLnBhZ2UgLSAxO1xuICAgICAgICBkYXRhSXRlbS5vZmZzZXQgPSAoZGF0YUl0ZW0ubGltaXQgKiBkYXRhSXRlbS5wYWdlKSAtIGRhdGFJdGVtLmxpbWl0O1xuICAgICAgICBkYXRhSXRlbS5yZWxvYWQubmV4dChEYXRlLm5vdygpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcGFnZVNpemVDaGFuZ2UodmFsdWUsIGRhdGFJdGVtKSB7XG4gICAgICAgIGRhdGFJdGVtLnBhZ2UgPSAxO1xuICAgICAgICBkYXRhSXRlbS5vZmZzZXQgPSAwO1xuICAgICAgICBkYXRhSXRlbS5saW1pdCA9IHZhbHVlO1xuICAgICAgICBkYXRhSXRlbS5yZWxvYWQubmV4dChEYXRlLm5vdygpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgc2VsZWN0KGFjdGlvbiwgc3RlcCwgcmVzZXQgPSB0cnVlKSB7XG4gICAgICAgIHRoaXMuam9pbkZpbHRlckZpZWxkcyA9IG51bGw7XG4gICAgICAgIC8vIFJlc2V0IGlmIHdlIGFyZSBzZWxlY3RpbmcgYW4gaXRlbSBhZ2Fpbiwgbm90IGxvYWRpbmcgaW5pdGlhbGx5LlxuICAgICAgICBpZiAocmVzZXQpIHtcbiAgICAgICAgICAgIHRoaXMuam9pblRyYW5zZm9ybWF0aW9uID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdqb2luJyxcbiAgICAgICAgICAgICAgICBjb25maWc6IHtcbiAgICAgICAgICAgICAgICAgICAgam9pbkZpbHRlcnM6IFtdLFxuICAgICAgICAgICAgICAgICAgICBqb2luQ29sdW1uczogW10sXG4gICAgICAgICAgICAgICAgICAgIGpvaW5QYXJhbWV0ZXJNYXBwaW5nczogW10sXG4gICAgICAgICAgICAgICAgICAgIHN0cmljdEpvaW46IGZhbHNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCByZXF1aXJlZFBhcmFtczogYW55ID0gW107XG5cbiAgICAgICAgaWYgKGFjdGlvbi5kYXRhc291cmNlS2V5KSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkU291cmNlID0ge1xuICAgICAgICAgICAgICAgIGRhdGFzZXRJbnN0YW5jZUlkOiBudWxsLFxuICAgICAgICAgICAgICAgIGRhdGFzb3VyY2VJbnN0YW5jZUtleTogYWN0aW9uLmRhdGFzb3VyY2VLZXksXG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtYXRpb25JbnN0YW5jZXM6IFtdLFxuICAgICAgICAgICAgICAgIHBhcmFtZXRlclZhbHVlczoge30sXG4gICAgICAgICAgICAgICAgcGFyYW1ldGVyczogW11cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmpvaW5UcmFuc2Zvcm1hdGlvbi5jb25maWcuam9pbmVkRGF0YVNvdXJjZUluc3RhbmNlS2V5ID0gYWN0aW9uLmRhdGFzb3VyY2VLZXk7XG5cbiAgICAgICAgICAgIHJlcXVpcmVkUGFyYW1zID0gYXdhaXQgdGhpcy5kYXRhc291cmNlU2VydmljZS5nZXRFdmFsdWF0ZWRQYXJhbWV0ZXJzKHtcbiAgICAgICAgICAgICAgICBrZXk6IGFjdGlvbi5kYXRhc291cmNlS2V5XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChhY3Rpb24uZGF0YXNldElkKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkU291cmNlID0gYXdhaXQgdGhpcy5kYXRhc2V0U2VydmljZS5nZXREYXRhc2V0KGFjdGlvbi5kYXRhc2V0SWQpO1xuICAgICAgICAgICAgdGhpcy5qb2luVHJhbnNmb3JtYXRpb24uY29uZmlnLmpvaW5lZERhdGFTZXRJbnN0YW5jZUlkID0gYWN0aW9uLmRhdGFzZXRJZDtcblxuICAgICAgICAgICAgcmVxdWlyZWRQYXJhbXMgPSBhd2FpdCB0aGlzLmRhdGFzZXRTZXJ2aWNlLmdldEV2YWx1YXRlZFBhcmFtZXRlcnModGhpcy5zZWxlY3RlZFNvdXJjZSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBleGlzdGluZ0pvaW5lZFBhcmFtZXRlcnMgPSB0aGlzLmpvaW5UcmFuc2Zvcm1hdGlvbi5jb25maWcuam9pblBhcmFtZXRlck1hcHBpbmdzIHx8IFtdO1xuXG4gICAgICAgIHRoaXMuY3JlYXRlUGFyYW1ldGVyU3RydWN0dXJlKHJlcXVpcmVkUGFyYW1zLCBleGlzdGluZ0pvaW5lZFBhcmFtZXRlcnMpO1xuXG4gICAgICAgIGlmICghdGhpcy5yZXF1aXJlZFBhcmFtZXRlcnMgfHwgIXRoaXMucmVxdWlyZWRQYXJhbWV0ZXJzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5nZXRKb2luQ29sdW1ucyhyZXNldCk7XG4gICAgICAgIH1cblxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHN0ZXAubmV4dCgpO1xuICAgICAgICB9LCAwKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdG9nZ2xlQWxsQ29sdW1ucyhldmVudCkge1xuICAgICAgICB0aGlzLmpvaW5Db2x1bW5zLm1hcChjb2x1bW4gPT4ge1xuICAgICAgICAgICAgY29sdW1uLnNlbGVjdGVkID0gZXZlbnQuY2hlY2tlZDtcbiAgICAgICAgICAgIHJldHVybiBjb2x1bW47XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhbGxTZWxlY3RlZCgpIHtcbiAgICAgICAgdGhpcy5hbGxDb2x1bW5zID0gXy5ldmVyeSh0aGlzLmpvaW5Db2x1bW5zLCAnc2VsZWN0ZWQnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0UGFyYW1ldGVyVmFsdWVzKHN0ZXApIHtcbiAgICAgICAgdGhpcy51cGRhdGVQYXJhbXMubmV4dChEYXRlLm5vdygpKTtcblxuICAgICAgICBhd2FpdCB0aGlzLmdldEpvaW5Db2x1bW5zKHRydWUpO1xuXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgc3RlcC5uZXh0KCk7XG4gICAgICAgIH0sIDApO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRFdmFsdWF0ZWRQYXJhbWV0ZXJzKHJlcXVpcmVkUGFyYW1ldGVycywgc3RlcD8pIHtcbiAgICAgICAgY29uc3QgcGFyYW1ldGVyTWFwcGluZ3MgPSBbXTtcbiAgICAgICAgcmVxdWlyZWRQYXJhbWV0ZXJzLmZvckVhY2gocGFyYW0gPT4ge1xuICAgICAgICAgICAgY29uc3QgbWFwcGluZzogYW55ID0ge3BhcmFtZXRlck5hbWU6IHBhcmFtLm5hbWV9O1xuICAgICAgICAgICAgaWYgKHBhcmFtLnNlbGVjdGVkVHlwZSA9PT0gJ0NvbHVtbicpIHtcbiAgICAgICAgICAgICAgICBtYXBwaW5nLnNvdXJjZUNvbHVtbk5hbWUgPSBwYXJhbS52YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocGFyYW0uc2VsZWN0ZWRUeXBlID09PSAnUGFyYW1ldGVyJykge1xuICAgICAgICAgICAgICAgIG1hcHBpbmcuc291cmNlUGFyYW1ldGVyTmFtZSA9IHBhcmFtLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcGFyYW1ldGVyTWFwcGluZ3MucHVzaChtYXBwaW5nKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuam9pblRyYW5zZm9ybWF0aW9uLmNvbmZpZy5qb2luUGFyYW1ldGVyTWFwcGluZ3MgPSBwYXJhbWV0ZXJNYXBwaW5ncztcbiAgICB9XG5cbiAgICBwdWJsaWMgam9pbigpIHtcbiAgICAgICAgY29uc3QgZmlsdGVycyA9IHRoaXMuam9pblRyYW5zZm9ybWF0aW9uLmNvbmZpZy5qb2luRmlsdGVycztcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRDb2x1bW5zID0gXy5maWx0ZXIodGhpcy5qb2luQ29sdW1ucywgJ3NlbGVjdGVkJyk7XG4gICAgICAgIHRoaXMuam9pblRyYW5zZm9ybWF0aW9uLmNvbmZpZy5qb2luQ29sdW1ucyA9IHNlbGVjdGVkQ29sdW1ucy5tYXAoY29sdW1uID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7bmFtZTogY29sdW1uLm5hbWUsIHRpdGxlOiBjb2x1bW4udGl0bGV9O1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kaWFsb2dSZWYuY2xvc2UodGhpcy5qb2luVHJhbnNmb3JtYXRpb24pO1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlUGFyYW1ldGVyU3RydWN0dXJlKHJlcXVpcmVkUGFyYW1ldGVycywgZXhpc3RpbmdWYWx1ZSA9IFtdKSB7XG4gICAgICAgIHRoaXMucmVxdWlyZWRQYXJhbWV0ZXJzID0gcmVxdWlyZWRQYXJhbWV0ZXJzLm1hcChwYXJhbSA9PiB7XG4gICAgICAgICAgICBwYXJhbS50eXBlID0gJ2pvaW4nO1xuICAgICAgICAgICAgcGFyYW0uc2VsZWN0ZWRUeXBlID0gJ0NvbHVtbic7XG5cbiAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nID0gXy5maW5kKGV4aXN0aW5nVmFsdWUsIHtwYXJhbWV0ZXJOYW1lOiBwYXJhbS5uYW1lfSk7XG4gICAgICAgICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXhpc3Rpbmcuc291cmNlQ29sdW1uTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbS52YWx1ZSA9IGV4aXN0aW5nLnNvdXJjZUNvbHVtbk5hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChleGlzdGluZy5zb3VyY2VQYXJhbWV0ZXJOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmFtLnNlbGVjdGVkVHlwZSA9ICdQYXJhbWV0ZXInO1xuICAgICAgICAgICAgICAgICAgICBwYXJhbS52YWx1ZSA9IGV4aXN0aW5nLnNvdXJjZVBhcmFtZXRlck5hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwYXJhbS52YWx1ZXMgPSBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ0NvbHVtbicsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlczogdGhpcy5maWx0ZXJGaWVsZHNcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdQYXJhbWV0ZXInLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IF8ubWFwKHRoaXMucGFyYW1ldGVyVmFsdWVzLCAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IHZhbHVlLnRpdGxlICsgJyAoJyArIHZhbHVlLmN1cnJlbnRWYWx1ZSArICcpJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiB2YWx1ZS5uYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICByZXR1cm4gcGFyYW07XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZ2V0Sm9pbkNvbHVtbnMocmVzZXQgPSB0cnVlKSB7XG4gICAgICAgIGlmIChyZXNldCkge1xuICAgICAgICAgICAgdGhpcy5qb2luVHJhbnNmb3JtYXRpb24uY29uZmlnLmpvaW5GaWx0ZXJzID0ge1xuICAgICAgICAgICAgICAgIGxvZ2ljOiAnQU5EJyxcbiAgICAgICAgICAgICAgICBmaWx0ZXJzOiBbe1xuICAgICAgICAgICAgICAgICAgICBsaHNFeHByZXNzaW9uOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgcmhzRXhwcmVzc2lvbjogJycsXG4gICAgICAgICAgICAgICAgICAgIGZpbHRlclR5cGU6ICdlcSdcbiAgICAgICAgICAgICAgICB9XSxcbiAgICAgICAgICAgICAgICBmaWx0ZXJKdW5jdGlvbnM6IFtdXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgd2UgaGF2ZSBqb2luIHBhcmFtZXRlciBtYXBwaW5ncyB0aGVuIHdlIG5lZWQgdG8gYWRkIHRoZSBwYXJhbWV0ZXIgdmFsdWUgdG8gdGhlIGV2YWx1YXRlIHRvIGdldCBjb2x1bW4gZGF0YVxuICAgICAgICBpZiAodGhpcy5qb2luVHJhbnNmb3JtYXRpb24uY29uZmlnLmpvaW5QYXJhbWV0ZXJNYXBwaW5ncyAmJlxuICAgICAgICAgICAgdGhpcy5qb2luVHJhbnNmb3JtYXRpb24uY29uZmlnLmpvaW5QYXJhbWV0ZXJNYXBwaW5ncy5sZW5ndGgpIHtcblxuICAgICAgICAgICAgY29uc3QgZmlyc3REYXRhUm93ID0gdGhpcy5kYXRhc2V0RWRpdG9yLmRhdGFzZXQuYWxsRGF0YVswXTtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlclZhbHVlcyA9IHt9O1xuICAgICAgICAgICAgdGhpcy5qb2luVHJhbnNmb3JtYXRpb24uY29uZmlnLmpvaW5QYXJhbWV0ZXJNYXBwaW5ncy5mb3JFYWNoKHBhcmFtID0+IHtcbiAgICAgICAgICAgICAgICBwYXJhbWV0ZXJWYWx1ZXNbcGFyYW0ucGFyYW1ldGVyTmFtZV0gPSBmaXJzdERhdGFSb3dbcGFyYW0uc291cmNlQ29sdW1uTmFtZV07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFNvdXJjZS5wYXJhbWV0ZXJWYWx1ZXMgPSBwYXJhbWV0ZXJWYWx1ZXM7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkYXRhOiBhbnkgPSBhd2FpdCB0aGlzLmRhdGFzZXRTZXJ2aWNlLmV2YWx1YXRlRGF0YXNldCh0aGlzLnNlbGVjdGVkU291cmNlLCAnMCcsICcxJyk7XG4gICAgICAgIGlmIChkYXRhLmNvbHVtbnMpIHtcbiAgICAgICAgICAgIHRoaXMuam9pbkZpbHRlckZpZWxkcyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5qb2luQ29sdW1ucyA9IFtdO1xuICAgICAgICAgICAgZGF0YS5jb2x1bW5zLmZvckVhY2goY29sdW1uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmpvaW5GaWx0ZXJGaWVsZHMucHVzaChcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IGNvbHVtbi50aXRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IGNvbHVtbi5uYW1lXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnN0IGR1cGxpY2F0ZSA9ICEhXy5maW5kKHRoaXMuZmlsdGVyRmllbGRzLCB7bmFtZTogY29sdW1uLm5hbWUsIHRpdGxlOiBjb2x1bW4udGl0bGV9KTtcbiAgICAgICAgICAgICAgICB0aGlzLmpvaW5Db2x1bW5zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDogIWR1cGxpY2F0ZSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogY29sdW1uLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiBjb2x1bW4udGl0bGUsXG4gICAgICAgICAgICAgICAgICAgIGR1cGxpY2F0ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERhdGFzZXRzKHNoYXJlZCwgbGltaXQsIG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRhc2V0U2VydmljZS5nZXREYXRhc2V0cyhcbiAgICAgICAgICAgIHRoaXMuc2VhcmNoVGV4dC5nZXRWYWx1ZSgpIHx8ICcnLFxuICAgICAgICAgICAgbGltaXQudG9TdHJpbmcoKSxcbiAgICAgICAgICAgIG9mZnNldC50b1N0cmluZygpLFxuICAgICAgICAgICAgc2hhcmVkID8gbnVsbCA6ICcnXG4gICAgICAgICkucGlwZShtYXAoKGRhdGFzZXRzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YXNldHM7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0RGF0YXNvdXJjZXMobGltaXQsIG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRhc291cmNlU2VydmljZS5nZXREYXRhc291cmNlcyhcbiAgICAgICAgICAgIHRoaXMuc2VhcmNoVGV4dC5nZXRWYWx1ZSgpIHx8ICcnLFxuICAgICAgICAgICAgbGltaXQudG9TdHJpbmcoKSxcbiAgICAgICAgICAgIG9mZnNldC50b1N0cmluZygpXG4gICAgICAgICkucGlwZShtYXAoKHNvdXJjZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBzb3VyY2VzO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFNuYXBzaG90cyhsaW1pdCwgb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGFQcm9jZXNzb3JTZXJ2aWNlLmZpbHRlclByb2Nlc3NvcnNCeVR5cGUoXG4gICAgICAgICAgICAnc25hcHNob3QnLFxuICAgICAgICAgICAgdGhpcy5zZWFyY2hUZXh0LmdldFZhbHVlKCkgfHwgJycsXG4gICAgICAgICAgICBsaW1pdC50b1N0cmluZygpLFxuICAgICAgICAgICAgb2Zmc2V0LnRvU3RyaW5nKClcbiAgICAgICAgKS5waXBlKG1hcCgoc25hcHNob3RzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXy5maWx0ZXIoc25hcHNob3RzLCBzbmFwc2hvdCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzbmFwc2hvdC50YXNrU3RhdHVzICE9PSAnUEVORElORyc7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJkaWFsb2dcIiBjZGtEcmFnIGNka0RyYWdSb290RWxlbWVudD1cIi5jZGstb3ZlcmxheS1wYW5lXCI+XG5cbiAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nLXRpdGxlXCIgY2RrRHJhZ0hhbmRsZT5cbiAgICAgICAgPGgyIG1hdC1kaWFsb2ctdGl0bGU+Sm9pbiBEYXRhPC9oMj5cblxuICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBtYXQtZGlhbG9nLWNsb3NlPlxuICAgICAgICAgICAgPG1hdC1pY29uPmNsZWFyPC9tYXQtaWNvbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nLWNvbnRlbnQgcC0wXCI+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImJvcmRlci10IGJnLWJsdWUtNTAgcC00XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LXNocmluay0wXCI+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gSGVyb2ljb24gbmFtZTogbWluaS9pbmZvcm1hdGlvbi1jaXJjbGUgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJoLTUgdy01IHRleHQtYmx1ZS00MDBcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cImN1cnJlbnRDb2xvclwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTE5IDEwLjVhOC41IDguNSAwIDExLTE3IDAgOC41IDguNSAwIDAxMTcgMHpNOC4yNSA5Ljc1QS43NS43NSAwIDAxOSA5aC4yNTNhMS43NSAxLjc1IDAgMDExLjcwOSAyLjEzbC0uNDYgMi4wNjZhLjI1LjI1IDAgMDAuMjQ1LjMwNEgxMWEuNzUuNzUgMCAwMTAgMS41aC0uMjUzYTEuNzUgMS43NSAwIDAxLTEuNzA5LTIuMTNsLjQ2LTIuMDY2YS4yNS4yNSAwIDAwLS4yNDUtLjMwNEg5YS43NS43NSAwIDAxLS43NS0uNzV6TTEwIDdhMSAxIDAgMTAwLTIgMSAxIDAgMDAwIDJ6XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaXAtcnVsZT1cImV2ZW5vZGRcIi8+XG4gICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtbC0zIGZsZXgtMSBtZDpmbGV4IG1kOmp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQtc20gdGV4dC1ibHVlLTcwMCBtYi0wXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBKb2luIERhdGEgZnVuY3Rpb25hbGl0eSBhbGxvd3MgeW91IHRvIG1lcmdlIGRhdGEgZnJvbSBhbm90aGVyIERhdGEgRmVlZCwgb3IgU3RvcmVkIFF1ZXJ5XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnRvIHRoaXMgZGF0YSBmZWVkLiA8Yj5TZWxlY3Q8L2I+IHRoZSBkYXRhIHRvIG1lcmdlIGFuZCBmb2xsb3cgdGhlIG9uIHNjcmVlbiBwcm9tcHRzIHRvXG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGpvaW4uXG4gICAgICAgICAgICAgICAgICAgIDwvcD5cblxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxtYXQtaG9yaXpvbnRhbC1zdGVwcGVyIFtsaW5lYXJdPVwidHJ1ZVwiICNzdGVwcGVyIFthbmltYXRpb25EdXJhdGlvbl09XCIwXCI+XG4gICAgICAgICAgICA8bWF0LXN0ZXAgW2NvbXBsZXRlZF09XCJzZWxlY3RlZFNvdXJjZVwiIGxhYmVsPVwiU2VsZWN0IGRhdGFcIj5cblxuICAgICAgICAgICAgICAgIDxraS1kYXRhLXBpY2tlciBjbGFzcz1cImJsb2NrXCIgc3R5bGU9XCJoZWlnaHQ6IDU0N3B4XCIgW2FkbWluXT1cImFkbWluXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGVjdGVkKT1cInNlbGVjdCgkZXZlbnQsIHN0ZXBwZXIpXCI+PC9raS1kYXRhLXBpY2tlcj5cblxuICAgICAgICAgICAgPC9tYXQtc3RlcD5cbiAgICAgICAgICAgIDxtYXQtc3RlcCAqbmdJZj1cInJlcXVpcmVkUGFyYW1ldGVycyAmJiByZXF1aXJlZFBhcmFtZXRlcnMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICAgICAgICBbY29tcGxldGVkXT1cImpvaW5UcmFuc2Zvcm1hdGlvbi5jb25maWcuam9pblBhcmFtZXRlck1hcHBpbmdzLmxlbmd0aCA+PSAxXCJcbiAgICAgICAgICAgICAgICAgICAgICBsYWJlbD1cIlJlcXVpcmVkIHBhcmFtZXRlcnNcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXgtNFwiPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIXNlbGVjdGVkU291cmNlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cD5QbGVhc2Ugc2VsZWN0IGVpdGhlciBhIERhdGFzb3VyY2Ugb3IgRGF0YXNldCB0byBqb2luIHRvLjwvcD5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwic2VsZWN0ZWRTb3VyY2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWItNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxiICpuZ0lmPVwiIWpvaW5UcmFuc2Zvcm1hdGlvbi5jb25maWcuam9pbmVkRGF0YUl0ZW1UaXRsZVwiPlNlbGVjdGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZToge3sgc2VsZWN0ZWRTb3VyY2UudGl0bGUgfHwgc2VsZWN0ZWRTb3VyY2UubmFtZSB9fTwvYj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YiAqbmdJZj1cImpvaW5UcmFuc2Zvcm1hdGlvbi5jb25maWcuam9pbmVkRGF0YUl0ZW1UaXRsZVwiPlNlbGVjdGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZToge3sgam9pblRyYW5zZm9ybWF0aW9uLmNvbmZpZy5qb2luZWREYXRhSXRlbVRpdGxlIH19PC9iPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItNFwiICpuZ0lmPVwicmVxdWlyZWRQYXJhbWV0ZXJzICYmIHJlcXVpcmVkUGFyYW1ldGVycy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8a2ktZGF0YXNldC1wYXJhbWV0ZXItdmFsdWVzIFtwYXJhbWV0ZXJWYWx1ZXNdPVwicmVxdWlyZWRQYXJhbWV0ZXJzXCIgW2hpZGVOZXddPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdXBkYXRlXT1cInVwZGF0ZVBhcmFtc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlZCk9XCJzZXRFdmFsdWF0ZWRQYXJhbWV0ZXJzKCRldmVudCwgc3RlcHBlcilcIj48L2tpLWRhdGFzZXQtcGFyYW1ldGVyLXZhbHVlcz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm91bmRlZC1tZCBiZy1ibHVlLTUwIHAtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LXNocmluay0wXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEhlcm9pY29uIG5hbWU6IHNvbGlkL2luZm9ybWF0aW9uLWNpcmNsZSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJoLTUgdy01IHRleHQtYmx1ZS00MDBcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTE4IDEwYTggOCAwIDExLTE2IDAgOCA4IDAgMDExNiAwem0tNy00YTEgMSAwIDExLTIgMCAxIDEgMCAwMTIgMHpNOSA5YTEgMSAwIDAwMCAydjNhMSAxIDAgMDAxIDFoMWExIDEgMCAxMDAtMnYtM2ExIDEgMCAwMC0xLTFIOXpcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaXAtcnVsZT1cImV2ZW5vZGRcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtbC0zIGZsZXgtMSBtZDpmbGV4IG1kOmp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXNtIHRleHQtYmx1ZS02MDAgbWItMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBzZWxlY3RlZCBzb3VyY2UgcmVxdWlyZXMgYSBwYXJhbWV0ZXIgdG8gYmUgc2V0IGluIG9yZGVyIGZvciB0aGUgZGF0YVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGJlIHJldHJpZXZlZC4gUGxlYXNlIGNob29zZSB0aGUgcmVsZXZhbnQgY29sdW1uIHRvIHVzZSBhcyB0aGUgcGFyYW1ldGVyIG9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hvb3NlIGFuIGV4aXN0aW5nIHBhcmFtZXRlciB2YWx1ZSBhbHJlYWR5IGRlZmluZWQgaW4gdGhpcyBxdWVyeS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9tYXQtc3RlcD5cbiAgICAgICAgICAgIDxtYXQtc3RlcCAqbmdJZj1cIiFyZXF1aXJlZFBhcmFtZXRlcnMgfHwgIXJlcXVpcmVkUGFyYW1ldGVycy5sZW5ndGhcIlxuICAgICAgICAgICAgICAgICAgICAgIFtjb21wbGV0ZWRdPVwiKCFqb2luRmlsdGVyRmllbGRzIHx8ICFqb2luRmlsdGVyRmllbGRzLmxlbmd0aCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIChfLmV2ZXJ5KGpvaW5UcmFuc2Zvcm1hdGlvbi5jb25maWcuam9pbkZpbHRlcnMuZmlsdGVycywgJ2xoc0V4cHJlc3Npb24nKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLmV2ZXJ5KGpvaW5UcmFuc2Zvcm1hdGlvbi5jb25maWcuam9pbkZpbHRlcnMuZmlsdGVycywgJ3Joc0V4cHJlc3Npb24nKSlcIlxuICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPVwiSm9pbiBjcml0ZXJpYVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteC00XCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCIhc2VsZWN0ZWRTb3VyY2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwPlBsZWFzZSBzZWxlY3QgZWl0aGVyIGEgRGF0YXNvdXJjZSBvciBEYXRhc2V0IHRvIGpvaW4gdG8uPC9wPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJzZWxlY3RlZFNvdXJjZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGIgKm5nSWY9XCIham9pblRyYW5zZm9ybWF0aW9uLmNvbmZpZy5qb2luZWREYXRhSXRlbVRpdGxlXCI+U2VsZWN0ZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlOiB7eyBzZWxlY3RlZFNvdXJjZS50aXRsZSB8fCBzZWxlY3RlZFNvdXJjZS5uYW1lIH19PC9iPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxiICpuZ0lmPVwiam9pblRyYW5zZm9ybWF0aW9uLmNvbmZpZy5qb2luZWREYXRhSXRlbVRpdGxlXCI+U2VsZWN0ZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlOiB7eyBqb2luVHJhbnNmb3JtYXRpb24uY29uZmlnLmpvaW5lZERhdGFJdGVtVGl0bGUgfX08L2I+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXktNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggWyhuZ01vZGVsKV09XCJqb2luVHJhbnNmb3JtYXRpb24uY29uZmlnLnN0cmljdEpvaW5cIj5TdHJpY3QgSm9pbj88L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cD48c21hbGw+SWYgdHVybmVkIG9uLCBkYXRhIHdpbGwgYmUgcHJ1bmVkIHRvIG9ubHkgcmV0dXJuIHJvd3MgdGhhdCBtYXRjaC48L3NtYWxsPjwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8a2ktZGF0YXNldC1maWx0ZXJzICpuZ0lmPVwiam9pbkZpbHRlckZpZWxkc1wiIFtmaWx0ZXJGaWVsZHNdPVwiZmlsdGVyRmllbGRzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2pvaW5GaWx0ZXJGaWVsZHNdPVwiam9pbkZpbHRlckZpZWxkc1wiIFtvcGVuU2lkZV09XCJvcGVuU2lkZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtqb2luRmllbGRzTmFtZV09XCJzZWxlY3RlZFNvdXJjZS50aXRsZSB8fCBzZWxlY3RlZFNvdXJjZS5uYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ZpbHRlckp1bmN0aW9uXT1cImpvaW5UcmFuc2Zvcm1hdGlvbi5jb25maWcuam9pbkZpbHRlcnNcIj48L2tpLWRhdGFzZXQtZmlsdGVycz5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIm9wZW5TaWRlLmdldFZhbHVlKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8a2ktd2hpdGVsaXN0ZWQtc3FsLWZ1bmN0aW9ucyBbZmllbGRzXT1cImZpbHRlckZpZWxkc1wiPjwva2ktd2hpdGVsaXN0ZWQtc3FsLWZ1bmN0aW9ucz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbWF0LXN0ZXA+XG5cbiAgICAgICAgICAgIDxtYXQtc3RlcCBbY29tcGxldGVkXT1cImZhbHNlXCIgbGFiZWw9XCJDb2x1bW4gZGVmaW5pdGlvblwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteC00XCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCIhc2VsZWN0ZWRTb3VyY2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwPlBsZWFzZSBzZWxlY3QgZWl0aGVyIGEgRGF0YXNvdXJjZSBvciBEYXRhc2V0IHRvIGpvaW4gdG8uPC9wPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJzZWxlY3RlZFNvdXJjZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGIgKm5nSWY9XCIham9pblRyYW5zZm9ybWF0aW9uLmNvbmZpZy5qb2luZWREYXRhSXRlbVRpdGxlXCI+U2VsZWN0ZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlOiB7eyBzZWxlY3RlZFNvdXJjZS50aXRsZSB8fCBzZWxlY3RlZFNvdXJjZS5uYW1lIH19PC9iPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxiICpuZ0lmPVwiam9pblRyYW5zZm9ybWF0aW9uLmNvbmZpZy5qb2luZWREYXRhSXRlbVRpdGxlXCI+U2VsZWN0ZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlOiB7eyBqb2luVHJhbnNmb3JtYXRpb24uY29uZmlnLmpvaW5lZERhdGFJdGVtVGl0bGUgfX08L2I+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwPlNlbGVjdCB0aGUgY29sdW1ucyB5b3Ugd291bGQgbGlrZSB0byB2aWV3LCBhbmQgc2V0IGEgbmV3IGNvbHVtbiBuYW1lIGlmIHJlcXVpcmVkLjwvcD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbHVtbi1kZWZpbml0aW9uIGFsaWduLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggWyhuZ01vZGVsKV09XCJhbGxDb2x1bW5zXCIgKGNoYW5nZSk9XCJ0b2dnbGVBbGxDb2x1bW5zKCRldmVudClcIj48L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtd1wiPkNvbHVtbiBOYW1lPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtd1wiPk5ldyBDb2x1bW4gVGl0bGU8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4tZGVmaW5pdGlvbiBhbGlnbi1jZW50ZXJcIiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGpvaW5Db2x1bW5zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBbKG5nTW9kZWwpXT1cImNvbHVtbi5zZWxlY3RlZFwiIChuZ01vZGVsQ2hhbmdlKT1cImFsbFNlbGVjdGVkKClcIj48L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFsobmdNb2RlbCldPVwiY29sdW1uLm5hbWVcIiBkaXNhYmxlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJjb2x1bW4udGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiY29sdW1uLmR1cGxpY2F0ZVwiIGNsYXNzPVwicHJpbWFyeVwiPkR1cGxpY2F0ZSBjb2x1bW4gbmFtZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9tYXQtc3RlcD5cblxuICAgICAgICA8L21hdC1ob3Jpem9udGFsLXN0ZXBwZXI+XG5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJkaWFsb2ctZm9vdGVyXCI+XG5cbiAgICAgICAgPCEtLSBCQUNLL0NBTkNFTCBCVVRUT05TLS0+XG4gICAgICAgIDxidXR0b24gKm5nSWY9XCJzdGVwcGVyLnNlbGVjdGVkSW5kZXggPT09IDBcIiBtYXQtc3Ryb2tlZC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgbWF0LWRpYWxvZy1jbG9zZT5DYW5jZWw8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiAqbmdJZj1cInN0ZXBwZXIuc2VsZWN0ZWRJbmRleCA+IDBcIiBtYXQtc3Ryb2tlZC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cInN0ZXBwZXIucHJldmlvdXMoKVwiPkJhY2tcbiAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgPCEtLSBNSURETEUgTkVYVCBCVVRUT05TIC0tPlxuICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwic3RlcHBlci5zZWxlY3RlZEluZGV4ID09PSAxXCI+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIXJlcXVpcmVkUGFyYW1ldGVycyB8fCAhcmVxdWlyZWRQYXJhbWV0ZXJzLmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWZsYXQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIChjbGljayk9XCJzdGVwcGVyLm5leHQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiKGpvaW5GaWx0ZXJGaWVsZHMgJiYgam9pbkZpbHRlckZpZWxkcy5sZW5ndGgpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICEoXy5ldmVyeShqb2luVHJhbnNmb3JtYXRpb24uY29uZmlnLmpvaW5GaWx0ZXJzLmZpbHRlcnMsICdsaHNFeHByZXNzaW9uJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5ldmVyeShqb2luVHJhbnNmb3JtYXRpb24uY29uZmlnLmpvaW5GaWx0ZXJzLmZpbHRlcnMsICdyaHNFeHByZXNzaW9uJykpXCI+XG4gICAgICAgICAgICAgICAgICAgIE5leHRcbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJyZXF1aXJlZFBhcmFtZXRlcnMgJiYgcmVxdWlyZWRQYXJhbWV0ZXJzLmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWZsYXQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIChjbGljayk9XCJnZXRQYXJhbWV0ZXJWYWx1ZXMoc3RlcHBlcilcIj5cbiAgICAgICAgICAgICAgICAgICAgTmV4dFxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPCEtLSBGSU5BTCBCVVRUT04gLS0+XG4gICAgICAgIDxidXR0b24gbWF0LWZsYXQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiICpuZ0lmPVwic3RlcHBlci5zZWxlY3RlZEluZGV4ID09PSAyXCIgKGNsaWNrKT1cImpvaW4oKVwiPlxuICAgICAgICAgICAgQ3JlYXRlIEpvaW5cbiAgICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG5cbjwvZGl2PlxuXG5cbiJdfQ==