opencode-mobile 1.0.11 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/bin/audit +31 -0
  2. package/bin/qr +13 -0
  3. package/dist/index.d.ts +11 -3
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +545 -3
  6. package/dist/index.js.map +1 -1
  7. package/dist/src/cli/endpoint-tester.d.ts +19 -0
  8. package/dist/src/cli/endpoint-tester.d.ts.map +1 -0
  9. package/dist/src/cli/endpoint-tester.js +233 -0
  10. package/dist/src/cli/endpoint-tester.js.map +1 -0
  11. package/dist/src/cli/index.d.ts +20 -0
  12. package/dist/src/cli/index.d.ts.map +1 -0
  13. package/dist/src/cli/index.js +166 -0
  14. package/dist/src/cli/index.js.map +1 -0
  15. package/dist/src/cli/push-tester.d.ts +16 -0
  16. package/dist/src/cli/push-tester.d.ts.map +1 -0
  17. package/dist/src/cli/push-tester.js +293 -0
  18. package/dist/src/cli/push-tester.js.map +1 -0
  19. package/dist/src/cli/qr.d.ts +5 -0
  20. package/dist/src/cli/qr.d.ts.map +1 -0
  21. package/dist/src/cli/qr.js +127 -0
  22. package/dist/src/cli/qr.js.map +1 -0
  23. package/dist/src/cli/report.d.ts +25 -0
  24. package/dist/src/cli/report.d.ts.map +1 -0
  25. package/dist/src/cli/report.js +215 -0
  26. package/dist/src/cli/report.js.map +1 -0
  27. package/dist/src/cli/server-manager.d.ts +28 -0
  28. package/dist/src/cli/server-manager.d.ts.map +1 -0
  29. package/dist/src/cli/server-manager.js +340 -0
  30. package/dist/src/cli/server-manager.js.map +1 -0
  31. package/dist/src/cli/test-runner.d.ts +16 -0
  32. package/dist/src/cli/test-runner.d.ts.map +1 -0
  33. package/dist/src/cli/test-runner.js +201 -0
  34. package/dist/src/cli/test-runner.js.map +1 -0
  35. package/dist/src/cli/tunnel-qr.d.ts +8 -0
  36. package/dist/src/cli/tunnel-qr.d.ts.map +1 -0
  37. package/dist/src/cli/tunnel-qr.js +163 -0
  38. package/dist/src/cli/tunnel-qr.js.map +1 -0
  39. package/dist/src/cli/tunnel-tester.d.ts +22 -0
  40. package/dist/src/cli/tunnel-tester.d.ts.map +1 -0
  41. package/dist/src/cli/tunnel-tester.js +360 -0
  42. package/dist/src/cli/tunnel-tester.js.map +1 -0
  43. package/dist/src/cli/types.d.ts +112 -0
  44. package/dist/src/cli/types.d.ts.map +1 -0
  45. package/dist/src/cli/types.js +5 -0
  46. package/dist/src/cli/types.js.map +1 -0
  47. package/dist/src/push/index.d.ts +1 -0
  48. package/dist/src/push/index.d.ts.map +1 -1
  49. package/dist/src/push/index.js +1 -0
  50. package/dist/src/push/index.js.map +1 -1
  51. package/dist/src/push/notification-handler.d.ts +58 -0
  52. package/dist/src/push/notification-handler.d.ts.map +1 -0
  53. package/dist/src/push/notification-handler.js +110 -0
  54. package/dist/src/push/notification-handler.js.map +1 -0
  55. package/dist/src/tunnel/cloudflare.d.ts +38 -1
  56. package/dist/src/tunnel/cloudflare.d.ts.map +1 -1
  57. package/dist/src/tunnel/cloudflare.js +148 -51
  58. package/dist/src/tunnel/cloudflare.js.map +1 -1
  59. package/dist/src/tunnel/localtunnel.d.ts +32 -1
  60. package/dist/src/tunnel/localtunnel.d.ts.map +1 -1
  61. package/dist/src/tunnel/localtunnel.js +75 -16
  62. package/dist/src/tunnel/localtunnel.js.map +1 -1
  63. package/dist/src/tunnel/metadata.d.ts +29 -0
  64. package/dist/src/tunnel/metadata.d.ts.map +1 -0
  65. package/dist/src/tunnel/metadata.js +83 -0
  66. package/dist/src/tunnel/metadata.js.map +1 -0
  67. package/dist/src/tunnel/ngrok.d.ts +24 -1
  68. package/dist/src/tunnel/ngrok.d.ts.map +1 -1
  69. package/dist/src/tunnel/ngrok.js +381 -20
  70. package/dist/src/tunnel/ngrok.js.map +1 -1
  71. package/dist/src/tunnel/qrcode.d.ts +14 -2
  72. package/dist/src/tunnel/qrcode.d.ts.map +1 -1
  73. package/dist/src/tunnel/qrcode.js +96 -8
  74. package/dist/src/tunnel/qrcode.js.map +1 -1
  75. package/package.json +22 -4
  76. package/dist/push-notifications.d.ts +0 -4
  77. package/dist/push-notifications.d.ts.map +0 -1
  78. package/dist/push-notifications.js +0 -260
  79. package/dist/push-notifications.js.map +0 -1
  80. package/dist/reverse-proxy.d.ts +0 -9
  81. package/dist/reverse-proxy.d.ts.map +0 -1
  82. package/dist/reverse-proxy.js +0 -78
  83. package/dist/reverse-proxy.js.map +0 -1
  84. package/dist/sdk-logger.d.ts +0 -19
  85. package/dist/sdk-logger.d.ts.map +0 -1
  86. package/dist/sdk-logger.js +0 -103
  87. package/dist/sdk-logger.js.map +0 -1
  88. package/dist/src/tunnel/index.d.ts +0 -29
  89. package/dist/src/tunnel/index.d.ts.map +0 -1
  90. package/dist/src/tunnel/index.js +0 -125
  91. package/dist/src/tunnel/index.js.map +0 -1
  92. package/dist/src/utils/port.d.ts +0 -12
  93. package/dist/src/utils/port.d.ts.map +0 -1
  94. package/dist/src/utils/port.js +0 -41
  95. package/dist/src/utils/port.js.map +0 -1
  96. package/dist/tunnel-manager.d.ts +0 -30
  97. package/dist/tunnel-manager.d.ts.map +0 -1
  98. package/dist/tunnel-manager.js +0 -641
  99. package/dist/tunnel-manager.js.map +0 -1
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Tunnel metadata storage for .config/opencode/tunnel.json
3
+ */
4
+ import * as fs from "fs";
5
+ import * as path from "path";
6
+ const CONFIG_DIR = path.join(process.env.HOME || "", ".config/opencode");
7
+ const TUNNEL_METADATA_FILE = path.join(CONFIG_DIR, "tunnel.json");
8
+ /**
9
+ * Load tunnel metadata from disk
10
+ */
11
+ export function loadTunnelMetadata() {
12
+ try {
13
+ if (fs.existsSync(TUNNEL_METADATA_FILE)) {
14
+ const data = fs.readFileSync(TUNNEL_METADATA_FILE, "utf-8");
15
+ return JSON.parse(data);
16
+ }
17
+ }
18
+ catch (e) {
19
+ console.error("[TunnelMetadata] Load error:", e);
20
+ }
21
+ return {
22
+ url: null,
23
+ tunnelId: null,
24
+ provider: null,
25
+ port: null,
26
+ targetPort: null,
27
+ startedAt: null,
28
+ lastUpdated: null,
29
+ };
30
+ }
31
+ /**
32
+ * Save tunnel metadata to disk
33
+ */
34
+ export function saveTunnelMetadata(metadata) {
35
+ try {
36
+ const dir = path.dirname(TUNNEL_METADATA_FILE);
37
+ if (!fs.existsSync(dir)) {
38
+ fs.mkdirSync(dir, { recursive: true });
39
+ }
40
+ metadata.lastUpdated = new Date().toISOString();
41
+ fs.writeFileSync(TUNNEL_METADATA_FILE, JSON.stringify(metadata, null, 2));
42
+ return true;
43
+ }
44
+ catch (error) {
45
+ console.error("[TunnelMetadata] Save error:", error);
46
+ }
47
+ return false;
48
+ }
49
+ /**
50
+ * Update tunnel metadata when a tunnel starts
51
+ */
52
+ export function updateTunnelMetadata(url, tunnelId, provider, port, targetPort) {
53
+ const metadata = {
54
+ url,
55
+ tunnelId,
56
+ provider,
57
+ port,
58
+ targetPort,
59
+ startedAt: new Date().toISOString(),
60
+ lastUpdated: new Date().toISOString(),
61
+ };
62
+ if (saveTunnelMetadata(metadata)) {
63
+ console.log("[TunnelMetadata] Saved to:", TUNNEL_METADATA_FILE);
64
+ }
65
+ }
66
+ /**
67
+ * Clear tunnel metadata when tunnel stops
68
+ */
69
+ export function clearTunnelMetadata() {
70
+ const metadata = {
71
+ url: null,
72
+ tunnelId: null,
73
+ provider: null,
74
+ port: null,
75
+ targetPort: null,
76
+ startedAt: null,
77
+ lastUpdated: new Date().toISOString(),
78
+ };
79
+ if (saveTunnelMetadata(metadata)) {
80
+ console.log("[TunnelMetadata] Cleared");
81
+ }
82
+ }
83
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../src/tunnel/metadata.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACzE,MAAM,oBAAoB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAYlE;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,oBAAoB,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;YAC5D,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,OAAO;QACL,GAAG,EAAE,IAAI;QACT,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,IAAI;QACV,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,IAAI;KAClB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAwB;IACzD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC/C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;QACD,QAAQ,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAChD,EAAE,CAAC,aAAa,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1E,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAAW,EACX,QAAgB,EAChB,QAAgB,EAChB,IAAY,EACZ,UAAkB;IAElB,MAAM,QAAQ,GAAmB;QAC/B,GAAG;QACH,QAAQ;QACR,QAAQ;QACR,IAAI;QACJ,UAAU;QACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAC;IACF,IAAI,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,oBAAoB,CAAC,CAAC;IAClE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,QAAQ,GAAmB;QAC/B,GAAG,EAAE,IAAI;QACT,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,IAAI;QACV,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAC;IACF,IAAI,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC"}
@@ -7,15 +7,38 @@ import type { TunnelConfig, TunnelInfo, NgrokDiagnostics } from "./types";
7
7
  */
