@sinequa/atomic-angular 0.0.146

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 (174) hide show
  1. package/assets/tailwind.css +334 -0
  2. package/esm2022/lib/assistant/index.mjs +2 -0
  3. package/esm2022/lib/assistant/signalR.web.service.mjs +81 -0
  4. package/esm2022/lib/components/dropdown-input.mjs +97 -0
  5. package/esm2022/lib/components/dropdown-list.mjs +35 -0
  6. package/esm2022/lib/components/dropdown.mjs +127 -0
  7. package/esm2022/lib/components/index.mjs +7 -0
  8. package/esm2022/lib/components/menu/index.mjs +3 -0
  9. package/esm2022/lib/components/menu/menu-item.mjs +22 -0
  10. package/esm2022/lib/components/menu/menu.mjs +99 -0
  11. package/esm2022/lib/components/metadata/index.mjs +2 -0
  12. package/esm2022/lib/components/metadata/metadata.component.mjs +65 -0
  13. package/esm2022/lib/components/theme/index.mjs +3 -0
  14. package/esm2022/lib/components/theme/theme-selector.component.mjs +67 -0
  15. package/esm2022/lib/components/theme/theme-toggle.component.mjs +67 -0
  16. package/esm2022/lib/directives/index.mjs +5 -0
  17. package/esm2022/lib/directives/infinite-scroll.directive.mjs +47 -0
  18. package/esm2022/lib/directives/select-article-on-click.directive.mjs +39 -0
  19. package/esm2022/lib/directives/show-bookmark.directive.mjs +55 -0
  20. package/esm2022/lib/directives/theme-provider.directive.mjs +31 -0
  21. package/esm2022/lib/guards/auth.guard.mjs +27 -0
  22. package/esm2022/lib/guards/index.mjs +3 -0
  23. package/esm2022/lib/guards/initialization.guard.mjs +41 -0
  24. package/esm2022/lib/interceptors/audit.interceptor.mjs +23 -0
  25. package/esm2022/lib/interceptors/auth.interceptor.mjs +49 -0
  26. package/esm2022/lib/interceptors/body.interceptor.mjs +24 -0
  27. package/esm2022/lib/interceptors/error.interceptor.mjs +35 -0
  28. package/esm2022/lib/interceptors/index.mjs +7 -0
  29. package/esm2022/lib/interceptors/toast.interceptor.mjs +27 -0
  30. package/esm2022/lib/models/aggregation.mjs +2 -0
  31. package/esm2022/lib/models/article-metadata.mjs +2 -0
  32. package/esm2022/lib/models/autocomplete.mjs +2 -0
  33. package/esm2022/lib/models/custom-json.mjs +2 -0
  34. package/esm2022/lib/models/filter-dropdown.mjs +2 -0
  35. package/esm2022/lib/models/index.mjs +7 -0
  36. package/esm2022/lib/models/user-settings.mjs +2 -0
  37. package/esm2022/lib/pipes/highlight-word.pipe.mjs +33 -0
  38. package/esm2022/lib/pipes/index.mjs +3 -0
  39. package/esm2022/lib/pipes/source-icon.pipe.mjs +43 -0
  40. package/esm2022/lib/public-api.mjs +18 -0
  41. package/esm2022/lib/resolvers/index.mjs +2 -0
  42. package/esm2022/lib/resolvers/query-name-resolver.mjs +14 -0
  43. package/esm2022/lib/resources/index.mjs +2 -0
  44. package/esm2022/lib/resources/themes.mjs +53 -0
  45. package/esm2022/lib/services/application.service.mjs +245 -0
  46. package/esm2022/lib/services/autocomplete.service.mjs +85 -0
  47. package/esm2022/lib/services/drawer/backdrop.service.mjs +23 -0
  48. package/esm2022/lib/services/drawer/drawer-stack.service.mjs +152 -0
  49. package/esm2022/lib/services/drawer/drawer.service.mjs +38 -0
  50. package/esm2022/lib/services/index.mjs +12 -0
  51. package/esm2022/lib/services/label.service.mjs +161 -0
  52. package/esm2022/lib/services/navigation.service.mjs +59 -0
  53. package/esm2022/lib/services/saved-searches.service.mjs +75 -0
  54. package/esm2022/lib/services/search.service.mjs +89 -0
  55. package/esm2022/lib/services/selection-history.service.mjs +92 -0
  56. package/esm2022/lib/services/selection.service.mjs +87 -0
  57. package/esm2022/lib/stores/aggregations.store.mjs +59 -0
  58. package/esm2022/lib/stores/app.store.mjs +270 -0
  59. package/esm2022/lib/stores/application.store.mjs +87 -0
  60. package/esm2022/lib/stores/index.mjs +9 -0
  61. package/esm2022/lib/stores/principal.store.mjs +47 -0
  62. package/esm2022/lib/stores/query-params.store.mjs +207 -0
  63. package/esm2022/lib/stores/selection.store.mjs +45 -0
  64. package/esm2022/lib/stores/theme.store.mjs +116 -0
  65. package/esm2022/lib/stores/user-settings.store.mjs +391 -0
  66. package/esm2022/lib/tokens/highlights.mjs +32 -0
  67. package/esm2022/lib/tokens/index.mjs +2 -0
  68. package/esm2022/lib/utils/debounced-signal.mjs +38 -0
  69. package/esm2022/lib/utils/index.mjs +8 -0
  70. package/esm2022/lib/utils/inline-worker.mjs +40 -0
  71. package/esm2022/lib/utils/query.mjs +58 -0
  72. package/esm2022/lib/utils/routes.mjs +28 -0
  73. package/esm2022/lib/utils/tailwind-utils.mjs +6 -0
  74. package/esm2022/lib/utils/theme-body-hook.mjs +18 -0
  75. package/esm2022/lib/utils/theme-registry.mjs +6 -0
  76. package/esm2022/lib/web-services/aggregations.service.mjs +104 -0
  77. package/esm2022/lib/web-services/app.service.mjs +48 -0
  78. package/esm2022/lib/web-services/audit.service.mjs +122 -0
  79. package/esm2022/lib/web-services/index.mjs +10 -0
  80. package/esm2022/lib/web-services/json-method-plugin.service.mjs +54 -0
  81. package/esm2022/lib/web-services/preview.service.mjs +327 -0
  82. package/esm2022/lib/web-services/principal.service.mjs +46 -0
  83. package/esm2022/lib/web-services/query.service.mjs +123 -0
  84. package/esm2022/lib/web-services/text-chunck.service.mjs +46 -0
  85. package/esm2022/public-api.mjs +5 -0
  86. package/esm2022/sinequa-atomic-angular.mjs +5 -0
  87. package/fesm2022/sinequa-atomic-angular.mjs +4420 -0
  88. package/fesm2022/sinequa-atomic-angular.mjs.map +1 -0
  89. package/index.d.ts +5 -0
  90. package/lib/assistant/index.d.ts +1 -0
  91. package/lib/assistant/signalR.web.service.d.ts +46 -0
  92. package/lib/components/dropdown-input.d.ts +18 -0
  93. package/lib/components/dropdown-list.d.ts +8 -0
  94. package/lib/components/dropdown.d.ts +50 -0
  95. package/lib/components/index.d.ts +6 -0
  96. package/lib/components/menu/index.d.ts +2 -0
  97. package/lib/components/menu/menu-item.d.ts +8 -0
  98. package/lib/components/menu/menu.d.ts +24 -0
  99. package/lib/components/metadata/index.d.ts +1 -0
  100. package/lib/components/metadata/metadata.component.d.ts +24 -0
  101. package/lib/components/theme/index.d.ts +2 -0
  102. package/lib/components/theme/theme-selector.component.d.ts +70 -0
  103. package/lib/components/theme/theme-toggle.component.d.ts +10 -0
  104. package/lib/directives/index.d.ts +4 -0
  105. package/lib/directives/infinite-scroll.directive.d.ts +30 -0
  106. package/lib/directives/select-article-on-click.directive.d.ts +14 -0
  107. package/lib/directives/show-bookmark.directive.d.ts +60 -0
  108. package/lib/directives/theme-provider.directive.d.ts +20 -0
  109. package/lib/guards/auth.guard.d.ts +7 -0
  110. package/lib/guards/index.d.ts +2 -0
  111. package/lib/guards/initialization.guard.d.ts +20 -0
  112. package/lib/interceptors/audit.interceptor.d.ts +13 -0
  113. package/lib/interceptors/auth.interceptor.d.ts +14 -0
  114. package/lib/interceptors/body.interceptor.d.ts +11 -0
  115. package/lib/interceptors/error.interceptor.d.ts +9 -0
  116. package/lib/interceptors/index.d.ts +5 -0
  117. package/lib/interceptors/toast.interceptor.d.ts +13 -0
  118. package/lib/models/aggregation.d.ts +12 -0
  119. package/lib/models/article-metadata.d.ts +5 -0
  120. package/lib/models/autocomplete.d.ts +5 -0
  121. package/lib/models/custom-json.d.ts +69 -0
  122. package/lib/models/filter-dropdown.d.ts +10 -0
  123. package/lib/models/index.d.ts +6 -0
  124. package/lib/models/user-settings.d.ts +38 -0
  125. package/lib/pipes/highlight-word.pipe.d.ts +22 -0
  126. package/lib/pipes/index.d.ts +2 -0
  127. package/lib/pipes/source-icon.pipe.d.ts +51 -0
  128. package/lib/public-api.d.ts +14 -0
  129. package/lib/resolvers/index.d.ts +1 -0
  130. package/lib/resolvers/query-name-resolver.d.ts +9 -0
  131. package/lib/resources/index.d.ts +1 -0
  132. package/lib/resources/themes.d.ts +51 -0
  133. package/lib/services/application.service.d.ts +183 -0
  134. package/lib/services/autocomplete.service.d.ts +96 -0
  135. package/lib/services/drawer/backdrop.service.d.ts +9 -0
  136. package/lib/services/drawer/drawer-stack.service.d.ts +70 -0
  137. package/lib/services/drawer/drawer.service.d.ts +15 -0
  138. package/lib/services/index.d.ts +11 -0
  139. package/lib/services/label.service.d.ts +114 -0
  140. package/lib/services/navigation.service.d.ts +33 -0
  141. package/lib/services/saved-searches.service.d.ts +149 -0
  142. package/lib/services/search.service.d.ts +159 -0
  143. package/lib/services/selection-history.service.d.ts +50 -0
  144. package/lib/services/selection.service.d.ts +123 -0
  145. package/lib/stores/aggregations.store.d.ts +25 -0
  146. package/lib/stores/app.store.d.ts +110 -0
  147. package/lib/stores/application.store.d.ts +83 -0
  148. package/lib/stores/index.d.ts +8 -0
  149. package/lib/stores/principal.store.d.ts +47 -0
  150. package/lib/stores/query-params.store.d.ts +128 -0
  151. package/lib/stores/selection.store.d.ts +52 -0
  152. package/lib/stores/theme.store.d.ts +66 -0
  153. package/lib/stores/user-settings.store.d.ts +111 -0
  154. package/lib/tokens/highlights.d.ts +8 -0
  155. package/lib/tokens/index.d.ts +1 -0
  156. package/lib/utils/debounced-signal.d.ts +25 -0
  157. package/lib/utils/index.d.ts +7 -0
  158. package/lib/utils/inline-worker.d.ts +11 -0
  159. package/lib/utils/query.d.ts +26 -0
  160. package/lib/utils/routes.d.ts +16 -0
  161. package/lib/utils/tailwind-utils.d.ts +2 -0
  162. package/lib/utils/theme-body-hook.d.ts +6 -0
  163. package/lib/utils/theme-registry.d.ts +3 -0
  164. package/lib/web-services/aggregations.service.d.ts +57 -0
  165. package/lib/web-services/app.service.d.ts +30 -0
  166. package/lib/web-services/audit.service.d.ts +72 -0
  167. package/lib/web-services/index.d.ts +9 -0
  168. package/lib/web-services/json-method-plugin.service.d.ts +41 -0
  169. package/lib/web-services/preview.service.d.ts +283 -0
  170. package/lib/web-services/principal.service.d.ts +28 -0
  171. package/lib/web-services/query.service.d.ts +29 -0
  172. package/lib/web-services/text-chunck.service.d.ts +22 -0
  173. package/package.json +28 -0
  174. package/public-api.d.ts +1 -0
