obsidian-dev-utils 97.0.0 → 99.0.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.
Files changed (143) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +1 -1
  3. package/dist/integration-test-plugin/main.js +686 -439
  4. package/dist/lib/cjs/__merged.cjs +22 -9
  5. package/dist/lib/cjs/__merged.d.cts +4 -3
  6. package/dist/lib/cjs/generated-during-build.cjs +1 -1
  7. package/dist/lib/cjs/obsidian/components/plugin-settings-component.cjs +36 -1
  8. package/dist/lib/cjs/obsidian/components/plugin-settings-component.d.cts +21 -0
  9. package/dist/lib/cjs/obsidian/components/plugin-suggestion-component.cjs +20 -6
  10. package/dist/lib/cjs/obsidian/components/plugin-suggestion-component.d.cts +26 -4
  11. package/dist/lib/cjs/obsidian/components/rename-delete-handler-component.cjs +38 -38
  12. package/dist/lib/cjs/obsidian/demo-vault-naming.cjs +167 -0
  13. package/dist/lib/cjs/obsidian/demo-vault-naming.d.cts +54 -0
  14. package/dist/lib/cjs/obsidian/desktop-demo-vault-opener.cjs +11 -5
  15. package/dist/lib/cjs/obsidian/desktop-demo-vault-opener.d.cts +10 -8
  16. package/dist/lib/cjs/obsidian/desktop-trusted-input.cjs +9 -9
  17. package/dist/lib/cjs/obsidian/desktop-trusted-input.d.cts +23 -4
  18. package/dist/lib/cjs/obsidian/file-change.cjs +6 -6
  19. package/dist/lib/cjs/obsidian/index.cjs +10 -1
  20. package/dist/lib/cjs/obsidian/index.d.cts +3 -0
  21. package/dist/lib/cjs/obsidian/link.cjs +33 -6
  22. package/dist/lib/cjs/obsidian/link.d.cts +35 -0
  23. package/dist/lib/cjs/obsidian/mobile-trusted-input.cjs +195 -0
  24. package/dist/lib/cjs/obsidian/mobile-trusted-input.d.cts +93 -0
  25. package/dist/lib/cjs/obsidian/plugin/obsidian-plugin-repo-paths.cjs +2 -1
  26. package/dist/lib/cjs/obsidian/plugin/obsidian-plugin-repo-paths.d.cts +4 -0
  27. package/dist/lib/cjs/obsidian/reference.cjs +9 -1
  28. package/dist/lib/cjs/obsidian/reference.d.cts +33 -0
  29. package/dist/lib/cjs/obsidian/resource-lock.cjs +122 -122
  30. package/dist/lib/cjs/obsidian/trusted-input.cjs +206 -0
  31. package/dist/lib/cjs/obsidian/trusted-input.d.cts +126 -0
  32. package/dist/lib/cjs/obsidian/validation.cjs +22 -3
  33. package/dist/lib/cjs/obsidian/validation.d.cts +37 -0
  34. package/dist/lib/cjs/obsidian/vault.cjs +4 -1
  35. package/dist/lib/cjs/obsidian/vault.d.cts +8 -1
  36. package/dist/lib/cjs/script-utils/build.cjs +30 -6
  37. package/dist/lib/cjs/script-utils/build.d.cts +5 -0
  38. package/dist/lib/cjs/script-utils/demo-vault.cjs +26 -6
  39. package/dist/lib/cjs/script-utils/demo-vault.d.cts +12 -8
  40. package/dist/lib/cjs/script-utils/exec.cjs +1 -1
  41. package/dist/lib/cjs/script-utils/formatters/dprint.cjs +3 -2
  42. package/dist/lib/cjs/script-utils/index.cjs +4 -1
  43. package/dist/lib/cjs/script-utils/index.d.cts +1 -0
  44. package/dist/lib/cjs/script-utils/linters/cspell.cjs +3 -3
  45. package/dist/lib/cjs/script-utils/linters/eslint-config.cjs +39 -1
  46. package/dist/lib/cjs/script-utils/linters/eslint-rules/index.cjs +16 -1
  47. package/dist/lib/cjs/script-utils/linters/eslint-rules/index.d.cts +5 -0
  48. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-description.cjs +254 -0
  49. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-description.d.cts +54 -0
  50. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-helpers.cjs +217 -0
  51. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-helpers.d.cts +141 -0
  52. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-id.cjs +214 -0
  53. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-id.d.cts +32 -0
  54. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-name.cjs +215 -0
  55. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-name.d.cts +30 -0
  56. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-schema.cjs +318 -0
  57. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-schema.d.cts +45 -0
  58. package/dist/lib/cjs/script-utils/linters/eslint-rules/obsidian-dev-utils-plugin.cjs +9 -1
  59. package/dist/lib/cjs/script-utils/linters/eslint.cjs +3 -2
  60. package/dist/lib/cjs/script-utils/linters/markdownlint.cjs +4 -4
  61. package/dist/lib/cjs/script-utils/nano-staged-config.cjs +7 -5
  62. package/dist/lib/cjs/script-utils/nano-staged-config.d.cts +5 -2
  63. package/dist/lib/cjs/script-utils/npm-run.cjs +4 -3
  64. package/dist/lib/cjs/script-utils/obsidian-dev-utils-repo-paths.cjs +10 -1
  65. package/dist/lib/cjs/script-utils/obsidian-dev-utils-repo-paths.d.cts +37 -1
  66. package/dist/lib/cjs/script-utils/package-manager.cjs +370 -0
  67. package/dist/lib/cjs/script-utils/package-manager.d.cts +93 -0
  68. package/dist/lib/cjs/script-utils/version.cjs +21 -9
  69. package/dist/lib/esm/__merged.d.mts +4 -3
  70. package/dist/lib/esm/__merged.mjs +24 -10
  71. package/dist/lib/esm/generated-during-build.mjs +1 -1
  72. package/dist/lib/esm/obsidian/components/plugin-settings-component.d.mts +21 -0
  73. package/dist/lib/esm/obsidian/components/plugin-settings-component.mjs +36 -1
  74. package/dist/lib/esm/obsidian/components/plugin-suggestion-component.d.mts +26 -4
  75. package/dist/lib/esm/obsidian/components/plugin-suggestion-component.mjs +20 -6
  76. package/dist/lib/esm/obsidian/components/rename-delete-handler-component.mjs +38 -38
  77. package/dist/lib/esm/obsidian/demo-vault-naming.d.mts +54 -0
  78. package/dist/lib/esm/obsidian/demo-vault-naming.mjs +61 -0
  79. package/dist/lib/esm/obsidian/desktop-demo-vault-opener.d.mts +10 -8
  80. package/dist/lib/esm/obsidian/desktop-demo-vault-opener.mjs +14 -5
  81. package/dist/lib/esm/obsidian/desktop-trusted-input.d.mts +23 -4
  82. package/dist/lib/esm/obsidian/desktop-trusted-input.mjs +9 -9
  83. package/dist/lib/esm/obsidian/file-change.mjs +6 -6
  84. package/dist/lib/esm/obsidian/index.d.mts +3 -0
  85. package/dist/lib/esm/obsidian/index.mjs +7 -1
  86. package/dist/lib/esm/obsidian/link.d.mts +35 -0
  87. package/dist/lib/esm/obsidian/link.mjs +38 -7
  88. package/dist/lib/esm/obsidian/mobile-trusted-input.d.mts +93 -0
  89. package/dist/lib/esm/obsidian/mobile-trusted-input.mjs +84 -0
  90. package/dist/lib/esm/obsidian/plugin/obsidian-plugin-repo-paths.d.mts +4 -0
  91. package/dist/lib/esm/obsidian/plugin/obsidian-plugin-repo-paths.mjs +2 -1
  92. package/dist/lib/esm/obsidian/reference.d.mts +33 -0
  93. package/dist/lib/esm/obsidian/reference.mjs +8 -1
  94. package/dist/lib/esm/obsidian/resource-lock.mjs +122 -122
  95. package/dist/lib/esm/obsidian/trusted-input.d.mts +126 -0
  96. package/dist/lib/esm/obsidian/trusted-input.mjs +85 -0
  97. package/dist/lib/esm/obsidian/validation.d.mts +37 -0
  98. package/dist/lib/esm/obsidian/validation.mjs +21 -2
  99. package/dist/lib/esm/obsidian/vault.d.mts +8 -1
  100. package/dist/lib/esm/obsidian/vault.mjs +4 -1
  101. package/dist/lib/esm/script-utils/build.d.mts +5 -0
  102. package/dist/lib/esm/script-utils/build.mjs +30 -6
  103. package/dist/lib/esm/script-utils/demo-vault.d.mts +12 -8
  104. package/dist/lib/esm/script-utils/demo-vault.mjs +29 -6
  105. package/dist/lib/esm/script-utils/exec.mjs +1 -1
  106. package/dist/lib/esm/script-utils/formatters/dprint.mjs +3 -2
  107. package/dist/lib/esm/script-utils/index.d.mts +1 -0
  108. package/dist/lib/esm/script-utils/index.mjs +3 -1
  109. package/dist/lib/esm/script-utils/linters/cspell.mjs +3 -3
  110. package/dist/lib/esm/script-utils/linters/eslint-config.mjs +39 -1
  111. package/dist/lib/esm/script-utils/linters/eslint-rules/index.d.mts +5 -0
  112. package/dist/lib/esm/script-utils/linters/eslint-rules/index.mjs +11 -1
  113. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-description.d.mts +54 -0
  114. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-description.mjs +148 -0
  115. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-helpers.d.mts +141 -0
  116. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-helpers.mjs +92 -0
  117. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-id.d.mts +32 -0
  118. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-id.mjs +111 -0
  119. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-name.d.mts +30 -0
  120. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-name.mjs +112 -0
  121. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-schema.d.mts +45 -0
  122. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-schema.mjs +217 -0
  123. package/dist/lib/esm/script-utils/linters/eslint-rules/obsidian-dev-utils-plugin.mjs +9 -1
  124. package/dist/lib/esm/script-utils/linters/eslint.mjs +3 -2
  125. package/dist/lib/esm/script-utils/linters/markdownlint.mjs +4 -4
  126. package/dist/lib/esm/script-utils/nano-staged-config.d.mts +5 -2
  127. package/dist/lib/esm/script-utils/nano-staged-config.mjs +7 -5
  128. package/dist/lib/esm/script-utils/npm-run.mjs +4 -3
  129. package/dist/lib/esm/script-utils/obsidian-dev-utils-repo-paths.d.mts +37 -1
  130. package/dist/lib/esm/script-utils/obsidian-dev-utils-repo-paths.mjs +10 -1
  131. package/dist/lib/esm/script-utils/package-manager.d.mts +93 -0
  132. package/dist/lib/esm/script-utils/package-manager.mjs +256 -0
  133. package/dist/lib/esm/script-utils/version.mjs +21 -9
  134. package/obsidian/demo-vault-naming/package.json +6 -0
  135. package/obsidian/mobile-trusted-input/package.json +6 -0
  136. package/obsidian/trusted-input/package.json +6 -0
  137. package/package.json +19 -17
  138. package/script-utils/linters/eslint-rules/manifest-description/package.json +6 -0
  139. package/script-utils/linters/eslint-rules/manifest-helpers/package.json +6 -0
  140. package/script-utils/linters/eslint-rules/manifest-id/package.json +6 -0
  141. package/script-utils/linters/eslint-rules/manifest-name/package.json +6 -0
  142. package/script-utils/linters/eslint-rules/manifest-schema/package.json +6 -0
  143. package/script-utils/package-manager/package.json +6 -0
