@hanzo/browser-extension 1.7.2

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 (134) hide show
  1. package/.github/workflows/docs.yml +44 -0
  2. package/.github/workflows/release.yml +55 -0
  3. package/LICENSE +21 -0
  4. package/README.md +126 -0
  5. package/dist/browser-extension/README.md +43 -0
  6. package/dist/browser-extension/ai-worker.js +30 -0
  7. package/dist/browser-extension/background-firefox.js +617 -0
  8. package/dist/browser-extension/background.js +2737 -0
  9. package/dist/browser-extension/browser-control.js +683 -0
  10. package/dist/browser-extension/cdp-bridge-server.js +444 -0
  11. package/dist/browser-extension/chrome/ai-worker.js +571 -0
  12. package/dist/browser-extension/chrome/background.js +2737 -0
  13. package/dist/browser-extension/chrome/callback.html +17 -0
  14. package/dist/browser-extension/chrome/content-script.js +1270 -0
  15. package/dist/browser-extension/chrome/icon128.png +0 -0
  16. package/dist/browser-extension/chrome/icon16.png +0 -0
  17. package/dist/browser-extension/chrome/icon32.png +0 -0
  18. package/dist/browser-extension/chrome/icon48.png +0 -0
  19. package/dist/browser-extension/chrome/manifest.json +57 -0
  20. package/dist/browser-extension/chrome/popup.css +519 -0
  21. package/dist/browser-extension/chrome/popup.html +242 -0
  22. package/dist/browser-extension/chrome/popup.js +267 -0
  23. package/dist/browser-extension/chrome/sidebar.css +1176 -0
  24. package/dist/browser-extension/chrome/sidebar.html +280 -0
  25. package/dist/browser-extension/chrome/sidebar.js +778 -0
  26. package/dist/browser-extension/cli.js +233 -0
  27. package/dist/browser-extension/content-script.js +1270 -0
  28. package/dist/browser-extension/firefox/ai-worker.js +571 -0
  29. package/dist/browser-extension/firefox/background.js +617 -0
  30. package/dist/browser-extension/firefox/callback.html +17 -0
  31. package/dist/browser-extension/firefox/content-script.js +1270 -0
  32. package/dist/browser-extension/firefox/icon128.png +0 -0
  33. package/dist/browser-extension/firefox/icon16.png +0 -0
  34. package/dist/browser-extension/firefox/icon32.png +0 -0
  35. package/dist/browser-extension/firefox/icon48.png +0 -0
  36. package/dist/browser-extension/firefox/manifest.json +66 -0
  37. package/dist/browser-extension/firefox/popup.css +519 -0
  38. package/dist/browser-extension/firefox/popup.html +242 -0
  39. package/dist/browser-extension/firefox/popup.js +267 -0
  40. package/dist/browser-extension/firefox/sidebar.css +1176 -0
  41. package/dist/browser-extension/firefox/sidebar.html +280 -0
  42. package/dist/browser-extension/firefox/sidebar.js +778 -0
  43. package/dist/browser-extension/hanzo-browser-extension-firefox-1.1.0.zip +0 -0
  44. package/dist/browser-extension/icon128.png +0 -0
  45. package/dist/browser-extension/icon16.png +0 -0
  46. package/dist/browser-extension/icon32.png +0 -0
  47. package/dist/browser-extension/icon48.png +0 -0
  48. package/dist/browser-extension/manifest.json +57 -0
  49. package/dist/browser-extension/package.json +41 -0
  50. package/dist/browser-extension/popup.css +468 -0
  51. package/dist/browser-extension/popup.html +191 -0
  52. package/dist/browser-extension/popup.js +267 -0
  53. package/dist/browser-extension/safari/Info.plist +21 -0
  54. package/dist/browser-extension/safari/ai-worker.js +571 -0
  55. package/dist/browser-extension/safari/background.js +2737 -0
  56. package/dist/browser-extension/safari/callback.html +17 -0
  57. package/dist/browser-extension/safari/content-script.js +1270 -0
  58. package/dist/browser-extension/safari/icon128.png +0 -0
  59. package/dist/browser-extension/safari/icon16.png +0 -0
  60. package/dist/browser-extension/safari/icon32.png +0 -0
  61. package/dist/browser-extension/safari/icon48.png +0 -0
  62. package/dist/browser-extension/safari/popup.css +519 -0
  63. package/dist/browser-extension/safari/popup.html +242 -0
  64. package/dist/browser-extension/safari/popup.js +267 -0
  65. package/dist/browser-extension/safari/sidebar.css +1176 -0
  66. package/dist/browser-extension/safari/sidebar.html +280 -0
  67. package/dist/browser-extension/safari/sidebar.js +778 -0
  68. package/dist/browser-extension/sidebar.css +718 -0
  69. package/dist/browser-extension/sidebar.html +184 -0
  70. package/dist/browser-extension/sidebar.js +778 -0
  71. package/dist/browser-extension/webgpu-ai.js +495 -0
  72. package/dist/cdp-bridge-server.js +411 -0
  73. package/dist/safari/Hanzo AI/Hanzo AI.xcodeproj/project.pbxproj +1047 -0
  74. package/dist/safari/Hanzo AI/Hanzo AI.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  75. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  76. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/Contents.json +98 -0
  77. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-128@1x.png +0 -0
  78. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-128@2x.png +0 -0
  79. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-16@1x.png +0 -0
  80. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-16@2x.png +0 -0
  81. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-256@1x.png +0 -0
  82. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-256@2x.png +0 -0
  83. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-32@1x.png +0 -0
  84. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-32@2x.png +0 -0
  85. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-512@1x.png +0 -0
  86. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-512@2x.png +0 -0
  87. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/universal-icon-1024@1x.png +0 -0
  88. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/Contents.json +6 -0
  89. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/LargeIcon.imageset/Contents.json +21 -0
  90. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/LargeIcon.imageset/icon128.png +0 -0
  91. package/dist/safari/Hanzo AI/Shared (App)/Resources/Base.lproj/Main.html +20 -0
  92. package/dist/safari/Hanzo AI/Shared (App)/Resources/Icon.png +0 -0
  93. package/dist/safari/Hanzo AI/Shared (App)/Resources/Script.js +24 -0
  94. package/dist/safari/Hanzo AI/Shared (App)/Resources/Style.css +61 -0
  95. package/dist/safari/Hanzo AI/Shared (App)/ViewController.swift +81 -0
  96. package/dist/safari/Hanzo AI/Shared (Extension)/SafariWebExtensionHandler.swift +42 -0
  97. package/dist/safari/Hanzo AI/iOS (App)/AppDelegate.swift +24 -0
  98. package/dist/safari/Hanzo AI/iOS (App)/Base.lproj/LaunchScreen.storyboard +36 -0
  99. package/dist/safari/Hanzo AI/iOS (App)/Base.lproj/Main.storyboard +38 -0
  100. package/dist/safari/Hanzo AI/iOS (App)/Info.plist +27 -0
  101. package/dist/safari/Hanzo AI/iOS (App)/SceneDelegate.swift +18 -0
  102. package/dist/safari/Hanzo AI/iOS (Extension)/Info.plist +13 -0
  103. package/dist/safari/Hanzo AI/macOS (App)/AppDelegate.swift +21 -0
  104. package/dist/safari/Hanzo AI/macOS (App)/Base.lproj/Main.storyboard +124 -0
  105. package/dist/safari/Hanzo AI/macOS (App)/Info.plist +8 -0
  106. package/dist/safari/Hanzo AI/macOS (Extension)/Info.plist +13 -0
  107. package/docs/_config.yml +13 -0
  108. package/docs/_layouts/default.html +435 -0
  109. package/docs/index.md +54 -0
  110. package/install-extension.sh +75 -0
  111. package/manifest.json +29 -0
  112. package/package.json +32 -0
  113. package/src/ai-worker.js +571 -0
  114. package/src/callback.html +17 -0
  115. package/src/chat-widget.tsx +93 -0
  116. package/src/icon128.png +0 -0
  117. package/src/icon16.png +0 -0
  118. package/src/icon32.png +0 -0
  119. package/src/icon48.png +0 -0
  120. package/src/manifest-firefox.json +66 -0
  121. package/src/manifest.json +57 -0
  122. package/src/package.json +41 -0
  123. package/src/popup.css +519 -0
  124. package/src/popup.html +242 -0
  125. package/src/popup.js +192 -0
  126. package/src/sidebar.css +1176 -0
  127. package/src/sidebar.html +280 -0
  128. package/src/sidebar.js +884 -0
  129. package/src/webgpu.d.ts +131 -0
  130. package/test/claude-integration.test.ts +251 -0
  131. package/test/server-frameworks-edge-cases.test.ts +145 -0
  132. package/test/server-frameworks.test.ts +395 -0
  133. package/test-cdp-connection.js +140 -0
  134. package/tsconfig.json +19 -0