@@ -0,0 +1,327 @@
1
+ import { HttpClient } from "@angular/common/http";
2
+ import { EventEmitter, Inject, Injectable, InjectionToken, Injector, inject } from "@angular/core";
3
+ import { DomSanitizer } from "@angular/platform-browser";
4
+ import { getState } from "@ngrx/signals";
5
+ import { EMPTY, Subject, catchError, tap } from "rxjs";
6
+ import { Audit, globalConfig } from "@sinequa/atomic";
7
+ import { SearchService } from "../services/search.service";
8
+ import { AppStore, ApplicationStore, QueryParamsStore, SelectionStore } from "../stores";
9
+ import { HIGHLIGHTS } from "../tokens";
10
+ import { AuditService } from "./audit.service";
11
+ import { QueryService } from "./query.service";
12
+ import * as i0 from "@angular/core";
13
+ const PREVIEW_CONFIG = new InjectionToken("Preview configuration", {
14
+ factory: () => ({
15
+ allowWorker: false
16
+ })
17
+ });
18
+ export class PreviewService {
19
+ constructor(highlights) {
20
+ this.highlights = highlights;
21
+ this.http = inject(HttpClient);
22
+ this.injector = inject(Injector);
23
+ this.API_URL = `${globalConfig.backendUrl}/${globalConfig.apiPath}`;
24
+ this.applicationStore = inject(ApplicationStore);
25
+ this.selectionStore = inject(SelectionStore);
26
+ this.queryParamsStore = inject(QueryParamsStore);
27
+ this.appStore = inject(AppStore);
28
+ this.sanitizer = inject(DomSanitizer);
29
+ this.queryService = inject(QueryService);
30
+ this.searchService = inject(SearchService);
31
+ this.auditService = inject(AuditService);
32
+ this.events = new EventEmitter();
33
+ // ! worker
34
+ this.onMessage = new Subject();
35
+ this.allowWoker = inject(PREVIEW_CONFIG).allowWorker;
36
+ this.highlightCategory = "extractslocations";
37
+ this.extracts = ["matchlocations", "extractslocations", "matchingpassages"];
38
+ this.entities = ["company", "geo", "person"];
39
+ window.addEventListener('message', this.receiveMessage.bind(this), false);
40
+ }
41
+ ngOnDestroy() {
42
+ window.removeEventListener('message', this.receiveMessage.bind(this), false);
43
+ }
44
+ /**
45
+ * Handles incoming messages from a MessageEvent.
46
+ *
47
+ * @param event - The MessageEvent containing the message data.
48
+ *
49
+ * The function processes messages of type 'ready' and 'get-html-results'.
50
+ *
51
+ * - For 'ready' messages:
52
+ * - Initializes the preview iframe with the app name and highlights.
53
+ * - If preview data is available, retrieves HTML content based on the current selection.
54
+ *
55
+ * - For 'get-html-results' messages:
56
+ * - Updates the application store with the extracted HTML results.
57
+ * - If no extracts are found, updates the application store with an empty array.
58
+ */
59
+ receiveMessage(event) {
60
+ const message = event.data;
61
+ // the webworker needs to be initialized with the app name to be able to load the correct webworker file (worker.js)
62
+ const { app } = globalConfig;
63
+ // when the iframe is ready, we can send the init message
64
+ if (message.type === 'ready') {
65
+ // Initialize the preview iframe with the app name and highlights
66
+ // app name is used to intialize the webworker
67
+ this.sendMessage({ action: "init", highlights: this.highlights, appname: app });
68
+ if (this.previewData) {
69
+ const { id } = getState(this.selectionStore);
70
+ this.events.emit('fetching');
71
+ this.retrieveHtmlContent(id, this.highlightCategory, this.previewData);
72
+ }
73
+ }
74
+ // when the iframe sends back the html content of the extracts (no worker)
75
+ if (message.type === 'get-html-results') {
76
+ const { id } = getState(this.selectionStore);
77
+ if (id) {
78
+ console.info("no worker");
79
+ const extracts = this.fetchExtracts(id, message.data, this.previewData);
80
+ this.applicationStore.updateExtracts(this.previewData?.record.id || '', extracts);
81
+ this.events.emit('fetched');
82
+ }
83
+ }
84
+ // when the iframe sends back the html content of the extracts (with worker)
85
+ // we update the extracts in the application store
86
+ if (message.type === 'get-html-results-webworker') {
87
+ console.info("with worker");
88
+ if (message.data.extracts.length === 0) {
89
+ this.events.emit('fetched');
90
+ this.applicationStore.updateExtracts(this.previewData?.record.id || '', []);
91
+ return;
92
+ }
93
+ const extracts = message.data.extracts.map((item) => ({
94
+ ...item,
95
+ text: this.sanitizer.bypassSecurityTrustHtml(item.text)
96
+ }));
97
+ this.applicationStore.updateExtracts(this.previewData?.record.id || '', extracts);
98
+ this.events.emit('fetched');
99
+ }
100
+ }
101
+ /**
102
+ * Generates a preview of the document with the given ID, applying the specified query parameters,
103
+ * custom highlights, and audit events.
104
+ *
105
+ * @param id - The unique identifier of the document to preview.
106
+ * @param q - Partial query parameters to customize the preview request.
107
+ * @param customHighlights - Optional array of custom highlights to apply to the preview.
108
+ * @param audit - Optional audit events to merge with the default audit record.
109
+ * @returns An Observable that emits the preview data.
110
+ */
111
+ preview(id, q, customHighlights, audit) {
112
+ const detail = this.getAuditPreviewDetail(id, q);
113
+ const defaultAudit = {
114
+ type: "Doc_Preview",
115
+ detail
116
+ };
117
+ // merge the default audit record with the provided audit record
118
+ const $auditRecord = audit ? { auditEvents: [{ ...defaultAudit, ...audit }] } : { auditEvents: [defaultAudit] };
119
+ const { app } = globalConfig;
120
+ const query = { ...this.queryParamsStore.getQuery(), ...q };
121
+ const browserUrl = `${window.location.origin}${window.location.pathname}`;
122
+ const body = {
123
+ app,
124
+ action: "get",
125
+ id,
126
+ query: { name: query.name, text: query.text },
127
+ browserUrl,
128
+ customHighlights,
129
+ $auditRecord
130
+ };
131
+ return this.http.post(this.API_URL + "/preview", body)
132
+ .pipe(tap((data) => this.setPreviewData(data)), catchError(error => {
133
+ console.error("queryService.preview failure - error: ", error);
134
+ return EMPTY;
135
+ }));
136
+ }
137
+ /**
138
+ * Closes the preview with the specified ID and updates the audit log.
139
+ *
140
+ * @param id - The ID of the preview to close.
141
+ * @param query - The partial query object used to retrieve the preview detail.
142
+ */
143
+ close(id, query) {
144
+ const detail = this.getAuditPreviewDetail(id, query);
145
+ const auditEvent = {
146
+ type: "Preview_Close" /* AuditEventType.Preview_Close */,
147
+ detail
148
+ };
149
+ Audit.notify(auditEvent);
150
+ }
151
+ /**
152
+ * Previews an article in a new browser's tab.
153
+ *
154
+ * @param article - The article to preview.
155
+ */
156
+ openExternal(article) {
157
+ const query = this.queryParamsStore.getQuery();
158
+ const detail = this.getAuditPreviewDetail(article.id, query);
159
+ const result = this.searchService.result;
160
+ this.auditService.notifyDocument("Click_ResultLink", article, result || detail.resultid || "", {
161
+ querytext: detail.querytext,
162
+ querylang: detail.querylang,
163
+ score: detail.score
164
+ }, {
165
+ queryhash: result ? result.rfmQueryHash : undefined,
166
+ querytext: detail.querytext,
167
+ querylang: detail.querylang
168
+ });
169
+ window.open(article.url1, '_blank', 'noopener noreferrer');
170
+ }
171
+ /**
172
+ * Sets the iframe window object.
173
+ *
174
+ * @param iframe - The window object of the iframe or null to unset.
175
+ */
176
+ setIframe(iframe) {
177
+ this.iframe = iframe;
178
+ }
179
+ /**
180
+ * Sets the preview data and updates the highlight category based on the provided data.
181
+ *
182
+ * @param data - The preview data to be set.
183
+ *
184
+ * If the provided data contains highlights per category with 'matchingpassages' having values,
185
+ * the highlight category is set to "matchingpassages". Otherwise, it is set to "extractslocations".
186
+ */
187
+ setPreviewData(data) {
188
+ this.previewData = data;
189
+ if (data) {
190
+ this.highlightCategory = data.highlightsPerCategory?.['matchingpassages']?.values.length ? "matchingpassages" : "extractslocations";
191
+ }
192
+ }
193
+ /**
194
+ * Sends a message to the iframe if it exists.
195
+ *
196
+ * @param message - The message to be sent. It can be of any type.
197
+ */
198
+ sendMessage(message) {
199
+ if (this.iframe) {
200
+ this.iframe.postMessage(message, '*');
201
+ }
202
+ }
203
+ /**
204
+ * Get preview id for an entity value for an index
205
+ * @param entity the entity type (i.e. "geo")
206
+ * @param value the entity value (i.e. "AUSTRALIA")
207
+ * @param index the entity index from its list
208
+ * @returns the html id
209
+ */
210
+ getEntityId(entity, value, index) {
211
+ if (!this.previewData)
212
+ return undefined;
213
+ return this.previewData.highlightsPerLocation
214
+ .filter(h => h.values.find(v => v === value))[index].positionInCategories[entity];
215
+ }
216
+ /**
217
+ * Send a message to the prewiew iFrame with the required data to retrieve HTML content for a specific highlight category
218
+ *
219
+ * @param id - The unique identifier for the request.
220
+ * @param highlightCategory - The category of highlights to retrieve.
221
+ * @param previewData - The data containing highlights and their locations.
222
+ */
223
+ retrieveHtmlContent(id, highlightCategory, previewData) {
224
+ // Generate the list of items we want to retrieve
225
+ const ids = previewData.highlightsPerCategory[highlightCategory]?.values[0]?.locations.map((_, i) => `${highlightCategory}_${i}`);
226
+ if (this.allowWoker) {
227
+ // if the worker is allowed, we send the message to the worker
228
+ this.sendMessage({ action: 'get-html-webworker', id, ids, previewData });
229
+ }
230
+ else {
231
+ this.sendMessage({ action: 'get-html', id, ids, previewData });
232
+ }
233
+ }
234
+ /**
235
+ * Sends a message to zoom in.
236
+ *
237
+ * This method triggers a "zoom-in" action by sending a message
238
+ * with the specified action type.
239
+ */
240
+ zoomIn() {
241
+ this.sendMessage({ action: "zoom-in" });
242
+ }
243
+ /**
244
+ * Sends a message to zoom out the preview.
245
+ *
246
+ * This method triggers a "zoom-out" action by sending a message
247
+ * to the relevant service or component.
248
+ */
249
+ zoomOut() {
250
+ this.sendMessage({ action: "zoom-out" });
251
+ }
252
+ /**
253
+ * Toggles the highlights based on the provided flags for extracts and entities.
254
+ *
255
+ * @param extracts - A boolean flag indicating whether to include extracts highlights.
256
+ * @param entities - A boolean flag indicating whether to include entities highlights.
257
+ */
258
+ toggle(extracts, entities) {
259
+ const extractsHighlights = extracts ? this.highlights.filter(h => this.extracts.includes(h.name)) : [];
260
+ const entitiesHighlights = entities ? this.highlights.filter(h => this.entities.includes(h.name)) : [];
261
+ const highlights = [...extractsHighlights, ...entitiesHighlights];
262
+ this.sendMessage({ action: "highlight", highlights });
263
+ }
264
+ getAuditPreviewDetail(id, q) {
265
+ const results = this.searchService.result;
266
+ const queryLanguage = results?.queryAnalysis?.queryLanguage
267
+ || q?.questionLanguage
268
+ || this.appStore.getQueryByName(q.name)?.questionLanguage;
269
+ const record = this.previewData?.record;
270
+ const collectionColumn = record?.collection;
271
+ const collection = !!collectionColumn ? collectionColumn[0] : id.split("|")[0];
272
+ const rank = !!record ? record.rank : 0;
273
+ const passages = record?.matchingpassages?.passages;
274
+ const score = passages && passages.length ? passages[0].score : undefined;
275
+ return {
276
+ docid: id,
277
+ rank,
278
+ collection,
279
+ source: collection.split("|")[0],
280
+ resultid: results.id,
281
+ querylang: queryLanguage,
282
+ querytext: q?.text,
283
+ filename: record?.filename,
284
+ fileext: record?.fileext,
285
+ score
286
+ };
287
+ }
288
+ fetchExtracts(id, extracts, data) {
289
+ // extracts contains the html of extracts in chronological order
290
+ // locations contains the list of start positions sorted by score
291
+ const locations = data.highlightsPerCategory[this.highlightCategory]?.values[0]?.locations || [];
292
+ // first extract all the extracts locations
293
+ let extractslocations = locations.map((l, relevanceIndex) => ({
294
+ startIndex: l.start,
295
+ relevanceIndex
296
+ }));
297
+ // sort them by start index
298
+ extractslocations.sort((a, b) => a.startIndex - b.startIndex);
299
+ // then extract the text of each extract
300
+ extractslocations = extractslocations.map((ex, textIndex) => ({
301
+ ...ex,
302
+ textIndex: textIndex,
303
+ text: extracts[textIndex] || "",
304
+ id: `${this.highlightCategory}_${textIndex}`,
305
+ }));
306
+ // then sanitize the text and remove empty extracts
307
+ const _extracts = extractslocations.filter(item => item.text.trim().length > 0).map(item => ({
308
+ ...item,
309
+ text: this.sanitizer.bypassSecurityTrustHtml(item.text)
310
+ }));
311
+ // finally sort them by relevance index
312
+ _extracts.sort((a, b) => a.relevanceIndex - b.relevanceIndex);
313
+ return _extracts;
314
+ }
315
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: PreviewService, deps: [{ token: HIGHLIGHTS }], target: i0.ɵɵFactoryTarget.Injectable }); }
316
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: PreviewService, providedIn: 'root' }); }
317
+ }
318
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: PreviewService, decorators: [{
319
+ type: Injectable,
320
+ args: [{
321
+ providedIn: 'root'
322
+ }]
323
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
324
+ type: Inject,
325
+ args: [HIGHLIGHTS]
326
+ }] }] });
327
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJldmlldy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXRvbWljLWFuZ3VsYXIvc3JjL2xpYi93ZWItc2VydmljZXMvcHJldmlldy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBYSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLEtBQUssRUFBYyxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVuRSxPQUFPLEVBQVcsS0FBSyxFQUFxRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVsSSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBVyxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbEcsT0FBTyxFQUFFLFVBQVUsRUFBb0IsTUFBTSxXQUFXLENBQUM7QUFFekQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7QUFHL0MsTUFBTSxjQUFjLEdBQUcsSUFBSSxjQUFjLENBQUMsdUJBQXVCLEVBQUU7SUFDakUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDZCxXQUFXLEVBQUUsS0FBSztLQUNuQixDQUFDO0NBQ0gsQ0FBQyxDQUFDO0FBV0gsTUFB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Q0FBQztJQUNuQixDQUFDOzhHQXhXVSxjQUFjLGtCQWtDZixVQUFVO2tIQWxDVCxjQUFjLGNBRmIsTUFBTTs7MkZBRVAsY0FBYztrQkFIMUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkI7OzBCQW1DSSxNQUFNOzJCQUFDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vbi9odHRwXCI7XHJcbmltcG9ydCB7IEV2ZW50RW1pdHRlciwgSW5qZWN0LCBJbmplY3RhYmxlLCBJbmplY3Rpb25Ub2tlbiwgSW5qZWN0b3IsIE9uRGVzdHJveSwgaW5qZWN0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0IHsgRG9tU2FuaXRpemVyIH0gZnJvbSBcIkBhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXJcIjtcclxuaW1wb3J0IHsgZ2V0U3RhdGUgfSBmcm9tIFwiQG5ncngvc2lnbmFsc1wiO1xyXG5pbXBvcnQgeyBFTVBUWSwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgY2F0Y2hFcnJvciwgdGFwIH0gZnJvbSBcInJ4anNcIjtcclxuXHJcbmltcG9ydCB7IEFydGljbGUsIEF1ZGl0LCBBdWRpdEV2ZW50VHlwZSwgQXVkaXRFdmVudHMsIEN1c3RvbUhpZ2hsaWdodHMsIFByZXZpZXdEYXRhLCBRdWVyeSwgZ2xvYmFsQ29uZmlnIH0gZnJvbSBcIkBzaW5lcXVhL2F0b21pY1wiO1xyXG5cclxuaW1wb3J0IHsgU2VhcmNoU2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlcy9zZWFyY2guc2VydmljZVwiO1xyXG5pbXBvcnQgeyBBcHBTdG9yZSwgQXBwbGljYXRpb25TdG9yZSwgRXh0cmFjdCwgUXVlcnlQYXJhbXNTdG9yZSwgU2VsZWN0aW9uU3RvcmUgfSBmcm9tIFwiLi4vc3RvcmVzXCI7XHJcbmltcG9ydCB7IEhJR0hMSUdIVFMsIFByZXZpZXdIaWdobGlnaHQgfSBmcm9tIFwiLi4vdG9rZW5zXCI7XHJcbmltcG9ydCB7IElubGluZVdvcmtlciB9IGZyb20gXCIuLi91dGlsc1wiO1xyXG5pbXBvcnQgeyBBdWRpdFNlcnZpY2UgfSBmcm9tIFwiLi9hdWRpdC5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFF1ZXJ5U2VydmljZSB9IGZyb20gXCIuL3F1ZXJ5LnNlcnZpY2VcIjtcclxuXHJcblxyXG5jb25zdCBQUkVWSUVXX0NPTkZJRyA9IG5ldyBJbmplY3Rpb25Ub2tlbihcIlByZXZpZXcgY29uZmlndXJhdGlvblwiLCB7XHJcbiAgZmFjdG9yeTogKCkgPT4gKHtcclxuICAgIGFsbG93V29ya2VyOiBmYWxzZVxyXG4gIH0pXHJcbn0pO1xyXG5cclxudHlwZSBFeHRyYWN0c0xvY2F0aW9ucyA9IEV4dHJhY3QgJiB7XHJcbiAgdGV4dDogc3RyaW5nIC8vIEhUTUwgdGV4dFxyXG59XHJcblxyXG5leHBvcnQgdHlwZSBFeHRyYWN0c0V2ZW50cyA9ICdmZXRjaGluZycgfCAnZmV0Y2hlZCcgfCAnZXJyb3InO1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290J1xyXG59KVxyXG5leHBvcnQgY2xhc3MgUHJldmlld1NlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xyXG4gIHByb3RlY3RlZCByZWFkb25seSBodHRwID0gaW5qZWN0KEh0dHBDbGllbnQpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSBpbmplY3RvciA9IGluamVjdChJbmplY3Rvcik7XHJcblxyXG4gIHByb3RlY3RlZCByZWFkb25seSBBUElfVVJMID0gYCR7Z2xvYmFsQ29uZmlnLmJhY2tlbmRVcmx9LyR7Z2xvYmFsQ29uZmlnLmFwaVBhdGh9YDtcclxuXHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGFwcGxpY2F0aW9uU3RvcmUgPSBpbmplY3QoQXBwbGljYXRpb25TdG9yZSk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHNlbGVjdGlvblN0b3JlID0gaW5qZWN0KFNlbGVjdGlvblN0b3JlKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcXVlcnlQYXJhbXNTdG9yZSA9IGluamVjdChRdWVyeVBhcmFtc1N0b3JlKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYXBwU3RvcmUgPSBpbmplY3QoQXBwU3RvcmUpO1xyXG5cclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc2FuaXRpemVyID0gaW5qZWN0KERvbVNhbml0aXplcik7XHJcblxyXG4gIHByb3RlY3RlZCByZWFkb25seSBxdWVyeVNlcnZpY2UgPSBpbmplY3QoUXVlcnlTZXJ2aWNlKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc2VhcmNoU2VydmljZSA9IGluamVjdChTZWFyY2hTZXJ2aWNlKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYXVkaXRTZXJ2aWNlID0gaW5qZWN0KEF1ZGl0U2VydmljZSk7XHJcblxyXG4gIGV2ZW50cyA9IG5ldyBFdmVudEVtaXR0ZXI8RXh0cmFjdHNFdmVudHM+KCk7XHJcblxyXG4gIC8vICEgd29ya2VyXHJcbiAgb25NZXNzYWdlID0gbmV3IFN1YmplY3Q8dW5rbm93bj4oKTtcclxuICB3b3JrZXI6IElubGluZVdvcmtlciB8IHVuZGVmaW5lZDtcclxuXHJcbiAgYWxsb3dXb2tlciA9IGluamVjdChQUkVWSUVXX0NPTkZJRykuYWxsb3dXb3JrZXI7XHJcblxyXG4gIHByb3RlY3RlZCBwcmV2aWV3RGF0YTogUHJldmlld0RhdGEgfCB1bmRlZmluZWQ7XHJcbiAgcHJvdGVjdGVkIGlmcmFtZTogV2luZG93IHwgbnVsbCB8IHVuZGVmaW5lZDtcclxuXHJcbiAgcHJvdGVjdGVkIGhpZ2hsaWdodENhdGVnb3J5ID0gXCJleHRyYWN0c2xvY2F0aW9uc1wiO1xyXG5cclxuICBleHRyYWN0cyA9IFtcIm1hdGNobG9jYXRpb25zXCIsIFwiZXh0cmFjdHNsb2NhdGlvbnNcIiwgXCJtYXRjaGluZ3Bhc3NhZ2VzXCJdO1xyXG4gIGVudGl0aWVzID0gW1wiY29tcGFueVwiLCBcImdlb1wiLCBcInBlcnNvblwiXTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBASW5qZWN0KEhJR0hMSUdIVFMpIHB1YmxpYyBoaWdobGlnaHRzOiBQcmV2aWV3SGlnaGxpZ2h0W10pIHtcclxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdGhpcy5yZWNlaXZlTWVzc2FnZS5iaW5kKHRoaXMpLCBmYWxzZSk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdGhpcy5yZWNlaXZlTWVzc2FnZS5iaW5kKHRoaXMpLCBmYWxzZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGVzIGluY29taW5nIG1lc3NhZ2VzIGZyb20gYSBNZXNzYWdlRXZlbnQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gZXZlbnQgLSBUaGUgTWVzc2FnZUV2ZW50IGNvbnRhaW5pbmcgdGhlIG1lc3NhZ2UgZGF0YS5cclxuICAgKlxyXG4gICAqIFRoZSBmdW5jdGlvbiBwcm9jZXNzZXMgbWVzc2FnZXMgb2YgdHlwZSAncmVhZHknIGFuZCAnZ2V0LWh0bWwtcmVzdWx0cycuXHJcbiAgICpcclxuICAgKiAtIEZvciAncmVhZHknIG1lc3NhZ2VzOlxyXG4gICAqICAgLSBJbml0aWFsaXplcyB0aGUgcHJldmlldyBpZnJhbWUgd2l0aCB0aGUgYXBwIG5hbWUgYW5kIGhpZ2hsaWdodHMuXHJcbiAgICogICAtIElmIHByZXZpZXcgZGF0YSBpcyBhdmFpbGFibGUsIHJldHJpZXZlcyBIVE1MIGNvbnRlbnQgYmFzZWQgb24gdGhlIGN1cnJlbnQgc2VsZWN0aW9uLlxyXG4gICAqXHJcbiAgICogLSBGb3IgJ2dldC1odG1sLXJlc3VsdHMnIG1lc3NhZ2VzOlxyXG4gICAqICAgLSBVcGRhdGVzIHRoZSBhcHBsaWNhdGlvbiBzdG9yZSB3aXRoIHRoZSBleHRyYWN0ZWQgSFRNTCByZXN1bHRzLlxyXG4gICAqICAgLSBJZiBubyBleHRyYWN0cyBhcmUgZm91bmQsIHVwZGF0ZXMgdGhlIGFwcGxpY2F0aW9uIHN0b3JlIHdpdGggYW4gZW1wdHkgYXJyYXkuXHJcbiAgICovXHJcbiAgcmVjZWl2ZU1lc3NhZ2UoZXZlbnQ6IE1lc3NhZ2VFdmVudCkge1xyXG4gICAgY29uc3QgbWVzc2FnZSA9IGV2ZW50LmRhdGE7XHJcbiAgICAvLyB0aGUgd2Vid29ya2VyIG5lZWRzIHRvIGJlIGluaXRpYWxpemVkIHdpdGggdGhlIGFwcCBuYW1lIHRvIGJlIGFibGUgdG8gbG9hZCB0aGUgY29ycmVjdCB3ZWJ3b3JrZXIgZmlsZSAod29ya2VyLmpzKVxyXG4gICAgY29uc3QgeyBhcHAgfSA9IGdsb2JhbENvbmZpZztcclxuXHJcbiAgICAvLyB3aGVuIHRoZSBpZnJhbWUgaXMgcmVhZHksIHdlIGNhbiBzZW5kIHRoZSBpbml0IG1lc3NhZ2VcclxuICAgIGlmIChtZXNzYWdlLnR5cGUgPT09ICdyZWFkeScpIHtcclxuICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgcHJldmlldyBpZnJhbWUgd2l0aCB0aGUgYXBwIG5hbWUgYW5kIGhpZ2hsaWdodHNcclxuICAgICAgLy8gYXBwIG5hbWUgaXMgdXNlZCB0byBpbnRpYWxpemUgdGhlIHdlYndvcmtlclxyXG4gICAgICB0aGlzLnNlbmRNZXNzYWdlKHsgYWN0aW9uOiBcImluaXRcIiwgaGlnaGxpZ2h0czogdGhpcy5oaWdobGlnaHRzLCBhcHBuYW1lOiBhcHAgfSk7XHJcblxyXG4gICAgICBpZiAodGhpcy5wcmV2aWV3RGF0YSkge1xyXG4gICAgICAgIGNvbnN0IHsgaWQgfSA9IGdldFN0YXRlKHRoaXMuc2VsZWN0aW9uU3RvcmUpO1xyXG4gICAgICAgIHRoaXMuZXZlbnRzLmVtaXQoJ2ZldGNoaW5nJyk7XHJcbiAgICAgICAgdGhpcy5yZXRyaWV2ZUh0bWxDb250ZW50KGlkLCB0aGlzLmhpZ2hsaWdodENhdGVnb3J5LCB0aGlzLnByZXZpZXdEYXRhKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIHdoZW4gdGhlIGlmcmFtZSBzZW5kcyBiYWNrIHRoZSBodG1sIGNvbnRlbnQgb2YgdGhlIGV4dHJhY3RzIChubyB3b3JrZXIpXHJcbiAgICBpZiAobWVzc2FnZS50eXBlID09PSAnZ2V0LWh0bWwtcmVzdWx0cycpIHtcclxuICAgICAgY29uc3QgeyBpZCB9ID0gZ2V0U3RhdGUodGhpcy5zZWxlY3Rpb25TdG9yZSlcclxuXHJcbiAgICAgIGlmIChpZCkge1xyXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIm5vIHdvcmtlclwiKTtcclxuICAgICAgICBjb25zdCBleHRyYWN0cyA9IHRoaXMuZmV0Y2hFeHRyYWN0cyhpZCwgbWVzc2FnZS5kYXRhLCB0aGlzLnByZXZpZXdEYXRhISk7XHJcbiAgICAgICAgdGhpcy5hcHBsaWNhdGlvblN0b3JlLnVwZGF0ZUV4dHJhY3RzKHRoaXMucHJldmlld0RhdGE/LnJlY29yZC5pZCB8fCAnJywgZXh0cmFjdHMpO1xyXG4gICAgICAgIHRoaXMuZXZlbnRzLmVtaXQoJ2ZldGNoZWQnKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIHdoZW4gdGhlIGlmcmFtZSBzZW5kcyBiYWNrIHRoZSBodG1sIGNvbnRlbnQgb2YgdGhlIGV4dHJhY3RzICh3aXRoIHdvcmtlcilcclxuICAgIC8vIHdlIHVwZGF0ZSB0aGUgZXh0cmFjdHMgaW4gdGhlIGFwcGxpY2F0aW9uIHN0b3JlXHJcbiAgICBpZiAobWVzc2FnZS50eXBlID09PSAnZ2V0LWh0bWwtcmVzdWx0cy13ZWJ3b3JrZXInKSB7XHJcbiAgICAgIGNvbnNvbGUuaW5mbyhcIndpdGggd29ya2VyXCIpO1xyXG5cclxuICAgICAgaWYgKG1lc3NhZ2UuZGF0YS5leHRyYWN0cy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KCdmZXRjaGVkJyk7XHJcbiAgICAgICAgdGhpcy5hcHBsaWNhdGlvblN0b3JlLnVwZGF0ZUV4dHJhY3RzKHRoaXMucHJldmlld0RhdGE/LnJlY29yZC5pZCB8fCAnJywgW10pO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgY29uc3QgZXh0cmFjdHM6IEV4dHJhY3RbXSA9IG1lc3NhZ2UuZGF0YS5leHRyYWN0cy5tYXAoKGl0ZW06IEV4dHJhY3RzTG9jYXRpb25zKSA9PiAoe1xyXG4gICAgICAgIC4uLml0ZW0sXHJcbiAgICAgICAgdGV4dDogdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdEh0bWwoaXRlbS50ZXh0KVxyXG4gICAgICB9KSk7XHJcblxyXG4gICAgICB0aGlzLmFwcGxpY2F0aW9uU3RvcmUudXBkYXRlRXh0cmFjdHModGhpcy5wcmV2aWV3RGF0YT8ucmVjb3JkLmlkIHx8ICcnLCBleHRyYWN0cyk7XHJcbiAgICAgIHRoaXMuZXZlbnRzLmVtaXQoJ2ZldGNoZWQnKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdlbmVyYXRlcyBhIHByZXZpZXcgb2YgdGhlIGRvY3VtZW50IHdpdGggdGhlIGdpdmVuIElELCBhcHBseWluZyB0aGUgc3BlY2lmaWVkIHF1ZXJ5IHBhcmFtZXRlcnMsXHJcbiAgICogY3VzdG9tIGhpZ2hsaWdodHMsIGFuZCBhdWRpdCBldmVudHMuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gaWQgLSBUaGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGRvY3VtZW50IHRvIHByZXZpZXcuXHJcbiAgICogQHBhcmFtIHEgLSBQYXJ0aWFsIHF1ZXJ5IHBhcmFtZXRlcnMgdG8gY3VzdG9taXplIHRoZSBwcmV2aWV3IHJlcXVlc3QuXHJcbiAgICogQHBhcmFtIGN1c3RvbUhpZ2hsaWdodHMgLSBPcHRpb25hbCBhcnJheSBvZiBjdXN0b20gaGlnaGxpZ2h0cyB0byBhcHBseSB0byB0aGUgcHJldmlldy5cclxuICAgKiBAcGFyYW0gYXVkaXQgLSBPcHRpb25hbCBhdWRpdCBldmVudHMgdG8gbWVyZ2Ugd2l0aCB0aGUgZGVmYXVsdCBhdWRpdCByZWNvcmQuXHJcbiAgICogQHJldHVybnMgQW4gT2JzZXJ2YWJsZSB0aGF0IGVtaXRzIHRoZSBwcmV2aWV3IGRhdGEuXHJcbiAgICovXHJcbiAgcHJldmlldyhpZDogc3RyaW5nLCBxOiBQYXJ0aWFsPFF1ZXJ5PiwgY3VzdG9tSGlnaGxpZ2h0cz86IEN1c3RvbUhpZ2hsaWdodHNbXSwgYXVkaXQ/OiBBdWRpdEV2ZW50cyk6IE9ic2VydmFibGU8UHJldmlld0RhdGE+IHtcclxuICAgIGNvbnN0IGRldGFpbCA9IHRoaXMuZ2V0QXVkaXRQcmV2aWV3RGV0YWlsKGlkLCBxKTtcclxuXHJcbiAgICBjb25zdCBkZWZhdWx0QXVkaXQ6IEF1ZGl0RXZlbnRzID0ge1xyXG4gICAgICB0eXBlOiBcIkRvY19QcmV2aWV3XCIsXHJcbiAgICAgIGRldGFpbFxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBtZXJnZSB0aGUgZGVmYXVsdCBhdWRpdCByZWNvcmQgd2l0aCB0aGUgcHJvdmlkZWQgYXVkaXQgcmVjb3JkXHJcbiAgICBjb25zdCAkYXVkaXRSZWNvcmQgPSBhdWRpdCA/IHsgYXVkaXRFdmVudHM6IFt7IC4uLmRlZmF1bHRBdWRpdCwgLi4uYXVkaXQgfV0gfSA6IHsgYXVkaXRFdmVudHM6IFtkZWZhdWx0QXVkaXRdIH07XHJcblxyXG4gICAgY29uc3QgeyBhcHAgfSA9IGdsb2JhbENvbmZpZztcclxuICAgIGNvbnN0IHF1ZXJ5ID0geyAuLi50aGlzLnF1ZXJ5UGFyYW1zU3RvcmUuZ2V0UXVlcnkoKSwgLi4ucSB9O1xyXG5cclxuICAgIGNvbnN0IGJyb3dzZXJVcmwgPSBgJHt3aW5kb3cubG9jYXRpb24ub3JpZ2lufSR7d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lfWA7XHJcblxyXG4gICAgY29uc3QgYm9keSA9IHtcclxuICAgICAgYXBwLFxyXG4gICAgICBhY3Rpb246IFwiZ2V0XCIsXHJcbiAgICAgIGlkLFxyXG4gICAgICBxdWVyeTogeyBuYW1lOiBxdWVyeS5uYW1lLCB0ZXh0OiBxdWVyeS50ZXh0IH0sXHJcbiAgICAgIGJyb3dzZXJVcmwsXHJcbiAgICAgIGN1c3RvbUhpZ2hsaWdodHMsXHJcbiAgICAgICRhdWRpdFJlY29yZFxyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8UHJldmlld0RhdGE+KHRoaXMuQVBJX1VSTCArIFwiL3ByZXZpZXdcIiwgYm9keSlcclxuICAgICAgLnBpcGUoXHJcbiAgICAgICAgdGFwKChkYXRhOiBQcmV2aWV3RGF0YSkgPT4gdGhpcy5zZXRQcmV2aWV3RGF0YShkYXRhKSksXHJcbiAgICAgICAgY2F0Y2hFcnJvcihlcnJvciA9PiB7XHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFwicXVlcnlTZXJ2aWNlLnByZXZpZXcgZmFpbHVyZSAtIGVycm9yOiBcIiwgZXJyb3IpO1xyXG4gICAgICAgICAgcmV0dXJuIEVNUFRZO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDbG9zZXMgdGhlIHByZXZpZXcgd2l0aCB0aGUgc3BlY2lmaWVkIElEIGFuZCB1cGRhdGVzIHRoZSBhdWRpdCBsb2cuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gaWQgLSBUaGUgSUQgb2YgdGhlIHByZXZpZXcgdG8gY2xvc2UuXHJcbiAgICogQHBhcmFtIHF1ZXJ5IC0gVGhlIHBhcnRpYWwgcXVlcnkgb2JqZWN0IHVzZWQgdG8gcmV0cmlldmUgdGhlIHByZXZpZXcgZGV0YWlsLlxyXG4gICAqL1xyXG4gIGNsb3NlKGlkOiBzdHJpbmcsIHF1ZXJ5OiBQYXJ0aWFsPFF1ZXJ5Pikge1xyXG4gICAgY29uc3QgZGV0YWlsID0gdGhpcy5nZXRBdWRpdFByZXZpZXdEZXRhaWwoaWQsIHF1ZXJ5KTtcclxuICAgIGNvbnN0IGF1ZGl0RXZlbnQgPSB7XHJcbiAgICAgIHR5cGU6IEF1ZGl0RXZlbnRUeXBlLlByZXZpZXdfQ2xvc2UsXHJcbiAgICAgIGRldGFpbFxyXG4gICAgfVxyXG4gICAgQXVkaXQubm90aWZ5KGF1ZGl0RXZlbnQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUHJldmlld3MgYW4gYXJ0aWNsZSBpbiBhIG5ldyBicm93c2VyJ3MgdGFiLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIGFydGljbGUgLSBUaGUgYXJ0aWNsZSB0byBwcmV2aWV3LlxyXG4gICAqL1xyXG4gIG9wZW5FeHRlcm5hbChhcnRpY2xlOiBBcnRpY2xlKSB7XHJcbiAgICBjb25zdCBxdWVyeSA9IHRoaXMucXVlcnlQYXJhbXNTdG9yZS5nZXRRdWVyeSgpO1xyXG4gICAgY29uc3QgZGV0YWlsID0gdGhpcy5nZXRBdWRpdFByZXZpZXdEZXRhaWwoYXJ0aWNsZS5pZCwgcXVlcnkpO1xyXG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy5zZWFyY2hTZXJ2aWNlLnJlc3VsdDtcclxuICAgIHRoaXMuYXVkaXRTZXJ2aWNlLm5vdGlmeURvY3VtZW50KFxyXG4gICAgICBcIkNsaWNrX1Jlc3VsdExpbmtcIixcclxuICAgICAgYXJ0aWNsZSxcclxuICAgICAgcmVzdWx0IHx8IGRldGFpbC5yZXN1bHRpZCB8fCBcIlwiLFxyXG4gICAgICB7XHJcbiAgICAgICAgcXVlcnl0ZXh0OiBkZXRhaWwucXVlcnl0ZXh0LFxyXG4gICAgICAgIHF1ZXJ5bGFuZzogZGV0YWlsLnF1ZXJ5bGFuZyxcclxuICAgICAgICBzY29yZTogZGV0YWlsLnNjb3JlXHJcbiAgICAgIH0sXHJcbiAgICAgIHtcclxuICAgICAgICBxdWVyeWhhc2g6IHJlc3VsdCA/IHJlc3VsdC5yZm1RdWVyeUhhc2ggOiB1bmRlZmluZWQsXHJcbiAgICAgICAgcXVlcnl0ZXh0OiBkZXRhaWwucXVlcnl0ZXh0LFxyXG4gICAgICAgIHF1ZXJ5bGFuZzogZGV0YWlsLnF1ZXJ5bGFuZ1xyXG4gICAgICB9XHJcbiAgICApXHJcbiAgICB3aW5kb3cub3BlbihhcnRpY2xlLnVybDEsICdfYmxhbmsnLCAnbm9vcGVuZXIgbm9yZWZlcnJlcicpO1xyXG4gIH1cclxuXHJcblxyXG4gIC8qKlxyXG4gICAqIFNldHMgdGhlIGlmcmFtZSB3aW5kb3cgb2JqZWN0LlxyXG4gICAqXHJcbiAgICogQHBhcmFtIGlmcmFtZSAtIFRoZSB3aW5kb3cgb2JqZWN0IG9mIHRoZSBpZnJhbWUgb3IgbnVsbCB0byB1bnNldC5cclxuICAgKi9cclxuICBzZXRJZnJhbWUoaWZyYW1lOiBXaW5kb3cgfCBudWxsKSB7XHJcbiAgICB0aGlzLmlmcmFtZSA9IGlmcmFtZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNldHMgdGhlIHByZXZpZXcgZGF0YSBhbmQgdXBkYXRlcyB0aGUgaGlnaGxpZ2h0IGNhdGVnb3J5IGJhc2VkIG9uIHRoZSBwcm92aWRlZCBkYXRhLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIGRhdGEgLSBUaGUgcHJldmlldyBkYXRhIHRvIGJlIHNldC5cclxuICAgKlxyXG4gICAqIElmIHRoZSBwcm92aWRlZCBkYXRhIGNvbnRhaW5zIGhpZ2hsaWdodHMgcGVyIGNhdGVnb3J5IHdpdGggJ21hdGNoaW5ncGFzc2FnZXMnIGhhdmluZyB2YWx1ZXMsXHJcbiAgICogdGhlIGhpZ2hsaWdodCBjYXRlZ29yeSBpcyBzZXQgdG8gXCJtYXRjaGluZ3Bhc3NhZ2VzXCIuIE90aGVyd2lzZSwgaXQgaXMgc2V0IHRvIFwiZXh0cmFjdHNsb2NhdGlvbnNcIi5cclxuICAgKi9cclxuICBzZXRQcmV2aWV3RGF0YShkYXRhOiBQcmV2aWV3RGF0YSkge1xyXG4gICAgdGhpcy5wcmV2aWV3RGF0YSA9IGRhdGE7XHJcblxyXG4gICAgaWYgKGRhdGEpIHtcclxuICAgICAgdGhpcy5oaWdobGlnaHRDYXRlZ29yeSA9IGRhdGEuaGlnaGxpZ2h0c1BlckNhdGVnb3J5Py5bJ21hdGNoaW5ncGFzc2FnZXMnXT8udmFsdWVzLmxlbmd0aCA/IFwibWF0Y2hpbmdwYXNzYWdlc1wiIDogXCJleHRyYWN0c2xvY2F0aW9uc1wiO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2VuZHMgYSBtZXNzYWdlIHRvIHRoZSBpZnJhbWUgaWYgaXQgZXhpc3RzLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBiZSBzZW50LiBJdCBjYW4gYmUgb2YgYW55IHR5cGUuXHJcbiAgICovXHJcbiAgc2VuZE1lc3NhZ2UobWVzc2FnZTogdW5rbm93bikge1xyXG4gICAgaWYgKHRoaXMuaWZyYW1lKSB7XHJcbiAgICAgIHRoaXMuaWZyYW1lIS5wb3N0TWVzc2FnZShtZXNzYWdlLCAnKicpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHByZXZpZXcgaWQgZm9yIGFuIGVudGl0eSB2YWx1ZSBmb3IgYW4gaW5kZXhcclxuICAgKiBAcGFyYW0gZW50aXR5IHRoZSBlbnRpdHkgdHlwZSAoaS5lLiBcImdlb1wiKVxyXG4gICAqIEBwYXJhbSB2YWx1ZSB0aGUgZW50aXR5IHZhbHVlIChpLmUuIFwiQVVTVFJBTElBXCIpXHJcbiAgICogQHBhcmFtIGluZGV4IHRoZSBlbnRpdHkgaW5kZXggZnJvbSBpdHMgbGlzdFxyXG4gICAqIEByZXR1cm5zIHRoZSBodG1sIGlkXHJcbiAgICovXHJcbiAgZ2V0RW50aXR5SWQoZW50aXR5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpOiBudW1iZXIgfCB1bmRlZmluZWQge1xyXG4gICAgaWYgKCF0aGlzLnByZXZpZXdEYXRhKSByZXR1cm4gdW5kZWZpbmVkO1xyXG5cclxuICAgIHJldHVybiB0aGlzLnByZXZpZXdEYXRhLmhpZ2hsaWdodHNQZXJMb2NhdGlvblxyXG4gICAgICAuZmlsdGVyKGggPT4gaC52YWx1ZXMuZmluZCh2ID0+IHYgPT09IHZhbHVlKSlbaW5kZXhdLnBvc2l0aW9uSW5DYXRlZ29yaWVzW2VudGl0eV07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZW5kIGEgbWVzc2FnZSB0byB0aGUgcHJld2lldyBpRnJhbWUgd2l0aCB0aGUgcmVxdWlyZWQgZGF0YSB0byByZXRyaWV2ZSBIVE1MIGNvbnRlbnQgZm9yIGEgc3BlY2lmaWMgaGlnaGxpZ2h0IGNhdGVnb3J5XHJcbiAgICpcclxuICAgKiBAcGFyYW0gaWQgLSBUaGUgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSByZXF1ZXN0LlxyXG4gICAqIEBwYXJhbSBoaWdobGlnaHRDYXRlZ29yeSAtIFRoZSBjYXRlZ29yeSBvZiBoaWdobGlnaHRzIHRvIHJldHJpZXZlLlxyXG4gICAqIEBwYXJhbSBwcmV2aWV3RGF0YSAtIFRoZSBkYXRhIGNvbnRhaW5pbmcgaGlnaGxpZ2h0cyBhbmQgdGhlaXIgbG9jYXRpb25zLlxyXG4gICAqL1xyXG4gIHJldHJpZXZlSHRtbENvbnRlbnQoaWQ6IHN0cmluZywgaGlnaGxpZ2h0Q2F0ZWdvcnk6IHN0cmluZywgcHJldmlld0RhdGE6IFByZXZpZXdEYXRhKSB7XHJcbiAgICAvLyBHZW5lcmF0ZSB0aGUgbGlzdCBvZiBpdGVtcyB3ZSB3YW50IHRvIHJldHJpZXZlXHJcbiAgICBjb25zdCBpZHMgPSBwcmV2aWV3RGF0YS5oaWdobGlnaHRzUGVyQ2F0ZWdvcnlbaGlnaGxpZ2h0Q2F0ZWdvcnldPy52YWx1ZXNbMF0/LmxvY2F0aW9ucy5tYXAoXHJcbiAgICAgIChfLCBpKSA9PiBgJHtoaWdobGlnaHRDYXRlZ29yeX1fJHtpfWBcclxuICAgICk7XHJcblxyXG4gICAgaWYgKHRoaXMuYWxsb3dXb2tlcikge1xyXG4gICAgICAvLyBpZiB0aGUgd29ya2VyIGlzIGFsbG93ZWQsIHdlIHNlbmQgdGhlIG1lc3NhZ2UgdG8gdGhlIHdvcmtlclxyXG4gICAgICB0aGlzLnNlbmRNZXNzYWdlKHsgYWN0aW9uOiAnZ2V0LWh0bWwtd2Vid29ya2VyJywgaWQsIGlkcywgcHJldmlld0RhdGEgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnNlbmRNZXNzYWdlKHsgYWN0aW9uOiAnZ2V0LWh0bWwnLCBpZCwgaWRzLCBwcmV2aWV3RGF0YSB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlbmRzIGEgbWVzc2FnZSB0byB6b29tIGluLlxyXG4gICAqXHJcbiAgICogVGhpcyBtZXRob2QgdHJpZ2dlcnMgYSBcInpvb20taW5cIiBhY3Rpb24gYnkgc2VuZGluZyBhIG1lc3NhZ2VcclxuICAgKiB3aXRoIHRoZSBzcGVjaWZpZWQgYWN0aW9uIHR5cGUuXHJcbiAgICovXHJcbiAgem9vbUluKCkge1xyXG4gICAgdGhpcy5zZW5kTWVzc2FnZSh7IGFjdGlvbjogXCJ6b29tLWluXCIgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZW5kcyBhIG1lc3NhZ2UgdG8gem9vbSBvdXQgdGhlIHByZXZpZXcuXHJcbiAgICpcclxuICAgKiBUaGlzIG1ldGhvZCB0cmlnZ2VycyBhIFwiem9vbS1vdXRcIiBhY3Rpb24gYnkgc2VuZGluZyBhIG1lc3NhZ2VcclxuICAgKiB0byB0aGUgcmVsZXZhbnQgc2VydmljZSBvciBjb21wb25lbnQuXHJcbiAgICovXHJcbiAgem9vbU91dCgpIHtcclxuICAgIHRoaXMuc2VuZE1lc3NhZ2UoeyBhY3Rpb246IFwiem9vbS1vdXRcIiB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRvZ2dsZXMgdGhlIGhpZ2hsaWdodHMgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGZsYWdzIGZvciBleHRyYWN0cyBhbmQgZW50aXRpZXMuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gZXh0cmFjdHMgLSBBIGJvb2xlYW4gZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gaW5jbHVkZSBleHRyYWN0cyBoaWdobGlnaHRzLlxyXG4gICAqIEBwYXJhbSBlbnRpdGllcyAtIEEgYm9vbGVhbiBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0byBpbmNsdWRlIGVudGl0aWVzIGhpZ2hsaWdodHMuXHJcbiAgICovXHJcbiAgdG9nZ2xlKGV4dHJhY3RzOiBib29sZWFuLCBlbnRpdGllczogYm9vbGVhbikge1xyXG4gICAgY29uc3QgZXh0cmFjdHNIaWdobGlnaHRzID0gZXh0cmFjdHMgPyB0aGlzLmhpZ2hsaWdodHMuZmlsdGVyKGggPT4gdGhpcy5leHRyYWN0cy5pbmNsdWRlcyhoLm5hbWUpKSA6IFtdO1xyXG4gICAgY29uc3QgZW50aXRpZXNIaWdobGlnaHRzID0gZW50aXRpZXMgPyB0aGlzLmhpZ2hsaWdodHMuZmlsdGVyKGggPT4gdGhpcy5lbnRpdGllcy5pbmNsdWRlcyhoLm5hbWUpKSA6IFtdO1xyXG4gICAgY29uc3QgaGlnaGxpZ2h0cyA9IFsuLi5leHRyYWN0c0hpZ2hsaWdodHMsIC4uLmVudGl0aWVzSGlnaGxpZ2h0c107XHJcblxyXG4gICAgdGhpcy5zZW5kTWVzc2FnZSh7IGFjdGlvbjogXCJoaWdobGlnaHRcIiwgaGlnaGxpZ2h0cyB9KTtcclxuICB9XHJcblxyXG4gIGdldEF1ZGl0UHJldmlld0RldGFpbChpZDogc3RyaW5nLCBxOiBQYXJ0aWFsPFF1ZXJ5Pikge1xyXG4gICAgY29uc3QgcmVzdWx0cyA9IHRoaXMuc2VhcmNoU2VydmljZS5yZXN1bHQ7XHJcbiAgICBjb25zdCBxdWVyeUxhbmd1YWdlID0gcmVzdWx0cz8ucXVlcnlBbmFseXNpcz8ucXVlcnlMYW5ndWFnZVxyXG4gICAgICB8fCBxPy5xdWVzdGlvbkxhbmd1YWdlXHJcbiAgICAgIHx8IHRoaXMuYXBwU3RvcmUuZ2V0UXVlcnlCeU5hbWUocS5uYW1lISk/LnF1ZXN0aW9uTGFuZ3VhZ2U7XHJcblxyXG4gICAgY29uc3QgcmVjb3JkID0gdGhpcy5wcmV2aWV3RGF0YT8ucmVjb3JkO1xyXG4gICAgY29uc3QgY29sbGVjdGlvbkNvbHVtbiA9IHJlY29yZD8uY29sbGVjdGlvbjtcclxuICAgIGNvbnN0IGNvbGxlY3Rpb24gPSAhIWNvbGxlY3Rpb25Db2x1bW4gPyBjb2xsZWN0aW9uQ29sdW1uWzBdIDogaWQuc3BsaXQoXCJ8XCIpWzBdO1xyXG4gICAgY29uc3QgcmFuayA9ICEhcmVjb3JkID8gcmVjb3JkLnJhbmsgOiAwO1xyXG4gICAgY29uc3QgcGFzc2FnZXMgPSByZWNvcmQ/Lm1hdGNoaW5ncGFzc2FnZXM/LnBhc3NhZ2VzO1xyXG4gICAgY29uc3Qgc2NvcmUgPSBwYXNzYWdlcyAmJiBwYXNzYWdlcy5sZW5ndGggPyBwYXNzYWdlc1swXS5zY29yZSA6IHVuZGVmaW5lZDtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGRvY2lkOiBpZCxcclxuICAgICAgcmFuayxcclxuICAgICAgY29sbGVjdGlvbixcclxuICAgICAgc291cmNlOiBjb2xsZWN0aW9uLnNwbGl0KFwifFwiKVswXSxcclxuICAgICAgcmVzdWx0aWQ6IHJlc3VsdHMuaWQsXHJcbiAgICAgIHF1ZXJ5bGFuZzogcXVlcnlMYW5ndWFnZSxcclxuICAgICAgcXVlcnl0ZXh0OiBxPy50ZXh0LFxyXG4gICAgICBmaWxlbmFtZTogcmVjb3JkPy5maWxlbmFtZSxcclxuICAgICAgZmlsZWV4dDogcmVjb3JkPy5maWxlZXh0LFxyXG4gICAgICBzY29yZVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBmZXRjaEV4dHJhY3RzKGlkOiBzdHJpbmcsIGV4dHJhY3RzOiBzdHJpbmdbXSwgZGF0YTogUHJldmlld0RhdGEpOiBFeHRyYWN0W10ge1xyXG4gICAgLy8gZXh0cmFjdHMgY29udGFpbnMgdGhlIGh0bWwgb2YgZXh0cmFjdHMgaW4gY2hyb25vbG9naWNhbCBvcmRlclxyXG4gICAgLy8gbG9jYXRpb25zIGNvbnRhaW5zIHRoZSBsaXN0IG9mIHN0YXJ0IHBvc2l0aW9ucyBzb3J0ZWQgYnkgc2NvcmVcclxuICAgIGNvbnN0IGxvY2F0aW9ucyA9IGRhdGEuaGlnaGxpZ2h0c1BlckNhdGVnb3J5W3RoaXMuaGlnaGxpZ2h0Q2F0ZWdvcnldPy52YWx1ZXNbMF0/LmxvY2F0aW9ucyB8fCBbXTtcclxuXHJcbiAgICAvLyBmaXJzdCBleHRyYWN0IGFsbCB0aGUgZXh0cmFjdHMgbG9jYXRpb25zXHJcbiAgICBsZXQgZXh0cmFjdHNsb2NhdGlvbnMgPSBsb2NhdGlvbnMubWFwKChsLCByZWxldmFuY2VJbmRleCkgPT4gKHtcclxuICAgICAgc3RhcnRJbmRleDogbC5zdGFydCxcclxuICAgICAgcmVsZXZhbmNlSW5kZXhcclxuICAgIH0pKSBhcyBFeHRyYWN0c0xvY2F0aW9uc1tdO1xyXG5cclxuICAgIC8vIHNvcnQgdGhlbSBieSBzdGFydCBpbmRleFxyXG4gICAgZXh0cmFjdHNsb2NhdGlvbnMuc29ydCgoYSwgYikgPT4gYS5zdGFydEluZGV4IC0gYi5zdGFydEluZGV4KTtcclxuXHJcbiAgICAvLyB0aGVuIGV4dHJhY3QgdGhlIHRleHQgb2YgZWFjaCBleHRyYWN0XHJcbiAgICBleHRyYWN0c2xvY2F0aW9ucyA9IGV4dHJhY3RzbG9jYXRpb25zLm1hcCgoZXgsIHRleHRJbmRleCkgPT4gKHtcclxuICAgICAgLi4uZXgsXHJcbiAgICAgIHRleHRJbmRleDogdGV4dEluZGV4LFxyXG4gICAgICB0ZXh0OiBleHRyYWN0c1t0ZXh0SW5kZXhdIHx8IFwiXCIsXHJcbiAgICAgIGlkOiBgJHt0aGlzLmhpZ2hsaWdodENhdGVnb3J5fV8ke3RleHRJbmRleH1gLFxyXG4gICAgfSkpO1xyXG5cclxuICAgIC8vIHRoZW4gc2FuaXRpemUgdGhlIHRleHQgYW5kIHJlbW92ZSBlbXB0eSBleHRyYWN0c1xyXG4gICAgY29uc3QgX2V4dHJhY3RzID0gZXh0cmFjdHNsb2NhdGlvbnMuZmlsdGVyKGl0ZW0gPT4gaXRlbS50ZXh0LnRyaW0oKS5sZW5ndGggPiAwKS5tYXAoaXRlbSA9PiAoe1xyXG4gICAgICAuLi5pdGVtLFxyXG4gICAgICB0ZXh0OiB0aGlzLnNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0SHRtbChpdGVtLnRleHQpXHJcbiAgICB9KSk7XHJcblxyXG4gICAgLy8gZmluYWxseSBzb3J0IHRoZW0gYnkgcmVsZXZhbmNlIGluZGV4XHJcbiAgICBfZXh0cmFjdHMuc29ydCgoYSwgYikgPT4gYS5yZWxldmFuY2VJbmRleCAtIGIucmVsZXZhbmNlSW5kZXgpO1xyXG5cclxuICAgIHJldHVybiBfZXh0cmFjdHM7XHJcbiAgfVxyXG59Il19
@@ -0,0 +1,46 @@
1
+ import { HttpClient, HttpParams } from "@angular/common/http";
2
+ import { Injectable, inject } from "@angular/core";
3
+ import { EMPTY, catchError } from "rxjs";
4
+ import { globalConfig } from "@sinequa/atomic";
5
+ import * as i0 from "@angular/core";
6
+ export class PrincipalService {
7
+ constructor() {
8
+ this.http = inject(HttpClient);
9
+ this.API_URL = `${globalConfig.backendUrl}/${globalConfig.apiPath}`;
10
+ }
11
+ /**
12
+ * Retrieves the principal information from the server.
13
+ *
14
+ * @returns Observable<Principal> An observable that emits the principal information.
15
+ *
16
+ * @remarks
17
+ * This method sends a GET request to the API endpoint to fetch the principal data.
18
+ * It includes query parameters to specify the action and to indicate that no authentication is required.
19
+ * In case of an error, it logs the error to the console and returns an empty observable.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * principalService.getPrincipal().subscribe(principal => {
24
+ * console.log(principal);
25
+ * });
26
+ * ```
27
+ */
28
+ getPrincipal() {
29
+ const params = new HttpParams().set("action", "get");
30
+ params.append("noAuthentication", "true");
31
+ return this.http.get(this.API_URL + "/principal", { params })
32
+ .pipe(catchError(error => {
33
+ console.error("PrincipalService.getPrincipal failure - error: ", error);
34
+ return EMPTY;
35
+ }));
36
+ }
37
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: PrincipalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
38
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: PrincipalService, providedIn: 'root' }); }
39
+ }
40
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: PrincipalService, decorators: [{
41
+ type: Injectable,
42
+ args: [{
43
+ providedIn: 'root'
44
+ }]
45
+ }] });
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpbmNpcGFsLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hdG9taWMtYW5ndWxhci9zcmMvbGliL3dlYi1zZXJ2aWNlcy9wcmluY2lwYWwuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzlELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxLQUFLLEVBQWMsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXJELE9BQU8sRUFBYSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7QUFLMUQsTUFBTSxPQUFPLGdCQUFnQjtJQUg3QjtRQUlxQixTQUFJLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRTFCLFlBQU8sR0FBRyxHQUFHLFlBQVksQ0FBQyxVQUFVLElBQUksWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO0tBK0JuRjtJQTdCQzs7Ozs7Ozs7Ozs7Ozs7OztPQWdCRztJQUNILFlBQVk7UUFDVixNQUFNLE1BQU0sR0FBRyxJQUFJLFVBQVUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDckQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUUxQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFZLElBQUksQ0FBQyxPQUFPLEdBQUcsWUFBWSxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUM7YUFDdkUsSUFBSSxDQUNILFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUNqQixPQUFPLENBQUMsS0FBSyxDQUFDLGlEQUFpRCxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3hFLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7OEdBakNVLGdCQUFnQjtrSEFBaEIsZ0JBQWdCLGNBRmYsTUFBTTs7MkZBRVAsZ0JBQWdCO2tCQUg1QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBQYXJhbXMgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uL2h0dHBcIjtcclxuaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0IHsgRU1QVFksIE9ic2VydmFibGUsIGNhdGNoRXJyb3IgfSBmcm9tIFwicnhqc1wiO1xyXG5cclxuaW1wb3J0IHsgUHJpbmNpcGFsLCBnbG9iYWxDb25maWcgfSBmcm9tIFwiQHNpbmVxdWEvYXRvbWljXCI7XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBQcmluY2lwYWxTZXJ2aWNlIHtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaHR0cCA9IGluamVjdChIdHRwQ2xpZW50KTtcclxuXHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IEFQSV9VUkwgPSBgJHtnbG9iYWxDb25maWcuYmFja2VuZFVybH0vJHtnbG9iYWxDb25maWcuYXBpUGF0aH1gO1xyXG5cclxuICAvKipcclxuICAgKiBSZXRyaWV2ZXMgdGhlIHByaW5jaXBhbCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBzZXJ2ZXIuXHJcbiAgICpcclxuICAgKiBAcmV0dXJucyBPYnNlcnZhYmxlPFByaW5jaXBhbD4gQW4gb2JzZXJ2YWJsZSB0aGF0IGVtaXRzIHRoZSBwcmluY2lwYWwgaW5mb3JtYXRpb24uXHJcbiAgICpcclxuICAgKiBAcmVtYXJrc1xyXG4gICAqIFRoaXMgbWV0aG9kIHNlbmRzIGEgR0VUIHJlcXVlc3QgdG8gdGhlIEFQSSBlbmRwb2ludCB0byBmZXRjaCB0aGUgcHJpbmNpcGFsIGRhdGEuXHJcbiAgICogSXQgaW5jbHVkZXMgcXVlcnkgcGFyYW1ldGVycyB0byBzcGVjaWZ5IHRoZSBhY3Rpb24gYW5kIHRvIGluZGljYXRlIHRoYXQgbm8gYXV0aGVudGljYXRpb24gaXMgcmVxdWlyZWQuXHJcbiAgICogSW4gY2FzZSBvZiBhbiBlcnJvciwgaXQgbG9ncyB0aGUgZXJyb3IgdG8gdGhlIGNvbnNvbGUgYW5kIHJldHVybnMgYW4gZW1wdHkgb2JzZXJ2YWJsZS5cclxuICAgKlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogYGBgdHlwZXNjcmlwdFxyXG4gICAqIHByaW5jaXBhbFNlcnZpY2UuZ2V0UHJpbmNpcGFsKCkuc3Vic2NyaWJlKHByaW5jaXBhbCA9PiB7XHJcbiAgICogICBjb25zb2xlLmxvZyhwcmluY2lwYWwpO1xyXG4gICAqIH0pO1xyXG4gICAqIGBgYFxyXG4gICAqL1xyXG4gIGdldFByaW5jaXBhbCgpOiBPYnNlcnZhYmxlPFByaW5jaXBhbD4ge1xyXG4gICAgY29uc3QgcGFyYW1zID0gbmV3IEh0dHBQYXJhbXMoKS5zZXQoXCJhY3Rpb25cIiwgXCJnZXRcIik7XHJcbiAgICBwYXJhbXMuYXBwZW5kKFwibm9BdXRoZW50aWNhdGlvblwiLCBcInRydWVcIik7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8UHJpbmNpcGFsPih0aGlzLkFQSV9VUkwgKyBcIi9wcmluY2lwYWxcIiwgeyBwYXJhbXMgfSlcclxuICAgIC5waXBlKFxyXG4gICAgICBjYXRjaEVycm9yKGVycm9yID0+IHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKFwiUHJpbmNpcGFsU2VydmljZS5nZXRQcmluY2lwYWwgZmFpbHVyZSAtIGVycm9yOiBcIiwgZXJyb3IpO1xyXG4gICAgICAgIHJldHVybiBFTVBUWTtcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG59Il19
@@ -0,0 +1,123 @@
1
+ import { HttpClient } from '@angular/common/http';
2
+ import { Injectable, inject } from '@angular/core';
3
+ import { EMPTY, catchError, map, of, tap } from 'rxjs';
4
+ import { buildPathsAndLevels, globalConfig } from '@sinequa/atomic';
5
+ import { AppStore, QueryParamsStore } from '../stores';
6
+ import * as i0 from "@angular/core";
7
+ const AGGREGATION_MAX_COUNT = 11;
8
+ export class QueryService {
9
+ constructor() {
10
+ this.http = inject(HttpClient);
11
+ this.appStore = inject(AppStore);
12
+ this.queryParamsStore = inject(QueryParamsStore);
13
+ this.API_URL = `${globalConfig.backendUrl}/${globalConfig.apiPath}`;
14
+ }
15
+ /**
16
+ * Performs a search query.
17
+ *
18
+ * @param q - The partial query object.
19
+ * @param includeQueryParams - Indicates whether to include query parameters automatically in the request.
20
+ * @param audit - The audit events object.
21
+ * @returns An observable that emits the search results.
22
+ */
23
+ search(q, includeQueryParams = true, audit) {
24
+ const $auditRecord = audit ? { auditEvents: [audit] } : undefined;
25
+ const { app } = globalConfig;
26
+ const currentQuery = q ?? this.queryParamsStore.getQuery();
27
+ const query = includeQueryParams ? { ...this.queryParamsStore.getQuery(), ...currentQuery } : currentQuery;
28
+ // Check if the search query is empty and if empty searches are allowed
29
+ // If not allowed, return an empty result
30
+ const allowEmptySearch = this.appStore.allowEmptySearch(query?.name || '');
31
+ if (allowEmptySearch === false && query?.text === '') {
32
+ return of({ records: [] });
33
+ }
34
+ const body = {
35
+ app,
36
+ query,
37
+ $auditRecord
38
+ };
39
+ return this.http.post(this.API_URL + "/query", body)
40
+ .pipe(catchError(error => {
41
+ console.error("queryService.getResults failure - error: ", error);
42
+ return of({});
43
+ }), map((result) => {
44
+ // update $hasMore flag
45
+ result.aggregations.forEach((agg) => {
46
+ agg.$hasMore = false;
47
+ if (!agg.isDistribution && !agg.isTree && agg.items) {
48
+ agg.$hasMore = agg.items.length === AGGREGATION_MAX_COUNT;
49
+ }
50
+ if (agg.isTree) {
51
+ buildPathsAndLevels(agg);
52
+ }
53
+ });
54
+ return result;
55
+ }), map(result => {
56
+ result.records?.map((article) => (Object.assign(article, { value: article.title, type: 'default' })));
57
+ return result;
58
+ }), map(result => {
59
+ const r = ({ ...result, nextPage: result.page < Math.ceil(result.rowCount / result.pageSize) ? result.page + 1 : undefined, previousPage: result.page > 1 ? result.page - 1 : undefined });
60
+ return r;
61
+ }), tap(response => console.log("queryService.getResults success - data: ", response)));
62
+ }
63
+ /**
64
+ * Performs a bulk search operation.
65
+ *
66
+ * @param q An array of Query objects representing the search queries.
67
+ * @param audit An optional AuditEvents object for auditing purposes.
68
+ * @returns An Observable that emits an array of Result objects.
69
+ */
70
+ bulkSearch(q, audit) {
71
+ const { app = '' } = globalConfig;
72
+ const body = {
73
+ methods: [],
74
+ propagateErrors: true,
75
+ $auditRecord: { auditEvents: [audit] }
76
+ };
77
+ for (const query of q) {
78
+ body.methods.push({
79
+ method: "query",
80
+ app,
81
+ query
82
+ });
83
+ }
84
+ return this.http.post(this.API_URL + "/multi", body)
85
+ .pipe(catchError(error => {
86
+ console.error("queryService.bulkSearch failure - error: ", error);
87
+ return EMPTY;
88
+ }), map(response => {
89
+ // update $hasMore flag
90
+ response.results.forEach((result) => {
91
+ result.aggregations.forEach((agg) => {
92
+ agg.$hasMore = false;
93
+ if (!agg.isDistribution && !agg.isTree && agg.items) {
94
+ agg.$hasMore = agg.items.length === AGGREGATION_MAX_COUNT;
95
+ }
96
+ if (agg.isTree) {
97
+ buildPathsAndLevels(agg);
98
+ }
99
+ });
100
+ });
101
+ return response.results;
102
+ }), map(results => {
103
+ results.forEach(result => result.records?.map((article) => (Object.assign(article, { value: article.title, type: 'default' }))));
104
+ return results;
105
+ }), map(results => {
106
+ return results.map(result => {
107
+ const r = ({ ...result, nextPage: result.page < Math.ceil(result.rowCount / result.pageSize) ? result.page + 1 : undefined, previousPage: result.page > 1 ? result.page - 1 : undefined });
108
+ return r;
109
+ });
110
+ }),
111
+ // map(response => ResultsSchema.parse(response) as T),
112
+ tap(response => console.log("queryService.bulkSearch success - data: ", response)));
113
+ }
114
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: QueryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
115
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: QueryService, providedIn: 'root' }); }
116
+ }
117
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: QueryService, decorators: [{
118
+ type: Injectable,
119
+ args: [{
120
+ providedIn: 'root'
121
+ }]
122
+ }] });
123
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnkuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2F0b21pYy1hbmd1bGFyL3NyYy9saWIvd2ViLXNlcnZpY2VzL3F1ZXJ5LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxLQUFLLEVBQWMsVUFBVSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRW5FLE9BQU8sRUFBeUgsbUJBQW1CLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFM0wsT0FBTyxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFdBQVcsQ0FBQzs7QUFFdkQsTUFBTSxxQkFBcUIsR0FBRyxFQUFFLENBQUM7QUFJakMsTUFBTSxPQUFPLFlBQVk7SUFIekI7UUFJcUIsU0FBSSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUU1QixhQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzVCLHFCQUFnQixHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO1FBRXpDLFlBQU8sR0FBRyxHQUFHLFlBQVksQ0FBQyxVQUFVLElBQUksWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO0tBbUluRjtJQWpJQzs7Ozs7OztPQU9HO0lBQ0gsTUFBTSxDQUFDLENBQWtCLEVBQUUsa0JBQWtCLEdBQUcsSUFBSSxFQUFFLEtBQW1CO1FBQ3ZFLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFFbEUsTUFBTSxFQUFF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RSxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUE7Z0JBQzFMLE9BQU8sQ0FBQyxDQUFDO1lBQ1gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUM7UUFDRix1REFBdUQ7UUFDdkQsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQ0FBMEMsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUNuRixDQUFDO0lBRU4sQ0FBQzs4R0F4SVUsWUFBWTtrSEFBWixZQUFZLGNBRlgsTUFBTTs7MkZBRVAsWUFBWTtrQkFIeEIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRU1QVFksIE9ic2VydmFibGUsIGNhdGNoRXJyb3IsIG1hcCwgb2YsIHRhcCB9IGZyb20gJ3J4anMnO1xyXG5cclxuaW1wb3J0IHsgQWdncmVnYXRpb24sIEFydGljbGUsIEF1ZGl0RXZlbnRzLCBDdXN0b21IaWdobGlnaHRzLCBQcmV2aWV3RGF0YSwgUXVlcnksIFJlc3VsdCwgVHJlZUFnZ3JlZ2F0aW9uLCBUcmVlQWdncmVnYXRpb25Ob2RlLCBidWlsZFBhdGhzQW5kTGV2ZWxzLCBnbG9iYWxDb25maWcgfSBmcm9tICdAc2luZXF1YS9hdG9taWMnO1xyXG5cclxuaW1wb3J0IHsgQXBwU3RvcmUsIFF1ZXJ5UGFyYW1zU3RvcmUgfSBmcm9tICcuLi9zdG9yZXMnO1xyXG5cclxuY29uc3QgQUdHUkVHQVRJT05fTUFYX0NPVU5UID0gMTE7XHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIFF1ZXJ5U2VydmljZSB7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGh0dHAgPSBpbmplY3QoSHR0cENsaWVudCk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgYXBwU3RvcmUgPSBpbmplY3QoQXBwU3RvcmUpO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgcXVlcnlQYXJhbXNTdG9yZSA9IGluamVjdChRdWVyeVBhcmFtc1N0b3JlKVxyXG5cclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgQVBJX1VSTCA9IGAke2dsb2JhbENvbmZpZy5iYWNrZW5kVXJsfS8ke2dsb2JhbENvbmZpZy5hcGlQYXRofWA7XHJcblxyXG4gIC8qKlxyXG4gICAqIFBlcmZvcm1zIGEgc2VhcmNoIHF1ZXJ5LlxyXG4gICAqXHJcbiAgICogQHBhcmFtIHEgLSBUaGUgcGFydGlhbCBxdWVyeSBvYmplY3QuXHJcbiAgICogQHBhcmFtIGluY2x1ZGVRdWVyeVBhcmFtcyAtIEluZGljYXRlcyB3aGV0aGVyIHRvIGluY2x1ZGUgcXVlcnkgcGFyYW1ldGVycyBhdXRvbWF0aWNhbGx5IGluIHRoZSByZXF1ZXN0LlxyXG4gICAqIEBwYXJhbSBhdWRpdCAtIFRoZSBhdWRpdCBldmVudHMgb2JqZWN0LlxyXG4gICAqIEByZXR1cm5zIEFuIG9ic2VydmFibGUgdGhhdCBlbWl0cyB0aGUgc2VhcmNoIHJlc3VsdHMuXHJcbiAgICovXHJcbiAgc2VhcmNoKHE/OiBQYXJ0aWFsPFF1ZXJ5PiwgaW5jbHVkZVF1ZXJ5UGFyYW1zID0gdHJ1ZSwgYXVkaXQ/OiBBdWRpdEV2ZW50cyk6IE9ic2VydmFibGU8UmVzdWx0PiB7XHJcbiAgICBjb25zdCAkYXVkaXRSZWNvcmQgPSBhdWRpdCA/IHsgYXVkaXRFdmVudHM6IFthdWRpdF0gfSA6IHVuZGVmaW5lZDtcclxuXHJcbiAgICBjb25zdCB7IGFwcCB9ID0gZ2xvYmFsQ29uZmlnO1xyXG4gICAgY29uc3QgY3VycmVudFF1ZXJ5ID0gcSA/PyB0aGlzLnF1ZXJ5UGFyYW1zU3RvcmUuZ2V0UXVlcnkoKTtcclxuICAgIGNvbnN0IHF1ZXJ5ID0gaW5jbHVkZVF1ZXJ5UGFyYW1zID8geyAuLi50aGlzLnF1ZXJ5UGFyYW1zU3RvcmUuZ2V0UXVlcnkoKSwgLi4uY3VycmVudFF1ZXJ5IH0gOiBjdXJyZW50UXVlcnk7XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgdGhlIHNlYXJjaCBxdWVyeSBpcyBlbXB0eSBhbmQgaWYgZW1wdHkgc2VhcmNoZXMgYXJlIGFsbG93ZWRcclxuICAgIC8vIElmIG5vdCBhbGxvd2VkLCByZXR1cm4gYW4gZW1wdHkgcmVzdWx0XHJcbiAgICBjb25zdCBhbGxvd0VtcHR5U2VhcmNoID0gdGhpcy5hcHBTdG9yZS5hbGxvd0VtcHR5U2VhcmNoKHF1ZXJ5Py5uYW1lIHx8ICcnKTtcclxuICAgIGlmIChhbGxvd0VtcHR5U2VhcmNoID09PSBmYWxzZSAmJiBxdWVyeT8udGV4dCA9PT0gJycpIHtcclxuICAgICAgcmV0dXJuIG9mKHsgcmVjb3JkczogW10gYXMgQXJ0aWNsZVtdIH0gYXMgUmVzdWx0KTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBib2R5ID0ge1xyXG4gICAgICBhcHAsXHJcbiAgICAgIHF1ZXJ5LFxyXG4gICAgICAkYXVkaXRSZWNvcmRcclxuICAgIH07XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PFJlc3VsdD4odGhpcy5BUElfVVJMICsgXCIvcXVlcnlcIiwgYm9keSlcclxuICAgICAgLnBpcGUoXHJcbiAgICAgICAgY2F0Y2hFcnJvcihlcnJvciA9PiB7XHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFwicXVlcnlTZXJ2aWNlLmdldFJlc3VsdHMgZmFpbHVyZSAtIGVycm9yOiBcIiwgZXJyb3IpO1xyXG4gICAgICAgICAgcmV0dXJuIG9mKHt9IGFzIFJlc3VsdCk7XHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgbWFwKChyZXN1bHQ6IFJlc3VsdCkgPT4ge1xyXG4gICAgICAgICAgLy8gdXBkYXRlICRoYXNNb3JlIGZsYWdcclxuICAgICAgICAgIHJlc3VsdC5hZ2dyZWdhdGlvbnMuZm9yRWFjaCgoYWdnOiBBZ2dyZWdhdGlvbikgPT4ge1xyXG4gICAgICAgICAgICBhZ2cuJGhhc01vcmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgaWYgKCFhZ2cuaXNEaXN0cmlidXRpb24gJiYgIWFnZy5pc1RyZWUgJiYgYWdnLml0ZW1zKSB7XHJcbiAgICAgICAgICAgICAgYWdnLiRoYXNNb3JlID0gYWdnLml0ZW1zLmxlbmd0aCA9PT0gQUdHUkVHQVRJT05fTUFYX0NPVU5UO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChhZ2cuaXNUcmVlKSB7XHJcbiAgICAgICAgICAgICAgYnVpbGRQYXRoc0FuZExldmVscyhhZ2cgYXMgVHJlZUFnZ3JlZ2F0aW9uKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIG1hcChyZXN1bHQgPT4ge1xyXG4gICAgICAgICAgcmVzdWx0LnJlY29yZHM/Lm1hcCgoYXJ0aWNsZTogQXJ0aWNsZSkgPT4gKE9iamVjdC5hc3NpZ24oYXJ0aWNsZSwgeyB2YWx1ZTogYXJ0aWNsZS50aXRsZSwgdHlwZTogJ2RlZmF1bHQnIH0pKSk7XHJcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIG1hcChyZXN1bHQgPT4ge1xyXG4gICAgICAgICAgY29uc3QgciA9ICh7IC4uLnJlc3VsdCwgbmV4dFBhZ2U6IHJlc3VsdC5wYWdlIDwgTWF0aC5jZWlsKHJlc3VsdC5yb3dDb3VudCAvIHJlc3VsdC5wYWdlU2l6ZSkgPyByZXN1bHQucGFnZSArIDEgOiB1bmRlZmluZWQsIHByZXZpb3VzUGFnZTogcmVzdWx0LnBhZ2UgPiAxID8gcmVzdWx0LnBhZ2UgLSAxIDogdW5kZWZpbmVkIH0pXHJcbiAgICAgICAgICByZXR1cm4gcjtcclxuICAgICAgICB9KSxcclxuICAgICAgICB0YXAocmVzcG9uc2UgPT4gY29uc29sZS5sb2coXCJxdWVyeVNlcnZpY2UuZ2V0UmVzdWx0cyBzdWNjZXNzIC0gZGF0YTogXCIsIHJlc3BvbnNlKSksXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQZXJmb3JtcyBhIGJ1bGsgc2VhcmNoIG9wZXJhdGlvbi5cclxuICAgKlxyXG4gICAqIEBwYXJhbSBxIEFuIGFycmF5IG9mIFF1ZXJ5IG9iamVjdHMgcmVwcmVzZW50aW5nIHRoZSBzZWFyY2ggcXVlcmllcy5cclxuICAgKiBAcGFyYW0gYXVkaXQgQW4gb3B0aW9uYWwgQXVkaXRFdmVudHMgb2JqZWN0IGZvciBhdWRpdGluZyBwdXJwb3Nlcy5cclxuICAgKiBAcmV0dXJucyBBbiBPYnNlcnZhYmxlIHRoYXQgZW1pdHMgYW4gYXJyYXkgb2YgUmVzdWx0IG9iamVjdHMuXHJcbiAgICovXHJcbiAgYnVsa1NlYXJjaChxOiBRdWVyeVtdLCBhdWRpdD86IEF1ZGl0RXZlbnRzKTogT2JzZXJ2YWJsZTxSZXN1bHRbXT4ge1xyXG5cclxuICAgIGNvbnN0IHsgYXBwID0gJycgfSA9IGdsb2JhbENvbmZpZztcclxuXHJcbiAgICBjb25zdCBib2R5OiB7XHJcbiAgICAgIG1ldGhvZHM6IHtcclxuICAgICAgICBtZXRob2Q6IHN0cmluZyxcclxuICAgICAgICBhcHA6IHN0cmluZyxcclxuICAgICAgICBxdWVyeTogUXVlcnlcclxuICAgICAgfVtdLFxyXG4gICAgICBwcm9wYWdhdGVFcnJvcnM6IHRydWUsXHJcbiAgICAgICRhdWRpdFJlY29yZD86IHsgYXVkaXRFdmVudHM6IFtBdWRpdEV2ZW50c10gfVxyXG4gICAgfSA9IHtcclxuICAgICAgbWV0aG9kczogW10sXHJcbiAgICAgIHByb3BhZ2F0ZUVycm9yczogdHJ1ZSxcclxuICAgICAgJGF1ZGl0UmVjb3JkOiB7IGF1ZGl0RXZlbnRzOiBbYXVkaXQhXSB9XHJcbiAgICB9O1xyXG5cclxuICAgIGZvciAoY29uc3QgcXVlcnkgb2YgcSkge1xyXG4gICAgICBib2R5Lm1ldGhvZHMucHVzaCh7XHJcbiAgICAgICAgbWV0aG9kOiBcInF1ZXJ5XCIsXHJcbiAgICAgICAgYXBwLFxyXG4gICAgICAgIHF1ZXJ5XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDx7IHJlc3VsdHM6IFJlc3VsdFtdIH0+KHRoaXMuQVBJX1VSTCArIFwiL211bHRpXCIsIGJvZHkpXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIGNhdGNoRXJyb3IoZXJyb3IgPT4ge1xyXG4gICAgICAgICAgY29uc29sZS5lcnJvcihcInF1ZXJ5U2VydmljZS5idWxrU2VhcmNoIGZhaWx1cmUgLSBlcnJvcjogXCIsIGVycm9yKTtcclxuICAgICAgICAgIHJldHVybiBFTVBUWTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBtYXAocmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgLy8gdXBkYXRlICRoYXNNb3JlIGZsYWdcclxuICAgICAgICAgIHJlc3BvbnNlLnJlc3VsdHMuZm9yRWFjaCgocmVzdWx0OiBSZXN1bHQpID0+IHtcclxuICAgICAgICAgICAgcmVzdWx0LmFnZ3JlZ2F0aW9ucy5mb3JFYWNoKChhZ2c6IEFnZ3JlZ2F0aW9uKSA9PiB7XHJcbiAgICAgICAgICAgICAgYWdnLiRoYXNNb3JlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgaWYgKCFhZ2cuaXNEaXN0cmlidXRpb24gJiYgIWFnZy5pc1RyZWUgJiYgYWdnLml0ZW1zKSB7XHJcbiAgICAgICAgICAgICAgICBhZ2cuJGhhc01vcmUgPSBhZ2cuaXRlbXMubGVuZ3RoID09PSBBR0dSRUdBVElPTl9NQVhfQ09VTlQ7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGlmIChhZ2cuaXNUcmVlKSB7XHJcbiAgICAgICAgICAgICAgICBidWlsZFBhdGhzQW5kTGV2ZWxzKGFnZyBhcyBUcmVlQWdncmVnYXRpb24pO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICB9KVxyXG5cclxuICAgICAgICAgIHJldHVybiByZXNwb25zZS5yZXN1bHRzO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIG1hcChyZXN1bHRzID0+IHtcclxuICAgICAgICAgIHJlc3VsdHMuZm9yRWFjaChyZXN1bHQgPT4gIHJlc3VsdC5yZWNvcmRzPy5tYXAoKGFydGljbGU6IEFydGljbGUpID0+IChPYmplY3QuYXNzaWduKGFydGljbGUsIHsgdmFsdWU6IGFydGljbGUudGl0bGUsIHR5cGU6ICdkZWZhdWx0JyB9KSkpKTtcclxuICAgICAgICAgIHJldHVybiByZXN1bHRzO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIG1hcChyZXN1bHRzID0+IHtcclxuICAgICAgICAgIHJldHVybiByZXN1bHRzLm1hcChyZXN1bHQgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCByID0gKHsgLi4ucmVzdWx0LCBuZXh0UGFnZTogcmVzdWx0LnBhZ2UgPCBNYXRoLmNlaWwocmVzdWx0LnJvd0NvdW50IC8gcmVzdWx0LnBhZ2VTaXplKSA/IHJlc3VsdC5wYWdlICsgMSA6IHVuZGVmaW5lZCwgcHJldmlvdXNQYWdlOiByZXN1bHQucGFnZSA+IDEgPyByZXN1bHQucGFnZSAtIDEgOiB1bmRlZmluZWQgfSlcclxuICAgICAgICAgICAgcmV0dXJuIHI7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9KSxcclxuICAgICAgICAvLyBtYXAocmVzcG9uc2UgPT4gUmVzdWx0c1NjaGVtYS5wYXJzZShyZXNwb25zZSkgYXMgVCksXHJcbiAgICAgICAgdGFwKHJlc3BvbnNlID0+IGNvbnNvbGUubG9nKFwicXVlcnlTZXJ2aWNlLmJ1bGtTZWFyY2ggc3VjY2VzcyAtIGRhdGE6IFwiLCByZXNwb25zZSkpLFxyXG4gICAgICApO1xyXG5cclxuICB9XHJcbn1cclxuIl19