@mnaoumov/obsidian-lib 10.3.0 → 10.4.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/command-handlers/undo-bulk-operation-command-handler/package.json +6 -0
- package/components/bulk-operation-commit-component/package.json +6 -0
- package/dist/lib/cjs/__merged.cjs +42 -1
- package/dist/lib/cjs/__merged.d.cts +5 -0
- package/dist/lib/cjs/bulk-operation-progress.cjs +120 -0
- package/dist/lib/cjs/bulk-operation-progress.d.cts +33 -0
- package/dist/lib/cjs/bulk-operation.cjs +220 -0
- package/dist/lib/cjs/bulk-operation.d.cts +237 -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/undo-bulk-operation-command-handler.cjs +164 -0
- package/dist/lib/cjs/command-handlers/undo-bulk-operation-command-handler.d.cts +51 -0
- package/dist/lib/cjs/components/bulk-operation-commit-component.cjs +337 -0
- package/dist/lib/cjs/components/bulk-operation-commit-component.d.cts +152 -0
- package/dist/lib/cjs/components/index.cjs +4 -1
- package/dist/lib/cjs/components/index.d.cts +1 -0
- package/dist/lib/cjs/desktop-bulk-operation-git.cjs +534 -0
- package/dist/lib/cjs/desktop-bulk-operation-git.d.cts +196 -0
- package/dist/lib/cjs/generated-during-build.cjs +1 -1
- package/dist/lib/cjs/i18n/locales/en.cjs +10 -1
- package/dist/lib/cjs/i18n/locales/en.d.cts +9 -0
- package/dist/lib/cjs/i18n/locales/translations-map.d.cts +9 -0
- package/dist/lib/cjs/index.cjs +10 -1
- package/dist/lib/cjs/index.d.cts +3 -0
- package/dist/lib/cjs/loop.cjs +3 -1
- package/dist/lib/esm/__merged.d.mts +5 -0
- package/dist/lib/esm/__merged.mjs +43 -1
- package/dist/lib/esm/bulk-operation-progress.d.mts +33 -0
- package/dist/lib/esm/bulk-operation-progress.mjs +31 -0
- package/dist/lib/esm/bulk-operation.d.mts +237 -0
- package/dist/lib/esm/bulk-operation.mjs +125 -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/undo-bulk-operation-command-handler.d.mts +51 -0
- package/dist/lib/esm/command-handlers/undo-bulk-operation-command-handler.mjs +76 -0
- package/dist/lib/esm/components/bulk-operation-commit-component.d.mts +152 -0
- package/dist/lib/esm/components/bulk-operation-commit-component.mjs +245 -0
- package/dist/lib/esm/components/index.d.mts +1 -0
- package/dist/lib/esm/components/index.mjs +3 -1
- package/dist/lib/esm/desktop-bulk-operation-git.d.mts +196 -0
- package/dist/lib/esm/desktop-bulk-operation-git.mjs +463 -0
- package/dist/lib/esm/generated-during-build.mjs +1 -1
- package/dist/lib/esm/i18n/locales/en.d.mts +9 -0
- package/dist/lib/esm/i18n/locales/en.mjs +10 -1
- package/dist/lib/esm/i18n/locales/translations-map.d.mts +9 -0
- package/dist/lib/esm/index.d.mts +3 -0
- package/dist/lib/esm/index.mjs +7 -1
- package/dist/lib/esm/loop.mjs +3 -1
- package/package.json +1 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/// <reference path="./library-references.d.cts" />
|
|
2
|
+
/**
|
|
3
|
+
* @file
|
|
4
|
+
*
|
|
5
|
+
* A realm-wide progress signal for bulk operations.
|
|
6
|
+
*
|
|
7
|
+
* A bulk operation wrapped in git commits holds a lease lock whose heartbeat must be refreshed by the operation's
|
|
8
|
+
* own progress, never by a free-running timer, so a hung operation goes stale like a crashed one. Rather than
|
|
9
|
+
* threading a callback through every plugin's call chain, the wrapper subscribes here while it runs, and
|
|
10
|
+
* {@link loop} reports after every item it processes. Code that drives a bulk operation without `loop()` calls
|
|
11
|
+
* {@link reportBulkOperationProgress} itself.
|
|
12
|
+
*
|
|
13
|
+
* The listener set lives in the shared-state bag under a versioned key, so a `loop()` bundled by one plugin's copy
|
|
14
|
+
* of this library reaches a listener registered by another's. Its shape is a cross-copy wire format: a `Set` of
|
|
15
|
+
* plain functions, read structurally.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* A listener notified whenever a bulk operation makes progress.
|
|
19
|
+
*/
|
|
20
|
+
export type BulkOperationProgressListener = () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Subscribes to bulk-operation progress.
|
|
23
|
+
*
|
|
24
|
+
* @param listener - The listener to notify on every progress report.
|
|
25
|
+
* @returns A function that unsubscribes the listener.
|
|
26
|
+
*/
|
|
27
|
+
export declare function registerBulkOperationProgressListener(listener: BulkOperationProgressListener): () => void;
|
|
28
|
+
/**
|
|
29
|
+
* Reports that a bulk operation has made progress, such as finishing one item.
|
|
30
|
+
*
|
|
31
|
+
* A listener that throws is skipped, so a progress report can never fail the operation reporting it.
|
|
32
|
+
*/
|
|
33
|
+
export declare function reportBulkOperationProgress(): void;
|
|
@@ -0,0 +1,220 @@
|
|
|
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 bulk_operation_exports = {};
|
|
116
|
+
__export(bulk_operation_exports, {
|
|
117
|
+
BULK_OPERATION_LOCK_FILE_NAME: () => BULK_OPERATION_LOCK_FILE_NAME,
|
|
118
|
+
BULK_OPERATION_LOCK_STALE_AFTER_IN_MILLISECONDS: () => BULK_OPERATION_LOCK_STALE_AFTER_IN_MILLISECONDS,
|
|
119
|
+
OPERATION_TRAILER_KEY: () => OPERATION_TRAILER_KEY,
|
|
120
|
+
PLUGIN_TRAILER_KEY: () => PLUGIN_TRAILER_KEY,
|
|
121
|
+
buildBeforeOperationCommitSubject: () => buildBeforeOperationCommitSubject,
|
|
122
|
+
buildOperationCommitMessage: () => buildOperationCommitMessage,
|
|
123
|
+
formatOperationId: () => formatOperationId,
|
|
124
|
+
getNextOperationId: () => getNextOperationId,
|
|
125
|
+
isBulkOperationLock: () => isBulkOperationLock,
|
|
126
|
+
isBulkOperationLockStale: () => isBulkOperationLockStale,
|
|
127
|
+
parseBulkOperationCommit: () => parseBulkOperationCommit,
|
|
128
|
+
parseOperationNumber: () => parseOperationNumber
|
|
129
|
+
});
|
|
130
|
+
module.exports = __toCommonJS(bulk_operation_exports);
|
|
131
|
+
var import_reg_exp = require('@mnaoumov/typescript-lib/reg-exp');
|
|
132
|
+
var import_type_guards = require('@mnaoumov/typescript-lib/type-guards');
|
|
133
|
+
const BULK_OPERATION_LOCK_FILE_NAME = "obsidian-bulk-operation.json";
|
|
134
|
+
const BULK_OPERATION_LOCK_STALE_AFTER_IN_MILLISECONDS = 12e4;
|
|
135
|
+
const OPERATION_TRAILER_KEY = "Obsidian-Bulk-Operation";
|
|
136
|
+
const PLUGIN_TRAILER_KEY = "Obsidian-Plugin";
|
|
137
|
+
const OPERATION_ID_PREFIX = "OP";
|
|
138
|
+
const isBulkOperationLockImpl = (0, import_type_guards.objectTypeGuard)({
|
|
139
|
+
heartbeatAt: import_type_guards.isNumber,
|
|
140
|
+
host: import_type_guards.isString,
|
|
141
|
+
operationId: import_type_guards.isString,
|
|
142
|
+
pluginId: import_type_guards.isString,
|
|
143
|
+
processId: import_type_guards.isNumber,
|
|
144
|
+
processStartedAt: import_type_guards.isNumber,
|
|
145
|
+
startedAt: import_type_guards.isNumber
|
|
146
|
+
});
|
|
147
|
+
function buildBeforeOperationCommitSubject(operationId) {
|
|
148
|
+
return `chore: before ${operationId}`;
|
|
149
|
+
}
|
|
150
|
+
function buildOperationCommitMessage(params) {
|
|
151
|
+
const subject = params.isInterrupted ? `${params.operationId} interrupted` : `${params.operationId}: ${normalizeSummary(params.summary ?? "")}`;
|
|
152
|
+
const body = `Timestamp: ${params.timestamp.toISOString()}
|
|
153
|
+
Changed-Files: ${String(params.changedFileCount)}
|
|
154
|
+
${PLUGIN_TRAILER_KEY}: ${params.pluginId}
|
|
155
|
+
${OPERATION_TRAILER_KEY}: ${params.operationId}`;
|
|
156
|
+
return { body, subject };
|
|
157
|
+
}
|
|
158
|
+
function formatOperationId(operationNumber) {
|
|
159
|
+
return `${OPERATION_ID_PREFIX}${String(operationNumber)}`;
|
|
160
|
+
}
|
|
161
|
+
function getNextOperationId(subjects) {
|
|
162
|
+
let maxOperationNumber = 0;
|
|
163
|
+
for (const subject of subjects) {
|
|
164
|
+
const operationNumber = parseOperationNumber(subject);
|
|
165
|
+
if (operationNumber !== null && operationNumber > maxOperationNumber) {
|
|
166
|
+
maxOperationNumber = operationNumber;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return formatOperationId(maxOperationNumber + 1);
|
|
170
|
+
}
|
|
171
|
+
function isBulkOperationLock(value) {
|
|
172
|
+
return isBulkOperationLockImpl(value);
|
|
173
|
+
}
|
|
174
|
+
function isBulkOperationLockStale(lock, context) {
|
|
175
|
+
if (context.now - lock.heartbeatAt >= BULK_OPERATION_LOCK_STALE_AFTER_IN_MILLISECONDS) {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
if (lock.host !== context.host) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
const wasHeartbeatBeforeBoot = context.bootedAt !== null && lock.heartbeatAt < context.bootedAt;
|
|
182
|
+
return wasHeartbeatBeforeBoot || context.isProcessAlive(lock.processId) === false;
|
|
183
|
+
}
|
|
184
|
+
function parseBulkOperationCommit(params) {
|
|
185
|
+
const match = /^OP(?<operationNumber>\d+)(?<kind>:| interrupted$)/.exec(params.subject);
|
|
186
|
+
if (!match) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
date: params.date,
|
|
191
|
+
isInterrupted: (0, import_reg_exp.getMandatoryNamedGroup)(match, "kind") !== ":",
|
|
192
|
+
operationId: formatOperationId(Number((0, import_reg_exp.getMandatoryNamedGroup)(match, "operationNumber"))),
|
|
193
|
+
sha: params.sha,
|
|
194
|
+
subject: params.subject
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
function parseOperationNumber(subject) {
|
|
198
|
+
const match = /^(?:chore: before )?OP(?<operationNumber>\d+)(?::| interrupted$|$)/.exec(subject);
|
|
199
|
+
return match ? Number((0, import_reg_exp.getMandatoryNamedGroup)(match, "operationNumber")) : null;
|
|
200
|
+
}
|
|
201
|
+
function normalizeSummary(summary) {
|
|
202
|
+
const normalized = summary.replaceAll(/\s+/g, " ").trim();
|
|
203
|
+
return normalized || "bulk operation";
|
|
204
|
+
}
|
|
205
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
206
|
+
0 && (module.exports = {
|
|
207
|
+
BULK_OPERATION_LOCK_FILE_NAME,
|
|
208
|
+
BULK_OPERATION_LOCK_STALE_AFTER_IN_MILLISECONDS,
|
|
209
|
+
OPERATION_TRAILER_KEY,
|
|
210
|
+
PLUGIN_TRAILER_KEY,
|
|
211
|
+
buildBeforeOperationCommitSubject,
|
|
212
|
+
buildOperationCommitMessage,
|
|
213
|
+
formatOperationId,
|
|
214
|
+
getNextOperationId,
|
|
215
|
+
isBulkOperationLock,
|
|
216
|
+
isBulkOperationLockStale,
|
|
217
|
+
parseBulkOperationCommit,
|
|
218
|
+
parseOperationNumber
|
|
219
|
+
});
|
|
220
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9idWxrLW9wZXJhdGlvbi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmaWxlXG4gKlxuICogVGhlIHBsYXRmb3JtLW5ldXRyYWwgaGFsZiBvZiBidWxrLW9wZXJhdGlvbiBnaXQgY29tbWl0czogdGhlIGxlYXNlLWxvY2sgcmVjb3JkLCB0aGUgYE9QPG4+YCBpZHMgYW5kIHRoZSBjb21taXRcbiAqIG1lc3NhZ2VzIHRoYXQgY2FycnkgdGhlbS5cbiAqXG4gKiBBIGJ1bGsgb3BlcmF0aW9uIHdyYXBwZWQgYnkgYEJ1bGtPcGVyYXRpb25Db21taXRDb21wb25lbnRgIGxhbmRzIGluIHRoZSB2YXVsdCdzIGdpdCByZXBvIGFzIG9uZSBjb21taXQgd2hvc2VcbiAqIHN1YmplY3QgaXMgYE9QPG4+OiA8c3VtbWFyeT5gLCBwcmVjZWRlZCAod2hlbiB0aGUgdHJlZSB3YXMgZGlydHkpIGJ5IGEgYGNob3JlOiBiZWZvcmUgT1A8bj5gIGNvbW1pdCBob2xkaW5nXG4gKiB3aGF0ZXZlciB3YXMgcGVuZGluZywgc28gYGdpdCByZXZlcnRgIG9mIHRoZSBgT1A8bj5gIGNvbW1pdCB1bmRvZXMgZXhhY3RseSB0aGF0IG9wZXJhdGlvbi4gRXZlcnl0aGluZyBpbiB0aGlzXG4gKiBtb2R1bGUgaXMgcHVyZSwgc28gaXQgaXMgc2hhcmVkIGJ5IHRoZSBkZXNrdG9wIGdpdCBsYXllciBhbmQgYnkgdGhlIHNjaGVkdWxlZCBhdXRvY29tbWl0IHRoYXQgcmVhZHMgdGhlIHNhbWUgbG9jay5cbiAqXG4gKiBUaGUgbG9jayByZWNvcmQgYW5kIHRoZSBjb21taXQgbWVzc2FnZSB0cmFpbGVycyBhcmUgYSB3aXJlIGZvcm1hdCBiZXR3ZWVuIHBsdWdpbnMgYnVpbHQgb24gZGlmZmVyZW50IGNvcGllcyBvZlxuICogdGhpcyBsaWJyYXJ5IGFuZCB0aGUgdmF1bHQgYXV0b2NvbW1pdCBzY3JpcHQ6IGZpZWxkcyBtYXkgYmUgYWRkZWQsIG5ldmVyIHJlbmFtZWQgb3IgcmVpbnRlcnByZXRlZC5cbiAqL1xuXG5pbXBvcnQgeyBnZXRNYW5kYXRvcnlOYW1lZEdyb3VwIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL3JlZy1leHAnO1xuaW1wb3J0IHtcbiAgaXNOdW1iZXIsXG4gIGlzU3RyaW5nLFxuICBvYmplY3RUeXBlR3VhcmRcbn0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL3R5cGUtZ3VhcmRzJztcblxuLyoqXG4gKiBUaGUgbmFtZSBvZiB0aGUgbGVhc2UtbG9jayBmaWxlLCBjcmVhdGVkIGluc2lkZSB0aGUgcmVwbydzIGdpdCBkaXJlY3Rvcnkgc28gaXQgaXMgbmV2ZXIgY29tbWl0dGVkIG9yXG4gKiBzeW5jZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBCVUxLX09QRVJBVElPTl9MT0NLX0ZJTEVfTkFNRSA9ICdvYnNpZGlhbi1idWxrLW9wZXJhdGlvbi5qc29uJztcblxuLyoqXG4gKiBIb3cgbG9uZyBhIGxvY2sgbWF5IGdvIHdpdGhvdXQgYSBoZWFydGJlYXQgYmVmb3JlIGl0IGNvdW50cyBhcyBzdGFsZS5cbiAqXG4gKiBJdCBlcnJzIGxvbmcgb24gcHVycG9zZTogaG9sZGluZyBhIGRlYWQgbG9jayB0b28gbG9uZyBvbmx5IG1ha2VzIGFuIGF1dG9jb21taXQgc2tpcCBhIHRpY2ssIHdoaWxlIGRlY2xhcmluZyBhXG4gKiBsaXZlIG9uZSBzdGFsZSBzcGxpdHMgaXRzIG9wZXJhdGlvbiBhY3Jvc3MgdHdvIGNvbW1pdHMuXG4gKi9cbmV4cG9ydCBjb25zdCBCVUxLX09QRVJBVElPTl9MT0NLX1NUQUxFX0FGVEVSX0lOX01JTExJU0VDT05EUyA9IDEyMF8wMDA7XG5cbi8qKlxuICogVGhlIHRyYWlsZXIga2V5IG5hbWluZyB0aGUgb3BlcmF0aW9uIGlkIGluIGEgYnVsay1vcGVyYXRpb24gY29tbWl0IGJvZHkuXG4gKi9cbmV4cG9ydCBjb25zdCBPUEVSQVRJT05fVFJBSUxFUl9LRVkgPSAnT2JzaWRpYW4tQnVsay1PcGVyYXRpb24nO1xuXG4vKipcbiAqIFRoZSB0cmFpbGVyIGtleSBuYW1pbmcgdGhlIHBsdWdpbiBpbiBhIGJ1bGstb3BlcmF0aW9uIGNvbW1pdCBib2R5LlxuICovXG5leHBvcnQgY29uc3QgUExVR0lOX1RSQUlMRVJfS0VZID0gJ09ic2lkaWFuLVBsdWdpbic7XG5cbmNvbnN0IE9QRVJBVElPTl9JRF9QUkVGSVggPSAnT1AnO1xuXG5jb25zdCBpc0J1bGtPcGVyYXRpb25Mb2NrSW1wbCA9IG9iamVjdFR5cGVHdWFyZDxCdWxrT3BlcmF0aW9uTG9jaz4oe1xuICBoZWFydGJlYXRBdDogaXNOdW1iZXIsXG4gIGhvc3Q6IGlzU3RyaW5nLFxuICBvcGVyYXRpb25JZDogaXNTdHJpbmcsXG4gIHBsdWdpbklkOiBpc1N0cmluZyxcbiAgcHJvY2Vzc0lkOiBpc051bWJlcixcbiAgcHJvY2Vzc1N0YXJ0ZWRBdDogaXNOdW1iZXIsXG4gIHN0YXJ0ZWRBdDogaXNOdW1iZXJcbn0pO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBidWlsZE9wZXJhdGlvbkNvbW1pdE1lc3NhZ2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkT3BlcmF0aW9uQ29tbWl0TWVzc2FnZVBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGZpbGVzIHRoZSBjb21taXQgY2hhbmdlcy5cbiAgICovXG4gIHJlYWRvbmx5IGNoYW5nZWRGaWxlQ291bnQ6IG51bWJlcjtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgb3BlcmF0aW9uIHdhcyBpbnRlcnJ1cHRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGlzSW50ZXJydXB0ZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgb3BlcmF0aW9uIGlkLCBzdWNoIGFzIGBPUDEyYC5cbiAgICovXG4gIHJlYWRvbmx5IG9wZXJhdGlvbklkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBpZCBvZiB0aGUgcGx1Z2luIHRoYXQgcmFuIHRoZSBvcGVyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5JZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIG9uZS1saW5lIGRlc2NyaXB0aW9uIG9mIHRoZSBvcGVyYXRpb24uIElnbm9yZWQgZm9yIGFuIGludGVycnVwdGVkIG9wZXJhdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IHN1bW1hcnk/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZW4gdGhlIG9wZXJhdGlvbiByYW4uXG4gICAqL1xuICByZWFkb25seSB0aW1lc3RhbXA6IERhdGU7XG59XG5cbi8qKlxuICogQSBidWxrLW9wZXJhdGlvbiBjb21taXQgZm91bmQgaW4gdGhlIHJlcG8gaGlzdG9yeS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBCdWxrT3BlcmF0aW9uQ29tbWl0IHtcbiAgLyoqXG4gICAqIFRoZSBjb21taXQgZGF0ZSwgYXMgYW4gSVNPIDg2MDEgc3RyaW5nLlxuICAgKi9cbiAgcmVhZG9ubHkgZGF0ZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBjb21taXQgcmVjb3JkcyBhbiBpbnRlcnJ1cHRlZCBvcGVyYXRpb24gcmF0aGVyIHRoYW4gYSBjb21wbGV0ZWQgb25lLlxuICAgKi9cbiAgcmVhZG9ubHkgaXNJbnRlcnJ1cHRlZDogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIG9wZXJhdGlvbiBpZCwgc3VjaCBhcyBgT1AxMmAuXG4gICAqL1xuICByZWFkb25seSBvcGVyYXRpb25JZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZnVsbCBjb21taXQgaGFzaC5cbiAgICovXG4gIHJlYWRvbmx5IHNoYTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgY29tbWl0IHN1YmplY3QuXG4gICAqL1xuICByZWFkb25seSBzdWJqZWN0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIGxlYXNlLWxvY2sgcmVjb3JkIHN0b3JlZCBpbiBgLmdpdC9vYnNpZGlhbi1idWxrLW9wZXJhdGlvbi5qc29uYCB3aGlsZSBhIGJ1bGsgb3BlcmF0aW9uIHJ1bnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnVsa09wZXJhdGlvbkxvY2sge1xuICAvKipcbiAgICogV2hlbiB0aGUgbG9jayB3YXMgbGFzdCByZWZyZXNoZWQgYnkgdGhlIG9wZXJhdGlvbidzIHByb2dyZXNzLCBhcyBlcG9jaCBtaWxsaXNlY29uZHMuXG4gICAqL1xuICByZWFkb25seSBoZWFydGJlYXRBdDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgaG9zdCBuYW1lIG9mIHRoZSBtYWNoaW5lIHJ1bm5pbmcgdGhlIG9wZXJhdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IGhvc3Q6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG9wZXJhdGlvbiBpZCwgc3VjaCBhcyBgT1AxMmAuXG4gICAqL1xuICByZWFkb25seSBvcGVyYXRpb25JZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgaWQgb2YgdGhlIHBsdWdpbiBydW5uaW5nIHRoZSBvcGVyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5JZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgaWQgb2YgdGhlIHByb2Nlc3MgcnVubmluZyBPYnNpZGlhbi4gT25seSBhIGZhc3QgcGF0aCBmb3IgYW4gYXBwIGNyYXNoOyBzdGFsZW5lc3MgbmV2ZXIgZGVwZW5kcyBvbiBpdC5cbiAgICovXG4gIHJlYWRvbmx5IHByb2Nlc3NJZDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaGVuIHRoZSBwcm9jZXNzIHJ1bm5pbmcgT2JzaWRpYW4gc3RhcnRlZCwgYXMgZXBvY2ggbWlsbGlzZWNvbmRzLCBzbyBhIHJlY3ljbGVkIHByb2Nlc3MgaWQgaXMgbm90IG1pc3Rha2VuIGZvclxuICAgKiB0aGUgb3JpZ2luYWwgb25lLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJvY2Vzc1N0YXJ0ZWRBdDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaGVuIHRoZSBvcGVyYXRpb24gc3RhcnRlZCwgYXMgZXBvY2ggbWlsbGlzZWNvbmRzLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhcnRlZEF0OiBudW1iZXI7XG59XG5cbi8qKlxuICogVGhlIGZhY3RzIHtAbGluayBpc0J1bGtPcGVyYXRpb25Mb2NrU3RhbGV9IHdlaWdocyBiZXNpZGVzIHRoZSBoZWFydGJlYXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnVsa09wZXJhdGlvbkxvY2tTdGFsZW5lc3NDb250ZXh0IHtcbiAgLyoqXG4gICAqIFdoZW4gdGhpcyBtYWNoaW5lIGxhc3QgYm9vdGVkLCBhcyBlcG9jaCBtaWxsaXNlY29uZHMsIG9yIGBudWxsYCB3aGVuIHVua25vd24uXG4gICAqL1xuICByZWFkb25seSBib290ZWRBdDogbnVsbCB8IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGhvc3QgbmFtZSBvZiB0aGlzIG1hY2hpbmUuXG4gICAqL1xuICByZWFkb25seSBob3N0OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHByb2Nlc3MgcmVjb3JkZWQgaW4gdGhlIGxvY2sgaXMgc3RpbGwgcnVubmluZyBvbiB0aGlzIG1hY2hpbmUsIG9yIGBudWxsYCB3aGVuIGl0IGNhbm5vdCBiZSB0b2xkLlxuICAgKi9cbiAgcmVhZG9ubHkgaXNQcm9jZXNzQWxpdmU6IChwcm9jZXNzSWQ6IG51bWJlcikgPT4gYm9vbGVhbiB8IG51bGw7XG5cbiAgLyoqXG4gICAqIFRoZSBjdXJyZW50IHRpbWUsIGFzIGVwb2NoIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIHJlYWRvbmx5IG5vdzogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRoZSBjb21taXQgbWVzc2FnZSBvZiBvbmUgYnVsay1vcGVyYXRpb24gY29tbWl0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE9wZXJhdGlvbkNvbW1pdE1lc3NhZ2Uge1xuICAvKipcbiAgICogVGhlIGNvbW1pdCBib2R5OiB0aGUgdGltZXN0YW1wLCB0aGUgcGx1Z2luIGFuZCB0aGUgY291bnRzLCBhcyBnaXQgdHJhaWxlcnMuXG4gICAqL1xuICByZWFkb25seSBib2R5OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBjb21taXQgc3ViamVjdC5cbiAgICovXG4gIHJlYWRvbmx5IHN1YmplY3Q6IHN0cmluZztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgcGFyc2VCdWxrT3BlcmF0aW9uQ29tbWl0fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYXJzZUJ1bGtPcGVyYXRpb25Db21taXRQYXJhbXMge1xuICAvKipcbiAgICogVGhlIGNvbW1pdCBkYXRlLCBhcyBhbiBJU08gODYwMSBzdHJpbmcuXG4gICAqL1xuICByZWFkb25seSBkYXRlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBmdWxsIGNvbW1pdCBoYXNoLlxuICAgKi9cbiAgcmVhZG9ubHkgc2hhOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBjb21taXQgc3ViamVjdC5cbiAgICovXG4gIHJlYWRvbmx5IHN1YmplY3Q6IHN0cmluZztcbn1cblxuLyoqXG4gKiBCdWlsZHMgdGhlIHN1YmplY3Qgb2YgdGhlIGNvbW1pdCB0aGF0IHNhdmVzIHdoYXRldmVyIHdhcyBwZW5kaW5nIGJlZm9yZSBhbiBvcGVyYXRpb24uXG4gKlxuICogQHBhcmFtIG9wZXJhdGlvbklkIC0gVGhlIG9wZXJhdGlvbiBpZCwgc3VjaCBhcyBgT1AxMmAuXG4gKiBAcmV0dXJucyBUaGUgY29tbWl0IHN1YmplY3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEJlZm9yZU9wZXJhdGlvbkNvbW1pdFN1YmplY3Qob3BlcmF0aW9uSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgY2hvcmU6IGJlZm9yZSAke29wZXJhdGlvbklkfWA7XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBtZXNzYWdlIG9mIHRoZSBjb21taXQgcmVjb3JkaW5nIGEgYnVsayBvcGVyYXRpb24sIG9yIGFuIGludGVycnVwdGVkIG9uZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBUaGUgY29tbWl0IHN1YmplY3QgYW5kIGJvZHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZE9wZXJhdGlvbkNvbW1pdE1lc3NhZ2UocGFyYW1zOiBCdWlsZE9wZXJhdGlvbkNvbW1pdE1lc3NhZ2VQYXJhbXMpOiBPcGVyYXRpb25Db21taXRNZXNzYWdlIHtcbiAgY29uc3Qgc3ViamVjdCA9IHBhcmFtcy5pc0ludGVycnVwdGVkXG4gICAgPyBgJHtwYXJhbXMub3BlcmF0aW9uSWR9IGludGVycnVwdGVkYFxuICAgIDogYCR7cGFyYW1zLm9wZXJhdGlvbklkfTogJHtub3JtYWxpemVTdW1tYXJ5KHBhcmFtcy5zdW1tYXJ5ID8/ICcnKX1gO1xuICAvLyBHaXQgdHJhaWxlcnMsIG9uZSBwZXIgbGluZSwgc28gYGdpdCBsb2cgLS1ncmVwYCBhbmQgYGdpdCBpbnRlcnByZXQtdHJhaWxlcnNgIGJvdGggcmVhZCB0aGVtLlxuICBjb25zdCBib2R5ID0gYFRpbWVzdGFtcDogJHtwYXJhbXMudGltZXN0YW1wLnRvSVNPU3RyaW5nKCl9XFxuQ2hhbmdlZC1GaWxlczogJHtTdHJpbmcocGFyYW1zLmNoYW5nZWRGaWxlQ291bnQpfVxcbmBcbiAgICArIGAke1BMVUdJTl9UUkFJTEVSX0tFWX06ICR7cGFyYW1zLnBsdWdpbklkfVxcbiR7T1BFUkFUSU9OX1RSQUlMRVJfS0VZfTogJHtwYXJhbXMub3BlcmF0aW9uSWR9YDtcbiAgcmV0dXJuIHsgYm9keSwgc3ViamVjdCB9O1xufVxuXG4vKipcbiAqIEZvcm1hdHMgYW4gb3BlcmF0aW9uIGlkIGZyb20gaXRzIG51bWJlci5cbiAqXG4gKiBAcGFyYW0gb3BlcmF0aW9uTnVtYmVyIC0gVGhlIG9wZXJhdGlvbiBudW1iZXIuXG4gKiBAcmV0dXJucyBUaGUgb3BlcmF0aW9uIGlkLCBzdWNoIGFzIGBPUDEyYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdE9wZXJhdGlvbklkKG9wZXJhdGlvbk51bWJlcjogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAke09QRVJBVElPTl9JRF9QUkVGSVh9JHtTdHJpbmcob3BlcmF0aW9uTnVtYmVyKX1gO1xufVxuXG4vKipcbiAqIEZpbmRzIHRoZSBuZXh0IG9wZXJhdGlvbiBpZCBmcm9tIHRoZSBzdWJqZWN0cyBvZiB0aGUgYnVsay1vcGVyYXRpb24gY29tbWl0cyBhbHJlYWR5IGluIHRoZSBoaXN0b3J5LlxuICpcbiAqIEBwYXJhbSBzdWJqZWN0cyAtIENvbW1pdCBzdWJqZWN0czsgYW55dGhpbmcgdGhhdCBpcyBub3QgYSBidWxrLW9wZXJhdGlvbiBzdWJqZWN0IGlzIGlnbm9yZWQuXG4gKiBAcmV0dXJucyBgT1A8bj5gIHdpdGggbiBvbmUgcGFzdCB0aGUgaGlnaGVzdCBudW1iZXIgZm91bmQsIG9yIGBPUDFgIHdoZW4gdGhlcmUgaXMgbm9uZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE5leHRPcGVyYXRpb25JZChzdWJqZWN0czogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmcge1xuICBsZXQgbWF4T3BlcmF0aW9uTnVtYmVyID0gMDtcbiAgZm9yIChjb25zdCBzdWJqZWN0IG9mIHN1YmplY3RzKSB7XG4gICAgY29uc3Qgb3BlcmF0aW9uTnVtYmVyID0gcGFyc2VPcGVyYXRpb25OdW1iZXIoc3ViamVjdCk7XG4gICAgaWYgKG9wZXJhdGlvbk51bWJlciAhPT0gbnVsbCAmJiBvcGVyYXRpb25OdW1iZXIgPiBtYXhPcGVyYXRpb25OdW1iZXIpIHtcbiAgICAgIG1heE9wZXJhdGlvbk51bWJlciA9IG9wZXJhdGlvbk51bWJlcjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZvcm1hdE9wZXJhdGlvbklkKG1heE9wZXJhdGlvbk51bWJlciArIDEpO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgdmFsdWUgaGFzIHRoZSBzaGFwZSBvZiBhIHtAbGluayBCdWxrT3BlcmF0aW9uTG9ja30uXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHJlYWQgZnJvbSB0aGUgbG9jayBmaWxlLlxuICogQHJldHVybnMgV2hldGhlciBpdCBpcyBhIGxvY2sgcmVjb3JkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNCdWxrT3BlcmF0aW9uTG9jayh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIEJ1bGtPcGVyYXRpb25Mb2NrIHtcbiAgcmV0dXJuIGlzQnVsa09wZXJhdGlvbkxvY2tJbXBsKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBEZWNpZGVzIHdoZXRoZXIgYSBsZWFzZSBsb2NrIGlzIHN0YWxlLCBzbyB3aG9ldmVyIGZpbmRzIGl0IG1heSBjb21taXQgdGhlIGxlZnRvdmVycyBhbmQgcmVtb3ZlIGl0LlxuICpcbiAqIFRoZSBoZWFydGJlYXQgaXMgdGhlIHJ1bGU7IHRoZSByZWJvb3QgYW5kIGNyYXNoZWQtcHJvY2VzcyBjaGVja3MgYXJlIG9ubHkgZmFzdCBwYXRocyB0aGF0IHNob3J0ZW4gdGhlIHdhaXQsIGFuZFxuICogbmVpdGhlciBjYW4gbWFrZSBhIGxvY2sgd2l0aCBhIGZyZXNoIGhlYXJ0YmVhdCBvbiBhbm90aGVyIG1hY2hpbmUgc3RhbGUuXG4gKlxuICogQHBhcmFtIGxvY2sgLSBUaGUgbG9jayByZWNvcmQuXG4gKiBAcGFyYW0gY29udGV4dCAtIFRoZSBmYWN0cyBhYm91dCB0aGlzIG1hY2hpbmUuXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBsb2NrIGlzIHN0YWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNCdWxrT3BlcmF0aW9uTG9ja1N0YWxlKGxvY2s6IEJ1bGtPcGVyYXRpb25Mb2NrLCBjb250ZXh0OiBCdWxrT3BlcmF0aW9uTG9ja1N0YWxlbmVzc0NvbnRleHQpOiBib29sZWFuIHtcbiAgaWYgKGNvbnRleHQubm93IC0gbG9jay5oZWFydGJlYXRBdCA+PSBCVUxLX09QRVJBVElPTl9MT0NLX1NUQUxFX0FGVEVSX0lOX01JTExJU0VDT05EUykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGxvY2suaG9zdCAhPT0gY29udGV4dC5ob3N0KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3Qgd2FzSGVhcnRiZWF0QmVmb3JlQm9vdCA9IGNvbnRleHQuYm9vdGVkQXQgIT09IG51bGwgJiYgbG9jay5oZWFydGJlYXRBdCA8IGNvbnRleHQuYm9vdGVkQXQ7XG4gIHJldHVybiB3YXNIZWFydGJlYXRCZWZvcmVCb290IHx8IGNvbnRleHQuaXNQcm9jZXNzQWxpdmUobG9jay5wcm9jZXNzSWQpID09PSBmYWxzZTtcbn1cblxuLyoqXG4gKiBQYXJzZXMgYSBidWxrLW9wZXJhdGlvbiBjb21taXQgc3ViamVjdCBpbnRvIHRoZSBjb21taXQgaXQgZGVzY3JpYmVzLCBza2lwcGluZyB0aGUgYGNob3JlOiBiZWZvcmVgIGNvbW1pdHMsIHdoaWNoXG4gKiBhcmUgbm90IG9wZXJhdGlvbnMuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBjb21taXQncyBoYXNoLCBkYXRlIGFuZCBzdWJqZWN0LlxuICogQHJldHVybnMgVGhlIGJ1bGstb3BlcmF0aW9uIGNvbW1pdCwgb3IgYG51bGxgIHdoZW4gdGhlIHN1YmplY3QgaXMgbm90IG9uZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQnVsa09wZXJhdGlvbkNvbW1pdChwYXJhbXM6IFBhcnNlQnVsa09wZXJhdGlvbkNvbW1pdFBhcmFtcyk6IEJ1bGtPcGVyYXRpb25Db21taXQgfCBudWxsIHtcbiAgY29uc3QgbWF0Y2ggPSAvXk9QKD88b3BlcmF0aW9uTnVtYmVyPlxcZCspKD88a2luZD46fCBpbnRlcnJ1cHRlZCQpLy5leGVjKHBhcmFtcy5zdWJqZWN0KTtcbiAgaWYgKCFtYXRjaCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiB7XG4gICAgZGF0ZTogcGFyYW1zLmRhdGUsXG4gICAgaXNJbnRlcnJ1cHRlZDogZ2V0TWFuZGF0b3J5TmFtZWRHcm91cChtYXRjaCwgJ2tpbmQnKSAhPT0gJzonLFxuICAgIG9wZXJhdGlvbklkOiBmb3JtYXRPcGVyYXRpb25JZChOdW1iZXIoZ2V0TWFuZGF0b3J5TmFtZWRHcm91cChtYXRjaCwgJ29wZXJhdGlvbk51bWJlcicpKSksXG4gICAgc2hhOiBwYXJhbXMuc2hhLFxuICAgIHN1YmplY3Q6IHBhcmFtcy5zdWJqZWN0XG4gIH07XG59XG5cbi8qKlxuICogUGFyc2VzIHRoZSBvcGVyYXRpb24gbnVtYmVyIG91dCBvZiBhIGJ1bGstb3BlcmF0aW9uIGNvbW1pdCBzdWJqZWN0LlxuICpcbiAqIFJlY29nbml6ZXMgYE9QPG4+OiA8c3VtbWFyeT5gLCBgT1A8bj4gaW50ZXJydXB0ZWRgIGFuZCBgY2hvcmU6IGJlZm9yZSBPUDxuPmAuXG4gKlxuICogQHBhcmFtIHN1YmplY3QgLSBUaGUgY29tbWl0IHN1YmplY3QuXG4gKiBAcmV0dXJucyBUaGUgb3BlcmF0aW9uIG51bWJlciwgb3IgYG51bGxgIHdoZW4gdGhlIHN1YmplY3QgaXMgbm90IGEgYnVsay1vcGVyYXRpb24gc3ViamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlT3BlcmF0aW9uTnVtYmVyKHN1YmplY3Q6IHN0cmluZyk6IG51bGwgfCBudW1iZXIge1xuICBjb25zdCBtYXRjaCA9IC9eKD86Y2hvcmU6IGJlZm9yZSApP09QKD88b3BlcmF0aW9uTnVtYmVyPlxcZCspKD86OnwgaW50ZXJydXB0ZWQkfCQpLy5leGVjKHN1YmplY3QpO1xuICByZXR1cm4gbWF0Y2ggPyBOdW1iZXIoZ2V0TWFuZGF0b3J5TmFtZWRHcm91cChtYXRjaCwgJ29wZXJhdGlvbk51bWJlcicpKSA6IG51bGw7XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVN1bW1hcnkoc3VtbWFyeTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHN1bW1hcnkucmVwbGFjZUFsbCgvXFxzKy9nLCAnICcpLnRyaW0oKTtcbiAgcmV0dXJuIG5vcm1hbGl6ZWQgfHwgJ2J1bGsgb3BlcmF0aW9uJztcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/// <reference path="./library-references.d.cts" />
|
|
2
|
+
/**
|
|
3
|
+
* @file
|
|
4
|
+
*
|
|
5
|
+
* The platform-neutral half of bulk-operation git commits: the lease-lock record, the `OP<n>` ids and the commit
|
|
6
|
+
* messages that carry them.
|
|
7
|
+
*
|
|
8
|
+
* A bulk operation wrapped by `BulkOperationCommitComponent` lands in the vault's git repo as one commit whose
|
|
9
|
+
* subject is `OP<n>: <summary>`, preceded (when the tree was dirty) by a `chore: before OP<n>` commit holding
|
|
10
|
+
* whatever was pending, so `git revert` of the `OP<n>` commit undoes exactly that operation. Everything in this
|
|
11
|
+
* module is pure, so it is shared by the desktop git layer and by the scheduled autocommit that reads the same lock.
|
|
12
|
+
*
|
|
13
|
+
* The lock record and the commit message trailers are a wire format between plugins built on different copies of
|
|
14
|
+
* this library and the vault autocommit script: fields may be added, never renamed or reinterpreted.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* The name of the lease-lock file, created inside the repo's git directory so it is never committed or
|
|
18
|
+
* synced.
|
|
19
|
+
*/
|
|
20
|
+
export declare const BULK_OPERATION_LOCK_FILE_NAME = "obsidian-bulk-operation.json";
|
|
21
|
+
/**
|
|
22
|
+
* How long a lock may go without a heartbeat before it counts as stale.
|
|
23
|
+
*
|
|
24
|
+
* It errs long on purpose: holding a dead lock too long only makes an autocommit skip a tick, while declaring a
|
|
25
|
+
* live one stale splits its operation across two commits.
|
|
26
|
+
*/
|
|
27
|
+
export declare const BULK_OPERATION_LOCK_STALE_AFTER_IN_MILLISECONDS = 120000;
|
|
28
|
+
/**
|
|
29
|
+
* The trailer key naming the operation id in a bulk-operation commit body.
|
|
30
|
+
*/
|
|
31
|
+
export declare const OPERATION_TRAILER_KEY = "Obsidian-Bulk-Operation";
|
|
32
|
+
/**
|
|
33
|
+
* The trailer key naming the plugin in a bulk-operation commit body.
|
|
34
|
+
*/
|
|
35
|
+
export declare const PLUGIN_TRAILER_KEY = "Obsidian-Plugin";
|
|
36
|
+
/**
|
|
37
|
+
* Parameters for {@link buildOperationCommitMessage}.
|
|
38
|
+
*/
|
|
39
|
+
export interface BuildOperationCommitMessageParams {
|
|
40
|
+
/**
|
|
41
|
+
* The number of files the commit changes.
|
|
42
|
+
*/
|
|
43
|
+
readonly changedFileCount: number;
|
|
44
|
+
/**
|
|
45
|
+
* Whether the operation was interrupted.
|
|
46
|
+
*/
|
|
47
|
+
readonly isInterrupted?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* The operation id, such as `OP12`.
|
|
50
|
+
*/
|
|
51
|
+
readonly operationId: string;
|
|
52
|
+
/**
|
|
53
|
+
* The id of the plugin that ran the operation.
|
|
54
|
+
*/
|
|
55
|
+
readonly pluginId: string;
|
|
56
|
+
/**
|
|
57
|
+
* A one-line description of the operation. Ignored for an interrupted operation.
|
|
58
|
+
*/
|
|
59
|
+
readonly summary?: string;
|
|
60
|
+
/**
|
|
61
|
+
* When the operation ran.
|
|
62
|
+
*/
|
|
63
|
+
readonly timestamp: Date;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A bulk-operation commit found in the repo history.
|
|
67
|
+
*/
|
|
68
|
+
export interface BulkOperationCommit {
|
|
69
|
+
/**
|
|
70
|
+
* The commit date, as an ISO 8601 string.
|
|
71
|
+
*/
|
|
72
|
+
readonly date: string;
|
|
73
|
+
/**
|
|
74
|
+
* Whether the commit records an interrupted operation rather than a completed one.
|
|
75
|
+
*/
|
|
76
|
+
readonly isInterrupted: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* The operation id, such as `OP12`.
|
|
79
|
+
*/
|
|
80
|
+
readonly operationId: string;
|
|
81
|
+
/**
|
|
82
|
+
* The full commit hash.
|
|
83
|
+
*/
|
|
84
|
+
readonly sha: string;
|
|
85
|
+
/**
|
|
86
|
+
* The commit subject.
|
|
87
|
+
*/
|
|
88
|
+
readonly subject: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The lease-lock record stored in `.git/obsidian-bulk-operation.json` while a bulk operation runs.
|
|
92
|
+
*/
|
|
93
|
+
export interface BulkOperationLock {
|
|
94
|
+
/**
|
|
95
|
+
* When the lock was last refreshed by the operation's progress, as epoch milliseconds.
|
|
96
|
+
*/
|
|
97
|
+
readonly heartbeatAt: number;
|
|
98
|
+
/**
|
|
99
|
+
* The host name of the machine running the operation.
|
|
100
|
+
*/
|
|
101
|
+
readonly host: string;
|
|
102
|
+
/**
|
|
103
|
+
* The operation id, such as `OP12`.
|
|
104
|
+
*/
|
|
105
|
+
readonly operationId: string;
|
|
106
|
+
/**
|
|
107
|
+
* The id of the plugin running the operation.
|
|
108
|
+
*/
|
|
109
|
+
readonly pluginId: string;
|
|
110
|
+
/**
|
|
111
|
+
* The id of the process running Obsidian. Only a fast path for an app crash; staleness never depends on it.
|
|
112
|
+
*/
|
|
113
|
+
readonly processId: number;
|
|
114
|
+
/**
|
|
115
|
+
* When the process running Obsidian started, as epoch milliseconds, so a recycled process id is not mistaken for
|
|
116
|
+
* the original one.
|
|
117
|
+
*/
|
|
118
|
+
readonly processStartedAt: number;
|
|
119
|
+
/**
|
|
120
|
+
* When the operation started, as epoch milliseconds.
|
|
121
|
+
*/
|
|
122
|
+
readonly startedAt: number;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The facts {@link isBulkOperationLockStale} weighs besides the heartbeat.
|
|
126
|
+
*/
|
|
127
|
+
export interface BulkOperationLockStalenessContext {
|
|
128
|
+
/**
|
|
129
|
+
* When this machine last booted, as epoch milliseconds, or `null` when unknown.
|
|
130
|
+
*/
|
|
131
|
+
readonly bootedAt: null | number;
|
|
132
|
+
/**
|
|
133
|
+
* The host name of this machine.
|
|
134
|
+
*/
|
|
135
|
+
readonly host: string;
|
|
136
|
+
/**
|
|
137
|
+
* Whether the process recorded in the lock is still running on this machine, or `null` when it cannot be told.
|
|
138
|
+
*/
|
|
139
|
+
readonly isProcessAlive: (processId: number) => boolean | null;
|
|
140
|
+
/**
|
|
141
|
+
* The current time, as epoch milliseconds.
|
|
142
|
+
*/
|
|
143
|
+
readonly now: number;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* The commit message of one bulk-operation commit.
|
|
147
|
+
*/
|
|
148
|
+
export interface OperationCommitMessage {
|
|
149
|
+
/**
|
|
150
|
+
* The commit body: the timestamp, the plugin and the counts, as git trailers.
|
|
151
|
+
*/
|
|
152
|
+
readonly body: string;
|
|
153
|
+
/**
|
|
154
|
+
* The commit subject.
|
|
155
|
+
*/
|
|
156
|
+
readonly subject: string;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Parameters for {@link parseBulkOperationCommit}.
|
|
160
|
+
*/
|
|
161
|
+
export interface ParseBulkOperationCommitParams {
|
|
162
|
+
/**
|
|
163
|
+
* The commit date, as an ISO 8601 string.
|
|
164
|
+
*/
|
|
165
|
+
readonly date: string;
|
|
166
|
+
/**
|
|
167
|
+
* The full commit hash.
|
|
168
|
+
*/
|
|
169
|
+
readonly sha: string;
|
|
170
|
+
/**
|
|
171
|
+
* The commit subject.
|
|
172
|
+
*/
|
|
173
|
+
readonly subject: string;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Builds the subject of the commit that saves whatever was pending before an operation.
|
|
177
|
+
*
|
|
178
|
+
* @param operationId - The operation id, such as `OP12`.
|
|
179
|
+
* @returns The commit subject.
|
|
180
|
+
*/
|
|
181
|
+
export declare function buildBeforeOperationCommitSubject(operationId: string): string;
|
|
182
|
+
/**
|
|
183
|
+
* Builds the message of the commit recording a bulk operation, or an interrupted one.
|
|
184
|
+
*
|
|
185
|
+
* @param params - The parameters.
|
|
186
|
+
* @returns The commit subject and body.
|
|
187
|
+
*/
|
|
188
|
+
export declare function buildOperationCommitMessage(params: BuildOperationCommitMessageParams): OperationCommitMessage;
|
|
189
|
+
/**
|
|
190
|
+
* Formats an operation id from its number.
|
|
191
|
+
*
|
|
192
|
+
* @param operationNumber - The operation number.
|
|
193
|
+
* @returns The operation id, such as `OP12`.
|
|
194
|
+
*/
|
|
195
|
+
export declare function formatOperationId(operationNumber: number): string;
|
|
196
|
+
/**
|
|
197
|
+
* Finds the next operation id from the subjects of the bulk-operation commits already in the history.
|
|
198
|
+
*
|
|
199
|
+
* @param subjects - Commit subjects; anything that is not a bulk-operation subject is ignored.
|
|
200
|
+
* @returns `OP<n>` with n one past the highest number found, or `OP1` when there is none.
|
|
201
|
+
*/
|
|
202
|
+
export declare function getNextOperationId(subjects: readonly string[]): string;
|
|
203
|
+
/**
|
|
204
|
+
* Checks whether a value has the shape of a {@link BulkOperationLock}.
|
|
205
|
+
*
|
|
206
|
+
* @param value - The value read from the lock file.
|
|
207
|
+
* @returns Whether it is a lock record.
|
|
208
|
+
*/
|
|
209
|
+
export declare function isBulkOperationLock(value: unknown): value is BulkOperationLock;
|
|
210
|
+
/**
|
|
211
|
+
* Decides whether a lease lock is stale, so whoever finds it may commit the leftovers and remove it.
|
|
212
|
+
*
|
|
213
|
+
* The heartbeat is the rule; the reboot and crashed-process checks are only fast paths that shorten the wait, and
|
|
214
|
+
* neither can make a lock with a fresh heartbeat on another machine stale.
|
|
215
|
+
*
|
|
216
|
+
* @param lock - The lock record.
|
|
217
|
+
* @param context - The facts about this machine.
|
|
218
|
+
* @returns Whether the lock is stale.
|
|
219
|
+
*/
|
|
220
|
+
export declare function isBulkOperationLockStale(lock: BulkOperationLock, context: BulkOperationLockStalenessContext): boolean;
|
|
221
|
+
/**
|
|
222
|
+
* Parses a bulk-operation commit subject into the commit it describes, skipping the `chore: before` commits, which
|
|
223
|
+
* are not operations.
|
|
224
|
+
*
|
|
225
|
+
* @param params - The commit's hash, date and subject.
|
|
226
|
+
* @returns The bulk-operation commit, or `null` when the subject is not one.
|
|
227
|
+
*/
|
|
228
|
+
export declare function parseBulkOperationCommit(params: ParseBulkOperationCommitParams): BulkOperationCommit | null;
|
|
229
|
+
/**
|
|
230
|
+
* Parses the operation number out of a bulk-operation commit subject.
|
|
231
|
+
*
|
|
232
|
+
* Recognizes `OP<n>: <summary>`, `OP<n> interrupted` and `chore: before OP<n>`.
|
|
233
|
+
*
|
|
234
|
+
* @param subject - The commit subject.
|
|
235
|
+
* @returns The operation number, or `null` when the subject is not a bulk-operation subject.
|
|
236
|
+
*/
|
|
237
|
+
export declare function parseOperationNumber(subject: string): null | number;
|
|
@@ -106,6 +106,7 @@ __export(command_handlers_exports, {
|
|
|
106
106
|
"global-command-handler": () => global_command_handler,
|
|
107
107
|
"open-demo-vault-command-handler": () => open_demo_vault_command_handler,
|
|
108
108
|
"open-settings-command-handler": () => open_settings_command_handler,
|
|
109
|
+
"undo-bulk-operation-command-handler": () => undo_bulk_operation_command_handler,
|
|
109
110
|
"unlock-active-note-command-handler": () => unlock_active_note_command_handler
|
|
110
111
|
});
|
|
111
112
|
module.exports = __toCommonJS(command_handlers_exports);
|
|
@@ -118,6 +119,7 @@ var folder_command_handler = __toESM(((module) => module && module.__esModule &&
|
|
|
118
119
|
var global_command_handler = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./global-command-handler.cjs')), 1);
|
|
119
120
|
var open_demo_vault_command_handler = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./open-demo-vault-command-handler.cjs')), 1);
|
|
120
121
|
var open_settings_command_handler = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./open-settings-command-handler.cjs')), 1);
|
|
122
|
+
var undo_bulk_operation_command_handler = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./undo-bulk-operation-command-handler.cjs')), 1);
|
|
121
123
|
var unlock_active_note_command_handler = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./unlock-active-note-command-handler.cjs')), 1);
|
|
122
124
|
// Annotate the CommonJS export names for ESM import in node:
|
|
123
125
|
0 && (module.exports = {
|
|
@@ -130,6 +132,7 @@ var unlock_active_note_command_handler = __toESM(((module) => module && module._
|
|
|
130
132
|
"global-command-handler": null,
|
|
131
133
|
"open-demo-vault-command-handler": null,
|
|
132
134
|
"open-settings-command-handler": null,
|
|
135
|
+
"undo-bulk-operation-command-handler": null,
|
|
133
136
|
"unlock-active-note-command-handler": null
|
|
134
137
|
});
|
|
135
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
138
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21tYW5kLWhhbmRsZXJzL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIFRISVMgSVMgQSBHRU5FUkFURUQvQlVORExFRCBGSUxFIEJZIEJVSUxEIFNDUklQVCAqL1xuXG5leHBvcnQgKiBhcyAnYWJzdHJhY3QtZmlsZS1jb21tYW5kLWhhbmRsZXInIGZyb20gJy4vYWJzdHJhY3QtZmlsZS1jb21tYW5kLWhhbmRsZXIudHMnO1xuZXhwb3J0ICogYXMgJ2NvbW1hbmQtaGFuZGxlci1jb21wb25lbnQnIGZyb20gJy4vY29tbWFuZC1oYW5kbGVyLWNvbXBvbmVudC50cyc7XG5leHBvcnQgKiBhcyAnY29tbWFuZC1oYW5kbGVyJyBmcm9tICcuL2NvbW1hbmQtaGFuZGxlci50cyc7XG5leHBvcnQgKiBhcyAnZWRpdG9yLWNvbW1hbmQtaGFuZGxlcicgZnJvbSAnLi9lZGl0b3ItY29tbWFuZC1oYW5kbGVyLnRzJztcbmV4cG9ydCAqIGFzICdmaWxlLWNvbW1hbmQtaGFuZGxlcicgZnJvbSAnLi9maWxlLWNvbW1hbmQtaGFuZGxlci50cyc7XG5leHBvcnQgKiBhcyAnZm9sZGVyLWNvbW1hbmQtaGFuZGxlcicgZnJvbSAnLi9mb2xkZXItY29tbWFuZC1oYW5kbGVyLnRzJztcbmV4cG9ydCAqIGFzICdnbG9iYWwtY29tbWFuZC1oYW5kbGVyJyBmcm9tICcuL2dsb2JhbC1jb21tYW5kLWhhbmRsZXIudHMnO1xuZXhwb3J0ICogYXMgJ29wZW4tZGVtby12YXVsdC1jb21tYW5kLWhhbmRsZXInIGZyb20gJy4vb3Blbi1kZW1vLXZhdWx0LWNvbW1hbmQtaGFuZGxlci50cyc7XG5leHBvcnQgKiBhcyAnb3Blbi1zZXR0aW5ncy1jb21tYW5kLWhhbmRsZXInIGZyb20gJy4vb3Blbi1zZXR0aW5ncy1jb21tYW5kLWhhbmRsZXIudHMnO1xuZXhwb3J0ICogYXMgJ3VuZG8tYnVsay1vcGVyYXRpb24tY29tbWFuZC1oYW5kbGVyJyBmcm9tICcuL3VuZG8tYnVsay1vcGVyYXRpb24tY29tbWFuZC1oYW5kbGVyLnRzJztcbmV4cG9ydCAqIGFzICd1bmxvY2stYWN0aXZlLW5vdGUtY29tbWFuZC1oYW5kbGVyJyBmcm9tICcuL3VubG9jay1hY3RpdmUtbm90ZS1jb21tYW5kLWhhbmRsZXIudHMnO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBLHlDQUFBQTtBQUFBLEVBQUEseUJBQUFDO0FBQUEsRUFBQSxtQ0FBQUM7QUFBQSxFQUFBLGdDQUFBQztBQUFBLEVBQUEsOEJBQUFDO0FBQUEsRUFBQSxnQ0FBQUM7QUFBQSxFQUFBLGdDQUFBQztBQUFBLEVBQUEseUNBQUFDO0FBQUEsRUFBQSx1Q0FBQUM7QUFBQSxFQUFBLDZDQUFBQztBQUFBLEVBQUEsNENBQUFDO0FBQUE7QUFBQTtBQUVBLElBQUFWLGdDQUFpRDtBQUNqRCxJQUFBRSw0QkFBNkM7QUFDN0MsSUFBQUQsa0JBQW1DO0FBQ25DLElBQUFFLHlCQUEwQztBQUMxQyxJQUFBQyx1QkFBd0M7QUFDeEMsSUFBQUMseUJBQTBDO0FBQzFDLElBQUFDLHlCQUEwQztBQUMxQyxJQUFBQyxrQ0FBbUQ7QUFDbkQsSUFBQUMsZ0NBQWlEO0FBQ2pELElBQUFDLHNDQUF1RDtBQUN2RCxJQUFBQyxxQ0FBc0Q7IiwibmFtZXMiOlsiYWJzdHJhY3QtZmlsZS1jb21tYW5kLWhhbmRsZXIiLCJjb21tYW5kLWhhbmRsZXIiLCJjb21tYW5kLWhhbmRsZXItY29tcG9uZW50IiwiZWRpdG9yLWNvbW1hbmQtaGFuZGxlciIsImZpbGUtY29tbWFuZC1oYW5kbGVyIiwiZm9sZGVyLWNvbW1hbmQtaGFuZGxlciIsImdsb2JhbC1jb21tYW5kLWhhbmRsZXIiLCJvcGVuLWRlbW8tdmF1bHQtY29tbWFuZC1oYW5kbGVyIiwib3Blbi1zZXR0aW5ncy1jb21tYW5kLWhhbmRsZXIiLCJ1bmRvLWJ1bGstb3BlcmF0aW9uLWNvbW1hbmQtaGFuZGxlciIsInVubG9jay1hY3RpdmUtbm90ZS1jb21tYW5kLWhhbmRsZXIiXX0=
|
|
@@ -8,4 +8,5 @@ export * as 'folder-command-handler' from './folder-command-handler.cjs';
|
|
|
8
8
|
export * as 'global-command-handler' from './global-command-handler.cjs';
|
|
9
9
|
export * as 'open-demo-vault-command-handler' from './open-demo-vault-command-handler.cjs';
|
|
10
10
|
export * as 'open-settings-command-handler' from './open-settings-command-handler.cjs';
|
|
11
|
+
export * as 'undo-bulk-operation-command-handler' from './undo-bulk-operation-command-handler.cjs';
|
|
11
12
|
export * as 'unlock-active-note-command-handler' from './unlock-active-note-command-handler.cjs';
|