obsidian-dev-utils 88.6.0 → 88.8.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 (64) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/integration-test-plugin/main.js +309 -190
  3. package/dist/lib/cjs/__merged.cjs +4 -1
  4. package/dist/lib/cjs/__merged.d.cts +1 -0
  5. package/dist/lib/cjs/generated-during-build.cjs +1 -1
  6. package/dist/lib/cjs/obsidian/components/index.cjs +6 -3
  7. package/dist/lib/cjs/obsidian/components/index.d.cts +1 -0
  8. package/dist/lib/cjs/obsidian/components/syntax-highlighting-component.cjs +244 -0
  9. package/dist/lib/cjs/obsidian/components/syntax-highlighting-component.d.cts +149 -0
  10. package/dist/lib/cjs/obsidian/plugin/plugin-settings-tab.cjs +1 -1
  11. package/dist/lib/cjs/script-utils/cli-utils.cjs +9 -1
  12. package/dist/lib/cjs/script-utils/cli-utils.d.cts +6 -0
  13. package/dist/lib/cjs/script-utils/env-toggle.cjs +180 -0
  14. package/dist/lib/cjs/script-utils/env-toggle.d.cts +42 -0
  15. package/dist/lib/cjs/script-utils/git.cjs +156 -0
  16. package/dist/lib/cjs/script-utils/git.d.cts +37 -0
  17. package/dist/lib/cjs/script-utils/index.cjs +7 -1
  18. package/dist/lib/cjs/script-utils/index.d.cts +2 -0
  19. package/dist/lib/cjs/script-utils/linters/cspell.cjs +11 -2
  20. package/dist/lib/cjs/script-utils/linters/cspell.d.cts +7 -0
  21. package/dist/lib/cjs/script-utils/linters/markdownlint-cli2-config.cjs +7 -4
  22. package/dist/lib/cjs/script-utils/linters/markdownlint.cjs +17 -8
  23. package/dist/lib/cjs/script-utils/nano-staged-config.cjs +7 -11
  24. package/dist/lib/cjs/script-utils/nano-staged-config.d.cts +7 -5
  25. package/dist/lib/cjs/script-utils/test-runners/index.cjs +6 -3
  26. package/dist/lib/cjs/script-utils/test-runners/index.d.cts +1 -0
  27. package/dist/lib/cjs/script-utils/test-runners/vitest-config.cjs +328 -0
  28. package/dist/lib/cjs/script-utils/test-runners/vitest-config.d.cts +118 -0
  29. package/dist/lib/esm/__merged.d.mts +1 -0
  30. package/dist/lib/esm/__merged.mjs +3 -1
  31. package/dist/lib/esm/generated-during-build.mjs +1 -1
  32. package/dist/lib/esm/obsidian/components/index.d.mts +1 -0
  33. package/dist/lib/esm/obsidian/components/index.mjs +4 -2
  34. package/dist/lib/esm/obsidian/components/syntax-highlighting-component.d.mts +149 -0
  35. package/dist/lib/esm/obsidian/components/syntax-highlighting-component.mjs +136 -0
  36. package/dist/lib/esm/obsidian/plugin/plugin-settings-tab.mjs +1 -1
  37. package/dist/lib/esm/script-utils/cli-utils.d.mts +6 -0
  38. package/dist/lib/esm/script-utils/cli-utils.mjs +9 -1
  39. package/dist/lib/esm/script-utils/env-toggle.d.mts +42 -0
  40. package/dist/lib/esm/script-utils/env-toggle.mjs +60 -0
  41. package/dist/lib/esm/script-utils/git.d.mts +37 -0
  42. package/dist/lib/esm/script-utils/git.mjs +48 -0
  43. package/dist/lib/esm/script-utils/index.d.mts +2 -0
  44. package/dist/lib/esm/script-utils/index.mjs +5 -1
  45. package/dist/lib/esm/script-utils/linters/cspell.d.mts +7 -0
  46. package/dist/lib/esm/script-utils/linters/cspell.mjs +15 -3
  47. package/dist/lib/esm/script-utils/linters/markdownlint-cli2-config.mjs +7 -4
  48. package/dist/lib/esm/script-utils/linters/markdownlint.mjs +17 -8
  49. package/dist/lib/esm/script-utils/nano-staged-config.d.mts +7 -5
  50. package/dist/lib/esm/script-utils/nano-staged-config.mjs +10 -11
  51. package/dist/lib/esm/script-utils/test-runners/index.d.mts +1 -0
  52. package/dist/lib/esm/script-utils/test-runners/index.mjs +4 -2
  53. package/dist/lib/esm/script-utils/test-runners/vitest-config.d.mts +118 -0
  54. package/dist/lib/esm/script-utils/test-runners/vitest-config.mjs +209 -0
  55. package/dist/templates/dprint.json +2 -2
  56. package/dist/templates/scripts/vitest-config.ts +2 -88
  57. package/obsidian/components/syntax-highlighting-component/package.json +6 -0
  58. package/package.json +2 -2
  59. package/script-utils/env-toggle/package.json +6 -0
  60. package/script-utils/git/package.json +6 -0
  61. package/script-utils/test-runners/vitest-config/package.json +6 -0
  62. package/@types/obsidian/package.json +0 -4
  63. package/dist/lib/cjs/@types/obsidian.d.cts +0 -28
  64. package/dist/lib/esm/@types/obsidian.d.mts +0 -28
