@igo2/context 1.15.5 → 1.15.6

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 (125) hide show
  1. package/esm2020/igo2-context.mjs +4 -4
  2. package/esm2020/lib/context-import-export/context-import-export/context-import-export.component.mjs +227 -227
  3. package/esm2020/lib/context-import-export/context-import-export.module.mjs +84 -84
  4. package/esm2020/lib/context-import-export/index.mjs +2 -2
  5. package/esm2020/lib/context-import-export/shared/context-export.errors.mjs +14 -14
  6. package/esm2020/lib/context-import-export/shared/context-export.interface.mjs +1 -1
  7. package/esm2020/lib/context-import-export/shared/context-export.service.mjs +37 -37
  8. package/esm2020/lib/context-import-export/shared/context-export.utils.mjs +14 -14
  9. package/esm2020/lib/context-import-export/shared/context-import.errors.mjs +32 -32
  10. package/esm2020/lib/context-import-export/shared/context-import.service.mjs +78 -78
  11. package/esm2020/lib/context-import-export/shared/context-import.utils.mjs +132 -132
  12. package/esm2020/lib/context-import-export/shared/index.mjs +7 -7
  13. package/esm2020/lib/context-manager/context-edit/context-edit-binding.directive.mjs +49 -49
  14. package/esm2020/lib/context-manager/context-edit/context-edit.component.mjs +45 -45
  15. package/esm2020/lib/context-manager/context-edit/index.mjs +2 -2
  16. package/esm2020/lib/context-manager/context-form/context-form.component.mjs +142 -142
  17. package/esm2020/lib/context-manager/context-form/index.mjs +1 -1
  18. package/esm2020/lib/context-manager/context-item/context-item.component.mjs +244 -244
  19. package/esm2020/lib/context-manager/context-item/index.mjs +1 -1
  20. package/esm2020/lib/context-manager/context-list/context-list-binding.directive.mjs +239 -239
  21. package/esm2020/lib/context-manager/context-list/context-list.component.mjs +591 -591
  22. package/esm2020/lib/context-manager/context-list/context-list.enum.mjs +6 -6
  23. package/esm2020/lib/context-manager/context-list/index.mjs +2 -2
  24. package/esm2020/lib/context-manager/context-manager.module.mjs +161 -161
  25. package/esm2020/lib/context-manager/context-permissions/context-permissions-binding.directive.mjs +98 -98
  26. package/esm2020/lib/context-manager/context-permissions/context-permissions.component.mjs +305 -305
  27. package/esm2020/lib/context-manager/context-permissions/index.mjs +2 -2
  28. package/esm2020/lib/context-manager/index.mjs +6 -6
  29. package/esm2020/lib/context-manager/shared/context.enum.mjs +12 -12
  30. package/esm2020/lib/context-manager/shared/context.interface.mjs +1 -1
  31. package/esm2020/lib/context-manager/shared/context.service.mjs +631 -631
  32. package/esm2020/lib/context-manager/shared/index.mjs +5 -5
  33. package/esm2020/lib/context-manager/shared/layer-context.directive.mjs +155 -155
  34. package/esm2020/lib/context-manager/shared/map-context.directive.mjs +69 -69
  35. package/esm2020/lib/context-map-button/bookmark-button/bookmark-button.component.mjs +65 -65
  36. package/esm2020/lib/context-map-button/bookmark-button/bookmark-dialog.component.mjs +49 -49
  37. package/esm2020/lib/context-map-button/bookmark-button/index.mjs +2 -2
  38. package/esm2020/lib/context-map-button/context-map-button.module.mjs +95 -95
  39. package/esm2020/lib/context-map-button/index.mjs +3 -3
  40. package/esm2020/lib/context-map-button/poi-button/index.mjs +3 -3
  41. package/esm2020/lib/context-map-button/poi-button/poi-button.component.mjs +160 -160
  42. package/esm2020/lib/context-map-button/poi-button/poi-dialog.component.mjs +49 -49
  43. package/esm2020/lib/context-map-button/poi-button/shared/index.mjs +2 -2
  44. package/esm2020/lib/context-map-button/poi-button/shared/poi.interface.mjs +1 -1
  45. package/esm2020/lib/context-map-button/poi-button/shared/poi.service.mjs +32 -32
  46. package/esm2020/lib/context-map-button/user-button/index.mjs +2 -2
  47. package/esm2020/lib/context-map-button/user-button/user-button.animation.mjs +16 -16
  48. package/esm2020/lib/context-map-button/user-button/user-button.component.mjs +103 -103
  49. package/esm2020/lib/context-map-button/user-button/user-dialog.component.mjs +65 -65
  50. package/esm2020/lib/context.module.mjs +44 -44
  51. package/esm2020/lib/share-map/index.mjs +4 -4
  52. package/esm2020/lib/share-map/share-map/share-map-api.component.mjs +169 -169
  53. package/esm2020/lib/share-map/share-map/share-map-url.component.mjs +242 -242
  54. package/esm2020/lib/share-map/share-map/share-map.component.mjs +56 -56
  55. package/esm2020/lib/share-map/share-map.module.mjs +66 -66
  56. package/esm2020/lib/share-map/shared/index.mjs +1 -1
  57. package/esm2020/lib/share-map/shared/share-map.service.mjs +209 -209
  58. package/esm2020/lib/sidenav/index.mjs +1 -1
  59. package/esm2020/lib/sidenav/sidenav.component.mjs +169 -169
  60. package/esm2020/lib/sidenav/sidenav.module.mjs +60 -60
  61. package/esm2020/public_api.mjs +14 -14
  62. package/fesm2015/igo2-context.mjs +4942 -4942
  63. package/fesm2020/igo2-context.mjs +4591 -4591
  64. package/index.d.ts +5 -5
  65. package/lib/context-import-export/context-import-export/context-import-export.component.d.ts +44 -44
  66. package/lib/context-import-export/context-import-export.module.d.ts +23 -23
  67. package/lib/context-import-export/index.d.ts +2 -2
  68. package/lib/context-import-export/shared/context-export.errors.d.ts +8 -8
  69. package/lib/context-import-export/shared/context-export.interface.d.ts +5 -5
  70. package/lib/context-import-export/shared/context-export.service.d.ts +10 -10
  71. package/lib/context-import-export/shared/context-export.utils.d.ts +4 -4
  72. package/lib/context-import-export/shared/context-import.errors.d.ts +17 -17
  73. package/lib/context-import-export/shared/context-import.service.d.ts +18 -18
  74. package/lib/context-import-export/shared/context-import.utils.d.ts +17 -17
  75. package/lib/context-import-export/shared/index.d.ts +7 -7
  76. package/lib/context-manager/context-edit/context-edit-binding.directive.d.ts +20 -20
  77. package/lib/context-manager/context-edit/context-edit.component.d.ts +14 -14
  78. package/lib/context-manager/context-edit/index.d.ts +2 -2
  79. package/lib/context-manager/context-form/context-form.component.d.ts +30 -30
  80. package/lib/context-manager/context-form/index.d.ts +1 -1
  81. package/lib/context-manager/context-item/context-item.component.d.ts +32 -32
  82. package/lib/context-manager/context-item/index.d.ts +1 -1
  83. package/lib/context-manager/context-list/context-list-binding.directive.d.ts +46 -46
  84. package/lib/context-manager/context-list/context-list.component.d.ts +93 -93
  85. package/lib/context-manager/context-list/context-list.enum.d.ts +5 -5
  86. package/lib/context-manager/context-list/index.d.ts +2 -2
  87. package/lib/context-manager/context-manager.module.d.ts +37 -37
  88. package/lib/context-manager/context-permissions/context-permissions-binding.directive.d.ts +23 -23
  89. package/lib/context-manager/context-permissions/context-permissions.component.d.ts +40 -40
  90. package/lib/context-manager/context-permissions/index.d.ts +2 -2
  91. package/lib/context-manager/index.d.ts +6 -6
  92. package/lib/context-manager/shared/context.enum.d.ts +10 -10
  93. package/lib/context-manager/shared/context.interface.d.ts +75 -75
  94. package/lib/context-manager/shared/context.service.d.ts +75 -75
  95. package/lib/context-manager/shared/index.d.ts +5 -5
  96. package/lib/context-manager/shared/layer-context.directive.d.ts +28 -28
  97. package/lib/context-manager/shared/map-context.directive.d.ts +19 -19
  98. package/lib/context-map-button/bookmark-button/bookmark-button.component.d.ts +20 -20
  99. package/lib/context-map-button/bookmark-button/bookmark-dialog.component.d.ts +9 -9
  100. package/lib/context-map-button/bookmark-button/index.d.ts +2 -2
  101. package/lib/context-map-button/context-map-button.module.d.ts +27 -27
  102. package/lib/context-map-button/index.d.ts +3 -3
  103. package/lib/context-map-button/poi-button/index.d.ts +3 -3
  104. package/lib/context-map-button/poi-button/poi-button.component.d.ts +34 -34
  105. package/lib/context-map-button/poi-button/poi-dialog.component.d.ts +9 -9
  106. package/lib/context-map-button/poi-button/shared/index.d.ts +2 -2
  107. package/lib/context-map-button/poi-button/shared/poi.interface.d.ts +7 -7
  108. package/lib/context-map-button/poi-button/shared/poi.service.d.ts +16 -16
  109. package/lib/context-map-button/user-button/index.d.ts +2 -2
  110. package/lib/context-map-button/user-button/user-button.animation.d.ts +2 -2
  111. package/lib/context-map-button/user-button/user-button.component.d.ts +25 -25
  112. package/lib/context-map-button/user-button/user-dialog.component.d.ts +15 -15
  113. package/lib/context.module.d.ts +16 -16
  114. package/lib/share-map/index.d.ts +4 -4
  115. package/lib/share-map/share-map/share-map-api.component.d.ts +27 -27
  116. package/lib/share-map/share-map/share-map-url.component.d.ts +26 -26
  117. package/lib/share-map/share-map/share-map.component.d.ts +11 -11
  118. package/lib/share-map/share-map.module.d.ts +21 -21
  119. package/lib/share-map/shared/index.d.ts +1 -1
  120. package/lib/share-map/shared/share-map.service.d.ts +17 -17
  121. package/lib/sidenav/index.d.ts +1 -1
  122. package/lib/sidenav/sidenav.component.d.ts +35 -35
  123. package/lib/sidenav/sidenav.module.d.ts +18 -18
  124. package/package.json +6 -6
  125. package/public_api.d.ts +11 -11
