@kdonev/termscape 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +288 -0
- package/dist/agents/env.d.ts +36 -0
- package/dist/agents/env.d.ts.map +1 -0
- package/dist/agents/env.js +61 -0
- package/dist/agents/env.js.map +1 -0
- package/dist/agents/profiles.d.ts +45 -0
- package/dist/agents/profiles.d.ts.map +1 -0
- package/dist/agents/profiles.js +123 -0
- package/dist/agents/profiles.js.map +1 -0
- package/dist/agents/resolve.d.ts +16 -0
- package/dist/agents/resolve.d.ts.map +1 -0
- package/dist/agents/resolve.js +71 -0
- package/dist/agents/resolve.js.map +1 -0
- package/dist/agents/router.d.ts +29 -0
- package/dist/agents/router.d.ts.map +1 -0
- package/dist/agents/router.js +83 -0
- package/dist/agents/router.js.map +1 -0
- package/dist/agents/tokens.d.ts +21 -0
- package/dist/agents/tokens.d.ts.map +1 -0
- package/dist/agents/tokens.js +39 -0
- package/dist/agents/tokens.js.map +1 -0
- package/dist/agents/wiring.d.ts +30 -0
- package/dist/agents/wiring.d.ts.map +1 -0
- package/dist/agents/wiring.js +110 -0
- package/dist/agents/wiring.js.map +1 -0
- package/dist/browser.d.ts +13 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +34 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +200 -0
- package/dist/cli.js.map +1 -0
- package/dist/db/index.d.ts +14 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +24 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrations.d.ts +15 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +176 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/store.d.ts +71 -0
- package/dist/db/store.d.ts.map +1 -0
- package/dist/db/store.js +341 -0
- package/dist/db/store.js.map +1 -0
- package/dist/hub.d.ts +188 -0
- package/dist/hub.d.ts.map +1 -0
- package/dist/hub.js +636 -0
- package/dist/hub.js.map +1 -0
- package/dist/hub.tgz +0 -0
- package/dist/mcp/server.d.ts +31 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +66 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/paths.d.ts +27 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +31 -0
- package/dist/paths.js.map +1 -0
- package/dist/protocol/address.d.ts +15 -0
- package/dist/protocol/address.d.ts.map +1 -0
- package/dist/protocol/address.js +39 -0
- package/dist/protocol/address.js.map +1 -0
- package/dist/protocol/domain.d.ts +151 -0
- package/dist/protocol/domain.d.ts.map +1 -0
- package/dist/protocol/domain.js +104 -0
- package/dist/protocol/domain.js.map +1 -0
- package/dist/protocol/index.d.ts +7 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +7 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/inject.d.ts +29 -0
- package/dist/protocol/inject.d.ts.map +1 -0
- package/dist/protocol/inject.js +40 -0
- package/dist/protocol/inject.js.map +1 -0
- package/dist/protocol/mcp-tools.d.ts +45 -0
- package/dist/protocol/mcp-tools.d.ts.map +1 -0
- package/dist/protocol/mcp-tools.js +46 -0
- package/dist/protocol/mcp-tools.js.map +1 -0
- package/dist/protocol/peer.d.ts +304 -0
- package/dist/protocol/peer.d.ts.map +1 -0
- package/dist/protocol/peer.js +183 -0
- package/dist/protocol/peer.js.map +1 -0
- package/dist/protocol/ws.d.ts +416 -0
- package/dist/protocol/ws.d.ts.map +1 -0
- package/dist/protocol/ws.js +119 -0
- package/dist/protocol/ws.js.map +1 -0
- package/dist/remote/deployer.d.ts +78 -0
- package/dist/remote/deployer.d.ts.map +1 -0
- package/dist/remote/deployer.js +216 -0
- package/dist/remote/deployer.js.map +1 -0
- package/dist/remote/enroll.d.ts +14 -0
- package/dist/remote/enroll.d.ts.map +1 -0
- package/dist/remote/enroll.js +244 -0
- package/dist/remote/enroll.js.map +1 -0
- package/dist/remote/join-script.d.ts +29 -0
- package/dist/remote/join-script.d.ts.map +1 -0
- package/dist/remote/join-script.js +709 -0
- package/dist/remote/join-script.js.map +1 -0
- package/dist/remote/join.d.ts +19 -0
- package/dist/remote/join.d.ts.map +1 -0
- package/dist/remote/join.js +195 -0
- package/dist/remote/join.js.map +1 -0
- package/dist/remote/lan.d.ts +45 -0
- package/dist/remote/lan.d.ts.map +1 -0
- package/dist/remote/lan.js +105 -0
- package/dist/remote/lan.js.map +1 -0
- package/dist/remote/peer-serve.d.ts +27 -0
- package/dist/remote/peer-serve.d.ts.map +1 -0
- package/dist/remote/peer-serve.js +274 -0
- package/dist/remote/peer-serve.js.map +1 -0
- package/dist/remote/peer.d.ts +62 -0
- package/dist/remote/peer.d.ts.map +1 -0
- package/dist/remote/peer.js +250 -0
- package/dist/remote/peer.js.map +1 -0
- package/dist/remote/registry.d.ts +104 -0
- package/dist/remote/registry.d.ts.map +1 -0
- package/dist/remote/registry.js +359 -0
- package/dist/remote/registry.js.map +1 -0
- package/dist/remote/tarball.d.ts +9 -0
- package/dist/remote/tarball.d.ts.map +1 -0
- package/dist/remote/tarball.js +22 -0
- package/dist/remote/tarball.js.map +1 -0
- package/dist/server.d.ts +54 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +438 -0
- package/dist/server.js.map +1 -0
- package/dist/session/manager.d.ts +104 -0
- package/dist/session/manager.d.ts.map +1 -0
- package/dist/session/manager.js +421 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/session/pty.d.ts +114 -0
- package/dist/session/pty.d.ts.map +1 -0
- package/dist/session/pty.js +300 -0
- package/dist/session/pty.js.map +1 -0
- package/package.json +49 -0
- package/web/assets/index-B2JtCtHa.css +1 -0
- package/web/assets/index-BOqZOoep.js +107 -0
- package/web/index.html +13 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"join-script.js","sourceRoot":"","sources":["../../src/remote/join-script.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,kFAAkF;AAClF,SAAS,EAAE,CAAC,CAAS;IACnB,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AACzC,CAAC;AAED,uEAAuE;AACvE,MAAM,SAAS,GAAG,sCAAsC,CAAC;AAEzD,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,KAAa;IAC3D,OAAO;kDACyC,MAAM;;;UAG9C,EAAE,CAAC,MAAM,CAAC;aACP,EAAE,CAAC,KAAK,CAAC;;YAEV,EAAE,CAAC,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqSxB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,KAAa;IAChE,OAAO,mDAAmD,MAAM;;;;eAInD,EAAE,CAAC,MAAM,CAAC;eACV,EAAE,CAAC,KAAK,CAAC;;eAET,EAAE,CAAC,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2W3B,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Hub } from '../hub.js';
|
|
2
|
+
import type { PeerServer } from './peer-serve.js';
|
|
3
|
+
export interface JoinOptions {
|
|
4
|
+
hub: Hub;
|
|
5
|
+
peerServer: PeerServer;
|
|
6
|
+
/** The canvas hub's origin, e.g. http://192.168.1.40:7333 */
|
|
7
|
+
hubUrl: string;
|
|
8
|
+
/** Single-use enrollment token; ignored once we hold a durable host token. */
|
|
9
|
+
joinToken?: string;
|
|
10
|
+
label?: string;
|
|
11
|
+
/** Where to keep the durable host token. Defaults to the hub home. */
|
|
12
|
+
tokenFile?: string;
|
|
13
|
+
log?: (line: string) => void;
|
|
14
|
+
}
|
|
15
|
+
export interface JoinLink {
|
|
16
|
+
stop(): void;
|
|
17
|
+
}
|
|
18
|
+
export declare function joinCanvas(opts: JoinOptions): JoinLink;
|
|
19
|
+
//# sourceMappingURL=join.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"join.d.ts","sourceRoot":"","sources":["../../src/remote/join.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAGrC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAuBlD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,GAAG,CAAC;IACT,UAAU,EAAE,UAAU,CAAC;IACvB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,IAAI,IAAI,CAAC;CACd;AAkCD,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,QAAQ,CAgJtD"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, rmSync } from 'node:fs';
|
|
2
|
+
import { hostname, platform, arch, homedir } from 'node:os';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
import { WebSocket } from 'ws';
|
|
5
|
+
import { PEER_SCHEMA_VERSION, PeerResponse } from '../protocol/index.js';
|
|
6
|
+
import { HUB_VERSION } from '../hub.js';
|
|
7
|
+
import { paths } from '../paths.js';
|
|
8
|
+
/**
|
|
9
|
+
* The joining machine's side of enrollment.
|
|
10
|
+
*
|
|
11
|
+
* It dials the canvas hub and then answers its requests — the same role a hub
|
|
12
|
+
* deployed over SSH plays on its `/peer` endpoint, just over a socket opened
|
|
13
|
+
* from this end. That is why this file is thin: `peer-serve.ts` does the work,
|
|
14
|
+
* and all that is left here is getting a socket to hand it and keeping one.
|
|
15
|
+
*
|
|
16
|
+
* The enrollment token is spent once. What comes back in `welcome` is a
|
|
17
|
+
* durable host token written to disk, so every later start — a reboot, a
|
|
18
|
+
* crash, a dropped link — rejoins silently with no second trip to the
|
|
19
|
+
* download page.
|
|
20
|
+
*
|
|
21
|
+
* The two TERMSCAPE_JOIN* markers below exist for the installer to grep. A hub
|
|
22
|
+
* that has started is not a hub that has joined, and reporting success on the
|
|
23
|
+
* former is how you end up telling someone they are connected when the canvas
|
|
24
|
+
* refused them.
|
|
25
|
+
*/
|
|
26
|
+
const MAX_BACKOFF_MS = 15_000;
|
|
27
|
+
function readHostToken(file) {
|
|
28
|
+
try {
|
|
29
|
+
const t = readFileSync(file, 'utf8').trim();
|
|
30
|
+
return t || null;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function writeHostToken(file, token) {
|
|
37
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
38
|
+
writeFileSync(file, token, { mode: 0o600 });
|
|
39
|
+
}
|
|
40
|
+
/** Drop a credential the canvas has told us it does not recognise. */
|
|
41
|
+
function clearHostToken(file) {
|
|
42
|
+
try {
|
|
43
|
+
rmSync(file, { force: true });
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// Nothing here depends on it being gone; the retry ignores it anyway.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** http://host:port -> ws://host:port/peer-in */
|
|
50
|
+
function peerInUrl(hubUrl) {
|
|
51
|
+
const u = new URL(hubUrl);
|
|
52
|
+
u.protocol = u.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
53
|
+
u.pathname = '/peer-in';
|
|
54
|
+
u.search = '';
|
|
55
|
+
return u.toString();
|
|
56
|
+
}
|
|
57
|
+
export function joinCanvas(opts) {
|
|
58
|
+
const log = opts.log ?? ((line) => console.log(`[join] ${line}`));
|
|
59
|
+
/**
|
|
60
|
+
* A refusal we cannot retry our way out of. The hub was started only to
|
|
61
|
+
* join, so there is nothing left for it to do; whoever owns the process
|
|
62
|
+
* listens for this and stops, which also frees the install for a re-run.
|
|
63
|
+
*/
|
|
64
|
+
const fatal = (message) => {
|
|
65
|
+
stopped = true;
|
|
66
|
+
log(`TERMSCAPE_JOIN_FAILED=${message}`);
|
|
67
|
+
opts.hub.emit('joinFailed', message);
|
|
68
|
+
};
|
|
69
|
+
const tokenFile = opts.tokenFile ?? paths.hostTokenFile();
|
|
70
|
+
const url = peerInUrl(opts.hubUrl);
|
|
71
|
+
let backoff = 500;
|
|
72
|
+
let stopped = false;
|
|
73
|
+
let socket = null;
|
|
74
|
+
let timer = null;
|
|
75
|
+
/**
|
|
76
|
+
* Whether the stored host token has already been tried and rejected. Once
|
|
77
|
+
* it has, the enrollment key the installer supplied is the only thing left
|
|
78
|
+
* worth trying, and it is tried exactly once.
|
|
79
|
+
*/
|
|
80
|
+
let hostTokenSpent = false;
|
|
81
|
+
function dial() {
|
|
82
|
+
if (stopped)
|
|
83
|
+
return;
|
|
84
|
+
const hostToken = hostTokenSpent ? null : readHostToken(tokenFile);
|
|
85
|
+
if (!hostToken && !opts.joinToken) {
|
|
86
|
+
fatal('no enrollment token and no stored host token; nothing to join with');
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const ws = new WebSocket(url);
|
|
90
|
+
socket = ws;
|
|
91
|
+
const usedHostToken = hostToken !== null;
|
|
92
|
+
// Set once the canvas hub accepts us, so a rejection is not retried
|
|
93
|
+
// forever as if it were a network blip.
|
|
94
|
+
let welcomed = false;
|
|
95
|
+
ws.on('open', () => {
|
|
96
|
+
const hello = {
|
|
97
|
+
t: 'hello',
|
|
98
|
+
token: hostToken ?? opts.joinToken,
|
|
99
|
+
hubVersion: HUB_VERSION,
|
|
100
|
+
schemaVersion: PEER_SCHEMA_VERSION,
|
|
101
|
+
// Only on first contact: after that the host token identifies us and
|
|
102
|
+
// the canvas hub already has a row describing this machine.
|
|
103
|
+
...(hostToken
|
|
104
|
+
? {}
|
|
105
|
+
: {
|
|
106
|
+
enroll: {
|
|
107
|
+
label: opts.label || hostname(),
|
|
108
|
+
platform: platform(),
|
|
109
|
+
arch: arch(),
|
|
110
|
+
homeDir: homedir(),
|
|
111
|
+
},
|
|
112
|
+
}),
|
|
113
|
+
};
|
|
114
|
+
ws.send(JSON.stringify(hello));
|
|
115
|
+
});
|
|
116
|
+
const onHandshake = (raw) => {
|
|
117
|
+
if (welcomed)
|
|
118
|
+
return;
|
|
119
|
+
let parsed;
|
|
120
|
+
try {
|
|
121
|
+
parsed = PeerResponse.safeParse(JSON.parse(raw.toString('utf8')));
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (!parsed.success)
|
|
127
|
+
return;
|
|
128
|
+
const msg = parsed.data;
|
|
129
|
+
if (msg.t === 'err') {
|
|
130
|
+
// A stored host token that the canvas no longer knows means this
|
|
131
|
+
// machine was removed from it — the common case being someone
|
|
132
|
+
// dropping the host and then re-running the join command. The fresh
|
|
133
|
+
// key they were just handed is exactly the answer, so use it rather
|
|
134
|
+
// than failing while holding an unused one.
|
|
135
|
+
if (usedHostToken && opts.joinToken && !hostTokenSpent) {
|
|
136
|
+
hostTokenSpent = true;
|
|
137
|
+
clearHostToken(tokenFile);
|
|
138
|
+
log('this canvas no longer knows this machine; enrolling again');
|
|
139
|
+
ws.close(); // The close handler redials, now without a host token.
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
// Otherwise a bad token or a version gap, which retrying will not fix.
|
|
143
|
+
fatal(msg.message);
|
|
144
|
+
ws.close();
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (msg.t !== 'welcome')
|
|
148
|
+
return;
|
|
149
|
+
if (msg.schemaVersion !== PEER_SCHEMA_VERSION) {
|
|
150
|
+
fatal(`schema mismatch: the canvas hub ${msg.hubVersion} speaks v${msg.schemaVersion}, ` +
|
|
151
|
+
`this hub speaks v${PEER_SCHEMA_VERSION}. Update whichever is older.`);
|
|
152
|
+
ws.close();
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (msg.hostToken) {
|
|
156
|
+
writeHostToken(tokenFile, msg.hostToken);
|
|
157
|
+
log('enrolled; this machine will rejoin on its own from now on');
|
|
158
|
+
}
|
|
159
|
+
welcomed = true;
|
|
160
|
+
backoff = 500;
|
|
161
|
+
ws.off('message', onHandshake);
|
|
162
|
+
// Hand the socket to the same code that serves an accepted /peer link.
|
|
163
|
+
// The canvas hub drives from here; we answer.
|
|
164
|
+
opts.peerServer.serve(ws, { preAuthed: true });
|
|
165
|
+
// Machine-readable: the installer waits for this, not for the port.
|
|
166
|
+
log(`TERMSCAPE_JOINED=1 joined ${opts.hubUrl}`);
|
|
167
|
+
};
|
|
168
|
+
ws.on('message', onHandshake);
|
|
169
|
+
ws.on('error', (err) => {
|
|
170
|
+
if (!welcomed)
|
|
171
|
+
log(`cannot reach ${opts.hubUrl}: ${err.message}`);
|
|
172
|
+
});
|
|
173
|
+
ws.on('close', () => {
|
|
174
|
+
socket = null;
|
|
175
|
+
if (stopped)
|
|
176
|
+
return;
|
|
177
|
+
if (welcomed)
|
|
178
|
+
log('link dropped; reconnecting');
|
|
179
|
+
timer = setTimeout(dial, backoff);
|
|
180
|
+
timer.unref?.();
|
|
181
|
+
backoff = Math.min(backoff * 2, MAX_BACKOFF_MS);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
dial();
|
|
185
|
+
return {
|
|
186
|
+
stop() {
|
|
187
|
+
stopped = true;
|
|
188
|
+
if (timer)
|
|
189
|
+
clearTimeout(timer);
|
|
190
|
+
socket?.close();
|
|
191
|
+
socket = null;
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=join.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"join.js","sourceRoot":"","sources":["../../src/remote/join.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAoB,MAAM,qBAAqB,CAAC;AAE1F,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGpC;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,cAAc,GAAG,MAAM,CAAC;AAmB9B,SAAS,aAAa,CAAC,IAAY;IACjC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,OAAO,CAAC,IAAI,IAAI,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,KAAa;IACjD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,sEAAsE;AACtE,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,CAAC;QACH,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;IACxE,CAAC;AACH,CAAC;AAED,iDAAiD;AACjD,SAAS,SAAS,CAAC,MAAc;IAC/B,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IACtD,CAAC,CAAC,QAAQ,GAAG,UAAU,CAAC;IACxB,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAiB;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1E;;;;OAIG;IACH,MAAM,KAAK,GAAG,CAAC,OAAe,EAAQ,EAAE;QACtC,OAAO,GAAG,IAAI,CAAC;QACf,GAAG,CAAC,yBAAyB,OAAO,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC,CAAC;IACF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;IAC1D,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,OAAO,GAAG,GAAG,CAAC;IAClB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,MAAM,GAAqB,IAAI,CAAC;IACpC,IAAI,KAAK,GAA0B,IAAI,CAAC;IACxC;;;;OAIG;IACH,IAAI,cAAc,GAAG,KAAK,CAAC;IAE3B,SAAS,IAAI;QACX,IAAI,OAAO;YAAE,OAAO;QAEpB,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QACnE,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClC,KAAK,CAAC,oEAAoE,CAAC,CAAC;YAC5E,OAAO;QACT,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,GAAG,EAAE,CAAC;QACZ,MAAM,aAAa,GAAG,SAAS,KAAK,IAAI,CAAC;QACzC,oEAAoE;QACpE,wCAAwC;QACxC,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;YACjB,MAAM,KAAK,GAAgB;gBACzB,CAAC,EAAE,OAAO;gBACV,KAAK,EAAE,SAAS,IAAI,IAAI,CAAC,SAAU;gBACnC,UAAU,EAAE,WAAW;gBACvB,aAAa,EAAE,mBAAmB;gBAClC,qEAAqE;gBACrE,4DAA4D;gBAC5D,GAAG,CAAC,SAAS;oBACX,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC;wBACE,MAAM,EAAE;4BACN,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,QAAQ,EAAE;4BAC/B,QAAQ,EAAE,QAAQ,EAAE;4BACpB,IAAI,EAAE,IAAI,EAAE;4BACZ,OAAO,EAAE,OAAO,EAAE;yBACnB;qBACF,CAAC;aACP,CAAC;YACF,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,CAAC,GAAW,EAAQ,EAAE;YACxC,IAAI,QAAQ;gBAAE,OAAO;YACrB,IAAI,MAAM,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACpE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO;YACT,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,OAAO;gBAAE,OAAO;YAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC;YAExB,IAAI,GAAG,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;gBACpB,iEAAiE;gBACjE,8DAA8D;gBAC9D,oEAAoE;gBACpE,oEAAoE;gBACpE,4CAA4C;gBAC5C,IAAI,aAAa,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,cAAc,EAAE,CAAC;oBACvD,cAAc,GAAG,IAAI,CAAC;oBACtB,cAAc,CAAC,SAAS,CAAC,CAAC;oBAC1B,GAAG,CAAC,2DAA2D,CAAC,CAAC;oBACjE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,uDAAuD;oBACnE,OAAO;gBACT,CAAC;gBACD,uEAAuE;gBACvE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACnB,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO;YACT,CAAC;YACD,IAAI,GAAG,CAAC,CAAC,KAAK,SAAS;gBAAE,OAAO;YAEhC,IAAI,GAAG,CAAC,aAAa,KAAK,mBAAmB,EAAE,CAAC;gBAC9C,KAAK,CACH,mCAAmC,GAAG,CAAC,UAAU,YAAY,GAAG,CAAC,aAAa,IAAI;oBAChF,oBAAoB,mBAAmB,8BAA8B,CACxE,CAAC;gBACF,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO;YACT,CAAC;YAED,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;gBAClB,cAAc,CAAC,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;gBACzC,GAAG,CAAC,2DAA2D,CAAC,CAAC;YACnE,CAAC;YAED,QAAQ,GAAG,IAAI,CAAC;YAChB,OAAO,GAAG,GAAG,CAAC;YACd,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAC/B,uEAAuE;YACvE,8CAA8C;YAC9C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/C,oEAAoE;YACpE,GAAG,CAAC,6BAA6B,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC;QAEF,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAE9B,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YAC5B,IAAI,CAAC,QAAQ;gBAAE,GAAG,CAAC,gBAAgB,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAClB,MAAM,GAAG,IAAI,CAAC;YACd,IAAI,OAAO;gBAAE,OAAO;YACpB,IAAI,QAAQ;gBAAE,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAChD,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAClC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;YAChB,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,EAAE,CAAC;IAEP,OAAO;QACL,IAAI;YACF,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,KAAK;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YAC/B,MAAM,EAAE,KAAK,EAAE,CAAC;YAChB,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Picking the address another machine can reach us on.
|
|
3
|
+
*
|
|
4
|
+
* `--listen lan` exists because the alternative is asking someone to work out
|
|
5
|
+
* their own IPv4 address before they can attach a second machine, which is
|
|
6
|
+
* exactly the kind of step that makes a feature go unused.
|
|
7
|
+
*/
|
|
8
|
+
/** First non-internal IPv4 address, preferring real NICs over virtual ones. */
|
|
9
|
+
export declare function lanAddress(): string | null;
|
|
10
|
+
/**
|
|
11
|
+
* Turn a `--listen` value into a bind address.
|
|
12
|
+
*
|
|
13
|
+
* `lan` binds the wildcard rather than the LAN address alone, because a
|
|
14
|
+
* process can only bind one address and loopback has to keep working: it is
|
|
15
|
+
* where the browser opens the canvas, and where every agent's generated MCP
|
|
16
|
+
* config points. Binding the LAN address by itself would take the hub off
|
|
17
|
+
* 127.0.0.1 and break both. The LAN address is still what gets *advertised* —
|
|
18
|
+
* see advertisedHost.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveBindHost(spec: string): string;
|
|
21
|
+
/** Whether a bind on this address also answers on 127.0.0.1. */
|
|
22
|
+
export declare function coversLoopback(host: string): boolean;
|
|
23
|
+
/** Bracket a bare IPv6 literal so it can sit in a URL. */
|
|
24
|
+
export declare function urlHost(host: string): string;
|
|
25
|
+
/** Whether a bound address is reachable from anywhere but this machine. */
|
|
26
|
+
export declare function isLoopback(host: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* The address to advertise for a given bind. A wildcard bind is reachable on
|
|
29
|
+
* every interface, so advertise the LAN one; anything else advertises itself.
|
|
30
|
+
*/
|
|
31
|
+
export declare function advertisedHost(host: string): string | null;
|
|
32
|
+
/**
|
|
33
|
+
* The machine's own name, when it is actually usable as a URL host.
|
|
34
|
+
*
|
|
35
|
+
* `http://studio:7777/join` is far easier to carry to another machine than
|
|
36
|
+
* `http://192.168.88.79:7777/join`, but only if that machine can resolve it —
|
|
37
|
+
* Windows does it over LLMNR/NetBIOS, macOS and Linux over mDNS, and neither
|
|
38
|
+
* is guaranteed. So the name is only offered when it resolves *here* to the
|
|
39
|
+
* very address we bound. That is a proxy, not a promise, which is why the
|
|
40
|
+
* caller keeps the numeric URL as a stated fallback rather than dropping it.
|
|
41
|
+
*
|
|
42
|
+
* Returns null when nothing resolves, and the caller falls back to the IP.
|
|
43
|
+
*/
|
|
44
|
+
export declare function preferredHostname(ip: string, resolve?: (name: string) => Promise<string[]>): Promise<string | null>;
|
|
45
|
+
//# sourceMappingURL=lan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lan.d.ts","sourceRoot":"","sources":["../../src/remote/lan.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AAEH,+EAA+E;AAC/E,wBAAgB,UAAU,IAAI,MAAM,GAAG,IAAI,CAa1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWpD;AAED,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,0DAA0D;AAC1D,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAkB,GAC5D,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgBxB"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { hostname, networkInterfaces } from 'node:os';
|
|
2
|
+
import { lookup } from 'node:dns/promises';
|
|
3
|
+
/**
|
|
4
|
+
* Picking the address another machine can reach us on.
|
|
5
|
+
*
|
|
6
|
+
* `--listen lan` exists because the alternative is asking someone to work out
|
|
7
|
+
* their own IPv4 address before they can attach a second machine, which is
|
|
8
|
+
* exactly the kind of step that makes a feature go unused.
|
|
9
|
+
*/
|
|
10
|
+
/** First non-internal IPv4 address, preferring real NICs over virtual ones. */
|
|
11
|
+
export function lanAddress() {
|
|
12
|
+
const candidates = [];
|
|
13
|
+
for (const [name, addrs] of Object.entries(networkInterfaces())) {
|
|
14
|
+
for (const a of addrs ?? []) {
|
|
15
|
+
if (a.family !== 'IPv4' || a.internal)
|
|
16
|
+
continue;
|
|
17
|
+
// Docker bridges, WSL adapters and VM host-only networks are reachable
|
|
18
|
+
// from almost nothing, so they lose to a real interface.
|
|
19
|
+
const virtual = /^(docker|br-|veth|vEthernet|virbr|utun|tailscale)/i.test(name);
|
|
20
|
+
if (virtual)
|
|
21
|
+
candidates.push(a.address);
|
|
22
|
+
else
|
|
23
|
+
candidates.unshift(a.address);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return candidates[0] ?? null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Turn a `--listen` value into a bind address.
|
|
30
|
+
*
|
|
31
|
+
* `lan` binds the wildcard rather than the LAN address alone, because a
|
|
32
|
+
* process can only bind one address and loopback has to keep working: it is
|
|
33
|
+
* where the browser opens the canvas, and where every agent's generated MCP
|
|
34
|
+
* config points. Binding the LAN address by itself would take the hub off
|
|
35
|
+
* 127.0.0.1 and break both. The LAN address is still what gets *advertised* —
|
|
36
|
+
* see advertisedHost.
|
|
37
|
+
*/
|
|
38
|
+
export function resolveBindHost(spec) {
|
|
39
|
+
if (spec === 'lan') {
|
|
40
|
+
if (!lanAddress()) {
|
|
41
|
+
throw new Error('--listen lan: no non-loopback IPv4 address on this machine. ' +
|
|
42
|
+
'Pass an explicit address instead.');
|
|
43
|
+
}
|
|
44
|
+
return '0.0.0.0';
|
|
45
|
+
}
|
|
46
|
+
return spec;
|
|
47
|
+
}
|
|
48
|
+
/** Whether a bind on this address also answers on 127.0.0.1. */
|
|
49
|
+
export function coversLoopback(host) {
|
|
50
|
+
return host === '0.0.0.0' || host === '::' || isLoopback(host);
|
|
51
|
+
}
|
|
52
|
+
/** Bracket a bare IPv6 literal so it can sit in a URL. */
|
|
53
|
+
export function urlHost(host) {
|
|
54
|
+
return host.includes(':') ? `[${host}]` : host;
|
|
55
|
+
}
|
|
56
|
+
/** Whether a bound address is reachable from anywhere but this machine. */
|
|
57
|
+
export function isLoopback(host) {
|
|
58
|
+
return host === '127.0.0.1' || host === 'localhost' || host === '::1';
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The address to advertise for a given bind. A wildcard bind is reachable on
|
|
62
|
+
* every interface, so advertise the LAN one; anything else advertises itself.
|
|
63
|
+
*/
|
|
64
|
+
export function advertisedHost(host) {
|
|
65
|
+
if (host === '0.0.0.0' || host === '::')
|
|
66
|
+
return lanAddress();
|
|
67
|
+
if (isLoopback(host))
|
|
68
|
+
return null;
|
|
69
|
+
return host.includes(':') ? `[${host}]` : host;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The machine's own name, when it is actually usable as a URL host.
|
|
73
|
+
*
|
|
74
|
+
* `http://studio:7777/join` is far easier to carry to another machine than
|
|
75
|
+
* `http://192.168.88.79:7777/join`, but only if that machine can resolve it —
|
|
76
|
+
* Windows does it over LLMNR/NetBIOS, macOS and Linux over mDNS, and neither
|
|
77
|
+
* is guaranteed. So the name is only offered when it resolves *here* to the
|
|
78
|
+
* very address we bound. That is a proxy, not a promise, which is why the
|
|
79
|
+
* caller keeps the numeric URL as a stated fallback rather than dropping it.
|
|
80
|
+
*
|
|
81
|
+
* Returns null when nothing resolves, and the caller falls back to the IP.
|
|
82
|
+
*/
|
|
83
|
+
export async function preferredHostname(ip, resolve = defaultResolve) {
|
|
84
|
+
const name = hostname().trim();
|
|
85
|
+
if (!name || isLoopback(name))
|
|
86
|
+
return null;
|
|
87
|
+
// Plain name first: a bare host is nicer to type than one with a suffix.
|
|
88
|
+
// `.local` is the mDNS form, which is what a Mac or a Linux box will answer.
|
|
89
|
+
const candidates = name.endsWith('.local') ? [name] : [name, `${name}.local`];
|
|
90
|
+
for (const candidate of candidates) {
|
|
91
|
+
try {
|
|
92
|
+
if ((await resolve(candidate)).includes(ip))
|
|
93
|
+
return candidate;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Does not resolve here; try the next shape.
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
async function defaultResolve(name) {
|
|
102
|
+
const found = await lookup(name, { all: true, family: 4 });
|
|
103
|
+
return found.map((a) => a.address);
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=lan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lan.js","sourceRoot":"","sources":["../../src/remote/lan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type PeerAgent, type PeerRelayAsk } from '../protocol/index.js';
|
|
2
|
+
import type { WebSocket } from 'ws';
|
|
3
|
+
import type { Hub } from '../hub.js';
|
|
4
|
+
/**
|
|
5
|
+
* The link back to the canvas, as the rest of this hub needs it. Separated
|
|
6
|
+
* from the serving machinery because a hub that owns a canvas has no uplink at
|
|
7
|
+
* all, and the difference should be a null check rather than a special case.
|
|
8
|
+
*/
|
|
9
|
+
export interface Uplink {
|
|
10
|
+
/** True while a canvas is attached to this hub. */
|
|
11
|
+
readonly attached: boolean;
|
|
12
|
+
/** Agents the canvas has told us about. Never this hub's own. */
|
|
13
|
+
agents(): PeerAgent[];
|
|
14
|
+
/** Ask the canvas to act on an address we cannot resolve ourselves. */
|
|
15
|
+
ask<T>(ask: PeerRelayAsk): Promise<T>;
|
|
16
|
+
}
|
|
17
|
+
export interface PeerServer extends Uplink {
|
|
18
|
+
/** Wire one accepted or dialled socket into this hub. */
|
|
19
|
+
serve(socket: WebSocket, opts?: {
|
|
20
|
+
preAuthed?: boolean;
|
|
21
|
+
}): void;
|
|
22
|
+
/** Number of peers currently attached. */
|
|
23
|
+
readonly size: number;
|
|
24
|
+
closeAll(): void;
|
|
25
|
+
}
|
|
26
|
+
export declare function createPeerServer(hub: Hub, clientToken: string): PeerServer;
|
|
27
|
+
//# sourceMappingURL=peer-serve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer-serve.d.ts","sourceRoot":"","sources":["../../src/remote/peer-serve.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,YAAY,EAGlB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAuBrC;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACrB,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,iEAAiE;IACjE,MAAM,IAAI,SAAS,EAAE,CAAC;IACtB,uEAAuE;IACvE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,UAAW,SAAQ,MAAM;IACxC,yDAAyD;IACzD,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/D,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,IAAI,IAAI,CAAC;CAClB;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,GAAG,UAAU,CAgQ1E"}
|