@@ -0,0 +1,1270 @@
1
+ "use strict";
2
+ (() => {
3
+ // src/content-script.ts
4
+ var HanzoContentScript = class {
5
+ constructor() {
6
+ this.setupClickHandler();
7
+ this.injectHelpers();
8
+ this.setupMessageHandlers();
9
+ }
10
+ setupClickHandler() {
11
+ document.addEventListener("click", (e) => {
12
+ if (!e.altKey) return;
13
+ e.preventDefault();
14
+ e.stopPropagation();
15
+ const element = e.target;
16
+ const source = this.extractSourceLocation(element);
17
+ const domPath = this.getDOMPath(element);
18
+ const event = {
19
+ event: "elementSelected",
20
+ framework: this.detectFramework(),
21
+ domPath,
22
+ source,
23
+ fallbackId: element.getAttribute("data-hanzo-id") || void 0
24
+ };
25
+ chrome.runtime.sendMessage({ action: "elementSelected", data: event });
26
+ });
27
+ }
28
+ setupMessageHandlers() {
29
+ chrome.runtime.onMessage.addListener((request, _sender, sendResponse) => {
30
+ var _a;
31
+ switch (request.action) {
32
+ case "ai.control.start":
33
+ aiOverlay.show(request.task || "AI is controlling this page");
34
+ sendResponse({ success: true });
35
+ return true;
36
+ case "ai.control.stop":
37
+ aiOverlay.hide();
38
+ sendResponse({ success: true });
39
+ return true;
40
+ case "ai.control.cursor":
41
+ aiOverlay.moveCursor(request.x, request.y);
42
+ sendResponse({ success: true });
43
+ return true;
44
+ case "ai.control.highlight":
45
+ aiOverlay.highlight(request.selector);
46
+ sendResponse({ success: true });
47
+ return true;
48
+ case "ai.control.status":
49
+ aiOverlay.updateStatus(request.text);
50
+ sendResponse({ success: true });
51
+ return true;
52
+ case "page.overlay.toggle":
53
+ sendResponse({
54
+ success: true,
55
+ open: pageOverlay.toggle()
56
+ });
57
+ return true;
58
+ case "page.overlay.show":
59
+ pageOverlay.show();
60
+ sendResponse({ success: true, open: true });
61
+ return true;
62
+ case "page.overlay.hide":
63
+ pageOverlay.hide();
64
+ sendResponse({ success: true, open: false });
65
+ return true;
66
+ case "page.overlay.status":
67
+ sendResponse({ success: true, open: pageOverlay.isOpen() });
68
+ return true;
69
+ }
70
+ if (request.action === "getContent") {
71
+ sendResponse({ content: ((_a = document.documentElement) == null ? void 0 : _a.outerHTML) || "" });
72
+ return true;
73
+ }
74
+ if (request.action === "setContent") {
75
+ if (typeof request.content === "string") {
76
+ document.open();
77
+ document.write(request.content);
78
+ document.close();
79
+ }
80
+ sendResponse({ success: true });
81
+ return true;
82
+ }
83
+ return false;
84
+ });
85
+ }
86
+ extractSourceLocation(element) {
87
+ const framework = this.detectFramework();
88
+ switch (framework) {
89
+ case "react":
90
+ return this.extractReactSource(element);
91
+ case "vue":
92
+ return this.extractVueSource(element);
93
+ case "svelte":
94
+ return this.extractSvelteSource(element);
95
+ default:
96
+ return void 0;
97
+ }
98
+ }
99
+ extractReactSource(element) {
100
+ var _a, _b;
101
+ const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
102
+ if (!hook) return void 0;
103
+ const fiber = this.findReactFiber(element);
104
+ if (!fiber) return void 0;
105
+ const source = fiber._debugSource || ((_a = fiber.pendingProps) == null ? void 0 : _a.__source) || ((_b = fiber.memoizedProps) == null ? void 0 : _b.__source);
106
+ if (source && source.fileName) {
107
+ return {
108
+ file: source.fileName,
109
+ line: source.lineNumber,
110
+ column: source.columnNumber
111
+ };
112
+ }
113
+ return void 0;
114
+ }
115
+ findReactFiber(element) {
116
+ const key = Object.keys(element).find(
117
+ (candidate) => candidate.startsWith("__reactInternalInstance$") || candidate.startsWith("__reactFiber$")
118
+ );
119
+ return key ? element[key] : null;
120
+ }
121
+ extractVueSource(element) {
122
+ var _a, _b;
123
+ const hook = window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
124
+ if (!hook) return void 0;
125
+ let instance = element.__vueParentComponent;
126
+ if (!instance) {
127
+ instance = element.__vue__;
128
+ }
129
+ if ((_a = instance == null ? void 0 : instance.type) == null ? void 0 : _a.__file) {
130
+ const location2 = {
131
+ file: instance.type.__file,
132
+ line: 1
133
+ };
134
+ if ((_b = instance.vnode) == null ? void 0 : _b.loc) {
135
+ location2.line = instance.vnode.loc.start.line;
136
+ location2.column = instance.vnode.loc.start.column;
137
+ }
138
+ return location2;
139
+ }
140
+ return void 0;
141
+ }
142
+ extractSvelteSource(element) {
143
+ var _a, _b;
144
+ const component = element.__svelte_component;
145
+ if ((_b = (_a = component == null ? void 0 : component.$$) == null ? void 0 : _a.ctx) == null ? void 0 : _b.$$_location) {
146
+ return component.$$.ctx.$$_location;
147
+ }
148
+ return void 0;
149
+ }
150
+ detectFramework() {
151
+ if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) return "react";
152
+ if (window.__VUE_DEVTOOLS_GLOBAL_HOOK__) return "vue";
153
+ if (window.__svelte) return "svelte";
154
+ return null;
155
+ }
156
+ getDOMPath(element) {
157
+ const path = [];
158
+ let current = element;
159
+ while (current && current !== document.body) {
160
+ let selector = current.tagName.toLowerCase();
161
+ if (current.id) {
162
+ selector += `#${current.id}`;
163
+ } else if (current.className) {
164
+ selector += `.${current.className.split(" ").join(".")}`;
165
+ }
166
+ path.unshift(selector);
167
+ current = current.parentElement;
168
+ }
169
+ return path.join(" > ");
170
+ }
171
+ injectHelpers() {
172
+ const style = document.createElement("style");
173
+ style.textContent = `
174
+ [data-hanzo-hover] {
175
+ outline: 2px dashed #ff6b6b !important;
176
+ outline-offset: 2px !important;
177
+ }
178
+ `;
179
+ document.head.appendChild(style);
180
+ document.addEventListener("mousemove", (e) => {
181
+ document.querySelectorAll("[data-hanzo-hover]").forEach((el) => {
182
+ el.removeAttribute("data-hanzo-hover");
183
+ });
184
+ if (e.altKey && e.target instanceof HTMLElement) {
185
+ e.target.setAttribute("data-hanzo-hover", "true");
186
+ }
187
+ });
188
+ }
189
+ };
190
+ var aiOverlay = /* @__PURE__ */ (() => {
191
+ let overlay = null;
192
+ let cursor = null;
193
+ let statusEl = null;
194
+ let cancelBtn = null;
195
+ let highlightEl = null;
196
+ let trailNodes = [];
197
+ let interactionBlockActive = false;
198
+ const OVERLAY_ID = "hanzo-ai-overlay";
199
+ const STYLES_ID = "hanzo-ai-overlay-styles";
200
+ const BLOCKED_EVENTS = [
201
+ "click",
202
+ "dblclick",
203
+ "mousedown",
204
+ "mouseup",
205
+ "contextmenu",
206
+ "pointerdown",
207
+ "pointerup",
208
+ "touchstart",
209
+ "touchmove",
210
+ "touchend",
211
+ "wheel",
212
+ "keydown",
213
+ "keyup",
214
+ "keypress"
215
+ ];
216
+ function injectStyles() {
217
+ if (document.getElementById(STYLES_ID)) return;
218
+ const style = document.createElement("style");
219
+ style.id = STYLES_ID;
220
+ style.textContent = `
221
+ /* ---- Overlay backdrop ---- */
222
+ #${OVERLAY_ID} {
223
+ position: fixed;
224
+ inset: 0;
225
+ z-index: 2147483646;
226
+ pointer-events: all;
227
+ background:
228
+ radial-gradient(90vw 90vh at 15% 8%, rgba(56, 189, 248, 0.10), transparent 55%),
229
+ radial-gradient(65vw 65vh at 84% 82%, rgba(99, 102, 241, 0.10), transparent 60%),
230
+ rgba(2, 4, 10, 0.42);
231
+ backdrop-filter: blur(1.5px);
232
+ opacity: 0;
233
+ transition: opacity 300ms ease;
234
+ }
235
+ #${OVERLAY_ID}.hanzo-visible {
236
+ opacity: 1;
237
+ }
238
+
239
+ /* ---- Pulsing cyan glow cursor ---- */
240
+ .hanzo-ai-cursor {
241
+ position: fixed;
242
+ width: 24px;
243
+ height: 24px;
244
+ z-index: 2147483647;
245
+ pointer-events: none;
246
+ border-radius: 50%;
247
+ border: 2px solid rgba(6, 182, 212, 0.95);
248
+ box-shadow:
249
+ 0 0 8px 2px rgba(6, 182, 212, 0.45),
250
+ 0 0 24px 6px rgba(6, 182, 212, 0.18);
251
+ transform: translate(-50%, -50%);
252
+ transition: left 0.18s ease-out, top 0.18s ease-out;
253
+ animation: hanzo-cursor-pulse 1.6s ease-in-out infinite;
254
+ opacity: 0;
255
+ }
256
+ .hanzo-ai-cursor.hanzo-visible {
257
+ opacity: 1;
258
+ transition: left 0.18s ease-out, top 0.18s ease-out, opacity 300ms ease;
259
+ }
260
+ @keyframes hanzo-cursor-pulse {
261
+ 0%, 100% {
262
+ box-shadow:
263
+ 0 0 8px 2px rgba(6, 182, 212, 0.45),
264
+ 0 0 24px 6px rgba(6, 182, 212, 0.18);
265
+ }
266
+ 50% {
267
+ box-shadow:
268
+ 0 0 14px 4px rgba(6, 182, 212, 0.65),
269
+ 0 0 36px 10px rgba(6, 182, 212, 0.28);
270
+ }
271
+ }
272
+
273
+ /* ---- Cursor trail ---- */
274
+ .hanzo-cursor-trail {
275
+ position: fixed;
276
+ width: 6px;
277
+ height: 6px;
278
+ border-radius: 50%;
279
+ background: rgba(6, 182, 212, 0.7);
280
+ z-index: 2147483646;
281
+ pointer-events: none;
282
+ transform: translate(-50%, -50%);
283
+ animation: hanzo-trail-fade 0.4s ease-out forwards;
284
+ }
285
+ @keyframes hanzo-trail-fade {
286
+ from { opacity: 0.7; transform: translate(-50%, -50%) scale(1); }
287
+ to { opacity: 0; transform: translate(-50%, -50%) scale(0.15); }
288
+ }
289
+
290
+ /* ---- Status banner (top center pill) ---- */
291
+ .hanzo-ai-status {
292
+ position: fixed;
293
+ top: 16px;
294
+ left: 50%;
295
+ transform: translateX(-50%);
296
+ z-index: 2147483647;
297
+ display: flex;
298
+ align-items: center;
299
+ gap: 10px;
300
+ max-width: 90vw;
301
+ padding: 10px 14px;
302
+ border-radius: 16px;
303
+ background: linear-gradient(135deg, rgba(8, 12, 20, 0.94), rgba(10, 16, 24, 0.96));
304
+ border: 1px solid rgba(56, 189, 248, 0.26);
305
+ color: #f3f4f6;
306
+ font: 13px/1.4 -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
307
+ box-shadow:
308
+ 0 10px 36px rgba(0, 0, 0, 0.46),
309
+ inset 0 1px 0 rgba(255, 255, 255, 0.08);
310
+ opacity: 0;
311
+ transition: opacity 300ms ease;
312
+ overflow: hidden;
313
+ }
314
+ .hanzo-ai-status::before {
315
+ content: '';
316
+ position: absolute;
317
+ inset: -2px auto -2px -20%;
318
+ width: 40%;
319
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.16), transparent);
320
+ transform: skewX(-18deg);
321
+ animation: hanzo-status-sheen 3.6s ease-in-out infinite;
322
+ pointer-events: none;
323
+ }
324
+ @keyframes hanzo-status-sheen {
325
+ 0%, 68% { left: -30%; opacity: 0; }
326
+ 72% { opacity: 0.4; }
327
+ 100% { left: 130%; opacity: 0; }
328
+ }
329
+ .hanzo-ai-status > * {
330
+ position: relative;
331
+ }
332
+ .hanzo-ai-status.hanzo-visible {
333
+ opacity: 1;
334
+ }
335
+
336
+ .hanzo-ai-status .hanzo-brand-bubble {
337
+ display: inline-flex;
338
+ align-items: center;
339
+ justify-content: center;
340
+ height: 20px;
341
+ min-width: 30px;
342
+ padding: 0 8px;
343
+ border-radius: 9999px;
344
+ font-size: 10px;
345
+ letter-spacing: 0.25px;
346
+ font-weight: 700;
347
+ text-transform: uppercase;
348
+ color: #e0f2fe;
349
+ background: linear-gradient(180deg, rgba(14, 116, 144, 0.95), rgba(15, 23, 42, 0.95));
350
+ border: 1px solid rgba(56, 189, 248, 0.35);
351
+ }
352
+
353
+ .hanzo-ai-status .hanzo-pulse-dot {
354
+ width: 8px;
355
+ height: 8px;
356
+ border-radius: 9999px;
357
+ background: #06b6d4;
358
+ animation: hanzo-dot-pulse 1.4s ease-in-out infinite;
359
+ }
360
+ @keyframes hanzo-dot-pulse {
361
+ 0%, 100% { opacity: 1; }
362
+ 50% { opacity: 0.4; }
363
+ }
364
+
365
+ .hanzo-ai-status .hanzo-label {
366
+ max-width: 46vw;
367
+ overflow: hidden;
368
+ text-overflow: ellipsis;
369
+ white-space: nowrap;
370
+ }
371
+
372
+ .hanzo-ai-status .hanzo-dots::after {
373
+ content: '';
374
+ animation: hanzo-animated-dots 1.5s steps(4) infinite;
375
+ }
376
+ @keyframes hanzo-animated-dots {
377
+ 0% { content: ''; }
378
+ 25% { content: '.'; }
379
+ 50% { content: '..'; }
380
+ 75% { content: '...'; }
381
+ }
382
+
383
+ .hanzo-ai-status .hanzo-stop-btn {
384
+ border: 1px solid rgba(255, 255, 255, 0.24);
385
+ background: rgba(0, 0, 0, 0.18);
386
+ color: #f8fafc;
387
+ border-radius: 10px;
388
+ padding: 4px 12px;
389
+ font-size: 12px;
390
+ cursor: pointer;
391
+ transition: background 0.15s, border-color 0.15s;
392
+ }
393
+ .hanzo-ai-status .hanzo-stop-btn:hover {
394
+ background: rgba(220, 38, 38, 0.28);
395
+ border-color: rgba(248, 113, 113, 0.6);
396
+ }
397
+
398
+ /* ---- "Take Back Control" button (bottom-right) ---- */
399
+ .hanzo-ai-cancel {
400
+ position: fixed;
401
+ bottom: 24px;
402
+ right: 24px;
403
+ z-index: 2147483647;
404
+ padding: 12px 24px;
405
+ border-radius: 10px;
406
+ border: 1px solid rgba(255, 255, 255, 0.2);
407
+ background: rgba(15, 18, 24, 0.95);
408
+ color: #f3f4f6;
409
+ font: 600 14px/1.4 -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
410
+ cursor: pointer;
411
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
412
+ pointer-events: auto;
413
+ opacity: 0;
414
+ transition: opacity 300ms ease, background 0.15s;
415
+ }
416
+ .hanzo-ai-cancel.hanzo-visible {
417
+ opacity: 1;
418
+ }
419
+ .hanzo-ai-cancel:hover {
420
+ background: rgba(220, 38, 38, 0.35);
421
+ border-color: rgba(220, 38, 38, 0.5);
422
+ }
423
+
424
+ /* ---- Element highlight ---- */
425
+ .hanzo-ai-highlight {
426
+ position: fixed;
427
+ z-index: 2147483647;
428
+ pointer-events: none;
429
+ border: 2px solid rgba(6, 182, 212, 0.85);
430
+ border-radius: 6px;
431
+ box-shadow: 0 0 0 3px rgba(6, 182, 212, 0.15);
432
+ transition: left 0.15s, top 0.15s, width 0.15s, height 0.15s;
433
+ }
434
+ `;
435
+ document.head.appendChild(style);
436
+ }
437
+ function isOverlayElement(target) {
438
+ if (!(target instanceof Node)) return false;
439
+ return !!((overlay == null ? void 0 : overlay.contains(target)) || (statusEl == null ? void 0 : statusEl.contains(target)) || (cancelBtn == null ? void 0 : cancelBtn.contains(target)) || (cursor == null ? void 0 : cursor.contains(target)) || (highlightEl == null ? void 0 : highlightEl.contains(target)));
440
+ }
441
+ function blockInteraction(event) {
442
+ if (!interactionBlockActive) return;
443
+ if (event instanceof KeyboardEvent && event.key === "Escape") {
444
+ chrome.runtime.sendMessage({ action: "ai.control.cancel" });
445
+ hide();
446
+ return;
447
+ }
448
+ if (isOverlayElement(event.target)) return;
449
+ event.preventDefault();
450
+ event.stopPropagation();
451
+ event.stopImmediatePropagation();
452
+ }
453
+ function setInteractionBlock(active) {
454
+ if (interactionBlockActive === active) return;
455
+ interactionBlockActive = active;
456
+ for (const eventName of BLOCKED_EVENTS) {
457
+ if (active) {
458
+ document.addEventListener(eventName, blockInteraction, true);
459
+ } else {
460
+ document.removeEventListener(eventName, blockInteraction, true);
461
+ }
462
+ }
463
+ }
464
+ function show(task) {
465
+ var _a;
466
+ if (overlay) hide();
467
+ injectStyles();
468
+ setInteractionBlock(true);
469
+ overlay = document.createElement("div");
470
+ overlay.id = OVERLAY_ID;
471
+ document.body.appendChild(overlay);
472
+ cursor = document.createElement("div");
473
+ cursor.className = "hanzo-ai-cursor";
474
+ cursor.style.left = `${window.innerWidth / 2}px`;
475
+ cursor.style.top = `${window.innerHeight / 2}px`;
476
+ document.body.appendChild(cursor);
477
+ statusEl = document.createElement("div");
478
+ statusEl.className = "hanzo-ai-status";
479
+ statusEl.innerHTML = `
480
+ <span class="hanzo-brand-bubble">AI</span>
481
+ <div class="hanzo-pulse-dot"></div>
482
+ <span class="hanzo-label">${escapeHtml(task || "Hanzo AI is controlling this tab")}</span><span class="hanzo-dots"></span>
483
+ <button class="hanzo-stop-btn">Stop</button>
484
+ `;
485
+ document.body.appendChild(statusEl);
486
+ (_a = statusEl.querySelector(".hanzo-stop-btn")) == null ? void 0 : _a.addEventListener("click", () => {
487
+ chrome.runtime.sendMessage({ action: "ai.control.cancel" });
488
+ hide();
489
+ });
490
+ cancelBtn = document.createElement("button");
491
+ cancelBtn.className = "hanzo-ai-cancel";
492
+ cancelBtn.textContent = "Take Back Control";
493
+ cancelBtn.addEventListener("click", () => {
494
+ chrome.runtime.sendMessage({ action: "ai.control.cancel" });
495
+ hide();
496
+ });
497
+ document.body.appendChild(cancelBtn);
498
+ requestAnimationFrame(() => {
499
+ overlay == null ? void 0 : overlay.classList.add("hanzo-visible");
500
+ cursor == null ? void 0 : cursor.classList.add("hanzo-visible");
501
+ statusEl == null ? void 0 : statusEl.classList.add("hanzo-visible");
502
+ cancelBtn == null ? void 0 : cancelBtn.classList.add("hanzo-visible");
503
+ });
504
+ }
505
+ function hide() {
506
+ overlay == null ? void 0 : overlay.classList.remove("hanzo-visible");
507
+ cursor == null ? void 0 : cursor.classList.remove("hanzo-visible");
508
+ statusEl == null ? void 0 : statusEl.classList.remove("hanzo-visible");
509
+ cancelBtn == null ? void 0 : cancelBtn.classList.remove("hanzo-visible");
510
+ const refs = { overlay, cursor, statusEl, cancelBtn, highlightEl };
511
+ const trails = [...trailNodes];
512
+ setTimeout(() => {
513
+ var _a, _b, _c, _d, _e;
514
+ (_a = refs.overlay) == null ? void 0 : _a.remove();
515
+ (_b = refs.cursor) == null ? void 0 : _b.remove();
516
+ (_c = refs.statusEl) == null ? void 0 : _c.remove();
517
+ (_d = refs.cancelBtn) == null ? void 0 : _d.remove();
518
+ (_e = refs.highlightEl) == null ? void 0 : _e.remove();
519
+ for (const node of trails) {
520
+ node.remove();
521
+ }
522
+ }, 320);
523
+ setInteractionBlock(false);
524
+ overlay = null;
525
+ cursor = null;
526
+ statusEl = null;
527
+ cancelBtn = null;
528
+ highlightEl = null;
529
+ trailNodes = [];
530
+ }
531
+ function moveCursor(x, y) {
532
+ var _a;
533
+ if (!cursor) return;
534
+ const clampedX = Math.max(0, Math.min(window.innerWidth, Number.isFinite(x) ? x : 0));
535
+ const clampedY = Math.max(0, Math.min(window.innerHeight, Number.isFinite(y) ? y : 0));
536
+ const trail = document.createElement("div");
537
+ trail.className = "hanzo-cursor-trail";
538
+ trail.style.left = `${clampedX}px`;
539
+ trail.style.top = `${clampedY}px`;
540
+ document.body.appendChild(trail);
541
+ trailNodes.push(trail);
542
+ setTimeout(() => {
543
+ trail.remove();
544
+ trailNodes = trailNodes.filter((node) => node !== trail);
545
+ }, 400);
546
+ while (trailNodes.length > 10) {
547
+ (_a = trailNodes.shift()) == null ? void 0 : _a.remove();
548
+ }
549
+ cursor.style.left = `${clampedX}px`;
550
+ cursor.style.top = `${clampedY}px`;
551
+ }
552
+ function highlight(selector) {
553
+ highlightEl == null ? void 0 : highlightEl.remove();
554
+ highlightEl = null;
555
+ if (!selector || typeof selector !== "string") return;
556
+ try {
557
+ const target = document.querySelector(selector);
558
+ if (!target) return;
559
+ const rect = target.getBoundingClientRect();
560
+ if (rect.width === 0 && rect.height === 0) return;
561
+ highlightEl = document.createElement("div");
562
+ highlightEl.className = "hanzo-ai-highlight";
563
+ highlightEl.style.left = `${Math.max(0, rect.left - 4)}px`;
564
+ highlightEl.style.top = `${Math.max(0, rect.top - 4)}px`;
565
+ highlightEl.style.width = `${rect.width + 8}px`;
566
+ highlightEl.style.height = `${rect.height + 8}px`;
567
+ document.body.appendChild(highlightEl);
568
+ } catch {
569
+ }
570
+ }
571
+ function updateStatus(text) {
572
+ if (!statusEl) return;
573
+ const label = statusEl.querySelector(".hanzo-label");
574
+ if (label) {
575
+ label.textContent = text || "Hanzo AI is controlling this tab";
576
+ }
577
+ }
578
+ function escapeHtml(text) {
579
+ const div = document.createElement("div");
580
+ div.textContent = text;
581
+ return div.innerHTML;
582
+ }
583
+ return { show, hide, moveCursor, highlight, updateStatus };
584
+ })();
585
+ var HanzoPageOverlay = class {
586
+ constructor() {
587
+ this.mounted = false;
588
+ this.enabled = false;
589
+ this.open = false;
590
+ this.sending = false;
591
+ this.watchMode = false;
592
+ this.editMode = false;
593
+ this.modelsLoaded = false;
594
+ this.messages = [];
595
+ this.selectedContext = null;
596
+ this.hoveredElement = null;
597
+ this.editingElement = null;
598
+ this.root = null;
599
+ this.launcher = null;
600
+ this.panel = null;
601
+ this.messagesEl = null;
602
+ this.inputEl = null;
603
+ this.sendBtn = null;
604
+ this.modelEl = null;
605
+ this.contextEl = null;
606
+ this.watchBtn = null;
607
+ this.editBtn = null;
608
+ this.statusEl = null;
609
+ this.highlightBox = null;
610
+ this.injectStyles();
611
+ this.mount();
612
+ this.bindGlobalEvents();
613
+ }
614
+ toggle() {
615
+ if (!this.enabled || !this.open) {
616
+ this.show();
617
+ return true;
618
+ }
619
+ this.hide();
620
+ return false;
621
+ }
622
+ show() {
623
+ var _a, _b;
624
+ this.ensureMounted();
625
+ this.enabled = true;
626
+ this.open = true;
627
+ (_a = this.root) == null ? void 0 : _a.setAttribute("data-enabled", "true");
628
+ (_b = this.root) == null ? void 0 : _b.setAttribute("data-open", "true");
629
+ this.loadModels();
630
+ this.focusInput();
631
+ }
632
+ hide() {
633
+ var _a;
634
+ this.open = false;
635
+ (_a = this.root) == null ? void 0 : _a.setAttribute("data-open", "false");
636
+ this.updateStatus("");
637
+ this.clearHighlight();
638
+ this.setWatchMode(false);
639
+ this.setEditMode(false);
640
+ }
641
+ isOpen() {
642
+ return this.open;
643
+ }
644
+ ensureMounted() {
645
+ if (this.mounted) return;
646
+ this.mount();
647
+ }
648
+ injectStyles() {
649
+ if (document.getElementById("hanzo-page-overlay-styles")) return;
650
+ const style = document.createElement("style");
651
+ style.id = "hanzo-page-overlay-styles";
652
+ style.textContent = `
653
+ #hanzo-page-overlay-root {
654
+ position: fixed;
655
+ right: 20px;
656
+ bottom: 20px;
657
+ z-index: 2147483645;
658
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
659
+ pointer-events: none;
660
+ }
661
+
662
+ #hanzo-page-overlay-root * {
663
+ box-sizing: border-box;
664
+ }
665
+
666
+ #hanzo-page-overlay-root[data-enabled="false"] .hanzo-page-launcher {
667
+ opacity: 0;
668
+ transform: translateY(16px);
669
+ pointer-events: none;
670
+ }
671
+
672
+ .hanzo-page-launcher {
673
+ width: 54px;
674
+ height: 54px;
675
+ border-radius: 9999px;
676
+ border: 1px solid rgba(255, 255, 255, 0.2);
677
+ background: linear-gradient(135deg, rgba(22, 24, 31, 0.96), rgba(7, 8, 12, 0.96));
678
+ color: #ffffff;
679
+ box-shadow: 0 14px 34px rgba(0, 0, 0, 0.35);
680
+ display: flex;
681
+ align-items: center;
682
+ justify-content: center;
683
+ cursor: pointer;
684
+ pointer-events: auto;
685
+ transition: transform 0.2s ease, opacity 0.2s ease;
686
+ }
687
+
688
+ .hanzo-page-launcher:hover {
689
+ transform: translateY(-2px);
690
+ }
691
+
692
+ .hanzo-page-panel {
693
+ width: min(420px, calc(100vw - 24px));
694
+ max-height: min(620px, calc(100vh - 28px));
695
+ border-radius: 16px;
696
+ border: 1px solid rgba(255, 255, 255, 0.16);
697
+ background: linear-gradient(180deg, rgba(11, 13, 18, 0.97), rgba(7, 8, 12, 0.97));
698
+ color: #eef2ff;
699
+ overflow: hidden;
700
+ box-shadow: 0 22px 48px rgba(0, 0, 0, 0.45);
701
+ transform-origin: bottom right;
702
+ transform: translateY(8px) scale(0.98);
703
+ opacity: 0;
704
+ pointer-events: none;
705
+ display: flex;
706
+ flex-direction: column;
707
+ margin-bottom: 10px;
708
+ transition: transform 0.18s ease, opacity 0.18s ease;
709
+ }
710
+
711
+ #hanzo-page-overlay-root[data-open="true"] .hanzo-page-panel {
712
+ transform: translateY(0) scale(1);
713
+ opacity: 1;
714
+ pointer-events: auto;
715
+ }
716
+
717
+ #hanzo-page-overlay-root[data-open="true"] .hanzo-page-launcher {
718
+ opacity: 0;
719
+ transform: scale(0.9);
720
+ pointer-events: none;
721
+ }
722
+
723
+ .hanzo-page-header {
724
+ display: flex;
725
+ align-items: center;
726
+ justify-content: space-between;
727
+ padding: 12px 14px;
728
+ border-bottom: 1px solid rgba(255, 255, 255, 0.12);
729
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent);
730
+ }
731
+
732
+ .hanzo-page-brand {
733
+ font-weight: 700;
734
+ letter-spacing: 0.2px;
735
+ font-size: 13px;
736
+ }
737
+
738
+ .hanzo-page-header-actions {
739
+ display: inline-flex;
740
+ align-items: center;
741
+ gap: 6px;
742
+ }
743
+
744
+ .hanzo-chip-btn {
745
+ border: 1px solid rgba(255, 255, 255, 0.2);
746
+ border-radius: 9999px;
747
+ padding: 4px 10px;
748
+ background: rgba(255, 255, 255, 0.02);
749
+ color: #d6deff;
750
+ cursor: pointer;
751
+ font-size: 11px;
752
+ }
753
+
754
+ .hanzo-chip-btn[data-active="true"] {
755
+ border-color: rgba(56, 189, 248, 0.62);
756
+ background: rgba(14, 116, 144, 0.3);
757
+ color: #e0f2fe;
758
+ }
759
+
760
+ .hanzo-icon-btn {
761
+ width: 28px;
762
+ height: 28px;
763
+ border-radius: 8px;
764
+ border: 1px solid rgba(255, 255, 255, 0.18);
765
+ background: transparent;
766
+ color: #e5e7eb;
767
+ cursor: pointer;
768
+ font-size: 16px;
769
+ }
770
+
771
+ .hanzo-page-meta {
772
+ padding: 10px 14px 6px 14px;
773
+ display: grid;
774
+ grid-template-columns: 1fr auto;
775
+ gap: 8px;
776
+ align-items: center;
777
+ }
778
+
779
+ .hanzo-page-context {
780
+ font-size: 11px;
781
+ color: #a5b4fc;
782
+ overflow: hidden;
783
+ text-overflow: ellipsis;
784
+ white-space: nowrap;
785
+ }
786
+
787
+ .hanzo-page-status {
788
+ font-size: 11px;
789
+ color: #93c5fd;
790
+ }
791
+
792
+ .hanzo-model-row {
793
+ padding: 0 14px 8px 14px;
794
+ }
795
+
796
+ .hanzo-model-row select {
797
+ width: 100%;
798
+ border-radius: 8px;
799
+ border: 1px solid rgba(255, 255, 255, 0.16);
800
+ background: rgba(255, 255, 255, 0.03);
801
+ color: #f1f5f9;
802
+ padding: 7px 9px;
803
+ font-size: 12px;
804
+ }
805
+
806
+ .hanzo-page-messages {
807
+ flex: 1;
808
+ min-height: 200px;
809
+ max-height: 370px;
810
+ overflow-y: auto;
811
+ padding: 8px 14px 12px 14px;
812
+ display: flex;
813
+ flex-direction: column;
814
+ gap: 8px;
815
+ }
816
+
817
+ .hanzo-page-msg {
818
+ padding: 9px 10px;
819
+ border-radius: 10px;
820
+ font-size: 12px;
821
+ line-height: 1.45;
822
+ word-break: break-word;
823
+ }
824
+
825
+ .hanzo-page-msg.user {
826
+ align-self: flex-end;
827
+ max-width: 88%;
828
+ background: rgba(59, 130, 246, 0.2);
829
+ border: 1px solid rgba(59, 130, 246, 0.4);
830
+ }
831
+
832
+ .hanzo-page-msg.assistant {
833
+ align-self: flex-start;
834
+ max-width: 92%;
835
+ background: rgba(255, 255, 255, 0.05);
836
+ border: 1px solid rgba(255, 255, 255, 0.12);
837
+ }
838
+
839
+ .hanzo-page-composer {
840
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
841
+ padding: 10px 12px;
842
+ display: flex;
843
+ gap: 8px;
844
+ align-items: flex-end;
845
+ }
846
+
847
+ .hanzo-page-composer textarea {
848
+ flex: 1;
849
+ min-height: 38px;
850
+ max-height: 110px;
851
+ resize: none;
852
+ border-radius: 10px;
853
+ border: 1px solid rgba(255, 255, 255, 0.17);
854
+ background: rgba(255, 255, 255, 0.03);
855
+ color: #f8fafc;
856
+ padding: 9px 11px;
857
+ font-size: 12px;
858
+ }
859
+
860
+ .hanzo-page-composer button {
861
+ min-width: 68px;
862
+ height: 38px;
863
+ border-radius: 10px;
864
+ border: 1px solid rgba(37, 99, 235, 0.65);
865
+ background: linear-gradient(180deg, rgba(37, 99, 235, 0.95), rgba(30, 64, 175, 0.95));
866
+ color: #eff6ff;
867
+ font-weight: 600;
868
+ font-size: 12px;
869
+ cursor: pointer;
870
+ }
871
+
872
+ .hanzo-page-composer button:disabled {
873
+ opacity: 0.55;
874
+ cursor: default;
875
+ }
876
+
877
+ .hanzo-page-highlight {
878
+ position: fixed;
879
+ z-index: 2147483644;
880
+ pointer-events: none;
881
+ border: 2px solid rgba(56, 189, 248, 0.95);
882
+ border-radius: 6px;
883
+ box-shadow: 0 0 0 2px rgba(14, 116, 144, 0.2);
884
+ }
885
+
886
+ [data-hanzo-inline-editing="true"] {
887
+ outline: 2px solid rgba(251, 191, 36, 0.92) !important;
888
+ outline-offset: 2px !important;
889
+ }
890
+ `;
891
+ document.head.appendChild(style);
892
+ }
893
+ mount() {
894
+ var _a, _b, _c, _d, _e, _f, _g;
895
+ if (this.mounted) return;
896
+ this.root = document.createElement("div");
897
+ this.root.id = "hanzo-page-overlay-root";
898
+ this.root.setAttribute("data-open", "false");
899
+ this.root.setAttribute("data-enabled", "false");
900
+ this.root.innerHTML = `
901
+ <div class="hanzo-page-panel" role="dialog" aria-label="Hanzo Page Assistant">
902
+ <div class="hanzo-page-header">
903
+ <div class="hanzo-page-brand">Hanzo Overlay</div>
904
+ <div class="hanzo-page-header-actions">
905
+ <button class="hanzo-chip-btn" data-role="watch" data-active="false" title="Watch elements on hover">Watch</button>
906
+ <button class="hanzo-chip-btn" data-role="edit" data-active="false" title="Click any element to edit text">Edit</button>
907
+ <button class="hanzo-icon-btn" data-role="close" title="Minimize">\xD7</button>
908
+ </div>
909
+ </div>
910
+ <div class="hanzo-page-meta">
911
+ <div class="hanzo-page-context">Use Watch to inspect page elements.</div>
912
+ <span class="hanzo-page-status"></span>
913
+ </div>
914
+ <div class="hanzo-model-row">
915
+ <select data-role="model">
916
+ <option value="claude-sonnet-4-20250514">Claude Sonnet 4</option>
917
+ <option value="claude-opus-4-20250514">Claude Opus 4</option>
918
+ <option value="gpt-4o">GPT-4o</option>
919
+ <option value="zen-coder-flash">Zen Coder Flash</option>
920
+ <option value="zen-max">Zen Max</option>
921
+ </select>
922
+ </div>
923
+ <div class="hanzo-page-messages" data-role="messages">
924
+ <div class="hanzo-page-msg assistant">Ask about this page, inspect any element, or turn on Edit mode to change text in-place.</div>
925
+ </div>
926
+ <div class="hanzo-page-composer">
927
+ <textarea data-role="input" rows="1" placeholder="Ask about this page..."></textarea>
928
+ <button data-role="send" type="button">Ask</button>
929
+ </div>
930
+ </div>
931
+ <button class="hanzo-page-launcher" data-role="launcher" type="button" title="Open Hanzo Overlay">AI</button>
932
+ `;
933
+ this.panel = this.root.querySelector(".hanzo-page-panel");
934
+ this.launcher = this.root.querySelector('[data-role="launcher"]');
935
+ this.messagesEl = this.root.querySelector('[data-role="messages"]');
936
+ this.inputEl = this.root.querySelector('[data-role="input"]');
937
+ this.sendBtn = this.root.querySelector('[data-role="send"]');
938
+ this.modelEl = this.root.querySelector('[data-role="model"]');
939
+ this.contextEl = this.root.querySelector(".hanzo-page-context");
940
+ this.watchBtn = this.root.querySelector('[data-role="watch"]');
941
+ this.editBtn = this.root.querySelector('[data-role="edit"]');
942
+ this.statusEl = this.root.querySelector(".hanzo-page-status");
943
+ (_a = this.launcher) == null ? void 0 : _a.addEventListener("click", () => this.show());
944
+ (_b = this.root.querySelector('[data-role="close"]')) == null ? void 0 : _b.addEventListener("click", () => this.hide());
945
+ (_c = this.watchBtn) == null ? void 0 : _c.addEventListener("click", () => this.setWatchMode(!this.watchMode));
946
+ (_d = this.editBtn) == null ? void 0 : _d.addEventListener("click", () => this.setEditMode(!this.editMode));
947
+ (_e = this.sendBtn) == null ? void 0 : _e.addEventListener("click", () => this.askPageQuestion());
948
+ (_f = this.inputEl) == null ? void 0 : _f.addEventListener("keydown", (event) => {
949
+ if (event.key === "Enter" && !event.shiftKey) {
950
+ event.preventDefault();
951
+ this.askPageQuestion();
952
+ }
953
+ });
954
+ (_g = this.inputEl) == null ? void 0 : _g.addEventListener("input", () => {
955
+ if (!this.inputEl) return;
956
+ this.inputEl.style.height = "auto";
957
+ this.inputEl.style.height = `${Math.min(this.inputEl.scrollHeight, 110)}px`;
958
+ });
959
+ document.documentElement.appendChild(this.root);
960
+ this.mounted = true;
961
+ }
962
+ bindGlobalEvents() {
963
+ document.addEventListener("mousemove", (event) => this.onMouseMove(event), true);
964
+ document.addEventListener("click", (event) => this.onDocumentClick(event), true);
965
+ document.addEventListener("keydown", (event) => this.onKeyDown(event), true);
966
+ }
967
+ onMouseMove(event) {
968
+ if (!this.watchMode) return;
969
+ const target = this.getPageTarget(event.target);
970
+ if (!target) return;
971
+ this.hoveredElement = target;
972
+ this.showHighlight(target);
973
+ if (!this.selectedContext) {
974
+ this.contextEl && (this.contextEl.textContent = this.getElementSummary(target));
975
+ }
976
+ }
977
+ onDocumentClick(event) {
978
+ if (!this.watchMode && !this.editMode) return;
979
+ const target = this.getPageTarget(event.target);
980
+ if (!target) return;
981
+ event.preventDefault();
982
+ event.stopPropagation();
983
+ event.stopImmediatePropagation();
984
+ if (this.watchMode) {
985
+ this.selectedContext = this.captureElementContext(target);
986
+ this.contextEl && (this.contextEl.textContent = this.getElementSummary(target));
987
+ this.updateStatus("Element selected");
988
+ }
989
+ if (this.editMode) {
990
+ this.enableInlineEdit(target);
991
+ this.updateStatus("Editing element");
992
+ }
993
+ }
994
+ onKeyDown(event) {
995
+ if (event.key === "Escape") {
996
+ if (this.editingElement) {
997
+ this.disableInlineEdit(this.editingElement, false);
998
+ this.updateStatus("Edit canceled");
999
+ event.preventDefault();
1000
+ return;
1001
+ }
1002
+ if (this.open) {
1003
+ this.hide();
1004
+ event.preventDefault();
1005
+ }
1006
+ }
1007
+ }
1008
+ getPageTarget(target) {
1009
+ var _a;
1010
+ if (!(target instanceof HTMLElement)) return null;
1011
+ if ((_a = this.root) == null ? void 0 : _a.contains(target)) return null;
1012
+ if (!target.isConnected) return null;
1013
+ if (target.tagName.toLowerCase() === "html" || target.tagName.toLowerCase() === "body") return null;
1014
+ return target;
1015
+ }
1016
+ setWatchMode(active) {
1017
+ var _a;
1018
+ this.watchMode = active;
1019
+ if (active) this.setEditMode(false);
1020
+ (_a = this.watchBtn) == null ? void 0 : _a.setAttribute("data-active", active ? "true" : "false");
1021
+ if (!active) {
1022
+ this.hoveredElement = null;
1023
+ this.clearHighlight();
1024
+ if (!this.selectedContext && this.contextEl) {
1025
+ this.contextEl.textContent = "Use Watch to inspect page elements.";
1026
+ }
1027
+ } else {
1028
+ this.updateStatus("Watch mode on");
1029
+ }
1030
+ }
1031
+ setEditMode(active) {
1032
+ var _a;
1033
+ this.editMode = active;
1034
+ if (active) this.setWatchMode(false);
1035
+ (_a = this.editBtn) == null ? void 0 : _a.setAttribute("data-active", active ? "true" : "false");
1036
+ if (!active && this.editingElement) {
1037
+ this.disableInlineEdit(this.editingElement, true);
1038
+ } else if (active) {
1039
+ this.updateStatus("Edit mode on");
1040
+ }
1041
+ }
1042
+ enableInlineEdit(element) {
1043
+ if (this.editingElement && this.editingElement !== element) {
1044
+ this.disableInlineEdit(this.editingElement, true);
1045
+ }
1046
+ if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
1047
+ element.focus();
1048
+ this.editingElement = element;
1049
+ return;
1050
+ }
1051
+ if (!element.hasAttribute("data-hanzo-original-html")) {
1052
+ element.setAttribute("data-hanzo-original-html", element.innerHTML);
1053
+ }
1054
+ element.setAttribute("contenteditable", "true");
1055
+ element.setAttribute("spellcheck", "true");
1056
+ element.setAttribute("data-hanzo-inline-editing", "true");
1057
+ element.focus();
1058
+ this.editingElement = element;
1059
+ const keydownHandler = (event) => {
1060
+ if (event.key === "Escape") {
1061
+ this.disableInlineEdit(element, false);
1062
+ this.updateStatus("Edit reverted");
1063
+ }
1064
+ if (event.key === "Enter" && !event.shiftKey) {
1065
+ event.preventDefault();
1066
+ this.disableInlineEdit(element, true);
1067
+ this.updateStatus("Edit applied");
1068
+ }
1069
+ };
1070
+ const blurHandler = () => {
1071
+ this.disableInlineEdit(element, true);
1072
+ this.updateStatus("Edit applied");
1073
+ };
1074
+ element.addEventListener("keydown", keydownHandler, { once: true });
1075
+ element.addEventListener("blur", blurHandler, { once: true });
1076
+ }
1077
+ disableInlineEdit(element, keepChanges) {
1078
+ if (!keepChanges) {
1079
+ const original = element.getAttribute("data-hanzo-original-html");
1080
+ if (original !== null) {
1081
+ element.innerHTML = original;
1082
+ }
1083
+ }
1084
+ element.removeAttribute("contenteditable");
1085
+ element.removeAttribute("spellcheck");
1086
+ element.removeAttribute("data-hanzo-inline-editing");
1087
+ element.removeAttribute("data-hanzo-original-html");
1088
+ if (this.editingElement === element) {
1089
+ this.editingElement = null;
1090
+ }
1091
+ }
1092
+ showHighlight(element) {
1093
+ const rect = element.getBoundingClientRect();
1094
+ if (rect.width === 0 && rect.height === 0) {
1095
+ this.clearHighlight();
1096
+ return;
1097
+ }
1098
+ if (!this.highlightBox) {
1099
+ this.highlightBox = document.createElement("div");
1100
+ this.highlightBox.className = "hanzo-page-highlight";
1101
+ document.documentElement.appendChild(this.highlightBox);
1102
+ }
1103
+ this.highlightBox.style.left = `${Math.max(0, rect.left - 3)}px`;
1104
+ this.highlightBox.style.top = `${Math.max(0, rect.top - 3)}px`;
1105
+ this.highlightBox.style.width = `${rect.width + 6}px`;
1106
+ this.highlightBox.style.height = `${rect.height + 6}px`;
1107
+ }
1108
+ clearHighlight() {
1109
+ var _a;
1110
+ (_a = this.highlightBox) == null ? void 0 : _a.remove();
1111
+ this.highlightBox = null;
1112
+ }
1113
+ captureElementContext(element) {
1114
+ const text = this.normalizeText(element.innerText || element.textContent || "");
1115
+ return {
1116
+ selector: this.buildSelector(element),
1117
+ tag: element.tagName.toLowerCase(),
1118
+ text: text.slice(0, 800),
1119
+ html: element.outerHTML.slice(0, 1200)
1120
+ };
1121
+ }
1122
+ buildSelector(element) {
1123
+ if (element.id) return `#${element.id}`;
1124
+ const parts = [];
1125
+ let current = element;
1126
+ let depth = 0;
1127
+ while (current && depth < 6) {
1128
+ let part = current.tagName.toLowerCase();
1129
+ if (current.classList.length > 0) {
1130
+ const className = Array.from(current.classList).slice(0, 2).join(".");
1131
+ if (className) part += `.${className}`;
1132
+ }
1133
+ const parent = current.parentElement;
1134
+ if (parent) {
1135
+ const siblings = Array.from(parent.children).filter((node) => node.tagName === current.tagName);
1136
+ if (siblings.length > 1) {
1137
+ const index = siblings.indexOf(current) + 1;
1138
+ part += `:nth-of-type(${index})`;
1139
+ }
1140
+ }
1141
+ parts.unshift(part);
1142
+ current = parent;
1143
+ depth += 1;
1144
+ }
1145
+ return parts.join(" > ");
1146
+ }
1147
+ normalizeText(value) {
1148
+ return value.replace(/\s+/g, " ").trim();
1149
+ }
1150
+ getElementSummary(element) {
1151
+ const ctx = this.captureElementContext(element);
1152
+ return `${ctx.tag} \u2022 ${ctx.selector}`;
1153
+ }
1154
+ async loadModels() {
1155
+ if (this.modelsLoaded || !this.modelEl) return;
1156
+ try {
1157
+ const response = await chrome.runtime.sendMessage({ action: "chat.listModels" });
1158
+ if (!(response == null ? void 0 : response.success) || !Array.isArray(response.models) || !response.models.length) {
1159
+ return;
1160
+ }
1161
+ const previous = this.modelEl.value;
1162
+ this.modelEl.innerHTML = "";
1163
+ for (const model of response.models) {
1164
+ if (!(model == null ? void 0 : model.id)) continue;
1165
+ const option = document.createElement("option");
1166
+ option.value = model.id;
1167
+ option.textContent = model.name || model.id;
1168
+ this.modelEl.appendChild(option);
1169
+ }
1170
+ if (previous && Array.from(this.modelEl.options).some((opt) => opt.value === previous)) {
1171
+ this.modelEl.value = previous;
1172
+ }
1173
+ this.modelsLoaded = true;
1174
+ } catch {
1175
+ }
1176
+ }
1177
+ focusInput() {
1178
+ if (!this.inputEl) return;
1179
+ this.inputEl.focus();
1180
+ }
1181
+ appendMessage(role, content) {
1182
+ if (!this.messagesEl) return;
1183
+ const div = document.createElement("div");
1184
+ div.className = `hanzo-page-msg ${role}`;
1185
+ div.textContent = content;
1186
+ this.messagesEl.appendChild(div);
1187
+ this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
1188
+ }
1189
+ updateStatus(text) {
1190
+ if (!this.statusEl) return;
1191
+ this.statusEl.textContent = text;
1192
+ }
1193
+ buildPageContext() {
1194
+ var _a, _b;
1195
+ const selection = this.normalizeText(((_b = (_a = window.getSelection) == null ? void 0 : _a.call(window)) == null ? void 0 : _b.toString()) || "");
1196
+ const contextLines = [
1197
+ `URL: ${location.href}`,
1198
+ `Title: ${document.title || "Untitled"}`
1199
+ ];
1200
+ if (selection) {
1201
+ contextLines.push(`TextSelection: ${selection.slice(0, 600)}`);
1202
+ }
1203
+ const elementContext = this.selectedContext || (this.hoveredElement ? this.captureElementContext(this.hoveredElement) : null);
1204
+ if (elementContext) {
1205
+ contextLines.push(`ElementSelector: ${elementContext.selector}`);
1206
+ if (elementContext.text) contextLines.push(`ElementText: ${elementContext.text.slice(0, 600)}`);
1207
+ contextLines.push(`ElementHTML: ${elementContext.html.slice(0, 800)}`);
1208
+ }
1209
+ return contextLines.join("\n");
1210
+ }
1211
+ async askPageQuestion() {
1212
+ var _a;
1213
+ if (this.sending || !this.inputEl) return;
1214
+ const prompt = this.normalizeText(this.inputEl.value);
1215
+ if (!prompt) return;
1216
+ const tokenResp = await chrome.runtime.sendMessage({ action: "auth.getToken" });
1217
+ if (!(tokenResp == null ? void 0 : tokenResp.success) || !tokenResp.token) {
1218
+ this.appendMessage("assistant", "Please sign in from the Hanzo sidebar/popup before using page chat.");
1219
+ return;
1220
+ }
1221
+ this.sending = true;
1222
+ this.updateStatus("Thinking...");
1223
+ this.sendBtn && (this.sendBtn.disabled = true);
1224
+ this.inputEl.value = "";
1225
+ this.inputEl.style.height = "auto";
1226
+ this.appendMessage("user", prompt);
1227
+ const systemContext = this.buildPageContext();
1228
+ const model = ((_a = this.modelEl) == null ? void 0 : _a.value) || "gpt-4o";
1229
+ const requestMessages = [
1230
+ {
1231
+ role: "system",
1232
+ content: [
1233
+ "You are Hanzo page overlay assistant.",
1234
+ "Use provided page context and selected element context when relevant.",
1235
+ "Be concise and provide concrete UI or DOM edit suggestions when asked.",
1236
+ "",
1237
+ systemContext
1238
+ ].join("\n")
1239
+ },
1240
+ ...this.messages.slice(-8),
1241
+ { role: "user", content: prompt }
1242
+ ];
1243
+ try {
1244
+ const response = await chrome.runtime.sendMessage({
1245
+ action: "chat.complete",
1246
+ model,
1247
+ messages: requestMessages
1248
+ });
1249
+ if (!(response == null ? void 0 : response.success) || !response.content) {
1250
+ throw new Error((response == null ? void 0 : response.error) || "No response from chat service");
1251
+ }
1252
+ const answer = String(response.content).trim();
1253
+ this.appendMessage("assistant", answer || "No response content.");
1254
+ this.messages.push({ role: "user", content: prompt }, { role: "assistant", content: answer });
1255
+ this.messages = this.messages.slice(-20);
1256
+ this.updateStatus("Ready");
1257
+ } catch (error) {
1258
+ this.appendMessage("assistant", `Error: ${(error == null ? void 0 : error.message) || "Chat request failed"}`);
1259
+ this.updateStatus("Error");
1260
+ } finally {
1261
+ this.sending = false;
1262
+ this.sendBtn && (this.sendBtn.disabled = false);
1263
+ this.focusInput();
1264
+ }
1265
+ }
1266
+ };
1267
+ var pageOverlay = new HanzoPageOverlay();
1268
+ new HanzoContentScript();
1269
+ })();
1270
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2NvbnRlbnQtc2NyaXB0LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvLyBIYW56byBCcm93c2VyIEV4dGVuc2lvbiAtIENvbnRlbnQgU2NyaXB0XG4vLyBDb25uZWN0cyBjbGlja2VkIGVsZW1lbnRzIHRvIHNvdXJjZSBjb2RlIHZpYSBzb3VyY2UtbWFwc1xuXG5pbnRlcmZhY2UgU291cmNlTG9jYXRpb24ge1xuICBmaWxlOiBzdHJpbmc7XG4gIGxpbmU6IG51bWJlcjtcbiAgY29sdW1uPzogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgRWxlbWVudFNlbGVjdGVkRXZlbnQge1xuICBldmVudDogJ2VsZW1lbnRTZWxlY3RlZCc7XG4gIGZyYW1ld29yazogc3RyaW5nIHwgbnVsbDtcbiAgZG9tUGF0aDogc3RyaW5nO1xuICBzb3VyY2U/OiBTb3VyY2VMb2NhdGlvbjtcbiAgZmFsbGJhY2tJZD86IHN0cmluZztcbn1cblxuY2xhc3MgSGFuem9Db250ZW50U2NyaXB0IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5zZXR1cENsaWNrSGFuZGxlcigpO1xuICAgIHRoaXMuaW5qZWN0SGVscGVycygpO1xuICAgIHRoaXMuc2V0dXBNZXNzYWdlSGFuZGxlcnMoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBDbGlja0hhbmRsZXIoKSB7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgaWYgKCFlLmFsdEtleSkgcmV0dXJuO1xuXG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICBjb25zdCBlbGVtZW50ID0gZS50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICBjb25zdCBzb3VyY2UgPSB0aGlzLmV4dHJhY3RTb3VyY2VMb2NhdGlvbihlbGVtZW50KTtcbiAgICAgIGNvbnN0IGRvbVBhdGggPSB0aGlzLmdldERPTVBhdGgoZWxlbWVudCk7XG5cbiAgICAgIGNvbnN0IGV2ZW50OiBFbGVtZW50U2VsZWN0ZWRFdmVudCA9IHtcbiAgICAgICAgZXZlbnQ6ICdlbGVtZW50U2VsZWN0ZWQnLFxuICAgICAgICBmcmFtZXdvcms6IHRoaXMuZGV0ZWN0RnJhbWV3b3JrKCksXG4gICAgICAgIGRvbVBhdGgsXG4gICAgICAgIHNvdXJjZSxcbiAgICAgICAgZmFsbGJhY2tJZDogZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaGFuem8taWQnKSB8fCB1bmRlZmluZWQsXG4gICAgICB9O1xuXG4gICAgICAvLyBSb3V0ZSB0aHJvdWdoIGJhY2tncm91bmQgc2NyaXB0ICh3b3JrcyB3aXRoIGJvdGggWkFQIGFuZCBsZWdhY3kgTUNQKVxuICAgICAgY2hyb21lLnJ1bnRpbWUuc2VuZE1lc3NhZ2UoeyBhY3Rpb246ICdlbGVtZW50U2VsZWN0ZWQnLCBkYXRhOiBldmVudCB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBNZXNzYWdlSGFuZGxlcnMoKSB7XG4gICAgY2hyb21lLnJ1bnRpbWUub25NZXNzYWdlLmFkZExpc3RlbmVyKChyZXF1ZXN0LCBfc2VuZGVyLCBzZW5kUmVzcG9uc2UpID0+IHtcbiAgICAgIHN3aXRjaCAocmVxdWVzdC5hY3Rpb24pIHtcbiAgICAgICAgY2FzZSAnYWkuY29udHJvbC5zdGFydCc6XG4gICAgICAgICAgYWlPdmVybGF5LnNob3cocmVxdWVzdC50YXNrIHx8ICdBSSBpcyBjb250cm9sbGluZyB0aGlzIHBhZ2UnKTtcbiAgICAgICAgICBzZW5kUmVzcG9uc2UoeyBzdWNjZXNzOiB0cnVlIH0pO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBjYXNlICdhaS5jb250cm9sLnN0b3AnOlxuICAgICAgICAgIGFpT3ZlcmxheS5oaWRlKCk7XG4gICAgICAgICAgc2VuZFJlc3BvbnNlKHsgc3VjY2VzczogdHJ1ZSB9KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgY2FzZSAnYWkuY29udHJvbC5jdXJzb3InOlxuICAgICAgICAgIGFpT3ZlcmxheS5tb3ZlQ3Vyc29yKHJlcXVlc3QueCwgcmVxdWVzdC55KTtcbiAgICAgICAgICBzZW5kUmVzcG9uc2UoeyBzdWNjZXNzOiB0cnVlIH0pO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBjYXNlICdhaS5jb250cm9sLmhpZ2hsaWdodCc6XG4gICAgICAgICAgYWlPdmVybGF5LmhpZ2hsaWdodChyZXF1ZXN0LnNlbGVjdG9yKTtcbiAgICAgICAgICBzZW5kUmVzcG9uc2UoeyBzdWNjZXNzOiB0cnVlIH0pO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBjYXNlICdhaS5jb250cm9sLnN0YXR1cyc6XG4gICAgICAgICAgYWlPdmVybGF5LnVwZGF0ZVN0YXR1cyhyZXF1ZXN0LnRleHQpO1xuICAgICAgICAgIHNlbmRSZXNwb25zZSh7IHN1Y2Nlc3M6IHRydWUgfSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIGNhc2UgJ3BhZ2Uub3ZlcmxheS50b2dnbGUnOlxuICAgICAgICAgIHNlbmRSZXNwb25zZSh7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgb3BlbjogcGFnZU92ZXJsYXkudG9nZ2xlKCksXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIGNhc2UgJ3BhZ2Uub3ZlcmxheS5zaG93JzpcbiAgICAgICAgICBwYWdlT3ZlcmxheS5zaG93KCk7XG4gICAgICAgICAgc2VuZFJlc3BvbnNlKHsgc3VjY2VzczogdHJ1ZSwgb3BlbjogdHJ1ZSB9KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgY2FzZSAncGFnZS5vdmVybGF5LmhpZGUnOlxuICAgICAgICAgIHBhZ2VPdmVybGF5LmhpZGUoKTtcbiAgICAgICAgICBzZW5kUmVzcG9uc2UoeyBzdWNjZXNzOiB0cnVlLCBvcGVuOiBmYWxzZSB9KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgY2FzZSAncGFnZS5vdmVybGF5LnN0YXR1cyc6XG4gICAgICAgICAgc2VuZFJlc3BvbnNlKHsgc3VjY2VzczogdHJ1ZSwgb3BlbjogcGFnZU92ZXJsYXkuaXNPcGVuKCkgfSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIC8vIFRhYiBmaWxlc3lzdGVtIHN1cHBvcnRcbiAgICAgIGlmIChyZXF1ZXN0LmFjdGlvbiA9PT0gJ2dldENvbnRlbnQnKSB7XG4gICAgICAgIHNlbmRSZXNwb25zZSh7IGNvbnRlbnQ6IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudD8ub3V0ZXJIVE1MIHx8ICcnIH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcXVlc3QuYWN0aW9uID09PSAnc2V0Q29udGVudCcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXF1ZXN0LmNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgZG9jdW1lbnQub3BlbigpO1xuICAgICAgICAgIGRvY3VtZW50LndyaXRlKHJlcXVlc3QuY29udGVudCk7XG4gICAgICAgICAgZG9jdW1lbnQuY2xvc2UoKTtcbiAgICAgICAgfVxuICAgICAgICBzZW5kUmVzcG9uc2UoeyBzdWNjZXNzOiB0cnVlIH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0U291cmNlTG9jYXRpb24oZWxlbWVudDogSFRNTEVsZW1lbnQpOiBTb3VyY2VMb2NhdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZnJhbWV3b3JrID0gdGhpcy5kZXRlY3RGcmFtZXdvcmsoKTtcblxuICAgIHN3aXRjaCAoZnJhbWV3b3JrKSB7XG4gICAgICBjYXNlICdyZWFjdCc6XG4gICAgICAgIHJldHVybiB0aGlzLmV4dHJhY3RSZWFjdFNvdXJjZShlbGVtZW50KTtcbiAgICAgIGNhc2UgJ3Z1ZSc6XG4gICAgICAgIHJldHVybiB0aGlzLmV4dHJhY3RWdWVTb3VyY2UoZWxlbWVudCk7XG4gICAgICBjYXNlICdzdmVsdGUnOlxuICAgICAgICByZXR1cm4gdGhpcy5leHRyYWN0U3ZlbHRlU291cmNlKGVsZW1lbnQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGV4dHJhY3RSZWFjdFNvdXJjZShlbGVtZW50OiBIVE1MRWxlbWVudCk6IFNvdXJjZUxvY2F0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBob29rID0gKHdpbmRvdyBhcyBhbnkpLl9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXztcbiAgICBpZiAoIWhvb2spIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBmaWJlciA9IHRoaXMuZmluZFJlYWN0RmliZXIoZWxlbWVudCk7XG4gICAgaWYgKCFmaWJlcikgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IHNvdXJjZSA9IGZpYmVyLl9kZWJ1Z1NvdXJjZSB8fCBmaWJlci5wZW5kaW5nUHJvcHM/Ll9fc291cmNlIHx8IGZpYmVyLm1lbW9pemVkUHJvcHM/Ll9fc291cmNlO1xuXG4gICAgaWYgKHNvdXJjZSAmJiBzb3VyY2UuZmlsZU5hbWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGZpbGU6IHNvdXJjZS5maWxlTmFtZSxcbiAgICAgICAgbGluZTogc291cmNlLmxpbmVOdW1iZXIsXG4gICAgICAgIGNvbHVtbjogc291cmNlLmNvbHVtbk51bWJlcixcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgZmluZFJlYWN0RmliZXIoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBhbnkge1xuICAgIGNvbnN0IGtleSA9IE9iamVjdC5rZXlzKGVsZW1lbnQpLmZpbmQoXG4gICAgICAoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUuc3RhcnRzV2l0aCgnX19yZWFjdEludGVybmFsSW5zdGFuY2UkJykgfHwgY2FuZGlkYXRlLnN0YXJ0c1dpdGgoJ19fcmVhY3RGaWJlciQnKSxcbiAgICApO1xuICAgIHJldHVybiBrZXkgPyAoZWxlbWVudCBhcyBhbnkpW2tleV0gOiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0VnVlU291cmNlKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogU291cmNlTG9jYXRpb24gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGhvb2sgPSAod2luZG93IGFzIGFueSkuX19WVUVfREVWVE9PTFNfR0xPQkFMX0hPT0tfXztcbiAgICBpZiAoIWhvb2spIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBsZXQgaW5zdGFuY2UgPSAoZWxlbWVudCBhcyBhbnkpLl9fdnVlUGFyZW50Q29tcG9uZW50O1xuICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgIGluc3RhbmNlID0gKGVsZW1lbnQgYXMgYW55KS5fX3Z1ZV9fO1xuICAgIH1cblxuICAgIGlmIChpbnN0YW5jZT8udHlwZT8uX19maWxlKSB7XG4gICAgICBjb25zdCBsb2NhdGlvbjogU291cmNlTG9jYXRpb24gPSB7XG4gICAgICAgIGZpbGU6IGluc3RhbmNlLnR5cGUuX19maWxlLFxuICAgICAgICBsaW5lOiAxLFxuICAgICAgfTtcblxuICAgICAgaWYgKGluc3RhbmNlLnZub2RlPy5sb2MpIHtcbiAgICAgICAgbG9jYXRpb24ubGluZSA9IGluc3RhbmNlLnZub2RlLmxvYy5zdGFydC5saW5lO1xuICAgICAgICBsb2NhdGlvbi5jb2x1bW4gPSBpbnN0YW5jZS52bm9kZS5sb2Muc3RhcnQuY29sdW1uO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbG9jYXRpb247XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgZXh0cmFjdFN2ZWx0ZVNvdXJjZShlbGVtZW50OiBIVE1MRWxlbWVudCk6IFNvdXJjZUxvY2F0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBjb21wb25lbnQgPSAoZWxlbWVudCBhcyBhbnkpLl9fc3ZlbHRlX2NvbXBvbmVudDtcbiAgICBpZiAoY29tcG9uZW50Py4kJD8uY3R4Py4kJF9sb2NhdGlvbikge1xuICAgICAgcmV0dXJuIGNvbXBvbmVudC4kJC5jdHguJCRfbG9jYXRpb247XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGRldGVjdEZyYW1ld29yaygpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAoKHdpbmRvdyBhcyBhbnkpLl9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXykgcmV0dXJuICdyZWFjdCc7XG4gICAgaWYgKCh3aW5kb3cgYXMgYW55KS5fX1ZVRV9ERVZUT09MU19HTE9CQUxfSE9PS19fKSByZXR1cm4gJ3Z1ZSc7XG4gICAgaWYgKCh3aW5kb3cgYXMgYW55KS5fX3N2ZWx0ZSkgcmV0dXJuICdzdmVsdGUnO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRET01QYXRoKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXRoOiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBjdXJyZW50OiBIVE1MRWxlbWVudCB8IG51bGwgPSBlbGVtZW50O1xuXG4gICAgd2hpbGUgKGN1cnJlbnQgJiYgY3VycmVudCAhPT0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgbGV0IHNlbGVjdG9yID0gY3VycmVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgIGlmIChjdXJyZW50LmlkKSB7XG4gICAgICAgIHNlbGVjdG9yICs9IGAjJHtjdXJyZW50LmlkfWA7XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnQuY2xhc3NOYW1lKSB7XG4gICAgICAgIHNlbGVjdG9yICs9IGAuJHtjdXJyZW50LmNsYXNzTmFtZS5zcGxpdCgnICcpLmpvaW4oJy4nKX1gO1xuICAgICAgfVxuXG4gICAgICBwYXRoLnVuc2hpZnQoc2VsZWN0b3IpO1xuICAgICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50RWxlbWVudDtcbiAgICB9XG5cbiAgICByZXR1cm4gcGF0aC5qb2luKCcgPiAnKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5qZWN0SGVscGVycygpIHtcbiAgICBjb25zdCBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gICAgc3R5bGUudGV4dENvbnRlbnQgPSBgXG4gICAgICBbZGF0YS1oYW56by1ob3Zlcl0ge1xuICAgICAgICBvdXRsaW5lOiAycHggZGFzaGVkICNmZjZiNmIgIWltcG9ydGFudDtcbiAgICAgICAgb3V0bGluZS1vZmZzZXQ6IDJweCAhaW1wb3J0YW50O1xuICAgICAgfVxuICAgIGA7XG4gICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG5cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCAoZSkgPT4ge1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW2RhdGEtaGFuem8taG92ZXJdJykuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCdkYXRhLWhhbnpvLWhvdmVyJyk7XG4gICAgICB9KTtcblxuICAgICAgaWYgKGUuYWx0S2V5ICYmIGUudGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgZS50YXJnZXQuc2V0QXR0cmlidXRlKCdkYXRhLWhhbnpvLWhvdmVyJywgJ3RydWUnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gQUkgQ29udHJvbCBPdmVybGF5IFx1MjAxNCB0YWtlb3ZlciB2aXN1YWwgZmVlZGJhY2sgKyB1c2VyIGludGVyYWN0aW9uIGxvY2tcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmNvbnN0IGFpT3ZlcmxheSA9ICgoKSA9PiB7XG4gIGxldCBvdmVybGF5OiBIVE1MRGl2RWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBsZXQgY3Vyc29yOiBIVE1MRGl2RWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBsZXQgc3RhdHVzRWw6IEhUTUxEaXZFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIGxldCBjYW5jZWxCdG46IEhUTUxCdXR0b25FbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIGxldCBoaWdobGlnaHRFbDogSFRNTERpdkVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgbGV0IHRyYWlsTm9kZXM6IEhUTUxEaXZFbGVtZW50W10gPSBbXTtcbiAgbGV0IGludGVyYWN0aW9uQmxvY2tBY3RpdmUgPSBmYWxzZTtcblxuICBjb25zdCBPVkVSTEFZX0lEID0gJ2hhbnpvLWFpLW92ZXJsYXknO1xuICBjb25zdCBTVFlMRVNfSUQgPSAnaGFuem8tYWktb3ZlcmxheS1zdHlsZXMnO1xuICBjb25zdCBCTE9DS0VEX0VWRU5UUyA9IFtcbiAgICAnY2xpY2snLCAnZGJsY2xpY2snLCAnbW91c2Vkb3duJywgJ21vdXNldXAnLCAnY29udGV4dG1lbnUnLFxuICAgICdwb2ludGVyZG93bicsICdwb2ludGVydXAnLCAndG91Y2hzdGFydCcsICd0b3VjaG1vdmUnLCAndG91Y2hlbmQnLCAnd2hlZWwnLFxuICAgICdrZXlkb3duJywgJ2tleXVwJywgJ2tleXByZXNzJyxcbiAgXTtcblxuICBmdW5jdGlvbiBpbmplY3RTdHlsZXMoKSB7XG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFNUWUxFU19JRCkpIHJldHVybjtcblxuICAgIGNvbnN0IHN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICBzdHlsZS5pZCA9IFNUWUxFU19JRDtcbiAgICBzdHlsZS50ZXh0Q29udGVudCA9IGBcbiAgICAgIC8qIC0tLS0gT3ZlcmxheSBiYWNrZHJvcCAtLS0tICovXG4gICAgICAjJHtPVkVSTEFZX0lEfSB7XG4gICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgICAgaW5zZXQ6IDA7XG4gICAgICAgIHotaW5kZXg6IDIxNDc0ODM2NDY7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBhbGw7XG4gICAgICAgIGJhY2tncm91bmQ6XG4gICAgICAgICAgcmFkaWFsLWdyYWRpZW50KDkwdncgOTB2aCBhdCAxNSUgOCUsIHJnYmEoNTYsIDE4OSwgMjQ4LCAwLjEwKSwgdHJhbnNwYXJlbnQgNTUlKSxcbiAgICAgICAgICByYWRpYWwtZ3JhZGllbnQoNjV2dyA2NXZoIGF0IDg0JSA4MiUsIHJnYmEoOTksIDEwMiwgMjQxLCAwLjEwKSwgdHJhbnNwYXJlbnQgNjAlKSxcbiAgICAgICAgICByZ2JhKDIsIDQsIDEwLCAwLjQyKTtcbiAgICAgICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDEuNXB4KTtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNpdGlvbjogb3BhY2l0eSAzMDBtcyBlYXNlO1xuICAgICAgfVxuICAgICAgIyR7T1ZFUkxBWV9JRH0uaGFuem8tdmlzaWJsZSB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICB9XG5cbiAgICAgIC8qIC0tLS0gUHVsc2luZyBjeWFuIGdsb3cgY3Vyc29yIC0tLS0gKi9cbiAgICAgIC5oYW56by1haS1jdXJzb3Ige1xuICAgICAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgICAgIHdpZHRoOiAyNHB4O1xuICAgICAgICBoZWlnaHQ6IDI0cHg7XG4gICAgICAgIHotaW5kZXg6IDIxNDc0ODM2NDc7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgICAgIGJvcmRlcjogMnB4IHNvbGlkIHJnYmEoNiwgMTgyLCAyMTIsIDAuOTUpO1xuICAgICAgICBib3gtc2hhZG93OlxuICAgICAgICAgIDAgMCA4cHggMnB4IHJnYmEoNiwgMTgyLCAyMTIsIDAuNDUpLFxuICAgICAgICAgIDAgMCAyNHB4IDZweCByZ2JhKDYsIDE4MiwgMjEyLCAwLjE4KTtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XG4gICAgICAgIHRyYW5zaXRpb246IGxlZnQgMC4xOHMgZWFzZS1vdXQsIHRvcCAwLjE4cyBlYXNlLW91dDtcbiAgICAgICAgYW5pbWF0aW9uOiBoYW56by1jdXJzb3ItcHVsc2UgMS42cyBlYXNlLWluLW91dCBpbmZpbml0ZTtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgIH1cbiAgICAgIC5oYW56by1haS1jdXJzb3IuaGFuem8tdmlzaWJsZSB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIHRyYW5zaXRpb246IGxlZnQgMC4xOHMgZWFzZS1vdXQsIHRvcCAwLjE4cyBlYXNlLW91dCwgb3BhY2l0eSAzMDBtcyBlYXNlO1xuICAgICAgfVxuICAgICAgQGtleWZyYW1lcyBoYW56by1jdXJzb3ItcHVsc2Uge1xuICAgICAgICAwJSwgMTAwJSB7XG4gICAgICAgICAgYm94LXNoYWRvdzpcbiAgICAgICAgICAgIDAgMCA4cHggMnB4IHJnYmEoNiwgMTgyLCAyMTIsIDAuNDUpLFxuICAgICAgICAgICAgMCAwIDI0cHggNnB4IHJnYmEoNiwgMTgyLCAyMTIsIDAuMTgpO1xuICAgICAgICB9XG4gICAgICAgIDUwJSB7XG4gICAgICAgICAgYm94LXNoYWRvdzpcbiAgICAgICAgICAgIDAgMCAxNHB4IDRweCByZ2JhKDYsIDE4MiwgMjEyLCAwLjY1KSxcbiAgICAgICAgICAgIDAgMCAzNnB4IDEwcHggcmdiYSg2LCAxODIsIDIxMiwgMC4yOCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLyogLS0tLSBDdXJzb3IgdHJhaWwgLS0tLSAqL1xuICAgICAgLmhhbnpvLWN1cnNvci10cmFpbCB7XG4gICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgICAgd2lkdGg6IDZweDtcbiAgICAgICAgaGVpZ2h0OiA2cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICAgICAgYmFja2dyb3VuZDogcmdiYSg2LCAxODIsIDIxMiwgMC43KTtcbiAgICAgICAgei1pbmRleDogMjE0NzQ4MzY0NjtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1xuICAgICAgICBhbmltYXRpb246IGhhbnpvLXRyYWlsLWZhZGUgMC40cyBlYXNlLW91dCBmb3J3YXJkcztcbiAgICAgIH1cbiAgICAgIEBrZXlmcmFtZXMgaGFuem8tdHJhaWwtZmFkZSB7XG4gICAgICAgIGZyb20geyBvcGFjaXR5OiAwLjc7IHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpIHNjYWxlKDEpOyB9XG4gICAgICAgIHRvIHsgb3BhY2l0eTogMDsgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSkgc2NhbGUoMC4xNSk7IH1cbiAgICAgIH1cblxuICAgICAgLyogLS0tLSBTdGF0dXMgYmFubmVyICh0b3AgY2VudGVyIHBpbGwpIC0tLS0gKi9cbiAgICAgIC5oYW56by1haS1zdGF0dXMge1xuICAgICAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgICAgIHRvcDogMTZweDtcbiAgICAgICAgbGVmdDogNTAlO1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUwJSk7XG4gICAgICAgIHotaW5kZXg6IDIxNDc0ODM2NDc7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIGdhcDogMTBweDtcbiAgICAgICAgbWF4LXdpZHRoOiA5MHZ3O1xuICAgICAgICBwYWRkaW5nOiAxMHB4IDE0cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDE2cHg7XG4gICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsIHJnYmEoOCwgMTIsIDIwLCAwLjk0KSwgcmdiYSgxMCwgMTYsIDI0LCAwLjk2KSk7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoNTYsIDE4OSwgMjQ4LCAwLjI2KTtcbiAgICAgICAgY29sb3I6ICNmM2Y0ZjY7XG4gICAgICAgIGZvbnQ6IDEzcHgvMS40IC1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgJ1NlZ29lIFVJJywgc2Fucy1zZXJpZjtcbiAgICAgICAgYm94LXNoYWRvdzpcbiAgICAgICAgICAwIDEwcHggMzZweCByZ2JhKDAsIDAsIDAsIDAuNDYpLFxuICAgICAgICAgIGluc2V0IDAgMXB4IDAgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjA4KTtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNpdGlvbjogb3BhY2l0eSAzMDBtcyBlYXNlO1xuICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgfVxuICAgICAgLmhhbnpvLWFpLXN0YXR1czo6YmVmb3JlIHtcbiAgICAgICAgY29udGVudDogJyc7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgaW5zZXQ6IC0ycHggYXV0byAtMnB4IC0yMCU7XG4gICAgICAgIHdpZHRoOiA0MCU7XG4gICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCg5MGRlZywgdHJhbnNwYXJlbnQsIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4xNiksIHRyYW5zcGFyZW50KTtcbiAgICAgICAgdHJhbnNmb3JtOiBza2V3WCgtMThkZWcpO1xuICAgICAgICBhbmltYXRpb246IGhhbnpvLXN0YXR1cy1zaGVlbiAzLjZzIGVhc2UtaW4tb3V0IGluZmluaXRlO1xuICAgICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgIH1cbiAgICAgIEBrZXlmcmFtZXMgaGFuem8tc3RhdHVzLXNoZWVuIHtcbiAgICAgICAgMCUsIDY4JSB7IGxlZnQ6IC0zMCU7IG9wYWNpdHk6IDA7IH1cbiAgICAgICAgNzIlIHsgb3BhY2l0eTogMC40OyB9XG4gICAgICAgIDEwMCUgeyBsZWZ0OiAxMzAlOyBvcGFjaXR5OiAwOyB9XG4gICAgICB9XG4gICAgICAuaGFuem8tYWktc3RhdHVzID4gKiB7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgIH1cbiAgICAgIC5oYW56by1haS1zdGF0dXMuaGFuem8tdmlzaWJsZSB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1haS1zdGF0dXMgLmhhbnpvLWJyYW5kLWJ1YmJsZSB7XG4gICAgICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgICAgaGVpZ2h0OiAyMHB4O1xuICAgICAgICBtaW4td2lkdGg6IDMwcHg7XG4gICAgICAgIHBhZGRpbmc6IDAgOHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiA5OTk5cHg7XG4gICAgICAgIGZvbnQtc2l6ZTogMTBweDtcbiAgICAgICAgbGV0dGVyLXNwYWNpbmc6IDAuMjVweDtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICAgICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgICAgICAgY29sb3I6ICNlMGYyZmU7XG4gICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxODBkZWcsIHJnYmEoMTQsIDExNiwgMTQ0LCAwLjk1KSwgcmdiYSgxNSwgMjMsIDQyLCAwLjk1KSk7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoNTYsIDE4OSwgMjQ4LCAwLjM1KTtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLWFpLXN0YXR1cyAuaGFuem8tcHVsc2UtZG90IHtcbiAgICAgICAgd2lkdGg6IDhweDtcbiAgICAgICAgaGVpZ2h0OiA4cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDk5OTlweDtcbiAgICAgICAgYmFja2dyb3VuZDogIzA2YjZkNDtcbiAgICAgICAgYW5pbWF0aW9uOiBoYW56by1kb3QtcHVsc2UgMS40cyBlYXNlLWluLW91dCBpbmZpbml0ZTtcbiAgICAgIH1cbiAgICAgIEBrZXlmcmFtZXMgaGFuem8tZG90LXB1bHNlIHtcbiAgICAgICAgMCUsIDEwMCUgeyBvcGFjaXR5OiAxOyB9XG4gICAgICAgIDUwJSB7IG9wYWNpdHk6IDAuNDsgfVxuICAgICAgfVxuXG4gICAgICAuaGFuem8tYWktc3RhdHVzIC5oYW56by1sYWJlbCB7XG4gICAgICAgIG1heC13aWR0aDogNDZ2dztcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1haS1zdGF0dXMgLmhhbnpvLWRvdHM6OmFmdGVyIHtcbiAgICAgICAgY29udGVudDogJyc7XG4gICAgICAgIGFuaW1hdGlvbjogaGFuem8tYW5pbWF0ZWQtZG90cyAxLjVzIHN0ZXBzKDQpIGluZmluaXRlO1xuICAgICAgfVxuICAgICAgQGtleWZyYW1lcyBoYW56by1hbmltYXRlZC1kb3RzIHtcbiAgICAgICAgMCUgeyBjb250ZW50OiAnJzsgfVxuICAgICAgICAyNSUgeyBjb250ZW50OiAnLic7IH1cbiAgICAgICAgNTAlIHsgY29udGVudDogJy4uJzsgfVxuICAgICAgICA3NSUgeyBjb250ZW50OiAnLi4uJzsgfVxuICAgICAgfVxuXG4gICAgICAuaGFuem8tYWktc3RhdHVzIC5oYW56by1zdG9wLWJ0biB7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4yNCk7XG4gICAgICAgIGJhY2tncm91bmQ6IHJnYmEoMCwgMCwgMCwgMC4xOCk7XG4gICAgICAgIGNvbG9yOiAjZjhmYWZjO1xuICAgICAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgICAgICBwYWRkaW5nOiA0cHggMTJweDtcbiAgICAgICAgZm9udC1zaXplOiAxMnB4O1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQgMC4xNXMsIGJvcmRlci1jb2xvciAwLjE1cztcbiAgICAgIH1cbiAgICAgIC5oYW56by1haS1zdGF0dXMgLmhhbnpvLXN0b3AtYnRuOmhvdmVyIHtcbiAgICAgICAgYmFja2dyb3VuZDogcmdiYSgyMjAsIDM4LCAzOCwgMC4yOCk7XG4gICAgICAgIGJvcmRlci1jb2xvcjogcmdiYSgyNDgsIDExMywgMTEzLCAwLjYpO1xuICAgICAgfVxuXG4gICAgICAvKiAtLS0tIFwiVGFrZSBCYWNrIENvbnRyb2xcIiBidXR0b24gKGJvdHRvbS1yaWdodCkgLS0tLSAqL1xuICAgICAgLmhhbnpvLWFpLWNhbmNlbCB7XG4gICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgICAgYm90dG9tOiAyNHB4O1xuICAgICAgICByaWdodDogMjRweDtcbiAgICAgICAgei1pbmRleDogMjE0NzQ4MzY0NztcbiAgICAgICAgcGFkZGluZzogMTJweCAyNHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMik7XG4gICAgICAgIGJhY2tncm91bmQ6IHJnYmEoMTUsIDE4LCAyNCwgMC45NSk7XG4gICAgICAgIGNvbG9yOiAjZjNmNGY2O1xuICAgICAgICBmb250OiA2MDAgMTRweC8xLjQgLWFwcGxlLXN5c3RlbSwgQmxpbmtNYWNTeXN0ZW1Gb250LCAnU2Vnb2UgVUknLCBzYW5zLXNlcmlmO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICAgIGJveC1zaGFkb3c6IDAgOHB4IDI0cHggcmdiYSgwLCAwLCAwLCAwLjQpO1xuICAgICAgICBwb2ludGVyLWV2ZW50czogYXV0bztcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNpdGlvbjogb3BhY2l0eSAzMDBtcyBlYXNlLCBiYWNrZ3JvdW5kIDAuMTVzO1xuICAgICAgfVxuICAgICAgLmhhbnpvLWFpLWNhbmNlbC5oYW56by12aXNpYmxlIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgIH1cbiAgICAgIC5oYW56by1haS1jYW5jZWw6aG92ZXIge1xuICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKDIyMCwgMzgsIDM4LCAwLjM1KTtcbiAgICAgICAgYm9yZGVyLWNvbG9yOiByZ2JhKDIyMCwgMzgsIDM4LCAwLjUpO1xuICAgICAgfVxuXG4gICAgICAvKiAtLS0tIEVsZW1lbnQgaGlnaGxpZ2h0IC0tLS0gKi9cbiAgICAgIC5oYW56by1haS1oaWdobGlnaHQge1xuICAgICAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgICAgIHotaW5kZXg6IDIxNDc0ODM2NDc7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgICAgICBib3JkZXI6IDJweCBzb2xpZCByZ2JhKDYsIDE4MiwgMjEyLCAwLjg1KTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogNnB4O1xuICAgICAgICBib3gtc2hhZG93OiAwIDAgMCAzcHggcmdiYSg2LCAxODIsIDIxMiwgMC4xNSk7XG4gICAgICAgIHRyYW5zaXRpb246IGxlZnQgMC4xNXMsIHRvcCAwLjE1cywgd2lkdGggMC4xNXMsIGhlaWdodCAwLjE1cztcbiAgICAgIH1cbiAgICBgO1xuICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc3R5bGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNPdmVybGF5RWxlbWVudCh0YXJnZXQ6IEV2ZW50VGFyZ2V0IHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIE5vZGUpKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuICEhKFxuICAgICAgb3ZlcmxheT8uY29udGFpbnModGFyZ2V0KSB8fFxuICAgICAgc3RhdHVzRWw/LmNvbnRhaW5zKHRhcmdldCkgfHxcbiAgICAgIGNhbmNlbEJ0bj8uY29udGFpbnModGFyZ2V0KSB8fFxuICAgICAgY3Vyc29yPy5jb250YWlucyh0YXJnZXQpIHx8XG4gICAgICBoaWdobGlnaHRFbD8uY29udGFpbnModGFyZ2V0KVxuICAgICk7XG4gIH1cblxuICBmdW5jdGlvbiBibG9ja0ludGVyYWN0aW9uKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGlmICghaW50ZXJhY3Rpb25CbG9ja0FjdGl2ZSkgcmV0dXJuO1xuXG4gICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgS2V5Ym9hcmRFdmVudCAmJiBldmVudC5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICBjaHJvbWUucnVudGltZS5zZW5kTWVzc2FnZSh7IGFjdGlvbjogJ2FpLmNvbnRyb2wuY2FuY2VsJyB9KTtcbiAgICAgIGhpZGUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoaXNPdmVybGF5RWxlbWVudChldmVudC50YXJnZXQpKSByZXR1cm47XG5cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0SW50ZXJhY3Rpb25CbG9jayhhY3RpdmU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoaW50ZXJhY3Rpb25CbG9ja0FjdGl2ZSA9PT0gYWN0aXZlKSByZXR1cm47XG5cbiAgICBpbnRlcmFjdGlvbkJsb2NrQWN0aXZlID0gYWN0aXZlO1xuICAgIGZvciAoY29uc3QgZXZlbnROYW1lIG9mIEJMT0NLRURfRVZFTlRTKSB7XG4gICAgICBpZiAoYWN0aXZlKSB7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBibG9ja0ludGVyYWN0aW9uLCB0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBibG9ja0ludGVyYWN0aW9uLCB0cnVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzaG93KHRhc2s6IHN0cmluZykge1xuICAgIGlmIChvdmVybGF5KSBoaWRlKCk7XG5cbiAgICBpbmplY3RTdHlsZXMoKTtcbiAgICBzZXRJbnRlcmFjdGlvbkJsb2NrKHRydWUpO1xuXG4gICAgLy8gQmFja2Ryb3BcbiAgICBvdmVybGF5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgb3ZlcmxheS5pZCA9IE9WRVJMQVlfSUQ7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChvdmVybGF5KTtcblxuICAgIC8vIEN1cnNvclxuICAgIGN1cnNvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGN1cnNvci5jbGFzc05hbWUgPSAnaGFuem8tYWktY3Vyc29yJztcbiAgICBjdXJzb3Iuc3R5bGUubGVmdCA9IGAke3dpbmRvdy5pbm5lcldpZHRoIC8gMn1weGA7XG4gICAgY3Vyc29yLnN0eWxlLnRvcCA9IGAke3dpbmRvdy5pbm5lckhlaWdodCAvIDJ9cHhgO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoY3Vyc29yKTtcblxuICAgIC8vIFN0YXR1cyBiYW5uZXJcbiAgICBzdGF0dXNFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHN0YXR1c0VsLmNsYXNzTmFtZSA9ICdoYW56by1haS1zdGF0dXMnO1xuICAgIHN0YXR1c0VsLmlubmVySFRNTCA9IGBcbiAgICAgIDxzcGFuIGNsYXNzPVwiaGFuem8tYnJhbmQtYnViYmxlXCI+QUk8L3NwYW4+XG4gICAgICA8ZGl2IGNsYXNzPVwiaGFuem8tcHVsc2UtZG90XCI+PC9kaXY+XG4gICAgICA8c3BhbiBjbGFzcz1cImhhbnpvLWxhYmVsXCI+JHtlc2NhcGVIdG1sKHRhc2sgfHwgJ0hhbnpvIEFJIGlzIGNvbnRyb2xsaW5nIHRoaXMgdGFiJyl9PC9zcGFuPjxzcGFuIGNsYXNzPVwiaGFuem8tZG90c1wiPjwvc3Bhbj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJoYW56by1zdG9wLWJ0blwiPlN0b3A8L2J1dHRvbj5cbiAgICBgO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoc3RhdHVzRWwpO1xuXG4gICAgc3RhdHVzRWwucXVlcnlTZWxlY3RvcignLmhhbnpvLXN0b3AtYnRuJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgY2hyb21lLnJ1bnRpbWUuc2VuZE1lc3NhZ2UoeyBhY3Rpb246ICdhaS5jb250cm9sLmNhbmNlbCcgfSk7XG4gICAgICBoaWRlKCk7XG4gICAgfSk7XG5cbiAgICAvLyBcIlRha2UgQmFjayBDb250cm9sXCIgYnV0dG9uXG4gICAgY2FuY2VsQnRuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7XG4gICAgY2FuY2VsQnRuLmNsYXNzTmFtZSA9ICdoYW56by1haS1jYW5jZWwnO1xuICAgIGNhbmNlbEJ0bi50ZXh0Q29udGVudCA9ICdUYWtlIEJhY2sgQ29udHJvbCc7XG4gICAgY2FuY2VsQnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgY2hyb21lLnJ1bnRpbWUuc2VuZE1lc3NhZ2UoeyBhY3Rpb246ICdhaS5jb250cm9sLmNhbmNlbCcgfSk7XG4gICAgICBoaWRlKCk7XG4gICAgfSk7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChjYW5jZWxCdG4pO1xuXG4gICAgLy8gRmFkZSBpbiAobmV4dCBmcmFtZSBzbyB0aGUgdHJhbnNpdGlvbiB0cmlnZ2VycylcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgb3ZlcmxheT8uY2xhc3NMaXN0LmFkZCgnaGFuem8tdmlzaWJsZScpO1xuICAgICAgY3Vyc29yPy5jbGFzc0xpc3QuYWRkKCdoYW56by12aXNpYmxlJyk7XG4gICAgICBzdGF0dXNFbD8uY2xhc3NMaXN0LmFkZCgnaGFuem8tdmlzaWJsZScpO1xuICAgICAgY2FuY2VsQnRuPy5jbGFzc0xpc3QuYWRkKCdoYW56by12aXNpYmxlJyk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBoaWRlKCkge1xuICAgIC8vIEZhZGUgb3V0XG4gICAgb3ZlcmxheT8uY2xhc3NMaXN0LnJlbW92ZSgnaGFuem8tdmlzaWJsZScpO1xuICAgIGN1cnNvcj8uY2xhc3NMaXN0LnJlbW92ZSgnaGFuem8tdmlzaWJsZScpO1xuICAgIHN0YXR1c0VsPy5jbGFzc0xpc3QucmVtb3ZlKCdoYW56by12aXNpYmxlJyk7XG4gICAgY2FuY2VsQnRuPy5jbGFzc0xpc3QucmVtb3ZlKCdoYW56by12aXNpYmxlJyk7XG5cbiAgICAvLyBSZW1vdmUgYWZ0ZXIgdHJhbnNpdGlvblxuICAgIGNvbnN0IHJlZnMgPSB7IG92ZXJsYXksIGN1cnNvciwgc3RhdHVzRWwsIGNhbmNlbEJ0biwgaGlnaGxpZ2h0RWwgfTtcbiAgICBjb25zdCB0cmFpbHMgPSBbLi4udHJhaWxOb2Rlc107XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHJlZnMub3ZlcmxheT8ucmVtb3ZlKCk7XG4gICAgICByZWZzLmN1cnNvcj8ucmVtb3ZlKCk7XG4gICAgICByZWZzLnN0YXR1c0VsPy5yZW1vdmUoKTtcbiAgICAgIHJlZnMuY2FuY2VsQnRuPy5yZW1vdmUoKTtcbiAgICAgIHJlZnMuaGlnaGxpZ2h0RWw/LnJlbW92ZSgpO1xuICAgICAgZm9yIChjb25zdCBub2RlIG9mIHRyYWlscykge1xuICAgICAgICBub2RlLnJlbW92ZSgpO1xuICAgICAgfVxuICAgIH0sIDMyMCk7XG5cbiAgICBzZXRJbnRlcmFjdGlvbkJsb2NrKGZhbHNlKTtcblxuICAgIG92ZXJsYXkgPSBudWxsO1xuICAgIGN1cnNvciA9IG51bGw7XG4gICAgc3RhdHVzRWwgPSBudWxsO1xuICAgIGNhbmNlbEJ0biA9IG51bGw7XG4gICAgaGlnaGxpZ2h0RWwgPSBudWxsO1xuICAgIHRyYWlsTm9kZXMgPSBbXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1vdmVDdXJzb3IoeDogbnVtYmVyLCB5OiBudW1iZXIpIHtcbiAgICBpZiAoIWN1cnNvcikgcmV0dXJuO1xuXG4gICAgY29uc3QgY2xhbXBlZFggPSBNYXRoLm1heCgwLCBNYXRoLm1pbih3aW5kb3cuaW5uZXJXaWR0aCwgTnVtYmVyLmlzRmluaXRlKHgpID8geCA6IDApKTtcbiAgICBjb25zdCBjbGFtcGVkWSA9IE1hdGgubWF4KDAsIE1hdGgubWluKHdpbmRvdy5pbm5lckhlaWdodCwgTnVtYmVyLmlzRmluaXRlKHkpID8geSA6IDApKTtcblxuICAgIC8vIFRyYWlsIGRvdFxuICAgIGNvbnN0IHRyYWlsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdHJhaWwuY2xhc3NOYW1lID0gJ2hhbnpvLWN1cnNvci10cmFpbCc7XG4gICAgdHJhaWwuc3R5bGUubGVmdCA9IGAke2NsYW1wZWRYfXB4YDtcbiAgICB0cmFpbC5zdHlsZS50b3AgPSBgJHtjbGFtcGVkWX1weGA7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0cmFpbCk7XG4gICAgdHJhaWxOb2Rlcy5wdXNoKHRyYWlsKTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdHJhaWwucmVtb3ZlKCk7XG4gICAgICB0cmFpbE5vZGVzID0gdHJhaWxOb2Rlcy5maWx0ZXIoKG5vZGUpID0+IG5vZGUgIT09IHRyYWlsKTtcbiAgICB9LCA0MDApO1xuXG4gICAgd2hpbGUgKHRyYWlsTm9kZXMubGVuZ3RoID4gMTApIHtcbiAgICAgIHRyYWlsTm9kZXMuc2hpZnQoKT8ucmVtb3ZlKCk7XG4gICAgfVxuXG4gICAgY3Vyc29yLnN0eWxlLmxlZnQgPSBgJHtjbGFtcGVkWH1weGA7XG4gICAgY3Vyc29yLnN0eWxlLnRvcCA9IGAke2NsYW1wZWRZfXB4YDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhpZ2hsaWdodChzZWxlY3Rvcjogc3RyaW5nKSB7XG4gICAgaGlnaGxpZ2h0RWw/LnJlbW92ZSgpO1xuICAgIGhpZ2hsaWdodEVsID0gbnVsbDtcblxuICAgIGlmICghc2VsZWN0b3IgfHwgdHlwZW9mIHNlbGVjdG9yICE9PSAnc3RyaW5nJykgcmV0dXJuO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgICAgaWYgKCF0YXJnZXQpIHJldHVybjtcblxuICAgICAgY29uc3QgcmVjdCA9IHRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGlmIChyZWN0LndpZHRoID09PSAwICYmIHJlY3QuaGVpZ2h0ID09PSAwKSByZXR1cm47XG5cbiAgICAgIGhpZ2hsaWdodEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBoaWdobGlnaHRFbC5jbGFzc05hbWUgPSAnaGFuem8tYWktaGlnaGxpZ2h0JztcbiAgICAgIGhpZ2hsaWdodEVsLnN0eWxlLmxlZnQgPSBgJHtNYXRoLm1heCgwLCByZWN0LmxlZnQgLSA0KX1weGA7XG4gICAgICBoaWdobGlnaHRFbC5zdHlsZS50b3AgPSBgJHtNYXRoLm1heCgwLCByZWN0LnRvcCAtIDQpfXB4YDtcbiAgICAgIGhpZ2hsaWdodEVsLnN0eWxlLndpZHRoID0gYCR7cmVjdC53aWR0aCArIDh9cHhgO1xuICAgICAgaGlnaGxpZ2h0RWwuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHQgKyA4fXB4YDtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaGlnaGxpZ2h0RWwpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gSWdub3JlIGludmFsaWQgc2VsZWN0b3JzLlxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVN0YXR1cyh0ZXh0OiBzdHJpbmcpIHtcbiAgICBpZiAoIXN0YXR1c0VsKSByZXR1cm47XG5cbiAgICBjb25zdCBsYWJlbCA9IHN0YXR1c0VsLnF1ZXJ5U2VsZWN0b3IoJy5oYW56by1sYWJlbCcpO1xuICAgIGlmIChsYWJlbCkge1xuICAgICAgbGFiZWwudGV4dENvbnRlbnQgPSB0ZXh0IHx8ICdIYW56byBBSSBpcyBjb250cm9sbGluZyB0aGlzIHRhYic7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZXNjYXBlSHRtbCh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi50ZXh0Q29udGVudCA9IHRleHQ7XG4gICAgcmV0dXJuIGRpdi5pbm5lckhUTUw7XG4gIH1cblxuICByZXR1cm4geyBzaG93LCBoaWRlLCBtb3ZlQ3Vyc29yLCBoaWdobGlnaHQsIHVwZGF0ZVN0YXR1cyB9O1xufSkoKTtcblxudHlwZSBPdmVybGF5Q2hhdFJvbGUgPSAndXNlcicgfCAnYXNzaXN0YW50JyB8ICdzeXN0ZW0nO1xuXG5pbnRlcmZhY2UgT3ZlcmxheUNoYXRNZXNzYWdlIHtcbiAgcm9sZTogT3ZlcmxheUNoYXRSb2xlO1xuICBjb250ZW50OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBPdmVybGF5RWxlbWVudENvbnRleHQge1xuICBzZWxlY3Rvcjogc3RyaW5nO1xuICB0YWc6IHN0cmluZztcbiAgdGV4dDogc3RyaW5nO1xuICBodG1sOiBzdHJpbmc7XG59XG5cbmNsYXNzIEhhbnpvUGFnZU92ZXJsYXkge1xuICBwcml2YXRlIG1vdW50ZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBlbmFibGVkID0gZmFsc2U7XG4gIHByaXZhdGUgb3BlbiA9IGZhbHNlO1xuICBwcml2YXRlIHNlbmRpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSB3YXRjaE1vZGUgPSBmYWxzZTtcbiAgcHJpdmF0ZSBlZGl0TW9kZSA9IGZhbHNlO1xuICBwcml2YXRlIG1vZGVsc0xvYWRlZCA9IGZhbHNlO1xuICBwcml2YXRlIG1lc3NhZ2VzOiBPdmVybGF5Q2hhdE1lc3NhZ2VbXSA9IFtdO1xuICBwcml2YXRlIHNlbGVjdGVkQ29udGV4dDogT3ZlcmxheUVsZW1lbnRDb250ZXh0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaG92ZXJlZEVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgZWRpdGluZ0VsZW1lbnQ6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSByb290OiBIVE1MRGl2RWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGxhdW5jaGVyOiBIVE1MQnV0dG9uRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHBhbmVsOiBIVE1MRGl2RWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIG1lc3NhZ2VzRWw6IEhUTUxEaXZFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaW5wdXRFbDogSFRNTFRleHRBcmVhRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHNlbmRCdG46IEhUTUxCdXR0b25FbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgbW9kZWxFbDogSFRNTFNlbGVjdEVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjb250ZXh0RWw6IEhUTUxEaXZFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgd2F0Y2hCdG46IEhUTUxCdXR0b25FbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgZWRpdEJ0bjogSFRNTEJ1dHRvbkVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBzdGF0dXNFbDogSFRNTFNwYW5FbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaGlnaGxpZ2h0Qm94OiBIVE1MRGl2RWxlbWVudCB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuaW5qZWN0U3R5bGVzKCk7XG4gICAgdGhpcy5tb3VudCgpO1xuICAgIHRoaXMuYmluZEdsb2JhbEV2ZW50cygpO1xuICB9XG5cbiAgdG9nZ2xlKCk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5lbmFibGVkIHx8ICF0aGlzLm9wZW4pIHtcbiAgICAgIHRoaXMuc2hvdygpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHRoaXMuaGlkZSgpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHNob3coKTogdm9pZCB7XG4gICAgdGhpcy5lbnN1cmVNb3VudGVkKCk7XG4gICAgdGhpcy5lbmFibGVkID0gdHJ1ZTtcbiAgICB0aGlzLm9wZW4gPSB0cnVlO1xuICAgIHRoaXMucm9vdD8uc2V0QXR0cmlidXRlKCdkYXRhLWVuYWJsZWQnLCAndHJ1ZScpO1xuICAgIHRoaXMucm9vdD8uc2V0QXR0cmlidXRlKCdkYXRhLW9wZW4nLCAndHJ1ZScpO1xuICAgIHRoaXMubG9hZE1vZGVscygpO1xuICAgIHRoaXMuZm9jdXNJbnB1dCgpO1xuICB9XG5cbiAgaGlkZSgpOiB2b2lkIHtcbiAgICB0aGlzLm9wZW4gPSBmYWxzZTtcbiAgICB0aGlzLnJvb3Q/LnNldEF0dHJpYnV0ZSgnZGF0YS1vcGVuJywgJ2ZhbHNlJyk7XG4gICAgdGhpcy51cGRhdGVTdGF0dXMoJycpO1xuICAgIHRoaXMuY2xlYXJIaWdobGlnaHQoKTtcbiAgICB0aGlzLnNldFdhdGNoTW9kZShmYWxzZSk7XG4gICAgdGhpcy5zZXRFZGl0TW9kZShmYWxzZSk7XG4gIH1cblxuICBpc09wZW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMub3BlbjtcbiAgfVxuXG4gIHByaXZhdGUgZW5zdXJlTW91bnRlZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tb3VudGVkKSByZXR1cm47XG4gICAgdGhpcy5tb3VudCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbmplY3RTdHlsZXMoKTogdm9pZCB7XG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoYW56by1wYWdlLW92ZXJsYXktc3R5bGVzJykpIHJldHVybjtcblxuICAgIGNvbnN0IHN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICBzdHlsZS5pZCA9ICdoYW56by1wYWdlLW92ZXJsYXktc3R5bGVzJztcbiAgICBzdHlsZS50ZXh0Q29udGVudCA9IGBcbiAgICAgICNoYW56by1wYWdlLW92ZXJsYXktcm9vdCB7XG4gICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgICAgcmlnaHQ6IDIwcHg7XG4gICAgICAgIGJvdHRvbTogMjBweDtcbiAgICAgICAgei1pbmRleDogMjE0NzQ4MzY0NTtcbiAgICAgICAgZm9udC1mYW1pbHk6IC1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgJ1NlZ29lIFVJJywgc2Fucy1zZXJpZjtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgICB9XG5cbiAgICAgICNoYW56by1wYWdlLW92ZXJsYXktcm9vdCAqIHtcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgIH1cblxuICAgICAgI2hhbnpvLXBhZ2Utb3ZlcmxheS1yb290W2RhdGEtZW5hYmxlZD1cImZhbHNlXCJdIC5oYW56by1wYWdlLWxhdW5jaGVyIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDE2cHgpO1xuICAgICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2UtbGF1bmNoZXIge1xuICAgICAgICB3aWR0aDogNTRweDtcbiAgICAgICAgaGVpZ2h0OiA1NHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiA5OTk5cHg7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4yKTtcbiAgICAgICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgcmdiYSgyMiwgMjQsIDMxLCAwLjk2KSwgcmdiYSg3LCA4LCAxMiwgMC45NikpO1xuICAgICAgICBjb2xvcjogI2ZmZmZmZjtcbiAgICAgICAgYm94LXNoYWRvdzogMCAxNHB4IDM0cHggcmdiYSgwLCAwLCAwLCAwLjM1KTtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IGF1dG87XG4gICAgICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjJzIGVhc2UsIG9wYWNpdHkgMC4ycyBlYXNlO1xuICAgICAgfVxuXG4gICAgICAuaGFuem8tcGFnZS1sYXVuY2hlcjpob3ZlciB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtMnB4KTtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2UtcGFuZWwge1xuICAgICAgICB3aWR0aDogbWluKDQyMHB4LCBjYWxjKDEwMHZ3IC0gMjRweCkpO1xuICAgICAgICBtYXgtaGVpZ2h0OiBtaW4oNjIwcHgsIGNhbGMoMTAwdmggLSAyOHB4KSk7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDE2cHg7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4xNik7XG4gICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxODBkZWcsIHJnYmEoMTEsIDEzLCAxOCwgMC45NyksIHJnYmEoNywgOCwgMTIsIDAuOTcpKTtcbiAgICAgICAgY29sb3I6ICNlZWYyZmY7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIGJveC1zaGFkb3c6IDAgMjJweCA0OHB4IHJnYmEoMCwgMCwgMCwgMC40NSk7XG4gICAgICAgIHRyYW5zZm9ybS1vcmlnaW46IGJvdHRvbSByaWdodDtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDhweCkgc2NhbGUoMC45OCk7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgICBtYXJnaW4tYm90dG9tOiAxMHB4O1xuICAgICAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC4xOHMgZWFzZSwgb3BhY2l0eSAwLjE4cyBlYXNlO1xuICAgICAgfVxuXG4gICAgICAjaGFuem8tcGFnZS1vdmVybGF5LXJvb3RbZGF0YS1vcGVuPVwidHJ1ZVwiXSAuaGFuem8tcGFnZS1wYW5lbCB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgwKSBzY2FsZSgxKTtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IGF1dG87XG4gICAgICB9XG5cbiAgICAgICNoYW56by1wYWdlLW92ZXJsYXktcm9vdFtkYXRhLW9wZW49XCJ0cnVlXCJdIC5oYW56by1wYWdlLWxhdW5jaGVyIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZSgwLjkpO1xuICAgICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2UtaGVhZGVyIHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgICBwYWRkaW5nOiAxMnB4IDE0cHg7XG4gICAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMTIpO1xuICAgICAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTgwZGVnLCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMDMpLCB0cmFuc3BhcmVudCk7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLWJyYW5kIHtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICAgICAgbGV0dGVyLXNwYWNpbmc6IDAuMnB4O1xuICAgICAgICBmb250LXNpemU6IDEzcHg7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLWhlYWRlci1hY3Rpb25zIHtcbiAgICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIGdhcDogNnB4O1xuICAgICAgfVxuXG4gICAgICAuaGFuem8tY2hpcC1idG4ge1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMik7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDk5OTlweDtcbiAgICAgICAgcGFkZGluZzogNHB4IDEwcHg7XG4gICAgICAgIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4wMik7XG4gICAgICAgIGNvbG9yOiAjZDZkZWZmO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICAgIGZvbnQtc2l6ZTogMTFweDtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLWNoaXAtYnRuW2RhdGEtYWN0aXZlPVwidHJ1ZVwiXSB7XG4gICAgICAgIGJvcmRlci1jb2xvcjogcmdiYSg1NiwgMTg5LCAyNDgsIDAuNjIpO1xuICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKDE0LCAxMTYsIDE0NCwgMC4zKTtcbiAgICAgICAgY29sb3I6ICNlMGYyZmU7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1pY29uLWJ0biB7XG4gICAgICAgIHdpZHRoOiAyOHB4O1xuICAgICAgICBoZWlnaHQ6IDI4cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjE4KTtcbiAgICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICAgIGNvbG9yOiAjZTVlN2ViO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2UtbWV0YSB7XG4gICAgICAgIHBhZGRpbmc6IDEwcHggMTRweCA2cHggMTRweDtcbiAgICAgICAgZGlzcGxheTogZ3JpZDtcbiAgICAgICAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAxZnIgYXV0bztcbiAgICAgICAgZ2FwOiA4cHg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLWNvbnRleHQge1xuICAgICAgICBmb250LXNpemU6IDExcHg7XG4gICAgICAgIGNvbG9yOiAjYTViNGZjO1xuICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2Utc3RhdHVzIHtcbiAgICAgICAgZm9udC1zaXplOiAxMXB4O1xuICAgICAgICBjb2xvcjogIzkzYzVmZDtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLW1vZGVsLXJvdyB7XG4gICAgICAgIHBhZGRpbmc6IDAgMTRweCA4cHggMTRweDtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLW1vZGVsLXJvdyBzZWxlY3Qge1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogOHB4O1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMTYpO1xuICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMDMpO1xuICAgICAgICBjb2xvcjogI2YxZjVmOTtcbiAgICAgICAgcGFkZGluZzogN3B4IDlweDtcbiAgICAgICAgZm9udC1zaXplOiAxMnB4O1xuICAgICAgfVxuXG4gICAgICAuaGFuem8tcGFnZS1tZXNzYWdlcyB7XG4gICAgICAgIGZsZXg6IDE7XG4gICAgICAgIG1pbi1oZWlnaHQ6IDIwMHB4O1xuICAgICAgICBtYXgtaGVpZ2h0OiAzNzBweDtcbiAgICAgICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICAgICAgcGFkZGluZzogOHB4IDE0cHggMTJweCAxNHB4O1xuICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgICBnYXA6IDhweDtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2UtbXNnIHtcbiAgICAgICAgcGFkZGluZzogOXB4IDEwcHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDEwcHg7XG4gICAgICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDEuNDU7XG4gICAgICAgIHdvcmQtYnJlYWs6IGJyZWFrLXdvcmQ7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLW1zZy51c2VyIHtcbiAgICAgICAgYWxpZ24tc2VsZjogZmxleC1lbmQ7XG4gICAgICAgIG1heC13aWR0aDogODglO1xuICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKDU5LCAxMzAsIDI0NiwgMC4yKTtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSg1OSwgMTMwLCAyNDYsIDAuNCk7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLW1zZy5hc3Npc3RhbnQge1xuICAgICAgICBhbGlnbi1zZWxmOiBmbGV4LXN0YXJ0O1xuICAgICAgICBtYXgtd2lkdGg6IDkyJTtcbiAgICAgICAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjA1KTtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjEyKTtcbiAgICAgIH1cblxuICAgICAgLmhhbnpvLXBhZ2UtY29tcG9zZXIge1xuICAgICAgICBib3JkZXItdG9wOiAxcHggc29saWQgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjEpO1xuICAgICAgICBwYWRkaW5nOiAxMHB4IDEycHg7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGdhcDogOHB4O1xuICAgICAgICBhbGlnbi1pdGVtczogZmxleC1lbmQ7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLWNvbXBvc2VyIHRleHRhcmVhIHtcbiAgICAgICAgZmxleDogMTtcbiAgICAgICAgbWluLWhlaWdodDogMzhweDtcbiAgICAgICAgbWF4LWhlaWdodDogMTEwcHg7XG4gICAgICAgIHJlc2l6ZTogbm9uZTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMTBweDtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjE3KTtcbiAgICAgICAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjAzKTtcbiAgICAgICAgY29sb3I6ICNmOGZhZmM7XG4gICAgICAgIHBhZGRpbmc6IDlweCAxMXB4O1xuICAgICAgICBmb250LXNpemU6IDEycHg7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLWNvbXBvc2VyIGJ1dHRvbiB7XG4gICAgICAgIG1pbi13aWR0aDogNjhweDtcbiAgICAgICAgaGVpZ2h0OiAzOHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDM3LCA5OSwgMjM1LCAwLjY1KTtcbiAgICAgICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDE4MGRlZywgcmdiYSgzNywgOTksIDIzNSwgMC45NSksIHJnYmEoMzAsIDY0LCAxNzUsIDAuOTUpKTtcbiAgICAgICAgY29sb3I6ICNlZmY2ZmY7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgfVxuXG4gICAgICAuaGFuem8tcGFnZS1jb21wb3NlciBidXR0b246ZGlzYWJsZWQge1xuICAgICAgICBvcGFjaXR5OiAwLjU1O1xuICAgICAgICBjdXJzb3I6IGRlZmF1bHQ7XG4gICAgICB9XG5cbiAgICAgIC5oYW56by1wYWdlLWhpZ2hsaWdodCB7XG4gICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgICAgei1pbmRleDogMjE0NzQ4MzY0NDtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgICAgIGJvcmRlcjogMnB4IHNvbGlkIHJnYmEoNTYsIDE4OSwgMjQ4LCAwLjk1KTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogNnB4O1xuICAgICAgICBib3gtc2hhZG93OiAwIDAgMCAycHggcmdiYSgxNCwgMTE2LCAxNDQsIDAuMik7XG4gICAgICB9XG5cbiAgICAgIFtkYXRhLWhhbnpvLWlubGluZS1lZGl0aW5nPVwidHJ1ZVwiXSB7XG4gICAgICAgIG91dGxpbmU6IDJweCBzb2xpZCByZ2JhKDI1MSwgMTkxLCAzNiwgMC45MikgIWltcG9ydGFudDtcbiAgICAgICAgb3V0bGluZS1vZmZzZXQ6IDJweCAhaW1wb3J0YW50O1xuICAgICAgfVxuICAgIGA7XG4gICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG4gIH1cblxuICBwcml2YXRlIG1vdW50KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1vdW50ZWQpIHJldHVybjtcblxuICAgIHRoaXMucm9vdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMucm9vdC5pZCA9ICdoYW56by1wYWdlLW92ZXJsYXktcm9vdCc7XG4gICAgdGhpcy5yb290LnNldEF0dHJpYnV0ZSgnZGF0YS1vcGVuJywgJ2ZhbHNlJyk7XG4gICAgdGhpcy5yb290LnNldEF0dHJpYnV0ZSgnZGF0YS1lbmFibGVkJywgJ2ZhbHNlJyk7XG4gICAgdGhpcy5yb290LmlubmVySFRNTCA9IGBcbiAgICAgIDxkaXYgY2xhc3M9XCJoYW56by1wYWdlLXBhbmVsXCIgcm9sZT1cImRpYWxvZ1wiIGFyaWEtbGFiZWw9XCJIYW56byBQYWdlIEFzc2lzdGFudFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaGFuem8tcGFnZS1oZWFkZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGFuem8tcGFnZS1icmFuZFwiPkhhbnpvIE92ZXJsYXk8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGFuem8tcGFnZS1oZWFkZXItYWN0aW9uc1wiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImhhbnpvLWNoaXAtYnRuXCIgZGF0YS1yb2xlPVwid2F0Y2hcIiBkYXRhLWFjdGl2ZT1cImZhbHNlXCIgdGl0bGU9XCJXYXRjaCBlbGVtZW50cyBvbiBob3ZlclwiPldhdGNoPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiaGFuem8tY2hpcC1idG5cIiBkYXRhLXJvbGU9XCJlZGl0XCIgZGF0YS1hY3RpdmU9XCJmYWxzZVwiIHRpdGxlPVwiQ2xpY2sgYW55IGVsZW1lbnQgdG8gZWRpdCB0ZXh0XCI+RWRpdDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImhhbnpvLWljb24tYnRuXCIgZGF0YS1yb2xlPVwiY2xvc2VcIiB0aXRsZT1cIk1pbmltaXplXCI+XHUwMEQ3PC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaGFuem8tcGFnZS1tZXRhXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImhhbnpvLXBhZ2UtY29udGV4dFwiPlVzZSBXYXRjaCB0byBpbnNwZWN0IHBhZ2UgZWxlbWVudHMuPC9kaXY+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJoYW56by1wYWdlLXN0YXR1c1wiPjwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJoYW56by1tb2RlbC1yb3dcIj5cbiAgICAgICAgICA8c2VsZWN0IGRhdGEtcm9sZT1cIm1vZGVsXCI+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiY2xhdWRlLXNvbm5ldC00LTIwMjUwNTE0XCI+Q2xhdWRlIFNvbm5ldCA0PC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiY2xhdWRlLW9wdXMtNC0yMDI1MDUxNFwiPkNsYXVkZSBPcHVzIDQ8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJncHQtNG9cIj5HUFQtNG88L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJ6ZW4tY29kZXItZmxhc2hcIj5aZW4gQ29kZXIgRmxhc2g8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJ6ZW4tbWF4XCI+WmVuIE1heDwvb3B0aW9uPlxuICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImhhbnpvLXBhZ2UtbWVzc2FnZXNcIiBkYXRhLXJvbGU9XCJtZXNzYWdlc1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJoYW56by1wYWdlLW1zZyBhc3Npc3RhbnRcIj5Bc2sgYWJvdXQgdGhpcyBwYWdlLCBpbnNwZWN0IGFueSBlbGVtZW50LCBvciB0dXJuIG9uIEVkaXQgbW9kZSB0byBjaGFuZ2UgdGV4dCBpbi1wbGFjZS48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJoYW56by1wYWdlLWNvbXBvc2VyXCI+XG4gICAgICAgICAgPHRleHRhcmVhIGRhdGEtcm9sZT1cImlucHV0XCIgcm93cz1cIjFcIiBwbGFjZWhvbGRlcj1cIkFzayBhYm91dCB0aGlzIHBhZ2UuLi5cIj48L3RleHRhcmVhPlxuICAgICAgICAgIDxidXR0b24gZGF0YS1yb2xlPVwic2VuZFwiIHR5cGU9XCJidXR0b25cIj5Bc2s8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJoYW56by1wYWdlLWxhdW5jaGVyXCIgZGF0YS1yb2xlPVwibGF1bmNoZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJPcGVuIEhhbnpvIE92ZXJsYXlcIj5BSTwvYnV0dG9uPlxuICAgIGA7XG5cbiAgICB0aGlzLnBhbmVsID0gdGhpcy5yb290LnF1ZXJ5U2VsZWN0b3IoJy5oYW56by1wYWdlLXBhbmVsJyk7XG4gICAgdGhpcy5sYXVuY2hlciA9IHRoaXMucm9vdC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1yb2xlPVwibGF1bmNoZXJcIl0nKTtcbiAgICB0aGlzLm1lc3NhZ2VzRWwgPSB0aGlzLnJvb3QucXVlcnlTZWxlY3RvcignW2RhdGEtcm9sZT1cIm1lc3NhZ2VzXCJdJyk7XG4gICAgdGhpcy5pbnB1dEVsID0gdGhpcy5yb290LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXJvbGU9XCJpbnB1dFwiXScpO1xuICAgIHRoaXMuc2VuZEJ0biA9IHRoaXMucm9vdC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1yb2xlPVwic2VuZFwiXScpO1xuICAgIHRoaXMubW9kZWxFbCA9IHRoaXMucm9vdC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1yb2xlPVwibW9kZWxcIl0nKTtcbiAgICB0aGlzLmNvbnRleHRFbCA9IHRoaXMucm9vdC5xdWVyeVNlbGVjdG9yKCcuaGFuem8tcGFnZS1jb250ZXh0Jyk7XG4gICAgdGhpcy53YXRjaEJ0biA9IHRoaXMucm9vdC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1yb2xlPVwid2F0Y2hcIl0nKTtcbiAgICB0aGlzLmVkaXRCdG4gPSB0aGlzLnJvb3QucXVlcnlTZWxlY3RvcignW2RhdGEtcm9sZT1cImVkaXRcIl0nKTtcbiAgICB0aGlzLnN0YXR1c0VsID0gdGhpcy5yb290LnF1ZXJ5U2VsZWN0b3IoJy5oYW56by1wYWdlLXN0YXR1cycpO1xuXG4gICAgdGhpcy5sYXVuY2hlcj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB0aGlzLnNob3coKSk7XG4gICAgdGhpcy5yb290LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXJvbGU9XCJjbG9zZVwiXScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHRoaXMuaGlkZSgpKTtcbiAgICB0aGlzLndhdGNoQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHRoaXMuc2V0V2F0Y2hNb2RlKCF0aGlzLndhdGNoTW9kZSkpO1xuICAgIHRoaXMuZWRpdEJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB0aGlzLnNldEVkaXRNb2RlKCF0aGlzLmVkaXRNb2RlKSk7XG4gICAgdGhpcy5zZW5kQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHRoaXMuYXNrUGFnZVF1ZXN0aW9uKCkpO1xuICAgIHRoaXMuaW5wdXRFbD8uYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChldmVudCkgPT4ge1xuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJyAmJiAhZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5hc2tQYWdlUXVlc3Rpb24oKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLmlucHV0RWw/LmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLmlucHV0RWwpIHJldHVybjtcbiAgICAgIHRoaXMuaW5wdXRFbC5zdHlsZS5oZWlnaHQgPSAnYXV0byc7XG4gICAgICB0aGlzLmlucHV0RWwuc3R5bGUuaGVpZ2h0ID0gYCR7TWF0aC5taW4odGhpcy5pbnB1dEVsLnNjcm9sbEhlaWdodCwgMTEwKX1weGA7XG4gICAgfSk7XG5cbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5yb290KTtcbiAgICB0aGlzLm1vdW50ZWQgPSB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBiaW5kR2xvYmFsRXZlbnRzKCk6IHZvaWQge1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIChldmVudCkgPT4gdGhpcy5vbk1vdXNlTW92ZShldmVudCksIHRydWUpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB0aGlzLm9uRG9jdW1lbnRDbGljayhldmVudCksIHRydWUpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCAoZXZlbnQpID0+IHRoaXMub25LZXlEb3duKGV2ZW50KSwgdHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VNb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLndhdGNoTW9kZSkgcmV0dXJuO1xuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuZ2V0UGFnZVRhcmdldChldmVudC50YXJnZXQpO1xuICAgIGlmICghdGFyZ2V0KSByZXR1cm47XG4gICAgdGhpcy5ob3ZlcmVkRWxlbWVudCA9IHRhcmdldDtcbiAgICB0aGlzLnNob3dIaWdobGlnaHQodGFyZ2V0KTtcbiAgICBpZiAoIXRoaXMuc2VsZWN0ZWRDb250ZXh0KSB7XG4gICAgICB0aGlzLmNvbnRleHRFbCAmJiAodGhpcy5jb250ZXh0RWwudGV4dENvbnRlbnQgPSB0aGlzLmdldEVsZW1lbnRTdW1tYXJ5KHRhcmdldCkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25Eb2N1bWVudENsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLndhdGNoTW9kZSAmJiAhdGhpcy5lZGl0TW9kZSkgcmV0dXJuO1xuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuZ2V0UGFnZVRhcmdldChldmVudC50YXJnZXQpO1xuICAgIGlmICghdGFyZ2V0KSByZXR1cm47XG5cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXG4gICAgaWYgKHRoaXMud2F0Y2hNb2RlKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkQ29udGV4dCA9IHRoaXMuY2FwdHVyZUVsZW1lbnRDb250ZXh0KHRhcmdldCk7XG4gICAgICB0aGlzLmNvbnRleHRFbCAmJiAodGhpcy5jb250ZXh0RWwudGV4dENvbnRlbnQgPSB0aGlzLmdldEVsZW1lbnRTdW1tYXJ5KHRhcmdldCkpO1xuICAgICAgdGhpcy51cGRhdGVTdGF0dXMoJ0VsZW1lbnQgc2VsZWN0ZWQnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5lZGl0TW9kZSkge1xuICAgICAgdGhpcy5lbmFibGVJbmxpbmVFZGl0KHRhcmdldCk7XG4gICAgICB0aGlzLnVwZGF0ZVN0YXR1cygnRWRpdGluZyBlbGVtZW50Jyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvbktleURvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnRXNjYXBlJykge1xuICAgICAgaWYgKHRoaXMuZWRpdGluZ0VsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5kaXNhYmxlSW5saW5lRWRpdCh0aGlzLmVkaXRpbmdFbGVtZW50LCBmYWxzZSk7XG4gICAgICAgIHRoaXMudXBkYXRlU3RhdHVzKCdFZGl0IGNhbmNlbGVkJyk7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm9wZW4pIHtcbiAgICAgICAgdGhpcy5oaWRlKCk7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRQYWdlVGFyZ2V0KHRhcmdldDogRXZlbnRUYXJnZXQgfCBudWxsKTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgICBpZiAoISh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHJldHVybiBudWxsO1xuICAgIGlmICh0aGlzLnJvb3Q/LmNvbnRhaW5zKHRhcmdldCkpIHJldHVybiBudWxsO1xuICAgIGlmICghdGFyZ2V0LmlzQ29ubmVjdGVkKSByZXR1cm4gbnVsbDtcbiAgICBpZiAodGFyZ2V0LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2h0bWwnIHx8IHRhcmdldC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdib2R5JykgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfVxuXG4gIHByaXZhdGUgc2V0V2F0Y2hNb2RlKGFjdGl2ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMud2F0Y2hNb2RlID0gYWN0aXZlO1xuICAgIGlmIChhY3RpdmUpIHRoaXMuc2V0RWRpdE1vZGUoZmFsc2UpO1xuICAgIHRoaXMud2F0Y2hCdG4/LnNldEF0dHJpYnV0ZSgnZGF0YS1hY3RpdmUnLCBhY3RpdmUgPyAndHJ1ZScgOiAnZmFsc2UnKTtcbiAgICBpZiAoIWFjdGl2ZSkge1xuICAgICAgdGhpcy5ob3ZlcmVkRWxlbWVudCA9IG51bGw7XG4gICAgICB0aGlzLmNsZWFySGlnaGxpZ2h0KCk7XG4gICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRDb250ZXh0ICYmIHRoaXMuY29udGV4dEVsKSB7XG4gICAgICAgIHRoaXMuY29udGV4dEVsLnRleHRDb250ZW50ID0gJ1VzZSBXYXRjaCB0byBpbnNwZWN0IHBhZ2UgZWxlbWVudHMuJztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51cGRhdGVTdGF0dXMoJ1dhdGNoIG1vZGUgb24nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldEVkaXRNb2RlKGFjdGl2ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuZWRpdE1vZGUgPSBhY3RpdmU7XG4gICAgaWYgKGFjdGl2ZSkgdGhpcy5zZXRXYXRjaE1vZGUoZmFsc2UpO1xuICAgIHRoaXMuZWRpdEJ0bj8uc2V0QXR0cmlidXRlKCdkYXRhLWFjdGl2ZScsIGFjdGl2ZSA/ICd0cnVlJyA6ICdmYWxzZScpO1xuICAgIGlmICghYWN0aXZlICYmIHRoaXMuZWRpdGluZ0VsZW1lbnQpIHtcbiAgICAgIHRoaXMuZGlzYWJsZUlubGluZUVkaXQodGhpcy5lZGl0aW5nRWxlbWVudCwgdHJ1ZSk7XG4gICAgfSBlbHNlIGlmIChhY3RpdmUpIHtcbiAgICAgIHRoaXMudXBkYXRlU3RhdHVzKCdFZGl0IG1vZGUgb24nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGVuYWJsZUlubGluZUVkaXQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lZGl0aW5nRWxlbWVudCAmJiB0aGlzLmVkaXRpbmdFbGVtZW50ICE9PSBlbGVtZW50KSB7XG4gICAgICB0aGlzLmRpc2FibGVJbmxpbmVFZGl0KHRoaXMuZWRpdGluZ0VsZW1lbnQsIHRydWUpO1xuICAgIH1cblxuICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCB8fCBlbGVtZW50IGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCkge1xuICAgICAgZWxlbWVudC5mb2N1cygpO1xuICAgICAgdGhpcy5lZGl0aW5nRWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFlbGVtZW50Lmhhc0F0dHJpYnV0ZSgnZGF0YS1oYW56by1vcmlnaW5hbC1odG1sJykpIHtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLWhhbnpvLW9yaWdpbmFsLWh0bWwnLCBlbGVtZW50LmlubmVySFRNTCk7XG4gICAgfVxuICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnLCAndHJ1ZScpO1xuICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdzcGVsbGNoZWNrJywgJ3RydWUnKTtcbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1oYW56by1pbmxpbmUtZWRpdGluZycsICd0cnVlJyk7XG4gICAgZWxlbWVudC5mb2N1cygpO1xuICAgIHRoaXMuZWRpdGluZ0VsZW1lbnQgPSBlbGVtZW50O1xuXG4gICAgY29uc3Qga2V5ZG93bkhhbmRsZXIgPSAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgIGlmIChldmVudC5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICAgIHRoaXMuZGlzYWJsZUlubGluZUVkaXQoZWxlbWVudCwgZmFsc2UpO1xuICAgICAgICB0aGlzLnVwZGF0ZVN0YXR1cygnRWRpdCByZXZlcnRlZCcpO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJyAmJiAhZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5kaXNhYmxlSW5saW5lRWRpdChlbGVtZW50LCB0cnVlKTtcbiAgICAgICAgdGhpcy51cGRhdGVTdGF0dXMoJ0VkaXQgYXBwbGllZCcpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBibHVySGFuZGxlciA9ICgpID0+IHtcbiAgICAgIHRoaXMuZGlzYWJsZUlubGluZUVkaXQoZWxlbWVudCwgdHJ1ZSk7XG4gICAgICB0aGlzLnVwZGF0ZVN0YXR1cygnRWRpdCBhcHBsaWVkJyk7XG4gICAgfTtcblxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGtleWRvd25IYW5kbGVyLCB7IG9uY2U6IHRydWUgfSk7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdibHVyJywgYmx1ckhhbmRsZXIsIHsgb25jZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZGlzYWJsZUlubGluZUVkaXQoZWxlbWVudDogSFRNTEVsZW1lbnQsIGtlZXBDaGFuZ2VzOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKCFrZWVwQ2hhbmdlcykge1xuICAgICAgY29uc3Qgb3JpZ2luYWwgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1oYW56by1vcmlnaW5hbC1odG1sJyk7XG4gICAgICBpZiAob3JpZ2luYWwgIT09IG51bGwpIHtcbiAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBvcmlnaW5hbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJyk7XG4gICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3NwZWxsY2hlY2snKTtcbiAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS1oYW56by1pbmxpbmUtZWRpdGluZycpO1xuICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdkYXRhLWhhbnpvLW9yaWdpbmFsLWh0bWwnKTtcblxuICAgIGlmICh0aGlzLmVkaXRpbmdFbGVtZW50ID09PSBlbGVtZW50KSB7XG4gICAgICB0aGlzLmVkaXRpbmdFbGVtZW50ID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNob3dIaWdobGlnaHQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcbiAgICBjb25zdCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBpZiAocmVjdC53aWR0aCA9PT0gMCAmJiByZWN0LmhlaWdodCA9PT0gMCkge1xuICAgICAgdGhpcy5jbGVhckhpZ2hsaWdodCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5oaWdobGlnaHRCb3gpIHtcbiAgICAgIHRoaXMuaGlnaGxpZ2h0Qm94ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICB0aGlzLmhpZ2hsaWdodEJveC5jbGFzc05hbWUgPSAnaGFuem8tcGFnZS1oaWdobGlnaHQnO1xuICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuaGlnaGxpZ2h0Qm94KTtcbiAgICB9XG5cbiAgICB0aGlzLmhpZ2hsaWdodEJveC5zdHlsZS5sZWZ0ID0gYCR7TWF0aC5tYXgoMCwgcmVjdC5sZWZ0IC0gMyl9cHhgO1xuICAgIHRoaXMuaGlnaGxpZ2h0Qm94LnN0eWxlLnRvcCA9IGAke01hdGgubWF4KDAsIHJlY3QudG9wIC0gMyl9cHhgO1xuICAgIHRoaXMuaGlnaGxpZ2h0Qm94LnN0eWxlLndpZHRoID0gYCR7cmVjdC53aWR0aCArIDZ9cHhgO1xuICAgIHRoaXMuaGlnaGxpZ2h0Qm94LnN0eWxlLmhlaWdodCA9IGAke3JlY3QuaGVpZ2h0ICsgNn1weGA7XG4gIH1cblxuICBwcml2YXRlIGNsZWFySGlnaGxpZ2h0KCk6IHZvaWQge1xuICAgIHRoaXMuaGlnaGxpZ2h0Qm94Py5yZW1vdmUoKTtcbiAgICB0aGlzLmhpZ2hsaWdodEJveCA9IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGNhcHR1cmVFbGVtZW50Q29udGV4dChlbGVtZW50OiBIVE1MRWxlbWVudCk6IE92ZXJsYXlFbGVtZW50Q29udGV4dCB7XG4gICAgY29uc3QgdGV4dCA9IHRoaXMubm9ybWFsaXplVGV4dChlbGVtZW50LmlubmVyVGV4dCB8fCBlbGVtZW50LnRleHRDb250ZW50IHx8ICcnKTtcbiAgICByZXR1cm4ge1xuICAgICAgc2VsZWN0b3I6IHRoaXMuYnVpbGRTZWxlY3RvcihlbGVtZW50KSxcbiAgICAgIHRhZzogZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCksXG4gICAgICB0ZXh0OiB0ZXh0LnNsaWNlKDAsIDgwMCksXG4gICAgICBodG1sOiBlbGVtZW50Lm91dGVySFRNTC5zbGljZSgwLCAxMjAwKSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFNlbGVjdG9yKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogc3RyaW5nIHtcbiAgICBpZiAoZWxlbWVudC5pZCkgcmV0dXJuIGAjJHtlbGVtZW50LmlkfWA7XG5cbiAgICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgY3VycmVudDogSFRNTEVsZW1lbnQgfCBudWxsID0gZWxlbWVudDtcbiAgICBsZXQgZGVwdGggPSAwO1xuXG4gICAgd2hpbGUgKGN1cnJlbnQgJiYgZGVwdGggPCA2KSB7XG4gICAgICBsZXQgcGFydCA9IGN1cnJlbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKGN1cnJlbnQuY2xhc3NMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgY2xhc3NOYW1lID0gQXJyYXkuZnJvbShjdXJyZW50LmNsYXNzTGlzdCkuc2xpY2UoMCwgMikuam9pbignLicpO1xuICAgICAgICBpZiAoY2xhc3NOYW1lKSBwYXJ0ICs9IGAuJHtjbGFzc05hbWV9YDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBhcmVudCA9IGN1cnJlbnQucGFyZW50RWxlbWVudDtcbiAgICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgY29uc3Qgc2libGluZ3MgPSBBcnJheS5mcm9tKHBhcmVudC5jaGlsZHJlbikuZmlsdGVyKChub2RlKSA9PiBub2RlLnRhZ05hbWUgPT09IGN1cnJlbnQhLnRhZ05hbWUpO1xuICAgICAgICBpZiAoc2libGluZ3MubGVuZ3RoID4gMSkge1xuICAgICAgICAgIGNvbnN0IGluZGV4ID0gc2libGluZ3MuaW5kZXhPZihjdXJyZW50KSArIDE7XG4gICAgICAgICAgcGFydCArPSBgOm50aC1vZi10eXBlKCR7aW5kZXh9KWA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHBhcnRzLnVuc2hpZnQocGFydCk7XG4gICAgICBjdXJyZW50ID0gcGFyZW50O1xuICAgICAgZGVwdGggKz0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFydHMuam9pbignID4gJyk7XG4gIH1cblxuICBwcml2YXRlIG5vcm1hbGl6ZVRleHQodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL1xccysvZywgJyAnKS50cmltKCk7XG4gIH1cblxuICBwcml2YXRlIGdldEVsZW1lbnRTdW1tYXJ5KGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogc3RyaW5nIHtcbiAgICBjb25zdCBjdHggPSB0aGlzLmNhcHR1cmVFbGVtZW50Q29udGV4dChlbGVtZW50KTtcbiAgICByZXR1cm4gYCR7Y3R4LnRhZ30gXHUyMDIyICR7Y3R4LnNlbGVjdG9yfWA7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRNb2RlbHMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMubW9kZWxzTG9hZGVkIHx8ICF0aGlzLm1vZGVsRWwpIHJldHVybjtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNocm9tZS5ydW50aW1lLnNlbmRNZXNzYWdlKHsgYWN0aW9uOiAnY2hhdC5saXN0TW9kZWxzJyB9KTtcbiAgICAgIGlmICghcmVzcG9uc2U/LnN1Y2Nlc3MgfHwgIUFycmF5LmlzQXJyYXkocmVzcG9uc2UubW9kZWxzKSB8fCAhcmVzcG9uc2UubW9kZWxzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHByZXZpb3VzID0gdGhpcy5tb2RlbEVsLnZhbHVlO1xuICAgICAgdGhpcy5tb2RlbEVsLmlubmVySFRNTCA9ICcnO1xuICAgICAgZm9yIChjb25zdCBtb2RlbCBvZiByZXNwb25zZS5tb2RlbHMpIHtcbiAgICAgICAgaWYgKCFtb2RlbD8uaWQpIGNvbnRpbnVlO1xuICAgICAgICBjb25zdCBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRpb24nKTtcbiAgICAgICAgb3B0aW9uLnZhbHVlID0gbW9kZWwuaWQ7XG4gICAgICAgIG9wdGlvbi50ZXh0Q29udGVudCA9IG1vZGVsLm5hbWUgfHwgbW9kZWwuaWQ7XG4gICAgICAgIHRoaXMubW9kZWxFbC5hcHBlbmRDaGlsZChvcHRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKHByZXZpb3VzICYmIEFycmF5LmZyb20odGhpcy5tb2RlbEVsLm9wdGlvbnMpLnNvbWUoKG9wdCkgPT4gb3B0LnZhbHVlID09PSBwcmV2aW91cykpIHtcbiAgICAgICAgdGhpcy5tb2RlbEVsLnZhbHVlID0gcHJldmlvdXM7XG4gICAgICB9XG4gICAgICB0aGlzLm1vZGVsc0xvYWRlZCA9IHRydWU7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBLZWVwIGxvY2FsIGRlZmF1bHRzIGlmIG1vZGVsIGZldGNoIGZhaWxzLlxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZm9jdXNJbnB1dCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaW5wdXRFbCkgcmV0dXJuO1xuICAgIHRoaXMuaW5wdXRFbC5mb2N1cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBlbmRNZXNzYWdlKHJvbGU6ICd1c2VyJyB8ICdhc3Npc3RhbnQnLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubWVzc2FnZXNFbCkgcmV0dXJuO1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5jbGFzc05hbWUgPSBgaGFuem8tcGFnZS1tc2cgJHtyb2xlfWA7XG4gICAgZGl2LnRleHRDb250ZW50ID0gY29udGVudDtcbiAgICB0aGlzLm1lc3NhZ2VzRWwuYXBwZW5kQ2hpbGQoZGl2KTtcbiAgICB0aGlzLm1lc3NhZ2VzRWwuc2Nyb2xsVG9wID0gdGhpcy5tZXNzYWdlc0VsLnNjcm9sbEhlaWdodDtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlU3RhdHVzKHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zdGF0dXNFbCkgcmV0dXJuO1xuICAgIHRoaXMuc3RhdHVzRWwudGV4dENvbnRlbnQgPSB0ZXh0O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFBhZ2VDb250ZXh0KCk6IHN0cmluZyB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gdGhpcy5ub3JtYWxpemVUZXh0KHdpbmRvdy5nZXRTZWxlY3Rpb24/LigpPy50b1N0cmluZygpIHx8ICcnKTtcbiAgICBjb25zdCBjb250ZXh0TGluZXMgPSBbXG4gICAgICBgVVJMOiAke2xvY2F0aW9uLmhyZWZ9YCxcbiAgICAgIGBUaXRsZTogJHtkb2N1bWVudC50aXRsZSB8fCAnVW50aXRsZWQnfWAsXG4gICAgXTtcblxuICAgIGlmIChzZWxlY3Rpb24pIHtcbiAgICAgIGNvbnRleHRMaW5lcy5wdXNoKGBUZXh0U2VsZWN0aW9uOiAke3NlbGVjdGlvbi5zbGljZSgwLCA2MDApfWApO1xuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnRDb250ZXh0ID0gdGhpcy5zZWxlY3RlZENvbnRleHQgfHwgKHRoaXMuaG92ZXJlZEVsZW1lbnQgPyB0aGlzLmNhcHR1cmVFbGVtZW50Q29udGV4dCh0aGlzLmhvdmVyZWRFbGVtZW50KSA6IG51bGwpO1xuICAgIGlmIChlbGVtZW50Q29udGV4dCkge1xuICAgICAgY29udGV4dExpbmVzLnB1c2goYEVsZW1lbnRTZWxlY3RvcjogJHtlbGVtZW50Q29udGV4dC5zZWxlY3Rvcn1gKTtcbiAgICAgIGlmIChlbGVtZW50Q29udGV4dC50ZXh0KSBjb250ZXh0TGluZXMucHVzaChgRWxlbWVudFRleHQ6ICR7ZWxlbWVudENvbnRleHQudGV4dC5zbGljZSgwLCA2MDApfWApO1xuICAgICAgY29udGV4dExpbmVzLnB1c2goYEVsZW1lbnRIVE1MOiAke2VsZW1lbnRDb250ZXh0Lmh0bWwuc2xpY2UoMCwgODAwKX1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29udGV4dExpbmVzLmpvaW4oJ1xcbicpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhc2tQYWdlUXVlc3Rpb24oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuc2VuZGluZyB8fCAhdGhpcy5pbnB1dEVsKSByZXR1cm47XG5cbiAgICBjb25zdCBwcm9tcHQgPSB0aGlzLm5vcm1hbGl6ZVRleHQodGhpcy5pbnB1dEVsLnZhbHVlKTtcbiAgICBpZiAoIXByb21wdCkgcmV0dXJuO1xuXG4gICAgY29uc3QgdG9rZW5SZXNwID0gYXdhaXQgY2hyb21lLnJ1bnRpbWUuc2VuZE1lc3NhZ2UoeyBhY3Rpb246ICdhdXRoLmdldFRva2VuJyB9KTtcbiAgICBpZiAoIXRva2VuUmVzcD8uc3VjY2VzcyB8fCAhdG9rZW5SZXNwLnRva2VuKSB7XG4gICAgICB0aGlzLmFwcGVuZE1lc3NhZ2UoJ2Fzc2lzdGFudCcsICdQbGVhc2Ugc2lnbiBpbiBmcm9tIHRoZSBIYW56byBzaWRlYmFyL3BvcHVwIGJlZm9yZSB1c2luZyBwYWdlIGNoYXQuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZW5kaW5nID0gdHJ1ZTtcbiAgICB0aGlzLnVwZGF0ZVN0YXR1cygnVGhpbmtpbmcuLi4nKTtcbiAgICB0aGlzLnNlbmRCdG4gJiYgKHRoaXMuc2VuZEJ0bi5kaXNhYmxlZCA9IHRydWUpO1xuXG4gICAgdGhpcy5pbnB1dEVsLnZhbHVlID0gJyc7XG4gICAgdGhpcy5pbnB1dEVsLnN0eWxlLmhlaWdodCA9ICdhdXRvJztcbiAgICB0aGlzLmFwcGVuZE1lc3NhZ2UoJ3VzZXInLCBwcm9tcHQpO1xuXG4gICAgY29uc3Qgc3lzdGVtQ29udGV4dCA9IHRoaXMuYnVpbGRQYWdlQ29udGV4dCgpO1xuICAgIGNvbnN0IG1vZGVsID0gdGhpcy5tb2RlbEVsPy52YWx1ZSB8fCAnZ3B0LTRvJztcbiAgICBjb25zdCByZXF1ZXN0TWVzc2FnZXM6IE92ZXJsYXlDaGF0TWVzc2FnZVtdID0gW1xuICAgICAge1xuICAgICAgICByb2xlOiAnc3lzdGVtJyxcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICdZb3UgYXJlIEhhbnpvIHBhZ2Ugb3ZlcmxheSBhc3Npc3RhbnQuJyxcbiAgICAgICAgICAnVXNlIHByb3ZpZGVkIHBhZ2UgY29udGV4dCBhbmQgc2VsZWN0ZWQgZWxlbWVudCBjb250ZXh0IHdoZW4gcmVsZXZhbnQuJyxcbiAgICAgICAgICAnQmUgY29uY2lzZSBhbmQgcHJvdmlkZSBjb25jcmV0ZSBVSSBvciBET00gZWRpdCBzdWdnZXN0aW9ucyB3aGVuIGFza2VkLicsXG4gICAgICAgICAgJycsXG4gICAgICAgICAgc3lzdGVtQ29udGV4dCxcbiAgICAgICAgXS5qb2luKCdcXG4nKSxcbiAgICAgIH0sXG4gICAgICAuLi50aGlzLm1lc3NhZ2VzLnNsaWNlKC04KSxcbiAgICAgIHsgcm9sZTogJ3VzZXInLCBjb250ZW50OiBwcm9tcHQgfSxcbiAgICBdO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2hyb21lLnJ1bnRpbWUuc2VuZE1lc3NhZ2Uoe1xuICAgICAgICBhY3Rpb246ICdjaGF0LmNvbXBsZXRlJyxcbiAgICAgICAgbW9kZWwsXG4gICAgICAgIG1lc3NhZ2VzOiByZXF1ZXN0TWVzc2FnZXMsXG4gICAgICB9KTtcblxuICAgICAgaWYgKCFyZXNwb25zZT8uc3VjY2VzcyB8fCAhcmVzcG9uc2UuY29udGVudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IocmVzcG9uc2U/LmVycm9yIHx8ICdObyByZXNwb25zZSBmcm9tIGNoYXQgc2VydmljZScpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBhbnN3ZXIgPSBTdHJpbmcocmVzcG9uc2UuY29udGVudCkudHJpbSgpO1xuICAgICAgdGhpcy5hcHBlbmRNZXNzYWdlKCdhc3Npc3RhbnQnLCBhbnN3ZXIgfHwgJ05vIHJlc3BvbnNlIGNvbnRlbnQuJyk7XG4gICAgICB0aGlzLm1lc3NhZ2VzLnB1c2goeyByb2xlOiAndXNlcicsIGNvbnRlbnQ6IHByb21wdCB9LCB7IHJvbGU6ICdhc3Npc3RhbnQnLCBjb250ZW50OiBhbnN3ZXIgfSk7XG4gICAgICB0aGlzLm1lc3NhZ2VzID0gdGhpcy5tZXNzYWdlcy5zbGljZSgtMjApO1xuICAgICAgdGhpcy51cGRhdGVTdGF0dXMoJ1JlYWR5Jyk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgdGhpcy5hcHBlbmRNZXNzYWdlKCdhc3Npc3RhbnQnLCBgRXJyb3I6ICR7ZXJyb3I/Lm1lc3NhZ2UgfHwgJ0NoYXQgcmVxdWVzdCBmYWlsZWQnfWApO1xuICAgICAgdGhpcy51cGRhdGVTdGF0dXMoJ0Vycm9yJyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuc2VuZGluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5zZW5kQnRuICYmICh0aGlzLnNlbmRCdG4uZGlzYWJsZWQgPSBmYWxzZSk7XG4gICAgICB0aGlzLmZvY3VzSW5wdXQoKTtcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgcGFnZU92ZXJsYXkgPSBuZXcgSGFuem9QYWdlT3Zlcmxh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QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7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QUFBLElBRVEsZ0JBQXNCO0FBQzVCLFVBQUksS0FBSyxRQUFTO0FBQ2xCLFdBQUssTUFBTTtBQUFBLElBQ2I7QUFBQSxJQUVRLGVBQXFCO0FBQzNCLFVBQUksU0FBUyxlQUFlLDJCQUEyQixFQUFHO0FBRTFELFlBQU0sUUFBUSxTQUFTLGNBQWMsT0FBTztBQUM1QyxZQUFNLEtBQUs7QUFDWCxZQUFNLGNBQWM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtB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