@mnaoumov/obsidian-lib 10.9.0 → 10.11.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/codemirror/editor-mode-extension/package.json +6 -0
- package/dist/lib/cjs/__merged.cjs +42 -1
- package/dist/lib/cjs/__merged.d.cts +6 -1
- package/dist/lib/cjs/codemirror/editor-mode-extension.cjs +180 -0
- package/dist/lib/cjs/codemirror/editor-mode-extension.d.cts +50 -0
- package/dist/lib/cjs/codemirror/index.cjs +4 -1
- package/dist/lib/cjs/codemirror/index.d.cts +1 -0
- package/dist/lib/cjs/codemirror/inline-token-widgets.cjs +4 -7
- package/dist/lib/cjs/components/plugin-settings-component.cjs +4 -3
- package/dist/lib/cjs/components/plugin-settings-component.d.cts +2 -1
- package/dist/lib/cjs/css-class.cjs +7 -1
- package/dist/lib/cjs/css-class.d.cts +24 -0
- package/dist/lib/cjs/generated-during-build.cjs +2 -2
- package/dist/lib/cjs/i18n/i18n.cjs +38 -10
- package/dist/lib/cjs/i18n/i18n.d.cts +29 -2
- package/dist/lib/cjs/i18n/locales/en.cjs +19 -1
- package/dist/lib/cjs/i18n/locales/en.d.cts +18 -0
- package/dist/lib/cjs/i18n/locales/translations-map.d.cts +18 -0
- package/dist/lib/cjs/index.cjs +7 -1
- package/dist/lib/cjs/index.d.cts +2 -0
- package/dist/lib/cjs/link.cjs +40 -1
- package/dist/lib/cjs/link.d.cts +37 -1
- package/dist/lib/cjs/modals/code-block-builder.cjs +486 -0
- package/dist/lib/cjs/modals/code-block-builder.d.cts +321 -0
- package/dist/lib/cjs/modals/index.cjs +4 -1
- package/dist/lib/cjs/modals/index.d.cts +1 -0
- package/dist/lib/cjs/plugin/index.cjs +4 -1
- package/dist/lib/cjs/plugin/index.d.cts +1 -0
- package/dist/lib/cjs/plugin/plugin-async-cleanup.cjs +189 -0
- package/dist/lib/cjs/plugin/plugin-async-cleanup.d.cts +111 -0
- package/dist/lib/cjs/plugin/plugin.cjs +47 -2
- package/dist/lib/cjs/plugin/plugin.d.cts +25 -1
- package/dist/lib/cjs/reference-definition.cjs +234 -0
- package/dist/lib/cjs/reference-definition.d.cts +47 -0
- package/dist/lib/cjs/release-asset.cjs +279 -0
- package/dist/lib/cjs/release-asset.d.cts +190 -0
- package/dist/lib/cjs/workspace.cjs +3 -2
- package/dist/lib/cjs/workspace.d.cts +6 -0
- package/dist/lib/esm/__merged.d.mts +6 -1
- package/dist/lib/esm/__merged.mjs +45 -1
- package/dist/lib/esm/codemirror/editor-mode-extension.d.mts +50 -0
- package/dist/lib/esm/codemirror/editor-mode-extension.mjs +93 -0
- package/dist/lib/esm/codemirror/index.d.mts +1 -0
- package/dist/lib/esm/codemirror/index.mjs +3 -1
- package/dist/lib/esm/codemirror/inline-token-widgets.mjs +3 -9
- package/dist/lib/esm/components/plugin-settings-component.d.mts +2 -1
- package/dist/lib/esm/components/plugin-settings-component.mjs +4 -3
- package/dist/lib/esm/css-class.d.mts +24 -0
- package/dist/lib/esm/css-class.mjs +7 -1
- package/dist/lib/esm/generated-during-build.mjs +2 -2
- package/dist/lib/esm/i18n/i18n.d.mts +29 -2
- package/dist/lib/esm/i18n/i18n.mjs +40 -10
- package/dist/lib/esm/i18n/locales/en.d.mts +18 -0
- package/dist/lib/esm/i18n/locales/en.mjs +19 -1
- package/dist/lib/esm/i18n/locales/translations-map.d.mts +18 -0
- package/dist/lib/esm/index.d.mts +2 -0
- package/dist/lib/esm/index.mjs +5 -1
- package/dist/lib/esm/link.d.mts +37 -1
- package/dist/lib/esm/link.mjs +40 -1
- package/dist/lib/esm/modals/code-block-builder.d.mts +321 -0
- package/dist/lib/esm/modals/code-block-builder.mjs +408 -0
- package/dist/lib/esm/modals/index.d.mts +1 -0
- package/dist/lib/esm/modals/index.mjs +3 -1
- package/dist/lib/esm/plugin/index.d.mts +1 -0
- package/dist/lib/esm/plugin/index.mjs +3 -1
- package/dist/lib/esm/plugin/plugin-async-cleanup.d.mts +111 -0
- package/dist/lib/esm/plugin/plugin-async-cleanup.mjs +96 -0
- package/dist/lib/esm/plugin/plugin.d.mts +25 -1
- package/dist/lib/esm/plugin/plugin.mjs +52 -2
- package/dist/lib/esm/reference-definition.d.mts +47 -0
- package/dist/lib/esm/reference-definition.mjs +146 -0
- package/dist/lib/esm/release-asset.d.mts +190 -0
- package/dist/lib/esm/release-asset.mjs +187 -0
- package/dist/lib/esm/workspace.d.mts +6 -0
- package/dist/lib/esm/workspace.mjs +3 -2
- package/dist/styles.css +31 -1
- package/modals/code-block-builder/package.json +6 -0
- package/package.json +1 -1
- package/plugin/plugin-async-cleanup/package.json +6 -0
package/dist/lib/cjs/link.d.cts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* functions to split paths, update links in files, and generate markdown links with various options.
|
|
8
8
|
*/
|
|
9
9
|
import type { MaybeReturn } from '@mnaoumov/typescript-lib/type' with { 'resolution-mode': 'import' };
|
|
10
|
-
import type { App, Reference, TFile } from 'obsidian' with { 'resolution-mode': 'import' };
|
|
10
|
+
import type { App, Reference, ReferenceLinkCache, TFile } from 'obsidian' with { 'resolution-mode': 'import' };
|
|
11
11
|
import type { Promisable } from 'type-fest' with { 'resolution-mode': 'import' };
|
|
12
12
|
import type { PathOrFile } from './file-system.cjs';
|
|
13
13
|
import type { LinkUpdateProgressReporter } from './link-update-progress.cjs';
|
|
@@ -392,6 +392,24 @@ export interface EditReferencesInContentParams {
|
|
|
392
392
|
* The function that converts each reference.
|
|
393
393
|
*/
|
|
394
394
|
readonly referenceConverter: (reference: Reference) => Promisable<MaybeReturn<string>>;
|
|
395
|
+
/**
|
|
396
|
+
* The function that returns the new destination of each reference-style link definition
|
|
397
|
+
* (`[id]: destination "title"`). Obsidian reports those in `CachedMetadata.referenceLinks`, not among the
|
|
398
|
+
* references {@link EditReferencesInContentParams.referenceConverter} receives, so without this function they
|
|
399
|
+
* are never edited.
|
|
400
|
+
*
|
|
401
|
+
* It returns the destination unescaped, in the form of `ReferenceLinkCache.link`, or `undefined` to leave the
|
|
402
|
+
* definition unchanged. Only the destination is rewritten: the id, the title, the angle brackets and every use
|
|
403
|
+
* of the definition (`[text][id]`, `[id]`) stay as written. A definition whose content no longer matches its
|
|
404
|
+
* metadata is left unchanged. See {@link referenceDefinitionToFileChange}.
|
|
405
|
+
*
|
|
406
|
+
* The offset range applies to the definition's whole position. The heading skip and
|
|
407
|
+
* {@link EditReferencesInContentParams.shouldSkipReference} do not apply, since a definition is never in a
|
|
408
|
+
* heading and is not a `Reference`.
|
|
409
|
+
*
|
|
410
|
+
* @default `undefined`, which leaves every definition unchanged
|
|
411
|
+
*/
|
|
412
|
+
readonly referenceDefinitionConverter?: (definition: ReferenceLinkCache) => Promisable<MaybeReturn<string>>;
|
|
395
413
|
/**
|
|
396
414
|
* Whether to also edit external links parsed from the note body. When `true`, the converter also
|
|
397
415
|
* receives references for external links.
|
|
@@ -476,6 +494,24 @@ export interface EditReferencesParams extends EditReferencesOptions {
|
|
|
476
494
|
* The function that converts each reference.
|
|
477
495
|
*/
|
|
478
496
|
readonly referenceConverter: (reference: Reference) => Promisable<MaybeReturn<string>>;
|
|
497
|
+
/**
|
|
498
|
+
* The function that returns the new destination of each reference-style link definition
|
|
499
|
+
* (`[id]: destination "title"`). Obsidian reports those in `CachedMetadata.referenceLinks`, not among the
|
|
500
|
+
* references {@link EditReferencesParams.referenceConverter} receives, so without this function they are never
|
|
501
|
+
* edited.
|
|
502
|
+
*
|
|
503
|
+
* It returns the destination unescaped, in the form of `ReferenceLinkCache.link`, or `undefined` to leave the
|
|
504
|
+
* definition unchanged. Only the destination is rewritten: the id, the title, the angle brackets and every use
|
|
505
|
+
* of the definition (`[text][id]`, `[id]`) stay as written. A definition whose content no longer matches its
|
|
506
|
+
* metadata is left unchanged. See {@link referenceDefinitionToFileChange}. A canvas file has no definitions.
|
|
507
|
+
*
|
|
508
|
+
* The offset range applies to the definition's whole position. The heading skip and
|
|
509
|
+
* {@link EditReferencesParams.shouldSkipReference} do not apply, since a definition is never in a heading and is
|
|
510
|
+
* not a `Reference`.
|
|
511
|
+
*
|
|
512
|
+
* @default `undefined`, which leaves every definition unchanged
|
|
513
|
+
*/
|
|
514
|
+
readonly referenceDefinitionConverter?: (definition: ReferenceLinkCache) => Promisable<MaybeReturn<string>>;
|
|
479
515
|
/**
|
|
480
516
|
* Whether to also edit external links parsed from the note body. When `true`, the converter also
|
|
481
517
|
* receives references for external links.
|
|
@@ -0,0 +1,486 @@
|
|
|
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 ensureBrowserProcess() {
|
|
7
|
+
const browserProcess = {
|
|
8
|
+
browser: true,
|
|
9
|
+
cwd() {
|
|
10
|
+
return "/";
|
|
11
|
+
},
|
|
12
|
+
env: {},
|
|
13
|
+
platform: "android"
|
|
14
|
+
};
|
|
15
|
+
const existingProcess = globalThis.process;
|
|
16
|
+
if (!existingProcess) {
|
|
17
|
+
globalThis.process = browserProcess;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (existingProcess.versions?.node) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const existingProcessRecord = existingProcess;
|
|
24
|
+
for (const [key, value] of Object.entries(browserProcess)) {
|
|
25
|
+
existingProcessRecord[key] ??= value;
|
|
26
|
+
}
|
|
27
|
+
existingProcessRecord["browser"] = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
ensureBrowserProcess();
|
|
31
|
+
})();
|
|
32
|
+
(function patchObsidianRequire() {
|
|
33
|
+
const originalRequire = require;
|
|
34
|
+
if (!originalRequire || originalRequire.__isPatched) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
require = Object.assign(
|
|
38
|
+
(id) => requirePatched(id),
|
|
39
|
+
originalRequire,
|
|
40
|
+
{
|
|
41
|
+
__isPatched: true
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
function extractDefault($module) {
|
|
45
|
+
return $module && $module.__esModule && "default" in $module ? $module.default : $module;
|
|
46
|
+
}
|
|
47
|
+
const OBSIDIAN_BUILT_IN_MODULE_NAMES = /* @__PURE__ */ new Set([
|
|
48
|
+
"@codemirror/autocomplete",
|
|
49
|
+
"@codemirror/collab",
|
|
50
|
+
"@codemirror/commands",
|
|
51
|
+
"@codemirror/language",
|
|
52
|
+
"@codemirror/lint",
|
|
53
|
+
"@codemirror/search",
|
|
54
|
+
"@codemirror/state",
|
|
55
|
+
"@codemirror/text",
|
|
56
|
+
"@codemirror/view",
|
|
57
|
+
"@lezer/common",
|
|
58
|
+
"@lezer/highlight",
|
|
59
|
+
"@lezer/lr",
|
|
60
|
+
"obsidian"
|
|
61
|
+
]);
|
|
62
|
+
const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = /* @__PURE__ */ new Set([
|
|
63
|
+
"@codemirror/closebrackets",
|
|
64
|
+
"@codemirror/comment",
|
|
65
|
+
"@codemirror/fold",
|
|
66
|
+
"@codemirror/gutter",
|
|
67
|
+
"@codemirror/highlight",
|
|
68
|
+
"@codemirror/history",
|
|
69
|
+
"@codemirror/matchbrackets",
|
|
70
|
+
"@codemirror/panel",
|
|
71
|
+
"@codemirror/rangeset",
|
|
72
|
+
"@codemirror/rectangular-selection",
|
|
73
|
+
"@codemirror/stream-parser",
|
|
74
|
+
"@codemirror/tooltip"
|
|
75
|
+
]);
|
|
76
|
+
function requirePatched(id) {
|
|
77
|
+
if (OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id)) {
|
|
78
|
+
return originalRequire?.(id);
|
|
79
|
+
}
|
|
80
|
+
const app = globalThis.app;
|
|
81
|
+
if (app?.isMobile) {
|
|
82
|
+
if (id === "process" || id === "node:process") {
|
|
83
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
|
|
84
|
+
return process;
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
const $module = originalRequire?.(id);
|
|
88
|
+
if ($module) {
|
|
89
|
+
return extractDefault($module);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
|
|
93
|
+
return {};
|
|
94
|
+
}
|
|
95
|
+
})();
|
|
96
|
+
|
|
97
|
+
"use strict";
|
|
98
|
+
var __defProp = Object.defineProperty;
|
|
99
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
100
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
101
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
102
|
+
var __export = (target, all) => {
|
|
103
|
+
for (var name in all)
|
|
104
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
105
|
+
};
|
|
106
|
+
var __copyProps = (to, from, except, desc) => {
|
|
107
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
108
|
+
for (let key of __getOwnPropNames(from))
|
|
109
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
110
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
111
|
+
}
|
|
112
|
+
return to;
|
|
113
|
+
};
|
|
114
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
115
|
+
var code_block_builder_exports = {};
|
|
116
|
+
__export(code_block_builder_exports, {
|
|
117
|
+
formatCodeBlock: () => formatCodeBlock,
|
|
118
|
+
showCodeBlockBuilder: () => showCodeBlockBuilder
|
|
119
|
+
});
|
|
120
|
+
module.exports = __toCommonJS(code_block_builder_exports);
|
|
121
|
+
var import_async = require('@mnaoumov/typescript-lib/async');
|
|
122
|
+
var import_type_guards = require('@mnaoumov/typescript-lib/type-guards');
|
|
123
|
+
var import_obsidian = require('obsidian');
|
|
124
|
+
var import_css_class = require('../css-class.cjs');
|
|
125
|
+
var import_i18n = require('../i18n/i18n.cjs');
|
|
126
|
+
var import_multiple_dropdown_component = require('../setting-components/multiple-dropdown-component.cjs');
|
|
127
|
+
var import_modal = require('./modal.cjs');
|
|
128
|
+
const DEFAULT_SEPARATOR = ",";
|
|
129
|
+
const MIN_FENCE_LENGTH = 3;
|
|
130
|
+
const ROOT_FOLDER_PATH = "/";
|
|
131
|
+
class CodeBlockBuilderModal extends import_modal.ModalBase {
|
|
132
|
+
codeBlock = "";
|
|
133
|
+
editor;
|
|
134
|
+
fields;
|
|
135
|
+
groupStates = [];
|
|
136
|
+
insertedCodeBlock = null;
|
|
137
|
+
language;
|
|
138
|
+
onUpdatePreview;
|
|
139
|
+
outputComponent = null;
|
|
140
|
+
previewEl = null;
|
|
141
|
+
title;
|
|
142
|
+
values = /* @__PURE__ */ new Map();
|
|
143
|
+
constructor(params) {
|
|
144
|
+
super(params);
|
|
145
|
+
this.addCssClasses(import_css_class.CssClass.CodeBlockBuilderModal);
|
|
146
|
+
this.editor = params.editor === void 0 ? params.app.workspace.activeEditor?.editor ?? null : params.editor;
|
|
147
|
+
this.fields = params.fields;
|
|
148
|
+
this.language = params.language;
|
|
149
|
+
this.onUpdatePreview = params.onUpdatePreview;
|
|
150
|
+
this.title = params.title ?? (0, import_i18n.t)(($) => $.obsidianLib.codeBlockBuilder.title);
|
|
151
|
+
for (const field of flattenFields(this.fields)) {
|
|
152
|
+
this.values.set(field.key, field.defaultValue);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
onClose() {
|
|
156
|
+
this.promiseResolve(this.insertedCodeBlock);
|
|
157
|
+
}
|
|
158
|
+
onOpen() {
|
|
159
|
+
this.titleEl.setText(this.title);
|
|
160
|
+
for (const input of this.fields) {
|
|
161
|
+
if (input.type !== "group" && input.isRequired) {
|
|
162
|
+
this.renderField(this.contentEl, input);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
for (const input of this.fields) {
|
|
166
|
+
if (input.type === "group") {
|
|
167
|
+
this.renderGroup(input);
|
|
168
|
+
} else if (!input.isRequired) {
|
|
169
|
+
this.renderField(this.contentEl, input);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
this.previewEl = this.contentEl.createDiv({ cls: import_css_class.CssClass.CodeBlockBuilderPreview });
|
|
173
|
+
this.renderOutput();
|
|
174
|
+
this.update();
|
|
175
|
+
}
|
|
176
|
+
addResetButton(setting, field, reset) {
|
|
177
|
+
if (field.isRequired) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
setting.addExtraButton((button) => {
|
|
181
|
+
button.setIcon("lucide-rotate-ccw").setTooltip((0, import_i18n.t)(($) => $.obsidianLib.codeBlockBuilder.reset, { value: formatValue(field, field.defaultValue) || '""' })).onClick(() => {
|
|
182
|
+
reset();
|
|
183
|
+
this.setValue(field.key, field.defaultValue);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
async copy() {
|
|
188
|
+
try {
|
|
189
|
+
await this.containerEl.win.navigator.clipboard.writeText(this.codeBlock);
|
|
190
|
+
new import_obsidian.Notice((0, import_i18n.t)(($) => $.obsidianLib.codeBlockBuilder.copied));
|
|
191
|
+
} catch {
|
|
192
|
+
new import_obsidian.Notice((0, import_i18n.t)(($) => $.obsidianLib.codeBlockBuilder.copyFailed));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
insert() {
|
|
196
|
+
if (!this.editor) {
|
|
197
|
+
new import_obsidian.Notice((0, import_i18n.t)(($) => $.obsidianLib.codeBlockBuilder.insertUnavailable));
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const cursor = this.editor.getCursor("from");
|
|
201
|
+
const textBeforeCursor = this.editor.getLine(cursor.line).slice(0, cursor.ch);
|
|
202
|
+
const prefix = textBeforeCursor === "" ? "" : "\n";
|
|
203
|
+
this.editor.replaceSelection(`${prefix}${this.codeBlock}
|
|
204
|
+
`);
|
|
205
|
+
this.insertedCodeBlock = this.codeBlock;
|
|
206
|
+
this.close();
|
|
207
|
+
}
|
|
208
|
+
renderBooleanField(setting, field) {
|
|
209
|
+
setting.addToggle((toggle) => {
|
|
210
|
+
toggle.setValue(field.defaultValue).onChange((value) => {
|
|
211
|
+
this.setValue(field.key, value);
|
|
212
|
+
});
|
|
213
|
+
this.addResetButton(setting, field, () => {
|
|
214
|
+
toggle.setValue(field.defaultValue);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
renderColorField(setting, field) {
|
|
219
|
+
setting.addColorPicker((colorPicker) => {
|
|
220
|
+
colorPicker.setValue(field.defaultValue).onChange((value) => {
|
|
221
|
+
this.setValue(field.key, value);
|
|
222
|
+
});
|
|
223
|
+
this.addResetButton(setting, field, () => {
|
|
224
|
+
colorPicker.setValue(field.defaultValue);
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
renderConditionalDropdownField(setting, field) {
|
|
229
|
+
const initialGroupIndex = Math.max(0, field.groups.findIndex((group) => Object.hasOwn(toRecord(group.options), field.defaultValue)));
|
|
230
|
+
const groupDropdown = new import_obsidian.DropdownComponent(setting.controlEl);
|
|
231
|
+
for (const [index, group] of field.groups.entries()) {
|
|
232
|
+
groupDropdown.addOption(String(index), group.name);
|
|
233
|
+
}
|
|
234
|
+
groupDropdown.setValue(String(initialGroupIndex));
|
|
235
|
+
const optionDropdown = new import_obsidian.DropdownComponent(setting.controlEl);
|
|
236
|
+
function fillOptions(groupIndex, value) {
|
|
237
|
+
const options = toRecord(field.groups[groupIndex]?.options ?? []);
|
|
238
|
+
const selectedValue = value ?? Object.keys(options)[0] ?? "";
|
|
239
|
+
optionDropdown.selectEl.empty();
|
|
240
|
+
optionDropdown.addOptions(options);
|
|
241
|
+
optionDropdown.setValue(selectedValue);
|
|
242
|
+
return selectedValue;
|
|
243
|
+
}
|
|
244
|
+
fillOptions(initialGroupIndex, field.defaultValue);
|
|
245
|
+
optionDropdown.onChange((value) => {
|
|
246
|
+
this.setValue(field.key, value);
|
|
247
|
+
});
|
|
248
|
+
groupDropdown.onChange((value) => {
|
|
249
|
+
this.setValue(field.key, fillOptions(Number(value)));
|
|
250
|
+
});
|
|
251
|
+
this.addResetButton(setting, field, () => {
|
|
252
|
+
groupDropdown.setValue(String(initialGroupIndex));
|
|
253
|
+
fillOptions(initialGroupIndex, field.defaultValue);
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
renderDropdownField(setting, field) {
|
|
257
|
+
setting.addDropdown((dropdown) => {
|
|
258
|
+
dropdown.addOptions(toRecord(field.options)).setValue(field.defaultValue).onChange((value) => {
|
|
259
|
+
this.setValue(field.key, value);
|
|
260
|
+
});
|
|
261
|
+
this.addResetButton(setting, field, () => {
|
|
262
|
+
dropdown.setValue(field.defaultValue);
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
renderField(containerEl, field) {
|
|
267
|
+
const setting = new import_obsidian.Setting(containerEl).setName(field.name);
|
|
268
|
+
if (field.description !== void 0) {
|
|
269
|
+
setting.setDesc(field.description);
|
|
270
|
+
}
|
|
271
|
+
switch (field.type) {
|
|
272
|
+
case "boolean": {
|
|
273
|
+
this.renderBooleanField(setting, field);
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
case "color": {
|
|
277
|
+
this.renderColorField(setting, field);
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
case "conditionalDropdown": {
|
|
281
|
+
this.renderConditionalDropdownField(setting, field);
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
case "dropdown": {
|
|
285
|
+
this.renderDropdownField(setting, field);
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
case "folder": {
|
|
289
|
+
this.renderFolderField(setting, field);
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
case "multipleDropdown": {
|
|
293
|
+
this.renderMultipleDropdownField(setting, field);
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
case "slider": {
|
|
297
|
+
this.renderSliderField(setting, field);
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
case "text": {
|
|
301
|
+
this.renderTextField(setting, field);
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
default: {
|
|
305
|
+
(0, import_type_guards.assertNever)(field);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
renderFolderField(setting, field) {
|
|
310
|
+
const options = {
|
|
311
|
+
[ROOT_FOLDER_PATH]: (0, import_i18n.t)(($) => $.obsidianLib.codeBlockBuilder.rootFolder)
|
|
312
|
+
};
|
|
313
|
+
const folderPaths = this.app.vault.getAllFolders(false).map((folder) => folder.path).sort((a, b) => a.localeCompare(b));
|
|
314
|
+
for (const folderPath of folderPaths) {
|
|
315
|
+
options[folderPath] = folderPath;
|
|
316
|
+
}
|
|
317
|
+
options[field.defaultValue] ??= field.defaultValue;
|
|
318
|
+
setting.addDropdown((dropdown) => {
|
|
319
|
+
dropdown.addOptions(options).setValue(field.defaultValue).onChange((value) => {
|
|
320
|
+
this.setValue(field.key, value);
|
|
321
|
+
});
|
|
322
|
+
this.addResetButton(setting, field, () => {
|
|
323
|
+
dropdown.setValue(field.defaultValue);
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
renderGroup(group) {
|
|
328
|
+
const groupEl = this.contentEl.createDiv({ cls: import_css_class.CssClass.CodeBlockBuilderGroup });
|
|
329
|
+
const headingSetting = new import_obsidian.Setting(groupEl).setName(group.name).setHeading();
|
|
330
|
+
const bodyEl = groupEl.createDiv({ cls: import_css_class.CssClass.CodeBlockBuilderGroupBody });
|
|
331
|
+
groupEl.addClass(import_css_class.CssClass.IsCollapsed);
|
|
332
|
+
headingSetting.addExtraButton((button) => {
|
|
333
|
+
const groupState = { button, groupEl };
|
|
334
|
+
this.groupStates.push(groupState);
|
|
335
|
+
updateGroupIcon(groupState);
|
|
336
|
+
button.onClick(() => {
|
|
337
|
+
this.setGroupExpanded(groupEl, groupEl.hasClass(import_css_class.CssClass.IsCollapsed));
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
for (const field of group.fields) {
|
|
341
|
+
this.renderField(bodyEl, field);
|
|
342
|
+
}
|
|
343
|
+
if (group.isInitiallyExpanded) {
|
|
344
|
+
this.setGroupExpanded(groupEl, true);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
renderMultipleDropdownField(setting, field) {
|
|
348
|
+
const dropdown = new import_multiple_dropdown_component.MultipleDropdownComponent(setting.controlEl).addOptions(toRecord(field.options)).setValue(field.defaultValue).onChange((value) => {
|
|
349
|
+
this.setValue(field.key, value);
|
|
350
|
+
});
|
|
351
|
+
setting.addComponent(() => dropdown);
|
|
352
|
+
this.addResetButton(setting, field, () => {
|
|
353
|
+
dropdown.setValue(field.defaultValue);
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
renderOutput() {
|
|
357
|
+
const setting = new import_obsidian.Setting(this.contentEl).setName((0, import_i18n.t)(($) => $.obsidianLib.codeBlockBuilder.output));
|
|
358
|
+
setting.settingEl.addClass(import_css_class.CssClass.CodeBlockBuilderOutput);
|
|
359
|
+
setting.addTextArea((textArea) => {
|
|
360
|
+
this.outputComponent = textArea;
|
|
361
|
+
textArea.inputEl.readOnly = true;
|
|
362
|
+
});
|
|
363
|
+
setting.addExtraButton((button) => {
|
|
364
|
+
button.setIcon("lucide-copy").setTooltip((0, import_i18n.t)(($) => $.obsidianLib.codeBlockBuilder.copy)).onClick(() => {
|
|
365
|
+
(0, import_async.invokeAsyncSafely)(() => this.copy());
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
setting.addExtraButton((button) => {
|
|
369
|
+
button.setIcon("lucide-file-input").setTooltip((0, import_i18n.t)(($) => this.editor ? $.obsidianLib.codeBlockBuilder.insert : $.obsidianLib.codeBlockBuilder.insertUnavailable)).onClick(() => {
|
|
370
|
+
this.insert();
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
renderSliderField(setting, field) {
|
|
375
|
+
setting.addSlider((slider) => {
|
|
376
|
+
slider.setLimits(Math.min(field.min, field.defaultValue), Math.max(field.max, field.defaultValue), field.step).setValue(field.defaultValue).onChange((value) => {
|
|
377
|
+
this.setValue(field.key, value);
|
|
378
|
+
});
|
|
379
|
+
this.addResetButton(setting, field, () => {
|
|
380
|
+
slider.setValue(field.defaultValue);
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
renderTextField(setting, field) {
|
|
385
|
+
setting.addText((text) => {
|
|
386
|
+
text.setPlaceholder(field.placeholder ?? "").setValue(field.defaultValue).onChange((value) => {
|
|
387
|
+
if (field.validationPattern && !doesMatchPattern(field.validationPattern, value)) {
|
|
388
|
+
text.inputEl.setCustomValidity((0, import_i18n.t)(($) => $.obsidianLib.codeBlockBuilder.invalidValue));
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
text.inputEl.setCustomValidity("");
|
|
392
|
+
this.setValue(field.key, value);
|
|
393
|
+
});
|
|
394
|
+
this.addResetButton(setting, field, () => {
|
|
395
|
+
text.setValue(field.defaultValue);
|
|
396
|
+
text.inputEl.setCustomValidity("");
|
|
397
|
+
});
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
setGroupExpanded(groupEl, isExpanded) {
|
|
401
|
+
for (const groupState of this.groupStates) {
|
|
402
|
+
const shouldExpand = isExpanded && groupState.groupEl === groupEl;
|
|
403
|
+
groupState.groupEl.toggleClass(import_css_class.CssClass.IsCollapsed, !shouldExpand);
|
|
404
|
+
updateGroupIcon(groupState);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
setValue(key, value) {
|
|
408
|
+
this.values.set(key, value);
|
|
409
|
+
this.update();
|
|
410
|
+
}
|
|
411
|
+
update() {
|
|
412
|
+
this.codeBlock = formatCodeBlock({
|
|
413
|
+
fields: this.fields,
|
|
414
|
+
language: this.language,
|
|
415
|
+
values: this.values
|
|
416
|
+
});
|
|
417
|
+
const outputComponent = (0, import_type_guards.ensureNonNullable)(this.outputComponent);
|
|
418
|
+
outputComponent.setValue(this.codeBlock);
|
|
419
|
+
outputComponent.inputEl.rows = this.codeBlock.split("\n").length;
|
|
420
|
+
if (this.onUpdatePreview) {
|
|
421
|
+
this.onUpdatePreview({
|
|
422
|
+
codeBlock: this.codeBlock,
|
|
423
|
+
previewEl: (0, import_type_guards.ensureNonNullable)(this.previewEl),
|
|
424
|
+
values: this.values
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
function formatCodeBlock(params) {
|
|
430
|
+
const lines = [];
|
|
431
|
+
for (const field of flattenFields(params.fields)) {
|
|
432
|
+
const value = params.values.get(field.key) ?? field.defaultValue;
|
|
433
|
+
const formattedValue = formatValue(field, value);
|
|
434
|
+
if (formattedValue === "") {
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
if (!field.isRequired && isSameValue(value, field.defaultValue)) {
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
lines.push(field.shouldOmitKey ? formattedValue : `${field.key}: ${formattedValue}`);
|
|
441
|
+
}
|
|
442
|
+
const body = lines.join("\n");
|
|
443
|
+
const longestBacktickRun = Math.max(0, ...Array.from(body.matchAll(/`+/g), (match) => match[0].length));
|
|
444
|
+
const fence = "`".repeat(Math.max(MIN_FENCE_LENGTH, longestBacktickRun + 1));
|
|
445
|
+
return lines.length === 0 ? `${fence}${params.language}
|
|
446
|
+
${fence}` : `${fence}${params.language}
|
|
447
|
+
${body}
|
|
448
|
+
${fence}`;
|
|
449
|
+
}
|
|
450
|
+
async function showCodeBlockBuilder(params) {
|
|
451
|
+
return await (0, import_modal.showModal)(
|
|
452
|
+
(promiseResolve) => new CodeBlockBuilderModal({
|
|
453
|
+
...params,
|
|
454
|
+
promiseResolve
|
|
455
|
+
})
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
function doesMatchPattern(pattern, value) {
|
|
459
|
+
pattern.lastIndex = 0;
|
|
460
|
+
return pattern.test(value);
|
|
461
|
+
}
|
|
462
|
+
function flattenFields(inputs) {
|
|
463
|
+
return inputs.flatMap((input) => input.type === "group" ? input.fields : [input]);
|
|
464
|
+
}
|
|
465
|
+
function formatValue(field, value) {
|
|
466
|
+
const separator = field.type === "multipleDropdown" ? field.separator ?? DEFAULT_SEPARATOR : DEFAULT_SEPARATOR;
|
|
467
|
+
return isStringArray(value) ? value.join(separator) : String(value);
|
|
468
|
+
}
|
|
469
|
+
function isSameValue(a, b) {
|
|
470
|
+
return isStringArray(a) && isStringArray(b) ? a.length === b.length && a.every((item, index) => item === b[index]) : a === b;
|
|
471
|
+
}
|
|
472
|
+
function isStringArray(value) {
|
|
473
|
+
return Array.isArray(value);
|
|
474
|
+
}
|
|
475
|
+
function toRecord(options) {
|
|
476
|
+
return isStringArray(options) ? Object.fromEntries(options.map((option) => [option, option])) : { ...options };
|
|
477
|
+
}
|
|
478
|
+
function updateGroupIcon(groupState) {
|
|
479
|
+
groupState.button.setIcon(groupState.groupEl.hasClass(import_css_class.CssClass.IsCollapsed) ? "lucide-chevron-down" : "lucide-chevron-up");
|
|
480
|
+
}
|
|
481
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
482
|
+
0 && (module.exports = {
|
|
483
|
+
formatCodeBlock,
|
|
484
|
+
showCodeBlockBuilder
|
|
485
|
+
});
|
|
486
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9tb2RhbHMvY29kZS1ibG9jay1idWlsZGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBDb250YWlucyB7QGxpbmsgc2hvd0NvZGVCbG9ja0J1aWxkZXJ9LCBhIG1vZGFsIHRoYXQgYnVpbGRzIGEgcGx1Z2luJ3MgY29kZSBibG9jayBmcm9tIGEgZGVjbGFyYXRpdmUgbGlzdCBvZiBmaWVsZHMsIGFuZFxuICoge0BsaW5rIGZvcm1hdENvZGVCbG9ja30sIHRoZSBwdXJlIGZvcm1hdHRlciBiZWhpbmQgaXQuXG4gKlxuICogRXZlcnkgZmllbGQgcmVuZGVycyBhcyBvbmUgc2V0dGluZ3Mgcm93LiBBIGZpZWxkIHdob3NlIHZhbHVlIGRpZmZlcnMgZnJvbSBpdHMgZGVmYXVsdCB3cml0ZXMgb25lIGBrZXk6IHZhbHVlYCBsaW5lXG4gKiBpbnRvIHRoZSBibG9jayAoYSByZXF1aXJlZCBmaWVsZCBhbHdheXMgZG9lcyksIHRoZSBibG9jayBpcyBzaG93biBsaXZlIHdpdGggYW4gb3B0aW9uYWwgcHJldmlldyB0aGUgcGx1Z2luIGRyYXdzLCBhbmRcbiAqIHRoZSB1c2VyIGNvcGllcyBpdCBvciBpbnNlcnRzIGl0IGludG8gdGhlIG5vdGUgYmVpbmcgZWRpdGVkLlxuICpcbiAqIEFkYXB0ZWQgZnJvbSB0aGUgY29kZSBibG9jayBjcmVhdG9yIG1vZGFsIG9mIGFsdGFyb2sncyBgb2JzaWRpYW4tZGV2LXV0aWxzYFxuICogKGh0dHBzOi8vZ2l0aHViLmNvbS9hbHRhcm9rL29ic2lkaWFuLWRldi11dGlscywgYHNyYy9jb2RlLWJsb2NrLWNyZWF0b3IvYCksIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBiZWxvdy4gVGhlIHBvcnRcbiAqIHRha2VzIHRoZSBhcHAgZnJvbSB0aGUgY2FsbGVyLCBtb3ZlcyB0aGUgc3R5bGVzIGludG8gdGhlIGxpYnJhcnkgc3R5bGVzaGVldCwgcmV1c2VzIHRoaXMgbGlicmFyeSdzIHNldHRpbmdcbiAqIGNvbXBvbmVudHMsIGFuZCBwaWNrcyBhIGZlbmNlIGxvbmdlciB0aGFuIGFueSBiYWNrdGljayBydW4gaW4gdGhlIHZhbHVlcy5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjYgQWx0YXJva1xuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZFxuICogZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4gKiByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG9cbiAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGVcbiAqIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEVcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUlxuICogQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuICogT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuICovXG5cbi8vIGNzcGVsbDp3b3JkcyBhbHRhcm9rIEFsdGFyb2sgcnJnZ2JiIC0tIFRoZSBhdXRob3IncyBoYW5kbGUsIGFzIHRoZSBsaWNlbnNlIG5vdGljZSBhYm92ZSBuYW1lcyBpdCwgYW5kIHRoZSBoZXggY29sb3Igbm90YXRpb24uXG5cbmltcG9ydCB0eXBlIHtcbiAgRWRpdG9yLFxuICBFeHRyYUJ1dHRvbkNvbXBvbmVudFxufSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB7IGludm9rZUFzeW5jU2FmZWx5IH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2FzeW5jJztcbmltcG9ydCB7XG4gIGFzc2VydE5ldmVyLFxuICBlbnN1cmVOb25OdWxsYWJsZVxufSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWIvdHlwZS1ndWFyZHMnO1xuaW1wb3J0IHtcbiAgRHJvcGRvd25Db21wb25lbnQsXG4gIE5vdGljZSxcbiAgU2V0dGluZyxcbiAgVGV4dEFyZWFDb21wb25lbnRcbn0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQgdHlwZSB7XG4gIE1vZGFsQmFzZUNvbnN0cnVjdG9yUGFyYW1zLFxuICBNb2RhbFBhcmFtc0Jhc2Vcbn0gZnJvbSAnLi9tb2RhbC50cyc7XG5cbmltcG9ydCB7IENzc0NsYXNzIH0gZnJvbSAnLi4vY3NzLWNsYXNzLnRzJztcbmltcG9ydCB7IHQgfSBmcm9tICcuLi9pMThuL2kxOG4udHMnO1xuaW1wb3J0IHsgTXVsdGlwbGVEcm9wZG93bkNvbXBvbmVudCB9IGZyb20gJy4uL3NldHRpbmctY29tcG9uZW50cy9tdWx0aXBsZS1kcm9wZG93bi1jb21wb25lbnQudHMnO1xuaW1wb3J0IHtcbiAgTW9kYWxCYXNlLFxuICBzaG93TW9kYWxcbn0gZnJvbSAnLi9tb2RhbC50cyc7XG5cbi8qKlxuICogQSBib29sZWFuIGZpZWxkLCByZW5kZXJlZCBhcyBhIHRvZ2dsZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb2RlQmxvY2tCdWlsZGVyQm9vbGVhbkZpZWxkIGV4dGVuZHMgQ29kZUJsb2NrQnVpbGRlckZpZWxkQmFzZTxib29sZWFuPiB7XG4gIC8qKlxuICAgKiBUaGUga2luZCBvZiB0aGUgZmllbGQuXG4gICAqL1xuICByZWFkb25seSB0eXBlOiAnYm9vbGVhbic7XG59XG5cbi8qKlxuICogQSBjb2xvciBmaWVsZCwgcmVuZGVyZWQgYXMgYSBjb2xvciBwaWNrZXIuIFRoZSB2YWx1ZSBpcyB0aGUgY29sb3IgYXMgYCNycmdnYmJgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvZGVCbG9ja0J1aWxkZXJDb2xvckZpZWxkIGV4dGVuZHMgQ29kZUJsb2NrQnVpbGRlckZpZWxkQmFzZTxzdHJpbmc+IHtcbiAgLyoqXG4gICAqIFRoZSBraW5kIG9mIHRoZSBmaWVsZC5cbiAgICovXG4gIHJlYWRvbmx5IHR5cGU6ICdjb2xvcic7XG59XG5cbi8qKlxuICogQSBwYWlyIG9mIGNhc2NhZGluZyBkcm9wZG93bnM6IHRoZSBmaXJzdCBwaWNrcyBhIGdyb3VwLCB0aGUgc2Vjb25kIG9uZSBvZiB0aGF0IGdyb3VwJ3Mgb3B0aW9ucy4gT25seSB0aGUgc2Vjb25kXG4gKiBkcm9wZG93bidzIHZhbHVlIGlzIHdyaXR0ZW4gaW50byB0aGUgY29kZSBibG9jay5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb2RlQmxvY2tCdWlsZGVyQ29uZGl0aW9uYWxEcm9wZG93bkZpZWxkIGV4dGVuZHMgQ29kZUJsb2NrQnVpbGRlckZpZWxkQmFzZTxzdHJpbmc+IHtcbiAgLyoqXG4gICAqIFRoZSBncm91cHMgb2Ygb3B0aW9ucy4gVGhlIGdyb3VwIGNvbnRhaW5pbmcge0BsaW5rIENvZGVCbG9ja0J1aWxkZXJGaWVsZEJhc2UuZGVmYXVsdFZhbHVlfSBpcyBzZWxlY3RlZCBmaXJzdCwgZWxzZVxuICAgKiB0aGUgZmlyc3QgZ3JvdXAuXG4gICAqL1xuICByZWFkb25seSBncm91cHM6IHJlYWRvbmx5IENvZGVCbG9ja0J1aWxkZXJPcHRpb25Hcm91cFtdO1xuXG4gIC8qKlxuICAgKiBUaGUga2luZCBvZiB0aGUgZmllbGQuXG4gICAqL1xuICByZWFkb25seSB0eXBlOiAnY29uZGl0aW9uYWxEcm9wZG93bic7XG59XG5cbi8qKlxuICogQSBzaW5nbGUtY2hvaWNlIGRyb3Bkb3duIGZpZWxkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvZGVCbG9ja0J1aWxkZXJEcm9wZG93bkZpZWxkIGV4dGVuZHMgQ29kZUJsb2NrQnVpbGRlckZpZWxkQmFzZTxzdHJpbmc+IHtcbiAgLyoqXG4gICAqIFRoZSBvcHRpb25zIG9mIHRoZSBkcm9wZG93bi5cbiAgICovXG4gIHJlYWRvbmx5IG9wdGlvbnM6IENvZGVCbG9ja0J1aWxkZXJPcHRpb25zO1xuXG4gIC8qKlxuICAgKiBUaGUga2luZCBvZiB0aGUgZmllbGQuXG4gICAqL1xuICByZWFkb25seSB0eXBlOiAnZHJvcGRvd24nO1xufVxuXG4vKipcbiAqIEEgZmllbGQgb2YgdGhlIGNvZGUgYmxvY2sgYnVpbGRlciwgb3RoZXIgdGhhbiBhIHtAbGluayBDb2RlQmxvY2tCdWlsZGVyR3JvdXB9LlxuICovXG5leHBvcnQgdHlwZSBDb2RlQmxvY2tCdWlsZGVyRmllbGQgPVxuICB8IENvZGVCbG9ja0J1aWxkZXJCb29sZWFuRmllbGRcbiAgfCBDb2RlQmxvY2tCdWlsZGVyQ29sb3JGaWVsZFxuICB8IENvZGVCbG9ja0J1aWxkZXJDb25kaXRpb25hbERyb3Bkb3duRmllbGRcbiAgfCBDb2RlQmxvY2tCdWlsZGVyRHJvcGRvd25GaWVsZFxuICB8IENvZGVCbG9ja0J1aWxkZXJGb2xkZXJGaWVsZFxuICB8IENvZGVCbG9ja0J1aWxkZXJNdWx0aXBsZURyb3Bkb3duRmllbGRcbiAgfCBDb2RlQmxvY2tCdWlsZGVyU2xpZGVyRmllbGRcbiAgfCBDb2RlQmxvY2tCdWlsZGVyVGV4dEZpZWxkO1xuXG4vKipcbiAqIFRoZSBtZW1iZXJzIGV2ZXJ5IHtAbGluayBDb2RlQmxvY2tCdWlsZGVyRmllbGR9IGhhcy5cbiAqXG4gKiBAdHlwZVBhcmFtIFZhbHVlIC0gVGhlIHR5cGUgb2YgdGhlIGZpZWxkJ3MgdmFsdWUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29kZUJsb2NrQnVpbGRlckZpZWxkQmFzZTxWYWx1ZSBleHRlbmRzIENvZGVCbG9ja0J1aWxkZXJWYWx1ZT4ge1xuICAvKipcbiAgICogVGhlIHZhbHVlIHRoZSBmaWVsZCBzdGFydHMgd2l0aC4gV2hpbGUgdGhlIGZpZWxkIGhvbGRzIGl0LCB0aGUgZmllbGQgd3JpdGVzIG5vdGhpbmcgaW50byB0aGUgY29kZSBibG9jaywgdW5sZXNzIGl0XG4gICAqIGlzIHtAbGluayBDb2RlQmxvY2tCdWlsZGVyRmllbGRCYXNlLmlzUmVxdWlyZWR9LlxuICAgKi9cbiAgcmVhZG9ubHkgZGVmYXVsdFZhbHVlOiBWYWx1ZTtcblxuICAvKipcbiAgICogQSBkZXNjcmlwdGlvbiBzaG93biB1bmRlciB0aGUgZmllbGQncyBuYW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGZpZWxkIGlzIGFsd2F5cyB3cml0dGVuIGludG8gdGhlIGNvZGUgYmxvY2suIEEgcmVxdWlyZWQgZmllbGQgaXMgc2hvd24gYWJvdmUgdGhlIG9wdGlvbmFsIG9uZXMgYW5kIGhhc1xuICAgKiBubyByZXNldCBidXR0b24uXG4gICAqXG4gICAqIEBkZWZhdWx0IGBmYWxzZWBcbiAgICovXG4gIHJlYWRvbmx5IGlzUmVxdWlyZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUga2V5IHRoZSBmaWVsZCdzIGxpbmUgaXMgd3JpdHRlbiB3aXRoLCBhbmQgdGhlIGtleSBvZiBpdHMgdmFsdWUgaW4gdGhlIHZhbHVlcyB0aGUgcHJldmlldyByZWNlaXZlcy4gVW5pcXVlIGFjcm9zc1xuICAgKiBhbGwgZmllbGRzLlxuICAgKi9cbiAgcmVhZG9ubHkga2V5OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBmaWVsZCwgc2hvd24gdG8gdGhlIHVzZXIuXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGZpZWxkJ3MgbGluZSBob2xkcyBpdHMgdmFsdWUgYWxvbmUsIHdpdGhvdXQgdGhlIGBrZXk6IGAgcHJlZml4LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgZmFsc2VgXG4gICAqL1xuICByZWFkb25seSBzaG91bGRPbWl0S2V5PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBIGZvbGRlciBmaWVsZDogYSBkcm9wZG93biBvZiBldmVyeSBmb2xkZXIgb2YgdGhlIHZhdWx0LiBUaGUgdmFsdWUgaXMgdGhlIGZvbGRlciBwYXRoLCBgL2AgZm9yIHRoZSB2YXVsdCByb290LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvZGVCbG9ja0J1aWxkZXJGb2xkZXJGaWVsZCBleHRlbmRzIENvZGVCbG9ja0J1aWxkZXJGaWVsZEJhc2U8c3RyaW5nPiB7XG4gIC8qKlxuICAgKiBUaGUga2luZCBvZiB0aGUgZmllbGQuXG4gICAqL1xuICByZWFkb25seSB0eXBlOiAnZm9sZGVyJztcbn1cblxuLyoqXG4gKiBBIGNvbGxhcHNpYmxlIGdyb3VwIG9mIGZpZWxkcy4gT25lIGdyb3VwIGlzIGV4cGFuZGVkIGF0IGEgdGltZTogZXhwYW5kaW5nIGEgZ3JvdXAgY29sbGFwc2VzIHRoZSBvdGhlcnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29kZUJsb2NrQnVpbGRlckdyb3VwIHtcbiAgLyoqXG4gICAqIFRoZSBmaWVsZHMgb2YgdGhlIGdyb3VwLiBBIHJlcXVpcmVkIGZpZWxkIGluc2lkZSBhIGdyb3VwIGlzIHN0aWxsIHdyaXR0ZW4gaW50byB0aGUgY29kZSBibG9jay5cbiAgICovXG4gIHJlYWRvbmx5IGZpZWxkczogcmVhZG9ubHkgQ29kZUJsb2NrQnVpbGRlckZpZWxkW107XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGdyb3VwIHN0YXJ0cyBleHBhbmRlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgYGZhbHNlYFxuICAgKi9cbiAgcmVhZG9ubHkgaXNJbml0aWFsbHlFeHBhbmRlZD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBoZWFkaW5nIG9mIHRoZSBncm91cC5cbiAgICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGtpbmQgb2YgdGhlIGVudHJ5LlxuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogJ2dyb3VwJztcbn1cblxuLyoqXG4gKiBBbiBlbnRyeSBvZiB7QGxpbmsgU2hvd0NvZGVCbG9ja0J1aWxkZXJQYXJhbXMuZmllbGRzfTogYSBmaWVsZCwgb3IgYSBncm91cCBvZiBmaWVsZHMuXG4gKi9cbmV4cG9ydCB0eXBlIENvZGVCbG9ja0J1aWxkZXJJbnB1dCA9IENvZGVCbG9ja0J1aWxkZXJGaWVsZCB8IENvZGVCbG9ja0J1aWxkZXJHcm91cDtcblxuLyoqXG4gKiBBIG11bHRpcGxlLWNob2ljZSBkcm9wZG93biBmaWVsZC4gSXRzIGxpbmUgaG9sZHMgdGhlIHNlbGVjdGVkIG9wdGlvbnMgam9pbmVkIGJ5XG4gKiB7QGxpbmsgQ29kZUJsb2NrQnVpbGRlck11bHRpcGxlRHJvcGRvd25GaWVsZC5zZXBhcmF0b3J9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvZGVCbG9ja0J1aWxkZXJNdWx0aXBsZURyb3Bkb3duRmllbGQgZXh0ZW5kcyBDb2RlQmxvY2tCdWlsZGVyRmllbGRCYXNlPHJlYWRvbmx5IHN0cmluZ1tdPiB7XG4gIC8qKlxuICAgKiBUaGUgb3B0aW9ucyBvZiB0aGUgZHJvcGRvd24uXG4gICAqL1xuICByZWFkb25seSBvcHRpb25zOiBDb2RlQmxvY2tCdWlsZGVyT3B0aW9ucztcblxuICAvKipcbiAgICogVGhlIHRleHQgdGhlIHNlbGVjdGVkIG9wdGlvbnMgYXJlIGpvaW5lZCB3aXRoLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgJywnYFxuICAgKi9cbiAgcmVhZG9ubHkgc2VwYXJhdG9yPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUga2luZCBvZiB0aGUgZmllbGQuXG4gICAqL1xuICByZWFkb25seSB0eXBlOiAnbXVsdGlwbGVEcm9wZG93bic7XG59XG5cbi8qKlxuICogQSBuYW1lZCBncm91cCBvZiBvcHRpb25zIG9mIGEge0BsaW5rIENvZGVCbG9ja0J1aWxkZXJDb25kaXRpb25hbERyb3Bkb3duRmllbGR9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvZGVCbG9ja0J1aWxkZXJPcHRpb25Hcm91cCB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgZ3JvdXAsIHNob3duIGluIHRoZSBmaXJzdCBkcm9wZG93bi5cbiAgICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG9wdGlvbnMgb2YgdGhlIGdyb3VwLCBzaG93biBpbiB0aGUgc2Vjb25kIGRyb3Bkb3duLlxuICAgKi9cbiAgcmVhZG9ubHkgb3B0aW9uczogQ29kZUJsb2NrQnVpbGRlck9wdGlvbnM7XG59XG5cbi8qKlxuICogVGhlIG9wdGlvbnMgb2YgYSBkcm9wZG93bjogYSBsaXN0IG9mIHZhbHVlcyBzaG93biBhcyB0aGV5IGFyZSwgb3IgYSBtYXAgZnJvbSBlYWNoIHZhbHVlIHRvIGl0cyBkaXNwbGF5IHRleHQuXG4gKi9cbmV4cG9ydCB0eXBlIENvZGVCbG9ja0J1aWxkZXJPcHRpb25zID0gUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4gfCByZWFkb25seSBzdHJpbmdbXTtcblxuLyoqXG4gKiBUaGUgcGFyYW1ldGVycyBvZiB7QGxpbmsgU2hvd0NvZGVCbG9ja0J1aWxkZXJQYXJhbXMub25VcGRhdGVQcmV2aWV3fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb2RlQmxvY2tCdWlsZGVyUHJldmlld1BhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgY29kZSBibG9jayBhcyBpdCBzdGFuZHMuXG4gICAqL1xuICByZWFkb25seSBjb2RlQmxvY2s6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGVsZW1lbnQgdG8gZHJhdyB0aGUgcHJldmlldyBpbnRvLiBUaGUgbW9kYWwgbmV2ZXIgY2xlYXJzIGl0LlxuICAgKi9cbiAgcmVhZG9ubHkgcHJldmlld0VsOiBIVE1MRWxlbWVudDtcblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgdmFsdWUgb2YgZXZlcnkgZmllbGQsIGJ5IGl0cyBrZXkuXG4gICAqL1xuICByZWFkb25seSB2YWx1ZXM6IFJlYWRvbmx5TWFwPHN0cmluZywgQ29kZUJsb2NrQnVpbGRlclZhbHVlPjtcbn1cblxuLyoqXG4gKiBBIHNsaWRlciBmaWVsZC4gQSB7QGxpbmsgQ29kZUJsb2NrQnVpbGRlckZpZWxkQmFzZS5kZWZhdWx0VmFsdWV9IG91dHNpZGUgdGhlIGJvdW5kcyB3aWRlbnMgdGhlbS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb2RlQmxvY2tCdWlsZGVyU2xpZGVyRmllbGQgZXh0ZW5kcyBDb2RlQmxvY2tCdWlsZGVyRmllbGRCYXNlPG51bWJlcj4ge1xuICAvKipcbiAgICogVGhlIHVwcGVyIGJvdW5kLlxuICAgKi9cbiAgcmVhZG9ubHkgbWF4OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBsb3dlciBib3VuZC5cbiAgICovXG4gIHJlYWRvbmx5IG1pbjogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgc3RlcC5cbiAgICovXG4gIHJlYWRvbmx5IHN0ZXA6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGtpbmQgb2YgdGhlIGZpZWxkLlxuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogJ3NsaWRlcic7XG59XG5cbi8qKlxuICogQSB0ZXh0IGZpZWxkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvZGVCbG9ja0J1aWxkZXJUZXh0RmllbGQgZXh0ZW5kcyBDb2RlQmxvY2tCdWlsZGVyRmllbGRCYXNlPHN0cmluZz4ge1xuICAvKipcbiAgICogQSBwbGFjZWhvbGRlciBzaG93biB3aGlsZSB0aGUgZmllbGQgaXMgZW1wdHkuXG4gICAqL1xuICByZWFkb25seSBwbGFjZWhvbGRlcj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGtpbmQgb2YgdGhlIGZpZWxkLlxuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogJ3RleHQnO1xuXG4gIC8qKlxuICAgKiBBIHBhdHRlcm4gdGhlIHZhbHVlIG11c3QgbWF0Y2guIFdoaWxlIGl0IGRvZXMgbm90LCB0aGUgZmllbGQgaXMgbWFya2VkIGludmFsaWQgYW5kIGtlZXBzIGl0cyBsYXN0IHZhbGlkIHZhbHVlLlxuICAgKi9cbiAgcmVhZG9ubHkgdmFsaWRhdGlvblBhdHRlcm4/OiBSZWdFeHA7XG59XG5cbi8qKlxuICogVGhlIHZhbHVlIG9mIGEge0BsaW5rIENvZGVCbG9ja0J1aWxkZXJGaWVsZH0uXG4gKi9cbmV4cG9ydCB0eXBlIENvZGVCbG9ja0J1aWxkZXJWYWx1ZSA9IGJvb2xlYW4gfCBudW1iZXIgfCByZWFkb25seSBzdHJpbmdbXSB8IHN0cmluZztcblxuLyoqXG4gKiBUaGUgcGFyYW1ldGVycyBvZiB7QGxpbmsgZm9ybWF0Q29kZUJsb2NrfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBGb3JtYXRDb2RlQmxvY2tQYXJhbXMge1xuICAvKipcbiAgICogVGhlIGZpZWxkcyBvZiB0aGUgY29kZSBibG9jay5cbiAgICovXG4gIHJlYWRvbmx5IGZpZWxkczogcmVhZG9ubHkgQ29kZUJsb2NrQnVpbGRlcklucHV0W107XG5cbiAgLyoqXG4gICAqIFRoZSBsYW5ndWFnZSBvZiB0aGUgY29kZSBibG9jay5cbiAgICovXG4gIHJlYWRvbmx5IGxhbmd1YWdlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSBvZiBlYWNoIGZpZWxkLCBieSBpdHMga2V5LiBBIGZpZWxkIG1pc3NpbmcgZnJvbSBpdCBob2xkcyBpdHMgZGVmYXVsdCB2YWx1ZS5cbiAgICovXG4gIHJlYWRvbmx5IHZhbHVlczogUmVhZG9ubHlNYXA8c3RyaW5nLCBDb2RlQmxvY2tCdWlsZGVyVmFsdWU+O1xufVxuXG4vKipcbiAqIFRoZSBwYXJhbWV0ZXJzIG9mIHtAbGluayBzaG93Q29kZUJsb2NrQnVpbGRlcn0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2hvd0NvZGVCbG9ja0J1aWxkZXJQYXJhbXMgZXh0ZW5kcyBNb2RhbFBhcmFtc0Jhc2Uge1xuICAvKipcbiAgICogVGhlIGVkaXRvciB0aGUgSW5zZXJ0IGJ1dHRvbiB3cml0ZXMgaW50by5cbiAgICpcbiAgICogQGRlZmF1bHQgVGhlIGFjdGl2ZSBlZGl0b3Igd2hlbiB0aGUgbW9kYWwgb3BlbnMuXG4gICAqL1xuICByZWFkb25seSBlZGl0b3I/OiBFZGl0b3IgfCBudWxsO1xuXG4gIC8qKlxuICAgKiBUaGUgZmllbGRzIG9mIHRoZSBjb2RlIGJsb2NrLCBpbiB0aGUgb3JkZXIgdGhleSBhcmUgd3JpdHRlbiBpbnRvIGl0LiBSZXF1aXJlZCBmaWVsZHMgYXJlIHNob3duIGZpcnN0LlxuICAgKi9cbiAgcmVhZG9ubHkgZmllbGRzOiByZWFkb25seSBDb2RlQmxvY2tCdWlsZGVySW5wdXRbXTtcblxuICAvKipcbiAgICogVGhlIGxhbmd1YWdlIG9mIHRoZSBjb2RlIGJsb2NrOiB0aGUgdGV4dCBhZnRlciBpdHMgb3BlbmluZyBmZW5jZS5cbiAgICovXG4gIHJlYWRvbmx5IGxhbmd1YWdlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIERyYXdzIGEgbGl2ZSBwcmV2aWV3IG9mIHRoZSBjb2RlIGJsb2NrLiBDYWxsZWQgb25jZSB3aGVuIHRoZSBtb2RhbCBvcGVucyBhbmQgYWdhaW4gYWZ0ZXIgZXZlcnkgY2hhbmdlLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHByZXZpZXcgZWxlbWVudCwgdGhlIGNvZGUgYmxvY2sgYW5kIHRoZSBjdXJyZW50IHZhbHVlcy5cbiAgICovXG4gIHJlYWRvbmx5IG9uVXBkYXRlUHJldmlldz86IChwYXJhbXM6IENvZGVCbG9ja0J1aWxkZXJQcmV2aWV3UGFyYW1zKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBUaGUgdGl0bGUgb2YgdGhlIG1vZGFsLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgJ0NvZGUgYmxvY2sgYnVpbGRlcidgXG4gICAqL1xuICByZWFkb25seSB0aXRsZT86IHN0cmluZztcbn1cblxuY29uc3QgREVGQVVMVF9TRVBBUkFUT1IgPSAnLCc7XG5jb25zdCBNSU5fRkVOQ0VfTEVOR1RIID0gMztcbmNvbnN0IFJPT1RfRk9MREVSX1BBVEggPSAnLyc7XG5cbnR5cGUgQ29kZUJsb2NrQnVpbGRlck1vZGFsQ29uc3RydWN0b3JQYXJhbXMgPSBNb2RhbEJhc2VDb25zdHJ1Y3RvclBhcmFtczxudWxsIHwgc3RyaW5nPiAmIFNob3dDb2RlQmxvY2tCdWlsZGVyUGFyYW1zO1xuXG5pbnRlcmZhY2UgR3JvdXBTdGF0ZSB7XG4gIHJlYWRvbmx5IGJ1dHRvbjogRXh0cmFCdXR0b25Db21wb25lbnQ7XG4gIHJlYWRvbmx5IGdyb3VwRWw6IEhUTUxFbGVtZW50O1xufVxuXG5jbGFzcyBDb2RlQmxvY2tCdWlsZGVyTW9kYWwgZXh0ZW5kcyBNb2RhbEJhc2U8bnVsbCB8IHN0cmluZz4ge1xuICBwcml2YXRlIGNvZGVCbG9jayA9ICcnO1xuICBwcml2YXRlIHJlYWRvbmx5IGVkaXRvcjogRWRpdG9yIHwgbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSBmaWVsZHM6IHJlYWRvbmx5IENvZGVCbG9ja0J1aWxkZXJJbnB1dFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IGdyb3VwU3RhdGVzOiBHcm91cFN0YXRlW10gPSBbXTtcbiAgcHJpdmF0ZSBpbnNlcnRlZENvZGVCbG9jazogbnVsbCB8IHN0cmluZyA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgbGFuZ3VhZ2U6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBvblVwZGF0ZVByZXZpZXc6ICgocGFyYW1zOiBDb2RlQmxvY2tCdWlsZGVyUHJldmlld1BhcmFtcykgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgb3V0cHV0Q29tcG9uZW50OiBudWxsIHwgVGV4dEFyZWFDb21wb25lbnQgPSBudWxsO1xuICBwcml2YXRlIHByZXZpZXdFbDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSB0aXRsZTogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IHZhbHVlcyA9IG5ldyBNYXA8c3RyaW5nLCBDb2RlQmxvY2tCdWlsZGVyVmFsdWU+KCk7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHBhcmFtczogQ29kZUJsb2NrQnVpbGRlck1vZGFsQ29uc3RydWN0b3JQYXJhbXMpIHtcbiAgICBzdXBlcihwYXJhbXMpO1xuICAgIHRoaXMuYWRkQ3NzQ2xhc3NlcyhDc3NDbGFzcy5Db2RlQmxvY2tCdWlsZGVyTW9kYWwpO1xuICAgIHRoaXMuZWRpdG9yID0gcGFyYW1zLmVkaXRvciA9PT0gdW5kZWZpbmVkID8gcGFyYW1zLmFwcC53b3Jrc3BhY2UuYWN0aXZlRWRpdG9yPy5lZGl0b3IgPz8gbnVsbCA6IHBhcmFtcy5lZGl0b3I7XG4gICAgdGhpcy5maWVsZHMgPSBwYXJhbXMuZmllbGRzO1xuICAgIHRoaXMubGFuZ3VhZ2UgPSBwYXJhbXMubGFuZ3VhZ2U7XG4gICAgdGhpcy5vblVwZGF0ZVByZXZpZXcgPSBwYXJhbXMub25VcGRhdGVQcmV2aWV3O1xuICAgIHRoaXMudGl0bGUgPSBwYXJhbXMudGl0bGUgPz8gdCgoJCkgPT4gJC5vYnNpZGlhbkxpYi5jb2RlQmxvY2tCdWlsZGVyLnRpdGxlKTtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGZsYXR0ZW5GaWVsZHModGhpcy5maWVsZHMpKSB7XG4gICAgICB0aGlzLnZhbHVlcy5zZXQoZmllbGQua2V5LCBmaWVsZC5kZWZhdWx0VmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBvdmVycmlkZSBvbkNsb3NlKCk6IHZvaWQge1xuICAgIHRoaXMucHJvbWlzZVJlc29sdmUodGhpcy5pbnNlcnRlZENvZGVCbG9jayk7XG4gIH1cblxuICBwdWJsaWMgb3ZlcnJpZGUgb25PcGVuKCk6IHZvaWQge1xuICAgIHRoaXMudGl0bGVFbC5zZXRUZXh0KHRoaXMudGl0bGUpO1xuXG4gICAgZm9yIChjb25zdCBpbnB1dCBvZiB0aGlzLmZpZWxkcykge1xuICAgICAgaWYgKGlucHV0LnR5cGUgIT09ICdncm91cCcgJiYgaW5wdXQuaXNSZXF1aXJlZCkge1xuICAgICAgICB0aGlzLnJlbmRlckZpZWxkKHRoaXMuY29udGVudEVsLCBpbnB1dCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBpbnB1dCBvZiB0aGlzLmZpZWxkcykge1xuICAgICAgaWYgKGlucHV0LnR5cGUgPT09ICdncm91cCcpIHtcbiAgICAgICAgdGhpcy5yZW5kZXJHcm91cChpbnB1dCk7XG4gICAgICB9IGVsc2UgaWYgKCFpbnB1dC5pc1JlcXVpcmVkKSB7XG4gICAgICAgIHRoaXMucmVuZGVyRmllbGQodGhpcy5jb250ZW50RWwsIGlucHV0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnByZXZpZXdFbCA9IHRoaXMuY29udGVudEVsLmNyZWF0ZURpdih7IGNsczogQ3NzQ2xhc3MuQ29kZUJsb2NrQnVpbGRlclByZXZpZXcgfSk7XG4gICAgdGhpcy5yZW5kZXJPdXRwdXQoKTtcbiAgICB0aGlzLnVwZGF0ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRSZXNldEJ1dHRvbihzZXR0aW5nOiBTZXR0aW5nLCBmaWVsZDogQ29kZUJsb2NrQnVpbGRlckZpZWxkLCByZXNldDogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIGlmIChmaWVsZC5pc1JlcXVpcmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc2V0dGluZy5hZGRFeHRyYUJ1dHRvbigoYnV0dG9uKSA9PiB7XG4gICAgICBidXR0b25cbiAgICAgICAgLnNldEljb24oJ2x1Y2lkZS1yb3RhdGUtY2N3JylcbiAgICAgICAgLnNldFRvb2x0aXAodCgoJCkgPT4gJC5vYnNpZGlhbkxpYi5jb2RlQmxvY2tCdWlsZGVyLnJlc2V0LCB7IHZhbHVlOiBmb3JtYXRWYWx1ZShmaWVsZCwgZmllbGQuZGVmYXVsdFZhbHVlKSB8fCAnXCJcIicgfSkpXG4gICAgICAgIC5vbkNsaWNrKCgpID0+IHtcbiAgICAgICAgICByZXNldCgpO1xuICAgICAgICAgIHRoaXMuc2V0VmFsdWUoZmllbGQua2V5LCBmaWVsZC5kZWZhdWx0VmFsdWUpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY29weSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5jb250YWluZXJFbC53aW4ubmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQodGhpcy5jb2RlQmxvY2spO1xuICAgICAgbmV3IE5vdGljZSh0KCgkKSA9PiAkLm9ic2lkaWFuTGliLmNvZGVCbG9ja0J1aWxkZXIuY29waWVkKSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBuZXcgTm90aWNlKHQoKCQpID0+ICQub2JzaWRpYW5MaWIuY29kZUJsb2NrQnVpbGRlci5jb3B5RmFpbGVkKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmVkaXRvcikge1xuICAgICAgbmV3IE5vdGljZSh0KCgkKSA9PiAkLm9ic2lkaWFuTGliLmNvZGVCbG9ja0J1aWxkZXIuaW5zZXJ0VW5hdmFpbGFibGUpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJzb3IgPSB0aGlzLmVkaXRvci5nZXRDdXJzb3IoJ2Zyb20nKTtcbiAgICBjb25zdCB0ZXh0QmVmb3JlQ3Vyc29yID0gdGhpcy5lZGl0b3IuZ2V0TGluZShjdXJzb3IubGluZSkuc2xpY2UoMCwgY3Vyc29yLmNoKTtcbiAgICBjb25zdCBwcmVmaXggPSB0ZXh0QmVmb3JlQ3Vyc29yID09PSAnJyA/ICcnIDogJ1xcbic7XG4gICAgdGhpcy5lZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgJHtwcmVmaXh9JHt0aGlzLmNvZGVCbG9ja31cXG5gKTtcbiAgICB0aGlzLmluc2VydGVkQ29kZUJsb2NrID0gdGhpcy5jb2RlQmxvY2s7XG4gICAgdGhpcy5jbG9zZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJCb29sZWFuRmllbGQoc2V0dGluZzogU2V0dGluZywgZmllbGQ6IENvZGVCbG9ja0J1aWxkZXJCb29sZWFuRmllbGQpOiB2b2lkIHtcbiAgICBzZXR0aW5nLmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XG4gICAgICB0b2dnbGVcbiAgICAgICAgLnNldFZhbHVlKGZpZWxkLmRlZmF1bHRWYWx1ZSlcbiAgICAgICAgLm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2V0VmFsdWUoZmllbGQua2V5LCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgdGhpcy5hZGRSZXNldEJ1dHRvbihzZXR0aW5nLCBmaWVsZCwgKCkgPT4ge1xuICAgICAgICB0b2dnbGUuc2V0VmFsdWUoZmllbGQuZGVmYXVsdFZhbHVlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJDb2xvckZpZWxkKHNldHRpbmc6IFNldHRpbmcsIGZpZWxkOiBDb2RlQmxvY2tCdWlsZGVyQ29sb3JGaWVsZCk6IHZvaWQge1xuICAgIHNldHRpbmcuYWRkQ29sb3JQaWNrZXIoKGNvbG9yUGlja2VyKSA9PiB7XG4gICAgICBjb2xvclBpY2tlclxuICAgICAgICAuc2V0VmFsdWUoZmllbGQuZGVmYXVsdFZhbHVlKVxuICAgICAgICAub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG4gICAgICAgICAgdGhpcy5zZXRWYWx1ZShmaWVsZC5rZXksIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICB0aGlzLmFkZFJlc2V0QnV0dG9uKHNldHRpbmcsIGZpZWxkLCAoKSA9PiB7XG4gICAgICAgIGNvbG9yUGlja2VyLnNldFZhbHVlKGZpZWxkLmRlZmF1bHRWYWx1ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyQ29uZGl0aW9uYWxEcm9wZG93bkZpZWxkKHNldHRpbmc6IFNldHRpbmcsIGZpZWxkOiBDb2RlQmxvY2tCdWlsZGVyQ29uZGl0aW9uYWxEcm9wZG93bkZpZWxkKTogdm9pZCB7XG4gICAgY29uc3QgaW5pdGlhbEdyb3VwSW5kZXggPSBNYXRoLm1heCgwLCBmaWVsZC5ncm91cHMuZmluZEluZGV4KChncm91cCkgPT4gT2JqZWN0Lmhhc093bih0b1JlY29yZChncm91cC5vcHRpb25zKSwgZmllbGQuZGVmYXVsdFZhbHVlKSkpO1xuICAgIGNvbnN0IGdyb3VwRHJvcGRvd24gPSBuZXcgRHJvcGRvd25Db21wb25lbnQoc2V0dGluZy5jb250cm9sRWwpO1xuICAgIGZvciAoY29uc3QgW2luZGV4LCBncm91cF0gb2YgZmllbGQuZ3JvdXBzLmVudHJpZXMoKSkge1xuICAgICAgZ3JvdXBEcm9wZG93bi5hZGRPcHRpb24oU3RyaW5nKGluZGV4KSwgZ3JvdXAubmFtZSk7XG4gICAgfVxuICAgIGdyb3VwRHJvcGRvd24uc2V0VmFsdWUoU3RyaW5nKGluaXRpYWxHcm91cEluZGV4KSk7XG5cbiAgICBjb25zdCBvcHRpb25Ecm9wZG93biA9IG5ldyBEcm9wZG93bkNvbXBvbmVudChzZXR0aW5nLmNvbnRyb2xFbCk7XG5cbiAgICBmdW5jdGlvbiBmaWxsT3B0aW9ucyhncm91cEluZGV4OiBudW1iZXIsIHZhbHVlPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB0b1JlY29yZChmaWVsZC5ncm91cHNbZ3JvdXBJbmRleF0/Lm9wdGlvbnMgPz8gW10pO1xuICAgICAgY29uc3Qgc2VsZWN0ZWRWYWx1ZSA9IHZhbHVlID8/IE9iamVjdC5rZXlzKG9wdGlvbnMpWzBdID8/ICcnO1xuICAgICAgb3B0aW9uRHJvcGRvd24uc2VsZWN0RWwuZW1wdHkoKTtcbiAgICAgIG9wdGlvbkRyb3Bkb3duLmFkZE9wdGlvbnMob3B0aW9ucyk7XG4gICAgICBvcHRpb25Ecm9wZG93bi5zZXRWYWx1ZShzZWxlY3RlZFZhbHVlKTtcbiAgICAgIHJldHVybiBzZWxlY3RlZFZhbHVlO1xuICAgIH1cblxuICAgIGZpbGxPcHRpb25zKGluaXRpYWxHcm91cEluZGV4LCBmaWVsZC5kZWZhdWx0VmFsdWUpO1xuICAgIG9wdGlvbkRyb3Bkb3duLm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuICAgICAgdGhpcy5zZXRWYWx1ZShmaWVsZC5rZXksIHZhbHVlKTtcbiAgICB9KTtcblxuICAgIGdyb3VwRHJvcGRvd24ub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG4gICAgICB0aGlzLnNldFZhbHVlKGZpZWxkLmtleSwgZmlsbE9wdGlvbnMoTnVtYmVyKHZhbHVlKSkpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5hZGRSZXNldEJ1dHRvbihzZXR0aW5nLCBmaWVsZCwgKCkgPT4ge1xuICAgICAgZ3JvdXBEcm9wZG93bi5zZXRWYWx1ZShTdHJpbmcoaW5pdGlhbEdyb3VwSW5kZXgpKTtcbiAgICAgIGZpbGxPcHRpb25zKGluaXRpYWxHcm91cEluZGV4LCBmaWVsZC5kZWZhdWx0VmFsdWUpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJEcm9wZG93bkZpZWxkKHNldHRpbmc6IFNldHRpbmcsIGZpZWxkOiBDb2RlQmxvY2tCdWlsZGVyRHJvcGRvd25GaWVsZCk6IHZvaWQge1xuICAgIHNldHRpbmcuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PiB7XG4gICAgICBkcm9wZG93blxuICAgICAgICAuYWRkT3B0aW9ucyh0b1JlY29yZChmaWVsZC5vcHRpb25zKSlcbiAgICAgICAgLnNldFZhbHVlKGZpZWxkLmRlZmF1bHRWYWx1ZSlcbiAgICAgICAgLm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2V0VmFsdWUoZmllbGQua2V5LCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgdGhpcy5hZGRSZXNldEJ1dHRvbihzZXR0aW5nLCBmaWVsZCwgKCkgPT4ge1xuICAgICAgICBkcm9wZG93bi5zZXRWYWx1ZShmaWVsZC5kZWZhdWx0VmFsdWUpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlckZpZWxkKGNvbnRhaW5lckVsOiBIVE1MRWxlbWVudCwgZmllbGQ6IENvZGVCbG9ja0J1aWxkZXJGaWVsZCk6IHZvaWQge1xuICAgIGNvbnN0IHNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbCkuc2V0TmFtZShmaWVsZC5uYW1lKTtcbiAgICBpZiAoZmllbGQuZGVzY3JpcHRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgc2V0dGluZy5zZXREZXNjKGZpZWxkLmRlc2NyaXB0aW9uKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGZpZWxkLnR5cGUpIHtcbiAgICAgIGNhc2UgJ2Jvb2xlYW4nOiB7XG4gICAgICAgIHRoaXMucmVuZGVyQm9vbGVhbkZpZWxkKHNldHRpbmcsIGZpZWxkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdjb2xvcic6IHtcbiAgICAgICAgdGhpcy5yZW5kZXJDb2xvckZpZWxkKHNldHRpbmcsIGZpZWxkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdjb25kaXRpb25hbERyb3Bkb3duJzoge1xuICAgICAgICB0aGlzLnJlbmRlckNvbmRpdGlvbmFsRHJvcGRvd25GaWVsZChzZXR0aW5nLCBmaWVsZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnZHJvcGRvd24nOiB7XG4gICAgICAgIHRoaXMucmVuZGVyRHJvcGRvd25GaWVsZChzZXR0aW5nLCBmaWVsZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnZm9sZGVyJzoge1xuICAgICAgICB0aGlzLnJlbmRlckZvbGRlckZpZWxkKHNldHRpbmcsIGZpZWxkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdtdWx0aXBsZURyb3Bkb3duJzoge1xuICAgICAgICB0aGlzLnJlbmRlck11bHRpcGxlRHJvcGRvd25GaWVsZChzZXR0aW5nLCBmaWVsZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnc2xpZGVyJzoge1xuICAgICAgICB0aGlzLnJlbmRlclNsaWRlckZpZWxkKHNldHRpbmcsIGZpZWxkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICd0ZXh0Jzoge1xuICAgICAgICB0aGlzLnJlbmRlclRleHRGaWVsZChzZXR0aW5nLCBmaWVsZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICBhc3NlcnROZXZlcihmaWVsZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJGb2xkZXJGaWVsZChzZXR0aW5nOiBTZXR0aW5nLCBmaWVsZDogQ29kZUJsb2NrQnVpbGRlckZvbGRlckZpZWxkKTogdm9pZCB7XG4gICAgY29uc3Qgb3B0aW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIFtST09UX0ZPTERFUl9QQVRIXTogdCgoJCkgPT4gJC5vYnNpZGlhbkxpYi5jb2RlQmxvY2tCdWlsZGVyLnJvb3RGb2xkZXIpXG4gICAgfTtcbiAgICBjb25zdCBmb2xkZXJQYXRocyA9IHRoaXMuYXBwLnZhdWx0LmdldEFsbEZvbGRlcnMoZmFsc2UpLm1hcCgoZm9sZGVyKSA9PiBmb2xkZXIucGF0aCkuc29ydCgoYSwgYikgPT4gYS5sb2NhbGVDb21wYXJlKGIpKTtcbiAgICBmb3IgKGNvbnN0IGZvbGRlclBhdGggb2YgZm9sZGVyUGF0aHMpIHtcbiAgICAgIG9wdGlvbnNbZm9sZGVyUGF0aF0gPSBmb2xkZXJQYXRoO1xuICAgIH1cblxuICAgIG9wdGlvbnNbZmllbGQuZGVmYXVsdFZhbHVlXSA/Pz0gZmllbGQuZGVmYXVsdFZhbHVlO1xuXG4gICAgc2V0dGluZy5hZGREcm9wZG93bigoZHJvcGRvd24pID0+IHtcbiAgICAgIGRyb3Bkb3duXG4gICAgICAgIC5hZGRPcHRpb25zKG9wdGlvbnMpXG4gICAgICAgIC5zZXRWYWx1ZShmaWVsZC5kZWZhdWx0VmFsdWUpXG4gICAgICAgIC5vbkNoYW5nZSgodmFsdWUpID0+IHtcbiAgICAgICAgICB0aGlzLnNldFZhbHVlKGZpZWxkLmtleSwgdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICAgIHRoaXMuYWRkUmVzZXRCdXR0b24oc2V0dGluZywgZmllbGQsICgpID0+IHtcbiAgICAgICAgZHJvcGRvd24uc2V0VmFsdWUoZmllbGQuZGVmYXVsdFZhbHVlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJHcm91cChncm91cDogQ29kZUJsb2NrQnVpbGRlckdyb3VwKTogdm9pZCB7XG4gICAgY29uc3QgZ3JvdXBFbCA9IHRoaXMuY29udGVudEVsLmNyZWF0ZURpdih7IGNsczogQ3NzQ2xhc3MuQ29kZUJsb2NrQnVpbGRlckdyb3VwIH0pO1xuICAgIGNvbnN0IGhlYWRpbmdTZXR0aW5nID0gbmV3IFNldHRpbmcoZ3JvdXBFbCkuc2V0TmFtZShncm91cC5uYW1lKS5zZXRIZWFkaW5nKCk7XG4gICAgY29uc3QgYm9keUVsID0gZ3JvdXBFbC5jcmVhdGVEaXYoeyBjbHM6IENzc0NsYXNzLkNvZGVCbG9ja0J1aWxkZXJHcm91cEJvZHkgfSk7XG5cbiAgICBncm91cEVsLmFkZENsYXNzKENzc0NsYXNzLklzQ29sbGFwc2VkKTtcbiAgICBoZWFkaW5nU2V0dGluZy5hZGRFeHRyYUJ1dHRvbigoYnV0dG9uKSA9PiB7XG4gICAgICBjb25zdCBncm91cFN0YXRlID0geyBidXR0b24sIGdyb3VwRWwgfTtcbiAgICAgIHRoaXMuZ3JvdXBTdGF0ZXMucHVzaChncm91cFN0YXRlKTtcbiAgICAgIHVwZGF0ZUdyb3VwSWNvbihncm91cFN0YXRlKTtcbiAgICAgIGJ1dHRvbi5vbkNsaWNrKCgpID0+IHtcbiAgICAgICAgdGhpcy5zZXRHcm91cEV4cGFuZGVkKGdyb3VwRWwsIGdyb3VwRWwuaGFzQ2xhc3MoQ3NzQ2xhc3MuSXNDb2xsYXBzZWQpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZm9yIChjb25zdCBmaWVsZCBvZiBncm91cC5maWVsZHMpIHtcbiAgICAgIHRoaXMucmVuZGVyRmllbGQoYm9keUVsLCBmaWVsZCk7XG4gICAgfVxuXG4gICAgaWYgKGdyb3VwLmlzSW5pdGlhbGx5RXhwYW5kZWQpIHtcbiAgICAgIHRoaXMuc2V0R3JvdXBFeHBhbmRlZChncm91cEVsLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlbmRlck11bHRpcGxlRHJvcGRvd25GaWVsZChzZXR0aW5nOiBTZXR0aW5nLCBmaWVsZDogQ29kZUJsb2NrQnVpbGRlck11bHRpcGxlRHJvcGRvd25GaWVsZCk6IHZvaWQge1xuICAgIGNvbnN0IGRyb3Bkb3duID0gbmV3IE11bHRpcGxlRHJvcGRvd25Db21wb25lbnQoc2V0dGluZy5jb250cm9sRWwpXG4gICAgICAuYWRkT3B0aW9ucyh0b1JlY29yZChmaWVsZC5vcHRpb25zKSlcbiAgICAgIC5zZXRWYWx1ZShmaWVsZC5kZWZhdWx0VmFsdWUpXG4gICAgICAub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0VmFsdWUoZmllbGQua2V5LCB2YWx1ZSk7XG4gICAgICB9KTtcbiAgICBzZXR0aW5nLmFkZENvbXBvbmVudCgoKSA9PiBkcm9wZG93bik7XG4gICAgdGhpcy5hZGRSZXNldEJ1dHRvbihzZXR0aW5nLCBmaWVsZCwgKCkgPT4ge1xuICAgICAgZHJvcGRvd24uc2V0VmFsdWUoZmllbGQuZGVmYXVsdFZhbHVlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyT3V0cHV0KCk6IHZvaWQge1xuICAgIGNvbnN0IHNldHRpbmcgPSBuZXcgU2V0dGluZyh0aGlzLmNvbnRlbnRFbCkuc2V0TmFtZSh0KCgkKSA9PiAkLm9ic2lkaWFuTGliLmNvZGVCbG9ja0J1aWxkZXIub3V0cHV0KSk7XG4gICAgc2V0dGluZy5zZXR0aW5nRWwuYWRkQ2xhc3MoQ3NzQ2xhc3MuQ29kZUJsb2NrQnVpbGRlck91dHB1dCk7XG4gICAgc2V0dGluZy5hZGRUZXh0QXJlYSgodGV4dEFyZWEpID0+IHtcbiAgICAgIHRoaXMub3V0cHV0Q29tcG9uZW50ID0gdGV4dEFyZWE7XG4gICAgICB0ZXh0QXJlYS5pbnB1dEVsLnJlYWRPbmx5ID0gdHJ1ZTtcbiAgICB9KTtcbiAgICBzZXR0aW5nLmFkZEV4dHJhQnV0dG9uKChidXR0b24pID0+IHtcbiAgICAgIGJ1dHRvblxuICAgICAgICAuc2V0SWNvbignbHVjaWRlLWNvcHknKVxuICAgICAgICAuc2V0VG9vbHRpcCh0KCgkKSA9PiAkLm9ic2lkaWFuTGliLmNvZGVCbG9ja0J1aWxkZXIuY29weSkpXG4gICAgICAgIC5vbkNsaWNrKCgpID0+IHtcbiAgICAgICAgICBpbnZva2VBc3luY1NhZmVseSgoKSA9PiB0aGlzLmNvcHkoKSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIHNldHRpbmcuYWRkRXh0cmFCdXR0b24oKGJ1dHRvbikgPT4ge1xuICAgICAgYnV0dG9uXG4gICAgICAgIC5zZXRJY29uKCdsdWNpZGUtZmlsZS1pbnB1dCcpXG4gICAgICAgIC5zZXRUb29sdGlwKHQoKCQpID0+IHRoaXMuZWRpdG9yID8gJC5vYnNpZGlhbkxpYi5jb2RlQmxvY2tCdWlsZGVyLmluc2VydCA6ICQub2JzaWRpYW5MaWIuY29kZUJsb2NrQnVpbGRlci5pbnNlcnRVbmF2YWlsYWJsZSkpXG4gICAgICAgIC5vbkNsaWNrKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmluc2VydCgpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyU2xpZGVyRmllbGQoc2V0dGluZzogU2V0dGluZywgZmllbGQ6IENvZGVCbG9ja0J1aWxkZXJTbGlkZXJGaWVsZCk6IHZvaWQge1xuICAgIHNldHRpbmcuYWRkU2xpZGVyKChzbGlkZXIpID0+IHtcbiAgICAgIHNsaWRlclxuICAgICAgICAuc2V0TGltaXRzKE1hdGgubWluKGZpZWxkLm1pbiwgZmllbGQuZGVmYXVsdFZhbHVlKSwgTWF0aC5tYXgoZmllbGQubWF4LCBmaWVsZC5kZWZhdWx0VmFsdWUpLCBmaWVsZC5zdGVwKVxuICAgICAgICAuc2V0VmFsdWUoZmllbGQuZGVmYXVsdFZhbHVlKVxuICAgICAgICAub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG4gICAgICAgICAgdGhpcy5zZXRWYWx1ZShmaWVsZC5rZXksIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICB0aGlzLmFkZFJlc2V0QnV0dG9uKHNldHRpbmcsIGZpZWxkLCAoKSA9PiB7XG4gICAgICAgIHNsaWRlci5zZXRWYWx1ZShmaWVsZC5kZWZhdWx0VmFsdWUpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlclRleHRGaWVsZChzZXR0aW5nOiBTZXR0aW5nLCBmaWVsZDogQ29kZUJsb2NrQnVpbGRlclRleHRGaWVsZCk6IHZvaWQge1xuICAgIHNldHRpbmcuYWRkVGV4dCgodGV4dCkgPT4ge1xuICAgICAgdGV4dFxuICAgICAgICAuc2V0UGxhY2Vob2xkZXIoZmllbGQucGxhY2Vob2xkZXIgPz8gJycpXG4gICAgICAgIC5zZXRWYWx1ZShmaWVsZC5kZWZhdWx0VmFsdWUpXG4gICAgICAgIC5vbkNoYW5nZSgodmFsdWUpID0+IHtcbiAgICAgICAgICBpZiAoZmllbGQudmFsaWRhdGlvblBhdHRlcm4gJiYgIWRvZXNNYXRjaFBhdHRlcm4oZmllbGQudmFsaWRhdGlvblBhdHRlcm4sIHZhbHVlKSkge1xuICAgICAgICAgICAgdGV4dC5pbnB1dEVsLnNldEN1c3RvbVZhbGlkaXR5KHQoKCQpID0+ICQub2JzaWRpYW5MaWIuY29kZUJsb2NrQnVpbGRlci5pbnZhbGlkVmFsdWUpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0ZXh0LmlucHV0RWwuc2V0Q3VzdG9tVmFsaWRpdHkoJycpO1xuICAgICAgICAgIHRoaXMuc2V0VmFsdWUoZmllbGQua2V5LCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgdGhpcy5hZGRSZXNldEJ1dHRvbihzZXR0aW5nLCBmaWVsZCwgKCkgPT4ge1xuICAgICAgICB0ZXh0LnNldFZhbHVlKGZpZWxkLmRlZmF1bHRWYWx1ZSk7XG4gICAgICAgIHRleHQuaW5wdXRFbC5zZXRDdXN0b21WYWxpZGl0eSgnJyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0R3JvdXBFeHBhbmRlZChncm91cEVsOiBIVE1MRWxlbWVudCwgaXNFeHBhbmRlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGZvciAoY29uc3QgZ3JvdXBTdGF0ZSBvZiB0aGlzLmdyb3VwU3RhdGVzKSB7XG4gICAgICBjb25zdCBzaG91bGRFeHBhbmQgPSBpc0V4cGFuZGVkICYmIGdyb3VwU3RhdGUuZ3JvdXBFbCA9PT0gZ3JvdXBFbDtcbiAgICAgIGdyb3VwU3RhdGUuZ3JvdXBFbC50b2dnbGVDbGFzcyhDc3NDbGFzcy5Jc0NvbGxhcHNlZCwgIXNob3VsZEV4cGFuZCk7XG4gICAgICB1cGRhdGVHcm91cEljb24oZ3JvdXBTdGF0ZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXRWYWx1ZShrZXk6IHN0cmluZywgdmFsdWU6IENvZGVCbG9ja0J1aWxkZXJWYWx1ZSk6IHZvaWQge1xuICAgIHRoaXMudmFsdWVzLnNldChrZXksIHZhbHVlKTtcbiAgICB0aGlzLnVwZGF0ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGUoKTogdm9pZCB7XG4gICAgdGhpcy5jb2RlQmxvY2sgPSBmb3JtYXRDb2RlQmxvY2soe1xuICAgICAgZmllbGRzOiB0aGlzLmZpZWxkcyxcbiAgICAgIGxhbmd1YWdlOiB0aGlzLmxhbmd1YWdlLFxuICAgICAgdmFsdWVzOiB0aGlzLnZhbHVlc1xuICAgIH0pO1xuXG4gICAgLy8gT25seSByZWFjaGVkIG9uY2UgYG9uT3BlbmAgaGFzIHJlbmRlcmVkIHRoZSBvdXRwdXQgYW5kIHRoZSBwcmV2aWV3IGVsZW1lbnQuXG4gICAgY29uc3Qgb3V0cHV0Q29tcG9uZW50ID0gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5vdXRwdXRDb21wb25lbnQpO1xuICAgIG91dHB1dENvbXBvbmVudC5zZXRWYWx1ZSh0aGlzLmNvZGVCbG9jayk7XG4gICAgb3V0cHV0Q29tcG9uZW50LmlucHV0RWwucm93cyA9IHRoaXMuY29kZUJsb2NrLnNwbGl0KCdcXG4nKS5sZW5ndGg7XG5cbiAgICBpZiAodGhpcy5vblVwZGF0ZVByZXZpZXcpIHtcbiAgICAgIHRoaXMub25VcGRhdGVQcmV2aWV3KHtcbiAgICAgICAgY29kZUJsb2NrOiB0aGlzLmNvZGVCbG9jayxcbiAgICAgICAgcHJldmlld0VsOiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLnByZXZpZXdFbCksXG4gICAgICAgIHZhbHVlczogdGhpcy52YWx1ZXNcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEZvcm1hdHMgYSBjb2RlIGJsb2NrIGZyb20gaXRzIGZpZWxkcyBhbmQgdGhlaXIgdmFsdWVzLlxuICpcbiAqIEVhY2ggZmllbGQgaG9sZGluZyBhIHZhbHVlIG90aGVyIHRoYW4gaXRzIGRlZmF1bHQsIG9yIG1hcmtlZCB7QGxpbmsgQ29kZUJsb2NrQnVpbGRlckZpZWxkQmFzZS5pc1JlcXVpcmVkfSwgd3JpdGVzIG9uZVxuICogbGluZSwgaW4gdGhlIG9yZGVyIG9mIHRoZSBmaWVsZHM7IGFuIGVtcHR5IHZhbHVlIHdyaXRlcyBub3RoaW5nLiBUaGUgZmVuY2UgaXMgb25lIGJhY2t0aWNrIGxvbmdlciB0aGFuIHRoZSBsb25nZXN0XG4gKiBiYWNrdGljayBydW4gaW4gdGhlIGxpbmVzLCBhbmQgbmV2ZXIgc2hvcnRlciB0aGFuIHRocmVlLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZmllbGRzLCB0aGUgbGFuZ3VhZ2UgYW5kIHRoZSB2YWx1ZXMuXG4gKiBAcmV0dXJucyBUaGUgY29kZSBibG9jaywgd2l0aG91dCBhIHRyYWlsaW5nIG5ld2xpbmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRDb2RlQmxvY2socGFyYW1zOiBGb3JtYXRDb2RlQmxvY2tQYXJhbXMpOiBzdHJpbmcge1xuICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChjb25zdCBmaWVsZCBvZiBmbGF0dGVuRmllbGRzKHBhcmFtcy5maWVsZHMpKSB7XG4gICAgY29uc3QgdmFsdWUgPSBwYXJhbXMudmFsdWVzLmdldChmaWVsZC5rZXkpID8/IGZpZWxkLmRlZmF1bHRWYWx1ZTtcbiAgICBjb25zdCBmb3JtYXR0ZWRWYWx1ZSA9IGZvcm1hdFZhbHVlKGZpZWxkLCB2YWx1ZSk7XG4gICAgaWYgKGZvcm1hdHRlZFZhbHVlID09PSAnJykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKCFmaWVsZC5pc1JlcXVpcmVkICYmIGlzU2FtZVZhbHVlKHZhbHVlLCBmaWVsZC5kZWZhdWx0VmFsdWUpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBsaW5lcy5wdXNoKGZpZWxkLnNob3VsZE9taXRLZXkgPyBmb3JtYXR0ZWRWYWx1ZSA6IGAke2ZpZWxkLmtleX06ICR7Zm9ybWF0dGVkVmFsdWV9YCk7XG4gIH1cblxuICBjb25zdCBib2R5ID0gbGluZXMuam9pbignXFxuJyk7XG4gIGNvbnN0IGxvbmdlc3RCYWNrdGlja1J1biA9IE1hdGgubWF4KDAsIC4uLkFycmF5LmZyb20oYm9keS5tYXRjaEFsbCgvYCsvZyksIChtYXRjaCkgPT4gbWF0Y2hbMF0ubGVuZ3RoKSk7XG4gIGNvbnN0IGZlbmNlID0gJ2AnLnJlcGVhdChNYXRoLm1heChNSU5fRkVOQ0VfTEVOR1RILCBsb25nZXN0QmFja3RpY2tSdW4gKyAxKSk7XG4gIHJldHVybiBsaW5lcy5sZW5ndGggPT09IDAgPyBgJHtmZW5jZX0ke3BhcmFtcy5sYW5ndWFnZX1cXG4ke2ZlbmNlfWAgOiBgJHtmZW5jZX0ke3BhcmFtcy5sYW5ndWFnZX1cXG4ke2JvZHl9XFxuJHtmZW5jZX1gO1xufVxuXG4vKipcbiAqIE9wZW5zIHRoZSBjb2RlIGJsb2NrIGJ1aWxkZXIgbW9kYWwuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBmaWVsZHMgb2YgdGhlIGNvZGUgYmxvY2sgYW5kIGhvdyB0byBwcmVzZW50IHRoZW0uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGNvZGUgYmxvY2sgd2hlbiB0aGUgdXNlciBpbnNlcnRlZCBpdCBpbnRvIHRoZSBub3RlLCBvciB3aXRoIGBudWxsYFxuICogd2hlbiB0aGUgbW9kYWwgd2FzIGNsb3NlZCBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaG93Q29kZUJsb2NrQnVpbGRlcihwYXJhbXM6IFNob3dDb2RlQmxvY2tCdWlsZGVyUGFyYW1zKTogUHJvbWlzZTxudWxsIHwgc3RyaW5nPiB7XG4gIHJldHVybiBhd2FpdCBzaG93TW9kYWw8bnVsbCB8IHN0cmluZz4oKHByb21pc2VSZXNvbHZlKSA9PlxuICAgIG5ldyBDb2RlQmxvY2tCdWlsZGVyTW9kYWwoe1xuICAgICAgLi4ucGFyYW1zLFxuICAgICAgcHJvbWlzZVJlc29sdmVcbiAgICB9KVxuICApO1xufVxuXG5mdW5jdGlvbiBkb2VzTWF0Y2hQYXR0ZXJuKHBhdHRlcm46IFJlZ0V4cCwgdmFsdWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBwYXR0ZXJuLmxhc3RJbmRleCA9IDA7XG4gIHJldHVybiBwYXR0ZXJuLnRlc3QodmFsdWUpO1xufVxuXG5mdW5jdGlvbiBmbGF0dGVuRmllbGRzKGlucHV0czogcmVhZG9ubHkgQ29kZUJsb2NrQnVpbGRlcklucHV0W10pOiBDb2RlQmxvY2tCdWlsZGVyRmllbGRbXSB7XG4gIHJldHVybiBpbnB1dHMuZmxhdE1hcCgoaW5wdXQpID0+IGlucHV0LnR5cGUgPT09ICdncm91cCcgPyBpbnB1dC5maWVsZHMgOiBbaW5wdXRdKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VmFsdWUoZmllbGQ6IENvZGVCbG9ja0J1aWxkZXJGaWVsZCwgdmFsdWU6IENvZGVCbG9ja0J1aWxkZXJWYWx1ZSk6IHN0cmluZyB7XG4gIGNvbnN0IHNlcGFyYXRvciA9IGZpZWxkLnR5cGUgPT09ICdtdWx0aXBsZURyb3Bkb3duJyA/IGZpZWxkLnNlcGFyYXRvciA/PyBERUZBVUxUX1NFUEFSQVRPUiA6IERFRkFVTFRfU0VQQVJBVE9SO1xuICByZXR1cm4gaXNTdHJpbmdBcnJheSh2YWx1ZSkgPyB2YWx1ZS5qb2luKHNlcGFyYXRvcikgOiBTdHJpbmcodmFsdWUpO1xufVxuXG5mdW5jdGlvbiBpc1NhbWVWYWx1ZShhOiBDb2RlQmxvY2tCdWlsZGVyVmFsdWUsIGI6IENvZGVCbG9ja0J1aWxkZXJWYWx1ZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gaXNTdHJpbmdBcnJheShhKSAmJiBpc1N0cmluZ0FycmF5KGIpID8gYS5sZW5ndGggPT09IGIubGVuZ3RoICYmIGEuZXZlcnkoKGl0ZW0sIGluZGV4KSA9PiBpdGVtID09PSBiW2luZGV4XSkgOiBhID09PSBiO1xufVxuXG5mdW5jdGlvbiBpc1N0cmluZ0FycmF5KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgcmVhZG9ubHkgc3RyaW5nW10ge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIHRvUmVjb3JkKG9wdGlvbnM6IENvZGVCbG9ja0J1aWxkZXJPcHRpb25zKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIHJldHVybiBpc1N0cmluZ0FycmF5KG9wdGlvbnMpID8gT2JqZWN0LmZyb21FbnRyaWVzKG9wdGlvbnMubWFwKChvcHRpb24pID0+IFtvcHRpb24sIG9wdGlvbl0pKSA6IHsgLi4ub3B0aW9ucyB9O1xufVxuXG5mdW5jdGlvbiB1cGRhdGVHcm91cEljb24oZ3JvdXBTdGF0ZTogR3JvdXBTdGF0ZSk6IHZvaWQge1xuICBncm91cFN0YXRlLmJ1dHRvbi5zZXRJY29uKGdyb3VwU3RhdGUuZ3JvdXBFbC5oYXNDbGFzcyhDc3NDbGFzcy5Jc0NvbGxhcHNlZCkgPyAnbHVjaWRlLWNoZXZyb24tZG93bicgOiAnbHVjaWRlLWNoZXZyb24tdXAnKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBc0NBLG1CQUFrQztBQUNsQyx5QkFHTztBQUNQLHNCQUtPO0FBT1AsdUJBQXlCO0FBQ3pCLGtCQUFrQjtBQUNsQix5Q0FBMEM7QUFDMUMsbUJBR087QUFrVVAsTUFBTSxvQkFBb0I7QUFDMUIsTUFBTSxtQkFBbUI7QUFDekIsTUFBTSxtQkFBbUI7QUFTekIsTUFBTSw4QkFBOEIsdUJBQXlCO0FBQUEsRUFDbkQsWUFBWTtBQUFBLEVBQ0g7QUFBQSxFQUNBO0FBQUEsRUFDQSxjQUE0QixDQUFDO0FBQUEsRUFDdEMsb0JBQW1DO0FBQUEsRUFDMUI7QUFBQSxFQUNBO0FBQUEsRUFDVCxrQkFBNEM7QUFBQSxFQUM1QyxZQUFnQztBQUFBLEVBQ3ZCO0FBQUEsRUFDQSxTQUFTLG9CQUFJLElBQW1DO0FBQUEsRUFFMUQsWUFBWSxRQUFnRDtBQUNqRSxVQUFNLE1BQU07QUFDWixTQUFLLGNBQWMsMEJBQVMscUJBQXFCO0FBQ2pELFNBQUssU0FB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
|