@esfaenza/extensions 15.2.48 → 15.2.51

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 (65) hide show
  1. package/{esm2022 → esm2020}/esfaenza-extensions.mjs +4 -4
  2. package/esm2020/lib/models/CallResult.mjs +6 -0
  3. package/esm2020/lib/models/CsvHeaders.mjs +6 -0
  4. package/{esm2022 → esm2020}/lib/models/ExportConsts.mjs +31 -31
  5. package/esm2020/lib/models/ExtensionsModuleConfig.mjs +4 -0
  6. package/esm2020/lib/models/GenericItem.mjs +6 -0
  7. package/{esm2022 → esm2020}/lib/models/InboundMessageTypes.mjs +6 -6
  8. package/esm2020/lib/models/InterComMessage.mjs +14 -0
  9. package/{esm2022 → esm2020}/lib/models/TypeCode.mjs +24 -24
  10. package/{esm2022 → esm2020}/lib/modules/extensions.module.mjs +32 -32
  11. package/esm2020/lib/pipes/loc_date.pipe.mjs +37 -0
  12. package/esm2020/lib/services/extensions.base.mjs +29 -0
  13. package/esm2020/lib/services/extensions.clipboard.service.mjs +219 -0
  14. package/esm2020/lib/services/extensions.dates.service.mjs +246 -0
  15. package/esm2020/lib/services/extensions.embedding.service.mjs +248 -0
  16. package/esm2020/lib/services/extensions.exports.service.mjs +615 -0
  17. package/esm2020/lib/services/extensions.hashing.service.mjs +310 -0
  18. package/esm2020/lib/services/extensions.intercom.service.mjs +54 -0
  19. package/esm2020/lib/services/extensions.messages.service.mjs +433 -0
  20. package/esm2020/lib/services/extensions.utilities.service.mjs +252 -0
  21. package/{esm2022 → esm2020}/lib/tokens.mjs +11 -11
  22. package/{esm2022 → esm2020}/public-api.mjs +21 -21
  23. package/fesm2015/esfaenza-extensions.mjs +2558 -0
  24. package/fesm2015/esfaenza-extensions.mjs.map +1 -0
  25. package/{fesm2022 → fesm2020}/esfaenza-extensions.mjs +2486 -2510
  26. package/fesm2020/esfaenza-extensions.mjs.map +1 -0
  27. package/index.d.ts +5 -5
  28. package/lib/models/CallResult.d.ts +23 -23
  29. package/lib/models/CsvHeaders.d.ts +25 -25
  30. package/lib/models/ExportConsts.d.ts +31 -31
  31. package/lib/models/ExtensionsModuleConfig.d.ts +9 -9
  32. package/lib/models/GenericItem.d.ts +9 -9
  33. package/lib/models/InboundMessageTypes.d.ts +5 -5
  34. package/lib/models/InterComMessage.d.ts +12 -12
  35. package/lib/models/TypeCode.d.ts +23 -23
  36. package/lib/modules/extensions.module.d.ts +11 -11
  37. package/lib/pipes/loc_date.pipe.d.ts +24 -24
  38. package/lib/services/extensions.base.d.ts +22 -22
  39. package/lib/services/extensions.clipboard.service.d.ts +54 -54
  40. package/lib/services/extensions.dates.service.d.ts +101 -99
  41. package/lib/services/extensions.embedding.service.d.ts +33 -28
  42. package/lib/services/extensions.exports.service.d.ts +234 -234
  43. package/lib/services/extensions.hashing.service.d.ts +121 -121
  44. package/lib/services/extensions.intercom.service.d.ts +28 -28
  45. package/lib/services/extensions.messages.service.d.ts +195 -195
  46. package/lib/services/extensions.utilities.service.d.ts +107 -107
  47. package/lib/tokens.d.ts +11 -11
  48. package/package.json +11 -5
  49. package/public-api.d.ts +18 -18
  50. package/esm2022/lib/models/CallResult.mjs +0 -24
  51. package/esm2022/lib/models/CsvHeaders.mjs +0 -26
  52. package/esm2022/lib/models/ExtensionsModuleConfig.mjs +0 -10
  53. package/esm2022/lib/models/GenericItem.mjs +0 -10
  54. package/esm2022/lib/models/InterComMessage.mjs +0 -16
  55. package/esm2022/lib/pipes/loc_date.pipe.mjs +0 -38
  56. package/esm2022/lib/services/extensions.base.mjs +0 -30
  57. package/esm2022/lib/services/extensions.clipboard.service.mjs +0 -221
  58. package/esm2022/lib/services/extensions.dates.service.mjs +0 -244
  59. package/esm2022/lib/services/extensions.embedding.service.mjs +0 -213
  60. package/esm2022/lib/services/extensions.exports.service.mjs +0 -617
  61. package/esm2022/lib/services/extensions.hashing.service.mjs +0 -308
  62. package/esm2022/lib/services/extensions.intercom.service.mjs +0 -52
  63. package/esm2022/lib/services/extensions.messages.service.mjs +0 -450
  64. package/esm2022/lib/services/extensions.utilities.service.mjs +0 -250
  65. package/fesm2022/esfaenza-extensions.mjs.map +0 -1
