@mnaoumov/obsidian-dev-toolkit 0.0.0 → 1.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.
- package/LICENSE +21 -0
- package/README.md +7 -1
- package/bundlers/esbuild/package.json +6 -0
- package/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin/package.json +6 -0
- package/bundlers/esbuild-impl/dependency/package.json +6 -0
- package/bundlers/esbuild-impl/fix-source-maps-plugin/package.json +6 -0
- package/bundlers/esbuild-impl/index/package.json +6 -0
- package/bundlers/esbuild-impl/obsidian-plugin-builder/package.json +6 -0
- package/bundlers/esbuild-impl/package.json +6 -0
- package/bundlers/esbuild-impl/preprocess-plugin/package.json +6 -0
- package/bundlers/esbuild-impl/rename-css-plugin/package.json +6 -0
- package/bundlers/index/package.json +6 -0
- package/bundlers/package.json +6 -0
- package/dist/demo-vault-helper/main.js +782 -0
- package/dist/demo-vault-helper/manifest.json +9 -0
- package/dist/integration-test-plugin/main.js +45388 -0
- package/dist/integration-test-plugin/manifest.json +8 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.cjs +335 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.d.cts +38 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/dependency.cjs +253 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/dependency.d.cts +20 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/fix-source-maps-plugin.cjs +226 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/fix-source-maps-plugin.d.cts +34 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/index.cjs +192 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/index.d.cts +7 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.cjs +375 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.d.cts +98 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/preprocess-plugin.cjs +247 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/preprocess-plugin.d.cts +30 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/rename-css-plugin.cjs +184 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/rename-css-plugin.d.cts +14 -0
- package/dist/lib/cjs/bundlers/esbuild.cjs +177 -0
- package/dist/lib/cjs/bundlers/esbuild.d.cts +11 -0
- package/dist/lib/cjs/bundlers/index.cjs +180 -0
- package/dist/lib/cjs/bundlers/index.d.cts +3 -0
- package/dist/lib/cjs/demo-vault-app-json.cjs +199 -0
- package/dist/lib/cjs/demo-vault-app-json.d.cts +93 -0
- package/dist/lib/cjs/demo-vault-buttons.cjs +580 -0
- package/dist/lib/cjs/demo-vault-buttons.d.cts +259 -0
- package/dist/lib/cjs/demo-vault-coverage.cjs +725 -0
- package/dist/lib/cjs/demo-vault-coverage.d.cts +533 -0
- package/dist/lib/cjs/demo-vault.cjs +309 -0
- package/dist/lib/cjs/demo-vault.d.cts +33 -0
- package/dist/lib/cjs/formatters/dprint.cjs +173 -0
- package/dist/lib/cjs/formatters/dprint.d.cts +15 -0
- package/dist/lib/cjs/formatters/index.cjs +177 -0
- package/dist/lib/cjs/formatters/index.d.cts +2 -0
- package/dist/lib/cjs/index.cjs +207 -0
- package/dist/lib/cjs/index.d.cts +16 -0
- package/dist/lib/cjs/integration-test-setup.cjs +142 -0
- package/dist/lib/cjs/integration-test-setup.d.cts +33 -0
- package/dist/lib/cjs/integration-test-vitest-global-setup.cjs +176 -0
- package/dist/lib/cjs/integration-test-vitest-global-setup.d.cts +39 -0
- package/dist/lib/cjs/jest-setup.cjs +147 -0
- package/dist/lib/cjs/jest-setup.d.cts +13 -0
- package/dist/lib/cjs/linters/eslint-config.cjs +365 -0
- package/dist/lib/cjs/linters/eslint-config.d.cts +25 -0
- package/dist/lib/cjs/linters/eslint-rules/index.cjs +201 -0
- package/dist/lib/cjs/linters/eslint-rules/index.d.cts +10 -0
- package/dist/lib/cjs/linters/eslint-rules/manifest-description.cjs +268 -0
- package/dist/lib/cjs/linters/eslint-rules/manifest-description.d.cts +54 -0
- package/dist/lib/cjs/linters/eslint-rules/manifest-helpers.cjs +231 -0
- package/dist/lib/cjs/linters/eslint-rules/manifest-helpers.d.cts +141 -0
- package/dist/lib/cjs/linters/eslint-rules/manifest-id.cjs +228 -0
- package/dist/lib/cjs/linters/eslint-rules/manifest-id.d.cts +32 -0
- package/dist/lib/cjs/linters/eslint-rules/manifest-name.cjs +229 -0
- package/dist/lib/cjs/linters/eslint-rules/manifest-name.d.cts +30 -0
- package/dist/lib/cjs/linters/eslint-rules/manifest-schema.cjs +329 -0
- package/dist/lib/cjs/linters/eslint-rules/manifest-schema.d.cts +45 -0
- package/dist/lib/cjs/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.cjs +670 -0
- package/dist/lib/cjs/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.d.cts +10 -0
- package/dist/lib/cjs/linters/eslint-rules/no-untrusted-input-events.cjs +260 -0
- package/dist/lib/cjs/linters/eslint-rules/no-untrusted-input-events.d.cts +10 -0
- package/dist/lib/cjs/linters/eslint-rules/obsidian-dev-utils-plugin.cjs +186 -0
- package/dist/lib/cjs/linters/eslint-rules/obsidian-dev-utils-plugin.d.cts +13 -0
- package/dist/lib/cjs/linters/eslint-rules/require-component-suffix.cjs +291 -0
- package/dist/lib/cjs/linters/eslint-rules/require-component-suffix.d.cts +18 -0
- package/dist/lib/cjs/linters/eslint.cjs +173 -0
- package/dist/lib/cjs/linters/eslint.d.cts +15 -0
- package/dist/lib/cjs/linters/index.cjs +189 -0
- package/dist/lib/cjs/linters/index.d.cts +6 -0
- package/dist/lib/cjs/linters/markdownlint.cjs +173 -0
- package/dist/lib/cjs/linters/markdownlint.d.cts +15 -0
- package/dist/lib/cjs/linters/obsidianmd-rule-custom-message.cjs +189 -0
- package/dist/lib/cjs/linters/obsidianmd-rule-custom-message.d.cts +40 -0
- package/dist/lib/cjs/obsidian-plugin-repo-paths.cjs +229 -0
- package/dist/lib/cjs/obsidian-plugin-repo-paths.d.cts +253 -0
- package/dist/lib/cjs/setup.cjs +176 -0
- package/dist/lib/cjs/setup.d.cts +21 -0
- package/dist/lib/cjs/templates.cjs +185 -0
- package/dist/lib/cjs/templates.d.cts +13 -0
- package/dist/lib/cjs/test-runners/index.cjs +183 -0
- package/dist/lib/cjs/test-runners/index.d.cts +4 -0
- package/dist/lib/cjs/test-runners/integration-test-plugin.cjs +224 -0
- package/dist/lib/cjs/test-runners/integration-test-plugin.d.cts +44 -0
- package/dist/lib/cjs/test-runners/performance-eval-cap.cjs +170 -0
- package/dist/lib/cjs/test-runners/performance-eval-cap.d.cts +27 -0
- package/dist/lib/cjs/test-runners/stale-build-global-setup.cjs +230 -0
- package/dist/lib/cjs/test-runners/stale-build-global-setup.d.cts +86 -0
- package/dist/lib/cjs/test-runners/vitest-config.cjs +497 -0
- package/dist/lib/cjs/test-runners/vitest-config.d.cts +200 -0
- package/dist/lib/cjs/version.cjs +275 -0
- package/dist/lib/cjs/version.d.cts +92 -0
- package/dist/lib/cjs/vitest-setup.cjs +147 -0
- package/dist/lib/cjs/vitest-setup.d.cts +11 -0
- package/dist/lib/esm/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.d.mts +38 -0
- package/dist/lib/esm/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.mjs +226 -0
- package/dist/lib/esm/bundlers/esbuild-impl/dependency.d.mts +20 -0
- package/dist/lib/esm/bundlers/esbuild-impl/dependency.mjs +138 -0
- package/dist/lib/esm/bundlers/esbuild-impl/fix-source-maps-plugin.d.mts +34 -0
- package/dist/lib/esm/bundlers/esbuild-impl/fix-source-maps-plugin.mjs +116 -0
- package/dist/lib/esm/bundlers/esbuild-impl/index.d.mts +7 -0
- package/dist/lib/esm/bundlers/esbuild-impl/index.mjs +64 -0
- package/dist/lib/esm/bundlers/esbuild-impl/obsidian-plugin-builder.d.mts +98 -0
- package/dist/lib/esm/bundlers/esbuild-impl/obsidian-plugin-builder.mjs +255 -0
- package/dist/lib/esm/bundlers/esbuild-impl/preprocess-plugin.d.mts +30 -0
- package/dist/lib/esm/bundlers/esbuild-impl/preprocess-plugin.mjs +134 -0
- package/dist/lib/esm/bundlers/esbuild-impl/rename-css-plugin.d.mts +14 -0
- package/dist/lib/esm/bundlers/esbuild-impl/rename-css-plugin.mjs +71 -0
- package/dist/lib/esm/bundlers/esbuild.d.mts +11 -0
- package/dist/lib/esm/bundlers/esbuild.mjs +66 -0
- package/dist/lib/esm/bundlers/index.d.mts +3 -0
- package/dist/lib/esm/bundlers/index.mjs +56 -0
- package/dist/lib/esm/demo-vault-app-json.d.mts +93 -0
- package/dist/lib/esm/demo-vault-app-json.mjs +83 -0
- package/dist/lib/esm/demo-vault-buttons.d.mts +259 -0
- package/dist/lib/esm/demo-vault-buttons.mjs +460 -0
- package/dist/lib/esm/demo-vault-coverage.d.mts +533 -0
- package/dist/lib/esm/demo-vault-coverage.mjs +626 -0
- package/dist/lib/esm/demo-vault.d.mts +33 -0
- package/dist/lib/esm/demo-vault.mjs +205 -0
- package/dist/lib/esm/formatters/dprint.d.mts +15 -0
- package/dist/lib/esm/formatters/dprint.mjs +60 -0
- package/dist/lib/esm/formatters/index.d.mts +2 -0
- package/dist/lib/esm/formatters/index.mjs +54 -0
- package/dist/lib/esm/index.d.mts +16 -0
- package/dist/lib/esm/index.mjs +74 -0
- package/dist/lib/esm/integration-test-setup.d.mts +33 -0
- package/dist/lib/esm/integration-test-setup.mjs +52 -0
- package/dist/lib/esm/integration-test-vitest-global-setup.d.mts +39 -0
- package/dist/lib/esm/integration-test-vitest-global-setup.mjs +65 -0
- package/dist/lib/esm/jest-setup.d.mts +13 -0
- package/dist/lib/esm/jest-setup.mjs +61 -0
- package/dist/lib/esm/linters/eslint-config.d.mts +25 -0
- package/dist/lib/esm/linters/eslint-config.mjs +247 -0
- package/dist/lib/esm/linters/eslint-rules/index.d.mts +10 -0
- package/dist/lib/esm/linters/eslint-rules/index.mjs +70 -0
- package/dist/lib/esm/linters/eslint-rules/manifest-description.d.mts +54 -0
- package/dist/lib/esm/linters/eslint-rules/manifest-description.mjs +154 -0
- package/dist/lib/esm/linters/eslint-rules/manifest-helpers.d.mts +141 -0
- package/dist/lib/esm/linters/eslint-rules/manifest-helpers.mjs +98 -0
- package/dist/lib/esm/linters/eslint-rules/manifest-id.d.mts +32 -0
- package/dist/lib/esm/linters/eslint-rules/manifest-id.mjs +117 -0
- package/dist/lib/esm/linters/eslint-rules/manifest-name.d.mts +30 -0
- package/dist/lib/esm/linters/eslint-rules/manifest-name.mjs +118 -0
- package/dist/lib/esm/linters/eslint-rules/manifest-schema.d.mts +45 -0
- package/dist/lib/esm/linters/eslint-rules/manifest-schema.mjs +220 -0
- package/dist/lib/esm/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.d.mts +10 -0
- package/dist/lib/esm/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.mjs +559 -0
- package/dist/lib/esm/linters/eslint-rules/no-untrusted-input-events.d.mts +10 -0
- package/dist/lib/esm/linters/eslint-rules/no-untrusted-input-events.mjs +146 -0
- package/dist/lib/esm/linters/eslint-rules/obsidian-dev-utils-plugin.d.mts +13 -0
- package/dist/lib/esm/linters/eslint-rules/obsidian-dev-utils-plugin.mjs +73 -0
- package/dist/lib/esm/linters/eslint-rules/require-component-suffix.d.mts +18 -0
- package/dist/lib/esm/linters/eslint-rules/require-component-suffix.mjs +175 -0
- package/dist/lib/esm/linters/eslint.d.mts +15 -0
- package/dist/lib/esm/linters/eslint.mjs +60 -0
- package/dist/lib/esm/linters/index.d.mts +6 -0
- package/dist/lib/esm/linters/index.mjs +62 -0
- package/dist/lib/esm/linters/markdownlint.d.mts +15 -0
- package/dist/lib/esm/linters/markdownlint.mjs +60 -0
- package/dist/lib/esm/linters/obsidianmd-rule-custom-message.d.mts +40 -0
- package/dist/lib/esm/linters/obsidianmd-rule-custom-message.mjs +75 -0
- package/dist/lib/esm/obsidian-plugin-repo-paths.d.mts +253 -0
- package/dist/lib/esm/obsidian-plugin-repo-paths.mjs +116 -0
- package/dist/lib/esm/setup.d.mts +21 -0
- package/dist/lib/esm/setup.mjs +63 -0
- package/dist/lib/esm/templates.d.mts +13 -0
- package/dist/lib/esm/templates.mjs +65 -0
- package/dist/lib/esm/test-runners/index.d.mts +4 -0
- package/dist/lib/esm/test-runners/index.mjs +58 -0
- package/dist/lib/esm/test-runners/integration-test-plugin.d.mts +44 -0
- package/dist/lib/esm/test-runners/integration-test-plugin.mjs +102 -0
- package/dist/lib/esm/test-runners/performance-eval-cap.d.mts +27 -0
- package/dist/lib/esm/test-runners/performance-eval-cap.mjs +56 -0
- package/dist/lib/esm/test-runners/stale-build-global-setup.d.mts +86 -0
- package/dist/lib/esm/test-runners/stale-build-global-setup.mjs +123 -0
- package/dist/lib/esm/test-runners/vitest-config.d.mts +200 -0
- package/dist/lib/esm/test-runners/vitest-config.mjs +377 -0
- package/dist/lib/esm/version.d.mts +92 -0
- package/dist/lib/esm/version.mjs +168 -0
- package/dist/lib/esm/vitest-setup.d.mts +11 -0
- package/dist/lib/esm/vitest-setup.mjs +61 -0
- package/dist/templates/.markdownlint-cli2.mjs +4 -0
- package/dist/templates/.nano-staged.mjs +4 -0
- package/dist/templates/commitlint.config.ts +3 -0
- package/dist/templates/dprint.json +26 -0
- package/dist/templates/eslint.config.mts +3 -0
- package/dist/templates/scripts/build/build-clean.ts +4 -0
- package/dist/templates/scripts/build/build-compile-svelte.ts +4 -0
- package/dist/templates/scripts/build/build-compile-typescript.ts +4 -0
- package/dist/templates/scripts/build/build-compile.ts +4 -0
- package/dist/templates/scripts/build/build-templates.ts +4 -0
- package/dist/templates/scripts/bundlers/esbuild/build.ts +4 -0
- package/dist/templates/scripts/bundlers/esbuild/dev.ts +4 -0
- package/dist/templates/scripts/commitlint-config.ts +3 -0
- package/dist/templates/scripts/eslint-config.ts +10 -0
- package/dist/templates/scripts/formatters/dprint/format-check.ts +8 -0
- package/dist/templates/scripts/formatters/dprint/format.ts +8 -0
- package/dist/templates/scripts/gate/gate.ts +10 -0
- package/dist/templates/scripts/linters/cspell/spellcheck.ts +8 -0
- package/dist/templates/scripts/linters/eslint/lint-fix.ts +8 -0
- package/dist/templates/scripts/linters/eslint/lint.ts +8 -0
- package/dist/templates/scripts/linters/markdownlint/lint-md-fix.ts +8 -0
- package/dist/templates/scripts/linters/markdownlint/lint-md.ts +8 -0
- package/dist/templates/scripts/linters/over-exposure/find-overexposed-fix.ts +25 -0
- package/dist/templates/scripts/linters/over-exposure/find-overexposed.ts +15 -0
- package/dist/templates/scripts/markdownlint-cli2-config.ts +3 -0
- package/dist/templates/scripts/nano-staged-config.ts +3 -0
- package/dist/templates/scripts/test-runners/vitest/test-coverage.ts +4 -0
- package/dist/templates/scripts/test-runners/vitest/test-watch.ts +4 -0
- package/dist/templates/scripts/test-runners/vitest/test.ts +4 -0
- package/dist/templates/scripts/version/version.ts +10 -0
- package/dist/templates/scripts/vitest-config.ts +3 -0
- package/dist/templates/vitest.config.ts +3 -0
- package/formatters/dprint/package.json +6 -0
- package/formatters/index/package.json +6 -0
- package/formatters/package.json +6 -0
- package/linters/eslint/package.json +6 -0
- package/linters/eslint-config/package.json +6 -0
- package/linters/eslint-rules/index/package.json +6 -0
- package/linters/eslint-rules/manifest-description/package.json +6 -0
- package/linters/eslint-rules/manifest-helpers/package.json +6 -0
- package/linters/eslint-rules/manifest-id/package.json +6 -0
- package/linters/eslint-rules/manifest-name/package.json +6 -0
- package/linters/eslint-rules/manifest-schema/package.json +6 -0
- package/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian/package.json +6 -0
- package/linters/eslint-rules/no-untrusted-input-events/package.json +6 -0
- package/linters/eslint-rules/obsidian-dev-utils-plugin/package.json +6 -0
- package/linters/eslint-rules/package.json +6 -0
- package/linters/eslint-rules/require-component-suffix/package.json +6 -0
- package/linters/index/package.json +6 -0
- package/linters/markdownlint/package.json +6 -0
- package/linters/obsidianmd-rule-custom-message/package.json +6 -0
- package/linters/package.json +6 -0
- package/package.json +241 -13
- package/test-runners/index/package.json +6 -0
- package/test-runners/integration-test-plugin/package.json +6 -0
- package/test-runners/package.json +6 -0
- package/test-runners/performance-eval-cap/package.json +6 -0
- package/test-runners/stale-build-global-setup/package.json +6 -0
- package/test-runners/vitest-config/package.json +6 -0
|
@@ -0,0 +1,497 @@
|
|
|
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 ensureDisposeSymbols(symbolConstructor = Symbol) {
|
|
8
|
+
symbolConstructor.asyncDispose ??= symbolConstructor.for('Symbol.asyncDispose');
|
|
9
|
+
symbolConstructor.dispose ??= symbolConstructor.for('Symbol.dispose');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function ensureBrowserProcess() {
|
|
13
|
+
const browserProcess = {
|
|
14
|
+
browser: true,
|
|
15
|
+
cwd() {
|
|
16
|
+
return '/';
|
|
17
|
+
},
|
|
18
|
+
env: {},
|
|
19
|
+
platform: 'android'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// 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.
|
|
23
|
+
const existingProcess = globalThis.process;
|
|
24
|
+
|
|
25
|
+
if (!existingProcess) {
|
|
26
|
+
// eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
|
|
27
|
+
globalThis.process = browserProcess;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (existingProcess.versions?.node) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const existingProcessRecord = existingProcess;
|
|
36
|
+
|
|
37
|
+
for (const [key, value] of Object.entries(browserProcess)) {
|
|
38
|
+
existingProcessRecord[key] ??= value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
existingProcessRecord['browser'] = true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function keepName($unknown) {
|
|
45
|
+
return $unknown;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
(function initCjs() {
|
|
49
|
+
// eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
|
|
50
|
+
const globalThisRecord = globalThis;
|
|
51
|
+
ensureDisposeSymbols();
|
|
52
|
+
globalThisRecord['__name'] ??= keepName;
|
|
53
|
+
globalThisRecord['__extractDefault'] ??= extractDefault;
|
|
54
|
+
|
|
55
|
+
ensureBrowserProcess();
|
|
56
|
+
|
|
57
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping -- Serialized with initCjs into the banner; at module scope it would be left out of it.
|
|
58
|
+
function extractDefault(module) {
|
|
59
|
+
return module && module.__esModule && 'default' in module ? module.default : module;
|
|
60
|
+
}
|
|
61
|
+
})();
|
|
62
|
+
})();
|
|
63
|
+
(function patchObsidianRequire() {
|
|
64
|
+
const originalRequire = require;
|
|
65
|
+
if (!originalRequire || originalRequire.__isPatched) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// eslint-disable-next-line no-global-assign, no-implicit-globals -- We need to patch the `require()` function.
|
|
70
|
+
require = Object.assign(
|
|
71
|
+
(id) => requirePatched(id),
|
|
72
|
+
originalRequire,
|
|
73
|
+
{
|
|
74
|
+
__isPatched: true
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
function extractDefault(module) {
|
|
79
|
+
return module && module.__esModule && 'default' in module ? module.default : module;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
|
|
83
|
+
'@codemirror/autocomplete',
|
|
84
|
+
'@codemirror/collab',
|
|
85
|
+
'@codemirror/commands',
|
|
86
|
+
'@codemirror/language',
|
|
87
|
+
'@codemirror/lint',
|
|
88
|
+
'@codemirror/search',
|
|
89
|
+
'@codemirror/state',
|
|
90
|
+
'@codemirror/text',
|
|
91
|
+
'@codemirror/view',
|
|
92
|
+
'@lezer/common',
|
|
93
|
+
'@lezer/highlight',
|
|
94
|
+
'@lezer/lr',
|
|
95
|
+
'obsidian']
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
|
|
99
|
+
'@codemirror/closebrackets',
|
|
100
|
+
'@codemirror/comment',
|
|
101
|
+
'@codemirror/fold',
|
|
102
|
+
'@codemirror/gutter',
|
|
103
|
+
'@codemirror/highlight',
|
|
104
|
+
'@codemirror/history',
|
|
105
|
+
'@codemirror/matchbrackets',
|
|
106
|
+
'@codemirror/panel',
|
|
107
|
+
'@codemirror/rangeset',
|
|
108
|
+
'@codemirror/rectangular-selection',
|
|
109
|
+
'@codemirror/stream-parser',
|
|
110
|
+
'@codemirror/tooltip']
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
function requirePatched(id) {
|
|
114
|
+
if (OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id)) {
|
|
115
|
+
return originalRequire?.(id);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated, obsidianmd/no-global-this -- Need access to app. Actively use globalThis.
|
|
119
|
+
if (globalThis.app.isMobile) {
|
|
120
|
+
if (id === 'process' || id === 'node:process') {
|
|
121
|
+
// eslint-disable-next-line no-console -- Valid usage.
|
|
122
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
|
|
123
|
+
|
|
124
|
+
return process;
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
const module = originalRequire?.(id);
|
|
128
|
+
if (module) {
|
|
129
|
+
return extractDefault(module);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// eslint-disable-next-line no-console -- Valid usage.
|
|
134
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
|
|
135
|
+
return {};
|
|
136
|
+
}
|
|
137
|
+
})();
|
|
138
|
+
|
|
139
|
+
"use strict";
|
|
140
|
+
var __create = Object.create;
|
|
141
|
+
var __defProp = Object.defineProperty;
|
|
142
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
143
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
144
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
145
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
146
|
+
var __export = (target, all) => {
|
|
147
|
+
for (var name in all)
|
|
148
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
149
|
+
};
|
|
150
|
+
var __copyProps = (to, from, except, desc) => {
|
|
151
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
152
|
+
for (let key of __getOwnPropNames(from))
|
|
153
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
154
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
155
|
+
}
|
|
156
|
+
return to;
|
|
157
|
+
};
|
|
158
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
159
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
160
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
161
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
162
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
163
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
164
|
+
mod
|
|
165
|
+
));
|
|
166
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
167
|
+
var vitest_config_exports = {};
|
|
168
|
+
__export(vitest_config_exports, {
|
|
169
|
+
DEFAULT_VITEST_REPORTERS: () => import_vitest_config.DEFAULT_VITEST_REPORTERS,
|
|
170
|
+
INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS: () => INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS,
|
|
171
|
+
ObsidianPluginVitestConfigContext: () => ObsidianPluginVitestConfigContext,
|
|
172
|
+
defineObsidianPluginVitestConfig: () => defineObsidianPluginVitestConfig
|
|
173
|
+
});
|
|
174
|
+
module.exports = __toCommonJS(vitest_config_exports);
|
|
175
|
+
var import_vitest_config = require('@mnaoumov/typescript-dev-toolkit/test-runners/vitest-config');
|
|
176
|
+
var import_node_process = __toESM(__extractDefault(require('node:process')), 1);
|
|
177
|
+
var import_obsidian_integration_testing = require('obsidian-integration-testing');
|
|
178
|
+
var import_config = require('vitest/config');
|
|
179
|
+
var import_performance_eval_cap = require('./performance-eval-cap.cjs');
|
|
180
|
+
const TRANSPORT_EVAL_CAP_MARGIN_IN_MILLISECONDS = 15e3;
|
|
181
|
+
const ANDROID_TIMEOUT_IN_MILLISECONDS = 6e4;
|
|
182
|
+
const HOOK_TIMEOUT_MULTIPLIER = 4;
|
|
183
|
+
const PERFORMANCE_TIMEOUT_IN_MILLISECONDS = import_performance_eval_cap.PERFORMANCE_EVAL_CAP_IN_MILLISECONDS + TRANSPORT_EVAL_CAP_MARGIN_IN_MILLISECONDS;
|
|
184
|
+
const INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS = import_obsidian_integration_testing.DEFAULT_EVAL_CAP_IN_MILLISECONDS + TRANSPORT_EVAL_CAP_MARGIN_IN_MILLISECONDS;
|
|
185
|
+
const ANDROID_TEST_FILES = "src/**/*.android.integration.test.ts";
|
|
186
|
+
const CROSS_PLATFORM_TEST_FILES = "src/**/*.cross-platform.integration.test.ts";
|
|
187
|
+
const DECLARATION_FILES = "src/**/*.d.ts";
|
|
188
|
+
const DESKTOP_PERFORMANCE_TEST_FILES = `src/**/*${import_performance_eval_cap.DESKTOP_PERFORMANCE_TEST_FILE_SUFFIX}`;
|
|
189
|
+
const DESKTOP_TEST_FILES = "src/**/*.desktop.integration.test.ts";
|
|
190
|
+
const INTEGRATION_TEST_FILES = "src/**/*.integration.test.ts";
|
|
191
|
+
const NO_APP_TEST_FILES = "src/**/*.no-app.integration.test.ts";
|
|
192
|
+
const UNIT_TEST_FILES = "src/**/*.test.ts";
|
|
193
|
+
const UNIT_TEST_GLOBAL_STUBS_PROJECT_NAME = "unit-tests:global-stubs";
|
|
194
|
+
const STALE_BUILD_GLOBAL_SETUP = "obsidian-dev-utils/script-utils/test-runners/stale-build-global-setup";
|
|
195
|
+
const OBSIDIAN_VERSION_ENV_VARIABLE_NAME = "OBSIDIAN_VERSION";
|
|
196
|
+
const SHARED_EXCLUDE = import_vitest_config.DEFAULT_VITEST_TEST_EXCLUDE;
|
|
197
|
+
class ObsidianPluginVitestConfigContext {
|
|
198
|
+
/**
|
|
199
|
+
* The `integration-tests:android` project, running the mobile-only and cross-platform suites against an
|
|
200
|
+
* Android emulator through Appium.
|
|
201
|
+
*/
|
|
202
|
+
android = {
|
|
203
|
+
environment: "node",
|
|
204
|
+
environmentOptions: {
|
|
205
|
+
obsidianTransport: {
|
|
206
|
+
appiumUrl: "http://localhost:4723",
|
|
207
|
+
avdName: "obsidian_test",
|
|
208
|
+
type: "obsidian-android-appium"
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
fileParallelism: false,
|
|
212
|
+
globalSetup: [STALE_BUILD_GLOBAL_SETUP, "obsidian-integration-testing/vitest-global-setup-plugin"],
|
|
213
|
+
hookTimeout: ANDROID_TIMEOUT_IN_MILLISECONDS * HOOK_TIMEOUT_MULTIPLIER,
|
|
214
|
+
include: [ANDROID_TEST_FILES, CROSS_PLATFORM_TEST_FILES],
|
|
215
|
+
name: "integration-tests:android",
|
|
216
|
+
setupFiles: ["obsidian-integration-testing/vitest-setup"],
|
|
217
|
+
testTimeout: ANDROID_TIMEOUT_IN_MILLISECONDS
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* The per-test budget of the Android integration project, in milliseconds. Booting an emulator and
|
|
221
|
+
* driving it over Appium is slower than the desktop path, hence its own constant.
|
|
222
|
+
*
|
|
223
|
+
* @default `60000`
|
|
224
|
+
*/
|
|
225
|
+
androidTimeoutInMilliseconds = ANDROID_TIMEOUT_IN_MILLISECONDS;
|
|
226
|
+
/**
|
|
227
|
+
* The per-test budget of the regular integration projects, in milliseconds.
|
|
228
|
+
*
|
|
229
|
+
* It deliberately CLEARS the transports' per-eval cap rather than matching it, so that a closure which
|
|
230
|
+
* outruns the cap fails with the harness's `EvalCapExceededError` — naming the cap and the remedy —
|
|
231
|
+
* instead of with vitest's anonymous timeout. Lowering it to the cap restores that blind spot.
|
|
232
|
+
*
|
|
233
|
+
* @default `45000`
|
|
234
|
+
*/
|
|
235
|
+
bigTimeoutInMilliseconds = INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS;
|
|
236
|
+
/**
|
|
237
|
+
* The coverage `exclude` globs. Push onto it to drop more files from the coverage report.
|
|
238
|
+
*
|
|
239
|
+
* Declaration files are excluded by default because the coverage `include` below is `src/**\/*.ts`,
|
|
240
|
+
* which a `.d.ts` matches. A declaration file emits no runtime code, so it reports 0% and no test can
|
|
241
|
+
* ever raise it — a plugin that grows one under `src/` silently loses its 100% gate, and the usual
|
|
242
|
+
* remedy of an inline `v8 ignore` comment does not apply to a type-only file.
|
|
243
|
+
*/
|
|
244
|
+
coverageExclude = [UNIT_TEST_FILES, DECLARATION_FILES];
|
|
245
|
+
/**
|
|
246
|
+
* The `integration-tests:desktop` project, running the desktop-only and cross-platform suites against a
|
|
247
|
+
* real desktop Obsidian over CDP.
|
|
248
|
+
*/
|
|
249
|
+
desktop = {
|
|
250
|
+
environment: "node",
|
|
251
|
+
fileParallelism: false,
|
|
252
|
+
globalSetup: [STALE_BUILD_GLOBAL_SETUP, "obsidian-integration-testing/vitest-global-setup-plugin"],
|
|
253
|
+
hookTimeout: INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS * HOOK_TIMEOUT_MULTIPLIER,
|
|
254
|
+
include: [DESKTOP_TEST_FILES, CROSS_PLATFORM_TEST_FILES],
|
|
255
|
+
name: "integration-tests:desktop",
|
|
256
|
+
setupFiles: ["obsidian-integration-testing/vitest-setup"],
|
|
257
|
+
testTimeout: INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* The `integration-tests:desktop-performance` project, running the at-scale suites. It is declared for
|
|
261
|
+
* every plugin even when there is no such suite yet — `passWithNoTests` makes an empty project free,
|
|
262
|
+
* and the matching `test:integration:desktop:performance` script exists in every plugin built on this library.
|
|
263
|
+
*
|
|
264
|
+
* A plugin's `test:integration` aggregate leaves this project out on purpose, and it stays out even on a
|
|
265
|
+
* machine with a desktop Obsidian set up. The reason is the fixture rather than the cost: a perf suite
|
|
266
|
+
* needs its own generated, populated vault, sized through env vars, and the aggregate's small temporary
|
|
267
|
+
* vault is the wrong one. The 600 s below is a timeout, not a duration — measured end to end, most perf
|
|
268
|
+
* suites finish in seconds, and only one that generates tens of thousands of notes takes minutes.
|
|
269
|
+
*
|
|
270
|
+
* Its CDP transport's per-eval cap is raised to 600 s as well (the budget clears it by the usual
|
|
271
|
+
* margin), because a perf suite's whole measurement is typically ONE long in-page evaluation, which the
|
|
272
|
+
* transport's 30 s default killed as a bare `CDP command timed out … Runtime.evaluate` naming neither the
|
|
273
|
+
* wait nor the assertion. Three plugins had each hand-written this raise in their own `editContext`
|
|
274
|
+
* before it moved here. Unlike a raised desktop cap, which is a backstop rather than a budget a closure
|
|
275
|
+
* may spend, this one IS a budget: `no-over-cap-wait-in-eval-in-obsidian` reads it for these files and
|
|
276
|
+
* for no other.
|
|
277
|
+
*
|
|
278
|
+
* No routine command runs them, but something does: a weekly sweep runs every plugin's
|
|
279
|
+
* `test:integration:desktop:performance`, which is also how to reach them by hand. Adding them to that
|
|
280
|
+
* aggregate is drift, not a gap to close.
|
|
281
|
+
*/
|
|
282
|
+
desktopPerformance = {
|
|
283
|
+
environment: "node",
|
|
284
|
+
environmentOptions: {
|
|
285
|
+
obsidianTransport: {
|
|
286
|
+
commandTimeoutInMilliseconds: import_performance_eval_cap.PERFORMANCE_EVAL_CAP_IN_MILLISECONDS,
|
|
287
|
+
type: "obsidian-cdp"
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
fileParallelism: false,
|
|
291
|
+
globalSetup: [STALE_BUILD_GLOBAL_SETUP, "obsidian-integration-testing/vitest-global-setup-plugin"],
|
|
292
|
+
hookTimeout: PERFORMANCE_TIMEOUT_IN_MILLISECONDS,
|
|
293
|
+
include: [DESKTOP_PERFORMANCE_TEST_FILES],
|
|
294
|
+
name: "integration-tests:desktop-performance",
|
|
295
|
+
setupFiles: ["obsidian-integration-testing/vitest-setup"],
|
|
296
|
+
testTimeout: PERFORMANCE_TIMEOUT_IN_MILLISECONDS
|
|
297
|
+
};
|
|
298
|
+
/**
|
|
299
|
+
* The unit test files that redefine `window`, `document`, `location` or `top`, which the `unit-tests`
|
|
300
|
+
* project's VM pool cannot run.
|
|
301
|
+
*
|
|
302
|
+
* Under `pool: 'vmThreads'` those four are non-configurable properties of the VM global, so
|
|
303
|
+
* `vi.stubGlobal('window', …)` or `Object.defineProperty(window, 'location', …)` throws
|
|
304
|
+
* `Cannot redefine property`. That is JS semantics, not a bug to route around. Every other global stays
|
|
305
|
+
* configurable and stubs normally.
|
|
306
|
+
*
|
|
307
|
+
* Push a file here and it leaves `unit-tests` for a sibling `unit-tests:global-stubs` project that is
|
|
308
|
+
* identical except for the pool, which is the default one. A plugin's `test` and `test:coverage` scripts
|
|
309
|
+
* name `unit-tests`, which also selects every `unit-tests:*` project, so the sibling runs and is covered
|
|
310
|
+
* without a script change. It is emitted only when this list is non-empty.
|
|
311
|
+
*
|
|
312
|
+
* To keep a whole suite on the default pool instead, set `unitTests.pool` to `'forks'` and say why.
|
|
313
|
+
*/
|
|
314
|
+
globalStubTestFiles = [];
|
|
315
|
+
/**
|
|
316
|
+
* The multiplier applied to a project's test budget to get its hook budget. A hook typically populates
|
|
317
|
+
* and opens a vault, so it needs several times what a single test does.
|
|
318
|
+
*
|
|
319
|
+
* @default `4`
|
|
320
|
+
*/
|
|
321
|
+
hookTimeoutMultiplier = HOOK_TIMEOUT_MULTIPLIER;
|
|
322
|
+
/**
|
|
323
|
+
* The `integration-tests:no-app` project, running the suites that need no Obsidian instance at all.
|
|
324
|
+
*/
|
|
325
|
+
noApp = {
|
|
326
|
+
environment: "node",
|
|
327
|
+
fileParallelism: false,
|
|
328
|
+
hookTimeout: INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS * HOOK_TIMEOUT_MULTIPLIER,
|
|
329
|
+
include: [NO_APP_TEST_FILES],
|
|
330
|
+
name: "integration-tests:no-app",
|
|
331
|
+
testTimeout: INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS
|
|
332
|
+
};
|
|
333
|
+
/**
|
|
334
|
+
* The per-eval cap the performance integration project gives its CDP transport, in milliseconds.
|
|
335
|
+
*
|
|
336
|
+
* @default `600000`
|
|
337
|
+
*/
|
|
338
|
+
performanceEvalCapInMilliseconds = import_performance_eval_cap.PERFORMANCE_EVAL_CAP_IN_MILLISECONDS;
|
|
339
|
+
/**
|
|
340
|
+
* The per-test budget of the performance integration project, in milliseconds. A performance vault is
|
|
341
|
+
* pre-populated with tens of thousands of notes before Obsidian opens, so both its setup and its tests
|
|
342
|
+
* need far more time than the regular integration projects.
|
|
343
|
+
*
|
|
344
|
+
* Like the regular budget, it CLEARS the project's per-eval cap
|
|
345
|
+
* ({@link ObsidianPluginVitestConfigContext.performanceEvalCapInMilliseconds}) rather than matching it,
|
|
346
|
+
* so an evaluation that outruns the cap reports itself instead of dying as vitest's anonymous timeout.
|
|
347
|
+
*
|
|
348
|
+
* @default `615000`
|
|
349
|
+
*/
|
|
350
|
+
performanceTimeoutInMilliseconds = PERFORMANCE_TIMEOUT_IN_MILLISECONDS;
|
|
351
|
+
/**
|
|
352
|
+
* The reporters the run prints through.
|
|
353
|
+
*
|
|
354
|
+
* Pinned rather than left to vitest, which resolves an unset `reporters` differently for a developer
|
|
355
|
+
* and for an AI coding session — see {@link DEFAULT_VITEST_REPORTERS} for the whole of why, and for
|
|
356
|
+
* what it deliberately leaves to vitest 5 itself.
|
|
357
|
+
*
|
|
358
|
+
* Push onto it to add a reporter beside the pinned one.
|
|
359
|
+
*
|
|
360
|
+
* @default {@link DEFAULT_VITEST_REPORTERS}
|
|
361
|
+
*/
|
|
362
|
+
reporters = [...import_vitest_config.DEFAULT_VITEST_REPORTERS];
|
|
363
|
+
/**
|
|
364
|
+
* The `unit-tests` project, running the mocked-Obsidian suites in `jsdom`.
|
|
365
|
+
*/
|
|
366
|
+
unitTests = {
|
|
367
|
+
environment: "jsdom",
|
|
368
|
+
exclude: [...SHARED_EXCLUDE, INTEGRATION_TEST_FILES],
|
|
369
|
+
// A threads/forks pool option that still reaches the worker under the VM pool below: measured
|
|
370
|
+
// 2026-09-16, `process.execArgv` carries it and Node's own `localStorage` descriptor is gone, as it
|
|
371
|
+
// is under `threads`. Without the flag the descriptor is back under both pools.
|
|
372
|
+
execArgv: ["--no-webstorage"],
|
|
373
|
+
include: [UNIT_TEST_FILES],
|
|
374
|
+
name: "unit-tests",
|
|
375
|
+
/*
|
|
376
|
+
* The default pool constructs one jsdom per test file, and that construction, not the tests, was
|
|
377
|
+
* the unit suite's cost: 67% of tracked time in `obsidian-dev-utils`' own suite. A VM pool builds
|
|
378
|
+
* the jsdom once per worker and gives each file a fresh VM context, so per-file isolation holds.
|
|
379
|
+
* Measured there on 2026-09-15: the jsdom project 36.06s -> 9.92s, `coverage/lcov.info`
|
|
380
|
+
* byte-identical to the default pool's, and no DOM, `globalThis` or prototype state crossing files.
|
|
381
|
+
* `isolate: false`, the other remedy vitest suggests, was slower (91.62s) and broke 68 tests.
|
|
382
|
+
* The one cost is redefining `window`, `document`, `location` or `top`: see `globalStubTestFiles`.
|
|
383
|
+
*/
|
|
384
|
+
pool: "vmThreads",
|
|
385
|
+
server: {
|
|
386
|
+
// eslint-disable-next-line unicorn/name-replacements -- `deps` is declared by `vitest`; renaming it here would not match the API.
|
|
387
|
+
deps: {
|
|
388
|
+
inline: ["@obsidian-typings", "obsidian-dev-utils"]
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
setupFiles: [
|
|
392
|
+
"obsidian-test-mocks/vitest-setup",
|
|
393
|
+
"obsidian-dev-utils/vitest-setup"
|
|
394
|
+
]
|
|
395
|
+
};
|
|
396
|
+
/**
|
|
397
|
+
* Creates a new context seeded with the standard projects.
|
|
398
|
+
*/
|
|
399
|
+
constructor() {
|
|
400
|
+
const obsidianVersion = import_node_process.default.env[OBSIDIAN_VERSION_ENV_VARIABLE_NAME];
|
|
401
|
+
if (obsidianVersion !== void 0) {
|
|
402
|
+
this.desktop.environmentOptions = {
|
|
403
|
+
obsidianTransport: {
|
|
404
|
+
obsidianVersion,
|
|
405
|
+
type: "obsidian-cdp"
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
function defineObsidianPluginVitestConfig(options = {}) {
|
|
412
|
+
const context = new ObsidianPluginVitestConfigContext();
|
|
413
|
+
if (options.editContext) {
|
|
414
|
+
options.editContext(context);
|
|
415
|
+
}
|
|
416
|
+
const customProjects = options.customProjects?.(context) ?? [];
|
|
417
|
+
validateCustomProjects(customProjects);
|
|
418
|
+
const unitTestsResolve = {
|
|
419
|
+
alias: {
|
|
420
|
+
obsidian: "obsidian-test-mocks/obsidian"
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
const globalStubTestFiles = [...context.globalStubTestFiles];
|
|
424
|
+
const unitTests = globalStubTestFiles.length === 0 ? context.unitTests : { ...context.unitTests, exclude: [...context.unitTests.exclude ?? [], ...globalStubTestFiles] };
|
|
425
|
+
const globalStubsProjects = globalStubTestFiles.length === 0 ? [] : [{
|
|
426
|
+
resolve: unitTestsResolve,
|
|
427
|
+
test: {
|
|
428
|
+
...context.unitTests,
|
|
429
|
+
include: globalStubTestFiles,
|
|
430
|
+
name: UNIT_TEST_GLOBAL_STUBS_PROJECT_NAME,
|
|
431
|
+
// The default pool, named rather than omitted so the spread above cannot carry the VM pool over.
|
|
432
|
+
pool: "forks"
|
|
433
|
+
}
|
|
434
|
+
}];
|
|
435
|
+
return (0, import_config.defineConfig)({
|
|
436
|
+
test: {
|
|
437
|
+
coverage: {
|
|
438
|
+
exclude: context.coverageExclude,
|
|
439
|
+
include: ["src/**/*.ts"],
|
|
440
|
+
provider: "v8",
|
|
441
|
+
reporter: ["text", "lcov", "html"],
|
|
442
|
+
reportsDirectory: "./coverage"
|
|
443
|
+
},
|
|
444
|
+
exclude: [...SHARED_EXCLUDE],
|
|
445
|
+
globals: false,
|
|
446
|
+
/*
|
|
447
|
+
* There is deliberately NO root-level `include` here, and restoring one breaks every project.
|
|
448
|
+
* Under vitest 4 a project's own `include` replaced the root one, so a root
|
|
449
|
+
* `include: [UNIT_TEST_FILES]` was merely redundant — the `unit-tests` project already declares
|
|
450
|
+
* that same glob for itself. Under vitest 5 the project glob no longer replaces it, and
|
|
451
|
+
* `src/**\/*.test.ts` is a superset of every project glob, so EVERY project collected EVERY test
|
|
452
|
+
* file: unit suites ran in the CDP integration environment and died on `Failed to resolve entry
|
|
453
|
+
* for package "obsidian"`, the screenshot-capture suites ran and rewrote checked-in PNGs, and the
|
|
454
|
+
* android / demo-vault suites ran under the desktop transport. Measured in a consumer: the desktop
|
|
455
|
+
* project collected 227 files instead of its own 105, and deleting this one line restored 105.
|
|
456
|
+
*/
|
|
457
|
+
passWithNoTests: true,
|
|
458
|
+
projects: [
|
|
459
|
+
{
|
|
460
|
+
resolve: unitTestsResolve,
|
|
461
|
+
test: unitTests
|
|
462
|
+
},
|
|
463
|
+
{ test: context.noApp },
|
|
464
|
+
{ test: context.desktop },
|
|
465
|
+
{ test: context.desktopPerformance },
|
|
466
|
+
{ test: context.android },
|
|
467
|
+
...globalStubsProjects,
|
|
468
|
+
...customProjects
|
|
469
|
+
],
|
|
470
|
+
reporters: [...context.reporters]
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
function validateCustomProjects(customProjects) {
|
|
475
|
+
for (const [index, customProject] of customProjects.entries()) {
|
|
476
|
+
if (typeof customProject !== "object" || "then" in customProject) {
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
const include = customProject.test?.include;
|
|
480
|
+
if (include && include.length > 0) {
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
const name = customProject.test?.name;
|
|
484
|
+
const label = typeof name === "string" ? name : name?.label ?? `at index ${String(index)}`;
|
|
485
|
+
throw new Error(
|
|
486
|
+
`The custom vitest project ${label} declares no \`test.include\`, so vitest falls back to its default glob and the project collects EVERY test file \u2014 including the \`*-capture.\` suites that rewrite checked-in screenshots. Declare an explicit \`include\`, or spread a standard project (\`...context.desktop\`) and override it.`
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
491
|
+
0 && (module.exports = {
|
|
492
|
+
DEFAULT_VITEST_REPORTERS,
|
|
493
|
+
INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS,
|
|
494
|
+
ObsidianPluginVitestConfigContext,
|
|
495
|
+
defineObsidianPluginVitestConfig
|
|
496
|
+
});
|
|
497
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL3Rlc3QtcnVubmVycy92aXRlc3QtY29uZmlnLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogU2hhcmVkIHZpdGVzdCBjb25maWd1cmF0aW9uIGZvciBPYnNpZGlhbiBwbHVnaW5zLlxuICpcbiAqIEV2ZXJ5IHBsdWdpbiBpbiB0aGUgd29ya3NwYWNlIGRlY2xhcmVzIHRoZSBzYW1lIGZpdmUgdml0ZXN0IHByb2plY3RzIFx1MjAxNCBgdW5pdC10ZXN0c2AgcGx1cyB0aGVcbiAqIGBpbnRlZ3JhdGlvbi10ZXN0czp7bm8tYXBwLGRlc2t0b3AsZGVza3RvcC1wZXJmb3JtYW5jZSxhbmRyb2lkfWAgZmFtaWx5IFx1MjAxNCB3aXRoIHRoZSBzYW1lIHRpbWVvdXRzLFxuICogYHNldHVwRmlsZXNgLCBhbmQgYGdsb2JhbFNldHVwYCB3aXJpbmcuIE1haW50YWluaW5nIHRoYXQgcGVyIHJlcG8gbWVhbnMgYSBjb252ZW50aW9uIGNoYW5nZSBjb3N0cyBvbmVcbiAqIG5lYXItaWRlbnRpY2FsIGVkaXQgcGVyIHBsdWdpbiwgYW5kIGFueSByZXBvIHRoYXQgaXMgbWlzc2VkIGRyaWZ0cyBzaWxlbnRseS4gVGhpcyBtb2R1bGUgb3ducyB0aGF0XG4gKiBjb25maWd1cmF0aW9uIG9uY2UsIHNvIGEgcGx1Z2luJ3MgYHNjcmlwdHMvdml0ZXN0LWNvbmZpZy50c2AgY29sbGFwc2VzIHRvIGEgc2luZ2xlIGNhbGwuXG4gKlxuICogVGhlIHNlYW0gbWlycm9ycyB7QGxpbmsgaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2Uvb2JzaWRpYW4tZGV2LXV0aWxzIHwgdGhlIEVTTGludCBvbmV9XG4gKiAoYGRlZmluZUVzbGludENvbmZpZ3NgKTogdGhlIGZhY3RvcnkgYnVpbGRzIGEgY29udGV4dCBob2xkaW5nIHRoZSBzdGFuZGFyZCBwcm9qZWN0cywgdGhlIGNhbGxlciBlZGl0c1xuICogaXQgaW4gcGxhY2UgdGhyb3VnaCB7QGxpbmsgRGVmaW5lT2JzaWRpYW5QbHVnaW5WaXRlc3RDb25maWdPcHRpb25zLmVkaXRDb250ZXh0fSwgYW5kIGFwcGVuZHMgYW55XG4gKiBwcm9qZWN0IHRoZSBiYXNlIGRvZXMgbm90IGtub3cgYWJvdXQgdGhyb3VnaFxuICoge0BsaW5rIERlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnT3B0aW9ucy5jdXN0b21Qcm9qZWN0c30uXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBWaXRlc3RSZXBvcnRlciB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWRldi10b29sa2l0L3Rlc3QtcnVubmVycy92aXRlc3QtY29uZmlnJztcbmltcG9ydCB0eXBlIHtcbiAgVGVzdFByb2plY3RDb25maWd1cmF0aW9uLFxuICBUZXN0UHJvamVjdElubGluZUNvbmZpZ3VyYXRpb24sXG4gIFZpdGVVc2VyQ29uZmlnXG59IGZyb20gJ3ZpdGVzdC9jb25maWcnO1xuXG5pbXBvcnQge1xuICBERUZBVUxUX1ZJVEVTVF9SRVBPUlRFUlMsXG4gIERFRkFVTFRfVklURVNUX1RFU1RfRVhDTFVERVxufSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1kZXYtdG9vbGtpdC90ZXN0LXJ1bm5lcnMvdml0ZXN0LWNvbmZpZyc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuaW1wb3J0IHsgREVGQVVMVF9FVkFMX0NBUF9JTl9NSUxMSVNFQ09ORFMgfSBmcm9tICdvYnNpZGlhbi1pbnRlZ3JhdGlvbi10ZXN0aW5nJztcbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gJ3ZpdGVzdC9jb25maWcnO1xuXG5pbXBvcnQge1xuICBERVNLVE9QX1BFUkZPUk1BTkNFX1RFU1RfRklMRV9TVUZGSVgsXG4gIFBFUkZPUk1BTkNFX0VWQUxfQ0FQX0lOX01JTExJU0VDT05EU1xufSBmcm9tICcuL3BlcmZvcm1hbmNlLWV2YWwtY2FwLnRzJztcblxuLyoqXG4gKiBUaGUgYHRlc3RgIHNlY3Rpb24gb2YgYSBzaW5nbGUgdml0ZXN0IHByb2plY3QgZW50cnkuXG4gKi9cbmV4cG9ydCB0eXBlIE9ic2lkaWFuUGx1Z2luVml0ZXN0UHJvamVjdENvbmZpZyA9IE5vbk51bGxhYmxlPFRlc3RQcm9qZWN0SW5saW5lQ29uZmlndXJhdGlvblsndGVzdCddPjtcblxuLyoqXG4gKiBPbmUgZW50cnkgb2YgYSB2aXRlc3QgYHJlcG9ydGVyc2AgbGlzdDogdGhlIG5hbWUgb2YgYSBidWlsdC1pbiByZXBvcnRlciBvciBhIHJlcG9ydGVyIGluc3RhbmNlLiBUaGUgc2FtZSBzaGFwZSBhc1xuICogdGhlIGxpYnJhcnkgY29uZmlndXJhdGlvbidzIHtAbGluayBWaXRlc3RSZXBvcnRlcn0uXG4gKi9cbmV4cG9ydCB0eXBlIE9ic2lkaWFuUGx1Z2luVml0ZXN0UmVwb3J0ZXIgPSBWaXRlc3RSZXBvcnRlcjtcblxuLy8gVGhlIGxpYnJhcnkgY29uZmlndXJhdGlvbidzIHBpbm5lZCByZXBvcnRlcnMsIHJlLWV4cG9ydGVkIHNvIGEgcGx1Z2luIHJlcG8gdGhhdCBhc3NlbWJsZXMgaXRzIHZpdGVzdCBwcm9qZWN0cyBieVxuLy8gaGFuZCBuZWVkcyBvbmx5IHRoaXMgcGFja2FnZS5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB1bmljb3JuL3ByZWZlci1leHBvcnQtZnJvbSAtLSBUaGUgYmluZGluZyBpcyBhbHNvIHVzZWQgYmVsb3csIHNvIGl0IGlzIGltcG9ydGVkIG9uY2UuXG5leHBvcnQgeyBERUZBVUxUX1ZJVEVTVF9SRVBPUlRFUlMgfTtcblxuLypcbiAqIEhvdyBtdWNoIGEgcHJvamVjdCdzIHBlci10ZXN0IGJ1ZGdldCBjbGVhcnMgYERFRkFVTFRfRVZBTF9DQVBfSU5fTUlMTElTRUNPTkRTYCBieSBcdTIwMTQgdGhlIHBlci1ldmFsIGNhcFxuICogQk9USCB0cmFuc3BvcnRzIGVuZm9yY2UsIGltcG9ydGVkIGZyb20gYG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmdgIHJhdGhlciB0aGFuIHJlc3RhdGVkIHNvIHRoZVxuICogYnVkZ2V0cyBiZWxvdyBhbmQgdGhlIGNhcCB0aGV5IGFyZSBzaXplZCBhZ2FpbnN0IGNhbiBuZXZlciBiZSB0d28gbnVtYmVycy4gT25lIGBldmFsSW5PYnNpZGlhbmAgY2xvc3VyZVxuICogZ2V0cyB0aGF0IG11Y2ggYW5kIG5vIG1vcmUsIG1lYXN1cmVkIGZyb20gdGhlIG1vbWVudCB0aGUgdHJhbnNwb3J0IGRpc3BhdGNoZXMgaXQ7IG91dHJ1bm5pbmcgaXQgcmFpc2VzXG4gKiBgRXZhbENhcEV4Y2VlZGVkRXJyb3JgLCB3aGljaCBuYW1lcyB0aGUgY2FwLCB0aGUgdHJhbnNwb3J0IHRoYXQgZW5mb3JjZWQgaXQsIGFuZCB0aGUgYHBvbGxJbk9ic2lkaWFuYFxuICogcmVtZWR5IFx1MjAxNCB0aGUgb25lIG1lc3NhZ2UgdGhhdCB0dXJucyBcInRoaXMgdGltZWQgb3V0XCIgaW50byBcInRoaXMgY2xvc3VyZSBhc2tlZCBmb3IgbW9yZSB0aW1lIHRoYW5cbiAqIGV4aXN0c1wiLlxuICpcbiAqIEEgdGVzdCBidWRnZXQgRVFVQUwgdG8gdGhlIGNhcCBtYWtlcyB0aGUgY2FwJ3Mgb3duIGRpYWdub3NpcyB1bnJlYWNoYWJsZTogdml0ZXN0IHN0YXJ0cyBpdHMgY2xvY2sgYXRcbiAqIHRoZSB0b3Agb2YgdGhlIHRlc3QgYW5kIHRoZSB0cmFuc3BvcnQgc3RhcnRzIGl0cyBvd24gb25seSBvbmNlIHRoZSBldmFsIGlzIGRpc3BhdGNoZWQsIHNvIHZpdGVzdCBhbHdheXNcbiAqIHdpbnMgYnkgdGhlIGZldyBtaWxsaXNlY29uZHMgaW4gYmV0d2VlbiBhbmQgcmVwb3J0cyBpdHMgYW5vbnltb3VzIGBUZXN0IHRpbWVkIG91dCBpbiAzMDAwMG1zYC4gVGhhdCBpc1xuICogbm90IGEgaHlwb3RoZXRpY2FsIFx1MjAxNCBpdCBpcyBob3cgZXZlcnkgb3Zlci1jYXAgZGVza3RvcCBldmFsIGhhZCBzdXJmYWNlZCBoZXJlIHVudGlsIHRoaXMgbWFyZ2luIGV4aXN0ZWQsXG4gKiBhbmQgb25lIG9mIHRoZW0gYWJvcnRlZCBhbiBvdGhlcndpc2UgZ3JlZW4gcmVsZWFzZSBmaXZlIG1pbnV0ZXMgaW50byB0aGUgcHJlZmxpZ2h0IHdpdGggbm8gaW5kaWNhdGlvblxuICogb2Ygd2hpY2ggd2FpdCB3YXMgdG8gYmxhbWUgKG1lYXN1cmVkIDIwMjYtMDktMTU6IDMwMDQ0IG1zIGJ1cm5lZCBhZ2FpbnN0IGEgMzAwMDAgbXMgYnVkZ2V0KS5cbiAqXG4gKiBUaGUgbWFyZ2luIGhhcyB0byBjb3ZlciBldmVyeXRoaW5nIGEgdGVzdCBkb2VzIEJFRk9SRSB0aGUgZXZhbCB0aGF0IGhhbmdzIFx1MjAxNCBlYXJsaWVyIG9uZXMgaW5jbHVkZWQgXHUyMDE0XG4gKiBzbyBpdCBpcyBhIGhlYWx0aHkgZnJhY3Rpb24gb2YgdGhlIGNhcCByYXRoZXIgdGhhbiBhIGNvdXBsZSBvZiBzZWNvbmRzLlxuICovXG5jb25zdCBUUkFOU1BPUlRfRVZBTF9DQVBfTUFSR0lOX0lOX01JTExJU0VDT05EUyA9IDE1XzAwMDtcblxuLypcbiAqIEFuZHJvaWQgd2FzIG5ldmVyIGFmZmVjdGVkLCBhbmQgdGhhdCBhc3ltbWV0cnkgaXMgdGhlIGV2aWRlbmNlIHRoZSBkZXNrdG9wIGVxdWFsaXR5IHdhcyBhbiBvdmVyc2lnaHRcbiAqIHJhdGhlciB0aGFuIGEgZGVjaXNpb246IGl0cyBidWRnZXQgaGFzIGFsd2F5cyBiZWVuIGRvdWJsZSB0aGUgQXBwaXVtIGNhcCwgc28gYW4gb3Zlci1jYXAgbW9iaWxlIGNsb3N1cmVcbiAqIGhhcyBhbHdheXMgYmVlbiBhYmxlIHRvIHJlcG9ydCBpdHNlbGYuXG4gKi9cbmNvbnN0IEFORFJPSURfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSA2MF8wMDA7XG5jb25zdCBIT09LX1RJTUVPVVRfTVVMVElQTElFUiA9IDQ7XG5cbi8qXG4gKiBUaGUgcGVyZm9ybWFuY2UgcHJvamVjdCdzIGJ1ZGdldCBjbGVhcnMgaXRzIG93biBwZXItZXZhbCBjYXAgYnkgdGhlIHNhbWUgbWFyZ2luLCBmb3IgdGhlIHNhbWUgcmVhc29uXG4gKiB0aGUgcmVndWxhciBidWRnZXQgY2xlYXJzIHRoZSB0cmFuc3BvcnQgZGVmYXVsdDogYW4gZXF1YWwgYnVkZ2V0IGxldHMgdml0ZXN0J3MgYW5vbnltb3VzIHRpbWVvdXQgd2luXG4gKiB0aGUgcmFjZSBhZ2FpbnN0IHRoZSBjYXAncyBvd24gYEV2YWxDYXBFeGNlZWRlZEVycm9yYC5cbiAqL1xuY29uc3QgUEVSRk9STUFOQ0VfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSBQRVJGT1JNQU5DRV9FVkFMX0NBUF9JTl9NSUxMSVNFQ09ORFMgKyBUUkFOU1BPUlRfRVZBTF9DQVBfTUFSR0lOX0lOX01JTExJU0VDT05EUztcblxuLyoqXG4gKiBUaGUgcGVyLXRlc3QgYnVkZ2V0IG9mIHRoZSByZWd1bGFyIGludGVncmF0aW9uIHByb2plY3RzLCBpbiBtaWxsaXNlY29uZHMuXG4gKlxuICogRXhwb3J0ZWQgYmVjYXVzZSBhIHJlcG8gdGhhdCBhc3NlbWJsZXMgaXRzIHZpdGVzdCBwcm9qZWN0cyBieSBoYW5kIGluc3RlYWQgb2YgdGhyb3VnaFxuICoge0BsaW5rIGRlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnfSBzdGlsbCBuZWVkcyB0aGUgc2FtZSByZWxhdGlvbnNoaXAgdG8gdGhlIHBlci1ldmFsIGNhcCwgYW5kXG4gKiByZXN0YXRpbmcgdGhlIG51bWJlciB0aGVyZSBpcyBob3cgdGhlIHR3byBkcmlmdCBhcGFydC5cbiAqL1xuZXhwb3J0IGNvbnN0IElOVEVHUkFUSU9OX1RFU1RfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSBERUZBVUxUX0VWQUxfQ0FQX0lOX01JTExJU0VDT05EUyArIFRSQU5TUE9SVF9FVkFMX0NBUF9NQVJHSU5fSU5fTUlMTElTRUNPTkRTO1xuXG5jb25zdCBBTkRST0lEX1RFU1RfRklMRVMgPSAnc3JjLyoqLyouYW5kcm9pZC5pbnRlZ3JhdGlvbi50ZXN0LnRzJztcbmNvbnN0IENST1NTX1BMQVRGT1JNX1RFU1RfRklMRVMgPSAnc3JjLyoqLyouY3Jvc3MtcGxhdGZvcm0uaW50ZWdyYXRpb24udGVzdC50cyc7XG5jb25zdCBERUNMQVJBVElPTl9GSUxFUyA9ICdzcmMvKiovKi5kLnRzJztcbmNvbnN0IERFU0tUT1BfUEVSRk9STUFOQ0VfVEVTVF9GSUxFUyA9IGBzcmMvKiovKiR7REVTS1RPUF9QRVJGT1JNQU5DRV9URVNUX0ZJTEVfU1VGRklYfWA7XG5jb25zdCBERVNLVE9QX1RFU1RfRklMRVMgPSAnc3JjLyoqLyouZGVza3RvcC5pbnRlZ3JhdGlvbi50ZXN0LnRzJztcbmNvbnN0IElOVEVHUkFUSU9OX1RFU1RfRklMRVMgPSAnc3JjLyoqLyouaW50ZWdyYXRpb24udGVzdC50cyc7XG5jb25zdCBOT19BUFBfVEVTVF9GSUxFUyA9ICdzcmMvKiovKi5uby1hcHAuaW50ZWdyYXRpb24udGVzdC50cyc7XG5jb25zdCBVTklUX1RFU1RfRklMRVMgPSAnc3JjLyoqLyoudGVzdC50cyc7XG5jb25zdCBVTklUX1RFU1RfR0xPQkFMX1NUVUJTX1BST0pFQ1RfTkFNRSA9ICd1bml0LXRlc3RzOmdsb2JhbC1zdHVicyc7XG5cbi8qXG4gKiBSdW5zIGJlZm9yZSB0aGUgaGFybmVzcydzIG93biBzZXR1cCBpbiBldmVyeSBwcm9qZWN0IHRoYXQgbG9hZHMgdGhlIHBsdWdpbiBmcm9tIGBkaXN0L2J1aWxkL21haW4uanNgLFxuICogYW5kIHJlZnVzZXMgdG8gc3RhcnQgd2hlbiB0aGF0IGJ1aWxkIGlzIG1pc3Npbmcgb3Igb2xkZXIgdGhhbiB0aGUgc291cmNlLiBBIHBsdWdpbidzXG4gKiBgdGVzdDppbnRlZ3JhdGlvbipgIHNjcmlwdHMgY2FsbCB2aXRlc3QgZGlyZWN0bHkgYW5kIG5ldmVyIGJ1aWxkLCBzbyB3aXRob3V0IGl0IGEgc2Vzc2lvbiB0aGF0IGVkaXRzXG4gKiBgc3JjL2AgYW5kIHJ1bnMgb25lIGludGVncmF0aW9uIHByb2plY3QgdGVzdHMgdGhlIHByZXZpb3VzIGJ1aWxkIGFuZCByZWFkcyB0aGUgcmVzdWx0IGFzIGEgZGVmZWN0LlxuICovXG5jb25zdCBTVEFMRV9CVUlMRF9HTE9CQUxfU0VUVVAgPSAnb2JzaWRpYW4tZGV2LXV0aWxzL3NjcmlwdC11dGlscy90ZXN0LXJ1bm5lcnMvc3RhbGUtYnVpbGQtZ2xvYmFsLXNldHVwJztcblxuY29uc3QgT0JTSURJQU5fVkVSU0lPTl9FTlZfVkFSSUFCTEVfTkFNRSA9ICdPQlNJRElBTl9WRVJTSU9OJztcbmNvbnN0IFNIQVJFRF9FWENMVURFID0gREVGQVVMVF9WSVRFU1RfVEVTVF9FWENMVURFO1xuXG4vKipcbiAqIFRoZSBvcHRpb25zIGZvciBkZWZpbmluZyBhIHBsdWdpbidzIHZpdGVzdCBjb25maWd1cmF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBBIGZ1bmN0aW9uIHRoYXQgYnVpbGRzIHByb2plY3RzIHRoZSBiYXNlIGNvbmZpZ3VyYXRpb24gZG9lcyBub3Qga25vdyBhYm91dCwgc3VjaCBhcyBhIHBsdWdpbidzIG93blxuICAgKiBgaW50ZWdyYXRpb24tdGVzdHM6ZGVtby12YXVsdGAgcHJvamVjdC4gVGhlIHJldHVybmVkIHByb2plY3RzIGFyZSBhcHBlbmRlZCBhZnRlciB0aGUgc3RhbmRhcmQgZml2ZS5cbiAgICpcbiAgICogQHBhcmFtIGNvbnRleHQgLSBUaGUgdml0ZXN0IGNvbmZpZ3VyYXRpb24gY29udGV4dC5cbiAgICogQHJldHVybnMgVGhlIGV4dHJhIHByb2plY3RzLlxuICAgKi9cbiAgcmVhZG9ubHkgY3VzdG9tUHJvamVjdHM/OiAoY29udGV4dDogT2JzaWRpYW5QbHVnaW5WaXRlc3RDb25maWdDb250ZXh0KSA9PiBUZXN0UHJvamVjdENvbmZpZ3VyYXRpb25bXTtcblxuICAvKipcbiAgICogQSBmdW5jdGlvbiB0aGF0IGVkaXRzIHRoZSB2aXRlc3QgY29uZmlndXJhdGlvbiBjb250ZXh0IGJlZm9yZSBpdCBpcyBhc3NlbWJsZWQgaW50byBhIGNvbmZpZ3VyYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSBjb250ZXh0IC0gVGhlIHZpdGVzdCBjb25maWd1cmF0aW9uIGNvbnRleHQuXG4gICAqL1xuICByZWFkb25seSBlZGl0Q29udGV4dD86IChjb250ZXh0OiBPYnNpZGlhblBsdWdpblZpdGVzdENvbmZpZ0NvbnRleHQpID0+IHZvaWQ7XG59XG5cbi8qKlxuICogVGhlIGNvbnRleHQgZm9yIGRlZmluaW5nIGEgcGx1Z2luJ3Mgdml0ZXN0IGNvbmZpZ3VyYXRpb24uXG4gKlxuICogRXZlcnkgbWVtYmVyIGlzIGxpdmU6IHRoZSBhcnJheXMgYW5kIG9iamVjdHMgaXQgZXhwb3NlcyBhcmUgdGhlIHZlcnkgb25lcyB0aGUgYXNzZW1ibGVkIGNvbmZpZ3VyYXRpb25cbiAqIGlzIGJ1aWx0IGZyb20sIHNvIGVkaXRpbmcgdGhlbSBpbiBwbGFjZSB0aHJvdWdoXG4gKiB7QGxpbmsgRGVmaW5lT2JzaWRpYW5QbHVnaW5WaXRlc3RDb25maWdPcHRpb25zLmVkaXRDb250ZXh0fSBpcyB3aGF0IGN1c3RvbWl6ZXMgdGhlIHJlc3VsdC5cbiAqL1xuZXhwb3J0IGNsYXNzIE9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnQ29udGV4dCB7XG4gIC8qKlxuICAgKiBUaGUgYGludGVncmF0aW9uLXRlc3RzOmFuZHJvaWRgIHByb2plY3QsIHJ1bm5pbmcgdGhlIG1vYmlsZS1vbmx5IGFuZCBjcm9zcy1wbGF0Zm9ybSBzdWl0ZXMgYWdhaW5zdCBhblxuICAgKiBBbmRyb2lkIGVtdWxhdG9yIHRocm91Z2ggQXBwaXVtLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFuZHJvaWQ6IE9ic2lkaWFuUGx1Z2luVml0ZXN0UHJvamVjdENvbmZpZyA9IHtcbiAgICBlbnZpcm9ubWVudDogJ25vZGUnLFxuICAgIGVudmlyb25tZW50T3B0aW9uczoge1xuICAgICAgb2JzaWRpYW5UcmFuc3BvcnQ6IHtcbiAgICAgICAgYXBwaXVtVXJsOiAnaHR0cDovL2xvY2FsaG9zdDo0NzIzJyxcbiAgICAgICAgYXZkTmFtZTogJ29ic2lkaWFuX3Rlc3QnLFxuICAgICAgICB0eXBlOiAnb2JzaWRpYW4tYW5kcm9pZC1hcHBpdW0nXG4gICAgICB9XG4gICAgfSxcbiAgICBmaWxlUGFyYWxsZWxpc206IGZhbHNlLFxuICAgIGdsb2JhbFNldHVwOiBbU1RBTEVfQlVJTERfR0xPQkFMX1NFVFVQLCAnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZy92aXRlc3QtZ2xvYmFsLXNldHVwLXBsdWdpbiddLFxuICAgIGhvb2tUaW1lb3V0OiBBTkRST0lEX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTICogSE9PS19USU1FT1VUX01VTFRJUExJRVIsXG4gICAgaW5jbHVkZTogW0FORFJPSURfVEVTVF9GSUxFUywgQ1JPU1NfUExBVEZPUk1fVEVTVF9GSUxFU10sXG4gICAgbmFtZTogJ2ludGVncmF0aW9uLXRlc3RzOmFuZHJvaWQnLFxuICAgIHNldHVwRmlsZXM6IFsnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZy92aXRlc3Qtc2V0dXAnXSxcbiAgICB0ZXN0VGltZW91dDogQU5EUk9JRF9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICB9O1xuXG4gIC8qKlxuICAgKiBUaGUgcGVyLXRlc3QgYnVkZ2V0IG9mIHRoZSBBbmRyb2lkIGludGVncmF0aW9uIHByb2plY3QsIGluIG1pbGxpc2Vjb25kcy4gQm9vdGluZyBhbiBlbXVsYXRvciBhbmRcbiAgICogZHJpdmluZyBpdCBvdmVyIEFwcGl1bSBpcyBzbG93ZXIgdGhhbiB0aGUgZGVza3RvcCBwYXRoLCBoZW5jZSBpdHMgb3duIGNvbnN0YW50LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgNjAwMDBgXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYW5kcm9pZFRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IEFORFJPSURfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG5cbiAgLyoqXG4gICAqIFRoZSBwZXItdGVzdCBidWRnZXQgb2YgdGhlIHJlZ3VsYXIgaW50ZWdyYXRpb24gcHJvamVjdHMsIGluIG1pbGxpc2Vjb25kcy5cbiAgICpcbiAgICogSXQgZGVsaWJlcmF0ZWx5IENMRUFSUyB0aGUgdHJhbnNwb3J0cycgcGVyLWV2YWwgY2FwIHJhdGhlciB0aGFuIG1hdGNoaW5nIGl0LCBzbyB0aGF0IGEgY2xvc3VyZSB3aGljaFxuICAgKiBvdXRydW5zIHRoZSBjYXAgZmFpbHMgd2l0aCB0aGUgaGFybmVzcydzIGBFdmFsQ2FwRXhjZWVkZWRFcnJvcmAgXHUyMDE0IG5hbWluZyB0aGUgY2FwIGFuZCB0aGUgcmVtZWR5IFx1MjAxNFxuICAgKiBpbnN0ZWFkIG9mIHdpdGggdml0ZXN0J3MgYW5vbnltb3VzIHRpbWVvdXQuIExvd2VyaW5nIGl0IHRvIHRoZSBjYXAgcmVzdG9yZXMgdGhhdCBibGluZCBzcG90LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgNDUwMDBgXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYmlnVGltZW91dEluTWlsbGlzZWNvbmRzID0gSU5URUdSQVRJT05fVEVTVF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcblxuICAvKipcbiAgICogVGhlIGNvdmVyYWdlIGBleGNsdWRlYCBnbG9icy4gUHVzaCBvbnRvIGl0IHRvIGRyb3AgbW9yZSBmaWxlcyBmcm9tIHRoZSBjb3ZlcmFnZSByZXBvcnQuXG4gICAqXG4gICAqIERlY2xhcmF0aW9uIGZpbGVzIGFyZSBleGNsdWRlZCBieSBkZWZhdWx0IGJlY2F1c2UgdGhlIGNvdmVyYWdlIGBpbmNsdWRlYCBiZWxvdyBpcyBgc3JjLyoqXFwvKi50c2AsXG4gICAqIHdoaWNoIGEgYC5kLnRzYCBtYXRjaGVzLiBBIGRlY2xhcmF0aW9uIGZpbGUgZW1pdHMgbm8gcnVudGltZSBjb2RlLCBzbyBpdCByZXBvcnRzIDAlIGFuZCBubyB0ZXN0IGNhblxuICAgKiBldmVyIHJhaXNlIGl0IFx1MjAxNCBhIHBsdWdpbiB0aGF0IGdyb3dzIG9uZSB1bmRlciBgc3JjL2Agc2lsZW50bHkgbG9zZXMgaXRzIDEwMCUgZ2F0ZSwgYW5kIHRoZSB1c3VhbFxuICAgKiByZW1lZHkgb2YgYW4gaW5saW5lIGB2OCBpZ25vcmVgIGNvbW1lbnQgZG9lcyBub3QgYXBwbHkgdG8gYSB0eXBlLW9ubHkgZmlsZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjb3ZlcmFnZUV4Y2x1ZGU6IHN0cmluZ1tdID0gW1VOSVRfVEVTVF9GSUxFUywgREVDTEFSQVRJT05fRklMRVNdO1xuXG4gIC8qKlxuICAgKiBUaGUgYGludGVncmF0aW9uLXRlc3RzOmRlc2t0b3BgIHByb2plY3QsIHJ1bm5pbmcgdGhlIGRlc2t0b3Atb25seSBhbmQgY3Jvc3MtcGxhdGZvcm0gc3VpdGVzIGFnYWluc3QgYVxuICAgKiByZWFsIGRlc2t0b3AgT2JzaWRpYW4gb3ZlciBDRFAuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZGVza3RvcDogT2JzaWRpYW5QbHVnaW5WaXRlc3RQcm9qZWN0Q29uZmlnID0ge1xuICAgIGVudmlyb25tZW50OiAnbm9kZScsXG4gICAgZmlsZVBhcmFsbGVsaXNtOiBmYWxzZSxcbiAgICBnbG9iYWxTZXR1cDogW1NUQUxFX0JVSUxEX0dMT0JBTF9TRVRVUCwgJ29ic2lkaWFuLWludGVncmF0aW9uLXRlc3Rpbmcvdml0ZXN0LWdsb2JhbC1zZXR1cC1wbHVnaW4nXSxcbiAgICBob29rVGltZW91dDogSU5URUdSQVRJT05fVEVTVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyAqIEhPT0tfVElNRU9VVF9NVUxUSVBMSUVSLFxuICAgIGluY2x1ZGU6IFtERVNLVE9QX1RFU1RfRklMRVMsIENST1NTX1BMQVRGT1JNX1RFU1RfRklMRVNdLFxuICAgIG5hbWU6ICdpbnRlZ3JhdGlvbi10ZXN0czpkZXNrdG9wJyxcbiAgICBzZXR1cEZpbGVzOiBbJ29ic2lkaWFuLWludGVncmF0aW9uLXRlc3Rpbmcvdml0ZXN0LXNldHVwJ10sXG4gICAgdGVzdFRpbWVvdXQ6IElOVEVHUkFUSU9OX1RFU1RfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFNcbiAgfTtcblxuICAvKipcbiAgICogVGhlIGBpbnRlZ3JhdGlvbi10ZXN0czpkZXNrdG9wLXBlcmZvcm1hbmNlYCBwcm9qZWN0LCBydW5uaW5nIHRoZSBhdC1zY2FsZSBzdWl0ZXMuIEl0IGlzIGRlY2xhcmVkIGZvclxuICAgKiBldmVyeSBwbHVnaW4gZXZlbiB3aGVuIHRoZXJlIGlzIG5vIHN1Y2ggc3VpdGUgeWV0IFx1MjAxNCBgcGFzc1dpdGhOb1Rlc3RzYCBtYWtlcyBhbiBlbXB0eSBwcm9qZWN0IGZyZWUsXG4gICAqIGFuZCB0aGUgbWF0Y2hpbmcgYHRlc3Q6aW50ZWdyYXRpb246ZGVza3RvcDpwZXJmb3JtYW5jZWAgc2NyaXB0IGV4aXN0cyBpbiBldmVyeSBwbHVnaW4gYnVpbHQgb24gdGhpcyBsaWJyYXJ5LlxuICAgKlxuICAgKiBBIHBsdWdpbidzIGB0ZXN0OmludGVncmF0aW9uYCBhZ2dyZWdhdGUgbGVhdmVzIHRoaXMgcHJvamVjdCBvdXQgb24gcHVycG9zZSwgYW5kIGl0IHN0YXlzIG91dCBldmVuIG9uIGFcbiAgICogbWFjaGluZSB3aXRoIGEgZGVza3RvcCBPYnNpZGlhbiBzZXQgdXAuIFRoZSByZWFzb24gaXMgdGhlIGZpeHR1cmUgcmF0aGVyIHRoYW4gdGhlIGNvc3Q6IGEgcGVyZiBzdWl0ZVxuICAgKiBuZWVkcyBpdHMgb3duIGdlbmVyYXRlZCwgcG9wdWxhdGVkIHZhdWx0LCBzaXplZCB0aHJvdWdoIGVudiB2YXJzLCBhbmQgdGhlIGFnZ3JlZ2F0ZSdzIHNtYWxsIHRlbXBvcmFyeVxuICAgKiB2YXVsdCBpcyB0aGUgd3Jvbmcgb25lLiBUaGUgNjAwIHMgYmVsb3cgaXMgYSB0aW1lb3V0LCBub3QgYSBkdXJhdGlvbiBcdTIwMTQgbWVhc3VyZWQgZW5kIHRvIGVuZCwgbW9zdCBwZXJmXG4gICAqIHN1aXRlcyBmaW5pc2ggaW4gc2Vjb25kcywgYW5kIG9ubHkgb25lIHRoYXQgZ2VuZXJhdGVzIHRlbnMgb2YgdGhvdXNhbmRzIG9mIG5vdGVzIHRha2VzIG1pbnV0ZXMuXG4gICAqXG4gICAqIEl0cyBDRFAgdHJhbnNwb3J0J3MgcGVyLWV2YWwgY2FwIGlzIHJhaXNlZCB0byA2MDAgcyBhcyB3ZWxsICh0aGUgYnVkZ2V0IGNsZWFycyBpdCBieSB0aGUgdXN1YWxcbiAgICogbWFyZ2luKSwgYmVjYXVzZSBhIHBlcmYgc3VpdGUncyB3aG9sZSBtZWFzdXJlbWVudCBpcyB0eXBpY2FsbHkgT05FIGxvbmcgaW4tcGFnZSBldmFsdWF0aW9uLCB3aGljaCB0aGVcbiAgICogdHJhbnNwb3J0J3MgMzAgcyBkZWZhdWx0IGtpbGxlZCBhcyBhIGJhcmUgYENEUCBjb21tYW5kIHRpbWVkIG91dCBcdTIwMjYgUnVudGltZS5ldmFsdWF0ZWAgbmFtaW5nIG5laXRoZXIgdGhlXG4gICAqIHdhaXQgbm9yIHRoZSBhc3NlcnRpb24uIFRocmVlIHBsdWdpbnMgaGFkIGVhY2ggaGFuZC13cml0dGVuIHRoaXMgcmFpc2UgaW4gdGhlaXIgb3duIGBlZGl0Q29udGV4dGBcbiAgICogYmVmb3JlIGl0IG1vdmVkIGhlcmUuIFVubGlrZSBhIHJhaXNlZCBkZXNrdG9wIGNhcCwgd2hpY2ggaXMgYSBiYWNrc3RvcCByYXRoZXIgdGhhbiBhIGJ1ZGdldCBhIGNsb3N1cmVcbiAgICogbWF5IHNwZW5kLCB0aGlzIG9uZSBJUyBhIGJ1ZGdldDogYG5vLW92ZXItY2FwLXdhaXQtaW4tZXZhbC1pbi1vYnNpZGlhbmAgcmVhZHMgaXQgZm9yIHRoZXNlIGZpbGVzIGFuZFxuICAgKiBmb3Igbm8gb3RoZXIuXG4gICAqXG4gICAqIE5vIHJvdXRpbmUgY29tbWFuZCBydW5zIHRoZW0sIGJ1dCBzb21ldGhpbmcgZG9lczogYSB3ZWVrbHkgc3dlZXAgcnVucyBldmVyeSBwbHVnaW4nc1xuICAgKiBgdGVzdDppbnRlZ3JhdGlvbjpkZXNrdG9wOnBlcmZvcm1hbmNlYCwgd2hpY2ggaXMgYWxzbyBob3cgdG8gcmVhY2ggdGhlbSBieSBoYW5kLiBBZGRpbmcgdGhlbSB0byB0aGF0XG4gICAqIGFnZ3JlZ2F0ZSBpcyBkcmlmdCwgbm90IGEgZ2FwIHRvIGNsb3NlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRlc2t0b3BQZXJmb3JtYW5jZTogT2JzaWRpYW5QbHVnaW5WaXRlc3RQcm9qZWN0Q29uZmlnID0ge1xuICAgIGVudmlyb25tZW50OiAnbm9kZScsXG4gICAgZW52aXJvbm1lbnRPcHRpb25zOiB7XG4gICAgICBvYnNpZGlhblRyYW5zcG9ydDoge1xuICAgICAgICBjb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzOiBQRVJGT1JNQU5DRV9FVkFMX0NBUF9JTl9NSUxMSVNFQ09ORFMsXG4gICAgICAgIHR5cGU6ICdvYnNpZGlhbi1jZHAnXG4gICAgICB9XG4gICAgfSxcbiAgICBmaWxlUGFyYWxsZWxpc206IGZhbHNlLFxuICAgIGdsb2JhbFNldHVwOiBbU1RBTEVfQlVJTERfR0xPQkFMX1NFVFVQLCAnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZy92aXRlc3QtZ2xvYmFsLXNldHVwLXBsdWdpbiddLFxuICAgIGhvb2tUaW1lb3V0OiBQRVJGT1JNQU5DRV9USU1FT1VUX0lOX01JTExJU0VDT05EUyxcbiAgICBpbmNsdWRlOiBbREVTS1RPUF9QRVJGT1JNQU5DRV9URVNUX0ZJTEVTXSxcbiAgICBuYW1lOiAnaW50ZWdyYXRpb24tdGVzdHM6ZGVza3RvcC1wZXJmb3JtYW5jZScsXG4gICAgc2V0dXBGaWxlczogWydvYnNpZGlhbi1pbnRlZ3JhdGlvbi10ZXN0aW5nL3ZpdGVzdC1zZXR1cCddLFxuICAgIHRlc3RUaW1lb3V0OiBQRVJGT1JNQU5DRV9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICB9O1xuXG4gIC8qKlxuICAgKiBUaGUgdW5pdCB0ZXN0IGZpbGVzIHRoYXQgcmVkZWZpbmUgYHdpbmRvd2AsIGBkb2N1bWVudGAsIGBsb2NhdGlvbmAgb3IgYHRvcGAsIHdoaWNoIHRoZSBgdW5pdC10ZXN0c2BcbiAgICogcHJvamVjdCdzIFZNIHBvb2wgY2Fubm90IHJ1bi5cbiAgICpcbiAgICogVW5kZXIgYHBvb2w6ICd2bVRocmVhZHMnYCB0aG9zZSBmb3VyIGFyZSBub24tY29uZmlndXJhYmxlIHByb3BlcnRpZXMgb2YgdGhlIFZNIGdsb2JhbCwgc29cbiAgICogYHZpLnN0dWJHbG9iYWwoJ3dpbmRvdycsIFx1MjAyNilgIG9yIGBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LCAnbG9jYXRpb24nLCBcdTIwMjYpYCB0aHJvd3NcbiAgICogYENhbm5vdCByZWRlZmluZSBwcm9wZXJ0eWAuIFRoYXQgaXMgSlMgc2VtYW50aWNzLCBub3QgYSBidWcgdG8gcm91dGUgYXJvdW5kLiBFdmVyeSBvdGhlciBnbG9iYWwgc3RheXNcbiAgICogY29uZmlndXJhYmxlIGFuZCBzdHVicyBub3JtYWxseS5cbiAgICpcbiAgICogUHVzaCBhIGZpbGUgaGVyZSBhbmQgaXQgbGVhdmVzIGB1bml0LXRlc3RzYCBmb3IgYSBzaWJsaW5nIGB1bml0LXRlc3RzOmdsb2JhbC1zdHVic2AgcHJvamVjdCB0aGF0IGlzXG4gICAqIGlkZW50aWNhbCBleGNlcHQgZm9yIHRoZSBwb29sLCB3aGljaCBpcyB0aGUgZGVmYXVsdCBvbmUuIEEgcGx1Z2luJ3MgYHRlc3RgIGFuZCBgdGVzdDpjb3ZlcmFnZWAgc2NyaXB0c1xuICAgKiBuYW1lIGB1bml0LXRlc3RzYCwgd2hpY2ggYWxzbyBzZWxlY3RzIGV2ZXJ5IGB1bml0LXRlc3RzOipgIHByb2plY3QsIHNvIHRoZSBzaWJsaW5nIHJ1bnMgYW5kIGlzIGNvdmVyZWRcbiAgICogd2l0aG91dCBhIHNjcmlwdCBjaGFuZ2UuIEl0IGlzIGVtaXR0ZWQgb25seSB3aGVuIHRoaXMgbGlzdCBpcyBub24tZW1wdHkuXG4gICAqXG4gICAqIFRvIGtlZXAgYSB3aG9sZSBzdWl0ZSBvbiB0aGUgZGVmYXVsdCBwb29sIGluc3RlYWQsIHNldCBgdW5pdFRlc3RzLnBvb2xgIHRvIGAnZm9ya3MnYCBhbmQgc2F5IHdoeS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBnbG9iYWxTdHViVGVzdEZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8qKlxuICAgKiBUaGUgbXVsdGlwbGllciBhcHBsaWVkIHRvIGEgcHJvamVjdCdzIHRlc3QgYnVkZ2V0IHRvIGdldCBpdHMgaG9vayBidWRnZXQuIEEgaG9vayB0eXBpY2FsbHkgcG9wdWxhdGVzXG4gICAqIGFuZCBvcGVucyBhIHZhdWx0LCBzbyBpdCBuZWVkcyBzZXZlcmFsIHRpbWVzIHdoYXQgYSBzaW5nbGUgdGVzdCBkb2VzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgNGBcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBob29rVGltZW91dE11bHRpcGxpZXIgPSBIT09LX1RJTUVPVVRfTVVMVElQTElFUjtcblxuICAvKipcbiAgICogVGhlIGBpbnRlZ3JhdGlvbi10ZXN0czpuby1hcHBgIHByb2plY3QsIHJ1bm5pbmcgdGhlIHN1aXRlcyB0aGF0IG5lZWQgbm8gT2JzaWRpYW4gaW5zdGFuY2UgYXQgYWxsLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG5vQXBwOiBPYnNpZGlhblBsdWdpblZpdGVzdFByb2plY3RDb25maWcgPSB7XG4gICAgZW52aXJvbm1lbnQ6ICdub2RlJyxcbiAgICBmaWxlUGFyYWxsZWxpc206IGZhbHNlLFxuICAgIGhvb2tUaW1lb3V0OiBJTlRFR1JBVElPTl9URVNUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTICogSE9PS19USU1FT1VUX01VTFRJUExJRVIsXG4gICAgaW5jbHVkZTogW05PX0FQUF9URVNUX0ZJTEVTXSxcbiAgICBuYW1lOiAnaW50ZWdyYXRpb24tdGVzdHM6bm8tYXBwJyxcbiAgICB0ZXN0VGltZW91dDogSU5URUdSQVRJT05fVEVTVF9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICB9O1xuXG4gIC8qKlxuICAgKiBUaGUgcGVyLWV2YWwgY2FwIHRoZSBwZXJmb3JtYW5jZSBpbnRlZ3JhdGlvbiBwcm9qZWN0IGdpdmVzIGl0cyBDRFAgdHJhbnNwb3J0LCBpbiBtaWxsaXNlY29uZHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGA2MDAwMDBgXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcGVyZm9ybWFuY2VFdmFsQ2FwSW5NaWxsaXNlY29uZHMgPSBQRVJGT1JNQU5DRV9FVkFMX0NBUF9JTl9NSUxMSVNFQ09ORFM7XG5cbiAgLyoqXG4gICAqIFRoZSBwZXItdGVzdCBidWRnZXQgb2YgdGhlIHBlcmZvcm1hbmNlIGludGVncmF0aW9uIHByb2plY3QsIGluIG1pbGxpc2Vjb25kcy4gQSBwZXJmb3JtYW5jZSB2YXVsdCBpc1xuICAgKiBwcmUtcG9wdWxhdGVkIHdpdGggdGVucyBvZiB0aG91c2FuZHMgb2Ygbm90ZXMgYmVmb3JlIE9ic2lkaWFuIG9wZW5zLCBzbyBib3RoIGl0cyBzZXR1cCBhbmQgaXRzIHRlc3RzXG4gICAqIG5lZWQgZmFyIG1vcmUgdGltZSB0aGFuIHRoZSByZWd1bGFyIGludGVncmF0aW9uIHByb2plY3RzLlxuICAgKlxuICAgKiBMaWtlIHRoZSByZWd1bGFyIGJ1ZGdldCwgaXQgQ0xFQVJTIHRoZSBwcm9qZWN0J3MgcGVyLWV2YWwgY2FwXG4gICAqICh7QGxpbmsgT2JzaWRpYW5QbHVnaW5WaXRlc3RDb25maWdDb250ZXh0LnBlcmZvcm1hbmNlRXZhbENhcEluTWlsbGlzZWNvbmRzfSkgcmF0aGVyIHRoYW4gbWF0Y2hpbmcgaXQsXG4gICAqIHNvIGFuIGV2YWx1YXRpb24gdGhhdCBvdXRydW5zIHRoZSBjYXAgcmVwb3J0cyBpdHNlbGYgaW5zdGVhZCBvZiBkeWluZyBhcyB2aXRlc3QncyBhbm9ueW1vdXMgdGltZW91dC5cbiAgICpcbiAgICogQGRlZmF1bHQgYDYxNTAwMGBcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwZXJmb3JtYW5jZVRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IFBFUkZPUk1BTkNFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVwb3J0ZXJzIHRoZSBydW4gcHJpbnRzIHRocm91Z2guXG4gICAqXG4gICAqIFBpbm5lZCByYXRoZXIgdGhhbiBsZWZ0IHRvIHZpdGVzdCwgd2hpY2ggcmVzb2x2ZXMgYW4gdW5zZXQgYHJlcG9ydGVyc2AgZGlmZmVyZW50bHkgZm9yIGEgZGV2ZWxvcGVyXG4gICAqIGFuZCBmb3IgYW4gQUkgY29kaW5nIHNlc3Npb24gXHUyMDE0IHNlZSB7QGxpbmsgREVGQVVMVF9WSVRFU1RfUkVQT1JURVJTfSBmb3IgdGhlIHdob2xlIG9mIHdoeSwgYW5kIGZvclxuICAgKiB3aGF0IGl0IGRlbGliZXJhdGVseSBsZWF2ZXMgdG8gdml0ZXN0IDUgaXRzZWxmLlxuICAgKlxuICAgKiBQdXNoIG9udG8gaXQgdG8gYWRkIGEgcmVwb3J0ZXIgYmVzaWRlIHRoZSBwaW5uZWQgb25lLlxuICAgKlxuICAgKiBAZGVmYXVsdCB7QGxpbmsgREVGQVVMVF9WSVRFU1RfUkVQT1JURVJTfVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHJlcG9ydGVyczogT2JzaWRpYW5QbHVnaW5WaXRlc3RSZXBvcnRlcltdID0gWy4uLkRFRkFVTFRfVklURVNUX1JFUE9SVEVSU107XG5cbiAgLyoqXG4gICAqIFRoZSBgdW5pdC10ZXN0c2AgcHJvamVjdCwgcnVubmluZyB0aGUgbW9ja2VkLU9ic2lkaWFuIHN1aXRlcyBpbiBganNkb21gLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHVuaXRUZXN0czogT2JzaWRpYW5QbHVnaW5WaXRlc3RQcm9qZWN0Q29uZmlnID0ge1xuICAgIGVudmlyb25tZW50OiAnanNkb20nLFxuICAgIGV4Y2x1ZGU6IFsuLi5TSEFSRURfRVhDTFVERSwgSU5URUdSQVRJT05fVEVTVF9GSUxFU10sXG4gICAgLy8gQSB0aHJlYWRzL2ZvcmtzIHBvb2wgb3B0aW9uIHRoYXQgc3RpbGwgcmVhY2hlcyB0aGUgd29ya2VyIHVuZGVyIHRoZSBWTSBwb29sIGJlbG93OiBtZWFzdXJlZFxuICAgIC8vIDIwMjYtMDktMTYsIGBwcm9jZXNzLmV4ZWNBcmd2YCBjYXJyaWVzIGl0IGFuZCBOb2RlJ3Mgb3duIGBsb2NhbFN0b3JhZ2VgIGRlc2NyaXB0b3IgaXMgZ29uZSwgYXMgaXRcbiAgICAvLyBpcyB1bmRlciBgdGhyZWFkc2AuIFdpdGhvdXQgdGhlIGZsYWcgdGhlIGRlc2NyaXB0b3IgaXMgYmFjayB1bmRlciBib3RoIHBvb2xzLlxuICAgIGV4ZWNBcmd2OiBbJy0tbm8td2Vic3RvcmFnZSddLFxuICAgIGluY2x1ZGU6IFtVTklUX1RFU1RfRklMRVNdLFxuICAgIG5hbWU6ICd1bml0LXRlc3RzJyxcbiAgICAvKlxuICAgICAqIFRoZSBkZWZhdWx0IHBvb2wgY29uc3RydWN0cyBvbmUganNkb20gcGVyIHRlc3QgZmlsZSwgYW5kIHRoYXQgY29uc3RydWN0aW9uLCBub3QgdGhlIHRlc3RzLCB3YXNcbiAgICAgKiB0aGUgdW5pdCBzdWl0ZSdzIGNvc3Q6IDY3JSBvZiB0cmFja2VkIHRpbWUgaW4gYG9ic2lkaWFuLWRldi11dGlsc2AnIG93biBzdWl0ZS4gQSBWTSBwb29sIGJ1aWxkc1xuICAgICAqIHRoZSBqc2RvbSBvbmNlIHBlciB3b3JrZXIgYW5kIGdpdmVzIGVhY2ggZmlsZSBhIGZyZXNoIFZNIGNvbnRleHQsIHNvIHBlci1maWxlIGlzb2xhdGlvbiBob2xkcy5cbiAgICAgKiBNZWFzdXJlZCB0aGVyZSBvbiAyMDI2LTA5LTE1OiB0aGUganNkb20gcHJvamVjdCAzNi4wNnMgLT4gOS45MnMsIGBjb3ZlcmFnZS9sY292LmluZm9gXG4gICAgICogYnl0ZS1pZGVudGljYWwgdG8gdGhlIGRlZmF1bHQgcG9vbCdzLCBhbmQgbm8gRE9NLCBgZ2xvYmFsVGhpc2Agb3IgcHJvdG90eXBlIHN0YXRlIGNyb3NzaW5nIGZpbGVzLlxuICAgICAqIGBpc29sYXRlOiBmYWxzZWAsIHRoZSBvdGhlciByZW1lZHkgdml0ZXN0IHN1Z2dlc3RzLCB3YXMgc2xvd2VyICg5MS42MnMpIGFuZCBicm9rZSA2OCB0ZXN0cy5cbiAgICAgKiBUaGUgb25lIGNvc3QgaXMgcmVkZWZpbmluZyBgd2luZG93YCwgYGRvY3VtZW50YCwgYGxvY2F0aW9uYCBvciBgdG9wYDogc2VlIGBnbG9iYWxTdHViVGVzdEZpbGVzYC5cbiAgICAgKi9cbiAgICBwb29sOiAndm1UaHJlYWRzJyxcbiAgICBzZXJ2ZXI6IHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB1bmljb3JuL25hbWUtcmVwbGFjZW1lbnRzIC0tIGBkZXBzYCBpcyBkZWNsYXJlZCBieSBgdml0ZXN0YDsgcmVuYW1pbmcgaXQgaGVyZSB3b3VsZCBub3QgbWF0Y2ggdGhlIEFQSS5cbiAgICAgIGRlcHM6IHtcbiAgICAgICAgaW5saW5lOiBbJ0BvYnNpZGlhbi10eXBpbmdzJywgJ29ic2lkaWFuLWRldi11dGlscyddXG4gICAgICB9XG4gICAgfSxcbiAgICBzZXR1cEZpbGVzOiBbXG4gICAgICAnb2JzaWRpYW4tdGVzdC1tb2Nrcy92aXRlc3Qtc2V0dXAnLFxuICAgICAgJ29ic2lkaWFuLWRldi11dGlscy92aXRlc3Qtc2V0dXAnXG4gICAgXVxuICB9O1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGNvbnRleHQgc2VlZGVkIHdpdGggdGhlIHN0YW5kYXJkIHByb2plY3RzLlxuICAgKi9cbiAgcHVibGljIGNvbnN0cnVjdG9yKCkge1xuICAgIGNvbnN0IG9ic2lkaWFuVmVyc2lvbiA9IHByb2Nlc3MuZW52W09CU0lESUFOX1ZFUlNJT05fRU5WX1ZBUklBQkxFX05BTUVdO1xuXG4gICAgLypcbiAgICAgKiBTdXBwb3J0IGlzIHRoZSByYW5nZSBbbGF0ZXN0IHB1YmxpYywgbGF0ZXN0IGNhdGFseXN0XSBhbmQgQk9USCBlbmRzIG11c3Qgd29yaywgc28gdGhlIHZlcnNpb25cbiAgICAgKiBpcyBhIGtub2IgcmF0aGVyIHRoYW4gYSBjb25zdGFudC4gVGhlIGtleSBpcyBhZGRlZCBPTkxZIHdoZW4gdGhlIHZhcmlhYmxlIGlzIHNldDogYW4gZXhwbGljaXRcbiAgICAgKiBgb2JzaWRpYW5WZXJzaW9uYCBtYWtlcyB0aGUgaGFybmVzcyByZXNvbHZlIGEgY29uY3JldGUgdmVyc2lvbiBhbmQgc3dhcCB0aGUgYXNhciwgd2hpY2ggaXMgbm90IHdoYXRcbiAgICAgKiBhbiB1bnBpbm5lZCBydW4gZG9lcywgc28gc2VlZGluZyBhIGRlZmF1bHQgaGVyZSB3b3VsZCBjaGFuZ2UgdGhlIGJlaGF2aW9yIG9mIGV2ZXJ5IHBsdWdpbi5cbiAgICAgKi9cbiAgICBpZiAob2JzaWRpYW5WZXJzaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuZGVza3RvcC5lbnZpcm9ubWVudE9wdGlvbnMgPSB7XG4gICAgICAgIG9ic2lkaWFuVHJhbnNwb3J0OiB7XG4gICAgICAgICAgb2JzaWRpYW5WZXJzaW9uLFxuICAgICAgICAgIHR5cGU6ICdvYnNpZGlhbi1jZHAnXG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGVmaW5lcyB0aGUgdml0ZXN0IGNvbmZpZ3VyYXRpb24gZm9yIGFuIE9ic2lkaWFuIHBsdWdpbi5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciBkZWZpbmluZyB0aGUgY29uZmlndXJhdGlvbi5cbiAqIEByZXR1cm5zIFRoZSB2aXRlc3QgY29uZmlndXJhdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnKG9wdGlvbnM6IERlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnT3B0aW9ucyA9IHt9KTogVml0ZVVzZXJDb25maWcge1xuICBjb25zdCBjb250ZXh0ID0gbmV3IE9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnQ29udGV4dCgpO1xuXG4gIGlmIChvcHRpb25zLmVkaXRDb250ZXh0KSB7XG4gICAgb3B0aW9ucy5lZGl0Q29udGV4dChjb250ZXh0KTtcbiAgfVxuXG4gIGNvbnN0IGN1c3RvbVByb2plY3RzID0gb3B0aW9ucy5jdXN0b21Qcm9qZWN0cz8uKGNvbnRleHQpID8/IFtdO1xuICB2YWxpZGF0ZUN1c3RvbVByb2plY3RzKGN1c3RvbVByb2plY3RzKTtcblxuICBjb25zdCB1bml0VGVzdHNSZXNvbHZlID0ge1xuICAgIGFsaWFzOiB7XG4gICAgICBvYnNpZGlhbjogJ29ic2lkaWFuLXRlc3QtbW9ja3Mvb2JzaWRpYW4nXG4gICAgfVxuICB9O1xuICBjb25zdCBnbG9iYWxTdHViVGVzdEZpbGVzID0gWy4uLmNvbnRleHQuZ2xvYmFsU3R1YlRlc3RGaWxlc107XG4gIGNvbnN0IHVuaXRUZXN0czogT2JzaWRpYW5QbHVnaW5WaXRlc3RQcm9qZWN0Q29uZmlnID0gZ2xvYmFsU3R1YlRlc3RGaWxlcy5sZW5ndGggPT09IDBcbiAgICA/IGNvbnRleHQudW5pdFRlc3RzXG4gICAgOiB7IC4uLmNvbnRleHQudW5pdFRlc3RzLCBleGNsdWRlOiBbLi4uY29udGV4dC51bml0VGVzdHMuZXhjbHVkZSA/PyBbXSwgLi4uZ2xvYmFsU3R1YlRlc3RGaWxlc10gfTtcbiAgY29uc3QgZ2xvYmFsU3R1YnNQcm9qZWN0czogVGVzdFByb2plY3RDb25maWd1cmF0aW9uW10gPSBnbG9iYWxTdHViVGVzdEZpbGVzLmxlbmd0aCA9PT0gMFxuICAgID8gW11cbiAgICA6IFt7XG4gICAgICByZXNvbHZlOiB1bml0VGVzdHNSZXNvbHZlLFxuICAgICAgdGVzdDoge1xuICAgICAgICAuLi5jb250ZXh0LnVuaXRUZXN0cyxcbiAgICAgICAgaW5jbHVkZTogZ2xvYmFsU3R1YlRlc3RGaWxlcyxcbiAgICAgICAgbmFtZTogVU5JVF9URVNUX0dMT0JBTF9TVFVCU19QUk9KRUNUX05BTUUsXG4gICAgICAgIC8vIFRoZSBkZWZhdWx0IHBvb2wsIG5hbWVkIHJhdGhlciB0aGFuIG9taXR0ZWQgc28gdGhlIHNwcmVhZCBhYm92ZSBjYW5ub3QgY2FycnkgdGhlIFZNIHBvb2wgb3Zlci5cbiAgICAgICAgcG9vbDogJ2ZvcmtzJ1xuICAgICAgfVxuICAgIH1dO1xuXG4gIHJldHVybiBkZWZpbmVDb25maWcoe1xuICAgIHRlc3Q6IHtcbiAgICAgIGNvdmVyYWdlOiB7XG4gICAgICAgIGV4Y2x1ZGU6IGNvbnRleHQuY292ZXJhZ2VFeGNsdWRlLFxuICAgICAgICBpbmNsdWRlOiBbJ3NyYy8qKi8qLnRzJ10sXG4gICAgICAgIHByb3ZpZGVyOiAndjgnLFxuICAgICAgICByZXBvcnRlcjogWyd0ZXh0JywgJ2xjb3YnLCAnaHRtbCddLFxuICAgICAgICByZXBvcnRzRGlyZWN0b3J5OiAnLi9jb3ZlcmFnZSdcbiAgICAgIH0sXG4gICAgICBleGNsdWRlOiBbLi4uU0hBUkVEX0VYQ0xVREVdLFxuICAgICAgZ2xvYmFsczogZmFsc2UsXG4gICAgICAvKlxuICAgICAgICogVGhlcmUgaXMgZGVsaWJlcmF0ZWx5IE5PIHJvb3QtbGV2ZWwgYGluY2x1ZGVgIGhlcmUsIGFuZCByZXN0b3Jpbmcgb25lIGJyZWFrcyBldmVyeSBwcm9qZWN0LlxuICAgICAgICogVW5kZXIgdml0ZXN0IDQgYSBwcm9qZWN0J3Mgb3duIGBpbmNsdWRlYCByZXBsYWNlZCB0aGUgcm9vdCBvbmUsIHNvIGEgcm9vdFxuICAgICAgICogYGluY2x1ZGU6IFtVTklUX1RFU1RfRklMRVNdYCB3YXMgbWVyZWx5IHJlZHVuZGFudCBcdTIwMTQgdGhlIGB1bml0LXRlc3RzYCBwcm9qZWN0IGFscmVhZHkgZGVjbGFyZXNcbiAgICAgICAqIHRoYXQgc2FtZSBnbG9iIGZvciBpdHNlbGYuIFVuZGVyIHZpdGVzdCA1IHRoZSBwcm9qZWN0IGdsb2Igbm8gbG9uZ2VyIHJlcGxhY2VzIGl0LCBhbmRcbiAgICAgICAqIGBzcmMvKipcXC8qLnRlc3QudHNgIGlzIGEgc3VwZXJzZXQgb2YgZXZlcnkgcHJvamVjdCBnbG9iLCBzbyBFVkVSWSBwcm9qZWN0IGNvbGxlY3RlZCBFVkVSWSB0ZXN0XG4gICAgICAgKiBmaWxlOiB1bml0IHN1aXRlcyByYW4gaW4gdGhlIENEUCBpbnRlZ3JhdGlvbiBlbnZpcm9ubWVudCBhbmQgZGllZCBvbiBgRmFpbGVkIHRvIHJlc29sdmUgZW50cnlcbiAgICAgICAqIGZvciBwYWNrYWdlIFwib2JzaWRpYW5cImAsIHRoZSBzY3JlZW5zaG90LWNhcHR1cmUgc3VpdGVzIHJhbiBhbmQgcmV3cm90ZSBjaGVja2VkLWluIFBOR3MsIGFuZCB0aGVcbiAgICAgICAqIGFuZHJvaWQgLyBkZW1vLXZhdWx0IHN1aXRlcyByYW4gdW5kZXIgdGhlIGRlc2t0b3AgdHJhbnNwb3J0LiBNZWFzdXJlZCBpbiBhIGNvbnN1bWVyOiB0aGUgZGVza3RvcFxuICAgICAgICogcHJvamVjdCBjb2xsZWN0ZWQgMjI3IGZpbGVzIGluc3RlYWQgb2YgaXRzIG93biAxMDUsIGFuZCBkZWxldGluZyB0aGlzIG9uZSBsaW5lIHJlc3RvcmVkIDEwNS5cbiAgICAgICAqL1xuICAgICAgcGFzc1dpdGhOb1Rlc3RzOiB0cnVlLFxuICAgICAgcHJvamVjdHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHJlc29sdmU6IHVuaXRUZXN0c1Jlc29sdmUsXG4gICAgICAgICAgdGVzdDogdW5pdFRlc3RzXG4gICAgICAgIH0sXG4gICAgICAgIHsgdGVzdDogY29udGV4dC5ub0FwcCB9LFxuICAgICAgICB7IHRlc3Q6IGNvbnRleHQuZGVza3RvcCB9LFxuICAgICAgICB7IHRlc3Q6IGNvbnRleHQuZGVza3RvcFBlcmZvcm1hbmNlIH0sXG4gICAgICAgIHsgdGVzdDogY29udGV4dC5hbmRyb2lkIH0sXG4gICAgICAgIC4uLmdsb2JhbFN0dWJzUHJvamVjdHMsXG4gICAgICAgIC4uLmN1c3RvbVByb2plY3RzXG4gICAgICBdLFxuICAgICAgcmVwb3J0ZXJzOiBbLi4uY29udGV4dC5yZXBvcnRlcnNdXG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBSZWZ1c2VzIGEgY3VzdG9tIHByb2plY3QgdGhhdCBkZWNsYXJlcyBubyBgaW5jbHVkZWAgZ2xvYiBvZiBpdHMgb3duLlxuICpcbiAqIFRoZSByb290IHNlY3Rpb24gZGVsaWJlcmF0ZWx5IGRlY2xhcmVzIG5vIGBpbmNsdWRlYCAoc2VlIHRoZSBjb21tZW50IG9uIGl0IGFib3ZlKSwgc28gYSBwcm9qZWN0IHRoYXRcbiAqIGRlY2xhcmVzIG5vbmUgZmFsbHMgYmFjayB0byB2aXRlc3QncyBvd24gZGVmYXVsdCBnbG9iIFx1MjAxNCB3aGljaCBtYXRjaGVzIEVWRVJZIHRlc3QgZmlsZSBpbiB0aGUgcmVwby5cbiAqIFRoYXQgcHJvamVjdCB0aGVuIHJ1bnMgdGhlIHVuaXQgc3VpdGVzIGluIGFuIE9ic2lkaWFuIGVudmlyb25tZW50LCB0aGUgYW5kcm9pZCBzdWl0ZXMgdW5kZXIgdGhlXG4gKiBkZXNrdG9wIHRyYW5zcG9ydCwgYW5kIHRoZSBgKi1jYXB0dXJlLmAgc2NyZWVuc2hvdCBzdWl0ZXMgdGhhdCBvcGVuIGEgd2luZG93IGFuZCByZXdyaXRlIGNoZWNrZWQtaW5cbiAqIFBOR3MuIEEgd2lkZW5lZCBwcm9qZWN0IGlzIHNpbGVudDogaXQgcGFzc2VzLCBzbG93bHksIGhhdmluZyBkb25lIGFsbCBvZiB0aGF0LlxuICpcbiAqIE9ubHkgYSBwbGFpbiBpbmxpbmUgY29uZmlndXJhdGlvbiBjYW4gYmUgY2hlY2tlZCBoZXJlLiBBIHByb2plY3QgbmFtZWQgYnkgYSBnbG9iIHN0cmluZywgYnVpbHQgYnkgYVxuICogZnVuY3Rpb24sIG9yIGF3YWl0ZWQgZnJvbSBhIHByb21pc2UgaXMgcmVzb2x2ZWQgYnkgdml0ZXN0IGl0c2VsZiwgb3V0IG9mIHRoaXMgZnVuY3Rpb24ncyByZWFjaC5cbiAqXG4gKiBAcGFyYW0gY3VzdG9tUHJvamVjdHMgLSBUaGUgcHJvamVjdHMgcmV0dXJuZWQgYnkge0BsaW5rIERlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnT3B0aW9ucy5jdXN0b21Qcm9qZWN0c30uXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlQ3VzdG9tUHJvamVjdHMoY3VzdG9tUHJvamVjdHM6IFRlc3RQcm9qZWN0Q29uZmlndXJhdGlvbltdKTogdm9pZCB7XG4gIGZvciAoY29uc3QgW2luZGV4LCBjdXN0b21Qcm9qZWN0XSBvZiBjdXN0b21Qcm9qZWN0cy5lbnRyaWVzKCkpIHtcbiAgICBpZiAodHlwZW9mIGN1c3RvbVByb2plY3QgIT09ICdvYmplY3QnIHx8ICd0aGVuJyBpbiBjdXN0b21Qcm9qZWN0KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBpbmNsdWRlID0gY3VzdG9tUHJvamVjdC50ZXN0Py5pbmNsdWRlO1xuXG4gICAgaWYgKGluY2x1ZGUgJiYgaW5jbHVkZS5sZW5ndGggPiAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBuYW1lID0gY3VzdG9tUHJvamVjdC50ZXN0Py5uYW1lO1xuICAgIGNvbnN0IGxhYmVsID0gdHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnID8gbmFtZSA6IG5hbWU/LmxhYmVsID8/IGBhdCBpbmRleCAke1N0cmluZyhpbmRleCl9YDtcblxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBUaGUgY3VzdG9tIHZpdGVzdCBwcm9qZWN0ICR7bGFiZWx9IGRlY2xhcmVzIG5vIFxcYHRlc3QuaW5jbHVkZVxcYCwgc28gdml0ZXN0IGZhbGxzIGJhY2sgdG8gaXRzIGRlZmF1bHQgZ2xvYiBhbmQgdGhlIHByb2plY3QgY29sbGVjdHMgRVZFUlkgdGVzdCBmaWxlIFx1MjAxNCBpbmNsdWRpbmcgdGhlIFxcYCotY2FwdHVyZS5cXGAgc3VpdGVzIHRoYXQgcmV3cml0ZSBjaGVja2VkLWluIHNjcmVlbnNob3RzLiBEZWNsYXJlIGFuIGV4cGxpY2l0IFxcYGluY2x1ZGVcXGAsIG9yIHNwcmVhZCBhIHN0YW5kYXJkIHByb2plY3QgKFxcYC4uLmNvbnRleHQuZGVza3RvcFxcYCkgYW5kIG92ZXJyaWRlIGl0LmBcbiAgICApO1xuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7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
|