@mnaoumov/obsidian-lib 10.4.0 → 10.5.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/incremental-parse-state-field/package.json +6 -0
- package/codemirror/markdown-editor-views/package.json +6 -0
- package/codemirror/range-set/package.json +6 -0
- package/command-handlers/open-bug-report-command-handler/package.json +6 -0
- package/components/embeddable-markdown-editor-component/package.json +6 -0
- package/components/reconfigurable-editor-extension-component/package.json +6 -0
- package/dist/lib/cjs/__merged.cjs +46 -1
- package/dist/lib/cjs/__merged.d.cts +11 -0
- package/dist/lib/cjs/attachment-path.cjs +3 -2
- package/dist/lib/cjs/bug-report.cjs +241 -0
- package/dist/lib/cjs/bug-report.d.cts +161 -0
- package/dist/lib/cjs/codemirror/incremental-parse-state-field.cjs +162 -0
- package/dist/lib/cjs/codemirror/incremental-parse-state-field.d.cts +37 -0
- package/dist/lib/cjs/codemirror/index.cjs +10 -1
- package/dist/lib/cjs/codemirror/index.d.cts +3 -0
- package/dist/lib/cjs/codemirror/markdown-editor-views.cjs +142 -0
- package/dist/lib/cjs/codemirror/markdown-editor-views.d.cts +34 -0
- package/dist/lib/cjs/codemirror/range-set.cjs +106 -0
- package/dist/lib/cjs/codemirror/range-set.d.cts +35 -0
- package/dist/lib/cjs/command-handlers/index.cjs +4 -1
- package/dist/lib/cjs/command-handlers/index.d.cts +1 -0
- package/dist/lib/cjs/command-handlers/open-bug-report-command-handler.cjs +139 -0
- package/dist/lib/cjs/command-handlers/open-bug-report-command-handler.d.cts +53 -0
- package/dist/lib/cjs/command-handlers/open-settings-command-handler.cjs +6 -3
- package/dist/lib/cjs/components/embeddable-markdown-editor-component.cjs +374 -0
- package/dist/lib/cjs/components/embeddable-markdown-editor-component.d.cts +221 -0
- package/dist/lib/cjs/components/index.cjs +7 -1
- package/dist/lib/cjs/components/index.d.cts +2 -0
- package/dist/lib/cjs/components/plugin-gate-component.cjs +6 -3
- package/dist/lib/cjs/components/reconfigurable-editor-extension-component.cjs +200 -0
- package/dist/lib/cjs/components/reconfigurable-editor-extension-component.d.cts +96 -0
- package/dist/lib/cjs/data-stores/local-data-store.cjs +2 -3
- package/dist/lib/cjs/desktop-operating-system.cjs +101 -0
- package/dist/lib/cjs/desktop-operating-system.d.cts +15 -0
- package/dist/lib/cjs/generated-during-build.cjs +1 -1
- package/dist/lib/cjs/index.cjs +16 -1
- package/dist/lib/cjs/index.d.cts +5 -0
- package/dist/lib/cjs/menu.cjs +118 -0
- package/dist/lib/cjs/menu.d.cts +65 -0
- package/dist/lib/cjs/mobile-app-info.cjs +167 -0
- package/dist/lib/cjs/mobile-app-info.d.cts +32 -0
- package/dist/lib/cjs/obsidian-settings.cjs +2 -2
- package/dist/lib/cjs/settings-modal.cjs +103 -0
- package/dist/lib/cjs/settings-modal.d.cts +33 -0
- package/dist/lib/esm/__merged.d.mts +11 -0
- package/dist/lib/esm/__merged.mjs +39 -1
- package/dist/lib/esm/attachment-path.mjs +3 -2
- package/dist/lib/esm/bug-report.d.mts +161 -0
- package/dist/lib/esm/bug-report.mjs +141 -0
- package/dist/lib/esm/codemirror/incremental-parse-state-field.d.mts +37 -0
- package/dist/lib/esm/codemirror/incremental-parse-state-field.mjs +74 -0
- package/dist/lib/esm/codemirror/index.d.mts +3 -0
- package/dist/lib/esm/codemirror/index.mjs +7 -1
- package/dist/lib/esm/codemirror/markdown-editor-views.d.mts +34 -0
- package/dist/lib/esm/codemirror/markdown-editor-views.mjs +53 -0
- package/dist/lib/esm/codemirror/range-set.d.mts +35 -0
- package/dist/lib/esm/codemirror/range-set.mjs +18 -0
- package/dist/lib/esm/command-handlers/index.d.mts +1 -0
- package/dist/lib/esm/command-handlers/index.mjs +3 -1
- package/dist/lib/esm/command-handlers/open-bug-report-command-handler.d.mts +53 -0
- package/dist/lib/esm/command-handlers/open-bug-report-command-handler.mjs +51 -0
- package/dist/lib/esm/command-handlers/open-settings-command-handler.mjs +6 -3
- package/dist/lib/esm/components/embeddable-markdown-editor-component.d.mts +221 -0
- package/dist/lib/esm/components/embeddable-markdown-editor-component.mjs +293 -0
- package/dist/lib/esm/components/index.d.mts +2 -0
- package/dist/lib/esm/components/index.mjs +5 -1
- package/dist/lib/esm/components/plugin-gate-component.mjs +6 -3
- package/dist/lib/esm/components/reconfigurable-editor-extension-component.d.mts +96 -0
- package/dist/lib/esm/components/reconfigurable-editor-extension-component.mjs +112 -0
- package/dist/lib/esm/data-stores/local-data-store.mjs +2 -3
- package/dist/lib/esm/desktop-operating-system.d.mts +15 -0
- package/dist/lib/esm/desktop-operating-system.mjs +16 -0
- package/dist/lib/esm/generated-during-build.mjs +1 -1
- package/dist/lib/esm/index.d.mts +5 -0
- package/dist/lib/esm/index.mjs +11 -1
- package/dist/lib/esm/menu.d.mts +65 -0
- package/dist/lib/esm/menu.mjs +30 -0
- package/dist/lib/esm/mobile-app-info.d.mts +32 -0
- package/dist/lib/esm/mobile-app-info.mjs +84 -0
- package/dist/lib/esm/obsidian-settings.mjs +6 -3
- package/dist/lib/esm/settings-modal.d.mts +33 -0
- package/dist/lib/esm/settings-modal.mjs +15 -0
- package/package.json +8 -6
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/// <reference path="../library-references.d.mts" />
|
|
2
|
+
/// <reference lib="dom" />
|
|
3
|
+
/**
|
|
4
|
+
* @file
|
|
5
|
+
*
|
|
6
|
+
* Contains class {@link EmbeddableMarkdownEditorComponent}: a full Obsidian Markdown editor (Live Preview, editor
|
|
7
|
+
* commands, hotkeys) mounted in any element and owned as a component.
|
|
8
|
+
*
|
|
9
|
+
* Obsidian does not export its editor class, so the component borrows it from a throwaway Markdown embed: an editable
|
|
10
|
+
* embed builds an iframed editor whose grandparent prototype is the scrollable Markdown editor every embed and table
|
|
11
|
+
* cell editor uses. The probe opens no leaf and fires no workspace event (`embeddable-markdown-editor-component
|
|
12
|
+
* .obsidian.integration.test.ts` measures that), and it runs once per copy of this library, on first use rather than at
|
|
13
|
+
* module load. The class is cached per copy and never in the shared-state bag, because a constructor is not plain data.
|
|
14
|
+
*
|
|
15
|
+
* Adapted from the "Embeddable CM Markdown Editor" gist
|
|
16
|
+
* (https://gist.github.com/Fevol/caa478ce303e69eabede7b12b2323838), itself a rework of the `Kanban` plugin's
|
|
17
|
+
* `src/components/Editor/MarkdownEditor.tsx`, under the MIT license below.
|
|
18
|
+
*
|
|
19
|
+
* Copyright 2024 Matthew Meyers, Fevol
|
|
20
|
+
*
|
|
21
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
22
|
+
* documentation files (the “Software”), to deal in the Software without restriction, including without limitation the
|
|
23
|
+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
|
24
|
+
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
25
|
+
*
|
|
26
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
|
27
|
+
* Software.
|
|
28
|
+
*
|
|
29
|
+
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
30
|
+
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
31
|
+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
32
|
+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
33
|
+
*/
|
|
34
|
+
import type { Extension } from '@codemirror/state';
|
|
35
|
+
import type { ViewUpdate } from '@codemirror/view';
|
|
36
|
+
import type { App, Editor } from 'obsidian';
|
|
37
|
+
import { EditorView } from '@codemirror/view';
|
|
38
|
+
import { ComponentEx } from './component-ex.mjs';
|
|
39
|
+
/**
|
|
40
|
+
* The parameters of the {@link EmbeddableMarkdownEditorComponent} constructor.
|
|
41
|
+
*/
|
|
42
|
+
export interface EmbeddableMarkdownEditorComponentConstructorParams {
|
|
43
|
+
/**
|
|
44
|
+
* The Obsidian app instance.
|
|
45
|
+
*/
|
|
46
|
+
readonly app: App;
|
|
47
|
+
/**
|
|
48
|
+
* A CSS class added to the editor element.
|
|
49
|
+
*/
|
|
50
|
+
readonly cls?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The element the editor is mounted in. The editor appends its own element to it and removes only that element when
|
|
53
|
+
* it unloads.
|
|
54
|
+
*/
|
|
55
|
+
readonly containerEl: HTMLElement;
|
|
56
|
+
/**
|
|
57
|
+
* The initial selection, as document offsets. The cursor starts at the beginning of the document otherwise.
|
|
58
|
+
*/
|
|
59
|
+
readonly cursorLocation?: EmbeddableMarkdownEditorComponentSelection;
|
|
60
|
+
/**
|
|
61
|
+
* Called when the editor loses focus, while the component is still loaded.
|
|
62
|
+
*/
|
|
63
|
+
readonly onBlur?: (component: EmbeddableMarkdownEditorComponent) => void;
|
|
64
|
+
/**
|
|
65
|
+
* Called after every change to the document.
|
|
66
|
+
*/
|
|
67
|
+
readonly onChange?: (update: ViewUpdate, component: EmbeddableMarkdownEditorComponent) => void;
|
|
68
|
+
/**
|
|
69
|
+
* Called on `Enter`, `Shift+Enter`, `Mod+Enter` and `Mod+Shift+Enter`.
|
|
70
|
+
*
|
|
71
|
+
* When given, `Mod+Enter` no longer runs the Obsidian hotkey bound to it (by default, opening the link under the
|
|
72
|
+
* cursor in a new tab) while the editor has the focus, so a form can use it to submit.
|
|
73
|
+
*
|
|
74
|
+
* @returns `true` when the key was handled, which stops the editor inserting a line break; `false` otherwise.
|
|
75
|
+
*/
|
|
76
|
+
readonly onEnter?: (params: EmbeddableMarkdownEditorComponentEnterParams) => boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Called on `Escape`. When given, the key goes no further.
|
|
79
|
+
*/
|
|
80
|
+
readonly onEscape?: (component: EmbeddableMarkdownEditorComponent) => void;
|
|
81
|
+
/**
|
|
82
|
+
* Called on a paste into the editor, before the editor handles it.
|
|
83
|
+
*/
|
|
84
|
+
readonly onPaste?: ($event: ClipboardEvent, component: EmbeddableMarkdownEditorComponent) => void;
|
|
85
|
+
/**
|
|
86
|
+
* The text shown while the document is empty.
|
|
87
|
+
*/
|
|
88
|
+
readonly placeholder?: string;
|
|
89
|
+
/**
|
|
90
|
+
* The initial document.
|
|
91
|
+
*/
|
|
92
|
+
readonly value?: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The parameters of {@link EmbeddableMarkdownEditorComponentConstructorParams.onEnter}.
|
|
96
|
+
*/
|
|
97
|
+
export interface EmbeddableMarkdownEditorComponentEnterParams {
|
|
98
|
+
/**
|
|
99
|
+
* The editor component the key was pressed in.
|
|
100
|
+
*/
|
|
101
|
+
readonly component: EmbeddableMarkdownEditorComponent;
|
|
102
|
+
/**
|
|
103
|
+
* Whether the platform modifier (`Ctrl`, or `Cmd` on macOS) was held.
|
|
104
|
+
*/
|
|
105
|
+
readonly isModifierPressed: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Whether `Shift` was held.
|
|
108
|
+
*/
|
|
109
|
+
readonly isShiftPressed: boolean;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* A selection in an {@link EmbeddableMarkdownEditorComponent}, as document offsets.
|
|
113
|
+
*/
|
|
114
|
+
export interface EmbeddableMarkdownEditorComponentSelection {
|
|
115
|
+
/**
|
|
116
|
+
* The offset the selection starts from.
|
|
117
|
+
*/
|
|
118
|
+
readonly anchor: number;
|
|
119
|
+
/**
|
|
120
|
+
* The offset the selection extends to, where the cursor is.
|
|
121
|
+
*/
|
|
122
|
+
readonly head: number;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* A full Obsidian Markdown editor mounted in any element: Live Preview, editor commands, hotkeys and the editor
|
|
126
|
+
* suggesters all work in it as they do in a note.
|
|
127
|
+
*
|
|
128
|
+
* Add it as a child of the component that owns its element; unloading it destroys the editor and removes the editor's
|
|
129
|
+
* element. It works on desktop and mobile.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* const editorComponent = this.addChild(new EmbeddableMarkdownEditorComponent({
|
|
134
|
+
* app: this.app,
|
|
135
|
+
* containerEl,
|
|
136
|
+
* onEnter: ({ component, isModifierPressed }) => {
|
|
137
|
+
* if (!isModifierPressed) {
|
|
138
|
+
* return false;
|
|
139
|
+
* }
|
|
140
|
+
* save(component.value);
|
|
141
|
+
* return true;
|
|
142
|
+
* },
|
|
143
|
+
* value: 'Initial text'
|
|
144
|
+
* }));
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export declare class EmbeddableMarkdownEditorComponent extends ComponentEx {
|
|
148
|
+
/**
|
|
149
|
+
* The Obsidian editor, as in a note.
|
|
150
|
+
*
|
|
151
|
+
* @returns The editor.
|
|
152
|
+
*/
|
|
153
|
+
get editor(): Editor;
|
|
154
|
+
/**
|
|
155
|
+
* The CodeMirror view behind the editor.
|
|
156
|
+
*
|
|
157
|
+
* @returns The CodeMirror view.
|
|
158
|
+
*/
|
|
159
|
+
get editorView(): EditorView;
|
|
160
|
+
/**
|
|
161
|
+
* The current document.
|
|
162
|
+
*
|
|
163
|
+
* @returns The document text.
|
|
164
|
+
*/
|
|
165
|
+
get value(): string;
|
|
166
|
+
/**
|
|
167
|
+
* The Obsidian app instance.
|
|
168
|
+
*/
|
|
169
|
+
protected readonly app: App;
|
|
170
|
+
/**
|
|
171
|
+
* The element the editor is mounted in.
|
|
172
|
+
*/
|
|
173
|
+
protected readonly containerEl: HTMLElement;
|
|
174
|
+
private readonly cls;
|
|
175
|
+
private readonly cursorLocation;
|
|
176
|
+
private readonly initialValue;
|
|
177
|
+
private readonly keymapScope;
|
|
178
|
+
private readonly onBlur;
|
|
179
|
+
private readonly onChange;
|
|
180
|
+
private readonly onEnter;
|
|
181
|
+
private readonly onEscape;
|
|
182
|
+
private readonly onPaste;
|
|
183
|
+
private readonly owner;
|
|
184
|
+
private readonly placeholderText;
|
|
185
|
+
private scrollableEditor;
|
|
186
|
+
/**
|
|
187
|
+
* Creates the component. The editor is built when the component loads.
|
|
188
|
+
*
|
|
189
|
+
* @param params - The parameters.
|
|
190
|
+
*/
|
|
191
|
+
constructor(params: EmbeddableMarkdownEditorComponentConstructorParams);
|
|
192
|
+
/**
|
|
193
|
+
* Focuses the editor.
|
|
194
|
+
*/
|
|
195
|
+
focus(): void;
|
|
196
|
+
/**
|
|
197
|
+
* Builds the editor and mounts it in the container.
|
|
198
|
+
*/
|
|
199
|
+
onload(): void;
|
|
200
|
+
/**
|
|
201
|
+
* Replaces the document.
|
|
202
|
+
*
|
|
203
|
+
* @param value - The new document.
|
|
204
|
+
*/
|
|
205
|
+
setValue(value: string): void;
|
|
206
|
+
/**
|
|
207
|
+
* Builds the editor's own extensions: the placeholder, the focus and paste handlers, and the key handlers.
|
|
208
|
+
*
|
|
209
|
+
* @returns The extensions.
|
|
210
|
+
*/
|
|
211
|
+
protected buildExtensions(): Extension[];
|
|
212
|
+
/**
|
|
213
|
+
* Called after every update of the editor, with whether the document changed.
|
|
214
|
+
*
|
|
215
|
+
* @param update - The CodeMirror update.
|
|
216
|
+
* @param isChanged - Whether the document changed.
|
|
217
|
+
*/
|
|
218
|
+
protected handleUpdate(update: ViewUpdate, isChanged: boolean): void;
|
|
219
|
+
private getScrollableEditor;
|
|
220
|
+
private isEnterHandled;
|
|
221
|
+
}
|
|
@@ -0,0 +1,293 @@
|
|
|
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
|
+
|
|
33
|
+
import {
|
|
34
|
+
EditorSelection,
|
|
35
|
+
Prec
|
|
36
|
+
} from "@codemirror/state";
|
|
37
|
+
import {
|
|
38
|
+
EditorView,
|
|
39
|
+
keymap,
|
|
40
|
+
placeholder
|
|
41
|
+
} from "@codemirror/view";
|
|
42
|
+
import { noop } from "@mnaoumov/typescript-lib/function";
|
|
43
|
+
import { castTo } from "@mnaoumov/typescript-lib/object-utils";
|
|
44
|
+
import { ensureNonNullable } from "@mnaoumov/typescript-lib/type-guards";
|
|
45
|
+
import { Scope } from "obsidian";
|
|
46
|
+
import { ComponentEx } from "./component-ex.mjs";
|
|
47
|
+
import { MonkeyAroundComponent } from "./monkey-around-component.mjs";
|
|
48
|
+
const scrollableMarkdownEditorConstructorCache = { value: null };
|
|
49
|
+
class EmbeddableMarkdownEditorComponent extends ComponentEx {
|
|
50
|
+
/**
|
|
51
|
+
* The Obsidian editor, as in a note.
|
|
52
|
+
*
|
|
53
|
+
* @returns The editor.
|
|
54
|
+
*/
|
|
55
|
+
get editor() {
|
|
56
|
+
return ensureNonNullable(this.getScrollableEditor().editor);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The CodeMirror view behind the editor.
|
|
60
|
+
*
|
|
61
|
+
* @returns The CodeMirror view.
|
|
62
|
+
*/
|
|
63
|
+
get editorView() {
|
|
64
|
+
return this.getScrollableEditor().cm;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The current document.
|
|
68
|
+
*
|
|
69
|
+
* @returns The document text.
|
|
70
|
+
*/
|
|
71
|
+
get value() {
|
|
72
|
+
return this.getScrollableEditor().cm.state.doc.toString();
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The Obsidian app instance.
|
|
76
|
+
*/
|
|
77
|
+
app;
|
|
78
|
+
/**
|
|
79
|
+
* The element the editor is mounted in.
|
|
80
|
+
*/
|
|
81
|
+
containerEl;
|
|
82
|
+
cls;
|
|
83
|
+
cursorLocation;
|
|
84
|
+
initialValue;
|
|
85
|
+
keymapScope;
|
|
86
|
+
onBlur;
|
|
87
|
+
onChange;
|
|
88
|
+
onEnter;
|
|
89
|
+
onEscape;
|
|
90
|
+
onPaste;
|
|
91
|
+
owner;
|
|
92
|
+
placeholderText;
|
|
93
|
+
scrollableEditor = null;
|
|
94
|
+
/**
|
|
95
|
+
* Creates the component. The editor is built when the component loads.
|
|
96
|
+
*
|
|
97
|
+
* @param params - The parameters.
|
|
98
|
+
*/
|
|
99
|
+
constructor(params) {
|
|
100
|
+
super();
|
|
101
|
+
this.app = params.app;
|
|
102
|
+
this.containerEl = params.containerEl;
|
|
103
|
+
this.cls = params.cls ?? "";
|
|
104
|
+
this.cursorLocation = params.cursorLocation ?? null;
|
|
105
|
+
this.initialValue = params.value ?? "";
|
|
106
|
+
this.onBlur = params.onBlur ?? null;
|
|
107
|
+
this.onChange = params.onChange ?? null;
|
|
108
|
+
this.onEnter = params.onEnter ?? null;
|
|
109
|
+
this.onEscape = params.onEscape ?? null;
|
|
110
|
+
this.onPaste = params.onPaste ?? null;
|
|
111
|
+
this.placeholderText = params.placeholder ?? "";
|
|
112
|
+
this.keymapScope = new Scope(params.app.scope);
|
|
113
|
+
this.owner = {
|
|
114
|
+
app: params.app,
|
|
115
|
+
editMode: null,
|
|
116
|
+
file: null,
|
|
117
|
+
getMode: () => "source",
|
|
118
|
+
hoverPopover: null,
|
|
119
|
+
syncScroll: noop
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Focuses the editor.
|
|
124
|
+
*/
|
|
125
|
+
focus() {
|
|
126
|
+
this.getScrollableEditor().focus();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Builds the editor and mounts it in the container.
|
|
130
|
+
*/
|
|
131
|
+
onload() {
|
|
132
|
+
super.onload();
|
|
133
|
+
const EditorConstructor = createEditorClass(getScrollableMarkdownEditorConstructor(this.app));
|
|
134
|
+
const scrollableEditor = new EditorConstructor(this.app, this.containerEl, this.owner, {
|
|
135
|
+
buildExtensions: () => this.buildExtensions(),
|
|
136
|
+
handleUpdate: (update, isChanged) => {
|
|
137
|
+
this.handleUpdate(update, isChanged);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
this.scrollableEditor = scrollableEditor;
|
|
141
|
+
this.owner.editMode = scrollableEditor;
|
|
142
|
+
this.owner.editor = ensureNonNullable(scrollableEditor.editor);
|
|
143
|
+
this.addChild(scrollableEditor);
|
|
144
|
+
if (this.onEnter) {
|
|
145
|
+
const submitHotkeyHandler = this.keymapScope.register(["Mod"], "Enter", () => true);
|
|
146
|
+
this.register(() => {
|
|
147
|
+
this.keymapScope.unregister(submitHotkeyHandler);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if (this.cls) {
|
|
151
|
+
scrollableEditor.editorEl.addClass(this.cls);
|
|
152
|
+
}
|
|
153
|
+
scrollableEditor.set(this.initialValue, false);
|
|
154
|
+
if (this.cursorLocation) {
|
|
155
|
+
scrollableEditor.cm.dispatch({
|
|
156
|
+
selection: EditorSelection.range(this.cursorLocation.anchor, this.cursorLocation.head)
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
const focusGuardPatchComponent = this.addChild(new MonkeyAroundComponent());
|
|
160
|
+
focusGuardPatchComponent.registerMethodPatch({
|
|
161
|
+
$object: this.app.workspace,
|
|
162
|
+
methodName: "setActiveLeaf",
|
|
163
|
+
patchHandler: ({ fallback }) => {
|
|
164
|
+
if (scrollableEditor.activeCM.hasFocus) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
fallback();
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
this.register(() => {
|
|
171
|
+
this.app.keymap.popScope(this.keymapScope);
|
|
172
|
+
if (this.app.workspace.activeEditor === this.owner) {
|
|
173
|
+
this.app.workspace.activeEditor = null;
|
|
174
|
+
}
|
|
175
|
+
scrollableEditor.destroy();
|
|
176
|
+
scrollableEditor.editorEl.remove();
|
|
177
|
+
this.owner.editMode = null;
|
|
178
|
+
delete this.owner.editor;
|
|
179
|
+
this.scrollableEditor = null;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Replaces the document.
|
|
184
|
+
*
|
|
185
|
+
* @param value - The new document.
|
|
186
|
+
*/
|
|
187
|
+
setValue(value) {
|
|
188
|
+
this.getScrollableEditor().set(value, false);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Builds the editor's own extensions: the placeholder, the focus and paste handlers, and the key handlers.
|
|
192
|
+
*
|
|
193
|
+
* @returns The extensions.
|
|
194
|
+
*/
|
|
195
|
+
buildExtensions() {
|
|
196
|
+
const extensions = [
|
|
197
|
+
EditorView.domEventHandlers({
|
|
198
|
+
blur: () => {
|
|
199
|
+
this.app.keymap.popScope(this.keymapScope);
|
|
200
|
+
if (this._loaded) {
|
|
201
|
+
this.onBlur?.(this);
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
focus: () => {
|
|
205
|
+
this.app.keymap.pushScope(this.keymapScope);
|
|
206
|
+
},
|
|
207
|
+
paste: ($event) => {
|
|
208
|
+
this.onPaste?.($event, this);
|
|
209
|
+
}
|
|
210
|
+
}),
|
|
211
|
+
Prec.highest(keymap.of([
|
|
212
|
+
{
|
|
213
|
+
key: "Enter",
|
|
214
|
+
run: () => this.isEnterHandled(false, false),
|
|
215
|
+
shift: () => this.isEnterHandled(false, true)
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
key: "Mod-Enter",
|
|
219
|
+
run: () => this.isEnterHandled(true, false),
|
|
220
|
+
shift: () => this.isEnterHandled(true, true)
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
key: "Escape",
|
|
224
|
+
preventDefault: true,
|
|
225
|
+
run: () => {
|
|
226
|
+
if (!this.onEscape) {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
this.onEscape(this);
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
]))
|
|
234
|
+
];
|
|
235
|
+
if (this.placeholderText) {
|
|
236
|
+
extensions.push(placeholder(this.placeholderText));
|
|
237
|
+
}
|
|
238
|
+
return extensions;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Called after every update of the editor, with whether the document changed.
|
|
242
|
+
*
|
|
243
|
+
* @param update - The CodeMirror update.
|
|
244
|
+
* @param isChanged - Whether the document changed.
|
|
245
|
+
*/
|
|
246
|
+
handleUpdate(update, isChanged) {
|
|
247
|
+
if (isChanged) {
|
|
248
|
+
this.onChange?.(update, this);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
getScrollableEditor() {
|
|
252
|
+
return ensureNonNullable(this.scrollableEditor, "The editor is built when the component loads.");
|
|
253
|
+
}
|
|
254
|
+
isEnterHandled(isModifierPressed, isShiftPressed) {
|
|
255
|
+
return this.onEnter?.({ component: this, isModifierPressed, isShiftPressed }) ?? false;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function createEditorClass(BaseConstructor) {
|
|
259
|
+
return class EmbeddedScrollableMarkdownEditor extends BaseConstructor {
|
|
260
|
+
constructor(app, containerEl, owner, hooks) {
|
|
261
|
+
super(app, containerEl, owner);
|
|
262
|
+
this.hooks = hooks;
|
|
263
|
+
}
|
|
264
|
+
hooks;
|
|
265
|
+
buildLocalExtensions() {
|
|
266
|
+
return [...super.buildLocalExtensions(), ...this.hooks.buildExtensions()];
|
|
267
|
+
}
|
|
268
|
+
onUpdate(update, isChanged) {
|
|
269
|
+
super.onUpdate(update, isChanged);
|
|
270
|
+
this.hooks.handleUpdate(update, isChanged);
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function getScrollableMarkdownEditorConstructor(app) {
|
|
275
|
+
if (scrollableMarkdownEditorConstructorCache.value) {
|
|
276
|
+
return scrollableMarkdownEditorConstructorCache.value;
|
|
277
|
+
}
|
|
278
|
+
const widgetEditorView = castTo(app.embedRegistry.embedByExtension.md({ app, containerEl: createDiv() }, castTo(null), ""));
|
|
279
|
+
try {
|
|
280
|
+
widgetEditorView.editable = true;
|
|
281
|
+
widgetEditorView.showEditor();
|
|
282
|
+
const iframedEditor = ensureNonNullable(widgetEditorView.editMode, "The Markdown embed built no editor.");
|
|
283
|
+
const scrollableEditorPrototype = castTo(Object.getPrototypeOf(Object.getPrototypeOf(iframedEditor)));
|
|
284
|
+
scrollableMarkdownEditorConstructorCache.value = scrollableEditorPrototype.constructor;
|
|
285
|
+
return scrollableEditorPrototype.constructor;
|
|
286
|
+
} finally {
|
|
287
|
+
widgetEditorView.unload();
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
export {
|
|
291
|
+
EmbeddableMarkdownEditorComponent
|
|
292
|
+
};
|
|
293
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2VtYmVkZGFibGUtbWFya2Rvd24tZWRpdG9yLWNvbXBvbmVudC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmaWxlXG4gKlxuICogQ29udGFpbnMgY2xhc3Mge0BsaW5rIEVtYmVkZGFibGVNYXJrZG93bkVkaXRvckNvbXBvbmVudH06IGEgZnVsbCBPYnNpZGlhbiBNYXJrZG93biBlZGl0b3IgKExpdmUgUHJldmlldywgZWRpdG9yXG4gKiBjb21tYW5kcywgaG90a2V5cykgbW91bnRlZCBpbiBhbnkgZWxlbWVudCBhbmQgb3duZWQgYXMgYSBjb21wb25lbnQuXG4gKlxuICogT2JzaWRpYW4gZG9lcyBub3QgZXhwb3J0IGl0cyBlZGl0b3IgY2xhc3MsIHNvIHRoZSBjb21wb25lbnQgYm9ycm93cyBpdCBmcm9tIGEgdGhyb3dhd2F5IE1hcmtkb3duIGVtYmVkOiBhbiBlZGl0YWJsZVxuICogZW1iZWQgYnVpbGRzIGFuIGlmcmFtZWQgZWRpdG9yIHdob3NlIGdyYW5kcGFyZW50IHByb3RvdHlwZSBpcyB0aGUgc2Nyb2xsYWJsZSBNYXJrZG93biBlZGl0b3IgZXZlcnkgZW1iZWQgYW5kIHRhYmxlXG4gKiBjZWxsIGVkaXRvciB1c2VzLiBUaGUgcHJvYmUgb3BlbnMgbm8gbGVhZiBhbmQgZmlyZXMgbm8gd29ya3NwYWNlIGV2ZW50IChgZW1iZWRkYWJsZS1tYXJrZG93bi1lZGl0b3ItY29tcG9uZW50XG4gKiAub2JzaWRpYW4uaW50ZWdyYXRpb24udGVzdC50c2AgbWVhc3VyZXMgdGhhdCksIGFuZCBpdCBydW5zIG9uY2UgcGVyIGNvcHkgb2YgdGhpcyBsaWJyYXJ5LCBvbiBmaXJzdCB1c2UgcmF0aGVyIHRoYW4gYXRcbiAqIG1vZHVsZSBsb2FkLiBUaGUgY2xhc3MgaXMgY2FjaGVkIHBlciBjb3B5IGFuZCBuZXZlciBpbiB0aGUgc2hhcmVkLXN0YXRlIGJhZywgYmVjYXVzZSBhIGNvbnN0cnVjdG9yIGlzIG5vdCBwbGFpbiBkYXRhLlxuICpcbiAqIEFkYXB0ZWQgZnJvbSB0aGUgXCJFbWJlZGRhYmxlIENNIE1hcmtkb3duIEVkaXRvclwiIGdpc3RcbiAqIChodHRwczovL2dpc3QuZ2l0aHViLmNvbS9GZXZvbC9jYWE0NzhjZTMwM2U2OWVhYmVkZTdiMTJiMjMyMzgzOCksIGl0c2VsZiBhIHJld29yayBvZiB0aGUgYEthbmJhbmAgcGx1Z2luJ3NcbiAqIGBzcmMvY29tcG9uZW50cy9FZGl0b3IvTWFya2Rvd25FZGl0b3IudHN4YCwgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGJlbG93LlxuICpcbiAqIENvcHlyaWdodCAyMDI0IE1hdHRoZXcgTWV5ZXJzLCBGZXZvbFxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZFxuICogZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIOKAnFNvZnR3YXJl4oCdKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbiAqIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0b1xuICogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZVxuICogU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIOKAnEFTIElT4oCdLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1JcbiAqIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1JcbiAqIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG4vLyBjc3BlbGw6d29yZHMgRmV2b2wgLS0gVGhlIGdpc3QgYXV0aG9yJ3MgaGFuZGxlLCBhcyB0aGUgbGljZW5zZSBub3RpY2UgYWJvdmUgbmFtZXMgaXQuXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBCdWlsZHMgb24gT2JzaWRpYW4ncyB1bmV4cG9ydGVkIGVkaXRvciBjbGFzcywgd2hpY2ggb25seSBhIHJ1bm5pbmcgT2JzaWRpYW4gaGFzOyBjb3ZlcmVkIGJ5IGl0cyBpbnRlZ3JhdGlvbiB0ZXN0LiAqL1xuXG5pbXBvcnQgdHlwZSB7IEV4dGVuc2lvbiB9IGZyb20gJ0Bjb2RlbWlycm9yL3N0YXRlJztcbmltcG9ydCB0eXBlIHsgVmlld1VwZGF0ZSB9IGZyb20gJ0Bjb2RlbWlycm9yL3ZpZXcnO1xuaW1wb3J0IHR5cGUge1xuICBFeHRyYWN0Q29uc3RydWN0b3IsXG4gIE1hcmtkb3duU2Nyb2xsYWJsZUVkaXRWaWV3LFxuICBNYXJrZG93blNjcm9sbGFibGVFZGl0Vmlld093bmVyLFxuICBXaWRnZXRFZGl0b3JWaWV3XG59IGZyb20gJ0BvYnNpZGlhbi10eXBpbmdzL29ic2lkaWFuLXB1YmxpYy1sYXRlc3QnO1xuaW1wb3J0IHR5cGUge1xuICBBcHAsXG4gIEVkaXRvcixcbiAgVEZpbGVcbn0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQge1xuICBFZGl0b3JTZWxlY3Rpb24sXG4gIFByZWNcbn0gZnJvbSAnQGNvZGVtaXJyb3Ivc3RhdGUnO1xuaW1wb3J0IHtcbiAgRWRpdG9yVmlldyxcbiAga2V5bWFwLFxuICBwbGFjZWhvbGRlclxufSBmcm9tICdAY29kZW1pcnJvci92aWV3JztcbmltcG9ydCB7IG5vb3AgfSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWIvZnVuY3Rpb24nO1xuaW1wb3J0IHsgY2FzdFRvIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL29iamVjdC11dGlscyc7XG5pbXBvcnQgeyBlbnN1cmVOb25OdWxsYWJsZSB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWxpYi90eXBlLWd1YXJkcyc7XG5pbXBvcnQgeyBTY29wZSB9IGZyb20gJ29ic2lkaWFuJztcblxuaW1wb3J0IHsgQ29tcG9uZW50RXggfSBmcm9tICcuL2NvbXBvbmVudC1leC50cyc7XG5pbXBvcnQgeyBNb25rZXlBcm91bmRDb21wb25lbnQgfSBmcm9tICcuL21vbmtleS1hcm91bmQtY29tcG9uZW50LnRzJztcblxuLyoqXG4gKiBUaGUgcGFyYW1ldGVycyBvZiB0aGUge0BsaW5rIEVtYmVkZGFibGVNYXJrZG93bkVkaXRvckNvbXBvbmVudH0gY29uc3RydWN0b3IuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRW1iZWRkYWJsZU1hcmtkb3duRWRpdG9yQ29tcG9uZW50Q29uc3RydWN0b3JQYXJhbXMge1xuICAvKipcbiAgICogVGhlIE9ic2lkaWFuIGFwcCBpbnN0YW5jZS5cbiAgICovXG4gIHJlYWRvbmx5IGFwcDogQXBwO1xuXG4gIC8qKlxuICAgKiBBIENTUyBjbGFzcyBhZGRlZCB0byB0aGUgZWRpdG9yIGVsZW1lbnQuXG4gICAqL1xuICByZWFkb25seSBjbHM/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBlbGVtZW50IHRoZSBlZGl0b3IgaXMgbW91bnRlZCBpbi4gVGhlIGVkaXRvciBhcHBlbmRzIGl0cyBvd24gZWxlbWVudCB0byBpdCBhbmQgcmVtb3ZlcyBvbmx5IHRoYXQgZWxlbWVudCB3aGVuXG4gICAqIGl0IHVubG9hZHMuXG4gICAqL1xuICByZWFkb25seSBjb250YWluZXJFbDogSFRNTEVsZW1lbnQ7XG5cbiAgLyoqXG4gICAqIFRoZSBpbml0aWFsIHNlbGVjdGlvbiwgYXMgZG9jdW1lbnQgb2Zmc2V0cy4gVGhlIGN1cnNvciBzdGFydHMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgZG9jdW1lbnQgb3RoZXJ3aXNlLlxuICAgKi9cbiAgcmVhZG9ubHkgY3Vyc29yTG9jYXRpb24/OiBFbWJlZGRhYmxlTWFya2Rvd25FZGl0b3JDb21wb25lbnRTZWxlY3Rpb247XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBlZGl0b3IgbG9zZXMgZm9jdXMsIHdoaWxlIHRoZSBjb21wb25lbnQgaXMgc3RpbGwgbG9hZGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgb25CbHVyPzogKGNvbXBvbmVudDogRW1iZWRkYWJsZU1hcmtkb3duRWRpdG9yQ29tcG9uZW50KSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBDYWxsZWQgYWZ0ZXIgZXZlcnkgY2hhbmdlIHRvIHRoZSBkb2N1bWVudC5cbiAgICovXG4gIHJlYWRvbmx5IG9uQ2hhbmdlPzogKHVwZGF0ZTogVmlld1VwZGF0ZSwgY29tcG9uZW50OiBFbWJlZGRhYmxlTWFya2Rvd25FZGl0b3JDb21wb25lbnQpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIENhbGxlZCBvbiBgRW50ZXJgLCBgU2hpZnQrRW50ZXJgLCBgTW9kK0VudGVyYCBhbmQgYE1vZCtTaGlmdCtFbnRlcmAuXG4gICAqXG4gICAqIFdoZW4gZ2l2ZW4sIGBNb2QrRW50ZXJgIG5vIGxvbmdlciBydW5zIHRoZSBPYnNpZGlhbiBob3RrZXkgYm91bmQgdG8gaXQgKGJ5IGRlZmF1bHQsIG9wZW5pbmcgdGhlIGxpbmsgdW5kZXIgdGhlXG4gICAqIGN1cnNvciBpbiBhIG5ldyB0YWIpIHdoaWxlIHRoZSBlZGl0b3IgaGFzIHRoZSBmb2N1cywgc28gYSBmb3JtIGNhbiB1c2UgaXQgdG8gc3VibWl0LlxuICAgKlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiB0aGUga2V5IHdhcyBoYW5kbGVkLCB3aGljaCBzdG9wcyB0aGUgZWRpdG9yIGluc2VydGluZyBhIGxpbmUgYnJlYWs7IGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKi9cbiAgcmVhZG9ubHkgb25FbnRlcj86IChwYXJhbXM6IEVtYmVkZGFibGVNYXJrZG93bkVkaXRvckNvbXBvbmVudEVudGVyUGFyYW1zKSA9PiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDYWxsZWQgb24gYEVzY2FwZWAuIFdoZW4gZ2l2ZW4sIHRoZSBrZXkgZ29lcyBubyBmdXJ0aGVyLlxuICAgKi9cbiAgcmVhZG9ubHkgb25Fc2NhcGU/OiAoY29tcG9uZW50OiBFbWJlZGRhYmxlTWFya2Rvd25FZGl0b3JDb21wb25lbnQpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIENhbGxlZCBvbiBhIHBhc3RlIGludG8gdGhlIGVkaXRvciwgYmVmb3JlIHRoZSBlZGl0b3IgaGFuZGxlcyBpdC5cbiAgICovXG4gIHJlYWRvbmx5IG9uUGFzdGU/OiAoJGV2ZW50OiBDbGlwYm9hcmRFdmVudCwgY29tcG9uZW50OiBFbWJlZGRhYmxlTWFya2Rvd25FZGl0b3JDb21wb25lbnQpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFRoZSB0ZXh0IHNob3duIHdoaWxlIHRoZSBkb2N1bWVudCBpcyBlbXB0eS5cbiAgICovXG4gIHJlYWRvbmx5IHBsYWNlaG9sZGVyPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgaW5pdGlhbCBkb2N1bWVudC5cbiAgICovXG4gIHJlYWRvbmx5IHZhbHVlPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRoZSBwYXJhbWV0ZXJzIG9mIHtAbGluayBFbWJlZGRhYmxlTWFya2Rvd25FZGl0b3JDb21wb25lbnRDb25zdHJ1Y3RvclBhcmFtcy5vbkVudGVyfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbWJlZGRhYmxlTWFya2Rvd25FZGl0b3JDb21wb25lbnRFbnRlclBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgZWRpdG9yIGNvbXBvbmVudCB0aGUga2V5IHdhcyBwcmVzc2VkIGluLlxuICAgKi9cbiAgcmVhZG9ubHkgY29tcG9uZW50OiBFbWJlZGRhYmxlTWFya2Rvd25FZGl0b3JDb21wb25lbnQ7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHBsYXRmb3JtIG1vZGlmaWVyIChgQ3RybGAsIG9yIGBDbWRgIG9uIG1hY09TKSB3YXMgaGVsZC5cbiAgICovXG4gIHJlYWRvbmx5IGlzTW9kaWZpZXJQcmVzc2VkOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGBTaGlmdGAgd2FzIGhlbGQuXG4gICAqL1xuICByZWFkb25seSBpc1NoaWZ0UHJlc3NlZDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBIHNlbGVjdGlvbiBpbiBhbiB7QGxpbmsgRW1iZWRkYWJsZU1hcmtkb3duRWRpdG9yQ29tcG9uZW50fSwgYXMgZG9jdW1lbnQgb2Zmc2V0cy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbWJlZGRhYmxlTWFya2Rvd25FZGl0b3JDb21wb25lbnRTZWxlY3Rpb24ge1xuICAvKipcbiAgICogVGhlIG9mZnNldCB0aGUgc2VsZWN0aW9uIHN0YXJ0cyBmcm9tLlxuICAgKi9cbiAgcmVhZG9ubHkgYW5jaG9yOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBvZmZzZXQgdGhlIHNlbGVjdGlvbiBleHRlbmRzIHRvLCB3aGVyZSB0aGUgY3Vyc29yIGlzLlxuICAgKi9cbiAgcmVhZG9ubHkgaGVhZDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgRWRpdG9ySG9va3Mge1xuICByZWFkb25seSBidWlsZEV4dGVuc2lvbnM6ICgpID0+IEV4dGVuc2lvbltdO1xuICByZWFkb25seSBoYW5kbGVVcGRhdGU6ICh1cGRhdGU6IFZpZXdVcGRhdGUsIGlzQ2hhbmdlZDogYm9vbGVhbikgPT4gdm9pZDtcbn1cblxudHlwZSBFbWJlZGRlZFNjcm9sbGFibGVNYXJrZG93bkVkaXRvckNvbnN0cnVjdG9yID0gbmV3IChcbiAgYXBwOiBBcHAsXG4gIGNvbnRhaW5lckVsOiBIVE1MRWxlbWVudCxcbiAgb3duZXI6IE1hcmtkb3duU2Nyb2xsYWJsZUVkaXRWaWV3T3duZXIsXG4gIGhvb2tzOiBFZGl0b3JIb29rc1xuKSA9PiBNYXJrZG93blNjcm9sbGFibGVFZGl0VmlldztcblxudHlwZSBTY3JvbGxhYmxlTWFya2Rvd25FZGl0b3JDb25zdHJ1Y3RvciA9IEV4dHJhY3RDb25zdHJ1Y3RvcjxNYXJrZG93blNjcm9sbGFibGVFZGl0Vmlldz47XG5cbmludGVyZmFjZSBTY3JvbGxhYmxlTWFya2Rvd25FZGl0b3JDb25zdHJ1Y3RvckNhY2hlIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHR5cGVzY3JpcHQtZGV2LXRvb2xraXQvcmVhZG9ubHktaW50ZXJmYWNlLW1lbWJlcnMgLS0gRmlsbGVkIG9uIGZpcnN0IHVzZS5cbiAgdmFsdWU6IG51bGwgfCBTY3JvbGxhYmxlTWFya2Rvd25FZGl0b3JDb25zdHJ1Y3Rvcjtcbn1cblxuLyogZXNsaW50LWRpc2FibGUgdHlwZXNjcmlwdC1kZXYtdG9vbGtpdC9yZWFkb25seS1pbnRlcmZhY2UtbWVtYmVycyAtLSBUaGUgb3duZXIgbGVhcm5zIGl0cyBlZGl0b3IgYWZ0ZXIgdGhlIGVkaXRvciwgd2hpY2ggbmVlZHMgdGhlIG93bmVyLCBpcyBidWlsdC4gKi9cbmludGVyZmFjZSBTY3JvbGxhYmxlTWFya2Rvd25FZGl0b3JPd25lciBleHRlbmRzIE1hcmtkb3duU2Nyb2xsYWJsZUVkaXRWaWV3T3duZXIge1xuICBlZGl0TW9kZTogTWFya2Rvd25TY3JvbGxhYmxlRWRpdFZpZXcgfCBudWxsO1xuICByZWFkb25seSBnZXRNb2RlOiAoKSA9PiAnc291cmNlJztcbn1cbi8qIGVzbGludC1lbmFibGUgdHlwZXNjcmlwdC1kZXYtdG9vbGtpdC9yZWFkb25seS1pbnRlcmZhY2UtbWVtYmVycyAtLSBSZXN0b3JlIHRoZSBydWxlIGFmdGVyIHRoZSBvd25lci4gKi9cblxuaW50ZXJmYWNlIFNjcm9sbGFibGVNYXJrZG93bkVkaXRvclByb3RvdHlwZSB7XG4gIHJlYWRvbmx5IGNvbnN0cnVjdG9yOiBTY3JvbGxhYmxlTWFya2Rvd25FZGl0b3JDb25zdHJ1Y3Rvcjtcbn1cblxuY29uc3Qgc2Nyb2xsYWJsZU1hcmtkb3duRWRpdG9yQ29uc3RydWN0b3JDYWNoZTogU2Nyb2xsYWJsZU1hcmtkb3duRWRpdG9yQ29uc3RydWN0b3JDYWNoZSA9IHsgdmFsdWU6IG51bGwgfTtcblxuLyoqXG4gKiBBIGZ1bGwgT2JzaWRpYW4gTWFya2Rvd24gZWRpdG9yIG1vdW50ZWQgaW4gYW55IGVsZW1lbnQ6IExpdmUgUHJldmlldywgZWRpdG9yIGNvbW1hbmRzLCBob3RrZXlzIGFuZCB0aGUgZWRpdG9yXG4gKiBzdWdnZXN0ZXJzIGFsbCB3b3JrIGluIGl0IGFzIHRoZXkgZG8gaW4gYSBub3RlLlxuICpcbiAqIEFkZCBpdCBhcyBhIGNoaWxkIG9mIHRoZSBjb21wb25lbnQgdGhhdCBvd25zIGl0cyBlbGVtZW50OyB1bmxvYWRpbmcgaXQgZGVzdHJveXMgdGhlIGVkaXRvciBhbmQgcmVtb3ZlcyB0aGUgZWRpdG9yJ3NcbiAqIGVsZW1lbnQuIEl0IHdvcmtzIG9uIGRlc2t0b3AgYW5kIG1vYmlsZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGNvbnN0IGVkaXRvckNvbXBvbmVudCA9IHRoaXMuYWRkQ2hpbGQobmV3IEVtYmVkZGFibGVNYXJrZG93bkVkaXRvckNvbXBvbmVudCh7XG4gKiAgIGFwcDogdGhpcy5hcHAsXG4gKiAgIGNvbnRhaW5lckVsLFxuICogICBvbkVudGVyOiAoeyBjb21wb25lbnQsIGlzTW9kaWZpZXJQcmVzc2VkIH0pID0+IHtcbiAqICAgICBpZiAoIWlzTW9kaWZpZXJQcmVzc2VkKSB7XG4gKiAgICAgICByZXR1cm4gZmFsc2U7XG4gKiAgICAgfVxuICogICAgIHNhdmUoY29tcG9uZW50LnZhbHVlKTtcbiAqICAgICByZXR1cm4gdHJ1ZTtcbiAqICAgfSxcbiAqICAgdmFsdWU6ICdJbml0aWFsIHRleHQnXG4gKiB9KSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIEVtYmVkZGFibGVNYXJrZG93bkVkaXRvckNvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudEV4IHtcbiAgLyoqXG4gICAqIFRoZSBPYnNpZGlhbiBlZGl0b3IsIGFzIGluIGEgbm90ZS5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGVkaXRvci5cbiAgICovXG4gIHB1YmxpYyBnZXQgZWRpdG9yKCk6IEVkaXRvciB7XG4gICAgcmV0dXJuIGVuc3VyZU5vbk51bGxhYmxlKHRoaXMuZ2V0U2Nyb2xsYWJsZUVkaXRvcigpLmVkaXRvcik7XG4gIH1cblxuICAvKipcbiAgICogVGhlIENvZGVNaXJyb3IgdmlldyBiZWhpbmQgdGhlIGVkaXRvci5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIENvZGVNaXJyb3Igdmlldy5cbiAgICovXG4gIHB1YmxpYyBnZXQgZWRpdG9yVmlldygpOiBFZGl0b3JWaWV3IHtcbiAgICByZXR1cm4gdGhpcy5nZXRTY3JvbGxhYmxlRWRpdG9yKCkuY207XG4gIH1cblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgZG9jdW1lbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBkb2N1bWVudCB0ZXh0LlxuICAgKi9cbiAgcHVibGljIGdldCB2YWx1ZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmdldFNjcm9sbGFibGVFZGl0b3IoKS5jbS5zdGF0ZS5kb2MudG9TdHJpbmcoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgT2JzaWRpYW4gYXBwIGluc3RhbmNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGFwcDogQXBwO1xuXG4gIC8qKlxuICAgKiBUaGUgZWxlbWVudCB0aGUgZWRpdG9yIGlzIG1vdW50ZWQgaW4uXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY29udGFpbmVyRWw6IEhUTUxFbGVtZW50O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY2xzOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgY3Vyc29yTG9jYXRpb246IEVtYmVkZGFibGVNYXJrZG93bkVkaXRvckNvbXBvbmVudFNlbGVjdGlvbiB8IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgaW5pdGlhbFZhbHVlOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkga2V5bWFwU2NvcGU6IFNjb3BlO1xuICBwcml2YXRlIHJlYWRvbmx5IG9uQmx1cjogKChjb21wb25lbnQ6IEVtYmVkZGFibGVNYXJrZG93bkVkaXRvckNvbXBvbmVudCkgPT4gdm9pZCkgfCBudWxsO1xuICBwcml2YXRlIHJlYWRvbmx5IG9uQ2hhbmdlOiAoKHVwZGF0ZTogVmlld1VwZGF0ZSwgY29tcG9uZW50OiBFbWJlZGRhYmxlTWFya2Rvd25FZGl0b3JDb21wb25lbnQpID0+IHZvaWQpIHwgbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSBvbkVudGVyOiAoKHBhcmFtczogRW1iZWRkYWJsZU1hcmtkb3duRWRpdG9yQ29tcG9uZW50RW50ZXJQYXJhbXMpID0+IGJvb2xlYW4pIHwgbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSBvbkVzY2FwZTogKChjb21wb25lbnQ6IEVtYmVkZGFibGVNYXJrZG93bkVkaXRvckNvbXBvbmVudCkgPT4gdm9pZCkgfCBudWxsO1xuICBwcml2YXRlIHJlYWRvbmx5IG9uUGFzdGU6ICgoJGV2ZW50OiBDbGlwYm9hcmRFdmVudCwgY29tcG9uZW50OiBFbWJlZGRhYmxlTWFya2Rvd25FZGl0b3JDb21wb25lbnQpID0+IHZvaWQpIHwgbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSBvd25lcjogU2Nyb2xsYWJsZU1hcmtkb3duRWRpdG9yT3duZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGxhY2Vob2xkZXJUZXh0OiBzdHJpbmc7XG4gIHByaXZhdGUgc2Nyb2xsYWJsZUVkaXRvcjogTWFya2Rvd25TY3JvbGxhYmxlRWRpdFZpZXcgfCBudWxsID0gbnVsbDtcblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgY29tcG9uZW50LiBUaGUgZWRpdG9yIGlzIGJ1aWx0IHdoZW4gdGhlIGNvbXBvbmVudCBsb2Fkcy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzLlxuICAgKi9cbiAgcHVibGljIGNvbnN0cnVjdG9yKHBhcmFtczogRW1iZWRkYWJsZU1hcmtkb3duRWRpdG9yQ29tcG9uZW50Q29uc3RydWN0b3JQYXJhbXMpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuYXBwID0gcGFyYW1zLmFwcDtcbiAgICB0aGlzLmNvbnRhaW5lckVsID0gcGFyYW1zLmNvbnRhaW5lckVsO1xuICAgIHRoaXMuY2xzID0gcGFyYW1zLmNscyA/PyAnJztcbiAgICB0aGlzLmN1cnNvckxvY2F0aW9uID0gcGFyYW1zLmN1cnNvckxvY2F0aW9uID8/IG51bGw7XG4gICAgdGhpcy5pbml0aWFsVmFsdWUgPSBwYXJhbXMudmFsdWUgPz8gJyc7XG4gICAgdGhpcy5vbkJsdXIgPSBwYXJhbXMub25CbHVyID8/IG51bGw7XG4gICAgdGhpcy5vbkNoYW5nZSA9IHBhcmFtcy5vbkNoYW5nZSA/PyBudWxsO1xuICAgIHRoaXMub25FbnRlciA9IHBhcmFtcy5vbkVudGVyID8/IG51bGw7XG4gICAgdGhpcy5vbkVzY2FwZSA9IHBhcmFtcy5vbkVzY2FwZSA/PyBudWxsO1xuICAgIHRoaXMub25QYXN0ZSA9IHBhcmFtcy5vblBhc3RlID8/IG51bGw7XG4gICAgdGhpcy5wbGFjZWhvbGRlclRleHQgPSBwYXJhbXMucGxhY2Vob2xkZXIgPz8gJyc7XG4gICAgdGhpcy5rZXltYXBTY29wZSA9IG5ldyBTY29wZShwYXJhbXMuYXBwLnNjb3BlKTtcbiAgICAvLyBUaGUgZWRpdG9yJ3Mgb3duZXIgc3RhbmRzIGluIGZvciBhIGBNYXJrZG93blZpZXdgLiBUaGUgZWRpdG9yIGNvbW1hbmRzIHJlYWNoIHRoZSBlZGl0b3IgdGhyb3VnaFxuICAgIC8vIGBhY3RpdmVFZGl0b3IuZWRpdE1vZGVgIGFuZCBgYWN0aXZlRWRpdG9yLmVkaXRvcmAsIGFuZCBzY3JvbGxpbmcgY2FsbHMgYmFjayBpbnRvIHRoZSBvd25lci5cbiAgICB0aGlzLm93bmVyID0ge1xuICAgICAgYXBwOiBwYXJhbXMuYXBwLFxuICAgICAgZWRpdE1vZGU6IG51bGwsXG4gICAgICBmaWxlOiBudWxsLFxuICAgICAgZ2V0TW9kZTogKCk6ICdzb3VyY2UnID0+ICdzb3VyY2UnLFxuICAgICAgaG92ZXJQb3BvdmVyOiBudWxsLFxuICAgICAgc3luY1Njcm9sbDogbm9vcFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRm9jdXNlcyB0aGUgZWRpdG9yLlxuICAgKi9cbiAgcHVibGljIGZvY3VzKCk6IHZvaWQge1xuICAgIHRoaXMuZ2V0U2Nyb2xsYWJsZUVkaXRvcigpLmZvY3VzKCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIHRoZSBlZGl0b3IgYW5kIG1vdW50cyBpdCBpbiB0aGUgY29udGFpbmVyLlxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIG9ubG9hZCgpOiB2b2lkIHtcbiAgICBzdXBlci5vbmxvYWQoKTtcbiAgICBjb25zdCBFZGl0b3JDb25zdHJ1Y3RvciA9IGNyZWF0ZUVkaXRvckNsYXNzKGdldFNjcm9sbGFibGVNYXJrZG93bkVkaXRvckNvbnN0cnVjdG9yKHRoaXMuYXBwKSk7XG4gICAgY29uc3Qgc2Nyb2xsYWJsZUVkaXRvciA9IG5ldyBFZGl0b3JDb25zdHJ1Y3Rvcih0aGlzLmFwcCwgdGhpcy5jb250YWluZXJFbCwgdGhpcy5vd25lciwge1xuICAgICAgYnVpbGRFeHRlbnNpb25zOiAoKTogRXh0ZW5zaW9uW10gPT4gdGhpcy5idWlsZEV4dGVuc2lvbnMoKSxcbiAgICAgIGhhbmRsZVVwZGF0ZTogKHVwZGF0ZTogVmlld1VwZGF0ZSwgaXNDaGFuZ2VkOiBib29sZWFuKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMuaGFuZGxlVXBkYXRlKHVwZGF0ZSwgaXNDaGFuZ2VkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLnNjcm9sbGFibGVFZGl0b3IgPSBzY3JvbGxhYmxlRWRpdG9yO1xuICAgIHRoaXMub3duZXIuZWRpdE1vZGUgPSBzY3JvbGxhYmxlRWRpdG9yO1xuICAgIHRoaXMub3duZXIuZWRpdG9yID0gZW5zdXJlTm9uTnVsbGFibGUoc2Nyb2xsYWJsZUVkaXRvci5lZGl0b3IpO1xuICAgIHRoaXMuYWRkQ2hpbGQoc2Nyb2xsYWJsZUVkaXRvcik7XG5cbiAgICBpZiAodGhpcy5vbkVudGVyKSB7XG4gICAgICAvLyBPYnNpZGlhbidzIGhvdGtleXMgcnVuIGJlZm9yZSBDb2RlTWlycm9yJ3Mga2V5bWFwLCBhbmQgYE1vZCtFbnRlcmAgb3BlbnMgdGhlIGxpbmsgdW5kZXIgdGhlIGN1cnNvci4gQSBoYW5kbGVyXG4gICAgICAvLyByZXR1cm5pbmcgYHRydWVgIHN0b3BzIHRoYXQgaG90a2V5IHdpdGhvdXQgc3RvcHBpbmcgdGhlIGV2ZW50LCBzbyB0aGUgZWRpdG9yIGtleW1hcCBzdGlsbCBzZWVzIHRoZSBrZXkuXG4gICAgICBjb25zdCBzdWJtaXRIb3RrZXlIYW5kbGVyID0gdGhpcy5rZXltYXBTY29wZS5yZWdpc3RlcihbJ01vZCddLCAnRW50ZXInLCAoKSA9PiB0cnVlKTtcbiAgICAgIHRoaXMucmVnaXN0ZXIoKCkgPT4ge1xuICAgICAgICB0aGlzLmtleW1hcFNjb3BlLnVucmVnaXN0ZXIoc3VibWl0SG90a2V5SGFuZGxlcik7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jbHMpIHtcbiAgICAgIHNjcm9sbGFibGVFZGl0b3IuZWRpdG9yRWwuYWRkQ2xhc3ModGhpcy5jbHMpO1xuICAgIH1cblxuICAgIHNjcm9sbGFibGVFZGl0b3Iuc2V0KHRoaXMuaW5pdGlhbFZhbHVlLCBmYWxzZSk7XG5cbiAgICBpZiAodGhpcy5jdXJzb3JMb2NhdGlvbikge1xuICAgICAgc2Nyb2xsYWJsZUVkaXRvci5jbS5kaXNwYXRjaCh7XG4gICAgICAgIHNlbGVjdGlvbjogRWRpdG9yU2VsZWN0aW9uLnJhbmdlKHRoaXMuY3Vyc29yTG9jYXRpb24uYW5jaG9yLCB0aGlzLmN1cnNvckxvY2F0aW9uLmhlYWQpXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBmb2N1c0d1YXJkUGF0Y2hDb21wb25lbnQgPSB0aGlzLmFkZENoaWxkKG5ldyBNb25rZXlBcm91bmRDb21wb25lbnQoKSk7XG4gICAgZm9jdXNHdWFyZFBhdGNoQ29tcG9uZW50LnJlZ2lzdGVyTWV0aG9kUGF0Y2goe1xuICAgICAgJG9iamVjdDogdGhpcy5hcHAud29ya3NwYWNlLFxuICAgICAgbWV0aG9kTmFtZTogJ3NldEFjdGl2ZUxlYWYnLFxuICAgICAgcGF0Y2hIYW5kbGVyOiAoeyBmYWxsYmFjayB9KSA9PiB7XG4gICAgICAgIC8vIEEgZm9jdXNlZCBlZGl0b3IgdGhhdCBiZWxvbmdzIHRvIG5vIGxlYWYgd291bGQgb3RoZXJ3aXNlIGxvc2UgaXRzIGZvY3VzIHRvIHRoZSBsZWFmIHRoZSB3b3Jrc3BhY2UgYWN0aXZhdGVzLlxuICAgICAgICBpZiAoc2Nyb2xsYWJsZUVkaXRvci5hY3RpdmVDTS5oYXNGb2N1cykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBmYWxsYmFjaygpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5yZWdpc3RlcigoKSA9PiB7XG4gICAgICB0aGlzLmFwcC5rZXltYXAucG9wU2NvcGUodGhpcy5rZXltYXBTY29wZSk7XG4gICAgICBpZiAodGhpcy5hcHAud29ya3NwYWNlLmFjdGl2ZUVkaXRvciA9PT0gdGhpcy5vd25lcikge1xuICAgICAgICB0aGlzLmFwcC53b3Jrc3BhY2UuYWN0aXZlRWRpdG9yID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHNjcm9sbGFibGVFZGl0b3IuZGVzdHJveSgpO1xuICAgICAgc2Nyb2xsYWJsZUVkaXRvci5lZGl0b3JFbC5yZW1vdmUoKTtcbiAgICAgIHRoaXMub3duZXIuZWRpdE1vZGUgPSBudWxsO1xuICAgICAgZGVsZXRlIHRoaXMub3duZXIuZWRpdG9yO1xuICAgICAgdGhpcy5zY3JvbGxhYmxlRWRpdG9yID0gbnVsbDtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyB0aGUgZG9jdW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBuZXcgZG9jdW1lbnQuXG4gICAqL1xuICBwdWJsaWMgc2V0VmFsdWUodmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZ2V0U2Nyb2xsYWJsZUVkaXRvcigpLnNldCh2YWx1ZSwgZmFsc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyB0aGUgZWRpdG9yJ3Mgb3duIGV4dGVuc2lvbnM6IHRoZSBwbGFjZWhvbGRlciwgdGhlIGZvY3VzIGFuZCBwYXN0ZSBoYW5kbGVycywgYW5kIHRoZSBrZXkgaGFuZGxlcnMuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBleHRlbnNpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkRXh0ZW5zaW9ucygpOiBFeHRlbnNpb25bXSB7XG4gICAgY29uc3QgZXh0ZW5zaW9uczogRXh0ZW5zaW9uW10gPSBbXG4gICAgICBFZGl0b3JWaWV3LmRvbUV2ZW50SGFuZGxlcnMoe1xuICAgICAgICBibHVyOiAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgdGhpcy5hcHAua2V5bWFwLnBvcFNjb3BlKHRoaXMua2V5bWFwU2NvcGUpO1xuICAgICAgICAgIGlmICh0aGlzLl9sb2FkZWQpIHtcbiAgICAgICAgICAgIHRoaXMub25CbHVyPy4odGhpcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBmb2N1czogKCk6IHZvaWQgPT4ge1xuICAgICAgICAgIHRoaXMuYXBwLmtleW1hcC5wdXNoU2NvcGUodGhpcy5rZXltYXBTY29wZSk7XG4gICAgICAgIH0sXG4gICAgICAgIHBhc3RlOiAoJGV2ZW50OiBDbGlwYm9hcmRFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgICAgIHRoaXMub25QYXN0ZT8uKCRldmVudCwgdGhpcyk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgUHJlYy5oaWdoZXN0KGtleW1hcC5vZihbXG4gICAgICAgIHtcbiAgICAgICAgICBrZXk6ICdFbnRlcicsXG4gICAgICAgICAgcnVuOiAoKTogYm9vbGVhbiA9PiB0aGlzLmlzRW50ZXJIYW5kbGVkKGZhbHNlLCBmYWxzZSksXG4gICAgICAgICAgc2hpZnQ6ICgpOiBib29sZWFuID0+IHRoaXMuaXNFbnRlckhhbmRsZWQoZmFsc2UsIHRydWUpXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBrZXk6ICdNb2QtRW50ZXInLFxuICAgICAgICAgIHJ1bjogKCk6IGJvb2xlYW4gPT4gdGhpcy5pc0VudGVySGFuZGxlZCh0cnVlLCBmYWxzZSksXG4gICAgICAgICAgc2hpZnQ6ICgpOiBib29sZWFuID0+IHRoaXMuaXNFbnRlckhhbmRsZWQodHJ1ZSwgdHJ1ZSlcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGtleTogJ0VzY2FwZScsXG4gICAgICAgICAgcHJldmVudERlZmF1bHQ6IHRydWUsXG4gICAgICAgICAgcnVuOiAoKTogYm9vbGVhbiA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMub25Fc2NhcGUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5vbkVzY2FwZSh0aGlzKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgXSkpXG4gICAgXTtcblxuICAgIGlmICh0aGlzLnBsYWNlaG9sZGVyVGV4dCkge1xuICAgICAgZXh0ZW5zaW9ucy5wdXNoKHBsYWNlaG9sZGVyKHRoaXMucGxhY2Vob2xkZXJUZXh0KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGV4dGVuc2lvbnM7XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIGFmdGVyIGV2ZXJ5IHVwZGF0ZSBvZiB0aGUgZWRpdG9yLCB3aXRoIHdoZXRoZXIgdGhlIGRvY3VtZW50IGNoYW5nZWQuXG4gICAqXG4gICAqIEBwYXJhbSB1cGRhdGUgLSBUaGUgQ29kZU1pcnJvciB1cGRhdGUuXG4gICAqIEBwYXJhbSBpc0NoYW5nZWQgLSBXaGV0aGVyIHRoZSBkb2N1bWVudCBjaGFuZ2VkLlxuICAgKi9cbiAgcHJvdGVjdGVkIGhhbmRsZVVwZGF0ZSh1cGRhdGU6IFZpZXdVcGRhdGUsIGlzQ2hhbmdlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmIChpc0NoYW5nZWQpIHtcbiAgICAgIHRoaXMub25DaGFuZ2U/Lih1cGRhdGUsIHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0U2Nyb2xsYWJsZUVkaXRvcigpOiBNYXJrZG93blNjcm9sbGFibGVFZGl0VmlldyB7XG4gICAgcmV0dXJuIGVuc3VyZU5vbk51bGxhYmxlKHRoaXMuc2Nyb2xsYWJsZUVkaXRvciwgJ1RoZSBlZGl0b3IgaXMgYnVpbHQgd2hlbiB0aGUgY29tcG9uZW50IGxvYWRzLicpO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0VudGVySGFuZGxlZChpc01vZGlmaWVyUHJlc3NlZDogYm9vbGVhbiwgaXNTaGlmdFByZXNzZWQ6IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5vbkVudGVyPy4oeyBjb21wb25lbnQ6IHRoaXMsIGlzTW9kaWZpZXJQcmVzc2VkLCBpc1NoaWZ0UHJlc3NlZCB9KSA/PyBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVFZGl0b3JDbGFzcyhCYXNlQ29uc3RydWN0b3I6IFNjcm9sbGFibGVNYXJrZG93bkVkaXRvckNvbnN0cnVjdG9yKTogRW1iZWRkZWRTY3JvbGxhYmxlTWFya2Rvd25FZGl0b3JDb25zdHJ1Y3RvciB7XG4gIHJldHVybiBjbGFzcyBFbWJlZGRlZFNjcm9sbGFibGVNYXJrZG93bkVkaXRvciBleHRlbmRzIEJhc2VDb25zdHJ1Y3RvciB7XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGFwcDogQXBwLCBjb250YWluZXJFbDogSFRNTEVsZW1lbnQsIG93bmVyOiBNYXJrZG93blNjcm9sbGFibGVFZGl0Vmlld093bmVyLCBwcml2YXRlIHJlYWRvbmx5IGhvb2tzOiBFZGl0b3JIb29rcykge1xuICAgICAgLy8gVGhlIGJhc2UgYnVpbGRzIGl0cyBleHRlbnNpb25zIGxhemlseSwgb24gdGhlIGZpcnN0IGBzZXQoKWAsIHNvIHRoZSBob29rcyBhcmUgbm90IG5lZWRlZCBkdXJpbmcgYHN1cGVyKClgLlxuICAgICAgc3VwZXIoYXBwLCBjb250YWluZXJFbCwgb3duZXIpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvdmVycmlkZSBidWlsZExvY2FsRXh0ZW5zaW9ucygpOiBFeHRlbnNpb25bXSB7XG4gICAgICByZXR1cm4gWy4uLnN1cGVyLmJ1aWxkTG9jYWxFeHRlbnNpb25zKCksIC4uLnRoaXMuaG9va3MuYnVpbGRFeHRlbnNpb25zKCldO1xuICAgIH1cblxuICAgIHB1YmxpYyBvdmVycmlkZSBvblVwZGF0ZSh1cGRhdGU6IFZpZXdVcGRhdGUsIGlzQ2hhbmdlZDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgc3VwZXIub25VcGRhdGUodXBkYXRlLCBpc0NoYW5nZWQpO1xuICAgICAgdGhpcy5ob29rcy5oYW5kbGVVcGRhdGUodXBkYXRlLCBpc0NoYW5nZWQpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U2Nyb2xsYWJsZU1hcmtkb3duRWRpdG9yQ29uc3RydWN0b3IoYXBwOiBBcHApOiBTY3JvbGxhYmxlTWFya2Rvd25FZGl0b3JDb25zdHJ1Y3RvciB7XG4gIGlmIChzY3JvbGxhYmxlTWFya2Rvd25FZGl0b3JDb25zdHJ1Y3RvckNhY2hlLnZhbHVlKSB7XG4gICAgcmV0dXJuIHNjcm9sbGFibGVNYXJrZG93bkVkaXRvckNvbnN0cnVjdG9yQ2FjaGUudmFsdWU7XG4gIH1cblxuICAvLyBBbiBlZGl0YWJsZSBNYXJrZG93biBlbWJlZCBidWlsZHMgYW4gaWZyYW1lZCBlZGl0b3Igd2hvc2UgYmFzZSBjbGFzcyBpcyB0aGUgc2Nyb2xsYWJsZSBlZGl0b3IuIFRoZSBlbWJlZCBpcyBnaXZlblxuICAvLyBubyBmaWxlLCB3aGljaCBpcyB3aGF0IGtlZXBzIGl0IGZyb20gcmVhZGluZyBvciB3YXRjaGluZyBvbmUuXG4gIGNvbnN0IHdpZGdldEVkaXRvclZpZXcgPSBjYXN0VG88V2lkZ2V0RWRpdG9yVmlldz4oYXBwLmVtYmVkUmVnaXN0cnkuZW1iZWRCeUV4dGVuc2lvbi5tZCh7IGFwcCwgY29udGFpbmVyRWw6IGNyZWF0ZURpdigpIH0sIGNhc3RUbzxURmlsZT4obnVsbCksICcnKSk7XG5cbiAgdHJ5IHtcbiAgICB3aWRnZXRFZGl0b3JWaWV3LmVkaXRhYmxlID0gdHJ1ZTtcbiAgICB3aWRnZXRFZGl0b3JWaWV3LnNob3dFZGl0b3IoKTtcbiAgICBjb25zdCBpZnJhbWVkRWRpdG9yID0gZW5zdXJlTm9uTnVsbGFibGUod2lkZ2V0RWRpdG9yVmlldy5lZGl0TW9kZSwgJ1RoZSBNYXJrZG93biBlbWJlZCBidWlsdCBubyBlZGl0b3IuJyk7XG4gICAgY29uc3Qgc2Nyb2xsYWJsZUVkaXRvclByb3RvdHlwZSA9IGNhc3RUbzxTY3JvbGxhYmxlTWFya2Rvd25FZGl0b3JQcm90b3R5cGU+KE9iamVjdC5nZXRQcm90b3R5cGVPZihPYmplY3QuZ2V0UHJvdG90eXBlT2YoaWZyYW1lZEVkaXRvcikgYXMgb2JqZWN0KSk7XG4gICAgc2Nyb2xsYWJsZU1hcmtkb3duRWRpdG9yQ29uc3RydWN0b3JDYWNoZS52YWx1ZSA9IHNjcm9sbGFibGVFZGl0b3JQcm90b3R5cGUuY29uc3RydWN0b3I7XG4gICAgcmV0dXJuIHNjcm9sbGFibGVFZGl0b3JQcm90b3R5cGUuY29uc3RydWN0b3I7XG4gIH0gZmluYWxseSB7XG4gICAgd2lkZ2V0RWRpdG9yVmlldy51bmxvYWQoKTtcbiAgfVxufVxuXG4vKiB2OCBpZ25vcmUgc3RvcCAqL1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWtEQTtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsWUFBWTtBQUNyQixTQUFTLGNBQWM7QUFDdkIsU0FBUyx5QkFBeUI7QUFDbEMsU0FBUyxhQUFhO0FBRXRCLFNBQVMsbUJBQW1CO0FBQzVCLFNBQVMsNkJBQTZCO0FBcUl0QyxNQUFNLDJDQUFxRixFQUFFLE9BQU8sS0FBSztBQXlCbEcsTUFBTSwwQ0FBMEMsWUFBWTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU1qRSxJQUFXLFNBQWlCO0FBQzFCLFdBQU8sa0JBQWtCLEtBQUssb0JBQW9CLEVBQUUsTUFBTTtBQUFBLEVBQzVEO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT0EsSUFBVyxhQUF5QjtBQUNsQyxXQUFPLEtBQUssb0JBQW9CLEVBQUU7QUFBQSxFQUNwQztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9BLElBQVcsUUFBZ0I7QUFDekIsV0FBTyxLQUFLLG9CQUFvQixFQUFFLEdBQUcsTUFBTSxJQUFJLFNBQVM7QUFBQSxFQUMxRDtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBS21CO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFLQTtBQUFBLEVBRUY7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVB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
|
|
@@ -10,6 +10,7 @@ export * as 'console-debug-component' from './console-debug-component.mjs';
|
|
|
10
10
|
export * as 'core-plugin-toggle-component' from './core-plugin-toggle-component.mjs';
|
|
11
11
|
export * as 'disposable-component' from './disposable-component.mjs';
|
|
12
12
|
export * as 'embed-extensions-component' from './embed-extensions-component.mjs';
|
|
13
|
+
export * as 'embeddable-markdown-editor-component' from './embeddable-markdown-editor-component.mjs';
|
|
13
14
|
export * as 'file-explorer-root-menu-component' from './file-explorer-root-menu-component.mjs';
|
|
14
15
|
export * as 'generate-markdown-link-default-params-component' from './generate-markdown-link-default-params-component.mjs';
|
|
15
16
|
export * as 'incremental-file-index-component' from './incremental-file-index-component.mjs';
|
|
@@ -24,6 +25,7 @@ export * as 'plugin-settings-component' from './plugin-settings-component.mjs';
|
|
|
24
25
|
export * as 'plugin-settings-tab-component' from './plugin-settings-tab-component.mjs';
|
|
25
26
|
export * as 'plugin-suggestion-component' from './plugin-suggestion-component.mjs';
|
|
26
27
|
export * as 'pointer-position-component' from './pointer-position-component.mjs';
|
|
28
|
+
export * as 'reconfigurable-editor-extension-component' from './reconfigurable-editor-extension-component.mjs';
|
|
27
29
|
export * as 'registry-component' from './registry-component.mjs';
|
|
28
30
|
export * as 'release-notes-component' from './release-notes-component.mjs';
|
|
29
31
|
export * as 'rename-delete-handler-component' from './rename-delete-handler-component.mjs';
|
|
@@ -14,6 +14,7 @@ import * as console_debug_component from "./console-debug-component.mjs";
|
|
|
14
14
|
import * as core_plugin_toggle_component from "./core-plugin-toggle-component.mjs";
|
|
15
15
|
import * as disposable_component from "./disposable-component.mjs";
|
|
16
16
|
import * as embed_extensions_component from "./embed-extensions-component.mjs";
|
|
17
|
+
import * as embeddable_markdown_editor_component from "./embeddable-markdown-editor-component.mjs";
|
|
17
18
|
import * as file_explorer_root_menu_component from "./file-explorer-root-menu-component.mjs";
|
|
18
19
|
import * as generate_markdown_link_default_params_component from "./generate-markdown-link-default-params-component.mjs";
|
|
19
20
|
import * as incremental_file_index_component from "./incremental-file-index-component.mjs";
|
|
@@ -28,6 +29,7 @@ import * as plugin_settings_component from "./plugin-settings-component.mjs";
|
|
|
28
29
|
import * as plugin_settings_tab_component from "./plugin-settings-tab-component.mjs";
|
|
29
30
|
import * as plugin_suggestion_component from "./plugin-suggestion-component.mjs";
|
|
30
31
|
import * as pointer_position_component from "./pointer-position-component.mjs";
|
|
32
|
+
import * as reconfigurable_editor_extension_component from "./reconfigurable-editor-extension-component.mjs";
|
|
31
33
|
import * as registry_component from "./registry-component.mjs";
|
|
32
34
|
import * as release_notes_component from "./release-notes-component.mjs";
|
|
33
35
|
import * as rename_delete_handler_component from "./rename-delete-handler-component.mjs";
|
|
@@ -47,6 +49,7 @@ export {
|
|
|
47
49
|
core_plugin_toggle_component as "core-plugin-toggle-component",
|
|
48
50
|
disposable_component as "disposable-component",
|
|
49
51
|
embed_extensions_component as "embed-extensions-component",
|
|
52
|
+
embeddable_markdown_editor_component as "embeddable-markdown-editor-component",
|
|
50
53
|
file_explorer_root_menu_component as "file-explorer-root-menu-component",
|
|
51
54
|
generate_markdown_link_default_params_component as "generate-markdown-link-default-params-component",
|
|
52
55
|
incremental_file_index_component as "incremental-file-index-component",
|
|
@@ -61,6 +64,7 @@ export {
|
|
|
61
64
|
plugin_settings_tab_component as "plugin-settings-tab-component",
|
|
62
65
|
plugin_suggestion_component as "plugin-suggestion-component",
|
|
63
66
|
pointer_position_component as "pointer-position-component",
|
|
67
|
+
reconfigurable_editor_extension_component as "reconfigurable-editor-extension-component",
|
|
64
68
|
registry_component as "registry-component",
|
|
65
69
|
release_notes_component as "release-notes-component",
|
|
66
70
|
rename_delete_handler_component as "rename-delete-handler-component",
|
|
@@ -69,4 +73,4 @@ export {
|
|
|
69
73
|
syntax_highlighting_component as "syntax-highlighting-component",
|
|
70
74
|
templates_language_component as "templates-language-component"
|
|
71
75
|
};
|
|
72
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
76
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvaW5kZXgudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qIFRISVMgSVMgQSBHRU5FUkFURUQvQlVORExFRCBGSUxFIEJZIEJVSUxEIFNDUklQVCAqL1xuXG5leHBvcnQgKiBhcyAnYWJvcnQtc2lnbmFsLWNvbXBvbmVudCcgZnJvbSAnLi9hYm9ydC1zaWduYWwtY29tcG9uZW50LnRzJztcbmV4cG9ydCAqIGFzICdhbGwtd2luZG93cy1ldmVudC1jb21wb25lbnQnIGZyb20gJy4vYWxsLXdpbmRvd3MtZXZlbnQtY29tcG9uZW50LnRzJztcbmV4cG9ydCAqIGFzICdhc3luYy1lcnJvci1oYW5kbGVyLWNvbXBvbmVudCcgZnJvbSAnLi9hc3luYy1lcnJvci1oYW5kbGVyLWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAnYXN5bmMtZXZlbnRzLWNvbXBvbmVudCcgZnJvbSAnLi9hc3luYy1ldmVudHMtY29tcG9uZW50LnRzJztcbmV4cG9ydCAqIGFzICdidWxrLW9wZXJhdGlvbi1jb21taXQtY29tcG9uZW50JyBmcm9tICcuL2J1bGstb3BlcmF0aW9uLWNvbW1pdC1jb21wb25lbnQudHMnO1xuZXhwb3J0ICogYXMgJ2Nhc2UtaW5zZW5zaXRpdmUtZmlsZS1pbmRleC1jb21wb25lbnQnIGZyb20gJy4vY2FzZS1pbnNlbnNpdGl2ZS1maWxlLWluZGV4LWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAnY29tcG9uZW50LWV4JyBmcm9tICcuL2NvbXBvbmVudC1leC50cyc7XG5leHBvcnQgKiBhcyAnY29uc29sZS1kZWJ1Zy1jb21wb25lbnQnIGZyb20gJy4vY29uc29sZS1kZWJ1Zy1jb21wb25lbnQudHMnO1xuZXhwb3J0ICogYXMgJ2NvcmUtcGx1Z2luLXRvZ2dsZS1jb21wb25lbnQnIGZyb20gJy4vY29yZS1wbHVnaW4tdG9nZ2xlLWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAnZGlzcG9zYWJsZS1jb21wb25lbnQnIGZyb20gJy4vZGlzcG9zYWJsZS1jb21wb25lbnQudHMnO1xuZXhwb3J0ICogYXMgJ2VtYmVkLWV4dGVuc2lvbnMtY29tcG9uZW50JyBmcm9tICcuL2VtYmVkLWV4dGVuc2lvbnMtY29tcG9uZW50LnRzJztcbmV4cG9ydCAqIGFzICdlbWJlZGRhYmxlLW1hcmtkb3duLWVkaXRvci1jb21wb25lbnQnIGZyb20gJy4vZW1iZWRkYWJsZS1tYXJrZG93bi1lZGl0b3ItY29tcG9uZW50LnRzJztcbmV4cG9ydCAqIGFzICdmaWxlLWV4cGxvcmVyLXJvb3QtbWVudS1jb21wb25lbnQnIGZyb20gJy4vZmlsZS1leHBsb3Jlci1yb290LW1lbnUtY29tcG9uZW50LnRzJztcbmV4cG9ydCAqIGFzICdnZW5lcmF0ZS1tYXJrZG93bi1saW5rLWRlZmF1bHQtcGFyYW1zLWNvbXBvbmVudCcgZnJvbSAnLi9nZW5lcmF0ZS1tYXJrZG93bi1saW5rLWRlZmF1bHQtcGFyYW1zLWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAnaW5jcmVtZW50YWwtZmlsZS1pbmRleC1jb21wb25lbnQnIGZyb20gJy4vaW5jcmVtZW50YWwtZmlsZS1pbmRleC1jb21wb25lbnQudHMnO1xuZXhwb3J0ICogYXMgJ2xheW91dC1yZWFkeS1jb21wb25lbnQnIGZyb20gJy4vbGF5b3V0LXJlYWR5LWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAnbWVudS1ldmVudC1yZWdpc3RyYXItY29tcG9uZW50JyBmcm9tICcuL21lbnUtZXZlbnQtcmVnaXN0cmFyLWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAnbW9ua2V5LWFyb3VuZC1jb21wb25lbnQnIGZyb20gJy4vbW9ua2V5LWFyb3VuZC1jb21wb25lbnQudHMnO1xuZXhwb3J0ICogYXMgJ25vdGVib29rLW5hdmlnYXRvci1tZW51LWV2ZW50LXJlZ2lzdHJhci1jb21wb25lbnQnIGZyb20gJy4vbm90ZWJvb2stbmF2aWdhdG9yLW1lbnUtZXZlbnQtcmVnaXN0cmFyLWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAncGx1Z2luLWNvbnRleHQtY29tcG9uZW50JyBmcm9tICcuL3BsdWdpbi1jb250ZXh0LWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAncGx1Z2luLWdhdGUtY29tcG9uZW50JyBmcm9tICcuL3BsdWdpbi1nYXRlLWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAncGx1Z2luLW5vdGljZS1jb21wb25lbnQnIGZyb20gJy4vcGx1Z2luLW5vdGljZS1jb21wb25lbnQudHMnO1xuZXhwb3J0ICogYXMgJ3BsdWdpbi1zZXR0aW5ncy1jb21wb25lbnQnIGZyb20gJy4vcGx1Z2luLXNldHRpbmdzLWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAncGx1Z2luLXNldHRpbmdzLXRhYi1jb21wb25lbnQnIGZyb20gJy4vcGx1Z2luLXNldHRpbmdzLXRhYi1jb21wb25lbnQudHMnO1xuZXhwb3J0ICogYXMgJ3BsdWdpbi1zdWdnZXN0aW9uLWNvbXBvbmVudCcgZnJvbSAnLi9wbHVnaW4tc3VnZ2VzdGlvbi1jb21wb25lbnQudHMnO1xuZXhwb3J0ICogYXMgJ3BvaW50ZXItcG9zaXRpb24tY29tcG9uZW50JyBmcm9tICcuL3BvaW50ZXItcG9zaXRpb24tY29tcG9uZW50LnRzJztcbmV4cG9ydCAqIGFzICdyZWNvbmZpZ3VyYWJsZS1lZGl0b3ItZXh0ZW5zaW9uLWNvbXBvbmVudCcgZnJvbSAnLi9yZWNvbmZpZ3VyYWJsZS1lZGl0b3ItZXh0ZW5zaW9uLWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAncmVnaXN0cnktY29tcG9uZW50JyBmcm9tICcuL3JlZ2lzdHJ5LWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAncmVsZWFzZS1ub3Rlcy1jb21wb25lbnQnIGZyb20gJy4vcmVsZWFzZS1ub3Rlcy1jb21wb25lbnQudHMnO1xuZXhwb3J0ICogYXMgJ3JlbmFtZS1kZWxldGUtaGFuZGxlci1jb21wb25lbnQnIGZyb20gJy4vcmVuYW1lLWRlbGV0ZS1oYW5kbGVyLWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAncm1kaXItZ3VhcmQtY29tcG9uZW50JyBmcm9tICcuL3JtZGlyLWd1YXJkLWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAnc2V0dGluZ3MtbWlncmF0aW9uLWNvbXBvbmVudCcgZnJvbSAnLi9zZXR0aW5ncy1taWdyYXRpb24tY29tcG9uZW50LnRzJztcbmV4cG9ydCAqIGFzICdzeW50YXgtaGlnaGxpZ2h0aW5nLWNvbXBvbmVudCcgZnJvbSAnLi9zeW50YXgtaGlnaGxpZ2h0aW5nLWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAndGVtcGxhdGVzLWxhbmd1YWdlLWNvbXBvbmVudCcgZnJvbSAnLi90ZW1wbGF0ZXMtbGFuZ3VhZ2UtY29tcG9uZW50LnRzJztcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7O0FBRUEsWUFBWUEsNEJBQThCO0FBQzFDLFlBQVlDLGlDQUFtQztBQUMvQyxZQUFZQyxtQ0FBcUM7QUFDakQsWUFBWUMsNEJBQThCO0FBQzFDLFlBQVlDLHFDQUF1QztBQUNuRCxZQUFZQywyQ0FBNkM7QUFDekQsWUFBWUMsa0JBQW9CO0FBQ2hDLFlBQVlDLDZCQUErQjtBQUMzQyxZQUFZQyxrQ0FBb0M7QUFDaEQsWUFBWUMsMEJBQTRCO0FBQ3hDLFlBQVlDLGdDQUFrQztBQUM5QyxZQUFZQywwQ0FBNEM7QUFDeEQsWUFBWUMsdUNBQXlDO0FBQ3JELFlBQVlDLHFEQUF1RDtBQUNuRSxZQUFZQyxzQ0FBd0M7QUFDcEQsWUFBWUMsNEJBQThCO0FBQzFDLFlBQVlDLG9DQUFzQztBQUNsRCxZQUFZQyw2QkFBK0I7QUFDM0MsWUFBWUMsdURBQXlEO0FBQ3JFLFlBQVlDLDhCQUFnQztBQUM1QyxZQUFZQywyQkFBNkI7QUFDekMsWUFBWUMsNkJBQStCO0FBQzNDLFlBQVlDLCtCQUFpQztBQUM3QyxZQUFZQyxtQ0FBcUM7QUFDakQsWUFBWUMsaUNBQW1DO0FBQy9DLFlBQVlDLGdDQUFrQztBQUM5QyxZQUFZQywrQ0FBaUQ7QUFDN0QsWUFBWUMsd0JBQTBCO0FBQ3RDLFlBQVlDLDZCQUErQjtBQUMzQyxZQUFZQyxxQ0FBdUM7QUFDbkQsWUFBWUMsMkJBQTZCO0FBQ3pDLFlBQVlDLGtDQUFvQztBQUNoRCxZQUFZQyxtQ0FBcUM7QUFDakQsWUFBWUMsa0NBQW9DOyIsCiAgIm5hbWVzIjogWyJhYm9ydC1zaWduYWwtY29tcG9uZW50IiwgImFsbC13aW5kb3dzLWV2ZW50LWNvbXBvbmVudCIsICJhc3luYy1lcnJvci1oYW5kbGVyLWNvbXBvbmVudCIsICJhc3luYy1ldmVudHMtY29tcG9uZW50IiwgImJ1bGstb3BlcmF0aW9uLWNvbW1pdC1jb21wb25lbnQiLCAiY2FzZS1pbnNlbnNpdGl2ZS1maWxlLWluZGV4LWNvbXBvbmVudCIsICJjb21wb25lbnQtZXgiLCAiY29uc29sZS1kZWJ1Zy1jb21wb25lbnQiLCAiY29yZS1wbHVnaW4tdG9nZ2xlLWNvbXBvbmVudCIsICJkaXNwb3NhYmxlLWNvbXBvbmVudCIsICJlbWJlZC1leHRlbnNpb25zLWNvbXBvbmVudCIsICJlbWJlZGRhYmxlLW1hcmtkb3duLWVkaXRvci1jb21wb25lbnQiLCAiZmlsZS1leHBsb3Jlci1yb290LW1lbnUtY29tcG9uZW50IiwgImdlbmVyYXRlLW1hcmtkb3duLWxpbmstZGVmYXVsdC1wYXJhbXMtY29tcG9uZW50IiwgImluY3JlbWVudGFsLWZpbGUtaW5kZXgtY29tcG9uZW50IiwgImxheW91dC1yZWFkeS1jb21wb25lbnQiLCAibWVudS1ldmVudC1yZWdpc3RyYXItY29tcG9uZW50IiwgIm1vbmtleS1hcm91bmQtY29tcG9uZW50IiwgIm5vdGVib29rLW5hdmlnYXRvci1tZW51LWV2ZW50LXJlZ2lzdHJhci1jb21wb25lbnQiLCAicGx1Z2luLWNvbnRleHQtY29tcG9uZW50IiwgInBsdWdpbi1nYXRlLWNvbXBvbmVudCIsICJwbHVnaW4tbm90aWNlLWNvbXBvbmVudCIsICJwbHVnaW4tc2V0dGluZ3MtY29tcG9uZW50IiwgInBsdWdpbi1zZXR0aW5ncy10YWItY29tcG9uZW50IiwgInBsdWdpbi1zdWdnZXN0aW9uLWNvbXBvbmVudCIsICJwb2ludGVyLXBvc2l0aW9uLWNvbXBvbmVudCIsICJyZWNvbmZpZ3VyYWJsZS1lZGl0b3ItZXh0ZW5zaW9uLWNvbXBvbmVudCIsICJyZWdpc3RyeS1jb21wb25lbnQiLCAicmVsZWFzZS1ub3Rlcy1jb21wb25lbnQiLCAicmVuYW1lLWRlbGV0ZS1oYW5kbGVyLWNvbXBvbmVudCIsICJybWRpci1ndWFyZC1jb21wb25lbnQiLCAic2V0dGluZ3MtbWlncmF0aW9uLWNvbXBvbmVudCIsICJzeW50YXgtaGlnaGxpZ2h0aW5nLWNvbXBvbmVudCIsICJ0ZW1wbGF0ZXMtbGFuZ3VhZ2UtY29tcG9uZW50Il0KfQo=
|