@playwright-repl/runner 0.23.1 → 0.24.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 (39) hide show
  1. package/dist/pw-cli.js +3 -6
  2. package/dist/pw-cli.js.map +1 -1
  3. package/package.json +4 -3
  4. package/dist/chrome-extension/background.js +0 -233485
  5. package/dist/chrome-extension/background.js.map +0 -1
  6. package/dist/chrome-extension/content/picker.js +0 -279
  7. package/dist/chrome-extension/content/recorder.js +0 -475
  8. package/dist/chrome-extension/devtools/console.html +0 -17
  9. package/dist/chrome-extension/devtools/console.js +0 -44
  10. package/dist/chrome-extension/devtools/console.js.map +0 -1
  11. package/dist/chrome-extension/devtools/devtools.html +0 -8
  12. package/dist/chrome-extension/devtools/devtools.js +0 -7
  13. package/dist/chrome-extension/devtools/devtools.js.map +0 -1
  14. package/dist/chrome-extension/icons/dramaturg_icon_128.png +0 -0
  15. package/dist/chrome-extension/icons/dramaturg_icon_16.png +0 -0
  16. package/dist/chrome-extension/icons/dramaturg_icon_32.png +0 -0
  17. package/dist/chrome-extension/icons/dramaturg_icon_48.png +0 -0
  18. package/dist/chrome-extension/index.css +0 -1333
  19. package/dist/chrome-extension/index.js +0 -12462
  20. package/dist/chrome-extension/index.js.map +0 -1
  21. package/dist/chrome-extension/index2.js +0 -27327
  22. package/dist/chrome-extension/index2.js.map +0 -1
  23. package/dist/chrome-extension/manifest.json +0 -46
  24. package/dist/chrome-extension/modulepreload-polyfill.js +0 -30
  25. package/dist/chrome-extension/modulepreload-polyfill.js.map +0 -1
  26. package/dist/chrome-extension/newtab/newtab.html +0 -202
  27. package/dist/chrome-extension/offscreen/offscreen.html +0 -6
  28. package/dist/chrome-extension/offscreen/offscreen.js +0 -54
  29. package/dist/chrome-extension/offscreen/offscreen.js.map +0 -1
  30. package/dist/chrome-extension/panel/panel.html +0 -16
  31. package/dist/chrome-extension/panel/panel.js +0 -2210
  32. package/dist/chrome-extension/panel/panel.js.map +0 -1
  33. package/dist/chrome-extension/preferences/preferences.html +0 -14
  34. package/dist/chrome-extension/preferences/preferences.js +0 -102
  35. package/dist/chrome-extension/preferences/preferences.js.map +0 -1
  36. package/dist/chrome-extension/settings.js +0 -13
  37. package/dist/chrome-extension/settings.js.map +0 -1
  38. package/dist/chrome-extension/sw-debugger-core.js +0 -1127
  39. package/dist/chrome-extension/sw-debugger-core.js.map +0 -1
