vite-plugin-opencode-assistant 1.0.2 → 1.0.3

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/dist/index.d.ts DELETED
@@ -1,23 +0,0 @@
1
- import type { Plugin } from 'vite';
2
- import { OpenCodeOptions } from './types.js';
3
- /**
4
- * OpenCode Vite 插件
5
- * @param options - 插件配置选项
6
- * @returns Vite 插件实例
7
- * @example
8
- * ```ts
9
- * // vite.config.ts
10
- * import opencode from 'vite-plugin-opencode'
11
- *
12
- * export default {
13
- * plugins: [
14
- * opencode({
15
- * webPort: 4097,
16
- * position: 'bottom-right',
17
- * theme: 'auto'
18
- * })
19
- * ]
20
- * }
21
- * ```
22
- */
23
- export default function opencodePlugin(options?: OpenCodeOptions): Plugin;
package/dist/index.js DELETED
@@ -1,451 +0,0 @@
1
- import path from 'path';
2
- import fs from 'fs';
3
- import http from 'http';
4
- import { fileURLToPath } from 'url';
5
- const __filename = fileURLToPath(import.meta.url);
6
- const __dirname = path.dirname(__filename);
7
- import { startOpenCodeWeb } from './web.js';
8
- import { injectWidget } from './injector.js';
9
- import { checkOpenCodeInstalled, findAvailablePort, killProcessOnPort, checkOpenCodeProcess } from './utils.js';
10
- import { DEFAULT_CONFIG, DEFAULT_RETRIES, RETRY_DELAY, PROCESS_KILL_DELAY, LOG_PREFIX, WIDGET_SCRIPT_PATH, CONTEXT_API_PATH, START_API_PATH, SESSIONS_API_PATH, } from './constants.js';
11
- /**
12
- * OpenCode Vite 插件
13
- * @param options - 插件配置选项
14
- * @returns Vite 插件实例
15
- * @example
16
- * ```ts
17
- * // vite.config.ts
18
- * import opencode from 'vite-plugin-opencode'
19
- *
20
- * export default {
21
- * plugins: [
22
- * opencode({
23
- * webPort: 4097,
24
- * position: 'bottom-right',
25
- * theme: 'auto'
26
- * })
27
- * ]
28
- * }
29
- * ```
30
- */
31
- export default function opencodePlugin(options = {}) {
32
- let webProcess = null;
33
- let sessionUrl = null;
34
- let actualWebPort = DEFAULT_CONFIG.webPort;
35
- let isStarted = false;
36
- let startPromise = null;
37
- let pageContext = { url: '', title: '' };
38
- const config = { ...DEFAULT_CONFIG, ...options };
39
- /**
40
- * 输出日志(仅在 verbose 模式下)
41
- */
42
- function log(message, ...args) {
43
- if (config.verbose) {
44
- console.log(`${LOG_PREFIX} ${message}`, ...args);
45
- }
46
- }
47
- /**
48
- * 输出错误日志
49
- */
50
- function logError(message, ...args) {
51
- console.error(`${LOG_PREFIX} ${message}`, ...args);
52
- }
53
- /**
54
- * Base64 编码字符串
55
- */
56
- function base64Encode(str) {
57
- return Buffer.from(str).toString('base64');
58
- }
59
- /**
60
- * 延迟执行
61
- */
62
- function sleep(ms) {
63
- return new Promise(resolve => setTimeout(resolve, ms));
64
- }
65
- /**
66
- * 创建 HTTP 请求 Promise
67
- */
68
- function createHttpRequest(options, body) {
69
- return new Promise((resolve, reject) => {
70
- const req = http.request(options, (res) => {
71
- let data = '';
72
- res.on('data', chunk => data += chunk);
73
- res.on('end', () => {
74
- try {
75
- resolve(JSON.parse(data));
76
- }
77
- catch {
78
- reject(new Error(`JSON parse error: ${data.substring(0, 100)}`));
79
- }
80
- });
81
- });
82
- req.on('error', reject);
83
- if (body)
84
- req.write(body);
85
- req.end();
86
- });
87
- }
88
- /**
89
- * 获取会话列表
90
- */
91
- async function getSessions(retries = DEFAULT_RETRIES) {
92
- let lastError = null;
93
- for (let i = 0; i < retries; i++) {
94
- try {
95
- return await createHttpRequest({
96
- hostname: config.hostname,
97
- port: actualWebPort,
98
- path: '/session',
99
- });
100
- }
101
- catch (e) {
102
- lastError = e instanceof Error ? e : new Error(String(e));
103
- if (i < retries - 1)
104
- await sleep(RETRY_DELAY);
105
- }
106
- }
107
- throw lastError;
108
- }
109
- /**
110
- * 创建新会话
111
- */
112
- async function createSession(retries = DEFAULT_RETRIES) {
113
- let lastError = null;
114
- for (let i = 0; i < retries; i++) {
115
- try {
116
- return await createHttpRequest({
117
- hostname: config.hostname,
118
- port: actualWebPort,
119
- path: '/session',
120
- method: 'POST',
121
- });
122
- }
123
- catch (e) {
124
- lastError = e instanceof Error ? e : new Error(String(e));
125
- if (i < retries - 1)
126
- await sleep(RETRY_DELAY);
127
- }
128
- }
129
- throw lastError;
130
- }
131
- /**
132
- * 删除会话
133
- */
134
- async function deleteSession(sessionId, retries = DEFAULT_RETRIES) {
135
- let lastError = null;
136
- for (let i = 0; i < retries; i++) {
137
- try {
138
- await createHttpRequest({
139
- hostname: config.hostname,
140
- port: actualWebPort,
141
- path: `/session/${sessionId}`,
142
- method: 'DELETE',
143
- });
144
- return;
145
- }
146
- catch (e) {
147
- lastError = e instanceof Error ? e : new Error(String(e));
148
- if (i < retries - 1)
149
- await sleep(RETRY_DELAY);
150
- }
151
- }
152
- throw lastError;
153
- }
154
- /**
155
- * 获取或创建会话
156
- */
157
- async function getOrCreateSession() {
158
- const projectDir = process.cwd();
159
- log('Getting sessions...');
160
- const sessions = await getSessions();
161
- log(`Found ${sessions.length} sessions`);
162
- const matchingSession = sessions.find(s => s.directory === projectDir);
163
- if (matchingSession) {
164
- return `http://${config.hostname}:${actualWebPort}/${base64Encode(projectDir)}/session/${matchingSession.id}`;
165
- }
166
- log('Creating new session...');
167
- const newSession = await createSession();
168
- return `http://${config.hostname}:${actualWebPort}/${base64Encode(projectDir)}/session/${newSession.id}`;
169
- }
170
- /**
171
- * 设置 OpenCode 插件
172
- */
173
- function setupOpenCodePlugin() {
174
- const projectDir = process.cwd();
175
- const cacheDir = path.join(projectDir, 'node_modules', '.cache', 'opencode');
176
- const pluginsDir = path.join(cacheDir, 'plugins');
177
- if (!fs.existsSync(pluginsDir)) {
178
- fs.mkdirSync(pluginsDir, { recursive: true });
179
- }
180
- const pluginSourcePath = path.join(__dirname, 'plugins', 'page-context.js');
181
- const pluginTargetPath = path.join(pluginsDir, 'page-context.js');
182
- if (fs.existsSync(pluginSourcePath)) {
183
- fs.copyFileSync(pluginSourcePath, pluginTargetPath);
184
- log(`Plugin installed to ${pluginTargetPath}`);
185
- }
186
- else {
187
- console.warn(`${LOG_PREFIX} Plugin source not found: ${pluginSourcePath}`);
188
- }
189
- return cacheDir;
190
- }
191
- /**
192
- * 启动服务
193
- */
194
- async function startServices(corsOrigins, contextApiUrl) {
195
- if (isStarted)
196
- return;
197
- if (startPromise)
198
- return startPromise;
199
- startPromise = (async () => {
200
- log('Starting OpenCode services...');
201
- if (!await checkOpenCodeInstalled()) {
202
- logError(`OpenCode is not installed!
203
-
204
- Please install OpenCode first:
205
-
206
- # Using Homebrew (macOS)
207
- brew install opencode-ai/tap/opencode
208
-
209
- # Or using the install script
210
- curl -fsSL https://opencode.ai/install | bash
211
- `);
212
- return;
213
- }
214
- actualWebPort = await findAvailablePort(config.webPort, config.hostname);
215
- if (actualWebPort !== config.webPort) {
216
- log(`Port ${config.webPort} is in use, using ${actualWebPort} instead`);
217
- }
218
- const existingProcess = await checkOpenCodeProcess(actualWebPort);
219
- if (existingProcess) {
220
- log(`Found existing OpenCode process on port ${actualWebPort}`);
221
- }
222
- else {
223
- const killed = await killProcessOnPort(actualWebPort, config.hostname);
224
- if (killed) {
225
- log(`Killed stale process on port ${actualWebPort}`);
226
- await sleep(PROCESS_KILL_DELAY);
227
- }
228
- }
229
- const configDir = setupOpenCodePlugin();
230
- if (!existingProcess) {
231
- webProcess = await startOpenCodeWeb({
232
- port: actualWebPort,
233
- hostname: config.hostname,
234
- serverUrl: '',
235
- cwd: process.cwd(),
236
- configDir,
237
- corsOrigins,
238
- contextApiUrl,
239
- });
240
- log(`OpenCode Web started at http://${config.hostname}:${actualWebPort}`);
241
- }
242
- try {
243
- sessionUrl = await getOrCreateSession();
244
- log(`Session URL: ${sessionUrl}`);
245
- }
246
- catch (e) {
247
- console.warn(`${LOG_PREFIX} Failed to get/create session:`, e);
248
- }
249
- isStarted = true;
250
- })();
251
- return startPromise;
252
- }
253
- /**
254
- * 停止服务
255
- */
256
- async function stopServices() {
257
- log('Stopping OpenCode services...');
258
- if (webProcess) {
259
- webProcess.kill('SIGTERM');
260
- await new Promise(resolve => {
261
- webProcess?.on('exit', () => resolve());
262
- setTimeout(() => {
263
- webProcess?.kill('SIGKILL');
264
- resolve();
265
- }, 3000);
266
- });
267
- webProcess = null;
268
- }
269
- if (isStarted) {
270
- await killProcessOnPort(actualWebPort, config.hostname);
271
- }
272
- isStarted = false;
273
- startPromise = null;
274
- }
275
- /**
276
- * 处理上下文 API 请求
277
- */
278
- function handleContextRequest(req, res) {
279
- res.setHeader('Content-Type', 'application/json');
280
- res.setHeader('Access-Control-Allow-Origin', '*');
281
- res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
282
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
283
- if (req.method === 'OPTIONS') {
284
- res.writeHead(200);
285
- res.end();
286
- return;
287
- }
288
- if (req.method === 'GET') {
289
- res.writeHead(200);
290
- res.end(JSON.stringify(pageContext));
291
- return;
292
- }
293
- if (req.method === 'DELETE') {
294
- pageContext.selectedElements = [];
295
- log('Selected elements cleared');
296
- res.writeHead(200);
297
- res.end(JSON.stringify({ success: true }));
298
- return;
299
- }
300
- if (req.method === 'POST') {
301
- let body = '';
302
- req.on('data', chunk => body += chunk);
303
- req.on('end', () => {
304
- try {
305
- const data = JSON.parse(body);
306
- pageContext = {
307
- url: data.url || '',
308
- title: data.title || '',
309
- selectedElements: data.selectedElements || [],
310
- };
311
- log(`Context updated: ${pageContext.url}`, data.selectedElements?.length ? `elements: ${data.selectedElements.length}` : '');
312
- res.writeHead(200);
313
- res.end(JSON.stringify({ success: true }));
314
- }
315
- catch {
316
- res.writeHead(400);
317
- res.end(JSON.stringify({ error: 'Invalid JSON' }));
318
- }
319
- });
320
- return;
321
- }
322
- res.writeHead(405);
323
- res.end(JSON.stringify({ error: 'Method not allowed' }));
324
- }
325
- return {
326
- name: 'vite-plugin-opencode',
327
- async configureServer(server) {
328
- if (!config.enabled)
329
- return;
330
- const vitePort = server.config.server.port || 5173;
331
- const viteHost = server.config.server.host || 'localhost';
332
- const viteOrigin = `http://${viteHost}:${vitePort}`;
333
- const contextApiUrl = `http://${viteHost}:${vitePort}${CONTEXT_API_PATH}`;
334
- if (!config.lazy) {
335
- await startServices([viteOrigin], contextApiUrl);
336
- }
337
- server.middlewares.use(WIDGET_SCRIPT_PATH, async (_req, res) => {
338
- if (config.lazy && !isStarted) {
339
- await startServices([viteOrigin], contextApiUrl);
340
- }
341
- const widgetPath = path.join(__dirname, 'client.js');
342
- if (fs.existsSync(widgetPath)) {
343
- res.setHeader('Content-Type', 'application/javascript');
344
- res.setHeader('Access-Control-Allow-Origin', '*');
345
- fs.createReadStream(widgetPath).pipe(res);
346
- }
347
- else {
348
- res.writeHead(404);
349
- res.end('Widget script not found');
350
- }
351
- });
352
- server.middlewares.use(CONTEXT_API_PATH, async (req, res) => {
353
- if (config.lazy && !isStarted) {
354
- await startServices([viteOrigin], contextApiUrl);
355
- }
356
- handleContextRequest(req, res);
357
- });
358
- server.middlewares.use(START_API_PATH, async (_req, res) => {
359
- res.setHeader('Content-Type', 'application/json');
360
- res.setHeader('Access-Control-Allow-Origin', '*');
361
- if (config.lazy && !isStarted) {
362
- try {
363
- await startServices([viteOrigin], contextApiUrl);
364
- res.writeHead(200);
365
- res.end(JSON.stringify({ success: true, sessionUrl }));
366
- }
367
- catch (e) {
368
- res.writeHead(500);
369
- res.end(JSON.stringify({ error: String(e) }));
370
- }
371
- }
372
- else {
373
- res.writeHead(200);
374
- res.end(JSON.stringify({ success: true, sessionUrl }));
375
- }
376
- });
377
- server.middlewares.use(SESSIONS_API_PATH, async (req, res) => {
378
- res.setHeader('Content-Type', 'application/json');
379
- res.setHeader('Access-Control-Allow-Origin', '*');
380
- res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
381
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
382
- if (req.method === 'OPTIONS') {
383
- res.writeHead(200);
384
- res.end();
385
- return;
386
- }
387
- if (config.lazy && !isStarted) {
388
- await startServices([viteOrigin], contextApiUrl);
389
- }
390
- try {
391
- if (req.method === 'GET') {
392
- const sessions = await getSessions();
393
- res.writeHead(200);
394
- res.end(JSON.stringify(sessions));
395
- }
396
- else if (req.method === 'POST') {
397
- const newSession = await createSession();
398
- res.writeHead(200);
399
- res.end(JSON.stringify(newSession));
400
- }
401
- else if (req.method === 'DELETE') {
402
- const url = new URL(req.url || '', `http://${req.headers.host}`);
403
- const sessionId = url.searchParams.get('id');
404
- if (!sessionId) {
405
- res.writeHead(400);
406
- res.end(JSON.stringify({ error: 'Session ID is required' }));
407
- return;
408
- }
409
- await deleteSession(sessionId);
410
- res.writeHead(200);
411
- res.end(JSON.stringify({ success: true }));
412
- }
413
- else {
414
- res.writeHead(405);
415
- res.end(JSON.stringify({ error: 'Method not allowed' }));
416
- }
417
- }
418
- catch (e) {
419
- res.writeHead(500);
420
- res.end(JSON.stringify({ error: String(e) }));
421
- }
422
- });
423
- server.httpServer?.on('close', stopServices);
424
- const cleanup = async () => {
425
- await stopServices();
426
- process.exit(0);
427
- };
428
- process.on('SIGINT', cleanup);
429
- process.on('SIGTERM', cleanup);
430
- process.on('exit', () => {
431
- webProcess?.kill('SIGKILL');
432
- });
433
- },
434
- transformIndexHtml(html) {
435
- const widget = injectWidget({
436
- webUrl: `http://${config.hostname}:${actualWebPort}`,
437
- serverUrl: `http://${config.hostname}:${actualWebPort}`,
438
- position: config.position,
439
- theme: config.theme,
440
- open: config.open,
441
- autoReload: config.autoReload,
442
- cwd: process.cwd(),
443
- sessionUrl: sessionUrl || undefined,
444
- lazy: config.lazy,
445
- hotkey: config.hotkey,
446
- });
447
- return html.replace('</body>', `${widget}</body>`);
448
- },
449
- };
450
- }
451
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQ3ZCLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQTtBQUNuQixPQUFPLElBQUksTUFBTSxNQUFNLENBQUE7QUFDdkIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEtBQUssQ0FBQTtBQUVuQyxNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtBQUNqRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFBO0FBRTFDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUMzQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQzVDLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUUvRyxPQUFPLEVBQ0wsY0FBYyxFQUNkLGVBQWUsRUFDZixXQUFXLEVBQ1gsa0JBQWtCLEVBQ2xCLFVBQVUsRUFDVixrQkFBa0IsRUFDbEIsZ0JBQWdCLEVBQ2hCLGNBQWMsRUFDZCxpQkFBaUIsR0FDbEIsTUFBTSxnQkFBZ0IsQ0FBQTtBQUV2Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sQ0FBQyxPQUFPLFVBQVUsY0FBYyxDQUFDLFVBQTJCLEVBQUU7SUFDbEUsSUFBSSxVQUFVLEdBQXdCLElBQUksQ0FBQTtJQUMxQyxJQUFJLFVBQVUsR0FBa0IsSUFBSSxDQUFBO0lBQ3BDLElBQUksYUFBYSxHQUFXLGNBQWMsQ0FBQyxPQUFPLENBQUE7SUFDbEQsSUFBSSxTQUFTLEdBQUcsS0FBSyxDQUFBO0lBQ3JCLElBQUksWUFBWSxHQUF5QixJQUFJLENBQUE7SUFD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Q25DLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtnQkFDakIsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO2FBQ3RCLENBQUMsQ0FBQTtZQUNGLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsR0FBRyxNQUFNLFNBQVMsQ0FBQyxDQUFBO1FBQ3BELENBQUM7S0FDRixDQUFBO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgUGx1Z2luLCBWaXRlRGV2U2VydmVyIH0gZnJvbSAndml0ZSdcbmltcG9ydCB7IHNwYXduLCBDaGlsZFByb2Nlc3MgfSBmcm9tICdjaGlsZF9wcm9jZXNzJ1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcbmltcG9ydCBmcyBmcm9tICdmcydcbmltcG9ydCBodHRwIGZyb20gJ2h0dHAnXG5pbXBvcnQgeyBmaWxlVVJMVG9QYXRoIH0gZnJvbSAndXJsJ1xuXG5jb25zdCBfX2ZpbGVuYW1lID0gZmlsZVVSTFRvUGF0aChpbXBvcnQubWV0YS51cmwpXG5jb25zdCBfX2Rpcm5hbWUgPSBwYXRoLmRpcm5hbWUoX19maWxlbmFtZSlcblxuaW1wb3J0IHsgc3RhcnRPcGVuQ29kZVdlYiB9IGZyb20gJy4vd2ViLmpzJ1xuaW1wb3J0IHsgaW5qZWN0V2lkZ2V0IH0gZnJvbSAnLi9pbmplY3Rvci5qcydcbmltcG9ydCB7IGNoZWNrT3BlbkNvZGVJbnN0YWxsZWQsIGZpbmRBdmFpbGFibGVQb3J0LCBraWxsUHJvY2Vzc09uUG9ydCwgY2hlY2tPcGVuQ29kZVByb2Nlc3MgfSBmcm9tICcuL3V0aWxzLmpzJ1xuaW1wb3J0IHsgT3BlbkNvZGVPcHRpb25zLCBTZXNzaW9uSW5mbywgUGFnZUNvbnRleHQgfSBmcm9tICcuL3R5cGVzLmpzJ1xuaW1wb3J0IHtcbiAgREVGQVVMVF9DT05GSUcsXG4gIERFRkFVTFRfUkVUUklFUyxcbiAgUkVUUllfREVMQVksXG4gIFBST0NFU1NfS0lMTF9ERUxBWSxcbiAgTE9HX1BSRUZJWCxcbiAgV0lER0VUX1NDUklQVF9QQVRILFxuICBDT05URVhUX0FQSV9QQVRILFxuICBTVEFSVF9BUElfUEFUSCxcbiAgU0VTU0lPTlNfQVBJX1BBVEgsXG59IGZyb20gJy4vY29uc3RhbnRzLmpzJ1xuXG4vKipcbiAqIE9wZW5Db2RlIFZpdGUg5o+S5Lu2XG4gKiBAcGFyYW0gb3B0aW9ucyAtIOaPkuS7tumFjee9rumAiemhuVxuICogQHJldHVybnMgVml0ZSDmj5Lku7blrp7kvotcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogLy8gdml0ZS5jb25maWcudHNcbiAqIGltcG9ydCBvcGVuY29kZSBmcm9tICd2aXRlLXBsdWdpbi1vcGVuY29kZSdcbiAqXG4gKiBleHBvcnQgZGVmYXVsdCB7XG4gKiAgIHBsdWdpbnM6IFtcbiAqICAgICBvcGVuY29kZSh7XG4gKiAgICAgICB3ZWJQb3J0OiA0MDk3LFxuICogICAgICAgcG9zaXRpb246ICdib3R0b20tcmlnaHQnLFxuICogICAgICAgdGhlbWU6ICdhdXRvJ1xuICogICAgIH0pXG4gKiAgIF1cbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBvcGVuY29kZVBsdWdpbihvcHRpb25zOiBPcGVuQ29kZU9wdGlvbnMgPSB7fSk6IFBsdWdpbiB7XG4gIGxldCB3ZWJQcm9jZXNzOiBDaGlsZFByb2Nlc3MgfCBudWxsID0gbnVsbFxuICBsZXQgc2Vzc2lvblVybDogc3RyaW5nIHwgbnVsbCA9IG51bGxcbiAgbGV0IGFjdHVhbFdlYlBvcnQ6IG51bWJlciA9IERFRkFVTFRfQ09ORklHLndlYlBvcnRcbiAgbGV0IGlzU3RhcnRlZCA9IGZhbHNlXG4gIGxldCBzdGFydFByb21pc2U6IFByb21pc2U8dm9pZD4gfCBudWxsID0gbnVsbFxuICBsZXQgcGFnZUNvbnRleHQ6IFBhZ2VDb250ZXh0ID0geyB1cmw6ICcnLCB0aXRsZTogJycgfVxuXG4gIGNvbnN0IGNvbmZpZyA9IHsgLi4uREVGQVVMVF9DT05GSUcsIC4uLm9wdGlvbnMgfVxuXG4gIC8qKlxuICAgKiDovpPlh7rml6Xlv5fvvIjku4XlnKggdmVyYm9zZSDmqKHlvI/kuIvvvIlcbiAgICovXG4gIGZ1bmN0aW9uIGxvZyhtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSk6IHZvaWQge1xuICAgIGlmIChjb25maWcudmVyYm9zZSkge1xuICAgICAgY29uc29sZS5sb2coYCR7TE9HX1BSRUZJWH0gJHttZXNzYWdlfWAsIC4uLmFyZ3MpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOi+k+WHuumUmeivr+aXpeW/l1xuICAgKi9cbiAgZnVuY3Rpb24gbG9nRXJyb3IobWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgICBjb25zb2xlLmVycm9yKGAke0xPR19QUkVGSVh9ICR7bWVzc2FnZX1gLCAuLi5hcmdzKVxuICB9XG5cbiAgLyoqXG4gICAqIEJhc2U2NCDnvJbnoIHlrZfnrKbkuLJcbiAgICovXG4gIGZ1bmN0aW9uIGJhc2U2NEVuY29kZShzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHN0cikudG9TdHJpbmcoJ2Jhc2U2NCcpXG4gIH1cblxuICAvKipcbiAgICog5bu26L+f5omn6KGMXG4gICAqL1xuICBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpXG4gIH1cblxuICAvKipcbiAgICog5Yib5bu6IEhUVFAg6K+35rGCIFByb21pc2VcbiAgICovXG4gIGZ1bmN0aW9uIGNyZWF0ZUh0dHBSZXF1ZXN0PFQ+KG9wdGlvbnM6IGh0dHAuUmVxdWVzdE9wdGlvbnMsIGJvZHk/OiBzdHJpbmcpOiBQcm9taXNlPFQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgcmVxID0gaHR0cC5yZXF1ZXN0KG9wdGlvbnMsIChyZXMpID0+IHtcbiAgICAgICAgbGV0IGRhdGEgPSAnJ1xuICAgICAgICByZXMub24oJ2RhdGEnLCBjaHVuayA9PiBkYXRhICs9IGNodW5rKVxuICAgICAgICByZXMub24oJ2VuZCcsICgpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVzb2x2ZShKU09OLnBhcnNlKGRhdGEpKVxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgSlNPTiBwYXJzZSBlcnJvcjogJHtkYXRhLnN1YnN0cmluZygwLCAxMDApfWApKVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH0pXG4gICAgICByZXEub24oJ2Vycm9yJywgcmVqZWN0KVxuICAgICAgaWYgKGJvZHkpIHJlcS53cml0ZShib2R5KVxuICAgICAgcmVxLmVuZCgpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5bkvJror53liJfooahcbiAgICovXG4gIGFzeW5jIGZ1bmN0aW9uIGdldFNlc3Npb25zKHJldHJpZXMgPSBERUZBVUxUX1JFVFJJRVMpOiBQcm9taXNlPFNlc3Npb25JbmZvW10+IHtcbiAgICBsZXQgbGFzdEVycm9yOiBFcnJvciB8IG51bGwgPSBudWxsXG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJldHJpZXM7IGkrKykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGNyZWF0ZUh0dHBSZXF1ZXN0PFNlc3Npb25JbmZvW10+KHtcbiAgICAgICAgICBob3N0bmFtZTogY29uZmlnLmhvc3RuYW1lLFxuICAgICAgICAgIHBvcnQ6IGFjdHVhbFdlYlBvcnQsXG4gICAgICAgICAgcGF0aDogJy9zZXNzaW9uJyxcbiAgICAgICAgfSlcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbGFzdEVycm9yID0gZSBpbnN0YW5jZW9mIEVycm9yID8gZSA6IG5ldyBFcnJvcihTdHJpbmcoZSkpXG4gICAgICAgIGlmIChpIDwgcmV0cmllcyAtIDEpIGF3YWl0IHNsZWVwKFJFVFJZX0RFTEFZKVxuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IGxhc3RFcnJvclxuICB9XG5cbiAgLyoqXG4gICAqIOWIm+W7uuaWsOS8muivnVxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlU2Vzc2lvbihyZXRyaWVzID0gREVGQVVMVF9SRVRSSUVTKTogUHJvbWlzZTxTZXNzaW9uSW5mbz4ge1xuICAgIGxldCBsYXN0RXJyb3I6IEVycm9yIHwgbnVsbCA9IG51bGxcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmV0cmllczsgaSsrKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgY3JlYXRlSHR0cFJlcXVlc3Q8U2Vzc2lvbkluZm8+KHtcbiAgICAgICAgICBob3N0bmFtZTogY29uZmlnLmhvc3RuYW1lLFxuICAgICAgICAgIHBvcnQ6IGFjdHVhbFdlYlBvcnQsXG4gICAgICAgICAgcGF0aDogJy9zZXNzaW9uJyxcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgfSlcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbGFzdEVycm9yID0gZSBpbnN0YW5jZW9mIEVycm9yID8gZSA6IG5ldyBFcnJvcihTdHJpbmcoZSkpXG4gICAgICAgIGlmIChpIDwgcmV0cmllcyAtIDEpIGF3YWl0IHNsZWVwKFJFVFJZX0RFTEFZKVxuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IGxhc3RFcnJvclxuICB9XG5cbiAgLyoqXG4gICAqIOWIoOmZpOS8muivnVxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gZGVsZXRlU2Vzc2lvbihzZXNzaW9uSWQ6IHN0cmluZywgcmV0cmllcyA9IERFRkFVTFRfUkVUUklFUyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxldCBsYXN0RXJyb3I6IEVycm9yIHwgbnVsbCA9IG51bGxcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmV0cmllczsgaSsrKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBjcmVhdGVIdHRwUmVxdWVzdDx2b2lkPih7XG4gICAgICAgICAgaG9zdG5hbWU6IGNvbmZpZy5ob3N0bmFtZSxcbiAgICAgICAgICBwb3J0OiBhY3R1YWxXZWJQb3J0LFxuICAgICAgICAgIHBhdGg6IGAvc2Vzc2lvbi8ke3Nlc3Npb25JZH1gLFxuICAgICAgICAgIG1ldGhvZDogJ0RFTEVURScsXG4gICAgICAgIH0pXG4gICAgICAgIHJldHVyblxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsYXN0RXJyb3IgPSBlIGluc3RhbmNlb2YgRXJyb3IgPyBlIDogbmV3IEVycm9yKFN0cmluZyhlKSlcbiAgICAgICAgaWYgKGkgPCByZXRyaWVzIC0gMSkgYXdhaXQgc2xlZXAoUkVUUllfREVMQVkpXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbGFzdEVycm9yXG4gIH1cblxuICAvKipcbiAgICog6I635Y+W5oiW5Yib5bu65Lya6K+dXG4gICAqL1xuICBhc3luYyBmdW5jdGlvbiBnZXRPckNyZWF0ZVNlc3Npb24oKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBwcm9qZWN0RGlyID0gcHJvY2Vzcy5jd2QoKVxuICAgIGxvZygnR2V0dGluZyBzZXNzaW9ucy4uLicpXG4gICAgY29uc3Qgc2Vzc2lvbnMgPSBhd2FpdCBnZXRTZXNzaW9ucygpXG4gICAgbG9nKGBGb3VuZCAke3Nlc3Npb25zLmxlbmd0aH0gc2Vzc2lvbnNgKVxuXG4gICAgY29uc3QgbWF0Y2hpbmdTZXNzaW9uID0gc2Vzc2lvbnMuZmluZChzID0+IHMuZGlyZWN0b3J5ID09PSBwcm9qZWN0RGlyKVxuXG4gICAgaWYgKG1hdGNoaW5nU2Vzc2lvbikge1xuICAgICAgcmV0dXJuIGBodHRwOi8vJHtjb25maWcuaG9zdG5hbWV9OiR7YWN0dWFsV2ViUG9ydH0vJHtiYXNlNjRFbmNvZGUocHJvamVjdERpcil9L3Nlc3Npb24vJHttYXRjaGluZ1Nlc3Npb24uaWR9YFxuICAgIH1cblxuICAgIGxvZygnQ3JlYXRpbmcgbmV3IHNlc3Npb24uLi4nKVxuICAgIGNvbnN0IG5ld1Nlc3Npb24gPSBhd2FpdCBjcmVhdGVTZXNzaW9uKClcbiAgICByZXR1cm4gYGh0dHA6Ly8ke2NvbmZpZy5ob3N0bmFtZX06JHthY3R1YWxXZWJQb3J0fS8ke2Jhc2U2NEVuY29kZShwcm9qZWN0RGlyKX0vc2Vzc2lvbi8ke25ld1Nlc3Npb24uaWR9YFxuICB9XG5cbiAgLyoqXG4gICAqIOiuvue9riBPcGVuQ29kZSDmj5Lku7ZcbiAgICovXG4gIGZ1bmN0aW9uIHNldHVwT3BlbkNvZGVQbHVnaW4oKTogc3RyaW5nIHtcbiAgICBjb25zdCBwcm9qZWN0RGlyID0gcHJvY2Vzcy5jd2QoKVxuICAgIGNvbnN0IGNhY2hlRGlyID0gcGF0aC5qb2luKHByb2plY3REaXIsICdub2RlX21vZHVsZXMnLCAnLmNhY2hlJywgJ29wZW5jb2RlJylcbiAgICBjb25zdCBwbHVnaW5zRGlyID0gcGF0aC5qb2luKGNhY2hlRGlyLCAncGx1Z2lucycpXG5cbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMocGx1Z2luc0RpcikpIHtcbiAgICAgIGZzLm1rZGlyU3luYyhwbHVnaW5zRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KVxuICAgIH1cblxuICAgIGNvbnN0IHBsdWdpblNvdXJjZVBhdGggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAncGx1Z2lucycsICdwYWdlLWNvbnRleHQuanMnKVxuICAgIGNvbnN0IHBsdWdpblRhcmdldFBhdGggPSBwYXRoLmpvaW4ocGx1Z2luc0RpciwgJ3BhZ2UtY29udGV4dC5qcycpXG5cbiAgICBpZiAoZnMuZXhpc3RzU3luYyhwbHVnaW5Tb3VyY2VQYXRoKSkge1xuICAgICAgZnMuY29weUZpbGVTeW5jKHBsdWdpblNvdXJjZVBhdGgsIHBsdWdpblRhcmdldFBhdGgpXG4gICAgICBsb2coYFBsdWdpbiBpbnN0YWxsZWQgdG8gJHtwbHVnaW5UYXJnZXRQYXRofWApXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybihgJHtMT0dfUFJFRklYfSBQbHVnaW4gc291cmNlIG5vdCBmb3VuZDogJHtwbHVnaW5Tb3VyY2VQYXRofWApXG4gICAgfVxuXG4gICAgcmV0dXJuIGNhY2hlRGlyXG4gIH1cblxuICAvKipcbiAgICog5ZCv5Yqo5pyN5YqhXG4gICAqL1xuICBhc3luYyBmdW5jdGlvbiBzdGFydFNlcnZpY2VzKGNvcnNPcmlnaW5zPzogc3RyaW5nW10sIGNvbnRleHRBcGlVcmw/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoaXNTdGFydGVkKSByZXR1cm5cbiAgICBpZiAoc3RhcnRQcm9taXNlKSByZXR1cm4gc3RhcnRQcm9taXNlXG5cbiAgICBzdGFydFByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgbG9nKCdTdGFydGluZyBPcGVuQ29kZSBzZXJ2aWNlcy4uLicpXG5cbiAgICAgIGlmICghYXdhaXQgY2hlY2tPcGVuQ29kZUluc3RhbGxlZCgpKSB7XG4gICAgICAgIGxvZ0Vycm9yKGBPcGVuQ29kZSBpcyBub3QgaW5zdGFsbGVkIVxuXG5QbGVhc2UgaW5zdGFsbCBPcGVuQ29kZSBmaXJzdDpcblxuICAjIFVzaW5nIEhvbWVicmV3IChtYWNPUylcbiAgYnJldyBpbnN0YWxsIG9wZW5jb2RlLWFpL3RhcC9vcGVuY29kZVxuXG4gICMgT3IgdXNpbmcgdGhlIGluc3RhbGwgc2NyaXB0XG4gIGN1cmwgLWZzU0wgaHR0cHM6Ly9vcGVuY29kZS5haS9pbnN0YWxsIHwgYmFzaFxuICAgICAgICBgKVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgYWN0dWFsV2ViUG9ydCA9IGF3YWl0IGZpbmRBdmFpbGFibGVQb3J0KGNvbmZpZy53ZWJQb3J0LCBjb25maWcuaG9zdG5hbWUpXG4gICAgICBpZiAoYWN0dWFsV2ViUG9ydCAhPT0gY29uZmlnLndlYlBvcnQpIHtcbiAgICAgICAgbG9nKGBQb3J0ICR7Y29uZmlnLndlYlBvcnR9IGlzIGluIHVzZSwgdXNpbmcgJHthY3R1YWxXZWJQb3J0fSBpbnN0ZWFkYClcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXhpc3RpbmdQcm9jZXNzID0gYXdhaXQgY2hlY2tPcGVuQ29kZVByb2Nlc3MoYWN0dWFsV2ViUG9ydClcbiAgICAgIGlmIChleGlzdGluZ1Byb2Nlc3MpIHtcbiAgICAgICAgbG9nKGBGb3VuZCBleGlzdGluZyBPcGVuQ29kZSBwcm9jZXNzIG9uIHBvcnQgJHthY3R1YWxXZWJQb3J0fWApXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBraWxsZWQgPSBhd2FpdCBraWxsUHJvY2Vzc09uUG9ydChhY3R1YWxXZWJQb3J0LCBjb25maWcuaG9zdG5hbWUpXG4gICAgICAgIGlmIChraWxsZWQpIHtcbiAgICAgICAgICBsb2coYEtpbGxlZCBzdGFsZSBwcm9jZXNzIG9uIHBvcnQgJHthY3R1YWxXZWJQb3J0fWApXG4gICAgICAgICAgYXdhaXQgc2xlZXAoUFJPQ0VTU19LSUxMX0RFTEFZKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNvbmZpZ0RpciA9IHNldHVwT3BlbkNvZGVQbHVnaW4oKVxuXG4gICAgICBpZiAoIWV4aXN0aW5nUHJvY2Vzcykge1xuICAgICAgICB3ZWJQcm9jZXNzID0gYXdhaXQgc3RhcnRPcGVuQ29kZVdlYih7XG4gICAgICAgICAgcG9ydDogYWN0dWFsV2ViUG9ydCxcbiAgICAgICAgICBob3N0bmFtZTogY29uZmlnLmhvc3RuYW1lLFxuICAgICAgICAgIHNlcnZlclVybDogJycsXG4gICAgICAgICAgY3dkOiBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICAgIGNvbmZpZ0RpcixcbiAgICAgICAgICBjb3JzT3JpZ2lucyxcbiAgICAgICAgICBjb250ZXh0QXBpVXJsLFxuICAgICAgICB9KVxuICAgICAgICBsb2coYE9wZW5Db2RlIFdlYiBzdGFydGVkIGF0IGh0dHA6Ly8ke2NvbmZpZy5ob3N0bmFtZX06JHthY3R1YWxXZWJQb3J0fWApXG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHNlc3Npb25VcmwgPSBhd2FpdCBnZXRPckNyZWF0ZVNlc3Npb24oKVxuICAgICAgICBsb2coYFNlc3Npb24gVVJMOiAke3Nlc3Npb25Vcmx9YClcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGAke0xPR19QUkVGSVh9IEZhaWxlZCB0byBnZXQvY3JlYXRlIHNlc3Npb246YCwgZSlcbiAgICAgIH1cblxuICAgICAgaXNTdGFydGVkID0gdHJ1ZVxuICAgIH0pKClcblxuICAgIHJldHVybiBzdGFydFByb21pc2VcbiAgfVxuXG4gIC8qKlxuICAgKiDlgZzmraLmnI3liqFcbiAgICovXG4gIGFzeW5jIGZ1bmN0aW9uIHN0b3BTZXJ2aWNlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2coJ1N0b3BwaW5nIE9wZW5Db2RlIHNlcnZpY2VzLi4uJylcbiAgICBcbiAgICBpZiAod2ViUHJvY2Vzcykge1xuICAgICAgd2ViUHJvY2Vzcy5raWxsKCdTSUdURVJNJylcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4ge1xuICAgICAgICB3ZWJQcm9jZXNzPy5vbignZXhpdCcsICgpID0+IHJlc29sdmUoKSlcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgd2ViUHJvY2Vzcz8ua2lsbCgnU0lHS0lMTCcpXG4gICAgICAgICAgcmVzb2x2ZSgpXG4gICAgICAgIH0sIDMwMDApXG4gICAgICB9KVxuICAgICAgd2ViUHJvY2VzcyA9IG51bGxcbiAgICB9XG4gICAgXG4gICAgaWYgKGlzU3RhcnRlZCkge1xuICAgICAgYXdhaXQga2lsbFByb2Nlc3NPblBvcnQoYWN0dWFsV2ViUG9ydCwgY29uZmlnLmhvc3RuYW1lKVxuICAgIH1cbiAgICBcbiAgICBpc1N0YXJ0ZWQgPSBmYWxzZVxuICAgIHN0YXJ0UHJvbWlzZSA9IG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiDlpITnkIbkuIrkuIvmlocgQVBJIOivt+axglxuICAgKi9cbiAgZnVuY3Rpb24gaGFuZGxlQ29udGV4dFJlcXVlc3QocmVxOiBodHRwLkluY29taW5nTWVzc2FnZSwgcmVzOiBodHRwLlNlcnZlclJlc3BvbnNlKTogdm9pZCB7XG4gICAgcmVzLnNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKVxuICAgIHJlcy5zZXRIZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicsICcqJylcbiAgICByZXMuc2V0SGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJywgJ0dFVCwgUE9TVCwgREVMRVRFLCBPUFRJT05TJylcbiAgICByZXMuc2V0SGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1IZWFkZXJzJywgJ0NvbnRlbnQtVHlwZScpXG5cbiAgICBpZiAocmVxLm1ldGhvZCA9PT0gJ09QVElPTlMnKSB7XG4gICAgICByZXMud3JpdGVIZWFkKDIwMClcbiAgICAgIHJlcy5lbmQoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHJlcS5tZXRob2QgPT09ICdHRVQnKSB7XG4gICAgICByZXMud3JpdGVIZWFkKDIwMClcbiAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkocGFnZUNvbnRleHQpKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHJlcS5tZXRob2QgPT09ICdERUxFVEUnKSB7XG4gICAgICBwYWdlQ29udGV4dC5zZWxlY3RlZEVsZW1lbnRzID0gW11cbiAgICAgIGxvZygnU2VsZWN0ZWQgZWxlbWVudHMgY2xlYXJlZCcpXG4gICAgICByZXMud3JpdGVIZWFkKDIwMClcbiAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBzdWNjZXNzOiB0cnVlIH0pKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHJlcS5tZXRob2QgPT09ICdQT1NUJykge1xuICAgICAgbGV0IGJvZHkgPSAnJ1xuICAgICAgcmVxLm9uKCdkYXRhJywgY2h1bmsgPT4gYm9keSArPSBjaHVuaylcbiAgICAgIHJlcS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKGJvZHkpXG4gICAgICAgICAgcGFnZUNvbnRleHQgPSB7XG4gICAgICAgICAgICB1cmw6IGRhdGEudXJsIHx8ICcnLFxuICAgICAgICAgICAgdGl0bGU6IGRhdGEudGl0bGUgfHwgJycsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzOiBkYXRhLnNlbGVjdGVkRWxlbWVudHMgfHwgW10sXG4gICAgICAgICAgfVxuICAgICAgICAgIGxvZyhgQ29udGV4dCB1cGRhdGVkOiAke3BhZ2VDb250ZXh0LnVybH1gLCBkYXRhLnNlbGVjdGVkRWxlbWVudHM/Lmxlbmd0aCA/IGBlbGVtZW50czogJHtkYXRhLnNlbGVjdGVkRWxlbWVudHMubGVuZ3RofWAgOiAnJylcbiAgICAgICAgICByZXMud3JpdGVIZWFkKDIwMClcbiAgICAgICAgICByZXMuZW5kKEpTT04uc3RyaW5naWZ5KHsgc3VjY2VzczogdHJ1ZSB9KSlcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmVzLndyaXRlSGVhZCg0MDApXG4gICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IGVycm9yOiAnSW52YWxpZCBKU09OJyB9KSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHJlcy53cml0ZUhlYWQoNDA1KVxuICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBlcnJvcjogJ01ldGhvZCBub3QgYWxsb3dlZCcgfSkpXG4gIH1cblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICd2aXRlLXBsdWdpbi1vcGVuY29kZScsXG5cbiAgICBhc3luYyBjb25maWd1cmVTZXJ2ZXIoc2VydmVyOiBWaXRlRGV2U2VydmVyKSB7XG4gICAgICBpZiAoIWNvbmZpZy5lbmFibGVkKSByZXR1cm5cblxuICAgICAgY29uc3Qgdml0ZVBvcnQgPSBzZXJ2ZXIuY29uZmlnLnNlcnZlci5wb3J0IHx8IDUxNzNcbiAgICAgIGNvbnN0IHZpdGVIb3N0ID0gc2VydmVyLmNvbmZpZy5zZXJ2ZXIuaG9zdCB8fCAnbG9jYWxob3N0J1xuICAgICAgY29uc3Qgdml0ZU9yaWdpbiA9IGBodHRwOi8vJHt2aXRlSG9zdH06JHt2aXRlUG9ydH1gXG4gICAgICBjb25zdCBjb250ZXh0QXBpVXJsID0gYGh0dHA6Ly8ke3ZpdGVIb3N0fToke3ZpdGVQb3J0fSR7Q09OVEVYVF9BUElfUEFUSH1gXG5cbiAgICAgIGlmICghY29uZmlnLmxhenkpIHtcbiAgICAgICAgYXdhaXQgc3RhcnRTZXJ2aWNlcyhbdml0ZU9yaWdpbl0sIGNvbnRleHRBcGlVcmwpXG4gICAgICB9XG5cbiAgICAgIHNlcnZlci5taWRkbGV3YXJlcy51c2UoV0lER0VUX1NDUklQVF9QQVRILCBhc3luYyAoX3JlcSwgcmVzKSA9PiB7XG4gICAgICAgIGlmIChjb25maWcubGF6eSAmJiAhaXNTdGFydGVkKSB7XG4gICAgICAgICAgYXdhaXQgc3RhcnRTZXJ2aWNlcyhbdml0ZU9yaWdpbl0sIGNvbnRleHRBcGlVcmwpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB3aWRnZXRQYXRoID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJ2NsaWVudC5qcycpXG4gICAgICAgIGlmIChmcy5leGlzdHNTeW5jKHdpZGdldFBhdGgpKSB7XG4gICAgICAgICAgcmVzLnNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQnKVxuICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicsICcqJylcbiAgICAgICAgICBmcy5jcmVhdGVSZWFkU3RyZWFtKHdpZGdldFBhdGgpLnBpcGUocmVzKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlcy53cml0ZUhlYWQoNDA0KVxuICAgICAgICAgIHJlcy5lbmQoJ1dpZGdldCBzY3JpcHQgbm90IGZvdW5kJylcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgICAgc2VydmVyLm1pZGRsZXdhcmVzLnVzZShDT05URVhUX0FQSV9QQVRILCBhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICAgICAgaWYgKGNvbmZpZy5sYXp5ICYmICFpc1N0YXJ0ZWQpIHtcbiAgICAgICAgICBhd2FpdCBzdGFydFNlcnZpY2VzKFt2aXRlT3JpZ2luXSwgY29udGV4dEFwaVVybClcbiAgICAgICAgfVxuICAgICAgICBoYW5kbGVDb250ZXh0UmVxdWVzdChyZXEgYXMgaHR0cC5JbmNvbWluZ01lc3NhZ2UsIHJlcylcbiAgICAgIH0pXG5cbiAgICAgIHNlcnZlci5taWRkbGV3YXJlcy51c2UoU1RBUlRfQVBJX1BBVEgsIGFzeW5jIChfcmVxLCByZXMpID0+IHtcbiAgICAgICAgcmVzLnNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKVxuICAgICAgICByZXMuc2V0SGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4nLCAnKicpXG5cbiAgICAgICAgaWYgKGNvbmZpZy5sYXp5ICYmICFpc1N0YXJ0ZWQpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgc3RhcnRTZXJ2aWNlcyhbdml0ZU9yaWdpbl0sIGNvbnRleHRBcGlVcmwpXG4gICAgICAgICAgICByZXMud3JpdGVIZWFkKDIwMClcbiAgICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBzdWNjZXNzOiB0cnVlLCBzZXNzaW9uVXJsIH0pKVxuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoNTAwKVxuICAgICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IGVycm9yOiBTdHJpbmcoZSkgfSkpXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlcy53cml0ZUhlYWQoMjAwKVxuICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBzdWNjZXNzOiB0cnVlLCBzZXNzaW9uVXJsIH0pKVxuICAgICAgICB9XG4gICAgICB9KVxuXG4gICAgICBzZXJ2ZXIubWlkZGxld2FyZXMudXNlKFNFU1NJT05TX0FQSV9QQVRILCBhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICAgICAgcmVzLnNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKVxuICAgICAgICByZXMuc2V0SGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4nLCAnKicpXG4gICAgICAgIHJlcy5zZXRIZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LU1ldGhvZHMnLCAnR0VULCBQT1NULCBERUxFVEUsIE9QVElPTlMnKVxuICAgICAgICByZXMuc2V0SGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1IZWFkZXJzJywgJ0NvbnRlbnQtVHlwZScpXG5cbiAgICAgICAgaWYgKHJlcS5tZXRob2QgPT09ICdPUFRJT05TJykge1xuICAgICAgICAgIHJlcy53cml0ZUhlYWQoMjAwKVxuICAgICAgICAgIHJlcy5lbmQoKVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbmZpZy5sYXp5ICYmICFpc1N0YXJ0ZWQpIHtcbiAgICAgICAgICBhd2FpdCBzdGFydFNlcnZpY2VzKFt2aXRlT3JpZ2luXSwgY29udGV4dEFwaVVybClcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKHJlcS5tZXRob2QgPT09ICdHRVQnKSB7XG4gICAgICAgICAgICBjb25zdCBzZXNzaW9ucyA9IGF3YWl0IGdldFNlc3Npb25zKClcbiAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoMjAwKVxuICAgICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeShzZXNzaW9ucykpXG4gICAgICAgICAgfSBlbHNlIGlmIChyZXEubWV0aG9kID09PSAnUE9TVCcpIHtcbiAgICAgICAgICAgIGNvbnN0IG5ld1Nlc3Npb24gPSBhd2FpdCBjcmVhdGVTZXNzaW9uKClcbiAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoMjAwKVxuICAgICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeShuZXdTZXNzaW9uKSlcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlcS5tZXRob2QgPT09ICdERUxFVEUnKSB7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHJlcS51cmwgfHwgJycsIGBodHRwOi8vJHtyZXEuaGVhZGVycy5ob3N0fWApXG4gICAgICAgICAgICBjb25zdCBzZXNzaW9uSWQgPSB1cmwuc2VhcmNoUGFyYW1zLmdldCgnaWQnKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAoIXNlc3Npb25JZCkge1xuICAgICAgICAgICAgICByZXMud3JpdGVIZWFkKDQwMClcbiAgICAgICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IGVycm9yOiAnU2Vzc2lvbiBJRCBpcyByZXF1aXJlZCcgfSkpXG4gICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBhd2FpdCBkZWxldGVTZXNzaW9uKHNlc3Npb25JZClcbiAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoMjAwKVxuICAgICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IHN1Y2Nlc3M6IHRydWUgfSkpXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoNDA1KVxuICAgICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IGVycm9yOiAnTWV0aG9kIG5vdCBhbGxvd2VkJyB9KSlcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICByZXMud3JpdGVIZWFkKDUwMClcbiAgICAgICAgICByZXMuZW5kKEpTT04uc3RyaW5naWZ5KHsgZXJyb3I6IFN0cmluZyhlKSB9KSlcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgICAgc2VydmVyLmh0dHBTZXJ2ZXI/Lm9uKCdjbG9zZScsIHN0b3BTZXJ2aWNlcylcbiAgICAgIFxuICAgICAgY29uc3QgY2xlYW51cCA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgc3RvcFNlcnZpY2VzKClcbiAgICAgICAgcHJvY2Vzcy5leGl0KDApXG4gICAgICB9XG4gICAgICBcbiAgICAgIHByb2Nlc3Mub24oJ1NJR0lOVCcsIGNsZWFudXApXG4gICAgICBwcm9jZXNzLm9uKCdTSUdURVJNJywgY2xlYW51cClcbiAgICAgIHByb2Nlc3Mub24oJ2V4aXQnLCAoKSA9PiB7XG4gICAgICAgIHdlYlByb2Nlc3M/LmtpbGwoJ1NJR0tJTEwnKVxuICAgICAgfSlcbiAgICB9LFxuXG4gICAgdHJhbnNmb3JtSW5kZXhIdG1sKGh0bWwpIHtcbiAgICAgIGNvbnN0IHdpZGdldCA9IGluamVjdFdpZGdldCh7XG4gICAgICAgIHdlYlVybDogYGh0dHA6Ly8ke2NvbmZpZy5ob3N0bmFtZX06JHthY3R1YWxXZWJQb3J0fWAsXG4gICAgICAgIHNlcnZlclVybDogYGh0dHA6Ly8ke2NvbmZpZy5ob3N0bmFtZX06JHthY3R1YWxXZWJQb3J0fWAsXG4gICAgICAgIHBvc2l0aW9uOiBjb25maWcucG9zaXRpb24sXG4gICAgICAgIHRoZW1lOiBjb25maWcudGhlbWUsXG4gICAgICAgIG9wZW46IGNvbmZpZy5vcGVuLFxuICAgICAgICBhdXRvUmVsb2FkOiBjb25maWcuYXV0b1JlbG9hZCxcbiAgICAgICAgY3dkOiBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICBzZXNzaW9uVXJsOiBzZXNzaW9uVXJsIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgbGF6eTogY29uZmlnLmxhenksXG4gICAgICAgIGhvdGtleTogY29uZmlnLmhvdGtleSxcbiAgICAgIH0pXG4gICAgICByZXR1cm4gaHRtbC5yZXBsYWNlKCc8L2JvZHk+JywgYCR7d2lkZ2V0fTwvYm9keT5gKVxuICAgIH0sXG4gIH1cbn1cbiJdfQ==
@@ -1,20 +0,0 @@
1
- import { WidgetOptions } from './types.js';
2
- /**
3
- * 生成挂件注入脚本标签
4
- * @param options - 挂件配置选项
5
- * @returns HTML 脚本标签字符串
6
- * @example
7
- * ```ts
8
- * const widget = injectWidget({
9
- * webUrl: 'http://127.0.0.1:4097',
10
- * serverUrl: 'http://127.0.0.1:4097',
11
- * position: 'bottom-right',
12
- * theme: 'auto',
13
- * open: false,
14
- * autoReload: true,
15
- * cwd: process.cwd()
16
- * })
17
- * // 返回: '<script src="/__opencode_widget__.js" data-opencode-config="..."></script>'
18
- * ```
19
- */
20
- export declare function injectWidget(options: WidgetOptions): string;
package/dist/injector.js DELETED
@@ -1,24 +0,0 @@
1
- import { WIDGET_SCRIPT_PATH, CONFIG_DATA_ATTR } from './constants.js';
2
- /**
3
- * 生成挂件注入脚本标签
4
- * @param options - 挂件配置选项
5
- * @returns HTML 脚本标签字符串
6
- * @example
7
- * ```ts
8
- * const widget = injectWidget({
9
- * webUrl: 'http://127.0.0.1:4097',
10
- * serverUrl: 'http://127.0.0.1:4097',
11
- * position: 'bottom-right',
12
- * theme: 'auto',
13
- * open: false,
14
- * autoReload: true,
15
- * cwd: process.cwd()
16
- * })
17
- * // 返回: '<script src="/__opencode_widget__.js" data-opencode-config="..."></script>'
18
- * ```
19
- */
20
- export function injectWidget(options) {
21
- const configBase64 = Buffer.from(JSON.stringify(options)).toString('base64');
22
- return `<script src="${WIDGET_SCRIPT_PATH}" ${CONFIG_DATA_ATTR}="${configBase64}"></script>`;
23
- }
24
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5qZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5qZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFFckU7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FBQyxPQUFzQjtJQUNqRCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDNUUsT0FBTyxnQkFBZ0Isa0JBQWtCLEtBQUssZ0JBQWdCLEtBQUssWUFBWSxhQUFhLENBQUE7QUFDOUYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFdpZGdldE9wdGlvbnMgfSBmcm9tICcuL3R5cGVzLmpzJ1xuaW1wb3J0IHsgV0lER0VUX1NDUklQVF9QQVRILCBDT05GSUdfREFUQV9BVFRSIH0gZnJvbSAnLi9jb25zdGFudHMuanMnXG5cbi8qKlxuICog55Sf5oiQ5oyC5Lu25rOo5YWl6ISa5pys5qCH562+XG4gKiBAcGFyYW0gb3B0aW9ucyAtIOaMguS7tumFjee9rumAiemhuVxuICogQHJldHVybnMgSFRNTCDohJrmnKzmoIfnrb7lrZfnrKbkuLJcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogY29uc3Qgd2lkZ2V0ID0gaW5qZWN0V2lkZ2V0KHtcbiAqICAgd2ViVXJsOiAnaHR0cDovLzEyNy4wLjAuMTo0MDk3JyxcbiAqICAgc2VydmVyVXJsOiAnaHR0cDovLzEyNy4wLjAuMTo0MDk3JyxcbiAqICAgcG9zaXRpb246ICdib3R0b20tcmlnaHQnLFxuICogICB0aGVtZTogJ2F1dG8nLFxuICogICBvcGVuOiBmYWxzZSxcbiAqICAgYXV0b1JlbG9hZDogdHJ1ZSxcbiAqICAgY3dkOiBwcm9jZXNzLmN3ZCgpXG4gKiB9KVxuICogLy8g6L+U5ZueOiAnPHNjcmlwdCBzcmM9XCIvX19vcGVuY29kZV93aWRnZXRfXy5qc1wiIGRhdGEtb3BlbmNvZGUtY29uZmlnPVwiLi4uXCI+PC9zY3JpcHQ+J1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RXaWRnZXQob3B0aW9uczogV2lkZ2V0T3B0aW9ucyk6IHN0cmluZyB7XG4gIGNvbnN0IGNvbmZpZ0Jhc2U2NCA9IEJ1ZmZlci5mcm9tKEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpKS50b1N0cmluZygnYmFzZTY0JylcbiAgcmV0dXJuIGA8c2NyaXB0IHNyYz1cIiR7V0lER0VUX1NDUklQVF9QQVRIfVwiICR7Q09ORklHX0RBVEFfQVRUUn09XCIke2NvbmZpZ0Jhc2U2NH1cIj48L3NjcmlwdD5gXG59XG4iXX0=