@nlabs/lex 1.46.2 → 1.47.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/__mocks__/LexConfig.js +20 -0
- package/__mocks__/boxen.js +7 -0
- package/__mocks__/build.js +16 -0
- package/__mocks__/chalk.js +23 -0
- package/__mocks__/compile.js +8 -0
- package/__mocks__/execa.js +21 -0
- package/__mocks__/ora.js +17 -0
- package/__mocks__/versions.js +12 -0
- package/dist/LexConfig.js +72 -14
- package/dist/commands/ai/ai.js +303 -0
- package/dist/commands/ai/index.js +7 -0
- package/dist/commands/build/build.js +350 -0
- package/dist/commands/clean/clean.js +31 -0
- package/dist/commands/compile/compile.js +195 -0
- package/dist/commands/config/config.js +43 -0
- package/dist/commands/copy/copy.js +38 -0
- package/dist/commands/create/create.js +124 -0
- package/dist/commands/dev/dev.js +70 -0
- package/dist/commands/init/init.js +93 -0
- package/dist/commands/link/link.js +15 -0
- package/dist/commands/lint/lint.js +656 -0
- package/dist/commands/migrate/migrate.js +37 -0
- package/dist/commands/publish/publish.js +104 -0
- package/dist/commands/test/test.js +327 -0
- package/dist/commands/update/update.js +62 -0
- package/dist/commands/upgrade/upgrade.js +47 -0
- package/dist/commands/versions/versions.js +41 -0
- package/dist/create/changelog.js +3 -3
- package/dist/index.js +35 -0
- package/dist/jest.config.lex.d.ts +2 -0
- package/dist/lex.js +25 -22
- package/dist/types.js +1 -0
- package/dist/utils/aiService.js +290 -0
- package/dist/utils/app.js +3 -3
- package/dist/utils/file.js +1 -1
- package/dist/utils/log.js +2 -1
- package/dist/utils/reactShim.js +3 -3
- package/dist/webpack.config.d.ts +2 -0
- package/eslint.config.js +10 -0
- package/index.cjs +20 -0
- package/jest.config.cjs +31 -27
- package/jest.config.lex.js +90 -38
- package/jest.setup.js +5 -0
- package/lex.config.js +50 -0
- package/package.json +69 -52
- package/{.postcssrc.js → postcss.config.js} +21 -9
- package/tsconfig.json +2 -1
- package/webpack.config.js +27 -11
- package/dist/commands/build.js +0 -265
- package/dist/commands/bulid.test.js +0 -317
- package/dist/commands/clean.js +0 -31
- package/dist/commands/clean.test.js +0 -63
- package/dist/commands/compile.js +0 -195
- package/dist/commands/compile.test.js +0 -93
- package/dist/commands/config.js +0 -43
- package/dist/commands/copy.js +0 -38
- package/dist/commands/create.js +0 -120
- package/dist/commands/dev.js +0 -70
- package/dist/commands/init.js +0 -93
- package/dist/commands/link.js +0 -15
- package/dist/commands/lint.js +0 -179
- package/dist/commands/migrate.js +0 -37
- package/dist/commands/publish.js +0 -104
- package/dist/commands/test.js +0 -190
- package/dist/commands/update.js +0 -64
- package/dist/commands/upgrade.js +0 -47
- package/dist/commands/versions.js +0 -41
- package/dist/commands/versions.test.js +0 -49
- package/dist/lint.js +0 -11
- package/jest.setup.ts +0 -3
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { readFileSync } from "fs";
|
|
2
|
+
import { sync as globSync } from "glob";
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import { LexConfig } from "../../LexConfig.js";
|
|
6
|
+
import { log } from "../../utils/log.js";
|
|
7
|
+
import { callAIService } from "../../utils/aiService.js";
|
|
8
|
+
if (process.env.CURSOR_EXTENSION === "true" || process.env.CURSOR_TERMINAL === "true" || process.env.CURSOR_APP === "true" || process.env.PATH?.includes("cursor") || process.env.CURSOR_SESSION_ID) {
|
|
9
|
+
process.env.CURSOR_IDE = "true";
|
|
10
|
+
}
|
|
11
|
+
const getFileContext = (filePath) => {
|
|
12
|
+
try {
|
|
13
|
+
const content = readFileSync(filePath, "utf-8");
|
|
14
|
+
return `File: ${filePath}
|
|
15
|
+
|
|
16
|
+
${content}`;
|
|
17
|
+
} catch (_error) {
|
|
18
|
+
return `Error reading file: ${filePath}`;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const getProjectContext = async (options) => {
|
|
22
|
+
const { file, task, context } = options;
|
|
23
|
+
if (context === false) {
|
|
24
|
+
return "";
|
|
25
|
+
}
|
|
26
|
+
let projectContext = "";
|
|
27
|
+
if (file) {
|
|
28
|
+
projectContext += getFileContext(file);
|
|
29
|
+
}
|
|
30
|
+
switch (task) {
|
|
31
|
+
case "generate":
|
|
32
|
+
const files = globSync("src/**/*.{ts,tsx,js,jsx}", {
|
|
33
|
+
cwd: process.cwd(),
|
|
34
|
+
ignore: ["**/node_modules/**", "**/dist/**", "**/*.test.*", "**/*.spec.*"],
|
|
35
|
+
maxDepth: 3
|
|
36
|
+
});
|
|
37
|
+
projectContext += `
|
|
38
|
+
|
|
39
|
+
Project structure:
|
|
40
|
+
${files.join("\n")}`;
|
|
41
|
+
break;
|
|
42
|
+
case "test":
|
|
43
|
+
if (file) {
|
|
44
|
+
const testConfig = getFileContext("jest.config.js");
|
|
45
|
+
projectContext += `
|
|
46
|
+
|
|
47
|
+
Test configuration:
|
|
48
|
+
${testConfig}`;
|
|
49
|
+
}
|
|
50
|
+
break;
|
|
51
|
+
case "optimize":
|
|
52
|
+
const webpackConfig = getFileContext("webpack.config.js");
|
|
53
|
+
projectContext += `
|
|
54
|
+
|
|
55
|
+
Webpack configuration:
|
|
56
|
+
${webpackConfig}`;
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
return projectContext;
|
|
62
|
+
};
|
|
63
|
+
const constructPrompt = (options, projectContext) => {
|
|
64
|
+
const { task = "help", prompt = "" } = options;
|
|
65
|
+
const taskInstructions = {
|
|
66
|
+
generate: "Generate code according to the following request. Make sure it follows best practices and is well documented:",
|
|
67
|
+
explain: "Explain the following code in detail, including any patterns, potential issues, and improvement suggestions:",
|
|
68
|
+
test: "Generate comprehensive unit tests for the following code:",
|
|
69
|
+
optimize: "Analyze the following code/configuration and suggest optimization improvements:",
|
|
70
|
+
help: "Provide guidance on the following development question:",
|
|
71
|
+
ask: "Provide guidance on the following development question:",
|
|
72
|
+
analyze: "Analyze the following code:"
|
|
73
|
+
};
|
|
74
|
+
const taskInstruction = taskInstructions[task] || taskInstructions.help;
|
|
75
|
+
let fullPrompt = `${taskInstruction}
|
|
76
|
+
|
|
77
|
+
${prompt}`;
|
|
78
|
+
if (projectContext) {
|
|
79
|
+
fullPrompt += `
|
|
80
|
+
|
|
81
|
+
===CONTEXT===
|
|
82
|
+
${projectContext}`;
|
|
83
|
+
}
|
|
84
|
+
return fullPrompt;
|
|
85
|
+
};
|
|
86
|
+
const displayResponse = (response, options) => {
|
|
87
|
+
const { task = "help", quiet = false } = options;
|
|
88
|
+
let content = "";
|
|
89
|
+
if (typeof response === "string") {
|
|
90
|
+
content = response;
|
|
91
|
+
} else if (response.choices?.[0]?.message?.content) {
|
|
92
|
+
content = response.choices[0].message.content;
|
|
93
|
+
} else if (response.content) {
|
|
94
|
+
content = response.content;
|
|
95
|
+
} else {
|
|
96
|
+
content = "No response received from AI model";
|
|
97
|
+
}
|
|
98
|
+
const cleanedContent = cleanResponse(content, options);
|
|
99
|
+
switch (task) {
|
|
100
|
+
case "generate":
|
|
101
|
+
log("\nGenerated Code:\n", "success", quiet);
|
|
102
|
+
log(cleanedContent, "default", quiet);
|
|
103
|
+
break;
|
|
104
|
+
case "explain":
|
|
105
|
+
log("\nCode Explanation:\n", "success", quiet);
|
|
106
|
+
log(cleanedContent, "default", quiet);
|
|
107
|
+
break;
|
|
108
|
+
case "test":
|
|
109
|
+
log("\nGenerated Tests:\n", "success", quiet);
|
|
110
|
+
log(cleanedContent, "default", quiet);
|
|
111
|
+
break;
|
|
112
|
+
case "optimize":
|
|
113
|
+
log("\nOptimization Suggestions:\n", "success", quiet);
|
|
114
|
+
log(cleanedContent, "default", quiet);
|
|
115
|
+
break;
|
|
116
|
+
default:
|
|
117
|
+
log("\nAI Response:\n", "success", quiet);
|
|
118
|
+
log(cleanedContent, "default", quiet);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const cleanResponse = (content, options) => {
|
|
123
|
+
const { prompt = "", task = "help" } = options;
|
|
124
|
+
if (!content) {
|
|
125
|
+
return content;
|
|
126
|
+
}
|
|
127
|
+
let cleanedContent = content;
|
|
128
|
+
const taskInstructions = {
|
|
129
|
+
generate: "Generate code according to the following request. Make sure it follows best practices and is well documented:",
|
|
130
|
+
explain: "Explain the following code in detail, including any patterns, potential issues, and improvement suggestions:",
|
|
131
|
+
test: "Generate comprehensive unit tests for the following code:",
|
|
132
|
+
optimize: "Analyze the following code/configuration and suggest optimization improvements:",
|
|
133
|
+
help: "Provide guidance on the following development question:",
|
|
134
|
+
ask: "Provide guidance on the following development question:",
|
|
135
|
+
analyze: "Analyze the following code:"
|
|
136
|
+
};
|
|
137
|
+
const instruction = taskInstructions[task] || "";
|
|
138
|
+
if (instruction && cleanedContent.includes(instruction)) {
|
|
139
|
+
cleanedContent = cleanedContent.replace(instruction, "").trim();
|
|
140
|
+
}
|
|
141
|
+
if (prompt && cleanedContent.includes(prompt)) {
|
|
142
|
+
cleanedContent = cleanedContent.replace(prompt, "").trim();
|
|
143
|
+
}
|
|
144
|
+
if (cleanedContent.includes("===CONTEXT===")) {
|
|
145
|
+
cleanedContent = cleanedContent.split("===CONTEXT===")[0].trim();
|
|
146
|
+
}
|
|
147
|
+
if (!cleanedContent) {
|
|
148
|
+
return content;
|
|
149
|
+
}
|
|
150
|
+
return cleanedContent;
|
|
151
|
+
};
|
|
152
|
+
const getProviderAuth = (provider) => {
|
|
153
|
+
if (process.cwd().includes("reaktor")) {
|
|
154
|
+
return "cursor-auth";
|
|
155
|
+
}
|
|
156
|
+
if (process.env.AI_API_KEY) {
|
|
157
|
+
return process.env.AI_API_KEY;
|
|
158
|
+
}
|
|
159
|
+
if (provider === "none" && process.env.CURSOR_IDE === "true") {
|
|
160
|
+
return "cursor-auth";
|
|
161
|
+
}
|
|
162
|
+
switch (provider) {
|
|
163
|
+
case "openai":
|
|
164
|
+
return process.env.OPENAI_API_KEY;
|
|
165
|
+
case "anthropic":
|
|
166
|
+
return process.env.ANTHROPIC_API_KEY;
|
|
167
|
+
case "cursor":
|
|
168
|
+
return "cursor-auth";
|
|
169
|
+
case "copilot":
|
|
170
|
+
return process.env.GITHUB_TOKEN;
|
|
171
|
+
case "none":
|
|
172
|
+
return void 0;
|
|
173
|
+
default:
|
|
174
|
+
return void 0;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
const detectCursorIDE = () => {
|
|
178
|
+
if (process.env.CURSOR_IDE === "true") {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
const possibleCursorSignals = [
|
|
182
|
+
process.env.CURSOR_EXTENSION === "true",
|
|
183
|
+
process.env.CURSOR_TERMINAL === "true",
|
|
184
|
+
process.env.CURSOR_APP === "true",
|
|
185
|
+
process.env.PATH?.includes("cursor"),
|
|
186
|
+
!!process.env.CURSOR_SESSION_ID
|
|
187
|
+
];
|
|
188
|
+
const isCursorIDE = possibleCursorSignals.some((signal) => signal);
|
|
189
|
+
if (isCursorIDE) {
|
|
190
|
+
process.env.CURSOR_IDE = "true";
|
|
191
|
+
}
|
|
192
|
+
return isCursorIDE;
|
|
193
|
+
};
|
|
194
|
+
const aiFunction = async (options) => {
|
|
195
|
+
try {
|
|
196
|
+
const config = LexConfig.config || {};
|
|
197
|
+
const aiConfig = config.ai || {};
|
|
198
|
+
const provider = options.provider || aiConfig.provider || "none";
|
|
199
|
+
if (provider === "none" && !process.env.CURSOR_EXTENSION) {
|
|
200
|
+
log(`${chalk.red("Error:")} No AI provider configured.`, "error");
|
|
201
|
+
return { error: "No AI provider configured" };
|
|
202
|
+
}
|
|
203
|
+
const task = options.task || "ask";
|
|
204
|
+
const validTasks = ["explain", "generate", "test", "analyze", "ask"];
|
|
205
|
+
if (!validTasks.includes(task)) {
|
|
206
|
+
log(`${chalk.red("Error:")} Invalid task "${task}". Valid tasks are: ${validTasks.join(", ")}`, "error");
|
|
207
|
+
return { error: `Invalid task "${task}"` };
|
|
208
|
+
}
|
|
209
|
+
let prompt = options.prompt;
|
|
210
|
+
if (!prompt) {
|
|
211
|
+
log(`${chalk.red("Error:")} No prompt provided. Use --prompt "Your prompt here"`, "error");
|
|
212
|
+
return { error: "No prompt provided" };
|
|
213
|
+
}
|
|
214
|
+
let context = "";
|
|
215
|
+
if (options.file) {
|
|
216
|
+
try {
|
|
217
|
+
const fs = await import("fs/promises");
|
|
218
|
+
const glob = await import("glob");
|
|
219
|
+
const files = await glob.glob(options.file);
|
|
220
|
+
if (files.length === 0) {
|
|
221
|
+
log(`${chalk.yellow("Warning:")} No files found matching "${options.file}"`, "warning");
|
|
222
|
+
} else {
|
|
223
|
+
for (const file of files) {
|
|
224
|
+
const content = await fs.readFile(file, "utf8");
|
|
225
|
+
context += `
|
|
226
|
+
===FILE: ${file}===
|
|
227
|
+
${content}
|
|
228
|
+
`;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
} catch (error) {
|
|
232
|
+
log(`${chalk.yellow("Warning:")} Error reading file: ${error.message}`, "warning");
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (options.dir) {
|
|
236
|
+
try {
|
|
237
|
+
const { execaSync } = await import("execa");
|
|
238
|
+
const result = execaSync("find", [options.dir, "-type", "f", "|", "sort"]);
|
|
239
|
+
context += `
|
|
240
|
+
===Project structure:===
|
|
241
|
+
${result.stdout}
|
|
242
|
+
`;
|
|
243
|
+
} catch (error) {
|
|
244
|
+
log(`${chalk.yellow("Warning:")} Error reading directory: ${error.message}`, "warning");
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
let formattedPrompt = "";
|
|
248
|
+
switch (task) {
|
|
249
|
+
case "explain":
|
|
250
|
+
formattedPrompt = `Explain the following code:
|
|
251
|
+
${prompt}`;
|
|
252
|
+
break;
|
|
253
|
+
case "generate":
|
|
254
|
+
formattedPrompt = `Generate code according to the following request:
|
|
255
|
+
${prompt}`;
|
|
256
|
+
break;
|
|
257
|
+
case "test":
|
|
258
|
+
formattedPrompt = `Generate comprehensive unit tests:
|
|
259
|
+
${prompt}`;
|
|
260
|
+
break;
|
|
261
|
+
case "analyze":
|
|
262
|
+
formattedPrompt = `Analyze the following code:
|
|
263
|
+
${prompt}`;
|
|
264
|
+
break;
|
|
265
|
+
case "ask":
|
|
266
|
+
formattedPrompt = `Provide guidance on the following development question:
|
|
267
|
+
${prompt}`;
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
if (context) {
|
|
271
|
+
formattedPrompt += `
|
|
272
|
+
===CONTEXT===
|
|
273
|
+
${context}`;
|
|
274
|
+
}
|
|
275
|
+
if ((provider === "cursor" || process.env.CURSOR_EXTENSION) && task === "generate") {
|
|
276
|
+
log(`Using Cursor IDE for code generation...`, "info");
|
|
277
|
+
log(`Note: For full code generation capabilities, please use Cursor IDE directly with Cmd+L or Cmd+K.`, "info");
|
|
278
|
+
log(`The CLI integration has limited capabilities for code generation.`, "warning");
|
|
279
|
+
} else if (provider === "cursor" || process.env.CURSOR_EXTENSION) {
|
|
280
|
+
log(`Using Cursor IDE for AI assistance...`, "info");
|
|
281
|
+
log(`Note: This is a limited integration. For full AI capabilities, use Cursor IDE directly.`, "info");
|
|
282
|
+
} else {
|
|
283
|
+
log(`Using ${provider} for AI assistance...`, "info");
|
|
284
|
+
}
|
|
285
|
+
const response = await callAIService(formattedPrompt, options.quiet || false);
|
|
286
|
+
log(`
|
|
287
|
+
${response}`, "success");
|
|
288
|
+
return { response };
|
|
289
|
+
} catch (error) {
|
|
290
|
+
log(`${chalk.red("Error:")} ${error.message}`, "error");
|
|
291
|
+
return { error: error.message };
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
const ai = new Command("ai").description("Use AI to help with development tasks").option("--provider <provider>", "AI provider to use (openai, anthropic, cursor)").option("--task <task>", "Task to perform (explain, generate, test, analyze, ask)").option("--prompt <prompt>", "Prompt to send to AI").option("--file <file>", "File to analyze").option("--dir <dir>", "Directory to analyze").action(async (options) => {
|
|
295
|
+
await aiFunction(options);
|
|
296
|
+
});
|
|
297
|
+
var ai_default = ai;
|
|
298
|
+
export {
|
|
299
|
+
ai,
|
|
300
|
+
aiFunction,
|
|
301
|
+
ai_default as default
|
|
302
|
+
};
|
|
303
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL2FpL2FpLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxOC1QcmVzZW50LCBOaXRyb2dlbiBMYWJzLCBJbmMuXG4gKiBDb3B5cmlnaHRzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIHRoZSBhY2NvbXBhbnlpbmcgTElDRU5TRSBmaWxlIGZvciB0ZXJtcy5cbiAqL1xuaW1wb3J0IHtyZWFkRmlsZVN5bmN9IGZyb20gJ2ZzJztcbmltcG9ydCB7c3luYyBhcyBnbG9iU3luY30gZnJvbSAnZ2xvYic7XG5pbXBvcnQgeyBDb21tYW5kIH0gZnJvbSAnY29tbWFuZGVyJztcbmltcG9ydCBjaGFsayBmcm9tICdjaGFsayc7XG5cbmltcG9ydCB7TGV4Q29uZmlnfSBmcm9tICcuLi8uLi9MZXhDb25maWcuanMnO1xuaW1wb3J0IHtsb2d9IGZyb20gJy4uLy4uL3V0aWxzL2xvZy5qcyc7XG5pbXBvcnQgeyBjYWxsQUlTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vdXRpbHMvYWlTZXJ2aWNlLmpzJztcblxuaWYgKHByb2Nlc3MuZW52LkNVUlNPUl9FWFRFTlNJT04gPT09ICd0cnVlJyB8fCBcbiAgICBwcm9jZXNzLmVudi5DVVJTT1JfVEVSTUlOQUwgPT09ICd0cnVlJyB8fCBcbiAgICBwcm9jZXNzLmVudi5DVVJTT1JfQVBQID09PSAndHJ1ZScgfHxcbiAgICBwcm9jZXNzLmVudi5QQVRIPy5pbmNsdWRlcygnY3Vyc29yJykgfHxcbiAgICBwcm9jZXNzLmVudi5DVVJTT1JfU0VTU0lPTl9JRCkge1xuICBwcm9jZXNzLmVudi5DVVJTT1JfSURFID0gJ3RydWUnO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFJT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGNsaU5hbWU/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNvbnRleHQ/OiBib29sZWFuO1xuICByZWFkb25seSBmaWxlPzogc3RyaW5nO1xuICByZWFkb25seSBsZXhDb25maWc/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IG1vZGVsPzogc3RyaW5nO1xuICByZWFkb25seSBwcm9tcHQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHF1aWV0PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdGFzaz86ICdnZW5lcmF0ZScgfCAnZXhwbGFpbicgfCAndGVzdCcgfCAnb3B0aW1pemUnIHwgJ2hlbHAnIHwgJ2FzaycgfCAnYW5hbHl6ZSc7XG4gIHJlYWRvbmx5IGRlYnVnPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcHJvdmlkZXI/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRpcj86IHN0cmluZztcbn1cblxuY29uc3QgZ2V0RmlsZUNvbnRleHQgPSAoZmlsZVBhdGg6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU3luYyhmaWxlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgcmV0dXJuIGBGaWxlOiAke2ZpbGVQYXRofVxcblxcbiR7Y29udGVudH1gO1xuICB9IGNhdGNoKF9lcnJvcikge1xuICAgIHJldHVybiBgRXJyb3IgcmVhZGluZyBmaWxlOiAke2ZpbGVQYXRofWA7XG4gIH1cbn07XG5cbmNvbnN0IGdldFByb2plY3RDb250ZXh0ID0gYXN5bmMgKG9wdGlvbnM6IEFJT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gIGNvbnN0IHtmaWxlLCB0YXNrLCBjb250ZXh0fSA9IG9wdGlvbnM7XG5cbiAgaWYoY29udGV4dCA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBsZXQgcHJvamVjdENvbnRleHQgPSAnJztcblxuICBpZihmaWxlKSB7XG4gICAgcHJvamVjdENvbnRleHQgKz0gZ2V0RmlsZUNvbnRleHQoZmlsZSk7XG4gIH1cblxuICBzd2l0Y2godGFzaykge1xuICAgIGNhc2UgJ2dlbmVyYXRlJzpcbiAgICAgIGNvbnN0IGZpbGVzID0gZ2xvYlN5bmMoJ3NyYy8qKi8qLnt0cyx0c3gsanMsanN4fScsIHtcbiAgICAgICAgY3dkOiBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICBpZ25vcmU6IFsnKiovbm9kZV9tb2R1bGVzLyoqJywgJyoqL2Rpc3QvKionLCAnKiovKi50ZXN0LionLCAnKiovKi5zcGVjLionXSxcbiAgICAgICAgbWF4RGVwdGg6IDNcbiAgICAgIH0pO1xuICAgICAgcHJvamVjdENvbnRleHQgKz0gYFxcblxcblByb2plY3Qgc3RydWN0dXJlOlxcbiR7ZmlsZXMuam9pbignXFxuJyl9YDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAndGVzdCc6XG4gICAgICBpZihmaWxlKSB7XG4gICAgICAgIGNvbnN0IHRlc3RDb25maWcgPSBnZXRGaWxlQ29udGV4dCgnamVzdC5jb25maWcuanMnKTtcbiAgICAgICAgcHJvamVjdENvbnRleHQgKz0gYFxcblxcblRlc3QgY29uZmlndXJhdGlvbjpcXG4ke3Rlc3RDb25maWd9YDtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnb3B0aW1pemUnOlxuICAgICAgY29uc3Qgd2VicGFja0NvbmZpZyA9IGdldEZpbGVDb250ZXh0KCd3ZWJwYWNrLmNvbmZpZy5qcycpO1xuICAgICAgcHJvamVjdENvbnRleHQgKz0gYFxcblxcbldlYnBhY2sgY29uZmlndXJhdGlvbjpcXG4ke3dlYnBhY2tDb25maWd9YDtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIHByb2plY3RDb250ZXh0O1xufTtcblxuY29uc3QgY29uc3RydWN0UHJvbXB0ID0gKG9wdGlvbnM6IEFJT3B0aW9ucywgcHJvamVjdENvbnRleHQ6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHt0YXNrID0gJ2hlbHAnLCBwcm9tcHQgPSAnJ30gPSBvcHRpb25zO1xuXG4gIGNvbnN0IHRhc2tJbnN0cnVjdGlvbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgZ2VuZXJhdGU6ICdHZW5lcmF0ZSBjb2RlIGFjY29yZGluZyB0byB0aGUgZm9sbG93aW5nIHJlcXVlc3QuIE1ha2Ugc3VyZSBpdCBmb2xsb3dzIGJlc3QgcHJhY3RpY2VzIGFuZCBpcyB3ZWxsIGRvY3VtZW50ZWQ6JyxcbiAgICBleHBsYWluOiAnRXhwbGFpbiB0aGUgZm9sbG93aW5nIGNvZGUgaW4gZGV0YWlsLCBpbmNsdWRpbmcgYW55IHBhdHRlcm5zLCBwb3RlbnRpYWwgaXNzdWVzLCBhbmQgaW1wcm92ZW1lbnQgc3VnZ2VzdGlvbnM6JyxcbiAgICB0ZXN0OiAnR2VuZXJhdGUgY29tcHJlaGVuc2l2ZSB1bml0IHRlc3RzIGZvciB0aGUgZm9sbG93aW5nIGNvZGU6JyxcbiAgICBvcHRpbWl6ZTogJ0FuYWx5emUgdGhlIGZvbGxvd2luZyBjb2RlL2NvbmZpZ3VyYXRpb24gYW5kIHN1Z2dlc3Qgb3B0aW1pemF0aW9uIGltcHJvdmVtZW50czonLFxuICAgIGhlbHA6ICdQcm92aWRlIGd1aWRhbmNlIG9uIHRoZSBmb2xsb3dpbmcgZGV2ZWxvcG1lbnQgcXVlc3Rpb246JyxcbiAgICBhc2s6ICdQcm92aWRlIGd1aWRhbmNlIG9uIHRoZSBmb2xsb3dpbmcgZGV2ZWxvcG1lbnQgcXVlc3Rpb246JyxcbiAgICBhbmFseXplOiAnQW5hbHl6ZSB0aGUgZm9sbG93aW5nIGNvZGU6J1xuICB9O1xuXG4gIGNvbnN0IHRhc2tJbnN0cnVjdGlvbiA9IHRhc2tJbnN0cnVjdGlvbnNbdGFza10gfHwgdGFza0luc3RydWN0aW9ucy5oZWxwO1xuXG4gIGxldCBmdWxsUHJvbXB0ID0gYCR7dGFza0luc3RydWN0aW9ufVxcblxcbiR7cHJvbXB0fWA7XG5cbiAgaWYocHJvamVjdENvbnRleHQpIHtcbiAgICBmdWxsUHJvbXB0ICs9IGBcXG5cXG49PT1DT05URVhUPT09XFxuJHtwcm9qZWN0Q29udGV4dH1gO1xuICB9XG5cbiAgcmV0dXJuIGZ1bGxQcm9tcHQ7XG59O1xuXG5jb25zdCBkaXNwbGF5UmVzcG9uc2UgPSAocmVzcG9uc2U6IGFueSwgb3B0aW9uczogQUlPcHRpb25zKTogdm9pZCA9PiB7XG4gIGNvbnN0IHt0YXNrID0gJ2hlbHAnLCBxdWlldCA9IGZhbHNlfSA9IG9wdGlvbnM7XG5cbiAgbGV0IGNvbnRlbnQgPSAnJztcbiAgXG4gIGlmICh0eXBlb2YgcmVzcG9uc2UgPT09ICdzdHJpbmcnKSB7XG4gICAgY29udGVudCA9IHJlc3BvbnNlO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlLmNob2ljZXM/LlswXT8ubWVzc2FnZT8uY29udGVudCkge1xuICAgIGNvbnRlbnQgPSByZXNwb25zZS5jaG9pY2VzWzBdLm1lc3NhZ2UuY29udGVudDtcbiAgfSBlbHNlIGlmIChyZXNwb25zZS5jb250ZW50KSB7XG4gICAgY29udGVudCA9IHJlc3BvbnNlLmNvbnRlbnQ7XG4gIH0gZWxzZSB7XG4gICAgY29udGVudCA9ICdObyByZXNwb25zZSByZWNlaXZlZCBmcm9tIEFJIG1vZGVsJztcbiAgfVxuICBcbiAgY29uc3QgY2xlYW5lZENvbnRlbnQgPSBjbGVhblJlc3BvbnNlKGNvbnRlbnQsIG9wdGlvbnMpO1xuICBcbiAgc3dpdGNoKHRhc2spIHtcbiAgICBjYXNlICdnZW5lcmF0ZSc6XG4gICAgICBsb2coJ1xcbkdlbmVyYXRlZCBDb2RlOlxcbicsICdzdWNjZXNzJywgcXVpZXQpO1xuICAgICAgbG9nKGNsZWFuZWRDb250ZW50LCAnZGVmYXVsdCcsIHF1aWV0KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnZXhwbGFpbic6XG4gICAgICBsb2coJ1xcbkNvZGUgRXhwbGFuYXRpb246XFxuJywgJ3N1Y2Nlc3MnLCBxdWlldCk7XG4gICAgICBsb2coY2xlYW5lZENvbnRlbnQsICdkZWZhdWx0JywgcXVpZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICd0ZXN0JzpcbiAgICAgIGxvZygnXFxuR2VuZXJhdGVkIFRlc3RzOlxcbicsICdzdWNjZXNzJywgcXVpZXQpO1xuICAgICAgbG9nKGNsZWFuZWRDb250ZW50LCAnZGVmYXVsdCcsIHF1aWV0KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnb3B0aW1pemUnOlxuICAgICAgbG9nKCdcXG5PcHRpbWl6YXRpb24gU3VnZ2VzdGlvbnM6XFxuJywgJ3N1Y2Nlc3MnLCBxdWlldCk7XG4gICAgICBsb2coY2xlYW5lZENvbnRlbnQsICdkZWZhdWx0JywgcXVpZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgbG9nKCdcXG5BSSBSZXNwb25zZTpcXG4nLCAnc3VjY2VzcycsIHF1aWV0KTtcbiAgICAgIGxvZyhjbGVhbmVkQ29udGVudCwgJ2RlZmF1bHQnLCBxdWlldCk7XG4gICAgICBicmVhaztcbiAgfVxufTtcblxuY29uc3QgY2xlYW5SZXNwb25zZSA9IChjb250ZW50OiBzdHJpbmcsIG9wdGlvbnM6IEFJT3B0aW9ucyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHtwcm9tcHQgPSAnJywgdGFzayA9ICdoZWxwJ30gPSBvcHRpb25zO1xuICBcbiAgaWYgKCFjb250ZW50KSB7XG4gICAgcmV0dXJuIGNvbnRlbnQ7XG4gIH1cbiAgXG4gIGxldCBjbGVhbmVkQ29udGVudCA9IGNvbnRlbnQ7XG4gIFxuICBjb25zdCB0YXNrSW5zdHJ1Y3Rpb25zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIGdlbmVyYXRlOiAnR2VuZXJhdGUgY29kZSBhY2NvcmRpbmcgdG8gdGhlIGZvbGxvd2luZyByZXF1ZXN0LiBNYWtlIHN1cmUgaXQgZm9sbG93cyBiZXN0IHByYWN0aWNlcyBhbmQgaXMgd2VsbCBkb2N1bWVudGVkOicsXG4gICAgZXhwbGFpbjogJ0V4cGxhaW4gdGhlIGZvbGxvd2luZyBjb2RlIGluIGRldGFpbCwgaW5jbHVkaW5nIGFueSBwYXR0ZXJucywgcG90ZW50aWFsIGlzc3VlcywgYW5kIGltcHJvdmVtZW50IHN1Z2dlc3Rpb25zOicsXG4gICAgdGVzdDogJ0dlbmVyYXRlIGNvbXByZWhlbnNpdmUgdW5pdCB0ZXN0cyBmb3IgdGhlIGZvbGxvd2luZyBjb2RlOicsXG4gICAgb3B0aW1pemU6ICdBbmFseXplIHRoZSBmb2xsb3dpbmcgY29kZS9jb25maWd1cmF0aW9uIGFuZCBzdWdnZXN0IG9wdGltaXphdGlvbiBpbXByb3ZlbWVudHM6JyxcbiAgICBoZWxwOiAnUHJvdmlkZSBndWlkYW5jZSBvbiB0aGUgZm9sbG93aW5nIGRldmVsb3BtZW50IHF1ZXN0aW9uOicsXG4gICAgYXNrOiAnUHJvdmlkZSBndWlkYW5jZSBvbiB0aGUgZm9sbG93aW5nIGRldmVsb3BtZW50IHF1ZXN0aW9uOicsXG4gICAgYW5hbHl6ZTogJ0FuYWx5emUgdGhlIGZvbGxvd2luZyBjb2RlOidcbiAgfTtcbiAgXG4gIGNvbnN0IGluc3RydWN0aW9uID0gdGFza0luc3RydWN0aW9uc1t0YXNrXSB8fCAnJztcblxuICBpZiAoaW5zdHJ1Y3Rpb24gJiYgY2xlYW5lZENvbnRlbnQuaW5jbHVkZXMoaW5zdHJ1Y3Rpb24pKSB7XG4gICAgY2xlYW5lZENvbnRlbnQgPSBjbGVhbmVkQ29udGVudC5yZXBsYWNlKGluc3RydWN0aW9uLCAnJykudHJpbSgpO1xuICB9XG4gIFxuICBpZiAocHJvbXB0ICYmIGNsZWFuZWRDb250ZW50LmluY2x1ZGVzKHByb21wdCkpIHtcbiAgICBjbGVhbmVkQ29udGVudCA9IGNsZWFuZWRDb250ZW50LnJlcGxhY2UocHJvbXB0LCAnJykudHJpbSgpO1xuICB9XG4gIFxuICBpZiAoY2xlYW5lZENvbnRlbnQuaW5jbHVkZXMoJz09PUNPTlRFWFQ9PT0nKSkge1xuICAgIGNsZWFuZWRDb250ZW50ID0gY2xlYW5lZENvbnRlbnQuc3BsaXQoJz09PUNPTlRFWFQ9PT0nKVswXS50cmltKCk7XG4gIH1cbiAgXG4gIGlmICghY2xlYW5lZENvbnRlbnQpIHtcbiAgICByZXR1cm4gY29udGVudDtcbiAgfVxuICBcbiAgcmV0dXJuIGNsZWFuZWRDb250ZW50O1xufTtcblxuY29uc3QgZ2V0UHJvdmlkZXJBdXRoID0gKHByb3ZpZGVyOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4ge1xuICBpZiAocHJvY2Vzcy5jd2QoKS5pbmNsdWRlcygncmVha3RvcicpKSB7XG4gICAgcmV0dXJuICdjdXJzb3ItYXV0aCc7XG4gIH1cblxuICBpZihwcm9jZXNzLmVudi5BSV9BUElfS0VZKSB7XG4gICAgcmV0dXJuIHByb2Nlc3MuZW52LkFJX0FQSV9LRVk7XG4gIH1cblxuICBpZihwcm92aWRlciA9PT0gJ25vbmUnICYmIHByb2Nlc3MuZW52LkNVUlNPUl9JREUgPT09ICd0cnVlJykge1xuICAgIHJldHVybiAnY3Vyc29yLWF1dGgnO1xuICB9XG5cbiAgc3dpdGNoKHByb3ZpZGVyKSB7XG4gICAgY2FzZSAnb3BlbmFpJzpcbiAgICAgIHJldHVybiBwcm9jZXNzLmVudi5PUEVOQUlfQVBJX0tFWTtcbiAgICBjYXNlICdhbnRocm9waWMnOlxuICAgICAgcmV0dXJuIHByb2Nlc3MuZW52LkFOVEhST1BJQ19BUElfS0VZO1xuICAgIGNhc2UgJ2N1cnNvcic6XG4gICAgICByZXR1cm4gJ2N1cnNvci1hdXRoJztcbiAgICBjYXNlICdjb3BpbG90JzpcbiAgICAgIHJldHVybiBwcm9jZXNzLmVudi5HSVRIVUJfVE9LRU47XG4gICAgY2FzZSAnbm9uZSc6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59O1xuXG5jb25zdCBkZXRlY3RDdXJzb3JJREUgPSAoKTogYm9vbGVhbiA9PiB7XG4gIGlmKHByb2Nlc3MuZW52LkNVUlNPUl9JREUgPT09ICd0cnVlJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIFxuICBjb25zdCBwb3NzaWJsZUN1cnNvclNpZ25hbHMgPSBbXG4gICAgcHJvY2Vzcy5lbnYuQ1VSU09SX0VYVEVOU0lPTiA9PT0gJ3RydWUnLFxuICAgIHByb2Nlc3MuZW52LkNVUlNPUl9URVJNSU5BTCA9PT0gJ3RydWUnLFxuICAgIHByb2Nlc3MuZW52LkNVUlNPUl9BUFAgPT09ICd0cnVlJyxcbiAgICBwcm9jZXNzLmVudi5QQVRIPy5pbmNsdWRlcygnY3Vyc29yJyksXG4gICAgISFwcm9jZXNzLmVudi5DVVJTT1JfU0VTU0lPTl9JRFxuICBdO1xuICBcbiAgY29uc3QgaXNDdXJzb3JJREUgPSBwb3NzaWJsZUN1cnNvclNpZ25hbHMuc29tZShzaWduYWwgPT4gc2lnbmFsKTtcbiAgXG4gIGlmKGlzQ3Vyc29ySURFKSB7XG4gICAgcHJvY2Vzcy5lbnYuQ1VSU09SX0lERSA9ICd0cnVlJztcbiAgfVxuICBcbiAgcmV0dXJuIGlzQ3Vyc29ySURFO1xufTtcblxuZXhwb3J0IGNvbnN0IGFpRnVuY3Rpb24gPSBhc3luYyAob3B0aW9uczogQUlPcHRpb25zKTogUHJvbWlzZTxhbnk+ID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBjb25maWcgPSBMZXhDb25maWcuY29uZmlnIHx8IHt9O1xuICAgIGNvbnN0IGFpQ29uZmlnID0gY29uZmlnLmFpIHx8IHt9O1xuICAgIGNvbnN0IHByb3ZpZGVyID0gb3B0aW9ucy5wcm92aWRlciB8fCBhaUNvbmZpZy5wcm92aWRlciB8fCAnbm9uZSc7XG4gICAgXG4gICAgaWYgKHByb3ZpZGVyID09PSAnbm9uZScgJiYgIXByb2Nlc3MuZW52LkNVUlNPUl9FWFRFTlNJT04pIHtcbiAgICAgIGxvZyhgJHtjaGFsay5yZWQoJ0Vycm9yOicpfSBObyBBSSBwcm92aWRlciBjb25maWd1cmVkLmAsICdlcnJvcicpO1xuICAgICAgcmV0dXJuIHsgZXJyb3I6ICdObyBBSSBwcm92aWRlciBjb25maWd1cmVkJyB9O1xuICAgIH1cblxuICAgIGNvbnN0IHRhc2sgPSBvcHRpb25zLnRhc2sgfHwgJ2Fzayc7XG4gICAgY29uc3QgdmFsaWRUYXNrcyA9IFsnZXhwbGFpbicsICdnZW5lcmF0ZScsICd0ZXN0JywgJ2FuYWx5emUnLCAnYXNrJ107XG5cbiAgICBpZiAoIXZhbGlkVGFza3MuaW5jbHVkZXModGFzaykpIHtcbiAgICAgIGxvZyhgJHtjaGFsay5yZWQoJ0Vycm9yOicpfSBJbnZhbGlkIHRhc2sgXCIke3Rhc2t9XCIuIFZhbGlkIHRhc2tzIGFyZTogJHt2YWxpZFRhc2tzLmpvaW4oJywgJyl9YCwgJ2Vycm9yJyk7XG4gICAgICByZXR1cm4geyBlcnJvcjogYEludmFsaWQgdGFzayBcIiR7dGFza31cImAgfTtcbiAgICB9XG5cbiAgICBsZXQgcHJvbXB0ID0gb3B0aW9ucy5wcm9tcHQ7XG5cbiAgICBpZiAoIXByb21wdCkge1xuICAgICAgbG9nKGAke2NoYWxrLnJlZCgnRXJyb3I6Jyl9IE5vIHByb21wdCBwcm92aWRlZC4gVXNlIC0tcHJvbXB0IFwiWW91ciBwcm9tcHQgaGVyZVwiYCwgJ2Vycm9yJyk7XG4gICAgICByZXR1cm4geyBlcnJvcjogJ05vIHByb21wdCBwcm92aWRlZCcgfTtcbiAgICB9XG5cbiAgICBsZXQgY29udGV4dCA9ICcnO1xuICAgIFxuICAgIGlmIChvcHRpb25zLmZpbGUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGZzID0gYXdhaXQgaW1wb3J0KCdmcy9wcm9taXNlcycpO1xuICAgICAgICBjb25zdCBnbG9iID0gYXdhaXQgaW1wb3J0KCdnbG9iJyk7XG4gICAgICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgZ2xvYi5nbG9iKG9wdGlvbnMuZmlsZSk7XG4gICAgICAgIFxuICAgICAgICBpZiAoZmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgbG9nKGAke2NoYWxrLnllbGxvdygnV2FybmluZzonKX0gTm8gZmlsZXMgZm91bmQgbWF0Y2hpbmcgXCIke29wdGlvbnMuZmlsZX1cImAsICd3YXJuaW5nJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgICAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUoZmlsZSwgJ3V0ZjgnKTtcbiAgICAgICAgICAgIGNvbnRleHQgKz0gYFxcbj09PUZJTEU6ICR7ZmlsZX09PT1cXG4ke2NvbnRlbnR9XFxuYDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZyhgJHtjaGFsay55ZWxsb3coJ1dhcm5pbmc6Jyl9IEVycm9yIHJlYWRpbmcgZmlsZTogJHtlcnJvci5tZXNzYWdlfWAsICd3YXJuaW5nJyk7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIGlmIChvcHRpb25zLmRpcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyBleGVjYVN5bmMgfSA9IGF3YWl0IGltcG9ydCgnZXhlY2EnKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZXhlY2FTeW5jKCdmaW5kJywgW29wdGlvbnMuZGlyLCAnLXR5cGUnLCAnZicsICd8JywgJ3NvcnQnXSk7XG4gICAgICAgIGNvbnRleHQgKz0gYFxcbj09PVByb2plY3Qgc3RydWN0dXJlOj09PVxcbiR7cmVzdWx0LnN0ZG91dH1cXG5gO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nKGAke2NoYWxrLnllbGxvdygnV2FybmluZzonKX0gRXJyb3IgcmVhZGluZyBkaXJlY3Rvcnk6ICR7ZXJyb3IubWVzc2FnZX1gLCAnd2FybmluZycpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBmb3JtYXR0ZWRQcm9tcHQgPSAnJztcblxuICAgIHN3aXRjaCh0YXNrKSB7XG4gICAgICBjYXNlICdleHBsYWluJzpcbiAgICAgICAgZm9ybWF0dGVkUHJvbXB0ID0gYEV4cGxhaW4gdGhlIGZvbGxvd2luZyBjb2RlOlxcbiR7cHJvbXB0fWA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZ2VuZXJhdGUnOlxuICAgICAgICBmb3JtYXR0ZWRQcm9tcHQgPSBgR2VuZXJhdGUgY29kZSBhY2NvcmRpbmcgdG8gdGhlIGZvbGxvd2luZyByZXF1ZXN0OlxcbiR7cHJvbXB0fWA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndGVzdCc6XG4gICAgICAgIGZvcm1hdHRlZFByb21wdCA9IGBHZW5lcmF0ZSBjb21wcmVoZW5zaXZlIHVuaXQgdGVzdHM6XFxuJHtwcm9tcHR9YDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdhbmFseXplJzpcbiAgICAgICAgZm9ybWF0dGVkUHJvbXB0ID0gYEFuYWx5emUgdGhlIGZvbGxvd2luZyBjb2RlOlxcbiR7cHJvbXB0fWA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYXNrJzpcbiAgICAgICAgZm9ybWF0dGVkUHJvbXB0ID0gYFByb3ZpZGUgZ3VpZGFuY2Ugb24gdGhlIGZvbGxvd2luZyBkZXZlbG9wbWVudCBxdWVzdGlvbjpcXG4ke3Byb21wdH1gO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCkge1xuICAgICAgZm9ybWF0dGVkUHJvbXB0ICs9IGBcXG49PT1DT05URVhUPT09XFxuJHtjb250ZXh0fWA7XG4gICAgfVxuXG4gICAgaWYgKChwcm92aWRlciA9PT0gJ2N1cnNvcicgfHwgcHJvY2Vzcy5lbnYuQ1VSU09SX0VYVEVOU0lPTikgJiYgdGFzayA9PT0gJ2dlbmVyYXRlJykge1xuICAgICAgbG9nKGBVc2luZyBDdXJzb3IgSURFIGZvciBjb2RlIGdlbmVyYXRpb24uLi5gLCAnaW5mbycpO1xuICAgICAgbG9nKGBOb3RlOiBGb3IgZnVsbCBjb2RlIGdlbmVyYXRpb24gY2FwYWJpbGl0aWVzLCBwbGVhc2UgdXNlIEN1cnNvciBJREUgZGlyZWN0bHkgd2l0aCBDbWQrTCBvciBDbWQrSy5gLCAnaW5mbycpO1xuICAgICAgbG9nKGBUaGUgQ0xJIGludGVncmF0aW9uIGhhcyBsaW1pdGVkIGNhcGFiaWxpdGllcyBmb3IgY29kZSBnZW5lcmF0aW9uLmAsICd3YXJuaW5nJyk7XG4gICAgfSBlbHNlIGlmIChwcm92aWRlciA9PT0gJ2N1cnNvcicgfHwgcHJvY2Vzcy5lbnYuQ1VSU09SX0VYVEVOU0lPTikge1xuICAgICAgbG9nKGBVc2luZyBDdXJzb3IgSURFIGZvciBBSSBhc3Npc3RhbmNlLi4uYCwgJ2luZm8nKTtcbiAgICAgIGxvZyhgTm90ZTogVGhpcyBpcyBhIGxpbWl0ZWQgaW50ZWdyYXRpb24uIEZvciBmdWxsIEFJIGNhcGFiaWxpdGllcywgdXNlIEN1cnNvciBJREUgZGlyZWN0bHkuYCwgJ2luZm8nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nKGBVc2luZyAke3Byb3ZpZGVyfSBmb3IgQUkgYXNzaXN0YW5jZS4uLmAsICdpbmZvJyk7XG4gICAgfVxuICAgIFxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2FsbEFJU2VydmljZShmb3JtYXR0ZWRQcm9tcHQsIG9wdGlvbnMucXVpZXQgfHwgZmFsc2UpO1xuICAgIFxuICAgIGxvZyhgXFxuJHtyZXNwb25zZX1gLCAnc3VjY2VzcycpO1xuICAgIFxuICAgIHJldHVybiB7IHJlc3BvbnNlIH07XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgbG9nKGAke2NoYWxrLnJlZCgnRXJyb3I6Jyl9ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InKTtcbiAgICByZXR1cm4geyBlcnJvcjogZXJyb3IubWVzc2FnZSB9O1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgYWkgPSBuZXcgQ29tbWFuZCgnYWknKVxuICAuZGVzY3JpcHRpb24oJ1VzZSBBSSB0byBoZWxwIHdpdGggZGV2ZWxvcG1lbnQgdGFza3MnKVxuICAub3B0aW9uKCctLXByb3ZpZGVyIDxwcm92aWRlcj4nLCAnQUkgcHJvdmlkZXIgdG8gdXNlIChvcGVuYWksIGFudGhyb3BpYywgY3Vyc29yKScpXG4gIC5vcHRpb24oJy0tdGFzayA8dGFzaz4nLCAnVGFzayB0byBwZXJmb3JtIChleHBsYWluLCBnZW5lcmF0ZSwgdGVzdCwgYW5hbHl6ZSwgYXNrKScpXG4gIC5vcHRpb24oJy0tcHJvbXB0IDxwcm9tcHQ+JywgJ1Byb21wdCB0byBzZW5kIHRvIEFJJylcbiAgLm9wdGlvbignLS1maWxlIDxmaWxlPicsICdGaWxlIHRvIGFuYWx5emUnKVxuICAub3B0aW9uKCctLWRpciA8ZGlyPicsICdEaXJlY3RvcnkgdG8gYW5hbHl6ZScpXG4gIC5hY3Rpb24oYXN5bmMgKG9wdGlvbnM6IEFJT3B0aW9ucykgPT4ge1xuICAgIGF3YWl0IGFpRnVuY3Rpb24ob3B0aW9ucyk7XG4gIH0pO1xuXG5leHBvcnQgZGVmYXVsdCBhaTsiXSwKICAibWFwcGluZ3MiOiAiQUFJQSxTQUFRLG9CQUFtQjtBQUMzQixTQUFRLFFBQVEsZ0JBQWU7QUFDL0IsU0FBUyxlQUFlO0FBQ3hCLE9BQU8sV0FBVztBQUVsQixTQUFRLGlCQUFnQjtBQUN4QixTQUFRLFdBQVU7QUFDbEIsU0FBUyxxQkFBcUI7QUFFOUIsSUFBSSxRQUFRLElBQUkscUJBQXFCLFVBQ2pDLFFBQVEsSUFBSSxvQkFBb0IsVUFDaEMsUUFBUSxJQUFJLGVBQWUsVUFDM0IsUUFBUSxJQUFJLE1BQU0sU0FBUyxRQUFRLEtBQ25DLFFBQVEsSUFBSSxtQkFBbUI7QUFDakMsVUFBUSxJQUFJLGFBQWE7QUFDM0I7QUFnQkEsTUFBTSxpQkFBaUIsQ0FBQyxhQUE2QjtBQUNuRCxNQUFJO0FBQ0YsVUFBTSxVQUFVLGFBQWEsVUFBVSxPQUFPO0FBQzlDLFdBQU8sU0FBUyxRQUFRO0FBQUE7QUFBQSxFQUFPLE9BQU87QUFBQSxFQUN4QyxTQUFRLFFBQVE7QUFDZCxXQUFPLHVCQUF1QixRQUFRO0FBQUEsRUFDeEM7QUFDRjtBQUVBLE1BQU0sb0JBQW9CLE9BQU8sWUFBd0M7QUFDdkUsUUFBTSxFQUFDLE1BQU0sTUFBTSxRQUFPLElBQUk7QUFFOUIsTUFBRyxZQUFZLE9BQU87QUFDcEIsV0FBTztBQUFBLEVBQ1Q7QUFFQSxNQUFJLGlCQUFpQjtBQUVyQixNQUFHLE1BQU07QUFDUCxzQkFBa0IsZUFBZSxJQUFJO0FBQUEsRUFDdkM7QUFFQSxVQUFPLE1BQU07QUFBQSxJQUNYLEtBQUs7QUFDSCxZQUFNLFFBQVEsU0FBUyw0QkFBNEI7QUFBQSxRQUNqRCxLQUFLLFFBQVEsSUFBSTtBQUFBLFFBQ2pCLFFBQVEsQ0FBQyxzQkFBc0IsY0FBYyxlQUFlLGFBQWE7QUFBQSxRQUN6RSxVQUFVO0FBQUEsTUFDWixD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
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import ai from "./ai.js";
|
|
2
|
+
var ai_default = ai;
|
|
3
|
+
export {
|
|
4
|
+
ai,
|
|
5
|
+
ai_default as default
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL2FpL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxOC1QcmVzZW50LCBOaXRyb2dlbiBMYWJzLCBJbmMuXG4gKiBDb3B5cmlnaHRzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIHRoZSBhY2NvbXBhbnlpbmcgTElDRU5TRSBmaWxlIGZvciB0ZXJtcy5cbiAqL1xuaW1wb3J0IGFpLCB7dHlwZSBBSU9wdGlvbnN9IGZyb20gJy4vYWkuanMnO1xuXG5leHBvcnQge2FpfTtcbmV4cG9ydCB0eXBlIHtBSU9wdGlvbnN9O1xuZXhwb3J0IGRlZmF1bHQgYWk7ICJdLAogICJtYXBwaW5ncyI6ICJBQUlBLE9BQU8sUUFBMEI7QUFJakMsSUFBTyxhQUFROyIsCiAgIm5hbWVzIjogW10KfQo=
|