obsidian-integration-testing 10.4.0 → 12.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/README.md +1 -1
- package/dist/lib/cjs/appium-server-marker.cjs +115 -0
- package/dist/lib/cjs/appium-server-marker.d.cts +81 -0
- package/dist/lib/cjs/cli.cjs +104 -19
- package/dist/lib/cjs/cli.d.cts +16 -8
- package/dist/lib/cjs/community-plugin-registry.cjs +52 -0
- package/dist/lib/cjs/community-plugin-registry.d.cts +116 -0
- package/dist/lib/cjs/context-provider.cjs +12 -1
- package/dist/lib/cjs/context-provider.d.cts +26 -3
- package/dist/lib/cjs/demo-vault-bootstrap.cjs +148 -0
- package/dist/lib/cjs/demo-vault-bootstrap.d.cts +113 -0
- package/dist/lib/cjs/demo-vault-populate.cjs +36 -9
- package/dist/lib/cjs/demo-vault-populate.d.cts +70 -0
- package/dist/lib/cjs/eval-in-obsidian.cjs +1 -1
- package/dist/lib/cjs/eval-in-obsidian.d.cts +97 -15
- package/dist/lib/cjs/index.cjs +16 -1
- package/dist/lib/cjs/index.d.cts +15 -8
- package/dist/lib/cjs/installer-asset.cjs +1 -1
- package/dist/lib/cjs/installer-asset.d.cts +1 -1
- package/dist/lib/cjs/integration-setup-failed-error.cjs +62 -0
- package/dist/lib/cjs/integration-setup-failed-error.d.cts +66 -0
- package/dist/lib/cjs/jest/global-setup.cjs +2 -2
- package/dist/lib/cjs/jest/global-setup.d.cts +5 -1
- package/dist/lib/cjs/kill-process-tree.cjs +18 -7
- package/dist/lib/cjs/kill-process-tree.d.cts +10 -2
- package/dist/lib/cjs/library.cjs +1 -1
- package/dist/lib/cjs/mobile-input.cjs +161 -0
- package/dist/lib/cjs/mobile-input.d.cts +160 -0
- package/dist/lib/cjs/namespace-bootstrap.cjs +136 -10
- package/dist/lib/cjs/obsidian-installer.cjs +1 -1
- package/dist/lib/cjs/obsidian-metadata.cjs +1257 -348
- package/dist/lib/cjs/obsidian-metadata.d.cts +74 -12
- package/dist/lib/cjs/obsidian-version-switch.cjs +3 -3
- package/dist/lib/cjs/open-obsidian-settings-tab.cjs +51 -0
- package/dist/lib/cjs/open-obsidian-settings-tab.d.cts +49 -0
- package/dist/lib/cjs/release-catalog.cjs +73 -0
- package/dist/lib/cjs/release-catalog.d.cts +125 -0
- package/dist/lib/cjs/transport-appium.cjs +122 -1
- package/dist/lib/cjs/transport-appium.d.cts +51 -0
- package/dist/lib/cjs/transport-desktop-cdp.cjs +7 -1
- package/dist/lib/cjs/transport-desktop-cdp.d.cts +2 -2
- package/dist/lib/cjs/transport-factory.cjs +237 -32
- package/dist/lib/cjs/transport-factory.d.cts +10 -1
- package/dist/lib/cjs/vitest/global-setup.cjs +13 -7
- package/dist/lib/cjs/vitest/global-setup.d.cts +5 -1
- package/dist/lib/cjs/vitest/setup.cjs +2 -1
- package/dist/lib/cjs/vitest/setup.d.cts +5 -0
- package/dist/lib/cjs/vitest/typings.d.cts +6 -4
- package/dist/lib/cjs/webview-cdp.cjs +264 -0
- package/dist/lib/cjs/webview-cdp.d.cts +152 -0
- package/dist/lib/cjs/wedged-appium-server.cjs +113 -0
- package/dist/lib/cjs/wedged-appium-server.d.cts +187 -0
- package/dist/lib/esm/appium-server-marker.d.mts +81 -0
- package/dist/lib/esm/appium-server-marker.mjs +83 -0
- package/dist/lib/esm/cli.d.mts +16 -8
- package/dist/lib/esm/cli.mjs +110 -19
- package/dist/lib/esm/community-plugin-registry.d.mts +116 -0
- package/dist/lib/esm/community-plugin-registry.mjs +23 -0
- package/dist/lib/esm/context-provider.d.mts +26 -3
- package/dist/lib/esm/context-provider.mjs +10 -1
- package/dist/lib/esm/demo-vault-bootstrap.d.mts +113 -0
- package/dist/lib/esm/demo-vault-bootstrap.mjs +127 -0
- package/dist/lib/esm/demo-vault-populate.d.mts +70 -0
- package/dist/lib/esm/demo-vault-populate.mjs +33 -8
- package/dist/lib/esm/eval-in-obsidian.d.mts +97 -15
- package/dist/lib/esm/eval-in-obsidian.mjs +1 -1
- package/dist/lib/esm/index.d.mts +15 -8
- package/dist/lib/esm/index.mjs +18 -2
- package/dist/lib/esm/installer-asset.d.mts +1 -1
- package/dist/lib/esm/installer-asset.mjs +1 -1
- package/dist/lib/esm/integration-setup-failed-error.d.mts +66 -0
- package/dist/lib/esm/integration-setup-failed-error.mjs +38 -0
- package/dist/lib/esm/jest/global-setup.d.mts +5 -1
- package/dist/lib/esm/jest/global-setup.mjs +2 -2
- package/dist/lib/esm/kill-process-tree.d.mts +10 -2
- package/dist/lib/esm/kill-process-tree.mjs +16 -6
- package/dist/lib/esm/library.mjs +1 -1
- package/dist/lib/esm/mobile-input.d.mts +160 -0
- package/dist/lib/esm/mobile-input.mjs +132 -0
- package/dist/lib/esm/namespace-bootstrap.mjs +139 -10
- package/dist/lib/esm/obsidian-installer.mjs +1 -1
- package/dist/lib/esm/obsidian-metadata.d.mts +74 -12
- package/dist/lib/esm/obsidian-metadata.mjs +1257 -348
- package/dist/lib/esm/obsidian-version-switch.mjs +3 -3
- package/dist/lib/esm/open-obsidian-settings-tab.d.mts +49 -0
- package/dist/lib/esm/open-obsidian-settings-tab.mjs +27 -0
- package/dist/lib/esm/release-catalog.d.mts +125 -0
- package/dist/lib/esm/release-catalog.mjs +46 -0
- package/dist/lib/esm/transport-appium.d.mts +51 -0
- package/dist/lib/esm/transport-appium.mjs +126 -1
- package/dist/lib/esm/transport-desktop-cdp.d.mts +2 -2
- package/dist/lib/esm/transport-desktop-cdp.mjs +7 -1
- package/dist/lib/esm/transport-factory.d.mts +10 -1
- package/dist/lib/esm/transport-factory.mjs +249 -35
- package/dist/lib/esm/vitest/global-setup.d.mts +5 -1
- package/dist/lib/esm/vitest/global-setup.mjs +14 -7
- package/dist/lib/esm/vitest/setup.d.mts +5 -0
- package/dist/lib/esm/vitest/setup.mjs +3 -1
- package/dist/lib/esm/vitest/typings.d.mts +6 -4
- package/dist/lib/esm/webview-cdp.d.mts +152 -0
- package/dist/lib/esm/webview-cdp.mjs +236 -0
- package/dist/lib/esm/wedged-appium-server.d.mts +187 -0
- package/dist/lib/esm/wedged-appium-server.mjs +86 -0
- package/package.json +13 -12
|
@@ -19,7 +19,16 @@ export declare function createTransportFromOptions(options?: ObsidianTransportOp
|
|
|
19
19
|
* The transport is cached per worker process so WebSocket/Appium sessions
|
|
20
20
|
* are reused across calls within the same test worker.
|
|
21
21
|
*
|
|
22
|
-
*
|
|
22
|
+
* This is the single entry point every worker-side caller uses for the **ambient**
|
|
23
|
+
* transport, so it is also where a failed global setup is turned into a failing test.
|
|
24
|
+
* A failed setup publishes no transport options, and `undefined` options mean the owned
|
|
25
|
+
* **desktop** CDP default — so without this guard an Android project's suite would run
|
|
26
|
+
* on desktop and then die on an unrelated CDP error, hiding the real cause (**L9**).
|
|
27
|
+
* The setup path itself is unaffected: `coreSetup` builds its transport through
|
|
28
|
+
* {@link createTransportFromOptions} with explicit options.
|
|
29
|
+
*
|
|
30
|
+
* @param options - Transport configuration. Defaults to an owned desktop CDP transport.
|
|
23
31
|
* @returns The cached or newly created transport.
|
|
32
|
+
* @throws {IntegrationSetupFailedError} When this project's global setup failed.
|
|
24
33
|
*/
|
|
25
34
|
export declare function getOrCreateTransport(options?: ObsidianTransportOptions): Promise<ObsidianTransport>;
|
|
@@ -28,8 +28,10 @@ var import_vitest = require("vitest");
|
|
|
28
28
|
var import_context_provider = require("../context-provider.cjs");
|
|
29
29
|
var import_error_to_string = require("../error-to-string.cjs");
|
|
30
30
|
var import_global_setup_core = require("../global-setup-core.cjs");
|
|
31
|
+
var import_integration_setup_failed_error = require("../integration-setup-failed-error.cjs");
|
|
31
32
|
var import_log = require("../log.cjs");
|
|
32
33
|
var import_temporary_vault = require("../temporary-vault.cjs");
|
|
34
|
+
(0, import_context_provider.setSetupErrorResolver)(() => (0, import_vitest.inject)("setupError"));
|
|
33
35
|
(0, import_context_provider.setTransportOptionsResolver)(() => (0, import_vitest.inject)("obsidianTransport"));
|
|
34
36
|
(0, import_context_provider.setVaultPathResolver)(() => (0, import_vitest.inject)("temporaryVaultPath"));
|
|
35
37
|
function createSetup(options) {
|
|
@@ -43,12 +45,16 @@ function createSetup(options) {
|
|
|
43
45
|
setupResult = await (0, import_global_setup_core.coreSetup)({
|
|
44
46
|
enableCommunityPlugins: options?.enableCommunityPlugins,
|
|
45
47
|
installPlugin: options?.installPlugin,
|
|
46
|
-
populate: options?.populate?.(),
|
|
48
|
+
populate: await options?.populate?.(),
|
|
47
49
|
transportOptions
|
|
48
50
|
});
|
|
49
51
|
} catch (error) {
|
|
50
|
-
(0, import_log.log)(`[integration-setup:${label}] Setup failed (
|
|
51
|
-
project.provide("setupError",
|
|
52
|
+
(0, import_log.log)(`[integration-setup:${label}] Setup failed (every test in this project will fail with this error): ${(0, import_error_to_string.errorToString)(error)}`);
|
|
53
|
+
project.provide("setupError", {
|
|
54
|
+
errorName: error instanceof Error ? error.name : "Error",
|
|
55
|
+
message: (0, import_error_to_string.errorToString)(error),
|
|
56
|
+
transportLabel: label
|
|
57
|
+
});
|
|
52
58
|
return;
|
|
53
59
|
}
|
|
54
60
|
project.provide("obsidianTransport", setupResult.transportOptions);
|
|
@@ -60,9 +66,9 @@ function createSetup(options) {
|
|
|
60
66
|
}
|
|
61
67
|
function getTemporaryVault() {
|
|
62
68
|
const temporaryVaultPath = (0, import_vitest.inject)("temporaryVaultPath");
|
|
63
|
-
const
|
|
64
|
-
if (
|
|
65
|
-
throw new
|
|
69
|
+
const setupError = (0, import_vitest.inject)("setupError");
|
|
70
|
+
if (setupError) {
|
|
71
|
+
throw new import_integration_setup_failed_error.IntegrationSetupFailedError(setupError);
|
|
66
72
|
}
|
|
67
73
|
return new import_temporary_vault.TemporaryVault(temporaryVaultPath);
|
|
68
74
|
}
|
|
@@ -76,4 +82,4 @@ const teardown = defaultGlobalSetup.teardown;
|
|
|
76
82
|
setup,
|
|
77
83
|
teardown
|
|
78
84
|
});
|
|
79
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL3ZpdGVzdC9nbG9iYWwtc2V0dXAudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBWaXRlc3QgZ2xvYmFsIHNldHVwIGFuZCB0ZWFyZG93biBhZGFwdGVyLlxuICpcbiAqIERlbGVnYXRlcyB0byB0aGUgZnJhbWV3b3JrLWFnbm9zdGljIGNvcmUgYW5kIGJyaWRnZXMgY29udGV4dFxuICogdG8gdGVzdCB3b3JrZXJzIHZpYSBWaXRlc3QncyBgcHJvamVjdC5wcm92aWRlYCAvIGBpbmplY3RgLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIHNldHVwIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgdHlwZSB7IFRlc3RQcm9qZWN0IH0gZnJvbSAndml0ZXN0L25vZGUnO1xuXG5pbXBvcnQgeyBpbmplY3QgfSBmcm9tICd2aXRlc3QnO1xuXG5pbXBvcnQgdHlwZSB7IENvcmVTZXR1cFJlc3VsdCB9IGZyb20gJy4uL2dsb2JhbC1zZXR1cC1jb3JlLmNqcyc7XG5pbXBvcnQgdHlwZSB7IFBvcHVsYXRlRmlsZXNQYXJhbXMgfSBmcm9tICcuLi90ZW1wb3JhcnktdmF1bHQuY2pzJztcbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIH0gZnJvbSAnLi4vdHJhbnNwb3J0LW9wdGlvbnMuY2pzJztcblxuaW1wb3J0IHtcbiAgc2V0VHJhbnNwb3J0T3B0aW9uc1Jlc29sdmVyLFxuICBzZXRWYXVsdFBhdGhSZXNvbHZlclxufSBmcm9tICcuLi9jb250ZXh0LXByb3ZpZGVyLmNqcyc7XG5pbXBvcnQgeyBlcnJvclRvU3RyaW5nIH0gZnJvbSAnLi4vZXJyb3ItdG8tc3RyaW5nLmNqcyc7XG5pbXBvcnQge1xuICBjb3JlU2V0dXAsXG4gIGNvcmVUZWFyZG93blxufSBmcm9tICcuLi9nbG9iYWwtc2V0dXAtY29yZS5janMnO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSAnLi4vbG9nLmNqcyc7XG5pbXBvcnQgeyBUZW1wb3JhcnlWYXVsdCB9IGZyb20gJy4uL3RlbXBvcmFyeS12YXVsdC5janMnO1xuXG5zZXRUcmFuc3BvcnRPcHRpb25zUmVzb2x2ZXIoKCkgPT4gaW5qZWN0KCdvYnNpZGlhblRyYW5zcG9ydCcpKTtcbnNldFZhdWx0UGF0aFJlc29sdmVyKCgpID0+IGluamVjdCgndGVtcG9yYXJ5VmF1bHRQYXRoJykpO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBjcmVhdGVTZXR1cH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlU2V0dXBPcHRpb25zIHtcbiAgLyoqXG4gICAqIENvbW11bml0eS1wbHVnaW4gaWRzIHRvIGVuYWJsZSBpbiB0aGUgdmF1bHQgaW4gYWRkaXRpb24gdG8gdGhlIHBsdWdpbi11bmRlci10ZXN0LFxuICAgKiBhZnRlciBpdCBpcyBlbmFibGVkIChzZWUge0BsaW5rIENvcmVTZXR1cFBhcmFtcy5lbmFibGVDb21tdW5pdHlQbHVnaW5zfSkuIFNlZWQgZWFjaFxuICAgKiBwbHVnaW4ncyBidWlsdCBmaWxlcyB2aWEge0BsaW5rIENyZWF0ZVNldHVwT3B0aW9ucy5wb3B1bGF0ZX0gKGUuZy4gd2l0aCBgYnVpbGREZW1vVmF1bHRQb3B1bGF0ZWApXG4gICAqIHNvIHRoZSBlbmFibGUgZmluZHMgdGhlbSBvbiBkaXNrLlxuICAgKi9cbiAgcmVhZG9ubHkgZW5hYmxlQ29tbXVuaXR5UGx1Z2lucz86IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGluc3RhbGwgYW5kIGVuYWJsZSB0aGUgYnVpbHQgcGx1Z2luIGluIHRoZSB0ZW1wIHZhdWx0LiBEZWZhdWx0c1xuICAgKiB0byBgdHJ1ZWAuIFNldCB0byBgZmFsc2VgIGZvciBhICoqbm9uLXBsdWdpbioqIGNvbnN1bWVyIHRoYXQgb25seSBuZWVkcyBhXG4gICAqIHJlZ2lzdGVyZWQsIGVtcHR5IHZhdWx0IHRvIGBldmFsSW5PYnNpZGlhbmAgYWdhaW5zdCBcdTIwMTQgdGhlIG93bmVkIGluc3RhbmNlIGlzXG4gICAqIHN0aWxsIGxhdW5jaGVkIGFuZCBpdHMgZW5kcG9pbnQgcHVibGlzaGVkIHRvIHdvcmtlcnMsIHNvIHJlLWV4cG9ydGluZ1xuICAgKiBgY3JlYXRlU2V0dXAoeyBpbnN0YWxsUGx1Z2luOiBmYWxzZSB9KWAgcmV1c2VzIHRoZSBzYW1lIGF0dGFjaCB3aXJpbmcgd2l0aCBub1xuICAgKiBwbHVnaW4gY29weS9lbmFibGUuIFNlZSB7QGxpbmsgQ29yZVNldHVwUGFyYW1zLmluc3RhbGxQbHVnaW59LlxuICAgKi9cbiAgcmVhZG9ubHkgaW5zdGFsbFBsdWdpbj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFJldHVybnMgZmlsZXMvZm9sZGVycyB0byB3cml0ZSBpbnRvIHRoZSB2YXVsdCBiZWZvcmUgT2JzaWRpYW4gb3BlbnMgaXQgKHNlZVxuICAgKiB7QGxpbmsgQ29yZVNldHVwUGFyYW1zLnBvcHVsYXRlfSkuIEEgdGh1bmsgc28gbGFyZ2UgZml4dHVyZXMgYXJlIGJ1aWx0IGxhemlseSxcbiAgICogb25jZSwgaW4gdGhlIHNldHVwIHByb2Nlc3MuXG4gICAqL1xuICBwb3B1bGF0ZT8odGhpczogdm9pZCk6IFBvcHVsYXRlRmlsZXNQYXJhbXM7XG59XG5cbi8qKlxuICogQSBWaXRlc3QgYGdsb2JhbFNldHVwYCBtb2R1bGUncyBgc2V0dXBgIC8gYHRlYXJkb3duYCBwYWlyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZpdGVzdEdsb2JhbFNldHVwIHtcbiAgc2V0dXAodGhpczogdm9pZCwgcHJvamVjdDogVGVzdFByb2plY3QpOiBQcm9taXNlPHZvaWQ+O1xuICB0ZWFyZG93bih0aGlzOiB2b2lkKTogUHJvbWlzZTx2b2lkPjtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgVml0ZXN0IGdsb2JhbCBzZXR1cC90ZWFyZG93biBwYWlyLCBvcHRpb25hbGx5IHByZS1wb3B1bGF0aW5nIHRoZSB2YXVsdFxuICogYmVmb3JlIE9ic2lkaWFuIG9wZW5zIGl0IFx1MjAxNCB1c2UgdGhpcyBmb3IgYSBkZWRpY2F0ZWQgbGFyZ2UtdmF1bHQvcGVyZm9ybWFuY2VcbiAqIHByb2plY3QuIFRoZSBwbGFpbiB7QGxpbmsgc2V0dXB9IC8ge0BsaW5rIHRlYXJkb3dufSBleHBvcnRzIGFyZSB0aGUgbm8tcG9wdWxhdGVcbiAqIGNhc2UgKGBjcmVhdGVTZXR1cCgpYCkuIFBhc3MgYHsgaW5zdGFsbFBsdWdpbjogZmFsc2UgfWAgZm9yIGEgbm9uLXBsdWdpbiBjb25zdW1lclxuICogdGhhdCBvbmx5IG5lZWRzIGEgcmVnaXN0ZXJlZCwgZW1wdHkgdmF1bHQgKHNlZSB7QGxpbmsgQ3JlYXRlU2V0dXBPcHRpb25zLmluc3RhbGxQbHVnaW59KS5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFNldHVwIG9wdGlvbnMuXG4gKiBAcmV0dXJucyBUaGUgYHNldHVwYCBhbmQgYHRlYXJkb3duYCBmdW5jdGlvbnMgdG8gcmUtZXhwb3J0IGZyb20gYSBgZ2xvYmFsU2V0dXBgIG1vZHVsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNldHVwKG9wdGlvbnM/OiBDcmVhdGVTZXR1cE9wdGlvbnMpOiBWaXRlc3RHbG9iYWxTZXR1cCB7XG4gIGxldCBzZXR1cFJlc3VsdDogQ29yZVNldHVwUmVzdWx0IHwgdW5kZWZpbmVkO1xuXG4gIHJldHVybiB7IHNldHVwLCB0ZWFyZG93biB9O1xuXG4gIGFzeW5jIGZ1bmN0aW9uIHNldHVwKHByb2plY3Q6IFRlc3RQcm9qZWN0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZW52aXJvbm1lbnRPcHRpb25zID0gcHJvamVjdC5jb25maWcuZW52aXJvbm1lbnRPcHRpb25zIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IHRyYW5zcG9ydE9wdGlvbnMgPSBlbnZpcm9ubWVudE9wdGlvbnM/Llsnb2JzaWRpYW5UcmFuc3BvcnQnXSBhcyBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQ7XG4gICAgY29uc3QgbGFiZWwgPSB0cmFuc3BvcnRPcHRpb25zPy50eXBlID8/ICdvYnNpZGlhbi1jZHAnO1xuXG4gICAgdHJ5IHtcbiAgICAgIHNldHVwUmVzdWx0ID0gYXdhaXQgY29yZVNldHVwKHtcbiAgICAgICAgZW5hYmxlQ29tbXVuaXR5UGx1Z2luczogb3B0aW9ucz8uZW5hYmxlQ29tbXVuaXR5UGx1Z2lucyxcbiAgICAgICAgaW5zdGFsbFBsdWdpbjogb3B0aW9ucz8uaW5zdGFsbFBsdWdpbixcbiAgICAgICAgcG9wdWxhdGU6IG9wdGlvbnM/LnBvcHVsYXRlPy4oKSxcbiAgICAgICAgdHJhbnNwb3J0T3B0aW9uc1xuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIC8vIENhdGNoIHNldHVwIGVycm9ycyBzbyB0aGF0IG90aGVyIHByb2plY3RzJyB0ZXN0cyBjYW4gc3RpbGwgcnVuLlxuICAgICAgLy8gSW5kaXZpZHVhbCB0ZXN0cyBpbiB0aGlzIHByb2plY3Qgd2lsbCBmYWlsIHdpdGggdGhlIHN0b3JlZCBlcnJvclxuICAgICAgLy8gV2hlbiB0aGV5IHRyeSB0byBpbmplY3QgdGhlIHRlbXAgdmF1bHQgcGF0aC5cbiAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBTZXR1cCBmYWlsZWQgKHRlc3RzIGZvciB0aGlzIHByb2plY3Qgd2lsbCBiZSBza2lwcGVkKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIHByb2plY3QucHJvdmlkZSgnc2V0dXBFcnJvcicsIGVycm9yVG9TdHJpbmcoZXJyb3IpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwcm9qZWN0LnByb3ZpZGUoJ29ic2lkaWFuVHJhbnNwb3J0Jywgc2V0dXBSZXN1bHQudHJhbnNwb3J0T3B0aW9ucyk7XG4gICAgcHJvamVjdC5wcm92aWRlKCd0ZW1wb3JhcnlWYXVsdFBhdGgnLCBzZXR1cFJlc3VsdC50ZW1wb3JhcnlWYXVsdC5wYXRoKTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHRlYXJkb3duKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IGNvcmVUZWFyZG93bihzZXR1cFJlc3VsdCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB0ZW1wb3JhcnkgdmF1bHQgcHJvdmlkZWQgYnkgdGhlIGdsb2JhbCBzZXR1cC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgdGVtcG9yYXJ5IHZhdWx0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGVtcG9yYXJ5VmF1bHQoKTogVGVtcG9yYXJ5VmF1bHQge1xuICBjb25zdCB0ZW1wb3JhcnlWYXVsdFBhdGggPSBpbmplY3QoJ3RlbXBvcmFyeVZhdWx0UGF0aCcpO1xuICBjb25zdCBzZXR1cEVycm9yTWVzc2FnZSA9IGluamVjdCgnc2V0dXBFcnJvcicpO1xuICBpZiAoc2V0dXBFcnJvck1lc3NhZ2UpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludGVncmF0aW9uIHNldHVwIGZhaWxlZCBcdTIwMTQgY2Fubm90IGdldCB0ZW1wIHZhdWx0OiAke3NldHVwRXJyb3JNZXNzYWdlfWApO1xuICB9XG4gIHJldHVybiBuZXcgVGVtcG9yYXJ5VmF1bHQodGVtcG9yYXJ5VmF1bHRQYXRoKTtcbn1cblxuY29uc3QgZGVmYXVsdEdsb2JhbFNldHVwID0gY3JlYXRlU2V0dXAoKTtcblxuLyoqXG4gKiBWaXRlc3QgZ2xvYmFsIHNldHVwIGZ1bmN0aW9uIChubyBwcmUtcG9wdWxhdGlvbikuXG4gKlxuICogQ29waWVzIHRoZSBidWlsdCBwbHVnaW4gaW50byBhIHRlbXBvcmFyeSB2YXVsdCwgZW5hYmxlcyBpdCB2aWEgYSByZW5kZXJlciBldmFsXG4gKiBvdmVyIHRoZSB0cmFuc3BvcnQsIGFuZCBwcm92aWRlcyBgdGVtcG9yYXJ5VmF1bHRQYXRoYCB0byB0ZXN0cy5cbiAqXG4gKiBAcGFyYW0gcHJvamVjdCAtIFRoZSBWaXRlc3QgcHJvamVjdC5cbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gc2V0dXAgY29tcGxldGVzLlxuICovXG5leHBvcnQgY29uc3Qgc2V0dXAgPSBkZWZhdWx0R2xvYmFsU2V0dXAuc2V0dXA7XG5cbi8qKlxuICogVml0ZXN0IGdsb2JhbCB0ZWFyZG93biBmdW5jdGlvbi5cbiAqXG4gKiBSZW1vdmVzIHRoZSB0ZW1wb3JhcnkgdmF1bHQgY3JlYXRlZCBkdXJpbmcgc2V0dXAuXG4gKlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0ZWFyZG93biBjb21wbGV0ZXMuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZWFyZG93biA9IGRlZmF1bHRHbG9iYWxTZXR1cC50ZWFyZG93bjtcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFhQSxvQkFBdUI7QUFNdkIsOEJBR087QUFDUCw2QkFBOEI7QUFDOUIsK0JBR087QUFDUCxpQkFBb0I7QUFDcEIsNkJBQStCO0FBQUEsSUFFL0IscURBQTRCLFVBQU0sc0JBQU8sbUJBQW1CLENBQUM7QUFBQSxJQUM3RCw4Q0FBcUIsVUFBTSxzQkFBTyxvQkFBb0IsQ0FBQztBQWtEaEQsU0FBUyxZQUFZLFNBQWlEO0FBQzNFLE1BQUk7QUFFSixTQUFPLEVBQUUsT0FBQUEsUUFBTyxVQUFBQyxVQUFTO0FBRXpCLGlCQUFlRCxPQUFNLFNBQXFDO0FBQ3hELFVBQU0scUJBQXFCLFFBQVEsT0FBTztBQUMxQyxVQUFNLG1CQUFtQixxQkFBcUIsbUJBQW1CO0FBQ2pFLFVBQU0sUUFBUSxrQkFBa0IsUUFBUTtBQUV4QyxRQUFJO0FBQ0Ysb0JBQWMsVUFBTSxvQ0FBVTtBQUFBLFFBQzVCLHdCQUF3QixTQUFTO0FBQUEsUUFDakMsZUFBZSxTQUFTO0FBQUEsUUFDeEIsVUFBVSxTQUFTLFdBQVc7QUFBQSxRQUM5QjtBQUFBLE1BQ0YsQ0FBQztBQUFBLElBQ0gsU0FBUyxPQUFnQjtBQUl2QiwwQkFBSSxzQkFBc0IsS0FBSyxnRUFBNEQsc0NBQWMsS0FBSyxDQUFDLEVBQUU7QUFDakgsY0FBUSxRQUFRLGtCQUFjLHNDQUFjLEtBQUssQ0FBQztBQUNsRDtBQUFBLElBQ0Y7QUFFQSxZQUFRLFFBQVEscUJBQXFCLFlBQVksZ0JBQWdCO0FBQ2pFLFlBQVEsUUFBUSxzQkFBc0IsWUFBWSxlQUFlLElBQUk7QUFBQSxFQUN2RTtBQUVBLGlCQUFlQyxZQUEwQjtBQUN2QyxjQUFNLHVDQUFhLFdBQVc7QUFBQSxFQUNoQztBQUNGO0FBT08sU0FBUyxvQkFBb0M7QUFDbEQsUUFBTSx5QkFBcUIsc0JBQU8sb0JBQW9CO0FBQ3RELFFBQU0sd0JBQW9CLHNCQUFPLFlBQVk7QUFDN0MsTUFBSSxtQkFBbUI7QUFDckIsVUFBTSxJQUFJLE1BQU0sMERBQXFELGlCQUFpQixFQUFFO0FBQUEsRUFDMUY7QUFDQSxTQUFPLElBQUksc0NBQWUsa0JBQWtCO0FBQzlDO0FBRUEsTUFBTSxxQkFBcUIsWUFBWTtBQVdoQyxNQUFNLFFBQVEsbUJBQW1CO0FBU2pDLE1BQU0sV0FBVyxtQkFBbUI7IiwKICAibmFtZXMiOiBbInNldHVwIiwgInRlYXJkb3duIl0KfQo=
|
|
85
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL3ZpdGVzdC9nbG9iYWwtc2V0dXAudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBWaXRlc3QgZ2xvYmFsIHNldHVwIGFuZCB0ZWFyZG93biBhZGFwdGVyLlxuICpcbiAqIERlbGVnYXRlcyB0byB0aGUgZnJhbWV3b3JrLWFnbm9zdGljIGNvcmUgYW5kIGJyaWRnZXMgY29udGV4dFxuICogdG8gdGVzdCB3b3JrZXJzIHZpYSBWaXRlc3QncyBgcHJvamVjdC5wcm92aWRlYCAvIGBpbmplY3RgLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIHNldHVwIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgdHlwZSB7IFRlc3RQcm9qZWN0IH0gZnJvbSAndml0ZXN0L25vZGUnO1xuXG5pbXBvcnQgeyBpbmplY3QgfSBmcm9tICd2aXRlc3QnO1xuXG5pbXBvcnQgdHlwZSB7IENvcmVTZXR1cFJlc3VsdCB9IGZyb20gJy4uL2dsb2JhbC1zZXR1cC1jb3JlLmNqcyc7XG5pbXBvcnQgdHlwZSB7IFBvcHVsYXRlRmlsZXNQYXJhbXMgfSBmcm9tICcuLi90ZW1wb3JhcnktdmF1bHQuY2pzJztcbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIH0gZnJvbSAnLi4vdHJhbnNwb3J0LW9wdGlvbnMuY2pzJztcblxuaW1wb3J0IHtcbiAgc2V0U2V0dXBFcnJvclJlc29sdmVyLFxuICBzZXRUcmFuc3BvcnRPcHRpb25zUmVzb2x2ZXIsXG4gIHNldFZhdWx0UGF0aFJlc29sdmVyXG59IGZyb20gJy4uL2NvbnRleHQtcHJvdmlkZXIuY2pzJztcbmltcG9ydCB7IGVycm9yVG9TdHJpbmcgfSBmcm9tICcuLi9lcnJvci10by1zdHJpbmcuY2pzJztcbmltcG9ydCB7XG4gIGNvcmVTZXR1cCxcbiAgY29yZVRlYXJkb3duXG59IGZyb20gJy4uL2dsb2JhbC1zZXR1cC1jb3JlLmNqcyc7XG5pbXBvcnQgeyBJbnRlZ3JhdGlvblNldHVwRmFpbGVkRXJyb3IgfSBmcm9tICcuLi9pbnRlZ3JhdGlvbi1zZXR1cC1mYWlsZWQtZXJyb3IuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4uL2xvZy5janMnO1xuaW1wb3J0IHsgVGVtcG9yYXJ5VmF1bHQgfSBmcm9tICcuLi90ZW1wb3JhcnktdmF1bHQuY2pzJztcblxuc2V0U2V0dXBFcnJvclJlc29sdmVyKCgpID0+IGluamVjdCgnc2V0dXBFcnJvcicpKTtcbnNldFRyYW5zcG9ydE9wdGlvbnNSZXNvbHZlcigoKSA9PiBpbmplY3QoJ29ic2lkaWFuVHJhbnNwb3J0JykpO1xuc2V0VmF1bHRQYXRoUmVzb2x2ZXIoKCkgPT4gaW5qZWN0KCd0ZW1wb3JhcnlWYXVsdFBhdGgnKSk7XG5cbi8qKlxuICogT3B0aW9ucyBmb3Ige0BsaW5rIGNyZWF0ZVNldHVwfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVTZXR1cE9wdGlvbnMge1xuICAvKipcbiAgICogQ29tbXVuaXR5LXBsdWdpbiBpZHMgdG8gZW5hYmxlIGluIHRoZSB2YXVsdCBpbiBhZGRpdGlvbiB0byB0aGUgcGx1Z2luLXVuZGVyLXRlc3QsXG4gICAqIGFmdGVyIGl0IGlzIGVuYWJsZWQgKHNlZSB7QGxpbmsgQ29yZVNldHVwUGFyYW1zLmVuYWJsZUNvbW11bml0eVBsdWdpbnN9KS4gU2VlZCBlYWNoXG4gICAqIHBsdWdpbidzIGJ1aWx0IGZpbGVzIHZpYSB7QGxpbmsgQ3JlYXRlU2V0dXBPcHRpb25zLnBvcHVsYXRlfSAoZS5nLiB3aXRoIGBidWlsZERlbW9WYXVsdFBvcHVsYXRlYClcbiAgICogc28gdGhlIGVuYWJsZSBmaW5kcyB0aGVtIG9uIGRpc2suXG4gICAqL1xuICByZWFkb25seSBlbmFibGVDb21tdW5pdHlQbHVnaW5zPzogcmVhZG9ubHkgc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gaW5zdGFsbCBhbmQgZW5hYmxlIHRoZSBidWlsdCBwbHVnaW4gaW4gdGhlIHRlbXAgdmF1bHQuIERlZmF1bHRzXG4gICAqIHRvIGB0cnVlYC4gU2V0IHRvIGBmYWxzZWAgZm9yIGEgKipub24tcGx1Z2luKiogY29uc3VtZXIgdGhhdCBvbmx5IG5lZWRzIGFcbiAgICogcmVnaXN0ZXJlZCwgZW1wdHkgdmF1bHQgdG8gYGV2YWxJbk9ic2lkaWFuYCBhZ2FpbnN0IFx1MjAxNCB0aGUgb3duZWQgaW5zdGFuY2UgaXNcbiAgICogc3RpbGwgbGF1bmNoZWQgYW5kIGl0cyBlbmRwb2ludCBwdWJsaXNoZWQgdG8gd29ya2Vycywgc28gcmUtZXhwb3J0aW5nXG4gICAqIGBjcmVhdGVTZXR1cCh7IGluc3RhbGxQbHVnaW46IGZhbHNlIH0pYCByZXVzZXMgdGhlIHNhbWUgYXR0YWNoIHdpcmluZyB3aXRoIG5vXG4gICAqIHBsdWdpbiBjb3B5L2VuYWJsZS4gU2VlIHtAbGluayBDb3JlU2V0dXBQYXJhbXMuaW5zdGFsbFBsdWdpbn0uXG4gICAqL1xuICByZWFkb25seSBpbnN0YWxsUGx1Z2luPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogUmV0dXJucyBmaWxlcy9mb2xkZXJzIHRvIHdyaXRlIGludG8gdGhlIHZhdWx0IGJlZm9yZSBPYnNpZGlhbiBvcGVucyBpdCAoc2VlXG4gICAqIHtAbGluayBDb3JlU2V0dXBQYXJhbXMucG9wdWxhdGV9KS4gQSB0aHVuayBzbyBsYXJnZSBmaXh0dXJlcyBhcmUgYnVpbHQgbGF6aWx5LFxuICAgKiBvbmNlLCBpbiB0aGUgc2V0dXAgcHJvY2Vzcy5cbiAgICpcbiAgICogTWF5IHJldHVybiBhIHByb21pc2UsIHNvIHRoZSBtYXAgY2FuIGJlIGJ1aWx0IGJ5IHNvbWV0aGluZyB0aGF0IG5lZWRzIHRoZSBuZXR3b3JrIFx1MjAxNCBub3RhYmx5XG4gICAqIGBidWlsZERlbW9WYXVsdFBvcHVsYXRlQXN5bmNgLCB3aGljaCBpbnN0YWxscyBhIGRlbW8gdmF1bHQncyBtaXNzaW5nIGNvbW11bml0eSBwbHVnaW5zIGJlZm9yZVxuICAgKiByZWFkaW5nIHRoZW0uIEEgc3luY2hyb25vdXMgdGh1bmsgKGUuZy4gYGJ1aWxkRGVtb1ZhdWx0UG9wdWxhdGVgKSBpcyB1bmNoYW5nZWQuXG4gICAqL1xuICBwb3B1bGF0ZT8odGhpczogdm9pZCk6IFBvcHVsYXRlRmlsZXNQYXJhbXMgfCBQcm9taXNlPFBvcHVsYXRlRmlsZXNQYXJhbXM+O1xufVxuXG4vKipcbiAqIEEgVml0ZXN0IGBnbG9iYWxTZXR1cGAgbW9kdWxlJ3MgYHNldHVwYCAvIGB0ZWFyZG93bmAgcGFpci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWaXRlc3RHbG9iYWxTZXR1cCB7XG4gIHNldHVwKHRoaXM6IHZvaWQsIHByb2plY3Q6IFRlc3RQcm9qZWN0KTogUHJvbWlzZTx2b2lkPjtcbiAgdGVhcmRvd24odGhpczogdm9pZCk6IFByb21pc2U8dm9pZD47XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIFZpdGVzdCBnbG9iYWwgc2V0dXAvdGVhcmRvd24gcGFpciwgb3B0aW9uYWxseSBwcmUtcG9wdWxhdGluZyB0aGUgdmF1bHRcbiAqIGJlZm9yZSBPYnNpZGlhbiBvcGVucyBpdCBcdTIwMTQgdXNlIHRoaXMgZm9yIGEgZGVkaWNhdGVkIGxhcmdlLXZhdWx0L3BlcmZvcm1hbmNlXG4gKiBwcm9qZWN0LiBUaGUgcGxhaW4ge0BsaW5rIHNldHVwfSAvIHtAbGluayB0ZWFyZG93bn0gZXhwb3J0cyBhcmUgdGhlIG5vLXBvcHVsYXRlXG4gKiBjYXNlIChgY3JlYXRlU2V0dXAoKWApLiBQYXNzIGB7IGluc3RhbGxQbHVnaW46IGZhbHNlIH1gIGZvciBhIG5vbi1wbHVnaW4gY29uc3VtZXJcbiAqIHRoYXQgb25seSBuZWVkcyBhIHJlZ2lzdGVyZWQsIGVtcHR5IHZhdWx0IChzZWUge0BsaW5rIENyZWF0ZVNldHVwT3B0aW9ucy5pbnN0YWxsUGx1Z2lufSkuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBTZXR1cCBvcHRpb25zLlxuICogQHJldHVybnMgVGhlIGBzZXR1cGAgYW5kIGB0ZWFyZG93bmAgZnVuY3Rpb25zIHRvIHJlLWV4cG9ydCBmcm9tIGEgYGdsb2JhbFNldHVwYCBtb2R1bGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTZXR1cChvcHRpb25zPzogQ3JlYXRlU2V0dXBPcHRpb25zKTogVml0ZXN0R2xvYmFsU2V0dXAge1xuICBsZXQgc2V0dXBSZXN1bHQ6IENvcmVTZXR1cFJlc3VsdCB8IHVuZGVmaW5lZDtcblxuICByZXR1cm4geyBzZXR1cCwgdGVhcmRvd24gfTtcblxuICBhc3luYyBmdW5jdGlvbiBzZXR1cChwcm9qZWN0OiBUZXN0UHJvamVjdCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGVudmlyb25tZW50T3B0aW9ucyA9IHByb2plY3QuY29uZmlnLmVudmlyb25tZW50T3B0aW9ucyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZDtcbiAgICBjb25zdCB0cmFuc3BvcnRPcHRpb25zID0gZW52aXJvbm1lbnRPcHRpb25zPy5bJ29ic2lkaWFuVHJhbnNwb3J0J10gYXMgT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IGxhYmVsID0gdHJhbnNwb3J0T3B0aW9ucz8udHlwZSA/PyAnb2JzaWRpYW4tY2RwJztcblxuICAgIHRyeSB7XG4gICAgICBzZXR1cFJlc3VsdCA9IGF3YWl0IGNvcmVTZXR1cCh7XG4gICAgICAgIGVuYWJsZUNvbW11bml0eVBsdWdpbnM6IG9wdGlvbnM/LmVuYWJsZUNvbW11bml0eVBsdWdpbnMsXG4gICAgICAgIGluc3RhbGxQbHVnaW46IG9wdGlvbnM/Lmluc3RhbGxQbHVnaW4sXG4gICAgICAgIHBvcHVsYXRlOiBhd2FpdCBvcHRpb25zPy5wb3B1bGF0ZT8uKCksXG4gICAgICAgIHRyYW5zcG9ydE9wdGlvbnNcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAvLyBDYXRjaCBzZXR1cCBlcnJvcnMgc28gdGhhdCBvdGhlciBwcm9qZWN0cycgdGVzdHMgY2FuIHN0aWxsIHJ1bi4gRXZlcnkgdGVzdCBpbiBUSElTIHByb2plY3RcbiAgICAgIC8vIFRoZW4gZmFpbHMgd2l0aCB0aGUgc3RvcmVkIGVycm9yOiBgZ2V0T3JDcmVhdGVUcmFuc3BvcnRgIHJlYWRzIGl0IHRocm91Z2ggdGhlIHNldHVwLWVycm9yXG4gICAgICAvLyBSZXNvbHZlciBhbmQgdGhyb3dzIGJlZm9yZSBpdCBjYW4gYnVpbGQgYSB0cmFuc3BvcnQuIFdpdGhvdXQgdGhhdCBhIHdvcmtlciBnZXRzIG5vIG9wdGlvbnNcbiAgICAgIC8vIEF0IGFsbCBhbmQgc2lsZW50bHkgcmVidWlsZHMgdGhlIG93bmVkIERFU0tUT1AgZGVmYXVsdCwgd2hhdGV2ZXIgcGxhdGZvcm0gdGhpcyBwcm9qZWN0IGFza2VkXG4gICAgICAvLyBGb3IgLS0gd2hpY2ggaXMgaG93IGFuIEFuZHJvaWQgcnVuIGNhbWUgdG8gcmVwb3J0IG5pbmUgYEZhaWxlZCB0byBwYXJzZSBVUkwgZnJvbSAvanNvbmBcbiAgICAgIC8vIEZhaWx1cmVzIHdoaWxlIHRoZSByZWFsIGNhdXNlIHNhdCBvbmNlLCBmYXIgYWJvdmUsIGluIHRoaXMgbG9nIChzZWUgQUdFTlRTLm1kIEw5KS5cbiAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBTZXR1cCBmYWlsZWQgKGV2ZXJ5IHRlc3QgaW4gdGhpcyBwcm9qZWN0IHdpbGwgZmFpbCB3aXRoIHRoaXMgZXJyb3IpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICAgICAgcHJvamVjdC5wcm92aWRlKCdzZXR1cEVycm9yJywge1xuICAgICAgICBlcnJvck5hbWU6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5uYW1lIDogJ0Vycm9yJyxcbiAgICAgICAgbWVzc2FnZTogZXJyb3JUb1N0cmluZyhlcnJvciksXG4gICAgICAgIHRyYW5zcG9ydExhYmVsOiBsYWJlbFxuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcHJvamVjdC5wcm92aWRlKCdvYnNpZGlhblRyYW5zcG9ydCcsIHNldHVwUmVzdWx0LnRyYW5zcG9ydE9wdGlvbnMpO1xuICAgIHByb2plY3QucHJvdmlkZSgndGVtcG9yYXJ5VmF1bHRQYXRoJywgc2V0dXBSZXN1bHQudGVtcG9yYXJ5VmF1bHQucGF0aCk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiB0ZWFyZG93bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBjb3JlVGVhcmRvd24oc2V0dXBSZXN1bHQpO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgdGVtcG9yYXJ5IHZhdWx0IHByb3ZpZGVkIGJ5IHRoZSBnbG9iYWwgc2V0dXAuXG4gKlxuICogQHJldHVybnMgVGhlIHRlbXBvcmFyeSB2YXVsdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRlbXBvcmFyeVZhdWx0KCk6IFRlbXBvcmFyeVZhdWx0IHtcbiAgY29uc3QgdGVtcG9yYXJ5VmF1bHRQYXRoID0gaW5qZWN0KCd0ZW1wb3JhcnlWYXVsdFBhdGgnKTtcbiAgY29uc3Qgc2V0dXBFcnJvciA9IGluamVjdCgnc2V0dXBFcnJvcicpO1xuICBpZiAoc2V0dXBFcnJvcikge1xuICAgIHRocm93IG5ldyBJbnRlZ3JhdGlvblNldHVwRmFpbGVkRXJyb3Ioc2V0dXBFcnJvcik7XG4gIH1cbiAgcmV0dXJuIG5ldyBUZW1wb3JhcnlWYXVsdCh0ZW1wb3JhcnlWYXVsdFBhdGgpO1xufVxuXG5jb25zdCBkZWZhdWx0R2xvYmFsU2V0dXAgPSBjcmVhdGVTZXR1cCgpO1xuXG4vKipcbiAqIFZpdGVzdCBnbG9iYWwgc2V0dXAgZnVuY3Rpb24gKG5vIHByZS1wb3B1bGF0aW9uKS5cbiAqXG4gKiBDb3BpZXMgdGhlIGJ1aWx0IHBsdWdpbiBpbnRvIGEgdGVtcG9yYXJ5IHZhdWx0LCBlbmFibGVzIGl0IHZpYSBhIHJlbmRlcmVyIGV2YWxcbiAqIG92ZXIgdGhlIHRyYW5zcG9ydCwgYW5kIHByb3ZpZGVzIGB0ZW1wb3JhcnlWYXVsdFBhdGhgIHRvIHRlc3RzLlxuICpcbiAqIEBwYXJhbSBwcm9qZWN0IC0gVGhlIFZpdGVzdCBwcm9qZWN0LlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBzZXR1cCBjb21wbGV0ZXMuXG4gKi9cbmV4cG9ydCBjb25zdCBzZXR1cCA9IGRlZmF1bHRHbG9iYWxTZXR1cC5zZXR1cDtcblxuLyoqXG4gKiBWaXRlc3QgZ2xvYmFsIHRlYXJkb3duIGZ1bmN0aW9uLlxuICpcbiAqIFJlbW92ZXMgdGhlIHRlbXBvcmFyeSB2YXVsdCBjcmVhdGVkIGR1cmluZyBzZXR1cC5cbiAqXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRlYXJkb3duIGNvbXBsZXRlcy5cbiAqL1xuZXhwb3J0IGNvbnN0IHRlYXJkb3duID0gZGVmYXVsdEdsb2JhbFNldHVwLnRlYXJkb3duO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWFBLG9CQUF1QjtBQU12Qiw4QkFJTztBQUNQLDZCQUE4QjtBQUM5QiwrQkFHTztBQUNQLDRDQUE0QztBQUM1QyxpQkFBb0I7QUFDcEIsNkJBQStCO0FBQUEsSUFFL0IsK0NBQXNCLFVBQU0sc0JBQU8sWUFBWSxDQUFDO0FBQUEsSUFDaEQscURBQTRCLFVBQU0sc0JBQU8sbUJBQW1CLENBQUM7QUFBQSxJQUM3RCw4Q0FBcUIsVUFBTSxzQkFBTyxvQkFBb0IsQ0FBQztBQXNEaEQsU0FBUyxZQUFZLFNBQWlEO0FBQzNFLE1BQUk7QUFFSixTQUFPLEVBQUUsT0FBQUEsUUFBTyxVQUFBQyxVQUFTO0FBRXpCLGlCQUFlRCxPQUFNLFNBQXFDO0FBQ3hELFVBQU0scUJBQXFCLFFBQVEsT0FBTztBQUMxQyxVQUFNLG1CQUFtQixxQkFBcUIsbUJBQW1CO0FBQ2pFLFVBQU0sUUFBUSxrQkFBa0IsUUFBUTtBQUV4QyxRQUFJO0FBQ0Ysb0JBQWMsVUFBTSxvQ0FBVTtBQUFBLFFBQzVCLHdCQUF3QixTQUFTO0FBQUEsUUFDakMsZUFBZSxTQUFTO0FBQUEsUUFDeEIsVUFBVSxNQUFNLFNBQVMsV0FBVztBQUFBLFFBQ3BDO0FBQUEsTUFDRixDQUFDO0FBQUEsSUFDSCxTQUFTLE9BQWdCO0FBT3ZCLDBCQUFJLHNCQUFzQixLQUFLLDhFQUEwRSxzQ0FBYyxLQUFLLENBQUMsRUFBRTtBQUMvSCxjQUFRLFFBQVEsY0FBYztBQUFBLFFBQzVCLFdBQVcsaUJBQWlCLFFBQVEsTUFBTSxPQUFPO0FBQUEsUUFDakQsYUFBUyxzQ0FBYyxLQUFLO0FBQUEsUUFDNUIsZ0JBQWdCO0FBQUEsTUFDbEIsQ0FBQztBQUNEO0FBQUEsSUFDRjtBQUVBLFlBQVEsUUFBUSxxQkFBcUIsWUFBWSxnQkFBZ0I7QUFDakUsWUFBUSxRQUFRLHNCQUFzQixZQUFZLGVBQWUsSUFBSTtBQUFBLEVBQ3ZFO0FBRUEsaUJBQWVDLFlBQTBCO0FBQ3ZDLGNBQU0sdUNBQWEsV0FBVztBQUFBLEVBQ2hDO0FBQ0Y7QUFPTyxTQUFTLG9CQUFvQztBQUNsRCxRQUFNLHlCQUFxQixzQkFBTyxvQkFBb0I7QUFDdEQsUUFBTSxpQkFBYSxzQkFBTyxZQUFZO0FBQ3RDLE1BQUksWUFBWTtBQUNkLFVBQU0sSUFBSSxrRUFBNEIsVUFBVTtBQUFBLEVBQ2xEO0FBQ0EsU0FBTyxJQUFJLHNDQUFlLGtCQUFrQjtBQUM5QztBQUVBLE1BQU0scUJBQXFCLFlBQVk7QUFXaEMsTUFBTSxRQUFRLG1CQUFtQjtBQVNqQyxNQUFNLFdBQVcsbUJBQW1COyIsCiAgIm5hbWVzIjogWyJzZXR1cCIsICJ0ZWFyZG93biJdCn0K
|
|
@@ -33,8 +33,12 @@ export interface CreateSetupOptions {
|
|
|
33
33
|
* Returns files/folders to write into the vault before Obsidian opens it (see
|
|
34
34
|
* {@link CoreSetupParams.populate}). A thunk so large fixtures are built lazily,
|
|
35
35
|
* once, in the setup process.
|
|
36
|
+
*
|
|
37
|
+
* May return a promise, so the map can be built by something that needs the network — notably
|
|
38
|
+
* `buildDemoVaultPopulateAsync`, which installs a demo vault's missing community plugins before
|
|
39
|
+
* reading them. A synchronous thunk (e.g. `buildDemoVaultPopulate`) is unchanged.
|
|
36
40
|
*/
|
|
37
|
-
populate?(this: void): PopulateFilesParams
|
|
41
|
+
populate?(this: void): PopulateFilesParams | Promise<PopulateFilesParams>;
|
|
38
42
|
}
|
|
39
43
|
/**
|
|
40
44
|
* A Vitest `globalSetup` module's `setup` / `teardown` pair.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var import_vitest = require("vitest");
|
|
3
3
|
var import_context_provider = require("../context-provider.cjs");
|
|
4
|
+
(0, import_context_provider.setSetupErrorResolver)(() => (0, import_vitest.inject)("setupError"));
|
|
4
5
|
(0, import_context_provider.setTransportOptionsResolver)(() => (0, import_vitest.inject)("obsidianTransport"));
|
|
5
6
|
(0, import_context_provider.setVaultPathResolver)(() => (0, import_vitest.inject)("temporaryVaultPath"));
|
|
6
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
7
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL3ZpdGVzdC9zZXR1cC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFZpdGVzdCAqKnBlci13b3JrZXIqKiBzZXR1cCBmaWxlLlxuICpcbiAqIFZpdGVzdCBydW5zIGBnbG9iYWxTZXR1cGAgb25seSBpbiB0aGUgbWFpbiBwcm9jZXNzLCBzbyB0aGUgdHJhbnNwb3J0LW9wdGlvbnNcbiAqIGFuZCB2YXVsdC1wYXRoIHJlc29sdmVycyByZWdpc3RlcmVkIHRoZXJlIG5ldmVyIGV4aXN0IGluIHRoZSB0ZXN0IHdvcmtlcnMgdGhhdFxuICogYWN0dWFsbHkgY2FsbCB7QGxpbmsgZXZhbEluT2JzaWRpYW59LiBBZGQgdGhpcyBtb2R1bGUgdG8gdGhlIGludGVncmF0aW9uXG4gKiBwcm9qZWN0J3MgYHNldHVwRmlsZXNgIHNvIGVhY2ggd29ya2VyIHJlZ2lzdGVycyB0aGUgcmVzb2x2ZXJzIGFuZCByZWFkcyB0aGVcbiAqIGNvbnRleHQgdGhlIGdsb2JhbCBzZXR1cCBwdWJsaXNoZWQgdmlhIGBwcm92aWRlYCAoZS5nLiB0aGUgb3duZWQgaW5zdGFuY2Unc1xuICogQ0RQIGBwb3J0YCkuIFdpdGhvdXQgaXQsIGEgd29ya2VyIGZhbGxzIGJhY2sgdG8gbGF1bmNoaW5nIGl0cyBvd24gdW4tcHJlcGFyZWRcbiAqIHRyYW5zcG9ydCBcdTIwMTQgd2hpY2gsIGZvciB0aGUgb3duZWQtQ0RQIGRlZmF1bHQsIGhhcyBubyBDRFAgZW5kcG9pbnQuXG4gKlxuICogVGhlIHNldHVwLWVycm9yIHJlc29sdmVyIGlzIHRoZSBzYW1lIGNoYW5uZWwgdXNlZCBpbiByZXZlcnNlOiB3aGVuIHRoZSBnbG9iYWwgc2V0dXBcbiAqIEZBSUxFRCBpdCBwdWJsaXNoZXMgbm90aGluZyBidXQgdGhlIGZhaWx1cmUsIGFuZCB0aGlzIHJlZ2lzdHJhdGlvbiBpcyB3aGF0IGxldHNcbiAqIGBnZXRPckNyZWF0ZVRyYW5zcG9ydGAgdGhyb3cgaXQgaW5zdGVhZCBvZiBxdWlldGx5IGJ1aWxkaW5nIHRoYXQgc2FtZSB1bi1wcmVwYXJlZFxuICogZGVza3RvcCB0cmFuc3BvcnQgaW4gYSBwcm9qZWN0IGNvbmZpZ3VyZWQgZm9yIGFub3RoZXIgcGxhdGZvcm0uXG4gKi9cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIHNldHVwIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgeyBpbmplY3QgfSBmcm9tICd2aXRlc3QnO1xuXG5pbXBvcnQge1xuICBzZXRTZXR1cEVycm9yUmVzb2x2ZXIsXG4gIHNldFRyYW5zcG9ydE9wdGlvbnNSZXNvbHZlcixcbiAgc2V0VmF1bHRQYXRoUmVzb2x2ZXJcbn0gZnJvbSAnLi4vY29udGV4dC1wcm92aWRlci5janMnO1xuXG5zZXRTZXR1cEVycm9yUmVzb2x2ZXIoKCkgPT4gaW5qZWN0KCdzZXR1cEVycm9yJykpO1xuc2V0VHJhbnNwb3J0T3B0aW9uc1Jlc29sdmVyKCgpID0+IGluamVjdCgnb2JzaWRpYW5UcmFuc3BvcnQnKSk7XG5zZXRWYXVsdFBhdGhSZXNvbHZlcigoKSA9PiBpbmplY3QoJ3RlbXBvcmFyeVZhdWx0UGF0aCcpKTtcblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7QUFvQkEsb0JBQXVCO0FBRXZCLDhCQUlPO0FBQUEsSUFFUCwrQ0FBc0IsVUFBTSxzQkFBTyxZQUFZLENBQUM7QUFBQSxJQUNoRCxxREFBNEIsVUFBTSxzQkFBTyxtQkFBbUIsQ0FBQztBQUFBLElBQzdELDhDQUFxQixVQUFNLHNCQUFPLG9CQUFvQixDQUFDOyIsCiAgIm5hbWVzIjogW10KfQo=
|
|
@@ -10,5 +10,10 @@
|
|
|
10
10
|
* context the global setup published via `provide` (e.g. the owned instance's
|
|
11
11
|
* CDP `port`). Without it, a worker falls back to launching its own un-prepared
|
|
12
12
|
* transport — which, for the owned-CDP default, has no CDP endpoint.
|
|
13
|
+
*
|
|
14
|
+
* The setup-error resolver is the same channel used in reverse: when the global setup
|
|
15
|
+
* FAILED it publishes nothing but the failure, and this registration is what lets
|
|
16
|
+
* `getOrCreateTransport` throw it instead of quietly building that same un-prepared
|
|
17
|
+
* desktop transport in a project configured for another platform.
|
|
13
18
|
*/
|
|
14
19
|
export {};
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* and `inject('obsidianTransport')` / `inject('temporaryVaultPath')`.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import type { IntegrationSetupFailedErrorConstructorParams } from '../integration-setup-failed-error.cjs';
|
|
14
15
|
import type { ObsidianTransportOptions } from '../transport-options.cjs';
|
|
15
16
|
|
|
16
17
|
// eslint-disable-next-line import-x/no-unassigned-import -- Forces module resolution so declare module augmentations merge correctly.
|
|
@@ -27,11 +28,12 @@ declare module 'vitest' {
|
|
|
27
28
|
obsidianTransport?: ObsidianTransportOptions;
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* The global setup's failure, serialized for the workers. Present only when
|
|
32
|
+
* setup failed; the per-worker setup file registers it as the setup-error
|
|
33
|
+
* resolver, and `getOrCreateTransport` throws it rather than let a worker
|
|
34
|
+
* build a transport the project never asked for.
|
|
33
35
|
*/
|
|
34
|
-
setupError?:
|
|
36
|
+
setupError?: IntegrationSetupFailedErrorConstructorParams;
|
|
35
37
|
|
|
36
38
|
/**
|
|
37
39
|
* Path to the temporary vault created by the global setup.
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var webview_cdp_exports = {};
|
|
20
|
+
__export(webview_cdp_exports, {
|
|
21
|
+
WebViewCdpConnection: () => WebViewCdpConnection,
|
|
22
|
+
connectToWebViewCdp: () => connectToWebViewCdp,
|
|
23
|
+
parseForwardedPort: () => parseForwardedPort,
|
|
24
|
+
parseWebViewDevtoolsSocketName: () => parseWebViewDevtoolsSocketName,
|
|
25
|
+
selectWebViewPageTarget: () => selectWebViewPageTarget
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(webview_cdp_exports);
|
|
28
|
+
var import_node_child_process = require("node:child_process");
|
|
29
|
+
var import_exec = require("./exec.cjs");
|
|
30
|
+
var import_log = require("./log.cjs");
|
|
31
|
+
var import_obsidian_instance = require("./obsidian-instance.cjs");
|
|
32
|
+
const ADB_TIMEOUT_IN_MILLISECONDS = 15e3;
|
|
33
|
+
const FORWARD_LIST_COLUMN_COUNT = 3;
|
|
34
|
+
const DECIMAL_RADIX = 10;
|
|
35
|
+
const CDP_COMMAND_TIMEOUT_IN_MILLISECONDS = 3e4;
|
|
36
|
+
const CDP_HOST = "127.0.0.1";
|
|
37
|
+
class WebViewCdpConnection {
|
|
38
|
+
/**
|
|
39
|
+
* Wraps an already-open debugger socket, plus what is needed to tear its port forward down.
|
|
40
|
+
*
|
|
41
|
+
* @param webSocket - The open debugger socket.
|
|
42
|
+
* @param deviceId - The adb device id, needed to drop the port forward on dispose.
|
|
43
|
+
* @param port - The forwarded local port.
|
|
44
|
+
*/
|
|
45
|
+
constructor(webSocket, deviceId, port) {
|
|
46
|
+
this.webSocket = webSocket;
|
|
47
|
+
this.deviceId = deviceId;
|
|
48
|
+
this.port = port;
|
|
49
|
+
this.webSocket.addEventListener("message", (event) => {
|
|
50
|
+
const message = JSON.parse(String(event.data));
|
|
51
|
+
if (message.method === void 0) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this.eventHandlers.get(message.method)?.(message.params ?? {});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
webSocket;
|
|
58
|
+
deviceId;
|
|
59
|
+
port;
|
|
60
|
+
/**
|
|
61
|
+
* Whether the socket is still usable.
|
|
62
|
+
*
|
|
63
|
+
* Restarting the app tears its WebView down and takes the debugger target with it, so a cached
|
|
64
|
+
* connection has to be re-checked rather than assumed live.
|
|
65
|
+
*
|
|
66
|
+
* @returns `true` while the socket is open.
|
|
67
|
+
*/
|
|
68
|
+
get isOpen() {
|
|
69
|
+
return this.webSocket.readyState === WebSocket.OPEN;
|
|
70
|
+
}
|
|
71
|
+
eventHandlers = /* @__PURE__ */ new Map();
|
|
72
|
+
messageId = 0;
|
|
73
|
+
/**
|
|
74
|
+
* Closes the socket and drops the adb port forward.
|
|
75
|
+
*/
|
|
76
|
+
async dispose() {
|
|
77
|
+
this.closeSocket();
|
|
78
|
+
await removeForward(this.deviceId, this.port);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Synchronous disposal, for `process.on('exit')` handlers where async work cannot run.
|
|
82
|
+
*
|
|
83
|
+
* Without this an abrupt worker exit leaves the port forward behind — the async {@link dispose} above
|
|
84
|
+
* never gets a turn.
|
|
85
|
+
*/
|
|
86
|
+
disposeSync() {
|
|
87
|
+
this.closeSocket();
|
|
88
|
+
try {
|
|
89
|
+
(0, import_node_child_process.execFileSync)("adb", ["-s", this.deviceId, "forward", "--remove", `tcp:${String(this.port)}`], {
|
|
90
|
+
stdio: "ignore",
|
|
91
|
+
timeout: ADB_TIMEOUT_IN_MILLISECONDS
|
|
92
|
+
});
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Subscribes to a CDP event. One handler per method; subscribing again replaces it.
|
|
98
|
+
*
|
|
99
|
+
* @param method - The CDP event name, e.g. `Runtime.bindingCalled`.
|
|
100
|
+
* @param handler - Called with the event parameters.
|
|
101
|
+
*/
|
|
102
|
+
on(method, handler) {
|
|
103
|
+
this.eventHandlers.set(method, handler);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Sends a CDP command and waits for its response.
|
|
107
|
+
*
|
|
108
|
+
* @param method - The CDP method name.
|
|
109
|
+
* @param params - The CDP method parameters.
|
|
110
|
+
* @returns The command result.
|
|
111
|
+
*/
|
|
112
|
+
send(method, params = {}) {
|
|
113
|
+
const id = ++this.messageId;
|
|
114
|
+
return new Promise((resolve, reject) => {
|
|
115
|
+
const timeout = setTimeout(() => {
|
|
116
|
+
this.webSocket.removeEventListener("message", handler);
|
|
117
|
+
reject(new Error(`WebView CDP command timed out after ${String(CDP_COMMAND_TIMEOUT_IN_MILLISECONDS)}ms: ${method}`));
|
|
118
|
+
}, CDP_COMMAND_TIMEOUT_IN_MILLISECONDS);
|
|
119
|
+
const handler = (event) => {
|
|
120
|
+
const message = JSON.parse(String(event.data));
|
|
121
|
+
if (message.id !== id) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
clearTimeout(timeout);
|
|
125
|
+
this.webSocket.removeEventListener("message", handler);
|
|
126
|
+
if (message.error) {
|
|
127
|
+
reject(new Error(`WebView CDP command ${method} failed: ${message.error.message ?? "unknown error"}`));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
resolve(message.result ?? {});
|
|
131
|
+
};
|
|
132
|
+
this.webSocket.addEventListener("message", handler);
|
|
133
|
+
this.webSocket.send(JSON.stringify({ id, method, params }));
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Sends an ordered command sequence, honoring each command's delay.
|
|
138
|
+
*
|
|
139
|
+
* @param commands - The commands to send, in order.
|
|
140
|
+
*/
|
|
141
|
+
async sendAll(commands) {
|
|
142
|
+
for (const command of commands) {
|
|
143
|
+
if (command.delayBeforeInMilliseconds !== void 0) {
|
|
144
|
+
await new Promise((resolve) => {
|
|
145
|
+
setTimeout(resolve, command.delayBeforeInMilliseconds);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
await this.send(command.method, command.params);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Closes the debugger socket and stops routing its events.
|
|
153
|
+
*/
|
|
154
|
+
closeSocket() {
|
|
155
|
+
this.eventHandlers.clear();
|
|
156
|
+
if (this.webSocket.readyState === WebSocket.OPEN) {
|
|
157
|
+
this.webSocket.close();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async function connectToWebViewCdp(params) {
|
|
162
|
+
const { appId, deviceId } = params;
|
|
163
|
+
const pidofOutput = await adb(deviceId, ["shell", "pidof", appId]);
|
|
164
|
+
const pid = pidofOutput.split(/\s+/, 1)[0] ?? "";
|
|
165
|
+
if (!pid) {
|
|
166
|
+
throw new Error(`${appId} is not running on ${deviceId}, so its WebView has no debugger to attach to.`);
|
|
167
|
+
}
|
|
168
|
+
const procNetUnix = await adb(deviceId, ["shell", "cat", "/proc/net/unix"]);
|
|
169
|
+
const socketName = parseWebViewDevtoolsSocketName(procNetUnix, pid);
|
|
170
|
+
const forwardList = await adb(deviceId, ["forward", "--list"]);
|
|
171
|
+
const existingPort = parseForwardedPort(forwardList, deviceId, socketName);
|
|
172
|
+
const port = existingPort ?? await (0, import_obsidian_instance.pickFreePort)();
|
|
173
|
+
if (existingPort === void 0) {
|
|
174
|
+
await adb(deviceId, ["forward", `tcp:${String(port)}`, `localabstract:${socketName}`]);
|
|
175
|
+
(0, import_log.log)(`[webview-cdp] Forwarded tcp:${String(port)} -> localabstract:${socketName} (${appId} pid ${pid})`);
|
|
176
|
+
} else {
|
|
177
|
+
(0, import_log.log)(`[webview-cdp] Reusing forward tcp:${String(port)} -> localabstract:${socketName} (${appId} pid ${pid})`);
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
const response = await fetch(`http://${CDP_HOST}:${String(port)}/json`);
|
|
181
|
+
const target = selectWebViewPageTarget(await response.json());
|
|
182
|
+
const webSocket = new WebSocket(target.webSocketDebuggerUrl ?? "");
|
|
183
|
+
await new Promise((resolve, reject) => {
|
|
184
|
+
webSocket.addEventListener("open", () => {
|
|
185
|
+
resolve();
|
|
186
|
+
}, { once: true });
|
|
187
|
+
webSocket.addEventListener("error", () => {
|
|
188
|
+
reject(new Error(`Could not open the WebView CDP socket at ${target.webSocketDebuggerUrl ?? ""}.`));
|
|
189
|
+
}, { once: true });
|
|
190
|
+
});
|
|
191
|
+
(0, import_log.log)(`[webview-cdp] Attached to WebView target "${target.title ?? ""}"`);
|
|
192
|
+
return new WebViewCdpConnection(webSocket, deviceId, port);
|
|
193
|
+
} catch (error) {
|
|
194
|
+
await removeForward(deviceId, port);
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function parseForwardedPort(forwardList, deviceId, socketName) {
|
|
199
|
+
for (const line of forwardList.split("\n")) {
|
|
200
|
+
const [lineDeviceId, local, remote] = line.trim().split(/\s+/, FORWARD_LIST_COLUMN_COUNT);
|
|
201
|
+
if (lineDeviceId !== deviceId || remote !== `localabstract:${socketName}` || !local?.startsWith("tcp:")) {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const port = Number.parseInt(local.slice("tcp:".length), DECIMAL_RADIX);
|
|
205
|
+
if (Number.isSafeInteger(port)) {
|
|
206
|
+
return port;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return void 0;
|
|
210
|
+
}
|
|
211
|
+
function parseWebViewDevtoolsSocketName(procNetUnix, pid) {
|
|
212
|
+
const names = [
|
|
213
|
+
...new Set([...procNetUnix.matchAll(/@webview_devtools_remote_\w+/g)].map((match) => match[0].slice("@".length)))
|
|
214
|
+
];
|
|
215
|
+
const [soleName, ...otherNames] = names;
|
|
216
|
+
if (soleName === void 0) {
|
|
217
|
+
throw new Error(
|
|
218
|
+
"No `webview_devtools_remote_*` socket on the device. Obsidian Mobile is not running, or its WebView debugger is disabled."
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
const exactName = `webview_devtools_remote_${pid}`;
|
|
222
|
+
if (names.includes(exactName)) {
|
|
223
|
+
return exactName;
|
|
224
|
+
}
|
|
225
|
+
if (otherNames.length === 0) {
|
|
226
|
+
return soleName;
|
|
227
|
+
}
|
|
228
|
+
throw new Error(
|
|
229
|
+
`No \`${exactName}\` socket, and ${String(names.length)} other debuggable WebViews are present (${names.join(", ")}), so the right one cannot be chosen.`
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
function selectWebViewPageTarget(targets) {
|
|
233
|
+
const target = targets.find((candidate) => candidate.type === "page" && Boolean(candidate.webSocketDebuggerUrl)) ?? targets.find((candidate) => Boolean(candidate.webSocketDebuggerUrl));
|
|
234
|
+
if (!target) {
|
|
235
|
+
throw new Error("The WebView debugger listed no target with a WebSocket endpoint.");
|
|
236
|
+
}
|
|
237
|
+
return target;
|
|
238
|
+
}
|
|
239
|
+
async function adb(deviceId, commandArguments) {
|
|
240
|
+
const stdout = await (0, import_exec.exec)(["adb", "-s", deviceId, ...commandArguments], {
|
|
241
|
+
isQuiet: true,
|
|
242
|
+
timeoutInMilliseconds: ADB_TIMEOUT_IN_MILLISECONDS
|
|
243
|
+
});
|
|
244
|
+
return stdout.trim();
|
|
245
|
+
}
|
|
246
|
+
async function removeForward(deviceId, port) {
|
|
247
|
+
try {
|
|
248
|
+
await (0, import_exec.exec)(["adb", "-s", deviceId, "forward", "--remove", `tcp:${String(port)}`], {
|
|
249
|
+
isQuiet: true,
|
|
250
|
+
shouldIgnoreExitCode: true,
|
|
251
|
+
timeoutInMilliseconds: ADB_TIMEOUT_IN_MILLISECONDS
|
|
252
|
+
});
|
|
253
|
+
} catch {
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
257
|
+
0 && (module.exports = {
|
|
258
|
+
WebViewCdpConnection,
|
|
259
|
+
connectToWebViewCdp,
|
|
260
|
+
parseForwardedPort,
|
|
261
|
+
parseWebViewDevtoolsSocketName,
|
|
262
|
+
selectWebViewPageTarget
|
|
263
|
+
});
|
|
264
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3dlYnZpZXctY2RwLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogQSBzZWNvbmQsIGluZGVwZW5kZW50IENocm9tZSBEZXZUb29scyBQcm90b2NvbCBjb25uZWN0aW9uIHRvIE9ic2lkaWFuIE1vYmlsZSdzIFdlYlZpZXcsIHVzZWQgdG8gaW5qZWN0XG4gKiAqKnRydXN0ZWQqKiBpbnB1dCBvbiBBbmRyb2lkIChzZWUgKipMMzkqKikuXG4gKlxuICogSXQgaXMgZGVsaWJlcmF0ZWx5IHNlcGFyYXRlIGZyb20gdGhlIEFwcGl1bSBzZXNzaW9uIHJhdGhlciB0aGFuIGxheWVyZWQgb24gaXQuIGBBcHBpdW1UcmFuc3BvcnQuZXZhbHVhdGVgXG4gKiBydW5zIHRoZSB3aG9sZSBgZXZhbEluT2JzaWRpYW5gIGNsb3N1cmUgaW5zaWRlIG9uZSBXM0MgKkV4ZWN1dGUgU2NyaXB0Kiwgd2hpY2ggYXdhaXRzIHRoZSByZXR1cm5lZFxuICogcHJvbWlzZSBcdTIwMTQgc28gd2hpbGUgYSBjbG9zdXJlIHNpdHMgd2FpdGluZyBvbiBgbGliLmNsaWNrRWxlbWVudCguLi4pYCwgdGhlIFdlYkRyaXZlciBzZXNzaW9uIGlzIGJ1c3kgYW5kXG4gKiBjYW5ub3QgYmUgYXNrZWQgdG8gZG8gYW55dGhpbmcgZWxzZS4gQ0RQIGlzIGlkLW11bHRpcGxleGVkIGFuZCBDaHJvbWl1bSBhY2NlcHRzIG11bHRpcGxlIGRlYnVnZ2VyXG4gKiBjbGllbnRzLCBzbyB0aGlzIHNvY2tldCBzdGF5cyBmcmVlIGV4YWN0bHkgd2hlbiB0aGUgQXBwaXVtIG9uZSBkb2VzIG5vdC4gVGhhdCBpcyB3aGF0IGxldHMgdGhlIHJlbmRlcmVyXG4gKiBjYWxsIGJhY2sgb3V0IHRvIHRoZSBob3N0IG1pZC1jbG9zdXJlLlxuICpcbiAqIFJlYWNoaW5nIHRoZSBXZWJWaWV3J3MgZGVidWdnZXIgaXMgYSB0d28tc3RlcDogdGhlIGFwcCBwdWJsaXNoZXMgYW4gYWJzdHJhY3QgdW5peCBzb2NrZXQgbmFtZWRcbiAqIGB3ZWJ2aWV3X2RldnRvb2xzX3JlbW90ZV88cGlkPmAsIGBhZGIgZm9yd2FyZGAgbWFwcyBpdCB0byBhIGxvY2FsIFRDUCBwb3J0LCBhbmQgdGhlIHVzdWFsIGAvanNvbmBcbiAqIGVuZHBvaW50IHRoZW4gbGlzdHMgdGhlIHBhZ2UgdGFyZ2V0cy5cbiAqL1xuXG5pbXBvcnQgeyBleGVjRmlsZVN5bmMgfSBmcm9tICdub2RlOmNoaWxkX3Byb2Nlc3MnO1xuXG5pbXBvcnQgdHlwZSB7IENkcElucHV0Q29tbWFuZCB9IGZyb20gJy4vbW9iaWxlLWlucHV0LmNqcyc7XG5cbmltcG9ydCB7IGV4ZWMgfSBmcm9tICcuL2V4ZWMuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5pbXBvcnQgeyBwaWNrRnJlZVBvcnQgfSBmcm9tICcuL29ic2lkaWFuLWluc3RhbmNlLmNqcyc7XG5cbmNvbnN0IEFEQl9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDE1XzAwMDtcbi8vIGBhZGIgZm9yd2FyZCAtLWxpc3RgIHByaW50cyB0aHJlZSBjb2x1bW5zOiBgPGRldmljZUlkPiB0Y3A6PHBvcnQ+IGxvY2FsYWJzdHJhY3Q6PHNvY2tldE5hbWU+YC5cbmNvbnN0IEZPUldBUkRfTElTVF9DT0xVTU5fQ09VTlQgPSAzO1xuY29uc3QgREVDSU1BTF9SQURJWCA9IDEwO1xuY29uc3QgQ0RQX0NPTU1BTkRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAzMF8wMDA7XG5jb25zdCBDRFBfSE9TVCA9ICcxMjcuMC4wLjEnO1xuXG4vKipcbiAqIE9uZSBlbnRyeSBvZiB0aGUgZGVidWdnZXIncyBgL2pzb25gIHRhcmdldCBsaXN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENkcFRhcmdldCB7XG4gIHJlYWRvbmx5IHRpdGxlPzogc3RyaW5nO1xuICByZWFkb25seSB0eXBlPzogc3RyaW5nO1xuICByZWFkb25seSB1cmw/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHdlYlNvY2tldERlYnVnZ2VyVXJsPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBjb25uZWN0VG9XZWJWaWV3Q2RwfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb25uZWN0VG9XZWJWaWV3Q2RwUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBBbmRyb2lkIGFwcGxpY2F0aW9uIGlkIHdob3NlIFdlYlZpZXcgdG8gYXR0YWNoIHRvLCBlLmcuIGBtZC5vYnNpZGlhbmAuXG4gICAqL1xuICByZWFkb25seSBhcHBJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYWRiIGRldmljZSBpZCAoYGVtdWxhdG9yLTU1NTRgLCBhIHNlcmlhbCkgdG8gcnVuIGFkYiBhZ2FpbnN0LlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgZXJyb3IgaGFsZiBvZiBhIGZhaWxlZCBDRFAgY29tbWFuZCByZXNwb25zZS5cbiAqL1xuaW50ZXJmYWNlIENkcEVycm9yIHtcbiAgcmVhZG9ubHkgbWVzc2FnZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBIYW5kbGVzIGEgQ0RQIGV2ZW50LlxuICovXG50eXBlIENkcEV2ZW50SGFuZGxlciA9IChwYXJhbXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiB2b2lkO1xuXG4vKipcbiAqIEEgQ0RQIG1lc3NhZ2U6IGVpdGhlciBhIHJlc3BvbnNlIHRvIGEgY29tbWFuZCAoYGlkYCkgb3IgYW4gZXZlbnQgKGBtZXRob2RgKS5cbiAqL1xuaW50ZXJmYWNlIENkcE1lc3NhZ2Uge1xuICByZWFkb25seSBlcnJvcj86IENkcEVycm9yO1xuICByZWFkb25seSBpZD86IG51bWJlcjtcbiAgcmVhZG9ubHkgbWV0aG9kPzogc3RyaW5nO1xuICByZWFkb25seSBwYXJhbXM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgcmVhZG9ubHkgcmVzdWx0PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIGNvZGUgKGEgbGl2ZSBXZWJTb2NrZXQgdG8gYSBXZWJWaWV3LCBhZGIgcG9ydCBmb3J3YXJkaW5nKS4gQ292ZXJlZCBieSB0aGUgQW5kcm9pZCBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IGJ5IHVuaXQgdGVzdHMuIEl0IGVuZHMgYmVmb3JlIGBwYXJzZUZvcndhcmRlZFBvcnRgOiBgcGVyZmVjdGlvbmlzdC9zb3J0LW1vZHVsZXNgIHBsYWNlcyB0aGUgcHVyZSwgdW5pdC10ZXN0ZWQgaGVscGVycyBBRlRFUiB0aGlzIGNsYXNzIGFuZCBgY29ubmVjdFRvV2ViVmlld0NkcGAsIHNvIHRoZXkgbXVzdCBzdGF5IG1lYXN1cmVkLiAqL1xuXG4vKipcbiAqIEFuIG9wZW4gQ0RQIGNvbm5lY3Rpb24gdG8gYSBXZWJWaWV3LlxuICpcbiAqIENvbW1hbmRzIGFyZSBpZC1tdWx0aXBsZXhlZCwgc28gYSBjb21tYW5kIGlzc3VlZCBmcm9tIGluc2lkZSBhbiBldmVudCBoYW5kbGVyIGNvbXBsZXRlcyB3aGlsZSBhbiBlYXJsaWVyXG4gKiBgUnVudGltZS5ldmFsdWF0ZWAgaXMgc3RpbGwgYXdhaXRpbmcgaXRzIHByb21pc2UgXHUyMDE0IHdoaWNoIGlzIHRoZSB3aG9sZSByZWFzb24gdGhpcyBjbGFzcyBleGlzdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBXZWJWaWV3Q2RwQ29ubmVjdGlvbiB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBzb2NrZXQgaXMgc3RpbGwgdXNhYmxlLlxuICAgKlxuICAgKiBSZXN0YXJ0aW5nIHRoZSBhcHAgdGVhcnMgaXRzIFdlYlZpZXcgZG93biBhbmQgdGFrZXMgdGhlIGRlYnVnZ2VyIHRhcmdldCB3aXRoIGl0LCBzbyBhIGNhY2hlZFxuICAgKiBjb25uZWN0aW9uIGhhcyB0byBiZSByZS1jaGVja2VkIHJhdGhlciB0aGFuIGFzc3VtZWQgbGl2ZS5cbiAgICpcbiAgICogQHJldHVybnMgYHRydWVgIHdoaWxlIHRoZSBzb2NrZXQgaXMgb3Blbi5cbiAgICovXG4gIHB1YmxpYyBnZXQgaXNPcGVuKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLndlYlNvY2tldC5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuT1BFTjtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgZXZlbnRIYW5kbGVycyA9IG5ldyBNYXA8c3RyaW5nLCBDZHBFdmVudEhhbmRsZXI+KCk7XG5cbiAgcHJpdmF0ZSBtZXNzYWdlSWQgPSAwO1xuXG4gIC8qKlxuICAgKiBXcmFwcyBhbiBhbHJlYWR5LW9wZW4gZGVidWdnZXIgc29ja2V0LCBwbHVzIHdoYXQgaXMgbmVlZGVkIHRvIHRlYXIgaXRzIHBvcnQgZm9yd2FyZCBkb3duLlxuICAgKlxuICAgKiBAcGFyYW0gd2ViU29ja2V0IC0gVGhlIG9wZW4gZGVidWdnZXIgc29ja2V0LlxuICAgKiBAcGFyYW0gZGV2aWNlSWQgLSBUaGUgYWRiIGRldmljZSBpZCwgbmVlZGVkIHRvIGRyb3AgdGhlIHBvcnQgZm9yd2FyZCBvbiBkaXNwb3NlLlxuICAgKiBAcGFyYW0gcG9ydCAtIFRoZSBmb3J3YXJkZWQgbG9jYWwgcG9ydC5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHdlYlNvY2tldDogV2ViU29ja2V0LCBwcml2YXRlIHJlYWRvbmx5IGRldmljZUlkOiBzdHJpbmcsIHByaXZhdGUgcmVhZG9ubHkgcG9ydDogbnVtYmVyKSB7XG4gICAgdGhpcy53ZWJTb2NrZXQuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIChldmVudDogTWVzc2FnZUV2ZW50KSA9PiB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gSlNPTi5wYXJzZShTdHJpbmcoZXZlbnQuZGF0YSkpIGFzIENkcE1lc3NhZ2U7XG4gICAgICBpZiAobWVzc2FnZS5tZXRob2QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZXZlbnRIYW5kbGVycy5nZXQobWVzc2FnZS5tZXRob2QpPy4obWVzc2FnZS5wYXJhbXMgPz8ge30pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlcyB0aGUgc29ja2V0IGFuZCBkcm9wcyB0aGUgYWRiIHBvcnQgZm9yd2FyZC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuY2xvc2VTb2NrZXQoKTtcbiAgICBhd2FpdCByZW1vdmVGb3J3YXJkKHRoaXMuZGV2aWNlSWQsIHRoaXMucG9ydCk7XG4gIH1cblxuICAvKipcbiAgICogU3luY2hyb25vdXMgZGlzcG9zYWwsIGZvciBgcHJvY2Vzcy5vbignZXhpdCcpYCBoYW5kbGVycyB3aGVyZSBhc3luYyB3b3JrIGNhbm5vdCBydW4uXG4gICAqXG4gICAqIFdpdGhvdXQgdGhpcyBhbiBhYnJ1cHQgd29ya2VyIGV4aXQgbGVhdmVzIHRoZSBwb3J0IGZvcndhcmQgYmVoaW5kIFx1MjAxNCB0aGUgYXN5bmMge0BsaW5rIGRpc3Bvc2V9IGFib3ZlXG4gICAqIG5ldmVyIGdldHMgYSB0dXJuLlxuICAgKi9cbiAgcHVibGljIGRpc3Bvc2VTeW5jKCk6IHZvaWQge1xuICAgIHRoaXMuY2xvc2VTb2NrZXQoKTtcbiAgICB0cnkge1xuICAgICAgZXhlY0ZpbGVTeW5jKCdhZGInLCBbJy1zJywgdGhpcy5kZXZpY2VJZCwgJ2ZvcndhcmQnLCAnLS1yZW1vdmUnLCBgdGNwOiR7U3RyaW5nKHRoaXMucG9ydCl9YF0sIHtcbiAgICAgICAgc3RkaW86ICdpZ25vcmUnLFxuICAgICAgICB0aW1lb3V0OiBBREJfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFNcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gQmVzdCBlZmZvcnQ6IGFkYiBkcm9wcyBldmVyeSBmb3J3YXJkIHdoZW4gdGhlIGRldmljZSBkaXNjb25uZWN0cyBhbnl3YXkuXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN1YnNjcmliZXMgdG8gYSBDRFAgZXZlbnQuIE9uZSBoYW5kbGVyIHBlciBtZXRob2Q7IHN1YnNjcmliaW5nIGFnYWluIHJlcGxhY2VzIGl0LlxuICAgKlxuICAgKiBAcGFyYW0gbWV0aG9kIC0gVGhlIENEUCBldmVudCBuYW1lLCBlLmcuIGBSdW50aW1lLmJpbmRpbmdDYWxsZWRgLlxuICAgKiBAcGFyYW0gaGFuZGxlciAtIENhbGxlZCB3aXRoIHRoZSBldmVudCBwYXJhbWV0ZXJzLlxuICAgKi9cbiAgcHVibGljIG9uKG1ldGhvZDogc3RyaW5nLCBoYW5kbGVyOiBDZHBFdmVudEhhbmRsZXIpOiB2b2lkIHtcbiAgICB0aGlzLmV2ZW50SGFuZGxlcnMuc2V0KG1ldGhvZCwgaGFuZGxlcik7XG4gIH1cblxuICAvKipcbiAgICogU2VuZHMgYSBDRFAgY29tbWFuZCBhbmQgd2FpdHMgZm9yIGl0cyByZXNwb25zZS5cbiAgICpcbiAgICogQHBhcmFtIG1ldGhvZCAtIFRoZSBDRFAgbWV0aG9kIG5hbWUuXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgQ0RQIG1ldGhvZCBwYXJhbWV0ZXJzLlxuICAgKiBAcmV0dXJucyBUaGUgY29tbWFuZCByZXN1bHQuXG4gICAqL1xuICBwdWJsaWMgc2VuZChtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9KTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ge1xuICAgIGNvbnN0IGlkID0gKyt0aGlzLm1lc3NhZ2VJZDtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLndlYlNvY2tldC5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgaGFuZGxlcik7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoYFdlYlZpZXcgQ0RQIGNvbW1hbmQgdGltZWQgb3V0IGFmdGVyICR7U3RyaW5nKENEUF9DT01NQU5EX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tczogJHttZXRob2R9YCkpO1xuICAgICAgfSwgQ0RQX0NPTU1BTkRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMpO1xuXG4gICAgICBjb25zdCBoYW5kbGVyID0gKGV2ZW50OiBNZXNzYWdlRXZlbnQpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IEpTT04ucGFyc2UoU3RyaW5nKGV2ZW50LmRhdGEpKSBhcyBDZHBNZXNzYWdlO1xuICAgICAgICBpZiAobWVzc2FnZS5pZCAhPT0gaWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIHRoaXMud2ViU29ja2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBoYW5kbGVyKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZXJyb3IpIHtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBXZWJWaWV3IENEUCBjb21tYW5kICR7bWV0aG9kfSBmYWlsZWQ6ICR7bWVzc2FnZS5lcnJvci5tZXNzYWdlID8/ICd1bmtub3duIGVycm9yJ31gKSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzb2x2ZShtZXNzYWdlLnJlc3VsdCA/PyB7fSk7XG4gICAgICB9O1xuXG4gICAgICB0aGlzLndlYlNvY2tldC5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgaGFuZGxlcik7XG4gICAgICB0aGlzLndlYlNvY2tldC5zZW5kKEpTT04uc3RyaW5naWZ5KHsgaWQsIG1ldGhvZCwgcGFyYW1zIH0pKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kcyBhbiBvcmRlcmVkIGNvbW1hbmQgc2VxdWVuY2UsIGhvbm9yaW5nIGVhY2ggY29tbWFuZCdzIGRlbGF5LlxuICAgKlxuICAgKiBAcGFyYW0gY29tbWFuZHMgLSBUaGUgY29tbWFuZHMgdG8gc2VuZCwgaW4gb3JkZXIuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc2VuZEFsbChjb21tYW5kczogcmVhZG9ubHkgQ2RwSW5wdXRDb21tYW5kW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGNvbnN0IGNvbW1hbmQgb2YgY29tbWFuZHMpIHtcbiAgICAgIGlmIChjb21tYW5kLmRlbGF5QmVmb3JlSW5NaWxsaXNlY29uZHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgY29tbWFuZC5kZWxheUJlZm9yZUluTWlsbGlzZWNvbmRzKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMuc2VuZChjb21tYW5kLm1ldGhvZCwgY29tbWFuZC5wYXJhbXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgdGhlIGRlYnVnZ2VyIHNvY2tldCBhbmQgc3RvcHMgcm91dGluZyBpdHMgZXZlbnRzLlxuICAgKi9cbiAgcHJpdmF0ZSBjbG9zZVNvY2tldCgpOiB2b2lkIHtcbiAgICB0aGlzLmV2ZW50SGFuZGxlcnMuY2xlYXIoKTtcbiAgICBpZiAodGhpcy53ZWJTb2NrZXQucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0Lk9QRU4pIHtcbiAgICAgIHRoaXMud2ViU29ja2V0LmNsb3NlKCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogT3BlbnMgYSBDRFAgY29ubmVjdGlvbiB0byB0aGUgYXBwJ3MgV2ViVmlldy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gV2hpY2ggYXBwIG9uIHdoaWNoIGRldmljZS5cbiAqIEByZXR1cm5zIFRoZSBvcGVuIGNvbm5lY3Rpb24uIERpc3Bvc2UgaXQgdG8gY2xvc2UgdGhlIHNvY2tldCBhbmQgZHJvcCB0aGUgYWRiIHBvcnQgZm9yd2FyZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvbm5lY3RUb1dlYlZpZXdDZHAocGFyYW1zOiBDb25uZWN0VG9XZWJWaWV3Q2RwUGFyYW1zKTogUHJvbWlzZTxXZWJWaWV3Q2RwQ29ubmVjdGlvbj4ge1xuICBjb25zdCB7IGFwcElkLCBkZXZpY2VJZCB9ID0gcGFyYW1zO1xuXG4gIC8vIGBwaWRvZmAgbGlzdHMgZXZlcnkgbWF0Y2hpbmcgcHJvY2VzczsgdGhlIGFwcCdzIG1haW4gb25lIGlzIGZpcnN0LlxuICBjb25zdCBwaWRvZk91dHB1dCA9IGF3YWl0IGFkYihkZXZpY2VJZCwgWydzaGVsbCcsICdwaWRvZicsIGFwcElkXSk7XG4gIGNvbnN0IHBpZCA9IHBpZG9mT3V0cHV0LnNwbGl0KC9cXHMrLywgMSlbMF0gPz8gJyc7XG4gIGlmICghcGlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke2FwcElkfSBpcyBub3QgcnVubmluZyBvbiAke2RldmljZUlkfSwgc28gaXRzIFdlYlZpZXcgaGFzIG5vIGRlYnVnZ2VyIHRvIGF0dGFjaCB0by5gKTtcbiAgfVxuXG4gIGNvbnN0IHByb2NOZXRVbml4ID0gYXdhaXQgYWRiKGRldmljZUlkLCBbJ3NoZWxsJywgJ2NhdCcsICcvcHJvYy9uZXQvdW5peCddKTtcbiAgY29uc3Qgc29ja2V0TmFtZSA9IHBhcnNlV2ViVmlld0RldnRvb2xzU29ja2V0TmFtZShwcm9jTmV0VW5peCwgcGlkKTtcblxuICBjb25zdCBmb3J3YXJkTGlzdCA9IGF3YWl0IGFkYihkZXZpY2VJZCwgWydmb3J3YXJkJywgJy0tbGlzdCddKTtcbiAgY29uc3QgZXhpc3RpbmdQb3J0ID0gcGFyc2VGb3J3YXJkZWRQb3J0KGZvcndhcmRMaXN0LCBkZXZpY2VJZCwgc29ja2V0TmFtZSk7XG4gIGNvbnN0IHBvcnQgPSBleGlzdGluZ1BvcnQgPz8gYXdhaXQgcGlja0ZyZWVQb3J0KCk7XG4gIGlmIChleGlzdGluZ1BvcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIGF3YWl0IGFkYihkZXZpY2VJZCwgWydmb3J3YXJkJywgYHRjcDoke1N0cmluZyhwb3J0KX1gLCBgbG9jYWxhYnN0cmFjdDoke3NvY2tldE5hbWV9YF0pO1xuICAgIGxvZyhgW3dlYnZpZXctY2RwXSBGb3J3YXJkZWQgdGNwOiR7U3RyaW5nKHBvcnQpfSAtPiBsb2NhbGFic3RyYWN0OiR7c29ja2V0TmFtZX0gKCR7YXBwSWR9IHBpZCAke3BpZH0pYCk7XG4gIH0gZWxzZSB7XG4gICAgbG9nKGBbd2Vidmlldy1jZHBdIFJldXNpbmcgZm9yd2FyZCB0Y3A6JHtTdHJpbmcocG9ydCl9IC0+IGxvY2FsYWJzdHJhY3Q6JHtzb2NrZXROYW1lfSAoJHthcHBJZH0gcGlkICR7cGlkfSlgKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgaHR0cDovLyR7Q0RQX0hPU1R9OiR7U3RyaW5nKHBvcnQpfS9qc29uYCk7XG4gICAgY29uc3QgdGFyZ2V0ID0gc2VsZWN0V2ViVmlld1BhZ2VUYXJnZXQoYXdhaXQgcmVzcG9uc2UuanNvbigpIGFzIENkcFRhcmdldFtdKTtcbiAgICBjb25zdCB3ZWJTb2NrZXQgPSBuZXcgV2ViU29ja2V0KHRhcmdldC53ZWJTb2NrZXREZWJ1Z2dlclVybCA/PyAnJyk7XG4gICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgd2ViU29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoJ29wZW4nLCAoKSA9PiB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0sIHsgb25jZTogdHJ1ZSB9KTtcbiAgICAgIHdlYlNvY2tldC5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsICgpID0+IHtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgQ291bGQgbm90IG9wZW4gdGhlIFdlYlZpZXcgQ0RQIHNvY2tldCBhdCAke3RhcmdldC53ZWJTb2NrZXREZWJ1Z2dlclVybCA/PyAnJ30uYCkpO1xuICAgICAgfSwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIH0pO1xuICAgIGxvZyhgW3dlYnZpZXctY2RwXSBBdHRhY2hlZCB0byBXZWJWaWV3IHRhcmdldCBcIiR7dGFyZ2V0LnRpdGxlID8/ICcnfVwiYCk7XG5cbiAgICByZXR1cm4gbmV3IFdlYlZpZXdDZHBDb25uZWN0aW9uKHdlYlNvY2tldCwgZGV2aWNlSWQsIHBvcnQpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGF3YWl0IHJlbW92ZUZvcndhcmQoZGV2aWNlSWQsIHBvcnQpO1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbi8qIHY4IGlnbm9yZSBzdG9wICovXG5cbi8qKlxuICogRmluZHMgYSBwb3J0IGFscmVhZHkgZm9yd2FyZGVkIHRvIHRoaXMgZGV2aWNlIHNvY2tldCwgc28gcmVwZWF0ZWQgcnVucyByZXVzZSBvbmUgZm9yd2FyZC5cbiAqXG4gKiBXaXRob3V0IHRoaXMgZXZlcnkgcnVuIGFsbG9jYXRlcyBhIGZyZXNoIHBvcnQsIGFuZCBhbnkgcnVuIHRoYXQgZXhpdHMgd2l0aG91dCB0aGUgYXN5bmNcbiAqIHtAbGluayBXZWJWaWV3Q2RwQ29ubmVjdGlvbi5kaXNwb3NlfSBcdTIwMTQgYW4gYWJydXB0IHdvcmtlciBleGl0LCB3aGVyZSBvbmx5IHRoZSBzeW5jaHJvbm91cyB0ZWFyZG93blxuICogcGF0aCBydW5zIFx1MjAxNCBsZWF2ZXMgaXRzIGZvcndhcmQgYmVoaW5kIGZvcmV2ZXIuIFJldXNlIGJvdW5kcyB0aGF0IHRvIGEgc2luZ2xlIGZvcndhcmQgcGVyIHNvY2tldFxuICogcmF0aGVyIHRoYW4gb25lIHBlciBydW4uXG4gKlxuICogQHBhcmFtIGZvcndhcmRMaXN0IC0gVGhlIG91dHB1dCBvZiBgYWRiIGZvcndhcmQgLS1saXN0YC5cbiAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBhZGIgZGV2aWNlIGlkIHRvIG1hdGNoLlxuICogQHBhcmFtIHNvY2tldE5hbWUgLSBUaGUgYWJzdHJhY3Qgc29ja2V0IG5hbWUgdG8gbWF0Y2guXG4gKiBAcmV0dXJucyBUaGUgYWxyZWFkeS1mb3J3YXJkZWQgbG9jYWwgcG9ydCwgb3IgYHVuZGVmaW5lZGAgd2hlbiB0aGVyZSBpcyBub25lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VGb3J3YXJkZWRQb3J0KGZvcndhcmRMaXN0OiBzdHJpbmcsIGRldmljZUlkOiBzdHJpbmcsIHNvY2tldE5hbWU6IHN0cmluZyk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGZvciAoY29uc3QgbGluZSBvZiBmb3J3YXJkTGlzdC5zcGxpdCgnXFxuJykpIHtcbiAgICAvLyBgYWRiIGZvcndhcmQgLS1saXN0YCBwcmludHMgYDxkZXZpY2VJZD4gdGNwOjxwb3J0PiBsb2NhbGFic3RyYWN0Ojxzb2NrZXROYW1lPmAuXG4gICAgY29uc3QgW2xpbmVEZXZpY2VJZCwgbG9jYWwsIHJlbW90ZV0gPSBsaW5lLnRyaW0oKS5zcGxpdCgvXFxzKy8sIEZPUldBUkRfTElTVF9DT0xVTU5fQ09VTlQpO1xuICAgIGlmIChsaW5lRGV2aWNlSWQgIT09IGRldmljZUlkIHx8IHJlbW90ZSAhPT0gYGxvY2FsYWJzdHJhY3Q6JHtzb2NrZXROYW1lfWAgfHwgIWxvY2FsPy5zdGFydHNXaXRoKCd0Y3A6JykpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHBvcnQgPSBOdW1iZXIucGFyc2VJbnQobG9jYWwuc2xpY2UoJ3RjcDonLmxlbmd0aCksIERFQ0lNQUxfUkFESVgpO1xuICAgIGlmIChOdW1iZXIuaXNTYWZlSW50ZWdlcihwb3J0KSkge1xuICAgICAgcmV0dXJuIHBvcnQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBQaWNrcyB0aGUgV2ViVmlldydzIGRldnRvb2xzIHNvY2tldCBuYW1lIG91dCBvZiBgL3Byb2MvbmV0L3VuaXhgLlxuICpcbiAqIEEgZGV2aWNlIGNhbiBob3N0IHNldmVyYWwgZGVidWdnYWJsZSBXZWJWaWV3cyAob3RoZXIgYXBwcywgYSBsZWZ0b3ZlciBwcm9jZXNzKSwgc28gdGhlIGFwcCdzIG93biBwaWQgaXNcbiAqIHdoYXQgZGlzYW1iaWd1YXRlcyB0aGVtLiBXaGVuIG5vIHNvY2tldCBtYXRjaGVzIHRoYXQgcGlkIHRoZSBzb2xlIHJlbWFpbmluZyBjYW5kaWRhdGUgaXMgdXNlZCBcdTIwMTQgYVxuICogV2ViVmlldyB3aG9zZSBzb2NrZXQgaXMgbmFtZWQgYWZ0ZXIgYSBjaGlsZCBwcm9jZXNzIHJhdGhlciB0aGFuIHRoZSBvbmUgYHBpZG9mYCByZXBvcnRlZCBzdGlsbCBoYXMgdG8gYmVcbiAqIHJlYWNoYWJsZSBcdTIwMTQgYnV0IHR3byB1bmF0dHJpYnV0YWJsZSBjYW5kaWRhdGVzIGlzIGFtYmlndW91cyBlbm91Z2ggdG8gcmVmdXNlLlxuICpcbiAqIEBwYXJhbSBwcm9jTmV0VW5peCAtIFRoZSBjb250ZW50cyBvZiBgL3Byb2MvbmV0L3VuaXhgLlxuICogQHBhcmFtIHBpZCAtIFRoZSBhcHBsaWNhdGlvbidzIHByb2Nlc3MgaWQuXG4gKiBAcmV0dXJucyBUaGUgc29ja2V0IG5hbWUsIGUuZy4gYHdlYnZpZXdfZGV2dG9vbHNfcmVtb3RlXzE4MDU2YC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlV2ViVmlld0RldnRvb2xzU29ja2V0TmFtZShwcm9jTmV0VW5peDogc3RyaW5nLCBwaWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vIFRoZSB3aG9sZSBtYXRjaCBtaW51cyBpdHMgbGVhZGluZyBgQGAsIHJhdGhlciB0aGFuIGEgbmFtZWQgY2FwdHVyZSBncm91cDogYSBtYW5kYXRvcnkgZ3JvdXAgaXMgYWx3YXlzXG4gIC8vIFByZXNlbnQgb25jZSB0aGUgcGF0dGVybiBoYXMgbWF0Y2hlZCwgc28gYG1hdGNoLmdyb3Vwcz8uWyduYW1lJ10gPz8gJydgIHdvdWxkIGxlYXZlIGJlaGluZCB0d28gYnJhbmNoZXNcbiAgLy8gTm8gaW5wdXQgY2FuIGV2ZXIgcmVhY2ggXHUyMDE0IGFuZCB0aGlzIGZpbGUgaXMgbWVhc3VyZWQgYWdhaW5zdCBhIDEwMCUgYnJhbmNoIGdhdGUuXG4gIGNvbnN0IG5hbWVzID0gW1xuICAgIC4uLm5ldyBTZXQoWy4uLnByb2NOZXRVbml4Lm1hdGNoQWxsKC9Ad2Vidmlld19kZXZ0b29sc19yZW1vdGVfXFx3Ky9nKV1cbiAgICAgIC5tYXAoKG1hdGNoKSA9PiBtYXRjaFswXS5zbGljZSgnQCcubGVuZ3RoKSkpXG4gIF07XG5cbiAgLy8gRGVzdHJ1Y3R1cmVkIHJhdGhlciB0aGFuIGluZGV4ZWQgZm9yIHRoZSBzYW1lIHJlYXNvbjogYHNvbGVOYW1lYCBjYXJyaWVzIHRoZSBcInRoZXJlIGlzIGF0IGxlYXN0IG9uZVwiXG4gIC8vIEZhY3QgaW4gdGhlIHR5cGUsIHNvIG5laXRoZXIgdGhlIGVtcHR5IGNoZWNrIGJlbG93IG5vciB0aGUgc2luZ2xlLWNhbmRpZGF0ZSBvbmUgbGVhdmVzIGEgZGVhZCBicmFuY2guXG4gIGNvbnN0IFtzb2xlTmFtZSwgLi4ub3RoZXJOYW1lc10gPSBuYW1lcztcblxuICBpZiAoc29sZU5hbWUgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdObyBgd2Vidmlld19kZXZ0b29sc19yZW1vdGVfKmAgc29ja2V0IG9uIHRoZSBkZXZpY2UuIE9ic2lkaWFuIE1vYmlsZSBpcyBub3QgcnVubmluZywgb3IgaXRzIFdlYlZpZXcgJ1xuICAgICAgICArICdkZWJ1Z2dlciBpcyBkaXNhYmxlZC4nXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IGV4YWN0TmFtZSA9IGB3ZWJ2aWV3X2RldnRvb2xzX3JlbW90ZV8ke3BpZH1gO1xuICBpZiAobmFtZXMuaW5jbHVkZXMoZXhhY3ROYW1lKSkge1xuICAgIHJldHVybiBleGFjdE5hbWU7XG4gIH1cblxuICBpZiAob3RoZXJOYW1lcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gc29sZU5hbWU7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgYE5vIFxcYCR7ZXhhY3ROYW1lfVxcYCBzb2NrZXQsIGFuZCAke1N0cmluZyhuYW1lcy5sZW5ndGgpfSBvdGhlciBkZWJ1Z2dhYmxlIFdlYlZpZXdzIGFyZSBwcmVzZW50IGBcbiAgICAgICsgYCgke25hbWVzLmpvaW4oJywgJyl9KSwgc28gdGhlIHJpZ2h0IG9uZSBjYW5ub3QgYmUgY2hvc2VuLmBcbiAgKTtcbn1cblxuLyoqXG4gKiBQaWNrcyB0aGUgT2JzaWRpYW4gcGFnZSB0YXJnZXQgb3V0IG9mIHRoZSBkZWJ1Z2dlcidzIGAvanNvbmAgbGlzdC5cbiAqXG4gKiBAcGFyYW0gdGFyZ2V0cyAtIFRoZSBgL2pzb25gIHJlc3BvbnNlLlxuICogQHJldHVybnMgVGhlIHBhZ2UgdGFyZ2V0IHRvIGF0dGFjaCB0by5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdFdlYlZpZXdQYWdlVGFyZ2V0KHRhcmdldHM6IHJlYWRvbmx5IENkcFRhcmdldFtdKTogQ2RwVGFyZ2V0IHtcbiAgY29uc3QgdGFyZ2V0ID0gdGFyZ2V0cy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS50eXBlID09PSAncGFnZScgJiYgQm9vbGVhbihjYW5kaWRhdGUud2ViU29ja2V0RGVidWdnZXJVcmwpKVxuICAgID8/IHRhcmdldHMuZmluZCgoY2FuZGlkYXRlKSA9PiBCb29sZWFuKGNhbmRpZGF0ZS53ZWJTb2NrZXREZWJ1Z2dlclVybCkpO1xuXG4gIGlmICghdGFyZ2V0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgV2ViVmlldyBkZWJ1Z2dlciBsaXN0ZWQgbm8gdGFyZ2V0IHdpdGggYSBXZWJTb2NrZXQgZW5kcG9pbnQuJyk7XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG4vKiB2OCBpZ25vcmUgc3RhcnQgLS0gSW50ZWdyYXRpb24tdGltZSBjb2RlIChhZGIgc2hlbGwtb3V0cykuIENvdmVyZWQgYnkgdGhlIEFuZHJvaWQgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCBieSB1bml0IHRlc3RzLiAqL1xuXG4vKipcbiAqIFJ1bnMgYW4gYWRiIGNvbW1hbmQgYWdhaW5zdCBvbmUgZGV2aWNlLlxuICpcbiAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBhZGIgZGV2aWNlIGlkLlxuICogQHBhcmFtIGNvbW1hbmRBcmd1bWVudHMgLSBUaGUgYWRiIGFyZ3VtZW50cyBhZnRlciBgLXMgPGRldmljZUlkPmAuXG4gKiBAcmV0dXJucyBUcmltbWVkIHN0ZG91dC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gYWRiKGRldmljZUlkOiBzdHJpbmcsIGNvbW1hbmRBcmd1bWVudHM6IHN0cmluZ1tdKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIGRldmljZUlkLCAuLi5jb21tYW5kQXJndW1lbnRzXSwge1xuICAgIGlzUXVpZXQ6IHRydWUsXG4gICAgdGltZW91dEluTWlsbGlzZWNvbmRzOiBBREJfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFNcbiAgfSk7XG5cbiAgcmV0dXJuIHN0ZG91dC50cmltKCk7XG59XG5cbi8qKlxuICogRHJvcHMgYW4gYWRiIHBvcnQgZm9yd2FyZCwgaWdub3JpbmcgdGhlIFwibm90IGZvdW5kXCIgY2FzZS5cbiAqXG4gKiBAcGFyYW0gZGV2aWNlSWQgLSBUaGUgYWRiIGRldmljZSBpZC5cbiAqIEBwYXJhbSBwb3J0IC0gVGhlIGZvcndhcmRlZCBsb2NhbCBwb3J0LlxuICovXG5hc3luYyBmdW5jdGlvbiByZW1vdmVGb3J3YXJkKGRldmljZUlkOiBzdHJpbmcsIHBvcnQ6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICB0cnkge1xuICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCBkZXZpY2VJZCwgJ2ZvcndhcmQnLCAnLS1yZW1vdmUnLCBgdGNwOiR7U3RyaW5nKHBvcnQpfWBdLCB7XG4gICAgICBpc1F1aWV0OiB0cnVlLFxuICAgICAgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsXG4gICAgICB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IEFEQl9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICAgIH0pO1xuICB9IGNhdGNoIHtcbiAgICAvLyBCZXN0IGVmZm9ydDogdGhlIGZvcndhcmQgaXMgcGVyLXJ1biBhbmQgYWRiIGRyb3BzIGl0IHdoZW4gdGhlIGRldmljZSBkaXNjb25uZWN0cyBhbnl3YXkuXG4gIH1cbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWtCQSxnQ0FBNkI7QUFJN0Isa0JBQXFCO0FBQ3JCLGlCQUFvQjtBQUNwQiwrQkFBNkI7QUFFN0IsTUFBTSw4QkFBOEI7QUFFcEMsTUFBTSw0QkFBNEI7QUFDbEMsTUFBTSxnQkFBZ0I7QUFDdEIsTUFBTSxzQ0FBc0M7QUFDNUMsTUFBTSxXQUFXO0FBMERWLE1BQU0scUJBQXFCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQXdCekIsWUFBNkIsV0FBdUMsVUFBbUMsTUFBYztBQUF4RjtBQUF1QztBQUFtQztBQUM1RyxTQUFLLFVBQVUsaUJBQWlCLFdBQVcsQ0FBQyxVQUF3QjtBQUNsRSxZQUFNLFVBQVUsS0FBSyxNQUFNLE9BQU8sTUFBTSxJQUFJLENBQUM7QUFDN0MsVUFBSSxRQUFRLFdBQVcsUUFBVztBQUNoQztBQUFBLE1BQ0Y7QUFFQSxXQUFLLGNBQWMsSUFBSSxRQUFRLE1BQU0sSUFBSSxRQUFRLFVBQVUsQ0FBQyxDQUFDO0FBQUEsSUFDL0QsQ0FBQztBQUFBLEVBQ0g7QUFBQSxFQVRvQztBQUFBLEVBQXVDO0FBQUEsRUFBbUM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFmOUcsSUFBVyxTQUFrQjtBQUMzQixXQUFPLEtBQUssVUFBVSxlQUFlLFVBQVU7QUFBQSxFQUNqRDtBQUFBLEVBRWlCLGdCQUFnQixvQkFBSSxJQUE2QjtBQUFBLEVBRTFELFlBQVk7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQXVCcEIsTUFBYSxVQUF5QjtBQUNwQyxTQUFLLFlB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
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
3
|
+
*
|
|
4
|
+
* A second, independent Chrome DevTools Protocol connection to Obsidian Mobile's WebView, used to inject
|
|
5
|
+
* **trusted** input on Android (see **L39**).
|
|
6
|
+
*
|
|
7
|
+
* It is deliberately separate from the Appium session rather than layered on it. `AppiumTransport.evaluate`
|
|
8
|
+
* runs the whole `evalInObsidian` closure inside one W3C *Execute Script*, which awaits the returned
|
|
9
|
+
* promise — so while a closure sits waiting on `lib.clickElement(...)`, the WebDriver session is busy and
|
|
10
|
+
* cannot be asked to do anything else. CDP is id-multiplexed and Chromium accepts multiple debugger
|
|
11
|
+
* clients, so this socket stays free exactly when the Appium one does not. That is what lets the renderer
|
|
12
|
+
* call back out to the host mid-closure.
|
|
13
|
+
*
|
|
14
|
+
* Reaching the WebView's debugger is a two-step: the app publishes an abstract unix socket named
|
|
15
|
+
* `webview_devtools_remote_<pid>`, `adb forward` maps it to a local TCP port, and the usual `/json`
|
|
16
|
+
* endpoint then lists the page targets.
|
|
17
|
+
*/
|
|
18
|
+
import type { CdpInputCommand } from './mobile-input.cjs';
|
|
19
|
+
/**
|
|
20
|
+
* One entry of the debugger's `/json` target list.
|
|
21
|
+
*/
|
|
22
|
+
export interface CdpTarget {
|
|
23
|
+
readonly title?: string;
|
|
24
|
+
readonly type?: string;
|
|
25
|
+
readonly url?: string;
|
|
26
|
+
readonly webSocketDebuggerUrl?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parameters for {@link connectToWebViewCdp}.
|
|
30
|
+
*/
|
|
31
|
+
export interface ConnectToWebViewCdpParams {
|
|
32
|
+
/**
|
|
33
|
+
* The Android application id whose WebView to attach to, e.g. `md.obsidian`.
|
|
34
|
+
*/
|
|
35
|
+
readonly appId: string;
|
|
36
|
+
/**
|
|
37
|
+
* The adb device id (`emulator-5554`, a serial) to run adb against.
|
|
38
|
+
*/
|
|
39
|
+
readonly deviceId: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Handles a CDP event.
|
|
43
|
+
*/
|
|
44
|
+
type CdpEventHandler = (params: Record<string, unknown>) => void;
|
|
45
|
+
/**
|
|
46
|
+
* An open CDP connection to a WebView.
|
|
47
|
+
*
|
|
48
|
+
* Commands are id-multiplexed, so a command issued from inside an event handler completes while an earlier
|
|
49
|
+
* `Runtime.evaluate` is still awaiting its promise — which is the whole reason this class exists.
|
|
50
|
+
*/
|
|
51
|
+
export declare class WebViewCdpConnection {
|
|
52
|
+
private readonly webSocket;
|
|
53
|
+
private readonly deviceId;
|
|
54
|
+
private readonly port;
|
|
55
|
+
/**
|
|
56
|
+
* Whether the socket is still usable.
|
|
57
|
+
*
|
|
58
|
+
* Restarting the app tears its WebView down and takes the debugger target with it, so a cached
|
|
59
|
+
* connection has to be re-checked rather than assumed live.
|
|
60
|
+
*
|
|
61
|
+
* @returns `true` while the socket is open.
|
|
62
|
+
*/
|
|
63
|
+
get isOpen(): boolean;
|
|
64
|
+
private readonly eventHandlers;
|
|
65
|
+
private messageId;
|
|
66
|
+
/**
|
|
67
|
+
* Wraps an already-open debugger socket, plus what is needed to tear its port forward down.
|
|
68
|
+
*
|
|
69
|
+
* @param webSocket - The open debugger socket.
|
|
70
|
+
* @param deviceId - The adb device id, needed to drop the port forward on dispose.
|
|
71
|
+
* @param port - The forwarded local port.
|
|
72
|
+
*/
|
|
73
|
+
constructor(webSocket: WebSocket, deviceId: string, port: number);
|
|
74
|
+
/**
|
|
75
|
+
* Closes the socket and drops the adb port forward.
|
|
76
|
+
*/
|
|
77
|
+
dispose(): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Synchronous disposal, for `process.on('exit')` handlers where async work cannot run.
|
|
80
|
+
*
|
|
81
|
+
* Without this an abrupt worker exit leaves the port forward behind — the async {@link dispose} above
|
|
82
|
+
* never gets a turn.
|
|
83
|
+
*/
|
|
84
|
+
disposeSync(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Subscribes to a CDP event. One handler per method; subscribing again replaces it.
|
|
87
|
+
*
|
|
88
|
+
* @param method - The CDP event name, e.g. `Runtime.bindingCalled`.
|
|
89
|
+
* @param handler - Called with the event parameters.
|
|
90
|
+
*/
|
|
91
|
+
on(method: string, handler: CdpEventHandler): void;
|
|
92
|
+
/**
|
|
93
|
+
* Sends a CDP command and waits for its response.
|
|
94
|
+
*
|
|
95
|
+
* @param method - The CDP method name.
|
|
96
|
+
* @param params - The CDP method parameters.
|
|
97
|
+
* @returns The command result.
|
|
98
|
+
*/
|
|
99
|
+
send(method: string, params?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
100
|
+
/**
|
|
101
|
+
* Sends an ordered command sequence, honoring each command's delay.
|
|
102
|
+
*
|
|
103
|
+
* @param commands - The commands to send, in order.
|
|
104
|
+
*/
|
|
105
|
+
sendAll(commands: readonly CdpInputCommand[]): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Closes the debugger socket and stops routing its events.
|
|
108
|
+
*/
|
|
109
|
+
private closeSocket;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Opens a CDP connection to the app's WebView.
|
|
113
|
+
*
|
|
114
|
+
* @param params - Which app on which device.
|
|
115
|
+
* @returns The open connection. Dispose it to close the socket and drop the adb port forward.
|
|
116
|
+
*/
|
|
117
|
+
export declare function connectToWebViewCdp(params: ConnectToWebViewCdpParams): Promise<WebViewCdpConnection>;
|
|
118
|
+
/**
|
|
119
|
+
* Finds a port already forwarded to this device socket, so repeated runs reuse one forward.
|
|
120
|
+
*
|
|
121
|
+
* Without this every run allocates a fresh port, and any run that exits without the async
|
|
122
|
+
* {@link WebViewCdpConnection.dispose} — an abrupt worker exit, where only the synchronous teardown
|
|
123
|
+
* path runs — leaves its forward behind forever. Reuse bounds that to a single forward per socket
|
|
124
|
+
* rather than one per run.
|
|
125
|
+
*
|
|
126
|
+
* @param forwardList - The output of `adb forward --list`.
|
|
127
|
+
* @param deviceId - The adb device id to match.
|
|
128
|
+
* @param socketName - The abstract socket name to match.
|
|
129
|
+
* @returns The already-forwarded local port, or `undefined` when there is none.
|
|
130
|
+
*/
|
|
131
|
+
export declare function parseForwardedPort(forwardList: string, deviceId: string, socketName: string): number | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* Picks the WebView's devtools socket name out of `/proc/net/unix`.
|
|
134
|
+
*
|
|
135
|
+
* A device can host several debuggable WebViews (other apps, a leftover process), so the app's own pid is
|
|
136
|
+
* what disambiguates them. When no socket matches that pid the sole remaining candidate is used — a
|
|
137
|
+
* WebView whose socket is named after a child process rather than the one `pidof` reported still has to be
|
|
138
|
+
* reachable — but two unattributable candidates is ambiguous enough to refuse.
|
|
139
|
+
*
|
|
140
|
+
* @param procNetUnix - The contents of `/proc/net/unix`.
|
|
141
|
+
* @param pid - The application's process id.
|
|
142
|
+
* @returns The socket name, e.g. `webview_devtools_remote_18056`.
|
|
143
|
+
*/
|
|
144
|
+
export declare function parseWebViewDevtoolsSocketName(procNetUnix: string, pid: string): string;
|
|
145
|
+
/**
|
|
146
|
+
* Picks the Obsidian page target out of the debugger's `/json` list.
|
|
147
|
+
*
|
|
148
|
+
* @param targets - The `/json` response.
|
|
149
|
+
* @returns The page target to attach to.
|
|
150
|
+
*/
|
|
151
|
+
export declare function selectWebViewPageTarget(targets: readonly CdpTarget[]): CdpTarget;
|
|
152
|
+
export {};
|