@esfaenza/es-diagrams 16.2.26 → 17.3.0

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 (59) hide show
  1. package/esm2022/esfaenza-es-diagrams.mjs +4 -4
  2. package/esm2022/lib/components/es-diagram.component.mjs +537 -537
  3. package/esm2022/lib/esdiagram.module.mjs +31 -31
  4. package/esm2022/lib/extensions/ReactiveExtensions.mjs +35 -35
  5. package/esm2022/lib/extensions/ResizeSensor.mjs +71 -71
  6. package/esm2022/lib/models/EsDiagramModuleConfig.mjs +5 -5
  7. package/esm2022/lib/models/component/contextmenu/ContextMenuCommand.mjs +5 -5
  8. package/esm2022/lib/models/component/contextmenu/ContextMenuOptions.mjs +6 -6
  9. package/esm2022/lib/models/component/grouping/ExpandCollapseOptions.mjs +5 -5
  10. package/esm2022/lib/models/component/nodes/NodeHTMLTemplate.mjs +5 -5
  11. package/esm2022/lib/models/component/nodes/NodeTemplate.mjs +5 -5
  12. package/esm2022/lib/models/component/nodes/ZoomLevelBasedTemplate.mjs +5 -5
  13. package/esm2022/lib/models/layouts/BreadthFirstLayoutOptionsImpl.mjs +34 -34
  14. package/esm2022/lib/models/layouts/CircleLayoutOptionsImpl.mjs +26 -26
  15. package/esm2022/lib/models/layouts/ConcentricLayoutOptionsImpl.mjs +63 -63
  16. package/esm2022/lib/models/layouts/CoseLayoutOptionsImpl.mjs +82 -82
  17. package/esm2022/lib/models/layouts/DagreLayoutOptionsImpl.mjs +51 -51
  18. package/esm2022/lib/models/layouts/GridLayoutOptionsImpl.mjs +37 -37
  19. package/esm2022/lib/models/layouts/NullLayoutOptionsImpl.mjs +14 -14
  20. package/esm2022/lib/models/layouts/PresetLayoutOptionsImpl.mjs +23 -23
  21. package/esm2022/lib/models/layouts/RandomLayoutOptionsImpl.mjs +35 -35
  22. package/esm2022/lib/models/layouts/base/AnimateLayoutOptionsImpl.mjs +41 -41
  23. package/esm2022/lib/models/layouts/base/BaseLayoutOptionsImpl.mjs +17 -17
  24. package/esm2022/lib/models/layouts/base/ShapedLayoutOptionsImpl.mjs +47 -47
  25. package/esm2022/lib/services/es-diagram.dispatcher.mjs +89 -89
  26. package/esm2022/lib/services/es-diagram.service.mjs +106 -106
  27. package/esm2022/lib/tokens.mjs +5 -5
  28. package/esm2022/public-api.mjs +23 -23
  29. package/fesm2022/esfaenza-es-diagrams.mjs +1320 -1320
  30. package/fesm2022/esfaenza-es-diagrams.mjs.map +1 -1
  31. package/index.d.ts +5 -5
  32. package/lib/components/es-diagram.component.d.ts +305 -305
  33. package/lib/esdiagram.module.d.ts +12 -12
  34. package/lib/extensions/ReactiveExtensions.d.ts +20 -20
  35. package/lib/extensions/ResizeSensor.d.ts +43 -43
  36. package/lib/models/EsDiagramModuleConfig.d.ts +9 -9
  37. package/lib/models/component/contextmenu/ContextMenuCommand.d.ts +27 -27
  38. package/lib/models/component/contextmenu/ContextMenuOptions.d.ts +79 -79
  39. package/lib/models/component/grouping/ExpandCollapseOptions.d.ts +22 -22
  40. package/lib/models/component/nodes/NodeHTMLTemplate.d.ts +14 -14
  41. package/lib/models/component/nodes/NodeTemplate.d.ts +13 -13
  42. package/lib/models/component/nodes/ZoomLevelBasedTemplate.d.ts +14 -14
  43. package/lib/models/layouts/BreadthFirstLayoutOptionsImpl.d.ts +40 -40
  44. package/lib/models/layouts/CircleLayoutOptionsImpl.d.ts +28 -28
  45. package/lib/models/layouts/ConcentricLayoutOptionsImpl.d.ts +74 -74
  46. package/lib/models/layouts/CoseLayoutOptionsImpl.d.ts +80 -80
  47. package/lib/models/layouts/DagreLayoutOptionsImpl.d.ts +48 -48
  48. package/lib/models/layouts/GridLayoutOptionsImpl.d.ts +39 -39
  49. package/lib/models/layouts/NullLayoutOptionsImpl.d.ts +12 -12
  50. package/lib/models/layouts/PresetLayoutOptionsImpl.d.ts +37 -37
  51. package/lib/models/layouts/RandomLayoutOptionsImpl.d.ts +33 -33
  52. package/lib/models/layouts/base/AnimateLayoutOptionsImpl.d.ts +40 -40
  53. package/lib/models/layouts/base/BaseLayoutOptionsImpl.d.ts +15 -15
  54. package/lib/models/layouts/base/ShapedLayoutOptionsImpl.d.ts +46 -46
  55. package/lib/services/es-diagram.dispatcher.d.ts +44 -44
  56. package/lib/services/es-diagram.service.d.ts +51 -51
  57. package/lib/tokens.d.ts +5 -5
  58. package/package.json +3 -3
  59. package/public-api.d.ts +20 -20