@@ -0,0 +1,248 @@
1
+ // Angular
2
+ import { Injectable } from "@angular/core";
3
+ // Libraries
4
+ import { Subject, filter } from "rxjs";
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "./extensions.messages.service";
7
+ import * as i2 from "@angular/router";
8
+ import * as i3 from "@angular/common";
9
+ /* Classe che contiene tutte le informazioni sull'embedding in un unico contenitore per semplicità */
10
+ export class AppEmbeddingExtensions {
11
+ constructor(msgService, router, location) {
12
+ this.msgService = msgService;
13
+ this.router = router;
14
+ this.location = location;
15
+ this.sidebarWidth = 230;
16
+ this.Embedded = false;
17
+ this.EmbeddingLevel = 0;
18
+ this.MessageObserver = new Subject();
19
+ this._reloadAllowed = true;
20
+ this.pushedHistories = [];
21
+ this.MessageBarrierDebouncMs = 250;
22
+ this.OnMessageCallBarrier = {};
23
+ this.MainWindow = window;
24
+ while (this.MainWindow.parent != this.MainWindow) {
25
+ this.MainWindow = this.MainWindow.parent;
26
+ this.EmbeddingLevel++;
27
+ this.Embedded = true;
28
+ // Fallback per farlo funzionare forzatamente mentre lo testo
29
+ this.EmbeddedModule = this.location.path().match(/module=([a-zA-Z_]+)/)?.[1];
30
+ if (!this.EmbeddedModule)
31
+ this.waitForMyConfigAndForceEmbeddedModule();
32
+ }
33
+ this.configureEmbeddability();
34
+ if (this.Embedded)
35
+ this.msgService.configureEmbeddability(this.MainWindow, this.MessageObserver);
36
+ this.MessageObserver.pipe(filter(ev => ev.event == "menu-navigation")).subscribe(event => {
37
+ // Mi interessa solo roba relativa all'embedding
38
+ if (!event.data.routerLink.startsWith("embed"))
39
+ return;
40
+ // emb/crm/parties/parties_search?blabla --> parties/parties_search
41
+ let normalizedRequestedRoute = event.data.routerLink.split("?")[0].split("/").slice(2).join("/");
42
+ ///pages_ext/parties/parties_search?blabla --> parties/parties_search
43
+ let normalizedFirstRoute = this.pushedHistories.length > 0 ? this.pushedHistories[0].from.split("?")[0].split("/").slice(2).join("/") : "";
44
+ // La route su cui sto navigando ora è uguale alla route in cui l'embedding è iniziato.
45
+ // Significa che devo simulare dei back fino a che non sono arrivato all'inizio
46
+ if (normalizedRequestedRoute == normalizedFirstRoute) {
47
+ this.router.navigate(["pages/" + event.data.routerLink, { wakeup: 1 }], { queryParams: event.data.queryParams, onSameUrlNavigation: "reload" });
48
+ this.pushedHistories = [];
49
+ }
50
+ });
51
+ }
52
+ waitForMyConfigAndForceEmbeddedModule() {
53
+ // Aspetto di ricevere il myconfig e setto con lui l'embeddedmodule. Questo viene eseguito solo se this.location.path() per qualche motivo non contiene il module
54
+ let interval = setInterval(() => {
55
+ if (myconfig?.AppData?.ModuleId) {
56
+ this.EmbeddedModule = myconfig.AppData.ModuleId;
57
+ clearInterval(interval);
58
+ }
59
+ }, 250);
60
+ }
61
+ IsReloadAllowed() {
62
+ let ret = this._reloadAllowed;
63
+ this._reloadAllowed = true;
64
+ return ret;
65
+ }
66
+ messageHash(event) {
67
+ return `${JSON.parse(JSON.stringify(event?.data))}`;
68
+ }
69
+ configureEmbeddability() {
70
+ window.onmessage = (event) => {
71
+ // Ignoro i miei messaggi dato che mi interessano solo quelli degli altri iframe
72
+ if (event.source == window && event?.data?.type != "modal-open")
73
+ return;
74
+ // Posso gestire lo stesso identico messaggio solo 1 volta ogni MessageBarrierDebouncMs
75
+ let messageHash = this.messageHash(event);
76
+ if (this.OnMessageCallBarrier[messageHash])
77
+ return;
78
+ else {
79
+ this.OnMessageCallBarrier[messageHash] = true;
80
+ setTimeout(() => delete this.OnMessageCallBarrier[messageHash], this.MessageBarrierDebouncMs);
81
+ }
82
+ this.MessageObserver.next({ event: "window-message", data: event?.data });
83
+ if (event?.data?.type == "alert") {
84
+ console.log(`Window message - alert -> Level: ${event?.data?.level}, Message: ${event?.data?.msg}`);
85
+ switch (event?.data?.level) {
86
+ case "success":
87
+ this.msgService.simpleSuccess(event?.data?.msg);
88
+ break;
89
+ case "warning":
90
+ this.msgService.simpleWarning(event?.data?.msg);
91
+ break;
92
+ case "error":
93
+ this.msgService.simpleError(event?.data?.msg);
94
+ break;
95
+ case "info":
96
+ this.msgService.simpleInfo(event?.data?.msg);
97
+ break;
98
+ }
99
+ }
100
+ else if (event?.data?.type == "replace-state") {
101
+ console.log(`Window message - replace-state -> Url: ${event?.data?.url}`);
102
+ this.location.replaceState(event?.data?.url);
103
+ }
104
+ else if (event?.data?.type == "confirm") {
105
+ console.log(`Window message - confirm -> Level: ${event?.data?.level}, Message: ${event?.data?.text}, Title: ${event?.data?.title}, ID: ${event?.data?.guid}`);
106
+ var sourceWindow = event.source;
107
+ var baseResponse = { type: "confirm-response", guid: event?.data?.guid };
108
+ switch (event?.data?.level) {
109
+ case "success":
110
+ this.msgService.simpleSuccessWithChoice(event?.data?.title, event?.data?.text, () => {
111
+ sourceWindow.postMessage({ result: true, ...baseResponse }, "*");
112
+ }, () => {
113
+ sourceWindow.postMessage({ result: false, ...baseResponse }, "*");
114
+ });
115
+ break;
116
+ case "warning":
117
+ this.msgService.simpleWarningWithChoice(event?.data?.title, event?.data?.text, () => {
118
+ sourceWindow.postMessage({ result: true, ...baseResponse }, "*");
119
+ }, () => {
120
+ sourceWindow.postMessage({ result: false, ...baseResponse }, "*");
121
+ });
122
+ break;
123
+ }
124
+ }
125
+ else if (event?.data?.type == "navigate") {
126
+ console.log(`Window message - navigate -> ${event?.data?.url}`);
127
+ var newTab = event?.data?.newTab;
128
+ var replaceState = event?.data?.replaceState;
129
+ var current = event?.data?.current;
130
+ // Controllo se il router sta seguendo la chiamata attuale. Escludo i query params che sono gli unici che possono essere seccati dai replaceState
131
+ // e che potrebbero fare del casino
132
+ if (!window.location.href.includes(this.router.url.split("?")[0])) {
133
+ console.warn("Doppia chiamata di navigazione, ignoro il secondo evento scoordinato dal router");
134
+ return;
135
+ }
136
+ let newRelativeUrl = this.router.createUrlTree([event?.data?.url]);
137
+ let baseUrl = window.location.href.replace(this.router.url.replace("?ignoreStorage=true", ''), '');
138
+ let newUrl = baseUrl + decodeURIComponent(newRelativeUrl.toString());
139
+ if (replaceState) {
140
+ this.pushedHistories.push({ _pushed: true, url: newUrl, from: current });
141
+ history.pushState({ _pushed: true }, "", newUrl);
142
+ }
143
+ else if (newTab)
144
+ window.open(newUrl, '_blank');
145
+ }
146
+ else if (event?.data?.type == "navigate-back") {
147
+ console.log(`Window message - navigate-back -> ${event?.data?.url}`);
148
+ this.onNavigateBack();
149
+ }
150
+ else if (event?.data?.type == "redirect") {
151
+ console.log(`Window message - redirect -> ${event?.data?.url}`);
152
+ window.location.href = event?.data?.url;
153
+ }
154
+ else if (event?.data?.type == "navigation") {
155
+ console.log(`Window message - Navigation -> ${event?.data?.internalNavigation ? "[internal]" : ""} ${event?.data?.title}`);
156
+ this.MessageObserver.next({ event: "navigation", data: event?.data });
157
+ }
158
+ else if (event?.data?.type == "modal-open") {
159
+ const wrapper = document.body.getElementsByClassName("main-wrapper")[0];
160
+ let wrapperStyles = window.getComputedStyle(wrapper);
161
+ const wrapperPaddingLeft = parseInt(wrapperStyles.getPropertyValue("padding-left"));
162
+ const wrapperPaddingRight = parseInt(wrapperStyles.getPropertyValue("padding-right"));
163
+ console.log(`Window message - Modal Open -> Backdrop Height: ${event?.data?.backdropHeight}`);
164
+ var bottomLeftover = 7; // Valore fisso... robina che rimane di sotto per un motivo o quell'altro
165
+ var topHeight = 86; // valore fisso, distanza fra il top e l'inizio dell'iframe, non sarà mai diverso
166
+ var rightSpace = wrapperPaddingRight; // valore fisso, distanza fra la fine dell'iframe e il lato sinistro dello schermo, non sarà mai diverso
167
+ var leftSpace = this.sidebarWidth + wrapperPaddingLeft;
168
+ let commonStyles = "position: absolute; z-index: 9999; background-color: #000; opacity: 0.5; ";
169
+ wrapper.style.setProperty("overflow", "hidden", "important");
170
+ const top = document.createElement("div");
171
+ top.className = "embedded-modal-top";
172
+ top.style.cssText = commonStyles + `height: ${topHeight}px; top: 0; width: calc(100% - ${leftSpace}px); left: ${leftSpace}px`;
173
+ top.id = "top";
174
+ const left = document.createElement("div");
175
+ left.className = "embedded-modal-left";
176
+ left.style.cssText = commonStyles + `height: 100%; top: 0; width: ${leftSpace}px;`;
177
+ left.id = "left";
178
+ const right = document.createElement("div");
179
+ right.className = "embedded-modal-right";
180
+ right.style.cssText = commonStyles + `height: calc(100% - ${topHeight}px); top: ${topHeight}px; right: 0; width: ${rightSpace}px;`;
181
+ right.id = "right";
182
+ const bottom = document.createElement("div");
183
+ bottom.className = "embedded-modal-bottom";
184
+ bottom.style.cssText = commonStyles + `height: ${bottomLeftover}px; bottom: 0; width: calc(100% - ${leftSpace + rightSpace}px); left: ${leftSpace}px`;
185
+ bottom.id = "bottom";
186
+ document.body.appendChild(top);
187
+ document.body.appendChild(left);
188
+ document.body.appendChild(right);
189
+ document.body.appendChild(bottom);
190
+ }
191
+ else if (event?.data?.type == "modal-close") {
192
+ console.log(`Window message - Modal Close`);
193
+ let wrapper = document.body.getElementsByClassName("main-wrapper")[0];
194
+ wrapper.style.removeProperty("overflow");
195
+ const top = document.getElementById("top");
196
+ const left = document.getElementById("left");
197
+ const right = document.getElementById("right");
198
+ const bottom = document.getElementById("bottom");
199
+ if (top)
200
+ document.body.removeChild(top);
201
+ if (left)
202
+ document.body.removeChild(left);
203
+ if (right)
204
+ document.body.removeChild(right);
205
+ if (bottom)
206
+ document.body.removeChild(bottom);
207
+ }
208
+ };
209
+ if (this.Embedded)
210
+ document.body.style.setProperty("overflow-y", "auto", "important");
211
+ }
212
+ onNavigateBack() {
213
+ if (history?.state?._pushed) {
214
+ this._reloadAllowed = false;
215
+ this.pushedHistories.pop();
216
+ history.back();
217
+ }
218
+ }
219
+ replaceState(basePath, url) {
220
+ // Esempio basePath: pages
221
+ // Esempio url: parties/leads_search
222
+ // Normalizzazione senza slash prima o dopo
223
+ basePath = basePath.endsWith("/") ? basePath.substring(0, basePath.length - 2) : basePath;
224
+ url = url.startsWith("/") ? url.substring(1) : url;
225
+ this.location.replaceState(`${basePath}/${url}`);
226
+ this.MainWindow.postMessage({ type: "replace-state", url: `pages/embed/${this.EmbeddedModule}/${url}` }, "*");
227
+ }
228
+ refreshBoundariesOnMenuCollapse() {
229
+ const wrapper = document.body.getElementsByClassName("main-wrapper")[0];
230
+ let wrapperStyles = window.getComputedStyle(wrapper);
231
+ const wrapperPaddingLeft = parseInt(wrapperStyles.getPropertyValue("padding-left"));
232
+ var leftSpace = 230 + wrapperPaddingLeft;
233
+ const left = document.getElementById("left");
234
+ const top = document.getElementById("top");
235
+ if (top) {
236
+ top.style.setProperty("left", (leftSpace) + "px");
237
+ top.style.setProperty("width", `calc(100% - ${leftSpace}px)`);
238
+ }
239
+ if (left)
240
+ left.style.setProperty("width", leftSpace + "px");
241
+ }
242
+ }
243
+ AppEmbeddingExtensions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AppEmbeddingExtensions, deps: [{ token: i1.MessageService }, { token: i2.Router }, { token: i3.Location }], target: i0.ɵɵFactoryTarget.Injectable });
244
+ AppEmbeddingExtensions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AppEmbeddingExtensions });
245
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AppEmbeddingExtensions, decorators: [{
246
+ type: Injectable
247
+ }], ctorParameters: function () { return [{ type: i1.MessageService }, { type: i2.Router }, { type: i3.Location }]; } });
248
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9ucy5lbWJlZGRpbmcuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2V4dGVuc2lvbnMvc3JjL2xpYi9zZXJ2aWNlcy9leHRlbnNpb25zLmVtYmVkZGluZy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFVBQVU7QUFDVixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBTzNDLFlBQVk7QUFDWixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7QUFJdkMscUdBQXFHO0FBRXJHLE1BQU0sT0FBTyxzQkFBc0I7SUFnQi9CLFlBQW9CLFVBQTBCLEVBQVUsTUFBYyxFQUFVLFFBQWtCO1FBQTlFLGVBQVUsR0FBVixVQUFVLENBQWdCO1FBQVUsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUFVLGFBQVEsR0FBUixRQUFRLENBQVU7UUFkM0YsaUJBQVksR0FBVyxHQUFHLENBQUM7UUFFM0IsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUMxQixtQkFBYyxHQUFXLENBQUMsQ0FBQztRQUczQixvQkFBZSxHQUF1QyxJQUFJLE9BQU8sRUFBNkIsQ0FBQztRQUU5RixtQkFBYyxHQUFZLElBQUksQ0FBQztRQUkvQixvQkFBZSxHQUFzRCxFQUFFLENBQUM7UUF5RHhFLDRCQUF1QixHQUFXLEdBQUcsQ0FBQztRQUN0Qyx5QkFBb0IsR0FBOEIsRUFBRSxDQUFBO1FBdkR4RCxJQUFJLENBQUMsVUFBVSxHQUEyQyxNQUFNLENBQUM7UUFDakUsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQzlDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUM7WUFDekMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxRQUFRLEdB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S0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztZQUNsRCxHQUFHLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsZUFBZSxTQUFTLEtBQUssQ0FBQyxDQUFDO1NBQ2pFO1FBRUQsSUFBSSxJQUFJO1lBQ0osSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLFNBQVMsR0FBRyxJQUFJLENBQUMsQ0FBQztJQUMxRCxDQUFDOzttSEFoUlEsc0JBQXNCO3VIQUF0QixzQkFBc0I7MkZBQXRCLHNCQUFzQjtrQkFEbEMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEFuZ3VsYXJcclxuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCB7IExvY2F0aW9uIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xyXG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tIFwiQGFuZ3VsYXIvcm91dGVyXCI7XHJcblxyXG4vLyBTZXJ2aWNlc1xyXG5pbXBvcnQgeyBNZXNzYWdlU2VydmljZSB9IGZyb20gXCIuL2V4dGVuc2lvbnMubWVzc2FnZXMuc2VydmljZVwiO1xyXG5cclxuLy8gTGlicmFyaWVzXHJcbmltcG9ydCB7IFN1YmplY3QsIGZpbHRlciB9IGZyb20gXCJyeGpzXCI7XHJcblxyXG5kZWNsYXJlIHZhciBteWNvbmZpZzogeyBBcHBEYXRhOiB7IE1vZHVsZUlkOiBzdHJpbmcgfTsgfTtcclxuXHJcbi8qIENsYXNzZSBjaGUgY29udGllbmUgdHV0dGUgbGUgaW5mb3JtYXppb25pIHN1bGwnZW1iZWRkaW5nIGluIHVuIHVuaWNvIGNvbnRlbml0b3JlIHBlciBzZW1wbGljaXTDoCAqL1xyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBBcHBFbWJlZGRpbmdFeHRlbnNpb25zIHtcclxuXHJcbiAgICBwdWJsaWMgc2lkZWJhcldpZHRoOiBudW1iZXIgPSAyMzA7XHJcblxyXG4gICAgcHVibGljIEVtYmVkZGVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBwdWJsaWMgRW1iZWRkaW5nTGV2ZWw6IG51bWJlciA9IDA7XHJcbiAgICBwdWJsaWMgTWFpbldpbmRvdzogYW55O1xyXG5cclxuICAgIHB1YmxpYyBNZXNzYWdlT2JzZXJ2ZXI6IFN1YmplY3Q8eyBldmVudDogYW55LCBkYXRhOiBhbnkgfT4gPSBuZXcgU3ViamVjdDx7IGV2ZW50OiBhbnksIGRhdGE6IGFueSB9PigpO1xyXG5cclxuICAgIHByaXZhdGUgX3JlbG9hZEFsbG93ZWQ6IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICAgIHB1YmxpYyBFbWJlZGRlZE1vZHVsZTogc3RyaW5nO1xyXG5cclxuICAgIHByaXZhdGUgcHVzaGVkSGlzdG9yaWVzOiB7IF9wdXNoZWQ6IGJvb2xlYW4sIHVybDogc3RyaW5nLCBmcm9tOiBzdHJpbmcgfVtdID0gW107XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBtc2dTZXJ2aWNlOiBNZXNzYWdlU2VydmljZSwgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlciwgcHJpdmF0ZSBsb2NhdGlvbjogTG9jYXRpb24pIHtcclxuICAgICAgICB0aGlzLk1haW5XaW5kb3cgPSA8eyBwYXJlbnQ6IGFueSwgcG9zdE1lc3NhZ2U6IEZ1bmN0aW9uIH0+d2luZG93O1xyXG4gICAgICAgIHdoaWxlICh0aGlzLk1haW5XaW5kb3cucGFyZW50ICE9IHRoaXMuTWFpbldpbmRvdykge1xyXG4gICAgICAgICAgICB0aGlzLk1haW5XaW5kb3cgPSB0aGlzLk1haW5XaW5kb3cucGFyZW50O1xyXG4gICAgICAgICAgICB0aGlzLkVtYmVkZGluZ0xldmVsKys7XHJcbiAgICAgICAgICAgIHRoaXMuRW1iZWRkZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgLy8gRmFsbGJhY2sgcGVyIGZhcmxvIGZ1bnppb25hcmUgZm9yemF0YW1lbnRlIG1lbnRyZSBsbyB0ZXN0b1xyXG4gICAgICAgICAgICB0aGlzLkVtYmVkZGVkTW9kdWxlID0gdGhpcy5sb2NhdGlvbi5wYXRoKCkubWF0Y2goL21vZHVsZT0oW2EtekEtWl9dKykvKT8uWzFdO1xyXG5cclxuICAgICAgICAgICAgaWYoIXRoaXMuRW1iZWRkZWRNb2R1bGUpXHJcbiAgICAgICAgICAgICAgICB0aGlzLndhaXRGb3JNeUNvbmZpZ0FuZEZvcmNlRW1iZWRkZWRNb2R1bGUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuY29uZmlndXJlRW1iZWRkYWJpbGl0eSgpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5FbWJlZGRlZClcclxuICAgICAgICAgICAgdGhpcy5tc2dTZXJ2aWNlLmNvbmZpZ3VyZUVtYmVkZGFiaWxpdHkodGhpcy5NYWluV2luZG93LCB0aGlzLk1lc3NhZ2VPYnNlcnZlcik7XHJcblxyXG4gICAgICAgIHRoaXMuTWVzc2FnZU9ic2VydmVyLnBpcGUoZmlsdGVyKGV2ID0+IGV2LmV2ZW50ID09IFwibWVudS1uYXZpZ2F0aW9uXCIpKS5zdWJzY3JpYmUoZXZlbnQgPT4ge1xyXG5cclxuICAgICAgICAgICAgLy8gTWkgaW50ZXJlc3NhIHNvbG8gcm9iYSByZWxhdGl2YSBhbGwnZW1iZWRkaW5nXHJcbiAgICAgICAgICAgIGlmICghZXZlbnQuZGF0YS5yb3V0ZXJMaW5rLnN0YXJ0c1dpdGgoXCJlbWJlZFwiKSlcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIC8vIGVtYi9jcm0vcGFydGllcy9wYXJ0aWVzX3NlYXJjaD9ibGFibGEgLS0+IHBhcnRpZXMvcGFydGllc19zZWFyY2hcclxuICAgICAgICAgICAgbGV0IG5vcm1hbGl6ZWRSZXF1ZXN0ZWRSb3V0ZSA9IGV2ZW50LmRhdGEucm91dGVyTGluay5zcGxpdChcIj9cIilbMF0uc3BsaXQoXCIvXCIpLnNsaWNlKDIpLmpvaW4oXCIvXCIpO1xyXG4gICAgICAgICAgICAvLy9wYWdlc19leHQvcGFydGllcy9wYXJ0aWVzX3NlYXJjaD9ibGFibGEgLS0+IHBhcnRpZXMvcGFydGllc19zZWFyY2hcclxuICAgICAgICAgICAgbGV0IG5vcm1hbGl6ZWRGaXJzdFJvdXRlID0gdGhpcy5wdXNoZWRIaXN0b3JpZXMubGVuZ3RoID4gMCA/IHRoaXMucHVzaGVkSGlzdG9yaWVzWzBdLmZyb20uc3BsaXQoXCI/XCIpWzBdLnNwbGl0KFwiL1wiKS5zbGljZSgyKS5qb2luKFwiL1wiKSA6IFwiXCI7XHJcbiAgICAgICAgICAgIC8vIExhIHJvdXRlIHN1IGN1aSBzdG8gbmF2aWdhbmRvIG9yYSDDqCB1Z3VhbGUgYWxsYSByb3V0ZSBpbiBjdWkgbCdlbWJlZGRpbmcgw6ggaW5pemlhdG8uIFxyXG4gICAgICAgICAgICAvLyBTaWduaWZpY2EgY2hlIGRldm8gc2ltdWxhcmUgZGVpIGJhY2sgZmlubyBhIGNoZSBub24gc29ubyBhcnJpdmF0byBhbGwnaW5pemlvXHJcbiAgICAgICAgICAgIGlmIChub3JtYWxpemVkUmVxdWVzdGVkUm91dGUgPT0gbm9ybWFsaXplZEZpcnN0Um91dGUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFtcInBhZ2VzL1wiICsgZXZlbnQuZGF0YS5yb3V0ZXJMaW5rLCB7d2FrZXVwOiAxfV0sIHsgcXVlcnlQYXJhbXM6IGV2ZW50LmRhdGEucXVlcnlQYXJhbXMsIG9uU2FtZVVybE5hdmlnYXRpb246IFwicmVsb2FkXCIgfSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnB1c2hlZEhpc3RvcmllcyA9IFtdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSB3YWl0Rm9yTXlDb25maWdBbmRGb3JjZUVtYmVkZGVkTW9kdWxlKCkge1xyXG5cclxuICAgICAgICAvLyBBc3BldHRvIGRpIHJpY2V2ZXJlIGlsIG15Y29uZmlnIGUgc2V0dG8gY29uIGx1aSBsJ2VtYmVkZGVkbW9kdWxlLiBRdWVzdG8gdmllbmUgZXNlZ3VpdG8gc29sbyBzZSB0aGlzLmxvY2F0aW9uLnBhdGgoKSBwZXIgcXVhbGNoZSBtb3Rpdm8gbm9uIGNvbnRpZW5lIGlsIG1vZHVsZVxyXG4gICAgICAgIGxldCBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcclxuICAgICAgICAgICAgaWYgKG15Y29uZmlnPy5BcHBEYXRhPy5Nb2R1bGVJZCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5FbWJlZGRlZE1vZHVsZSA9IG15Y29uZmlnLkFwcERhdGEuTW9kdWxlSWQ7XHJcbiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKGludGVydmFsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sIDI1MCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIElzUmVsb2FkQWxsb3dlZCgpIHtcclxuICAgICAgICBsZXQgcmV0ID0gdGhpcy5fcmVsb2FkQWxsb3dlZDtcclxuICAgICAgICB0aGlzLl9yZWxvYWRBbGxvd2VkID0gdHJ1ZTtcclxuICAgICAgICByZXR1cm4gcmV0O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgTWVzc2FnZUJhcnJpZXJEZWJvdW5jTXM6IG51bWJlciA9IDI1MDtcclxuICAgIHByaXZhdGUgT25NZXNzYWdlQ2FsbEJhcnJpZXI6IHsgW2lkOiBzdHJpbmddOiBib29sZWFuIH0gPSB7fVxyXG4gICAgcHJpdmF0ZSBtZXNzYWdlSGFzaChldmVudDogTWVzc2FnZUV2ZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGAke0pTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZXZlbnQ/LmRhdGEpKX1gO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbmZpZ3VyZUVtYmVkZGFiaWxpdHkoKSB7XHJcbiAgICAgICAgd2luZG93Lm9ubWVzc2FnZSA9IChldmVudDogTWVzc2FnZUV2ZW50KSA9PiB7XHJcbiAgICAgICAgICAgIC8vIElnbm9ybyBpIG1pZWkgbWVzc2FnZ2kgZGF0byBjaGUgbWkgaW50ZXJlc3Nhbm8gc29sbyBxdWVsbGkgZGVnbGkgYWx0cmkgaWZyYW1lXHJcbiAgICAgICAgICAgIGlmIChldmVudC5zb3VyY2UgPT0gd2luZG93ICYmIGV2ZW50Py5kYXRhPy50eXBlICE9IFwibW9kYWwtb3BlblwiKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgLy8gUG9zc28gZ2VzdGlyZSBsbyBzdGVzc28gaWRlbnRpY28gbWVzc2FnZ2lvIHNvbG8gMSB2b2x0YSBvZ25pIE1lc3NhZ2VCYXJyaWVyRGVib3VuY01zXHJcbiAgICAgICAgICAgIGxldCBtZXNzYWdlSGFzaCA9IHRoaXMubWVzc2FnZUhhc2goZXZlbnQpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5Pbk1lc3NhZ2VDYWxsQmFycmllclttZXNzYWdlSGFzaF0pXHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5Pbk1lc3NhZ2VDYWxsQmFycmllclttZXNzYWdlSGFzaF0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiBkZWxldGUgdGhpcy5Pbk1lc3NhZ2VDYWxsQmFycmllclttZXNzYWdlSGFzaF0sIHRoaXMuTWVzc2FnZUJhcnJpZXJEZWJvdW5jTXMpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLk1lc3NhZ2VPYnNlcnZlci5uZXh0KHsgZXZlbnQ6IFwid2luZG93LW1lc3NhZ2VcIiwgZGF0YTogZXZlbnQ/LmRhdGEgfSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoZXZlbnQ/LmRhdGE/LnR5cGUgPT0gXCJhbGVydFwiKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgV2luZG93IG1lc3NhZ2UgLSBhbGVydCAtPiBMZXZlbDogJHtldmVudD8uZGF0YT8ubGV2ZWx9LCBNZXNzYWdlOiAke2V2ZW50Py5kYXRhPy5tc2d9YCk7XHJcblxyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChldmVudD8uZGF0YT8ubGV2ZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwic3VjY2Vzc1wiOiB0aGlzLm1zZ1NlcnZpY2Uuc2ltcGxlU3VjY2VzcyhldmVudD8uZGF0YT8ubXNnKTsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIndhcm5pbmdcIjogdGhpcy5tc2dTZXJ2aWNlLnNpbXBsZVdhcm5pbmcoZXZlbnQ/LmRhdGE/Lm1zZyk7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJlcnJvclwiOiB0aGlzLm1zZ1NlcnZpY2Uuc2ltcGxlRXJyb3IoZXZlbnQ/LmRhdGE/Lm1zZyk7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJpbmZvXCI6IHRoaXMubXNnU2VydmljZS5zaW1wbGVJbmZvKGV2ZW50Py5kYXRhPy5tc2cpOyBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChldmVudD8uZGF0YT8udHlwZSA9PSBcInJlcGxhY2Utc3RhdGVcIikge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFdpbmRvdyBtZXNzYWdlIC0gcmVwbGFjZS1zdGF0ZSAtPiBVcmw6ICR7ZXZlbnQ/LmRhdGE/LnVybH1gKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2F0aW9uLnJlcGxhY2VTdGF0ZShldmVudD8uZGF0YT8udXJsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChldmVudD8uZGF0YT8udHlwZSA9PSBcImNvbmZpcm1cIikge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFdpbmRvdyBtZXNzYWdlIC0gY29uZmlybSAtPiBMZXZlbDogJHtldmVudD8uZGF0YT8ubGV2ZWx9LCBNZXNzYWdlOiAke2V2ZW50Py5kYXRhPy50ZXh0fSwgVGl0bGU6ICR7ZXZlbnQ/LmRhdGE/LnRpdGxlfSwgSUQ6ICR7ZXZlbnQ/LmRhdGE/Lmd1aWR9YCk7XHJcblxyXG4gICAgICAgICAgICAgICAgdmFyIHNvdXJjZVdpbmRvdyA9IChldmVudC5zb3VyY2UgYXMgV2luZG93KTtcclxuICAgICAgICAgICAgICAgIHZhciBiYXNlUmVzcG9uc2UgPSB7IHR5cGU6IFwiY29uZmlybS1yZXNwb25zZVwiLCBndWlkOiBldmVudD8uZGF0YT8uZ3VpZCB9O1xyXG5cclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQ/LmRhdGE/LmxldmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInN1Y2Nlc3NcIjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tc2dTZXJ2aWNlLnNpbXBsZVN1Y2Nlc3NXaXRoQ2hvaWNlKGV2ZW50Py5kYXRhPy50aXRsZSwgZXZlbnQ/LmRhdGE/LnRleHQsICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZVdpbmRvdy5wb3N0TWVzc2FnZSh7IHJlc3VsdDogdHJ1ZSwgLi4uYmFzZVJlc3BvbnNlIH0sIFwiKlwiKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VXaW5kb3cucG9zdE1lc3NhZ2UoeyByZXN1bHQ6IGZhbHNlLCAuLi5iYXNlUmVzcG9uc2UgfSwgXCIqXCIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwid2FybmluZ1wiOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1zZ1NlcnZpY2Uuc2ltcGxlV2FybmluZ1dpdGhDaG9pY2UoZXZlbnQ/LmRhdGE/LnRpdGxlLCBldmVudD8uZGF0YT8udGV4dCwgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlV2luZG93LnBvc3RNZXNzYWdlKHsgcmVzdWx0OiB0cnVlLCAuLi5iYXNlUmVzcG9uc2UgfSwgXCIqXCIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZVdpbmRvdy5wb3N0TWVzc2FnZSh7IHJlc3VsdDogZmFsc2UsIC4uLmJhc2VSZXNwb25zZSB9LCBcIipcIilcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChldmVudD8uZGF0YT8udHlwZSA9PSBcIm5hdmlnYXRlXCIpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBXaW5kb3cgbWVzc2FnZSAtIG5hdmlnYXRlIC0+ICR7ZXZlbnQ/LmRhdGE/LnVybH1gKTtcclxuICAgICAgICAgICAgICAgIHZhciBuZXdUYWIgPSBldmVudD8uZGF0YT8ubmV3VGFiO1xyXG4gICAgICAgICAgICAgICAgdmFyIHJlcGxhY2VTdGF0ZSA9IGV2ZW50Py5kYXRhPy5yZXBsYWNlU3RhdGVcclxuICAgICAgICAgICAgICAgIHZhciBjdXJyZW50ID0gZXZlbnQ/LmRhdGE/LmN1cnJlbnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQ29udHJvbGxvIHNlIGlsIHJvdXRlciBzdGEgc2VndWVuZG8gbGEgY2hpYW1hdGEgYXR0dWFsZS4gRXNjbHVkbyBpIHF1ZXJ5IHBhcmFtcyBjaGUgc29ubyBnbGkgdW5pY2kgY2hlIHBvc3Nvbm8gZXNzZXJlIHNlY2NhdGkgZGFpIHJlcGxhY2VTdGF0ZVxyXG4gICAgICAgICAgICAgICAgLy8gZSBjaGUgcG90cmViYmVybyBmYXJlIGRlbCBjYXNpbm9cclxuICAgICAgICAgICAgICAgIGlmICghd2luZG93LmxvY2F0aW9uLmhyZWYuaW5jbHVkZXModGhpcy5yb3V0ZXIudXJsLnNwbGl0KFwiP1wiKVswXSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXCJEb3BwaWEgY2hpYW1hdGEgZGkgbmF2aWdhemlvbmUsIGlnbm9ybyBpbCBzZWNvbmRvIGV2ZW50byBzY29vcmRpbmF0byBkYWwgcm91dGVyXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgbmV3UmVsYXRpdmVVcmwgPSB0aGlzLnJvdXRlci5jcmVhdGVVcmxUcmVlKFtldmVudD8uZGF0YT8udXJsXSk7XHJcbiAgICAgICAgICAgICAgICBsZXQgYmFzZVVybCA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnJlcGxhY2UodGhpcy5yb3V0ZXIudXJsLnJlcGxhY2UoXCI/aWdub3JlU3RvcmFnZT10cnVlXCIgLCAnJyksICcnKTtcclxuICAgICAgICAgICAgICAgIGxldCBuZXdVcmwgPSBiYXNlVXJsICsgZGVjb2RlVVJJQ29tcG9uZW50KG5ld1JlbGF0aXZlVXJsLnRvU3RyaW5nKCkpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXBsYWNlU3RhdGUpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1c2hlZEhpc3Rvcmllcy5wdXNoKHsgX3B1c2hlZDogdHJ1ZSwgdXJsOiBuZXdVcmwsIGZyb206IGN1cnJlbnQgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaGlzdG9yeS5wdXNoU3RhdGUoeyBfcHVzaGVkOiB0cnVlIH0sIFwiXCIsIG5ld1VybCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChuZXdUYWIpXHJcbiAgICAgICAgICAgICAgICAgICAgd2luZG93Lm9wZW4obmV3VXJsLCAnX2JsYW5rJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoZXZlbnQ/LmRhdGE/LnR5cGUgPT0gXCJuYXZpZ2F0ZS1iYWNrXCIpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBXaW5kb3cgbWVzc2FnZSAtIG5hdmlnYXRlLWJhY2sgLT4gJHtldmVudD8uZGF0YT8udXJsfWApO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbk5hdmlnYXRlQmFjaygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGV2ZW50Py5kYXRhPy50eXBlID09IFwicmVkaXJlY3RcIikge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFdpbmRvdyBtZXNzYWdlIC0gcmVkaXJlY3QgLT4gJHtldmVudD8uZGF0YT8udXJsfWApO1xyXG5cclxuICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gZXZlbnQ/LmRhdGE/LnVybDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChldmVudD8uZGF0YT8udHlwZSA9PSBcIm5hdmlnYXRpb25cIikge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFdpbmRvdyBtZXNzYWdlIC0gTmF2aWdhdGlvbiAtPiAke2V2ZW50Py5kYXRhPy5pbnRlcm5hbE5hdmlnYXRpb24gPyBcIltpbnRlcm5hbF1cIiA6IFwiXCJ9ICR7ZXZlbnQ/LmRhdGE/LnRpdGxlfWApO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuTWVzc2FnZU9ic2VydmVyLm5leHQoeyBldmVudDogXCJuYXZpZ2F0aW9uXCIsIGRhdGE6IGV2ZW50Py5kYXRhIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGV2ZW50Py5kYXRhPy50eXBlID09IFwibW9kYWwtb3BlblwiKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB3cmFwcGVyID0gZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwibWFpbi13cmFwcGVyXCIpWzBdIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgbGV0IHdyYXBwZXJTdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh3cmFwcGVyKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHdyYXBwZXJQYWRkaW5nTGVmdCA9IHBhcnNlSW50KHdyYXBwZXJTdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZShcInBhZGRpbmctbGVmdFwiKSk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB3cmFwcGVyUGFkZGluZ1JpZ2h0ID0gcGFyc2VJbnQod3JhcHBlclN0eWxlcy5nZXRQcm9wZXJ0eVZhbHVlKFwicGFkZGluZy1yaWdodFwiKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFdpbmRvdyBtZXNzYWdlIC0gTW9kYWwgT3BlbiAtPiBCYWNrZHJvcCBIZWlnaHQ6ICR7ZXZlbnQ/LmRhdGE/LmJhY2tkcm9wSGVpZ2h0fWApO1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciBib3R0b21MZWZ0b3ZlcjogbnVtYmVyID0gNzsgLy8gVmFsb3JlIGZpc3NvLi4uIHJvYmluYSBjaGUgcmltYW5lIGRpIHNvdHRvIHBlciB1biBtb3Rpdm8gbyBxdWVsbCdhbHRyb1xyXG4gICAgICAgICAgICAgICAgdmFyIHRvcEhlaWdodDogbnVtYmVyID0gODY7IC8vIHZhbG9yZSBmaXNzbywgZGlzdGFuemEgZnJhIGlsIHRvcCBlIGwnaW5pemlvIGRlbGwnaWZyYW1lLCBub24gc2Fyw6AgbWFpIGRpdmVyc29cclxuICAgICAgICAgICAgICAgIHZhciByaWdodFNwYWNlOiBudW1iZXIgPSB3cmFwcGVyUGFkZGluZ1JpZ2h0OyAvLyB2YWxvcmUgZmlzc28sIGRpc3RhbnphIGZyYSBsYSBmaW5lIGRlbGwnaWZyYW1lIGUgaWwgbGF0byBzaW5pc3RybyBkZWxsbyBzY2hlcm1vLCBub24gc2Fyw6AgbWFpIGRpdmVyc29cclxuICAgICAgICAgICAgICAgIHZhciBsZWZ0U3BhY2U6IG51bWJlciA9IHRoaXMuc2lkZWJhcldpZHRoICsgd3JhcHBlclBhZGRpbmdMZWZ0O1xyXG5cclxuICAgICAgICAgICAgICAgIGxldCBjb21tb25TdHlsZXMgPSBcInBvc2l0aW9uOiBhYnNvbHV0ZTsgei1pbmRleDogOTk5OTsgYmFja2dyb3VuZC1jb2xvcjogIzAwMDsgb3BhY2l0eTogMC41OyBcIjtcclxuXHJcbiAgICAgICAgICAgICAgICB3cmFwcGVyLnN0eWxlLnNldFByb3BlcnR5KFwib3ZlcmZsb3dcIiwgXCJoaWRkZW5cIiwgXCJpbXBvcnRhbnRcIik7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgdG9wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcclxuICAgICAgICAgICAgICAgIHRvcC5jbGFzc05hbWUgPSBcImVtYmVkZGVkLW1vZGFsLXRvcFwiO1xyXG4gICAgICAgICAgICAgICAgdG9wLnN0eWxlLmNzc1RleHQgPSBjb21tb25TdHlsZXMgKyBgaGVpZ2h0OiAke3RvcEhlaWdodH1weDsgdG9wOiAwOyB3aWR0aDogY2FsYygxMDAlIC0gJHtsZWZ0U3BhY2V9cHgpOyBsZWZ0OiAke2xlZnRTcGFjZX1weGA7XHJcbiAgICAgICAgICAgICAgICB0b3AuaWQgPSBcInRvcFwiO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGxlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xyXG4gICAgICAgICAgICAgICAgbGVmdC5jbGFzc05hbWUgPSBcImVtYmVkZGVkLW1vZGFsLWxlZnRcIjtcclxuICAgICAgICAgICAgICAgIGxlZnQuc3R5bGUuY3NzVGV4dCA9IGNvbW1vblN0eWxlcyArIGBoZWlnaHQ6IDEwMCU7IHRvcDogMDsgd2lkdGg6ICR7bGVmdFNwYWNlfXB4O2A7XHJcbiAgICAgICAgICAgICAgICBsZWZ0LmlkID0gXCJsZWZ0XCI7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgcmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xyXG4gICAgICAgICAgICAgICAgcmlnaHQuY2xhc3NOYW1lID0gXCJlbWJlZGRlZC1tb2RhbC1yaWdodFwiO1xyXG4gICAgICAgICAgICAgICAgcmlnaHQuc3R5bGUuY3NzVGV4dCA9IGNvbW1vblN0eWxlcyArIGBoZWlnaHQ6IGNhbGMoMTAwJSAtICR7dG9wSGVpZ2h0fXB4KTsgdG9wOiAke3RvcEhlaWdodH1weDsgcmlnaHQ6IDA7IHdpZHRoOiAke3JpZ2h0U3BhY2V9cHg7YDtcclxuICAgICAgICAgICAgICAgIHJpZ2h0LmlkID0gXCJyaWdodFwiO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGJvdHRvbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XHJcbiAgICAgICAgICAgICAgICBib3R0b20uY2xhc3NOYW1lID0gXCJlbWJlZGRlZC1tb2RhbC1ib3R0b21cIjtcclxuICAgICAgICAgICAgICAgIGJvdHRvbS5zdHlsZS5jc3NUZXh0ID0gY29tbW9uU3R5bGVzICsgYGhlaWdodDogJHtib3R0b21MZWZ0b3Zlcn1weDsgYm90dG9tOiAwOyB3aWR0aDogY2FsYygxMDAlIC0gJHtsZWZ0U3BhY2UgKyByaWdodFNwYWNlfXB4KTsgbGVmdDogJHtsZWZ0U3BhY2V9cHhgO1xyXG4gICAgICAgICAgICAgICAgYm90dG9tLmlkID0gXCJib3R0b21cIjtcclxuXHJcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRvcCk7XHJcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGxlZnQpO1xyXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChyaWdodCk7XHJcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGJvdHRvbSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoZXZlbnQ/LmRhdGE/LnR5cGUgPT0gXCJtb2RhbC1jbG9zZVwiKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgV2luZG93IG1lc3NhZ2UgLSBNb2RhbCBDbG9zZWApO1xyXG5cclxuICAgICAgICAgICAgICAgIGxldCB3cmFwcGVyID0gZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwibWFpbi13cmFwcGVyXCIpWzBdIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgd3JhcHBlci5zdHlsZS5yZW1vdmVQcm9wZXJ0eShcIm92ZXJmbG93XCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHRvcCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwidG9wXCIpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbGVmdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibGVmdFwiKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJpZ2h0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJyaWdodFwiKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJvdHRvbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYm90dG9tXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0b3ApIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodG9wKTtcclxuICAgICAgICAgICAgICAgIGlmIChsZWZ0KSBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGxlZnQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHJpZ2h0KSBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKHJpZ2h0KTtcclxuICAgICAgICAgICAgICAgIGlmIChib3R0b20pIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoYm90dG9tKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGlmICh0aGlzLkVtYmVkZGVkKVxyXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnNldFByb3BlcnR5KFwib3ZlcmZsb3cteVwiLCBcImF1dG9cIiwgXCJpbXBvcnRhbnRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBvbk5hdmlnYXRlQmFjaygpIHtcclxuICAgICAgICBcclxuICAgICAgICBpZiAoaGlzdG9yeT8uc3RhdGU/Ll9wdXNoZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5fcmVsb2FkQWxsb3dlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLnB1c2hlZEhpc3Rvcmllcy5wb3AoKTtcclxuICAgICAgICAgICAgaGlzdG9yeS5iYWNrKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyByZXBsYWNlU3RhdGUoYmFzZVBhdGg6IHN0cmluZywgdXJsOiBzdHJpbmcpIHtcclxuICAgICAgICAvLyBFc2VtcGlvIGJhc2VQYXRoOiBwYWdlc1xyXG4gICAgICAgIC8vIEVzZW1waW8gdXJsOiBwYXJ0aWVzL2xlYWRzX3NlYXJjaFxyXG5cclxuICAgICAgICAvLyBOb3JtYWxpenphemlvbmUgc2VuemEgc2xhc2ggcHJpbWEgbyBkb3BvXHJcbiAgICAgICAgYmFzZVBhdGggPSBiYXNlUGF0aC5lbmRzV2l0aChcIi9cIikgPyBiYXNlUGF0aC5zdWJzdHJpbmcoMCwgYmFzZVBhdGgubGVuZ3RoIC0yKSA6IGJhc2VQYXRoO1xyXG4gICAgICAgIHVybCA9IHVybC5zdGFydHNXaXRoKFwiL1wiKSA/IHVybC5zdWJzdHJpbmcoMSkgOiB1cmw7XHJcblxyXG4gICAgICAgIHRoaXMubG9jYXRpb24ucmVwbGFjZVN0YXRlKGAke2Jhc2VQYXRofS8ke3VybH1gKTtcclxuICAgICAgICB0aGlzLk1haW5XaW5kb3cucG9zdE1lc3NhZ2UoeyB0eXBlOiBcInJlcGxhY2Utc3RhdGVcIiwgdXJsOiBgcGFnZXMvZW1iZWQvJHt0aGlzLkVtYmVkZGVkTW9kdWxlfS8ke3VybH1gIH0sIFwiKlwiKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcmVmcmVzaEJvdW5kYXJpZXNPbk1lbnVDb2xsYXBzZSgpIHtcclxuICAgICAgICBjb25zdCB3cmFwcGVyID0gZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwibWFpbi13cmFwcGVyXCIpWzBdIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICAgIGxldCB3cmFwcGVyU3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUod3JhcHBlcik7XHJcbiAgICAgICAgY29uc3Qgd3JhcHBlclBhZGRpbmdMZWZ0ID0gcGFyc2VJbnQod3JhcHBlclN0eWxlcy5nZXRQcm9wZXJ0eVZhbHVlKFwicGFkZGluZy1sZWZ0XCIpKTtcclxuICAgICAgICB2YXIgbGVmdFNwYWNlOiBudW1iZXIgPSAyMzAgKyB3cmFwcGVyUGFkZGluZ0xlZnQ7XHJcblxyXG4gICAgICAgIGNvbnN0IGxlZnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImxlZnRcIik7XHJcbiAgICAgICAgY29uc3QgdG9wID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJ0b3BcIik7XHJcblxyXG4gICAgICAgIGlmICh0b3ApIHtcclxuICAgICAgICAgICAgdG9wLnN0eWxlLnNldFByb3BlcnR5KFwibGVmdFwiLCAobGVmdFNwYWNlKSArIFwicHhcIik7XHJcbiAgICAgICAgICAgIHRvcC5zdHlsZS5zZXRQcm9wZXJ0eShcIndpZHRoXCIsIGBjYWxjKDEwMCUgLSAke2xlZnRTcGFjZX1weClgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChsZWZ0KVxyXG4gICAgICAgICAgICBsZWZ0LnN0eWxlLnNldFByb3BlcnR5KFwid2lkdGhcIiwgbGVmdFNwYWNlICsgXCJweFwiKTtcclxuICAgIH1cclxufSJdfQ==