@@ -0,0 +1,206 @@
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
+
6
+ (function () {
7
+ function ensureBrowserProcess() {
8
+ const browserProcess = {
9
+ browser: true,
10
+ cwd() {
11
+ return '/';
12
+ },
13
+ env: {},
14
+ platform: 'android'
15
+ };
16
+
17
+ // eslint-disable-next-line obsidianmd/no-global-this, unicorn/no-unnecessary-global-this -- Must stay `globalThis`-qualified: in the emitted banner a bare `process` is a free identifier, so reading it where the host has none throws a ReferenceError instead of yielding `undefined`. That is the very case this function exists to handle.
18
+ const existingProcess = globalThis.process;
19
+
20
+ if (!existingProcess) {
21
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
22
+ globalThis.process = browserProcess;
23
+ return;
24
+ }
25
+
26
+ if (existingProcess.versions?.node) {
27
+ return;
28
+ }
29
+
30
+ const existingProcessRecord = existingProcess;
31
+
32
+ for (const [key, value] of Object.entries(browserProcess)) {
33
+ existingProcessRecord[key] ??= value;
34
+ }
35
+
36
+ existingProcessRecord['browser'] = true;
37
+ }
38
+
39
+ function keepName($unknown) {
40
+ return $unknown;
41
+ }
42
+
43
+ (function initCjs() {
44
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
45
+ const globalThisRecord = globalThis;
46
+ globalThisRecord['__name'] ??= keepName;
47
+ const originalRequire = require;
48
+ if (originalRequire && !originalRequire.__isPatched) {
49
+ // eslint-disable-next-line no-global-assign, no-implicit-globals -- We need to patch the `require()` function.
50
+ require = Object.assign(
51
+ (id) => requirePatched(id),
52
+ originalRequire,
53
+ {
54
+ __isPatched: true
55
+ }
56
+ );
57
+ }
58
+
59
+ globalThisRecord['__extractDefault'] ??= extractDefault;
60
+
61
+ ensureBrowserProcess();
62
+
63
+ function extractDefault(module) {
64
+ return module && module.__esModule && 'default' in module ? module.default : module;
65
+ }
66
+
67
+ const OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
68
+ '@codemirror/autocomplete',
69
+ '@codemirror/collab',
70
+ '@codemirror/commands',
71
+ '@codemirror/language',
72
+ '@codemirror/lint',
73
+ '@codemirror/search',
74
+ '@codemirror/state',
75
+ '@codemirror/text',
76
+ '@codemirror/view',
77
+ '@lezer/common',
78
+ '@lezer/highlight',
79
+ '@lezer/lr',
80
+ 'obsidian']
81
+ );
82
+
83
+ const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
84
+ '@codemirror/closebrackets',
85
+ '@codemirror/comment',
86
+ '@codemirror/fold',
87
+ '@codemirror/gutter',
88
+ '@codemirror/highlight',
89
+ '@codemirror/history',
90
+ '@codemirror/matchbrackets',
91
+ '@codemirror/panel',
92
+ '@codemirror/rangeset',
93
+ '@codemirror/rectangular-selection',
94
+ '@codemirror/stream-parser',
95
+ '@codemirror/tooltip']
96
+ );
97
+
98
+ function requirePatched(id) {
99
+ if (OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id)) {
100
+ return originalRequire?.(id);
101
+ }
102
+
103
+ // eslint-disable-next-line @typescript-eslint/no-deprecated, obsidianmd/no-global-this -- Need access to app. Actively use globalThis.
104
+ if (globalThis.app.isMobile) {
105
+ if (id === 'process' || id === 'node:process') {
106
+ // eslint-disable-next-line no-console -- Valid usage.
107
+ console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
108
+
109
+ return process;
110
+ }
111
+ } else {
112
+ const module = originalRequire?.(id);
113
+ if (module) {
114
+ return extractDefault(module);
115
+ }
116
+ }
117
+
118
+ // eslint-disable-next-line no-console -- Valid usage.
119
+ console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
120
+ return {};
121
+ }
122
+ })();
123
+ })();
124
+
125
+ "use strict";
126
+ var __create = Object.create;
127
+ var __defProp = Object.defineProperty;
128
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
129
+ var __getOwnPropNames = Object.getOwnPropertyNames;
130
+ var __getProtoOf = Object.getPrototypeOf;
131
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
132
+ var __export = (target, all) => {
133
+ for (var name in all)
134
+ __defProp(target, name, { get: all[name], enumerable: true });
135
+ };
136
+ var __copyProps = (to, from, except, desc) => {
137
+ if (from && typeof from === "object" || typeof from === "function") {
138
+ for (let key of __getOwnPropNames(from))
139
+ if (!__hasOwnProp.call(to, key) && key !== except)
140
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
141
+ }
142
+ return to;
143
+ };
144
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
145
+ // If the importer is in node compatibility mode or this is not an ESM
146
+ // file that has been converted to a CommonJS file using a Babel-
147
+ // compatible transform (i.e. "__esModule" has not been set), then set
148
+ // "default" to the CommonJS "module.exports" for node compatibility.
149
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
150
+ mod
151
+ ));
152
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
153
+ var trusted_input_exports = {};
154
+ __export(trusted_input_exports, {
155
+ clickElement: () => clickElement,
156
+ clickMouse: () => clickMouse,
157
+ hoverElement: () => hoverElement,
158
+ moveMouse: () => moveMouse,
159
+ pressKey: () => pressKey,
160
+ typeIntoEditor: () => typeIntoEditor,
161
+ unhoverElement: () => unhoverElement
162
+ });
163
+ module.exports = __toCommonJS(trusted_input_exports);
164
+ var import_obsidian = require('obsidian');
165
+ async function clickElement(params) {
166
+ const arm = await loadArm();
167
+ await arm.clickElement(params);
168
+ }
169
+ async function clickMouse(params) {
170
+ const arm = await loadArm();
171
+ await arm.clickMouse(params);
172
+ }
173
+ async function hoverElement(params) {
174
+ const arm = await loadArm();
175
+ await arm.hoverElement(params);
176
+ }
177
+ async function moveMouse(params) {
178
+ const arm = await loadArm();
179
+ await arm.moveMouse(params);
180
+ }
181
+ async function pressKey(params) {
182
+ const arm = await loadArm();
183
+ await arm.pressKey(params);
184
+ }
185
+ async function typeIntoEditor(params) {
186
+ const arm = await loadArm();
187
+ await arm.typeIntoEditor(params);
188
+ }
189
+ async function unhoverElement(params) {
190
+ const arm = await loadArm();
191
+ await arm.unhoverElement(params);
192
+ }
193
+ async function loadArm() {
194
+ return import_obsidian.Platform.isDesktopApp ? await import("./desktop-trusted-input.cjs") : await import("./mobile-trusted-input.cjs");
195
+ }
196
+ // Annotate the CommonJS export names for ESM import in node:
197
+ 0 && (module.exports = {
198
+ clickElement,
199
+ clickMouse,
200
+ hoverElement,
201
+ moveMouse,
202
+ pressKey,
203
+ typeIntoEditor,
204
+ unhoverElement
205
+ });
206
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL3RydXN0ZWQtaW5wdXQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBUcnVzdGVkIGlucHV0IGhlbHBlcnMgdGhhdCB3b3JrIG9uICoqZWl0aGVyIHBsYXRmb3JtKiogXHUyMDE0IHRoZSBkb2N1bWVudGVkIGVudHJ5IHBvaW50IGZvciBrZXlzdHJva2VzLFxuICogcG9pbnRlciBtb3ZlcyBhbmQgY2xpY2tzIHRoYXQgT2JzaWRpYW4gYWN0dWFsbHkgYmVsaWV2ZXMuXG4gKlxuICogVW50cnVzdGVkIGlucHV0IChgZWxlbWVudC5kaXNwYXRjaEV2ZW50KG5ldyBNb3VzZUV2ZW50KCdjbGljaycpKWApIGlzIHNpbGVudGx5IGlnbm9yZWQgYnkgQ29kZU1pcnJvcixcbiAqIGJ5IHRoZSBDU1MgYDpob3ZlcmAgZW5naW5lIGFuZCBieSBldmVyeSBgZS5pc1RydXN0ZWRgIGd1YXJkIGluIE9ic2lkaWFuLCBzbyBhIHRlc3QgZHJpdmluZyBpdCBleGVyY2lzZXNcbiAqIG5vdGhpbmcgd2hpbGUgc3RpbGwgcGFzc2luZy4gQSB0cnVzdGVkIGV2ZW50IGhhcyB0byBjb21lIGZyb20gb3V0c2lkZSB0aGUgcmVuZGVyZXIsIGFuZCBob3cgaXQgZ2V0c1xuICogdGhlcmUgaXMgcGxhdGZvcm0tc3BlY2lmaWM6IEVsZWN0cm9uJ3MgYHdlYkNvbnRlbnRzLnNlbmRJbnB1dEV2ZW50YCBvbiBkZXNrdG9wLCBhIENEUCBpbmplY3Rpb25cbiAqIHJvdW5kLXRyaXBwZWQgdGhyb3VnaCB0aGUgaGFybmVzcydzIGhvc3QgY2hhbm5lbCBvbiBtb2JpbGUuXG4gKlxuICogVGhpcyBtb2R1bGUgKippbnRlcm5hbGl6ZXMgdGhhdCBzcGxpdCoqIChzZWUgdGhlIHByb2plY3QgYEFHRU5UUy5tZGAgKipMNioqKTogaXQgc3RheXNcbiAqIGNyb3NzLXBsYXRmb3JtLWxvYWRhYmxlIFx1MjAxNCBubyBwbGF0Zm9ybS1vbmx5IG1vZHVsZSBpcyBvbiBpdHMgaW1wb3J0IGdyYXBoIFx1MjAxNCBhbmQgZWFjaCBoZWxwZXIgZGVmZXJzIHRvIGFcbiAqIGBQbGF0Zm9ybWAtZ2F0ZWQgY2FsbC10aW1lIGR5bmFtaWMgYGltcG9ydCgpYCBvZiB0aGUgYXJtIHRoYXQgZml0cy4gU28gYSBjb25zdW1lciB3cml0ZXNcbiAqIGBhd2FpdCBjbGlja0VsZW1lbnQoeyBlbGVtZW50IH0pYCBvbmNlIGFuZCBuZXZlciBhIHBsYXRmb3JtIGNoZWNrLlxuICpcbiAqIFRoZSBhcm1zIHJlbWFpbiBpbXBvcnRhYmxlIGRpcmVjdGx5LCBmb3IgYSBjYWxsZXIgbWFraW5nIGEgZGVsaWJlcmF0ZSBwbGF0Zm9ybSBjb21taXRtZW50OlxuICoge0BsaW5rIC4vZGVza3RvcC10cnVzdGVkLWlucHV0LnRzIHwgZGVza3RvcC10cnVzdGVkLWlucHV0fSBhbmRcbiAqIHtAbGluayAuL21vYmlsZS10cnVzdGVkLWlucHV0LnRzIHwgbW9iaWxlLXRydXN0ZWQtaW5wdXR9LiBQcmVmZXIgdGhpcyBmYWNhZGUgb3RoZXJ3aXNlLlxuICpcbiAqICoqRXZlcnkgaGVscGVyIG11c3QgYmUgYXdhaXRlZC4qKiBUaGUgZGVza3RvcCBhcm0gaGFzIG5vdGhpbmcgdG8gd2FpdCBmb3IsIGJ1dCB0aGUgbW9iaWxlIGFybSdzXG4gKiBpbmplY3Rpb24gaXMgYSByb3VuZC10cmlwIHRvIHRoZSBob3N0LCBzbyBhIG1pc3NpbmcgYGF3YWl0YCBsZXRzIHRoZSBhc3NlcnRpb24gcnVuIGJlZm9yZSB0aGUgaW5wdXQgaGFzXG4gKiBsYW5kZWQuIFRoZSBzaWduYXR1cmUgaXMgdGhlIHNhbWUgb24gYm90aCBwbGF0Zm9ybXMgcHJlY2lzZWx5IHNvIHRoYXQgYSBzdWl0ZSBncm93aW5nIGEgbW9iaWxlIGxhbmVcbiAqIGRvZXMgbm90IGhhdmUgdG8gYmUgcmV3cml0dGVuLlxuICpcbiAqICoqTm90IGV2ZXJ5IGhlbHBlciBzdXJ2aXZlcyB0aGUgcG9ydC4qKiBgbW92ZU1vdXNlYCwgYGhvdmVyRWxlbWVudGAgYW5kIGB1bmhvdmVyRWxlbWVudGAgKip0aHJvdyoqIG9uXG4gKiBtb2JpbGU6IGEgdG91Y2ggc2NyZWVuIGhhcyBubyBwZXJzaXN0ZW50IHBvaW50ZXIgYW5kIGA6aG92ZXJgIGhhcyBubyB0b3VjaCBlcXVpdmFsZW50LiBUaGV5IHRocm93XG4gKiByYXRoZXIgdGhhbiBuby1vcCwgYmVjYXVzZSBhIHNpbGVudCBuby1vcCBpcyBleGFjdGx5IHRoZSBmYWxzZSBjb25maWRlbmNlIHRydXN0ZWQgaW5wdXQgZXhpc3RzIHRvIGVuZC5cbiAqIEdhdGUgdGhvc2Ugb24gYFBsYXRmb3JtLmlzRGVza3RvcEFwcGAsIG9yIGRyaXZlIHRoZSBlbGVtZW50IHdpdGgge0BsaW5rIGNsaWNrRWxlbWVudH0gaW5zdGVhZC5cbiAqL1xuXG5pbXBvcnQgeyBQbGF0Zm9ybSB9IGZyb20gJ29ic2lkaWFuJztcblxuaW1wb3J0IHR5cGUge1xuICBDbGlja0VsZW1lbnRQYXJhbXMsXG4gIENsaWNrTW91c2VQYXJhbXMsXG4gIEhvdmVyRWxlbWVudFBhcmFtcyxcbiAgTW92ZU1vdXNlUGFyYW1zLFxuICBQcmVzc0tleVBhcmFtcyxcbiAgVHlwZUludG9FZGl0b3JQYXJhbXMsXG4gIFVuaG92ZXJFbGVtZW50UGFyYW1zXG59IGZyb20gJy4vZGVza3RvcC10cnVzdGVkLWlucHV0LnRzJztcblxuZXhwb3J0IHR5cGUge1xuICBDbGlja0VsZW1lbnRQYXJhbXMsXG4gIENsaWNrTW91c2VQYXJhbXMsXG4gIEhvdmVyRWxlbWVudFBhcmFtcyxcbiAgTW91c2VCdXR0b24sXG4gIE1vdmVNb3VzZVBhcmFtcyxcbiAgUHJlc3NLZXlQYXJhbXMsXG4gIFR5cGVJbnRvRWRpdG9yUGFyYW1zLFxuICBVbmhvdmVyRWxlbWVudFBhcmFtc1xufSBmcm9tICcuL2Rlc2t0b3AtdHJ1c3RlZC1pbnB1dC50cyc7XG5cbi8vIFRoZSBzZXZlbiBoZWxwZXJzIGJvdGggYXJtcyBleHBvcnQsIHdpdGggaWRlbnRpY2FsIHNpZ25hdHVyZXMuIFR5cGVkIG9mZiB0aGUgbW9iaWxlIGFybSBiZWNhdXNlIGl0XG4vLyBFeHBvcnRzIG5vdGhpbmcgZWxzZTsgdGhlIGRlc2t0b3AgYXJtIGFkZGl0aW9uYWxseSBleHBvcnRzIHRoZSBwYXJhbWV0ZXIgY29udHJhY3RzIGJvdGggc2hhcmUuXG50eXBlIFRydXN0ZWRJbnB1dEFybSA9IHR5cGVvZiBpbXBvcnQoJy4vbW9iaWxlLXRydXN0ZWQtaW5wdXQudHMnKTtcblxuLyoqXG4gKiBDbGlja3MgdGhlIGNlbnRlciBvZiBhbiBlbGVtZW50IHVzaW5nICoqdHJ1c3RlZCoqIGlucHV0IFx1MjAxNCBFbGVjdHJvbidzIGBzZW5kSW5wdXRFdmVudGAgb24gZGVza3RvcCwgYSBDRFBcbiAqIHRvdWNoIHRhcCBpbiB0aGUgV2ViVmlldyBvbiBtb2JpbGUuXG4gKlxuICogVGhlIGVsZW1lbnQtcmVsYXRpdmUgY291bnRlcnBhcnQgb2Yge0BsaW5rIGNsaWNrTW91c2V9LCBtaXJyb3JpbmcgdGhlIHtAbGluayBtb3ZlTW91c2V9IC9cbiAqIHtAbGluayBob3ZlckVsZW1lbnR9IHNwbGl0LiBVc2Uge0BsaW5rIGNsaWNrTW91c2V9IGRpcmVjdGx5IHdoZW4gdGhlIHBvaW50IHRvIGNsaWNrIGlzICoqbm90KiogdGhlXG4gKiBlbGVtZW50J3MgY2VudGVyIFx1MjAxNCB0aGUgbWFya2Rvd24gZWRpdG9yJ3MgbWFyZ2luLCBmb3IgaW5zdGFuY2UsIGxpZXMgaW5zaWRlIGBjbS5zY3JvbGxET01gIGJ1dCBvdXRzaWRlXG4gKiBgLmNtLXNpemVyYCwgc28gbm8gZWxlbWVudCdzIGNlbnRlciBsYW5kcyBvbiBpdC5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGVsZW1lbnQgdG8gY2xpY2ssIHRoZSBidXR0b24gdG8gcHJlc3MgYW5kIGFueSBtb2RpZmllcnMgdG8gaG9sZC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgY2xpY2sgaGFzIGJlZW4gaW5qZWN0ZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGlja0VsZW1lbnQocGFyYW1zOiBDbGlja0VsZW1lbnRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgYXJtID0gYXdhaXQgbG9hZEFybSgpO1xuICBhd2FpdCBhcm0uY2xpY2tFbGVtZW50KHBhcmFtcyk7XG59XG5cbi8qKlxuICogQ2xpY2tzIGF0IHRoZSBnaXZlbiB2aWV3cG9ydCBjb29yZGluYXRlcyB1c2luZyAqKnRydXN0ZWQqKiBpbnB1dCwgc28gdGhlIHJlbmRlcmVyIHN5bnRoZXNpemVzIGEgcmVhbFxuICogYGNsaWNrYCAob3IgYGNvbnRleHRtZW51YCwgZm9yIHRoZSByaWdodCBidXR0b24pIHdpdGggYGlzVHJ1c3RlZCA9PT0gdHJ1ZWAuXG4gKlxuICogVGhlIGxvdy1sZXZlbCBwcmltaXRpdmU6IG9uZSBjbGljayBhdCBvbmUgcG9pbnQsIHdpdGggbm8gd2FpdGluZyBmb3IgYW55IGVmZmVjdCBcdTIwMTQgY2FsbGVycyBwb2xsIHRoZWlyIG93blxuICogcmVhZGluZXNzIHNpZ25hbC4gUHJlZmVyIHtAbGluayBjbGlja0VsZW1lbnR9IGZvciBlbGVtZW50LXJlbGF0aXZlIGNsaWNrcy5cbiAqXG4gKiBBIHJlYWwgY29udGV4dCBtZW51IGFjdHVhbGx5IG9wZW5zLCBzbyBhIHN1aXRlIGRyaXZpbmcgYSByaWdodCBjbGljayBtdXN0IGNsb3NlIGl0IChvciByZW1vdmUgdGhlXG4gKiBsZWZ0b3ZlciBgLm1lbnVgIGVsZW1lbnQpIGJlZm9yZSB0aGUgbmV4dCB0ZXN0LlxuICpcbiAqICoqT24gbW9iaWxlIHRoZSBidXR0b24gbW9kZWwgZG9lcyBub3Qgc3Vydml2ZSB0aGUgcG9ydCoqOiB0b3VjaCBoYXMgbm8gYnV0dG9ucywgc28gYCdsZWZ0J2AgKHRoZVxuICogZGVmYXVsdCkgaXMgYSAqKnRhcCoqLCBgJ3JpZ2h0J2AgaXMgdGhlICoqbG9uZy1wcmVzcyoqIHRoYXQgb3BlbnMgT2JzaWRpYW4gTW9iaWxlJ3MgY29udGV4dCBtZW51LCBhbmRcbiAqIGAnbWlkZGxlJ2AgdGhyb3dzLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgdmlld3BvcnQgY29vcmRpbmF0ZXMgdG8gY2xpY2sgYXQsIHRoZSBidXR0b24gdG8gcHJlc3MgYW5kIGFueSBtb2RpZmllcnMgdG8gaG9sZC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgY2xpY2sgaGFzIGJlZW4gaW5qZWN0ZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGlja01vdXNlKHBhcmFtczogQ2xpY2tNb3VzZVBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBhcm0gPSBhd2FpdCBsb2FkQXJtKCk7XG4gIGF3YWl0IGFybS5jbGlja01vdXNlKHBhcmFtcyk7XG59XG5cbi8qKlxuICogTW92ZXMgdGhlIHBvaW50ZXIgdG8gdGhlIGNlbnRlciBvZiBhbiBlbGVtZW50IHVzaW5nICoqdHJ1c3RlZCoqIHBvaW50ZXIgaW5wdXQsIHRoZW4gcG9sbHMgdW50aWwgdGhlXG4gKiBlbGVtZW50IGFjdHVhbGx5IG1hdGNoZXMgYDpob3ZlcmAuXG4gKlxuICogKipEZXNrdG9wIG9ubHkqKiBcdTIwMTQgaXQgdGhyb3dzIG9uIG1vYmlsZSwgd2hlcmUgYDpob3ZlcmAgaGFzIG5vIHRvdWNoIGVxdWl2YWxlbnQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBlbGVtZW50IHRvIGhvdmVyLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBlbGVtZW50IG1hdGNoZXMgYDpob3ZlcmAuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBob3ZlckVsZW1lbnQocGFyYW1zOiBIb3ZlckVsZW1lbnRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgYXJtID0gYXdhaXQgbG9hZEFybSgpO1xuICBhd2FpdCBhcm0uaG92ZXJFbGVtZW50KHBhcmFtcyk7XG59XG5cbi8qKlxuICogTW92ZXMgdGhlIHBvaW50ZXIgdG8gdGhlIGdpdmVuIHZpZXdwb3J0IGNvb3JkaW5hdGVzIHVzaW5nIGEgKip0cnVzdGVkKiogcG9pbnRlciBtb3ZlLCBzbyBgOmhvdmVyYCBydWxlc1xuICogZ2VudWluZWx5IGFwcGx5LlxuICpcbiAqIFRoZSBsb3ctbGV2ZWwgcHJpbWl0aXZlOiBhIHNpbmdsZSBtb3ZlIHRoYXQgZG9lcyAqKm5vdCoqIHdhaXQgZm9yIGFueSBzdGF0ZSB0byBzZXR0bGUuIFByZWZlclxuICoge0BsaW5rIGhvdmVyRWxlbWVudH0gLyB7QGxpbmsgdW5ob3ZlckVsZW1lbnR9IGZvciBlbGVtZW50LXJlbGF0aXZlIG1vdmVzLlxuICpcbiAqICoqRGVza3RvcCBvbmx5KiogXHUyMDE0IGl0IHRocm93cyBvbiBtb2JpbGUsIHdoaWNoIGhhcyBubyBwZXJzaXN0ZW50IHBvaW50ZXIgdG8gbW92ZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHZpZXdwb3J0IGNvb3JkaW5hdGVzIHRvIG1vdmUgdG8uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIG1vdmUgaGFzIGJlZW4gaW5qZWN0ZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtb3ZlTW91c2UocGFyYW1zOiBNb3ZlTW91c2VQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgYXJtID0gYXdhaXQgbG9hZEFybSgpO1xuICBhd2FpdCBhcm0ubW92ZU1vdXNlKHBhcmFtcyk7XG59XG5cbi8qKlxuICogUHJlc3NlcyBhIHNpbmdsZSBrZXkgKG9wdGlvbmFsbHkgd2l0aCBtb2RpZmllcnMpIHVzaW5nICoqdHJ1c3RlZCoqIGtleWJvYXJkIGlucHV0LCBmaXJpbmcgdGhlIGZ1bGwgcmVhbFxuICoga2V5IHBpcGVsaW5lIFx1MjAxNCBga2V5ZG93bmAgXHUyMTkyIGBrZXlwcmVzc2AgXHUyMTkyIGBiZWZvcmVpbnB1dGAgXHUyMTkyIGBpbnB1dGAgXHUyMTkyIGBrZXl1cGAuXG4gKlxuICogSXQgaXMgZGVsaXZlcmVkIHRvIHRoZSB3aW5kb3cncyBET00tZm9jdXNlZCBlbGVtZW50LCBzbyB0aGUgY2FsbGVyIGZvY3VzZXMgdGhlIHRhcmdldCBmaXJzdCBhbmQgdGhlblxuICogYXdhaXRzIHRoZSBleHBlY3RlZCBlZmZlY3Q7IHRoZSBwcmVzcyBpdHNlbGYgcG9sbHMgZm9yIG5vdGhpbmcuIE9uIG1vYmlsZSB0aGUgYWNjZXB0ZWQga2V5cyBhcmUgdGhlXG4gKiBuYW1lZCBvbmVzIChgJ0VudGVyJ2AsIGAnRXNjYXBlJ2AsIGAnVGFiJ2AsIGAnQmFja3NwYWNlJ2AsIGAnRGVsZXRlJ2AsIHRoZSBhcnJvd3MpIHBsdXMgc2luZ2xlIHByaW50YWJsZVxuICogY2hhcmFjdGVycyBcdTIwMTQgYW55dGhpbmcgZWxzZSB0aHJvd3MgcmF0aGVyIHRoYW4gcHJlc3Npbmcgbm90aGluZy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGtleSB0byBwcmVzcyBhbmQgYW55IG1vZGlmaWVycyB0byBob2xkLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBrZXkgcHJlc3MgaGFzIGJlZW4gaW5qZWN0ZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcmVzc0tleShwYXJhbXM6IFByZXNzS2V5UGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGFybSA9IGF3YWl0IGxvYWRBcm0oKTtcbiAgYXdhaXQgYXJtLnByZXNzS2V5KHBhcmFtcyk7XG59XG5cbi8qKlxuICogVHlwZXMgdGV4dCBpbnRvIGEgQ29kZU1pcnJvciBlZGl0b3IgdXNpbmcgKip0cnVzdGVkKioga2V5Ym9hcmQgaW5wdXQuXG4gKlxuICogRm9jdXNlcyB0aGUgZWRpdG9yIChjYXJldCB0byB0aGUgZW5kKSBhbmQgcHJlc3NlcyBldmVyeSBjb2RlIHBvaW50IG9mIHRoZSB0ZXh0IFx1MjAxNCB0aGUgc2FtZSB0cnVzdGVkXG4gKiBzZXF1ZW5jZSBhIHJlYWwgdXNlciBwcm9kdWNlcyBcdTIwMTQgc28gdGhlIHRleHQgcmVhY2hlcyB0aGUgZG9jdW1lbnQgKipvbmx5IGlmIHRoZSBlZGl0b3IgZ2VudWluZWx5IGhvbGRzXG4gKiBmb2N1cyoqLiBUaGVuIGl0IHBvbGxzIHVudGlsIHRoZSBkb2N1bWVudCByZWZsZWN0cyB0aGUgaW5wdXQsIG9yIGEgYm91bmRlZCB0aW1lb3V0IGVsYXBzZXMgKHRoZSBleHBlY3RlZFxuICogb3V0Y29tZSB3aGVuIHRoZSBlZGl0b3IgaXMgcmVhZC1vbmx5IG9yIGZvY3VzIHdhcyBzdG9sZW4pLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZWRpdG9yIHRvIHR5cGUgaW50byBhbmQgdGhlIHRleHQgdG8gdHlwZS5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUga2V5c3Ryb2tlcyBoYXZlIHNldHRsZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0eXBlSW50b0VkaXRvcihwYXJhbXM6IFR5cGVJbnRvRWRpdG9yUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGFybSA9IGF3YWl0IGxvYWRBcm0oKTtcbiAgYXdhaXQgYXJtLnR5cGVJbnRvRWRpdG9yKHBhcmFtcyk7XG59XG5cbi8qKlxuICogTW92ZXMgdGhlIHBvaW50ZXIgdG8gYSBwb2ludCBqdXN0IG91dHNpZGUgYW4gZWxlbWVudCdzIGJvdW5kaW5nIGJveCB1c2luZyBhICoqdHJ1c3RlZCoqIHBvaW50ZXIgbW92ZSxcbiAqIHRoZW4gcG9sbHMgdW50aWwgdGhlIGVsZW1lbnQgbm8gbG9uZ2VyIG1hdGNoZXMgYDpob3ZlcmAuXG4gKlxuICogVGhlIGludmVyc2Ugb2Yge0BsaW5rIGhvdmVyRWxlbWVudH0uIFdoZW4gYW4gZWxlbWVudCBzcGFucyB0aGUgZnVsbCB2aWV3cG9ydCAobm8gcG9pbnQgb3V0c2lkZSBpdHMgYm94XG4gKiBpcyByZWFjaGFibGUpLCB1c2Uge0BsaW5rIG1vdmVNb3VzZX0gZGlyZWN0bHkgdG8gbW92ZSB0aGUgcG9pbnRlciB0byBhIGtub3duIGVtcHR5IGNvb3JkaW5hdGUgaW5zdGVhZC5cbiAqXG4gKiAqKkRlc2t0b3Agb25seSoqIFx1MjAxNCBpdCB0aHJvd3Mgb24gbW9iaWxlLCBmb3IgdGhlIHNhbWUgcmVhc29uIHtAbGluayBob3ZlckVsZW1lbnR9IGRvZXMuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBlbGVtZW50IHRvIG1vdmUgdGhlIHBvaW50ZXIgYXdheSBmcm9tLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBlbGVtZW50IG5vIGxvbmdlciBtYXRjaGVzIGA6aG92ZXJgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdW5ob3ZlckVsZW1lbnQocGFyYW1zOiBVbmhvdmVyRWxlbWVudFBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBhcm0gPSBhd2FpdCBsb2FkQXJtKCk7XG4gIGF3YWl0IGFybS51bmhvdmVyRWxlbWVudChwYXJhbXMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBsb2FkQXJtKCk6IFByb21pc2U8VHJ1c3RlZElucHV0QXJtPiB7XG4gIC8vIENvbmRpdGlvbmFsIGltcG9ydCBvZiB0aGUgcGxhdGZvcm0tb25seSBhcm0sIGF0IGNhbGwgdGltZTogbmVpdGhlciBhcm0gaXMgb24gdGhlIG90aGVyIHBsYXRmb3JtJ3NcbiAgLy8gTG9hZCBwYXRoLCBhbmQgdGhlIHNwZWNpZmllcnMgc3RheSBsaXRlcmFsIHNvIGVzYnVpbGQgYnVuZGxlcyBib3RoLlxuICByZXR1cm4gUGxhdGZvcm0uaXNEZXNrdG9wQXBwID8gYXdhaXQgaW1wb3J0KCcuL2Rlc2t0b3AtdHJ1c3RlZC1pbnB1dC50cycpIDogYXdhaXQgaW1wb3J0KCcuL21vYmlsZS10cnVzdGVkLWlucHV0LnRzJyk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFnQ0Esc0JBQXlCO0FBdUN6QixlQUFzQixhQUFhLFFBQTJDO0FBQzVFLFFBQU0sTUFBTSxNQUFNLFFBQVE7QUFDMUIsUUFBTSxJQUFJLGFBQWEsTUFBTTtBQUMvQjtBQW1CQSxlQUFzQixXQUFXLFFBQXlDO0FBQ3hFLFFBQU0sTUFBTSxNQUFNLFFBQVE7QUFDMUIsUUFBTSxJQUFJLFdBQVcsTUFBTTtBQUM3QjtBQVdBLGVBQXNCLGFBQWEsUUFBMkM7QUFDNUUsUUFBTSxNQUFNLE1BQU0sUUFBUTtBQUMxQixRQUFNLElBQUksYUFBYSxNQUFNO0FBQy9CO0FBY0EsZUFBc0IsVUFBVSxRQUF3QztBQUN0RSxRQUFNLE1BQU0sTUFBTSxRQUFRO0FBQzFCLFFBQU0sSUFBSSxVQUFVLE1BQU07QUFDNUI7QUFjQSxlQUFzQixTQUFTLFFBQXVDO0FBQ3BFLFFBQU0sTUFBTSxNQUFNLFFBQVE7QUFDMUIsUUFBTSxJQUFJLFNBQVMsTUFBTTtBQUMzQjtBQWFBLGVBQXNCLGVBQWUsUUFBNkM7QUFDaEYsUUFBTSxNQUFNLE1BQU0sUUFBUTtBQUMxQixRQUFNLElBQUksZUFBZSxNQUFNO0FBQ2pDO0FBY0EsZUFBc0IsZUFBZSxRQUE2QztBQUNoRixRQUFNLE1BQU0sTUFBTSxRQUFRO0FBQzFCLFFBQU0sSUFBSSxlQUFlLE1BQU07QUFDakM7QUFFQSxlQUFlLFVBQW9DO0FBR2pELFNBQU8seUJBQVMsZUFBZSxNQUFNLE9BQU8sNEJBQTRCLElBQUksTUFBTSxPQUFPLDJCQUEyQjtBQUN0SDsiLAogICJuYW1lcyI6IFtdCn0K
@@ -0,0 +1,126 @@
1
+ /// <reference path="../library.d.cts" />
2
+ /**
3
+ * @file
4
+ *
5
+ * Trusted input helpers that work on **either platform** — the documented entry point for keystrokes,
6
+ * pointer moves and clicks that Obsidian actually believes.
7
+ *
8
+ * Untrusted input (`element.dispatchEvent(new MouseEvent('click'))`) is silently ignored by CodeMirror,
9
+ * by the CSS `:hover` engine and by every `e.isTrusted` guard in Obsidian, so a test driving it exercises
10
+ * nothing while still passing. A trusted event has to come from outside the renderer, and how it gets
11
+ * there is platform-specific: Electron's `webContents.sendInputEvent` on desktop, a CDP injection
12
+ * round-tripped through the harness's host channel on mobile.
13
+ *
14
+ * This module **internalizes that split** (see the project `AGENTS.md` **L6**): it stays
15
+ * cross-platform-loadable — no platform-only module is on its import graph — and each helper defers to a
16
+ * `Platform`-gated call-time dynamic `import()` of the arm that fits. So a consumer writes
17
+ * `await clickElement({ element })` once and never a platform check.
18
+ *
19
+ * The arms remain importable directly, for a caller making a deliberate platform commitment:
20
+ * {@link ./desktop-trusted-input.ts | desktop-trusted-input} and
21
+ * {@link ./mobile-trusted-input.ts | mobile-trusted-input}. Prefer this facade otherwise.
22
+ *
23
+ * **Every helper must be awaited.** The desktop arm has nothing to wait for, but the mobile arm's
24
+ * injection is a round-trip to the host, so a missing `await` lets the assertion run before the input has
25
+ * landed. The signature is the same on both platforms precisely so that a suite growing a mobile lane
26
+ * does not have to be rewritten.
27
+ *
28
+ * **Not every helper survives the port.** `moveMouse`, `hoverElement` and `unhoverElement` **throw** on
29
+ * mobile: a touch screen has no persistent pointer and `:hover` has no touch equivalent. They throw
30
+ * rather than no-op, because a silent no-op is exactly the false confidence trusted input exists to end.
31
+ * Gate those on `Platform.isDesktopApp`, or drive the element with {@link clickElement} instead.
32
+ */
33
+ import type { ClickElementParams, ClickMouseParams, HoverElementParams, MoveMouseParams, PressKeyParams, TypeIntoEditorParams, UnhoverElementParams } from './desktop-trusted-input.cjs';
34
+ export type { ClickElementParams, ClickMouseParams, HoverElementParams, MouseButton, MoveMouseParams, PressKeyParams, TypeIntoEditorParams, UnhoverElementParams } from './desktop-trusted-input.cjs';
35
+ /**
36
+ * Clicks the center of an element using **trusted** input — Electron's `sendInputEvent` on desktop, a CDP
37
+ * touch tap in the WebView on mobile.
38
+ *
39
+ * The element-relative counterpart of {@link clickMouse}, mirroring the {@link moveMouse} /
40
+ * {@link hoverElement} split. Use {@link clickMouse} directly when the point to click is **not** the
41
+ * element's center — the markdown editor's margin, for instance, lies inside `cm.scrollDOM` but outside
42
+ * `.cm-sizer`, so no element's center lands on it.
43
+ *
44
+ * @param params - The element to click, the button to press and any modifiers to hold.
45
+ * @returns A {@link Promise} that resolves once the click has been injected.
46
+ */
47
+ export declare function clickElement(params: ClickElementParams): Promise<void>;
48
+ /**
49
+ * Clicks at the given viewport coordinates using **trusted** input, so the renderer synthesizes a real
50
+ * `click` (or `contextmenu`, for the right button) with `isTrusted === true`.
51
+ *
52
+ * The low-level primitive: one click at one point, with no waiting for any effect — callers poll their own
53
+ * readiness signal. Prefer {@link clickElement} for element-relative clicks.
54
+ *
55
+ * A real context menu actually opens, so a suite driving a right click must close it (or remove the
56
+ * leftover `.menu` element) before the next test.
57
+ *
58
+ * **On mobile the button model does not survive the port**: touch has no buttons, so `'left'` (the
59
+ * default) is a **tap**, `'right'` is the **long-press** that opens Obsidian Mobile's context menu, and
60
+ * `'middle'` throws.
61
+ *
62
+ * @param params - The viewport coordinates to click at, the button to press and any modifiers to hold.
63
+ * @returns A {@link Promise} that resolves once the click has been injected.
64
+ */
65
+ export declare function clickMouse(params: ClickMouseParams): Promise<void>;
66
+ /**
67
+ * Moves the pointer to the center of an element using **trusted** pointer input, then polls until the
68
+ * element actually matches `:hover`.
69
+ *
70
+ * **Desktop only** — it throws on mobile, where `:hover` has no touch equivalent.
71
+ *
72
+ * @param params - The element to hover.
73
+ * @returns A {@link Promise} that resolves once the element matches `:hover`.
74
+ */
75
+ export declare function hoverElement(params: HoverElementParams): Promise<void>;
76
+ /**
77
+ * Moves the pointer to the given viewport coordinates using a **trusted** pointer move, so `:hover` rules
78
+ * genuinely apply.
79
+ *
80
+ * The low-level primitive: a single move that does **not** wait for any state to settle. Prefer
81
+ * {@link hoverElement} / {@link unhoverElement} for element-relative moves.
82
+ *
83
+ * **Desktop only** — it throws on mobile, which has no persistent pointer to move.
84
+ *
85
+ * @param params - The viewport coordinates to move to.
86
+ * @returns A {@link Promise} that resolves once the move has been injected.
87
+ */
88
+ export declare function moveMouse(params: MoveMouseParams): Promise<void>;
89
+ /**
90
+ * Presses a single key (optionally with modifiers) using **trusted** keyboard input, firing the full real
91
+ * key pipeline — `keydown` → `keypress` → `beforeinput` → `input` → `keyup`.
92
+ *
93
+ * It is delivered to the window's DOM-focused element, so the caller focuses the target first and then
94
+ * awaits the expected effect; the press itself polls for nothing. On mobile the accepted keys are the
95
+ * named ones (`'Enter'`, `'Escape'`, `'Tab'`, `'Backspace'`, `'Delete'`, the arrows) plus single printable
96
+ * characters — anything else throws rather than pressing nothing.
97
+ *
98
+ * @param params - The key to press and any modifiers to hold.
99
+ * @returns A {@link Promise} that resolves once the key press has been injected.
100
+ */
101
+ export declare function pressKey(params: PressKeyParams): Promise<void>;
102
+ /**
103
+ * Types text into a CodeMirror editor using **trusted** keyboard input.
104
+ *
105
+ * Focuses the editor (caret to the end) and presses every code point of the text — the same trusted
106
+ * sequence a real user produces — so the text reaches the document **only if the editor genuinely holds
107
+ * focus**. Then it polls until the document reflects the input, or a bounded timeout elapses (the expected
108
+ * outcome when the editor is read-only or focus was stolen).
109
+ *
110
+ * @param params - The editor to type into and the text to type.
111
+ * @returns A {@link Promise} that resolves once the keystrokes have settled.
112
+ */
113
+ export declare function typeIntoEditor(params: TypeIntoEditorParams): Promise<void>;
114
+ /**
115
+ * Moves the pointer to a point just outside an element's bounding box using a **trusted** pointer move,
116
+ * then polls until the element no longer matches `:hover`.
117
+ *
118
+ * The inverse of {@link hoverElement}. When an element spans the full viewport (no point outside its box
119
+ * is reachable), use {@link moveMouse} directly to move the pointer to a known empty coordinate instead.
120
+ *
121
+ * **Desktop only** — it throws on mobile, for the same reason {@link hoverElement} does.
122
+ *
123
+ * @param params - The element to move the pointer away from.
124
+ * @returns A {@link Promise} that resolves once the element no longer matches `:hover`.
125
+ */
126
+ export declare function unhoverElement(params: UnhoverElementParams): Promise<void>;
@@ -147,10 +147,14 @@ __export(validation_exports, {
147
147
  WINDOWS_UNSAFE_PATH_CHARS: () => WINDOWS_UNSAFE_PATH_CHARS,
148
148
  getOsAndObsidianUnsafePathCharsRegExp: () => getOsAndObsidianUnsafePathCharsRegExp,
149
149
  getOsUnsafePathCharsRegExp: () => getOsUnsafePathCharsRegExp,
150
- isValidationMessageHolder: () => isValidationMessageHolder
150
+ hasWindowsTrailingChars: () => hasWindowsTrailingChars,
151
+ isValidationMessageHolder: () => isValidationMessageHolder,
152
+ isWindowsReservedName: () => isWindowsReservedName,
153
+ trimWindowsTrailingChars: () => trimWindowsTrailingChars
151
154
  });