@@ -1,537 +1,537 @@
1
- import { Component, EventEmitter, Input, Optional, Output, ViewChild } from '@angular/core';
2
- import { ResizeSensor } from "../extensions/ResizeSensor";
3
- import * as cy_ from 'cytoscape';
4
- import * as i0 from "@angular/core";
5
- import * as i1 from "../services/es-diagram.service";
6
- import * as i2 from "../services/es-diagram.dispatcher";
7
- import * as i3 from "../extensions/ReactiveExtensions";
8
- /** @ignore */ const cytoscape = cy_.default ? cy_.default : cy_;
9
- /**
10
- * Componente che si occupa di graficare un diagramma e di gestirne il ciclo di vita
11
- */
12
- export class EsDiagramComponent {
13
- /**
14
- * Costruttore
15
- *
16
- * @ignore
17
- */
18
- constructor(service, dispatcher, exts) {
19
- this.service = service;
20
- this.dispatcher = dispatcher;
21
- this.exts = exts;
22
- /**
23
- * Nome del diagramma, fondamentale assegnarlo per permettere alla libreria di schedularne la creazione
24
- */
25
- this.name = "";
26
- /**
27
- * Indica se utilizzare il menù contestuale a ruota attorno ad ogni nodo
28
- */
29
- this.UseContextMenu = false;
30
- /**
31
- * Dice al componente se il diagramma deve utilizzare il sistema di estensione per l'expand e collapse dei gruppi
32
- */
33
- this.UseExpandCollapse = false;
34
- /**
35
- * Blocco completo delle opzioni, alternativo all'assegnazione di **Elements**, **NodeStyles**, **EdgeStyles**, e **Layout**.
36
- *
37
- * Qualora entrambe venissero specificate verrà effettuata un'unione fra queste opzioni e quelle specificate, dando priorità alle specificate
38
- */
39
- this.NativeOptions = {};
40
- /**
41
- * Aggiorna automaticamente le dimensioni del diagramma quando cambiano le dimensioni della finestra
42
- */
43
- this.AutoupdateSize = true;
44
- /**
45
- * Indica di mantenere la posizione dei nodi qualora venissero cambiati dall'Input **Elements**.
46
- *
47
- * Se l'ID di un nodo è uguale all'ID di un nodo presente in precedenza, il nuovo nodo ne erediterà la posizione
48
- */
49
- this.PreserveElementsPosition = true;
50
- /**
51
- * Qualora venisse modificato l'Input **Elements**, piuttosto che mettere semplicemente il nuovo Elemento in base al Layout precedente, applica anche un'animazione
52
- *
53
- * Funziona solamente se il **Layout** corrente del diagramma supporta le animazioni
54
- */
55
- this.AnimateLayoutChanges = true;
56
- /**
57
- * Attiva una modalità di selezione "smart"... o perlomeno "smarter" del default di Cytoscape.
58
- *
59
- * - Il click di un elemento non selezionato lo seleziona
60
- * - Il click di un elemento selezionato lo deseleziona
61
- * - Lo stato di selezione viene persistito sull'oggetto originale invece di rimanere in un internal
62
- * - All'assegnazione di oggetti selezionati, questi vengono marcati correttamente con l'overlay di selezione
63
- *
64
- * N.B: la chiamata all'evento **onNodeClick** avviene **DOPO** la gestione della selezione
65
- */
66
- this.SmartSelection = false;
67
- /**
68
- * Indica di selezionare un elemento per volta qualora **SmartSelection** fosse attivo
69
- */
70
- this.SingleSelection = false;
71
- /**
72
- * CSS per la graficazione della selezione dei nodi. Quando un nodo verrà selezionato avrà sopra di se un overlay che 'sborda' di **overlay-padding** pixel,
73
- * di colore **overlay-color** e con un opacità **overlay-opacity**
74
- *
75
- * Assegnando "{}" a questo input, la Smart selection viene gestita ma la gestione grafica è affidata all'utente,
76
- * ad esempio usando dei **NodeHTMLTemplates** che definiscano selettori su nodi ":selected"
77
- *
78
- * @default {'overlay-color':'blue','overlay-opacity':0.5,'overlay-padding':7}
79
- */
80
- this.SmartSelectionStyles = null;
81
- /**
82
- * Periodo di throttle da quando viene effettuato un resize a quando ricalcolare le dimensioni del diagramma.
83
- *
84
- * Può essere tenuto a 0 (redraw istantaneo) finché non ci sono problemi di prestazioni con eventualmente tanti resize a poca distanza l'uno dall'altro.
85
- */
86
- this.ResizeThrottleTime = 0;
87
- /**
88
- * Fornisce il global della libreria (namespace **cytoscape**) e si aspetta che dopo operazioni di importazione
89
- * lasciate all'utente vengano aggiunti tutti i moduli desiderati.
90
- *
91
- * È **fondamentale** che il primo parametro (il nome del modulo) sia uguale a ciò di cui viene fatto il require in modo che la libreria
92
- * possa controllare che il modulo importato non sia già stato importato in precedenza
93
- *
94
- * ## Esempio:
95
- *
96
- * ```typescript
97
- * (global) => {
98
- * return import("cytoscape-extension-library").then(module => global.use("cytoscape-extension-library", module.default));
99
- *
100
- * ...
101
- * }
102
- * ```
103
- */
104
- this.ExtensionModulesImporter = null;
105
- /**
106
- * Fornisce l'istanza attuale di Cytoscape da cui è possibile prendere le librerie di estensione caricate in **ExtensionModulesImporter**
107
- * e configurarle in base ai comportamenti specifici
108
- *
109
- * ## Esempio:
110
- *
111
- * ```typescript
112
- * (cytoscapeCore) => {
113
- * // Fare questo lavoro per ogni estensione caricata
114
- * let extensionConfiguration = { ... };
115
- * let extensionInstance = cytoscapeCore.extensionLibrary(extensionConfiguration);
116
- * extensionInstance.doSomethingSpecificToThisExtension();
117
- *
118
- * ...
119
- * }
120
- * ```
121
- */
122
- this.ExtensionModulesApplyer = null;
123
- /**
124
- * Evento lanciato al click di un nodo, contiene l'oggetto **data** del nodo in questione
125
- */
126
- this.onNodeClick = new EventEmitter();
127
- /**
128
- * Evento lanciato alla selezione o deselezione di un nodo, contiene l'oggetto **data** del nodo in questione e informazioni sul suo stato di selezione
129
- */
130
- this.onNodeSelection = new EventEmitter();
131
- /**
132
- * Evento lanciato al termine del Layouting. Se si vuole eseguire codice dopo che il Layout è fatto e completamente graficato, questo è il punto
133
- */
134
- this.onLayoutDone = new EventEmitter();
135
- /**
136
- * Evento lanciato al termine del caricamento del diagramma
137
- */
138
- this.onLoaded = new EventEmitter();
139
- /**
140
- * Indica se il rendering del diagramma è terminato
141
- */
142
- this.Rendered = false;
143
- /**
144
- * Api dell'estensione expand-collapse per permettere di effettuare operazioni dall'esterno del diagramma. Vengono valorizzate se **UseExpandCollapse** è **true**
145
- */
146
- this.ExpandCollapseApi = null;
147
- /**
148
- * Api dell'estensione html-node per permettere di effettuare operazioni dall'esterno del diagramma. Vengono valorizzate se sono impostati dei **NodeHTMLTemplates**
149
- */
150
- this.HtmlNodeApi = null;
151
- }
152
- /**
153
- * @ignore
154
- *
155
- * Angular Pipeline
156
- */
157
- ngAfterViewInit() {
158
- if (!this.service || !this.dispatcher)
159
- throw "Il modulo @esfaenza/diagrams non è stato importato con il forRoot();";
160
- this.dispatchLoadChart();
161
- }
162
- /**
163
- * All'onDestroy ripulisco la memoria dal diagramma
164
- */
165
- ngOnDestroy() {
166
- if (this.resizeObserver) {
167
- this.resizeObserver.dispose();
168
- this.resizeObserver = null;
169
- }
170
- if (this.cy) {
171
- this.service.log("I", "Diagram" + " " + this.name + ": Unloading destroyed diagram", false);
172
- this.cy.destroy();
173
- this.dispatcher.deregister(this.name);
174
- }
175
- else
176
- this.service.log("I", "Chart " + this.name + ": Unloading uncreated chart component. It probably was a duplicated", false);
177
- }
178
- /**
179
- * Registra il diagramma attuale nel Dispatcher in modo che venga caricato appena possibile
180
- */
181
- dispatchLoadChart() {
182
- this.dispatcher.register(this.name, () => { return this.render(); });
183
- }
184
- /**
185
- * @ignore
186
- *
187
- * Angular Pipeline: Gestione ri-graficazione del diagramma, se possibile
188
- */
189
- ngOnChanges(changes) {
190
- let toCheck = ["Templates", "UseContextMenu", "ContextMenuOptions", "UseExpandCollapse", "ExpandCollapseOptions", "NodeStyles", "EdgeStyles", "NativeOptions"];
191
- if (this.Rendered && toCheck.some(t => changes[t]))
192
- this.service.log("W", "Redraw based on dynamic Input change is supported only for 'Elements' and 'Layout' inputs, please destroy the component and recreate it with the new settings");
193
- let elementChanges = changes["Elements"];
194
- let layoutChanges = changes["Layout"];
195
- if (elementChanges && !elementChanges.firstChange) {
196
- this.service.log("I", "Elements have been changed after diagram initialization");
197
- // Cambiamento agli Elementi: ripulisco gli elementi vecchi, prendo i nuovi, li sistemo e li riassegno.
198
- // Se il nuovo Input Elements è roba strana mi limito a ripulire il diagramma
199
- // Se cytoscape aveva già degli elementi precedentemente ne prendo le posizioni in modo da ridisegnarli partendo dallo stesso punto (carino per le animazioni)
200
- let elements = elementChanges?.currentValue;
201
- let previous_elements = this.PreserveElementsPosition ? this.cy.nodes() : null;
202
- this.cy.elements().remove();
203
- if (elements && elements.length && elements.length > 0) {
204
- this.reviewCytoscapeElements(elements, previous_elements);
205
- this.cy.add(elements);
206
- if (this.SmartSelection)
207
- this.setupElementsSelectionIfNeeded();
208
- // Se solo gli elementi cambiano, riapplico il Layout precedente
209
- if (!layoutChanges && this.LastLayout) {
210
- // Se devo animare le modifche al layout forzo il parametro relativo
211
- if (this.AnimateLayoutChanges)
212
- this.LastLayout.animate = true;
213
- this.cy.layout(this.LastLayout).run();
214
- }
215
- }
216
- }
217
- // Se il layout cambia lo applico e me lo salvo come layout precedente per il futuro
218
- if (layoutChanges && !layoutChanges.firstChange) {
219
- this.service.log("I", "Layout have been changed after diagram initialization");
220
- this.LastLayout = JSON.parse(JSON.stringify(layoutChanges.currentValue));
221
- this.cy.layout(this.LastLayout).run();
222
- }
223
- }
224
- /**
225
- * Effettua il rendering del diagramma
226
- */
227
- async render() {
228
- // Tiro fuori le opzioni con cui generare il diagramma
229
- let cyOptions = this.getCompletedOptions();
230
- this.NodesHierarchy = cyOptions.elements && cyOptions.elements.some(t => t.data.parent);
231
- // Carico eventuali classi di estensione che servono
232
- await this.performModulesLoading();
233
- // Genero il diagramma
234
- this.cy = cytoscape(cyOptions);
235
- // Collego gli eventi al componente
236
- this.bindCytoscapeEvents();
237
- // Utilizzo le classi di estensione caricate precedentemente per fare il resto delle mie operazioni
238
- this.performOperationsWithLoadedModules();
239
- // Imposto la variabile Rendered a true in modo che se da adesso vengono fatte modifiche che dovrebbero causare un redraw posso accorgermene
240
- // e mandare a cagare lo stronzo di turno
241
- this.Rendered = true;
242
- // Se devo aggiornare in automatico in base alla dimensione del contenitore collego il ResizeObserver
243
- if (this.AutoupdateSize)
244
- this.listenOnChanges();
245
- if (this.SmartSelection) {
246
- this.setupSelectionStyles();
247
- this.setupElementsSelectionIfNeeded();
248
- }
249
- this.onLoaded.emit();
250
- }
251
- /**
252
- * Prende tutti gli elementi appena assegnati, e se qualcuno era selezionato la situazione viene persistita su cytoscape
253
- */
254
- setupElementsSelectionIfNeeded() {
255
- for (let i = 0; i < this.Elements.length; i++) {
256
- let eldata = this.Elements[i].data;
257
- if (eldata.__selected) {
258
- let el = this.cy.$id(eldata.id);
259
- el.select();
260
- }
261
- }
262
- }
263
- /**
264
- * Carica gli stili per mostrare carina la selezione dei nodi
265
- */
266
- setupSelectionStyles() {
267
- let cssItem = this.SmartSelectionStyles || {
268
- 'overlay-color': 'blue',
269
- 'overlay-opacity': 0.5,
270
- 'overlay-padding': 7
271
- };
272
- // Backdoor per poter assegnare "{}" a SmartSelectionStyles in modo di utilizzare la smart selection ma senza che nessuno stile venga applicato
273
- // ad esempio qualora si volesse utilizzare l'htmlnode per gestire la grafica degli elementi selezionati
274
- if (cssItem['overlay-color'] && cssItem['overlay-opacity'] && cssItem['overlay-padding'])
275
- this.cy.style().selector('node:selected').css(cssItem);
276
- }
277
- /**
278
- * Registra l'ascolto al contenitore del grafico e in caso di modifiche alla dimensione, al massimo una volta ogni 500 millisecondi, lo ridisegna
279
- */
280
- listenOnChanges() {
281
- this.resizeObserver = new ResizeSensor(this.cyGraph.nativeElement, () => {
282
- this.exts.throttle(this.name, this.onContainerSizeChanged.bind(this), this.ResizeThrottleTime);
283
- });
284
- }
285
- /**
286
- * Funzione che si occupa di gestire il repaint del diagramma
287
- */
288
- onContainerSizeChanged() {
289
- this.service.log("I", "Diagram container size has changed, redrawing");
290
- this.cy.resize();
291
- this.cy.fit();
292
- }
293
- /**
294
- * Collega tutti gli eventi che mi possono servire e li espone in output
295
- */
296
- bindCytoscapeEvents() {
297
- this.cy.bind('click', 'node', (event) => {
298
- let targetData = event.target.data();
299
- if (this.SmartSelection) {
300
- // In caso di selezione singola ripulisco tutti gli elementi precedentemente selezionati
301
- if (this.SingleSelection) {
302
- let selected = this.cy.elements('node:selected');
303
- selected.forEach(el => {
304
- el.selectify();
305
- el.unselect();
306
- el.unselectify();
307
- el.data("__selected", false);
308
- });
309
- }
310
- let id = targetData.id;
311
- let el = this.cy.$id(id);
312
- let selected = el.selected();
313
- el.selectify();
314
- if (selected)
315
- el.unselect();
316
- else
317
- el.select();
318
- el.unselectify();
319
- // Questo va anche nella lista degli elementi originali (this.Elements) dato che cytoscape li prende per riferimento (bbbbbravo cyto-chan)
320
- el.data("__selected", !selected);
321
- }
322
- this.onNodeClick.emit({ data: targetData });
323
- });
324
- this.cy.bind('select', 'node', (event) => {
325
- let targetData = event.target.data();
326
- this.onNodeSelection.emit({ data: targetData, selected: true });
327
- });
328
- this.cy.bind('layoutstop', (event) => {
329
- this.onLayoutDone.emit();
330
- });
331
- this.cy.bind('unselect', 'node', (event) => {
332
- let targetData = event.target.data();
333
- this.onNodeSelection.emit({ data: targetData, selected: false });
334
- });
335
- // Altri eventi...
336
- }
337
- /**
338
- * Metodo che serve per caricare tutte le estensioni della libreria in base a ciò che viene utilizzato
339
- */
340
- async performModulesLoading() {
341
- if (this.Layout.name == 'dagre')
342
- await this.loadInternal("cytoscape-dagre");
343
- if (this.NodeHTMLTemplates && this.NodeHTMLTemplates.length > 0)
344
- await this.loadInternal("cytoscape-html-node");
345
- if (this.UseContextMenu)
346
- await this.loadInternal("cytoscape-cxtmenu");
347
- if (this.NodesHierarchy && this.UseExpandCollapse)
348
- await this.loadInternal("cytoscape-expand-collapse");
349
- if (this.ExtensionModulesImporter) {
350
- // Wrappo il namespace in modo che possa dire la mia sul fatto che l'utente aggiunga un modulo o meno :D
351
- var wrappedCytoscape = {
352
- use: (moduleName, module) => {
353
- if (!module)
354
- this.service.log("E", this.service.loc("Received an undefined module. Make sure you are correctly loading it") + ": " + moduleName, false);
355
- if (["cytoscape-dagre", "cytoscape-html-node", "cytoscape-cxtmenu", "cytoscape-expand-collapse"].includes(moduleName))
356
- this.service.log("W", this.service.loc("Module") + " " + moduleName + " " + this.service.loc("is loaded and managed directly by this library. You don't need to import it or use it directly, just be sure to set the relative options"), false);
357
- else
358
- cytoscape.use(module);
359
- }
360
- };
361
- await this.ExtensionModulesImporter(wrappedCytoscape);
362
- }
363
- }
364
- /**
365
- * Metodo che serve per caricare tutte le estensioni della libreria in base a ciò che viene utilizzato con le opzioni definite dagli Input
366
- */
367
- performOperationsWithLoadedModules() {
368
- let anyCy = this.cy;
369
- // Utilizzo del layout, lo salvo per poterlo riutilizzare in futuro
370
- if (this.Layout) {
371
- this.LastLayout = JSON.parse(JSON.stringify(this.Layout));
372
- this.cy.layout(this.LastLayout).run();
373
- }
374
- // Utilizzo dell'HTML node
375
- if (this.NodeHTMLTemplates && this.NodeHTMLTemplates.length > 0) {
376
- this.HtmlNodeApi = anyCy.htmlnode();
377
- this.HtmlNodeApi.createHtmlNode(cytoscape, this.cy, this.NodeHTMLTemplates);
378
- }
379
- // Utilizzo del Context Menu
380
- if (this.UseContextMenu)
381
- this.ContextMenuOptions.forEach(o => { anyCy.cxtmenu(o); });
382
- // Utilizzo dell'expand collapse solo quando c'è una gerarchia di nodi
383
- if (this.NodesHierarchy && this.UseExpandCollapse)
384
- this.ExpandCollapseApi = anyCy.expandCollapse(this.ExpandCollapseOptions);
385
- // Utilizzo di estensioni extra, implementazione affidata al programmatore
386
- if (this.ExtensionModulesApplyer)
387
- this.ExtensionModulesApplyer(this.cy);
388
- }
389
- updateCardData() {
390
- if (!this.HtmlNodeApi) {
391
- this.service.log("E", "Cannot update NodeHTMLTemplates as they don't seem to be used");
392
- return;
393
- }
394
- this.HtmlNodeApi.update();
395
- }
396
- /**
397
- * Metodo interno per il caricamento dei moduli di estensione
398
- *
399
- * @param {'cytoscape-expand-collapse' | 'cytoscape-cxtmenu' | 'cytoscape-html-node' | 'cytoscape-dagre'} moduleId Modulo da caricare
400
- */
401
- async loadInternal(moduleId) {
402
- let toLoad = await this.service.importIfNeeded(moduleId);
403
- if (toLoad)
404
- cytoscape.use(toLoad);
405
- }
406
- /**
407
- * Metodo che basandosi sulle opzioni native eventualmente assegnate le completa con gli Input addizionali
408
- *
409
- * @returns {cy_.CytoscapeOptions} Opzioni finali unite da Input ed opzioni native
410
- */
411
- getCompletedOptions() {
412
- var opts = this.NativeOptions || {};
413
- opts.container = this.cyGraph.nativeElement;
414
- opts.style = opts.style || [];
415
- // Per tutte le cose per cui gli Input hanno priorità sovrascrivo gli originali delle opzioni
416
- if (this.NodeStyles || this.EdgeStyles) {
417
- opts.style = [];
418
- if (this.NodeStyles)
419
- opts.style.push({ selector: 'node', css: this.NodeStyles });
420
- if (this.EdgeStyles)
421
- opts.style.push({ selector: 'edge', css: this.EdgeStyles });
422
- }
423
- if (this.Elements)
424
- opts.elements = this.Elements;
425
- this.reviewCytoscapeElements(opts.elements);
426
- if (this.Layout)
427
- opts.layout = this.Layout;
428
- if (this.Readonly) {
429
- // Questo coso fa effetti strani....
430
- //opts.autolock = true;
431
- opts.autoungrabify = true;
432
- opts.autounselectify = false;
433
- opts.boxSelectionEnabled = true;
434
- opts.userZoomingEnabled = false;
435
- opts.userPanningEnabled = false;
436
- }
437
- return opts;
438
- }
439
- /**
440
- * Aggiustamenti degli elementi di Cytoscape.
441
- *
442
- * I nodi non vengono toccati.
443
- *
444
- * Per ogni edge viene controllato se è specificata una sorgente ed una destinazione, in caso contrario si cerca di dedurli dall'ID
445
- *
446
- * @param {cytoscape.ElementDefinition[]} elements Elementi da sistemare
447
- */
448
- reviewCytoscapeElements(elements, prevPositions) {
449
- let hasPreviousPositions = prevPositions && prevPositions.length > 0;
450
- let positionCache = {};
451
- if (hasPreviousPositions) {
452
- for (let i = 0; i < prevPositions.length; i++) {
453
- let item = prevPositions[i];
454
- if (!positionCache[item.data().id])
455
- positionCache[item.data().id] = item.position();
456
- }
457
- }
458
- for (let i = 0; i < elements.length; i++) {
459
- let el = elements[i];
460
- if (el.group == "edges" && (!el.data.source && !el.data.target)) {
461
- if (!el.data.id.includes("-"))
462
- this.service.log("E", "If you don't specify a source and a target for an edge you have to write its id in the format {source}-{target}");
463
- else {
464
- var sourceTarget = el.data.id.split('-');
465
- el.data.source = sourceTarget[0].trim();
466
- el.data.target = sourceTarget[1].trim();
467
- }
468
- }
469
- if (hasPreviousPositions && el.group == "nodes")
470
- el.position = positionCache[el.data.id];
471
- }
472
- }
473
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EsDiagramComponent, deps: [{ token: i1.EsDiagramService, optional: true }, { token: i2.EsDiagramDispatcher, optional: true }, { token: i3.ReactiveExtensions }], target: i0.ɵɵFactoryTarget.Component }); }
474
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: EsDiagramComponent, selector: "es-diagram", inputs: { name: "name", UseContextMenu: "UseContextMenu", ContextMenuOptions: "ContextMenuOptions", UseExpandCollapse: "UseExpandCollapse", ExpandCollapseOptions: "ExpandCollapseOptions", NativeOptions: "NativeOptions", Elements: "Elements", NodeStyles: "NodeStyles", EdgeStyles: "EdgeStyles", Readonly: "Readonly", AutoupdateSize: "AutoupdateSize", PreserveElementsPosition: "PreserveElementsPosition", AnimateLayoutChanges: "AnimateLayoutChanges", SmartSelection: "SmartSelection", SingleSelection: "SingleSelection", SmartSelectionStyles: "SmartSelectionStyles", ResizeThrottleTime: "ResizeThrottleTime", Layout: "Layout", NodeHTMLTemplates: "NodeHTMLTemplates", ExtensionModulesImporter: "ExtensionModulesImporter", ExtensionModulesApplyer: "ExtensionModulesApplyer" }, outputs: { onNodeClick: "onNodeClick", onNodeSelection: "onNodeSelection", onLayoutDone: "onLayoutDone", onLoaded: "onLoaded" }, viewQueries: [{ propertyName: "cyGraph", first: true, predicate: ["graph"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div #graph class=\"graph-wrapper {{name}}\"></div>", styles: [".graph-wrapper{height:100%;width:100%}.html-node-notransition{transition:none!important;transform:none!important}\n"] }); }
475
- }
476
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EsDiagramComponent, decorators: [{
477
- type: Component,
478
- args: [{ selector: 'es-diagram', template: "<div #graph class=\"graph-wrapper {{name}}\"></div>", styles: [".graph-wrapper{height:100%;width:100%}.html-node-notransition{transition:none!important;transform:none!important}\n"] }]
479
- }], ctorParameters: function () { return [{ type: i1.EsDiagramService, decorators: [{
480
- type: Optional
481
- }] }, { type: i2.EsDiagramDispatcher, decorators: [{
482
- type: Optional
483
- }] }, { type: i3.ReactiveExtensions }]; }, propDecorators: { cyGraph: [{
484
- type: ViewChild,
485
- args: ['graph']
486
- }], name: [{
487
- type: Input
488
- }], UseContextMenu: [{
489
- type: Input
490
- }], ContextMenuOptions: [{
491
- type: Input
492
- }], UseExpandCollapse: [{
493
- type: Input
494
- }], ExpandCollapseOptions: [{
495
- type: Input
496
- }], NativeOptions: [{
497
- type: Input
498
- }], Elements: [{
499
- type: Input
500
- }], NodeStyles: [{
501
- type: Input
502
- }], EdgeStyles: [{
503
- type: Input
504
- }], Readonly: [{
505
- type: Input
506
- }], AutoupdateSize: [{
507
- type: Input
508
- }], PreserveElementsPosition: [{
509
- type: Input
510
- }], AnimateLayoutChanges: [{
511
- type: Input
512
- }], SmartSelection: [{
513
- type: Input
514
- }], SingleSelection: [{
515
- type: Input
516
- }], SmartSelectionStyles: [{
517
- type: Input
518
- }], ResizeThrottleTime: [{
519
- type: Input
520
- }], Layout: [{
521
- type: Input
522
- }], NodeHTMLTemplates: [{
523
- type: Input
524
- }], ExtensionModulesImporter: [{
525
- type: Input
526
- }], ExtensionModulesApplyer: [{
527
- type: Input
528
- }], onNodeClick: [{
529
- type: Output
530
- }], onNodeSelection: [{
531
- type: Output
532
- }], onLayoutDone: [{
533
- type: Output
534
- }], onLoaded: [{
535
- type: Output
536
- }] } });
537
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXMtZGlhZ3JhbS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9lcy1kaWFncmFtcy9zcmMvbGliL2NvbXBvbmVudHMvZXMtZGlhZ3JhbS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9lcy1kaWFncmFtcy9zcmMvbGliL2NvbXBvbmVudHMvZXMtZGlhZ3JhbS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQWEsUUFBUSxFQUFFLE1BQU0sRUFBaUIsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBa0JqSSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFJMUQsT0FBTyxLQUFLLEdBQUcsTUFBTSxXQUFXLENBQUM7Ozs7O0FBQ2pDLGNBQWMsQ0FBQSxNQUFNLFNBQVMsR0FBUyxHQUFJLENBQUMsT0FBTyxDQUFBLENBQUMsQ0FBTyxHQUFJLENBQUMsT0FBTyxDQUFBLENBQUMsQ0FBQyxHQUFHLENBQUM7QUFFNUU7O0dBRUc7QUFNSCxNQUFNLE9BQU8sa0JBQWtCO0lBK043Qjs7OztPQUlHO0lBQ0gsWUFBZ0MsT0FBeUIsRUFBc0IsVUFBK0IsRUFBVSxJQUF3QjtRQUFoSCxZQUFPLEdBQVAsT0FBTyxDQUFrQjtRQUFzQixlQUFVLEdBQVYsVUFBVSxDQUFxQjtRQUFVLFNBQUksR0FBSixJQUFJLENBQW9CO1FBN05oSjs7V0FFRztRQUNNLFNBQUksR0FBVyxFQUFFLENBQUM7UUFFM0I7O1dBRUc7UUFDTSxtQkFBYyxHQUFZLEtBQUssQ0FBQztRQVN6Qzs7V0FFRztRQUNNLHNCQUFpQixHQUFZLEtBQUssQ0FBQztRQU81Qzs7OztXQUlHO1FBQ00sa0JBQWEsR0FBK0IsRUFBRSxDQUFDO1FBc0J4RDs7V0FFRztRQUNNLG1CQUFjLEdBQVksSUFBSSxDQUFD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QUFLO2dCQW1CRyx3QkFBd0I7c0JBQWhDLEtBQUs7Z0JBbUJHLHVCQUF1QjtzQkFBL0IsS0FBSztnQkFLSSxXQUFXO3NCQUFwQixNQUFNO2dCQUtHLGVBQWU7c0JBQXhCLE1BQU07Z0JBS0csWUFBWTtzQkFBckIsTUFBTTtnQkFLRyxRQUFRO3NCQUFqQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE9wdGlvbmFsLCBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXHJcblxyXG5pbXBvcnQgeyBDb250ZXh0TWVudU9wdGlvbnMgfSBmcm9tICcuLi9tb2RlbHMvY29tcG9uZW50L2NvbnRleHRtZW51L0NvbnRleHRNZW51T3B0aW9ucyc7XHJcbmltcG9ydCB7IEV4cGFuZENvbGxhcHNlT3B0aW9ucyB9IGZyb20gJy4uL21vZGVscy9jb21wb25lbnQvZ3JvdXBpbmcvRXhwYW5kQ29sbGFwc2VPcHRpb25zJztcclxuaW1wb3J0IHsgTm9kZUhUTUxUZW1wbGF0ZSB9IGZyb20gJy4uL21vZGVscy9jb21wb25lbnQvbm9kZXMvTm9kZUhUTUxUZW1wbGF0ZSc7XHJcblxyXG5pbXBvcnQgeyBCcmVhZHRoRmlyc3RMYXlvdXRPcHRpb25zSW1wbCB9IGZyb20gJy4uL21vZGVscy9sYXlvdXRzL0JyZWFkdGhGaXJzdExheW91dE9wdGlvbnNJbXBsJztcclxuaW1wb3J0IHsgQ2lyY2xlTGF5b3V0T3B0aW9uc0ltcGwgfSBmcm9tICcuLi9tb2RlbHMvbGF5b3V0cy9DaXJjbGVMYXlvdXRPcHRpb25zSW1wbCc7XHJcbmltcG9ydCB7IENvbmNlbnRyaWNMYXlvdXRPcHRpb25zSW1wbCB9IGZyb20gJy4uL21vZGVscy9sYXlvdXRzL0NvbmNlbnRyaWNMYXlvdXRPcHRpb25zSW1wbCc7XHJcbmltcG9ydCB7IENvc2VMYXlvdXRPcHRpb25zSW1wbCB9IGZyb20gJy4uL21vZGVscy9sYXlvdXRzL0Nvc2VMYXlvdXRPcHRpb25zSW1wbCc7XHJcbmltcG9ydCB7IERhZ3JlTGF5b3V0T3B0aW9uc0ltcGwgfSBmcm9tICcuLi9tb2RlbHMvbGF5b3V0cy9EYWdyZUxheW91dE9wdGlvbnNJbXBsJztcclxuaW1wb3J0IHsgR3JpZExheW91dE9wdGlvbnNJbXBsIH0gZnJvbSAnLi4vbW9kZWxzL2xheW91dHMvR3JpZExheW91dE9wdGlvbnNJbXBsJztcclxuaW1wb3J0IHsgTnVsbExheW91dE9wdGlvbnNJbXBsIH0gZnJvbSAnLi4vbW9kZWxzL2xheW91dHMvTnVsbExheW91dE9wdGlvbnNJbXBsJztcclxuaW1wb3J0IHsgUHJlc2V0TGF5b3V0T3B0aW9uc0ltcGwgfSBmcm9tICcuLi9tb2RlbHMvbGF5b3V0cy9QcmVzZXRMYXlvdXRPcHRpb25zSW1wbCc7XHJcbmltcG9ydCB7IFJhbmRvbUxheW91dE9wdGlvbnNJbXBsIH0gZnJvbSAnLi4vbW9kZWxzL2xheW91dHMvUmFuZG9tTGF5b3V0T3B0aW9uc0ltcGwnO1xyXG5cclxuaW1wb3J0IHsgRXNEaWFncmFtU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2VzLWRpYWdyYW0uc2VydmljZSc7XHJcbmltcG9ydCB7IEVzRGlhZ3JhbURpc3BhdGNoZXIgfSBmcm9tICcuLi9zZXJ2aWNlcy9lcy1kaWFncmFtLmRpc3BhdGNoZXInO1xyXG5pbXBvcnQgeyBSZXNpemVTZW5zb3IgfSBmcm9tIFwiLi4vZXh0ZW5zaW9ucy9SZXNpemVTZW5zb3JcIjtcclxuXHJcbmltcG9ydCB7IFJlYWN0aXZlRXh0ZW5zaW9ucyB9IGZyb20gJy4uL2V4dGVuc2lvbnMvUmVhY3RpdmVFeHRlbnNpb25zJztcclxuXHJcbmltcG9ydCAqIGFzIGN5XyBmcm9tICdjeXRvc2NhcGUnO1xyXG4vKiogQGlnbm9yZSAqL2NvbnN0IGN5dG9zY2FwZSA9ICg8YW55PmN5XykuZGVmYXVsdD8gKDxhbnk+Y3lfKS5kZWZhdWx0OiBjeV87XHJcblxyXG4vKipcclxuICogQ29tcG9uZW50ZSBjaGUgc2kgb2NjdXBhIGRpIGdyYWZpY2FyZSB1biBkaWFncmFtbWEgZSBkaSBnZXN0aXJuZSBpbCBjaWNsbyBkaSB2aXRhXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2VzLWRpYWdyYW0nLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9lcy1kaWFncmFtLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9lcy1kaWFncmFtLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIEVzRGlhZ3JhbUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XHJcblxyXG4gIC8qKlxyXG4gICAqIFJpZmVyaW1lbnRvIGFsbCdvZ2dldHRvIEhUTUwgc3UgY3VpIGNyZWFyZSBpbCBkaWFncmFtbWFcclxuICAgKi9cclxuICBAVmlld0NoaWxkKCdncmFwaCcpIGN5R3JhcGg6IEVsZW1lbnRSZWY7XHJcblxyXG4gIC8qKlxyXG4gICAqIE5vbWUgZGVsIGRpYWdyYW1tYSwgZm9uZGFtZW50YWxlIGFzc2VnbmFybG8gcGVyIHBlcm1ldHRlcmUgYWxsYSBsaWJyZXJpYSBkaSBzY2hlZHVsYXJuZSBsYSBjcmVhemlvbmVcclxuICAgKi9cclxuICBASW5wdXQoKSBuYW1lOiBzdHJpbmcgPSBcIlwiO1xyXG5cclxuICAvKipcclxuICAgKiBJbmRpY2Egc2UgdXRpbGl6emFyZSBpbCBtZW7DuSBjb250ZXN0dWFsZSBhIHJ1b3RhIGF0dG9ybm8gYWQgb2duaSBub2RvXHJcbiAgICovXHJcbiAgQElucHV0KCkgVXNlQ29udGV4dE1lbnU6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogSW5kaWNhIGxlIG9wemlvbmkgZGVsIG1lbsO5IGNvbnRlc3R1YWxlIHF1YWxvcmEgKipVc2VDb250ZXh0TWVudSoqIGZvc3NlICoqdHJ1ZSoqLlxyXG4gICAqIFxyXG4gICAqIE9nbmkgZWxlbWVudG8gZGkgcXVlc3RvIGFycmF5IMOoIHVuIHNlbGV0dG9yZSBjb24gaWwgbWVudSBkYSBtb3N0cmFyZSBwZXIgcXVlbGxhIGNhc2lzdGljYVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIENvbnRleHRNZW51T3B0aW9uczogQ29udGV4dE1lbnVPcHRpb25zW107XHJcblxyXG4gIC8qKlxyXG4gICAqIERpY2UgYWwgY29tcG9uZW50ZSBzZSBpbCBkaWFncmFtbWEgZGV2ZSB1dGlsaXp6YXJlIGlsIHNpc3RlbWEgZGkgZXN0ZW5zaW9uZSBwZXIgbCdleHBhbmQgZSBjb2xsYXBzZSBkZWkgZ3J1cHBpXHJcbiAgICovXHJcbiAgQElucHV0KCkgVXNlRXhwYW5kQ29sbGFwc2U6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogT3B6aW9uaSBuYXRpdmUgZGVsbCdlc3RlbnNpb25lIGV4cGFuZC1jb2xsYXBzZSwgdmVuZ29ubyBvdnZpYW1lbnRlIHV0aWxpenphdGUgc29sbyBzZSAqKlVzZUV4cGFuZENvbGxhcHNlKiogw6ggKip0cnVlKipcclxuICAgKi9cclxuICBASW5wdXQoKSBFeHBhbmRDb2xsYXBzZU9wdGlvbnM6IEV4cGFuZENvbGxhcHNlT3B0aW9ucztcclxuXHJcbiAgLyoqXHJcbiAgICogQmxvY2NvIGNvbXBsZXRvIGRlbGxlIG9wemlvbmksIGFsdGVybmF0aXZvIGFsbCdhc3NlZ25hemlvbmUgZGkgKipFbGVtZW50cyoqLCAqKk5vZGVTdHlsZXMqKiwgKipFZGdlU3R5bGVzKiosIGUgKipMYXlvdXQqKi5cclxuICAgKiBcclxuICAgKiBRdWFsb3JhIGVudHJhbWJlIHZlbmlzc2VybyBzcGVjaWZpY2F0ZSB2ZXJyw6AgZWZmZXR0dWF0YSB1bid1bmlvbmUgZnJhIHF1ZXN0ZSBvcHppb25pIGUgcXVlbGxlIHNwZWNpZmljYXRlLCBkYW5kbyBwcmlvcml0w6AgYWxsZSBzcGVjaWZpY2F0ZVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIE5hdGl2ZU9wdGlvbnM6IGN5dG9zY2FwZS5DeXRvc2NhcGVPcHRpb25zID0ge307XHJcblxyXG4gIC8qKlxyXG4gICAqIERlZmluaXppb25lIGRlZ2xpIGVsZW1lbnRpIGRhIG1vc3RyYXJlIG5lbCBkaWFncmFtbWFcclxuICAgKi9cclxuICBASW5wdXQoKSBFbGVtZW50czogY3l0b3NjYXBlLkVsZW1lbnREZWZpbml0aW9uW107XHJcblxyXG4gIC8qKlxyXG4gICAqIERlZmluaXppb25lIGRlZ2xpIHN0aWxpIGRlaSBub2RpXHJcbiAgICovXHJcbiAgQElucHV0KCkgTm9kZVN0eWxlczogY3l0b3NjYXBlLkNzcy5Ob2RlO1xyXG5cclxuICAvKipcclxuICAgKiBEZWZpbml6aW9uZSBkZWdsaSBzdGlsaSBkZWkgY29sbGVnYW1lbnRpIGZyYSBpIG5vZGlcclxuICAgKi9cclxuICBASW5wdXQoKSBFZGdlU3R5bGVzOiBjeXRvc2NhcGUuQ3NzLkVkZ2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIEluIHVuIGRpYWdyYW1tYSBpbiBzb2xhIGxldHR1cmEgdHV0dGUgbGUgaW50ZXJhemlvbmkgdXRlbnRlIHNvbm8gYW5udWxsYXRlXHJcbiAgICovXHJcbiAgQElucHV0KCkgUmVhZG9ubHk6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIEFnZ2lvcm5hIGF1dG9tYXRpY2FtZW50ZSBsZSBkaW1lbnNpb25pIGRlbCBkaWFncmFtbWEgcXVhbmRvIGNhbWJpYW5vIGxlIGRpbWVuc2lvbmkgZGVsbGEgZmluZXN0cmFcclxuICAgKi9cclxuICBASW5wdXQoKSBBdXRvdXBkYXRlU2l6ZTogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIEluZGljYSBkaSBtYW50ZW5lcmUgbGEgcG9zaXppb25lIGRlaSBub2RpIHF1YWxvcmEgdmVuaXNzZXJvIGNhbWJpYXRpIGRhbGwnSW5wdXQgKipFbGVtZW50cyoqLlxyXG4gICAqIFxyXG4gICAqIFNlIGwnSUQgZGkgdW4gbm9kbyDDqCB1Z3VhbGUgYWxsJ0lEIGRpIHVuIG5vZG8gcHJlc2VudGUgaW4gcHJlY2VkZW56YSwgaWwgbnVvdm8gbm9kbyBuZSBlcmVkaXRlcsOgIGxhIHBvc2l6aW9uZVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIFByZXNlcnZlRWxlbWVudHNQb3NpdGlvbjogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIFF1YWxvcmEgdmVuaXNzZSBtb2RpZmljYXRvIGwnSW5wdXQgKipFbGVtZW50cyoqLCBwaXV0dG9zdG8gY2hlIG1ldHRlcmUgc2VtcGxpY2VtZW50ZSBpbCBudW92byBFbGVtZW50byBpbiBiYXNlIGFsIExheW91dCBwcmVjZWRlbnRlLCBhcHBsaWNhIGFuY2hlIHVuJ2FuaW1hemlvbmUgXHJcbiAgICogXHJcbiAgICogRnVuemlvbmEgc29sYW1lbnRlIHNlIGlsICoqTGF5b3V0KiogY29ycmVudGUgZGVsIGRpYWdyYW1tYSBzdXBwb3J0YSBsZSBhbmltYXppb25pXHJcbiAgICovXHJcbiAgQElucHV0KCkgQW5pbWF0ZUxheW91dENoYW5nZXM6IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICAvKipcclxuICAgKiBBdHRpdmEgdW5hIG1vZGFsaXTDoCBkaSBzZWxlemlvbmUgXCJzbWFydFwiLi4uIG8gcGVybG9tZW5vIFwic21hcnRlclwiIGRlbCBkZWZhdWx0IGRpIEN5dG9zY2FwZS5cclxuICAgKiBcclxuICAgKiAtIElsIGNsaWNrIGRpIHVuIGVsZW1lbnRvIG5vbiBzZWxlemlvbmF0byBsbyBzZWxlemlvbmFcclxuICAgKiAtIElsIGNsaWNrIGRpIHVuIGVsZW1lbnRvIHNlbGV6aW9uYXRvIGxvIGRlc2VsZXppb25hXHJcbiAgICogLSBMbyBzdGF0byBkaSBzZWxlemlvbmUgdmllbmUgcGVyc2lzdGl0byBzdWxsJ29nZ2V0dG8gb3JpZ2luYWxlIGludmVjZSBkaSByaW1hbmVyZSBpbiB1biBpbnRlcm5hbFxyXG4gICAqIC0gQWxsJ2Fzc2VnbmF6aW9uZSBkaSBvZ2dldHRpIHNlbGV6aW9uYXRpLCBxdWVzdGkgdmVuZ29ubyBtYXJjYXRpIGNvcnJldHRhbWVudGUgY29uIGwnb3ZlcmxheSBkaSBzZWxlemlvbmVcclxuICAgKiBcclxuICAgKiBOLkI6IGxhIGNoaWFtYXRhIGFsbCdldmVudG8gKipvbk5vZGVDbGljayoqIGF2dmllbmUgKipET1BPKiogbGEgZ2VzdGlvbmUgZGVsbGEgc2VsZXppb25lXHJcbiAgICovXHJcbiAgQElucHV0KCkgU21hcnRTZWxlY3Rpb246IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogSW5kaWNhIGRpIHNlbGV6aW9uYXJlIHVuIGVsZW1lbnRvIHBlciB2b2x0YSBxdWFsb3JhICoqU21hcnRTZWxlY3Rpb24qKiBmb3NzZSBhdHRpdm9cclxuICAgKi9cclxuICBASW5wdXQoKSBTaW5nbGVTZWxlY3Rpb246IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogQ1NTIHBlciBsYSBncmFmaWNhemlvbmUgZGVsbGEgc2VsZXppb25lIGRlaSBub2RpLiBRdWFuZG8gdW4gbm9kbyB2ZXJyw6Agc2VsZXppb25hdG8gYXZyw6Agc29wcmEgZGkgc2UgdW4gb3ZlcmxheSBjaGUgJ3Nib3JkYScgZGkgKipvdmVybGF5LXBhZGRpbmcqKiBwaXhlbCxcclxuICAgKiBkaSBjb2xvcmUgKipvdmVybGF5LWNvbG9yKiogZSBjb24gdW4gb3BhY2l0w6AgKipvdmVybGF5LW9wYWNpdHkqKlxyXG4gICAqIFxyXG4gICAqIEFzc2VnbmFuZG8gXCJ7fVwiIGEgcXVlc3RvIGlucHV0LCBsYSBTbWFydCBzZWxlY3Rpb24gdmllbmUgZ2VzdGl0YSBtYSBsYSBnZXN0aW9uZSBncmFmaWNhIMOoIGFmZmlkYXRhIGFsbCd1dGVudGUsXHJcbiAgICogYWQgZXNlbXBpbyB1c2FuZG8gZGVpICoqTm9kZUhUTUxUZW1wbGF0ZXMqKiBjaGUgZGVmaW5pc2Nhbm8gc2VsZXR0b3JpIHN1IG5vZGkgXCI6c2VsZWN0ZWRcIlxyXG4gICAqIFxyXG4gICAqIEBkZWZhdWx0IHsnb3ZlcmxheS1jb2xvcic6J2JsdWUnLCdvdmVybGF5LW9wYWNpdHknOjAuNSwnb3ZlcmxheS1wYWRkaW5nJzo3fVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIFNtYXJ0U2VsZWN0aW9uU3R5bGVzOiB7ICdvdmVybGF5LWNvbG9yJzogc3RyaW5nLCAnb3ZlcmxheS1vcGFjaXR5JzogbnVtYmVyLCAnb3ZlcmxheS1wYWRkaW5nJzogbnVtYmVyIH0gPSBudWxsXHJcblxyXG4gIC8qKlxyXG4gICAqIFBlcmlvZG8gZGkgdGhyb3R0bGUgZGEgcXVhbmRvIHZpZW5lIGVmZmV0dHVhdG8gdW4gcmVzaXplIGEgcXVhbmRvIHJpY2FsY29sYXJlIGxlIGRpbWVuc2lvbmkgZGVsIGRpYWdyYW1tYS5cclxuICAgKiBcclxuICAgKiBQdcOyIGVzc2VyZSB0ZW51dG8gYSAwIChyZWRyYXcgaXN0YW50YW5lbykgZmluY2jDqSBub24gY2kgc29ubyBwcm9ibGVtaSBkaSBwcmVzdGF6aW9uaSBjb24gZXZlbnR1YWxtZW50ZSB0YW50aSByZXNpemUgYSBwb2NhIGRpc3RhbnphIGwndW5vIGRhbGwnYWx0cm8uXHJcbiAgICovXHJcbiAgQElucHV0KCkgUmVzaXplVGhyb3R0bGVUaW1lOiBudW1iZXIgPSAwO1xyXG5cclxuICAvKipcclxuICAgKiBMYXlvdXQgZGkgb3JkaW5hbWVudG8gZGVpIG5vZGlcclxuICAgKi9cclxuICBASW5wdXQoKSBMYXlvdXQ6IEJyZWFkdGhGaXJzdExheW91dE9wdGlvbnNJbXBsIHwgQ2lyY2xlTGF5b3V0T3B0aW9uc0ltcGwgfCBDb25jZW50cmljTGF5b3V0T3B0aW9uc0ltcGwgfFxyXG4gICAgQ29zZUxheW91dE9wdGlvbnNJbXBsIHwgRGFncmVMYXlvdXRPcHRpb25zSW1wbCB8IEdyaWRMYXlvdXRPcHRpb25zSW1wbCB8IE51bGxMYXlvdXRPcHRpb25zSW1wbCB8IFByZXNldExheW91dE9wdGlvbnNJbXBsIHxcclxuICAgIFJhbmRvbUxheW91dE9wdGlvbnNJbXBsO1xyXG5cclxuICAvKipcclxuICAgKiBUZW1wbGF0ZSBIVE1MIGRhIGFwcGxpY2FyZSBhaSBub2RpIHBlciBkYXJnbGkgc3RpbGkgcGFydGljb2xhcmksIGRpdmVyc2kgZGFsbGUgc2hhcGUgZGkgZGVmYXVsdFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIE5vZGVIVE1MVGVtcGxhdGVzOiBOb2RlSFRNTFRlbXBsYXRlW107XHJcblxyXG4gIC8qKlxyXG4gICAqIEZvcm5pc2NlIGlsIGdsb2JhbCBkZWxsYSBsaWJyZXJpYSAobmFtZXNwYWNlICoqY3l0b3NjYXBlKiopIGUgc2kgYXNwZXR0YSBjaGUgZG9wbyBvcGVyYXppb25pIGRpIGltcG9ydGF6aW9uZSBcclxuICAgKiBsYXNjaWF0ZSBhbGwndXRlbnRlIHZlbmdhbm8gYWdnaXVudGkgdHV0dGkgaSBtb2R1bGkgZGVzaWRlcmF0aS4gXHJcbiAgICogXHJcbiAgICogw4ggKipmb25kYW1lbnRhbGUqKiBjaGUgaWwgcHJpbW8gcGFyYW1ldHJvIChpbCBub21lIGRlbCBtb2R1bG8pIHNpYSB1Z3VhbGUgYSBjacOyIGRpIGN1aSB2aWVuZSBmYXR0byBpbCByZXF1aXJlIGluIG1vZG8gY2hlIGxhIGxpYnJlcmlhXHJcbiAgICogcG9zc2EgY29udHJvbGxhcmUgY2hlIGlsIG1vZHVsbyBpbXBvcnRhdG8gbm9uIHNpYSBnacOgIHN0YXRvIGltcG9ydGF0byBpbiBwcmVjZWRlbnphXHJcbiAgICogXHJcbiAgICogIyMgRXNlbXBpbzpcclxuICAgKiBcclxuICAgKiBgYGB0eXBlc2NyaXB0XHJcbiAgICogKGdsb2JhbCkgPT4ge1xyXG4gICAqICAgIHJldHVybiBpbXBvcnQoXCJjeXRvc2NhcGUtZXh0ZW5zaW9uLWxpYnJhcnlcIikudGhlbihtb2R1bGUgPT4gZ2xvYmFsLnVzZShcImN5dG9zY2FwZS1leHRlbnNpb24tbGlicmFyeVwiLCBtb2R1bGUuZGVmYXVsdCkpO1xyXG4gICAqIFxyXG4gICAqICAgIC4uLlxyXG4gICAqIH1cclxuICAgKiBgYGBcclxuICAgKi9cclxuICBASW5wdXQoKSBFeHRlbnNpb25Nb2R1bGVzSW1wb3J0ZXI6IChnbG9iYWw6IHsgdXNlOiAobW9kdWxlTmFtZTogc3RyaW5nLCBtb2R1bGU6IHZvaWQgfCBjeXRvc2NhcGUuRXh0KSA9PiB2b2lkIH0pID0+IFByb21pc2U8YW55PiA9IG51bGw7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZvcm5pc2NlIGwnaXN0YW56YSBhdHR1YWxlIGRpIEN5dG9zY2FwZSBkYSBjdWkgw6ggcG9zc2liaWxlIHByZW5kZXJlIGxlIGxpYnJlcmllIGRpIGVzdGVuc2lvbmUgY2FyaWNhdGUgaW4gKipFeHRlbnNpb25Nb2R1bGVzSW1wb3J0ZXIqKlxyXG4gICAqIGUgY29uZmlndXJhcmxlIGluIGJhc2UgYWkgY29tcG9ydGFtZW50aSBzcGVjaWZpY2lcclxuICAgKiBcclxuICAgKiAjIyBFc2VtcGlvOlxyXG4gICAqIFxyXG4gICAqIGBgYHR5cGVzY3JpcHRcclxuICAgKiAoY3l0b3NjYXBlQ29yZSkgPT4ge1xyXG4gICAqICAgIC8vIEZhcmUgcXVlc3RvIGxhdm9ybyBwZXIgb2duaSBlc3RlbnNpb25lIGNhcmljYXRhXHJcbiAgICogICAgbGV0IGV4dGVuc2lvbkNvbmZpZ3VyYXRpb24gPSB7IC4uLiB9O1xyXG4gICAqICAgIGxldCBleHRlbnNpb25JbnN0YW5jZSA9IGN5dG9zY2FwZUNvcmUuZXh0ZW5zaW9uTGlicmFyeShleHRlbnNpb25Db25maWd1cmF0aW9uKTtcclxuICAgKiAgICBleHRlbnNpb25JbnN0YW5jZS5kb1NvbWV0aGluZ1NwZWNpZmljVG9UaGlzRXh0ZW5zaW9uKCk7XHJcbiAgICogXHJcbiAgICogICAgLi4uXHJcbiAgICogfVxyXG4gICAqIGBgYFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIEV4dGVuc2lvbk1vZHVsZXNBcHBseWVyOiAoY3l0b3NjYXBlQ29yZTogY3l0b3NjYXBlLkNvcmUpID0+IHZvaWQgPSBudWxsO1xyXG5cclxuICAvKipcclxuICAgKiBFdmVudG8gbGFuY2lhdG8gYWwgY2xpY2sgZGkgdW4gbm9kbywgY29udGllbmUgbCdvZ2dldHRvICoqZGF0YSoqIGRlbCBub2RvIGluIHF1ZXN0aW9uZVxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKSBvbk5vZGVDbGljazogRXZlbnRFbWl0dGVyPHsgZGF0YTogYW55IH0+ID0gbmV3IEV2ZW50RW1pdHRlcjx7IGRhdGE6IGFueSB9PigpO1xyXG5cclxuICAvKipcclxuICAgKiBFdmVudG8gbGFuY2lhdG8gYWxsYSBzZWxlemlvbmUgbyBkZXNlbGV6aW9uZSBkaSB1biBub2RvLCBjb250aWVuZSBsJ29nZ2V0dG8gKipkYXRhKiogZGVsIG5vZG8gaW4gcXVlc3Rpb25lIGUgaW5mb3JtYXppb25pIHN1bCBzdW8gc3RhdG8gZGkgc2VsZXppb25lXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIG9uTm9kZVNlbGVjdGlvbjogRXZlbnRFbWl0dGVyPHsgZGF0YTogYW55LCBzZWxlY3RlZDogYm9vbGVhbiB9PiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBkYXRhOiBhbnksIHNlbGVjdGVkOiBib29sZWFuIH0+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEV2ZW50byBsYW5jaWF0byBhbCB0ZXJtaW5lIGRlbCBMYXlvdXRpbmcuIFNlIHNpIHZ1b2xlIGVzZWd1aXJlIGNvZGljZSBkb3BvIGNoZSBpbCBMYXlvdXQgw6ggZmF0dG8gZSBjb21wbGV0YW1lbnRlIGdyYWZpY2F0bywgcXVlc3RvIMOoIGlsIHB1bnRvXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIG9uTGF5b3V0RG9uZTogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICAvKipcclxuICAgKiBFdmVudG8gbGFuY2lhdG8gYWwgdGVybWluZSBkZWwgY2FyaWNhbWVudG8gZGVsIGRpYWdyYW1tYVxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKSBvbkxvYWRlZDogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICAvKipcclxuICAgKiBWYXJpYWJpbGUgc3UgY3VpIHNhbHZhcnNpIHNlIGkgbm9kaSBoYW5ubyB1bmEgZ2VyYXJjaGlhIGEgZ3J1cHBpIG8gbm8uIFNlcnZlIHBlciBwb2kgY2FyaWNhcmUgbCdlc3RlbnNpb25lIGV4cGFuZC1jb2xsYXBzZSBxdWFsb3JhIGZvc3NlIHJpY2hpZXN0YVxyXG4gICAqL1xyXG4gIHByaXZhdGUgTm9kZXNIaWVyYXJjaHk6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIEluZGljYSBzZSBpbCByZW5kZXJpbmcgZGVsIGRpYWdyYW1tYSDDqCB0ZXJtaW5hdG9cclxuICAgKi9cclxuICBwcml2YXRlIFJlbmRlcmVkOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIElzdGFuemEgZGVsIGRpYWdyYW1tYSBhdHR1YWxtZW50ZSBpbiB1c29cclxuICAgKi9cclxuICBwdWJsaWMgY3k6IGN5dG9zY2FwZS5Db3JlXHJcblxyXG4gIC8qKlxyXG4gICAqIEFwaSBkZWxsJ2VzdGVuc2lvbmUgZXhwYW5kLWNvbGxhcHNlIHBlciBwZXJtZXR0ZXJlIGRpIGVmZmV0dHVhcmUgb3BlcmF6aW9uaSBkYWxsJ2VzdGVybm8gZGVsIGRpYWdyYW1tYS4gVmVuZ29ubyB2YWxvcml6emF0ZSBzZSAqKlVzZUV4cGFuZENvbGxhcHNlKiogw6ggKip0cnVlKipcclxuICAgKi9cclxuICBwdWJsaWMgRXhwYW5kQ29sbGFwc2VBcGk6IGFueSA9IG51bGw7XHJcblxyXG4gIC8qKlxyXG4gICAqIEFwaSBkZWxsJ2VzdGVuc2lvbmUgaHRtbC1ub2RlIHBlciBwZXJtZXR0ZXJlIGRpIGVmZmV0dHVhcmUgb3BlcmF6aW9uaSBkYWxsJ2VzdGVybm8gZGVsIGRpYWdyYW1tYS4gVmVuZ29ubyB2YWxvcml6emF0ZSBzZSBzb25vIGltcG9zdGF0aSBkZWkgKipOb2RlSFRNTFRlbXBsYXRlcyoqXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBIdG1sTm9kZUFwaTogYW55ID0gbnVsbDtcclxuXHJcbiAgLyoqXHJcbiAgICogT3NzZXJ2YXRvcmUgZGVsbGUgbW9kaWZpY2hlIGFsIGNvbnRlbml0b3JlIGRlbCBkaWFncmFtbWFcclxuICAgKi9cclxuICBwcml2YXRlIHJlc2l6ZU9ic2VydmVyOiBSZXNpemVTZW5zb3I7XHJcblxyXG4gIC8qKlxyXG4gICAqIFJpZmVyaW1lbnRvIGFsbCd1bHRpbW8gbGF5b3V0IHV0aWxpenphdG8uIFZpZW5lIHJpYXBwbGljYXRvIHF1YWxvcmEgdmVuaXNzZSBjYW1iaWF0byBsJ0lucHV0ICoqRWxlbWVudHMqKi5cclxuICAgKiBcclxuICAgKiBOb24gdXRpbGl6em8gaWwgbWFrZUxheW91dHMgcGVyY2jDqSBhbHRyaW1lbnRpIHJpc2NoaWVyZWkgZGkgY3JlYXJlIHVuIGxheW91dCByaWZlcml0byBhIFggZWxlbWVudGksIG5lIGFnZ2l1bmdvIDEsIHJpYXBwbGljbyBpbCBMYXlvdXQgXHJcbiAgICogbWEgbWkgdmllbmUgcmlhcHBsaWNhdG8gYSBYIGVsZW1lbnRpIGludmVjZSBjaGUgWCArIDFcclxuICAgKi9cclxuICBwcml2YXRlIExhc3RMYXlvdXQ6IGN5dG9zY2FwZS5MYXlvdXRPcHRpb25zO1xyXG5cclxuICAvKipcclxuICAgKiBDb3N0cnV0dG9yZVxyXG4gICAqIFxyXG4gICAqIEBpZ25vcmVcclxuICAgKi9cclxuICBjb25zdHJ1Y3RvcihAT3B0aW9uYWwoKSBwcml2YXRlIHNlcnZpY2U6IEVzRGlhZ3JhbVNlcnZpY2UsIEBPcHRpb25hbCgpIHByaXZhdGUgZGlzcGF0Y2hlcjogRXNEaWFncmFtRGlzcGF0Y2hlciwgcHJpdmF0ZSBleHRzOiBSZWFjdGl2ZUV4dGVuc2lvbnMpIHsgfVxyXG5cclxuICAvKipcclxuICAgKiBAaWdub3JlIFxyXG4gICAqIFxyXG4gICAqIEFuZ3VsYXIgUGlwZWxpbmVcclxuICAgKi9cclxuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgaWYgKCF0aGlzLnNlcnZpY2UgfHwgIXRoaXMuZGlzcGF0Y2hlcilcclxuICAgICAgdGhyb3cgXCJJbCBtb2R1bG8gQGVzZmFlbnphL2RpYWdyYW1zIG5vbiDDqCBzdGF0byBpbXBvcnRhdG8gY29uIGlsIGZvclJvb3QoKTtcIjtcclxuXHJcbiAgICB0aGlzLmRpc3BhdGNoTG9hZENoYXJ0KCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBbGwnb25EZXN0cm95IHJpcHVsaXNjbyBsYSBtZW1vcmlhIGRhbCBkaWFncmFtbWFcclxuICAgKi9cclxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICBpZiAodGhpcy5yZXNpemVPYnNlcnZlcikge1xyXG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyLmRpc3Bvc2UoKTtcclxuICAgICAgdGhpcy5yZXNpemVPYnNlcnZlciA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuY3kpIHtcclxuICAgICAgdGhpcy5zZXJ2aWNlLmxvZyhcIklcIiwgXCJEaWFncmFtXCIgKyBcIiBcIiArIHRoaXMubmFtZSArIFwiOiBVbmxvYWRpbmcgZGVzdHJveWVkIGRpYWdyYW1cIiwgZmFsc2UpO1xyXG4gICAgICB0aGlzLmN5LmRlc3Ryb3koKTtcclxuICAgICAgdGhpcy5kaXNwYXRjaGVyLmRlcmVnaXN0ZXIodGhpcy5uYW1lKTtcclxuICAgIH1cclxuICAgIGVsc2VcclxuICAgICAgdGhpcy5zZXJ2aWNlLmxvZyhcIklcIiwgXCJDaGFydCBcIiArIHRoaXMubmFtZSArIFwiOiBVbmxvYWRpbmcgdW5jcmVhdGVkIGNoYXJ0IGNvbXBvbmVudC4gSXQgcHJvYmFibHkgd2FzIGEgZHVwbGljYXRlZFwiLCBmYWxzZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RyYSBpbCBkaWFncmFtbWEgYXR0dWFsZSBuZWwgRGlzcGF0Y2hlciBpbiBtb2RvIGNoZSB2ZW5nYSBjYXJpY2F0byBhcHBlbmEgcG9zc2liaWxlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBkaXNwYXRjaExvYWRDaGFydCgpOiB2b2lkIHtcclxuICAgIHRoaXMuZGlzcGF0Y2hlci5yZWdpc3Rlcih0aGlzLm5hbWUsICgpID0+IHsgcmV0dXJuIHRoaXMucmVuZGVyKCk7IH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQGlnbm9yZSBcclxuICAgKiBcclxuICAgKiBBbmd1bGFyIFBpcGVsaW5lOiBHZXN0aW9uZSByaS1ncmFmaWNhemlvbmUgZGVsIGRpYWdyYW1tYSwgc2UgcG9zc2liaWxlXHJcbiAgICovXHJcbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiBhbnkge1xyXG4gICAgbGV0IHRvQ2hlY2sgPSBbXCJUZW1wbGF0ZXNcIiwgXCJVc2VDb250ZXh0TWVudVwiLCBcIkNvbnRleHRNZW51T3B0aW9uc1wiLCBcIlVzZUV4cGFuZENvbGxhcHNlXCIsIFwiRXhwYW5kQ29sbGFwc2VPcHRpb25zXCIsIFwiTm9kZVN0eWxlc1wiLCBcIkVkZ2VTdHlsZXNcIiwgXCJOYXRpdmVPcHRpb25zXCJdO1xyXG5cclxuICAgIGlmICh0aGlzLlJlbmRlcmVkICYmIHRvQ2hlY2suc29tZSh0ID0+IGNoYW5nZXNbdF0pKVxyXG4gICAgICB0aGlzLnNlcnZpY2UubG9nKFwiV1wiLCBcIlJlZHJhdyBiYXNlZCBvbiBkeW5hbWljIElucHV0IGNoYW5nZSBpcyBzdXBwb3J0ZWQgb25seSBmb3IgJ0VsZW1lbnRzJyBhbmQgJ0xheW91dCcgaW5wdXRzLCBwbGVhc2UgZGVzdHJveSB0aGUgY29tcG9uZW50IGFuZCByZWNyZWF0ZSBpdCB3aXRoIHRoZSBuZXcgc2V0dGluZ3NcIik7XHJcblxyXG4gICAgbGV0IGVsZW1lbnRDaGFuZ2VzID0gY2hhbmdlc1tcIkVsZW1lbnRzXCJdO1xyXG4gICAgbGV0IGxheW91dENoYW5nZXMgPSBjaGFuZ2VzW1wiTGF5b3V0XCJdO1xyXG4gICAgaWYgKGVsZW1lbnRDaGFuZ2VzICYmICFlbGVtZW50Q2hhbmdlcy5maXJzdENoYW5nZSkge1xyXG4gICAgICB0aGlzLnNlcnZpY2UubG9nKFwiSVwiLCBcIkVsZW1lbnRzIGhhdmUgYmVlbiBjaGFuZ2VkIGFmdGVyIGRpYWdyYW0gaW5pdGlhbGl6YXRpb25cIik7XHJcblxyXG4gICAgICAvLyBDYW1iaWFtZW50byBhZ2xpIEVsZW1lbnRpOiByaXB1bGlzY28gZ2xpIGVsZW1lbnRpIHZlY2NoaSwgcHJlbmRvIGkgbnVvdmksIGxpIHNpc3RlbW8gZSBsaSByaWFzc2Vnbm8uIFxyXG4gICAgICAvLyBTZSBpbCBudW92byBJbnB1dCBFbGVtZW50cyDDqCByb2JhIHN0cmFuYSBtaSBsaW1pdG8gYSByaXB1bGlyZSBpbCBkaWFncmFtbWFcclxuICAgICAgLy8gU2UgY3l0b3NjYXBlIGF2ZXZhIGdpw6AgZGVnbGkgZWxlbWVudGkgcHJlY2VkZW50ZW1lbnRlIG5lIHByZW5kbyBsZSBwb3NpemlvbmkgaW4gbW9kbyBkYSByaWRpc2VnbmFybGkgcGFydGVuZG8gZGFsbG8gc3Rlc3NvIHB1bnRvIChjYXJpbm8gcGVyIGxlIGFuaW1hemlvbmkpXHJcbiAgICAgIGxldCBlbGVtZW50cyA9IGVsZW1lbnRDaGFuZ2VzPy5jdXJyZW50VmFsdWU7XHJcbiAgICAgIGxldCBwcmV2aW91c19lbGVtZW50cyA9IHRoaXMuUHJlc2VydmVFbGVtZW50c1Bvc2l0aW9uID8gPGFueT50aGlzLmN5Lm5vZGVzKCkgOiBudWxsO1xyXG5cclxuICAgICAgdGhpcy5jeS5lbGVtZW50cygpLnJlbW92ZSgpO1xyXG4gICAgICBpZiAoZWxlbWVudHMgJiYgZWxlbWVudHMubGVuZ3RoICYmIGVsZW1lbnRzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICB0aGlzLnJldmlld0N5dG9zY2FwZUVsZW1lbnRzKGVsZW1lbnRzLCBwcmV2aW91c19lbGVtZW50cyk7XHJcbiAgICAgICAgdGhpcy5jeS5hZGQoZWxlbWVudHMpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5TbWFydFNlbGVjdGlvbilcclxuICAgICAgICAgIHRoaXMuc2V0dXBFbGVtZW50c1NlbGVjdGlvbklmTmVlZGVkKCk7XHJcblxyXG4gICAgICAgIC8vIFNlIHNvbG8gZ2xpIGVsZW1lbnRpIGNhbWJpYW5vLCByaWFwcGxpY28gaWwgTGF5b3V0IHByZWNlZGVudGVcclxuICAgICAgICBpZiAoIWxheW91dENoYW5nZXMgJiYgdGhpcy5MYXN0TGF5b3V0KSB7XHJcblxyXG4gICAgICAgICAgLy8gU2UgZGV2byBhbmltYXJlIGxlIG1vZGlmY2hlIGFsIGxheW91dCBmb3J6byBpbCBwYXJhbWV0cm8gcmVsYXRpdm9cclxuICAgICAgICAgIGlmICh0aGlzLkFuaW1hdGVMYXlvdXRDaGFuZ2VzKVxyXG4gICAgICAgICAgICAoPGFueT50aGlzLkxhc3RMYXlvdXQpLmFuaW1hdGUgPSB0cnVlO1xyXG5cclxuICAgICAgICAgIHRoaXMuY3kubGF5b3V0KHRoaXMuTGFzdExheW91dCkucnVuKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gU2UgaWwgbGF5b3V0IGNhbWJpYSBsbyBhcHBsaWNvIGUgbWUgbG8gc2Fsdm8gY29tZSBsYXlvdXQgcHJlY2VkZW50ZSBwZXIgaWwgZnV0dXJvXHJcbiAgICBpZiAobGF5b3V0Q2hhbmdlcyAmJiAhbGF5b3V0Q2hhbmdlcy5maXJzdENoYW5nZSkge1xyXG4gICAgICB0aGlzLnNlcnZpY2UubG9nKFwiSVwiLCBcIkxheW91dCBoYXZlIGJlZW4gY2hhbmdlZCBhZnRlciBkaWFncmFtIGluaXRpYWxpemF0aW9uXCIpO1xyXG4gICAgICB0aGlzLkxhc3RMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGxheW91dENoYW5nZXMuY3VycmVudFZhbHVlKSk7XHJcbiAgICAgIHRoaXMuY3kubGF5b3V0KHRoaXMuTGFzdExheW91dCkucnVuKClcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEVmZmV0dHVhIGlsIHJlbmRlcmluZyBkZWwgZGlhZ3JhbW1hXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhc3luYyByZW5kZXIoKSB7XHJcblxyXG4gICAgLy8gVGlybyBmdW9yaSBsZSBvcHppb25pIGNvbiBjdWkgZ2VuZXJhcmUgaWwgZGlhZ3JhbW1hXHJcbiAgICBsZXQgY3lPcHRpb25zID0gdGhpcy5nZXRDb21wbGV0ZWRPcHRpb25zKCk7XHJcbiAgICB0aGlzLk5vZGVzSGllcmFyY2h5ID0gY3lPcHRpb25zLmVsZW1lbnRzICYmICg8Y3lfLkVsZW1lbnREZWZpbml0aW9uW10+Y3lPcHRpb25zLmVsZW1lbnRzKS5zb21lKHQgPT4gdC5kYXRhLnBhcmVudCk7XHJcblxyXG4gICAgLy8gQ2FyaWNvIGV2ZW50dWFsaSBjbGFzc2kgZGkgZXN0ZW5zaW9uZSBjaGUgc2Vydm9ub1xyXG4gICAgYXdhaXQgdGhpcy5wZXJmb3JtTW9kdWxlc0xvYWRpbmcoKTtcclxuXHJcbiAgICAvLyBHZW5lcm8gaWwgZGlhZ3JhbW1hXHJcbiAgICB0aGlzLmN5ID0gY3l0b3NjYXBlKGN5T3B0aW9ucyk7XHJcblxyXG4gICAgLy8gQ29sbGVnbyBnbGkgZXZlbnRpIGFsIGNvbXBvbmVudGVcclxuICAgIHRoaXMuYmluZEN5dG9zY2FwZUV2ZW50cygpO1xyXG5cclxuICAgIC8vIFV0aWxpenpvIGxlIGNsYXNzaSBkaSBlc3RlbnNpb25lIGNhcmljYXRlIHByZWNlZGVudGVtZW50ZSBwZXIgZmFyZSBpbCByZXN0byBkZWxsZSBtaWUgb3BlcmF6aW9uaVxyXG4gICAgdGhpcy5wZXJmb3JtT3BlcmF0aW9uc1dpdGhMb2FkZWRNb2R1bGVzKCk7XHJcblxyXG4gICAgLy8gSW1wb3N0byBsYSB2YXJpYWJpbGUgUmVuZGVyZWQgYSB0cnVlIGluIG1vZG8gY2hlIHNlIGRhIGFkZXNzbyB2ZW5nb25vIGZhdHRlIG1vZGlmaWNoZSBjaGUgZG92cmViYmVybyBjYXVzYXJlIHVuIHJlZHJhdyBwb3NzbyBhY2Nvcmdlcm1lbmVcclxuICAgIC8vIGUgbWFuZGFyZSBhIGNhZ2FyZSBsbyBzdHJvbnpvIGRpIHR1cm5vXHJcbiAgICB0aGlzLlJlbmRlcmVkID0gdHJ1ZTtcclxuXHJcbiAgICAvLyBTZSBkZXZvIGFnZ2lvcm5hcmUgaW4gYXV0b21hdGljbyBpbiBiYXNlIGFsbGEgZGltZW5zaW9uZSBkZWwgY29udGVuaXRvcmUgY29sbGVnbyBpbCBSZXNpemVPYnNlcnZlclxyXG4gICAgaWYgKHRoaXMuQXV0b3VwZGF0ZVNpemUpXHJcbiAgICAgIHRoaXMubGlzdGVuT25DaGFuZ2VzKCk7XHJcblxyXG4gICAgaWYgKHRoaXMuU21hcnRTZWxlY3Rpb24pIHtcclxuICAgICAgdGhpcy5zZXR1cFNlbGVjdGlvblN0eWxlcygpO1xyXG4gICAgICB0aGlzLnNldHVwRWxlbWVudHNTZWxlY3Rpb25JZk5lZWRlZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMub25Mb2FkZWQuZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUHJlbmRlIHR1dHRpIGdsaSBlbGVtZW50aSBhcHBlbmEgYXNzZWduYXRpLCBlIHNlIHF1YWxjdW5vIGVyYSBzZWxlemlvbmF0byBsYSBzaXR1YXppb25lIHZpZW5lIHBlcnNpc3RpdGEgc3UgY3l0b3NjYXBlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZXR1cEVsZW1lbnRzU2VsZWN0aW9uSWZOZWVkZWQoKSB7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuRWxlbWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgbGV0IGVsZGF0YSA9IDxhbnk+dGhpcy5FbGVtZW50c1tpXS5kYXRhO1xyXG4gICAgICBpZiAoZWxkYXRhLl9fc2VsZWN0ZWQpIHtcclxuICAgICAgICBsZXQgZWwgPSB0aGlzLmN5LiRpZChlbGRhdGEuaWQpO1xyXG4gICAgICAgIGVsLnNlbGVjdCgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDYXJpY2EgZ2xpIHN0aWxpIHBlciBtb3N0cmFyZSBjYXJpbmEgbGEgc2VsZXppb25lIGRlaSBub2RpXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZXR1cFNlbGVjdGlvblN0eWxlcygpe1xyXG4gICAgbGV0IGNzc0l0ZW0gPSB0aGlzLlNtYXJ0U2VsZWN0aW9uU3R5bGVzIHx8IHtcclxuICAgICAgJ292ZXJsYXktY29sb3InOiAnYmx1ZScsXHJcbiAgICAgICdvdmVybGF5LW9wYWNpdHknOiAwLjUsXHJcbiAgICAgICdvdmVybGF5LXBhZGRpbmcnOiA3XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIEJhY2tkb29yIHBlciBwb3RlciBhc3NlZ25hcmUgXCJ7fVwiIGEgU21hcnRTZWxlY3Rpb25TdHlsZXMgaW4gbW9kbyBkaSB1dGlsaXp6YXJlIGxhIHNtYXJ0IHNlbGVjdGlvbiBtYSBzZW56YSBjaGUgbmVzc3VubyBzdGlsZSB2ZW5nYSBhcHBsaWNhdG9cclxuICAgIC8vIGFkIGVzZW1waW8gcXVhbG9yYSBzaSB2b2xlc3NlIHV0aWxpenphcmUgbCdodG1sbm9kZSBwZXIgZ2VzdGlyZSBsYSBncmFmaWNhIGRlZ2xpIGVsZW1lbnRpIHNlbGV6aW9uYXRpXHJcbiAgICBpZihjc3NJdGVtWydvdmVybGF5LWNvbG9yJ10gJiYgY3NzSXRlbVsnb3ZlcmxheS1vcGFjaXR5J10gJiYgY3NzSXRlbVsnb3ZlcmxheS1wYWRkaW5nJ10pXHJcbiAgICAgICg8YW55PnRoaXMuY3kuc3R5bGUoKSkuc2VsZWN0b3IoJ25vZGU6c2VsZWN0ZWQnKS5jc3MoY3NzSXRlbSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RyYSBsJ2FzY29sdG8gYWwgY29udGVuaXRvcmUgZGVsIGdyYWZpY28gZSBpbiBjYXNvIGRpIG1vZGlmaWNoZSBhbGxhIGRpbWVuc2lvbmUsIGFsIG1hc3NpbW8gdW5hIHZvbHRhIG9nbmkgNTAwIG1pbGxpc2Vjb25kaSwgbG8gcmlkaXNlZ25hXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBsaXN0ZW5PbkNoYW5nZXMoKSB7XHJcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZVNlbnNvcih0aGlzLmN5R3JhcGgubmF0aXZlRWxlbWVudCwgKCkgPT4ge1xyXG4gICAgICB0aGlzLmV4dHMudGhyb3R0bGUodGhpcy5uYW1lLCB0aGlzLm9uQ29udGFpbmVyU2l6ZUNoYW5nZWQuYmluZCh0aGlzKSwgdGhpcy5SZXNpemVUaHJvdHRsZVRpbWUpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBGdW56aW9uZSBjaGUgc2kgb2NjdXBhIGRpIGdlc3RpcmUgaWwgcmVwYWludCBkZWwgZGlhZ3JhbW1hXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBvbkNvbnRhaW5lclNpemVDaGFuZ2VkKCkge1xyXG4gICAgdGhpcy5zZXJ2aWNlLmxvZyhcIklcIiwgXCJEaWFncmFtIGNvbnRhaW5lciBzaXplIGhhcyBjaGFuZ2VkLCByZWRyYXdpbmdcIik7XHJcbiAgICB0aGlzLmN5LnJlc2l6ZSgpO1xyXG4gICAgdGhpcy5jeS5maXQoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbGxlZ2EgdHV0dGkgZ2xpIGV2ZW50aSBjaGUgbWkgcG9zc29ubyBzZXJ2aXJlIGUgbGkgZXNwb25lIGluIG91dHB1dFxyXG4gICAqL1xyXG4gIHByaXZhdGUgYmluZEN5dG9zY2FwZUV2ZW50cygpIHtcclxuICAgIHRoaXMuY3kuYmluZCgnY2xpY2snLCAnbm9kZScsIChldmVudCkgPT4ge1xyXG4gICAgICBsZXQgdGFyZ2V0RGF0YSA9IGV2ZW50LnRhcmdldC5kYXRhKClcclxuICAgICAgaWYgKHRoaXMuU21hcnRTZWxlY3Rpb24pIHtcclxuXHJcbiAgICAgICAgLy8gSW4gY2FzbyBkaSBzZWxlemlvbmUgc2luZ29sYSByaXB1bGlzY28gdHV0dGkgZ2xpIGVsZW1lbnRpIHByZWNlZGVudGVtZW50ZSBzZWxlemlvbmF0aVxyXG4gICAgICAgIGlmICh0aGlzLlNpbmdsZVNlbGVjdGlvbikge1xyXG4gICAgICAgICAgbGV0IHNlbGVjdGVkID0gdGhpcy5jeS5lbGVtZW50cygnbm9kZTpzZWxlY3RlZCcpO1xyXG4gICAgICAgICAgc2VsZWN0ZWQuZm9yRWFjaChlbCA9PiB7XHJcbiAgICAgICAgICAgIGVsLnNlbGVjdGlmeSgpO1xyXG4gICAgICAgICAgICBlbC51bnNlbGVjdCgpO1xyXG4gICAgICAgICAgICBlbC51bnNlbGVjdGlmeSgpO1xyXG4gICAgICAgICAgICBlbC5kYXRhKFwiX19zZWxlY3RlZFwiLCBmYWxzZSk7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgbGV0IGlkID0gdGFyZ2V0RGF0YS5pZFxyXG4gICAgICAgIGxldCBlbCA9IHRoaXMuY3kuJGlkKGlkKTtcclxuICAgICAgICBsZXQgc2VsZWN0ZWQgPSBlbC5zZWxlY3RlZCgpO1xyXG5cclxuICAgICAgICBlbC5zZWxlY3RpZnkoKTtcclxuICAgICAgICBpZiAoc2VsZWN0ZWQpXHJcbiAgICAgICAgICBlbC51bnNlbGVjdCgpO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgIGVsLnNlbGVjdCgpO1xyXG4gICAgICAgIGVsLnVuc2VsZWN0aWZ5KCk7XHJcblxyXG4gICAgICAgIC8vIFF1ZXN0byB2YSBhbmNoZSBuZWxsYSBsaXN0YSBkZWdsaSBlbGVtZW50aSBvcmlnaW5hbGkgKHRoaXMuRWxlbWVudHMpIGRhdG8gY2hlIGN5dG9zY2FwZSBsaSBwcmVuZGUgcGVyIHJpZmVyaW1lbnRvIChiYmJiYnJhdm8gY3l0by1jaGFuKVxyXG4gICAgICAgIGVsLmRhdGEoXCJfX3NlbGVjdGVkXCIsICFzZWxlY3RlZCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMub25Ob2RlQ2xpY2suZW1pdCh7IGRhdGE6IHRhcmdldERhdGEgfSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmN5LmJpbmQoJ3NlbGVjdCcsICdub2RlJywgKGV2ZW50KSA9PiB7XHJcbiAgICAgIGxldCB0YXJnZXREYXRhID0gZXZlbnQudGFyZ2V0LmRhdGEoKVxyXG5cclxuICAgICAgdGhpcy5vbk5vZGVTZWxlY3Rpb24uZW1pdCh7IGRhdGE6IHRhcmdldERhdGEsIHNlbGVjdGVkOiB0cnVlIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5jeS5iaW5kKCdsYXlvdXRzdG9wJywgKGV2ZW50KSA9PiB7XHJcbiAgICAgIHRoaXMub25MYXlvdXREb25lLmVtaXQoKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuY3kuYmluZCgndW5zZWxlY3QnLCAnbm9kZScsIChldmVudCkgPT4ge1xyXG4gICAgICBsZXQgdGFyZ2V0RGF0YSA9IGV2ZW50LnRhcmdldC5kYXRhKClcclxuXHJcbiAgICAgIHRoaXMub25Ob2RlU2VsZWN0aW9uLmVtaXQoeyBkYXRhOiB0YXJnZXREYXRhLCBzZWxlY3RlZDogZmFsc2UgfSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBBbHRyaSBldmVudGkuLi5cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldG9kbyBjaGUgc2VydmUgcGVyIGNhcmljYXJlIHR1dHRlIGxlIGVzdGVuc2lvbmkgZGVsbGEgbGlicmVyaWEgaW4gYmFzZSBhIGNpw7IgY2hlIHZpZW5lIHV0aWxpenphdG9cclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIHBlcmZvcm1Nb2R1bGVzTG9hZGluZygpIHtcclxuICAgIGlmICh0aGlzLkxheW91dC5uYW1lID09ICdkYWdyZScpXHJcbiAgICAgIGF3YWl0IHRoaXMubG9hZEludGVybmFsKFwiY3l0b3NjYXBlLWRhZ3JlXCIpO1xyXG5cclxuICAgIGlmICh0aGlzLk5vZGVIVE1MVGVtcGxhdGVzICYmIHRoaXMuTm9kZUhUTUxUZW1wbGF0ZXMubGVuZ3RoID4gMClcclxuICAgICAgYXdhaXQgdGhpcy5sb2FkSW50ZXJuYWwoXCJjeXRvc2NhcGUtaHRtbC1ub2RlXCIpO1xyXG5cclxuICAgIGlmICh0aGlzLlVzZUNvbnRleHRNZW51KVxyXG4gICAgICBhd2FpdCB0aGlzLmxvYWRJbnRlcm5hbChcImN5dG9zY2FwZS1jeHRtZW51XCIpO1xyXG5cclxuICAgIGlmICh0aGlzLk5vZGVzSGllcmFyY2h5ICYmIHRoaXMuVXNlRXhwYW5kQ29sbGFwc2UpXHJcbiAgICAgIGF3YWl0IHRoaXMubG9hZEludGVybmFsKFwiY3l0b3NjYXBlLWV4cGFuZC1jb2xsYXBzZVwiKTtcclxuXHJcbiAgICBpZiAodGhpcy5FeHRlbnNpb25Nb2R1bGVzSW1wb3J0ZXIpIHtcclxuICAgICAgLy8gV3JhcHBvIGlsIG5hbWVzcGFjZSBpbiBtb2RvIGNoZSBwb3NzYSBkaXJlIGxhIG1pYSBzdWwgZmF0dG8gY2hlIGwndXRlbnRlIGFnZ2l1bmdhIHVuIG1vZHVsbyBvIG1lbm8gOkRcclxuICAgICAgdmFyIHdyYXBwZWRDeXRvc2NhcGUgPSB7XHJcbiAgICAgICAgdXNlOiAobW9kdWxlTmFtZTogc3RyaW5nLCBtb2R1bGU6IGN5dG9zY2FwZS5FeHQpID0+IHtcclxuICAgICAgICAgIGlmICghbW9kdWxlKVxyXG4gICAgICAgICAgICB0aGlzLnNlcnZpY2UubG9nKFwiRVwiLCB0aGlzLnNlcnZpY2UubG9jKFwiUmVjZWl2ZWQgYW4gdW5kZWZpbmVkIG1vZHVsZS4gTWFrZSBzdXJlIHlvdSBhcmUgY29ycmVjdGx5IGxvYWRpbmcgaXRcIikgKyBcIjogXCIgKyBtb2R1bGVOYW1lLCBmYWxzZSk7XHJcblxyXG4gICAgICAgICAgaWYgKFtcImN5dG9zY2FwZS1kYWdyZVwiLCBcImN5dG9zY2FwZS1odG1sLW5vZGVcIiwgXCJjeXRvc2NhcGUtY3h0bWVudVwiLCBcImN5dG9zY2FwZS1leHBhbmQtY29sbGFwc2VcIl0uaW5jbHVkZXMobW9kdWxlTmFtZSkpXHJcbiAgICAgICAgICAgIHRoaXMuc2VydmljZS5sb2coXCJXXCIsIHRoaXMuc2VydmljZS5sb2MoXCJNb2R1bGVcIikgKyBcIiBcIiArIG1vZHVsZU5hbWUgKyBcIiBcIiArIHRoaXMuc2VydmljZS5sb2MoXCJpcyBsb2FkZWQgYW5kIG1hbmFnZWQgZGlyZWN0bHkgYnkgdGhpcyBsaWJyYXJ5LiBZb3UgZG9uJ3QgbmVlZCB0byBpbXBvcnQgaXQgb3IgdXNlIGl0IGRpcmVjdGx5LCBqdXN0IGJlIHN1cmUgdG8gc2V0IHRoZSByZWxhdGl2ZSBvcHRpb25zXCIpLCBmYWxzZSk7XHJcbiAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIGN5dG9zY2FwZS51c2UobW9kdWxlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGF3YWl0IHRoaXMuRXh0ZW5zaW9uTW9kdWxlc0ltcG9ydGVyKHdyYXBwZWRDeXRvc2NhcGUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0b2RvIGNoZSBzZXJ2ZSBwZXIgY2FyaWNhcmUgdHV0dGUgbGUgZXN0ZW5zaW9uaSBkZWxsYSBsaWJyZXJpYSBpbiBiYXNlIGEgY2nDsiBjaGUgdmllbmUgdXRpbGl6emF0byBjb24gbGUgb3B6aW9uaSBkZWZpbml0ZSBkYWdsaSBJbnB1dFxyXG4gICAqL1xyXG4gIHByaXZhdGUgcGVyZm9ybU9wZXJhdGlvbnNXaXRoTG9hZGVkTW9kdWxlcygpIHtcclxuXHJcbiAgICBsZXQgYW55Q3kgPSAoPGFueT50aGlzLmN5KTtcclxuXHJcbiAgICAvLyBVdGlsaXp6byBkZWwgbGF5b3V0LCBsbyBzYWx2byBwZXIgcG90ZXJsbyByaXV0aWxpenphcmUgaW4gZnV0dXJvXHJcbiAgICBpZiAodGhpcy5MYXlvdXQpIHtcclxuICAgICAgdGhpcy5MYXN0TGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLkxheW91dCkpO1xyXG4gICAgICB0aGlzLmN5LmxheW91dCh0aGlzLkxhc3RMYXlvdXQpLnJ1bigpXHJcbiAgICB9XHJcblxyXG4gICAgLy8gVXRpbGl6em8gZGVsbCdIVE1MIG5vZGVcclxuICAgIGlmICh0aGlzLk5vZGVIVE1MVGVtcGxhdGVzICYmIHRoaXMuTm9kZUhUTUxUZW1wbGF0ZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICB0aGlzLkh0bWxOb2RlQXBpID0gYW55Q3kuaHRtbG5vZGUoKTtcclxuICAgICAgdGhpcy5IdG1sTm9kZUFwaS5jcmVhdGVIdG1sTm9kZShjeXRvc2NhcGUsIHRoaXMuY3ksIHRoaXMuTm9kZUhUTUxUZW1wbGF0ZXMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFV0aWxpenpvIGRlbCBDb250ZXh0IE1lbnVcclxuICAgIGlmICh0aGlzLlVzZUNvbnRleHRNZW51KVxyXG4gICAgICB0aGlzLkNvbnRleHRNZW51T3B0aW9ucy5mb3JFYWNoKG8gPT4geyBhbnlDeS5jeHRtZW51KG8pOyB9KTtcclxuXHJcbiAgICAvLyBVdGlsaXp6byBkZWxsJ2V4cGFuZCBjb2xsYXBzZSBzb2xvIHF1YW5kbyBjJ8OoIHVuYSBnZXJhcmNoaWEgZGkgbm9kaVxyXG4gICAgaWYgKHRoaXMuTm9kZXNIaWVyYXJjaHkgJiYgdGhpcy5Vc2VFeHBhbmRDb2xsYXBzZSlcclxuICAgICAgdGhpcy5FeHBhbmRDb2xsYXBzZUFwaSA9IGFueUN5LmV4cGFuZENvbGxhcHNlKHRoaXMuRXhwYW5kQ29sbGFwc2VPcHRpb25zKTtcclxuXHJcbiAgICAvLyBVdGlsaXp6byBkaSBlc3RlbnNpb25pIGV4dHJhLCBpbXBsZW1lbnRhemlvbmUgYWZmaWRhdGEgYWwgcHJvZ3JhbW1hdG9yZVxyXG4gICAgaWYgKHRoaXMuRXh0ZW5zaW9uTW9kdWxlc0FwcGx5ZXIpXHJcbiAgICAgIHRoaXMuRXh0ZW5zaW9uTW9kdWxlc0FwcGx5ZXIodGhpcy5jeSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgdXBkYXRlQ2FyZERhdGEoKSB7XHJcbiAgICBpZiAoIXRoaXMuSHRtbE5vZGVBcGkpIHtcclxuICAgICAgdGhpcy5zZXJ2aWNlLmxvZyhcIkVcIiwgXCJDYW5ub3QgdXBkYXRlIE5vZGVIVE1MVGVtcGxhdGVzIGFzIHRoZXkgZG9uJ3Qgc2VlbSB0byBiZSB1c2VkXCIpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLkh0bWxOb2RlQXBpLnVwZGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0b2RvIGludGVybm8gcGVyIGlsIGNhcmljYW1lbnRvIGRlaSBtb2R1bGkgZGkgZXN0ZW5zaW9uZVxyXG4gICAqIFxyXG4gICAqIEBwYXJhbSB7J2N5dG9zY2FwZS1leHBhbmQtY29sbGFwc2UnIHwgJ2N5dG9zY2FwZS1jeHRtZW51JyB8ICdjeXRvc2NhcGUtaHRtbC1ub2RlJyB8ICdjeXRvc2NhcGUtZGFncmUnfSBtb2R1bGVJZCBNb2R1bG8gZGEgY2FyaWNhcmVcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIGxvYWRJbnRlcm5hbChtb2R1bGVJZDogJ2N5dG9zY2FwZS1leHBhbmQtY29sbGFwc2UnIHwgJ2N5dG9zY2FwZS1jeHRtZW51JyB8ICdjeXRvc2NhcGUtaHRtbC1ub2RlJyB8ICdjeXRvc2NhcGUtZGFncmUnKSB7XHJcbiAgICBsZXQgdG9Mb2FkID0gYXdhaXQgdGhpcy5zZXJ2aWNlLmltcG9ydElmTmVlZGVkKG1vZHVsZUlkKTtcclxuICAgIGlmICh0b0xvYWQpIGN5dG9zY2FwZS51c2UodG9Mb2FkKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldG9kbyBjaGUgYmFzYW5kb3NpIHN1bGxlIG9wemlvbmkgbmF0aXZlIGV2ZW50dWFsbWVudGUgYXNzZWduYXRlIGxlIGNvbXBsZXRhIGNvbiBnbGkgSW5wdXQgYWRkaXppb25hbGlcclxuICAgKiBcclxuICAgKiBAcmV0dXJucyB7Y3lfLkN5dG9zY2FwZU9wdGlvbnN9IE9wemlvbmkgZmluYWxpIHVuaXRlIGRhIElucHV0IGVkIG9wemlvbmkgbmF0aXZlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRDb21wbGV0ZWRPcHRpb25zKCk6IGN5Xy5DeXRvc2NhcGVPcHRpb25zIHtcclxuICAgIHZhciBvcHRzOiBjeV8uQ3l0b3NjYXBlT3B0aW9ucyA9IHRoaXMuTmF0aXZlT3B0aW9ucyB8fCB7fTtcclxuICAgIG9wdHMuY29udGFpbmVyID0gdGhpcy5jeUdyYXBoLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBvcHRzLnN0eWxlID0gb3B0cy5zdHlsZSB8fCBbXTtcclxuXHJcbiAgICAvLyBQZXIgdHV0dGUgbGUgY29zZSBwZXIgY3VpIGdsaSBJbnB1dCBoYW5ubyBwcmlvcml0w6Agc292cmFzY3Jpdm8gZ2xpIG9yaWdpbmFsaSBkZWxsZSBvcHppb25pXHJcblxyXG4gICAgaWYgKHRoaXMuTm9kZVN0eWxlcyB8fCB0aGlzLkVkZ2VTdHlsZXMpIHtcclxuICAgICAgb3B0cy5zdHlsZSA9IFtdO1xyXG4gICAgICBpZiAodGhpcy5Ob2RlU3R5bGVzKSBvcHRzLnN0eWxlLnB1c2goeyBzZWxlY3RvcjogJ25vZGUnLCBjc3M6IHRoaXMuTm9kZVN0eWxlcyB9KTtcclxuICAgICAgaWYgKHRoaXMuRWRnZVN0eWxlcykgb3B0cy5zdHlsZS5wdXNoKHsgc2VsZWN0b3I6ICdlZGdlJywgY3NzOiB0aGlzLkVkZ2VTdHlsZXMgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuRWxlbWVudHMpXHJcbiAgICAgIG9wdHMuZWxlbWVudHMgPSB0aGlzLkVsZW1lbnRzO1xyXG5cclxuICAgIHRoaXMucmV2aWV3Q3l0b3NjYXBlRWxlbWVudHMoPGN5dG9zY2FwZS5FbGVtZW50RGVmaW5pdGlvbltdPm9wdHMuZWxlbWVudHMpO1xyXG5cclxuICAgIGlmICh0aGlzLkxheW91dClcclxuICAgICAgb3B0cy5sYXlvdXQgPSB0aGlzLkxheW91dDtcclxuXHJcbiAgICBpZiAodGhpcy5SZWFkb25seSkge1xyXG4gICAgICAvLyBRdWVzdG8gY29zbyBmYSBlZmZldHRpIHN0cmFuaS4uLi5cclxuICAgICAgLy9vcHRzLmF1dG9sb2NrID0gdHJ1ZTtcclxuXHJcbiAgICAgIG9wdHMuYXV0b3VuZ3JhYmlmeSA9IHRydWU7XHJcbiAgICAgIG9wdHMuYXV0b3Vuc2VsZWN0aWZ5ID0gZmFsc2U7XHJcbiAgICAgIG9wdHMuYm94U2VsZWN0aW9uRW5hYmxlZCA9IHRydWU7XHJcbiAgICAgIG9wdHMudXNlclpvb21pbmdFbmFibGVkID0gZmFsc2U7XHJcbiAgICAgIG9wdHMudXNlclBhbm5pbmdFbmFibGVkID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG9wdHM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBZ2dpdXN0YW1lbnRpIGRlZ2xpIGVsZW1lbnRpIGRpIEN5dG9zY2FwZS4gXHJcbiAgICogXHJcbiAgICogSSBub2RpIG5vbiB2ZW5nb25vIHRvY2NhdGkuXHJcbiAgICogXHJcbiAgICogUGVyIG9nbmkgZWRnZSB2aWVuZSBjb250cm9sbGF0byBzZSDDqCBzcGVjaWZpY2F0YSB1bmEgc29yZ2VudGUgZWQgdW5hIGRlc3RpbmF6aW9uZSwgaW4gY2FzbyBjb250cmFyaW8gc2kgY2VyY2EgZGkgZGVkdXJsaSBkYWxsJ0lEXHJcbiAgICogXHJcbiAgICogQHBhcmFtIHtjeXRvc2NhcGUuRWxlbWVudERlZmluaXRpb25bXX0gZWxlbWVudHMgRWxlbWVudGkgZGEgc2lzdGVtYXJlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZXZpZXdDeXRvc2NhcGVFbGVtZW50cyhlbGVtZW50czogY3l0b3NjYXBlLkVsZW1lbnREZWZpbml0aW9uW10sIHByZXZQb3NpdGlvbnM/OiBhbnkpIHtcclxuICAgIGxldCBoYXNQcmV2aW91c1Bvc2l0aW9ucyA9IHByZXZQb3NpdGlvbnMgJiYgcHJldlBvc2l0aW9ucy5sZW5ndGggPiAwO1xyXG4gICAgbGV0IHBvc2l0aW9uQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBjeXRvc2NhcGUuUG9zaXRpb24gfSA9IHt9O1xyXG5cclxuICAgIGlmIChoYXNQcmV2aW91c1Bvc2l0aW9ucykge1xyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXZQb3NpdGlvbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBsZXQgaXRlbSA9IHByZXZQb3NpdGlvbnNbaV07XHJcbiAgICAgICAgaWYgKCFwb3NpdGlvbkNhY2hlW2l0ZW0uZGF0YSgpLmlkXSlcclxuICAgICAgICAgIHBvc2l0aW9uQ2FjaGVbaXRlbS5kYXRhKCkuaWRdID0gaXRlbS5wb3NpdGlvbigpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICBsZXQgZWwgPSBlbGVtZW50c1tpXTtcclxuICAgICAgaWYgKGVsLmdyb3VwID09IFwiZWRnZXNcIiAmJiAoIWVsLmRhdGEuc291cmNlICYmICFlbC5kYXRhLnRhcmdldCkpIHtcclxuICAgICAgICBpZiAoIWVsLmRhdGEuaWQuaW5jbHVkZXMoXCItXCIpKVxyXG4gICAgICAgICAgdGhpcy5zZXJ2aWNlLmxvZyhcIkVcIiwgXCJJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhIHNvdXJjZSBhbmQgYSB0YXJnZXQgZm9yIGFuIGVkZ2UgeW91IGhhdmUgdG8gd3JpdGUgaXRzIGlkIGluIHRoZSBmb3JtYXQge3NvdXJjZX0te3RhcmdldH1cIik7XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICB2YXIgc291cmNlVGFyZ2V0ID0gZWwuZGF0YS5pZC5zcGxpdCgnLScpO1xyXG4gICAgICAgICAgZWwuZGF0YS5zb3VyY2UgPSBzb3VyY2VUYXJnZXRbMF0udHJpbSgpO1xyXG4gICAgICAgICAgZWwuZGF0YS50YXJnZXQgPSBzb3VyY2VUYXJnZXRbMV0udHJpbSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKGhhc1ByZXZpb3VzUG9zaXRpb25zICYmIGVsLmdyb3VwID09IFwibm9kZXNcIilcclxuICAgICAgICBlbC5wb3NpdGlvbiA9IHBvc2l0aW9uQ2FjaGVbZWwuZGF0YS5pZF1cclxuICAgIH1cclxuICB9XHJcbn0iLCI8ZGl2ICNncmFwaCBjbGFzcz1cImdyYXBoLXdyYXBwZXIge3tuYW1lfX1cIj48L2Rpdj4iXX0=
1
+ import { Component, EventEmitter, Input, Optional, Output, ViewChild } from '@angular/core';
2
+ import { ResizeSensor } from "../extensions/ResizeSensor";
3
+ import * as cy_ from 'cytoscape';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "../services/es-diagram.service";
6
+ import * as i2 from "../services/es-diagram.dispatcher";
7
+ import * as i3 from "../extensions/ReactiveExtensions";
8
+ /** @ignore */ const cytoscape = cy_.default ? cy_.default : cy_;
9
+ /**
10
+ * Componente che si occupa di graficare un diagramma e di gestirne il ciclo di vita
11
+ */
12
+ export class EsDiagramComponent {
13
+ /**
14
+ * Costruttore
15
+ *
16
+ * @ignore
17
+ */
18
+ constructor(service, dispatcher, exts) {
19
+ this.service = service;
20
+ this.dispatcher = dispatcher;
21
+ this.exts = exts;
22
+ /**
23
+ * Nome del diagramma, fondamentale assegnarlo per permettere alla libreria di schedularne la creazione
24
+ */
25
+ this.name = "";
26
+ /**
27
+ * Indica se utilizzare il menù contestuale a ruota attorno ad ogni nodo
28
+ */
29
+ this.UseContextMenu = false;
30
+ /**
31
+ * Dice al componente se il diagramma deve utilizzare il sistema di estensione per l'expand e collapse dei gruppi
32
+ */
33
+ this.UseExpandCollapse = false;
34
+ /**
35
+ * Blocco completo delle opzioni, alternativo all'assegnazione di **Elements**, **NodeStyles**, **EdgeStyles**, e **Layout**.
36
+ *
37
+ * Qualora entrambe venissero specificate verrà effettuata un'unione fra queste opzioni e quelle specificate, dando priorità alle specificate
38
+ */
39
+ this.NativeOptions = {};
40
+ /**
41
+ * Aggiorna automaticamente le dimensioni del diagramma quando cambiano le dimensioni della finestra
42
+ */
43
+ this.AutoupdateSize = true;
44
+ /**
45
+ * Indica di mantenere la posizione dei nodi qualora venissero cambiati dall'Input **Elements**.
46
+ *
47
+ * Se l'ID di un nodo è uguale all'ID di un nodo presente in precedenza, il nuovo nodo ne erediterà la posizione
48
+ */
49
+ this.PreserveElementsPosition = true;
50
+ /**
51
+ * Qualora venisse modificato l'Input **Elements**, piuttosto che mettere semplicemente il nuovo Elemento in base al Layout precedente, applica anche un'animazione
52
+ *
53
+ * Funziona solamente se il **Layout** corrente del diagramma supporta le animazioni
54
+ */
55
+ this.AnimateLayoutChanges = true;
56
+ /**
57
+ * Attiva una modalità di selezione "smart"... o perlomeno "smarter" del default di Cytoscape.
58
+ *
59
+ * - Il click di un elemento non selezionato lo seleziona
60
+ * - Il click di un elemento selezionato lo deseleziona
61
+ * - Lo stato di selezione viene persistito sull'oggetto originale invece di rimanere in un internal
62
+ * - All'assegnazione di oggetti selezionati, questi vengono marcati correttamente con l'overlay di selezione
63
+ *
64
+ * N.B: la chiamata all'evento **onNodeClick** avviene **DOPO** la gestione della selezione
65
+ */
66
+ this.SmartSelection = false;
67
+ /**
68
+ * Indica di selezionare un elemento per volta qualora **SmartSelection** fosse attivo
69
+ */
70
+ this.SingleSelection = false;
71
+ /**
72
+ * CSS per la graficazione della selezione dei nodi. Quando un nodo verrà selezionato avrà sopra di se un overlay che 'sborda' di **overlay-padding** pixel,
73
+ * di colore **overlay-color** e con un opacità **overlay-opacity**
74
+ *
75
+ * Assegnando "{}" a questo input, la Smart selection viene gestita ma la gestione grafica è affidata all'utente,
76
+ * ad esempio usando dei **NodeHTMLTemplates** che definiscano selettori su nodi ":selected"
77
+ *
78
+ * @default {'overlay-color':'blue','overlay-opacity':0.5,'overlay-padding':7}
79
+ */
80
+ this.SmartSelectionStyles = null;
81
+ /**
82
+ * Periodo di throttle da quando viene effettuato un resize a quando ricalcolare le dimensioni del diagramma.
83
+ *
84
+ * Può essere tenuto a 0 (redraw istantaneo) finché non ci sono problemi di prestazioni con eventualmente tanti resize a poca distanza l'uno dall'altro.
85
+ */
86
+ this.ResizeThrottleTime = 0;
87
+ /**
88
+ * Fornisce il global della libreria (namespace **cytoscape**) e si aspetta che dopo operazioni di importazione
89
+ * lasciate all'utente vengano aggiunti tutti i moduli desiderati.
90
+ *
91
+ * È **fondamentale** che il primo parametro (il nome del modulo) sia uguale a ciò di cui viene fatto il require in modo che la libreria
92
+ * possa controllare che il modulo importato non sia già stato importato in precedenza
93
+ *
94
+ * ## Esempio:
95
+ *
96
+ * ```typescript
97
+ * (global) => {
98
+ * return import("cytoscape-extension-library").then(module => global.use("cytoscape-extension-library", module.default));
99
+ *
100
+ * ...
101
+ * }
102
+ * ```
103
+ */
104
+ this.ExtensionModulesImporter = null;
105
+ /**
106
+ * Fornisce l'istanza attuale di Cytoscape da cui è possibile prendere le librerie di estensione caricate in **ExtensionModulesImporter**
107
+ * e configurarle in base ai comportamenti specifici
108
+ *
109
+ * ## Esempio:
110
+ *
111
+ * ```typescript
112
+ * (cytoscapeCore) => {
113
+ * // Fare questo lavoro per ogni estensione caricata
114
+ * let extensionConfiguration = { ... };
115
+ * let extensionInstance = cytoscapeCore.extensionLibrary(extensionConfiguration);
116
+ * extensionInstance.doSomethingSpecificToThisExtension();
117
+ *
118
+ * ...
119
+ * }
120
+ * ```
121
+ */
122
+ this.ExtensionModulesApplyer = null;
123
+ /**
124
+ * Evento lanciato al click di un nodo, contiene l'oggetto **data** del nodo in questione
125
+ */
126
+ this.onNodeClick = new EventEmitter();
127
+ /**
128
+ * Evento lanciato alla selezione o deselezione di un nodo, contiene l'oggetto **data** del nodo in questione e informazioni sul suo stato di selezione
129
+ */
130
+ this.onNodeSelection = new EventEmitter();
131
+ /**
132
+ * Evento lanciato al termine del Layouting. Se si vuole eseguire codice dopo che il Layout è fatto e completamente graficato, questo è il punto
133
+ */
134
+ this.onLayoutDone = new EventEmitter();
135
+ /**
136
+ * Evento lanciato al termine del caricamento del diagramma
137
+ */
138
+ this.onLoaded = new EventEmitter();
139
+ /**
140
+ * Indica se il rendering del diagramma è terminato
141
+ */
142
+ this.Rendered = false;
143
+ /**
144
+ * Api dell'estensione expand-collapse per permettere di effettuare operazioni dall'esterno del diagramma. Vengono valorizzate se **UseExpandCollapse** è **true**
145
+ */
146
+ this.ExpandCollapseApi = null;
147
+ /**
148
+ * Api dell'estensione html-node per permettere di effettuare operazioni dall'esterno del diagramma. Vengono valorizzate se sono impostati dei **NodeHTMLTemplates**
149
+ */
150
+ this.HtmlNodeApi = null;
151
+ }
152
+ /**
153
+ * @ignore
154
+ *
155
+ * Angular Pipeline
156
+ */
157
+ ngAfterViewInit() {
158
+ if (!this.service || !this.dispatcher)
159
+ throw "Il modulo @esfaenza/diagrams non è stato importato con il forRoot();";
160
+ this.dispatchLoadChart();
161
+ }
162
+ /**
163
+ * All'onDestroy ripulisco la memoria dal diagramma
164
+ */
165
+ ngOnDestroy() {
166
+ if (this.resizeObserver) {
167
+ this.resizeObserver.dispose();
168
+ this.resizeObserver = null;
169
+ }
170
+ if (this.cy) {
171
+ this.service.log("I", "Diagram" + " " + this.name + ": Unloading destroyed diagram", false);
172
+ this.cy.destroy();
173
+ this.dispatcher.deregister(this.name);
174
+ }
175
+ else
176
+ this.service.log("I", "Chart " + this.name + ": Unloading uncreated chart component. It probably was a duplicated", false);
177
+ }
178
+ /**
179
+ * Registra il diagramma attuale nel Dispatcher in modo che venga caricato appena possibile
180
+ */
181
+ dispatchLoadChart() {
182
+ this.dispatcher.register(this.name, () => { return this.render(); });
183
+ }
184
+ /**
185
+ * @ignore
186
+ *
187
+ * Angular Pipeline: Gestione ri-graficazione del diagramma, se possibile
188
+ */
189
+ ngOnChanges(changes) {
190
+ let toCheck = ["Templates", "UseContextMenu", "ContextMenuOptions", "UseExpandCollapse", "ExpandCollapseOptions", "NodeStyles", "EdgeStyles", "NativeOptions"];
191
+ if (this.Rendered && toCheck.some(t => changes[t]))
192
+ this.service.log("W", "Redraw based on dynamic Input change is supported only for 'Elements' and 'Layout' inputs, please destroy the component and recreate it with the new settings");
193
+ let elementChanges = changes["Elements"];
194
+ let layoutChanges = changes["Layout"];
195
+ if (elementChanges && !elementChanges.firstChange) {
196
+ this.service.log("I", "Elements have been changed after diagram initialization");
197
+ // Cambiamento agli Elementi: ripulisco gli elementi vecchi, prendo i nuovi, li sistemo e li riassegno.
198
+ // Se il nuovo Input Elements è roba strana mi limito a ripulire il diagramma
199
+ // Se cytoscape aveva già degli elementi precedentemente ne prendo le posizioni in modo da ridisegnarli partendo dallo stesso punto (carino per le animazioni)
200
+ let elements = elementChanges?.currentValue;
201
+ let previous_elements = this.PreserveElementsPosition ? this.cy.nodes() : null;
202
+ this.cy.elements().remove();
203
+ if (elements && elements.length && elements.length > 0) {
204
+ this.reviewCytoscapeElements(elements, previous_elements);
205
+ this.cy.add(elements);
206
+ if (this.SmartSelection)
207
+ this.setupElementsSelectionIfNeeded();
208
+ // Se solo gli elementi cambiano, riapplico il Layout precedente
209
+ if (!layoutChanges && this.LastLayout) {
210
+ // Se devo animare le modifche al layout forzo il parametro relativo
211
+ if (this.AnimateLayoutChanges)
212
+ this.LastLayout.animate = true;
213
+ this.cy.layout(this.LastLayout).run();
214
+ }
215
+ }
216
+ }
217
+ // Se il layout cambia lo applico e me lo salvo come layout precedente per il futuro
218
+ if (layoutChanges && !layoutChanges.firstChange) {
219
+ this.service.log("I", "Layout have been changed after diagram initialization");
220
+ this.LastLayout = JSON.parse(JSON.stringify(layoutChanges.currentValue));
221
+ this.cy.layout(this.LastLayout).run();
222
+ }
223
+ }
224
+ /**
225
+ * Effettua il rendering del diagramma
226
+ */
227
+ async render() {
228
+ // Tiro fuori le opzioni con cui generare il diagramma
229
+ let cyOptions = this.getCompletedOptions();
230
+ this.NodesHierarchy = cyOptions.elements && cyOptions.elements.some(t => t.data.parent);
231
+ // Carico eventuali classi di estensione che servono
232
+ await this.performModulesLoading();
233
+ // Genero il diagramma
234
+ this.cy = cytoscape(cyOptions);
235
+ // Collego gli eventi al componente
236
+ this.bindCytoscapeEvents();
237
+ // Utilizzo le classi di estensione caricate precedentemente per fare il resto delle mie operazioni
238
+ this.performOperationsWithLoadedModules();
239
+ // Imposto la variabile Rendered a true in modo che se da adesso vengono fatte modifiche che dovrebbero causare un redraw posso accorgermene
240
+ // e mandare a cagare lo stronzo di turno
241
+ this.Rendered = true;
242
+ // Se devo aggiornare in automatico in base alla dimensione del contenitore collego il ResizeObserver
243
+ if (this.AutoupdateSize)
244
+ this.listenOnChanges();
245
+ if (this.SmartSelection) {
246
+ this.setupSelectionStyles();
247
+ this.setupElementsSelectionIfNeeded();
248
+ }
249
+ this.onLoaded.emit();
250
+ }
251
+ /**
252
+ * Prende tutti gli elementi appena assegnati, e se qualcuno era selezionato la situazione viene persistita su cytoscape
253
+ */
254
+ setupElementsSelectionIfNeeded() {
255
+ for (let i = 0; i < this.Elements.length; i++) {
256
+ let eldata = this.Elements[i].data;
257
+ if (eldata.__selected) {
258
+ let el = this.cy.$id(eldata.id);
259
+ el.select();
260
+ }
261
+ }
262
+ }
263
+ /**
264
+ * Carica gli stili per mostrare carina la selezione dei nodi
265
+ */
266
+ setupSelectionStyles() {
267
+ let cssItem = this.SmartSelectionStyles || {
268
+ 'overlay-color': 'blue',
269
+ 'overlay-opacity': 0.5,
270
+ 'overlay-padding': 7
271
+ };
272
+ // Backdoor per poter assegnare "{}" a SmartSelectionStyles in modo di utilizzare la smart selection ma senza che nessuno stile venga applicato
273
+ // ad esempio qualora si volesse utilizzare l'htmlnode per gestire la grafica degli elementi selezionati
274
+ if (cssItem['overlay-color'] && cssItem['overlay-opacity'] && cssItem['overlay-padding'])
275
+ this.cy.style().selector('node:selected').css(cssItem);
276
+ }
277
+ /**
278
+ * Registra l'ascolto al contenitore del grafico e in caso di modifiche alla dimensione, al massimo una volta ogni 500 millisecondi, lo ridisegna
279
+ */
280
+ listenOnChanges() {
281
+ this.resizeObserver = new ResizeSensor(this.cyGraph.nativeElement, () => {
282
+ this.exts.throttle(this.name, this.onContainerSizeChanged.bind(this), this.ResizeThrottleTime);
283
+ });
284
+ }
285
+ /**
286
+ * Funzione che si occupa di gestire il repaint del diagramma
287
+ */
288
+ onContainerSizeChanged() {
289
+ this.service.log("I", "Diagram container size has changed, redrawing");
290
+ this.cy.resize();
291
+ this.cy.fit();
292
+ }
293
+ /**
294
+ * Collega tutti gli eventi che mi possono servire e li espone in output
295
+ */
296
+ bindCytoscapeEvents() {
297
+ this.cy.bind('click', 'node', (event) => {
298
+ let targetData = event.target.data();
299
+ if (this.SmartSelection) {
300
+ // In caso di selezione singola ripulisco tutti gli elementi precedentemente selezionati
301
+ if (this.SingleSelection) {
302
+ let selected = this.cy.elements('node:selected');
303
+ selected.forEach(el => {
304
+ el.selectify();
305
+ el.unselect();
306
+ el.unselectify();
307
+ el.data("__selected", false);
308
+ });
309
+ }
310
+ let id = targetData.id;
311
+ let el = this.cy.$id(id);
312
+ let selected = el.selected();
313
+ el.selectify();
314
+ if (selected)
315
+ el.unselect();
316
+ else
317
+ el.select();
318
+ el.unselectify();
319
+ // Questo va anche nella lista degli elementi originali (this.Elements) dato che cytoscape li prende per riferimento (bbbbbravo cyto-chan)
320
+ el.data("__selected", !selected);
321
+ }
322
+ this.onNodeClick.emit({ data: targetData });
323
+ });
324
+ this.cy.bind('select', 'node', (event) => {
325
+ let targetData = event.target.data();
326
+ this.onNodeSelection.emit({ data: targetData, selected: true });
327
+ });
328
+ this.cy.bind('layoutstop', (event) => {
329
+ this.onLayoutDone.emit();
330
+ });
331
+ this.cy.bind('unselect', 'node', (event) => {
332
+ let targetData = event.target.data();
333
+ this.onNodeSelection.emit({ data: targetData, selected: false });
334
+ });
335
+ // Altri eventi...
336
+ }
337
+ /**
338
+ * Metodo che serve per caricare tutte le estensioni della libreria in base a ciò che viene utilizzato
339
+ */
340
+ async performModulesLoading() {
341
+ if (this.Layout.name == 'dagre')
342
+ await this.loadInternal("cytoscape-dagre");
343
+ if (this.NodeHTMLTemplates && this.NodeHTMLTemplates.length > 0)
344
+ await this.loadInternal("cytoscape-html-node");
345
+ if (this.UseContextMenu)
346
+ await this.loadInternal("cytoscape-cxtmenu");
347
+ if (this.NodesHierarchy && this.UseExpandCollapse)
348
+ await this.loadInternal("cytoscape-expand-collapse");
349
+ if (this.ExtensionModulesImporter) {
350
+ // Wrappo il namespace in modo che possa dire la mia sul fatto che l'utente aggiunga un modulo o meno :D
351
+ var wrappedCytoscape = {
352
+ use: (moduleName, module) => {
353
+ if (!module)
354
+ this.service.log("E", this.service.loc("Received an undefined module. Make sure you are correctly loading it") + ": " + moduleName, false);
355
+ if (["cytoscape-dagre", "cytoscape-html-node", "cytoscape-cxtmenu", "cytoscape-expand-collapse"].includes(moduleName))
356
+ this.service.log("W", this.service.loc("Module") + " " + moduleName + " " + this.service.loc("is loaded and managed directly by this library. You don't need to import it or use it directly, just be sure to set the relative options"), false);
357
+ else
358
+ cytoscape.use(module);
359
+ }
360
+ };
361
+ await this.ExtensionModulesImporter(wrappedCytoscape);
362
+ }
363
+ }
364
+ /**
365
+ * Metodo che serve per caricare tutte le estensioni della libreria in base a ciò che viene utilizzato con le opzioni definite dagli Input
366
+ */
367
+ performOperationsWithLoadedModules() {
368
+ let anyCy = this.cy;
369
+ // Utilizzo del layout, lo salvo per poterlo riutilizzare in futuro
370
+ if (this.Layout) {
371
+ this.LastLayout = JSON.parse(JSON.stringify(this.Layout));
372
+ this.cy.layout(this.LastLayout).run();
373
+ }
374
+ // Utilizzo dell'HTML node
375
+ if (this.NodeHTMLTemplates && this.NodeHTMLTemplates.length > 0) {
376
+ this.HtmlNodeApi = anyCy.htmlnode();
377
+ this.HtmlNodeApi.createHtmlNode(cytoscape, this.cy, this.NodeHTMLTemplates);
378
+ }
379
+ // Utilizzo del Context Menu
380
+ if (this.UseContextMenu)
381
+ this.ContextMenuOptions.forEach(o => { anyCy.cxtmenu(o); });
382
+ // Utilizzo dell'expand collapse solo quando c'è una gerarchia di nodi
383
+ if (this.NodesHierarchy && this.UseExpandCollapse)
384
+ this.ExpandCollapseApi = anyCy.expandCollapse(this.ExpandCollapseOptions);
385
+ // Utilizzo di estensioni extra, implementazione affidata al programmatore
386
+ if (this.ExtensionModulesApplyer)
387
+ this.ExtensionModulesApplyer(this.cy);
388
+ }
389
+ updateCardData() {
390
+ if (!this.HtmlNodeApi) {
391
+ this.service.log("E", "Cannot update NodeHTMLTemplates as they don't seem to be used");
392
+ return;
393
+ }
394
+ this.HtmlNodeApi.update();
395
+ }
396
+ /**
397
+ * Metodo interno per il caricamento dei moduli di estensione
398
+ *
399
+ * @param {'cytoscape-expand-collapse' | 'cytoscape-cxtmenu' | 'cytoscape-html-node' | 'cytoscape-dagre'} moduleId Modulo da caricare
400
+ */
401
+ async loadInternal(moduleId) {
402
+ let toLoad = await this.service.importIfNeeded(moduleId);
403
+ if (toLoad)
404
+ cytoscape.use(toLoad);
405
+ }
406
+ /**
407
+ * Metodo che basandosi sulle opzioni native eventualmente assegnate le completa con gli Input addizionali
408
+ *
409
+ * @returns {cy_.CytoscapeOptions} Opzioni finali unite da Input ed opzioni native
410
+ */
411
+ getCompletedOptions() {
412
+ var opts = this.NativeOptions || {};
413
+ opts.container = this.cyGraph.nativeElement;
414
+ opts.style = opts.style || [];
415
+ // Per tutte le cose per cui gli Input hanno priorità sovrascrivo gli originali delle opzioni
416
+ if (this.NodeStyles || this.EdgeStyles) {
417
+ opts.style = [];
418
+ if (this.NodeStyles)
419
+ opts.style.push({ selector: 'node', css: this.NodeStyles });
420
+ if (this.EdgeStyles)
421
+ opts.style.push({ selector: 'edge', css: this.EdgeStyles });
422
+ }
423
+ if (this.Elements)
424
+ opts.elements = this.Elements;
425
+ this.reviewCytoscapeElements(opts.elements);
426
+ if (this.Layout)
427
+ opts.layout = this.Layout;
428
+ if (this.Readonly) {
429
+ // Questo coso fa effetti strani....
430
+ //opts.autolock = true;
431
+ opts.autoungrabify = true;
432
+ opts.autounselectify = false;
433
+ opts.boxSelectionEnabled = true;
434
+ opts.userZoomingEnabled = false;
435
+ opts.userPanningEnabled = false;
436
+ }
437
+ return opts;
438
+ }
439
+ /**
440
+ * Aggiustamenti degli elementi di Cytoscape.
441
+ *
442
+ * I nodi non vengono toccati.
443
+ *
444
+ * Per ogni edge viene controllato se è specificata una sorgente ed una destinazione, in caso contrario si cerca di dedurli dall'ID
445
+ *
446
+ * @param {cytoscape.ElementDefinition[]} elements Elementi da sistemare
447
+ */
448
+ reviewCytoscapeElements(elements, prevPositions) {
449
+ let hasPreviousPositions = prevPositions && prevPositions.length > 0;
450
+ let positionCache = {};
451
+ if (hasPreviousPositions) {
452
+ for (let i = 0; i < prevPositions.length; i++) {
453
+ let item = prevPositions[i];
454
+ if (!positionCache[item.data().id])
455
+ positionCache[item.data().id] = item.position();
456
+ }
457
+ }
458
+ for (let i = 0; i < elements.length; i++) {
459
+ let el = elements[i];
460
+ if (el.group == "edges" && (!el.data.source && !el.data.target)) {
461
+ if (!el.data.id.includes("-"))
462
+ this.service.log("E", "If you don't specify a source and a target for an edge you have to write its id in the format {source}-{target}");
463
+ else {
464
+ var sourceTarget = el.data.id.split('-');
465
+ el.data.source = sourceTarget[0].trim();
466
+ el.data.target = sourceTarget[1].trim();
467
+ }
468
+ }
469
+ if (hasPreviousPositions && el.group == "nodes")
470
+ el.position = positionCache[el.data.id];
471
+ }
472
+ }
473
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EsDiagramComponent, deps: [{ token: i1.EsDiagramService, optional: true }, { token: i2.EsDiagramDispatcher, optional: true }, { token: i3.ReactiveExtensions }], target: i0.ɵɵFactoryTarget.Component }); }
474
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: EsDiagramComponent, selector: "es-diagram", inputs: { name: "name", UseContextMenu: "UseContextMenu", ContextMenuOptions: "ContextMenuOptions", UseExpandCollapse: "UseExpandCollapse", ExpandCollapseOptions: "ExpandCollapseOptions", NativeOptions: "NativeOptions", Elements: "Elements", NodeStyles: "NodeStyles", EdgeStyles: "EdgeStyles", Readonly: "Readonly", AutoupdateSize: "AutoupdateSize", PreserveElementsPosition: "PreserveElementsPosition", AnimateLayoutChanges: "AnimateLayoutChanges", SmartSelection: "SmartSelection", SingleSelection: "SingleSelection", SmartSelectionStyles: "SmartSelectionStyles", ResizeThrottleTime: "ResizeThrottleTime", Layout: "Layout", NodeHTMLTemplates: "NodeHTMLTemplates", ExtensionModulesImporter: "ExtensionModulesImporter", ExtensionModulesApplyer: "ExtensionModulesApplyer" }, outputs: { onNodeClick: "onNodeClick", onNodeSelection: "onNodeSelection", onLayoutDone: "onLayoutDone", onLoaded: "onLoaded" }, viewQueries: [{ propertyName: "cyGraph", first: true, predicate: ["graph"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div #graph class=\"graph-wrapper {{name}}\"></div>", styles: [".graph-wrapper{height:100%;width:100%}.html-node-notransition{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important;-o-transform:none!important;-moz-transform:none!important;-ms-transform:none!important;-webkit-transform:none!important;transform:none!important}\n"] }); }
475
+ }
476
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EsDiagramComponent, decorators: [{
477
+ type: Component,
478
+ args: [{ selector: 'es-diagram', template: "<div #graph class=\"graph-wrapper {{name}}\"></div>", styles: [".graph-wrapper{height:100%;width:100%}.html-node-notransition{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important;-o-transform:none!important;-moz-transform:none!important;-ms-transform:none!important;-webkit-transform:none!important;transform:none!important}\n"] }]
479
+ }], ctorParameters: () => [{ type: i1.EsDiagramService, decorators: [{
480
+ type: Optional
481
+ }] }, { type: i2.EsDiagramDispatcher, decorators: [{
482
+ type: Optional
483
+ }] }, { type: i3.ReactiveExtensions }], propDecorators: { cyGraph: [{
484
+ type: ViewChild,
485
+ args: ['graph']
486
+ }], name: [{
487
+ type: Input
488
+ }], UseContextMenu: [{
489
+ type: Input
490
+ }], ContextMenuOptions: [{
491
+ type: Input
492
+ }], UseExpandCollapse: [{
493
+ type: Input
494
+ }], ExpandCollapseOptions: [{
495
+ type: Input
496
+ }], NativeOptions: [{
497
+ type: Input
498
+ }], Elements: [{
499
+ type: Input
500
+ }], NodeStyles: [{
501
+ type: Input
502
+ }], EdgeStyles: [{
503
+ type: Input
504
+ }], Readonly: [{
505
+ type: Input
506
+ }], AutoupdateSize: [{
507
+ type: Input
508
+ }], PreserveElementsPosition: [{
509
+ type: Input
510
+ }], AnimateLayoutChanges: [{
511
+ type: Input
512
+ }], SmartSelection: [{
513
+ type: Input
514
+ }], SingleSelection: [{
515
+ type: Input
516
+ }], SmartSelectionStyles: [{
517
+ type: Input
518
+ }], ResizeThrottleTime: [{
519
+ type: Input
520
+ }], Layout: [{
521
+ type: Input
522
+ }], NodeHTMLTemplates: [{
523
+ type: Input
524
+ }], ExtensionModulesImporter: [{
525
+ type: Input
526
+ }], ExtensionModulesApplyer: [{
527
+ type: Input
528
+ }], onNodeClick: [{
529
+ type: Output
530
+ }], onNodeSelection: [{
531
+ type: Output
532
+ }], onLayoutDone: [{
533
+ type: Output
534
+ }], onLoaded: [{
535
+ type: Output
536
+ }] } });
537
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXMtZGlhZ3JhbS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9lcy1kaWFncmFtcy9zcmMvbGliL2NvbXBvbmVudHMvZXMtZGlhZ3JhbS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9lcy1kaWFncmFtcy9zcmMvbGliL2NvbXBvbmVudHMvZXMtZGlhZ3JhbS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQWEsUUFBUSxFQUFFLE1BQU0sRUFBaUIsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBa0JqSSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFJMUQsT0FBTyxLQUFLLEdBQUcsTUFBTSxXQUFXLENBQUM7Ozs7O0FBQ2pDLGNBQWMsQ0FBQSxNQUFNLFNBQVMsR0FBUyxHQUFJLENBQUMsT0FBTyxDQUFBLENBQUMsQ0FBTyxHQUFJLENBQUMsT0FBTyxDQUFBLENBQUMsQ0FBQyxHQUFHLENBQUM7QUFFNUU7O0dBRUc7QUFNSCxNQUFNLE9BQU8sa0JBQWtCO0lBK043Qjs7OztPQUlHO0lBQ0gsWUFBZ0MsT0FBeUIsRUFBc0IsVUFBK0IsRUFBVSxJQUF3QjtRQUFoSCxZQUFPLEdBQVAsT0FBTyxDQUFrQjtRQUFzQixlQUFVLEdBQVYsVUFBVSxDQUFxQjtRQUFVLFNBQUksR0FBSixJQUFJLENBQW9CO1FBN05oSjs7V0FFRztRQUNNLFNBQUksR0FBVyxFQUFFLENBQUM7UUFFM0I7O1dBRUc7UUFDTSxtQkFBYyxHQUFZLEtBQUssQ0FBQztRQVN6Qzs7V0FFRztRQUNNLHNCQUFpQixHQUFZLEtBQUssQ0FBQztRQU81Qzs7OztXQUlHO1FBQ00sa0JBQWEsR0FBK0IsRUFBRSxDQUFDO1FBc0J4RDs7V0FFRztRQUNNLG1CQUFjLEdBQVksSUFBSSxDQUFD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QWhCLEtBQUs7Z0JBS0csY0FBYztzQkFBdEIsS0FBSztnQkFPRyx3QkFBd0I7c0JBQWhDLEtBQUs7Z0JBT0csb0JBQW9CO3NCQUE1QixLQUFLO2dCQVlHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBS0csZUFBZTtzQkFBdkIsS0FBSztnQkFXRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBT0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUtHLE1BQU07c0JBQWQsS0FBSztnQkFPRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBbUJHLHdCQUF3QjtzQkFBaEMsS0FBSztnQkFtQkcsdUJBQXVCO3NCQUEvQixLQUFLO2dCQUtJLFdBQVc7c0JBQXBCLE1BQU07Z0JBS0csZUFBZTtzQkFBeEIsTUFBTTtnQkFLRyxZQUFZO3NCQUFyQixNQUFNO2dCQUtHLFFBQVE7c0JBQWpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uQ2hhbmdlcywgT3B0aW9uYWwsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcclxuXHJcbmltcG9ydCB7IENvbnRleHRNZW51T3B0aW9ucyB9IGZyb20gJy4uL21vZGVscy9jb21wb25lbnQvY29udGV4dG1lbnUvQ29udGV4dE1lbnVPcHRpb25zJztcclxuaW1wb3J0IHsgRXhwYW5kQ29sbGFwc2VPcHRpb25zIH0gZnJvbSAnLi4vbW9kZWxzL2NvbXBvbmVudC9ncm91cGluZy9FeHBhbmRDb2xsYXBzZU9wdGlvbnMnO1xyXG5pbXBvcnQgeyBOb2RlSFRNTFRlbXBsYXRlIH0gZnJvbSAnLi4vbW9kZWxzL2NvbXBvbmVudC9ub2Rlcy9Ob2RlSFRNTFRlbXBsYXRlJztcclxuXHJcbmltcG9ydCB7IEJyZWFkdGhGaXJzdExheW91dE9wdGlvbnNJbXBsIH0gZnJvbSAnLi4vbW9kZWxzL2xheW91dHMvQnJlYWR0aEZpcnN0TGF5b3V0T3B0aW9uc0ltcGwnO1xyXG5pbXBvcnQgeyBDaXJjbGVMYXlvdXRPcHRpb25zSW1wbCB9IGZyb20gJy4uL21vZGVscy9sYXlvdXRzL0NpcmNsZUxheW91dE9wdGlvbnNJbXBsJztcclxuaW1wb3J0IHsgQ29uY2VudHJpY0xheW91dE9wdGlvbnNJbXBsIH0gZnJvbSAnLi4vbW9kZWxzL2xheW91dHMvQ29uY2VudHJpY0xheW91dE9wdGlvbnNJbXBsJztcclxuaW1wb3J0IHsgQ29zZUxheW91dE9wdGlvbnNJbXBsIH0gZnJvbSAnLi4vbW9kZWxzL2xheW91dHMvQ29zZUxheW91dE9wdGlvbnNJbXBsJztcclxuaW1wb3J0IHsgRGFncmVMYXlvdXRPcHRpb25zSW1wbCB9IGZyb20gJy4uL21vZGVscy9sYXlvdXRzL0RhZ3JlTGF5b3V0T3B0aW9uc0ltcGwnO1xyXG5pbXBvcnQgeyBHcmlkTGF5b3V0T3B0aW9uc0ltcGwgfSBmcm9tICcuLi9tb2RlbHMvbGF5b3V0cy9HcmlkTGF5b3V0T3B0aW9uc0ltcGwnO1xyXG5pbXBvcnQgeyBOdWxsTGF5b3V0T3B0aW9uc0ltcGwgfSBmcm9tICcuLi9tb2RlbHMvbGF5b3V0cy9OdWxsTGF5b3V0T3B0aW9uc0ltcGwnO1xyXG5pbXBvcnQgeyBQcmVzZXRMYXlvdXRPcHRpb25zSW1wbCB9IGZyb20gJy4uL21vZGVscy9sYXlvdXRzL1ByZXNldExheW91dE9wdGlvbnNJbXBsJztcclxuaW1wb3J0IHsgUmFuZG9tTGF5b3V0T3B0aW9uc0ltcGwgfSBmcm9tICcuLi9tb2RlbHMvbGF5b3V0cy9SYW5kb21MYXlvdXRPcHRpb25zSW1wbCc7XHJcblxyXG5pbXBvcnQgeyBFc0RpYWdyYW1TZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvZXMtZGlhZ3JhbS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRXNEaWFncmFtRGlzcGF0Y2hlciB9IGZyb20gJy4uL3NlcnZpY2VzL2VzLWRpYWdyYW0uZGlzcGF0Y2hlcic7XHJcbmltcG9ydCB7IFJlc2l6ZVNlbnNvciB9IGZyb20gXCIuLi9leHRlbnNpb25zL1Jlc2l6ZVNlbnNvclwiO1xyXG5cclxuaW1wb3J0IHsgUmVhY3RpdmVFeHRlbnNpb25zIH0gZnJvbSAnLi4vZXh0ZW5zaW9ucy9SZWFjdGl2ZUV4dGVuc2lvbnMnO1xyXG5cclxuaW1wb3J0ICogYXMgY3lfIGZyb20gJ2N5dG9zY2FwZSc7XHJcbi8qKiBAaWdub3JlICovY29uc3QgY3l0b3NjYXBlID0gKDxhbnk+Y3lfKS5kZWZhdWx0PyAoPGFueT5jeV8pLmRlZmF1bHQ6IGN5XztcclxuXHJcbi8qKlxyXG4gKiBDb21wb25lbnRlIGNoZSBzaSBvY2N1cGEgZGkgZ3JhZmljYXJlIHVuIGRpYWdyYW1tYSBlIGRpIGdlc3Rpcm5lIGlsIGNpY2xvIGRpIHZpdGFcclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZXMtZGlhZ3JhbScsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2VzLWRpYWdyYW0uY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2VzLWRpYWdyYW0uY29tcG9uZW50LnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRXNEaWFncmFtQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcclxuXHJcbiAgLyoqXHJcbiAgICogUmlmZXJpbWVudG8gYWxsJ29nZ2V0dG8gSFRNTCBzdSBjdWkgY3JlYXJlIGlsIGRpYWdyYW1tYVxyXG4gICAqL1xyXG4gIEBWaWV3Q2hpbGQoJ2dyYXBoJykgY3lHcmFwaDogRWxlbWVudFJlZjtcclxuXHJcbiAgLyoqXHJcbiAgICogTm9tZSBkZWwgZGlhZ3JhbW1hLCBmb25kYW1lbnRhbGUgYXNzZWduYXJsbyBwZXIgcGVybWV0dGVyZSBhbGxhIGxpYnJlcmlhIGRpIHNjaGVkdWxhcm5lIGxhIGNyZWF6aW9uZVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIG5hbWU6IHN0cmluZyA9IFwiXCI7XHJcblxyXG4gIC8qKlxyXG4gICAqIEluZGljYSBzZSB1dGlsaXp6YXJlIGlsIG1lbsO5IGNvbnRlc3R1YWxlIGEgcnVvdGEgYXR0b3JubyBhZCBvZ25pIG5vZG9cclxuICAgKi9cclxuICBASW5wdXQoKSBVc2VDb250ZXh0TWVudTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvKipcclxuICAgKiBJbmRpY2EgbGUgb3B6aW9uaSBkZWwgbWVuw7kgY29udGVzdHVhbGUgcXVhbG9yYSAqKlVzZUNvbnRleHRNZW51KiogZm9zc2UgKip0cnVlKiouXHJcbiAgICogXHJcbiAgICogT2duaSBlbGVtZW50byBkaSBxdWVzdG8gYXJyYXkgw6ggdW4gc2VsZXR0b3JlIGNvbiBpbCBtZW51IGRhIG1vc3RyYXJlIHBlciBxdWVsbGEgY2FzaXN0aWNhXHJcbiAgICovXHJcbiAgQElucHV0KCkgQ29udGV4dE1lbnVPcHRpb25zOiBDb250ZXh0TWVudU9wdGlvbnNbXTtcclxuXHJcbiAgLyoqXHJcbiAgICogRGljZSBhbCBjb21wb25lbnRlIHNlIGlsIGRpYWdyYW1tYSBkZXZlIHV0aWxpenphcmUgaWwgc2lzdGVtYSBkaSBlc3RlbnNpb25lIHBlciBsJ2V4cGFuZCBlIGNvbGxhcHNlIGRlaSBncnVwcGlcclxuICAgKi9cclxuICBASW5wdXQoKSBVc2VFeHBhbmRDb2xsYXBzZTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvKipcclxuICAgKiBPcHppb25pIG5hdGl2ZSBkZWxsJ2VzdGVuc2lvbmUgZXhwYW5kLWNvbGxhcHNlLCB2ZW5nb25vIG92dmlhbWVudGUgdXRpbGl6emF0ZSBzb2xvIHNlICoqVXNlRXhwYW5kQ29sbGFwc2UqKiDDqCAqKnRydWUqKlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIEV4cGFuZENvbGxhcHNlT3B0aW9uczogRXhwYW5kQ29sbGFwc2VPcHRpb25zO1xyXG5cclxuICAvKipcclxuICAgKiBCbG9jY28gY29tcGxldG8gZGVsbGUgb3B6aW9uaSwgYWx0ZXJuYXRpdm8gYWxsJ2Fzc2VnbmF6aW9uZSBkaSAqKkVsZW1lbnRzKiosICoqTm9kZVN0eWxlcyoqLCAqKkVkZ2VTdHlsZXMqKiwgZSAqKkxheW91dCoqLlxyXG4gICAqIFxyXG4gICAqIFF1YWxvcmEgZW50cmFtYmUgdmVuaXNzZXJvIHNwZWNpZmljYXRlIHZlcnLDoCBlZmZldHR1YXRhIHVuJ3VuaW9uZSBmcmEgcXVlc3RlIG9wemlvbmkgZSBxdWVsbGUgc3BlY2lmaWNhdGUsIGRhbmRvIHByaW9yaXTDoCBhbGxlIHNwZWNpZmljYXRlXHJcbiAgICovXHJcbiAgQElucHV0KCkgTmF0aXZlT3B0aW9uczogY3l0b3NjYXBlLkN5dG9zY2FwZU9wdGlvbnMgPSB7fTtcclxuXHJcbiAgLyoqXHJcbiAgICogRGVmaW5pemlvbmUgZGVnbGkgZWxlbWVudGkgZGEgbW9zdHJhcmUgbmVsIGRpYWdyYW1tYVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIEVsZW1lbnRzOiBjeXRvc2NhcGUuRWxlbWVudERlZmluaXRpb25bXTtcclxuXHJcbiAgLyoqXHJcbiAgICogRGVmaW5pemlvbmUgZGVnbGkgc3RpbGkgZGVpIG5vZGlcclxuICAgKi9cclxuICBASW5wdXQoKSBOb2RlU3R5bGVzOiBjeXRvc2NhcGUuQ3NzLk5vZGU7XHJcblxyXG4gIC8qKlxyXG4gICAqIERlZmluaXppb25lIGRlZ2xpIHN0aWxpIGRlaSBjb2xsZWdhbWVudGkgZnJhIGkgbm9kaVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIEVkZ2VTdHlsZXM6IGN5dG9zY2FwZS5Dc3MuRWRnZTtcclxuXHJcbiAgLyoqXHJcbiAgICogSW4gdW4gZGlhZ3JhbW1hIGluIHNvbGEgbGV0dHVyYSB0dXR0ZSBsZSBpbnRlcmF6aW9uaSB1dGVudGUgc29ubyBhbm51bGxhdGVcclxuICAgKi9cclxuICBASW5wdXQoKSBSZWFkb25seTogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogQWdnaW9ybmEgYXV0b21hdGljYW1lbnRlIGxlIGRpbWVuc2lvbmkgZGVsIGRpYWdyYW1tYSBxdWFuZG8gY2FtYmlhbm8gbGUgZGltZW5zaW9uaSBkZWxsYSBmaW5lc3RyYVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIEF1dG91cGRhdGVTaXplOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogSW5kaWNhIGRpIG1hbnRlbmVyZSBsYSBwb3NpemlvbmUgZGVpIG5vZGkgcXVhbG9yYSB2ZW5pc3Nlcm8gY2FtYmlhdGkgZGFsbCdJbnB1dCAqKkVsZW1lbnRzKiouXHJcbiAgICogXHJcbiAgICogU2UgbCdJRCBkaSB1biBub2RvIMOoIHVndWFsZSBhbGwnSUQgZGkgdW4gbm9kbyBwcmVzZW50ZSBpbiBwcmVjZWRlbnphLCBpbCBudW92byBub2RvIG5lIGVyZWRpdGVyw6AgbGEgcG9zaXppb25lXHJcbiAgICovXHJcbiAgQElucHV0KCkgUHJlc2VydmVFbGVtZW50c1Bvc2l0aW9uOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogUXVhbG9yYSB2ZW5pc3NlIG1vZGlmaWNhdG8gbCdJbnB1dCAqKkVsZW1lbnRzKiosIHBpdXR0b3N0byBjaGUgbWV0dGVyZSBzZW1wbGljZW1lbnRlIGlsIG51b3ZvIEVsZW1lbnRvIGluIGJhc2UgYWwgTGF5b3V0IHByZWNlZGVudGUsIGFwcGxpY2EgYW5jaGUgdW4nYW5pbWF6aW9uZSBcclxuICAgKiBcclxuICAgKiBGdW56aW9uYSBzb2xhbWVudGUgc2UgaWwgKipMYXlvdXQqKiBjb3JyZW50ZSBkZWwgZGlhZ3JhbW1hIHN1cHBvcnRhIGxlIGFuaW1hemlvbmlcclxuICAgKi9cclxuICBASW5wdXQoKSBBbmltYXRlTGF5b3V0Q2hhbmdlczogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIEF0dGl2YSB1bmEgbW9kYWxpdMOgIGRpIHNlbGV6aW9uZSBcInNtYXJ0XCIuLi4gbyBwZXJsb21lbm8gXCJzbWFydGVyXCIgZGVsIGRlZmF1bHQgZGkgQ3l0b3NjYXBlLlxyXG4gICAqIFxyXG4gICAqIC0gSWwgY2xpY2sgZGkgdW4gZWxlbWVudG8gbm9uIHNlbGV6aW9uYXRvIGxvIHNlbGV6aW9uYVxyXG4gICAqIC0gSWwgY2xpY2sgZGkgdW4gZWxlbWVudG8gc2VsZXppb25hdG8gbG8gZGVzZWxlemlvbmFcclxuICAgKiAtIExvIHN0YXRvIGRpIHNlbGV6aW9uZSB2aWVuZSBwZXJzaXN0aXRvIHN1bGwnb2dnZXR0byBvcmlnaW5hbGUgaW52ZWNlIGRpIHJpbWFuZXJlIGluIHVuIGludGVybmFsXHJcbiAgICogLSBBbGwnYXNzZWduYXppb25lIGRpIG9nZ2V0dGkgc2VsZXppb25hdGksIHF1ZXN0aSB2ZW5nb25vIG1hcmNhdGkgY29ycmV0dGFtZW50ZSBjb24gbCdvdmVybGF5IGRpIHNlbGV6aW9uZVxyXG4gICAqIFxyXG4gICAqIE4uQjogbGEgY2hpYW1hdGEgYWxsJ2V2ZW50byAqKm9uTm9kZUNsaWNrKiogYXZ2aWVuZSAqKkRPUE8qKiBsYSBnZXN0aW9uZSBkZWxsYSBzZWxlemlvbmVcclxuICAgKi9cclxuICBASW5wdXQoKSBTbWFydFNlbGVjdGlvbjogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvKipcclxuICAgKiBJbmRpY2EgZGkgc2VsZXppb25hcmUgdW4gZWxlbWVudG8gcGVyIHZvbHRhIHF1YWxvcmEgKipTbWFydFNlbGVjdGlvbioqIGZvc3NlIGF0dGl2b1xyXG4gICAqL1xyXG4gIEBJbnB1dCgpIFNpbmdsZVNlbGVjdGlvbjogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvKipcclxuICAgKiBDU1MgcGVyIGxhIGdyYWZpY2F6aW9uZSBkZWxsYSBzZWxlemlvbmUgZGVpIG5vZGkuIFF1YW5kbyB1biBub2RvIHZlcnLDoCBzZWxlemlvbmF0byBhdnLDoCBzb3ByYSBkaSBzZSB1biBvdmVybGF5IGNoZSAnc2JvcmRhJyBkaSAqKm92ZXJsYXktcGFkZGluZyoqIHBpeGVsLFxyXG4gICAqIGRpIGNvbG9yZSAqKm92ZXJsYXktY29sb3IqKiBlIGNvbiB1biBvcGFjaXTDoCAqKm92ZXJsYXktb3BhY2l0eSoqXHJcbiAgICogXHJcbiAgICogQXNzZWduYW5kbyBcInt9XCIgYSBxdWVzdG8gaW5wdXQsIGxhIFNtYXJ0IHNlbGVjdGlvbiB2aWVuZSBnZXN0aXRhIG1hIGxhIGdlc3Rpb25lIGdyYWZpY2Egw6ggYWZmaWRhdGEgYWxsJ3V0ZW50ZSxcclxuICAgKiBhZCBlc2VtcGlvIHVzYW5kbyBkZWkgKipOb2RlSFRNTFRlbXBsYXRlcyoqIGNoZSBkZWZpbmlzY2FubyBzZWxldHRvcmkgc3Ugbm9kaSBcIjpzZWxlY3RlZFwiXHJcbiAgICogXHJcbiAgICogQGRlZmF1bHQgeydvdmVybGF5LWNvbG9yJzonYmx1ZScsJ292ZXJsYXktb3BhY2l0eSc6MC41LCdvdmVybGF5LXBhZGRpbmcnOjd9XHJcbiAgICovXHJcbiAgQElucHV0KCkgU21hcnRTZWxlY3Rpb25TdHlsZXM6IHsgJ292ZXJsYXktY29sb3InOiBzdHJpbmcsICdvdmVybGF5LW9wYWNpdHknOiBudW1iZXIsICdvdmVybGF5LXBhZGRpbmcnOiBudW1iZXIgfSA9IG51bGxcclxuXHJcbiAgLyoqXHJcbiAgICogUGVyaW9kbyBkaSB0aHJvdHRsZSBkYSBxdWFuZG8gdmllbmUgZWZmZXR0dWF0byB1biByZXNpemUgYSBxdWFuZG8gcmljYWxjb2xhcmUgbGUgZGltZW5zaW9uaSBkZWwgZGlhZ3JhbW1hLlxyXG4gICAqIFxyXG4gICAqIFB1w7IgZXNzZXJlIHRlbnV0byBhIDAgKHJlZHJhdyBpc3RhbnRhbmVvKSBmaW5jaMOpIG5vbiBjaSBzb25vIHByb2JsZW1pIGRpIHByZXN0YXppb25pIGNvbiBldmVudHVhbG1lbnRlIHRhbnRpIHJlc2l6ZSBhIHBvY2EgZGlzdGFuemEgbCd1bm8gZGFsbCdhbHRyby5cclxuICAgKi9cclxuICBASW5wdXQoKSBSZXNpemVUaHJvdHRsZVRpbWU6IG51bWJlciA9IDA7XHJcblxyXG4gIC8qKlxyXG4gICAqIExheW91dCBkaSBvcmRpbmFtZW50byBkZWkgbm9kaVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIExheW91dDogQnJlYWR0aEZpcnN0TGF5b3V0T3B0aW9uc0ltcGwgfCBDaXJjbGVMYXlvdXRPcHRpb25zSW1wbCB8IENvbmNlbnRyaWNMYXlvdXRPcHRpb25zSW1wbCB8XHJcbiAgICBDb3NlTGF5b3V0T3B0aW9uc0ltcGwgfCBEYWdyZUxheW91dE9wdGlvbnNJbXBsIHwgR3JpZExheW91dE9wdGlvbnNJbXBsIHwgTnVsbExheW91dE9wdGlvbnNJbXBsIHwgUHJlc2V0TGF5b3V0T3B0aW9uc0ltcGwgfFxyXG4gICAgUmFuZG9tTGF5b3V0T3B0aW9uc0ltcGw7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRlbXBsYXRlIEhUTUwgZGEgYXBwbGljYXJlIGFpIG5vZGkgcGVyIGRhcmdsaSBzdGlsaSBwYXJ0aWNvbGFyaSwgZGl2ZXJzaSBkYWxsZSBzaGFwZSBkaSBkZWZhdWx0XHJcbiAgICovXHJcbiAgQElucHV0KCkgTm9kZUhUTUxUZW1wbGF0ZXM6IE5vZGVIVE1MVGVtcGxhdGVbXTtcclxuXHJcbiAgLyoqXHJcbiAgICogRm9ybmlzY2UgaWwgZ2xvYmFsIGRlbGxhIGxpYnJlcmlhIChuYW1lc3BhY2UgKipjeXRvc2NhcGUqKikgZSBzaSBhc3BldHRhIGNoZSBkb3BvIG9wZXJhemlvbmkgZGkgaW1wb3J0YXppb25lIFxyXG4gICAqIGxhc2NpYXRlIGFsbCd1dGVudGUgdmVuZ2FubyBhZ2dpdW50aSB0dXR0aSBpIG1vZHVsaSBkZXNpZGVyYXRpLiBcclxuICAgKiBcclxuICAgKiDDiCAqKmZvbmRhbWVudGFsZSoqIGNoZSBpbCBwcmltbyBwYXJhbWV0cm8gKGlsIG5vbWUgZGVsIG1vZHVsbykgc2lhIHVndWFsZSBhIGNpw7IgZGkgY3VpIHZpZW5lIGZhdHRvIGlsIHJlcXVpcmUgaW4gbW9kbyBjaGUgbGEgbGlicmVyaWFcclxuICAgKiBwb3NzYSBjb250cm9sbGFyZSBjaGUgaWwgbW9kdWxvIGltcG9ydGF0byBub24gc2lhIGdpw6Agc3RhdG8gaW1wb3J0YXRvIGluIHByZWNlZGVuemFcclxuICAgKiBcclxuICAgKiAjIyBFc2VtcGlvOlxyXG4gICAqIFxyXG4gICAqIGBgYHR5cGVzY3JpcHRcclxuICAgKiAoZ2xvYmFsKSA9PiB7XHJcbiAgICogICAgcmV0dXJuIGltcG9ydChcImN5dG9zY2FwZS1leHRlbnNpb24tbGlicmFyeVwiKS50aGVuKG1vZHVsZSA9PiBnbG9iYWwudXNlKFwiY3l0b3NjYXBlLWV4dGVuc2lvbi1saWJyYXJ5XCIsIG1vZHVsZS5kZWZhdWx0KSk7XHJcbiAgICogXHJcbiAgICogICAgLi4uXHJcbiAgICogfVxyXG4gICAqIGBgYFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIEV4dGVuc2lvbk1vZHVsZXNJbXBvcnRlcjogKGdsb2JhbDogeyB1c2U6IChtb2R1bGVOYW1lOiBzdHJpbmcsIG1vZHVsZTogdm9pZCB8IGN5dG9zY2FwZS5FeHQpID0+IHZvaWQgfSkgPT4gUHJvbWlzZTxhbnk+ID0gbnVsbDtcclxuXHJcbiAgLyoqXHJcbiAgICogRm9ybmlzY2UgbCdpc3RhbnphIGF0dHVhbGUgZGkgQ3l0b3NjYXBlIGRhIGN1aSDDqCBwb3NzaWJpbGUgcHJlbmRlcmUgbGUgbGlicmVyaWUgZGkgZXN0ZW5zaW9uZSBjYXJpY2F0ZSBpbiAqKkV4dGVuc2lvbk1vZHVsZXNJbXBvcnRlcioqXHJcbiAgICogZSBjb25maWd1cmFybGUgaW4gYmFzZSBhaSBjb21wb3J0YW1lbnRpIHNwZWNpZmljaVxyXG4gICAqIFxyXG4gICAqICMjIEVzZW1waW86XHJcbiAgICogXHJcbiAgICogYGBgdHlwZXNjcmlwdFxyXG4gICAqIChjeXRvc2NhcGVDb3JlKSA9PiB7XHJcbiAgICogICAgLy8gRmFyZSBxdWVzdG8gbGF2b3JvIHBlciBvZ25pIGVzdGVuc2lvbmUgY2FyaWNhdGFcclxuICAgKiAgICBsZXQgZXh0ZW5zaW9uQ29uZmlndXJhdGlvbiA9IHsgLi4uIH07XHJcbiAgICogICAgbGV0IGV4dGVuc2lvbkluc3RhbmNlID0gY3l0b3NjYXBlQ29yZS5leHRlbnNpb25MaWJyYXJ5KGV4dGVuc2lvbkNvbmZpZ3VyYXRpb24pO1xyXG4gICAqICAgIGV4dGVuc2lvbkluc3RhbmNlLmRvU29tZXRoaW5nU3BlY2lmaWNUb1RoaXNFeHRlbnNpb24oKTtcclxuICAgKiBcclxuICAgKiAgICAuLi5cclxuICAgKiB9XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgQElucHV0KCkgRXh0ZW5zaW9uTW9kdWxlc0FwcGx5ZXI6IChjeXRvc2NhcGVDb3JlOiBjeXRvc2NhcGUuQ29yZSkgPT4gdm9pZCA9IG51bGw7XHJcblxyXG4gIC8qKlxyXG4gICAqIEV2ZW50byBsYW5jaWF0byBhbCBjbGljayBkaSB1biBub2RvLCBjb250aWVuZSBsJ29nZ2V0dG8gKipkYXRhKiogZGVsIG5vZG8gaW4gcXVlc3Rpb25lXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIG9uTm9kZUNsaWNrOiBFdmVudEVtaXR0ZXI8eyBkYXRhOiBhbnkgfT4gPSBuZXcgRXZlbnRFbWl0dGVyPHsgZGF0YTogYW55IH0+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEV2ZW50byBsYW5jaWF0byBhbGxhIHNlbGV6aW9uZSBvIGRlc2VsZXppb25lIGRpIHVuIG5vZG8sIGNvbnRpZW5lIGwnb2dnZXR0byAqKmRhdGEqKiBkZWwgbm9kbyBpbiBxdWVzdGlvbmUgZSBpbmZvcm1hemlvbmkgc3VsIHN1byBzdGF0byBkaSBzZWxlemlvbmVcclxuICAgKi9cclxuICBAT3V0cHV0KCkgb25Ob2RlU2VsZWN0aW9uOiBFdmVudEVtaXR0ZXI8eyBkYXRhOiBhbnksIHNlbGVjdGVkOiBib29sZWFuIH0+ID0gbmV3IEV2ZW50RW1pdHRlcjx7IGRhdGE6IGFueSwgc2VsZWN0ZWQ6IGJvb2xlYW4gfT4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRXZlbnRvIGxhbmNpYXRvIGFsIHRlcm1pbmUgZGVsIExheW91dGluZy4gU2Ugc2kgdnVvbGUgZXNlZ3VpcmUgY29kaWNlIGRvcG8gY2hlIGlsIExheW91dCDDqCBmYXR0byBlIGNvbXBsZXRhbWVudGUgZ3JhZmljYXRvLCBxdWVzdG8gw6ggaWwgcHVudG9cclxuICAgKi9cclxuICBAT3V0cHV0KCkgb25MYXlvdXREb25lOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEV2ZW50byBsYW5jaWF0byBhbCB0ZXJtaW5lIGRlbCBjYXJpY2FtZW50byBkZWwgZGlhZ3JhbW1hXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIG9uTG9hZGVkOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIFZhcmlhYmlsZSBzdSBjdWkgc2FsdmFyc2kgc2UgaSBub2RpIGhhbm5vIHVuYSBnZXJhcmNoaWEgYSBncnVwcGkgbyBuby4gU2VydmUgcGVyIHBvaSBjYXJpY2FyZSBsJ2VzdGVuc2lvbmUgZXhwYW5kLWNvbGxhcHNlIHF1YWxvcmEgZm9zc2UgcmljaGllc3RhXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBOb2Rlc0hpZXJhcmNoeTogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogSW5kaWNhIHNlIGlsIHJlbmRlcmluZyBkZWwgZGlhZ3JhbW1hIMOoIHRlcm1pbmF0b1xyXG4gICAqL1xyXG4gIHByaXZhdGUgUmVuZGVyZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogSXN0YW56YSBkZWwgZGlhZ3JhbW1hIGF0dHVhbG1lbnRlIGluIHVzb1xyXG4gICAqL1xyXG4gIHB1YmxpYyBjeTogY3l0b3NjYXBlLkNvcmVcclxuXHJcbiAgLyoqXHJcbiAgICogQXBpIGRlbGwnZXN0ZW5zaW9uZSBleHBhbmQtY29sbGFwc2UgcGVyIHBlcm1ldHRlcmUgZGkgZWZmZXR0dWFyZSBvcGVyYXppb25pIGRhbGwnZXN0ZXJubyBkZWwgZGlhZ3JhbW1hLiBWZW5nb25vIHZhbG9yaXp6YXRlIHNlICoqVXNlRXhwYW5kQ29sbGFwc2UqKiDDqCAqKnRydWUqKlxyXG4gICAqL1xyXG4gIHB1YmxpYyBFeHBhbmRDb2xsYXBzZUFwaTogYW55ID0gbnVsbDtcclxuXHJcbiAgLyoqXHJcbiAgICogQXBpIGRlbGwnZXN0ZW5zaW9uZSBodG1sLW5vZGUgcGVyIHBlcm1ldHRlcmUgZGkgZWZmZXR0dWFyZSBvcGVyYXppb25pIGRhbGwnZXN0ZXJubyBkZWwgZGlhZ3JhbW1hLiBWZW5nb25vIHZhbG9yaXp6YXRlIHNlIHNvbm8gaW1wb3N0YXRpIGRlaSAqKk5vZGVIVE1MVGVtcGxhdGVzKipcclxuICAgKi9cclxuICBwcml2YXRlIEh0bWxOb2RlQXBpOiBhbnkgPSBudWxsO1xyXG5cclxuICAvKipcclxuICAgKiBPc3NlcnZhdG9yZSBkZWxsZSBtb2RpZmljaGUgYWwgY29udGVuaXRvcmUgZGVsIGRpYWdyYW1tYVxyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVzaXplT2JzZXJ2ZXI6IFJlc2l6ZVNlbnNvcjtcclxuXHJcbiAgLyoqXHJcbiAgICogUmlmZXJpbWVudG8gYWxsJ3VsdGltbyBsYXlvdXQgdXRpbGl6emF0by4gVmllbmUgcmlhcHBsaWNhdG8gcXVhbG9yYSB2ZW5pc3NlIGNhbWJpYXRvIGwnSW5wdXQgKipFbGVtZW50cyoqLlxyXG4gICAqIFxyXG4gICAqIE5vbiB1dGlsaXp6byBpbCBtYWtlTGF5b3V0cyBwZXJjaMOpIGFsdHJpbWVudGkgcmlzY2hpZXJlaSBkaSBjcmVhcmUgdW4gbGF5b3V0IHJpZmVyaXRvIGEgWCBlbGVtZW50aSwgbmUgYWdnaXVuZ28gMSwgcmlhcHBsaWNvIGlsIExheW91dCBcclxuICAgKiBtYSBtaSB2aWVuZSByaWFwcGxpY2F0byBhIFggZWxlbWVudGkgaW52ZWNlIGNoZSBYICsgMVxyXG4gICAqL1xyXG4gIHByaXZhdGUgTGFzdExheW91dDogY3l0b3NjYXBlLkxheW91dE9wdGlvbnM7XHJcblxyXG4gIC8qKlxyXG4gICAqIENvc3RydXR0b3JlXHJcbiAgICogXHJcbiAgICogQGlnbm9yZVxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIHByaXZhdGUgc2VydmljZTogRXNEaWFncmFtU2VydmljZSwgQE9wdGlvbmFsKCkgcHJpdmF0ZSBkaXNwYXRjaGVyOiBFc0RpYWdyYW1EaXNwYXRjaGVyLCBwcml2YXRlIGV4dHM6IFJlYWN0aXZlRXh0ZW5zaW9ucykgeyB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBpZ25vcmUgXHJcbiAgICogXHJcbiAgICogQW5ndWxhciBQaXBlbGluZVxyXG4gICAqL1xyXG4gIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICBpZiAoIXRoaXMuc2VydmljZSB8fCAhdGhpcy5kaXNwYXRjaGVyKVxyXG4gICAgICB0aHJvdyBcIklsIG1vZHVsbyBAZXNmYWVuemEvZGlhZ3JhbXMgbm9uIMOoIHN0YXRvIGltcG9ydGF0byBjb24gaWwgZm9yUm9vdCgpO1wiO1xyXG5cclxuICAgIHRoaXMuZGlzcGF0Y2hMb2FkQ2hhcnQoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFsbCdvbkRlc3Ryb3kgcmlwdWxpc2NvIGxhIG1lbW9yaWEgZGFsIGRpYWdyYW1tYVxyXG4gICAqL1xyXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcclxuICAgIGlmICh0aGlzLnJlc2l6ZU9ic2VydmVyKSB7XHJcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIuZGlzcG9zZSgpO1xyXG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5jeSkge1xyXG4gICAgICB0aGlzLnNlcnZpY2UubG9nKFwiSVwiLCBcIkRpYWdyYW1cIiArIFwiIFwiICsgdGhpcy5uYW1lICsgXCI6IFVubG9hZGluZyBkZXN0cm95ZWQgZGlhZ3JhbVwiLCBmYWxzZSk7XHJcbiAgICAgIHRoaXMuY3kuZGVzdHJveSgpO1xyXG4gICAgICB0aGlzLmRpc3BhdGNoZXIuZGVyZWdpc3Rlcih0aGlzLm5hbWUpO1xyXG4gICAgfVxyXG4gICAgZWxzZVxyXG4gICAgICB0aGlzLnNlcnZpY2UubG9nKFwiSVwiLCBcIkNoYXJ0IFwiICsgdGhpcy5uYW1lICsgXCI6IFVubG9hZGluZyB1bmNyZWF0ZWQgY2hhcnQgY29tcG9uZW50LiBJdCBwcm9iYWJseSB3YXMgYSBkdXBsaWNhdGVkXCIsIGZhbHNlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlZ2lzdHJhIGlsIGRpYWdyYW1tYSBhdHR1YWxlIG5lbCBEaXNwYXRjaGVyIGluIG1vZG8gY2hlIHZlbmdhIGNhcmljYXRvIGFwcGVuYSBwb3NzaWJpbGVcclxuICAgKi9cclxuICBwcml2YXRlIGRpc3BhdGNoTG9hZENoYXJ0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5kaXNwYXRjaGVyLnJlZ2lzdGVyKHRoaXMubmFtZSwgKCkgPT4geyByZXR1cm4gdGhpcy5yZW5kZXIoKTsgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBAaWdub3JlIFxyXG4gICAqIFxyXG4gICAqIEFuZ3VsYXIgUGlwZWxpbmU6IEdlc3Rpb25lIHJpLWdyYWZpY2F6aW9uZSBkZWwgZGlhZ3JhbW1hLCBzZSBwb3NzaWJpbGVcclxuICAgKi9cclxuICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IGFueSB7XHJcbiAgICBsZXQgdG9DaGVjayA9IFtcIlRlbXBsYXRlc1wiLCBcIlVzZUNvbnRleHRNZW51XCIsIFwiQ29udGV4dE1lbnVPcHRpb25zXCIsIFwiVXNlRXhwYW5kQ29sbGFwc2VcIiwgXCJFeHBhbmRDb2xsYXBzZU9wdGlvbnNcIiwgXCJOb2RlU3R5bGVzXCIsIFwiRWRnZVN0eWxlc1wiLCBcIk5hdGl2ZU9wdGlvbnNcIl07XHJcblxyXG4gICAgaWYgKHRoaXMuUmVuZGVyZWQgJiYgdG9DaGVjay5zb21lKHQgPT4gY2hhbmdlc1t0XSkpXHJcbiAgICAgIHRoaXMuc2VydmljZS5sb2coXCJXXCIsIFwiUmVkcmF3IGJhc2VkIG9uIGR5bmFtaWMgSW5wdXQgY2hhbmdlIGlzIHN1cHBvcnRlZCBvbmx5IGZvciAnRWxlbWVudHMnIGFuZCAnTGF5b3V0JyBpbnB1dHMsIHBsZWFzZSBkZXN0cm95IHRoZSBjb21wb25lbnQgYW5kIHJlY3JlYXRlIGl0IHdpdGggdGhlIG5ldyBzZXR0aW5nc1wiKTtcclxuXHJcbiAgICBsZXQgZWxlbWVudENoYW5nZXMgPSBjaGFuZ2VzW1wiRWxlbWVudHNcIl07XHJcbiAgICBsZXQgbGF5b3V0Q2hhbmdlcyA9IGNoYW5nZXNbXCJMYXlvdXRcIl07XHJcbiAgICBpZiAoZWxlbWVudENoYW5nZXMgJiYgIWVsZW1lbnRDaGFuZ2VzLmZpcnN0Q2hhbmdlKSB7XHJcbiAgICAgIHRoaXMuc2VydmljZS5sb2coXCJJXCIsIFwiRWxlbWVudHMgaGF2ZSBiZWVuIGNoYW5nZWQgYWZ0ZXIgZGlhZ3JhbSBpbml0aWFsaXphdGlvblwiKTtcclxuXHJcbiAgICAgIC8vIENhbWJpYW1lbnRvIGFnbGkgRWxlbWVudGk6IHJpcHVsaXNjbyBnbGkgZWxlbWVudGkgdmVjY2hpLCBwcmVuZG8gaSBudW92aSwgbGkgc2lzdGVtbyBlIGxpIHJpYXNzZWduby4gXHJcbiAgICAgIC8vIFNlIGlsIG51b3ZvIElucHV0IEVsZW1lbnRzIMOoIHJvYmEgc3RyYW5hIG1pIGxpbWl0byBhIHJpcHVsaXJlIGlsIGRpYWdyYW1tYVxyXG4gICAgICAvLyBTZSBjeXRvc2NhcGUgYXZldmEgZ2nDoCBkZWdsaSBlbGVtZW50aSBwcmVjZWRlbnRlbWVudGUgbmUgcHJlbmRvIGxlIHBvc2l6aW9uaSBpbiBtb2RvIGRhIHJpZGlzZWduYXJsaSBwYXJ0ZW5kbyBkYWxsbyBzdGVzc28gcHVudG8gKGNhcmlubyBwZXIgbGUgYW5pbWF6aW9uaSlcclxuICAgICAgbGV0IGVsZW1lbnRzID0gZWxlbWVudENoYW5nZXM/LmN1cnJlbnRWYWx1ZTtcclxuICAgICAgbGV0IHByZXZpb3VzX2VsZW1lbnRzID0gdGhpcy5QcmVzZXJ2ZUVsZW1lbnRzUG9zaXRpb24gPyA8YW55PnRoaXMuY3kubm9kZXMoKSA6IG51bGw7XHJcblxyXG4gICAgICB0aGlzLmN5LmVsZW1lbnRzKCkucmVtb3ZlKCk7XHJcbiAgICAgIGlmIChlbGVtZW50cyAmJiBlbGVtZW50cy5sZW5ndGggJiYgZWxlbWVudHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHRoaXMucmV2aWV3Q3l0b3NjYXBlRWxlbWVudHMoZWxlbWVudHMsIHByZXZpb3VzX2VsZW1lbnRzKTtcclxuICAgICAgICB0aGlzLmN5LmFkZChlbGVtZW50cyk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLlNtYXJ0U2VsZWN0aW9uKVxyXG4gICAgICAgICAgdGhpcy5zZXR1cEVsZW1lbnRzU2VsZWN0aW9uSWZOZWVkZWQoKTtcclxuXHJcbiAgICAgICAgLy8gU2Ugc29sbyBnbGkgZWxlbWVudGkgY2FtYmlhbm8sIHJpYXBwbGljbyBpbCBMYXlvdXQgcHJlY2VkZW50ZVxyXG4gICAgICAgIGlmICghbGF5b3V0Q2hhbmdlcyAmJiB0aGlzLkxhc3RMYXlvdXQpIHtcclxuXHJcbiAgICAgICAgICAvLyBTZSBkZXZvIGFuaW1hcmUgbGUgbW9kaWZjaGUgYWwgbGF5b3V0IGZvcnpvIGlsIHBhcmFtZXRybyByZWxhdGl2b1xyXG4gICAgICAgICAgaWYgKHRoaXMuQW5pbWF0ZUxheW91dENoYW5nZXMpXHJcbiAgICAgICAgICAgICg8YW55PnRoaXMuTGFzdExheW91dCkuYW5pbWF0ZSA9IHRydWU7XHJcblxyXG4gICAgICAgICAgdGhpcy5jeS5sYXlvdXQodGhpcy5MYXN0TGF5b3V0KS5ydW4oKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBTZSBpbCBsYXlvdXQgY2FtYmlhIGxvIGFwcGxpY28gZSBtZSBsbyBzYWx2byBjb21lIGxheW91dCBwcmVjZWRlbnRlIHBlciBpbCBmdXR1cm9cclxuICAgIGlmIChsYXlvdXRDaGFuZ2VzICYmICFsYXlvdXRDaGFuZ2VzLmZpcnN0Q2hhbmdlKSB7XHJcbiAgICAgIHRoaXMuc2VydmljZS5sb2coXCJJXCIsIFwiTGF5b3V0IGhhdmUgYmVlbiBjaGFuZ2VkIGFmdGVyIGRpYWdyYW0gaW5pdGlhbGl6YXRpb25cIik7XHJcbiAgICAgIHRoaXMuTGFzdExheW91dCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkobGF5b3V0Q2hhbmdlcy5jdXJyZW50VmFsdWUpKTtcclxuICAgICAgdGhpcy5jeS5sYXlvdXQodGhpcy5MYXN0TGF5b3V0KS5ydW4oKVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRWZmZXR0dWEgaWwgcmVuZGVyaW5nIGRlbCBkaWFncmFtbWFcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIHJlbmRlcigpIHtcclxuXHJcbiAgICAvLyBUaXJvIGZ1b3JpIGxlIG9wemlvbmkgY29uIGN1aSBnZW5lcmFyZSBpbCBkaWFncmFtbWFcclxuICAgIGxldCBjeU9wdGlvbnMgPSB0aGlzLmdldENvbXBsZXRlZE9wdGlvbnMoKTtcclxuICAgIHRoaXMuTm9kZXNIaWVyYXJjaHkgPSBjeU9wdGlvbnMuZWxlbWVudHMgJiYgKDxjeV8uRWxlbWVudERlZmluaXRpb25bXT5jeU9wdGlvbnMuZWxlbWVudHMpLnNvbWUodCA9PiB0LmRhdGEucGFyZW50KTtcclxuXHJcbiAgICAvLyBDYXJpY28gZXZlbnR1YWxpIGNsYXNzaSBkaSBlc3RlbnNpb25lIGNoZSBzZXJ2b25vXHJcbiAgICBhd2FpdCB0aGlzLnBlcmZvcm1Nb2R1bGVzTG9hZGluZygpO1xyXG5cclxuICAgIC8vIEdlbmVybyBpbCBkaWFncmFtbWFcclxuICAgIHRoaXMuY3kgPSBjeXRvc2NhcGUoY3lPcHRpb25zKTtcclxuXHJcbiAgICAvLyBDb2xsZWdvIGdsaSBldmVudGkgYWwgY29tcG9uZW50ZVxyXG4gICAgdGhpcy5iaW5kQ3l0b3NjYXBlRXZlbnRzKCk7XHJcblxyXG4gICAgLy8gVXRpbGl6em8gbGUgY2xhc3NpIGRpIGVzdGVuc2lvbmUgY2FyaWNhdGUgcHJlY2VkZW50ZW1lbnRlIHBlciBmYXJlIGlsIHJlc3RvIGRlbGxlIG1pZSBvcGVyYXppb25pXHJcbiAgICB0aGlzLnBlcmZvcm1PcGVyYXRpb25zV2l0aExvYWRlZE1vZHVsZXMoKTtcclxuXHJcbiAgICAvLyBJbXBvc3RvIGxhIHZhcmlhYmlsZSBSZW5kZXJlZCBhIHRydWUgaW4gbW9kbyBjaGUgc2UgZGEgYWRlc3NvIHZlbmdvbm8gZmF0dGUgbW9kaWZpY2hlIGNoZSBkb3ZyZWJiZXJvIGNhdXNhcmUgdW4gcmVkcmF3IHBvc3NvIGFjY29yZ2VybWVuZVxyXG4gICAgLy8gZSBtYW5kYXJlIGEgY2FnYXJlIGxvIHN0cm9uem8gZGkgdHVybm9cclxuICAgIHRoaXMuUmVuZGVyZWQgPSB0cnVlO1xyXG5cclxuICAgIC8vIFNlIGRldm8gYWdnaW9ybmFyZSBpbiBhdXRvbWF0aWNvIGluIGJhc2UgYWxsYSBkaW1lbnNpb25lIGRlbCBjb250ZW5pdG9yZSBjb2xsZWdvIGlsIFJlc2l6ZU9ic2VydmVyXHJcbiAgICBpZiAodGhpcy5BdXRvdXBkYXRlU2l6ZSlcclxuICAgICAgdGhpcy5saXN0ZW5PbkNoYW5nZXMoKTtcclxuXHJcbiAgICBpZiAodGhpcy5TbWFydFNlbGVjdGlvbikge1xyXG4gICAgICB0aGlzLnNldHVwU2VsZWN0aW9uU3R5bGVzKCk7XHJcbiAgICAgIHRoaXMuc2V0dXBFbGVtZW50c1NlbGVjdGlvbklmTmVlZGVkKCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5vbkxvYWRlZC5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQcmVuZGUgdHV0dGkgZ2xpIGVsZW1lbnRpIGFwcGVuYSBhc3NlZ25hdGksIGUgc2UgcXVhbGN1bm8gZXJhIHNlbGV6aW9uYXRvIGxhIHNpdHVhemlvbmUgdmllbmUgcGVyc2lzdGl0YSBzdSBjeXRvc2NhcGVcclxuICAgKi9cclxuICBwcml2YXRlIHNldHVwRWxlbWVudHNTZWxlY3Rpb25JZk5lZWRlZCgpIHtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5FbGVtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICBsZXQgZWxkYXRhID0gPGFueT50aGlzLkVsZW1lbnRzW2ldLmRhdGE7XHJcbiAgICAgIGlmIChlbGRhdGEuX19zZWxlY3RlZCkge1xyXG4gICAgICAgIGxldCBlbCA9IHRoaXMuY3kuJGlkKGVsZGF0YS5pZCk7XHJcbiAgICAgICAgZWwuc2VsZWN0KCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENhcmljYSBnbGkgc3RpbGkgcGVyIG1vc3RyYXJlIGNhcmluYSBsYSBzZWxlemlvbmUgZGVpIG5vZGlcclxuICAgKi9cclxuICBwcml2YXRlIHNldHVwU2VsZWN0aW9uU3R5bGVzKCl7XHJcbiAgICBsZXQgY3NzSXRlbSA9IHRoaXMuU21hcnRTZWxlY3Rpb25TdHlsZXMgfHwge1xyXG4gICAgICAnb3ZlcmxheS1jb2xvcic6ICdibHVlJyxcclxuICAgICAgJ292ZXJsYXktb3BhY2l0eSc6IDAuNSxcclxuICAgICAgJ292ZXJsYXktcGFkZGluZyc6IDdcclxuICAgIH07XHJcblxyXG4gICAgLy8gQmFja2Rvb3IgcGVyIHBvdGVyIGFzc2VnbmFyZSBcInt9XCIgYSBTbWFydFNlbGVjdGlvblN0eWxlcyBpbiBtb2RvIGRpIHV0aWxpenphcmUgbGEgc21hcnQgc2VsZWN0aW9uIG1hIHNlbnphIGNoZSBuZXNzdW5vIHN0aWxlIHZlbmdhIGFwcGxpY2F0b1xyXG4gICAgLy8gYWQgZXNlbXBpbyBxdWFsb3JhIHNpIHZvbGVzc2UgdXRpbGl6emFyZSBsJ2h0bWxub2RlIHBlciBnZXN0aXJlIGxhIGdyYWZpY2EgZGVnbGkgZWxlbWVudGkgc2VsZXppb25hdGlcclxuICAgIGlmKGNzc0l0ZW1bJ292ZXJsYXktY29sb3InXSAmJiBjc3NJdGVtWydvdmVybGF5LW9wYWNpdHknXSAmJiBjc3NJdGVtWydvdmVybGF5LXBhZGRpbmcnXSlcclxuICAgICAgKDxhbnk+dGhpcy5jeS5zdHlsZSgpKS5zZWxlY3Rvcignbm9kZTpzZWxlY3RlZCcpLmNzcyhjc3NJdGVtKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlZ2lzdHJhIGwnYXNjb2x0byBhbCBjb250ZW5pdG9yZSBkZWwgZ3JhZmljbyBlIGluIGNhc28gZGkgbW9kaWZpY2hlIGFsbGEgZGltZW5zaW9uZSwgYWwgbWFzc2ltbyB1bmEgdm9sdGEgb2duaSA1MDAgbWlsbGlzZWNvbmRpLCBsbyByaWRpc2VnbmFcclxuICAgKi9cclxuICBwcml2YXRlIGxpc3Rlbk9uQ2hhbmdlcygpIHtcclxuICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplU2Vuc29yKHRoaXMuY3lHcmFwaC5uYXRpdmVFbGVtZW50LCAoKSA9PiB7XHJcbiAgICAgIHRoaXMuZXh0cy50aHJvdHRsZSh0aGlzLm5hbWUsIHRoaXMub25Db250YWluZXJTaXplQ2hhbmdlZC5iaW5kKHRoaXMpLCB0aGlzLlJlc2l6ZVRocm90dGxlVGltZSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZ1bnppb25lIGNoZSBzaSBvY2N1cGEgZGkgZ2VzdGlyZSBpbCByZXBhaW50IGRlbCBkaWFncmFtbWFcclxuICAgKi9cclxuICBwcml2YXRlIG9uQ29udGFpbmVyU2l6ZUNoYW5nZWQoKSB7XHJcbiAgICB0aGlzLnNlcnZpY2UubG9nKFwiSVwiLCBcIkRpYWdyYW0gY29udGFpbmVyIHNpemUgaGFzIGNoYW5nZWQsIHJlZHJhd2luZ1wiKTtcclxuICAgIHRoaXMuY3kucmVzaXplKCk7XHJcbiAgICB0aGlzLmN5LmZpdCgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ29sbGVnYSB0dXR0aSBnbGkgZXZlbnRpIGNoZSBtaSBwb3Nzb25vIHNlcnZpcmUgZSBsaSBlc3BvbmUgaW4gb3V0cHV0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBiaW5kQ3l0b3NjYXBlRXZlbnRzKCkge1xyXG4gICAgdGhpcy5jeS5iaW5kKCdjbGljaycsICdub2RlJywgKGV2ZW50KSA9PiB7XHJcbiAgICAgIGxldCB0YXJnZXREYXRhID0gZXZlbnQudGFyZ2V0LmRhdGEoKVxyXG4gICAgICBpZiAodGhpcy5TbWFydFNlbGVjdGlvbikge1xyXG5cclxuICAgICAgICAvLyBJbiBjYXNvIGRpIHNlbGV6aW9uZSBzaW5nb2xhIHJpcHVsaXNjbyB0dXR0aSBnbGkgZWxlbWVudGkgcHJlY2VkZW50ZW1lbnRlIHNlbGV6aW9uYXRpXHJcbiAgICAgICAgaWYgKHRoaXMuU2luZ2xlU2VsZWN0aW9uKSB7XHJcbiAgICAgICAgICBsZXQgc2VsZWN0ZWQgPSB0aGlzLmN5LmVsZW1lbnRzKCdub2RlOnNlbGVjdGVkJyk7XHJcbiAgICAgICAgICBzZWxlY3RlZC5mb3JFYWNoKGVsID0+IHtcclxuICAgICAgICAgICAgZWwuc2VsZWN0aWZ5KCk7XHJcbiAgICAgICAgICAgIGVsLnVuc2VsZWN0KCk7XHJcbiAgICAgICAgICAgIGVsLnVuc2VsZWN0aWZ5KCk7XHJcbiAgICAgICAgICAgIGVsLmRhdGEoXCJfX3NlbGVjdGVkXCIsIGZhbHNlKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBsZXQgaWQgPSB0YXJnZXREYXRhLmlkXHJcbiAgICAgICAgbGV0IGVsID0gdGhpcy5jeS4kaWQoaWQpO1xyXG4gICAgICAgIGxldCBzZWxlY3RlZCA9IGVsLnNlbGVjdGVkKCk7XHJcblxyXG4gICAgICAgIGVsLnNlbGVjdGlmeSgpO1xyXG4gICAgICAgIGlmIChzZWxlY3RlZClcclxuICAgICAgICAgIGVsLnVuc2VsZWN0KCk7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgZWwuc2VsZWN0KCk7XHJcbiAgICAgICAgZWwudW5zZWxlY3RpZnkoKTtcclxuXHJcbiAgICAgICAgLy8gUXVlc3RvIHZhIGFuY2hlIG5lbGxhIGxpc3RhIGRlZ2xpIGVsZW1lbnRpIG9yaWdpbmFsaSAodGhpcy5FbGVtZW50cykgZGF0byBjaGUgY3l0b3NjYXBlIGxpIHByZW5kZSBwZXIgcmlmZXJpbWVudG8gKGJiYmJicmF2byBjeXRvLWNoYW4pXHJcbiAgICAgICAgZWwuZGF0YShcIl9fc2VsZWN0ZWRcIiwgIXNlbGVjdGVkKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5vbk5vZGVDbGljay5lbWl0KHsgZGF0YTogdGFyZ2V0RGF0YSB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuY3kuYmluZCgnc2VsZWN0JywgJ25vZGUnLCAoZXZlbnQpID0+IHtcclxuICAgICAgbGV0IHRhcmdldERhdGEgPSBldmVudC50YXJnZXQuZGF0YSgpXHJcblxyXG4gICAgICB0aGlzLm9uTm9kZVNlbGVjdGlvbi5lbWl0KHsgZGF0YTogdGFyZ2V0RGF0YSwgc2VsZWN0ZWQ6IHRydWUgfSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmN5LmJpbmQoJ2xheW91dHN0b3AnLCAoZXZlbnQpID0+IHtcclxuICAgICAgdGhpcy5vbkxheW91dERvbmUuZW1pdCgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5jeS5iaW5kKCd1bnNlbGVjdCcsICdub2RlJywgKGV2ZW50KSA9PiB7XHJcbiAgICAgIGxldCB0YXJnZXREYXRhID0gZXZlbnQudGFyZ2V0LmRhdGEoKVxyXG5cclxuICAgICAgdGhpcy5vbk5vZGVTZWxlY3Rpb24uZW1pdCh7IGRhdGE6IHRhcmdldERhdGEsIHNlbGVjdGVkOiBmYWxzZSB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIEFsdHJpIGV2ZW50aS4uLlxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0b2RvIGNoZSBzZXJ2ZSBwZXIgY2FyaWNhcmUgdHV0dGUgbGUgZXN0ZW5zaW9uaSBkZWxsYSBsaWJyZXJpYSBpbiBiYXNlIGEgY2nDsiBjaGUgdmllbmUgdXRpbGl6emF0b1xyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgcGVyZm9ybU1vZHVsZXNMb2FkaW5nKCkge1xyXG4gICAgaWYgKHRoaXMuTGF5b3V0Lm5hbWUgPT0gJ2RhZ3JlJylcclxuICAgICAgYXdhaXQgdGhpcy5sb2FkSW50ZXJuYWwoXCJjeXRvc2NhcGUtZGFncmVcIik7XHJcblxyXG4gICAgaWYgKHRoaXMuTm9kZUhUTUxUZW1wbGF0ZXMgJiYgdGhpcy5Ob2RlSFRNTFRlbXBsYXRlcy5sZW5ndGggPiAwKVxyXG4gICAgICBhd2FpdCB0aGlzLmxvYWRJbnRlcm5hbChcImN5dG9zY2FwZS1odG1sLW5vZGVcIik7XHJcblxyXG4gICAgaWYgKHRoaXMuVXNlQ29udGV4dE1lbnUpXHJcbiAgICAgIGF3YWl0IHRoaXMubG9hZEludGVybmFsKFwiY3l0b3NjYXBlLWN4dG1lbnVcIik7XHJcblxyXG4gICAgaWYgKHRoaXMuTm9kZXNIaWVyYXJjaHkgJiYgdGhpcy5Vc2VFeHBhbmRDb2xsYXBzZSlcclxuICAgICAgYXdhaXQgdGhpcy5sb2FkSW50ZXJuYWwoXCJjeXRvc2NhcGUtZXhwYW5kLWNvbGxhcHNlXCIpO1xyXG5cclxuICAgIGlmICh0aGlzLkV4dGVuc2lvbk1vZHVsZXNJbXBvcnRlcikge1xyXG4gICAgICAvLyBXcmFwcG8gaWwgbmFtZXNwYWNlIGluIG1vZG8gY2hlIHBvc3NhIGRpcmUgbGEgbWlhIHN1bCBmYXR0byBjaGUgbCd1dGVudGUgYWdnaXVuZ2EgdW4gbW9kdWxvIG8gbWVubyA6RFxyXG4gICAgICB2YXIgd3JhcHBlZEN5dG9zY2FwZSA9IHtcclxuICAgICAgICB1c2U6IChtb2R1bGVOYW1lOiBzdHJpbmcsIG1vZHVsZTogY3l0b3NjYXBlLkV4dCkgPT4ge1xyXG4gICAgICAgICAgaWYgKCFtb2R1bGUpXHJcbiAgICAgICAgICAgIHRoaXMuc2VydmljZS5sb2coXCJFXCIsIHRoaXMuc2VydmljZS5sb2MoXCJSZWNlaXZlZCBhbiB1bmRlZmluZWQgbW9kdWxlLiBNYWtlIHN1cmUgeW91IGFyZSBjb3JyZWN0bHkgbG9hZGluZyBpdFwiKSArIFwiOiBcIiArIG1vZHVsZU5hbWUsIGZhbHNlKTtcclxuXHJcbiAgICAgICAgICBpZiAoW1wiY3l0b3NjYXBlLWRhZ3JlXCIsIFwiY3l0b3NjYXBlLWh0bWwtbm9kZVwiLCBcImN5dG9zY2FwZS1jeHRtZW51XCIsIFwiY3l0b3NjYXBlLWV4cGFuZC1jb2xsYXBzZVwiXS5pbmNsdWRlcyhtb2R1bGVOYW1lKSlcclxuICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLmxvZyhcIldcIiwgdGhpcy5zZXJ2aWNlLmxvYyhcIk1vZHVsZVwiKSArIFwiIFwiICsgbW9kdWxlTmFtZSArIFwiIFwiICsgdGhpcy5zZXJ2aWNlLmxvYyhcImlzIGxvYWRlZCBhbmQgbWFuYWdlZCBkaXJlY3RseSBieSB0aGlzIGxpYnJhcnkuIFlvdSBkb24ndCBuZWVkIHRvIGltcG9ydCBpdCBvciB1c2UgaXQgZGlyZWN0bHksIGp1c3QgYmUgc3VyZSB0byBzZXQgdGhlIHJlbGF0aXZlIG9wdGlvbnNcIiksIGZhbHNlKTtcclxuICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgY3l0b3NjYXBlLnVzZShtb2R1bGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgYXdhaXQgdGhpcy5FeHRlbnNpb25Nb2R1bGVzSW1wb3J0ZXIod3JhcHBlZEN5dG9zY2FwZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNZXRvZG8gY2hlIHNlcnZlIHBlciBjYXJpY2FyZSB0dXR0ZSBsZSBlc3RlbnNpb25pIGRlbGxhIGxpYnJlcmlhIGluIGJhc2UgYSBjacOyIGNoZSB2aWVuZSB1dGlsaXp6YXRvIGNvbiBsZSBvcHppb25pIGRlZmluaXRlIGRhZ2xpIElucHV0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBwZXJmb3JtT3BlcmF0aW9uc1dpdGhMb2FkZWRNb2R1bGVzKCkge1xyXG5cclxuICAgIGxldCBhbnlDeSA9ICg8YW55PnRoaXMuY3kpO1xyXG5cclxuICAgIC8vIFV0aWxpenpvIGRlbCBsYXlvdXQsIGxvIHNhbHZvIHBlciBwb3RlcmxvIHJpdXRpbGl6emFyZSBpbiBmdXR1cm9cclxuICAgIGlmICh0aGlzLkxheW91dCkge1xyXG4gICAgICB0aGlzLkxhc3RMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuTGF5b3V0KSk7XHJcbiAgICAgIHRoaXMuY3kubGF5b3V0KHRoaXMuTGFzdExheW91dCkucnVuKClcclxuICAgIH1cclxuXHJcbiAgICAvLyBVdGlsaXp6byBkZWxsJ0hUTUwgbm9kZVxyXG4gICAgaWYgKHRoaXMuTm9kZUhUTUxUZW1wbGF0ZXMgJiYgdGhpcy5Ob2RlSFRNTFRlbXBsYXRlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMuSHRtbE5vZGVBcGkgPSBhbnlDeS5odG1sbm9kZSgpO1xyXG4gICAgICB0aGlzLkh0bWxOb2RlQXBpLmNyZWF0ZUh0bWxOb2RlKGN5dG9zY2FwZSwgdGhpcy5jeSwgdGhpcy5Ob2RlSFRNTFRlbXBsYXRlcyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVXRpbGl6em8gZGVsIENvbnRleHQgTWVudVxyXG4gICAgaWYgKHRoaXMuVXNlQ29udGV4dE1lbnUpXHJcbiAgICAgIHRoaXMuQ29udGV4dE1lbnVPcHRpb25zLmZvckVhY2gobyA9PiB7IGFueUN5LmN4dG1lbnUobyk7IH0pO1xyXG5cclxuICAgIC8vIFV0aWxpenpvIGRlbGwnZXhwYW5kIGNvbGxhcHNlIHNvbG8gcXVhbmRvIGMnw6ggdW5hIGdlcmFyY2hpYSBkaSBub2RpXHJcbiAgICBpZiAodGhpcy5Ob2Rlc0hpZXJhcmNoeSAmJiB0aGlzLlVzZUV4cGFuZENvbGxhcHNlKVxyXG4gICAgICB0aGlzLkV4cGFuZENvbGxhcHNlQXBpID0gYW55Q3kuZXhwYW5kQ29sbGFwc2UodGhpcy5FeHBhbmRDb2xsYXBzZU9wdGlvbnMpO1xyXG5cclxuICAgIC8vIFV0aWxpenpvIGRpIGVzdGVuc2lvbmkgZXh0cmEsIGltcGxlbWVudGF6aW9uZSBhZmZpZGF0YSBhbCBwcm9ncmFtbWF0b3JlXHJcbiAgICBpZiAodGhpcy5FeHRlbnNpb25Nb2R1bGVzQXBwbHllcilcclxuICAgICAgdGhpcy5FeHRlbnNpb25Nb2R1bGVzQXBwbHllcih0aGlzLmN5KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB1cGRhdGVDYXJkRGF0YSgpIHtcclxuICAgIGlmICghdGhpcy5IdG1sTm9kZUFwaSkge1xyXG4gICAgICB0aGlzLnNlcnZpY2UubG9nKFwiRVwiLCBcIkNhbm5vdCB1cGRhdGUgTm9kZUhUTUxUZW1wbGF0ZXMgYXMgdGhleSBkb24ndCBzZWVtIHRvIGJlIHVzZWRcIik7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMuSHRtbE5vZGVBcGkudXBkYXRlKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNZXRvZG8gaW50ZXJubyBwZXIgaWwgY2FyaWNhbWVudG8gZGVpIG1vZHVsaSBkaSBlc3RlbnNpb25lXHJcbiAgICogXHJcbiAgICogQHBhcmFtIHsnY3l0b3NjYXBlLWV4cGFuZC1jb2xsYXBzZScgfCAnY3l0b3NjYXBlLWN4dG1lbnUnIHwgJ2N5dG9zY2FwZS1odG1sLW5vZGUnIHwgJ2N5dG9zY2FwZS1kYWdyZSd9IG1vZHVsZUlkIE1vZHVsbyBkYSBjYXJpY2FyZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgbG9hZEludGVybmFsKG1vZHVsZUlkOiAnY3l0b3NjYXBlLWV4cGFuZC1jb2xsYXBzZScgfCAnY3l0b3NjYXBlLWN4dG1lbnUnIHwgJ2N5dG9zY2FwZS1odG1sLW5vZGUnIHwgJ2N5dG9zY2FwZS1kYWdyZScpIHtcclxuICAgIGxldCB0b0xvYWQgPSBhd2FpdCB0aGlzLnNlcnZpY2UuaW1wb3J0SWZOZWVkZWQobW9kdWxlSWQpO1xyXG4gICAgaWYgKHRvTG9hZCkgY3l0b3NjYXBlLnVzZSh0b0xvYWQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0b2RvIGNoZSBiYXNhbmRvc2kgc3VsbGUgb3B6aW9uaSBuYXRpdmUgZXZlbnR1YWxtZW50ZSBhc3NlZ25hdGUgbGUgY29tcGxldGEgY29uIGdsaSBJbnB1dCBhZGRpemlvbmFsaVxyXG4gICAqIFxyXG4gICAqIEByZXR1cm5zIHtjeV8uQ3l0b3NjYXBlT3B0aW9uc30gT3B6aW9uaSBmaW5hbGkgdW5pdGUgZGEgSW5wdXQgZWQgb3B6aW9uaSBuYXRpdmVcclxuICAgKi9cclxuICBwcml2YXRlIGdldENvbXBsZXRlZE9wdGlvbnMoKTogY3lfLkN5dG9zY2FwZU9wdGlvbnMge1xyXG4gICAgdmFyIG9wdHM6IGN5Xy5DeXRvc2NhcGVPcHRpb25zID0gdGhpcy5OYXRpdmVPcHRpb25zIHx8IHt9O1xyXG4gICAgb3B0cy5jb250YWluZXIgPSB0aGlzLmN5R3JhcGgubmF0aXZlRWxlbWVudDtcclxuICAgIG9wdHMuc3R5bGUgPSBvcHRzLnN0eWxlIHx8IFtdO1xyXG5cclxuICAgIC8vIFBlciB0dXR0ZSBsZSBjb3NlIHBlciBjdWkgZ2xpIElucHV0IGhhbm5vIHByaW9yaXTDoCBzb3ZyYXNjcml2byBnbGkgb3JpZ2luYWxpIGRlbGxlIG9wemlvbmlcclxuXHJcbiAgICBpZiAodGhpcy5Ob2RlU3R5bGVzIHx8IHRoaXMuRWRnZVN0eWxlcykge1xyXG4gICAgICBvcHRzLnN0eWxlID0gW107XHJcbiAgICAgIGlmICh0aGlzLk5vZGVTdHlsZXMpIG9wdHMuc3R5bGUucHVzaCh7IHNlbGVjdG9yOiAnbm9kZScsIGNzczogdGhpcy5Ob2RlU3R5bGVzIH0pO1xyXG4gICAgICBpZiAodGhpcy5FZGdlU3R5bGVzKSBvcHRzLnN0eWxlLnB1c2goeyBzZWxlY3RvcjogJ2VkZ2UnLCBjc3M6IHRoaXMuRWRnZVN0eWxlcyB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5FbGVtZW50cylcclxuICAgICAgb3B0cy5lbGVtZW50cyA9IHRoaXMuRWxlbWVudHM7XHJcblxyXG4gICAgdGhpcy5yZXZpZXdDeXRvc2NhcGVFbGVtZW50cyg8Y3l0b3NjYXBlLkVsZW1lbnREZWZpbml0aW9uW10+b3B0cy5lbGVtZW50cyk7XHJcblxyXG4gICAgaWYgKHRoaXMuTGF5b3V0KVxyXG4gICAgICBvcHRzLmxheW91dCA9IHRoaXMuTGF5b3V0O1xyXG5cclxuICAgIGlmICh0aGlzLlJlYWRvbmx5KSB7XHJcbiAgICAgIC8vIFF1ZXN0byBjb3NvIGZhIGVmZmV0dGkgc3RyYW5pLi4uLlxyXG4gICAgICAvL29wdHMuYXV0b2xvY2sgPSB0cnVlO1xyXG5cclxuICAgICAgb3B0cy5hdXRvdW5ncmFiaWZ5ID0gdHJ1ZTtcclxuICAgICAgb3B0cy5hdXRvdW5zZWxlY3RpZnkgPSBmYWxzZTtcclxuICAgICAgb3B0cy5ib3hTZWxlY3Rpb25FbmFibGVkID0gdHJ1ZTtcclxuICAgICAgb3B0cy51c2VyWm9vbWluZ0VuYWJsZWQgPSBmYWxzZTtcclxuICAgICAgb3B0cy51c2VyUGFubmluZ0VuYWJsZWQgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gb3B0cztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFnZ2l1c3RhbWVudGkgZGVnbGkgZWxlbWVudGkgZGkgQ3l0b3NjYXBlLiBcclxuICAgKiBcclxuICAgKiBJIG5vZGkgbm9uIHZlbmdvbm8gdG9jY2F0aS5cclxuICAgKiBcclxuICAgKiBQZXIgb2duaSBlZGdlIHZpZW5lIGNvbnRyb2xsYXRvIHNlIMOoIHNwZWNpZmljYXRhIHVuYSBzb3JnZW50ZSBlZCB1bmEgZGVzdGluYXppb25lLCBpbiBjYXNvIGNvbnRyYXJpbyBzaSBjZXJjYSBkaSBkZWR1cmxpIGRhbGwnSURcclxuICAgKiBcclxuICAgKiBAcGFyYW0ge2N5dG9zY2FwZS5FbGVtZW50RGVmaW5pdGlvbltdfSBlbGVtZW50cyBFbGVtZW50aSBkYSBzaXN0ZW1hcmVcclxuICAgKi9cclxuICBwcml2YXRlIHJldmlld0N5dG9zY2FwZUVsZW1lbnRzKGVsZW1lbnRzOiBjeXRvc2NhcGUuRWxlbWVudERlZmluaXRpb25bXSwgcHJldlBvc2l0aW9ucz86IGFueSkge1xyXG4gICAgbGV0IGhhc1ByZXZpb3VzUG9zaXRpb25zID0gcHJldlBvc2l0aW9ucyAmJiBwcmV2UG9zaXRpb25zLmxlbmd0aCA+IDA7XHJcbiAgICBsZXQgcG9zaXRpb25DYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IGN5dG9zY2FwZS5Qb3NpdGlvbiB9ID0ge307XHJcblxyXG4gICAgaWYgKGhhc1ByZXZpb3VzUG9zaXRpb25zKSB7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJldlBvc2l0aW9ucy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGxldCBpdGVtID0gcHJldlBvc2l0aW9uc1tpXTtcclxuICAgICAgICBpZiAoIXBvc2l0aW9uQ2FjaGVbaXRlbS5kYXRhKCkuaWRdKVxyXG4gICAgICAgICAgcG9zaXRpb25DYWNoZVtpdGVtLmRhdGEoKS5pZF0gPSBpdGVtLnBvc2l0aW9uKCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGxldCBlbCA9IGVsZW1lbnRzW2ldO1xyXG4gICAgICBpZiAoZWwuZ3JvdXAgPT0gXCJlZGdlc1wiICYmICghZWwuZGF0YS5zb3VyY2UgJiYgIWVsLmRhdGEudGFyZ2V0KSkge1xyXG4gICAgICAgIGlmICghZWwuZGF0YS5pZC5pbmNsdWRlcyhcIi1cIikpXHJcbiAgICAgICAgICB0aGlzLnNlcnZpY2UubG9nKFwiRVwiLCBcIklmIHlvdSBkb24ndCBzcGVjaWZ5IGEgc291cmNlIGFuZCBhIHRhcmdldCBmb3IgYW4gZWRnZSB5b3UgaGF2ZSB0byB3cml0ZSBpdHMgaWQgaW4gdGhlIGZvcm1hdCB7c291cmNlfS17dGFyZ2V0fVwiKTtcclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgIHZhciBzb3VyY2VUYXJnZXQgPSBlbC5kYXRhLmlkLnNwbGl0KCctJyk7XHJcbiAgICAgICAgICBlbC5kYXRhLnNvdXJjZSA9IHNvdXJjZVRhcmdldFswXS50cmltKCk7XHJcbiAgICAgICAgICBlbC5kYXRhLnRhcmdldCA9IHNvdXJjZVRhcmdldFsxXS50cmltKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaGFzUHJldmlvdXNQb3NpdGlvbnMgJiYgZWwuZ3JvdXAgPT0gXCJub2Rlc1wiKVxyXG4gICAgICAgIGVsLnBvc2l0aW9uID0gcG9zaXRpb25DYWNoZVtlbC5kYXRhLmlkXVxyXG4gICAgfVxyXG4gIH1cclxufSIsIjxkaXYgI2dyYXBoIGNsYXNzPVwiZ3JhcGgtd3JhcHBlciB7e25hbWV9fVwiPjwvZGl2PiJdfQ==