@@ -0,0 +1,209 @@
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 initEsm() {
7
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
8
+ if (globalThis.process) {
9
+ return;
10
+ }
11
+
12
+ const browserProcess = {
13
+ browser: true,
14
+ cwd() {
15
+ return '/';
16
+ },
17
+ env: {},
18
+ platform: 'android'
19
+ };
20
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
21
+ globalThis.process = browserProcess;
22
+ })();
23
+
24
+ import process from "node:process";
25
+ import { defineConfig } from "vitest/config";
26
+ const ANDROID_TIMEOUT_IN_MILLISECONDS = 6e4;
27
+ const BIG_TIMEOUT_IN_MILLISECONDS = 3e4;
28
+ const HOOK_TIMEOUT_MULTIPLIER = 4;
29
+ const PERFORMANCE_TIMEOUT_IN_MILLISECONDS = 6e5;
30
+ const ANDROID_TEST_FILES = "src/**/*.android.integration.test.ts";
31
+ const CROSS_PLATFORM_TEST_FILES = "src/**/*.cross-platform.integration.test.ts";
32
+ const DESKTOP_PERFORMANCE_TEST_FILES = "src/**/*.desktop-performance.integration.test.ts";
33
+ const DESKTOP_TEST_FILES = "src/**/*.desktop.integration.test.ts";
34
+ const INTEGRATION_TEST_FILES = "src/**/*.integration.test.ts";
35
+ const NO_APP_TEST_FILES = "src/**/*.no-app.integration.test.ts";
36
+ const UNIT_TEST_FILES = "src/**/*.test.ts";
37
+ const OBSIDIAN_VERSION_ENV_VARIABLE_NAME = "OBSIDIAN_VERSION";
38
+ const SHARED_EXCLUDE = ["node_modules", "dist"];
39
+ class ObsidianPluginVitestConfigContext {
40
+ /**
41
+ * The `integration-tests:android` project, running the mobile-only and cross-platform suites against an
42
+ * Android emulator through Appium.
43
+ */
44
+ android = {
45
+ environment: "node",
46
+ environmentOptions: {
47
+ obsidianTransport: {
48
+ appiumUrl: "http://localhost:4723",
49
+ avdName: "obsidian_test",
50
+ type: "obsidian-android-appium"
51
+ }
52
+ },
53
+ fileParallelism: false,
54
+ globalSetup: ["obsidian-integration-testing/vitest-global-setup-plugin"],
55
+ hookTimeout: ANDROID_TIMEOUT_IN_MILLISECONDS * HOOK_TIMEOUT_MULTIPLIER,
56
+ include: [ANDROID_TEST_FILES, CROSS_PLATFORM_TEST_FILES],
57
+ name: "integration-tests:android",
58
+ setupFiles: ["obsidian-integration-testing/vitest-setup"],
59
+ testTimeout: ANDROID_TIMEOUT_IN_MILLISECONDS
60
+ };
61
+ /**
62
+ * The per-test budget of the Android integration project, in milliseconds. Booting an emulator and
63
+ * driving it over Appium is slower than the desktop path, hence its own constant.
64
+ *
65
+ * @default `60000`
66
+ */
67
+ androidTimeoutInMilliseconds = ANDROID_TIMEOUT_IN_MILLISECONDS;
68
+ /**
69
+ * The per-test budget of the regular integration projects, in milliseconds.
70
+ *
71
+ * @default `30000`
72
+ */
73
+ bigTimeoutInMilliseconds = BIG_TIMEOUT_IN_MILLISECONDS;
74
+ /**
75
+ * The coverage `exclude` globs. Push onto it to drop more files from the coverage report.
76
+ */
77
+ coverageExclude = [UNIT_TEST_FILES];
78
+ /**
79
+ * The `integration-tests:desktop` project, running the desktop-only and cross-platform suites against a
80
+ * real desktop Obsidian over CDP.
81
+ */
82
+ desktop = {
83
+ environment: "node",
84
+ fileParallelism: false,
85
+ globalSetup: ["obsidian-integration-testing/vitest-global-setup-plugin"],
86
+ hookTimeout: BIG_TIMEOUT_IN_MILLISECONDS * HOOK_TIMEOUT_MULTIPLIER,
87
+ include: [DESKTOP_TEST_FILES, CROSS_PLATFORM_TEST_FILES],
88
+ name: "integration-tests:desktop",
89
+ setupFiles: ["obsidian-integration-testing/vitest-setup"],
90
+ testTimeout: BIG_TIMEOUT_IN_MILLISECONDS
91
+ };
92
+ /**
93
+ * The `integration-tests:desktop-performance` project, running the at-scale suites. It is declared for
94
+ * every plugin even when there is no such suite yet — `passWithNoTests` makes an empty project free,
95
+ * and the matching `test:integration:desktop:performance` script exists fleet-wide.
96
+ */
97
+ desktopPerformance = {
98
+ environment: "node",
99
+ fileParallelism: false,
100
+ globalSetup: ["obsidian-integration-testing/vitest-global-setup-plugin"],
101
+ hookTimeout: PERFORMANCE_TIMEOUT_IN_MILLISECONDS,
102
+ include: [DESKTOP_PERFORMANCE_TEST_FILES],
103
+ name: "integration-tests:desktop-performance",
104
+ setupFiles: ["obsidian-integration-testing/vitest-setup"],
105
+ testTimeout: PERFORMANCE_TIMEOUT_IN_MILLISECONDS
106
+ };
107
+ /**
108
+ * The multiplier applied to a project's test budget to get its hook budget. A hook typically populates
109
+ * and opens a vault, so it needs several times what a single test does.
110
+ *
111
+ * @default `4`
112
+ */
113
+ hookTimeoutMultiplier = HOOK_TIMEOUT_MULTIPLIER;
114
+ /**
115
+ * The `integration-tests:no-app` project, running the suites that need no Obsidian instance at all.
116
+ */
117
+ noApp = {
118
+ environment: "node",
119
+ fileParallelism: false,
120
+ hookTimeout: BIG_TIMEOUT_IN_MILLISECONDS * HOOK_TIMEOUT_MULTIPLIER,
121
+ include: [NO_APP_TEST_FILES],
122
+ name: "integration-tests:no-app",
123
+ testTimeout: BIG_TIMEOUT_IN_MILLISECONDS
124
+ };
125
+ /**
126
+ * The per-test budget of the performance integration project, in milliseconds. A performance vault is
127
+ * pre-populated with tens of thousands of notes before Obsidian opens, so both its setup and its tests
128
+ * need far more time than the regular integration projects.
129
+ *
130
+ * @default `600000`
131
+ */
132
+ performanceTimeoutInMilliseconds = PERFORMANCE_TIMEOUT_IN_MILLISECONDS;
133
+ /**
134
+ * The `unit-tests` project, running the mocked-Obsidian suites in `jsdom`.
135
+ */
136
+ unitTests = {
137
+ environment: "jsdom",
138
+ exclude: [...SHARED_EXCLUDE, INTEGRATION_TEST_FILES],
139
+ execArgv: ["--no-webstorage"],
140
+ include: [UNIT_TEST_FILES],
141
+ name: "unit-tests",
142
+ server: {
143
+ deps: {
144
+ inline: ["@obsidian-typings", "obsidian-dev-utils"]
145
+ }
146
+ },
147
+ setupFiles: [
148
+ "obsidian-test-mocks/vitest-setup",
149
+ "obsidian-test-mocks/obsidian-typings/vitest-setup",
150
+ "obsidian-dev-utils/vitest-setup"
151
+ ]
152
+ };
153
+ /**
154
+ * Creates a new context seeded with the standard projects.
155
+ */
156
+ constructor() {
157
+ const obsidianVersion = process.env[OBSIDIAN_VERSION_ENV_VARIABLE_NAME];
158
+ if (obsidianVersion !== void 0) {
159
+ this.desktop.environmentOptions = {
160
+ obsidianTransport: {
161
+ obsidianVersion,
162
+ type: "obsidian-cdp"
163
+ }
164
+ };
165
+ }
166
+ }
167
+ }
168
+ function defineObsidianPluginVitestConfig(options = {}) {
169
+ const context = new ObsidianPluginVitestConfigContext();
170
+ if (options.editContext) {
171
+ options.editContext(context);
172
+ }
173
+ const customProjects = options.customProjects?.(context) ?? [];
174
+ return defineConfig({
175
+ test: {
176
+ coverage: {
177
+ exclude: context.coverageExclude,
178
+ include: ["src/**/*.ts"],
179
+ provider: "v8",
180
+ reporter: ["text", "lcov", "html"],
181
+ reportsDirectory: "./coverage"
182
+ },
183
+ exclude: [...SHARED_EXCLUDE],
184
+ globals: false,
185
+ include: [UNIT_TEST_FILES],
186
+ passWithNoTests: true,
187
+ projects: [
188
+ {
189
+ resolve: {
190
+ alias: {
191
+ obsidian: "obsidian-test-mocks/obsidian"
192
+ }
193
+ },
194
+ test: context.unitTests
195
+ },
196
+ { test: context.noApp },
197
+ { test: context.desktop },
198
+ { test: context.desktopPerformance },
199
+ { test: context.android },
200
+ ...customProjects
201
+ ]
202
+ }
203
+ });
204
+ }
205
+ export {
206
+ ObsidianPluginVitestConfigContext,
207
+ defineObsidianPluginVitestConfig
208
+ };
209
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vc3JjL3NjcmlwdC11dGlscy90ZXN0LXJ1bm5lcnMvdml0ZXN0LWNvbmZpZy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFNoYXJlZCB2aXRlc3QgY29uZmlndXJhdGlvbiBmb3IgT2JzaWRpYW4gcGx1Z2lucy5cbiAqXG4gKiBFdmVyeSBwbHVnaW4gaW4gdGhlIHdvcmtzcGFjZSBkZWNsYXJlcyB0aGUgc2FtZSBmaXZlIHZpdGVzdCBwcm9qZWN0cyBcdTIwMTQgYHVuaXQtdGVzdHNgIHBsdXMgdGhlXG4gKiBgaW50ZWdyYXRpb24tdGVzdHM6e25vLWFwcCxkZXNrdG9wLGRlc2t0b3AtcGVyZm9ybWFuY2UsYW5kcm9pZH1gIGZhbWlseSBcdTIwMTQgd2l0aCB0aGUgc2FtZSB0aW1lb3V0cyxcbiAqIGBzZXR1cEZpbGVzYCwgYW5kIGBnbG9iYWxTZXR1cGAgd2lyaW5nLiBNYWludGFpbmluZyB0aGF0IHBlciByZXBvIG1lYW5zIGEgY29udmVudGlvbiBjaGFuZ2UgY29zdHMgb25lXG4gKiBuZWFyLWlkZW50aWNhbCBlZGl0IHBlciBwbHVnaW4sIGFuZCBhbnkgcmVwbyB0aGF0IGlzIG1pc3NlZCBkcmlmdHMgc2lsZW50bHkuIFRoaXMgbW9kdWxlIG93bnMgdGhhdFxuICogY29uZmlndXJhdGlvbiBvbmNlLCBzbyBhIHBsdWdpbidzIGBzY3JpcHRzL3ZpdGVzdC1jb25maWcudHNgIGNvbGxhcHNlcyB0byBhIHNpbmdsZSBjYWxsLlxuICpcbiAqIFRoZSBzZWFtIG1pcnJvcnMge0BsaW5rIGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL29ic2lkaWFuLWRldi11dGlscyB8IHRoZSBFU0xpbnQgb25lfVxuICogKGBkZWZpbmVFc2xpbnRDb25maWdzYCk6IHRoZSBmYWN0b3J5IGJ1aWxkcyBhIGNvbnRleHQgaG9sZGluZyB0aGUgc3RhbmRhcmQgcHJvamVjdHMsIHRoZSBjYWxsZXIgZWRpdHNcbiAqIGl0IGluIHBsYWNlIHRocm91Z2gge0BsaW5rIERlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnT3B0aW9ucy5lZGl0Q29udGV4dH0sIGFuZCBhcHBlbmRzIGFueVxuICogcHJvamVjdCB0aGUgYmFzZSBkb2VzIG5vdCBrbm93IGFib3V0IHRocm91Z2hcbiAqIHtAbGluayBEZWZpbmVPYnNpZGlhblBsdWdpblZpdGVzdENvbmZpZ09wdGlvbnMuY3VzdG9tUHJvamVjdHN9LlxuICovXG5cbmltcG9ydCB0eXBlIHtcbiAgVGVzdFByb2plY3RDb25maWd1cmF0aW9uLFxuICBUZXN0UHJvamVjdElubGluZUNvbmZpZ3VyYXRpb24sXG4gIFZpdGVVc2VyQ29uZmlnXG59IGZyb20gJ3ZpdGVzdC9jb25maWcnO1xuXG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZXN0L2NvbmZpZyc7XG5cbi8qKlxuICogVGhlIGB0ZXN0YCBzZWN0aW9uIG9mIGEgc2luZ2xlIHZpdGVzdCBwcm9qZWN0IGVudHJ5LlxuICovXG5leHBvcnQgdHlwZSBPYnNpZGlhblBsdWdpblZpdGVzdFByb2plY3RDb25maWcgPSBOb25OdWxsYWJsZTxUZXN0UHJvamVjdElubGluZUNvbmZpZ3VyYXRpb25bJ3Rlc3QnXT47XG5cbmNvbnN0IEFORFJPSURfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSA2MF8wMDA7XG5jb25zdCBCSUdfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAzMF8wMDA7XG5jb25zdCBIT09LX1RJTUVPVVRfTVVMVElQTElFUiA9IDQ7XG5jb25zdCBQRVJGT1JNQU5DRV9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDYwMF8wMDA7XG5cbmNvbnN0IEFORFJPSURfVEVTVF9GSUxFUyA9ICdzcmMvKiovKi5hbmRyb2lkLmludGVncmF0aW9uLnRlc3QudHMnO1xuY29uc3QgQ1JPU1NfUExBVEZPUk1fVEVTVF9GSUxFUyA9ICdzcmMvKiovKi5jcm9zcy1wbGF0Zm9ybS5pbnRlZ3JhdGlvbi50ZXN0LnRzJztcbmNvbnN0IERFU0tUT1BfUEVSRk9STUFOQ0VfVEVTVF9GSUxFUyA9ICdzcmMvKiovKi5kZXNrdG9wLXBlcmZvcm1hbmNlLmludGVncmF0aW9uLnRlc3QudHMnO1xuY29uc3QgREVTS1RPUF9URVNUX0ZJTEVTID0gJ3NyYy8qKi8qLmRlc2t0b3AuaW50ZWdyYXRpb24udGVzdC50cyc7XG5jb25zdCBJTlRFR1JBVElPTl9URVNUX0ZJTEVTID0gJ3NyYy8qKi8qLmludGVncmF0aW9uLnRlc3QudHMnO1xuY29uc3QgTk9fQVBQX1RFU1RfRklMRVMgPSAnc3JjLyoqLyoubm8tYXBwLmludGVncmF0aW9uLnRlc3QudHMnO1xuY29uc3QgVU5JVF9URVNUX0ZJTEVTID0gJ3NyYy8qKi8qLnRlc3QudHMnO1xuXG5jb25zdCBPQlNJRElBTl9WRVJTSU9OX0VOVl9WQVJJQUJMRV9OQU1FID0gJ09CU0lESUFOX1ZFUlNJT04nO1xuY29uc3QgU0hBUkVEX0VYQ0xVREUgPSBbJ25vZGVfbW9kdWxlcycsICdkaXN0J107XG5cbi8qKlxuICogVGhlIG9wdGlvbnMgZm9yIGRlZmluaW5nIGEgcGx1Z2luJ3Mgdml0ZXN0IGNvbmZpZ3VyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGVmaW5lT2JzaWRpYW5QbHVnaW5WaXRlc3RDb25maWdPcHRpb25zIHtcbiAgLyoqXG4gICAqIEEgZnVuY3Rpb24gdGhhdCBidWlsZHMgcHJvamVjdHMgdGhlIGJhc2UgY29uZmlndXJhdGlvbiBkb2VzIG5vdCBrbm93IGFib3V0LCBzdWNoIGFzIGEgcGx1Z2luJ3Mgb3duXG4gICAqIGBpbnRlZ3JhdGlvbi10ZXN0czpkZW1vLXZhdWx0YCBwcm9qZWN0LiBUaGUgcmV0dXJuZWQgcHJvamVjdHMgYXJlIGFwcGVuZGVkIGFmdGVyIHRoZSBzdGFuZGFyZCBmaXZlLlxuICAgKlxuICAgKiBAcGFyYW0gY29udGV4dCAtIFRoZSB2aXRlc3QgY29uZmlndXJhdGlvbiBjb250ZXh0LlxuICAgKiBAcmV0dXJucyBUaGUgZXh0cmEgcHJvamVjdHMuXG4gICAqL1xuICBjdXN0b21Qcm9qZWN0cz8oY29udGV4dDogT2JzaWRpYW5QbHVnaW5WaXRlc3RDb25maWdDb250ZXh0KTogVGVzdFByb2plY3RDb25maWd1cmF0aW9uW107XG5cbiAgLyoqXG4gICAqIEEgZnVuY3Rpb24gdGhhdCBlZGl0cyB0aGUgdml0ZXN0IGNvbmZpZ3VyYXRpb24gY29udGV4dCBiZWZvcmUgaXQgaXMgYXNzZW1ibGVkIGludG8gYSBjb25maWd1cmF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gY29udGV4dCAtIFRoZSB2aXRlc3QgY29uZmlndXJhdGlvbiBjb250ZXh0LlxuICAgKi9cbiAgZWRpdENvbnRleHQ/KGNvbnRleHQ6IE9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnQ29udGV4dCk6IHZvaWQ7XG59XG5cbi8qKlxuICogVGhlIGNvbnRleHQgZm9yIGRlZmluaW5nIGEgcGx1Z2luJ3Mgdml0ZXN0IGNvbmZpZ3VyYXRpb24uXG4gKlxuICogRXZlcnkgbWVtYmVyIGlzIGxpdmU6IHRoZSBhcnJheXMgYW5kIG9iamVjdHMgaXQgZXhwb3NlcyBhcmUgdGhlIHZlcnkgb25lcyB0aGUgYXNzZW1ibGVkIGNvbmZpZ3VyYXRpb25cbiAqIGlzIGJ1aWx0IGZyb20sIHNvIGVkaXRpbmcgdGhlbSBpbiBwbGFjZSB0aHJvdWdoXG4gKiB7QGxpbmsgRGVmaW5lT2JzaWRpYW5QbHVnaW5WaXRlc3RDb25maWdPcHRpb25zLmVkaXRDb250ZXh0fSBpcyB3aGF0IGN1c3RvbWl6ZXMgdGhlIHJlc3VsdC5cbiAqL1xuZXhwb3J0IGNsYXNzIE9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnQ29udGV4dCB7XG4gIC8qKlxuICAgKiBUaGUgYGludGVncmF0aW9uLXRlc3RzOmFuZHJvaWRgIHByb2plY3QsIHJ1bm5pbmcgdGhlIG1vYmlsZS1vbmx5IGFuZCBjcm9zcy1wbGF0Zm9ybSBzdWl0ZXMgYWdhaW5zdCBhblxuICAgKiBBbmRyb2lkIGVtdWxhdG9yIHRocm91Z2ggQXBwaXVtLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFuZHJvaWQ6IE9ic2lkaWFuUGx1Z2luVml0ZXN0UHJvamVjdENvbmZpZyA9IHtcbiAgICBlbnZpcm9ubWVudDogJ25vZGUnLFxuICAgIGVudmlyb25tZW50T3B0aW9uczoge1xuICAgICAgb2JzaWRpYW5UcmFuc3BvcnQ6IHtcbiAgICAgICAgYXBwaXVtVXJsOiAnaHR0cDovL2xvY2FsaG9zdDo0NzIzJyxcbiAgICAgICAgYXZkTmFtZTogJ29ic2lkaWFuX3Rlc3QnLFxuICAgICAgICB0eXBlOiAnb2JzaWRpYW4tYW5kcm9pZC1hcHBpdW0nXG4gICAgICB9XG4gICAgfSxcbiAgICBmaWxlUGFyYWxsZWxpc206IGZhbHNlLFxuICAgIGdsb2JhbFNldHVwOiBbJ29ic2lkaWFuLWludGVncmF0aW9uLXRlc3Rpbmcvdml0ZXN0LWdsb2JhbC1zZXR1cC1wbHVnaW4nXSxcbiAgICBob29rVGltZW91dDogQU5EUk9JRF9USU1FT1VUX0lOX01JTExJU0VDT05EUyAqIEhPT0tfVElNRU9VVF9NVUxUSVBMSUVSLFxuICAgIGluY2x1ZGU6IFtBTkRST0lEX1RFU1RfRklMRVMsIENST1NTX1BMQVRGT1JNX1RFU1RfRklMRVNdLFxuICAgIG5hbWU6ICdpbnRlZ3JhdGlvbi10ZXN0czphbmRyb2lkJyxcbiAgICBzZXR1cEZpbGVzOiBbJ29ic2lkaWFuLWludGVncmF0aW9uLXRlc3Rpbmcvdml0ZXN0LXNldHVwJ10sXG4gICAgdGVzdFRpbWVvdXQ6IEFORFJPSURfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFNcbiAgfTtcblxuICAvKipcbiAgICogVGhlIHBlci10ZXN0IGJ1ZGdldCBvZiB0aGUgQW5kcm9pZCBpbnRlZ3JhdGlvbiBwcm9qZWN0LCBpbiBtaWxsaXNlY29uZHMuIEJvb3RpbmcgYW4gZW11bGF0b3IgYW5kXG4gICAqIGRyaXZpbmcgaXQgb3ZlciBBcHBpdW0gaXMgc2xvd2VyIHRoYW4gdGhlIGRlc2t0b3AgcGF0aCwgaGVuY2UgaXRzIG93biBjb25zdGFudC5cbiAgICpcbiAgICogQGRlZmF1bHQgYDYwMDAwYFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFuZHJvaWRUaW1lb3V0SW5NaWxsaXNlY29uZHMgPSBBTkRST0lEX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuXG4gIC8qKlxuICAgKiBUaGUgcGVyLXRlc3QgYnVkZ2V0IG9mIHRoZSByZWd1bGFyIGludGVncmF0aW9uIHByb2plY3RzLCBpbiBtaWxsaXNlY29uZHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGAzMDAwMGBcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBiaWdUaW1lb3V0SW5NaWxsaXNlY29uZHMgPSBCSUdfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG5cbiAgLyoqXG4gICAqIFRoZSBjb3ZlcmFnZSBgZXhjbHVkZWAgZ2xvYnMuIFB1c2ggb250byBpdCB0byBkcm9wIG1vcmUgZmlsZXMgZnJvbSB0aGUgY292ZXJhZ2UgcmVwb3J0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNvdmVyYWdlRXhjbHVkZTogc3RyaW5nW10gPSBbVU5JVF9URVNUX0ZJTEVTXTtcblxuICAvKipcbiAgICogVGhlIGBpbnRlZ3JhdGlvbi10ZXN0czpkZXNrdG9wYCBwcm9qZWN0LCBydW5uaW5nIHRoZSBkZXNrdG9wLW9ubHkgYW5kIGNyb3NzLXBsYXRmb3JtIHN1aXRlcyBhZ2FpbnN0IGFcbiAgICogcmVhbCBkZXNrdG9wIE9ic2lkaWFuIG92ZXIgQ0RQLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRlc2t0b3A6IE9ic2lkaWFuUGx1Z2luVml0ZXN0UHJvamVjdENvbmZpZyA9IHtcbiAgICBlbnZpcm9ubWVudDogJ25vZGUnLFxuICAgIGZpbGVQYXJhbGxlbGlzbTogZmFsc2UsXG4gICAgZ2xvYmFsU2V0dXA6IFsnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZy92aXRlc3QtZ2xvYmFsLXNldHVwLXBsdWdpbiddLFxuICAgIGhvb2tUaW1lb3V0OiBCSUdfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgKiBIT09LX1RJTUVPVVRfTVVMVElQTElFUixcbiAgICBpbmNsdWRlOiBbREVTS1RPUF9URVNUX0ZJTEVTLCBDUk9TU19QTEFURk9STV9URVNUX0ZJTEVTXSxcbiAgICBuYW1lOiAnaW50ZWdyYXRpb24tdGVzdHM6ZGVza3RvcCcsXG4gICAgc2V0dXBGaWxlczogWydvYnNpZGlhbi1pbnRlZ3JhdGlvbi10ZXN0aW5nL3ZpdGVzdC1zZXR1cCddLFxuICAgIHRlc3RUaW1lb3V0OiBCSUdfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFNcbiAgfTtcblxuICAvKipcbiAgICogVGhlIGBpbnRlZ3JhdGlvbi10ZXN0czpkZXNrdG9wLXBlcmZvcm1hbmNlYCBwcm9qZWN0LCBydW5uaW5nIHRoZSBhdC1zY2FsZSBzdWl0ZXMuIEl0IGlzIGRlY2xhcmVkIGZvclxuICAgKiBldmVyeSBwbHVnaW4gZXZlbiB3aGVuIHRoZXJlIGlzIG5vIHN1Y2ggc3VpdGUgeWV0IFx1MjAxNCBgcGFzc1dpdGhOb1Rlc3RzYCBtYWtlcyBhbiBlbXB0eSBwcm9qZWN0IGZyZWUsXG4gICAqIGFuZCB0aGUgbWF0Y2hpbmcgYHRlc3Q6aW50ZWdyYXRpb246ZGVza3RvcDpwZXJmb3JtYW5jZWAgc2NyaXB0IGV4aXN0cyBmbGVldC13aWRlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRlc2t0b3BQZXJmb3JtYW5jZTogT2JzaWRpYW5QbHVnaW5WaXRlc3RQcm9qZWN0Q29uZmlnID0ge1xuICAgIGVudmlyb25tZW50OiAnbm9kZScsXG4gICAgZmlsZVBhcmFsbGVsaXNtOiBmYWxzZSxcbiAgICBnbG9iYWxTZXR1cDogWydvYnNpZGlhbi1pbnRlZ3JhdGlvbi10ZXN0aW5nL3ZpdGVzdC1nbG9iYWwtc2V0dXAtcGx1Z2luJ10sXG4gICAgaG9va1RpbWVvdXQ6IFBFUkZPUk1BTkNFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTLFxuICAgIGluY2x1ZGU6IFtERVNLVE9QX1BFUkZPUk1BTkNFX1RFU1RfRklMRVNdLFxuICAgIG5hbWU6ICdpbnRlZ3JhdGlvbi10ZXN0czpkZXNrdG9wLXBlcmZvcm1hbmNlJyxcbiAgICBzZXR1cEZpbGVzOiBbJ29ic2lkaWFuLWludGVncmF0aW9uLXRlc3Rpbmcvdml0ZXN0LXNldHVwJ10sXG4gICAgdGVzdFRpbWVvdXQ6IFBFUkZPUk1BTkNFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTXG4gIH07XG5cbiAgLyoqXG4gICAqIFRoZSBtdWx0aXBsaWVyIGFwcGxpZWQgdG8gYSBwcm9qZWN0J3MgdGVzdCBidWRnZXQgdG8gZ2V0IGl0cyBob29rIGJ1ZGdldC4gQSBob29rIHR5cGljYWxseSBwb3B1bGF0ZXNcbiAgICogYW5kIG9wZW5zIGEgdmF1bHQsIHNvIGl0IG5lZWRzIHNldmVyYWwgdGltZXMgd2hhdCBhIHNpbmdsZSB0ZXN0IGRvZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGA0YFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGhvb2tUaW1lb3V0TXVsdGlwbGllciA9IEhPT0tfVElNRU9VVF9NVUxUSVBMSUVSO1xuXG4gIC8qKlxuICAgKiBUaGUgYGludGVncmF0aW9uLXRlc3RzOm5vLWFwcGAgcHJvamVjdCwgcnVubmluZyB0aGUgc3VpdGVzIHRoYXQgbmVlZCBubyBPYnNpZGlhbiBpbnN0YW5jZSBhdCBhbGwuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbm9BcHA6IE9ic2lkaWFuUGx1Z2luVml0ZXN0UHJvamVjdENvbmZpZyA9IHtcbiAgICBlbnZpcm9ubWVudDogJ25vZGUnLFxuICAgIGZpbGVQYXJhbGxlbGlzbTogZmFsc2UsXG4gICAgaG9va1RpbWVvdXQ6IEJJR19USU1FT1VUX0lOX01JTExJU0VDT05EUyAqIEhPT0tfVElNRU9VVF9NVUxUSVBMSUVSLFxuICAgIGluY2x1ZGU6IFtOT19BUFBfVEVTVF9GSUxFU10sXG4gICAgbmFtZTogJ2ludGVncmF0aW9uLXRlc3RzOm5vLWFwcCcsXG4gICAgdGVzdFRpbWVvdXQ6IEJJR19USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICB9O1xuXG4gIC8qKlxuICAgKiBUaGUgcGVyLXRlc3QgYnVkZ2V0IG9mIHRoZSBwZXJmb3JtYW5jZSBpbnRlZ3JhdGlvbiBwcm9qZWN0LCBpbiBtaWxsaXNlY29uZHMuIEEgcGVyZm9ybWFuY2UgdmF1bHQgaXNcbiAgICogcHJlLXBvcHVsYXRlZCB3aXRoIHRlbnMgb2YgdGhvdXNhbmRzIG9mIG5vdGVzIGJlZm9yZSBPYnNpZGlhbiBvcGVucywgc28gYm90aCBpdHMgc2V0dXAgYW5kIGl0cyB0ZXN0c1xuICAgKiBuZWVkIGZhciBtb3JlIHRpbWUgdGhhbiB0aGUgcmVndWxhciBpbnRlZ3JhdGlvbiBwcm9qZWN0cy5cbiAgICpcbiAgICogQGRlZmF1bHQgYDYwMDAwMGBcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwZXJmb3JtYW5jZVRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IFBFUkZPUk1BTkNFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuXG4gIC8qKlxuICAgKiBUaGUgYHVuaXQtdGVzdHNgIHByb2plY3QsIHJ1bm5pbmcgdGhlIG1vY2tlZC1PYnNpZGlhbiBzdWl0ZXMgaW4gYGpzZG9tYC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB1bml0VGVzdHM6IE9ic2lkaWFuUGx1Z2luVml0ZXN0UHJvamVjdENvbmZpZyA9IHtcbiAgICBlbnZpcm9ubWVudDogJ2pzZG9tJyxcbiAgICBleGNsdWRlOiBbLi4uU0hBUkVEX0VYQ0xVREUsIElOVEVHUkFUSU9OX1RFU1RfRklMRVNdLFxuICAgIGV4ZWNBcmd2OiBbJy0tbm8td2Vic3RvcmFnZSddLFxuICAgIGluY2x1ZGU6IFtVTklUX1RFU1RfRklMRVNdLFxuICAgIG5hbWU6ICd1bml0LXRlc3RzJyxcbiAgICBzZXJ2ZXI6IHtcbiAgICAgIGRlcHM6IHtcbiAgICAgICAgaW5saW5lOiBbJ0BvYnNpZGlhbi10eXBpbmdzJywgJ29ic2lkaWFuLWRldi11dGlscyddXG4gICAgICB9XG4gICAgfSxcbiAgICBzZXR1cEZpbGVzOiBbXG4gICAgICAnb2JzaWRpYW4tdGVzdC1tb2Nrcy92aXRlc3Qtc2V0dXAnLFxuICAgICAgJ29ic2lkaWFuLXRlc3QtbW9ja3Mvb2JzaWRpYW4tdHlwaW5ncy92aXRlc3Qtc2V0dXAnLFxuICAgICAgJ29ic2lkaWFuLWRldi11dGlscy92aXRlc3Qtc2V0dXAnXG4gICAgXVxuICB9O1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGNvbnRleHQgc2VlZGVkIHdpdGggdGhlIHN0YW5kYXJkIHByb2plY3RzLlxuICAgKi9cbiAgcHVibGljIGNvbnN0cnVjdG9yKCkge1xuICAgIGNvbnN0IG9ic2lkaWFuVmVyc2lvbiA9IHByb2Nlc3MuZW52W09CU0lESUFOX1ZFUlNJT05fRU5WX1ZBUklBQkxFX05BTUVdO1xuXG4gICAgLypcbiAgICAgKiBTdXBwb3J0IGlzIHRoZSByYW5nZSBbbGF0ZXN0IHB1YmxpYywgbGF0ZXN0IGNhdGFseXN0XSBhbmQgQk9USCBlbmRzIG11c3Qgd29yayAoRzk5KSwgc28gdGhlIHZlcnNpb25cbiAgICAgKiBpcyBhIGtub2IgcmF0aGVyIHRoYW4gYSBjb25zdGFudC4gVGhlIGtleSBpcyBhZGRlZCBPTkxZIHdoZW4gdGhlIHZhcmlhYmxlIGlzIHNldDogYW4gZXhwbGljaXRcbiAgICAgKiBgb2JzaWRpYW5WZXJzaW9uYCBtYWtlcyB0aGUgaGFybmVzcyByZXNvbHZlIGEgY29uY3JldGUgdmVyc2lvbiBhbmQgc3dhcCB0aGUgYXNhciwgd2hpY2ggaXMgbm90IHdoYXRcbiAgICAgKiBhbiB1bnBpbm5lZCBydW4gZG9lcywgc28gc2VlZGluZyBhIGRlZmF1bHQgaGVyZSB3b3VsZCBjaGFuZ2UgdGhlIGJlaGF2aW9yIG9mIGV2ZXJ5IHBsdWdpbi5cbiAgICAgKi9cbiAgICBpZiAob2JzaWRpYW5WZXJzaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuZGVza3RvcC5lbnZpcm9ubWVudE9wdGlvbnMgPSB7XG4gICAgICAgIG9ic2lkaWFuVHJhbnNwb3J0OiB7XG4gICAgICAgICAgb2JzaWRpYW5WZXJzaW9uLFxuICAgICAgICAgIHR5cGU6ICdvYnNpZGlhbi1jZHAnXG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGVmaW5lcyB0aGUgdml0ZXN0IGNvbmZpZ3VyYXRpb24gZm9yIGFuIE9ic2lkaWFuIHBsdWdpbi5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciBkZWZpbmluZyB0aGUgY29uZmlndXJhdGlvbi5cbiAqIEByZXR1cm5zIFRoZSB2aXRlc3QgY29uZmlndXJhdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnKG9wdGlvbnM6IERlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnT3B0aW9ucyA9IHt9KTogVml0ZVVzZXJDb25maWcge1xuICBjb25zdCBjb250ZXh0ID0gbmV3IE9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnQ29udGV4dCgpO1xuXG4gIGlmIChvcHRpb25zLmVkaXRDb250ZXh0KSB7XG4gICAgb3B0aW9ucy5lZGl0Q29udGV4dChjb250ZXh0KTtcbiAgfVxuXG4gIGNvbnN0IGN1c3RvbVByb2plY3RzID0gb3B0aW9ucy5jdXN0b21Qcm9qZWN0cz8uKGNvbnRleHQpID8/IFtdO1xuXG4gIHJldHVybiBkZWZpbmVDb25maWcoe1xuICAgIHRlc3Q6IHtcbiAgICAgIGNvdmVyYWdlOiB7XG4gICAgICAgIGV4Y2x1ZGU6IGNvbnRleHQuY292ZXJhZ2VFeGNsdWRlLFxuICAgICAgICBpbmNsdWRlOiBbJ3NyYy8qKi8qLnRzJ10sXG4gICAgICAgIHByb3ZpZGVyOiAndjgnLFxuICAgICAgICByZXBvcnRlcjogWyd0ZXh0JywgJ2xjb3YnLCAnaHRtbCddLFxuICAgICAgICByZXBvcnRzRGlyZWN0b3J5OiAnLi9jb3ZlcmFnZSdcbiAgICAgIH0sXG4gICAgICBleGNsdWRlOiBbLi4uU0hBUkVEX0VYQ0xVREVdLFxuICAgICAgZ2xvYmFsczogZmFsc2UsXG4gICAgICBpbmNsdWRlOiBbVU5JVF9URVNUX0ZJTEVTXSxcbiAgICAgIHBhc3NXaXRoTm9UZXN0czogdHJ1ZSxcbiAgICAgIHByb2plY3RzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICByZXNvbHZlOiB7XG4gICAgICAgICAgICBhbGlhczoge1xuICAgICAgICAgICAgICBvYnNpZGlhbjogJ29ic2lkaWFuLXRlc3QtbW9ja3Mvb2JzaWRpYW4nXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB0ZXN0OiBjb250ZXh0LnVuaXRUZXN0c1xuICAgICAgICB9LFxuICAgICAgICB7IHRlc3Q6IGNvbnRleHQubm9BcHAgfSxcbiAgICAgICAgeyB0ZXN0OiBjb250ZXh0LmRlc2t0b3AgfSxcbiAgICAgICAgeyB0ZXN0OiBjb250ZXh0LmRlc2t0b3BQZXJmb3JtYW5jZSB9LFxuICAgICAgICB7IHRlc3Q6IGNvbnRleHQuYW5kcm9pZCB9LFxuICAgICAgICAuLi5jdXN0b21Qcm9qZWN0c1xuICAgICAgXVxuICAgIH1cbiAgfSk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXdCQSxPQUFPLGFBQWE7QUFDcEIsU0FBUyxvQkFBb0I7QUFPN0IsTUFBTSxrQ0FBa0M7QUFDeEMsTUFBTSw4QkFBOEI7QUFDcEMsTUFBTSwwQkFBMEI7QUFDaEMsTUFBTSxzQ0FBc0M7QUFFNUMsTUFBTSxxQkFBcUI7QUFDM0IsTUFBTSw0QkFBNEI7QUFDbEMsTUFBTSxpQ0FBaUM7QUFDdkMsTUFBTSxxQkFBcUI7QUFDM0IsTUFBTSx5QkFBeUI7QUFDL0IsTUFBTSxvQkFBb0I7QUFDMUIsTUFBTSxrQkFBa0I7QUFFeEIsTUFBTSxxQ0FBcUM7QUFDM0MsTUFBTSxpQkFBaUIsQ0FBQyxnQkFBZ0IsTUFBTTtBQThCdkMsTUFBTSxrQ0FBa0M7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSzdCLFVBQTZDO0FBQUEsSUFDM0QsYUFBYTtBQUFBLElBQ2Isb0JBQW9CO0FBQUEsTUFDbEIsbUJBQW1CO0FBQUEsUUFDakIsV0FBVztBQUFBLFFBQ1gsU0FBUztBQUFBLFFBQ1QsTUFBTTtBQUFBLE1BQ1I7QUFBQSxJQUNGO0FBQUEsSUFDQSxpQkFBaUI7QUFBQSxJQUNqQixhQUFhLENBQUMseURBQXlEO0FBQUEsSUFDdkUsYUFBYSxrQ0FBa0M7QUFBQSxJQUMvQyxTQUFTLENBQUMsb0JBQW9CLHlCQUF5QjtBQUFBLElBQ3ZELE1BQU07QUFBQSxJQUNOLFlBQVksQ0FBQywyQ0FBMkM7QUFBQSxJQUN4RCxhQUFhO0FBQUEsRUFDZjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBUWdCLCtCQUErQjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU8vQiwyQkFBMkI7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUszQixrQkFBNEIsQ0FBQyxlQUFlO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU01QyxVQUE2QztBQUFBLElBQzNELGFBQWE7QUFBQSxJQUNiLGlCQUFpQjtBQUFBLElBQ2pCLGFBQWEsQ0FBQyx5REFBeUQ7QUFBQSxJQUN2RSxhQUFhLDhCQUE4QjtBQUFBLElBQzNDLFNBQVMsQ0FBQyxvQkFBb0IseUJBQXlCO0FBQUEsSUFDdkQsTUFBTTtBQUFBLElBQ04sWUFBWSxDQUFDLDJDQUEyQztBQUFBLElBQ3hELGFBQWE7QUFBQSxFQUNmO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT2dCLHFCQUF3RDtBQUFBLElBQ3RFLGFBQWE7QUFBQSxJQUNiLGlCQUFpQjtBQUFBLElBQ2pCLGFBQWEsQ0FBQyx5REFBeUQ7QUFBQSxJQUN2RSxhQUFhO0FBQUEsSUFDYixTQUFTLENBQUMsOEJBQThCO0FBQUEsSUFDeEMsTUFBTTtBQUFBLElBQ04sWUFBWSxDQUFDLDJDQUEyQztBQUFBLElBQ3hELGFBQWE7QUFBQSxFQUNmO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFRZ0Isd0JBQXdCO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFLeEIsUUFBMkM7QUFBQSxJQUN6RCxhQUFhO0FBQUEsSUFDYixpQkFBaUI7QUFBQSxJQUNqQixhQUFhLDhCQUE4QjtBQUFBLElBQzNDLFNBQVMsQ0FBQyxpQkFBaUI7QUFBQSxJQUMzQixNQUFNO0FBQUEsSUFDTixhQUFhO0FBQUEsRUFDZjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFTZ0IsbUNBQW1DO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFLbkMsWUFBK0M7QUFBQSxJQUM3RCxhQUFhO0FBQUEsSUFDYixTQUFTLENBQUMsR0FBRyxnQkFBZ0Isc0JBQXNCO0FBQUEsSUFDbkQsVUFBVSxDQUFDLGlCQUFpQjtBQUFBLElBQzVCLFNBQVMsQ0FBQyxlQUFlO0FBQUEsSUFDekIsTUFBTTtBQUFBLElBQ04sUUFBUTtBQUFBLE1BQ04sTUFBTTtBQUFBLFFBQ0osUUFBUSxDQUFDLHFCQUFxQixvQkFBb0I7QUFBQSxNQUNwRDtBQUFBLElBQ0Y7QUFBQSxJQUNBLFlBQVk7QUFBQSxNQUNWO0FBQUEsTUFDQTtBQUFBLE1BQ0E7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBS08sY0FBYztBQUNuQixVQUFNLGtCQUFrQixRQUFRLElBQUksa0NBQWtDO0FBUXRFLFFBQUksb0JBQW9CLFFBQVc7QUFDakMsV0FBSyxRQUFRLHFCQUFxQjtBQUFBLFFBQ2hDLG1CQUFtQjtBQUFBLFVBQ2pCO0FBQUEsVUFDQSxNQUFNO0FBQUEsUUFDUjtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGO0FBUU8sU0FBUyxpQ0FBaUMsVUFBbUQsQ0FBQyxHQUFtQjtBQUN0SCxRQUFNLFVBQVUsSUFBSSxrQ0FBa0M7QUFFdEQsTUFBSSxRQUFRLGFBQWE7QUFDdkIsWUFBUSxZQUFZLE9BQU87QUFBQSxFQUM3QjtBQUVBLFFBQU0saUJBQWlCLFFBQVEsaUJBQWlCLE9BQU8sS0FBSyxDQUFDO0FBRTdELFNBQU8sYUFBYTtBQUFBLElBQ2xCLE1BQU07QUFBQSxNQUNKLFVBQVU7QUFBQSxRQUNSLFNBQVMsUUFBUTtBQUFBLFFBQ2pCLFNBQVMsQ0FBQyxhQUFhO0FBQUEsUUFDdkIsVUFBVTtBQUFBLFFBQ1YsVUFBVSxDQUFDLFFBQVEsUUFBUSxNQUFNO0FBQUEsUUFDakMsa0JBQWtCO0FBQUEsTUFDcEI7QUFBQSxNQUNBLFNBQVMsQ0FBQyxHQUFHLGNBQWM7QUFBQSxNQUMzQixTQUFTO0FBQUEsTUFDVCxTQUFTLENBQUMsZUFBZTtBQUFBLE1BQ3pCLGlCQUFpQjtBQUFBLE1BQ2pCLFVBQVU7QUFBQSxRQUNSO0FBQUEsVUFDRSxTQUFTO0FBQUEsWUFDUCxPQUFPO0FBQUEsY0FDTCxVQUFVO0FBQUEsWUFDWjtBQUFBLFVBQ0Y7QUFBQSxVQUNBLE1BQU0sUUFBUTtBQUFBLFFBQ2hCO0FBQUEsUUFDQSxFQUFFLE1BQU0sUUFBUSxNQUFNO0FBQUEsUUFDdEIsRUFBRSxNQUFNLFFBQVEsUUFBUTtBQUFBLFFBQ3hCLEVBQUUsTUFBTSxRQUFRLG1CQUFtQjtBQUFBLFFBQ25DLEVBQUUsTUFBTSxRQUFRLFFBQVE7QUFBQSxRQUN4QixHQUFHO0FBQUEsTUFDTDtBQUFBLElBQ0Y7QUFBQSxFQUNGLENBQUM7QUFDSDsiLAogICJuYW1lcyI6IFtdCn0K
@@ -12,9 +12,9 @@
12
12
  },