@@ -1,632 +1,632 @@
1
- import { Injectable, Optional } from '@angular/core';
2
- import { BehaviorSubject, of, Subject } from 'rxjs';
3
- import { map, tap, catchError, debounceTime, mergeMap, first, skip } from 'rxjs/operators';
4
- import olPoint from 'ol/geom/Point';
5
- import GeoJSON from 'ol/format/GeoJSON';
6
- import Cluster from 'ol/source/Cluster';
7
- import olVectorSource from 'ol/source/Vector';
8
- import { uuid, ObjectUtils } from '@igo2/utils';
9
- import { TypePermission } from './context.enum';
10
- import * as i0 from "@angular/core";
11
- import * as i1 from "@angular/common/http";
12
- import * as i2 from "@igo2/auth";
13
- import * as i3 from "@igo2/core";
14
- import * as i4 from "@igo2/geo";
15
- export class ContextService {
16
- constructor(http, authService, languageService, config, messageService, storageService, exportService, route) {
17
- this.http = http;
18
- this.authService = authService;
19
- this.languageService = languageService;
20
- this.config = config;
21
- this.messageService = messageService;
22
- this.storageService = storageService;
23
- this.exportService = exportService;
24
- this.route = route;
25
- this.context$ = new BehaviorSubject(undefined);
26
- this.contexts$ = new BehaviorSubject({ ours: [] });
27
- this.defaultContextId$ = new BehaviorSubject(undefined);
28
- this.editedContext$ = new BehaviorSubject(undefined);
29
- this.importedContext = [];
30
- this.toolsChanged$ = new Subject();
31
- this.mapViewFromRoute = {};
32
- this.options = Object.assign({
33
- basePath: 'contexts',
34
- contextListFile: '_contexts.json',
35
- defaultContextUri: '_default'
36
- }, this.config.getConfig('context'));
37
- this.baseUrl = this.options.url;
38
- this.readParamsFromRoute();
39
- if (this.authService.hasAuthService) {
40
- this.authService.logged$.subscribe((logged) => {
41
- if (logged) {
42
- this.contexts$.pipe(skip(1), first()).subscribe((c) => {
43
- this.handleContextsChange();
44
- });
45
- this.loadContexts();
46
- }
47
- });
48
- }
49
- else {
50
- this.loadContexts();
51
- this.handleContextsChange(false);
52
- }
53
- }
54
- get defaultContextUri() {
55
- return this.storageService.get('favorite.context.uri') || this._defaultContextUri || this.options.defaultContextUri;
56
- }
57
- set defaultContextUri(uri) {
58
- this._defaultContextUri = uri;
59
- }
60
- get(permissions, hidden) {
61
- let url = this.baseUrl + '/contexts';
62
- if (permissions && this.authService.authenticated) {
63
- url += '?permission=' + permissions.join();
64
- if (hidden) {
65
- url += '&hidden=true';
66
- }
67
- }
68
- return this.http.get(url);
69
- }
70
- getById(id) {
71
- const url = this.baseUrl + '/contexts/' + id;
72
- return this.http.get(url);
73
- }
74
- getDetails(id) {
75
- const url = `${this.baseUrl}/contexts/${id}/details`;
76
- return this.http.get(url).pipe(catchError((res) => {
77
- this.handleError(res, id);
78
- throw res;
79
- }));
80
- }
81
- getDefault() {
82
- if (this.authService.authenticated) {
83
- const url = this.baseUrl + '/contexts/default';
84
- return this.http.get(url).pipe(tap((context) => {
85
- this.defaultContextId$.next(context.id);
86
- }));
87
- }
88
- else {
89
- const uri = this.storageService.get('favorite.context.uri');
90
- this.defaultContextId$.next(uri);
91
- return this.getContextByUri(uri);
92
- }
93
- }
94
- getProfilByUser() {
95
- if (this.baseUrl) {
96
- const url = this.baseUrl + '/profils?';
97
- return this.http.get(url);
98
- }
99
- return of([]);
100
- }
101
- setDefault(id) {
102
- if (this.authService.authenticated) {
103
- const url = this.baseUrl + '/contexts/default';
104
- return this.http.post(url, { defaultContextId: id });
105
- }
106
- else {
107
- this.storageService.set('favorite.context.uri', id);
108
- return of(undefined);
109
- }
110
- }
111
- hideContext(id) {
112
- const url = this.baseUrl + '/contexts/' + id + '/hide';
113
- return this.http.post(url, {});
114
- }
115
- showContext(id) {
116
- const url = this.baseUrl + '/contexts/' + id + '/show';
117
- return this.http.post(url, {});
118
- }
119
- delete(id, imported = false) {
120
- const contexts = { ours: [] };
121
- Object.keys(this.contexts$.value).forEach((key) => (contexts[key] = this.contexts$.value[key].filter((c) => c.id !== id)));
122
- if (imported) {
123
- this.importedContext = this.importedContext.filter((c) => c.id !== id);
124
- return of(this.contexts$.next(contexts));
125
- }
126
- const url = this.baseUrl + '/contexts/' + id;
127
- return this.http.delete(url).pipe(tap((res) => {
128
- this.contexts$.next(contexts);
129
- }));
130
- }
131
- create(context) {
132
- const url = this.baseUrl + '/contexts';
133
- return this.http.post(url, context).pipe(map((contextCreated) => {
134
- if (this.authService.authenticated) {
135
- contextCreated.permission = TypePermission[TypePermission.write];
136
- }
137
- else {
138
- contextCreated.permission = TypePermission[TypePermission.read];
139
- }
140
- this.contexts$.value.ours.unshift(contextCreated);
141
- this.contexts$.next(this.contexts$.value);
142
- return contextCreated;
143
- }));
144
- }
145
- clone(id, properties = {}) {
146
- const url = this.baseUrl + '/contexts/' + id + '/clone';
147
- return this.http.post(url, properties).pipe(map((contextCloned) => {
148
- contextCloned.permission = TypePermission[TypePermission.write];
149
- this.contexts$.value.ours.unshift(contextCloned);
150
- this.contexts$.next(this.contexts$.value);
151
- return contextCloned;
152
- }));
153
- }
154
- update(id, context) {
155
- const url = this.baseUrl + '/contexts/' + id;
156
- return this.http.patch(url, context);
157
- }
158
- // =================================================================
159
- addToolAssociation(contextId, toolId) {
160
- const url = `${this.baseUrl}/contexts/${contextId}/tools`;
161
- const association = {
162
- toolId
163
- };
164
- return this.http.post(url, association);
165
- }
166
- deleteToolAssociation(contextId, toolId) {
167
- const url = `${this.baseUrl}/contexts/${contextId}/tools/${toolId}`;
168
- return this.http.delete(url);
169
- }
170
- getPermissions(id) {
171
- const url = this.baseUrl + '/contexts/' + id + '/permissions';
172
- return this.http.get(url);
173
- }
174
- addPermissionAssociation(contextId, profil, type) {
175
- const url = `${this.baseUrl}/contexts/${contextId}/permissions`;
176
- const association = {
177
- profil,
178
- typePermission: type
179
- };
180
- return this.http.post(url, association).pipe(catchError((res) => {
181
- this.handleError(res, undefined, true);
182
- throw [res]; // TODO Not sure about this.
183
- }));
184
- }
185
- deletePermissionAssociation(contextId, permissionId) {
186
- const url = `${this.baseUrl}/contexts/${contextId}/permissions/${permissionId}`;
187
- return this.http.delete(url);
188
- }
189
- // ======================================================================
190
- getLocalContexts() {
191
- const url = this.getPath(this.options.contextListFile);
192
- return this.http.get(url).pipe(map((res) => {
193
- return { ours: res };
194
- }));
195
- }
196
- getLocalContext(uri) {
197
- const url = this.getPath(`${uri}.json`);
198
- return this.http.get(url).pipe(mergeMap((res) => {
199
- if (!res.base) {
200
- return of(res);
201
- }
202
- const urlBase = this.getPath(`${res.base}.json`);
203
- return this.http.get(urlBase).pipe(map((resBase) => {
204
- const resMerge = res;
205
- resMerge.map = ObjectUtils.mergeDeep(resBase.map, res.map);
206
- resMerge.layers = (resBase.layers || [])
207
- .concat(res.layers || [])
208
- .reverse()
209
- .filter((l, index, self) => !l.id || self.findIndex((l2) => l2.id === l.id) === index)
210
- .reverse();
211
- resMerge.toolbar = res.toolbar || resBase.toolbar;
212
- resMerge.message = res.message || resBase.message;
213
- resMerge.messages = res.messages || resBase.messages;
214
- resMerge.tools = (res.tools || [])
215
- .concat(resBase.tools || [])
216
- .filter((t, index, self) => self.findIndex((t2) => t2.name === t.name) === index);
217
- return resMerge;
218
- }), catchError((err) => {
219
- this.handleError(err, uri);
220
- throw err;
221
- }));
222
- }), catchError((err2) => {
223
- this.handleError(err2, uri);
224
- throw err2;
225
- }));
226
- }
227
- loadContexts(permissions, hidden) {
228
- let request;
229
- if (this.baseUrl) {
230
- request = this.get(permissions, hidden);
231
- }
232
- else {
233
- request = this.getLocalContexts();
234
- }
235
- request.subscribe((contexts) => {
236
- contexts.ours = this.importedContext.concat(contexts.ours);
237
- this.contexts$.next(contexts);
238
- });
239
- }
240
- loadDefaultContext() {
241
- const loadFct = (direct = false) => {
242
- if (!direct && this.baseUrl && this.authService.authenticated) {
243
- this.getDefault().subscribe((_context) => {
244
- this.defaultContextUri = _context.uri;
245
- this.addContextToList(_context);
246
- this.setContext(_context);
247
- }, () => {
248
- this.defaultContextId$.next(undefined);
249
- this.loadContext(this.defaultContextUri);
250
- });
251
- }
252
- else {
253
- this.loadContext(this.defaultContextUri);
254
- }
255
- };
256
- if (this.route && this.route.options.contextKey) {
257
- this.route.queryParams.pipe(debounceTime(100)).subscribe((params) => {
258
- const contextParam = params[this.route.options.contextKey];
259
- let direct = false;
260
- if (contextParam) {
261
- this.defaultContextUri = contextParam;
262
- direct = true;
263
- }
264
- loadFct(direct);
265
- });
266
- }
267
- else {
268
- loadFct();
269
- }
270
- }
271
- loadContext(uri) {
272
- const context = this.context$.value;
273
- if (context && context.uri === uri) {
274
- return;
275
- }
276
- this.getContextByUri(uri)
277
- .pipe(first())
278
- .subscribe((_context) => {
279
- this.addContextToList(_context);
280
- this.setContext(_context);
281
- }, (err) => {
282
- if (uri !== this.options.defaultContextUri) {
283
- this.loadContext(this.options.defaultContextUri);
284
- }
285
- });
286
- }
287
- setContext(context) {
288
- this.handleContextMessage(context);
289
- const currentContext = this.context$.value;
290
- if (currentContext && context && context.id === currentContext.id) {
291
- if (context.map.view.keepCurrentView === undefined) {
292
- context.map.view.keepCurrentView = true;
293
- }
294
- this.context$.next(context);
295
- return;
296
- }
297
- if (!context.map) {
298
- context.map = { view: {} };
299
- }
300
- Object.assign(context.map.view, this.mapViewFromRoute);
301
- this.context$.next(context);
302
- }
303
- loadEditedContext(uri) {
304
- this.getContextByUri(uri).subscribe((_context) => {
305
- this.setEditedContext(_context);
306
- });
307
- }
308
- setEditedContext(context) {
309
- this.editedContext$.next(context);
310
- }
311
- getContextFromMap(igoMap, empty) {
312
- const view = igoMap.ol.getView();
313
- const proj = view.getProjection().getCode();
314
- const center = new olPoint(view.getCenter()).transform(proj, 'EPSG:4326');
315
- const context = {
316
- uri: uuid(),
317
- title: '',
318
- scope: 'private',
319
- map: {
320
- view: {
321
- center: center.getCoordinates(),
322
- zoom: view.getZoom(),
323
- projection: proj,
324
- maxZoomOnExtent: igoMap.viewController.maxZoomOnExtent
325
- }
326
- },
327
- layers: [],
328
- tools: []
329
- };
330
- let layers = [];
331
- if (empty === true) {
332
- layers = igoMap.layers$
333
- .getValue()
334
- .filter((lay) => lay.baseLayer === true ||
335
- lay.options.id === 'searchPointerSummaryId')
336
- .sort((a, b) => a.zIndex - b.zIndex);
337
- }
338
- else {
339
- layers = igoMap.layers$.getValue().filter(lay => !lay.id.includes('WfsWorkspaceTableDest')).sort((a, b) => a.zIndex - b.zIndex);
340
- }
341
- let i = 0;
342
- for (const l of layers) {
343
- const layer = l;
344
- const opts = {
345
- id: layer.options.id ? String(layer.options.id) : undefined,
346
- layerOptions: {
347
- title: layer.options.title,
348
- zIndex: ++i,
349
- visible: layer.visible,
350
- security: layer.security
351
- },
352
- sourceOptions: {
353
- type: layer.dataSource.options.type,
354
- params: layer.dataSource.options.params,
355
- url: layer.dataSource.options.url,
356
- queryable: layer.queryable
357
- }
358
- };
359
- if (opts.sourceOptions.type) {
360
- context.layers.push(opts);
361
- }
362
- }
363
- context.tools = this.tools.map((tool) => {
364
- return { id: String(tool.id), global: tool.global };
365
- });
366
- return context;
367
- }
368
- getContextFromLayers(igoMap, layers, name) {
369
- const currentContext = this.context$.getValue();
370
- const view = igoMap.ol.getView();
371
- const proj = view.getProjection().getCode();
372
- const center = new olPoint(view.getCenter()).transform(proj, 'EPSG:4326');
373
- const context = {
374
- uri: name,
375
- title: name,
376
- map: {
377
- view: {
378
- center: center.getCoordinates(),
379
- zoom: view.getZoom(),
380
- projection: proj
381
- }
382
- },
383
- layers: [],
384
- toolbar: [],
385
- tools: [],
386
- extraFeatures: []
387
- };
388
- const currentLayers = igoMap.layers$.getValue();
389
- context.layers = currentLayers
390
- .filter((l) => l.baseLayer)
391
- .map((l) => {
392
- return {
393
- baseLayer: true,
394
- sourceOptions: l.options.sourceOptions,
395
- title: l.options.title,
396
- visible: l.visible
397
- };
398
- });
399
- layers.forEach((layer) => {
400
- // Do not seem to work properly. layerFound is always undefined.
401
- const layerFound = currentContext.layers.find((contextLayer) => {
402
- const source = contextLayer.source;
403
- return source && layer.id === source.id && !contextLayer.baseLayer;
404
- });
405
- if (layerFound) {
406
- let layerStyle = layerFound[`style`];
407
- if (layerFound[`igoStyle`][`styleByAttribute`]) {
408
- layerStyle = undefined;
409
- }
410
- else if (layerFound[`igoStyle`][`clusterBaseStyle`]) {
411
- layerStyle = undefined;
412
- delete layerFound.sourceOptions[`source`];
413
- delete layerFound.sourceOptions[`format`];
414
- }
415
- const opts = {
416
- baseLayer: layerFound.baseLayer,
417
- title: layer.options.title,
418
- zIndex: layer.zIndex,
419
- igoStyle: {
420
- styleByAttribute: layerFound[`igoStyle`][`styleByAttribute`],
421
- clusterBaseStyle: layerFound[`igoStyle`][`clusterBaseStyle`],
422
- },
423
- style: layerStyle,
424
- clusterParam: layerFound[`clusterParam`],
425
- visible: layer.visible,
426
- opacity: layer.opacity,
427
- sourceOptions: layerFound.sourceOptions
428
- };
429
- context.layers.push(opts);
430
- }
431
- else {
432
- if (!(layer.ol.getSource() instanceof olVectorSource)) {
433
- const catalogLayer = layer.options;
434
- catalogLayer.zIndex = layer.zIndex;
435
- delete catalogLayer.source;
436
- context.layers.push(catalogLayer);
437
- }
438
- else {
439
- let features;
440
- const writer = new GeoJSON();
441
- if (layer.ol.getSource() instanceof Cluster) {
442
- const clusterSource = layer.ol.getSource();
443
- let olFeatures = clusterSource.getFeatures();
444
- olFeatures = olFeatures.flatMap((cluster) => cluster.get('features'));
445
- const cleanedOlFeatures = this.exportService.generateFeature(olFeatures, 'GeoJSON', '_featureStore');
446
- features = writer.writeFeatures(cleanedOlFeatures, {
447
- dataProjection: 'EPSG:4326',
448
- featureProjection: 'EPSG:3857'
449
- });
450
- }
451
- else {
452
- const source = layer.ol.getSource();
453
- const olFeatures = source.getFeatures();
454
- const cleanedOlFeatures = this.exportService.generateFeature(olFeatures, 'GeoJSON', '_featureStore');
455
- features = writer.writeFeatures(cleanedOlFeatures, {
456
- dataProjection: 'EPSG:4326',
457
- featureProjection: 'EPSG:3857'
458
- });
459
- }
460
- features = JSON.parse(features);
461
- features.name = layer.options.title;
462
- context.extraFeatures.push(features);
463
- }
464
- }
465
- });
466
- context.toolbar = this.toolbar;
467
- context.tools = this.tools;
468
- return context;
469
- }
470
- setTools(tools) {
471
- this.tools = tools;
472
- }
473
- setToolbar(toolbar) {
474
- this.toolbar = toolbar;
475
- }
476
- handleContextMessage(context) {
477
- if (this.context$.value && context.uri && this.context$.value.uri !== context.uri) {
478
- this.messageService.removeAllAreNotError();
479
- }
480
- context.messages = context.messages ? context.messages : [];
481
- context.messages.push(context.message);
482
- context.messages.map(message => {
483
- if (message) {
484
- this.messageService.message(message);
485
- }
486
- });
487
- }
488
- getContextByUri(uri) {
489
- if (this.baseUrl) {
490
- let contextToLoad;
491
- for (const key of Object.keys(this.contexts$.value)) {
492
- contextToLoad = this.contexts$.value[key].find((c) => {
493
- return c.uri === uri;
494
- });
495
- if (contextToLoad) {
496
- break;
497
- }
498
- }
499
- if (contextToLoad && contextToLoad.imported) {
500
- return of(contextToLoad);
501
- }
502
- // TODO : use always id or uri
503
- const id = contextToLoad ? contextToLoad.id : uri;
504
- return this.getDetails(id);
505
- }
506
- const importedContext = this.contexts$.value.ours.find((currentContext) => {
507
- return currentContext.uri === uri && currentContext.imported === true;
508
- });
509
- if (importedContext) {
510
- return of(importedContext);
511
- }
512
- else {
513
- return this.getLocalContext(uri);
514
- }
515
- }
516
- getContextLayers(igoMap) {
517
- const layers = [];
518
- const mapLayers = igoMap.layers$.getValue();
519
- mapLayers.forEach((layer) => {
520
- if (!layer.baseLayer && layer.options.id !== 'searchPointerSummaryId') {
521
- layers.push(layer);
522
- }
523
- });
524
- return layers;
525
- }
526
- readParamsFromRoute() {
527
- if (!this.route) {
528
- return;
529
- }
530
- this.route.queryParams.subscribe((params) => {
531
- const centerKey = this.route.options.centerKey;
532
- if (centerKey && params[centerKey]) {
533
- const centerParams = params[centerKey];
534
- this.mapViewFromRoute.center = centerParams.split(',').map(Number);
535
- }
536
- const projectionKey = this.route.options.projectionKey;
537
- if (projectionKey && params[projectionKey]) {
538
- const projectionParam = params[projectionKey];
539
- this.mapViewFromRoute.projection = projectionParam;
540
- }
541
- const zoomKey = this.route.options.zoomKey;
542
- if (zoomKey && params[zoomKey]) {
543
- const zoomParam = params[zoomKey];
544
- this.mapViewFromRoute.zoom = Number(zoomParam);
545
- }
546
- });
547
- }
548
- getPath(file) {
549
- const basePath = this.options.basePath.replace(/\/$/, '');
550
- return `${basePath}/${file}`;
551
- }
552
- handleError(error, uri, permissionError) {
553
- const context = this.contexts$.value.ours.find((obj) => obj.uri === uri);
554
- const titleContext = context ? context.title : uri;
555
- error.error.title = this.languageService.translate.instant('igo.context.contextManager.invalid.title');
556
- error.error.message = this.languageService.translate.instant('igo.context.contextManager.invalid.text', { value: titleContext });
557
- error.error.toDisplay = true;
558
- if (permissionError) {
559
- error.error.title = this.languageService.translate.instant('igo.context.contextManager.errors.addPermissionTitle');
560
- error.error.message = this.languageService.translate.instant('igo.context.contextManager.errors.addPermission');
561
- }
562
- this.messageService.error('igo.context.contextManager.errors.addPermission', 'igo.context.contextManager.errors.addPermissionTitle');
563
- }
564
- handleContextsChange(keepCurrentContext = true) {
565
- const context = this.context$.value;
566
- const editedContext = this.editedContext$.value;
567
- if (!context || context.uri === this.options.defaultContextUri) {
568
- keepCurrentContext = false;
569
- }
570
- if (!keepCurrentContext || !this.findContext(context)) {
571
- this.defaultContextUri = undefined;
572
- this.loadDefaultContext();
573
- }
574
- else {
575
- this.getContextByUri(context.uri)
576
- .pipe(first())
577
- .subscribe((newContext) => {
578
- this.toolsChanged$.next(newContext);
579
- });
580
- if (this.baseUrl && this.authService.authenticated) {
581
- this.getDefault().subscribe();
582
- }
583
- }
584
- const editedFound = this.findContext(editedContext);
585
- if (!editedFound || editedFound.permission !== 'write') {
586
- this.setEditedContext(undefined);
587
- }
588
- }
589
- addContextToList(context) {
590
- const contextFound = this.findContext(context);
591
- if (!contextFound) {
592
- const contextSimplifie = {
593
- id: context.id,
594
- uri: context.uri,
595
- title: context.title,
596
- scope: context.scope,
597
- permission: TypePermission[TypePermission.read]
598
- };
599
- if (this.contexts$.value && this.contexts$.value.public) {
600
- this.contexts$.value.public.push(contextSimplifie);
601
- this.contexts$.next(this.contexts$.value);
602
- }
603
- }
604
- }
605
- findContext(context) {
606
- if (!context) {
607
- return false;
608
- }
609
- const contexts = this.contexts$.value;
610
- let found;
611
- for (const key of Object.keys(contexts)) {
612
- const value = contexts[key];
613
- found = value.find((c) => (context.id && c.id === context.id) ||
614
- (context.uri && c.uri === context.uri));
615
- if (found) {
616
- break;
617
- }
618
- }
619
- return found;
620
- }
621
- }
622
- ContextService.ɵfac = function ContextService_Factory(t) { return new (t || ContextService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(i2.AuthService), i0.ɵɵinject(i3.LanguageService), i0.ɵɵinject(i3.ConfigService), i0.ɵɵinject(i3.MessageService), i0.ɵɵinject(i3.StorageService), i0.ɵɵinject(i4.ExportService), i0.ɵɵinject(i3.RouteService, 8)); };
623
- ContextService.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: ContextService, factory: ContextService.ɵfac, providedIn: 'root' });
624
- (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ContextService, [{
625
- type: Injectable,
626
- args: [{
627
- providedIn: 'root'
628
- }]
629
- }], function () { return [{ type: i1.HttpClient }, { type: i2.AuthService }, { type: i3.LanguageService }, { type: i3.ConfigService }, { type: i3.MessageService }, { type: i3.StorageService }, { type: i4.ExportService }, { type: i3.RouteService, decorators: [{
630
- type: Optional
631
- }] }]; }, null); })();
1
+ import { Injectable, Optional } from '@angular/core';
2
+ import { BehaviorSubject, of, Subject } from 'rxjs';
3
+ import { map, tap, catchError, debounceTime, mergeMap, first, skip } from 'rxjs/operators';
4
+ import olPoint from 'ol/geom/Point';
5
+ import GeoJSON from 'ol/format/GeoJSON';
6
+ import Cluster from 'ol/source/Cluster';
7
+ import olVectorSource from 'ol/source/Vector';
8
+ import { uuid, ObjectUtils } from '@igo2/utils';
9
+ import { TypePermission } from './context.enum';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@angular/common/http";
12
+ import * as i2 from "@igo2/auth";
13
+ import * as i3 from "@igo2/core";
14
+ import * as i4 from "@igo2/geo";
15
+ export class ContextService {
16
+ constructor(http, authService, languageService, config, messageService, storageService, exportService, route) {
17
+ this.http = http;
18
+ this.authService = authService;
19
+ this.languageService = languageService;
20
+ this.config = config;
21
+ this.messageService = messageService;
22
+ this.storageService = storageService;
23
+ this.exportService = exportService;
24
+ this.route = route;
25
+ this.context$ = new BehaviorSubject(undefined);
26
+ this.contexts$ = new BehaviorSubject({ ours: [] });
27
+ this.defaultContextId$ = new BehaviorSubject(undefined);
28
+ this.editedContext$ = new BehaviorSubject(undefined);
29
+ this.importedContext = [];
30
+ this.toolsChanged$ = new Subject();
31
+ this.mapViewFromRoute = {};
32
+ this.options = Object.assign({
33
+ basePath: 'contexts',
34
+ contextListFile: '_contexts.json',
35
+ defaultContextUri: '_default'
36
+ }, this.config.getConfig('context'));
37
+ this.baseUrl = this.options.url;
38
+ this.readParamsFromRoute();
39
+ if (this.authService.hasAuthService) {
40
+ this.authService.logged$.subscribe((logged) => {
41
+ if (logged) {
42
+ this.contexts$.pipe(skip(1), first()).subscribe((c) => {
43
+ this.handleContextsChange();
44
+ });
45
+ this.loadContexts();
46
+ }
47
+ });
48
+ }
49
+ else {
50
+ this.loadContexts();
51
+ this.handleContextsChange(false);
52
+ }
53
+ }
54
+ get defaultContextUri() {
55
+ return this.storageService.get('favorite.context.uri') || this._defaultContextUri || this.options.defaultContextUri;
56
+ }
57
+ set defaultContextUri(uri) {
58
+ this._defaultContextUri = uri;
59
+ }
60
+ get(permissions, hidden) {
61
+ let url = this.baseUrl + '/contexts';
62
+ if (permissions && this.authService.authenticated) {
63
+ url += '?permission=' + permissions.join();
64
+ if (hidden) {
65
+ url += '&hidden=true';
66
+ }
67
+ }
68
+ return this.http.get(url);
69
+ }
70
+ getById(id) {
71
+ const url = this.baseUrl + '/contexts/' + id;
72
+ return this.http.get(url);
73
+ }
74
+ getDetails(id) {
75
+ const url = `${this.baseUrl}/contexts/${id}/details`;
76
+ return this.http.get(url).pipe(catchError((res) => {
77
+ this.handleError(res, id);
78
+ throw res;
79
+ }));
80
+ }
81
+ getDefault() {
82
+ if (this.authService.authenticated) {
83
+ const url = this.baseUrl + '/contexts/default';
84
+ return this.http.get(url).pipe(tap((context) => {
85
+ this.defaultContextId$.next(context.id);
86
+ }));
87
+ }
88
+ else {
89
+ const uri = this.storageService.get('favorite.context.uri');
90
+ this.defaultContextId$.next(uri);
91
+ return this.getContextByUri(uri);
92
+ }
93
+ }
94
+ getProfilByUser() {
95
+ if (this.baseUrl) {
96
+ const url = this.baseUrl + '/profils?';
97
+ return this.http.get(url);
98
+ }
99
+ return of([]);
100
+ }
101
+ setDefault(id) {
102
+ if (this.authService.authenticated) {
103
+ const url = this.baseUrl + '/contexts/default';
104
+ return this.http.post(url, { defaultContextId: id });
105
+ }
106
+ else {
107
+ this.storageService.set('favorite.context.uri', id);
108
+ return of(undefined);
109
+ }
110
+ }
111
+ hideContext(id) {
112
+ const url = this.baseUrl + '/contexts/' + id + '/hide';
113
+ return this.http.post(url, {});
114
+ }
115
+ showContext(id) {
116
+ const url = this.baseUrl + '/contexts/' + id + '/show';
117
+ return this.http.post(url, {});
118
+ }
119
+ delete(id, imported = false) {
120
+ const contexts = { ours: [] };
121
+ Object.keys(this.contexts$.value).forEach((key) => (contexts[key] = this.contexts$.value[key].filter((c) => c.id !== id)));
122
+ if (imported) {
123
+ this.importedContext = this.importedContext.filter((c) => c.id !== id);
124
+ return of(this.contexts$.next(contexts));
125
+ }
126
+ const url = this.baseUrl + '/contexts/' + id;
127
+ return this.http.delete(url).pipe(tap((res) => {
128
+ this.contexts$.next(contexts);
129
+ }));
130
+ }
131
+ create(context) {
132
+ const url = this.baseUrl + '/contexts';
133
+ return this.http.post(url, context).pipe(map((contextCreated) => {
134
+ if (this.authService.authenticated) {
135
+ contextCreated.permission = TypePermission[TypePermission.write];
136
+ }
137
+ else {
138
+ contextCreated.permission = TypePermission[TypePermission.read];
139
+ }
140
+ this.contexts$.value.ours.unshift(contextCreated);
141
+ this.contexts$.next(this.contexts$.value);
142
+ return contextCreated;
143
+ }));
144
+ }
145
+ clone(id, properties = {}) {
146
+ const url = this.baseUrl + '/contexts/' + id + '/clone';
147
+ return this.http.post(url, properties).pipe(map((contextCloned) => {
148
+ contextCloned.permission = TypePermission[TypePermission.write];
149
+ this.contexts$.value.ours.unshift(contextCloned);
150
+ this.contexts$.next(this.contexts$.value);
151
+ return contextCloned;
152
+ }));
153
+ }
154
+ update(id, context) {
155
+ const url = this.baseUrl + '/contexts/' + id;
156
+ return this.http.patch(url, context);
157
+ }
158
+ // =================================================================
159
+ addToolAssociation(contextId, toolId) {
160
+ const url = `${this.baseUrl}/contexts/${contextId}/tools`;
161
+ const association = {
162
+ toolId
163
+ };
164
+ return this.http.post(url, association);
165
+ }
166
+ deleteToolAssociation(contextId, toolId) {
167
+ const url = `${this.baseUrl}/contexts/${contextId}/tools/${toolId}`;
168
+ return this.http.delete(url);
169
+ }
170
+ getPermissions(id) {
171
+ const url = this.baseUrl + '/contexts/' + id + '/permissions';
172
+ return this.http.get(url);
173
+ }
174
+ addPermissionAssociation(contextId, profil, type) {
175
+ const url = `${this.baseUrl}/contexts/${contextId}/permissions`;
176
+ const association = {
177
+ profil,
178
+ typePermission: type
179
+ };
180
+ return this.http.post(url, association).pipe(catchError((res) => {
181
+ this.handleError(res, undefined, true);
182
+ throw [res]; // TODO Not sure about this.
183
+ }));
184
+ }
185
+ deletePermissionAssociation(contextId, permissionId) {
186
+ const url = `${this.baseUrl}/contexts/${contextId}/permissions/${permissionId}`;
187
+ return this.http.delete(url);
188
+ }
189
+ // ======================================================================
190
+ getLocalContexts() {
191
+ const url = this.getPath(this.options.contextListFile);
192
+ return this.http.get(url).pipe(map((res) => {
193
+ return { ours: res };
194
+ }));
195
+ }
196
+ getLocalContext(uri) {
197
+ const url = this.getPath(`${uri}.json`);
198
+ return this.http.get(url).pipe(mergeMap((res) => {
199
+ if (!res.base) {
200
+ return of(res);
201
+ }
202
+ const urlBase = this.getPath(`${res.base}.json`);
203
+ return this.http.get(urlBase).pipe(map((resBase) => {
204
+ const resMerge = res;
205
+ resMerge.map = ObjectUtils.mergeDeep(resBase.map, res.map);
206
+ resMerge.layers = (resBase.layers || [])
207
+ .concat(res.layers || [])
208
+ .reverse()
209
+ .filter((l, index, self) => !l.id || self.findIndex((l2) => l2.id === l.id) === index)
210
+ .reverse();
211
+ resMerge.toolbar = res.toolbar || resBase.toolbar;
212
+ resMerge.message = res.message || resBase.message;
213
+ resMerge.messages = res.messages || resBase.messages;
214
+ resMerge.tools = (res.tools || [])
215
+ .concat(resBase.tools || [])
216
+ .filter((t, index, self) => self.findIndex((t2) => t2.name === t.name) === index);
217
+ return resMerge;
218
+ }), catchError((err) => {
219
+ this.handleError(err, uri);
220
+ throw err;
221
+ }));
222
+ }), catchError((err2) => {
223
+ this.handleError(err2, uri);
224
+ throw err2;
225
+ }));
226
+ }
227
+ loadContexts(permissions, hidden) {
228
+ let request;
229
+ if (this.baseUrl) {
230
+ request = this.get(permissions, hidden);
231
+ }
232
+ else {
233
+ request = this.getLocalContexts();
234
+ }
235
+ request.subscribe((contexts) => {
236
+ contexts.ours = this.importedContext.concat(contexts.ours);
237
+ this.contexts$.next(contexts);
238
+ });
239
+ }
240
+ loadDefaultContext() {
241
+ const loadFct = (direct = false) => {
242
+ if (!direct && this.baseUrl && this.authService.authenticated) {
243
+ this.getDefault().subscribe((_context) => {
244
+ this.defaultContextUri = _context.uri;
245
+ this.addContextToList(_context);
246
+ this.setContext(_context);
247
+ }, () => {
248
+ this.defaultContextId$.next(undefined);
249
+ this.loadContext(this.defaultContextUri);
250
+ });
251
+ }
252
+ else {
253
+ this.loadContext(this.defaultContextUri);
254
+ }
255
+ };
256
+ if (this.route && this.route.options.contextKey) {
257
+ this.route.queryParams.pipe(debounceTime(100)).subscribe((params) => {
258
+ const contextParam = params[this.route.options.contextKey];
259
+ let direct = false;
260
+ if (contextParam) {
261
+ this.defaultContextUri = contextParam;
262
+ direct = true;
263
+ }
264
+ loadFct(direct);
265
+ });
266
+ }
267
+ else {
268
+ loadFct();
269
+ }
270
+ }
271
+ loadContext(uri) {
272
+ const context = this.context$.value;
273
+ if (context && context.uri === uri) {
274
+ return;
275
+ }
276
+ this.getContextByUri(uri)
277
+ .pipe(first())
278
+ .subscribe((_context) => {
279
+ this.addContextToList(_context);
280
+ this.setContext(_context);
281
+ }, (err) => {
282
+ if (uri !== this.options.defaultContextUri) {
283
+ this.loadContext(this.options.defaultContextUri);
284
+ }
285
+ });
286
+ }
287
+ setContext(context) {
288
+ this.handleContextMessage(context);
289
+ const currentContext = this.context$.value;
290
+ if (currentContext && context && context.id === currentContext.id) {
291
+ if (context.map.view.keepCurrentView === undefined) {
292
+ context.map.view.keepCurrentView = true;
293
+ }
294
+ this.context$.next(context);
295
+ return;
296
+ }
297
+ if (!context.map) {
298
+ context.map = { view: {} };
299
+ }
300
+ Object.assign(context.map.view, this.mapViewFromRoute);
301
+ this.context$.next(context);
302
+ }
303
+ loadEditedContext(uri) {
304
+ this.getContextByUri(uri).subscribe((_context) => {
305
+ this.setEditedContext(_context);
306
+ });
307
+ }
308
+ setEditedContext(context) {
309
+ this.editedContext$.next(context);
310
+ }
311
+ getContextFromMap(igoMap, empty) {
312
+ const view = igoMap.ol.getView();
313
+ const proj = view.getProjection().getCode();
314
+ const center = new olPoint(view.getCenter()).transform(proj, 'EPSG:4326');
315
+ const context = {
316
+ uri: uuid(),
317
+ title: '',
318
+ scope: 'private',
319
+ map: {
320
+ view: {
321
+ center: center.getCoordinates(),
322
+ zoom: view.getZoom(),
323
+ projection: proj,
324
+ maxZoomOnExtent: igoMap.viewController.maxZoomOnExtent
325
+ }
326
+ },
327
+ layers: [],
328
+ tools: []
329
+ };
330
+ let layers = [];
331
+ if (empty === true) {
332
+ layers = igoMap.layers$
333
+ .getValue()
334
+ .filter((lay) => lay.baseLayer === true ||
335
+ lay.options.id === 'searchPointerSummaryId')
336
+ .sort((a, b) => a.zIndex - b.zIndex);
337
+ }
338
+ else {
339
+ layers = igoMap.layers$.getValue().filter(lay => !lay.id.includes('WfsWorkspaceTableDest')).sort((a, b) => a.zIndex - b.zIndex);
340
+ }
341
+ let i = 0;
342
+ for (const l of layers) {
343
+ const layer = l;
344
+ const opts = {
345
+ id: layer.options.id ? String(layer.options.id) : undefined,
346
+ layerOptions: {
347
+ title: layer.options.title,
348
+ zIndex: ++i,
349
+ visible: layer.visible,
350
+ security: layer.security
351
+ },
352
+ sourceOptions: {
353
+ type: layer.dataSource.options.type,
354
+ params: layer.dataSource.options.params,
355
+ url: layer.dataSource.options.url,
356
+ queryable: layer.queryable
357
+ }
358
+ };
359
+ if (opts.sourceOptions.type) {
360
+ context.layers.push(opts);
361
+ }
362
+ }
363
+ context.tools = this.tools.map((tool) => {
364
+ return { id: String(tool.id), global: tool.global };
365
+ });
366
+ return context;
367
+ }
368
+ getContextFromLayers(igoMap, layers, name) {
369
+ const currentContext = this.context$.getValue();
370
+ const view = igoMap.ol.getView();
371
+ const proj = view.getProjection().getCode();
372
+ const center = new olPoint(view.getCenter()).transform(proj, 'EPSG:4326');
373
+ const context = {
374
+ uri: name,
375
+ title: name,
376
+ map: {
377
+ view: {
378
+ center: center.getCoordinates(),
379
+ zoom: view.getZoom(),
380
+ projection: proj
381
+ }
382
+ },
383
+ layers: [],
384
+ toolbar: [],
385
+ tools: [],
386
+ extraFeatures: []
387
+ };
388
+ const currentLayers = igoMap.layers$.getValue();
389
+ context.layers = currentLayers
390
+ .filter((l) => l.baseLayer)
391
+ .map((l) => {
392
+ return {
393
+ baseLayer: true,
394
+ sourceOptions: l.options.sourceOptions,
395
+ title: l.options.title,
396
+ visible: l.visible
397
+ };
398
+ });
399
+ layers.forEach((layer) => {
400
+ // Do not seem to work properly. layerFound is always undefined.
401
+ const layerFound = currentContext.layers.find((contextLayer) => {
402
+ const source = contextLayer.source;
403
+ return source && layer.id === source.id && !contextLayer.baseLayer;
404
+ });
405
+ if (layerFound) {
406
+ let layerStyle = layerFound[`style`];
407
+ if (layerFound[`igoStyle`][`styleByAttribute`]) {
408
+ layerStyle = undefined;
409
+ }
410
+ else if (layerFound[`igoStyle`][`clusterBaseStyle`]) {
411
+ layerStyle = undefined;
412
+ delete layerFound.sourceOptions[`source`];
413
+ delete layerFound.sourceOptions[`format`];
414
+ }
415
+ const opts = {
416
+ baseLayer: layerFound.baseLayer,
417
+ title: layer.options.title,
418
+ zIndex: layer.zIndex,
419
+ igoStyle: {
420
+ styleByAttribute: layerFound[`igoStyle`][`styleByAttribute`],
421
+ clusterBaseStyle: layerFound[`igoStyle`][`clusterBaseStyle`],
422
+ },
423
+ style: layerStyle,
424
+ clusterParam: layerFound[`clusterParam`],
425
+ visible: layer.visible,
426
+ opacity: layer.opacity,
427
+ sourceOptions: layerFound.sourceOptions
428
+ };
429
+ context.layers.push(opts);
430
+ }
431
+ else {
432
+ if (!(layer.ol.getSource() instanceof olVectorSource)) {
433
+ const catalogLayer = layer.options;
434
+ catalogLayer.zIndex = layer.zIndex;
435
+ delete catalogLayer.source;
436
+ context.layers.push(catalogLayer);
437
+ }
438
+ else {
439
+ let features;
440
+ const writer = new GeoJSON();
441
+ if (layer.ol.getSource() instanceof Cluster) {
442
+ const clusterSource = layer.ol.getSource();
443
+ let olFeatures = clusterSource.getFeatures();
444
+ olFeatures = olFeatures.flatMap((cluster) => cluster.get('features'));
445
+ const cleanedOlFeatures = this.exportService.generateFeature(olFeatures, 'GeoJSON', '_featureStore');
446
+ features = writer.writeFeatures(cleanedOlFeatures, {
447
+ dataProjection: 'EPSG:4326',
448
+ featureProjection: 'EPSG:3857'
449
+ });
450
+ }
451
+ else {
452
+ const source = layer.ol.getSource();
453
+ const olFeatures = source.getFeatures();
454
+ const cleanedOlFeatures = this.exportService.generateFeature(olFeatures, 'GeoJSON', '_featureStore');
455
+ features = writer.writeFeatures(cleanedOlFeatures, {
456
+ dataProjection: 'EPSG:4326',
457
+ featureProjection: 'EPSG:3857'
458
+ });
459
+ }
460
+ features = JSON.parse(features);
461
+ features.name = layer.options.title;
462
+ context.extraFeatures.push(features);
463
+ }
464
+ }
465
+ });
466
+ context.toolbar = this.toolbar;
467
+ context.tools = this.tools;
468
+ return context;
469
+ }
470
+ setTools(tools) {
471
+ this.tools = tools;
472
+ }
473
+ setToolbar(toolbar) {
474
+ this.toolbar = toolbar;
475
+ }
476
+ handleContextMessage(context) {
477
+ if (this.context$.value && context.uri && this.context$.value.uri !== context.uri) {
478
+ this.messageService.removeAllAreNotError();
479
+ }
480
+ context.messages = context.messages ? context.messages : [];
481
+ context.messages.push(context.message);
482
+ context.messages.map(message => {
483
+ if (message) {
484
+ this.messageService.message(message);
485
+ }
486
+ });
487
+ }
488
+ getContextByUri(uri) {
489
+ if (this.baseUrl) {
490
+ let contextToLoad;
491
+ for (const key of Object.keys(this.contexts$.value)) {
492
+ contextToLoad = this.contexts$.value[key].find((c) => {
493
+ return c.uri === uri;
494
+ });
495
+ if (contextToLoad) {
496
+ break;
497
+ }
498
+ }
499
+ if (contextToLoad && contextToLoad.imported) {
500
+ return of(contextToLoad);
501
+ }
502
+ // TODO : use always id or uri
503
+ const id = contextToLoad ? contextToLoad.id : uri;
504
+ return this.getDetails(id);
505
+ }
506
+ const importedContext = this.contexts$.value.ours.find((currentContext) => {
507
+ return currentContext.uri === uri && currentContext.imported === true;
508
+ });
509
+ if (importedContext) {
510
+ return of(importedContext);
511
+ }
512
+ else {
513
+ return this.getLocalContext(uri);
514
+ }
515
+ }
516
+ getContextLayers(igoMap) {
517
+ const layers = [];
518
+ const mapLayers = igoMap.layers$.getValue();
519
+ mapLayers.forEach((layer) => {
520
+ if (!layer.baseLayer && layer.options.id !== 'searchPointerSummaryId') {
521
+ layers.push(layer);
522
+ }
523
+ });
524
+ return layers;
525
+ }
526
+ readParamsFromRoute() {
527
+ if (!this.route) {
528
+ return;
529
+ }
530
+ this.route.queryParams.subscribe((params) => {
531
+ const centerKey = this.route.options.centerKey;
532
+ if (centerKey && params[centerKey]) {
533
+ const centerParams = params[centerKey];
534
+ this.mapViewFromRoute.center = centerParams.split(',').map(Number);
535
+ }
536
+ const projectionKey = this.route.options.projectionKey;
537
+ if (projectionKey && params[projectionKey]) {
538
+ const projectionParam = params[projectionKey];
539
+ this.mapViewFromRoute.projection = projectionParam;
540
+ }
541
+ const zoomKey = this.route.options.zoomKey;
542
+ if (zoomKey && params[zoomKey]) {
543
+ const zoomParam = params[zoomKey];
544
+ this.mapViewFromRoute.zoom = Number(zoomParam);
545
+ }
546
+ });
547
+ }
548
+ getPath(file) {
549
+ const basePath = this.options.basePath.replace(/\/$/, '');
550
+ return `${basePath}/${file}`;
551
+ }
552
+ handleError(error, uri, permissionError) {
553
+ const context = this.contexts$.value.ours.find((obj) => obj.uri === uri);
554
+ const titleContext = context ? context.title : uri;
555
+ error.error.title = this.languageService.translate.instant('igo.context.contextManager.invalid.title');
556
+ error.error.message = this.languageService.translate.instant('igo.context.contextManager.invalid.text', { value: titleContext });
557
+ error.error.toDisplay = true;
558
+ if (permissionError) {
559
+ error.error.title = this.languageService.translate.instant('igo.context.contextManager.errors.addPermissionTitle');
560
+ error.error.message = this.languageService.translate.instant('igo.context.contextManager.errors.addPermission');
561
+ }
562
+ this.messageService.error('igo.context.contextManager.errors.addPermission', 'igo.context.contextManager.errors.addPermissionTitle');
563
+ }
564
+ handleContextsChange(keepCurrentContext = true) {
565
+ const context = this.context$.value;
566
+ const editedContext = this.editedContext$.value;
567
+ if (!context || context.uri === this.options.defaultContextUri) {
568
+ keepCurrentContext = false;
569
+ }
570
+ if (!keepCurrentContext || !this.findContext(context)) {
571
+ this.defaultContextUri = undefined;
572
+ this.loadDefaultContext();
573
+ }
574
+ else {
575
+ this.getContextByUri(context.uri)
576
+ .pipe(first())
577
+ .subscribe((newContext) => {
578
+ this.toolsChanged$.next(newContext);
579
+ });
580
+ if (this.baseUrl && this.authService.authenticated) {
581
+ this.getDefault().subscribe();
582
+ }
583
+ }
584
+ const editedFound = this.findContext(editedContext);
585
+ if (!editedFound || editedFound.permission !== 'write') {
586
+ this.setEditedContext(undefined);
587
+ }
588
+ }
589
+ addContextToList(context) {
590
+ const contextFound = this.findContext(context);
591
+ if (!contextFound) {
592
+ const contextSimplifie = {
593
+ id: context.id,
594
+ uri: context.uri,
595
+ title: context.title,
596
+ scope: context.scope,
597
+ permission: TypePermission[TypePermission.read]
598
+ };
599
+ if (this.contexts$.value && this.contexts$.value.public) {
600
+ this.contexts$.value.public.push(contextSimplifie);
601
+ this.contexts$.next(this.contexts$.value);
602
+ }
603
+ }
604
+ }
605
+ findContext(context) {
606
+ if (!context) {
607
+ return false;
608
+ }
609
+ const contexts = this.contexts$.value;
610
+ let found;
611
+ for (const key of Object.keys(contexts)) {
612
+ const value = contexts[key];
613
+ found = value.find((c) => (context.id && c.id === context.id) ||
614
+ (context.uri && c.uri === context.uri));
615
+ if (found) {
616
+ break;
617
+ }
618
+ }
619
+ return found;
620
+ }
621
+ }
622
+ ContextService.ɵfac = function ContextService_Factory(t) { return new (t || ContextService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(i2.AuthService), i0.ɵɵinject(i3.LanguageService), i0.ɵɵinject(i3.ConfigService), i0.ɵɵinject(i3.MessageService), i0.ɵɵinject(i3.StorageService), i0.ɵɵinject(i4.ExportService), i0.ɵɵinject(i3.RouteService, 8)); };
623
+ ContextService.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: ContextService, factory: ContextService.ɵfac, providedIn: 'root' });
624
+ (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ContextService, [{
625
+ type: Injectable,
626
+ args: [{
627
+ providedIn: 'root'
628
+ }]
629
+ }], function () { return [{ type: i1.HttpClient }, { type: i2.AuthService }, { type: i3.LanguageService }, { type: i3.ConfigService }, { type: i3.MessageService }, { type: i3.StorageService }, { type: i4.ExportService }, { type: i3.RouteService, decorators: [{
630
+ type: Optional
631
+ }] }]; }, null); })();
632
632
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29udGV4dC9zcmMvbGliL2NvbnRleHQtbWFuYWdlci9zaGFyZWQvY29udGV4dC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3JELE9BQU8sRUFBRSxlQUFlLEVBQWMsRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoRSxPQUFPLEVBQ0wsR0FBRyxFQUNILEdBQUcsRUFDSCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFFBQVEsRUFDUixLQUFLLEVBQ0wsSUFBSSxFQUNMLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3BDLE9BQU8sT0FBTyxNQUFNLG1CQUFtQixDQUFDO0FBQ3hDLE9BQU8sT0FBTyxNQUFNLG1CQUFtQixDQUFDO0FBQ3hDLE9BQU8sY0FBYyxNQUFNLGtCQUFrQixDQUFDO0FBRzlDLE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBY2hELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7O0FBY2hELE1BQU0sT0FBTyxjQUFjO0lBd0J6QixZQUNVLElBQWdCLEVBQ2hCLFdBQXdCLEVBQ3hCLGVBQWdDLEVBQ2hDLE1BQXFCLEVBQ3JCLGNBQThCLEVBQzlCLGNBQThCLEVBQzlCLGFBQTRCLEVBQ2hCLEtBQW1CO1FBUC9CLFNBQUksR0FBSixJQUFJLENBQVk7UUFDaEIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLFdBQU0sR0FBTixNQUFNLENBQWU7UUFDckIsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLG1CQUFjLEdBQWQsY0FB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Q3pDLENBQUM7WUFDRixJQUFJLEtBQUssRUFBRTtnQkFDVCxNQUFNO2FBQ1A7U0FDRjtRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQzs7NEVBaHdCVSxjQUFjO29FQUFkLGNBQWMsV0FBZCxjQUFjLG1CQUZiLE1BQU07dUZBRVAsY0FBYztjQUgxQixVQUFVO2VBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7O3NCQWlDSSxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgT3B0aW9uYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBFcnJvclJlc3BvbnNlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuXG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIG9mLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBtYXAsXG4gIHRhcCxcbiAgY2F0Y2hFcnJvcixcbiAgZGVib3VuY2VUaW1lLFxuICBtZXJnZU1hcCxcbiAgZmlyc3QsXG4gIHNraXBcbn0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgb2xQb2ludCBmcm9tICdvbC9nZW9tL1BvaW50JztcbmltcG9ydCBHZW9KU09OIGZyb20gJ29sL2Zvcm1hdC9HZW9KU09OJztcbmltcG9ydCBDbHVzdGVyIGZyb20gJ29sL3NvdXJjZS9DbHVzdGVyJztcbmltcG9ydCBvbFZlY3RvclNvdXJjZSBmcm9tICdvbC9zb3VyY2UvVmVjdG9yJztcblxuaW1wb3J0IHsgVG9vbCB9IGZyb20gJ0BpZ28yL2NvbW1vbic7XG5pbXBvcnQgeyB1dWlkLCBPYmplY3RVdGlscyB9IGZyb20gJ0BpZ28yL3V0aWxzJztcbmltcG9ydCB7XG4gIENvbmZpZ1NlcnZpY2UsXG4gIFJvdXRlU2VydmljZSxcbiAgTWVzc2FnZSxcbiAgTWVzc2FnZVNlcnZpY2UsXG4gIExhbmd1YWdlU2VydmljZSxcbiAgU3RvcmFnZVNlcnZpY2Vcbn0gZnJvbSAnQGlnbzIvY29yZSc7XG5cbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnQGlnbzIvYXV0aCc7XG5pbXBvcnQgdHlwZSB7IElnb01hcCwgTGF5ZXIsIExheWVyT3B0aW9ucyB9IGZyb20gJ0BpZ28yL2dlbyc7XG5pbXBvcnQgeyBFeHBvcnRTZXJ2aWNlIH0gZnJvbSAnQGlnbzIvZ2VvJztcblxuaW1wb3J0IHsgVHlwZVBlcm1pc3Npb24gfSBmcm9tICcuL2NvbnRleHQuZW51bSc7XG5pbXBvcnQge1xuICBDb250ZXh0c0xpc3QsXG4gIENvbnRleHRTZXJ2aWNlT3B0aW9ucyxcbiAgQ29udGV4dCxcbiAgRGV0YWlsZWRDb250ZXh0LFxuICBDb250ZXh0TWFwVmlldyxcbiAgQ29udGV4dFBlcm1pc3Npb24sXG4gIENvbnRleHRQcm9maWxzXG59IGZyb20gJy4vY29udGV4dC5pbnRlcmZhY2UnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBDb250ZXh0U2VydmljZSB7XG4gIHB1YmxpYyBjb250ZXh0JCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGV0YWlsZWRDb250ZXh0Pih1bmRlZmluZWQpO1xuICBwdWJsaWMgY29udGV4dHMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDb250ZXh0c0xpc3Q+KHsgb3VyczogW10gfSk7XG4gIHB1YmxpYyBkZWZhdWx0Q29udGV4dElkJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPih1bmRlZmluZWQpO1xuICBwdWJsaWMgZWRpdGVkQ29udGV4dCQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PERldGFpbGVkQ29udGV4dD4odW5kZWZpbmVkKTtcbiAgcHVibGljIGltcG9ydGVkQ29udGV4dDogQXJyYXk8RGV0YWlsZWRDb250ZXh0PiA9IFtdO1xuICBwdWJsaWMgdG9vbHNDaGFuZ2VkJCA9IG5ldyBTdWJqZWN0PERldGFpbGVkQ29udGV4dD4oKTtcbiAgcHJpdmF0ZSBtYXBWaWV3RnJvbVJvdXRlOiBDb250ZXh0TWFwVmlldyA9IHt9O1xuICBwcml2YXRlIG9wdGlvbnM6IENvbnRleHRTZXJ2aWNlT3B0aW9ucztcbiAgcHJpdmF0ZSBiYXNlVXJsOiBzdHJpbmc7XG5cbiAgLy8gVW50aWwgdGhlIENvbnRleHRTZXJ2aWNlIGlzIGNvbXBsZXRlbHkgcmVmYWN0b3JlZCwgdGhpcyBpcyBuZWVkZWRcbiAgLy8gdG8gdHJhY2sgdGhlIGN1cnJlbnQgdG9vbHNcbiAgcHJpdmF0ZSB0b29sczogVG9vbFtdO1xuICBwcml2YXRlIHRvb2xiYXI6IHN0cmluZ1tdO1xuXG4gIGdldCBkZWZhdWx0Q29udGV4dFVyaSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnN0b3JhZ2VTZXJ2aWNlLmdldCgnZmF2b3JpdGUuY29udGV4dC51cmknKSBhcyBzdHJpbmcgfHwgdGhpcy5fZGVmYXVsdENvbnRleHRVcmkgfHwgdGhpcy5vcHRpb25zLmRlZmF1bHRDb250ZXh0VXJpO1xuICB9XG4gIHNldCBkZWZhdWx0Q29udGV4dFVyaSh1cmk6IHN0cmluZykge1xuICAgIHRoaXMuX2RlZmF1bHRDb250ZXh0VXJpID0gdXJpO1xuICB9XG4gIHByaXZhdGUgX2RlZmF1bHRDb250ZXh0VXJpOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxuICAgIHByaXZhdGUgYXV0aFNlcnZpY2U6IEF1dGhTZXJ2aWNlLFxuICAgIHByaXZhdGUgbGFuZ3VhZ2VTZXJ2aWNlOiBMYW5ndWFnZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBjb25maWc6IENvbmZpZ1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBtZXNzYWdlU2VydmljZTogTWVzc2FnZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBzdG9yYWdlU2VydmljZTogU3RvcmFnZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBleHBvcnRTZXJ2aWNlOiBFeHBvcnRTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgcm91dGU6IFJvdXRlU2VydmljZVxuICApIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKFxuICAgICAge1xuICAgICAgICBiYXNlUGF0aDogJ2NvbnRleHRzJyxcbiAgICAgICAgY29udGV4dExpc3RGaWxlOiAnX2NvbnRleHRzLmpzb24nLFxuICAgICAgICBkZWZhdWx0Q29udGV4dFVyaTogJ19kZWZhdWx0J1xuICAgICAgfSxcbiAgICAgIHRoaXMuY29uZmlnLmdldENvbmZpZygnY29udGV4dCcpXG4gICAgKTtcblxuICAgIHRoaXMuYmFzZVVybCA9IHRoaXMub3B0aW9ucy51cmw7XG5cbiAgICB0aGlzLnJlYWRQYXJhbXNGcm9tUm91dGUoKTtcblxuICAgIGlmICh0aGlzLmF1dGhTZXJ2aWNlLmhhc0F1dGhTZXJ2aWNlKSB7XG4gICAgICB0aGlzLmF1dGhTZXJ2aWNlLmxvZ2dlZCQuc3Vic2NyaWJlKChsb2dnZWQpID0+IHtcbiAgICAgICAgaWYgKGxvZ2dlZCkge1xuICAgICAgICAgIHRoaXMuY29udGV4dHMkLnBpcGUoc2tpcCgxKSwgZmlyc3QoKSkuc3Vic2NyaWJlKChjKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUNvbnRleHRzQ2hhbmdlKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy5sb2FkQ29udGV4dHMoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9hZENvbnRleHRzKCk7XG4gICAgICB0aGlzLmhhbmRsZUNvbnRleHRzQ2hhbmdlKGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBnZXQocGVybWlzc2lvbnM/OiBzdHJpbmdbXSwgaGlkZGVuPzogYm9vbGVhbik6IE9ic2VydmFibGU8Q29udGV4dHNMaXN0PiB7XG4gICAgbGV0IHVybCA9IHRoaXMuYmFzZVVybCArICcvY29udGV4dHMnO1xuICAgIGlmIChwZXJtaXNzaW9ucyAmJiB0aGlzLmF1dGhTZXJ2aWNlLmF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgIHVybCArPSAnP3Blcm1pc3Npb249JyArIHBlcm1pc3Npb25zLmpvaW4oKTtcbiAgICAgIGlmIChoaWRkZW4pIHtcbiAgICAgICAgdXJsICs9ICcmaGlkZGVuPXRydWUnO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5odHRwLmdldDxDb250ZXh0c0xpc3Q+KHVybCk7XG4gIH1cblxuICBnZXRCeUlkKGlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPENvbnRleHQ+IHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmJhc2VVcmwgKyAnL2NvbnRleHRzLycgKyBpZDtcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldDxDb250ZXh0Pih1cmwpO1xuICB9XG5cbiAgZ2V0RGV0YWlscyhpZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxEZXRhaWxlZENvbnRleHQ+IHtcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmJhc2VVcmx9L2NvbnRleHRzLyR7aWR9L2RldGFpbHNgO1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PERldGFpbGVkQ29udGV4dD4odXJsKS5waXBlKFxuICAgICAgY2F0Y2hFcnJvcigocmVzKSA9PiB7XG4gICAgICAgIHRoaXMuaGFuZGxlRXJyb3IocmVzLCBpZCk7XG4gICAgICAgIHRocm93IHJlcztcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGdldERlZmF1bHQoKTogT2JzZXJ2YWJsZTxEZXRhaWxlZENvbnRleHQ+IHtcbiAgICBpZiAodGhpcy5hdXRoU2VydmljZS5hdXRoZW50aWNhdGVkKSB7XG4gICAgICBjb25zdCB1cmwgPSB0aGlzLmJhc2VVcmwgKyAnL2NvbnRleHRzL2RlZmF1bHQnO1xuICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8RGV0YWlsZWRDb250ZXh0Pih1cmwpLnBpcGUoXG4gICAgICAgIHRhcCgoY29udGV4dCkgPT4ge1xuICAgICAgICAgIHRoaXMuZGVmYXVsdENvbnRleHRJZCQubmV4dChjb250ZXh0LmlkKTtcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHVyaSA9IHRoaXMuc3RvcmFnZVNlcnZpY2UuZ2V0KCdmYXZvcml0ZS5jb250ZXh0LnVyaScpIGFzIHN0cmluZztcbiAgICAgIHRoaXMuZGVmYXVsdENvbnRleHRJZCQubmV4dCh1cmkpO1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0Q29udGV4dEJ5VXJpKHVyaSk7XG4gICAgfVxuXG4gIH1cblxuICBnZXRQcm9maWxCeVVzZXIoKTogT2JzZXJ2YWJsZTxDb250ZXh0UHJvZmlsc1tdPiB7XG4gICAgaWYgKHRoaXMuYmFzZVVybCkge1xuICAgICAgY29uc3QgdXJsID0gdGhpcy5iYXNlVXJsICsgJy9wcm9maWxzPyc7XG4gICAgICByZXR1cm4gdGhpcy5odHRwLmdldDxDb250ZXh0UHJvZmlsc1tdPih1cmwpO1xuICAgIH1cbiAgICByZXR1cm4gb2YoW10pO1xuICB9XG5cbiAgc2V0RGVmYXVsdChpZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICBpZiAodGhpcy5hdXRoU2VydmljZS5hdXRoZW50aWNhdGVkKSB7XG4gICAgICBjb25zdCB1cmwgPSB0aGlzLmJhc2VVcmwgKyAnL2NvbnRleHRzL2RlZmF1bHQnO1xuICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KHVybCwgeyBkZWZhdWx0Q29udGV4dElkOiBpZCB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zdG9yYWdlU2VydmljZS5zZXQoJ2Zhdm9yaXRlLmNvbnRleHQudXJpJywgaWQpO1xuICAgICAgcmV0dXJuIG9mKHVuZGVmaW5lZCk7XG4gICAgfVxuICB9XG5cbiAgaGlkZUNvbnRleHQoaWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHVybCA9IHRoaXMuYmFzZVVybCArICcvY29udGV4dHMvJyArIGlkICsgJy9oaWRlJztcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QodXJsLCB7fSk7XG4gIH1cblxuICBzaG93Q29udGV4dChpZDogc3RyaW5nKSB7XG4gICAgY29uc3QgdXJsID0gdGhpcy5iYXNlVXJsICsgJy9jb250ZXh0cy8nICsgaWQgKyAnL3Nob3cnO1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdCh1cmwsIHt9KTtcbiAgfVxuXG4gIGRlbGV0ZShpZDogc3RyaW5nLCBpbXBvcnRlZCA9IGZhbHNlKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgY29uc3QgY29udGV4dHM6IENvbnRleHRzTGlzdCA9IHsgb3VyczogW10gfTtcbiAgICBPYmplY3Qua2V5cyh0aGlzLmNvbnRleHRzJC52YWx1ZSkuZm9yRWFjaChcbiAgICAgIChrZXkpID0+XG4gICAgICAgIChjb250ZXh0c1trZXldID0gdGhpcy5jb250ZXh0cyQudmFsdWVba2V5XS5maWx0ZXIoKGMpID0+IGMuaWQgIT09IGlkKSlcbiAgICApO1xuXG4gICAgaWYgKGltcG9ydGVkKSB7XG4gICAgICB0aGlzLmltcG9ydGVkQ29udGV4dCA9IHRoaXMuaW1wb3J0ZWRDb250ZXh0LmZpbHRlcigoYykgPT4gYy5pZCAhPT0gaWQpO1xuICAgICAgcmV0dXJuIG9mKHRoaXMuY29udGV4dHMkLm5leHQoY29udGV4dHMpKTtcbiAgICB9XG5cbiAgICBjb25zdCB1cmwgPSB0aGlzLmJhc2VVcmwgKyAnL2NvbnRleHRzLycgKyBpZDtcbiAgICByZXR1cm4gdGhpcy5odHRwLmRlbGV0ZTx2b2lkPih1cmwpLnBpcGUoXG4gICAgICB0YXAoKHJlcykgPT4ge1xuICAgICAgICB0aGlzLmNvbnRleHRzJC5uZXh0KGNvbnRleHRzKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGNyZWF0ZShjb250ZXh0OiBEZXRhaWxlZENvbnRleHQpOiBPYnNlcnZhYmxlPENvbnRleHQ+IHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmJhc2VVcmwgKyAnL2NvbnRleHRzJztcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8Q29udGV4dD4odXJsLCBjb250ZXh0KS5waXBlKFxuICAgICAgbWFwKChjb250ZXh0Q3JlYXRlZCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5hdXRoU2VydmljZS5hdXRoZW50aWNhdGVkKSB7XG4gICAgICAgICAgY29udGV4dENyZWF0ZWQucGVybWlzc2lvbiA9IFR5cGVQZXJtaXNzaW9uW1R5cGVQZXJtaXNzaW9uLndyaXRlXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb250ZXh0Q3JlYXRlZC5wZXJtaXNzaW9uID0gVHlwZVBlcm1pc3Npb25bVHlwZVBlcm1pc3Npb24ucmVhZF07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb250ZXh0cyQudmFsdWUub3Vycy51bnNoaWZ0KGNvbnRleHRDcmVhdGVkKTtcbiAgICAgICAgdGhpcy5jb250ZXh0cyQubmV4dCh0aGlzLmNvbnRleHRzJC52YWx1ZSk7XG4gICAgICAgIHJldHVybiBjb250ZXh0Q3JlYXRlZDtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGNsb25lKGlkOiBzdHJpbmcsIHByb3BlcnRpZXMgPSB7fSk6IE9ic2VydmFibGU8Q29udGV4dD4ge1xuICAgIGNvbnN0IHVybCA9IHRoaXMuYmFzZVVybCArICcvY29udGV4dHMvJyArIGlkICsgJy9jbG9uZSc7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PENvbnRleHQ+KHVybCwgcHJvcGVydGllcykucGlwZShcbiAgICAgIG1hcCgoY29udGV4dENsb25lZCkgPT4ge1xuICAgICAgICBjb250ZXh0Q2xvbmVkLnBlcm1pc3Npb24gPSBUeXBlUGVybWlzc2lvbltUeXBlUGVybWlzc2lvbi53cml0ZV07XG4gICAgICAgIHRoaXMuY29udGV4dHMkLnZhbHVlLm91cnMudW5zaGlmdChjb250ZXh0Q2xvbmVkKTtcbiAgICAgICAgdGhpcy5jb250ZXh0cyQubmV4dCh0aGlzLmNvbnRleHRzJC52YWx1ZSk7XG4gICAgICAgIHJldHVybiBjb250ZXh0Q2xvbmVkO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgdXBkYXRlKGlkOiBzdHJpbmcsIGNvbnRleHQ6IENvbnRleHQpOiBPYnNlcnZhYmxlPENvbnRleHQ+IHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmJhc2VVcmwgKyAnL2NvbnRleHRzLycgKyBpZDtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBhdGNoPENvbnRleHQ+KHVybCwgY29udGV4dCk7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGFkZFRvb2xBc3NvY2lhdGlvbihjb250ZXh0SWQ6IHN0cmluZywgdG9vbElkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmJhc2VVcmx9L2NvbnRleHRzLyR7Y29udGV4dElkfS90b29sc2A7XG4gICAgY29uc3QgYXNzb2NpYXRpb24gPSB7XG4gICAgICB0b29sSWRcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDx2b2lkPih1cmwsIGFzc29jaWF0aW9uKTtcbiAgfVxuXG4gIGRlbGV0ZVRvb2xBc3NvY2lhdGlvbihjb250ZXh0SWQ6IHN0cmluZywgdG9vbElkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuYmFzZVVybH0vY29udGV4dHMvJHtjb250ZXh0SWR9L3Rvb2xzLyR7dG9vbElkfWA7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5kZWxldGUodXJsKTtcbiAgfVxuXG4gIGdldFBlcm1pc3Npb25zKGlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPENvbnRleHRQZXJtaXNzaW9uW10+IHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmJhc2VVcmwgKyAnL2NvbnRleHRzLycgKyBpZCArICcvcGVybWlzc2lvbnMnO1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PENvbnRleHRQZXJtaXNzaW9uW10+KHVybCk7XG4gIH1cblxuICBhZGRQZXJtaXNzaW9uQXNzb2NpYXRpb24oXG4gICAgY29udGV4dElkOiBzdHJpbmcsXG4gICAgcHJvZmlsOiBzdHJpbmcsXG4gICAgdHlwZTogVHlwZVBlcm1pc3Npb25cbiAgKTogT2JzZXJ2YWJsZTxDb250ZXh0UGVybWlzc2lvbltdPiB7XG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5iYXNlVXJsfS9jb250ZXh0cy8ke2NvbnRleHRJZH0vcGVybWlzc2lvbnNgO1xuICAgIGNvbnN0IGFzc29jaWF0aW9uID0ge1xuICAgICAgcHJvZmlsLFxuICAgICAgdHlwZVBlcm1pc3Npb246IHR5cGVcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PENvbnRleHRQZXJtaXNzaW9uW10+KHVybCwgYXNzb2NpYXRpb24pLnBpcGUoXG4gICAgICBjYXRjaEVycm9yKChyZXMpID0+IHtcbiAgICAgICAgdGhpcy5oYW5kbGVFcnJvcihyZXMsIHVuZGVmaW5lZCwgdHJ1ZSk7XG4gICAgICAgIHRocm93IFtyZXNdOyAvLyBUT0RPIE5vdCBzdXJlIGFib3V0IHRoaXMuXG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBkZWxldGVQZXJtaXNzaW9uQXNzb2NpYXRpb24oXG4gICAgY29udGV4dElkOiBzdHJpbmcsXG4gICAgcGVybWlzc2lvbklkOiBzdHJpbmdcbiAgKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5iYXNlVXJsfS9jb250ZXh0cy8ke2NvbnRleHRJZH0vcGVybWlzc2lvbnMvJHtwZXJtaXNzaW9uSWR9YDtcbiAgICByZXR1cm4gdGhpcy5odHRwLmRlbGV0ZTx2b2lkPih1cmwpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGdldExvY2FsQ29udGV4dHMoKTogT2JzZXJ2YWJsZTxDb250ZXh0c0xpc3Q+IHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmdldFBhdGgodGhpcy5vcHRpb25zLmNvbnRleHRMaXN0RmlsZSk7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8Q29udGV4dHNMaXN0Pih1cmwpLnBpcGUoXG4gICAgICBtYXAoKHJlczogYW55KSA9PiB7XG4gICAgICAgIHJldHVybiB7IG91cnM6IHJlcyB9O1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgZ2V0TG9jYWxDb250ZXh0KHVyaTogc3RyaW5nKTogT2JzZXJ2YWJsZTxEZXRhaWxlZENvbnRleHQ+IHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmdldFBhdGgoYCR7dXJpfS5qc29uYCk7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8RGV0YWlsZWRDb250ZXh0Pih1cmwpLnBpcGUoXG4gICAgICBtZXJnZU1hcCgocmVzKSA9PiB7XG4gICAgICAgIGlmICghcmVzLmJhc2UpIHtcbiAgICAgICAgICByZXR1cm4gb2YocmVzKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1cmxCYXNlID0gdGhpcy5nZXRQYXRoKGAke3Jlcy5iYXNlfS5qc29uYCk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PERldGFpbGVkQ29udGV4dD4odXJsQmFzZSkucGlwZShcbiAgICAgICAgICBtYXAoKHJlc0Jhc2U6IERldGFpbGVkQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzTWVyZ2UgPSByZXM7XG4gICAgICAgICAgICByZXNNZXJnZS5tYXAgPSBPYmplY3RVdGlscy5tZXJnZURlZXAocmVzQmFzZS5tYXAsIHJlcy5tYXApO1xuICAgICAgICAgICAgcmVzTWVyZ2UubGF5ZXJzID0gKHJlc0Jhc2UubGF5ZXJzIHx8IFtdKVxuICAgICAgICAgICAgICAuY29uY2F0KHJlcy5sYXllcnMgfHwgW10pXG4gICAgICAgICAgICAgIC5yZXZlcnNlKClcbiAgICAgICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgICAgICAobCwgaW5kZXgsIHNlbGYpID0+XG4gICAgICAgICAgICAgICAgICAhbC5pZCB8fCBzZWxmLmZpbmRJbmRleCgobDIpID0+IGwyLmlkID09PSBsLmlkKSA9PT0gaW5kZXhcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAucmV2ZXJzZSgpO1xuICAgICAgICAgICAgcmVzTWVyZ2UudG9vbGJhciA9IHJlcy50b29sYmFyIHx8IHJlc0Jhc2UudG9vbGJhcjtcbiAgICAgICAgICAgIHJlc01lcmdlLm1lc3NhZ2UgPSByZXMubWVzc2FnZSB8fCByZXNCYXNlLm1lc3NhZ2U7XG4gICAgICAgICAgICByZXNNZXJnZS5tZXNzYWdlcyA9IHJlcy5tZXNzYWdlcyB8fCByZXNCYXNlLm1lc3NhZ2VzO1xuICAgICAgICAgICAgcmVzTWVyZ2UudG9vbHMgPSAocmVzLnRvb2xzIHx8IFtdKVxuICAgICAgICAgICAgICAuY29uY2F0KHJlc0Jhc2UudG9vbHMgfHwgW10pXG4gICAgICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAgICAgKHQsIGluZGV4LCBzZWxmKSA9PlxuICAgICAgICAgICAgICAgICAgc2VsZi5maW5kSW5kZXgoKHQyKSA9PiB0Mi5uYW1lID09PSB0Lm5hbWUpID09PSBpbmRleFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIHJlc01lcmdlO1xuICAgICAgICAgIH0pLFxuICAgICAgICAgIGNhdGNoRXJyb3IoKGVycikgPT4ge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVFcnJvcihlcnIsIHVyaSk7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pLFxuICAgICAgY2F0Y2hFcnJvcigoZXJyMikgPT4ge1xuICAgICAgICB0aGlzLmhhbmRsZUVycm9yKGVycjIsIHVyaSk7XG4gICAgICAgIHRocm93IGVycjI7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBsb2FkQ29udGV4dHMocGVybWlzc2lvbnM/OiBzdHJpbmdbXSwgaGlkZGVuPzogYm9vbGVhbikge1xuICAgIGxldCByZXF1ZXN0O1xuICAgIGlmICh0aGlzLmJhc2VVcmwpIHtcbiAgICAgIHJlcXVlc3QgPSB0aGlzLmdldChwZXJtaXNzaW9ucywgaGlkZGVuKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVxdWVzdCA9IHRoaXMuZ2V0TG9jYWxDb250ZXh0cygpO1xuICAgIH1cbiAgICByZXF1ZXN0LnN1YnNjcmliZSgoY29udGV4dHMpID0+IHtcbiAgICAgIGNvbnRleHRzLm91cnMgPSB0aGlzLmltcG9ydGVkQ29udGV4dC5jb25jYXQoY29udGV4dHMub3Vycyk7XG4gICAgICB0aGlzLmNvbnRleHRzJC5uZXh0KGNvbnRleHRzKTtcbiAgICB9KTtcbiAgfVxuXG4gIGxvYWREZWZhdWx0Q29udGV4dCgpIHtcbiAgICBjb25zdCBsb2FkRmN0ID0gKGRpcmVjdCA9IGZhbHNlKSA9PiB7XG4gICAgICBpZiAoIWRpcmVjdCAmJiB0aGlzLmJhc2VVcmwgJiYgdGhpcy5hdXRoU2VydmljZS5hdXRoZW50aWNhdGVkKSB7XG4gICAgICAgIHRoaXMuZ2V0RGVmYXVsdCgpLnN1YnNjcmliZShcbiAgICAgICAgICAoX2NvbnRleHQ6IERldGFpbGVkQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29udGV4dFVyaSA9IF9jb250ZXh0LnVyaTtcbiAgICAgICAgICAgIHRoaXMuYWRkQ29udGV4dFRvTGlzdChfY29udGV4dCk7XG4gICAgICAgICAgICB0aGlzLnNldENvbnRleHQoX2NvbnRleHQpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29udGV4dElkJC5uZXh0KHVuZGVmaW5lZCk7XG4gICAgICAgICAgICB0aGlzLmxvYWRDb250ZXh0KHRoaXMuZGVmYXVsdENvbnRleHRVcmkpO1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubG9hZENvbnRleHQodGhpcy5kZWZhdWx0Q29udGV4dFVyaSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmICh0aGlzLnJvdXRlICYmIHRoaXMucm91dGUub3B0aW9ucy5jb250ZXh0S2V5KSB7XG4gICAgICB0aGlzLnJvdXRlLnF1ZXJ5UGFyYW1zLnBpcGUoZGVib3VuY2VUaW1lKDEwMCkpLnN1YnNjcmliZSgocGFyYW1zKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRQYXJhbSA9IHBhcmFtc1t0aGlzLnJvdXRlLm9wdGlvbnMuY29udGV4dEtleSBhcyBzdHJpbmddO1xuICAgICAgICBsZXQgZGlyZWN0ID0gZmFsc2U7XG4gICAgICAgIGlmIChjb250ZXh0UGFyYW0pIHtcbiAgICAgICAgICB0aGlzLmRlZmF1bHRDb250ZXh0VXJpID0gY29udGV4dFBhcmFtO1xuICAgICAgICAgIGRpcmVjdCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgbG9hZEZjdChkaXJlY3QpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvYWRGY3QoKTtcbiAgICB9XG4gIH1cblxuICBsb2FkQ29udGV4dCh1cmk6IHN0cmluZykge1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmNvbnRleHQkLnZhbHVlO1xuXG4gICAgaWYgKGNvbnRleHQgJiYgY29udGV4dC51cmkgPT09IHVyaSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZ2V0Q29udGV4dEJ5VXJpKHVyaSlcbiAgICAgIC5waXBlKGZpcnN0KCkpXG4gICAgICAuc3Vic2NyaWJlKFxuICAgICAgICAoX2NvbnRleHQ6IERldGFpbGVkQ29udGV4dCkgPT4ge1xuICAgICAgICAgIHRoaXMuYWRkQ29udGV4dFRvTGlzdChfY29udGV4dCk7XG4gICAgICAgICAgdGhpcy5zZXRDb250ZXh0KF9jb250ZXh0KTtcbiAgICAgICAgfSxcbiAgICAgICAgKGVycikgPT4ge1xuICAgICAgICAgIGlmICh1cmkgIT09IHRoaXMub3B0aW9ucy5kZWZhdWx0Q29udGV4dFVyaSkge1xuICAgICAgICAgICAgdGhpcy5sb2FkQ29udGV4dCh0aGlzLm9wdGlvbnMuZGVmYXVsdENvbnRleHRVcmkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgfVxuXG4gIHNldENvbnRleHQoY29udGV4dDogRGV0YWlsZWRDb250ZXh0KSB7XG4gICAgdGhpcy5oYW5kbGVDb250ZXh0TWVzc2FnZShjb250ZXh0KTtcbiAgICBjb25zdCBjdXJyZW50Q29udGV4dCA9IHRoaXMuY29udGV4dCQudmFsdWU7XG4gICAgaWYgKGN1cnJlbnRDb250ZXh0ICYmIGNvbnRleHQgJiYgY29udGV4dC5pZCA9PT0gY3VycmVudENvbnRleHQuaWQpIHtcbiAgICAgIGlmIChjb250ZXh0Lm1hcC52aWV3LmtlZXBDdXJyZW50VmlldyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnRleHQubWFwLnZpZXcua2VlcEN1cnJlbnRWaWV3ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY29udGV4dCQubmV4dChjb250ZXh0KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWNvbnRleHQubWFwKSB7XG4gICAgICBjb250ZXh0Lm1hcCA9IHsgdmlldzoge30gfTtcbiAgICB9XG5cbiAgICBPYmplY3QuYXNzaWduKGNvbnRleHQubWFwLnZpZXcsIHRoaXMubWFwVmlld0Zyb21Sb3V0ZSk7XG5cbiAgICB0aGlzLmNvbnRleHQkLm5leHQoY29udGV4dCk7XG4gIH1cblxuICBsb2FkRWRpdGVkQ29udGV4dCh1cmk6IHN0cmluZykge1xuICAgIHRoaXMuZ2V0Q29udGV4dEJ5VXJpKHVyaSkuc3Vic2NyaWJlKChfY29udGV4dDogRGV0YWlsZWRDb250ZXh0KSA9PiB7XG4gICAgICB0aGlzLnNldEVkaXRlZENvbnRleHQoX2NvbnRleHQpO1xuICAgIH0pO1xuICB9XG5cbiAgc2V0RWRpdGVkQ29udGV4dChjb250ZXh0OiBEZXRhaWxlZENvbnRleHQpIHtcbiAgICB0aGlzLmVkaXRlZENvbnRleHQkLm5leHQoY29udGV4dCk7XG4gIH1cblxuICBnZXRDb250ZXh0RnJvbU1hcChpZ29NYXA6IElnb01hcCwgZW1wdHk/OiBib29sZWFuKTogRGV0YWlsZWRDb250ZXh0IHtcbiAgICBjb25zdCB2aWV3ID0gaWdvTWFwLm9sLmdldFZpZXcoKTtcbiAgICBjb25zdCBwcm9qID0gdmlldy5nZXRQcm9qZWN0aW9uKCkuZ2V0Q29kZSgpO1xuICAgIGNvbnN0IGNlbnRlcjogYW55ID0gbmV3IG9sUG9pbnQodmlldy5nZXRDZW50ZXIoKSkudHJhbnNmb3JtKFxuICAgICAgcHJvaixcbiAgICAgICdFUFNHOjQzMjYnXG4gICAgKTtcblxuICAgIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgICB1cmk6IHV1aWQoKSxcbiAgICAgIHRpdGxlOiAnJyxcbiAgICAgIHNjb3BlOiAncHJpdmF0ZScsXG4gICAgICBtYXA6IHtcbiAgICAgICAgdmlldzoge1xuICAgICAgICAgIGNlbnRlcjogY2VudGVyLmdldENvb3JkaW5hdGVzKCksXG4gICAgICAgICAgem9vbTogdmlldy5nZXRab29tKCksXG4gICAgICAgICAgcHJvamVjdGlvbjogcHJvaixcbiAgICAgICAgICBtYXhab29tT25FeHRlbnQ6IGlnb01hcC52aWV3Q29udHJvbGxlci5tYXhab29tT25FeHRlbnRcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGxheWVyczogW10sXG4gICAgICB0b29sczogW11cbiAgICB9O1xuXG4gICAgbGV0IGxheWVycyA9IFtdO1xuICAgIGlmIChlbXB0eSA9PT0gdHJ1ZSkge1xuICAgICAgbGF5ZXJzID0gaWdvTWFwLmxheWVycyRcbiAgICAgICAgLmdldFZhbHVlKClcbiAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAobGF5KSA9PlxuICAgICAgICAgICAgbGF5LmJhc2VMYXllciA9PT0gdHJ1ZSB8fFxuICAgICAgICAgICAgbGF5Lm9wdGlvbnMuaWQgPT09ICdzZWFyY2hQb2ludGVyU3VtbWFyeUlkJ1xuICAgICAgICApXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhLnpJbmRleCAtIGIuekluZGV4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGF5ZXJzID0gaWdvTWFwLmxheWVycyQuZ2V0VmFsdWUoKS5maWx0ZXIobGF5ID0+ICFsYXkuaWQuaW5jbHVkZXMoJ1dmc1dvcmtzcGFjZVRhYmxlRGVzdCcpKS5zb3J0KChhLCBiKSA9PiBhLnpJbmRleCAtIGIuekluZGV4KTtcbiAgICB9XG5cbiAgICBsZXQgaSA9IDA7XG4gICAgZm9yIChjb25zdCBsIG9mIGxheWVycykge1xuICAgICAgY29uc3QgbGF5ZXI6IGFueSA9IGw7XG4gICAgICBjb25zdCBvcHRzID0ge1xuICAgICAgICBpZDogbGF5ZXIub3B0aW9ucy5pZCA/IFN0cmluZyhsYXllci5vcHRpb25zLmlkKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgbGF5ZXJPcHRpb25zOiB7XG4gICAgICAgICAgdGl0bGU6IGxheWVyLm9wdGlvbnMudGl0bGUsXG4gICAgICAgICAgekluZGV4OiArK2ksXG4gICAgICAgICAgdmlzaWJsZTogbGF5ZXIudmlzaWJsZSxcbiAgICAgICAgICBzZWN1cml0eTogbGF5ZXIuc2VjdXJpdHlcbiAgICAgICAgfSBhcyBMYXllck9wdGlvbnMsXG4gICAgICAgIHNvdXJjZU9wdGlvbnM6IHtcbiAgICAgICAgICB0eXBlOiBsYXllci5kYXRhU291cmNlLm9wdGlvbnMudHlwZSxcbiAgICAgICAgICBwYXJhbXM6IGxheWVyLmRhdGFTb3VyY2Uub3B0aW9ucy5wYXJhbXMsXG4gICAgICAgICAgdXJsOiBsYXllci5kYXRhU291cmNlLm9wdGlvbnMudXJsLFxuICAgICAgICAgIHF1ZXJ5YWJsZTogbGF5ZXIucXVlcnlhYmxlXG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBpZiAob3B0cy5zb3VyY2VPcHRpb25zLnR5cGUpIHtcbiAgICAgICAgY29udGV4dC5sYXllcnMucHVzaChvcHRzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb250ZXh0LnRvb2xzID0gdGhpcy50b29scy5tYXAoKHRvb2wpID0+IHtcbiAgICAgIHJldHVybiB7IGlkOiBTdHJpbmcodG9vbC5pZCksIGdsb2JhbDogdG9vbC5nbG9iYWwgfTtcbiAgICB9KTtcblxuICAgIHJldHVybiBjb250ZXh0O1xuICB9XG5cbiAgZ2V0Q29udGV4dEZyb21MYXllcnMoXG4gICAgaWdvTWFwOiBJZ29NYXAsXG4gICAgbGF5ZXJzOiBMYXllcltdLFxuICAgIG5hbWU6IHN0cmluZ1xuICApOiBEZXRhaWxlZENvbnRleHQge1xuICAgIGNvbnN0IGN1cnJlbnRDb250ZXh0ID0gdGhpcy5jb250ZXh0JC5nZXRWYWx1ZSgpO1xuICAgIGNvbnN0IHZpZXcgPSBpZ29NYXAub2wuZ2V0VmlldygpO1xuICAgIGNvbnN0IHByb2ogPSB2aWV3LmdldFByb2plY3Rpb24oKS5nZXRDb2RlKCk7XG4gICAgY29uc3QgY2VudGVyOiBhbnkgPSBuZXcgb2xQb2ludCh2aWV3LmdldENlbnRlcigpKS50cmFuc2Zvcm0oXG4gICAgICBwcm9qLFxuICAgICAgJ0VQU0c6NDMyNidcbiAgICApO1xuXG4gICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgIHVyaTogbmFtZSxcbiAgICAgIHRpdGxlOiBuYW1lLFxuICAgICAgbWFwOiB7XG4gICAgICAgIHZpZXc6IHtcbiAgICAgICAgICBjZW50ZXI6IGNlbnRlci5nZXRDb29yZGluYXRlcygpLFxuICAgICAgICAgIHpvb206IHZpZXcuZ2V0Wm9vbSgpLFxuICAgICAgICAgIHByb2plY3Rpb246IHByb2pcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGxheWVyczogW10sXG4gICAgICB0b29sYmFyOiBbXSxcbiAgICAgIHRvb2xzOiBbXSxcbiAgICAgIGV4dHJhRmVhdHVyZXM6IFtdXG4gICAgfTtcblxuICAgIGNvbnN0IGN1cnJlbnRMYXllcnMgPSBpZ29NYXAubGF5ZXJzJC5nZXRWYWx1ZSgpO1xuICAgIGNvbnRleHQubGF5ZXJzID0gY3VycmVudExheWVyc1xuICAgICAgLmZpbHRlcigobCkgPT4gbC5iYXNlTGF5ZXIpXG4gICAgICAubWFwKChsKSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgYmFzZUxheWVyOiB0cnVlLFxuICAgICAgICAgIHNvdXJjZU9wdGlvbnM6IGwub3B0aW9ucy5zb3VyY2VPcHRpb25zLFxuICAgICAgICAgIHRpdGxlOiBsLm9wdGlvbnMudGl0bGUsXG4gICAgICAgICAgdmlzaWJsZTogbC52aXNpYmxlXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgIGxheWVycy5mb3JFYWNoKChsYXllcikgPT4ge1xuICAgICAgLy8gRG8gbm90IHNlZW0gdG8gd29yayBwcm9wZXJseS4gbGF5ZXJGb3VuZCBpcyBhbHdheXMgdW5kZWZpbmVkLlxuICAgICAgY29uc3QgbGF5ZXJGb3VuZCA9IGN1cnJlbnRDb250ZXh0LmxheWVycy5maW5kKFxuICAgICAgICAoY29udGV4dExheWVyKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc291cmNlID0gY29udGV4dExheWVyLnNvdXJjZTtcbiAgICAgICAgICByZXR1cm4gc291cmNlICYmIGxheWVyLmlkID09PSBzb3VyY2UuaWQgJiYgIWNvbnRleHRMYXllci5iYXNlTGF5ZXI7XG4gICAgICAgIH0pO1xuICAgICAgaWYgKGxheWVyRm91bmQpIHtcbiAgICAgICAgbGV0IGxheWVyU3R5bGUgPSBsYXllckZvdW5kW2BzdHlsZWBdO1xuICAgICAgICBpZiAobGF5ZXJGb3VuZFtgaWdvU3R5bGVgXVtgc3R5bGVCeUF0dHJpYnV0ZWBdKSB7XG4gICAgICAgICAgbGF5ZXJTdHlsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfSBlbHNlIGlmIChsYXllckZvdW5kW2BpZ29TdHlsZWBdW2BjbHVzdGVyQmFzZVN0eWxlYF0pIHtcbiAgICAgICAgICBsYXllclN0eWxlID0gdW5kZWZpbmVkO1xuICAgICAgICAgIGRlbGV0ZSBsYXllckZvdW5kLnNvdXJjZU9wdGlvbnNbYHNvdXJjZWBdO1xuICAgICAgICAgIGRlbGV0ZSBsYXllckZvdW5kLnNvdXJjZU9wdGlvbnNbYGZvcm1hdGBdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdHMgPSB7XG4gICAgICAgICAgYmFzZUxheWVyOiBsYXllckZvdW5kLmJhc2VMYXllcixcbiAgICAgICAgICB0aXRsZTogbGF5ZXIub3B0aW9ucy50aXRsZSxcbiAgICAgICAgICB6SW5kZXg6IGxheWVyLnpJbmRleCxcbiAgICAgICAgICBpZ29TdHlsZToge1xuICAgICAgICAgICAgc3R5bGVCeUF0dHJpYnV0ZTogbGF5ZXJGb3VuZFtgaWdvU3R5bGVgXVtgc3R5bGVCeUF0dHJpYnV0ZWBdLFxuICAgICAgICAgICAgY2x1c3RlckJhc2VTdHlsZTogbGF5ZXJGb3VuZFtgaWdvU3R5bGVgXVtgY2x1c3RlckJhc2VTdHlsZWBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc3R5bGU6IGxheWVyU3R5bGUsXG4gICAgICAgICAgY2x1c3RlclBhcmFtOiBsYXllckZvdW5kW2BjbHVzdGVyUGFyYW1gXSxcbiAgICAgICAgICB2aXNpYmxlOiBsYXllci52aXNpYmxlLFxuICAgICAgICAgIG9wYWNpdHk6IGxheWVyLm9wYWNpdHksXG4gICAgICAgICAgc291cmNlT3B0aW9uczogbGF5ZXJGb3VuZC5zb3VyY2VPcHRpb25zXG4gICAgICAgIH07XG4gICAgICAgIGNvbnRleHQubGF5ZXJzLnB1c2gob3B0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoIShsYXllci5vbC5nZXRTb3VyY2UoKSBpbnN0YW5jZW9mIG9sVmVjdG9yU291cmNlKSkge1xuICAgICAgICAgIGNvbnN0IGNhdGFsb2dMYXllciA9IGxheWVyLm9wdGlvbnM7XG4gICAgICAgICAgY2F0YWxvZ0xheWVyLnpJbmRleCA9IGxheWVyLnpJbmRleDtcbiAgICAgICAgICBkZWxldGUgY2F0YWxvZ0xheWVyLnNvdXJjZTtcbiAgICAgICAgICBjb250ZXh0LmxheWVycy5wdXNoKGNhdGFsb2dMYXllcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGV0IGZlYXR1cmVzO1xuICAgICAgICAgIGNvbnN0IHdyaXRlciA9IG5ldyBHZW9KU09OKCk7XG4gICAgICAgICAgaWYgKGxheWVyLm9sLmdldFNvdXJjZSgpIGluc3RhbmNlb2YgQ2x1c3Rlcikge1xuICAgICAgICAgICAgY29uc3QgY2x1c3RlclNvdXJjZSA9IGxheWVyLm9sLmdldFNvdXJjZSgpIGFzIENsdXN0ZXI7XG4gICAgICAgICAgICBsZXQgb2xGZWF0dXJlcyA9IGNsdXN0ZXJTb3VyY2UuZ2V0RmVhdHVyZXMoKTtcbiAgICAgICAgICAgIG9sRmVhdHVyZXMgPSAob2xGZWF0dXJlcyBhcyBhbnkpLmZsYXRNYXAoKGNsdXN0ZXI6IGFueSkgPT4gY2x1c3Rlci5nZXQoJ2ZlYXR1cmVzJykpO1xuICAgICAgICAgICAgY29uc3QgY2xlYW5lZE9sRmVhdHVyZXMgPSB0aGlzLmV4cG9ydFNlcnZpY2UuZ2VuZXJhdGVGZWF0dXJlKG9sRmVhdHVyZXMsICdHZW9KU09OJywgJ19mZWF0dXJlU3RvcmUnKTtcbiAgICAgICAgICAgIGZlYXR1cmVzID0gd3JpdGVyLndyaXRlRmVhdHVyZXMoXG4gICAgICAgICAgICAgIGNsZWFuZWRPbEZlYXR1cmVzLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZGF0YVByb2plY3Rpb246ICdFUFNHOjQzMjYnLFxuICAgICAgICAgICAgICAgIGZlYXR1cmVQcm9qZWN0aW9uOiAnRVBTRzozODU3J1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBsYXllci5vbC5nZXRTb3VyY2UoKSBhcyBvbFZlY3RvclNvdXJjZTtcbiAgICAgICAgICAgIGNvbnN0IG9sRmVhdHVyZXMgPSBzb3VyY2UuZ2V0RmVhdHVyZXMoKTtcbiAgICAgICAgICAgIGNvbnN0IGNsZWFuZWRPbEZlYXR1cmVzID0gdGhpcy5leHBvcnRTZXJ2aWNlLmdlbmVyYXRlRmVhdHVyZShvbEZlYXR1cmVzLCAnR2VvSlNPTicsICdfZmVhdHVyZVN0b3JlJyk7XG4gICAgICAgICAgICBmZWF0dXJlcyA9IHdyaXRlci53cml0ZUZlYXR1cmVzKFxuICAgICAgICAgICAgICBjbGVhbmVkT2xGZWF0dXJlcyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGRhdGFQcm9qZWN0aW9uOiAnRVBTRzo0MzI2JyxcbiAgICAgICAgICAgICAgICBmZWF0dXJlUHJvamVjdGlvbjogJ0VQU0c6Mzg1NydcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZmVhdHVyZXMgPSBKU09OLnBhcnNlKGZlYXR1cmVzKTtcbiAgICAgICAgICBmZWF0dXJlcy5uYW1lID0gbGF5ZXIub3B0aW9ucy50aXRsZTtcbiAgICAgICAgICBjb250ZXh0LmV4dHJhRmVhdHVyZXMucHVzaChmZWF0dXJlcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNvbnRleHQudG9vbGJhciA9IHRoaXMudG9vbGJhcjtcbiAgICBjb250ZXh0LnRvb2xzID0gdGhpcy50b29scztcblxuICAgIHJldHVybiBjb250ZXh0O1xuICB9XG5cbiAgc2V0VG9vbHModG9vbHM6IFRvb2xbXSkge1xuICAgIHRoaXMudG9vbHMgPSB0b29scztcbiAgfVxuXG4gIHNldFRvb2xiYXIodG9vbGJhcjogc3RyaW5nW10pIHtcbiAgICB0aGlzLnRvb2xiYXIgPSB0b29sYmFyO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVDb250ZXh0TWVzc2FnZShjb250ZXh0OiBEZXRhaWxlZENvbnRleHQpIHtcbiAgICBpZiAodGhpcy5jb250ZXh0JC52YWx1ZSAmJiBjb250ZXh0LnVyaSAmJiB0aGlzLmNvbnRleHQkLnZhbHVlLnVyaSAhPT0gY29udGV4dC51cmkpIHtcbiAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UucmVtb3ZlQWxsQXJlTm90RXJyb3IoKTtcbiAgICB9XG5cbiAgICBjb250ZXh0Lm1lc3NhZ2VzID0gY29udGV4dC5tZXNzYWdlcyA/IGNvbnRleHQubWVzc2FnZXMgOiBbXTtcbiAgICBjb250ZXh0Lm1lc3NhZ2VzLnB1c2goY29udGV4dC5tZXNzYWdlKTtcbiAgICBjb250ZXh0Lm1lc3NhZ2VzLm1hcChtZXNzYWdlID0+IHtcbiAgICAgIGlmIChtZXNzYWdlKSB7XG4gICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UubWVzc2FnZShtZXNzYWdlIGFzIE1lc3NhZ2UpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb250ZXh0QnlVcmkodXJpOiBzdHJpbmcpOiBPYnNlcnZhYmxlPERldGFpbGVkQ29udGV4dD4ge1xuICAgIGlmICh0aGlzLmJhc2VVcmwpIHtcbiAgICAgIGxldCBjb250ZXh0VG9Mb2FkO1xuICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy5jb250ZXh0cyQudmFsdWUpKSB7XG4gICAgICAgIGNvbnRleHRUb0xvYWQgPSB0aGlzLmNvbnRleHRzJC52YWx1ZVtrZXldLmZpbmQoKGMpID0+IHtcbiAgICAgICAgICByZXR1cm4gYy51cmkgPT09IHVyaTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChjb250ZXh0VG9Mb2FkKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGNvbnRleHRUb0xvYWQgJiYgY29udGV4dFRvTG9hZC5pbXBvcnRlZCkge1xuICAgICAgICByZXR1cm4gb2YoY29udGV4dFRvTG9hZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFRPRE8gOiB1c2UgYWx3YXlzIGlkIG9yIHVyaVxuICAgICAgY29uc3QgaWQgPSBjb250ZXh0VG9Mb2FkID8gY29udGV4dFRvTG9hZC5pZCA6IHVyaTtcbiAgICAgIHJldHVybiB0aGlzLmdldERldGFpbHMoaWQpO1xuICAgIH1cblxuICAgIGNvbnN0IGltcG9ydGVkQ29udGV4dCA9IHRoaXMuY29udGV4dHMkLnZhbHVlLm91cnMuZmluZCgoY3VycmVudENvbnRleHQpID0+IHtcbiAgICAgIHJldHVybiBjdXJyZW50Q29udGV4dC51cmkgPT09IHVyaSAmJiBjdXJyZW50Q29udGV4dC5pbXBvcnRlZCA9PT0gdHJ1ZTtcbiAgICB9KTtcblxuICAgIGlmIChpbXBvcnRlZENvbnRleHQpIHtcbiAgICAgIHJldHVybiBvZihpbXBvcnRlZENvbnRleHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRMb2NhbENvbnRleHQodXJpKTtcbiAgICB9XG4gIH1cblxuICBnZXRDb250ZXh0TGF5ZXJzKGlnb01hcDogSWdvTWFwKSB7XG4gICAgY29uc3QgbGF5ZXJzOiBMYXllcltdID0gW107XG4gICAgY29uc3QgbWFwTGF5ZXJzID0gaWdvTWFwLmxheWVycyQuZ2V0VmFsdWUoKTtcbiAgICBtYXBMYXllcnMuZm9yRWFjaCgobGF5ZXIpID0+IHtcbiAgICAgIGlmICghbGF5ZXIuYmFzZUxheWVyICYmIGxheWVyLm9wdGlvbnMuaWQgIT09ICdzZWFyY2hQb2ludGVyU3VtbWFyeUlkJykge1xuICAgICAgICBsYXllcnMucHVzaChsYXllcik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGxheWVycztcbiAgfVxuXG4gIHByaXZhdGUgcmVhZFBhcmFtc0Zyb21Sb3V0ZSgpIHtcbiAgICBpZiAoIXRoaXMucm91dGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnJvdXRlLnF1ZXJ5UGFyYW1zLnN1YnNjcmliZSgocGFyYW1zKSA9PiB7XG4gICAgICBjb25zdCBjZW50ZXJLZXkgPSB0aGlzLnJvdXRlLm9wdGlvbnMuY2VudGVyS2V5O1xuICAgICAgaWYgKGNlbnRlcktleSAmJiBwYXJhbXNbY2VudGVyS2V5IGFzIHN0cmluZ10pIHtcbiAgICAgICAgY29uc3QgY2VudGVyUGFyYW1zID0gcGFyYW1zW2NlbnRlcktleSBhcyBzdHJpbmddO1xuICAgICAgICB0aGlzLm1hcFZpZXdGcm9tUm91dGUuY2VudGVyID0gY2VudGVyUGFyYW1zLnNwbGl0KCcsJykubWFwKE51bWJlcik7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHByb2plY3Rpb25LZXkgPSB0aGlzLnJvdXRlLm9wdGlvbnMucHJvamVjdGlvbktleTtcbiAgICAgIGlmIChwcm9qZWN0aW9uS2V5ICYmIHBhcmFtc1twcm9qZWN0aW9uS2V5IGFzIHN0cmluZ10pIHtcbiAgICAgICAgY29uc3QgcHJvamVjdGlvblBhcmFtID0gcGFyYW1zW3Byb2plY3Rpb25LZXkgYXMgc3RyaW5nXTtcbiAgICAgICAgdGhpcy5tYXBWaWV3RnJvbVJvdXRlLnByb2plY3Rpb24gPSBwcm9qZWN0aW9uUGFyYW07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHpvb21LZXkgPSB0aGlzLnJvdXRlLm9wdGlvbnMuem9vbUtleTtcbiAgICAgIGlmICh6b29tS2V5ICYmIHBhcmFtc1t6b29tS2V5IGFzIHN0cmluZ10pIHtcbiAgICAgICAgY29uc3Qgem9vbVBhcmFtID0gcGFyYW1zW3pvb21LZXkgYXMgc3RyaW5nXTtcbiAgICAgICAgdGhpcy5tYXBWaWV3RnJvbVJvdXRlLnpvb20gPSBOdW1iZXIoem9vbVBhcmFtKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UGF0aChmaWxlOiBzdHJpbmcpIHtcbiAgICBjb25zdCBiYXNlUGF0aCA9IHRoaXMub3B0aW9ucy5iYXNlUGF0aC5yZXBsYWNlKC9cXC8kLywgJycpO1xuXG4gICAgcmV0dXJuIGAke2Jhc2VQYXRofS8ke2ZpbGV9YDtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlRXJyb3IoXG4gICAgZXJyb3I6IEh0dHBFcnJvclJlc3BvbnNlLFxuICAgIHVyaTogc3RyaW5nLFxuICAgIHBlcm1pc3Npb25FcnJvcj86IGJvb2xlYW5cbiAgKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHRoaXMuY29udGV4dHMkLnZhbHVlLm91cnMuZmluZCgob2JqKSA9PiBvYmoudXJpID09PSB1cmkpO1xuICAgIGNvbnN0IHRpdGxlQ29udGV4dCA9IGNvbnRleHQgPyBjb250ZXh0LnRpdGxlIDogdXJpO1xuICAgIGVycm9yLmVycm9yLnRpdGxlID0gdGhpcy5sYW5ndWFnZVNlcnZpY2UudHJhbnNsYXRlLmluc3RhbnQoXG4gICAgICAnaWdvLmNvbnRleHQuY29udGV4dE1hbmFnZXIuaW52YWxpZC50aXRsZSdcbiAgICApO1xuXG4gICAgZXJyb3IuZXJyb3IubWVzc2FnZSA9IHRoaXMubGFuZ3VhZ2VTZXJ2aWNlLnRyYW5zbGF0ZS5pbnN0YW50KFxuICAgICAgJ2lnby5jb250ZXh0LmNvbnRleHRNYW5hZ2VyLmludmFsaWQudGV4dCcsXG4gICAgICB7IHZhbHVlOiB0aXRsZUNvbnRleHQgfVxuICAgICk7XG5cbiAgICBlcnJvci5lcnJvci50b0Rpc3BsYXkgPSB0cnVlO1xuXG4gICAgaWYgKHBlcm1pc3Npb25FcnJvcikge1xuICAgICAgZXJyb3IuZXJyb3IudGl0bGUgPSB0aGlzLmxhbmd1YWdlU2VydmljZS50cmFuc2xhdGUuaW5zdGFudChcbiAgICAgICAgJ2lnby5jb250ZXh0LmNvbnRleHRNYW5hZ2VyLmVycm9ycy5hZGRQZXJtaXNzaW9uVGl0bGUnXG4gICAgICApO1xuICAgICAgZXJyb3IuZXJyb3IubWVzc2FnZSA9IHRoaXMubGFuZ3VhZ2VTZXJ2aWNlLnRyYW5zbGF0ZS5pbnN0YW50KFxuICAgICAgICAnaWdvLmNvbnRleHQuY29udGV4dE1hbmFnZXIuZXJyb3JzLmFkZFBlcm1pc3Npb24nXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmVycm9yKFxuICAgICAgJ2lnby5jb250ZXh0LmNvbnRleHRNYW5hZ2VyLmVycm9ycy5hZGRQZXJtaXNzaW9uJyxcbiAgICAgICdpZ28uY29udGV4dC5jb250ZXh0TWFuYWdlci5lcnJvcnMuYWRkUGVybWlzc2lvblRpdGxlJyk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUNvbnRleHRzQ2hhbmdlKFxuICAgIGtlZXBDdXJyZW50Q29udGV4dCA9IHRydWVcbiAgKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHRoaXMuY29udGV4dCQudmFsdWU7XG4gICAgY29uc3QgZWRpdGVkQ29udGV4dCA9IHRoaXMuZWRpdGVkQ29udGV4dCQudmFsdWU7XG4gICAgaWYgKCFjb250ZXh0IHx8IGNvbnRleHQudXJpID09PSB0aGlzLm9wdGlvbnMuZGVmYXVsdENvbnRleHRVcmkpIHtcbiAgICAgIGtlZXBDdXJyZW50Q29udGV4dCA9IGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIWtlZXBDdXJyZW50Q29udGV4dCB8fCAhdGhpcy5maW5kQ29udGV4dChjb250ZXh0KSkge1xuICAgICAgdGhpcy5kZWZhdWx0Q29udGV4dFVyaSA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMubG9hZERlZmF1bHRDb250ZXh0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZ2V0Q29udGV4dEJ5VXJpKGNvbnRleHQudXJpKVxuICAgICAgICAucGlwZShmaXJzdCgpKVxuICAgICAgICAuc3Vic2NyaWJlKFxuICAgICAgICAgIChuZXdDb250ZXh0OiBEZXRhaWxlZENvbnRleHQpID0+IHtcbiAgICAgICAgICAgIHRoaXMudG9vbHNDaGFuZ2VkJC5uZXh0KG5ld0NvbnRleHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgaWYgKHRoaXMuYmFzZVVybCAmJiB0aGlzLmF1dGhTZXJ2aWNlLmF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgICAgdGhpcy5nZXREZWZhdWx0KCkuc3Vic2NyaWJlKCk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGVkaXRlZEZvdW5kID0gdGhpcy5maW5kQ29udGV4dChlZGl0ZWRDb250ZXh0KTtcbiAgICBpZiAoIWVkaXRlZEZvdW5kIHx8IGVkaXRlZEZvdW5kLnBlcm1pc3Npb24gIT09ICd3cml0ZScpIHtcbiAgICAgIHRoaXMuc2V0RWRpdGVkQ29udGV4dCh1bmRlZmluZWQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYWRkQ29udGV4dFRvTGlzdChjb250ZXh0OiBDb250ZXh0KSB7XG4gICAgY29uc3QgY29udGV4dEZvdW5kID0gdGhpcy5maW5kQ29udGV4dChjb250ZXh0KTtcbiAgICBpZiAoIWNvbnRleHRGb3VuZCkge1xuICAgICAgY29uc3QgY29udGV4dFNpbXBsaWZpZSA9IHtcbiAgICAgICAgaWQ6IGNvbnRleHQuaWQsXG4gICAgICAgIHVyaTogY29udGV4dC51cmksXG4gICAgICAgIHRpdGxlOiBjb250ZXh0LnRpdGxlLFxuICAgICAgICBzY29wZTogY29udGV4dC5zY29wZSxcbiAgICAgICAgcGVybWlzc2lvbjogVHlwZVBlcm1pc3Npb25bVHlwZVBlcm1pc3Npb24ucmVhZF1cbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLmNvbnRleHRzJC52YWx1ZSAmJiB0aGlzLmNvbnRleHRzJC52YWx1ZS5wdWJsaWMpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0cyQudmFsdWUucHVibGljLnB1c2goY29udGV4dFNpbXBsaWZpZSk7XG4gICAgICAgIHRoaXMuY29udGV4dHMkLm5leHQodGhpcy5jb250ZXh0cyQudmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZmluZENvbnRleHQoY29udGV4dDogQ29udGV4dCkge1xuICAgIGlmICghY29udGV4dCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRleHRzID0gdGhpcy5jb250ZXh0cyQudmFsdWU7XG4gICAgbGV0IGZvdW5kO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNvbnRleHRzKSkge1xuICAgICAgY29uc3QgdmFsdWUgPSBjb250ZXh0c1trZXldO1xuICAgICAgZm91bmQgPSB2YWx1ZS5maW5kKFxuICAgICAgICAoYykgPT5cbiAgICAgICAgICAoY29udGV4dC5pZCAmJiBjLmlkID09PSBjb250ZXh0LmlkKSB8fFxuICAgICAgICAgIChjb250ZXh0LnVyaSAmJiBjLnVyaSA9PT0gY29udGV4dC51cmkpXG4gICAgICApO1xuICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmb3VuZDtcbiAgfVxufVxuIl19