dbctx 1.5.0 → 2.0.1

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 (141) hide show
  1. package/dist/app/assemble.d.mts.map +1 -1
  2. package/dist/app/assemble.mjs +20 -4
  3. package/dist/app/list.d.mts +4 -0
  4. package/dist/app/list.d.mts.map +1 -0
  5. package/dist/app/list.mjs +93 -0
  6. package/dist/app/load-introspection.d.mts +26 -0
  7. package/dist/app/load-introspection.d.mts.map +1 -0
  8. package/dist/app/load-introspection.mjs +89 -0
  9. package/dist/app/login.d.mts +2 -0
  10. package/dist/app/login.d.mts.map +1 -0
  11. package/dist/app/login.mjs +69 -0
  12. package/dist/app/open-url.d.mts +2 -0
  13. package/dist/app/open-url.d.mts.map +1 -1
  14. package/dist/app/open-url.mjs +8 -3
  15. package/dist/app/sample.d.mts +24 -0
  16. package/dist/app/sample.d.mts.map +1 -0
  17. package/dist/app/sample.mjs +257 -0
  18. package/dist/app/session.d.mts +1 -0
  19. package/dist/app/session.d.mts.map +1 -1
  20. package/dist/app/session.mjs +44 -4
  21. package/dist/app/tail.d.mts +13 -0
  22. package/dist/app/tail.d.mts.map +1 -0
  23. package/dist/app/tail.mjs +168 -0
  24. package/dist/db/check-constraints.d.mts +9 -0
  25. package/dist/db/check-constraints.d.mts.map +1 -0
  26. package/dist/db/check-constraints.mjs +17 -0
  27. package/dist/db/custom-types.d.mts +26 -0
  28. package/dist/db/custom-types.d.mts.map +1 -0
  29. package/dist/db/custom-types.mjs +61 -0
  30. package/dist/db/extensions.d.mts +8 -0
  31. package/dist/db/extensions.d.mts.map +1 -0
  32. package/dist/db/extensions.mjs +14 -0
  33. package/dist/db/functions.d.mts +11 -0
  34. package/dist/db/functions.d.mts.map +1 -0
  35. package/dist/db/functions.mjs +23 -0
  36. package/dist/db/index.d.mts +9 -0
  37. package/dist/db/index.d.mts.map +1 -1
  38. package/dist/db/index.mjs +10 -1
  39. package/dist/db/planner-stats.d.mts +33 -0
  40. package/dist/db/planner-stats.d.mts.map +1 -0
  41. package/dist/db/planner-stats.mjs +103 -0
  42. package/dist/db/rls.d.mts +21 -0
  43. package/dist/db/rls.d.mts.map +1 -0
  44. package/dist/db/rls.mjs +48 -0
  45. package/dist/db/sample.d.mts +16 -0
  46. package/dist/db/sample.d.mts.map +1 -0
  47. package/dist/db/sample.mjs +73 -0
  48. package/dist/db/sequences.d.mts +15 -0
  49. package/dist/db/sequences.d.mts.map +1 -0
  50. package/dist/db/sequences.mjs +31 -0
  51. package/dist/db/triggers.d.mts +11 -0
  52. package/dist/db/triggers.d.mts.map +1 -0
  53. package/dist/db/triggers.mjs +21 -0
  54. package/dist/flow/events.d.mts +115 -0
  55. package/dist/flow/events.d.mts.map +1 -0
  56. package/dist/flow/events.mjs +2 -0
  57. package/dist/flow/interpreter.d.mts +21 -0
  58. package/dist/flow/interpreter.d.mts.map +1 -0
  59. package/dist/flow/interpreter.mjs +605 -0
  60. package/dist/flow/projection.d.mts +17 -0
  61. package/dist/flow/projection.d.mts.map +1 -0
  62. package/dist/flow/projection.mjs +83 -0
  63. package/dist/flow/projection.test.d.mts +2 -0
  64. package/dist/flow/projection.test.d.mts.map +1 -0
  65. package/dist/flow/projection.test.mjs +162 -0
  66. package/dist/flow/reducer.d.mts +5 -0
  67. package/dist/flow/reducer.d.mts.map +1 -0
  68. package/dist/flow/reducer.mjs +306 -0
  69. package/dist/flow/reducer.test.d.mts +2 -0
  70. package/dist/flow/reducer.test.d.mts.map +1 -0
  71. package/dist/flow/reducer.test.mjs +479 -0
  72. package/dist/flow/run.d.mts +3 -0
  73. package/dist/flow/run.d.mts.map +1 -0
  74. package/dist/flow/run.mjs +89 -0
  75. package/dist/flow/states.d.mts +54 -0
  76. package/dist/flow/states.d.mts.map +1 -0
  77. package/dist/flow/states.mjs +39 -0
  78. package/dist/index.d.mts +7 -1
  79. package/dist/index.d.mts.map +1 -1
  80. package/dist/index.mjs +112 -13
  81. package/dist/lib/atomic-write.d.mts +4 -0
  82. package/dist/lib/atomic-write.d.mts.map +1 -0
  83. package/dist/lib/atomic-write.mjs +75 -0
  84. package/dist/lib/stream-job.d.mts +19 -0
  85. package/dist/lib/stream-job.d.mts.map +1 -0
  86. package/dist/lib/stream-job.mjs +55 -0
  87. package/dist/lib/trpc-url.mjs +2 -2
  88. package/dist/lib/trpc.mjs +2 -2
  89. package/dist/logger.d.mts.map +1 -1
  90. package/dist/logger.mjs +6 -3
  91. package/dist/providers/TrpcProvider.js +3 -3
  92. package/dist/store.d.mts +95 -2
  93. package/dist/store.d.mts.map +1 -1
  94. package/dist/store.mjs +64 -1
  95. package/dist/ui/App.d.ts +1 -1
  96. package/dist/ui/App.d.ts.map +1 -1
  97. package/dist/ui/App.js +22 -4
  98. package/dist/ui/components/Analyze.d.ts +10 -0
  99. package/dist/ui/components/Analyze.d.ts.map +1 -0
  100. package/dist/ui/components/Analyze.js +54 -0
  101. package/dist/ui/components/Billing.d.ts +10 -0
  102. package/dist/ui/components/Billing.d.ts.map +1 -0
  103. package/dist/ui/components/Billing.js +40 -0
  104. package/dist/ui/components/DB.d.ts.map +1 -1
  105. package/dist/ui/components/DB.js +2 -2
  106. package/dist/ui/components/DatabasePicker.d.ts +13 -0
  107. package/dist/ui/components/DatabasePicker.d.ts.map +1 -0
  108. package/dist/ui/components/DatabasePicker.js +79 -0
  109. package/dist/ui/components/Enrich.d.ts +10 -0
  110. package/dist/ui/components/Enrich.d.ts.map +1 -0
  111. package/dist/ui/components/Enrich.js +41 -0
  112. package/dist/ui/components/Gate.js +2 -2
  113. package/dist/ui/components/Introspect.d.ts.map +1 -1
  114. package/dist/ui/components/Introspect.js +2 -2
  115. package/dist/ui/components/IntrospectionUpload.d.ts +10 -0
  116. package/dist/ui/components/IntrospectionUpload.d.ts.map +1 -0
  117. package/dist/ui/components/IntrospectionUpload.js +30 -0
  118. package/dist/ui/components/Login.d.ts +19 -0
  119. package/dist/ui/components/Login.d.ts.map +1 -0
  120. package/dist/ui/components/Login.js +38 -0
  121. package/dist/ui/components/OutputJson.d.ts.map +1 -1
  122. package/dist/ui/components/OutputJson.js +2 -2
  123. package/dist/ui/components/SSH.d.ts.map +1 -1
  124. package/dist/ui/components/SSH.js +2 -2
  125. package/dist/ui/components/SamplesUpload.d.ts +10 -0
  126. package/dist/ui/components/SamplesUpload.d.ts.map +1 -0
  127. package/dist/ui/components/SamplesUpload.js +24 -0
  128. package/dist/ui/components/Sampling.d.ts +10 -0
  129. package/dist/ui/components/Sampling.d.ts.map +1 -0
  130. package/dist/ui/components/Sampling.js +58 -0
  131. package/dist/ui/components/Session.d.ts.map +1 -1
  132. package/dist/ui/components/Session.js +4 -4
  133. package/dist/ui/components/Spinner.d.ts.map +1 -1
  134. package/dist/ui/components/Spinner.js +17 -5
  135. package/dist/validatePaths.d.mts +1 -1
  136. package/dist/validatePaths.d.mts.map +1 -1
  137. package/dist/validatePaths.mjs +5 -1
  138. package/package.json +7 -7
  139. package/dist/app/index.d.mts +0 -3
  140. package/dist/app/index.d.mts.map +0 -1
  141. package/dist/app/index.mjs +0 -156
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbctx",
3
- "version": "1.5.0",
3
+ "version": "2.0.1",
4
4
  "description": "AI-enriched database context for humans and coding agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