152
155
  module.exports = __toCommonJS(validation_exports);
153
156
  var import_obsidian = require('obsidian');
157
+ var import_path = require('../path.cjs');
154
158
  var import_reg_exp = require('../reg-exp.cjs');
155
159
  function isValidationMessageHolder(value) {
156
160
  return value.validationMessage !== void 0;
@@ -158,6 +162,8 @@ function isValidationMessageHolder(value) {
158
162
  const OBSIDIAN_UNSAFE_FILENAME_CHARS = /[#^[\]|]/g;
159
163
  const WINDOWS_UNSAFE_PATH_CHARS = /[*\\/<>:|?"]/g;
160
164
  const UNIX_UNSAFE_PATH_CHARS = /[\0/]/g;
165
+ const WINDOWS_RESERVED_NAME_REG_EXP = /^(?:AUX|COM[1-9]|CON|LPT[1-9]|NUL|PRN)$/i;
166
+ const WINDOWS_TRAILING_CHARS_REG_EXP = /[ .]+$/;
161
167
  function getOsAndObsidianUnsafePathCharsRegExp(isWindows) {
162
168
  return (0, import_reg_exp.oneOf)([
163
169
  getOsUnsafePathCharsRegExp(isWindows),
@@ -168,6 +174,16 @@ function getOsUnsafePathCharsRegExp(isWindows) {
168
174
  isWindows ??= import_obsidian.Platform.isWin;
169
175
  return isWindows ? WINDOWS_UNSAFE_PATH_CHARS : UNIX_UNSAFE_PATH_CHARS;
170
176
  }
177
+ function hasWindowsTrailingChars(name) {
178
+ return WINDOWS_TRAILING_CHARS_REG_EXP.test(name);
179
+ }
180
+ function isWindowsReservedName(name) {
181
+ const trimmedName = trimWindowsTrailingChars(name);
182
+ return WINDOWS_RESERVED_NAME_REG_EXP.test((0, import_path.basename)(trimmedName, (0, import_path.extname)(trimmedName)));
183
+ }
184
+ function trimWindowsTrailingChars(name) {
185
+ return name.replace(WINDOWS_TRAILING_CHARS_REG_EXP, "");
186
+ }
171
187
  // Annotate the CommonJS export names for ESM import in node:
172
188
  0 && (module.exports = {
173
189
  OBSIDIAN_UNSAFE_FILENAME_CHARS,
@@ -175,6 +191,9 @@ function getOsUnsafePathCharsRegExp(isWindows) {
175
191
  WINDOWS_UNSAFE_PATH_CHARS,
176
192
  getOsAndObsidianUnsafePathCharsRegExp,
177
193
  getOsUnsafePathCharsRegExp,
178
- isValidationMessageHolder
194
+ hasWindowsTrailingChars,
195
+ isValidationMessageHolder,
196
+ isWindowsReservedName,
197
+ trimWindowsTrailingChars
179
198
  });
180
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL3ZhbGlkYXRpb24udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBWYWxpZGF0aW9uIHV0aWxpdGllcy5cbiAqL1xuXG5pbXBvcnQgeyBQbGF0Zm9ybSB9IGZyb20gJ29ic2lkaWFuJztcblxuaW1wb3J0IHsgb25lT2YgfSBmcm9tICcuLi9yZWctZXhwLnRzJztcblxuLyoqXG4gKiBIb2xkcyBhIHZhbGlkYXRpb24gbWVzc2FnZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uTWVzc2FnZUhvbGRlciB7XG4gIC8qKlxuICAgKiBBIHZhbGlkYXRpb24gbWVzc2FnZS5cbiAgICovXG4gIHZhbGlkYXRpb25NZXNzYWdlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGEgdmFsaWRhdGlvbiBtZXNzYWdlIGhvbGRlci5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlIGlzIGEgdmFsaWRhdGlvbiBtZXNzYWdlIGhvbGRlciwgYGZhbHNlYCBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkYXRpb25NZXNzYWdlSG9sZGVyKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgVmFsaWRhdGlvbk1lc3NhZ2VIb2xkZXIge1xuICByZXR1cm4gKHZhbHVlIGFzIFBhcnRpYWw8VmFsaWRhdGlvbk1lc3NhZ2VIb2xkZXI+KS52YWxpZGF0aW9uTWVzc2FnZSAhPT0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIE1hdGNoZXMgY2hhcmFjdGVycyB0aGF0IGFyZSBub3Qgc2FmZSB0byB1c2UgaW4gZmlsZSBuYW1lcyB3aXRoaW4gT2JzaWRpYW4uXG4gKi9cbmV4cG9ydCBjb25zdCBPQlNJRElBTl9VTlNBRkVfRklMRU5BTUVfQ0hBUlMgPSAvWyNeW1xcXXxdL2c7XG5cbi8qKlxuICogV2luZG93cy1zcGVjaWZpYyB1bnNhZmUgZmlsZSBuYW1lIHBhdGggY2hhcmFjdGVycy5cbiAqL1xuZXhwb3J0IGNvbnN0IFdJTkRPV1NfVU5TQUZFX1BBVEhfQ0hBUlMgPSAvWypcXFxcLzw+Onw/XCJdL2c7XG5cbi8qKlxuICogVW5peC1zcGVjaWZpYyB1bnNhZmUgZmlsZSBuYW1lIHBhdGggY2hhcmFjdGVycy5cbiAqL1xuZXhwb3J0IGNvbnN0IFVOSVhfVU5TQUZFX1BBVEhfQ0hBUlMgPSAvW1xcMC9dL2c7XG5cbi8qKlxuICogUmV0dXJucyBhIHJlZ2V4cCBtYXRjaGluZyBhbGwgdW5zYWZlIGNoYXJhY3RlcnMgaW4gZmlsZSBuYW1lcy9wYXRocy5cbiAqXG4gKiBJbmNsdWRlcyBib3RoIE9TLXNwZWNpZmljIHJlc3RyaWN0aW9ucyBhbmQgT2JzaWRpYW4tc3BlY2lmaWMgb25lcy5cbiAqXG4gKiBAcGFyYW0gaXNXaW5kb3dzIC0gV2hldGhlciB0byBpbmNsdWRlIFdpbmRvd3Mtc3BlY2lmaWMgcmVzdHJpY3Rpb25zLiBEZWZhdWx0cyB0byBgUGxhdGZvcm0uaXNXaW5gLlxuICogQHJldHVybnMgQSByZWdleHAgbWF0Y2hpbmcgYWxsIHVuc2FmZSBjaGFyYWN0ZXJzIGluIGZpbGUgbmFtZXMvcGF0aHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRPc0FuZE9ic2lkaWFuVW5zYWZlUGF0aENoYXJzUmVnRXhwKGlzV2luZG93cz86IGJvb2xlYW4pOiBSZWdFeHAge1xuICByZXR1cm4gb25lT2YoW1xuICAgIGdldE9zVW5zYWZlUGF0aENoYXJzUmVnRXhwKGlzV2luZG93cyksXG4gICAgT0JTSURJQU5fVU5TQUZFX0ZJTEVOQU1FX0NIQVJTXG4gIF0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSByZWdleHAgbWF0Y2hpbmcgY2hhcmFjdGVycyB0aGF0IGFyZSBub3Qgc2FmZSB0byB1c2UgaW4gZmlsZSBuYW1lcy9wYXRocyBhdCB0aGUgT1MgbGV2ZWwuXG4gKlxuICogQHBhcmFtIGlzV2luZG93cyAtIFdoZXRoZXIgdG8gaW5jbHVkZSBXaW5kb3dzLXNwZWNpZmljIHJlc3RyaWN0aW9ucy4gRGVmYXVsdHMgdG8gYFBsYXRmb3JtLmlzV2luYC5cbiAqIEByZXR1cm5zIEEgcmVnZXhwIG1hdGNoaW5nIGNoYXJhY3RlcnMgdGhhdCBhcmUgbm90IHNhZmUgdG8gdXNlIGluIGZpbGUgbmFtZXMvcGF0aHMgYXQgdGhlIE9TIGxldmVsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0T3NVbnNhZmVQYXRoQ2hhcnNSZWdFeHAoaXNXaW5kb3dzPzogYm9vbGVhbik6IFJlZ0V4cCB7XG4gIGlzV2luZG93cyA/Pz0gUGxhdGZvcm0uaXNXaW47XG4gIHJldHVybiBpc1dpbmRvd3MgPyBXSU5ET1dTX1VOU0FGRV9QQVRIX0NIQVJTIDogVU5JWF9VTlNBRkVfUEFUSF9DSEFSUztcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQU1BLHNCQUF5QjtBQUV6QixxQkFBc0I7QUFrQmYsU0FBUywwQkFBMEIsT0FBa0Q7QUFDMUYsU0FBUSxNQUEyQyxzQkFBc0I7QUFDM0U7QUFLTyxNQUFNLGlDQUFpQztBQUt2QyxNQUFNLDRCQUE0QjtBQUtsQyxNQUFNLHlCQUF5QjtBQVUvQixTQUFTLHNDQUFzQyxXQUE2QjtBQUNqRixhQUFPLHNCQUFNO0FBQUEsSUFDWCwyQkFBMkIsU0FBUztBQUFBLElBQ3BDO0FBQUEsRUFDRixDQUFDO0FBQ0g7QUFRTyxTQUFTLDJCQUEyQixXQUE2QjtBQUN0RSxnQkFBYyx5QkFBUztBQUN2QixTQUFPLFlBQVksNEJBQTRCO0FBQ2pEOyIsCiAgIm5hbWVzIjogW10KfQo=
199
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL3ZhbGlkYXRpb24udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBWYWxpZGF0aW9uIHV0aWxpdGllcy5cbiAqL1xuXG5pbXBvcnQgeyBQbGF0Zm9ybSB9IGZyb20gJ29ic2lkaWFuJztcblxuaW1wb3J0IHtcbiAgYmFzZW5hbWUsXG4gIGV4dG5hbWVcbn0gZnJvbSAnLi4vcGF0aC50cyc7XG5pbXBvcnQgeyBvbmVPZiB9IGZyb20gJy4uL3JlZy1leHAudHMnO1xuXG4vKipcbiAqIEhvbGRzIGEgdmFsaWRhdGlvbiBtZXNzYWdlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb25NZXNzYWdlSG9sZGVyIHtcbiAgLyoqXG4gICAqIEEgdmFsaWRhdGlvbiBtZXNzYWdlLlxuICAgKi9cbiAgdmFsaWRhdGlvbk1lc3NhZ2U6IHN0cmluZztcbn1cblxuLyoqXG4gKiBUeXBlIGd1YXJkIHRvIGNoZWNrIGlmIGEgdmFsdWUgaXMgYSB2YWxpZGF0aW9uIG1lc3NhZ2UgaG9sZGVyLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWUgaXMgYSB2YWxpZGF0aW9uIG1lc3NhZ2UgaG9sZGVyLCBgZmFsc2VgIG90aGVyd2lzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRhdGlvbk1lc3NhZ2VIb2xkZXIodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBWYWxpZGF0aW9uTWVzc2FnZUhvbGRlciB7XG4gIHJldHVybiAodmFsdWUgYXMgUGFydGlhbDxWYWxpZGF0aW9uTWVzc2FnZUhvbGRlcj4pLnZhbGlkYXRpb25NZXNzYWdlICE9PSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogTWF0Y2hlcyBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCBzYWZlIHRvIHVzZSBpbiBmaWxlIG5hbWVzIHdpdGhpbiBPYnNpZGlhbi5cbiAqL1xuZXhwb3J0IGNvbnN0IE9CU0lESUFOX1VOU0FGRV9GSUxFTkFNRV9DSEFSUyA9IC9bI15bXFxdfF0vZztcblxuLyoqXG4gKiBXaW5kb3dzLXNwZWNpZmljIHVuc2FmZSBmaWxlIG5hbWUgcGF0aCBjaGFyYWN0ZXJzLlxuICovXG5leHBvcnQgY29uc3QgV0lORE9XU19VTlNBRkVfUEFUSF9DSEFSUyA9IC9bKlxcXFwvPD46fD9cIl0vZztcblxuLyoqXG4gKiBVbml4LXNwZWNpZmljIHVuc2FmZSBmaWxlIG5hbWUgcGF0aCBjaGFyYWN0ZXJzLlxuICovXG5leHBvcnQgY29uc3QgVU5JWF9VTlNBRkVfUEFUSF9DSEFSUyA9IC9bXFwwL10vZztcblxuLyoqXG4gKiBUaGUgTVMtRE9TIGRldmljZSBuYW1lcyBXaW5kb3dzIHN0aWxsIHJlZnVzZXMgYXMgYSBmaWxlIG5hbWUsIHdpdGggb3Igd2l0aG91dCBhbiBleHRlbnNpb24uXG4gKlxuICogYENPTklOJGAgLyBgQ09OT1VUJGAgYW5kIHRoZSBzdXBlcnNjcmlwdCBgQ09NXHUwMEIyYCBmb3JtcyBhcmUgZGVsaWJlcmF0ZWx5IGFic2VudDogdGhleSBhcmUgYWNjZXB0ZWQgYnlcbiAqIGV2ZXJ5IFdpbmRvd3MgdmVyc2lvbiB0aGF0IHJ1bnMgT2JzaWRpYW4sIGFuZCBtYXRjaGluZyB0aGVtIHdvdWxkIHJlbmFtZSBmaWxlcyB0aGF0IHdvcmsuXG4gKlxuICogVW5saWtlIHRoZSBleHBvcnRlZCBjaGFyYWN0ZXIgc2V0cyBhYm92ZSwgdGhpcyBjYXJyaWVzIG5vIGBnYCBmbGFnLCBzbyBgdGVzdGAgbWF5IGJlIGNhbGxlZCBvbiBpdFxuICogcmVwZWF0ZWRseSBcdTIwMTQgYSBgZ2AtZmxhZ2dlZCByZWdleHAgYWR2YW5jZXMgYGxhc3RJbmRleGAgYW5kIGFuc3dlcnMgZGlmZmVyZW50bHkgb24gY29uc2VjdXRpdmUgY2FsbHMuXG4gKi9cbmNvbnN0IFdJTkRPV1NfUkVTRVJWRURfTkFNRV9SRUdfRVhQID0gL14oPzpBVVh8Q09NWzEtOV18Q09OfExQVFsxLTldfE5VTHxQUk4pJC9pO1xuXG4vKipcbiAqIFRoZSB0cmFpbGluZyBkb3RzIGFuZCBzcGFjZXMgV2luZG93cyBzdHJpcHMgZnJvbSBhIG5hbWUgYmVmb3JlIGl0IGRvZXMgYW55dGhpbmcgZWxzZSB3aXRoIGl0LlxuICovXG5jb25zdCBXSU5ET1dTX1RSQUlMSU5HX0NIQVJTX1JFR19FWFAgPSAvWyAuXSskLztcblxuLyoqXG4gKiBSZXR1cm5zIGEgcmVnZXhwIG1hdGNoaW5nIGFsbCB1bnNhZmUgY2hhcmFjdGVycyBpbiBmaWxlIG5hbWVzL3BhdGhzLlxuICpcbiAqIEluY2x1ZGVzIGJvdGggT1Mtc3BlY2lmaWMgcmVzdHJpY3Rpb25zIGFuZCBPYnNpZGlhbi1zcGVjaWZpYyBvbmVzLlxuICpcbiAqIEBwYXJhbSBpc1dpbmRvd3MgLSBXaGV0aGVyIHRvIGluY2x1ZGUgV2luZG93cy1zcGVjaWZpYyByZXN0cmljdGlvbnMuIERlZmF1bHRzIHRvIGBQbGF0Zm9ybS5pc1dpbmAuXG4gKiBAcmV0dXJucyBBIHJlZ2V4cCBtYXRjaGluZyBhbGwgdW5zYWZlIGNoYXJhY3RlcnMgaW4gZmlsZSBuYW1lcy9wYXRocy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE9zQW5kT2JzaWRpYW5VbnNhZmVQYXRoQ2hhcnNSZWdFeHAoaXNXaW5kb3dzPzogYm9vbGVhbik6IFJlZ0V4cCB7XG4gIHJldHVybiBvbmVPZihbXG4gICAgZ2V0T3NVbnNhZmVQYXRoQ2hhcnNSZWdFeHAoaXNXaW5kb3dzKSxcbiAgICBPQlNJRElBTl9VTlNBRkVfRklMRU5BTUVfQ0hBUlNcbiAgXSk7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIHJlZ2V4cCBtYXRjaGluZyBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCBzYWZlIHRvIHVzZSBpbiBmaWxlIG5hbWVzL3BhdGhzIGF0IHRoZSBPUyBsZXZlbC5cbiAqXG4gKiBAcGFyYW0gaXNXaW5kb3dzIC0gV2hldGhlciB0byBpbmNsdWRlIFdpbmRvd3Mtc3BlY2lmaWMgcmVzdHJpY3Rpb25zLiBEZWZhdWx0cyB0byBgUGxhdGZvcm0uaXNXaW5gLlxuICogQHJldHVybnMgQSByZWdleHAgbWF0Y2hpbmcgY2hhcmFjdGVycyB0aGF0IGFyZSBub3Qgc2FmZSB0byB1c2UgaW4gZmlsZSBuYW1lcy9wYXRocyBhdCB0aGUgT1MgbGV2ZWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRPc1Vuc2FmZVBhdGhDaGFyc1JlZ0V4cChpc1dpbmRvd3M/OiBib29sZWFuKTogUmVnRXhwIHtcbiAgaXNXaW5kb3dzID8/PSBQbGF0Zm9ybS5pc1dpbjtcbiAgcmV0dXJuIGlzV2luZG93cyA/IFdJTkRPV1NfVU5TQUZFX1BBVEhfQ0hBUlMgOiBVTklYX1VOU0FGRV9QQVRIX0NIQVJTO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgbmFtZSBlbmRzIHdpdGggdGhlIGRvdHMgb3Igc3BhY2VzIFdpbmRvd3MgcmVmdXNlcy5cbiAqXG4gKiBBbnN3ZXJzIGZvciBXaW5kb3dzIHJlZ2FyZGxlc3Mgb2YgdGhlIHBsYXRmb3JtIGluIHVzZTogYSB2YXVsdCBpcyBzeW5jZWQsIHNvIHRoZSBydWxlcyB0aGF0IG1hdHRlciBhcmVcbiAqIG5vdCBuZWNlc3NhcmlseSB0aG9zZSBvZiB0aGUgbWFjaGluZSBhc2tpbmcuXG4gKlxuICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSB0byBjaGVjay4gQSBzaW5nbGUgcGF0aCBzZWdtZW50LCBub3QgYSBwYXRoLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBuYW1lIGVuZHMgd2l0aCBhIGRvdCBvciBhIHNwYWNlLCBgZmFsc2VgIG90aGVyd2lzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1dpbmRvd3NUcmFpbGluZ0NoYXJzKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gV0lORE9XU19UUkFJTElOR19DSEFSU19SRUdfRVhQLnRlc3QobmFtZSk7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBuYW1lIGlzIG9uZSBvZiB0aGUgTVMtRE9TIGRldmljZSBuYW1lcyBXaW5kb3dzIHJlZnVzZXMuXG4gKlxuICogVHdvIHN0ZXBzIHRoZSBjYWxsZXIgd291bGQgb3RoZXJ3aXNlIGhhdmUgdG8ga25vdyBhYm91dCBoYXBwZW4gaGVyZTogdHJhaWxpbmcgZG90cyBhbmQgc3BhY2VzIGFyZVxuICogdHJpbW1lZCBCRUZPUkUgdGhlIHRlc3QsIGJlY2F1c2UgV2luZG93cyBzdHJpcHMgdGhlbSBiZWZvcmUgZGVjaWRpbmcgYW5kIGBDT04gYCBpcyB0aGVyZWZvcmUgYXNcbiAqIHJlc2VydmVkIGFzIGBDT05gOyBhbmQgdGhlIGV4dGVuc2lvbiBpcyBkcm9wcGVkLCBiZWNhdXNlIGBDT04ubWRgIGlzIHJlc2VydmVkIHRvby5cbiAqXG4gKiBgQ09OSU4kYCAvIGBDT05PVVQkYCBhbmQgdGhlIHN1cGVyc2NyaXB0IGBDT01cdTAwQjJgIGZvcm1zIGFyZSBkZWxpYmVyYXRlbHkgTk9UIHJlc2VydmVkOiB0aGV5IGFyZSBhY2NlcHRlZFxuICogYnkgZXZlcnkgV2luZG93cyB2ZXJzaW9uIHRoYXQgcnVucyBPYnNpZGlhbiwgYW5kIG1hdGNoaW5nIHRoZW0gd291bGQgcmVuYW1lIGZpbGVzIHRoYXQgd29yay5cbiAqXG4gKiBBbnN3ZXJzIGZvciBXaW5kb3dzIHJlZ2FyZGxlc3Mgb2YgdGhlIHBsYXRmb3JtIGluIHVzZTogYSB2YXVsdCBpcyBzeW5jZWQsIHNvIHRoZSBydWxlcyB0aGF0IG1hdHRlciBhcmVcbiAqIG5vdCBuZWNlc3NhcmlseSB0aG9zZSBvZiB0aGUgbWFjaGluZSBhc2tpbmcuXG4gKlxuICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSB0byBjaGVjay4gQSBzaW5nbGUgcGF0aCBzZWdtZW50LCB3aXRoIG9yIHdpdGhvdXQgaXRzIGV4dGVuc2lvbi5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbmFtZSBpcyByZXNlcnZlZCwgYGZhbHNlYCBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1dpbmRvd3NSZXNlcnZlZE5hbWUobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IHRyaW1tZWROYW1lID0gdHJpbVdpbmRvd3NUcmFpbGluZ0NoYXJzKG5hbWUpO1xuICByZXR1cm4gV0lORE9XU19SRVNFUlZFRF9OQU1FX1JFR19FWFAudGVzdChiYXNlbmFtZSh0cmltbWVkTmFtZSwgZXh0bmFtZSh0cmltbWVkTmFtZSkpKTtcbn1cblxuLyoqXG4gKiBSZW1vdmVzIHRoZSB0cmFpbGluZyBkb3RzIGFuZCBzcGFjZXMgV2luZG93cyByZWZ1c2VzIGZyb20gdGhlIGVuZCBvZiBhIG5hbWUuXG4gKlxuICogVHJpbSBiZWZvcmUgdGVzdGluZyBmb3IgYSByZXNlcnZlZCBuYW1lLCBuZXZlciBhZnRlcjogdHJpbW1pbmcgYWZ0ZXJ3YXJkcyB0dXJucyBhbiBhY2NlcHRlZCBgQ09OIGAgaW50b1xuICogYSByZWplY3RlZCBgQ09OYC4ge0BsaW5rIGlzV2luZG93c1Jlc2VydmVkTmFtZX0gYWxyZWFkeSBkb2VzIHRoaXMgaW50ZXJuYWxseS5cbiAqXG4gKiBAcGFyYW0gbmFtZSAtIFRoZSBuYW1lIHRvIHRyaW0uIEEgc2luZ2xlIHBhdGggc2VnbWVudCwgbm90IGEgcGF0aC5cbiAqIEByZXR1cm5zIFRoZSBuYW1lIHdpdGhvdXQgaXRzIHRyYWlsaW5nIGRvdHMgYW5kIHNwYWNlcywgd2hpY2ggbWF5IGJlIGVtcHR5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJpbVdpbmRvd3NUcmFpbGluZ0NoYXJzKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBuYW1lLnJlcGxhY2UoV0lORE9XU19UUkFJTElOR19DSEFSU19SRUdfRVhQLCAnJyk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFNQSxzQkFBeUI7QUFFekIsa0JBR087QUFDUCxxQkFBc0I7QUFrQmYsU0FBUywwQkFBMEIsT0FBa0Q7QUFDMUYsU0FBUSxNQUEyQyxzQkFBc0I7QUFDM0U7QUFLTyxNQUFNLGlDQUFpQztBQUt2QyxNQUFNLDRCQUE0QjtBQUtsQyxNQUFNLHlCQUF5QjtBQVd0QyxNQUFNLGdDQUFnQztBQUt0QyxNQUFNLGlDQUFpQztBQVVoQyxTQUFTLHNDQUFzQyxXQUE2QjtBQUNqRixhQUFPLHNCQUFNO0FBQUEsSUFDWCwyQkFBMkIsU0FBUztBQUFBLElBQ3BDO0FBQUEsRUFDRixDQUFDO0FBQ0g7QUFRTyxTQUFTLDJCQUEyQixXQUE2QjtBQUN0RSxnQkFBYyx5QkFBUztBQUN2QixTQUFPLFlBQVksNEJBQTRCO0FBQ2pEO0FBV08sU0FBUyx3QkFBd0IsTUFBdUI7QUFDN0QsU0FBTywrQkFBK0IsS0FBSyxJQUFJO0FBQ2pEO0FBa0JPLFNBQVMsc0JBQXNCLE1BQXVCO0FBQzNELFFBQU0sY0FBYyx5QkFBeUIsSUFBSTtBQUNqRCxTQUFPLDhCQUE4QixTQUFLLHNCQUFTLGlCQUFhLHFCQUFRLFdBQVcsQ0FBQyxDQUFDO0FBQ3ZGO0FBV08sU0FBUyx5QkFBeUIsTUFBc0I7QUFDN0QsU0FBTyxLQUFLLFFBQVEsZ0NBQWdDLEVBQUU7QUFDeEQ7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -48,3 +48,40 @@ export declare function getOsAndObsidianUnsafePathCharsRegExp(isWindows?: boolea
48
48
  * @returns A regexp matching characters that are not safe to use in file names/paths at the OS level.
49
49
  */
50
50
  export declare function getOsUnsafePathCharsRegExp(isWindows?: boolean): RegExp;
51
+ /**
52
+ * Checks whether a name ends with the dots or spaces Windows refuses.
53
+ *
54
+ * Answers for Windows regardless of the platform in use: a vault is synced, so the rules that matter are
55
+ * not necessarily those of the machine asking.
56
+ *
57
+ * @param name - The name to check. A single path segment, not a path.
58
+ * @returns `true` if the name ends with a dot or a space, `false` otherwise.
59
+ */
60
+ export declare function hasWindowsTrailingChars(name: string): boolean;
61
+ /**
62
+ * Checks whether a name is one of the MS-DOS device names Windows refuses.
63
+ *
64
+ * Two steps the caller would otherwise have to know about happen here: trailing dots and spaces are
65
+ * trimmed BEFORE the test, because Windows strips them before deciding and `CON ` is therefore as
66
+ * reserved as `CON`; and the extension is dropped, because `CON.md` is reserved too.
67
+ *
68
+ * `CONIN$` / `CONOUT$` and the superscript `COM²` forms are deliberately NOT reserved: they are accepted
69
+ * by every Windows version that runs Obsidian, and matching them would rename files that work.
70
+ *
71
+ * Answers for Windows regardless of the platform in use: a vault is synced, so the rules that matter are
72
+ * not necessarily those of the machine asking.
73
+ *
74
+ * @param name - The name to check. A single path segment, with or without its extension.
75
+ * @returns `true` if the name is reserved, `false` otherwise.
76
+ */
77
+ export declare function isWindowsReservedName(name: string): boolean;
78
+ /**
79
+ * Removes the trailing dots and spaces Windows refuses from the end of a name.
80
+ *
81
+ * Trim before testing for a reserved name, never after: trimming afterwards turns an accepted `CON ` into
82
+ * a rejected `CON`. {@link isWindowsReservedName} already does this internally.
83
+ *
84
+ * @param name - The name to trim. A single path segment, not a path.
85
+ * @returns The name without its trailing dots and spaces, which may be empty.
86
+ */
87
+ export declare function trimWindowsTrailingChars(name: string): string;