@@ -1,279 +0,0 @@
1
- "use strict";
2
- (() => {
3
- // src/content/locator.ts
4
- var IMPLICIT_ROLES = {
5
- A: (el) => el.hasAttribute("href") ? "link" : null,
6
- BUTTON: "button",
7
- H1: "heading",
8
- H2: "heading",
9
- H3: "heading",
10
- H4: "heading",
11
- H5: "heading",
12
- H6: "heading",
13
- INPUT: (el) => {
14
- const type = el.type.toLowerCase();
15
- if (type === "checkbox") return "checkbox";
16
- if (type === "radio") return "radio";
17
- if (type === "submit" || type === "reset" || type === "button") return "button";
18
- if (type === "hidden") return null;
19
- return "textbox";
20
- },
21
- TEXTAREA: "textbox",
22
- SELECT: "combobox",
23
- IMG: "img",
24
- NAV: "navigation",
25
- MAIN: "main",
26
- HEADER: "banner",
27
- FOOTER: "contentinfo",
28
- UL: "list",
29
- OL: "list",
30
- LI: "listitem",
31
- TABLE: "table",
32
- TR: "row",
33
- TH: "columnheader",
34
- TD: "cell",
35
- FORM: "form",
36
- DIALOG: "dialog",
37
- ARTICLE: "article"
38
- };
39
- function getImplicitRole(el) {
40
- const explicit = el.getAttribute("role");
41
- if (explicit && explicit !== "none" && explicit !== "presentation") return explicit;
42
- const entry = IMPLICIT_ROLES[el.tagName];
43
- if (!entry) return null;
44
- return typeof entry === "function" ? entry(el) : entry;
45
- }
46
- function getAccessibleName(el) {
47
- const ariaLabel = el.getAttribute("aria-label");
48
- if (ariaLabel) return ariaLabel.trim();
49
- const labelledBy = el.getAttribute("aria-labelledby");
50
- if (labelledBy) {
51
- const parts = labelledBy.split(/\s+/).map((id) => document.getElementById(id)?.textContent?.trim()).filter(Boolean);
52
- if (parts.length) return parts.join(" ");
53
- }
54
- if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {
55
- const label = getLabel(el);
56
- if (label) return label;
57
- }
58
- const role = getImplicitRole(el);
59
- const NAME_FROM_CONTENT = /* @__PURE__ */ new Set([
60
- "button",
61
- "link",
62
- "heading",
63
- "tab",
64
- "menuitem",
65
- "menuitemcheckbox",
66
- "menuitemradio",
67
- "option",
68
- "radio",
69
- "checkbox",
70
- "switch",
71
- "cell",
72
- "columnheader",
73
- "rowheader",
74
- "tooltip",
75
- "treeitem"
76
- ]);
77
- if (role && NAME_FROM_CONTENT.has(role)) {
78
- const text = (el.textContent || "").trim();
79
- if (text && text.length <= 80) return text;
80
- }
81
- if (el.tagName === "IMG") {
82
- const alt = el.getAttribute("alt");
83
- if (alt) return alt.trim();
84
- }
85
- return "";
86
- }
87
- function getLabel(el) {
88
- if (el.id) {
89
- const label = document.querySelector(`label[for="${CSS.escape(el.id)}"]`);
90
- if (label) return (label.textContent || "").trim();
91
- }
92
- const parentLabel = el.closest("label");
93
- if (parentLabel) {
94
- const clone = parentLabel.cloneNode(true);
95
- clone.querySelectorAll("input,textarea,select").forEach((c) => c.remove());
96
- const text = (clone.textContent || "").trim();
97
- if (text) return text;
98
- }
99
- return "";
100
- }
101
- var CONTAINER_ROLES = /* @__PURE__ */ new Set(["listitem", "row", "article", "group"]);
102
- function getContextText(ancestor, exclude) {
103
- function findText(node) {
104
- for (const child of node.childNodes) {
105
- if (child === exclude) continue;
106
- if (child.nodeType === Node.ELEMENT_NODE && child.contains(exclude)) {
107
- const inner = findText(child);
108
- if (inner) return inner;
109
- continue;
110
- }
111
- const text = (child.textContent || "").trim();
112
- if (text && text.length <= 50) return text;
113
- }
114
- return "";
115
- }
116
- return findText(ancestor);
117
- }
118
- function findContainerAncestor(el) {
119
- let current = el.parentElement;
120
- while (current && current !== document.body && current !== document.documentElement) {
121
- const role = getImplicitRole(current);
122
- if (role && CONTAINER_ROLES.has(role)) return { ancestor: current, role };
123
- current = current.parentElement;
124
- }
125
- return null;
126
- }
127
- function tryAncestorContext(el, role, name, matches) {
128
- const container = findContainerAncestor(el);
129
- if (!container) return null;
130
- const contextText = getContextText(container.ancestor, el);
131
- if (!contextText || contextText.length > 50) return null;
132
- let count = 0;
133
- for (const match of matches) {
134
- const mc = findContainerAncestor(match);
135
- if (!mc || mc.role !== container.role) continue;
136
- if ((mc.ancestor.textContent || "").includes(contextText)) {
137
- count++;
138
- if (count > 1) return null;
139
- }
140
- }
141
- if (count !== 1) return null;
142
- return `getByRole(${escapeString(container.role)}).filter({ hasText: ${escapeString(contextText)} }).getByRole(${escapeString(role)}, { name: ${escapeString(name)} })`;
143
- }
144
- function findByRoleAndName(role, name) {
145
- const matches = [];
146
- for (const el of document.querySelectorAll("*")) {
147
- if (getImplicitRole(el) === role && getAccessibleName(el) === name && el.checkVisibility?.() !== false)
148
- matches.push(el);
149
- }
150
- return matches;
151
- }
152
- function escapeString(s) {
153
- if (!s.includes("'")) return `'${s}'`;
154
- if (!s.includes('"')) return `"${s}"`;
155
- return `'${s.replace(/'/g, "\\'")}'`;
156
- }
157
- function generateLocator(el) {
158
- const testId = el.getAttribute("data-testid") || el.getAttribute("data-test-id");
159
- if (testId) return `getByTestId(${escapeString(testId)})`;
160
- const role = getImplicitRole(el);
161
- const name = getAccessibleName(el);
162
- if (role && name) {
163
- const matches = findByRoleAndName(role, name);
164
- if (matches.length > 1) {
165
- const ancestorLocator = tryAncestorContext(el, role, name, matches);
166
- if (ancestorLocator) return ancestorLocator;
167
- const base = `getByRole(${escapeString(role)}, { name: ${escapeString(name)}, exact: true })`;
168
- const idx = matches.indexOf(el);
169
- return idx === 0 ? base + ".first()" : base + `.nth(${idx})`;
170
- }
171
- return `getByRole(${escapeString(role)}, { name: ${escapeString(name)} })`;
172
- }
173
- if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {
174
- const label = getLabel(el);
175
- if (label) return `getByLabel(${escapeString(label)})`;
176
- }
177
- const placeholder = el.getAttribute("placeholder");
178
- if (placeholder) return `getByPlaceholder(${escapeString(placeholder)})`;
179
- const alt = el.getAttribute("alt");
180
- if (alt && ["IMG", "APPLET", "AREA", "INPUT"].includes(el.tagName))
181
- return `getByAltText(${escapeString(alt)})`;
182
- const title = el.getAttribute("title");
183
- if (title) return `getByTitle(${escapeString(title)})`;
184
- const text = (el.textContent || "").trim();
185
- if (text && text.length <= 80) return `getByText(${escapeString(text)})`;
186
- if (role) return `getByRole(${escapeString(role)})`;
187
- return `locator(${escapeString(buildCssSelector(el))})`;
188
- }
189
- function buildCssSelector(el) {
190
- const tag = el.tagName.toLowerCase();
191
- if (el.id) return `${tag}#${CSS.escape(el.id)}`;
192
- const classes = [...el.classList].slice(0, 2).map((c) => "." + CSS.escape(c)).join("");
193
- if (classes) return `${tag}${classes}`;
194
- return tag;
195
- }
196
-
197
- // src/content/picker.ts
198
- function getOuterHtml(el) {
199
- const outer = el.outerHTML;
200
- if (outer.length <= 200) return outer;
201
- const tag = el.tagName.toLowerCase();
202
- const open = outer.slice(0, outer.indexOf(">") + 1);
203
- return `${open}...</${tag}>`;
204
- }
205
- function gatherInfo(el) {
206
- const rect = el.getBoundingClientRect();
207
- const attrs = {};
208
- for (const a of el.attributes) attrs[a.name] = a.value;
209
- return {
210
- locator: generateLocator(el),
211
- tag: el.tagName.toLowerCase(),
212
- text: (el.textContent || "").trim().slice(0, 200),
213
- html: getOuterHtml(el),
214
- attributes: attrs,
215
- visible: rect.width > 0 && rect.height > 0,
216
- enabled: !el.disabled,
217
- box: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
218
- value: el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement ? el.value : void 0,
219
- checked: el instanceof HTMLInputElement && (el.type === "checkbox" || el.type === "radio") ? el.checked : void 0
220
- };
221
- }
222
- var highlight = document.createElement("div");
223
- highlight.style.cssText = "position:fixed;pointer-events:none;z-index:2147483646;border:2px solid #6fa8dc;background:rgba(111,168,220,0.2);display:none;box-sizing:border-box;";
224
- var currentElement = null;
225
- function onMouseMove(e) {
226
- const target = document.elementFromPoint(e.clientX, e.clientY);
227
- if (!target || target === highlight) return;
228
- if (target === currentElement) return;
229
- currentElement = target;
230
- const rect = target.getBoundingClientRect();
231
- highlight.style.display = "block";
232
- highlight.style.left = rect.left + "px";
233
- highlight.style.top = rect.top + "px";
234
- highlight.style.width = rect.width + "px";
235
- highlight.style.height = rect.height + "px";
236
- }
237
- function onClick(e) {
238
- e.preventDefault();
239
- e.stopPropagation();
240
- e.stopImmediatePropagation();
241
- if (!currentElement) return;
242
- const info = gatherInfo(currentElement);
243
- const pickId = Math.random().toString(36).slice(2);
244
- currentElement.setAttribute("data-pw-pick-id", pickId);
245
- cleanup();
246
- chrome.runtime.sendMessage({ type: "element-picked-raw", pickId, info });
247
- }
248
- function onKeyDown(e) {
249
- if (e.key === "Escape") {
250
- e.preventDefault();
251
- e.stopImmediatePropagation();
252
- cleanup();
253
- chrome.runtime.sendMessage({ type: "pick-cancelled" });
254
- }
255
- }
256
- function cleanup() {
257
- window.__pw_picker_active = false;
258
- currentElement = null;
259
- highlight.remove();
260
- document.removeEventListener("mousemove", onMouseMove, true);
261
- document.removeEventListener("click", onClick, true);
262
- document.removeEventListener("keydown", onKeyDown, true);
263
- chrome.runtime.onMessage.removeListener(onMessage);
264
- }
265
- function onMessage(msg) {
266
- if (msg.type === "pick-stop") cleanup();
267
- }
268
- function init() {
269
- if (window.__pw_picker_active) return;
270
- window.__pw_picker_active = true;
271
- document.documentElement.appendChild(highlight);
272
- chrome.runtime.onMessage.addListener(onMessage);
273
- document.addEventListener("mousemove", onMouseMove, true);
274
- document.addEventListener("click", onClick, true);
275
- document.addEventListener("keydown", onKeyDown, true);
276
- }
277
- init();
278
- })();
279
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL2NvbnRlbnQvbG9jYXRvci50cyIsICJzcmMvY29udGVudC9waWNrZXIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxyXG4gKiBTaGFyZWQgbG9jYXRvciBnZW5lcmF0aW9uIHV0aWxpdGllcy5cclxuICogVXNlZCBieSBib3RoIHBpY2tlci50cyBhbmQgcmVjb3JkZXIudHMgY29udGVudCBzY3JpcHRzLlxyXG4gKiBWaXRlIGlubGluZXMgdGhpcyBpbnRvIGVhY2ggY29udGVudCBzY3JpcHQgYnVuZGxlIFx1MjAxNCBubyBydW50aW1lIG1vZHVsZSBsb2FkaW5nLlxyXG4gKi9cclxuXHJcbi8vIFx1MjUwMFx1MjUwMFx1MjUwMCBJbXBsaWNpdCBBUklBIHJvbGVzIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxyXG5cclxuZXhwb3J0IGNvbnN0IElNUExJQ0lUX1JPTEVTOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCAoKGVsOiBFbGVtZW50KSA9PiBzdHJpbmcgfCBudWxsKT4gPSB7XHJcbiAgICBBOiAoZWwpID0+IGVsLmhhc0F0dHJpYnV0ZSgnaHJlZicpID8gJ2xpbmsnIDogbnVsbCxcclxuICAgIEJVVFRPTjogJ2J1dHRvbicsXHJcbiAgICBIMTogJ2hlYWRpbmcnLCBIMjogJ2hlYWRpbmcnLCBIMzogJ2hlYWRpbmcnLCBINDogJ2hlYWRpbmcnLCBINTogJ2hlYWRpbmcnLCBINjogJ2hlYWRpbmcnLFxyXG4gICAgSU5QVVQ6IChlbCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHR5cGUgPSAoZWwgYXMgSFRNTElucHV0RWxlbWVudCkudHlwZS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgIGlmICh0eXBlID09PSAnY2hlY2tib3gnKSByZXR1cm4gJ2NoZWNrYm94JztcclxuICAgICAgICBpZiAodHlwZSA9PT0gJ3JhZGlvJykgcmV0dXJuICdyYWRpbyc7XHJcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdWJtaXQnIHx8IHR5cGUgPT09ICdyZXNldCcgfHwgdHlwZSA9PT0gJ2J1dHRvbicpIHJldHVybiAnYnV0dG9uJztcclxuICAgICAgICBpZiAodHlwZSA9PT0gJ2hpZGRlbicpIHJldHVybiBudWxsO1xyXG4gICAgICAgIHJldHVybiAndGV4dGJveCc7XHJcbiAgICB9LFxyXG4gICAgVEVYVEFSRUE6ICd0ZXh0Ym94JyxcclxuICAgIFNFTEVDVDogJ2NvbWJvYm94JyxcclxuICAgIElNRzogJ2ltZycsXHJcbiAgICBOQVY6ICduYXZpZ2F0aW9uJyxcclxuICAgIE1BSU46ICdtYWluJyxcclxuICAgIEhFQURFUjogJ2Jhbm5lcicsXHJcbiAgICBGT09URVI6ICdjb250ZW50aW5mbycsXHJcbiAgICBVTDogJ2xpc3QnLCBPTDogJ2xpc3QnLFxyXG4gICAgTEk6ICdsaXN0aXRlbScsXHJcbiAgICBUQUJMRTogJ3RhYmxlJyxcclxuICAgIFRSOiAncm93JyxcclxuICAgIFRIOiAnY29sdW1uaGVhZGVyJyxcclxuICAgIFREOiAnY2VsbCcsXHJcbiAgICBGT1JNOiAnZm9ybScsXHJcbiAgICBESUFMT0c6ICdkaWFsb2cnLFxyXG4gICAgQVJUSUNMRTogJ2FydGljbGUnLFxyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEltcGxpY2l0Um9sZShlbDogRWxlbWVudCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgZXhwbGljaXQgPSBlbC5nZXRBdHRyaWJ1dGUoJ3JvbGUnKTtcclxuICAgIGlmIChleHBsaWNpdCAmJiBleHBsaWNpdCAhPT0gJ25vbmUnICYmIGV4cGxpY2l0ICE9PSAncHJlc2VudGF0aW9uJykgcmV0dXJuIGV4cGxpY2l0O1xyXG4gICAgY29uc3QgZW50cnkgPSBJTVBMSUNJVF9ST0xFU1tlbC50YWdOYW1lXTtcclxuICAgIGlmICghZW50cnkpIHJldHVybiBudWxsO1xyXG4gICAgcmV0dXJuIHR5cGVvZiBlbnRyeSA9PT0gJ2Z1bmN0aW9uJyA/IGVudHJ5KGVsKSA6IGVudHJ5O1xyXG59XHJcblxyXG4vLyBcdTI1MDBcdTI1MDBcdTI1MDAgQWNjZXNzaWJsZSBuYW1lIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEFjY2Vzc2libGVOYW1lKGVsOiBFbGVtZW50KTogc3RyaW5nIHtcclxuICAgIC8vIGFyaWEtbGFiZWxcclxuICAgIGNvbnN0IGFyaWFMYWJlbCA9IGVsLmdldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbCcpO1xyXG4gICAgaWYgKGFyaWFMYWJlbCkgcmV0dXJuIGFyaWFMYWJlbC50cmltKCk7XHJcblxyXG4gICAgLy8gYXJpYS1sYWJlbGxlZGJ5XHJcbiAgICBjb25zdCBsYWJlbGxlZEJ5ID0gZWwuZ2V0QXR0cmlidXRlKCdhcmlhLWxhYmVsbGVkYnknKTtcclxuICAgIGlmIChsYWJlbGxlZEJ5KSB7XHJcbiAgICAgICAgY29uc3QgcGFydHMgPSBsYWJlbGxlZEJ5LnNwbGl0KC9cXHMrLykubWFwKGlkID0+IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKT8udGV4dENvbnRlbnQ/LnRyaW0oKSkuZmlsdGVyKEJvb2xlYW4pO1xyXG4gICAgICAgIGlmIChwYXJ0cy5sZW5ndGgpIHJldHVybiBwYXJ0cy5qb2luKCcgJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRm9yIGlucHV0czogYXNzb2NpYXRlZCA8bGFiZWw+XHJcbiAgICBpZiAoZWwgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50IHx8IGVsIGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCB8fCBlbCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50KSB7XHJcbiAgICAgICAgY29uc3QgbGFiZWwgPSBnZXRMYWJlbChlbCk7XHJcbiAgICAgICAgaWYgKGxhYmVsKSByZXR1cm4gbGFiZWw7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRm9yIHJvbGVzIHRoYXQgZ2V0IG5hbWUgZnJvbSBjb250ZW50IChBUklBIFwibmFtZSBmcm9tIGNvbnRlbnRcIiByb2xlcylcclxuICAgIGNvbnN0IHJvbGUgPSBnZXRJbXBsaWNpdFJvbGUoZWwpO1xyXG4gICAgY29uc3QgTkFNRV9GUk9NX0NPTlRFTlQgPSBuZXcgU2V0KFtcclxuICAgICAgICAnYnV0dG9uJywgJ2xpbmsnLCAnaGVhZGluZycsICd0YWInLCAnbWVudWl0ZW0nLCAnbWVudWl0ZW1jaGVja2JveCcsXHJcbiAgICAgICAgJ21lbnVpdGVtcmFkaW8nLCAnb3B0aW9uJywgJ3JhZGlvJywgJ2NoZWNrYm94JywgJ3N3aXRjaCcsICdjZWxsJyxcclxuICAgICAgICAnY29sdW1uaGVhZGVyJywgJ3Jvd2hlYWRlcicsICd0b29sdGlwJywgJ3RyZWVpdGVtJyxcclxuICAgIF0pO1xyXG4gICAgaWYgKHJvbGUgJiYgTkFNRV9GUk9NX0NPTlRFTlQuaGFzKHJvbGUpKSB7XHJcbiAgICAgICAgY29uc3QgdGV4dCA9IChlbC50ZXh0Q29udGVudCB8fCAnJykudHJpbSgpO1xyXG4gICAgICAgIGlmICh0ZXh0ICYmIHRleHQubGVuZ3RoIDw9IDgwKSByZXR1cm4gdGV4dDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBhbHQgZm9yIGltYWdlc1xyXG4gICAgaWYgKGVsLnRhZ05hbWUgPT09ICdJTUcnKSB7XHJcbiAgICAgICAgY29uc3QgYWx0ID0gZWwuZ2V0QXR0cmlidXRlKCdhbHQnKTtcclxuICAgICAgICBpZiAoYWx0KSByZXR1cm4gYWx0LnRyaW0oKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gJyc7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRMYWJlbChlbDogSFRNTElucHV0RWxlbWVudCB8IEhUTUxUZXh0QXJlYUVsZW1lbnQgfCBIVE1MU2VsZWN0RWxlbWVudCk6IHN0cmluZyB7XHJcbiAgICAvLyBFeHBsaWNpdCBsYWJlbCB2aWEgZm9yIGF0dHJpYnV0ZVxyXG4gICAgaWYgKGVsLmlkKSB7XHJcbiAgICAgICAgY29uc3QgbGFiZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBsYWJlbFtmb3I9XCIke0NTUy5lc2NhcGUoZWwuaWQpfVwiXWApO1xyXG4gICAgICAgIGlmIChsYWJlbCkgcmV0dXJuIChsYWJlbC50ZXh0Q29udGVudCB8fCAnJykudHJpbSgpO1xyXG4gICAgfVxyXG4gICAgLy8gSW1wbGljaXQgbGFiZWwgKGFuY2VzdG9yKVxyXG4gICAgY29uc3QgcGFyZW50TGFiZWwgPSBlbC5jbG9zZXN0KCdsYWJlbCcpO1xyXG4gICAgaWYgKHBhcmVudExhYmVsKSB7XHJcbiAgICAgICAgLy8gR2V0IGxhYmVsIHRleHQgZXhjbHVkaW5nIHRoZSBpbnB1dCdzIG93biB0ZXh0XHJcbiAgICAgICAgY29uc3QgY2xvbmUgPSBwYXJlbnRMYWJlbC5jbG9uZU5vZGUodHJ1ZSkgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgY2xvbmUucXVlcnlTZWxlY3RvckFsbCgnaW5wdXQsdGV4dGFyZWEsc2VsZWN0JykuZm9yRWFjaChjID0+IGMucmVtb3ZlKCkpO1xyXG4gICAgICAgIGNvbnN0IHRleHQgPSAoY2xvbmUudGV4dENvbnRlbnQgfHwgJycpLnRyaW0oKTtcclxuICAgICAgICBpZiAodGV4dCkgcmV0dXJuIHRleHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gJyc7XHJcbn1cclxuXHJcbi8vIFx1MjUwMFx1MjUwMFx1MjUwMCBBbmNlc3RvciBjb250ZXh0IGRpc2FtYmlndWF0aW9uIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxyXG5cclxuLyoqIENvbnRhaW5lciByb2xlcyBzdWl0YWJsZSBmb3IgYW5jZXN0b3ItY29udGV4dCBkaXNhbWJpZ3VhdGlvbi4gKi9cclxuY29uc3QgQ09OVEFJTkVSX1JPTEVTID0gbmV3IFNldChbJ2xpc3RpdGVtJywgJ3JvdycsICdhcnRpY2xlJywgJ2dyb3VwJ10pO1xyXG5cclxuLyoqXHJcbiAqIEZpbmQgZGlzdGluY3RpdmUgdGV4dCBpbiBhbiBhbmNlc3RvciB0aGF0IGRvZXNuJ3QgY29tZSBmcm9tIHRoZSBleGNsdWRlZCBlbGVtZW50J3Mgc3VidHJlZS5cclxuICogUmV0dXJucyB0ZXh0IGZyb20gdGhlIGZpcnN0IGNoaWxkIHN1YnRyZWUgdGhhdCBkb2Vzbid0IGNvbnRhaW4gdGhlIGV4Y2x1ZGVkIGVsZW1lbnQsXHJcbiAqIHJlY3Vyc2luZyBpbnRvIHdyYXBwZXJzIHRoYXQgZG8gY29udGFpbiBpdC4gVGhpcyBlbnN1cmVzIHRoZSByZXR1cm5lZCB0ZXh0IGlzIGFcclxuICogY29udGlndW91cyBzdWJzdHJpbmcgb2YgdGhlIGFuY2VzdG9yJ3MgZnVsbCB0ZXh0Q29udGVudCAobmVlZGVkIGZvciBoYXNUZXh0IG1hdGNoaW5nKS5cclxuICovXHJcbmZ1bmN0aW9uIGdldENvbnRleHRUZXh0KGFuY2VzdG9yOiBFbGVtZW50LCBleGNsdWRlOiBFbGVtZW50KTogc3RyaW5nIHtcclxuICAgIGZ1bmN0aW9uIGZpbmRUZXh0KG5vZGU6IE5vZGUpOiBzdHJpbmcge1xyXG4gICAgICAgIGZvciAoY29uc3QgY2hpbGQgb2Ygbm9kZS5jaGlsZE5vZGVzKSB7XHJcbiAgICAgICAgICAgIGlmIChjaGlsZCA9PT0gZXhjbHVkZSkgY29udGludWU7XHJcbiAgICAgICAgICAgIGlmIChjaGlsZC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiYgKGNoaWxkIGFzIEVsZW1lbnQpLmNvbnRhaW5zKGV4Y2x1ZGUpKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBUaGlzIHN1YnRyZWUgY29udGFpbnMgdGhlIHRhcmdldCBcdTIwMTQgcmVjdXJzZSB0byBmaW5kIG5vbi10YXJnZXQgc2libGluZ3NcclxuICAgICAgICAgICAgICAgIGNvbnN0IGlubmVyID0gZmluZFRleHQoY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGlubmVyKSByZXR1cm4gaW5uZXI7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCB0ZXh0ID0gKGNoaWxkLnRleHRDb250ZW50IHx8ICcnKS50cmltKCk7XHJcbiAgICAgICAgICAgIGlmICh0ZXh0ICYmIHRleHQubGVuZ3RoIDw9IDUwKSByZXR1cm4gdGV4dDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZpbmRUZXh0KGFuY2VzdG9yKTtcclxufVxyXG5cclxuLyoqIFdhbGsgdXAgZnJvbSBlbCB0byBmaW5kIG5lYXJlc3QgYW5jZXN0b3Igd2l0aCBhIGNvbnRhaW5lciByb2xlLiAqL1xyXG5mdW5jdGlvbiBmaW5kQ29udGFpbmVyQW5jZXN0b3IoZWw6IEVsZW1lbnQpOiB7IGFuY2VzdG9yOiBFbGVtZW50OyByb2xlOiBzdHJpbmcgfSB8IG51bGwge1xyXG4gICAgbGV0IGN1cnJlbnQgPSBlbC5wYXJlbnRFbGVtZW50O1xyXG4gICAgd2hpbGUgKGN1cnJlbnQgJiYgY3VycmVudCAhPT0gZG9jdW1lbnQuYm9keSAmJiBjdXJyZW50ICE9PSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCByb2xlID0gZ2V0SW1wbGljaXRSb2xlKGN1cnJlbnQpO1xyXG4gICAgICAgIGlmIChyb2xlICYmIENPTlRBSU5FUl9ST0xFUy5oYXMocm9sZSkpIHJldHVybiB7IGFuY2VzdG9yOiBjdXJyZW50LCByb2xlIH07XHJcbiAgICAgICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50RWxlbWVudDtcclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG59XHJcblxyXG4vKipcclxuICogVHJ5IHRvIGRpc2FtYmlndWF0ZSB1c2luZyBhbmNlc3RvciBjb250ZXh0LlxyXG4gKiBSZXR1cm5zIGEgY2hhaW5lZCBsb2NhdG9yIGxpa2U6XHJcbiAqICAgZ2V0QnlSb2xlKCdsaXN0aXRlbScpLmZpbHRlcih7IGhhc1RleHQ6ICdyZWFkaW5nJyB9KS5nZXRCeVJvbGUoJ2J1dHRvbicsIHsgbmFtZTogJ0RlbGV0ZScgfSlcclxuICogb3IgbnVsbCBpZiBhbmNlc3RvciBjb250ZXh0IGRvZXNuJ3QgcHJvZHVjZSBhIHVuaXF1ZSByZXN1bHQuXHJcbiAqL1xyXG5mdW5jdGlvbiB0cnlBbmNlc3RvckNvbnRleHQoZWw6IEVsZW1lbnQsIHJvbGU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBtYXRjaGVzOiBFbGVtZW50W10pOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IGNvbnRhaW5lciA9IGZpbmRDb250YWluZXJBbmNlc3RvcihlbCk7XHJcbiAgICBpZiAoIWNvbnRhaW5lcikgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgY29uc3QgY29udGV4dFRleHQgPSBnZXRDb250ZXh0VGV4dChjb250YWluZXIuYW5jZXN0b3IsIGVsKTtcclxuICAgIGlmICghY29udGV4dFRleHQgfHwgY29udGV4dFRleHQubGVuZ3RoID4gNTApIHJldHVybiBudWxsO1xyXG5cclxuICAgIC8vIFZlcmlmeSB1bmlxdWVuZXNzOiBvbmx5IG9uZSBtYXRjaCdzIGNvbnRhaW5lciBhbmNlc3RvciBzaG91bGQgY29udGFpbiB0aGlzIHRleHRcclxuICAgIGxldCBjb3VudCA9IDA7XHJcbiAgICBmb3IgKGNvbnN0IG1hdGNoIG9mIG1hdGNoZXMpIHtcclxuICAgICAgICBjb25zdCBtYyA9IGZpbmRDb250YWluZXJBbmNlc3RvcihtYXRjaCk7XHJcbiAgICAgICAgaWYgKCFtYyB8fCBtYy5yb2xlICE9PSBjb250YWluZXIucm9sZSkgY29udGludWU7XHJcbiAgICAgICAgaWYgKChtYy5hbmNlc3Rvci50ZXh0Q29udGVudCB8fCAnJykuaW5jbHVkZXMoY29udGV4dFRleHQpKSB7XHJcbiAgICAgICAgICAgIGNvdW50Kys7XHJcbiAgICAgICAgICAgIGlmIChjb3VudCA+IDEpIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChjb3VudCAhPT0gMSkgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgcmV0dXJuIGBnZXRCeVJvbGUoJHtlc2NhcGVTdHJpbmcoY29udGFpbmVyLnJvbGUpfSkuZmlsdGVyKHsgaGFzVGV4dDogJHtlc2NhcGVTdHJpbmcoY29udGV4dFRleHQpfSB9KS5nZXRCeVJvbGUoJHtlc2NhcGVTdHJpbmcocm9sZSl9LCB7IG5hbWU6ICR7ZXNjYXBlU3RyaW5nKG5hbWUpfSB9KWA7XHJcbn1cclxuXHJcbi8vIFx1MjUwMFx1MjUwMFx1MjUwMCBMb2NhdG9yIGRpc2FtYmlndWF0aW9uIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRCeVJvbGVBbmROYW1lKHJvbGU6IHN0cmluZywgbmFtZTogc3RyaW5nKTogRWxlbWVudFtdIHtcclxuICAgIGNvbnN0IG1hdGNoZXM6IEVsZW1lbnRbXSA9IFtdO1xyXG4gICAgZm9yIChjb25zdCBlbCBvZiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcqJykpIHtcclxuICAgICAgICBpZiAoZ2V0SW1wbGljaXRSb2xlKGVsKSA9PT0gcm9sZSAmJiBnZXRBY2Nlc3NpYmxlTmFtZShlbCkgPT09IG5hbWVcclxuICAgICAgICAgICAgJiYgKGVsIGFzIEhUTUxFbGVtZW50KS5jaGVja1Zpc2liaWxpdHk/LigpICE9PSBmYWxzZSlcclxuICAgICAgICAgICAgbWF0Y2hlcy5wdXNoKGVsKTtcclxuICAgIH1cclxuICAgIHJldHVybiBtYXRjaGVzO1xyXG59XHJcblxyXG4vKiogTGlrZSBmaW5kQnlSb2xlQW5kTmFtZSBidXQgaW5jbHVkZXMgaGlkZGVuIGVsZW1lbnRzIChmb3IgaG92ZXIgZGV0ZWN0aW9uKS4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRBbGxCeVJvbGVBbmROYW1lKHJvbGU6IHN0cmluZywgbmFtZTogc3RyaW5nKTogRWxlbWVudFtdIHtcclxuICAgIGNvbnN0IG1hdGNoZXM6IEVsZW1lbnRbXSA9IFtdO1xyXG4gICAgZm9yIChjb25zdCBlbCBvZiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcqJykpIHtcclxuICAgICAgICBpZiAoZ2V0SW1wbGljaXRSb2xlKGVsKSA9PT0gcm9sZSAmJiBnZXRBY2Nlc3NpYmxlTmFtZShlbCkgPT09IG5hbWUpXHJcbiAgICAgICAgICAgIG1hdGNoZXMucHVzaChlbCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbWF0Y2hlcztcclxufVxyXG5cclxuLyoqIEZpbmQgdGhlIG5lYXJlc3QgOmhvdmVyIGFuY2VzdG9yIChmb3IgcmVjb3JkaW5nIGhvdmVyIGJlZm9yZSBjbGljaykuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBmaW5kSG92ZXJBbmNlc3RvcihlbDogRWxlbWVudCk6IEVsZW1lbnQgfCBudWxsIHtcclxuICAgIGxldCBhbmNlc3RvciA9IGVsLnBhcmVudEVsZW1lbnQ7XHJcbiAgICB3aGlsZSAoYW5jZXN0b3IgJiYgYW5jZXN0b3IgIT09IGRvY3VtZW50LmJvZHkgJiYgYW5jZXN0b3IgIT09IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xyXG4gICAgICAgIGlmIChhbmNlc3Rvci5tYXRjaGVzKCc6aG92ZXInKSkgcmV0dXJuIGFuY2VzdG9yO1xyXG4gICAgICAgIGFuY2VzdG9yID0gYW5jZXN0b3IucGFyZW50RWxlbWVudDtcclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2sgaWYgZWxlbWVudCBpcyByZXZlYWxlZCBieSBhIDpob3ZlciBDU1MgcnVsZS5cclxuICogU2NhbnMgc3R5bGVzaGVldHMgZm9yIHJ1bGVzIGxpa2UgYC5wYXJlbnQ6aG92ZXIgLmNoaWxkIHsgZGlzcGxheTogaW5saW5lLWJsb2NrIH1gLlxyXG4gKiBBdCBjbGljayB0aW1lIHRoZSBhbmNlc3RvciBJUyBob3ZlcmVkLCBzbyBlbC5tYXRjaGVzKCkgd29ya3MgYWdhaW5zdCA6aG92ZXIgc2VsZWN0b3JzLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGlzSG92ZXJSZXZlYWxlZChlbDogRWxlbWVudCk6IGJvb2xlYW4ge1xyXG4gICAgZm9yIChjb25zdCBzaGVldCBvZiBkb2N1bWVudC5zdHlsZVNoZWV0cykge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgcnVsZSBvZiBzaGVldC5jc3NSdWxlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCEocnVsZSBpbnN0YW5jZW9mIENTU1N0eWxlUnVsZSkpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFydWxlLnNlbGVjdG9yVGV4dC5pbmNsdWRlcygnOmhvdmVyJykpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcyA9IHJ1bGUuc3R5bGU7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZXZlYWxzID0gKHMuZGlzcGxheSAmJiBzLmRpc3BsYXkgIT09ICdub25lJykgfHxcclxuICAgICAgICAgICAgICAgICAgICBzLnZpc2liaWxpdHkgPT09ICd2aXNpYmxlJyB8fFxyXG4gICAgICAgICAgICAgICAgICAgIChzLm9wYWNpdHkgJiYgcy5vcGFjaXR5ICE9PSAnMCcpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFyZXZlYWxzKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIHRyeSB7IGlmIChlbC5tYXRjaGVzKHJ1bGUuc2VsZWN0b3JUZXh0KSkgcmV0dXJuIHRydWU7IH0gY2F0Y2ggeyAvKiBpbnZhbGlkIHNlbGVjdG9yICovIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gY2F0Y2ggeyAvKiBjcm9zcy1vcmlnaW4gc3R5bGVzaGVldCAqLyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbn1cclxuXHJcbi8vIFx1MjUwMFx1MjUwMFx1MjUwMCBMb2NhdG9yIHN0cmluZyBjb252ZXJzaW9uIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxyXG5cclxuLyoqXHJcbiAqIFBhcnNlIGEgSlMgbG9jYXRvciBzdHJpbmcgaW50byBQVyBrZXl3b3JkIGFyZ3MuXHJcbiAqIGUuZy4gYGdldEJ5Um9sZSgndGFiJywgeyBuYW1lOiAnbnBtJywgZXhhY3Q6IHRydWUgfSkubnRoKDEpYCBcdTIxOTIgYHRhYiBcIm5wbVwiIC0tbnRoIDFgXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gbG9jYXRvclRvUHdBcmdzKGxvY2F0b3I6IHN0cmluZywgcm9sZT86IHN0cmluZyB8IG51bGwpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgcSA9IChzOiBzdHJpbmcpID0+IGBcIiR7c31cImA7XHJcblxyXG4gICAgLy8gRXh0cmFjdCBudGggbW9kaWZpZXJcclxuICAgIGxldCBudGggPSAnJztcclxuICAgIGlmICgvXFwuZmlyc3RcXChcXCkvLnRlc3QobG9jYXRvcikpIG50aCA9ICcgLS1udGggMCc7XHJcbiAgICBlbHNlIGlmICgvXFwubGFzdFxcKFxcKS8udGVzdChsb2NhdG9yKSkgbnRoID0gJyAtLW50aCAtMSc7XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBjb25zdCBudGhNYXRjaCA9IGxvY2F0b3IubWF0Y2goL1xcLm50aFxcKChcXGQrKVxcKS8pO1xyXG4gICAgICAgIGlmIChudGhNYXRjaCkgbnRoID0gYCAtLW50aCAke250aE1hdGNoWzFdfWA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZ2V0QnlSb2xlIHdpdGggbmFtZSBcdTIwMTQgYWxyZWFkeSBoYXMgcm9sZVxyXG4gICAgY29uc3Qgcm9sZU5hbWVNYXRjaCA9IGxvY2F0b3IubWF0Y2goL2dldEJ5Um9sZVxcKFsnXCJdKC4rPylbJ1wiXSxcXHMqXFx7W159XSpuYW1lOlxccypbJ1wiXSguKz8pWydcIl0vKTtcclxuICAgIGlmIChyb2xlTmFtZU1hdGNoKSByZXR1cm4gYCR7cm9sZU5hbWVNYXRjaFsxXX0gJHtxKHJvbGVOYW1lTWF0Y2hbMl0pfSR7bnRofWA7XHJcblxyXG4gICAgLy8gZ2V0QnlSb2xlIHdpdGhvdXQgbmFtZSBcdTIwMTQgYWxyZWFkeSBoYXMgcm9sZVxyXG4gICAgY29uc3Qgcm9sZU1hdGNoID0gbG9jYXRvci5tYXRjaCgvZ2V0QnlSb2xlXFwoWydcIl0oLis/KVsnXCJdXFwpLyk7XHJcbiAgICBpZiAocm9sZU1hdGNoKSByZXR1cm4gYCR7cm9sZU1hdGNoWzFdfSR7bnRofWA7XHJcblxyXG4gICAgLy8gZ2V0QnlUZXN0SWQgXHUyMDE0IHRlc3QgSUQgaXMgbm90IGFuIGFjY2Vzc2libGUgbmFtZSwgZG9uJ3QgYWRkIHJvbGVcclxuICAgIGNvbnN0IHRlc3RJZE1hdGNoID0gbG9jYXRvci5tYXRjaCgvZ2V0QnlUZXN0SWRcXChbJ1wiXSguKz8pWydcIl1cXCkvKTtcclxuICAgIGlmICh0ZXN0SWRNYXRjaCkgcmV0dXJuIGAke3EodGVzdElkTWF0Y2hbMV0pfSR7bnRofWA7XHJcblxyXG4gICAgLy8gZ2V0QnlMYWJlbCAvIGdldEJ5VGV4dCAvIGdldEJ5UGxhY2Vob2xkZXIgLyBnZXRCeVRpdGxlIC8gZ2V0QnlBbHRUZXh0IFx1MjAxNCBwcmVwZW5kIHJvbGUgaWYgYXZhaWxhYmxlXHJcbiAgICBjb25zdCBnZXRCeU1hdGNoID0gbG9jYXRvci5tYXRjaCgvZ2V0QnlcXHcrXFwoWydcIl0oLis/KVsnXCJdXFwpLyk7XHJcbiAgICBpZiAoZ2V0QnlNYXRjaCkge1xyXG4gICAgICAgIGNvbnN0IHByZWZpeCA9IHJvbGUgPyBgJHtyb2xlfSBgIDogJyc7XHJcbiAgICAgICAgcmV0dXJuIGAke3ByZWZpeH0ke3EoZ2V0QnlNYXRjaFsxXSl9JHtudGh9YDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBsb2NhdG9yKCdjc3MnKSBmYWxsYmFja1xyXG4gICAgY29uc3QgbG9jYXRvck1hdGNoID0gbG9jYXRvci5tYXRjaCgvbG9jYXRvclxcKFsnXCJdKC4rPylbJ1wiXVxcKS8pO1xyXG4gICAgaWYgKGxvY2F0b3JNYXRjaCkgcmV0dXJuIGAke3EobG9jYXRvck1hdGNoWzFdKX0ke250aH1gO1xyXG5cclxuICAgIHJldHVybiBxKGxvY2F0b3IpO1xyXG59XHJcblxyXG4vLyBcdTI1MDBcdTI1MDBcdTI1MDAgTG9jYXRvciBnZW5lcmF0aW9uIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZVN0cmluZyhzOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgaWYgKCFzLmluY2x1ZGVzKFwiJ1wiKSkgcmV0dXJuIGAnJHtzfSdgO1xyXG4gICAgaWYgKCFzLmluY2x1ZGVzKCdcIicpKSByZXR1cm4gYFwiJHtzfVwiYDtcclxuICAgIHJldHVybiBgJyR7cy5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIil9J2A7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUxvY2F0b3IoZWw6IEVsZW1lbnQpOiBzdHJpbmcge1xyXG4gICAgLy8gMS4gVGVzdCBJRFxyXG4gICAgY29uc3QgdGVzdElkID0gZWwuZ2V0QXR0cmlidXRlKCdkYXRhLXRlc3RpZCcpIHx8IGVsLmdldEF0dHJpYnV0ZSgnZGF0YS10ZXN0LWlkJyk7XHJcbiAgICBpZiAodGVzdElkKSByZXR1cm4gYGdldEJ5VGVzdElkKCR7ZXNjYXBlU3RyaW5nKHRlc3RJZCl9KWA7XHJcblxyXG4gICAgLy8gMi4gUm9sZSArIGFjY2Vzc2libGUgbmFtZVxyXG4gICAgY29uc3Qgcm9sZSA9IGdldEltcGxpY2l0Um9sZShlbCk7XHJcbiAgICBjb25zdCBuYW1lID0gZ2V0QWNjZXNzaWJsZU5hbWUoZWwpO1xyXG4gICAgaWYgKHJvbGUgJiYgbmFtZSkge1xyXG4gICAgICAgIC8vIERpc2FtYmlndWF0ZSB3aGVuIG11bHRpcGxlIGVsZW1lbnRzIHNoYXJlIHNhbWUgcm9sZSArIG5hbWVcclxuICAgICAgICBjb25zdCBtYXRjaGVzID0gZmluZEJ5Um9sZUFuZE5hbWUocm9sZSwgbmFtZSk7XHJcbiAgICAgICAgaWYgKG1hdGNoZXMubGVuZ3RoID4gMSkge1xyXG4gICAgICAgICAgICAvLyBUcnkgYW5jZXN0b3IgY29udGV4dCBmaXJzdCAocmVhZGFibGUgY2hhaW5lZCBsb2NhdG9ycylcclxuICAgICAgICAgICAgY29uc3QgYW5jZXN0b3JMb2NhdG9yID0gdHJ5QW5jZXN0b3JDb250ZXh0KGVsLCByb2xlLCBuYW1lLCBtYXRjaGVzKTtcclxuICAgICAgICAgICAgaWYgKGFuY2VzdG9yTG9jYXRvcikgcmV0dXJuIGFuY2VzdG9yTG9jYXRvcjtcclxuICAgICAgICAgICAgLy8gRmFsbGJhY2sgdG8gbnRoLWJhc2VkIGRpc2FtYmlndWF0aW9uXHJcbiAgICAgICAgICAgIGNvbnN0IGJhc2UgPSBgZ2V0QnlSb2xlKCR7ZXNjYXBlU3RyaW5nKHJvbGUpfSwgeyBuYW1lOiAke2VzY2FwZVN0cmluZyhuYW1lKX0sIGV4YWN0OiB0cnVlIH0pYDtcclxuICAgICAgICAgICAgY29uc3QgaWR4ID0gbWF0Y2hlcy5pbmRleE9mKGVsKTtcclxuICAgICAgICAgICAgcmV0dXJuIGlkeCA9PT0gMCA/IGJhc2UgKyAnLmZpcnN0KCknIDogYmFzZSArIGAubnRoKCR7aWR4fSlgO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYGdldEJ5Um9sZSgke2VzY2FwZVN0cmluZyhyb2xlKX0sIHsgbmFtZTogJHtlc2NhcGVTdHJpbmcobmFtZSl9IH0pYDtcclxuICAgIH1cclxuXHJcbiAgICAvLyAzLiBMYWJlbCAoZm9yIGZvcm0gZWxlbWVudHMpXHJcbiAgICBpZiAoZWwgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50IHx8IGVsIGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCB8fCBlbCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50KSB7XHJcbiAgICAgICAgY29uc3QgbGFiZWwgPSBnZXRMYWJlbChlbCk7XHJcbiAgICAgICAgaWYgKGxhYmVsKSByZXR1cm4gYGdldEJ5TGFiZWwoJHtlc2NhcGVTdHJpbmcobGFiZWwpfSlgO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIDQuIFBsYWNlaG9sZGVyXHJcbiAgICBjb25zdCBwbGFjZWhvbGRlciA9IGVsLmdldEF0dHJpYnV0ZSgncGxhY2Vob2xkZXInKTtcclxuICAgIGlmIChwbGFjZWhvbGRlcikgcmV0dXJuIGBnZXRCeVBsYWNlaG9sZGVyKCR7ZXNjYXBlU3RyaW5nKHBsYWNlaG9sZGVyKX0pYDtcclxuXHJcbiAgICAvLyA1LiBBbHQgdGV4dFxyXG4gICAgY29uc3QgYWx0ID0gZWwuZ2V0QXR0cmlidXRlKCdhbHQnKTtcclxuICAgIGlmIChhbHQgJiYgWydJTUcnLCAnQVBQTEVUJywgJ0FSRUEnLCAnSU5QVVQnXS5pbmNsdWRlcyhlbC50YWdOYW1lKSlcclxuICAgICAgICByZXR1cm4gYGdldEJ5QWx0VGV4dCgke2VzY2FwZVN0cmluZyhhbHQpfSlgO1xyXG5cclxuICAgIC8vIDYuIFRpdGxlXHJcbiAgICBjb25zdCB0aXRsZSA9IGVsLmdldEF0dHJpYnV0ZSgndGl0bGUnKTtcclxuICAgIGlmICh0aXRsZSkgcmV0dXJuIGBnZXRCeVRpdGxlKCR7ZXNjYXBlU3RyaW5nKHRpdGxlKX0pYDtcclxuXHJcbiAgICAvLyA3LiBUZXh0IGNvbnRlbnRcclxuICAgIGNvbnN0IHRleHQgPSAoZWwudGV4dENvbnRlbnQgfHwgJycpLnRyaW0oKTtcclxuICAgIGlmICh0ZXh0ICYmIHRleHQubGVuZ3RoIDw9IDgwKSByZXR1cm4gYGdldEJ5VGV4dCgke2VzY2FwZVN0cmluZyh0ZXh0KX0pYDtcclxuXHJcbiAgICAvLyA4LiBSb2xlIHdpdGhvdXQgbmFtZVxyXG4gICAgaWYgKHJvbGUpIHJldHVybiBgZ2V0QnlSb2xlKCR7ZXNjYXBlU3RyaW5nKHJvbGUpfSlgO1xyXG5cclxuICAgIC8vIDkuIENTUyBmYWxsYmFja1xyXG4gICAgcmV0dXJuIGBsb2NhdG9yKCR7ZXNjYXBlU3RyaW5nKGJ1aWxkQ3NzU2VsZWN0b3IoZWwpKX0pYDtcclxufVxyXG5cclxuLyoqIFNob3J0aGFuZCBtYXBwaW5nIGZvciBQVyAtLWluIGZsYWcgKGxpc3RpdGVtIFx1MjE5MiBsaXN0IGZvciByZWFkYWJpbGl0eSkuICovXHJcbmNvbnN0IFJPTEVfU0hPUlRIQU5EUzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgbGlzdGl0ZW06ICdsaXN0JyB9O1xyXG5cclxuLyoqXHJcbiAqIEdlbmVyYXRlIHNlcGFyYXRlIEpTIGFuZCBQVyBsb2NhdG9ycy5cclxuICogSlMgdXNlcyBhbmNlc3RvciBjb250ZXh0ICguZmlsdGVyIGNoYWlucyk7IFBXIHVzZXMgLS1pbiBmbGFnLlxyXG4gKiBGYWxscyBiYWNrIHRvIC5udGgoKSB3aGVuIGFuY2VzdG9yIGNvbnRleHQgaXNuJ3QgYXZhaWxhYmxlLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlTG9jYXRvclBhaXIoZWw6IEVsZW1lbnQpOiB7IGpzOiBzdHJpbmc7IHB3OiBzdHJpbmc7IGFuY2VzdG9yPzogeyByb2xlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9IH0ge1xyXG4gICAgY29uc3QganNMb2NhdG9yID0gZ2VuZXJhdGVMb2NhdG9yKGVsKTtcclxuICAgIGlmICghanNMb2NhdG9yLmluY2x1ZGVzKCcuZmlsdGVyKCcpKSByZXR1cm4geyBqczoganNMb2NhdG9yLCBwdzoganNMb2NhdG9yIH07XHJcblxyXG4gICAgLy8gSlMgdXNlZCBhbmNlc3RvciBjb250ZXh0IFx1MjAxNCBleHRyYWN0IGFuY2VzdG9yIGluZm8gZm9yIFBXIC0taW4gZmxhZ1xyXG4gICAgY29uc3Qgcm9sZSA9IGdldEltcGxpY2l0Um9sZShlbCkhO1xyXG4gICAgY29uc3QgbmFtZSA9IGdldEFjY2Vzc2libGVOYW1lKGVsKTtcclxuICAgIGNvbnN0IGNvbnRhaW5lciA9IGZpbmRDb250YWluZXJBbmNlc3RvcihlbCk7XHJcbiAgICBjb25zdCBjb250ZXh0VGV4dCA9IGNvbnRhaW5lciA/IGdldENvbnRleHRUZXh0KGNvbnRhaW5lci5hbmNlc3RvciwgZWwpIDogJyc7XHJcblxyXG4gICAgaWYgKGNvbnRhaW5lciAmJiBjb250ZXh0VGV4dCkge1xyXG4gICAgICAgIGNvbnN0IHB3TG9jYXRvciA9IGBnZXRCeVJvbGUoJHtlc2NhcGVTdHJpbmcocm9sZSl9LCB7IG5hbWU6ICR7ZXNjYXBlU3RyaW5nKG5hbWUpfSB9KWA7XHJcbiAgICAgICAgY29uc3Qgc2hvcnRSb2xlID0gUk9MRV9TSE9SVEhBTkRTW2NvbnRhaW5lci5yb2xlXSA/PyBjb250YWluZXIucm9sZTtcclxuICAgICAgICByZXR1cm4geyBqczoganNMb2NhdG9yLCBwdzogcHdMb2NhdG9yLCBhbmNlc3RvcjogeyByb2xlOiBzaG9ydFJvbGUsIHRleHQ6IGNvbnRleHRUZXh0IH0gfTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBObyBhbmNlc3RvciBjb250ZXh0IFx1MjAxNCBmYWxsIGJhY2sgdG8gLm50aCgpXHJcbiAgICBjb25zdCBtYXRjaGVzID0gZmluZEJ5Um9sZUFuZE5hbWUocm9sZSwgbmFtZSk7XHJcbiAgICBjb25zdCBiYXNlID0gYGdldEJ5Um9sZSgke2VzY2FwZVN0cmluZyhyb2xlKX0sIHsgbmFtZTogJHtlc2NhcGVTdHJpbmcobmFtZSl9LCBleGFjdDogdHJ1ZSB9KWA7XHJcbiAgICBjb25zdCBpZHggPSBtYXRjaGVzLmluZGV4T2YoZWwpO1xyXG4gICAgY29uc3QgcHdMb2NhdG9yID0gaWR4ID09PSAwID8gYmFzZSArICcuZmlyc3QoKScgOiBiYXNlICsgYC5udGgoJHtpZHh9KWA7XHJcbiAgICByZXR1cm4geyBqczoganNMb2NhdG9yLCBwdzogcHdMb2NhdG9yIH07XHJcbn1cclxuXHJcbi8vIFx1MjUwMFx1MjUwMFx1MjUwMCBFbGVtZW50IGNsYXNzaWZpY2F0aW9uIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxyXG5cclxuLyoqIENoZWNrIGlmIGVsZW1lbnQgaXMgYSB0ZXh0LWVudHJ5IGZpZWxkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBpc1RleHRGaWVsZChlbDogRWxlbWVudCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKGVsIGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCkgcmV0dXJuIHRydWU7XHJcbiAgICBpZiAoZWwgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50KSB7XHJcbiAgICAgICAgY29uc3QgdHlwZSA9IGVsLnR5cGUudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICByZXR1cm4gIVsnY2hlY2tib3gnLCAncmFkaW8nLCAnc3VibWl0JywgJ3Jlc2V0JywgJ2J1dHRvbicsICdoaWRkZW4nLCAnZmlsZScsICdpbWFnZScsICdyYW5nZScsICdjb2xvciddLmluY2x1ZGVzKHR5cGUpO1xyXG4gICAgfVxyXG4gICAgLy8gY29udGVudGVkaXRhYmxlXHJcbiAgICBpZiAoZWwuZ2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnKSA9PT0gJ3RydWUnKSByZXR1cm4gdHJ1ZTtcclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuLyoqIENoZWNrIGlmIGVsZW1lbnQgaXMgYSBjaGVja2JveCBvciByYWRpbyAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaXNDaGVja2FibGUoZWw6IEVsZW1lbnQpOiBib29sZWFuIHtcclxuICAgIHJldHVybiBlbCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQgJiYgKGVsLnR5cGUgPT09ICdjaGVja2JveCcgfHwgZWwudHlwZSA9PT0gJ3JhZGlvJyk7XHJcbn1cclxuXHJcbi8vIFx1MjUwMFx1MjUwMFx1MjUwMCBDb21tYW5kIGJ1aWxkaW5nIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxyXG5cclxuLyoqIEJ1aWxkIGJvdGggUFcgYW5kIEpTIGNvbW1hbmQgc3RyaW5ncyBmb3IgYSByZWNvcmRlciBhY3Rpb24gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQ29tbWFuZHMoYWN0aW9uOiBzdHJpbmcsIGVsOiBFbGVtZW50LCBvcHRzPzoge1xyXG4gICAgdmFsdWU/OiBzdHJpbmc7XHJcbiAgICBrZXk/OiBzdHJpbmc7XHJcbiAgICBjaGVja2VkPzogYm9vbGVhbjtcclxuICAgIG9wdGlvbj86IHN0cmluZztcclxufSk6IHsgcHc6IHN0cmluZzsganM6IHN0cmluZyB9IHwgbnVsbCB7XHJcbiAgICBjb25zdCB7IGpzOiBqc0xvY2F0b3IsIHB3OiBwd0xvY2F0b3IsIGFuY2VzdG9yIH0gPSBnZW5lcmF0ZUxvY2F0b3JQYWlyKGVsKTtcclxuICAgIGNvbnN0IGpzTG9jID0gYHBhZ2UuJHtqc0xvY2F0b3J9YDtcclxuICAgIGNvbnN0IHJvbGUgPSBnZXRJbXBsaWNpdFJvbGUoZWwpO1xyXG4gICAgY29uc3QgcHdBcmdzID0gbG9jYXRvclRvUHdBcmdzKHB3TG9jYXRvciwgcm9sZSk7XHJcbiAgICBjb25zdCBxID0gKHM6IHN0cmluZykgPT4gYFwiJHtzfVwiYDtcclxuICAgIGNvbnN0IGluRmxhZyA9IGFuY2VzdG9yID8gYCAtLWluICR7YW5jZXN0b3Iucm9sZX0gJHtxKGFuY2VzdG9yLnRleHQpfWAgOiAnJztcclxuXHJcbiAgICBzd2l0Y2ggKGFjdGlvbikge1xyXG4gICAgICAgIGNhc2UgJ2hvdmVyJzpcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHB3OiBgaG92ZXIgJHtwd0FyZ3N9JHtpbkZsYWd9YCxcclxuICAgICAgICAgICAgICAgIGpzOiBgYXdhaXQgJHtqc0xvY30uaG92ZXIoKTtgLFxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICBjYXNlICdjbGljayc6XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBwdzogYGNsaWNrICR7cHdBcmdzfSR7aW5GbGFnfWAsXHJcbiAgICAgICAgICAgICAgICBqczogYGF3YWl0ICR7anNMb2N9LmNsaWNrKCk7YCxcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgY2FzZSAnZmlsbCc6IHtcclxuICAgICAgICAgICAgY29uc3QgdmFsID0gb3B0cz8udmFsdWUgPz8gJyc7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBwdzogYGZpbGwgJHtwd0FyZ3N9ICR7cSh2YWwpfSR7aW5GbGFnfWAsXHJcbiAgICAgICAgICAgICAgICBqczogYGF3YWl0ICR7anNMb2N9LmZpbGwoJHtlc2NhcGVTdHJpbmcodmFsKX0pO2AsXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjYXNlICdjaGVjayc6XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBwdzogYGNoZWNrICR7cHdBcmdzfSR7aW5GbGFnfWAsXHJcbiAgICAgICAgICAgICAgICBqczogYGF3YWl0ICR7anNMb2N9LmNoZWNrKCk7YCxcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgY2FzZSAndW5jaGVjayc6XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBwdzogYHVuY2hlY2sgJHtwd0FyZ3N9JHtpbkZsYWd9YCxcclxuICAgICAgICAgICAgICAgIGpzOiBgYXdhaXQgJHtqc0xvY30udW5jaGVjaygpO2AsXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgIGNhc2UgJ3NlbGVjdCc6IHtcclxuICAgICAgICAgICAgY29uc3Qgb3B0VmFsID0gb3B0cz8ub3B0aW9uID8/ICcnO1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgcHc6IGBzZWxlY3QgJHtwd0FyZ3N9ICR7cShvcHRWYWwpfSR7aW5GbGFnfWAsXHJcbiAgICAgICAgICAgICAgICBqczogYGF3YWl0ICR7anNMb2N9LnNlbGVjdE9wdGlvbigke2VzY2FwZVN0cmluZyhvcHRWYWwpfSk7YCxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNhc2UgJ3ByZXNzJzoge1xyXG4gICAgICAgICAgICBjb25zdCBrZXkgPSBvcHRzPy5rZXkgPz8gJyc7XHJcbiAgICAgICAgICAgIGlmIChwd0FyZ3MpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHc6IGBwcmVzcyAke3B3QXJnc30gJHtrZXl9JHtpbkZsYWd9YCxcclxuICAgICAgICAgICAgICAgICAgICBqczogYGF3YWl0ICR7anNMb2N9LnByZXNzKCR7ZXNjYXBlU3RyaW5nKGtleSl9KTtgLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBHbG9iYWwga2V5IHByZXNzIChubyBsb2NhdG9yIGNvbnRleHQpXHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBwdzogYHByZXNzICR7a2V5fWAsXHJcbiAgICAgICAgICAgICAgICBqczogYGF3YWl0IHBhZ2Uua2V5Ym9hcmQucHJlc3MoJHtlc2NhcGVTdHJpbmcoa2V5KX0pO2AsXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxufVxyXG5cclxuLy8gXHUyNTAwXHUyNTAwXHUyNTAwIENTUyBzZWxlY3RvciBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBidWlsZENzc1NlbGVjdG9yKGVsOiBFbGVtZW50KTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHRhZyA9IGVsLnRhZ05hbWUudG9Mb3dlckNhc2UoKTtcclxuICAgIGlmIChlbC5pZCkgcmV0dXJuIGAke3RhZ30jJHtDU1MuZXNjYXBlKGVsLmlkKX1gO1xyXG4gICAgY29uc3QgY2xhc3NlcyA9IFsuLi5lbC5jbGFzc0xpc3RdLnNsaWNlKDAsIDIpLm1hcChjID0+ICcuJyArIENTUy5lc2NhcGUoYykpLmpvaW4oJycpO1xyXG4gICAgaWYgKGNsYXNzZXMpIHJldHVybiBgJHt0YWd9JHtjbGFzc2VzfWA7XHJcbiAgICByZXR1cm4gdGFnO1xyXG59XHJcbiIsICIvKipcclxuICogRWxlbWVudCBwaWNrZXIgY29udGVudCBzY3JpcHQuXHJcbiAqIEluamVjdGVkIGludG8gdGhlIGFjdGl2ZSB0YWIgdmlhIGNocm9tZS5zY3JpcHRpbmcuZXhlY3V0ZVNjcmlwdC5cclxuICogSGlnaGxpZ2h0cyBlbGVtZW50cyBvbiBob3ZlciwgY2FwdHVyZXMgY2xpY2ssIGdlbmVyYXRlcyBsb2NhdG9yICsgZWxlbWVudCBpbmZvLlxyXG4gKi9cclxuaW1wb3J0IHsgZ2VuZXJhdGVMb2NhdG9yIH0gZnJvbSAnLi9sb2NhdG9yJztcclxuXHJcbi8vIFx1MjUwMFx1MjUwMFx1MjUwMCBFbGVtZW50IGluZm8gZ2F0aGVyaW5nIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldE91dGVySHRtbChlbDogRWxlbWVudCk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBvdXRlciA9IGVsLm91dGVySFRNTDtcclxuICAgIGlmIChvdXRlci5sZW5ndGggPD0gMjAwKSByZXR1cm4gb3V0ZXI7XHJcbiAgICBjb25zdCB0YWcgPSBlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCk7XHJcbiAgICBjb25zdCBvcGVuID0gb3V0ZXIuc2xpY2UoMCwgb3V0ZXIuaW5kZXhPZignPicpICsgMSk7XHJcbiAgICByZXR1cm4gYCR7b3Blbn0uLi48LyR7dGFnfT5gO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2F0aGVySW5mbyhlbDogRWxlbWVudCkge1xyXG4gICAgY29uc3QgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3QgYXR0cnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcclxuICAgIGZvciAoY29uc3QgYSBvZiBlbC5hdHRyaWJ1dGVzKSBhdHRyc1thLm5hbWVdID0gYS52YWx1ZTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgbG9jYXRvcjogZ2VuZXJhdGVMb2NhdG9yKGVsKSxcclxuICAgICAgICB0YWc6IGVsLnRhZ05hbWUudG9Mb3dlckNhc2UoKSxcclxuICAgICAgICB0ZXh0OiAoZWwudGV4dENvbnRlbnQgfHwgJycpLnRyaW0oKS5zbGljZSgwLCAyMDApLFxyXG4gICAgICAgIGh0bWw6IGdldE91dGVySHRtbChlbCksXHJcbiAgICAgICAgYXR0cmlidXRlczogYXR0cnMsXHJcbiAgICAgICAgdmlzaWJsZTogcmVjdC53aWR0aCA+IDAgJiYgcmVjdC5oZWlnaHQgPiAwLFxyXG4gICAgICAgIGVuYWJsZWQ6ICEoZWwgYXMgSFRNTEJ1dHRvbkVsZW1lbnQpLmRpc2FibGVkLFxyXG4gICAgICAgIGJveDogeyB4OiByZWN0LngsIHk6IHJlY3QueSwgd2lkdGg6IHJlY3Qud2lkdGgsIGhlaWdodDogcmVjdC5oZWlnaHQgfSxcclxuICAgICAgICB2YWx1ZTogKGVsIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCB8fCBlbCBpbnN0YW5jZW9mIEhUTUxUZXh0QXJlYUVsZW1lbnQgfHwgZWwgaW5zdGFuY2VvZiBIVE1MU2VsZWN0RWxlbWVudClcclxuICAgICAgICAgICAgPyBlbC52YWx1ZSA6IHVuZGVmaW5lZCxcclxuICAgICAgICBjaGVja2VkOiAoZWwgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50ICYmIChlbC50eXBlID09PSAnY2hlY2tib3gnIHx8IGVsLnR5cGUgPT09ICdyYWRpbycpKVxyXG4gICAgICAgICAgICA/IGVsLmNoZWNrZWQgOiB1bmRlZmluZWQsXHJcbiAgICB9O1xyXG59XHJcblxyXG4vLyBcdTI1MDBcdTI1MDBcdTI1MDAgT3ZlcmxheSArIHN0YXRlIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxyXG5cclxuZXhwb3J0IGNvbnN0IGhpZ2hsaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG5oaWdobGlnaHQuc3R5bGUuY3NzVGV4dCA9ICdwb3NpdGlvbjpmaXhlZDtwb2ludGVyLWV2ZW50czpub25lO3otaW5kZXg6MjE0NzQ4MzY0Njtib3JkZXI6MnB4IHNvbGlkICM2ZmE4ZGM7YmFja2dyb3VuZDpyZ2JhKDExMSwxNjgsMjIwLDAuMik7ZGlzcGxheTpub25lO2JveC1zaXppbmc6Ym9yZGVyLWJveDsnO1xyXG5cclxuZXhwb3J0IGxldCBjdXJyZW50RWxlbWVudDogRWxlbWVudCB8IG51bGwgPSBudWxsO1xyXG5cclxuLy8gXHUyNTAwXHUyNTAwXHUyNTAwIEV2ZW50IGhhbmRsZXJzIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG9uTW91c2VNb3ZlKGU6IE1vdXNlRXZlbnQpIHtcclxuICAgIGNvbnN0IHRhcmdldCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZS5jbGllbnRYLCBlLmNsaWVudFkpO1xyXG4gICAgaWYgKCF0YXJnZXQgfHwgdGFyZ2V0ID09PSBoaWdobGlnaHQpIHJldHVybjtcclxuICAgIGlmICh0YXJnZXQgPT09IGN1cnJlbnRFbGVtZW50KSByZXR1cm47XHJcbiAgICBjdXJyZW50RWxlbWVudCA9IHRhcmdldDtcclxuXHJcbiAgICBjb25zdCByZWN0ID0gdGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgaGlnaGxpZ2h0LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG4gICAgaGlnaGxpZ2h0LnN0eWxlLmxlZnQgPSByZWN0LmxlZnQgKyAncHgnO1xyXG4gICAgaGlnaGxpZ2h0LnN0eWxlLnRvcCA9IHJlY3QudG9wICsgJ3B4JztcclxuICAgIGhpZ2hsaWdodC5zdHlsZS53aWR0aCA9IHJlY3Qud2lkdGggKyAncHgnO1xyXG4gICAgaGlnaGxpZ2h0LnN0eWxlLmhlaWdodCA9IHJlY3QuaGVpZ2h0ICsgJ3B4JztcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG9uQ2xpY2soZTogTW91c2VFdmVudCkge1xyXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcblxyXG4gICAgaWYgKCFjdXJyZW50RWxlbWVudCkgcmV0dXJuO1xyXG4gICAgY29uc3QgaW5mbyA9IGdhdGhlckluZm8oY3VycmVudEVsZW1lbnQpO1xyXG4gICAgLy8gTWFyayBlbGVtZW50IHNvIENEUCBjYW4gZmluZCBpdCBmb3IgX2dlbmVyYXRlTG9jYXRvclN0cmluZygpXHJcbiAgICBjb25zdCBwaWNrSWQgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyKTtcclxuICAgIGN1cnJlbnRFbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1wdy1waWNrLWlkJywgcGlja0lkKTtcclxuICAgIGNsZWFudXAoKTtcclxuICAgIGNocm9tZS5ydW50aW1lLnNlbmRNZXNzYWdlKHsgdHlwZTogJ2VsZW1lbnQtcGlja2VkLXJhdycsIHBpY2tJZCwgaW5mbyB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG9uS2V5RG93bihlOiBLZXlib2FyZEV2ZW50KSB7XHJcbiAgICBpZiAoZS5rZXkgPT09ICdFc2NhcGUnKSB7XHJcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgY2xlYW51cCgpO1xyXG4gICAgICAgIGNocm9tZS5ydW50aW1lLnNlbmRNZXNzYWdlKHsgdHlwZTogJ3BpY2stY2FuY2VsbGVkJyB9KTtcclxuICAgIH1cclxufVxyXG5cclxuLy8gXHUyNTAwXHUyNTAwXHUyNTAwIExpZmVjeWNsZSBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjbGVhbnVwKCkge1xyXG4gICAgKHdpbmRvdyBhcyBhbnkpLl9fcHdfcGlja2VyX2FjdGl2ZSA9IGZhbHNlO1xyXG4gICAgY3VycmVudEVsZW1lbnQgPSBudWxsO1xyXG4gICAgaGlnaGxpZ2h0LnJlbW92ZSgpO1xyXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgb25Nb3VzZU1vdmUsIHRydWUpO1xyXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBvbkNsaWNrLCB0cnVlKTtcclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBvbktleURvd24sIHRydWUpO1xyXG4gICAgY2hyb21lLnJ1bnRpbWUub25NZXNzYWdlLnJlbW92ZUxpc3RlbmVyKG9uTWVzc2FnZSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG9uTWVzc2FnZShtc2c6IGFueSkge1xyXG4gICAgaWYgKG1zZy50eXBlID09PSAncGljay1zdG9wJykgY2xlYW51cCgpO1xyXG59XHJcblxyXG4vLyBcdTI1MDBcdTI1MDBcdTI1MDAgSW5pdCBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBpbml0KCkge1xyXG4gICAgLy8gR3VhcmQgYWdhaW5zdCBkb3VibGUtaW5qZWN0aW9uXHJcbiAgICBpZiAoKHdpbmRvdyBhcyBhbnkpLl9fcHdfcGlja2VyX2FjdGl2ZSkgcmV0dXJuO1xyXG4gICAgKHdpbmRvdyBhcyBhbnkpLl9fcHdfcGlja2VyX2FjdGl2ZSA9IHRydWU7XHJcblxyXG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKGhpZ2hsaWdodCk7XHJcblxyXG4gICAgY2hyb21lLnJ1bnRpbWUub25NZXNzYWdlLmFkZExpc3RlbmVyKG9uTWVzc2FnZSk7XHJcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBvbk1vdXNlTW92ZSwgdHJ1ZSk7XHJcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIG9uQ2xpY2ssIHRydWUpO1xyXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5RG93biwg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