@mnaoumov/obsidian-lib 10.5.0 → 10.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/codemirror/inline-token-widgets/package.json +6 -0
- package/codemirror/settings-facet/package.json +6 -0
- package/components/settings-facet-component/package.json +6 -0
- package/dist/lib/cjs/__merged.cjs +104 -1
- package/dist/lib/cjs/__merged.d.cts +20 -3
- package/dist/lib/cjs/anchored-suggest.cjs +232 -0
- package/dist/lib/cjs/anchored-suggest.d.cts +116 -0
- package/dist/lib/cjs/backlink-index.cjs +44 -8
- package/dist/lib/cjs/backlink-index.d.cts +23 -0
- package/dist/lib/cjs/bug-report.cjs +4 -2
- package/dist/lib/cjs/bug-report.d.cts +1 -1
- package/dist/lib/cjs/bulk-operation-progress.cjs +16 -1
- package/dist/lib/cjs/bulk-operation-progress.d.cts +22 -0
- package/dist/lib/cjs/case-insensitive-file-index.cjs +9 -1
- package/dist/lib/cjs/code-block-render-handoff.cjs +272 -0
- package/dist/lib/cjs/code-block-render-handoff.d.cts +131 -0
- package/dist/lib/cjs/codemirror/index.cjs +7 -1
- package/dist/lib/cjs/codemirror/index.d.cts +2 -0
- package/dist/lib/cjs/codemirror/inline-token-widgets.cjs +250 -0
- package/dist/lib/cjs/codemirror/inline-token-widgets.d.cts +109 -0
- package/dist/lib/cjs/codemirror/settings-facet.cjs +132 -0
- package/dist/lib/cjs/codemirror/settings-facet.d.cts +19 -0
- package/dist/lib/cjs/community-plugins.cjs +19 -2
- package/dist/lib/cjs/community-plugins.d.cts +14 -0
- package/dist/lib/cjs/components/bulk-operation-commit-component.cjs +5 -2
- package/dist/lib/cjs/components/index.cjs +4 -1
- package/dist/lib/cjs/components/index.d.cts +1 -0
- package/dist/lib/cjs/components/rename-delete-handler-component.cjs +105 -2
- package/dist/lib/cjs/components/settings-facet-component.cjs +136 -0
- package/dist/lib/cjs/components/settings-facet-component.d.cts +68 -0
- package/dist/lib/cjs/css-class.cjs +8 -1
- package/dist/lib/cjs/css-class.d.cts +28 -0
- package/dist/lib/cjs/desktop-bulk-operation-git.cjs +38 -13
- package/dist/lib/cjs/desktop-bulk-operation-git.d.cts +21 -1
- package/dist/lib/cjs/desktop-request-url-stream.cjs +258 -0
- package/dist/lib/cjs/desktop-request-url-stream.d.cts +22 -0
- package/dist/lib/cjs/editor-suggest-registrar.cjs +8 -2
- package/dist/lib/cjs/editor-suggest-registrar.d.cts +14 -2
- package/dist/lib/cjs/editor-suggest.cjs +198 -0
- package/dist/lib/cjs/editor-suggest.d.cts +103 -0
- package/dist/lib/cjs/generated-during-build.cjs +2 -2
- package/dist/lib/cjs/hotkey.cjs +185 -0
- package/dist/lib/cjs/hotkey.d.cts +59 -0
- package/dist/lib/cjs/i18n/locales/en.cjs +14 -1
- package/dist/lib/cjs/i18n/locales/en.d.cts +13 -0
- package/dist/lib/cjs/i18n/locales/translations-map.d.cts +13 -0
- package/dist/lib/cjs/index.cjs +31 -1
- package/dist/lib/cjs/index.d.cts +10 -0
- package/dist/lib/cjs/inline-token-renderer.cjs +145 -0
- package/dist/lib/cjs/inline-token-renderer.d.cts +88 -0
- package/dist/lib/cjs/link-and-tag-input-suggest.cjs +325 -0
- package/dist/lib/cjs/link-and-tag-input-suggest.d.cts +229 -0
- package/dist/lib/cjs/markdown-code-block-processor.cjs +13 -1
- package/dist/lib/cjs/markdown-code-block-processor.d.cts +18 -0
- package/dist/lib/cjs/markdown.cjs +6 -1
- package/dist/lib/cjs/markdown.d.cts +10 -1
- package/dist/lib/cjs/modals/modal.cjs +8 -5
- package/dist/lib/cjs/modals/modal.d.cts +4 -0
- package/dist/lib/cjs/plugin/plugin.cjs +5 -2
- package/dist/lib/cjs/plugin/plugin.d.cts +2 -0
- package/dist/lib/cjs/rendered-markdown.cjs +306 -0
- package/dist/lib/cjs/rendered-markdown.d.cts +77 -0
- package/dist/lib/cjs/request-url.cjs +523 -0
- package/dist/lib/cjs/request-url.d.cts +233 -0
- package/dist/lib/cjs/setting-components/folder-list-component.cjs +216 -0
- package/dist/lib/cjs/setting-components/folder-list-component.d.cts +73 -0
- package/dist/lib/cjs/setting-components/hotkey-component.cjs +260 -0
- package/dist/lib/cjs/setting-components/hotkey-component.d.cts +85 -0
- package/dist/lib/cjs/setting-components/index.cjs +13 -1
- package/dist/lib/cjs/setting-components/index.d.cts +4 -0
- package/dist/lib/cjs/setting-components/list-component.cjs +291 -0
- package/dist/lib/cjs/setting-components/list-component.d.cts +106 -0
- package/dist/lib/cjs/setting-components/tag-list-component.cjs +220 -0
- package/dist/lib/cjs/setting-components/tag-list-component.d.cts +82 -0
- package/dist/lib/cjs/setting-ex.cjs +51 -1
- package/dist/lib/cjs/setting-ex.d.cts +35 -1
- package/dist/lib/cjs/settings-tabs.cjs +258 -0
- package/dist/lib/cjs/settings-tabs.d.cts +101 -0
- package/dist/lib/esm/__merged.d.mts +20 -3
- package/dist/lib/esm/__merged.mjs +110 -2
- package/dist/lib/esm/anchored-suggest.d.mts +116 -0
- package/dist/lib/esm/anchored-suggest.mjs +144 -0
- package/dist/lib/esm/backlink-index.d.mts +23 -0
- package/dist/lib/esm/backlink-index.mjs +42 -7
- package/dist/lib/esm/bug-report.d.mts +1 -1
- package/dist/lib/esm/bug-report.mjs +4 -2
- package/dist/lib/esm/bulk-operation-progress.d.mts +22 -0
- package/dist/lib/esm/bulk-operation-progress.mjs +14 -1
- package/dist/lib/esm/case-insensitive-file-index.mjs +9 -1
- package/dist/lib/esm/code-block-render-handoff.d.mts +131 -0
- package/dist/lib/esm/code-block-render-handoff.mjs +183 -0
- package/dist/lib/esm/codemirror/index.d.mts +2 -0
- package/dist/lib/esm/codemirror/index.mjs +5 -1
- package/dist/lib/esm/codemirror/inline-token-widgets.d.mts +109 -0
- package/dist/lib/esm/codemirror/inline-token-widgets.mjs +167 -0
- package/dist/lib/esm/codemirror/settings-facet.d.mts +19 -0
- package/dist/lib/esm/codemirror/settings-facet.mjs +44 -0
- package/dist/lib/esm/community-plugins.d.mts +14 -0
- package/dist/lib/esm/community-plugins.mjs +18 -2
- package/dist/lib/esm/components/bulk-operation-commit-component.mjs +5 -2
- package/dist/lib/esm/components/index.d.mts +1 -0
- package/dist/lib/esm/components/index.mjs +3 -1
- package/dist/lib/esm/components/rename-delete-handler-component.mjs +105 -2
- package/dist/lib/esm/components/settings-facet-component.d.mts +68 -0
- package/dist/lib/esm/components/settings-facet-component.mjs +48 -0
- package/dist/lib/esm/css-class.d.mts +28 -0
- package/dist/lib/esm/css-class.mjs +8 -1
- package/dist/lib/esm/desktop-bulk-operation-git.d.mts +21 -1
- package/dist/lib/esm/desktop-bulk-operation-git.mjs +38 -13
- package/dist/lib/esm/desktop-request-url-stream.d.mts +22 -0
- package/dist/lib/esm/desktop-request-url-stream.mjs +170 -0
- package/dist/lib/esm/editor-suggest-registrar.d.mts +14 -2
- package/dist/lib/esm/editor-suggest-registrar.mjs +8 -2
- package/dist/lib/esm/editor-suggest.d.mts +103 -0
- package/dist/lib/esm/editor-suggest.mjs +109 -0
- package/dist/lib/esm/generated-during-build.mjs +2 -2
- package/dist/lib/esm/hotkey.d.mts +59 -0
- package/dist/lib/esm/hotkey.mjs +95 -0
- package/dist/lib/esm/i18n/locales/en.d.mts +13 -0
- package/dist/lib/esm/i18n/locales/en.mjs +14 -1
- package/dist/lib/esm/i18n/locales/translations-map.d.mts +13 -0
- package/dist/lib/esm/index.d.mts +10 -0
- package/dist/lib/esm/index.mjs +21 -1
- package/dist/lib/esm/inline-token-renderer.d.mts +88 -0
- package/dist/lib/esm/inline-token-renderer.mjs +59 -0
- package/dist/lib/esm/link-and-tag-input-suggest.d.mts +229 -0
- package/dist/lib/esm/link-and-tag-input-suggest.mjs +239 -0
- package/dist/lib/esm/markdown-code-block-processor.d.mts +18 -0
- package/dist/lib/esm/markdown-code-block-processor.mjs +16 -1
- package/dist/lib/esm/markdown.d.mts +10 -1
- package/dist/lib/esm/markdown.mjs +9 -1
- package/dist/lib/esm/modals/modal.d.mts +4 -0
- package/dist/lib/esm/modals/modal.mjs +8 -5
- package/dist/lib/esm/plugin/plugin.d.mts +2 -0
- package/dist/lib/esm/plugin/plugin.mjs +5 -2
- package/dist/lib/esm/rendered-markdown.d.mts +77 -0
- package/dist/lib/esm/rendered-markdown.mjs +219 -0
- package/dist/lib/esm/request-url.d.mts +233 -0
- package/dist/lib/esm/request-url.mjs +428 -0
- package/dist/lib/esm/setting-components/folder-list-component.d.mts +73 -0
- package/dist/lib/esm/setting-components/folder-list-component.mjs +131 -0
- package/dist/lib/esm/setting-components/hotkey-component.d.mts +85 -0
- package/dist/lib/esm/setting-components/hotkey-component.mjs +178 -0
- package/dist/lib/esm/setting-components/index.d.mts +4 -0
- package/dist/lib/esm/setting-components/index.mjs +9 -1
- package/dist/lib/esm/setting-components/list-component.d.mts +106 -0
- package/dist/lib/esm/setting-components/list-component.mjs +206 -0
- package/dist/lib/esm/setting-components/tag-list-component.d.mts +82 -0
- package/dist/lib/esm/setting-components/tag-list-component.mjs +131 -0
- package/dist/lib/esm/setting-ex.d.mts +35 -1
- package/dist/lib/esm/setting-ex.mjs +51 -1
- package/dist/lib/esm/settings-tabs.d.mts +101 -0
- package/dist/lib/esm/settings-tabs.mjs +170 -0
- package/dist/styles.css +83 -1
- package/package.json +3 -3
- package/setting-components/folder-list-component/package.json +6 -0
- package/setting-components/hotkey-component/package.json +6 -0
- package/setting-components/list-component/package.json +6 -0
- package/setting-components/tag-list-component/package.json +6 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/// <reference path="./library-references.d.cts" />
|
|
2
|
+
/// <reference lib="dom" />
|
|
3
|
+
/**
|
|
4
|
+
* @file
|
|
5
|
+
*
|
|
6
|
+
* The parts of a Reading view's behavior that Obsidian keeps inside its preview renderer, ported for
|
|
7
|
+
* markdown rendered anywhere else with `MarkdownRenderer.render`.
|
|
8
|
+
*
|
|
9
|
+
* `MarkdownPreviewRenderer.registerDomEvents` covers internal and external links, tags, drags, context
|
|
10
|
+
* menus and the footnote HOVER. Three things it does not cover, read from Obsidian `1.15.0`: the footnote
|
|
11
|
+
* CLICK (`onFootnoteLinkClick`), and the heading and list FOLDING, whose indicators the renderer only adds
|
|
12
|
+
* in its own `onRender` and whose clicks only it handles. Without these, a footnote click in standalone
|
|
13
|
+
* rendered markdown falls through to the browser's hash navigation, and nothing can be folded.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Parameters for {@link registerFoldHandlers}.
|
|
17
|
+
*/
|
|
18
|
+
export interface RegisterFoldHandlersParams {
|
|
19
|
+
/**
|
|
20
|
+
* The element markdown was rendered into, the one `MarkdownRenderer.render` was handed. Its direct
|
|
21
|
+
* children are the rendered blocks a folded heading hides.
|
|
22
|
+
*/
|
|
23
|
+
readonly el: HTMLElement;
|
|
24
|
+
/**
|
|
25
|
+
* Whether headings can be folded.
|
|
26
|
+
*
|
|
27
|
+
* @default `true`
|
|
28
|
+
*/
|
|
29
|
+
readonly shouldFoldHeadings?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Whether list items with a nested list can be folded.
|
|
32
|
+
*
|
|
33
|
+
* @default `true`
|
|
34
|
+
*/
|
|
35
|
+
readonly shouldFoldLists?: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Parameters for {@link registerFootnoteLinkHandler}.
|
|
39
|
+
*/
|
|
40
|
+
export interface RegisterFootnoteLinkHandlerParams {
|
|
41
|
+
/**
|
|
42
|
+
* The element markdown was rendered into.
|
|
43
|
+
*/
|
|
44
|
+
readonly el: HTMLElement;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Whether an element belongs to the markdown rendered into `rootEl`, rather than to a Reading view or a
|
|
48
|
+
* Bases view nested inside it (an embed), which handles its own events. A port of Obsidian's static
|
|
49
|
+
* `MarkdownPreviewRenderer.belongsToMe`, which `obsidian-typings` does not declare.
|
|
50
|
+
*
|
|
51
|
+
* @param element - The element an event landed on.
|
|
52
|
+
* @param rootEl - The element markdown was rendered into.
|
|
53
|
+
* @returns Whether the element is `rootEl` itself or sits inside it with no nested view in between.
|
|
54
|
+
*/
|
|
55
|
+
export declare function isOwnedByRenderedMarkdown(element: Element, rootEl: HTMLElement): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Makes the headings and the nested lists of rendered markdown foldable, the way they are in a Reading
|
|
58
|
+
* view: it adds Obsidian's own collapse indicators and handles their clicks.
|
|
59
|
+
*
|
|
60
|
+
* A folded heading hides every block after it up to the next heading of the same or a higher level;
|
|
61
|
+
* unfolding it shows them again, except those a folded heading among them still hides. A folded list
|
|
62
|
+
* item hides its nested lists. Call it again after the element is re-rendered: blocks that already have
|
|
63
|
+
* an indicator are left alone, and the click handler is registered only once per element.
|
|
64
|
+
*
|
|
65
|
+
* @param params - The parameters.
|
|
66
|
+
*/
|
|
67
|
+
export declare function registerFoldHandlers(params: RegisterFoldHandlersParams): void;
|
|
68
|
+
/**
|
|
69
|
+
* Makes a footnote link in rendered markdown act as it does in a Reading view: a click scrolls to the
|
|
70
|
+
* footnote, or back to its reference, and flashes it, instead of navigating to the link's `#` hash.
|
|
71
|
+
*
|
|
72
|
+
* Registered by `registerLinkHandlers`, which is the usual way in; call it directly only for an element
|
|
73
|
+
* whose other links are handled some other way.
|
|
74
|
+
*
|
|
75
|
+
* @param params - The parameters.
|
|
76
|
+
*/
|
|
77
|
+
export declare function registerFootnoteLinkHandler(params: RegisterFootnoteLinkHandlerParams): void;
|
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
/*
|
|
2
|
+
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
3
|
+
if you want to view the source, please visit the github repository of this plugin
|
|
4
|
+
*/
|
|
5
|
+
(function () {
|
|
6
|
+
function ensureDisposeSymbols(symbolConstructor = Symbol) {
|
|
7
|
+
symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
|
|
8
|
+
symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function ensureBrowserProcess() {
|
|
12
|
+
const browserProcess = {
|
|
13
|
+
browser: true,
|
|
14
|
+
cwd() {
|
|
15
|
+
return "/";
|
|
16
|
+
},
|
|
17
|
+
env: {},
|
|
18
|
+
platform: "android"
|
|
19
|
+
};
|
|
20
|
+
const existingProcess = globalThis.process;
|
|
21
|
+
if (!existingProcess) {
|
|
22
|
+
globalThis.process = browserProcess;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (existingProcess.versions?.node) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const existingProcessRecord = existingProcess;
|
|
29
|
+
for (const [key, value] of Object.entries(browserProcess)) {
|
|
30
|
+
existingProcessRecord[key] ??= value;
|
|
31
|
+
}
|
|
32
|
+
existingProcessRecord["browser"] = true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
ensureDisposeSymbols();
|
|
36
|
+
ensureBrowserProcess();
|
|
37
|
+
})();
|
|
38
|
+
(function patchObsidianRequire() {
|
|
39
|
+
const originalRequire = require;
|
|
40
|
+
if (!originalRequire || originalRequire.__isPatched) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
require = Object.assign(
|
|
44
|
+
(id) => requirePatched(id),
|
|
45
|
+
originalRequire,
|
|
46
|
+
{
|
|
47
|
+
__isPatched: true
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
function extractDefault($module) {
|
|
51
|
+
return $module && $module.__esModule && "default" in $module ? $module.default : $module;
|
|
52
|
+
}
|
|
53
|
+
const OBSIDIAN_BUILT_IN_MODULE_NAMES = /* @__PURE__ */ new Set([
|
|
54
|
+
"@codemirror/autocomplete",
|
|
55
|
+
"@codemirror/collab",
|
|
56
|
+
"@codemirror/commands",
|
|
57
|
+
"@codemirror/language",
|
|
58
|
+
"@codemirror/lint",
|
|
59
|
+
"@codemirror/search",
|
|
60
|
+
"@codemirror/state",
|
|
61
|
+
"@codemirror/text",
|
|
62
|
+
"@codemirror/view",
|
|
63
|
+
"@lezer/common",
|
|
64
|
+
"@lezer/highlight",
|
|
65
|
+
"@lezer/lr",
|
|
66
|
+
"obsidian"
|
|
67
|
+
]);
|
|
68
|
+
const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = /* @__PURE__ */ new Set([
|
|
69
|
+
"@codemirror/closebrackets",
|
|
70
|
+
"@codemirror/comment",
|
|
71
|
+
"@codemirror/fold",
|
|
72
|
+
"@codemirror/gutter",
|
|
73
|
+
"@codemirror/highlight",
|
|
74
|
+
"@codemirror/history",
|
|
75
|
+
"@codemirror/matchbrackets",
|
|
76
|
+
"@codemirror/panel",
|
|
77
|
+
"@codemirror/rangeset",
|
|
78
|
+
"@codemirror/rectangular-selection",
|
|
79
|
+
"@codemirror/stream-parser",
|
|
80
|
+
"@codemirror/tooltip"
|
|
81
|
+
]);
|
|
82
|
+
function requirePatched(id) {
|
|
83
|
+
if (OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id)) {
|
|
84
|
+
return originalRequire?.(id);
|
|
85
|
+
}
|
|
86
|
+
const app = globalThis.app;
|
|
87
|
+
if (app?.isMobile) {
|
|
88
|
+
if (id === "process" || id === "node:process") {
|
|
89
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
|
|
90
|
+
return process;
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
const $module = originalRequire?.(id);
|
|
94
|
+
if ($module) {
|
|
95
|
+
return extractDefault($module);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
|
|
99
|
+
return {};
|
|
100
|
+
}
|
|
101
|
+
})();
|
|
102
|
+
|
|
103
|
+
"use strict";
|
|
104
|
+
var __create = Object.create;
|
|
105
|
+
var __defProp = Object.defineProperty;
|
|
106
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
107
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
108
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
109
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
110
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
|
|
111
|
+
var __typeError = (msg) => {
|
|
112
|
+
throw TypeError(msg);
|
|
113
|
+
};
|
|
114
|
+
var __export = (target, all) => {
|
|
115
|
+
for (var name in all)
|
|
116
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
117
|
+
};
|
|
118
|
+
var __copyProps = (to, from, except, desc) => {
|
|
119
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
120
|
+
for (let key of __getOwnPropNames(from))
|
|
121
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
122
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
123
|
+
}
|
|
124
|
+
return to;
|
|
125
|
+
};
|
|
126
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
127
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
128
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
129
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
130
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
131
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
132
|
+
mod
|
|
133
|
+
));
|
|
134
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
135
|
+
var __using = (stack, value, async) => {
|
|
136
|
+
if (value != null) {
|
|
137
|
+
if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
|
|
138
|
+
var dispose, inner;
|
|
139
|
+
if (async) dispose = value[__knownSymbol("asyncDispose")];
|
|
140
|
+
if (dispose === void 0) {
|
|
141
|
+
dispose = value[__knownSymbol("dispose")];
|
|
142
|
+
if (async) inner = dispose;
|
|
143
|
+
}
|
|
144
|
+
if (typeof dispose !== "function") __typeError("Object not disposable");
|
|
145
|
+
if (inner) dispose = function() {
|
|
146
|
+
try {
|
|
147
|
+
inner.call(this);
|
|
148
|
+
} catch (e) {
|
|
149
|
+
return Promise.reject(e);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
stack.push([async, dispose, value]);
|
|
153
|
+
} else if (async) {
|
|
154
|
+
stack.push([async]);
|
|
155
|
+
}
|
|
156
|
+
return value;
|
|
157
|
+
};
|
|
158
|
+
var __callDispose = (stack, error, hasError) => {
|
|
159
|
+
var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
|
|
160
|
+
return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
|
|
161
|
+
};
|
|
162
|
+
var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
|
|
163
|
+
var next = (it) => {
|
|
164
|
+
while (it = stack.pop()) {
|
|
165
|
+
try {
|
|
166
|
+
var result = it[1] && it[1].call(it[2]);
|
|
167
|
+
if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
|
|
168
|
+
} catch (e) {
|
|
169
|
+
fail(e);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (hasError) throw error;
|
|
173
|
+
};
|
|
174
|
+
return next();
|
|
175
|
+
};
|
|
176
|
+
var request_url_exports = {};
|
|
177
|
+
__export(request_url_exports, {
|
|
178
|
+
RequestUrlError: () => RequestUrlError,
|
|
179
|
+
createRequestUrlFetch: () => createRequestUrlFetch,
|
|
180
|
+
encodeRequestUrlRequest: () => encodeRequestUrlRequest,
|
|
181
|
+
requestUrlEx: () => requestUrlEx,
|
|
182
|
+
requestUrlStream: () => requestUrlStream
|
|
183
|
+
});
|
|
184
|
+
module.exports = __toCommonJS(request_url_exports);
|
|
185
|
+
var import_abort_controller = require('@mnaoumov/typescript-lib/abort-controller');
|
|
186
|
+
var import_function = require('@mnaoumov/typescript-lib/function');
|
|
187
|
+
var import_object_utils = require('@mnaoumov/typescript-lib/object-utils');
|
|
188
|
+
var import_obsidian = require('obsidian');
|
|
189
|
+
const HTTP_ERROR_STATUS_MIN = 400;
|
|
190
|
+
const ERROR_MESSAGE_BODY_LENGTH = 200;
|
|
191
|
+
const HTTP_SWITCHING_PROTOCOLS_STATUS = 101;
|
|
192
|
+
const HTTP_EARLY_HINTS_STATUS = 103;
|
|
193
|
+
const HTTP_NO_CONTENT_STATUS = 204;
|
|
194
|
+
const HTTP_RESET_CONTENT_STATUS = 205;
|
|
195
|
+
const HTTP_NOT_MODIFIED_STATUS = 304;
|
|
196
|
+
const NULL_BODY_STATUSES = /* @__PURE__ */ new Set([
|
|
197
|
+
HTTP_EARLY_HINTS_STATUS,
|
|
198
|
+
HTTP_NO_CONTENT_STATUS,
|
|
199
|
+
HTTP_NOT_MODIFIED_STATUS,
|
|
200
|
+
HTTP_RESET_CONTENT_STATUS,
|
|
201
|
+
HTTP_SWITCHING_PROTOCOLS_STATUS
|
|
202
|
+
]);
|
|
203
|
+
const SUPPORTED_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
204
|
+
const CONTENT_TYPE_HEADER = "content-type";
|
|
205
|
+
const HEX_RADIX = 16;
|
|
206
|
+
const BOUNDARY_RANDOM_PART_COUNT = 2;
|
|
207
|
+
const RANDOM_PART_START = 2;
|
|
208
|
+
class RequestUrlError extends Error {
|
|
209
|
+
/**
|
|
210
|
+
* The response headers.
|
|
211
|
+
*/
|
|
212
|
+
headers;
|
|
213
|
+
/**
|
|
214
|
+
* The HTTP method.
|
|
215
|
+
*/
|
|
216
|
+
method;
|
|
217
|
+
/**
|
|
218
|
+
* The status code.
|
|
219
|
+
*/
|
|
220
|
+
status;
|
|
221
|
+
/**
|
|
222
|
+
* The response body as text.
|
|
223
|
+
*/
|
|
224
|
+
text;
|
|
225
|
+
/**
|
|
226
|
+
* The URL.
|
|
227
|
+
*/
|
|
228
|
+
url;
|
|
229
|
+
/**
|
|
230
|
+
* Creates a {@link RequestUrlError}.
|
|
231
|
+
*
|
|
232
|
+
* @param params - The failed request and its response.
|
|
233
|
+
*/
|
|
234
|
+
constructor(params) {
|
|
235
|
+
const bodyExcerpt = params.text.length > ERROR_MESSAGE_BODY_LENGTH ? `${params.text.slice(0, ERROR_MESSAGE_BODY_LENGTH)}\u2026` : params.text;
|
|
236
|
+
super(`${params.method} ${params.url} failed with status ${String(params.status)}${bodyExcerpt ? `: ${bodyExcerpt}` : ""}`);
|
|
237
|
+
this.name = "RequestUrlError";
|
|
238
|
+
this.headers = params.headers;
|
|
239
|
+
this.method = params.method;
|
|
240
|
+
this.status = params.status;
|
|
241
|
+
this.text = params.text;
|
|
242
|
+
this.url = params.url;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Parses the response body as JSON.
|
|
246
|
+
*
|
|
247
|
+
* @returns The parsed body.
|
|
248
|
+
*/
|
|
249
|
+
json() {
|
|
250
|
+
return JSON.parse(this.text);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function createRequestUrlFetch(options = {}) {
|
|
254
|
+
return async (input, init = {}) => {
|
|
255
|
+
let request = null;
|
|
256
|
+
let url;
|
|
257
|
+
if (typeof input === "string") {
|
|
258
|
+
url = input;
|
|
259
|
+
} else if ("method" in input) {
|
|
260
|
+
request = input;
|
|
261
|
+
url = input.url;
|
|
262
|
+
} else {
|
|
263
|
+
url = input.href;
|
|
264
|
+
}
|
|
265
|
+
const method = (init.method ?? request?.method ?? "GET").toUpperCase();
|
|
266
|
+
const headers = toHeaderRecord(request?.headers, init.headers);
|
|
267
|
+
let body = init.body ?? void 0;
|
|
268
|
+
if (body === void 0 && request && method !== "GET" && method !== "HEAD") {
|
|
269
|
+
body = await request.arrayBuffer();
|
|
270
|
+
}
|
|
271
|
+
const params = {
|
|
272
|
+
abortSignal: init.signal ?? request?.signal ?? void 0,
|
|
273
|
+
body,
|
|
274
|
+
headers,
|
|
275
|
+
method,
|
|
276
|
+
shouldThrowOnHttpError: false,
|
|
277
|
+
timeoutInMilliseconds: options.timeoutInMilliseconds,
|
|
278
|
+
url
|
|
279
|
+
};
|
|
280
|
+
if (options.shouldStream) {
|
|
281
|
+
const streamResponse = await requestUrlStream(params);
|
|
282
|
+
return createResponse(streamResponse.status, streamResponse.headers, streamResponse.body, streamResponse.url);
|
|
283
|
+
}
|
|
284
|
+
const response = await requestUrlEx(params);
|
|
285
|
+
return createResponse(response.status, response.headers, response.arrayBuffer, url);
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
async function encodeRequestUrlRequest(params) {
|
|
289
|
+
const url = assertHttpUrl(params.url);
|
|
290
|
+
const abortSignal = (0, import_abort_controller.abortSignalAny)(
|
|
291
|
+
params.abortSignal,
|
|
292
|
+
params.timeoutInMilliseconds === void 0 ? void 0 : (0, import_abort_controller.abortSignalTimeout)(params.timeoutInMilliseconds)
|
|
293
|
+
);
|
|
294
|
+
abortSignal.throwIfAborted();
|
|
295
|
+
const encodedBody = await encodeBody(params.body);
|
|
296
|
+
abortSignal.throwIfAborted();
|
|
297
|
+
const headers = { ...params.headers };
|
|
298
|
+
const hasContentTypeHeader = Object.keys(headers).some((name) => name.toLowerCase() === CONTENT_TYPE_HEADER);
|
|
299
|
+
const contentType = params.contentType ?? (hasContentTypeHeader ? void 0 : encodedBody.contentType);
|
|
300
|
+
if (contentType !== void 0) {
|
|
301
|
+
for (const name of Object.keys(headers)) {
|
|
302
|
+
if (name.toLowerCase() === CONTENT_TYPE_HEADER) {
|
|
303
|
+
delete headers[name];
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
headers["Content-Type"] = contentType;
|
|
307
|
+
}
|
|
308
|
+
return (0, import_object_utils.normalizeOptionalProperties)({
|
|
309
|
+
abortSignal,
|
|
310
|
+
body: encodedBody.body,
|
|
311
|
+
headers,
|
|
312
|
+
method: (params.method ?? "GET").toUpperCase(),
|
|
313
|
+
url
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
async function requestUrlEx(params) {
|
|
317
|
+
const request = await encodeRequestUrlRequest(params);
|
|
318
|
+
const obsidianRequest = (0, import_object_utils.normalizeOptionalProperties)({
|
|
319
|
+
body: request.body,
|
|
320
|
+
headers: { ...request.headers },
|
|
321
|
+
method: request.method,
|
|
322
|
+
throw: false,
|
|
323
|
+
url: request.url
|
|
324
|
+
});
|
|
325
|
+
const response = await raceWithAbort(Promise.resolve((0, import_obsidian.requestUrl)(obsidianRequest)), request.abortSignal);
|
|
326
|
+
if ((params.shouldThrowOnHttpError ?? true) && response.status >= HTTP_ERROR_STATUS_MIN) {
|
|
327
|
+
throw new RequestUrlError({
|
|
328
|
+
headers: response.headers,
|
|
329
|
+
method: request.method,
|
|
330
|
+
status: response.status,
|
|
331
|
+
text: response.text,
|
|
332
|
+
url: request.url
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
return response;
|
|
336
|
+
}
|
|
337
|
+
async function requestUrlStream(params) {
|
|
338
|
+
const request = await encodeRequestUrlRequest(params);
|
|
339
|
+
let response;
|
|
340
|
+
if (import_obsidian.Platform.isDesktopApp) {
|
|
341
|
+
const { openDesktopRequestUrlStream } = await import("./desktop-request-url-stream.cjs");
|
|
342
|
+
response = await openDesktopRequestUrlStream(request);
|
|
343
|
+
} else {
|
|
344
|
+
const bufferedResponse = await requestUrlEx({
|
|
345
|
+
abortSignal: request.abortSignal,
|
|
346
|
+
body: request.body,
|
|
347
|
+
headers: request.headers,
|
|
348
|
+
method: request.method,
|
|
349
|
+
shouldThrowOnHttpError: false,
|
|
350
|
+
url: request.url
|
|
351
|
+
});
|
|
352
|
+
response = {
|
|
353
|
+
body: createSingleChunkStream(bufferedResponse.arrayBuffer),
|
|
354
|
+
headers: bufferedResponse.headers,
|
|
355
|
+
status: bufferedResponse.status,
|
|
356
|
+
url: request.url
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
if ((params.shouldThrowOnHttpError ?? true) && response.status >= HTTP_ERROR_STATUS_MIN) {
|
|
360
|
+
const text = new TextDecoder().decode(await readStream(response.body));
|
|
361
|
+
throw new RequestUrlError({
|
|
362
|
+
headers: response.headers,
|
|
363
|
+
method: request.method,
|
|
364
|
+
status: response.status,
|
|
365
|
+
text,
|
|
366
|
+
url: response.url
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
return response;
|
|
370
|
+
}
|
|
371
|
+
function assertHttpUrl(url) {
|
|
372
|
+
let parsedUrl;
|
|
373
|
+
try {
|
|
374
|
+
parsedUrl = new URL(url);
|
|
375
|
+
} catch {
|
|
376
|
+
throw new TypeError(`Invalid URL: ${url}`);
|
|
377
|
+
}
|
|
378
|
+
if (!SUPPORTED_PROTOCOLS.has(parsedUrl.protocol)) {
|
|
379
|
+
throw new TypeError(`Unsupported protocol ${parsedUrl.protocol} in ${url}: only http: and https: URLs can be requested`);
|
|
380
|
+
}
|
|
381
|
+
return url;
|
|
382
|
+
}
|
|
383
|
+
function concatBytes(chunks) {
|
|
384
|
+
const length = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
|
|
385
|
+
const bytes = new Uint8Array(length);
|
|
386
|
+
let offset = 0;
|
|
387
|
+
for (const chunk of chunks) {
|
|
388
|
+
bytes.set(chunk, offset);
|
|
389
|
+
offset += chunk.byteLength;
|
|
390
|
+
}
|
|
391
|
+
return bytes.buffer;
|
|
392
|
+
}
|
|
393
|
+
function createResponse(status, headers, body, url) {
|
|
394
|
+
const response = new Response(NULL_BODY_STATUSES.has(status) ? null : body, {
|
|
395
|
+
headers: new Headers({ ...headers }),
|
|
396
|
+
status
|
|
397
|
+
});
|
|
398
|
+
Object.defineProperty(response, "url", { value: url });
|
|
399
|
+
return response;
|
|
400
|
+
}
|
|
401
|
+
function createSingleChunkStream(arrayBuffer) {
|
|
402
|
+
return new ReadableStream({
|
|
403
|
+
start(controller) {
|
|
404
|
+
if (arrayBuffer.byteLength > 0) {
|
|
405
|
+
controller.enqueue(new Uint8Array(arrayBuffer));
|
|
406
|
+
}
|
|
407
|
+
controller.close();
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
async function encodeBody(body) {
|
|
412
|
+
if (body === void 0 || typeof body === "string") {
|
|
413
|
+
return (0, import_object_utils.normalizeOptionalProperties)({ body });
|
|
414
|
+
}
|
|
415
|
+
switch (Object.prototype.toString.call(body)) {
|
|
416
|
+
case "[object ArrayBuffer]": {
|
|
417
|
+
return { body };
|
|
418
|
+
}
|
|
419
|
+
case "[object Blob]":
|
|
420
|
+
case "[object File]": {
|
|
421
|
+
const blob = body;
|
|
422
|
+
return (0, import_object_utils.normalizeOptionalProperties)({ body: await blob.arrayBuffer(), contentType: blob.type || void 0 });
|
|
423
|
+
}
|
|
424
|
+
case "[object FormData]": {
|
|
425
|
+
return await encodeFormData(body);
|
|
426
|
+
}
|
|
427
|
+
case "[object ReadableStream]": {
|
|
428
|
+
return { body: await readStream(body) };
|
|
429
|
+
}
|
|
430
|
+
case "[object URLSearchParams]": {
|
|
431
|
+
return { body: body.toString(), contentType: "application/x-www-form-urlencoded;charset=UTF-8" };
|
|
432
|
+
}
|
|
433
|
+
default: {
|
|
434
|
+
if (ArrayBuffer.isView(body)) {
|
|
435
|
+
return { body: new Uint8Array(body.buffer, body.byteOffset, body.byteLength).slice().buffer };
|
|
436
|
+
}
|
|
437
|
+
throw new TypeError(`Unsupported request body: ${Object.prototype.toString.call(body)}`);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
async function encodeFormData(formData) {
|
|
442
|
+
const boundary = `----ObsidianLibFormBoundary${generateRandomHex()}`;
|
|
443
|
+
const textEncoder = new TextEncoder();
|
|
444
|
+
const chunks = [];
|
|
445
|
+
const entries = [];
|
|
446
|
+
formData.forEach((value, name) => {
|
|
447
|
+
entries.push([name, value]);
|
|
448
|
+
});
|
|
449
|
+
for (const [name, value] of entries) {
|
|
450
|
+
let header = `--${boundary}\r
|
|
451
|
+
Content-Disposition: form-data; name="${escapeMultipartName(name)}"`;
|
|
452
|
+
if (typeof value === "string") {
|
|
453
|
+
chunks.push(textEncoder.encode(`${header}\r
|
|
454
|
+
\r
|
|
455
|
+
${value}\r
|
|
456
|
+
`));
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
header += `; filename="${escapeMultipartName(value.name)}"\r
|
|
460
|
+
Content-Type: ${value.type || "application/octet-stream"}\r
|
|
461
|
+
\r
|
|
462
|
+
`;
|
|
463
|
+
chunks.push(textEncoder.encode(header), new Uint8Array(await value.arrayBuffer()), textEncoder.encode("\r\n"));
|
|
464
|
+
}
|
|
465
|
+
chunks.push(textEncoder.encode(`--${boundary}--\r
|
|
466
|
+
`));
|
|
467
|
+
return { body: concatBytes(chunks), contentType: `multipart/form-data; boundary=${boundary}` };
|
|
468
|
+
}
|
|
469
|
+
function escapeMultipartName(name) {
|
|
470
|
+
return name.replaceAll('"', "%22").replaceAll("\r", "%0D").replaceAll("\n", "%0A");
|
|
471
|
+
}
|
|
472
|
+
function generateRandomHex() {
|
|
473
|
+
return Array.from({ length: BOUNDARY_RANDOM_PART_COUNT }, () => Math.random().toString(HEX_RADIX).slice(RANDOM_PART_START)).join("");
|
|
474
|
+
}
|
|
475
|
+
async function raceWithAbort(promise, abortSignal) {
|
|
476
|
+
var _stack = [];
|
|
477
|
+
try {
|
|
478
|
+
let rejectOnAbort = import_function.noop;
|
|
479
|
+
const abortPromise = new Promise((_resolve, reject) => {
|
|
480
|
+
rejectOnAbort = reject;
|
|
481
|
+
});
|
|
482
|
+
const _abortListener = __using(_stack, (0, import_abort_controller.onAbort)(abortSignal, () => {
|
|
483
|
+
rejectOnAbort(abortSignal.reason);
|
|
484
|
+
}));
|
|
485
|
+
return await Promise.race([promise, abortPromise]);
|
|
486
|
+
} catch (_) {
|
|
487
|
+
var _error = _, _hasError = true;
|
|
488
|
+
} finally {
|
|
489
|
+
__callDispose(_stack, _error, _hasError);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
async function readStream(stream) {
|
|
493
|
+
const reader = stream.getReader();
|
|
494
|
+
const chunks = [];
|
|
495
|
+
for (; ; ) {
|
|
496
|
+
const result = await reader.read();
|
|
497
|
+
if (result.done) {
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
chunks.push(result.value);
|
|
501
|
+
}
|
|
502
|
+
return concatBytes(chunks);
|
|
503
|
+
}
|
|
504
|
+
function toHeaderRecord(requestHeaders, initHeaders) {
|
|
505
|
+
const headers = new Headers(requestHeaders);
|
|
506
|
+
new Headers(initHeaders).forEach((value, name) => {
|
|
507
|
+
headers.set(name, value);
|
|
508
|
+
});
|
|
509
|
+
const record = {};
|
|
510
|
+
headers.forEach((value, name) => {
|
|
511
|
+
record[name] = value;
|
|
512
|
+
});
|
|
513
|
+
return record;
|
|
514
|
+
}
|
|
515
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
516
|
+
0 && (module.exports = {
|
|
517
|
+
RequestUrlError,
|
|
518
|
+
createRequestUrlFetch,
|
|
519
|
+
encodeRequestUrlRequest,
|
|
520
|
+
requestUrlEx,
|
|
521
|
+
requestUrlStream
|
|
522
|
+
});
|
|
523
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZXF1ZXN0LXVybC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuL25vLXVuc3VwcG9ydGVkLWZlYXR1cmVzL25vZGUtYnVpbHRpbnMgLS0gVGhlc2UgYXJlIE9ic2lkaWFuIHJlbmRlcmVyIFdlYiBBUElzLCBub3QgTm9kZSBidWlsdGlucy4gKi9cbi8qKlxuICogQGZpbGVcbiAqXG4gKiBBIHdyYXBwZXIgb3ZlciBPYnNpZGlhbidzIHtAbGluayByZXF1ZXN0VXJsfSB0aGF0IGZpbGxzIHRoZSBnYXBzIHBsdWdpbnMga2VlcCBoYW5kLXJvbGxpbmc6IGFuIGFib3J0IHNpZ25hbCBhbmQgYVxuICogdGltZW91dCwgcmVxdWVzdCBib2RpZXMgYmV5b25kIGBzdHJpbmcgfCBBcnJheUJ1ZmZlcmAgKGBGb3JtRGF0YWAsIGBVUkxTZWFyY2hQYXJhbXNgLCBgQmxvYmAsIHR5cGVkIGFycmF5cyBhbmRcbiAqIHN0cmVhbXMpLCBhbiBlcnJvciB0aGF0IGNhcnJpZXMgdGhlIHN0YXR1cyBhbmQgdGhlIGJvZHksIGFuIHVwLWZyb250IHByb3RvY29sIGNoZWNrLCBhIHN0cmVhbWVkIHJlc3BvbnNlIGJvZHksIGFuZFxuICogYSBgZmV0Y2hgLWNvbXBhdGlibGUgYWRhcHRlciB0aGF0IHRoaXJkLXBhcnR5IFNES3MgY2FuIHRha2UuXG4gKlxuICogYHJlcXVlc3RVcmxgIGl0c2VsZiBjYW5ub3QgYmUgY2FuY2VsbGVkOiBhbiBhYm9ydCBvciBhIHRpbWVvdXQgc2V0dGxlcyB0aGUgcmV0dXJuZWQgcHJvbWlzZSBhdCBvbmNlLCB3aGlsZSB0aGVcbiAqIHVuZGVybHlpbmcgcmVxdWVzdCBydW5zIHRvIGNvbXBsZXRpb24gYW5kIGl0cyByZXN1bHQgaXMgZHJvcHBlZC4gVGhlIHN0cmVhbWVkIHZhcmlhbnQgcmVhbGx5IGNhbmNlbHMgb24gZGVza3RvcCxcbiAqIHdoZXJlIGl0IGdvZXMgdGhyb3VnaCBgbm9kZTpodHRwYCAvIGBub2RlOmh0dHBzYDsgdGhhdCBtb2R1bGUgaXMgaW1wb3J0ZWQgZHluYW1pY2FsbHksIHNvIHRoaXMgb25lIHN0YXlzXG4gKiBjcm9zcy1wbGF0Zm9ybS1sb2FkYWJsZS4gT24gbW9iaWxlIHRoZSBzdHJlYW1lZCB2YXJpYW50IGZhbGxzIGJhY2sgdG8gYHJlcXVlc3RVcmxgIGFuZCBkZWxpdmVycyB0aGUgd2hvbGUgYm9keSBhcyBhXG4gKiBzaW5nbGUgY2h1bmsuXG4gKi9cblxuaW1wb3J0IHR5cGUge1xuICBSZXF1ZXN0VXJsUGFyYW0sXG4gIFJlcXVlc3RVcmxSZXNwb25zZVxufSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB7XG4gIGFib3J0U2lnbmFsQW55LFxuICBhYm9ydFNpZ25hbFRpbWVvdXQsXG4gIG9uQWJvcnRcbn0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2Fib3J0LWNvbnRyb2xsZXInO1xuaW1wb3J0IHsgbm9vcCB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWxpYi9mdW5jdGlvbic7XG5pbXBvcnQgeyBub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXMgfSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWIvb2JqZWN0LXV0aWxzJztcbmltcG9ydCB7XG4gIFBsYXRmb3JtLFxuICByZXF1ZXN0VXJsXG59IGZyb20gJ29ic2lkaWFuJztcblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgY3JlYXRlUmVxdWVzdFVybEZldGNofS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVSZXF1ZXN0VXJsRmV0Y2hPcHRpb25zIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gc3RyZWFtIHRoZSByZXNwb25zZSBib2R5IHRocm91Z2gge0BsaW5rIHJlcXVlc3RVcmxTdHJlYW19IHJhdGhlciB0aGFuIGJ1ZmZlciBpdC4gU3RyZWFtaW5nIGlzIHJlYWwgb25cbiAgICogZGVza3RvcCBvbmx5OyBvbiBtb2JpbGUgdGhlIGJvZHkgc3RpbGwgYXJyaXZlcyBhcyBvbmUgY2h1bmsuIERlZmF1bHRzIHRvIGBmYWxzZWAuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRTdHJlYW0/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgYXBwbGllZCB0byBldmVyeSByZXF1ZXN0LCBvbiB0b3Agb2YgdGhlIHJlcXVlc3QncyBvd24gYHNpZ25hbGAuXG4gICAqL1xuICByZWFkb25seSB0aW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogVGhlIHJlcXVlc3QgaW4gdGhlIGZvcm0gdGhlIHRyYW5zcG9ydHMgdGFrZTogdmFsaWRhdGVkLCB3aXRoIHRoZSBib2R5IGVuY29kZWQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRW5jb2RlZFJlcXVlc3RVcmxSZXF1ZXN0IHtcbiAgLyoqXG4gICAqIEFib3J0cyB0aGUgcmVxdWVzdC5cbiAgICovXG4gIHJlYWRvbmx5IGFib3J0U2lnbmFsOiBBYm9ydFNpZ25hbDtcblxuICAvKipcbiAgICogVGhlIGVuY29kZWQgYm9keS5cbiAgICovXG4gIHJlYWRvbmx5IGJvZHk/OiBBcnJheUJ1ZmZlciB8IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlcXVlc3QgaGVhZGVycywgaW5jbHVkaW5nIHRoZSBjb250ZW50IHR5cGUuXG4gICAqL1xuICByZWFkb25seSBoZWFkZXJzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PjtcblxuICAvKipcbiAgICogVGhlIEhUVFAgbWV0aG9kLCB1cHBlcmNhc2UuXG4gICAqL1xuICByZWFkb25seSBtZXRob2Q6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIFVSTC5cbiAgICovXG4gIHJlYWRvbmx5IHVybDogc3RyaW5nO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBlbmNvZGVSZXF1ZXN0VXJsUmVxdWVzdH0uXG4gKi9cbmV4cG9ydCB0eXBlIEVuY29kZVJlcXVlc3RVcmxSZXF1ZXN0UGFyYW1zID0gUmVxdWVzdFVybEV4UGFyYW1zO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHRoZSB7QGxpbmsgUmVxdWVzdFVybEVycm9yfSBjb25zdHJ1Y3Rvci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXF1ZXN0VXJsRXJyb3JDb25zdHJ1Y3RvclBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgcmVzcG9uc2UgaGVhZGVycy5cbiAgICovXG4gIHJlYWRvbmx5IGhlYWRlcnM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHN0cmluZz4+O1xuXG4gIC8qKlxuICAgKiBUaGUgSFRUUCBtZXRob2QuXG4gICAqL1xuICByZWFkb25seSBtZXRob2Q6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHN0YXR1cyBjb2RlLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhdHVzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSByZXNwb25zZSBib2R5IGFzIHRleHQuXG4gICAqL1xuICByZWFkb25seSB0ZXh0OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBVUkwuXG4gICAqL1xuICByZWFkb25seSB1cmw6IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIHJlcXVlc3QgYm9keSB7QGxpbmsgcmVxdWVzdFVybEV4fSBhY2NlcHRzOiBldmVyeXRoaW5nIGBmZXRjaGAgYWNjZXB0cy5cbiAqL1xuZXhwb3J0IHR5cGUgUmVxdWVzdFVybEV4Qm9keSA9IEFycmF5QnVmZmVyIHwgQXJyYXlCdWZmZXJWaWV3IHwgQmxvYiB8IEZvcm1EYXRhIHwgUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4gfCBzdHJpbmcgfCBVUkxTZWFyY2hQYXJhbXM7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHJlcXVlc3RVcmxFeH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVxdWVzdFVybEV4UGFyYW1zIHtcbiAgLyoqXG4gICAqIEFib3J0cyB0aGUgcmVxdWVzdC4gVGhlIHByb21pc2UgcmVqZWN0cyB3aXRoIHRoZSBzaWduYWwncyByZWFzb24uXG4gICAqL1xuICByZWFkb25seSBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVxdWVzdCBib2R5LlxuICAgKi9cbiAgcmVhZG9ubHkgYm9keT86IFJlcXVlc3RVcmxFeEJvZHkgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSBjb250ZW50IHR5cGUuIFdoZW4gb21pdHRlZCwgaXQgaXMgZGVyaXZlZCBmcm9tIHRoZSBib2R5OiBhIGBGb3JtRGF0YWAgYm9keSBnZXRzIGBtdWx0aXBhcnQvZm9ybS1kYXRhYCB3aXRoIGl0c1xuICAgKiBib3VuZGFyeSwgYSBgVVJMU2VhcmNoUGFyYW1zYCBib2R5IGBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRgIGFuZCBhIGBCbG9iYCBib2R5IGl0cyBvd24gdHlwZSDigJQgdW5sZXNzXG4gICAqIHtAbGluayBSZXF1ZXN0VXJsRXhQYXJhbXMuaGVhZGVyc30gYWxyZWFkeSBjYXJyaWVzIGEgYENvbnRlbnQtVHlwZWAuXG4gICAqL1xuICByZWFkb25seSBjb250ZW50VHlwZT86IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVGhlIHJlcXVlc3QgaGVhZGVycy5cbiAgICovXG4gIHJlYWRvbmx5IGhlYWRlcnM/OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVGhlIEhUVFAgbWV0aG9kLiBEZWZhdWx0cyB0byBgR0VUYC5cbiAgICovXG4gIHJlYWRvbmx5IG1ldGhvZD86IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogV2hldGhlciB0byB0aHJvdyBhIHtAbGluayBSZXF1ZXN0VXJsRXJyb3J9IHdoZW4gdGhlIHN0YXR1cyBjb2RlIGlzIDQwMCBvciBoaWdoZXIuIERlZmF1bHRzIHRvIGB0cnVlYC5cbiAgICovXG4gIHJlYWRvbmx5IHNob3VsZFRocm93T25IdHRwRXJyb3I/OiBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBUaGUgdGltZW91dCBpbiBtaWxsaXNlY29uZHMuIFRoZSBwcm9taXNlIHJlamVjdHMgd2l0aCBhIGBUaW1lb3V0RXJyb3JgIHtAbGluayBET01FeGNlcHRpb259IG9uY2UgaXQgZWxhcHNlcy5cbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXRJbk1pbGxpc2Vjb25kcz86IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVGhlIFVSTC4gT25seSBgaHR0cDpgIGFuZCBgaHR0cHM6YCBVUkxzIGFyZSBhY2NlcHRlZC5cbiAgICovXG4gIHJlYWRvbmx5IHVybDogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgYGZldGNoYC1jb21wYXRpYmxlIGZ1bmN0aW9uIGJ1aWx0IG9uIHtAbGluayByZXF1ZXN0VXJsfS5cbiAqL1xuZXhwb3J0IHR5cGUgUmVxdWVzdFVybEZldGNoID0gKGlucHV0OiBSZXF1ZXN0IHwgc3RyaW5nIHwgVVJMLCBpbml0PzogUmVxdWVzdEluaXQpID0+IFByb21pc2U8UmVzcG9uc2U+O1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayByZXF1ZXN0VXJsU3RyZWFtfS5cbiAqL1xuZXhwb3J0IHR5cGUgUmVxdWVzdFVybFN0cmVhbVBhcmFtcyA9IFJlcXVlc3RVcmxFeFBhcmFtcztcblxuLyoqXG4gKiBUaGUgcmVzcG9uc2Ugb2Yge0BsaW5rIHJlcXVlc3RVcmxTdHJlYW19LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RVcmxTdHJlYW1SZXNwb25zZSB7XG4gIC8qKlxuICAgKiBUaGUgcmVzcG9uc2UgYm9keS5cbiAgICovXG4gIHJlYWRvbmx5IGJvZHk6IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+O1xuXG4gIC8qKlxuICAgKiBUaGUgcmVzcG9uc2UgaGVhZGVycywgd2l0aCBsb3dlcmNhc2UgbmFtZXMuXG4gICAqL1xuICByZWFkb25seSBoZWFkZXJzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PjtcblxuICAvKipcbiAgICogVGhlIHN0YXR1cyBjb2RlLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhdHVzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBmaW5hbCBVUkwsIGFmdGVyIGFueSByZWRpcmVjdHMuXG4gICAqL1xuICByZWFkb25seSB1cmw6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIEVuY29kZWRCb2R5IHtcbiAgcmVhZG9ubHkgYm9keT86IEFycmF5QnVmZmVyIHwgc3RyaW5nO1xuICByZWFkb25seSBjb250ZW50VHlwZT86IHN0cmluZztcbn1cblxuY29uc3QgSFRUUF9FUlJPUl9TVEFUVVNfTUlOID0gNDAwO1xuY29uc3QgRVJST1JfTUVTU0FHRV9CT0RZX0xFTkdUSCA9IDIwMDtcbmNvbnN0IEhUVFBfU1dJVENISU5HX1BST1RPQ09MU19TVEFUVVMgPSAxMDE7XG5jb25zdCBIVFRQX0VBUkxZX0hJTlRTX1NUQVRVUyA9IDEwMztcbmNvbnN0IEhUVFBfTk9fQ09OVEVOVF9TVEFUVVMgPSAyMDQ7XG5jb25zdCBIVFRQX1JFU0VUX0NPTlRFTlRfU1RBVFVTID0gMjA1O1xuY29uc3QgSFRUUF9OT1RfTU9ESUZJRURfU1RBVFVTID0gMzA0O1xuLy8gVGhlIHN0YXR1c2VzIGEgUmVzcG9uc2UgcmVmdXNlcyBhIGJvZHkgZm9yLlxuY29uc3QgTlVMTF9CT0RZX1NUQVRVU0VTID0gbmV3IFNldChbXG4gIEhUVFBfRUFSTFlfSElOVFNfU1RBVFVTLFxuICBIVFRQX05PX0NPTlRFTlRfU1RBVFVTLFxuICBIVFRQX05PVF9NT0RJRklFRF9TVEFUVVMsXG4gIEhUVFBfUkVTRVRfQ09OVEVOVF9TVEFUVVMsXG4gIEhUVFBfU1dJVENISU5HX1BST1RPQ09MU19TVEFUVVNcbl0pO1xuY29uc3QgU1VQUE9SVEVEX1BST1RPQ09MUyA9IG5ldyBTZXQoWydodHRwOicsICdodHRwczonXSk7XG5jb25zdCBDT05URU5UX1RZUEVfSEVBREVSID0gJ2NvbnRlbnQtdHlwZSc7XG5jb25zdCBIRVhfUkFESVggPSAxNjtcbmNvbnN0IEJPVU5EQVJZX1JBTkRPTV9QQVJUX0NPVU5UID0gMjtcbmNvbnN0IFJBTkRPTV9QQVJUX1NUQVJUID0gMjtcblxuLyoqXG4gKiBUaGUgZXJyb3Ige0BsaW5rIHJlcXVlc3RVcmxFeH0gYW5kIHtAbGluayByZXF1ZXN0VXJsU3RyZWFtfSB0aHJvdyBmb3IgYSBzdGF0dXMgY29kZSBvZiA0MDAgb3IgaGlnaGVyLlxuICovXG5leHBvcnQgY2xhc3MgUmVxdWVzdFVybEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogVGhlIHJlc3BvbnNlIGhlYWRlcnMuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaGVhZGVyczogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nPj47XG5cbiAgLyoqXG4gICAqIFRoZSBIVFRQIG1ldGhvZC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBtZXRob2Q6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHN0YXR1cyBjb2RlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHN0YXR1czogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVzcG9uc2UgYm9keSBhcyB0ZXh0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHRleHQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIFVSTC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB1cmw6IHN0cmluZztcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHtAbGluayBSZXF1ZXN0VXJsRXJyb3J9LlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGZhaWxlZCByZXF1ZXN0IGFuZCBpdHMgcmVzcG9uc2UuXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IocGFyYW1zOiBSZXF1ZXN0VXJsRXJyb3JDb25zdHJ1Y3RvclBhcmFtcykge1xuICAgIGNvbnN0IGJvZHlFeGNlcnB0ID0gcGFyYW1zLnRleHQubGVuZ3RoID4gRVJST1JfTUVTU0FHRV9CT0RZX0xFTkdUSCA/IGAke3BhcmFtcy50ZXh0LnNsaWNlKDAsIEVSUk9SX01FU1NBR0VfQk9EWV9MRU5HVEgpfeKApmAgOiBwYXJhbXMudGV4dDtcbiAgICBzdXBlcihgJHtwYXJhbXMubWV0aG9kfSAke3BhcmFtcy51cmx9IGZhaWxlZCB3aXRoIHN0YXR1cyAke1N0cmluZyhwYXJhbXMuc3RhdHVzKX0ke2JvZHlFeGNlcnB0ID8gYDogJHtib2R5RXhjZXJwdH1gIDogJyd9YCk7XG4gICAgdGhpcy5uYW1lID0gJ1JlcXVlc3RVcmxFcnJvcic7XG4gICAgdGhpcy5oZWFkZXJzID0gcGFyYW1zLmhlYWRlcnM7XG4gICAgdGhpcy5tZXRob2QgPSBwYXJhbXMubWV0aG9kO1xuICAgIHRoaXMuc3RhdHVzID0gcGFyYW1zLnN0YXR1cztcbiAgICB0aGlzLnRleHQgPSBwYXJhbXMudGV4dDtcbiAgICB0aGlzLnVybCA9IHBhcmFtcy51cmw7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIHRoZSByZXNwb25zZSBib2R5IGFzIEpTT04uXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBwYXJzZWQgYm9keS5cbiAgICovXG4gIHB1YmxpYyBqc29uKCk6IHVua25vd24ge1xuICAgIHJldHVybiBKU09OLnBhcnNlKHRoaXMudGV4dCk7XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgYGZldGNoYC1jb21wYXRpYmxlIGZ1bmN0aW9uIGJ1aWx0IG9uIHtAbGluayByZXF1ZXN0VXJsfSwgZm9yIFNES3MgdGhhdCB0YWtlIGEgY3VzdG9tIGBmZXRjaGAgKE9wZW5BSSxcbiAqIExhbmdDaGFpbiwgT0F1dGggY2xpZW50cykgYW5kIHdvdWxkIG90aGVyd2lzZSBoaXQgQ09SUy5cbiAqXG4gKiBVbmxpa2UgYGZldGNoYCwgaXQgbmV2ZXIgcmVqZWN0cyBvbiBhbiBIVFRQIGVycm9yIHN0YXR1czogaXQgcmVzb2x2ZXMgd2l0aCBhIHtAbGluayBSZXNwb25zZX0gY2FycnlpbmcgdGhhdCBzdGF0dXMsXG4gKiBleGFjdGx5IGFzIGBmZXRjaGAgZG9lcy4gSXQgcmVqZWN0cyB3aXRoIGEgYFR5cGVFcnJvcmAgZm9yIGEgVVJMIHRoYXQgaXMgbm90IGBodHRwOmAgb3IgYGh0dHBzOmAuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgb3B0aW9ucy5cbiAqIEByZXR1cm5zIFRoZSBgZmV0Y2hgLWNvbXBhdGlibGUgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSZXF1ZXN0VXJsRmV0Y2gob3B0aW9uczogQ3JlYXRlUmVxdWVzdFVybEZldGNoT3B0aW9ucyA9IHt9KTogUmVxdWVzdFVybEZldGNoIHtcbiAgcmV0dXJuIGFzeW5jIChpbnB1dCwgaW5pdCA9IHt9KSA9PiB7XG4gICAgbGV0IHJlcXVlc3Q6IG51bGwgfCBSZXF1ZXN0ID0gbnVsbDtcbiAgICBsZXQgdXJsOiBzdHJpbmc7XG4gICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHVybCA9IGlucHV0O1xuICAgIH0gZWxzZSBpZiAoJ21ldGhvZCcgaW4gaW5wdXQpIHtcbiAgICAgIC8vIEEgYFVSTGAgaGFzIG5vIGBtZXRob2RgOyBgaW5zdGFuY2VvZmAgd291bGQgZmFpbCBhY3Jvc3Mgd2luZG93cy5cbiAgICAgIHJlcXVlc3QgPSBpbnB1dDtcbiAgICAgIHVybCA9IGlucHV0LnVybDtcbiAgICB9IGVsc2Uge1xuICAgICAgdXJsID0gaW5wdXQuaHJlZjtcbiAgICB9XG4gICAgY29uc3QgbWV0aG9kID0gKGluaXQubWV0aG9kID8/IHJlcXVlc3Q/Lm1ldGhvZCA/PyAnR0VUJykudG9VcHBlckNhc2UoKTtcbiAgICBjb25zdCBoZWFkZXJzID0gdG9IZWFkZXJSZWNvcmQocmVxdWVzdD8uaGVhZGVycywgaW5pdC5oZWFkZXJzKTtcbiAgICBsZXQgYm9keTogUmVxdWVzdFVybEV4Qm9keSB8IHVuZGVmaW5lZCA9IGluaXQuYm9keSA/PyB1bmRlZmluZWQ7XG4gICAgaWYgKGJvZHkgPT09IHVuZGVmaW5lZCAmJiByZXF1ZXN0ICYmIG1ldGhvZCAhPT0gJ0dFVCcgJiYgbWV0aG9kICE9PSAnSEVBRCcpIHtcbiAgICAgIGJvZHkgPSBhd2FpdCByZXF1ZXN0LmFycmF5QnVmZmVyKCk7XG4gICAgfVxuICAgIGNvbnN0IHBhcmFtczogUmVxdWVzdFVybEV4UGFyYW1zID0ge1xuICAgICAgYWJvcnRTaWduYWw6IGluaXQuc2lnbmFsID8/IHJlcXVlc3Q/LnNpZ25hbCA/PyB1bmRlZmluZWQsXG4gICAgICBib2R5LFxuICAgICAgaGVhZGVycyxcbiAgICAgIG1ldGhvZCxcbiAgICAgIHNob3VsZFRocm93T25IdHRwRXJyb3I6IGZhbHNlLFxuICAgICAgdGltZW91dEluTWlsbGlzZWNvbmRzOiBvcHRpb25zLnRpbWVvdXRJbk1pbGxpc2Vjb25kcyxcbiAgICAgIHVybFxuICAgIH07XG5cbiAgICBpZiAob3B0aW9ucy5zaG91bGRTdHJlYW0pIHtcbiAgICAgIGNvbnN0IHN0cmVhbVJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFVybFN0cmVhbShwYXJhbXMpO1xuICAgICAgcmV0dXJuIGNyZWF0ZVJlc3BvbnNlKHN0cmVhbVJlc3BvbnNlLnN0YXR1cywgc3RyZWFtUmVzcG9uc2UuaGVhZGVycywgc3RyZWFtUmVzcG9uc2UuYm9keSwgc3RyZWFtUmVzcG9uc2UudXJsKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHJlcXVlc3RVcmxFeChwYXJhbXMpO1xuICAgIHJldHVybiBjcmVhdGVSZXNwb25zZShyZXNwb25zZS5zdGF0dXMsIHJlc3BvbnNlLmhlYWRlcnMsIHJlc3BvbnNlLmFycmF5QnVmZmVyLCB1cmwpO1xuICB9O1xufVxuXG4vKipcbiAqIEVuY29kZXMgYSByZXF1ZXN0IGZvciBhIHRyYW5zcG9ydDogdmFsaWRhdGVzIHRoZSBVUkwsIGNvbWJpbmVzIHRoZSBhYm9ydCBzaWduYWwgd2l0aCB0aGUgdGltZW91dCwgZW5jb2RlcyB0aGUgYm9keVxuICogYW5kIHNldHRsZXMgdGhlIGNvbnRlbnQgdHlwZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHJlcXVlc3QuXG4gKiBAcmV0dXJucyBUaGUgZW5jb2RlZCByZXF1ZXN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW5jb2RlUmVxdWVzdFVybFJlcXVlc3QocGFyYW1zOiBFbmNvZGVSZXF1ZXN0VXJsUmVxdWVzdFBhcmFtcyk6IFByb21pc2U8RW5jb2RlZFJlcXVlc3RVcmxSZXF1ZXN0PiB7XG4gIGNvbnN0IHVybCA9IGFzc2VydEh0dHBVcmwocGFyYW1zLnVybCk7XG4gIGNvbnN0IGFib3J0U2lnbmFsID0gYWJvcnRTaWduYWxBbnkoXG4gICAgcGFyYW1zLmFib3J0U2lnbmFsLFxuICAgIHBhcmFtcy50aW1lb3V0SW5NaWxsaXNlY29uZHMgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGFib3J0U2lnbmFsVGltZW91dChwYXJhbXMudGltZW91dEluTWlsbGlzZWNvbmRzKVxuICApO1xuICBhYm9ydFNpZ25hbC50aHJvd0lmQWJvcnRlZCgpO1xuXG4gIGNvbnN0IGVuY29kZWRCb2R5ID0gYXdhaXQgZW5jb2RlQm9keShwYXJhbXMuYm9keSk7XG4gIGFib3J0U2lnbmFsLnRocm93SWZBYm9ydGVkKCk7XG5cbiAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgLi4ucGFyYW1zLmhlYWRlcnMgfTtcbiAgY29uc3QgaGFzQ29udGVudFR5cGVIZWFkZXIgPSBPYmplY3Qua2V5cyhoZWFkZXJzKS5zb21lKChuYW1lKSA9PiBuYW1lLnRvTG93ZXJDYXNlKCkgPT09IENPTlRFTlRfVFlQRV9IRUFERVIpO1xuICBjb25zdCBjb250ZW50VHlwZSA9IHBhcmFtcy5jb250ZW50VHlwZSA/PyAoaGFzQ29udGVudFR5cGVIZWFkZXIgPyB1bmRlZmluZWQgOiBlbmNvZGVkQm9keS5jb250ZW50VHlwZSk7XG4gIGlmIChjb250ZW50VHlwZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKGhlYWRlcnMpKSB7XG4gICAgICBpZiAobmFtZS50b0xvd2VyQ2FzZSgpID09PSBDT05URU5UX1RZUEVfSEVBREVSKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZHluYW1pYy1kZWxldGUgLS0gQSBoZWFkZXIgcmVjb3JkIGlzIGtleWVkIGJ5IG5hbWUuXG4gICAgICAgIGRlbGV0ZSBoZWFkZXJzW25hbWVdO1xuICAgICAgfVxuICAgIH1cbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9IGNvbnRlbnRUeXBlO1xuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllczxFbmNvZGVkUmVxdWVzdFVybFJlcXVlc3Q+KHtcbiAgICBhYm9ydFNpZ25hbCxcbiAgICBib2R5OiBlbmNvZGVkQm9keS5ib2R5LFxuICAgIGhlYWRlcnMsXG4gICAgbWV0aG9kOiAocGFyYW1zLm1ldGhvZCA/PyAnR0VUJykudG9VcHBlckNhc2UoKSxcbiAgICB1cmxcbiAgfSk7XG59XG5cbi8qKlxuICogUmVxdWVzdHMgYSBVUkwgdGhyb3VnaCB7QGxpbmsgcmVxdWVzdFVybH0sIHdpdGggYW4gYWJvcnQgc2lnbmFsLCBhIHRpbWVvdXQsIHJpY2hlciBib2RpZXMsIGEgcHJvdG9jb2wgY2hlY2sgYW5kIGFcbiAqIHtAbGluayBSZXF1ZXN0VXJsRXJyb3J9IGZvciBhbiBIVFRQIGVycm9yIHN0YXR1cy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHJlcXVlc3QuXG4gKiBAcmV0dXJucyBUaGUgcmVzcG9uc2UuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXF1ZXN0VXJsRXgocGFyYW1zOiBSZXF1ZXN0VXJsRXhQYXJhbXMpOiBQcm9taXNlPFJlcXVlc3RVcmxSZXNwb25zZT4ge1xuICBjb25zdCByZXF1ZXN0ID0gYXdhaXQgZW5jb2RlUmVxdWVzdFVybFJlcXVlc3QocGFyYW1zKTtcbiAgY29uc3Qgb2JzaWRpYW5SZXF1ZXN0OiBSZXF1ZXN0VXJsUGFyYW0gPSBub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXM8UmVxdWVzdFVybFBhcmFtPih7XG4gICAgYm9keTogcmVxdWVzdC5ib2R5LFxuICAgIGhlYWRlcnM6IHsgLi4ucmVxdWVzdC5oZWFkZXJzIH0sXG4gICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICB0aHJvdzogZmFsc2UsXG4gICAgdXJsOiByZXF1ZXN0LnVybFxuICB9KTtcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByYWNlV2l0aEFib3J0KFByb21pc2UucmVzb2x2ZShyZXF1ZXN0VXJsKG9ic2lkaWFuUmVxdWVzdCkpLCByZXF1ZXN0LmFib3J0U2lnbmFsKTtcbiAgaWYgKChwYXJhbXMuc2hvdWxkVGhyb3dPbkh0dHBFcnJvciA/PyB0cnVlKSAmJiByZXNwb25zZS5zdGF0dXMgPj0gSFRUUF9FUlJPUl9TVEFUVVNfTUlOKSB7XG4gICAgdGhyb3cgbmV3IFJlcXVlc3RVcmxFcnJvcih7XG4gICAgICBoZWFkZXJzOiByZXNwb25zZS5oZWFkZXJzLFxuICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgdGV4dDogcmVzcG9uc2UudGV4dCxcbiAgICAgIHVybDogcmVxdWVzdC51cmxcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gcmVzcG9uc2U7XG59XG5cbi8qKlxuICogUmVxdWVzdHMgYSBVUkwgYW5kIHJldHVybnMgaXRzIGJvZHkgYXMgYSBzdHJlYW0uXG4gKlxuICogT24gZGVza3RvcCB0aGUgcmVxdWVzdCBnb2VzIHRocm91Z2ggYG5vZGU6aHR0cGAgLyBgbm9kZTpodHRwc2AsIHNvIHRoZSBib2R5IHN0cmVhbXMgYXMgaXQgYXJyaXZlcywgYW4gYWJvcnQgcmVhbGx5XG4gKiBjYW5jZWxzIHRoZSByZXF1ZXN0LCBhbmQgcmVkaXJlY3RzIGFyZSBmb2xsb3dlZC4gT24gbW9iaWxlIGl0IGZhbGxzIGJhY2sgdG8ge0BsaW5rIHJlcXVlc3RVcmx9LCBhbmQgdGhlIHdob2xlIGJvZHlcbiAqIGFycml2ZXMgYXMgYSBzaW5nbGUgY2h1bmsuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSByZXF1ZXN0LlxuICogQHJldHVybnMgVGhlIHJlc3BvbnNlLCB3aXRoIGEgc3RyZWFtZWQgYm9keS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcXVlc3RVcmxTdHJlYW0ocGFyYW1zOiBSZXF1ZXN0VXJsU3RyZWFtUGFyYW1zKTogUHJvbWlzZTxSZXF1ZXN0VXJsU3RyZWFtUmVzcG9uc2U+IHtcbiAgY29uc3QgcmVxdWVzdCA9IGF3YWl0IGVuY29kZVJlcXVlc3RVcmxSZXF1ZXN0KHBhcmFtcyk7XG4gIGxldCByZXNwb25zZTogUmVxdWVzdFVybFN0cmVhbVJlc3BvbnNlO1xuICBpZiAoUGxhdGZvcm0uaXNEZXNrdG9wQXBwKSB7XG4gICAgY29uc3QgeyBvcGVuRGVza3RvcFJlcXVlc3RVcmxTdHJlYW0gfSA9IGF3YWl0IGltcG9ydCgnLi9kZXNrdG9wLXJlcXVlc3QtdXJsLXN0cmVhbS50cycpO1xuICAgIHJlc3BvbnNlID0gYXdhaXQgb3BlbkRlc2t0b3BSZXF1ZXN0VXJsU3RyZWFtKHJlcXVlc3QpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGJ1ZmZlcmVkUmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0VXJsRXgoe1xuICAgICAgYWJvcnRTaWduYWw6IHJlcXVlc3QuYWJvcnRTaWduYWwsXG4gICAgICBib2R5OiByZXF1ZXN0LmJvZHksXG4gICAgICBoZWFkZXJzOiByZXF1ZXN0LmhlYWRlcnMsXG4gICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgc2hvdWxkVGhyb3dPbkh0dHBFcnJvcjogZmFsc2UsXG4gICAgICB1cmw6IHJlcXVlc3QudXJsXG4gICAgfSk7XG4gICAgcmVzcG9uc2UgPSB7XG4gICAgICBib2R5OiBjcmVhdGVTaW5nbGVDaHVua1N0cmVhbShidWZmZXJlZFJlc3BvbnNlLmFycmF5QnVmZmVyKSxcbiAgICAgIGhlYWRlcnM6IGJ1ZmZlcmVkUmVzcG9uc2UuaGVhZGVycyxcbiAgICAgIHN0YXR1czogYnVmZmVyZWRSZXNwb25zZS5zdGF0dXMsXG4gICAgICB1cmw6IHJlcXVlc3QudXJsXG4gICAgfTtcbiAgfVxuXG4gIGlmICgocGFyYW1zLnNob3VsZFRocm93T25IdHRwRXJyb3IgPz8gdHJ1ZSkgJiYgcmVzcG9uc2Uuc3RhdHVzID49IEhUVFBfRVJST1JfU1RBVFVTX01JTikge1xuICAgIGNvbnN0IHRleHQgPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoYXdhaXQgcmVhZFN0cmVhbShyZXNwb25zZS5ib2R5KSk7XG4gICAgdGhyb3cgbmV3IFJlcXVlc3RVcmxFcnJvcih7XG4gICAgICBoZWFkZXJzOiByZXNwb25zZS5oZWFkZXJzLFxuICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgdGV4dCxcbiAgICAgIHVybDogcmVzcG9uc2UudXJsXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIHJlc3BvbnNlO1xufVxuXG5mdW5jdGlvbiBhc3NlcnRIdHRwVXJsKHVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgbGV0IHBhcnNlZFVybDogVVJMO1xuICB0cnkge1xuICAgIHBhcnNlZFVybCA9IG5ldyBVUkwodXJsKTtcbiAgfSBjYXRjaCB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgSW52YWxpZCBVUkw6ICR7dXJsfWApO1xuICB9XG4gIGlmICghU1VQUE9SVEVEX1BST1RPQ09MUy5oYXMocGFyc2VkVXJsLnByb3RvY29sKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFVuc3VwcG9ydGVkIHByb3RvY29sICR7cGFyc2VkVXJsLnByb3RvY29sfSBpbiAke3VybH06IG9ubHkgaHR0cDogYW5kIGh0dHBzOiBVUkxzIGNhbiBiZSByZXF1ZXN0ZWRgKTtcbiAgfVxuICByZXR1cm4gdXJsO1xufVxuXG5mdW5jdGlvbiBjb25jYXRCeXRlcyhjaHVua3M6IHJlYWRvbmx5IFVpbnQ4QXJyYXlbXSk6IEFycmF5QnVmZmVyIHtcbiAgY29uc3QgbGVuZ3RoID0gY2h1bmtzLnJlZHVjZSgoc3VtLCBjaHVuaykgPT4gc3VtICsgY2h1bmsuYnl0ZUxlbmd0aCwgMCk7XG4gIGNvbnN0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKTtcbiAgbGV0IG9mZnNldCA9IDA7XG4gIGZvciAoY29uc3QgY2h1bmsgb2YgY2h1bmtzKSB7XG4gICAgYnl0ZXMuc2V0KGNodW5rLCBvZmZzZXQpO1xuICAgIG9mZnNldCArPSBjaHVuay5ieXRlTGVuZ3RoO1xuICB9XG4gIHJldHVybiBieXRlcy5idWZmZXI7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVJlc3BvbnNlKHN0YXR1czogbnVtYmVyLCBoZWFkZXJzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PiwgYm9keTogQXJyYXlCdWZmZXIgfCBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PiwgdXJsOiBzdHJpbmcpOiBSZXNwb25zZSB7XG4gIGNvbnN0IHJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKE5VTExfQk9EWV9TVEFUVVNFUy5oYXMoc3RhdHVzKSA/IG51bGwgOiBib2R5LCB7XG4gICAgaGVhZGVyczogbmV3IEhlYWRlcnMoeyAuLi5oZWFkZXJzIH0pLFxuICAgIHN0YXR1c1xuICB9KTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlc3BvbnNlLCAndXJsJywgeyB2YWx1ZTogdXJsIH0pO1xuICByZXR1cm4gcmVzcG9uc2U7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVNpbmdsZUNodW5rU3RyZWFtKGFycmF5QnVmZmVyOiBBcnJheUJ1ZmZlcik6IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+IHtcbiAgcmV0dXJuIG5ldyBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5Pih7XG4gICAgc3RhcnQoY29udHJvbGxlcik6IHZvaWQge1xuICAgICAgaWYgKGFycmF5QnVmZmVyLmJ5dGVMZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlcikpO1xuICAgICAgfVxuICAgICAgY29udHJvbGxlci5jbG9zZSgpO1xuICAgIH1cbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGVuY29kZUJvZHkoYm9keTogUmVxdWVzdFVybEV4Qm9keSB8IHVuZGVmaW5lZCk6IFByb21pc2U8RW5jb2RlZEJvZHk+IHtcbiAgaWYgKGJvZHkgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gbm9ybWFsaXplT3B0aW9uYWxQcm9wZXJ0aWVzPEVuY29kZWRCb2R5Pih7IGJvZHkgfSk7XG4gIH1cblxuICAvLyBgaW5zdGFuY2VvZmAgZmFpbHMgYWNyb3NzIHdpbmRvd3MsIHNvIHRoZSBib2R5IGtpbmRzIGFyZSB0b2xkIGFwYXJ0IGJ5IHRoZWlyIGJ1aWx0LWluIHRhZ3MuXG4gIHN3aXRjaCAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGJvZHkpKSB7XG4gICAgY2FzZSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nOiB7XG4gICAgICByZXR1cm4geyBib2R5OiBib2R5IGFzIEFycmF5QnVmZmVyIH07XG4gICAgfVxuICAgIGNhc2UgJ1tvYmplY3QgQmxvYl0nOlxuICAgIGNhc2UgJ1tvYmplY3QgRmlsZV0nOiB7XG4gICAgICBjb25zdCBibG9iID0gYm9keSBhcyBCbG9iO1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllczxFbmNvZGVkQm9keT4oeyBib2R5OiBhd2FpdCBibG9iLmFycmF5QnVmZmVyKCksIGNvbnRlbnRUeXBlOiBibG9iLnR5cGUgfHwgdW5kZWZpbmVkIH0pO1xuICAgIH1cbiAgICBjYXNlICdbb2JqZWN0IEZvcm1EYXRhXSc6IHtcbiAgICAgIHJldHVybiBhd2FpdCBlbmNvZGVGb3JtRGF0YShib2R5IGFzIEZvcm1EYXRhKTtcbiAgICB9XG4gICAgY2FzZSAnW29iamVjdCBSZWFkYWJsZVN0cmVhbV0nOiB7XG4gICAgICByZXR1cm4geyBib2R5OiBhd2FpdCByZWFkU3RyZWFtKGJvZHkgYXMgUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4pIH07XG4gICAgfVxuICAgIGNhc2UgJ1tvYmplY3QgVVJMU2VhcmNoUGFyYW1zXSc6IHtcbiAgICAgIHJldHVybiB7IGJvZHk6IChib2R5IGFzIFVSTFNlYXJjaFBhcmFtcykudG9TdHJpbmcoKSwgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7Y2hhcnNldD1VVEYtOCcgfTtcbiAgICB9XG4gICAgZGVmYXVsdDoge1xuICAgICAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhib2R5KSkge1xuICAgICAgICByZXR1cm4geyBib2R5OiBuZXcgVWludDhBcnJheShib2R5LmJ1ZmZlciwgYm9keS5ieXRlT2Zmc2V0LCBib2R5LmJ5dGVMZW5ndGgpLnNsaWNlKCkuYnVmZmVyIH07XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBVbnN1cHBvcnRlZCByZXF1ZXN0IGJvZHk6ICR7T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGJvZHkpfWApO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBlbmNvZGVGb3JtRGF0YShmb3JtRGF0YTogRm9ybURhdGEpOiBQcm9taXNlPEVuY29kZWRCb2R5PiB7XG4gIGNvbnN0IGJvdW5kYXJ5ID0gYC0tLS1PYnNpZGlhbkxpYkZvcm1Cb3VuZGFyeSR7Z2VuZXJhdGVSYW5kb21IZXgoKX1gO1xuICBjb25zdCB0ZXh0RW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpO1xuICBjb25zdCBjaHVua3M6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuICBjb25zdCBlbnRyaWVzOiBbc3RyaW5nLCBGb3JtRGF0YUVudHJ5VmFsdWVdW10gPSBbXTtcbiAgZm9ybURhdGEuZm9yRWFjaCgodmFsdWUsIG5hbWUpID0+IHtcbiAgICBlbnRyaWVzLnB1c2goW25hbWUsIHZhbHVlXSk7XG4gIH0pO1xuXG4gIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBlbnRyaWVzKSB7XG4gICAgbGV0IGhlYWRlciA9IGAtLSR7Ym91bmRhcnl9XFxyXFxuQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPVwiJHtlc2NhcGVNdWx0aXBhcnROYW1lKG5hbWUpfVwiYDtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgY2h1bmtzLnB1c2godGV4dEVuY29kZXIuZW5jb2RlKGAke2hlYWRlcn1cXHJcXG5cXHJcXG4ke3ZhbHVlfVxcclxcbmApKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBoZWFkZXIgKz0gYDsgZmlsZW5hbWU9XCIke2VzY2FwZU11bHRpcGFydE5hbWUodmFsdWUubmFtZSl9XCJcXHJcXG5Db250ZW50LVR5cGU6ICR7dmFsdWUudHlwZSB8fCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJ31cXHJcXG5cXHJcXG5gO1xuICAgIGNodW5rcy5wdXNoKHRleHRFbmNvZGVyLmVuY29kZShoZWFkZXIpLCBuZXcgVWludDhBcnJheShhd2FpdCB2YWx1ZS5hcnJheUJ1ZmZlcigpKSwgdGV4dEVuY29kZXIuZW5jb2RlKCdcXHJcXG4nKSk7XG4gIH1cblxuICBjaHVua3MucHVzaCh0ZXh0RW5jb2Rlci5lbmNvZGUoYC0tJHtib3VuZGFyeX0tLVxcclxcbmApKTtcbiAgcmV0dXJuIHsgYm9keTogY29uY2F0Qnl0ZXMoY2h1bmtzKSwgY29udGVudFR5cGU6IGBtdWx0aXBhcnQvZm9ybS1kYXRhOyBib3VuZGFyeT0ke2JvdW5kYXJ5fWAgfTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlTXVsdGlwYXJ0TmFtZShuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBUaGUgZXNjYXBpbmcgdGhlIEhUTUwgc3RhbmRhcmQgcHJlc2NyaWJlcyBmb3IgbXVsdGlwYXJ0L2Zvcm0tZGF0YSBuYW1lcyBhbmQgZmlsZSBuYW1lcy5cbiAgcmV0dXJuIG5hbWUucmVwbGFjZUFsbCgnXCInLCAnJTIyJykucmVwbGFjZUFsbCgnXFxyJywgJyUwRCcpLnJlcGxhY2VBbGwoJ1xcbicsICclMEEnKTtcbn1cblxuZnVuY3Rpb24gZ2VuZXJhdGVSYW5kb21IZXgoKTogc3RyaW5nIHtcbiAgcmV0dXJuIEFycmF5LmZyb20oeyBsZW5ndGg6IEJPVU5EQVJZX1JBTkRPTV9QQVJUX0NPVU5UIH0sICgpID0+IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoSEVYX1JBRElYKS5zbGljZShSQU5ET01fUEFSVF9TVEFSVCkpLmpvaW4oJycpO1xufVxuXG5hc3luYyBmdW5jdGlvbiByYWNlV2l0aEFib3J0PFQ+KHByb21pc2U6IFByb21pc2U8VD4sIGFib3J0U2lnbmFsOiBBYm9ydFNpZ25hbCk6IFByb21pc2U8VD4ge1xuICBsZXQgcmVqZWN0T25BYm9ydDogKHJlYXNvbjogRXJyb3IpID0+IHZvaWQgPSBub29wO1xuICBjb25zdCBhYm9ydFByb21pc2UgPSBuZXcgUHJvbWlzZTxuZXZlcj4oKF9yZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICByZWplY3RPbkFib3J0ID0gcmVqZWN0O1xuICB9KTtcbiAgdXNpbmcgX2Fib3J0TGlzdGVuZXIgPSBvbkFib3J0KGFib3J0U2lnbmFsLCAoKSA9PiB7XG4gICAgLy8gVGhlIHJlYXNvbiBpcyB3aGF0ZXZlciB0aGUgY2FsbGVyIGFib3J0ZWQgd2l0aCwgYW4gYEFib3J0RXJyb3JgIG9yIGBUaW1lb3V0RXJyb3JgIGJ5IGRlZmF1bHQuXG4gICAgcmVqZWN0T25BYm9ydChhYm9ydFNpZ25hbC5yZWFzb24gYXMgRXJyb3IpO1xuICB9KTtcbiAgcmV0dXJuIGF3YWl0IFByb21pc2UucmFjZShbcHJvbWlzZSwgYWJvcnRQcm9taXNlXSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlYWRTdHJlYW0oc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5Pik6IFByb21pc2U8QXJyYXlCdWZmZXI+IHtcbiAgY29uc3QgcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpO1xuICBjb25zdCBjaHVua3M6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuICBmb3IgKDs7KSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcbiAgICBpZiAocmVzdWx0LmRvbmUpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjaHVua3MucHVzaChyZXN1bHQudmFsdWUpO1xuICB9XG4gIHJldHVybiBjb25jYXRCeXRlcyhjaHVua3MpO1xufVxuXG5mdW5jdGlvbiB0b0hlYWRlclJlY29yZChyZXF1ZXN0SGVhZGVyczogSGVhZGVycyB8IHVuZGVmaW5lZCwgaW5pdEhlYWRlcnM6IEhlYWRlcnNJbml0IHwgdW5kZWZpbmVkKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycyhyZXF1ZXN0SGVhZGVycyk7XG4gIG5ldyBIZWFkZXJzKGluaXRIZWFkZXJzKS5mb3JFYWNoKCh2YWx1ZSwgbmFtZSkgPT4ge1xuICAgIGhlYWRlcnMuc2V0KG5hbWUsIHZhbHVlKTtcbiAgfSk7XG4gIGNvbnN0IHJlY29yZDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBoZWFkZXJzLmZvckVhY2goKHZhbHVlLCBuYW1lKSA9PiB7XG4gICAgcmVjb3JkW25hbWVdID0gdmFsdWU7XG4gIH0pO1xuICByZXR1cm4gcmVjb3JkO1xufVxuLyogZXNsaW50LWVuYWJsZSBuL25vLXVuc3VwcG9ydGVkLWZlYXR1cmVzL25vZGUtYnVpbHRpbnMgLS0gVGhlc2UgYXJlIE9ic2lkaWFuIHJlbmRlcmVyIFdlYiBBUElzLCBub3QgTm9kZSBidWlsdGlucy4gKi9cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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
|