wxt 0.6.6 → 0.7.1-alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -10,8 +10,9 @@ import { Manifest } from 'webextension-polyfill';
10
10
  declare class ContentScriptContext extends AbortController {
11
11
  #private;
12
12
  private readonly contentScriptName;
13
+ readonly options?: Omit<ContentScriptDefinition, "main"> | undefined;
13
14
  static SCRIPT_STARTED_MESSAGE_TYPE: string;
14
- constructor(contentScriptName: string);
15
+ constructor(contentScriptName: string, options?: Omit<ContentScriptDefinition, "main"> | undefined);
15
16
  get isInvalid(): boolean;
16
17
  get isValid(): boolean;
17
18
  /**
@@ -119,6 +120,18 @@ interface ContentScriptDefinition extends ExcludableEntrypoint {
119
120
  * @default "ISOLATED"
120
121
  */
121
122
  world?: 'ISOLATED' | 'MAIN';
123
+ /**
124
+ * Customize how imported/generated styles are injected with the content script. Regardless of the
125
+ * mode selected, CSS will always be built and included in the output directory.
126
+ *
127
+ * - `"manifest"` - Include the CSS in the manifest, under the content script's `css` array.
128
+ * - `"manual"` - Exclude the CSS from the manifest. You are responsible for manually loading it
129
+ * onto the page. Use `browser.runtime.getURL("content-scripts/<name>.css")` to get the file's
130
+ * URL
131
+ *
132
+ * @default "manifest"
133
+ */
134
+ cssInjectionMode?: 'manifest' | 'manual' | 'ui';
122
135
  /**
123
136
  * Main function executed when the content script is loaded.
124
137
  */
@@ -150,6 +163,133 @@ declare function defineContentScript(definition: ContentScriptDefinition): Conte
150
163
  declare function defineBackground(main: () => void): BackgroundScriptDefintition;
151
164
  declare function defineBackground(definition: BackgroundScriptDefintition): BackgroundScriptDefintition;
152
165
 
153
- declare function mountContentScriptUi(): void;
166
+ /**
167
+ * Utility for mounting content script UI's with isolated styles. Automatically removed from the DOM
168
+ * when the content script's context is invalidated.
169
+ *
170
+ * See <https://wxt.dev/guide/content-scripts.html#ui> for full documentation.
171
+ *
172
+ * @example
173
+ * // entrypoints/example-ui.content/index.ts
174
+ * import "./style.css"
175
+ *
176
+ * export default defineContentScript({
177
+ * matches: ["*://*.google.com/*"],
178
+ * cssInjectionMode: "ui",
179
+ *
180
+ * async main(ctx) {
181
+ * const ui = await createContentScriptUi(ctx, {
182
+ * name: "example-overlay",
183
+ * type: "modal",
184
+ * mount(container) {
185
+ * const app = document.createElement("div");
186
+ * app.textContent = "Content Script UI";
187
+ * container.append(app);
188
+ * }
189
+ * })
190
+ * ui.mount();
191
+ * }
192
+ * })
193
+ */
194
+ declare function createContentScriptUi<T>(ctx: ContentScriptContext, options: ContentScriptUiOptions<T>): Promise<ContentScriptUi<T>>;
195
+ interface ContentScriptUi<T> {
196
+ /**
197
+ * The `HTMLElement` hosting the shadow root used to isolate the UI's styles. This is the element
198
+ * that get's added to the DOM. This element's style is not isolated from the webpage.
199
+ */
200
+ shadowHost: HTMLElement;
201
+ /**
202
+ * The container element inside the `ShadowRoot` whose styles are isolated. The UI is mounted
203
+ * inside this `HTMLElement`.
204
+ */
205
+ uiContainer: HTMLElement;
206
+ /**
207
+ * The shadow root performing the isolation.
208
+ */
209
+ shadow: ShadowRoot;
210
+ /**
211
+ * Custom data returned from the `options.mount` function.
212
+ */
213
+ mounted: T;
214
+ /**
215
+ * Function that mounts or remounts the UI on the page.
216
+ */
217
+ mount: () => void;
218
+ /**
219
+ * Function that removes the UI from the webpage.
220
+ */
221
+ remove: () => void;
222
+ }
223
+ interface BaseContentScriptUiOptions<T> {
224
+ /**
225
+ * The name of the custom component used to host the ShadowRoot. Must be kebab-case.
226
+ */
227
+ name: string;
228
+ /**
229
+ * In combination with `anchor`, decide how to add the UI to the DOM.
230
+ *
231
+ * - `"last"` (default) - Add the UI as the last child of the `anchor` element
232
+ * - `"first"` - Add the UI as the last child of the `anchor` element
233
+ * - `"replace"` - Replace the `anchor` element with the UI.
234
+ * - `"before"` - Add the UI as the sibling before the `anchor` element
235
+ * - `"after"` - Add the UI as the sibling after the `anchor` element
236
+ * - `(anchor, ui) => void` - Customizable function that let's you add the UI to the DOM
237
+ */
238
+ append?: ContentScriptAppendMode | ((anchor: Element, ui: Element) => void);
239
+ /**
240
+ * A CSS selector, element, or function that returns one of the two. Along with `append`, the
241
+ * `anchor` dictates where in the page the UI will be added.
242
+ */
243
+ anchor?: string | Element | null | undefined | (() => string | Element | null | undefined);
244
+ /**
245
+ * Callback executed when mounting the UI. This function should create and append the UI to the
246
+ * `container` element. It is called every time `ui.mount()` is called
247
+ *
248
+ * Optionally return a value that can be accessed at `ui.mounted` or in the `onRemove` callback.
249
+ */
250
+ mount: (container: Element) => T;
251
+ /**
252
+ * Callback called when the UI is removed from the webpage. Use to cleanup your UI, like
253
+ * unmounting your vue or react apps.
254
+ */
255
+ onRemove?: (mounted: T) => void;
256
+ /**
257
+ * Custom CSS text to apply to the UI. If your content script imports/generates CSS and you've
258
+ * set `cssInjectionMode: "ui"`, the imported CSS will be included automatically. You do not need
259
+ * to pass those styles in here. This is for any additional styles not in the imported CSS.
260
+ *
261
+ * See <https://wxt.dev/guide/content-scripts.html#ui> for more info.
262
+ */
263
+ css?: string;
264
+ }
265
+ type OverlayContentScriptUiOptions<T> = BaseContentScriptUiOptions<T> & {
266
+ type: 'overlay';
267
+ /**
268
+ * When using `type: "overlay"`, the mounted element is 0px by 0px in size. Alignment specifies
269
+ * which corner is aligned with that 0x0 pixel space.
270
+ *
271
+ * @default "top-left"
272
+ */
273
+ alignment?: ContentScriptUiOverlayAlignment;
274
+ /**
275
+ * The `z-index` used on the `shadowHost`. Set to a positive number to show your UI over website
276
+ * content.
277
+ */
278
+ zIndex?: number;
279
+ };
280
+ type ModalContentScriptUiOptions<T> = BaseContentScriptUiOptions<T> & {
281
+ type: 'modal';
282
+ /**
283
+ * The `z-index` used on the `shadowHost`. Set to a positive number to show your UI over website
284
+ * content.
285
+ */
286
+ zIndex?: number;
287
+ };
288
+ type InlineContentScriptUiOptions<T> = BaseContentScriptUiOptions<T> & {
289
+ type: 'inline';
290
+ };
291
+ type ContentScriptUiOverlayAlignment = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
292
+ type ContentScriptAppendMode = 'last' | 'first' | 'replace' | 'before' | 'after';
293
+ type ContentScriptUiOptions<T> = OverlayContentScriptUiOptions<T> | ModalContentScriptUiOptions<T> | InlineContentScriptUiOptions<T>;
154
294
 
155
- export { ContentScriptContext, defineBackground, defineContentScript, mountContentScriptUi };
295
+ export { ContentScriptAppendMode, ContentScriptContext, ContentScriptUi, ContentScriptUiOptions, ContentScriptUiOverlayAlignment, InlineContentScriptUiOptions, ModalContentScriptUiOptions, OverlayContentScriptUiOptions, createContentScriptUi, defineBackground, defineContentScript };
package/dist/client.js CHANGED
@@ -10,10 +10,8 @@ function defineBackground(arg) {
10
10
  return arg;
11
11
  }
12
12
 
13
- // src/client/mountContentScriptUi.ts
14
- function mountContentScriptUi() {
15
- throw Error("Not implemented: mountContentScriptUi");
16
- }
13
+ // src/client/createContentScriptUi.ts
14
+ import { createIsolatedElement } from "@webext-core/isolated-element";
17
15
 
18
16
  // src/client/browser.ts
19
17
  import originalBrowser from "webextension-polyfill";
@@ -37,11 +35,129 @@ var logger = {
37
35
  error: (...args) => print(console.error, ...args)
38
36
  };
39
37
 
38
+ // src/client/createContentScriptUi.ts
39
+ async function createContentScriptUi(ctx, options) {
40
+ const css = [options.css ?? ""];
41
+ if (ctx.options?.cssInjectionMode === "ui") {
42
+ css.push(await loadCss());
43
+ }
44
+ const {
45
+ isolatedElement: uiContainer,
46
+ parentElement: shadowHost,
47
+ shadow
48
+ } = await createIsolatedElement({
49
+ name: options.name,
50
+ css: {
51
+ textContent: css.join("\n").trim()
52
+ },
53
+ mode: "open"
54
+ });
55
+ const getAnchor = () => {
56
+ if (options.anchor == null)
57
+ return document.body;
58
+ let resolved = typeof options.anchor === "function" ? options.anchor() : options.anchor;
59
+ if (typeof resolved === "string")
60
+ return document.querySelector(resolved) ?? void 0;
61
+ return resolved ?? void 0;
62
+ };
63
+ let mounted;
64
+ const mount = () => {
65
+ const anchor = getAnchor();
66
+ if (anchor == null)
67
+ throw Error(
68
+ "Failed to mount content script ui: could not find anchor element"
69
+ );
70
+ mounted = options.mount(uiContainer);
71
+ switch (options.append) {
72
+ case void 0:
73
+ case "last":
74
+ anchor.append(shadowHost);
75
+ break;
76
+ case "first":
77
+ if (anchor.firstChild) {
78
+ anchor.insertBefore(shadowHost, anchor.firstChild);
79
+ } else {
80
+ anchor.append(shadowHost);
81
+ }
82
+ break;
83
+ case "replace":
84
+ anchor.replaceWith(shadowHost);
85
+ break;
86
+ case "after":
87
+ anchor.replaceWith(anchor, shadowHost);
88
+ break;
89
+ case "before":
90
+ anchor.replaceWith(shadowHost, anchor);
91
+ break;
92
+ default:
93
+ options.append(anchor, shadowHost);
94
+ break;
95
+ }
96
+ if (options.type !== "inline") {
97
+ if (options.zIndex != null)
98
+ shadowHost.style.zIndex = String(options.zIndex);
99
+ shadowHost.style.overflow = "visible";
100
+ shadowHost.style.position = "relative";
101
+ shadowHost.style.width = "0";
102
+ shadowHost.style.height = "0";
103
+ shadowHost.style.display = "block";
104
+ const html = shadow.querySelector("html");
105
+ if (options.type === "overlay") {
106
+ html.style.position = "absolute";
107
+ if (options.alignment?.startsWith("bottom-"))
108
+ html.style.bottom = "0";
109
+ else
110
+ html.style.top = "0";
111
+ if (options.alignment?.endsWith("-right"))
112
+ html.style.right = "0";
113
+ else
114
+ html.style.left = "0";
115
+ } else {
116
+ html.style.position = "fixed";
117
+ html.style.top = "0";
118
+ html.style.bottom = "0";
119
+ html.style.left = "0";
120
+ html.style.right = "0";
121
+ }
122
+ }
123
+ };
124
+ const remove = () => {
125
+ shadowHost.remove();
126
+ options.onRemove?.(mounted);
127
+ while (uiContainer.lastChild)
128
+ uiContainer.removeChild(uiContainer.lastChild);
129
+ };
130
+ ctx.onInvalidated(remove);
131
+ return {
132
+ shadow,
133
+ shadowHost,
134
+ uiContainer,
135
+ mount,
136
+ remove,
137
+ mounted
138
+ };
139
+ }
140
+ async function loadCss() {
141
+ const url = browser.runtime.getURL(`/content-scripts/${__ENTRYPOINT__}.css`);
142
+ try {
143
+ const res = await fetch(url);
144
+ const css = await res.text();
145
+ return css.replaceAll(":root", ":host");
146
+ } catch (err) {
147
+ logger.warn(
148
+ `Failed to load styles @ ${url}. Did you forget to import the stylesheet in your entrypoint?`,
149
+ err
150
+ );
151
+ return "";
152
+ }
153
+ }
154
+
40
155
  // src/client/utils/ContentScriptContext.ts
41
156
  var ContentScriptContext = class _ContentScriptContext extends AbortController {
42
- constructor(contentScriptName) {
157
+ constructor(contentScriptName, options) {
43
158
  super();
44
159
  this.contentScriptName = contentScriptName;
160
+ this.options = options;
45
161
  if (this.#isTopFrame) {
46
162
  this.#stopOldScripts();
47
163
  }
@@ -165,10 +281,13 @@ var ContentScriptContext = class _ContentScriptContext extends AbortController {
165
281
  );
166
282
  }
167
283
  #stopOldScripts() {
168
- window.postMessage({
169
- event: _ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE,
170
- contentScriptName: this.contentScriptName
171
- });
284
+ window.postMessage(
285
+ {
286
+ event: _ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE,
287
+ contentScriptName: this.contentScriptName
288
+ },
289
+ "*"
290
+ );
172
291
  }
173
292
  #listenForNewerScripts() {
174
293
  const cb = (event) => {
@@ -182,8 +301,8 @@ var ContentScriptContext = class _ContentScriptContext extends AbortController {
182
301
  };
183
302
  export {
184
303
  ContentScriptContext,
304
+ createContentScriptUi,
185
305
  defineBackground,
186
- defineContentScript,
187
- mountContentScriptUi
306
+ defineContentScript
188
307
  };
189
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2NsaWVudC9kZWZpbmVDb250ZW50U2NyaXB0LnRzIiwgIi4uL3NyYy9jbGllbnQvZGVmaW5lQmFja2dyb3VuZC50cyIsICIuLi9zcmMvY2xpZW50L21vdW50Q29udGVudFNjcmlwdFVpLnRzIiwgIi4uL3NyYy9jbGllbnQvYnJvd3Nlci50cyIsICIuLi9zcmMvY2xpZW50L3V0aWxzL2xvZ2dlci50cyIsICIuLi9zcmMvY2xpZW50L3V0aWxzL0NvbnRlbnRTY3JpcHRDb250ZXh0LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBDb250ZW50U2NyaXB0RGVmaW5pdGlvbiB9IGZyb20gJy4uL2NvcmUvdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZGVmaW5lQ29udGVudFNjcmlwdChcbiAgZGVmaW5pdGlvbjogQ29udGVudFNjcmlwdERlZmluaXRpb24sXG4pOiBDb250ZW50U2NyaXB0RGVmaW5pdGlvbiB7XG4gIHJldHVybiBkZWZpbml0aW9uO1xufVxuIiwgImltcG9ydCB7IEJhY2tncm91bmRTY3JpcHREZWZpbnRpdGlvbiB9IGZyb20gJy4uJztcblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmluZUJhY2tncm91bmQobWFpbjogKCkgPT4gdm9pZCk6IEJhY2tncm91bmRTY3JpcHREZWZpbnRpdGlvbjtcbmV4cG9ydCBmdW5jdGlvbiBkZWZpbmVCYWNrZ3JvdW5kKFxuICBkZWZpbml0aW9uOiBCYWNrZ3JvdW5kU2NyaXB0RGVmaW50aXRpb24sXG4pOiBCYWNrZ3JvdW5kU2NyaXB0RGVmaW50aXRpb247XG5leHBvcnQgZnVuY3Rpb24gZGVmaW5lQmFja2dyb3VuZChcbiAgYXJnOiAoKCkgPT4gdm9pZCkgfCBCYWNrZ3JvdW5kU2NyaXB0RGVmaW50aXRpb24sXG4pOiBCYWNrZ3JvdW5kU2NyaXB0RGVmaW50aXRpb24ge1xuICBpZiAodHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJykgcmV0dXJuIHsgbWFpbjogYXJnIH07XG4gIHJldHVybiBhcmc7XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIG1vdW50Q29udGVudFNjcmlwdFVpKCkge1xuICB0aHJvdyBFcnJvcignTm90IGltcGxlbWVudGVkOiBtb3VudENvbnRlbnRTY3JpcHRVaScpO1xufVxuIiwgImltcG9ydCBvcmlnaW5hbEJyb3dzZXIsIHsgQnJvd3NlciwgUnVudGltZSwgSTE4biB9IGZyb20gJ3dlYmV4dGVuc2lvbi1wb2x5ZmlsbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXVnbWVudGVkQnJvd3NlciBleHRlbmRzIEJyb3dzZXIge1xuICBydW50aW1lOiBXeHRSdW50aW1lO1xuICBpMThuOiBXeHRJMThuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFd4dFJ1bnRpbWUgZXh0ZW5kcyBSdW50aW1lLlN0YXRpYyB7XG4gIC8vIE92ZXJyaWRlbiBwZXItcHJvamVjdFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFd4dEkxOG4gZXh0ZW5kcyBJMThuLlN0YXRpYyB7XG4gIC8vIE92ZXJyaWRlbiBwZXItcHJvamVjdFxufVxuXG5leHBvcnQgY29uc3QgYnJvd3NlcjogQXVnbWVudGVkQnJvd3NlciA9IG9yaWdpbmFsQnJvd3NlcjtcbiIsICJmdW5jdGlvbiBwcmludChtZXRob2Q6ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCwgLi4uYXJnczogYW55W10pIHtcbiAgaWYgKGltcG9ydC5tZXRhLmVudi5NT0RFID09PSAncHJvZHVjdGlvbicpIHJldHVybjtcblxuICBpZiAodHlwZW9mIGFyZ3NbMF0gPT09ICdzdHJpbmcnKSB7XG4gICAgY29uc3QgbWVzc2FnZSA9IGFyZ3Muc2hpZnQoKTtcbiAgICBtZXRob2QoYFt3eHRdICR7bWVzc2FnZX1gLCAuLi5hcmdzKTtcbiAgfSBlbHNlIHtcbiAgICBtZXRob2QoJ1t3eHRdJywgLi4uYXJncyk7XG4gIH1cbn1cblxuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCBgY29uc29sZWAgd2l0aCBhIFwiW3d4dF1cIiBwcmVmaXhcbiAqL1xuZXhwb3J0IGNvbnN0IGxvZ2dlciA9IHtcbiAgZGVidWc6ICguLi5hcmdzOiBhbnlbXSkgPT4gcHJpbnQoY29uc29sZS5kZWJ1ZywgLi4uYXJncyksXG4gIGxvZzogKC4uLmFyZ3M6IGFueVtdKSA9PiBwcmludChjb25zb2xlLmxvZywgLi4uYXJncyksXG4gIHdhcm46ICguLi5hcmdzOiBhbnlbXSkgPT4gcHJpbnQoY29uc29sZS53YXJuLCAuLi5hcmdzKSxcbiAgZXJyb3I6ICguLi5hcmdzOiBhbnlbXSkgPT4gcHJpbnQoY29uc29sZS5lcnJvciwgLi4uYXJncyksXG59O1xuIiwgImltcG9ydCB7IGJyb3dzZXIgfSBmcm9tICcuLi9icm93c2VyJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcblxuLyoqXG4gKiBFeHRlbmRzIFtgQWJvcnRDb250cm9sbGVyYF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0Fib3J0Q29udHJvbGxlcikuXG4gKiBVc2VkIHRvIGRldGVjdCBhbmQgc3RvcCBjb250ZW50IHNjcmlwdCBjb2RlIHdoZW4gdGhlIHNjcmlwdCBpcyBpbnZhbGlkYXRlZC5cbiAqXG4gKiBJdCBhbHNvIHByb3ZpZGVzIHNldmVyYWwgdXRpbGl0aWVzIGxpa2UgYGN0eC5zZXRUaW1lb3V0YCBhbmQgYGN0eC5zZXRJbnRlcnZhbGAgdGhhdCBzaG91bGQgYmUgdXNlZCBpblxuICogY29udGVudCBzY3JpcHRzIGluc3RlYWQgb2YgYHdpbmRvdy5zZXRUaW1lb3V0YCBvciBgd2luZG93LnNldEludGVydmFsYC5cbiAqL1xuZXhwb3J0IGNsYXNzIENvbnRlbnRTY3JpcHRDb250ZXh0IGV4dGVuZHMgQWJvcnRDb250cm9sbGVyIHtcbiAgc3RhdGljIFNDUklQVF9TVEFSVEVEX01FU1NBR0VfVFlQRSA9ICd3eHQ6Y29udGVudC1zY3JpcHQtc3RhcnRlZCc7XG5cbiAgI2lzVG9wRnJhbWUgPSB3aW5kb3cuc2VsZiA9PT0gd2luZG93LnRvcDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGNvbnRlbnRTY3JpcHROYW1lOiBzdHJpbmcpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgaWYgKHRoaXMuI2lzVG9wRnJhbWUpIHtcbiAgICAgIHRoaXMuI3N0b3BPbGRTY3JpcHRzKCk7XG4gICAgfVxuICAgIHRoaXMuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAvLyBSdW4gb24gbmV4dCB0aWNrIHNvIHRoZSBsaXN0ZW5lciBpdCBhZGRzIGlzbid0IHRyaWdnZXJlZCBieSBzdG9wT2xkU2NyaXB0XG4gICAgICB0aGlzLiNsaXN0ZW5Gb3JOZXdlclNjcmlwdHMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBpc0ludmFsaWQoKTogYm9vbGVhbiB7XG4gICAgaWYgKGJyb3dzZXIucnVudGltZS5pZCA9PSBudWxsKSB7XG4gICAgICB0aGlzLm5vdGlmeUludmFsaWRhdGVkKCk7IC8vIFNldHMgYHNpZ25hbC5hYm9ydGVkYCB0byB0cnVlXG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNpZ25hbC5hYm9ydGVkO1xuICB9XG5cbiAgZ2V0IGlzVmFsaWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLmlzSW52YWxpZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBsaXN0ZW5lciB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSBjb250ZW50IHNjcmlwdCdzIGNvbnRleHQgaXMgaW52YWxpZGF0ZWQuXG4gICAqXG4gICAqIEByZXR1cm5zIEEgZnVuY3Rpb24gdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYnJvd3Nlci5ydW50aW1lLm9uTWVzc2FnZS5hZGRMaXN0ZW5lcihjYik7XG4gICAqIGNvbnN0IHJlbW92ZUludmFsaWRhdGVkTGlzdGVuZXIgPSBjdHgub25JbnZhbGlkYXRlZCgoKSA9PiB7XG4gICAqICAgYnJvd3Nlci5ydW50aW1lLm9uTWVzc2FnZS5yZW1vdmVMaXN0ZW5lcihjYik7XG4gICAqIH0pXG4gICAqIC8vIC4uLlxuICAgKiByZW1vdmVJbnZhbGlkYXRlZExpc3RlbmVyKCk7XG4gICAqL1xuICBvbkludmFsaWRhdGVkKGNiOiAoKSA9PiB2b2lkKTogKCkgPT4gdm9pZCB7XG4gICAgdGhpcy5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBjYik7XG4gICAgcmV0dXJuICgpID0+IHRoaXMuc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgY2IpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIHByb21pc2UgdGhhdCBuZXZlciByZXNvbHZlcy4gVXNlZnVsIGlmIHlvdSBoYXZlIGFuIGFzeW5jIGZ1bmN0aW9uIHRoYXQgc2hvdWxkbid0IHJ1blxuICAgKiBhZnRlciB0aGUgY29udGV4dCBpcyBleHBpcmVkLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zdCBnZXRWYWx1ZUZyb21TdG9yYWdlID0gYXN5bmMgKCkgPT4ge1xuICAgKiAgIGlmIChjdHguaXNJbnZhbGlkKSByZXR1cm4gY3R4LmJsb2NrKCk7XG4gICAqXG4gICAqICAgLy8gLi4uXG4gICAqIH1cbiAgICovXG4gIGJsb2NrPFQ+KCk6IFByb21pc2U8VD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgoKSA9PiB7XG4gICAgICAvLyBub29wXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogV3JhcHBlciBhcm91bmQgYHdpbmRvdy5zZXRJbnRlcnZhbGAgdGhhdCBhdXRvbWF0aWNhbGx5IGNsZWFycyB0aGUgaW50ZXJ2YWwgd2hlbiBpbnZhbGlkYXRlZC5cbiAgICovXG4gIHNldEludGVydmFsKGhhbmRsZXI6ICgpID0+IHZvaWQsIHRpbWVvdXQ/OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IGlkID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaXNWYWxpZCkgaGFuZGxlcigpO1xuICAgIH0sIHRpbWVvdXQpIGFzIHVua25vd24gYXMgbnVtYmVyO1xuICAgIHRoaXMub25JbnZhbGlkYXRlZCgoKSA9PiBjbGVhckludGVydmFsKGlkKSk7XG4gICAgcmV0dXJuIGlkO1xuICB9XG5cbiAgLyoqXG4gICAqIFdyYXBwZXIgYXJvdW5kIGB3aW5kb3cuc2V0VGltZW91dGAgdGhhdCBhdXRvbWF0aWNhbGx5IGNsZWFycyB0aGUgaW50ZXJ2YWwgd2hlbiBpbnZhbGlkYXRlZC5cbiAgICovXG4gIHNldFRpbWVvdXQoaGFuZGxlcjogKCkgPT4gdm9pZCwgdGltZW91dD86IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3QgaWQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmlzVmFsaWQpIGhhbmRsZXIoKTtcbiAgICB9LCB0aW1lb3V0KSBhcyB1bmtub3duIGFzIG51bWJlcjtcbiAgICB0aGlzLm9uSW52YWxpZGF0ZWQoKCkgPT4gY2xlYXJUaW1lb3V0KGlkKSk7XG4gICAgcmV0dXJuIGlkO1xuICB9XG5cbiAgLyoqXG4gICAqIFdyYXBwZXIgYXJvdW5kIGB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lYCB0aGF0IGF1dG9tYXRpY2FsbHkgY2FuY2VscyB0aGUgcmVxdWVzdCB3aGVuXG4gICAqIGludmFsaWRhdGVkLlxuICAgKi9cbiAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGNhbGxiYWNrOiBGcmFtZVJlcXVlc3RDYWxsYmFjayk6IG51bWJlciB7XG4gICAgY29uc3QgaWQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKC4uLmFyZ3MpID0+IHtcbiAgICAgIGlmICh0aGlzLmlzVmFsaWQpIGNhbGxiYWNrKC4uLmFyZ3MpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5vbkludmFsaWRhdGVkKCgpID0+IGNhbmNlbEFuaW1hdGlvbkZyYW1lKGlkKSk7XG4gICAgcmV0dXJuIGlkO1xuICB9XG5cbiAgLyoqXG4gICAqIFdyYXBwZXIgYXJvdW5kIGB3aW5kb3cucmVxdWVzdElkbGVDYWxsYmFja2AgdGhhdCBhdXRvbWF0aWNhbGx5IGNhbmNlbHMgdGhlIHJlcXVlc3Qgd2hlblxuICAgKiBpbnZhbGlkYXRlZC5cbiAgICovXG4gIHJlcXVlc3RJZGxlQ2FsbGJhY2soXG4gICAgY2FsbGJhY2s6IElkbGVSZXF1ZXN0Q2FsbGJhY2ssXG4gICAgb3B0aW9ucz86IElkbGVSZXF1ZXN0T3B0aW9ucyxcbiAgKTogbnVtYmVyIHtcbiAgICBjb25zdCBpZCA9IHJlcXVlc3RJZGxlQ2FsbGJhY2soKC4uLmFyZ3MpID0+IHtcbiAgICAgIGlmICghdGhpcy5zaWduYWwuYWJvcnRlZCkgY2FsbGJhY2soLi4uYXJncyk7XG4gICAgfSwgb3B0aW9ucyk7XG5cbiAgICB0aGlzLm9uSW52YWxpZGF0ZWQoKCkgPT4gY2FuY2VsSWRsZUNhbGxiYWNrKGlkKSk7XG4gICAgcmV0dXJuIGlkO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGwgYHRhcmdldC5hZGRFdmVudExpc3RlbmVyYCBhbmQgcmVtb3ZlIHRoZSBldmVudCBsaXN0ZW5lciB3aGVuIHRoZSBjb250ZXh0IGlzIGludmFsaWRhdGVkLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjdHguYWRkRXZlbnRMaXN0ZW5lcih3aW5kb3csIFwibW91c2Vtb3ZlXCIsICgpID0+IHtcbiAgICogICAvLyAuLi5cbiAgICogfSk7XG4gICAqIGN0eC5hZGRFdmVudExpc3RlbmVyKGRvY3VtZW50LCBcInZpc2liaWxpdHljaGFuZ2VcIiwgKCkgPT4ge1xuICAgKiAgIC8vIC4uLlxuICAgKiB9KTtcbiAgICovXG4gIGFkZEV2ZW50TGlzdGVuZXIoXG4gICAgdGFyZ2V0OiBhbnksXG4gICAgdHlwZTogc3RyaW5nLFxuICAgIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQsXG4gICAgb3B0aW9ucz86IEFkZEV2ZW50TGlzdGVuZXJPcHRpb25zLFxuICApIHtcbiAgICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcj8uKHR5cGUsIGhhbmRsZXIsIG9wdGlvbnMpO1xuICAgIHRoaXMub25JbnZhbGlkYXRlZChcbiAgICAgICgpID0+IHRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyPy4odHlwZSwgaGFuZGxlciwgb3B0aW9ucyksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBYm9ydCB0aGUgYWJvcnQgY29udHJvbGxlciBhbmQgZXhlY3V0ZSBhbGwgYG9uSW52YWxpZGF0ZWRgIGxpc3RlbmVycy5cbiAgICovXG4gIG5vdGlmeUludmFsaWRhdGVkKCkge1xuICAgIHRoaXMuYWJvcnQoJ0NvbnRlbnQgc2NyaXB0IGNvbnRleHQgaW52YWxpZGF0ZWQnKTtcbiAgICBsb2dnZXIuZGVidWcoXG4gICAgICBgQ29udGVudCBzY3JpcHQgXCIke3RoaXMuY29udGVudFNjcmlwdE5hbWV9XCIgY29udGV4dCBpbnZhbGlkYXRlZGAsXG4gICAgKTtcbiAgfVxuXG4gICNzdG9wT2xkU2NyaXB0cygpIHtcbiAgICAvLyBVc2UgcG9zdE1lc3NhZ2Ugc28gaXQgZ2V0J3Mgc2VudCB0byBhbGwgdGhlIGZyYW1lcyBvZiB0aGUgcGFnZS5cbiAgICB3aW5kb3cucG9zdE1lc3NhZ2Uoe1xuICAgICAgZXZlbnQ6IENvbnRlbnRTY3JpcHRDb250ZXh0LlNDUklQVF9TVEFSVEVEX01FU1NBR0VfVFlQRSxcbiAgICAgIGNvbnRlbnRTY3JpcHROYW1lOiB0aGlzLmNvbnRlbnRTY3JpcHROYW1lLFxuICAgIH0pO1xuICB9XG5cbiAgI2xpc3RlbkZvck5ld2VyU2NyaXB0cygpIHtcbiAgICBjb25zdCBjYiA9IChldmVudDogTWVzc2FnZUV2ZW50KSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIGV2ZW50LmRhdGE/LnR5cGUgPT09IENvbnRlbnRTY3JpcHRDb250ZXh0LlNDUklQVF9TVEFSVEVEX01FU1NBR0VfVFlQRSAmJlxuICAgICAgICBldmVudC5kYXRhPy5jb250ZW50U2NyaXB0TmFtZSA9PT0gdGhpcy5jb250ZW50U2NyaXB0TmFtZVxuICAgICAgKSB7XG4gICAgICAgIHRoaXMubm90aWZ5SW52YWxpZGF0ZWQoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGNiKTtcbiAgICB0aGlzLm9uSW52YWxpZGF0ZWQoKCkgPT4gcmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGNiKSk7XG4gIH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7QUFFTyxTQUFTLG9CQUNkLFlBQ3lCO0FBQ3pCLFNBQU87QUFDVDs7O0FDQU8sU0FBUyxpQkFDZCxLQUM2QjtBQUM3QixNQUFJLE9BQU8sUUFBUTtBQUFZLFdBQU8sRUFBRSxNQUFNLElBQUk7QUFDbEQsU0FBTztBQUNUOzs7QUNYTyxTQUFTLHVCQUF1QjtBQUNyQyxRQUFNLE1BQU0sdUNBQXVDO0FBQ3JEOzs7QUNGQSxPQUFPLHFCQUFpRDtBQWVqRCxJQUFNLFVBQTRCOzs7QUNmekMsU0FBUyxNQUFNLFdBQXFDLE1BQWE7QUFDL0QsTUFBSSxZQUFZLElBQUksU0FBUztBQUFjO0FBRTNDLE1BQUksT0FBTyxLQUFLLENBQUMsTUFBTSxVQUFVO0FBQy9CLFVBQU0sVUFBVSxLQUFLLE1BQU07QUFDM0IsV0FBTyxTQUFTLE9BQU8sSUFBSSxHQUFHLElBQUk7QUFBQSxFQUNwQyxPQUFPO0FBQ0wsV0FBTyxTQUFTLEdBQUcsSUFBSTtBQUFBLEVBQ3pCO0FBQ0Y7QUFLTyxJQUFNLFNBQVM7QUFBQSxFQUNwQixPQUFPLElBQUksU0FBZ0IsTUFBTSxRQUFRLE9BQU8sR0FBRyxJQUFJO0FBQUEsRUFDdkQsS0FBSyxJQUFJLFNBQWdCLE1BQU0sUUFBUSxLQUFLLEdBQUcsSUFBSTtBQUFBLEVBQ25ELE1BQU0sSUFBSSxTQUFnQixNQUFNLFFBQVEsTUFBTSxHQUFHLElBQUk7QUFBQSxFQUNyRCxPQUFPLElBQUksU0FBZ0IsTUFBTSxRQUFRLE9BQU8sR0FBRyxJQUFJO0FBQ3pEOzs7QUNUTyxJQUFNLHVCQUFOLE1BQU0sOEJBQTZCLGdCQUFnQjtBQUFBLEVBS3hELFlBQTZCLG1CQUEyQjtBQUN0RCxVQUFNO0FBRHFCO0FBRzNCLFFBQUksS0FBSyxhQUFhO0FBQ3BCLFdBQUssZ0JBQWdCO0FBQUEsSUFDdkI7QUFDQSxTQUFLLFdBQVcsTUFBTTtBQUVwQixXQUFLLHVCQUF1QjtBQUFBLElBQzlCLENBQUM7QUFBQSxFQUNIO0FBQUEsRUFkQSxPQUFPLDhCQUE4QjtBQUFBLEVBRXJDLGNBQWMsT0FBTyxTQUFTLE9BQU87QUFBQSxFQWNyQyxJQUFJLFlBQXFCO0FBQ3ZCLFFBQUksUUFBUSxRQUFRLE1BQU0sTUFBTTtBQUM5QixXQUFLLGtCQUFrQjtBQUFBLElBQ3pCO0FBQ0EsV0FBTyxLQUFLLE9BQU87QUFBQSxFQUNyQjtBQUFBLEVBRUEsSUFBSSxVQUFtQjtBQUNyQixXQUFPLENBQUMsS0FBSztBQUFBLEVBQ2Y7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBZUEsY0FBYyxJQUE0QjtBQUN4QyxTQUFLLE9BQU8saUJBQWlCLFNBQVMsRUFBRTtBQUN4QyxXQUFPLE1BQU0sS0FBSyxPQUFPLG9CQUFvQixTQUFTLEVBQUU7QUFBQSxFQUMxRDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQWFBLFFBQXVCO0FBQ3JCLFdBQU8sSUFBSSxRQUFRLE1BQU07QUFBQSxJQUV6QixDQUFDO0FBQUEsRUFDSDtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBS0EsWUFBWSxTQUFxQixTQUEwQjtBQUN6RCxVQUFNLEtBQUssWUFBWSxNQUFNO0FBQzNCLFVBQUksS0FBSztBQUFTLGdCQUFRO0FBQUEsSUFDNUIsR0FBRyxPQUFPO0FBQ1YsU0FBSyxjQUFjLE1BQU0sY0FBYyxFQUFFLENBQUM7QUFDMUMsV0FBTztBQUFBLEVBQ1Q7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUtBLFdBQVcsU0FBcUIsU0FBMEI7QUFDeEQsVUFBTSxLQUFLLFdBQVcsTUFBTTtBQUMxQixVQUFJLEtBQUs7QUFBUyxnQkFBUTtBQUFBLElBQzVCLEdBQUcsT0FBTztBQUNWLFNBQUssY0FBYyxNQUFNLGFBQWEsRUFBRSxDQUFDO0FBQ3pDLFdBQU87QUFBQSxFQUNUO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU1BLHNCQUFzQixVQUF3QztBQUM1RCxVQUFNLEtBQUssc0JBQXNCLElBQUksU0FBUztBQUM1QyxVQUFJLEtBQUs7QUFBUyxpQkFBUyxHQUFHLElBQUk7QUFBQSxJQUNwQyxDQUFDO0FBRUQsU0FBSyxjQUFjLE1BQU0scUJBQXFCLEVBQUUsQ0FBQztBQUNqRCxXQUFPO0FBQUEsRUFDVDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFNQSxvQkFDRSxVQUNBLFNBQ1E7QUFDUixVQUFNLEtBQUssb0JBQW9CLElBQUksU0FBUztBQUMxQyxVQUFJLENBQUMsS0FBSyxPQUFPO0FBQVMsaUJBQVMsR0FBRyxJQUFJO0FBQUEsSUFDNUMsR0FBRyxPQUFPO0FBRVYsU0FBSyxjQUFjLE1BQU0sbUJBQW1CLEVBQUUsQ0FBQztBQUMvQyxXQUFPO0FBQUEsRUFDVDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQWFBLGlCQUNFLFFBQ0EsTUFDQSxTQUNBLFNBQ0E7QUFDQSxXQUFPLG1CQUFtQixNQUFNLFNBQVMsT0FBTztBQUNoRCxTQUFLO0FBQUEsTUFDSCxNQUFNLE9BQU8sc0JBQXNCLE1BQU0sU0FBUyxPQUFPO0FBQUEsSUFDM0Q7QUFBQSxFQUNGO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFLQSxvQkFBb0I7QUFDbEIsU0FBSyxNQUFNLG9DQUFvQztBQUMvQyxXQUFPO0FBQUEsTUFDTCxtQkFBbUIsS0FBSyxpQkFBaUI7QUFBQSxJQUMzQztBQUFBLEVBQ0Y7QUFBQSxFQUVBLGtCQUFrQjtBQUVoQixXQUFPLFlBQVk7QUFBQSxNQUNqQixPQUFPLHNCQUFxQjtBQUFBLE1BQzVCLG1CQUFtQixLQUFLO0FBQUEsSUFDMUIsQ0FBQztBQUFBLEVBQ0g7QUFBQSxFQUVBLHlCQUF5QjtBQUN2QixVQUFNLEtBQUssQ0FBQyxVQUF3QjtBQUNsQyxVQUNFLE1BQU0sTUFBTSxTQUFTLHNCQUFxQiwrQkFDMUMsTUFBTSxNQUFNLHNCQUFzQixLQUFLLG1CQUN2QztBQUNBLGFBQUssa0JBQWtCO0FBQUEsTUFDekI7QUFBQSxJQUNGO0FBRUEscUJBQWlCLFdBQVcsRUFBRTtBQUM5QixTQUFLLGNBQWMsTUFBTSxvQkFBb0IsV0FBVyxFQUFFLENBQUM7QUFBQSxFQUM3RDtBQUNGOyIsCiAgIm5hbWVzIjogW10KfQo=
308
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2NsaWVudC9kZWZpbmVDb250ZW50U2NyaXB0LnRzIiwgIi4uL3NyYy9jbGllbnQvZGVmaW5lQmFja2dyb3VuZC50cyIsICIuLi9zcmMvY2xpZW50L2NyZWF0ZUNvbnRlbnRTY3JpcHRVaS50cyIsICIuLi9zcmMvY2xpZW50L2Jyb3dzZXIudHMiLCAiLi4vc3JjL2NsaWVudC91dGlscy9sb2dnZXIudHMiLCAiLi4vc3JjL2NsaWVudC91dGlscy9Db250ZW50U2NyaXB0Q29udGV4dC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgQ29udGVudFNjcmlwdERlZmluaXRpb24gfSBmcm9tICcuLi9jb3JlL3R5cGVzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmluZUNvbnRlbnRTY3JpcHQoXG4gIGRlZmluaXRpb246IENvbnRlbnRTY3JpcHREZWZpbml0aW9uLFxuKTogQ29udGVudFNjcmlwdERlZmluaXRpb24ge1xuICByZXR1cm4gZGVmaW5pdGlvbjtcbn1cbiIsICJpbXBvcnQgeyBCYWNrZ3JvdW5kU2NyaXB0RGVmaW50aXRpb24gfSBmcm9tICcuLic7XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZpbmVCYWNrZ3JvdW5kKG1haW46ICgpID0+IHZvaWQpOiBCYWNrZ3JvdW5kU2NyaXB0RGVmaW50aXRpb247XG5leHBvcnQgZnVuY3Rpb24gZGVmaW5lQmFja2dyb3VuZChcbiAgZGVmaW5pdGlvbjogQmFja2dyb3VuZFNjcmlwdERlZmludGl0aW9uLFxuKTogQmFja2dyb3VuZFNjcmlwdERlZmludGl0aW9uO1xuZXhwb3J0IGZ1bmN0aW9uIGRlZmluZUJhY2tncm91bmQoXG4gIGFyZzogKCgpID0+IHZvaWQpIHwgQmFja2dyb3VuZFNjcmlwdERlZmludGl0aW9uLFxuKTogQmFja2dyb3VuZFNjcmlwdERlZmludGl0aW9uIHtcbiAgaWYgKHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbicpIHJldHVybiB7IG1haW46IGFyZyB9O1xuICByZXR1cm4gYXJnO1xufVxuIiwgImltcG9ydCB7IGNyZWF0ZUlzb2xhdGVkRWxlbWVudCB9IGZyb20gJ0B3ZWJleHQtY29yZS9pc29sYXRlZC1lbGVtZW50JztcbmltcG9ydCB7IGJyb3dzZXIgfSBmcm9tICcuL2Jyb3dzZXInO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi91dGlscy9sb2dnZXInO1xuaW1wb3J0IHsgQ29udGVudFNjcmlwdENvbnRleHQgfSBmcm9tICcuJztcblxuLyoqXG4gKiBVdGlsaXR5IGZvciBtb3VudGluZyBjb250ZW50IHNjcmlwdCBVSSdzIHdpdGggaXNvbGF0ZWQgc3R5bGVzLiBBdXRvbWF0aWNhbGx5IHJlbW92ZWQgZnJvbSB0aGUgRE9NXG4gKiB3aGVuIHRoZSBjb250ZW50IHNjcmlwdCdzIGNvbnRleHQgaXMgaW52YWxpZGF0ZWQuXG4gKlxuICogU2VlIDxodHRwczovL3d4dC5kZXYvZ3VpZGUvY29udGVudC1zY3JpcHRzLmh0bWwjdWk+IGZvciBmdWxsIGRvY3VtZW50YXRpb24uXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGVudHJ5cG9pbnRzL2V4YW1wbGUtdWkuY29udGVudC9pbmRleC50c1xuICogaW1wb3J0IFwiLi9zdHlsZS5jc3NcIlxuICpcbiAqIGV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbnRlbnRTY3JpcHQoe1xuICogICBtYXRjaGVzOiBbXCIqOi8vKi5nb29nbGUuY29tLypcIl0sXG4gKiAgIGNzc0luamVjdGlvbk1vZGU6IFwidWlcIixcbiAqXG4gKiAgIGFzeW5jIG1haW4oY3R4KSB7XG4gKiAgICAgY29uc3QgdWkgPSBhd2FpdCBjcmVhdGVDb250ZW50U2NyaXB0VWkoY3R4LCB7XG4gKiAgICAgICBuYW1lOiBcImV4YW1wbGUtb3ZlcmxheVwiLFxuICogICAgICAgdHlwZTogXCJtb2RhbFwiLFxuICogICAgICAgbW91bnQoY29udGFpbmVyKSB7XG4gKiAgICAgICAgIGNvbnN0IGFwcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gKiAgICAgICAgIGFwcC50ZXh0Q29udGVudCA9IFwiQ29udGVudCBTY3JpcHQgVUlcIjtcbiAqICAgICAgICAgY29udGFpbmVyLmFwcGVuZChhcHApO1xuICogICAgICAgfVxuICogICAgIH0pXG4gKiAgICAgdWkubW91bnQoKTtcbiAqICAgfVxuICogfSlcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUNvbnRlbnRTY3JpcHRVaTxUPihcbiAgY3R4OiBDb250ZW50U2NyaXB0Q29udGV4dCxcbiAgb3B0aW9uczogQ29udGVudFNjcmlwdFVpT3B0aW9uczxUPixcbik6IFByb21pc2U8Q29udGVudFNjcmlwdFVpPFQ+PiB7XG4gIGNvbnN0IGNzcyA9IFtvcHRpb25zLmNzcyA/PyAnJ107XG4gIGlmIChjdHgub3B0aW9ucz8uY3NzSW5qZWN0aW9uTW9kZSA9PT0gJ3VpJykge1xuICAgIGNzcy5wdXNoKGF3YWl0IGxvYWRDc3MoKSk7XG4gIH1cblxuICBjb25zdCB7XG4gICAgaXNvbGF0ZWRFbGVtZW50OiB1aUNvbnRhaW5lcixcbiAgICBwYXJlbnRFbGVtZW50OiBzaGFkb3dIb3N0LFxuICAgIHNoYWRvdyxcbiAgfSA9IGF3YWl0IGNyZWF0ZUlzb2xhdGVkRWxlbWVudCh7XG4gICAgbmFtZTogb3B0aW9ucy5uYW1lLFxuICAgIGNzczoge1xuICAgICAgdGV4dENvbnRlbnQ6IGNzcy5qb2luKCdcXG4nKS50cmltKCksXG4gICAgfSxcbiAgICBtb2RlOiAnb3BlbicsXG4gIH0pO1xuXG4gIGNvbnN0IGdldEFuY2hvciA9ICgpOiBFbGVtZW50IHwgdW5kZWZpbmVkID0+IHtcbiAgICBpZiAob3B0aW9ucy5hbmNob3IgPT0gbnVsbCkgcmV0dXJuIGRvY3VtZW50LmJvZHk7XG5cbiAgICBsZXQgcmVzb2x2ZWQgPVxuICAgICAgdHlwZW9mIG9wdGlvbnMuYW5jaG9yID09PSAnZnVuY3Rpb24nID8gb3B0aW9ucy5hbmNob3IoKSA6IG9wdGlvbnMuYW5jaG9yO1xuICAgIGlmICh0eXBlb2YgcmVzb2x2ZWQgPT09ICdzdHJpbmcnKVxuICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8RWxlbWVudD4ocmVzb2x2ZWQpID8/IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gcmVzb2x2ZWQgPz8gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGxldCBtb3VudGVkOiBUO1xuXG4gIGNvbnN0IG1vdW50ID0gKCkgPT4ge1xuICAgIGNvbnN0IGFuY2hvciA9IGdldEFuY2hvcigpO1xuICAgIGlmIChhbmNob3IgPT0gbnVsbClcbiAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAnRmFpbGVkIHRvIG1vdW50IGNvbnRlbnQgc2NyaXB0IHVpOiBjb3VsZCBub3QgZmluZCBhbmNob3IgZWxlbWVudCcsXG4gICAgICApO1xuXG4gICAgLy8gTW91bnQgVUkgaW5zaWRlIHNoYWRvdyByb290XG4gICAgbW91bnRlZCA9IG9wdGlvbnMubW91bnQodWlDb250YWluZXIpO1xuXG4gICAgLy8gQWRkIHNoYWRvdyByb290IGVsZW1lbnQgdG8gRE9NXG4gICAgc3dpdGNoIChvcHRpb25zLmFwcGVuZCkge1xuICAgICAgY2FzZSB1bmRlZmluZWQ6XG4gICAgICBjYXNlICdsYXN0JzpcbiAgICAgICAgYW5jaG9yLmFwcGVuZChzaGFkb3dIb3N0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdmaXJzdCc6XG4gICAgICAgIGlmIChhbmNob3IuZmlyc3RDaGlsZCkge1xuICAgICAgICAgIGFuY2hvci5pbnNlcnRCZWZvcmUoc2hhZG93SG9zdCwgYW5jaG9yLmZpcnN0Q2hpbGQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFuY2hvci5hcHBlbmQoc2hhZG93SG9zdCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdyZXBsYWNlJzpcbiAgICAgICAgYW5jaG9yLnJlcGxhY2VXaXRoKHNoYWRvd0hvc3QpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2FmdGVyJzpcbiAgICAgICAgYW5jaG9yLnJlcGxhY2VXaXRoKGFuY2hvciwgc2hhZG93SG9zdCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYmVmb3JlJzpcbiAgICAgICAgYW5jaG9yLnJlcGxhY2VXaXRoKHNoYWRvd0hvc3QsIGFuY2hvcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgb3B0aW9ucy5hcHBlbmQoYW5jaG9yLCBzaGFkb3dIb3N0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gQXBwbHkgdHlwZXNcbiAgICBpZiAob3B0aW9ucy50eXBlICE9PSAnaW5saW5lJykge1xuICAgICAgaWYgKG9wdGlvbnMuekluZGV4ICE9IG51bGwpXG4gICAgICAgIHNoYWRvd0hvc3Quc3R5bGUuekluZGV4ID0gU3RyaW5nKG9wdGlvbnMuekluZGV4KTtcblxuICAgICAgc2hhZG93SG9zdC5zdHlsZS5vdmVyZmxvdyA9ICd2aXNpYmxlJztcbiAgICAgIHNoYWRvd0hvc3Quc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgICAgc2hhZG93SG9zdC5zdHlsZS53aWR0aCA9ICcwJztcbiAgICAgIHNoYWRvd0hvc3Quc3R5bGUuaGVpZ2h0ID0gJzAnO1xuICAgICAgc2hhZG93SG9zdC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblxuICAgICAgY29uc3QgaHRtbCA9IHNoYWRvdy5xdWVyeVNlbGVjdG9yKCdodG1sJykhO1xuICAgICAgLy8gSFRNTCBkb2Vzbid0IGV4aXN0IGluIHRlc3RzXG4gICAgICBpZiAob3B0aW9ucy50eXBlID09PSAnb3ZlcmxheScpIHtcbiAgICAgICAgaHRtbC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgICAgIGlmIChvcHRpb25zLmFsaWdubWVudD8uc3RhcnRzV2l0aCgnYm90dG9tLScpKSBodG1sLnN0eWxlLmJvdHRvbSA9ICcwJztcbiAgICAgICAgZWxzZSBodG1sLnN0eWxlLnRvcCA9ICcwJztcblxuICAgICAgICBpZiAob3B0aW9ucy5hbGlnbm1lbnQ/LmVuZHNXaXRoKCctcmlnaHQnKSkgaHRtbC5zdHlsZS5yaWdodCA9ICcwJztcbiAgICAgICAgZWxzZSBodG1sLnN0eWxlLmxlZnQgPSAnMCc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBodG1sLnN0eWxlLnBvc2l0aW9uID0gJ2ZpeGVkJztcbiAgICAgICAgaHRtbC5zdHlsZS50b3AgPSAnMCc7XG4gICAgICAgIGh0bWwuc3R5bGUuYm90dG9tID0gJzAnO1xuICAgICAgICBodG1sLnN0eWxlLmxlZnQgPSAnMCc7XG4gICAgICAgIGh0bWwuc3R5bGUucmlnaHQgPSAnMCc7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHJlbW92ZSA9ICgpID0+IHtcbiAgICAvLyBEZXRhdGNoIHNoYWRvdyByb290IGZyb20gRE9NXG4gICAgc2hhZG93SG9zdC5yZW1vdmUoKTtcbiAgICAvLyBDbGVhbnVwIG1vdW50ZWQgc3RhdGVcbiAgICBvcHRpb25zLm9uUmVtb3ZlPy4obW91bnRlZCk7XG4gICAgLy8gUmVtb3ZlIGNoaWxkcmVuIGZyb20gdWlDb250YWluZXJcbiAgICB3aGlsZSAodWlDb250YWluZXIubGFzdENoaWxkKVxuICAgICAgdWlDb250YWluZXIucmVtb3ZlQ2hpbGQodWlDb250YWluZXIubGFzdENoaWxkKTtcbiAgfTtcblxuICBjdHgub25JbnZhbGlkYXRlZChyZW1vdmUpO1xuXG4gIHJldHVybiB7XG4gICAgc2hhZG93LFxuICAgIHNoYWRvd0hvc3QsXG4gICAgdWlDb250YWluZXIsXG4gICAgbW91bnQsXG4gICAgcmVtb3ZlLFxuICAgIG1vdW50ZWQ6IG1vdW50ZWQhLFxuICB9O1xufVxuXG4vKipcbiAqIExvYWQgdGhlIENTUyBmb3IgdGhlIGN1cnJlbnQgZW50cnlwb2ludC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gbG9hZENzcygpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCB1cmwgPSBicm93c2VyLnJ1bnRpbWUuZ2V0VVJMKGAvY29udGVudC1zY3JpcHRzLyR7X19FTlRSWVBPSU5UX199LmNzc2ApO1xuICB0cnkge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKHVybCk7XG4gICAgY29uc3QgY3NzID0gYXdhaXQgcmVzLnRleHQoKTtcblxuICAgIC8vIFJlcGxhY2UgOnJvb3Qgc2VsZWN0b3JzIHdpdGggOmhvc3Qgc2luY2Ugd2UncmUgaW4gYSBzaGFkb3cgcm9vdFxuICAgIHJldHVybiBjc3MucmVwbGFjZUFsbCgnOnJvb3QnLCAnOmhvc3QnKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICBgRmFpbGVkIHRvIGxvYWQgc3R5bGVzIEAgJHt1cmx9LiBEaWQgeW91IGZvcmdldCB0byBpbXBvcnQgdGhlIHN0eWxlc2hlZXQgaW4geW91ciBlbnRyeXBvaW50P2AsXG4gICAgICBlcnIsXG4gICAgKTtcbiAgICByZXR1cm4gJyc7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb250ZW50U2NyaXB0VWk8VD4ge1xuICAvKipcbiAgICogVGhlIGBIVE1MRWxlbWVudGAgaG9zdGluZyB0aGUgc2hhZG93IHJvb3QgdXNlZCB0byBpc29sYXRlIHRoZSBVSSdzIHN0eWxlcy4gVGhpcyBpcyB0aGUgZWxlbWVudFxuICAgKiB0aGF0IGdldCdzIGFkZGVkIHRvIHRoZSBET00uIFRoaXMgZWxlbWVudCdzIHN0eWxlIGlzIG5vdCBpc29sYXRlZCBmcm9tIHRoZSB3ZWJwYWdlLlxuICAgKi9cbiAgc2hhZG93SG9zdDogSFRNTEVsZW1lbnQ7XG4gIC8qKlxuICAgKiBUaGUgY29udGFpbmVyIGVsZW1lbnQgaW5zaWRlIHRoZSBgU2hhZG93Um9vdGAgd2hvc2Ugc3R5bGVzIGFyZSBpc29sYXRlZC4gVGhlIFVJIGlzIG1vdW50ZWRcbiAgICogaW5zaWRlIHRoaXMgYEhUTUxFbGVtZW50YC5cbiAgICovXG4gIHVpQ29udGFpbmVyOiBIVE1MRWxlbWVudDtcbiAgLyoqXG4gICAqIFRoZSBzaGFkb3cgcm9vdCBwZXJmb3JtaW5nIHRoZSBpc29sYXRpb24uXG4gICAqL1xuICBzaGFkb3c6IFNoYWRvd1Jvb3Q7XG4gIC8qKlxuICAgKiBDdXN0b20gZGF0YSByZXR1cm5lZCBmcm9tIHRoZSBgb3B0aW9ucy5tb3VudGAgZnVuY3Rpb24uXG4gICAqL1xuICBtb3VudGVkOiBUO1xuICAvKipcbiAgICogRnVuY3Rpb24gdGhhdCBtb3VudHMgb3IgcmVtb3VudHMgdGhlIFVJIG9uIHRoZSBwYWdlLlxuICAgKi9cbiAgbW91bnQ6ICgpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBGdW5jdGlvbiB0aGF0IHJlbW92ZXMgdGhlIFVJIGZyb20gdGhlIHdlYnBhZ2UuXG4gICAqL1xuICByZW1vdmU6ICgpID0+IHZvaWQ7XG59XG5cbmludGVyZmFjZSBCYXNlQ29udGVudFNjcmlwdFVpT3B0aW9uczxUPiB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgY3VzdG9tIGNvbXBvbmVudCB1c2VkIHRvIGhvc3QgdGhlIFNoYWRvd1Jvb3QuIE11c3QgYmUga2ViYWItY2FzZS5cbiAgICovXG4gIG5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIEluIGNvbWJpbmF0aW9uIHdpdGggYGFuY2hvcmAsIGRlY2lkZSBob3cgdG8gYWRkIHRoZSBVSSB0byB0aGUgRE9NLlxuICAgKlxuICAgKiAtIGBcImxhc3RcImAgKGRlZmF1bHQpIC0gQWRkIHRoZSBVSSBhcyB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgYGFuY2hvcmAgZWxlbWVudFxuICAgKiAtIGBcImZpcnN0XCJgIC0gQWRkIHRoZSBVSSBhcyB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgYGFuY2hvcmAgZWxlbWVudFxuICAgKiAtIGBcInJlcGxhY2VcImAgLSBSZXBsYWNlIHRoZSBgYW5jaG9yYCBlbGVtZW50IHdpdGggdGhlIFVJLlxuICAgKiAtIGBcImJlZm9yZVwiYCAtIEFkZCB0aGUgVUkgYXMgdGhlIHNpYmxpbmcgYmVmb3JlIHRoZSBgYW5jaG9yYCBlbGVtZW50XG4gICAqIC0gYFwiYWZ0ZXJcImAgLSBBZGQgdGhlIFVJIGFzIHRoZSBzaWJsaW5nIGFmdGVyIHRoZSBgYW5jaG9yYCBlbGVtZW50XG4gICAqIC0gYChhbmNob3IsIHVpKSA9PiB2b2lkYCAtIEN1c3RvbWl6YWJsZSBmdW5jdGlvbiB0aGF0IGxldCdzIHlvdSBhZGQgdGhlIFVJIHRvIHRoZSBET01cbiAgICovXG4gIGFwcGVuZD86IENvbnRlbnRTY3JpcHRBcHBlbmRNb2RlIHwgKChhbmNob3I6IEVsZW1lbnQsIHVpOiBFbGVtZW50KSA9PiB2b2lkKTtcbiAgLyoqXG4gICAqIEEgQ1NTIHNlbGVjdG9yLCBlbGVtZW50LCBvciBmdW5jdGlvbiB0aGF0IHJldHVybnMgb25lIG9mIHRoZSB0d28uIEFsb25nIHdpdGggYGFwcGVuZGAsIHRoZVxuICAgKiBgYW5jaG9yYCBkaWN0YXRlcyB3aGVyZSBpbiB0aGUgcGFnZSB0aGUgVUkgd2lsbCBiZSBhZGRlZC5cbiAgICovXG4gIGFuY2hvcj86XG4gICAgfCBzdHJpbmdcbiAgICB8IEVsZW1lbnRcbiAgICB8IG51bGxcbiAgICB8IHVuZGVmaW5lZFxuICAgIHwgKCgpID0+IHN0cmluZyB8IEVsZW1lbnQgfCBudWxsIHwgdW5kZWZpbmVkKTtcbiAgLyoqXG4gICAqIENhbGxiYWNrIGV4ZWN1dGVkIHdoZW4gbW91bnRpbmcgdGhlIFVJLiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBjcmVhdGUgYW5kIGFwcGVuZCB0aGUgVUkgdG8gdGhlXG4gICAqIGBjb250YWluZXJgIGVsZW1lbnQuIEl0IGlzIGNhbGxlZCBldmVyeSB0aW1lIGB1aS5tb3VudCgpYCBpcyBjYWxsZWRcbiAgICpcbiAgICogT3B0aW9uYWxseSByZXR1cm4gYSB2YWx1ZSB0aGF0IGNhbiBiZSBhY2Nlc3NlZCBhdCBgdWkubW91bnRlZGAgb3IgaW4gdGhlIGBvblJlbW92ZWAgY2FsbGJhY2suXG4gICAqL1xuICBtb3VudDogKGNvbnRhaW5lcjogRWxlbWVudCkgPT4gVDtcbiAgLyoqXG4gICAqIENhbGxiYWNrIGNhbGxlZCB3aGVuIHRoZSBVSSBpcyByZW1vdmVkIGZyb20gdGhlIHdlYnBhZ2UuIFVzZSB0byBjbGVhbnVwIHlvdXIgVUksIGxpa2VcbiAgICogdW5tb3VudGluZyB5b3VyIHZ1ZSBvciByZWFjdCBhcHBzLlxuICAgKi9cbiAgb25SZW1vdmU/OiAobW91bnRlZDogVCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIEN1c3RvbSBDU1MgdGV4dCB0byBhcHBseSB0byB0aGUgVUkuIElmIHlvdXIgY29udGVudCBzY3JpcHQgaW1wb3J0cy9nZW5lcmF0ZXMgQ1NTIGFuZCB5b3UndmVcbiAgICogc2V0IGBjc3NJbmplY3Rpb25Nb2RlOiBcInVpXCJgLCB0aGUgaW1wb3J0ZWQgQ1NTIHdpbGwgYmUgaW5jbHVkZWQgYXV0b21hdGljYWxseS4gWW91IGRvIG5vdCBuZWVkXG4gICAqIHRvIHBhc3MgdGhvc2Ugc3R5bGVzIGluIGhlcmUuIFRoaXMgaXMgZm9yIGFueSBhZGRpdGlvbmFsIHN0eWxlcyBub3QgaW4gdGhlIGltcG9ydGVkIENTUy5cbiAgICpcbiAgICogU2VlIDxodHRwczovL3d4dC5kZXYvZ3VpZGUvY29udGVudC1zY3JpcHRzLmh0bWwjdWk+IGZvciBtb3JlIGluZm8uXG4gICAqL1xuICBjc3M/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIE92ZXJsYXlDb250ZW50U2NyaXB0VWlPcHRpb25zPFQ+ID0gQmFzZUNvbnRlbnRTY3JpcHRVaU9wdGlvbnM8VD4gJiB7XG4gIHR5cGU6ICdvdmVybGF5JztcbiAgLyoqXG4gICAqIFdoZW4gdXNpbmcgYHR5cGU6IFwib3ZlcmxheVwiYCwgdGhlIG1vdW50ZWQgZWxlbWVudCBpcyAwcHggYnkgMHB4IGluIHNpemUuIEFsaWdubWVudCBzcGVjaWZpZXNcbiAgICogd2hpY2ggY29ybmVyIGlzIGFsaWduZWQgd2l0aCB0aGF0IDB4MCBwaXhlbCBzcGFjZS5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJ0b3AtbGVmdFwiXG4gICAqL1xuICBhbGlnbm1lbnQ/OiBDb250ZW50U2NyaXB0VWlPdmVybGF5QWxpZ25tZW50O1xuICAvKipcbiAgICogVGhlIGB6LWluZGV4YCB1c2VkIG9uIHRoZSBgc2hhZG93SG9zdGAuIFNldCB0byBhIHBvc2l0aXZlIG51bWJlciB0byBzaG93IHlvdXIgVUkgb3ZlciB3ZWJzaXRlXG4gICAqIGNvbnRlbnQuXG4gICAqL1xuICB6SW5kZXg/OiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBNb2RhbENvbnRlbnRTY3JpcHRVaU9wdGlvbnM8VD4gPSBCYXNlQ29udGVudFNjcmlwdFVpT3B0aW9uczxUPiAmIHtcbiAgdHlwZTogJ21vZGFsJztcbiAgLyoqXG4gICAqIFRoZSBgei1pbmRleGAgdXNlZCBvbiB0aGUgYHNoYWRvd0hvc3RgLiBTZXQgdG8gYSBwb3NpdGl2ZSBudW1iZXIgdG8gc2hvdyB5b3VyIFVJIG92ZXIgd2Vic2l0ZVxuICAgKiBjb250ZW50LlxuICAgKi9cbiAgekluZGV4PzogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgSW5saW5lQ29udGVudFNjcmlwdFVpT3B0aW9uczxUPiA9IEJhc2VDb250ZW50U2NyaXB0VWlPcHRpb25zPFQ+ICYge1xuICB0eXBlOiAnaW5saW5lJztcbn07XG5cbmV4cG9ydCB0eXBlIENvbnRlbnRTY3JpcHRVaU92ZXJsYXlBbGlnbm1lbnQgPVxuICB8ICd0b3AtbGVmdCdcbiAgfCAndG9wLXJpZ2h0J1xuICB8ICdib3R0b20tbGVmdCdcbiAgfCAnYm90dG9tLXJpZ2h0JztcblxuZXhwb3J0IHR5cGUgQ29udGVudFNjcmlwdEFwcGVuZE1vZGUgPVxuICB8ICdsYXN0J1xuICB8ICdmaXJzdCdcbiAgfCAncmVwbGFjZSdcbiAgfCAnYmVmb3JlJ1xuICB8ICdhZnRlcic7XG5cbmV4cG9ydCB0eXBlIENvbnRlbnRTY3JpcHRVaU9wdGlvbnM8VD4gPVxuICB8IE92ZXJsYXlDb250ZW50U2NyaXB0VWlPcHRpb25zPFQ+XG4gIHwgTW9kYWxDb250ZW50U2NyaXB0VWlPcHRpb25zPFQ+XG4gIHwgSW5saW5lQ29udGVudFNjcmlwdFVpT3B0aW9uczxUPjtcbiIsICJpbXBvcnQgb3JpZ2luYWxCcm93c2VyLCB7IEJyb3dzZXIsIFJ1bnRpbWUsIEkxOG4gfSBmcm9tICd3ZWJleHRlbnNpb24tcG9seWZpbGwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEF1Z21lbnRlZEJyb3dzZXIgZXh0ZW5kcyBCcm93c2VyIHtcbiAgcnVudGltZTogV3h0UnVudGltZTtcbiAgaTE4bjogV3h0STE4bjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXeHRSdW50aW1lIGV4dGVuZHMgUnVudGltZS5TdGF0aWMge1xuICAvLyBPdmVycmlkZW4gcGVyLXByb2plY3Rcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXeHRJMThuIGV4dGVuZHMgSTE4bi5TdGF0aWMge1xuICAvLyBPdmVycmlkZW4gcGVyLXByb2plY3Rcbn1cblxuZXhwb3J0IGNvbnN0IGJyb3dzZXI6IEF1Z21lbnRlZEJyb3dzZXIgPSBvcmlnaW5hbEJyb3dzZXI7XG4iLCAiZnVuY3Rpb24gcHJpbnQobWV0aG9kOiAoLi4uYXJnczogYW55W10pID0+IHZvaWQsIC4uLmFyZ3M6IGFueVtdKSB7XG4gIGlmIChpbXBvcnQubWV0YS5lbnYuTU9ERSA9PT0gJ3Byb2R1Y3Rpb24nKSByZXR1cm47XG5cbiAgaWYgKHR5cGVvZiBhcmdzWzBdID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBhcmdzLnNoaWZ0KCk7XG4gICAgbWV0aG9kKGBbd3h0XSAke21lc3NhZ2V9YCwgLi4uYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgbWV0aG9kKCdbd3h0XScsIC4uLmFyZ3MpO1xuICB9XG59XG5cbi8qKlxuICogV3JhcHBlciBhcm91bmQgYGNvbnNvbGVgIHdpdGggYSBcIlt3eHRdXCIgcHJlZml4XG4gKi9cbmV4cG9ydCBjb25zdCBsb2dnZXIgPSB7XG4gIGRlYnVnOiAoLi4uYXJnczogYW55W10pID0+IHByaW50KGNvbnNvbGUuZGVidWcsIC4uLmFyZ3MpLFxuICBsb2c6ICguLi5hcmdzOiBhbnlbXSkgPT4gcHJpbnQoY29uc29sZS5sb2csIC4uLmFyZ3MpLFxuICB3YXJuOiAoLi4uYXJnczogYW55W10pID0+IHByaW50KGNvbnNvbGUud2FybiwgLi4uYXJncyksXG4gIGVycm9yOiAoLi4uYXJnczogYW55W10pID0+IHByaW50KGNvbnNvbGUuZXJyb3IsIC4uLmFyZ3MpLFxufTtcbiIsICJpbXBvcnQgeyBDb250ZW50U2NyaXB0RGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgYnJvd3NlciB9IGZyb20gJy4uL2Jyb3dzZXInO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuXG4vKipcbiAqIEV4dGVuZHMgW2BBYm9ydENvbnRyb2xsZXJgXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQWJvcnRDb250cm9sbGVyKS5cbiAqIFVzZWQgdG8gZGV0ZWN0IGFuZCBzdG9wIGNvbnRlbnQgc2NyaXB0IGNvZGUgd2hlbiB0aGUgc2NyaXB0IGlzIGludmFsaWRhdGVkLlxuICpcbiAqIEl0IGFsc28gcHJvdmlkZXMgc2V2ZXJhbCB1dGlsaXRpZXMgbGlrZSBgY3R4LnNldFRpbWVvdXRgIGFuZCBgY3R4LnNldEludGVydmFsYCB0aGF0IHNob3VsZCBiZSB1c2VkIGluXG4gKiBjb250ZW50IHNjcmlwdHMgaW5zdGVhZCBvZiBgd2luZG93LnNldFRpbWVvdXRgIG9yIGB3aW5kb3cuc2V0SW50ZXJ2YWxgLlxuICovXG5leHBvcnQgY2xhc3MgQ29udGVudFNjcmlwdENvbnRleHQgZXh0ZW5kcyBBYm9ydENvbnRyb2xsZXIge1xuICBzdGF0aWMgU0NSSVBUX1NUQVJURURfTUVTU0FHRV9UWVBFID0gJ3d4dDpjb250ZW50LXNjcmlwdC1zdGFydGVkJztcblxuICAjaXNUb3BGcmFtZSA9IHdpbmRvdy5zZWxmID09PSB3aW5kb3cudG9wO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY29udGVudFNjcmlwdE5hbWU6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgb3B0aW9ucz86IE9taXQ8Q29udGVudFNjcmlwdERlZmluaXRpb24sICdtYWluJz4sXG4gICkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBpZiAodGhpcy4jaXNUb3BGcmFtZSkge1xuICAgICAgdGhpcy4jc3RvcE9sZFNjcmlwdHMoKTtcbiAgICB9XG4gICAgdGhpcy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIC8vIFJ1biBvbiBuZXh0IHRpY2sgc28gdGhlIGxpc3RlbmVyIGl0IGFkZHMgaXNuJ3QgdHJpZ2dlcmVkIGJ5IHN0b3BPbGRTY3JpcHRcbiAgICAgIHRoaXMuI2xpc3RlbkZvck5ld2VyU2NyaXB0cygpO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0IGlzSW52YWxpZCgpOiBib29sZWFuIHtcbiAgICBpZiAoYnJvd3Nlci5ydW50aW1lLmlkID09IG51bGwpIHtcbiAgICAgIHRoaXMubm90aWZ5SW52YWxpZGF0ZWQoKTsgLy8gU2V0cyBgc2lnbmFsLmFib3J0ZWRgIHRvIHRydWVcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2lnbmFsLmFib3J0ZWQ7XG4gIH1cblxuICBnZXQgaXNWYWxpZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMuaXNJbnZhbGlkO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIGxpc3RlbmVyIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhlIGNvbnRlbnQgc2NyaXB0J3MgY29udGV4dCBpcyBpbnZhbGlkYXRlZC5cbiAgICpcbiAgICogQHJldHVybnMgQSBmdW5jdGlvbiB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBicm93c2VyLnJ1bnRpbWUub25NZXNzYWdlLmFkZExpc3RlbmVyKGNiKTtcbiAgICogY29uc3QgcmVtb3ZlSW52YWxpZGF0ZWRMaXN0ZW5lciA9IGN0eC5vbkludmFsaWRhdGVkKCgpID0+IHtcbiAgICogICBicm93c2VyLnJ1bnRpbWUub25NZXNzYWdlLnJlbW92ZUxpc3RlbmVyKGNiKTtcbiAgICogfSlcbiAgICogLy8gLi4uXG4gICAqIHJlbW92ZUludmFsaWRhdGVkTGlzdGVuZXIoKTtcbiAgICovXG4gIG9uSW52YWxpZGF0ZWQoY2I6ICgpID0+IHZvaWQpOiAoKSA9PiB2b2lkIHtcbiAgICB0aGlzLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsIGNiKTtcbiAgICByZXR1cm4gKCkgPT4gdGhpcy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBjYik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgcHJvbWlzZSB0aGF0IG5ldmVyIHJlc29sdmVzLiBVc2VmdWwgaWYgeW91IGhhdmUgYW4gYXN5bmMgZnVuY3Rpb24gdGhhdCBzaG91bGRuJ3QgcnVuXG4gICAqIGFmdGVyIHRoZSBjb250ZXh0IGlzIGV4cGlyZWQuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IGdldFZhbHVlRnJvbVN0b3JhZ2UgPSBhc3luYyAoKSA9PiB7XG4gICAqICAgaWYgKGN0eC5pc0ludmFsaWQpIHJldHVybiBjdHguYmxvY2soKTtcbiAgICpcbiAgICogICAvLyAuLi5cbiAgICogfVxuICAgKi9cbiAgYmxvY2s8VD4oKTogUHJvbWlzZTxUPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKCgpID0+IHtcbiAgICAgIC8vIG5vb3BcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXcmFwcGVyIGFyb3VuZCBgd2luZG93LnNldEludGVydmFsYCB0aGF0IGF1dG9tYXRpY2FsbHkgY2xlYXJzIHRoZSBpbnRlcnZhbCB3aGVuIGludmFsaWRhdGVkLlxuICAgKi9cbiAgc2V0SW50ZXJ2YWwoaGFuZGxlcjogKCkgPT4gdm9pZCwgdGltZW91dD86IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3QgaWQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5pc1ZhbGlkKSBoYW5kbGVyKCk7XG4gICAgfSwgdGltZW91dCkgYXMgdW5rbm93biBhcyBudW1iZXI7XG4gICAgdGhpcy5vbkludmFsaWRhdGVkKCgpID0+IGNsZWFySW50ZXJ2YWwoaWQpKTtcbiAgICByZXR1cm4gaWQ7XG4gIH1cblxuICAvKipcbiAgICogV3JhcHBlciBhcm91bmQgYHdpbmRvdy5zZXRUaW1lb3V0YCB0aGF0IGF1dG9tYXRpY2FsbHkgY2xlYXJzIHRoZSBpbnRlcnZhbCB3aGVuIGludmFsaWRhdGVkLlxuICAgKi9cbiAgc2V0VGltZW91dChoYW5kbGVyOiAoKSA9PiB2b2lkLCB0aW1lb3V0PzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBpZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaXNWYWxpZCkgaGFuZGxlcigpO1xuICAgIH0sIHRpbWVvdXQpIGFzIHVua25vd24gYXMgbnVtYmVyO1xuICAgIHRoaXMub25JbnZhbGlkYXRlZCgoKSA9PiBjbGVhclRpbWVvdXQoaWQpKTtcbiAgICByZXR1cm4gaWQ7XG4gIH1cblxuICAvKipcbiAgICogV3JhcHBlciBhcm91bmQgYHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWVgIHRoYXQgYXV0b21hdGljYWxseSBjYW5jZWxzIHRoZSByZXF1ZXN0IHdoZW5cbiAgICogaW52YWxpZGF0ZWQuXG4gICAqL1xuICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoY2FsbGJhY2s6IEZyYW1lUmVxdWVzdENhbGxiYWNrKTogbnVtYmVyIHtcbiAgICBjb25zdCBpZCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoLi4uYXJncykgPT4ge1xuICAgICAgaWYgKHRoaXMuaXNWYWxpZCkgY2FsbGJhY2soLi4uYXJncyk7XG4gICAgfSk7XG5cbiAgICB0aGlzLm9uSW52YWxpZGF0ZWQoKCkgPT4gY2FuY2VsQW5pbWF0aW9uRnJhbWUoaWQpKTtcbiAgICByZXR1cm4gaWQ7XG4gIH1cblxuICAvKipcbiAgICogV3JhcHBlciBhcm91bmQgYHdpbmRvdy5yZXF1ZXN0SWRsZUNhbGxiYWNrYCB0aGF0IGF1dG9tYXRpY2FsbHkgY2FuY2VscyB0aGUgcmVxdWVzdCB3aGVuXG4gICAqIGludmFsaWRhdGVkLlxuICAgKi9cbiAgcmVxdWVzdElkbGVDYWxsYmFjayhcbiAgICBjYWxsYmFjazogSWRsZVJlcXVlc3RDYWxsYmFjayxcbiAgICBvcHRpb25zPzogSWRsZVJlcXVlc3RPcHRpb25zLFxuICApOiBudW1iZXIge1xuICAgIGNvbnN0IGlkID0gcmVxdWVzdElkbGVDYWxsYmFjaygoLi4uYXJncykgPT4ge1xuICAgICAgaWYgKCF0aGlzLnNpZ25hbC5hYm9ydGVkKSBjYWxsYmFjayguLi5hcmdzKTtcbiAgICB9LCBvcHRpb25zKTtcblxuICAgIHRoaXMub25JbnZhbGlkYXRlZCgoKSA9PiBjYW5jZWxJZGxlQ2FsbGJhY2soaWQpKTtcbiAgICByZXR1cm4gaWQ7XG4gIH1cblxuICAvKipcbiAgICogQ2FsbCBgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXJgIGFuZCByZW1vdmUgdGhlIGV2ZW50IGxpc3RlbmVyIHdoZW4gdGhlIGNvbnRleHQgaXMgaW52YWxpZGF0ZWQuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGN0eC5hZGRFdmVudExpc3RlbmVyKHdpbmRvdywgXCJtb3VzZW1vdmVcIiwgKCkgPT4ge1xuICAgKiAgIC8vIC4uLlxuICAgKiB9KTtcbiAgICogY3R4LmFkZEV2ZW50TGlzdGVuZXIoZG9jdW1lbnQsIFwidmlzaWJpbGl0eWNoYW5nZVwiLCAoKSA9PiB7XG4gICAqICAgLy8gLi4uXG4gICAqIH0pO1xuICAgKi9cbiAgYWRkRXZlbnRMaXN0ZW5lcihcbiAgICB0YXJnZXQ6IGFueSxcbiAgICB0eXBlOiBzdHJpbmcsXG4gICAgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCxcbiAgICBvcHRpb25zPzogQWRkRXZlbnRMaXN0ZW5lck9wdGlvbnMsXG4gICkge1xuICAgIHRhcmdldC5hZGRFdmVudExpc3RlbmVyPy4odHlwZSwgaGFuZGxlciwgb3B0aW9ucyk7XG4gICAgdGhpcy5vbkludmFsaWRhdGVkKFxuICAgICAgKCkgPT4gdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXI/Lih0eXBlLCBoYW5kbGVyLCBvcHRpb25zKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFib3J0IHRoZSBhYm9ydCBjb250cm9sbGVyIGFuZCBleGVjdXRlIGFsbCBgb25JbnZhbGlkYXRlZGAgbGlzdGVuZXJzLlxuICAgKi9cbiAgbm90aWZ5SW52YWxpZGF0ZWQoKSB7XG4gICAgdGhpcy5hYm9ydCgnQ29udGVudCBzY3JpcHQgY29udGV4dCBpbnZhbGlkYXRlZCcpO1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBDb250ZW50IHNjcmlwdCBcIiR7dGhpcy5jb250ZW50U2NyaXB0TmFtZX1cIiBjb250ZXh0IGludmFsaWRhdGVkYCxcbiAgICApO1xuICB9XG5cbiAgI3N0b3BPbGRTY3JpcHRzKCkge1xuICAgIC8vIFVzZSBwb3N0TWVzc2FnZSBzbyBpdCBnZXQncyBzZW50IHRvIGFsbCB0aGUgZnJhbWVzIG9mIHRoZSBwYWdlLlxuICAgIHdpbmRvdy5wb3N0TWVzc2FnZShcbiAgICAgIHtcbiAgICAgICAgZXZlbnQ6IENvbnRlbnRTY3JpcHRDb250ZXh0LlNDUklQVF9TVEFSVEVEX01FU1NBR0VfVFlQRSxcbiAgICAgICAgY29udGVudFNjcmlwdE5hbWU6IHRoaXMuY29udGVudFNjcmlwdE5hbWUsXG4gICAgICB9LFxuICAgICAgJyonLFxuICAgICk7XG4gIH1cblxuICAjbGlzdGVuRm9yTmV3ZXJTY3JpcHRzKCkge1xuICAgIGNvbnN0IGNiID0gKGV2ZW50OiBNZXNzYWdlRXZlbnQpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgZXZlbnQuZGF0YT8udHlwZSA9PT0gQ29udGVudFNjcmlwdENvbnRleHQuU0NSSVBUX1NUQVJURURfTUVTU0FHRV9UWVBFICYmXG4gICAgICAgIGV2ZW50LmRhdGE/LmNvbnRlbnRTY3JpcHROYW1lID09PSB0aGlzLmNvbnRlbnRTY3JpcHROYW1lXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5ub3RpZnlJbnZhbGlkYXRlZCgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBhZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgY2IpO1xuICAgIHRoaXMub25JbnZhbGlkYXRlZCgoKSA9PiByZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgY2IpKTtcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUVPLFNBQVMsb0JBQ2QsWUFDeUI7QUFDekIsU0FBTztBQUNUOzs7QUNBTyxTQUFTLGlCQUNkLEtBQzZCO0FBQzdCLE1BQUksT0FBTyxRQUFRO0FBQVksV0FBTyxFQUFFLE1BQU0sSUFBSTtBQUNsRCxTQUFPO0FBQ1Q7OztBQ1hBLFNBQVMsNkJBQTZCOzs7QUNBdEMsT0FBTyxxQkFBaUQ7QUFlakQsSUFBTSxVQUE0Qjs7O0FDZnpDLFNBQVMsTUFBTSxXQUFxQyxNQUFhO0FBQy9ELE1BQUksWUFBWSxJQUFJLFNBQVM7QUFBYztBQUUzQyxNQUFJLE9BQU8sS0FBSyxDQUFDLE1BQU0sVUFBVTtBQUMvQixVQUFNLFVBQVUsS0FBSyxNQUFNO0FBQzNCLFdBQU8sU0FBUyxPQUFPLElBQUksR0FBRyxJQUFJO0FBQUEsRUFDcEMsT0FBTztBQUNMLFdBQU8sU0FBUyxHQUFHLElBQUk7QUFBQSxFQUN6QjtBQUNGO0FBS08sSUFBTSxTQUFTO0FBQUEsRUFDcEIsT0FBTyxJQUFJLFNBQWdCLE1BQU0sUUFBUSxPQUFPLEdBQUcsSUFBSTtBQUFBLEVBQ3ZELEtBQUssSUFBSSxTQUFnQixNQUFNLFFBQVEsS0FBSyxHQUFHLElBQUk7QUFBQSxFQUNuRCxNQUFNLElBQUksU0FBZ0IsTUFBTSxRQUFRLE1BQU0sR0FBRyxJQUFJO0FBQUEsRUFDckQsT0FBTyxJQUFJLFNBQWdCLE1BQU0sUUFBUSxPQUFPLEdBQUcsSUFBSTtBQUN6RDs7O0FGY0EsZUFBc0Isc0JBQ3BCLEtBQ0EsU0FDNkI7QUFDN0IsUUFBTSxNQUFNLENBQUMsUUFBUSxPQUFPLEVBQUU7QUFDOUIsTUFB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