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