13
13
  "json": {},
14
14
  "markdown": {},
15
+ // dprint respects .gitignore by default (--no-gitignore opts out), so dist and node_modules need no
16
+ // Entry here. Only paths git does NOT ignore belong below.
15
17
  "excludes": [
16
- "dist",
17
- "**/node_modules",
18
18
  "**/*-lock.json",
19
19
  "**/*.md"
20
20
  ],
@@ -1,89 +1,3 @@
1
- import { defineConfig } from 'vitest/config';
1
+ import { defineObsidianPluginVitestConfig } from 'obsidian-dev-utils/script-utils/test-runners/vitest-config';
2
2
 
3
- const SHARED_EXCLUDE = ['node_modules', 'dist'];
4
- const BIG_TIMEOUT_IN_MILLISECONDS = 30_000;
5
- const ANDROID_TIMEOUT_IN_MILLISECONDS = 60_000;
6
- const HOOK_TIMEOUT_MULTIPLIER = 4;
7
-
8
- export const config = defineConfig({
9
- test: {
10
- coverage: {
11
- exclude: [
12
- 'src/**/*.test.ts'
13
- ],
14
- include: ['src/**/*.ts'],
15
- provider: 'v8',
16
- reporter: ['text', 'lcov', 'html'],
17
- reportsDirectory: './coverage'
18
- },
19
- exclude: ['node_modules', 'dist'],
20
- globals: false,
21
- include: ['src/**/*.test.ts'],
22
- passWithNoTests: true,
23
- projects: [
24
- {
25
- resolve: {
26
- alias: {
27
- obsidian: 'obsidian-test-mocks/obsidian'
28
- }
29
- },
30
- test: {
31
- environment: 'jsdom',
32
- exclude: [...SHARED_EXCLUDE, 'src/**/*.integration.test.ts'],
33
- execArgv: ['--no-webstorage'],
34
- include: ['src/**/*.test.ts'],
35
- name: 'unit-tests',
36
- server: {
37
- deps: {
38
- inline: ['@obsidian-typings', 'obsidian-dev-utils']
39
- }
40
- },
41
- setupFiles: [
42
- 'obsidian-test-mocks/vitest-setup',
43
- 'obsidian-test-mocks/obsidian-typings/vitest-setup',
44
- 'obsidian-dev-utils/vitest-setup'
45
- ]
46
- }
47
- },
48
- {
49
- test: {
50
- environment: 'node',
51
- fileParallelism: false,
52
- hookTimeout: BIG_TIMEOUT_IN_MILLISECONDS * HOOK_TIMEOUT_MULTIPLIER,
53
- include: ['src/**/*.no-app.integration.test.ts'],
54
- name: 'integration-tests:no-app',
55
- testTimeout: BIG_TIMEOUT_IN_MILLISECONDS
56
- }
57
- },
58
- {
59
- test: {
60
- environment: 'node',
61
- fileParallelism: false,
62
- globalSetup: ['obsidian-integration-testing/vitest-global-setup-plugin'],
63
- hookTimeout: BIG_TIMEOUT_IN_MILLISECONDS * HOOK_TIMEOUT_MULTIPLIER,
64
- include: ['src/**/*.desktop.integration.test.ts'],
65
- name: 'integration-tests:desktop',
66
- testTimeout: BIG_TIMEOUT_IN_MILLISECONDS
67
- }
68
- },
69
- {
70
- test: {
71
- environment: 'node',
72
- environmentOptions: {
73
- obsidianTransport: {
74
- appiumUrl: 'http://localhost:4723',
75
- avdName: 'obsidian_test',
76
- type: 'obsidian-android-appium'
77
- }
78
- },
79
- fileParallelism: false,
80
- globalSetup: ['obsidian-integration-testing/vitest-global-setup-plugin'],
81
- hookTimeout: ANDROID_TIMEOUT_IN_MILLISECONDS * HOOK_TIMEOUT_MULTIPLIER,
82
- include: ['src/**/*.android.integration.test.ts'],
83
- name: 'integration-tests:android',
84
- testTimeout: ANDROID_TIMEOUT_IN_MILLISECONDS
85
- }
86
- }
87
- ]
88
- }
89
- });
3
+ export const config = defineObsidianPluginVitestConfig();
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../../../dist/lib/cjs/obsidian/components/syntax-highlighting-component.cjs",
3
+ "module": "../../../dist/lib/esm/obsidian/components/syntax-highlighting-component.mjs",
4
+ "type": "module",
5
+ "types": "../../../dist/lib/cjs/obsidian/components/syntax-highlighting-component.d.cts"
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "obsidian-dev-utils",
3
- "version": "88.6.0",
3
+ "version": "88.8.0",
4
4
  "description": "This is the collection of useful functions that you can use for your Obsidian plugin development.",