8
8
  export declare function diagnoseNgrok(): Promise<NgrokDiagnostics>;
9
9
  /**
10
- * Start an ngrok tunnel
10
+ * Ensure ngrok is ready for use (diagnose + interactive setup if needed)
11
+ */
12
+ export declare function ensureNgrokReady(): Promise<{
13
+ ready: boolean;
14
+ authtoken: string | null;
15
+ }>;
16
+ /**
17
+ * Start an ngrok tunnel with multi-strategy fallback
11
18
  */
12
19
  export declare function startNgrokTunnel(config: TunnelConfig): Promise<TunnelInfo>;
13
20
  /**
14
21
  * Stop the ngrok tunnel
15
22
  */
16
23
  export declare function stopNgrokTunnel(): Promise<void>;
24
+ /**
25
+ * Stop ngrok (legacy name for compatibility)
26
+ */
27
+ export declare function stopNgrok(): Promise<void>;
17
28
  /**
18
29
  * Check if ngrok is installed
19
30
  */
20
31
  export declare function isNgrokInstalled(): Promise<boolean>;
32
+ /**
33
+ * Get current ngrok instance (for testing)
34
+ */
35
+ export declare function getInstance(): any;
36
+ /**
37
+ * Set ngrok instance (for testing)
38
+ */
39
+ export declare function setInstance(instance: any): void;
40
+ /**
41
+ * Clear ngrok instance (for testing)
42
+ */
43
+ export declare function clearInstance(): void;
21
44
  //# sourceMappingURL=ngrok.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ngrok.d.ts","sourceRoot":"","sources":["../../../src/tunnel/ngrok.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAI1E;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAyC/D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAgBhF;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAKrD;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CASzD"}