@@ -28,9 +28,6 @@
28
28
  "url": "https://github.com/dbctx/dbctx"
29
29
  },
30
30
  "license": "MIT",
31
- "imports": {
32
- "#client/*": "./dist/*"
33
- },
34
31
  "dependencies": {
35
32
  "@tanstack/react-query": "5.90.20",
36
33
  "@trpc/client": "11.8.1",
@@ -50,9 +47,11 @@
50
47
  "scope-utilities": "2.2.1",
51
48
  "ssh-config": "5.0.4",
52
49
  "ssh2": "1.17.0",
50
+ "terminal-link": "5.0.0",
53
51
  "uuidv7": "1.0.2",
54
52
  "winston": "3.19.0",
55
- "zod": "4.3.6"
53
+ "zod": "4.3.6",
54
+ "@dbctx/common": "0.0.0"
56
55
  },
57
56
  "devDependencies": {
58
57
  "@types/node": "24.0.0",
@@ -63,7 +62,7 @@
63
62
  "cross-env": "7.0.3",
64
63
  "prettier": "3.8.1",
65
64
  "typescript": "5.9.3",
66
- "@dbctx/core": "1.1.1"
65
+ "@dbctx/core": "2.0.5"
67
66
  },
68
67
  "volta": {
69
68
  "node": "24.0.0"
@@ -75,6 +74,7 @@
75
74
  "start": "tsc && node ./dist/index.mjs",
76
75
  "dev": "tsc --watch --preserveWatchOutput",
77
76
  "build": "tsc",
78
- "build:ts:watch": "tsc --watch --preserveWatchOutput"
77
+ "build:ts:watch": "tsc --watch --preserveWatchOutput",
78
+ "test": "tsc && node --test dist/flow/*.test.mjs"
79
79
  }