5
5
  "keywords": [
6
6
  "obsidian"
@@ -689,7 +689,7 @@
689
689
  "@eslint/config-helpers": "^0.7.0",
690
690
  "@eslint/js": "^10.0.1",
691
691
  "@lezer/common": "1.5.2",
692
- "@obsidian-typings/obsidian-public-latest": "^6.27.0",
692
+ "@obsidian-typings/obsidian-public-latest": "^6.29.0",
693
693
  "@stylistic/eslint-plugin": "^5.10.0",
694
694
  "@tsconfig/strictest": "^2.0.8",
695
695
  "@types/babel__core": "^7.20.5",
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../../dist/lib/cjs/script-utils/env-toggle.cjs",
3
+ "module": "../../dist/lib/esm/script-utils/env-toggle.mjs",
4
+ "type": "module",
5
+ "types": "../../dist/lib/cjs/script-utils/env-toggle.d.cts"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../../dist/lib/cjs/script-utils/git.cjs",
3
+ "module": "../../dist/lib/esm/script-utils/git.mjs",
4
+ "type": "module",
5
+ "types": "../../dist/lib/cjs/script-utils/git.d.cts"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../../../dist/lib/cjs/script-utils/test-runners/vitest-config.cjs",
3
+ "module": "../../../dist/lib/esm/script-utils/test-runners/vitest-config.mjs",
4
+ "type": "module",
5
+ "types": "../../../dist/lib/cjs/script-utils/test-runners/vitest-config.d.cts"
6
+ }
@@ -1,4 +0,0 @@
1
- {
2
- "type": "module",
3
- "types": "../../dist/lib/cjs/@types/obsidian.d.cts"
4
- }
@@ -1,28 +0,0 @@
1
- /// <reference path="../library.d.cts" />
2
- /**
3
- * @file
4
- *
5
- * Augments the Obsidian typings with the `disabled` predicate that `SettingDefinitionRender` honours at
6
- * runtime but does not declare.
7
- *
8
- * Obsidian's `obsidian.d.ts` puts `disabled` on `SettingDefinitionControl` and `SettingDefinitionAction`
9
- * only. The 1.13.4 renderer, however, reads it off every definition it draws —
10
- * `'disabled' in def ? def.disabled : def.control?.disabled`, then `setting.setDisabled(...)`, which toggles
11
- * the row's `is-disabled` class and propagates to every registered component. So a `render` row can carry the
12
- * predicate too, and `refreshDomState()` re-evaluates it without a re-render — the mechanism
13
- * `PluginSettingsTabBase.settingEx` builds on.
14
- *
15
- * Observed and tested in Obsidian 1.13.4.
16
- */
17
-
18
- export {};
19
-
20
- declare module 'obsidian' {
21
- interface SettingDefinitionRender {
22
- /**
23
- * Disables the row. Evaluated on each render and on every `refreshDomState()`. `Setting.setDisabled` is
24
- * applied to the row, which also disables every component registered on it.
25
- */
26
- disabled?: (() => boolean) | boolean;
27
- }
28
- }
@@ -1,28 +0,0 @@
1
- /// <reference path="../library.d.mts" />
2
- /**
3
- * @file
4
- *
5
- * Augments the Obsidian typings with the `disabled` predicate that `SettingDefinitionRender` honours at
6
- * runtime but does not declare.
7
- *
8
- * Obsidian's `obsidian.d.ts` puts `disabled` on `SettingDefinitionControl` and `SettingDefinitionAction`
9
- * only. The 1.13.4 renderer, however, reads it off every definition it draws —
10
- * `'disabled' in def ? def.disabled : def.control?.disabled`, then `setting.setDisabled(...)`, which toggles
11
- * the row's `is-disabled` class and propagates to every registered component. So a `render` row can carry the
12
- * predicate too, and `refreshDomState()` re-evaluates it without a re-render — the mechanism
13
- * `PluginSettingsTabBase.settingEx` builds on.
14
- *
15
- * Observed and tested in Obsidian 1.13.4.
16
- */
17
-
18
- export {};
19
-
20
- declare module 'obsidian' {
21
- interface SettingDefinitionRender {
22
- /**
23
- * Disables the row. Evaluated on each render and on every `refreshDomState()`. `Setting.setDisabled` is
24
- * applied to the row, which also disables every component registered on it.
25
- */
26
- disabled?: (() => boolean) | boolean;
27
- }
28
- }