1
+ {"version":3,"file":"ngrok.d.ts","sourceRoot":"","sources":["../../../src/tunnel/ngrok.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAI1E;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC,CA+F/D;AAoED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CA8C9F;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAyPhF;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAKrD;AAED;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CASzD;AAGD;;GAEG;AACH,wBAAgB,WAAW,IAAI,GAAG,CAEjC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC"}
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * Ngrok tunnel provider implementation
3
3
  */
4
- import * as fs from "fs";
5
- import ngrok from "@ngrok/ngrok";
4
+ import * as ngrok from "@ngrok/ngrok";
6
5
  let ngrokInstance = null;
7
6
  /**
8
7
  * Diagnose ngrok installation and configuration
@@ -36,34 +35,371 @@ export async function diagnoseNgrok() {
36
35
  const { existsSync } = await import("fs");
37
36
  if (existsSync(configPath)) {
38
37
  diagnostics.configPath = configPath;
39
- const content = fs.readFileSync(configPath, "utf-8");
40
- diagnostics.authtokenConfigured = content.includes("authtoken:");
41
38
  break;
42
39
  }
43
40
  }
44
- catch {
45
- // Continue to next path
41
+ catch { }
42
+ }
43
+ if (!diagnostics.configPath) {
44
+ diagnostics.error = "No ngrok config found";
45
+ return diagnostics;
46
+ }
47
+ try {
48
+ const { readFileSync } = await import("fs");
49
+ const configContent = readFileSync(diagnostics.configPath, "utf-8");
50
+ // Check for v3 format first (current standard)
51
+ const v3Match = configContent.match(/agent:\s*\n\s*authtoken:\s*(.+)/);
52
+ // Fallback to v2 format (deprecated but still supported)
53
+ const v2Match = configContent.match(/authtoken:\s*(.+)/);
54
+ const authtoken = v3Match?.[1]?.trim() || v2Match?.[1]?.trim();
55
+ if (authtoken && authtoken.length > 10) {
56
+ diagnostics.authtokenConfigured = true;
57
+ // Validate authtoken by calling ngrok API
58
+ try {
59
+ const { promisify } = await import("util");
60
+ const execAsync = promisify((await import("child_process")).exec);
61
+ // Quick API check - timeout after 5 seconds
62
+ try {
63
+ const result = await execAsync(`curl -s --max-time 5 -H "Authorization: Bearer ${authtoken}" https://api.ngrok.com/tunnels 2>&1`);
64
+ const output = result.stdout + result.stderr;
65
+ // Only fail on clear auth errors
66
+ const hasAuthError = output.includes("ERR_NGROK_206") ||
67
+ output.includes("authentication") ||
68
+ output.includes("invalid_token") ||
69
+ output.includes("Unauthorized");
70
+ if (hasAuthError && output.length < 200) {
71
+ diagnostics.error = "Authtoken invalid or expired";
72
+ }
73
+ else {
74
+ // Any other response means token is valid
75
+ diagnostics.authtokenValid = true;
76
+ }
77
+ }
78
+ catch {
79
+ // If curl fails, proceed anyway - SDK might work
80
+ diagnostics.authtokenValid = true;
81
+ }
82
+ }
83
+ catch (e) {
84
+ diagnostics.error = `Authtoken test failed: ${e.message}`;
85
+ }
86
+ }
87
+ else {
88
+ diagnostics.error = "No authtoken in config";
46
89
  }
47
90
  }
91
+ catch (e) {
92
+ diagnostics.error = `Failed to read config: ${e.message}`;
93
+ }
48
94
  return diagnostics;
49
95
  }
50
96
  /**
51
- * Start an ngrok tunnel
97
+ * Setup ngrok with user input for authtoken
52
98
  */
53
- export async function startNgrokTunnel(config) {
54
- const tunnel = await ngrok.connect({
55
- addr: config.port,
56
- authtoken: config.authToken,
57
- region: config.region,
58
- subdomain: config.subdomain,
99
+ async function setupNgrokWithUserInput() {
100
+ console.log("\n[Setup] Ngrok configuration needed.");
101
+ console.log("[Setup] 1. Get authtoken from: https://dashboard.ngrok.com/get-started/your-authtoken");
102
+ console.log("[Setup] 2. Run: ngrok config add-authtoken YOUR_AUTHTOKEN");
103
+ console.log("");
104
+ const readline = await import("readline");
105
+ const rl = readline.createInterface({
106
+ input: process.stdin,
107
+ output: process.stdout,
108
+ });
109
+ return new Promise((resolve) => {
110
+ rl.question("[Setup] Paste your ngrok authtoken (or press Enter to skip): ", async (authtoken) => {
111
+ rl.close();
112
+ if (!authtoken || authtoken.trim().length < 10) {
113
+ console.log("[Setup] Skipping ngrok setup.");
114
+ resolve(null);
115
+ return;
116
+ }
117
+ const token = authtoken.trim();
118
+ try {
119
+ const { promisify } = await import("util");
120
+ const execAsync = promisify((await import("child_process")).exec);
121
+ // Use ngrok config command which writes v3 format
122
+ await execAsync(`ngrok config add-authtoken ${token}`);
123
+ console.log("[Setup] Ngrok authtoken configured successfully! (v3 format)");
124
+ resolve(token);
125
+ }
126
+ catch (e) {
127
+ // If ngrok config command fails, write v3 format manually
128
+ console.log("[Setup] Ngrok config command failed, writing config manually...");
129
+ try {
130
+ const { writeFileSync, existsSync, mkdirSync } = await import("fs");
131
+ const configPath = `${process.env.HOME}/Library/Application Support/ngrok/ngrok.yml`;
132
+ const configDir = `${process.env.HOME}/Library/Application Support/ngrok`;
133
+ if (!existsSync(configDir)) {
134
+ mkdirSync(configDir, { recursive: true });
135
+ }
136
+ // Write v3 format
137
+ const v3Config = `version: "3"
138
+
139
+ agent:
140
+ authtoken: ${token}
141
+ `;
142
+ writeFileSync(configPath, v3Config);
143
+ console.log("[Setup] Ngrok config written successfully! (v3 format)");
144
+ resolve(token);
145
+ }
146
+ catch (writeError) {
147
+ console.error(`[Setup] Failed to write config: ${writeError.message}`);
148
+ resolve(null);
149
+ }
150
+ }
151
+ });
59
152
  });
60
- ngrokInstance = tunnel;
61
- return {
62
- url: tunnel.url(),
63
- tunnelId: tunnel.id(),
64
- port: config.port,
65
- provider: "ngrok",
66
- };
153
+ }
154
+ /**
155
+ * Ensure ngrok is ready for use (diagnose + interactive setup if needed)
156
+ */
157
+ export async function ensureNgrokReady() {
158
+ console.log("\n[Diagnostics] Checking ngrok configuration...");
159
+ const diagnostics = await diagnoseNgrok();
160
+ console.log(`[Diagnostics] Installed: ${diagnostics.installed ? "✓" : "✗"}`);
161
+ console.log(`[Diagnostics] Config: ${diagnostics.configPath || "none"}`);
162
+ console.log(`[Diagnostics] Authtoken: ${diagnostics.authtokenConfigured ? "✓" : "✗"}`);
163
+ if (diagnostics.error) {
164
+ console.log(`[Diagnostics] Issue: ${diagnostics.error}`);
165
+ }
166
+ if (!diagnostics.installed) {
167
+ console.log("\n[Setup] Please install ngrok: brew install ngrok");
168
+ return { ready: false, authtoken: null };
169
+ }
170
+ if (!diagnostics.authtokenConfigured || diagnostics.error) {
171
+ const authtoken = await setupNgrokWithUserInput();
172
+ return { ready: !!authtoken, authtoken };
173
+ }
174
+ // Extract authtoken from config for SDK usage
175
+ let authtokenValue = null;
176
+ if (diagnostics.configPath) {
177
+ try {
178
+ const { readFileSync } = require("fs");
179
+ const configContent = readFileSync(diagnostics.configPath, "utf-8");
180
+ // Check for v3 format first (current standard)
181
+ const v3Match = configContent.match(/agent:\s*\n\s*authtoken:\s*(.+)/);
182
+ // Fallback to v2 format (deprecated but still supported)
183
+ const v2Match = configContent.match(/authtoken:\s*(.+)/);
184
+ const token = v3Match?.[1]?.trim() || v2Match?.[1]?.trim();
185
+ if (token && token.length > 10) {
186
+ authtokenValue = token;
187
+ }
188
+ }
189
+ catch (e) {
190
+ // Failed to read authtoken, continue without it
191
+ }
192
+ }
193
+ console.log("[Diagnostics] Ngrok appears configured, attempting connection...");
194
+ return { ready: true, authtoken: authtokenValue };
195
+ }
196
+ /**
197
+ * Start an ngrok tunnel with multi-strategy fallback
198
+ */
199
+ export async function startNgrokTunnel(config) {
200
+ const { exec } = await import("child_process");
201
+ const { promisify } = await import("util");
202
+ const execAsync = promisify(exec);
203
+ async function cleanupNgrok() {
204
+ try {
205
+ await ngrok.kill();
206
+ ngrokInstance = null;
207
+ }
208
+ catch (e) {
209
+ console.log("[Tunnel] Could not clean up ngrok session");
210
+ }
211
+ }
212
+ // First, ensure ngrok is properly configured
213
+ const { ready, authtoken } = await ensureNgrokReady();
214
+ if (!ready) {
215
+ throw new Error("Ngrok not configured. Please set up your authtoken.");
216
+ }
217
+ await cleanupNgrok();
218
+ console.log("\n[Tunnel] Starting ngrok...");
219
+ // Get config path for debugging
220
+ const configPaths = [
221
+ `${process.env.HOME}/Library/Application Support/ngrok/ngrok.yml`,
222
+ `${process.env.HOME}/.config/ngrok/ngrok.yml`,
223
+ "/etc/ngrok/ngrok.yml",
224
+ ];
225
+ let activeConfigPath = "none";
226
+ for (const p of configPaths) {
227
+ try {
228
+ const { existsSync } = require("fs");
229
+ if (existsSync(p)) {
230
+ activeConfigPath = p;
231
+ break;
232
+ }
233
+ }
234
+ catch { }
235
+ }
236
+ // Read config for debugging
237
+ let configContent = "";
238
+ if (activeConfigPath !== "none") {
239
+ try {
240
+ const { readFileSync } = require("fs");
241
+ configContent = readFileSync(activeConfigPath, "utf-8");
242
+ }
243
+ catch {
244
+ configContent = "(failed to read)";
245
+ }
246
+ }
247
+ console.log(`[Tunnel] Config: ${activeConfigPath}`);
248
+ console.log(`[Tunnel] Format: ${configContent.includes('version: "3"') ? "v3" : configContent.includes("version: 2") ? "v2" : "unknown"}`);
249
+ console.log(`[Tunnel] Token: ${configContent.includes("authtoken:") || configContent.includes("agent:") ? "✓" : "✗"}`);
250
+ // Try multiple strategies if one fails
251
+ const strategies = [
252
+ // Strategy 1: Basic ngrok.forward() with direct authtoken
253
+ async () => {
254
+ console.log("[Tunnel] Strategy 1: ngrok.forward() with direct token...");
255
+ const token = config.authToken || authtoken;
256
+ if (!token || typeof token !== "string") {
257
+ throw new Error("No valid authtoken available for Strategy 1");
258
+ }
259
+ console.log(`[Tunnel] Token: ${token.substring(0, 8)}... (direct token)`);
260
+ const listener = await ngrok.forward({
261
+ addr: config.port,
262
+ authtoken: token,
263
+ });
264
+ console.log(`[Tunnel] URL: ${listener.url()}`);
265
+ return listener.url();
266
+ },
267
+ // Strategy 2: With session metadata and SessionBuilder
268
+ async () => {
269
+ console.log("[Tunnel] Strategy 2: SessionBuilder + metadata...");
270
+ await cleanupNgrok();
271
+ await new Promise((resolve) => setTimeout(resolve, 2000));
272
+ const token = config.authToken || authtoken;
273
+ if (!token || typeof token !== "string") {
274
+ throw new Error("No valid authtoken available for Strategy 2");
275
+ }
276
+ console.log(`[Tunnel] Token: ${token.substring(0, 8)}... (direct token)`);
277
+ // Use SessionBuilder for more control
278
+ const session = await new ngrok.SessionBuilder()
279
+ .authtoken(token)
280
+ .metadata(`opencode-${Date.now()}`)
281
+ .connect();
282
+ const listener = await session.httpEndpoint()
283
+ .listenAndForward(`localhost:${config.port}`);
284
+ console.log(`[Tunnel] URL: ${listener.url()}`);
285
+ return listener.url();
286
+ },
287
+ // Strategy 3: Clean session with SessionBuilder
288
+ async () => {
289
+ console.log("[Tunnel] Strategy 3: clean session with SessionBuilder...");
290
+ await cleanupNgrok();
291
+ await new Promise((resolve) => setTimeout(resolve, 3000));
292
+ const token = config.authToken || authtoken;
293
+ if (!token || typeof token !== "string") {
294
+ throw new Error("No valid authtoken available for Strategy 3");
295
+ }
296
+ console.log(`[Tunnel] Token: ${token.substring(0, 8)}... (direct token)`);
297
+ // Create a completely fresh session with direct token
298
+ const session = await new ngrok.SessionBuilder()
299
+ .authtoken(token)
300
+ .connect();
301
+ const listener = await session.httpEndpoint()
302
+ .listenAndForward(`localhost:${config.port}`);
303
+ console.log(`[Tunnel] URL: ${listener.url()}`);
304
+ return listener.url();
305
+ },
306
+ // Strategy 4: Use ngrok binary directly
307
+ async () => {
308
+ console.log("[Tunnel] Strategy 4: ngrok binary...");
309
+ await cleanupNgrok();
310
+ await new Promise((resolve) => setTimeout(resolve, 2000));
311
+ const configPath = activeConfigPath !== "none" ? activeConfigPath : "";
312
+ console.log(`[Tunnel] Config: ${configPath || "(default)"}`);
313
+ const cmd = configPath
314
+ ? `ngrok http ${config.port} --config="${configPath}" --log=stdout 2>&1`
315
+ : `ngrok http ${config.port} --log=stdout 2>&1`;
316
+ console.log(`[Tunnel] Running: ngrok http ${config.port}`);
317
+ const { spawn } = require("child_process");
318
+ const ngrokProcess = spawn("sh", ["-c", cmd], {
319
+ stdio: ["ignore", "pipe", "pipe"],
320
+ });
321
+ let output = "";
322
+ let resolved = false;
323
+ let resolvePromise;
324
+ const onData = (data) => {
325
+ const text = data.toString();
326
+ output += text;
327
+ // Extract URL from format: url=https://abc.ngrok-free.app
328
+ const urlMatch = text.match(/url=([^\s]+)/);
329
+ if (urlMatch && !resolved) {
330
+ resolved = true;
331
+ ngrokProcess.kill();
332
+ if (resolvePromise)
333
+ resolvePromise(true);
334
+ console.log(`[Tunnel] URL: ${urlMatch[1]}`);
335
+ }
336
+ };
337
+ ngrokProcess.stdout.on("data", onData);
338
+ ngrokProcess.stderr.on("data", onData);
339
+ const waitPromise = new Promise((resolve) => {
340
+ resolvePromise = resolve;
341
+ });
342
+ const timeoutPromise = new Promise((_resolve, reject) => {
343
+ setTimeout(() => {
344
+ if (!resolved) {
345
+ ngrokProcess.kill();
346
+ reject(new Error("timeout"));
347
+ }
348
+ }, 15000);
349
+ });
350
+ await Promise.race([waitPromise, timeoutPromise]);
351
+ // Final extraction
352
+ const finalUrlMatch = output.match(/url=([^\s]+)/);
353
+ if (finalUrlMatch) {
354
+ return finalUrlMatch[1];
355
+ }
356
+ throw new Error("failed to extract URL");
357
+ },
358
+ ];
359
+ let lastError = null;
360
+ let firstAuthError = null;
361
+ for (let i = 0; i < strategies.length; i++) {
362
+ try {
363
+ console.log(`[Tunnel] Connecting to port ${config.port}...`);
364
+ ngrokInstance = await strategies[i]();
365
+ const tunnelUrl = ngrokInstance;
366
+ const urlObj = new URL(tunnelUrl);
367
+ const tunnelId = urlObj.hostname.split(".")[0];
368
+ console.log("[Tunnel] URL:", tunnelUrl);
369
+ return {
370
+ url: tunnelUrl,
371
+ tunnelId,
372
+ port: config.port,
373
+ provider: "ngrok",
374
+ };
375
+ }
376
+ catch (error) {
377
+ lastError = error;
378
+ console.log(`[Tunnel] Strategy ${i + 1} failed: ${error.message}`);
379
+ // Capture first auth-related error for proper detection
380
+ const errorMsg = error.message.toLowerCase();
381
+ const isAuthError = errorMsg.includes("invalid tunnel configuration") ||
382
+ errorMsg.includes("authtoken") ||
383
+ errorMsg.includes("authentication") ||
384
+ errorMsg.includes("auth token") ||
385
+ errorMsg.includes("session failed");
386
+ if (isAuthError && !firstAuthError) {
387
+ firstAuthError = error;
388
+ console.log(`[Tunnel] Auth error detected in strategy ${i + 1}: ${error.message}`);
389
+ }
390
+ if (i === strategies.length - 1) {
391
+ console.error(`[Tunnel] All strategies exhausted. Last error: ${error.message}`);
392
+ // If we captured an auth error earlier, throw that instead
393
+ if (firstAuthError) {
394
+ console.error(`[Tunnel] Original auth error: ${firstAuthError.message}`);
395
+ throw firstAuthError;
396
+ }
397
+ throw error;
398
+ }
399
+ console.log(`[Tunnel] Trying next strategy...`);
400
+ }
401
+ }
402
+ throw lastError || new Error("Unknown error");
67
403
  }
68
404
  /**
69
405
  * Stop the ngrok tunnel
@@ -74,6 +410,12 @@ export async function stopNgrokTunnel() {
74
410
  ngrokInstance = null;
75
411
  }
76
412
  }
413
+ /**
414
+ * Stop ngrok (legacy name for compatibility)
415
+ */
416
+ export async function stopNgrok() {
417
+ await stopNgrokTunnel();
418
+ }
77
419
  /**
78
420
  * Check if ngrok is installed
79
421
  */
@@ -88,4 +430,23 @@ export async function isNgrokInstalled() {
88
430
  return false;
89
431
  }
90
432
  }
433
+ // Test helper functions
434
+ /**
435
+ * Get current ngrok instance (for testing)
436
+ */
437
+ export function getInstance() {
438
+ return ngrokInstance;
439
+ }
440
+ /**
441
+ * Set ngrok instance (for testing)
442
+ */
443
+ export function setInstance(instance) {
444
+ ngrokInstance = instance;
445
+ }
446
+ /**
447
+ * Clear ngrok instance (for testing)
448
+ */
449
+ export function clearInstance() {
450
+ ngrokInstance = null;
451
+ }
91
452
  //# sourceMappingURL=ngrok.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ngrok.js","sourceRoot":"","sources":["../../../src/tunnel/ngrok.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngrok.js","sourceRoot":"","sources":["../../../src/tunnel/ngrok.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,IAAI,aAAa,GAAQ,IAAI,CAAC;AAE9B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,WAAW,GAAqB;QACpC,SAAS,EAAE,KAAK;QAChB,mBAAmB,EAAE,KAAK;QAC1B,cAAc,EAAE,KAAK;QACrB,eAAe,EAAE,CAAC;QAClB,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,IAAI;KACZ,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,SAAS,CAAC,aAAa,CAAC,CAAC;QAC/B,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,WAAW,CAAC,KAAK,GAAG,qBAAqB,CAAC;QAC1C,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,WAAW,GAAG;QAClB,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,8CAA8C;QACjE,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,0BAA0B;QAC7C,sBAAsB;KACvB,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC3B,WAAW,CAAC,UAAU,GAAG,UAAU,CAAC;gBACpC,MAAM;YACR,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QAC5B,WAAW,CAAC,KAAK,GAAG,uBAAuB,CAAC;QAC5C,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,aAAa,GAAG,YAAY,CAAC,WAAW,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAEpE,+CAA+C;QAC/C,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACvE,yDAAyD;QACzD,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAEzD,MAAM,SAAS,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QAE/D,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACvC,WAAW,CAAC,mBAAmB,GAAG,IAAI,CAAC;YAEvC,0CAA0C;YAC1C,IAAI,CAAC;gBACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAElE,4CAA4C;gBAC5C,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAC5B,kDAAkD,SAAS,sCAAsC,CAClG,CAAC;oBAEF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;oBAE7C,iCAAiC;oBACjC,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;wBAC/B,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC;wBACjC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;wBAChC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;oBAEtD,IAAI,YAAY,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;wBACxC,WAAW,CAAC,KAAK,GAAG,8BAA8B,CAAC;oBACrD,CAAC;yBAAM,CAAC;wBACN,0CAA0C;wBAC1C,WAAW,CAAC,cAAc,GAAG,IAAI,CAAC;oBACpC,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,iDAAiD;oBACjD,WAAW,CAAC,cAAc,GAAG,IAAI,CAAC;gBACpC,CAAC;YACH,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,WAAW,CAAC,KAAK,GAAG,0BAA0B,CAAC,CAAC,OAAO,EAAE,CAAC;YAC5D,CAAC;QACH,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,KAAK,GAAG,wBAAwB,CAAC;QAC/C,CAAC;IACH,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,WAAW,CAAC,KAAK,GAAG,0BAA0B,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5D,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,uBAAuB;IACpC,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,uFAAuF,CAAC,CAAC;IACrG,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,+DAA+D,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;YAC/F,EAAE,CAAC,KAAK,EAAE,CAAC;YAEX,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBAC/C,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;gBAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;gBACd,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;YAE/B,IAAI,CAAC;gBACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAElE,kDAAkD;gBAClD,MAAM,SAAS,CAAC,8BAA8B,KAAK,EAAE,CAAC,CAAC;gBACvD,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;gBAC5E,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,0DAA0D;gBAC1D,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;gBAC/E,IAAI,CAAC;oBACH,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;oBAEpE,MAAM,UAAU,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,8CAA8C,CAAC;oBACrF,MAAM,SAAS,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,oCAAoC,CAAC;oBAE1E,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;wBAC3B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC5C,CAAC;oBAED,kBAAkB;oBAClB,MAAM,QAAQ,GAAG;;;eAGZ,KAAK;CACnB,CAAC;oBACQ,aAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;oBACpC,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;oBACtE,OAAO,CAAC,KAAK,CAAC,CAAC;gBACjB,CAAC;gBAAC,OAAO,UAAe,EAAE,CAAC;oBACzB,OAAO,CAAC,KAAK,CAAC,mCAAmC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;oBACvE,OAAO,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IAE/D,MAAM,WAAW,GAAG,MAAM,aAAa,EAAE,CAAC;IAE1C,OAAO,CAAC,GAAG,CAAC,4BAA4B,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,yBAAyB,WAAW,CAAC,UAAU,IAAI,MAAM,EAAE,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,4BAA4B,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAEvF,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,wBAAwB,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;QAClE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,mBAAmB,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;QAC1D,MAAM,SAAS,GAAG,MAAM,uBAAuB,EAAE,CAAC;QAClD,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC;IAC3C,CAAC;IAED,8CAA8C;IAC9C,IAAI,cAAc,GAAkB,IAAI,CAAC;IACzC,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM,aAAa,GAAG,YAAY,CAAC,WAAW,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAEpE,+CAA+C;YAC/C,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACvE,yDAAyD;YACzD,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAEzD,MAAM,KAAK,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;YAC3D,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBAC/B,cAAc,GAAG,KAAK,CAAC;YACzB,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,gDAAgD;QAClD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;IAChF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAoB;IACzD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;IAC/C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAElC,KAAK,UAAU,YAAY;QACzB,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,aAAa,GAAG,IAAI,CAAC;QACvB,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,MAAM,gBAAgB,EAAE,CAAC;IAEtD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,YAAY,EAAE,CAAC;IAErB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAE5C,gCAAgC;IAChC,MAAM,WAAW,GAAG;QAClB,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,8CAA8C;QACjE,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,0BAA0B;QAC7C,sBAAsB;KACvB,CAAC;IACF,IAAI,gBAAgB,GAAG,MAAM,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClB,gBAAgB,GAAG,CAAC,CAAC;gBACrB,MAAM;YACR,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,4BAA4B;IAC5B,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,IAAI,gBAAgB,KAAK,MAAM,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YACvC,aAAa,GAAG,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YAAC,aAAa,GAAG,kBAAkB,CAAC;QAAC,CAAC;IACjD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,oBAAoB,gBAAgB,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,oBAAoB,aAAa,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3I,OAAO,CAAC,GAAG,CAAC,mBAAmB,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAEvH,uCAAuC;IACvC,MAAM,UAAU,GAAG;QACjB,0DAA0D;QAC1D,KAAK,IAAI,EAAE;YACT,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;YAEzE,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC;YAC5C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;YACjE,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,oBAAoB,CAAC,CAAC;YAE1E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC;gBACnC,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;YAEH,OAAO,CAAC,GAAG,CAAC,iBAAiB,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC/C,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC;QACxB,CAAC;QAED,uDAAuD;QACvD,KAAK,IAAI,EAAE;YACT,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;YACjE,MAAM,YAAY,EAAE,CAAC;YACrB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;YAE1D,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC;YAC5C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;YACjE,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,oBAAoB,CAAC,CAAC;YAE1E,sCAAsC;YACtC,MAAM,OAAO,GAAG,MAAM,IAAI,KAAK,CAAC,cAAc,EAAE;iBAC7C,SAAS,CAAC,KAAK,CAAC;iBAChB,QAAQ,CAAC,YAAY,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;iBAClC,OAAO,EAAE,CAAC;YAEb,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE;iBAC1C,gBAAgB,CAAC,aAAa,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YAEhD,OAAO,CAAC,GAAG,CAAC,iBAAiB,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC/C,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC;QACxB,CAAC;QAED,gDAAgD;QAChD,KAAK,IAAI,EAAE;YACT,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;YACzE,MAAM,YAAY,EAAE,CAAC;YACrB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;YAE1D,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC;YAC5C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;YACjE,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,oBAAoB,CAAC,CAAC;YAE1E,sDAAsD;YACtD,MAAM,OAAO,GAAG,MAAM,IAAI,KAAK,CAAC,cAAc,EAAE;iBAC7C,SAAS,CAAC,KAAK,CAAC;iBAChB,OAAO,EAAE,CAAC;YAEb,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE;iBAC1C,gBAAgB,CAAC,aAAa,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YAEhD,OAAO,CAAC,GAAG,CAAC,iBAAiB,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC/C,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC;QACxB,CAAC;QAED,wCAAwC;QACxC,KAAK,IAAI,EAAE;YACT,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;YACpD,MAAM,YAAY,EAAE,CAAC;YACrB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;YAE1D,MAAM,UAAU,GAAG,gBAAgB,KAAK,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,OAAO,CAAC,GAAG,CAAC,oBAAoB,UAAU,IAAI,WAAW,EAAE,CAAC,CAAC;YAE7D,MAAM,GAAG,GAAG,UAAU;gBACpB,CAAC,CAAC,cAAc,MAAM,CAAC,IAAI,cAAc,UAAU,qBAAqB;gBACxE,CAAC,CAAC,cAAc,MAAM,CAAC,IAAI,oBAAoB,CAAC;YAElD,OAAO,CAAC,GAAG,CAAC,gCAAgC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YAE3D,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;YAC3C,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE;gBAC5C,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;aAClC,CAAC,CAAC;YAEH,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,cAAwC,CAAC;YAE7C,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;gBAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC7B,MAAM,IAAI,IAAI,CAAC;gBAEf,0DAA0D;gBAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;gBAC5C,IAAI,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAC1B,QAAQ,GAAG,IAAI,CAAC;oBAChB,YAAY,CAAC,IAAI,EAAE,CAAC;oBACpB,IAAI,cAAc;wBAAE,cAAc,CAAC,IAAI,CAAC,CAAC;oBACzC,OAAO,CAAC,GAAG,CAAC,iBAAiB,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC,CAAC;YAEF,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACvC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAEvC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;gBACnD,cAAc,GAAG,OAAO,CAAC;YAC3B,CAAC,CAAC,CAAC;YAEH,MAAM,cAAc,GAAG,IAAI,OAAO,CAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;gBAC7D,UAAU,CAAC,GAAG,EAAE;oBACd,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACd,YAAY,CAAC,IAAI,EAAE,CAAC;wBACpB,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;oBAC/B,CAAC;gBACH,CAAC,EAAE,KAAK,CAAC,CAAC;YACZ,CAAC,CAAC,CAAC;YAEH,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC;YAElD,mBAAmB;YACnB,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YACnD,IAAI,aAAa,EAAE,CAAC;gBAClB,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;YAC1B,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;KACF,CAAC;IAEF,IAAI,SAAS,GAAiB,IAAI,CAAC;IACnC,IAAI,cAAc,GAAiB,IAAI,CAAC;IAExC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,+BAA+B,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC;YAC7D,aAAa,GAAG,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAEtC,MAAM,SAAS,GAAG,aAAa,CAAC;YAChC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;YAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAE/C,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;YAExC,OAAO;gBACL,GAAG,EAAE,SAAS;gBACd,QAAQ;gBACR,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,QAAQ,EAAE,OAAO;aAClB,CAAC;QAEJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,SAAS,GAAG,KAAK,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAEnE,wDAAwD;YACxD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC7C,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,8BAA8B,CAAC;gBACjD,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAC9B,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBACnC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC;gBAC/B,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;YAExD,IAAI,WAAW,IAAI,CAAC,cAAc,EAAE,CAAC;gBACnC,cAAc,GAAG,KAAK,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACrF,CAAC;YAED,IAAI,CAAC,KAAK,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,OAAO,CAAC,KAAK,CAAC,kDAAkD,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAEjF,2DAA2D;gBAC3D,IAAI,cAAc,EAAE,CAAC;oBACnB,OAAO,CAAC,KAAK,CAAC,iCAAiC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC;oBACzE,MAAM,cAAc,CAAC;gBACvB,CAAC;gBAED,MAAM,KAAK,CAAC;YACd,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC;QAC5B,aAAa,GAAG,IAAI,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,eAAe,EAAE,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,SAAS,CAAC,aAAa,CAAC,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,wBAAwB;AACxB;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,QAAa;IACvC,aAAa,GAAG,QAAQ,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,aAAa,GAAG,IAAI,CAAC;AACvB,CAAC"}
@@ -2,9 +2,21 @@
2
2
  * QR code display utilities
3
3
  */
4
4
  /**
5
- * Display QR code in terminal
5
+ * Display QR code in terminal with validation
6
6
  */
7
- export declare function displayQRCode(url: string): void;
7
+ export declare function displayQRCode(url: string): Promise<void>;
8
+ /**
9
+ * Generate QR code as ASCII string
10
+ */
11
+ export declare function generateQRCodeAscii(url: string): Promise<string>;
12
+ /**
13
+ * Generate QR code as ASCII string without ANSI colors
14
+ */
15
+ export declare function generateQRCodeAsciiPlain(url: string): Promise<string>;
16
+ /**
17
+ * Display QR code and optionally save to file
18
+ */
19
+ export declare function displayQRCodeAndSave(url: string, filepath?: string): Promise<string>;
8
20
  /**
9
21
  * Generate QR code as data URL
10
22
  */
@@ -1 +1 @@
1
- {"version":3,"file":"qrcode.d.ts","sourceRoot":"","sources":["../../../src/tunnel/qrcode.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAQ/C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAExE"}
1
+ {"version":3,"file":"qrcode.d.ts","sourceRoot":"","sources":["../../../src/tunnel/qrcode.ts"],"names":[],"mappings":"AAAA;;GAEG;AAuBH;;GAEG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB9D;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAetE;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgB3E;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAExE"}