80
80
  }
@@ -1,3 +0,0 @@
1
- import { TStore } from '../store.mjs';
2
- export declare function run(store: TStore): Promise<void>;
3
- //# sourceMappingURL=index.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"./src/","sources":["app/index.mts"],"names":[],"mappings":"AAIA,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAgBpC,wBAAsB,GAAG,CAAC,KAAK,EAAE,MAAM,iBAyLtC"}
@@ -1,156 +0,0 @@
1
- import { existsSync } from 'node:fs';
2
- import { mkdir, writeFile } from 'node:fs/promises';
3
- import { dirname } from 'node:path';
4
- import { connectSSH } from './ssh.mjs';
5
- import { connectDB } from './db.mjs';
6
- import { assembleDatabase } from './assemble.mjs';
7
- import { createSession, waitForAuthorization, connectAccount, checkGate, } from './session.mjs';
8
- import { readConfig, flushConfig } from './config.mjs';
9
- import { TRPCClientError } from '@trpc/client';
10
- import { when, runInAction } from 'mobx';
11
- import { DBCTX_DEV } from '#client/lib/env.mjs';
12
- import { logger } from '../logger.mjs';
13
- export async function run(store) {
14
- try {
15
- const cleanupSSH = await connectSSH(store);
16
- if (store.steps.sshConnection.enabled) {
17
- await when(() => ['connected', 'error'].includes(store.steps.sshConnection.state));
18
- if (store.steps.sshConnection.state === 'error') {
19
- cleanupSSH?.();
20
- return;
21
- }
22
- if (store.outputOptions.stopAfter === 'ssh-connect') {
23
- cleanupSSH?.();
24
- process.exit(0);
25
- }
26
- }
27
- const db = await connectDB(store);
28
- await when(() => ['connected', 'error'].includes(store.steps.databaseConnection.state));
29
- if (store.steps.databaseConnection.state === 'error') {
30
- db?.cleanup();
31
- cleanupSSH?.();
32
- return;
33
- }
34
- if (store.outputOptions.stopAfter === 'db-connect') {
35
- db?.cleanup();
36
- cleanupSSH?.();
37
- process.exit(0);
38
- }
39
- if (db) {
40
- const result = await assembleDatabase(db.pool, store);
41
- if (DBCTX_DEV) {
42
- const { databaseIntrospectionSchema } = await import('@dbctx/core/schemas/introspection');
43
- databaseIntrospectionSchema.parse(result);
44
- }
45
- if (store.outputOptions.stopAfter === 'introspection') {
46
- db.pool.end();
47
- cleanupSSH?.();
48
- process.exit(0);
49
- }
50
- // Account + gate check (before explanation prompt)
51
- const config = await readConfig();
52
- try {
53
- const sessionId = await createSession(db.pool, result, store, config.token ?? null, config.device_id);
54
- if (config.token) {
55
- try {
56
- await connectAccount(config.token, store);
57
- const canContinue = await checkGate(config.token, store);
58
- if (!canContinue) {
59
- db.pool.end();
60
- return;
61
- }
62
- }
63
- catch (err) {
64
- if (err instanceof TRPCClientError &&
65
- (err.data?.code === 'UNAUTHORIZED' ||
66
- err.data?.code === 'NOT_FOUND')) {
67
- await flushConfig();
68
- }
69
- else {
70
- throw err;
71
- }
72
- }
73
- }
74
- if (store.steps.account.state !== 'connected') {
75
- await waitForAuthorization(sessionId, store);
76
- const freshToken = (await readConfig()).token;
77
- if (freshToken) {
78
- const canContinue = await checkGate(freshToken, store);
79
- if (!canContinue) {
80
- db.pool.end();
81
- return;
82
- }
83
- }
84
- }
85
- }
86
- catch (err) {
87
- runInAction(() => {
88
- store.steps.account.state = 'error';
89
- store.steps.account.error =
90
- err instanceof Error
91
- ? err.message
92
- : 'Session creation failed';
93
- });
94
- }
95
- // User explanation step
96
- if (store.outputOptions.explanation) {
97
- runInAction(() => {
98
- store.steps.userExplanation.state = 'done';
99
- store.steps.userExplanation.value =
100
- store.outputOptions.explanation;
101
- });
102
- result.userExplanation = store.outputOptions.explanation;
103
- }
104
- else {
105
- runInAction(() => {
106
- store.steps.userExplanation.state = 'prompting';
107
- });
108
- await when(() => store.steps.userExplanation.state === 'done');
109
- result.userExplanation = store.steps.userExplanation.value;
110
- }
111
- if (store.outputOptions.outputIntrospectionJson) {
112
- const outputPath = store.outputOptions.outputIntrospectionJson;
113
- if (existsSync(outputPath) && !store.outputOptions.overwrite) {
114
- runInAction(() => {
115
- store.steps.outputJson.state = 'prompting-overwrite';
116
- store.steps.outputJson.path = outputPath;
117
- });
118
- await when(() => store.steps.outputJson.confirmed !== null);
119
- if (!store.steps.outputJson.confirmed) {
120
- db.pool.end();
121
- cleanupSSH?.();
122
- process.exit(0);
123
- }
124
- }
125
- runInAction(() => {
126
- store.steps.outputJson.state = 'writing';
127
- store.steps.outputJson.path = outputPath;
128
- });
129
- try {
130
- await mkdir(dirname(outputPath), { recursive: true });
131
- await writeFile(outputPath, JSON.stringify(result, null, 2));
132
- runInAction(() => {
133
- store.steps.outputJson.state = 'done';
134
- });
135
- }
136
- catch (err) {
137
- runInAction(() => {
138
- store.steps.outputJson.state = 'error';
139
- store.steps.outputJson.error =
140
- err instanceof Error ? err.message : String(err);
141
- });
142
- db.pool.end();
143
- cleanupSSH?.();
144
- return;
145
- }
146
- }
147
- db.pool.end();
148
- }
149
- }
150
- catch (err) {
151
- if (DBCTX_DEV) {
152
- logger.error(`${err}`, { error: err });
153
- }
154
- }
155
- }
156
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXgubWpzIiwic291cmNlUm9vdCI6Ii4vc3JjLyIsInNvdXJjZXMiOlsiYXBwL2luZGV4Lm10cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBQ25DLE9BQU8sRUFBQyxLQUFLLEVBQUUsU0FBUyxFQUFDLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFDLE9BQU8sRUFBQyxNQUFNLFdBQVcsQ0FBQztBQUdsQyxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQ3JDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDbkMsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEQsT0FBTyxFQUNILGFBQWEsRUFDYixvQkFBb0IsRUFDcEIsY0FBYyxFQUNkLFNBQVMsR0FDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsVUFBVSxFQUFFLFdBQVcsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUNyRCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFBQyxJQUFJLEVBQUUsV0FBVyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ3ZDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUM5QyxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRXJDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsR0FBRyxDQUFDLEtBQWE7SUFDbkMsSUFBSSxDQUFDO1FBQ0QsTUFBTSxVQUFVLEdBQUcsTUFBTSxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFM0MsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNwQyxNQUFNLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FDWixDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxRQUFR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LENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ3pELENBQUMsQ0FBQyxDQUFDO29CQUNILEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7b0JBQ2QsVUFBVSxFQUFFLEVBQUUsQ0FBQztvQkFDZixPQUFPO2dCQUNYLENBQUM7WUFDTCxDQUFDO1lBRUQsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNsQixDQUFDO0lBQ0wsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDWCxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQ1osTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQyxDQUFDLENBQUM7UUFDekMsQ0FBQztJQUNMLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtleGlzdHNTeW5jfSBmcm9tICdub2RlOmZzJztcbmltcG9ydCB7bWtkaXIsIHdyaXRlRmlsZX0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQge2Rpcm5hbWV9IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB7VFN0b3JlfSBmcm9tICcuLi9zdG9yZS5tanMnO1xuaW1wb3J0IHtjb25uZWN0U1NIfSBmcm9tICcuL3NzaC5tanMnO1xuaW1wb3J0IHtjb25uZWN0REJ9IGZyb20gJy4vZGIubWpzJztcbmltcG9ydCB7YXNzZW1ibGVEYXRhYmFzZX0gZnJvbSAnLi9hc3NlbWJsZS5tanMnO1xuaW1wb3J0IHtcbiAgICBjcmVhdGVTZXNzaW9uLFxuICAgIHdhaXRGb3JBdXRob3JpemF0aW9uLFxuICAgIGNvbm5lY3RBY2NvdW50LFxuICAgIGNoZWNrR2F0ZSxcbn0gZnJvbSAnLi9zZXNzaW9uLm1qcyc7XG5pbXBvcnQge3JlYWRDb25maWcsIGZsdXNoQ29uZmlnfSBmcm9tICcuL2NvbmZpZy5tanMnO1xuaW1wb3J0IHtUUlBDQ2xpZW50RXJyb3J9IGZyb20gJ0B0cnBjL2NsaWVudCc7XG5pbXBvcnQge3doZW4sIHJ1bkluQWN0aW9ufSBmcm9tICdtb2J4JztcbmltcG9ydCB7REJDVFhfREVWfSBmcm9tICcjY2xpZW50L2xpYi9lbnYubWpzJztcbmltcG9ydCB7bG9nZ2VyfSBmcm9tICcuLi9sb2dnZXIubWpzJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bihzdG9yZTogVFN0b3JlKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgY2xlYW51cFNTSCA9IGF3YWl0IGNvbm5lY3RTU0goc3RvcmUpO1xuXG4gICAgICAgIGlmIChzdG9yZS5zdGVwcy5zc2hDb25uZWN0aW9uLmVuYWJsZWQpIHtcbiAgICAgICAgICAgIGF3YWl0IHdoZW4oKCkgPT5cbiAgICAgICAgICAgICAgICBbJ2Nvbm5lY3RlZCcsICdlcnJvciddLmluY2x1ZGVzKFxuICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy5zc2hDb25uZWN0aW9uLnN0YXRlLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBpZiAoc3RvcmUuc3RlcHMuc3NoQ29ubmVjdGlvbi5zdGF0ZSA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgICAgICAgIGNsZWFudXBTU0g/LigpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN0b3JlLm91dHB1dE9wdGlvbnMuc3RvcEFmdGVyID09PSAnc3NoLWNvbm5lY3QnKSB7XG4gICAgICAgICAgICAgICAgY2xlYW51cFNTSD8uKCk7XG4gICAgICAgICAgICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGIgPSBhd2FpdCBjb25uZWN0REIoc3RvcmUpO1xuXG4gICAgICAgIGF3YWl0IHdoZW4oKCkgPT5cbiAgICAgICAgICAgIFsnY29ubmVjdGVkJywgJ2Vycm9yJ10uaW5jbHVkZXMoXG4gICAgICAgICAgICAgICAgc3RvcmUuc3RlcHMuZGF0YWJhc2VDb25uZWN0aW9uLnN0YXRlLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoc3RvcmUuc3RlcHMuZGF0YWJhc2VDb25uZWN0aW9uLnN0YXRlID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgICBkYj8uY2xlYW51cCgpO1xuICAgICAgICAgICAgY2xlYW51cFNTSD8uKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RvcmUub3V0cHV0T3B0aW9ucy5zdG9wQWZ0ZXIgPT09ICdkYi1jb25uZWN0Jykge1xuICAgICAgICAgICAgZGI/LmNsZWFudXAoKTtcbiAgICAgICAgICAgIGNsZWFudXBTU0g/LigpO1xuICAgICAgICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRiKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhc3NlbWJsZURhdGFiYXNlKGRiLnBvb2wsIHN0b3JlKTtcblxuICAgICAgICAgICAgaWYgKERCQ1RYX0RFVikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHtkYXRhYmFzZUludHJvc3BlY3Rpb25TY2hlbWF9ID1cbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgaW1wb3J0KCdAZGJjdHgvY29yZS9zY2hlbWFzL2ludHJvc3BlY3Rpb24nKTtcbiAgICAgICAgICAgICAgICBkYXRhYmFzZUludHJvc3BlY3Rpb25TY2hlbWEucGFyc2UocmVzdWx0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN0b3JlLm91dHB1dE9wdGlvbnMuc3RvcEFmdGVyID09PSAnaW50cm9zcGVjdGlvbicpIHtcbiAgICAgICAgICAgICAgICBkYi5wb29sLmVuZCgpO1xuICAgICAgICAgICAgICAgIGNsZWFudXBTU0g/LigpO1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWNjb3VudCArIGdhdGUgY2hlY2sgKGJlZm9yZSBleHBsYW5hdGlvbiBwcm9tcHQpXG4gICAgICAgICAgICBjb25zdCBjb25maWcgPSBhd2FpdCByZWFkQ29uZmlnKCk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gYXdhaXQgY3JlYXRlU2Vzc2lvbihcbiAgICAgICAgICAgICAgICAgICAgZGIucG9vbCxcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgICAgICAgICAgICBzdG9yZSxcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLnRva2VuID8/IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5kZXZpY2VfaWQsXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIGlmIChjb25maWcudG9rZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBY2NvdW50KGNvbmZpZy50b2tlbiwgc3RvcmUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuQ29udGludWUgPSBhd2FpdCBjaGVja0dhdGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLnRva2VuLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlLFxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2FuQ29udGludWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYi5wb29sLmVuZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyIGluc3RhbmNlb2YgVFJQQ0NsaWVudEVycm9yICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVyci5kYXRhPy5jb2RlID09PSAnVU5BVVRIT1JJWkVEJyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnIuZGF0YT8uY29kZSA9PT0gJ05PVF9GT1VORCcpXG4gICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBmbHVzaENvbmZpZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoc3RvcmUuc3RlcHMuYWNjb3VudC5zdGF0ZSAhPT0gJ2Nvbm5lY3RlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgd2FpdEZvckF1dGhvcml6YXRpb24oc2Vzc2lvbklkLCBzdG9yZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZnJlc2hUb2tlbiA9IChhd2FpdCByZWFkQ29uZmlnKCkpLnRva2VuO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZnJlc2hUb2tlbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuQ29udGludWUgPSBhd2FpdCBjaGVja0dhdGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlc2hUb2tlbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNhbkNvbnRpbnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGIucG9vbC5lbmQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBydW5JbkFjdGlvbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHN0b3JlLnN0ZXBzLmFjY291bnQuc3RhdGUgPSAnZXJyb3InO1xuICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy5hY2NvdW50LmVycm9yID1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVyciBpbnN0YW5jZW9mIEVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBlcnIubWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJ1Nlc3Npb24gY3JlYXRpb24gZmFpbGVkJztcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVXNlciBleHBsYW5hdGlvbiBzdGVwXG4gICAgICAgICAgICBpZiAoc3RvcmUub3V0cHV0T3B0aW9ucy5leHBsYW5hdGlvbikge1xuICAgICAgICAgICAgICAgIHJ1bkluQWN0aW9uKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3RvcmUuc3RlcHMudXNlckV4cGxhbmF0aW9uLnN0YXRlID0gJ2RvbmUnO1xuICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy51c2VyRXhwbGFuYXRpb24udmFsdWUgPVxuICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmUub3V0cHV0T3B0aW9ucy5leHBsYW5hdGlvbjtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXN1bHQudXNlckV4cGxhbmF0aW9uID0gc3RvcmUub3V0cHV0T3B0aW9ucy5leHBsYW5hdGlvbjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcnVuSW5BY3Rpb24oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy51c2VyRXhwbGFuYXRpb24uc3RhdGUgPSAncHJvbXB0aW5nJztcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBhd2FpdCB3aGVuKCgpID0+IHN0b3JlLnN0ZXBzLnVzZXJFeHBsYW5hdGlvbi5zdGF0ZSA9PT0gJ2RvbmUnKTtcbiAgICAgICAgICAgICAgICByZXN1bHQudXNlckV4cGxhbmF0aW9uID0gc3RvcmUuc3RlcHMudXNlckV4cGxhbmF0aW9uLnZhbHVlITtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN0b3JlLm91dHB1dE9wdGlvbnMub3V0cHV0SW50cm9zcGVjdGlvbkpzb24pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRQYXRoID0gc3RvcmUub3V0cHV0T3B0aW9ucy5vdXRwdXRJbnRyb3NwZWN0aW9uSnNvbjtcblxuICAgICAgICAgICAgICAgIGlmIChleGlzdHNTeW5jKG91dHB1dFBhdGgpICYmICFzdG9yZS5vdXRwdXRPcHRpb25zLm92ZXJ3cml0ZSkge1xuICAgICAgICAgICAgICAgICAgICBydW5JbkFjdGlvbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy5vdXRwdXRKc29uLnN0YXRlID0gJ3Byb21wdGluZy1vdmVyd3JpdGUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmUuc3RlcHMub3V0cHV0SnNvbi5wYXRoID0gb3V0cHV0UGF0aDtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgd2hlbigoKSA9PiBzdG9yZS5zdGVwcy5vdXRwdXRKc29uLmNvbmZpcm1lZCAhPT0gbnVsbCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdG9yZS5zdGVwcy5vdXRwdXRKc29uLmNvbmZpcm1lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGIucG9vbC5lbmQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFudXBTU0g/LigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcnVuSW5BY3Rpb24oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy5vdXRwdXRKc29uLnN0YXRlID0gJ3dyaXRpbmcnO1xuICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy5vdXRwdXRKc29uLnBhdGggPSBvdXRwdXRQYXRoO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgbWtkaXIoZGlybmFtZShvdXRwdXRQYXRoKSwge3JlY3Vyc2l2ZTogdHJ1ZX0pO1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCB3cml0ZUZpbGUoXG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRQYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkocmVzdWx0LCBudWxsLCAyKSxcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgcnVuSW5BY3Rpb24oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmUuc3RlcHMub3V0cHV0SnNvbi5zdGF0ZSA9ICdkb25lJztcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bkluQWN0aW9uKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlLnN0ZXBzLm91dHB1dEpzb24uc3RhdGUgPSAnZXJyb3InO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmUuc3RlcHMub3V0cHV0SnNvbi5lcnJvciA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgZGIucG9vbC5lbmQoKTtcbiAgICAgICAgICAgICAgICAgICAgY2xlYW51cFNTSD8uKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRiLnBvb2wuZW5kKCk7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKERCQ1RYX0RFVikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGAke2Vycn1gLCB7ZXJyb3I6IGVycn0pO1xuICAgICAgICB9XG4gICAgfVxufVxuIl19