@nlabs/lex 1.48.6 → 1.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/.storybook/main.ts +9 -2
  2. package/.vscode/settings.json +1 -6
  3. package/README.md +276 -4
  4. package/eslint.config.mjs +24 -0
  5. package/examples/lex.config.js +18 -8
  6. package/examples/serverless-example/README.md +109 -0
  7. package/examples/serverless-example/dist/handlers/echo.js +15 -0
  8. package/examples/serverless-example/dist/handlers/graphql.js +137 -0
  9. package/examples/serverless-example/dist/handlers/hello.js +15 -0
  10. package/examples/serverless-example/dist/handlers/test.js +17 -0
  11. package/examples/serverless-example/dist/handlers/websocket.js +14 -0
  12. package/examples/serverless-example/lex.config.mjs +74 -0
  13. package/jest.config.mjs +13 -12
  14. package/{dist → lib}/LexConfig.d.ts +14 -6
  15. package/lib/LexConfig.js +268 -0
  16. package/lib/commands/ai/ai.js +303 -0
  17. package/{dist → lib}/commands/build/build.d.ts +3 -0
  18. package/lib/commands/build/build.js +494 -0
  19. package/{dist → lib}/commands/clean/clean.js +1 -1
  20. package/lib/commands/compile/compile.js +241 -0
  21. package/lib/commands/copy/copy.js +38 -0
  22. package/{dist → lib}/commands/create/create.js +1 -1
  23. package/{dist → lib}/commands/dev/dev.d.ts +2 -0
  24. package/lib/commands/dev/dev.js +286 -0
  25. package/{dist → lib}/commands/init/init.js +1 -1
  26. package/{dist → lib}/commands/lint/lint.d.ts +4 -1
  27. package/lib/commands/lint/lint.js +993 -0
  28. package/{dist → lib}/commands/migrate/migrate.js +1 -1
  29. package/lib/commands/publish/publish.js +104 -0
  30. package/lib/commands/serverless/serverless.d.ts +17 -0
  31. package/lib/commands/serverless/serverless.js +662 -0
  32. package/lib/commands/storybook/storybook.js +249 -0
  33. package/lib/commands/test/test.js +428 -0
  34. package/lib/commands/update/update.js +128 -0
  35. package/lib/commands/versions/versions.js +41 -0
  36. package/{dist → lib}/create/changelog.js +1 -1
  37. package/{dist → lib}/index.d.ts +2 -0
  38. package/{dist → lib}/index.js +3 -1
  39. package/lib/lex.js +73 -0
  40. package/lib/storybook/index.d.ts +5 -0
  41. package/lib/types.js +1 -0
  42. package/lib/utils/aiService.d.ts +9 -0
  43. package/lib/utils/aiService.js +299 -0
  44. package/{dist → lib}/utils/app.d.ts +3 -0
  45. package/lib/utils/app.js +296 -0
  46. package/lib/utils/deepMerge.js +26 -0
  47. package/{dist → lib}/utils/file.d.ts +7 -3
  48. package/lib/utils/file.js +229 -0
  49. package/lib/utils/translations.d.ts +1 -0
  50. package/lib/utils/translations.js +74 -0
  51. package/package.json +62 -50
  52. package/postcss.config.js +5 -3
  53. package/tsconfig.build.json +2 -2
  54. package/webpack.config.js +229 -39
  55. package/dist/LexConfig.js +0 -286
  56. package/dist/commands/ai/ai.js +0 -303
  57. package/dist/commands/build/build.js +0 -404
  58. package/dist/commands/compile/compile.js +0 -234
  59. package/dist/commands/copy/copy.js +0 -38
  60. package/dist/commands/dev/dev.js +0 -74
  61. package/dist/commands/lint/lint.js +0 -811
  62. package/dist/commands/publish/publish.js +0 -104
  63. package/dist/commands/storybook/storybook.js +0 -249
  64. package/dist/commands/test/test.js +0 -429
  65. package/dist/commands/update/update.js +0 -132
  66. package/dist/commands/versions/versions.js +0 -41
  67. package/dist/lex.js +0 -70
  68. package/dist/utils/aiService.d.ts +0 -9
  69. package/dist/utils/aiService.js +0 -299
  70. package/dist/utils/app.js +0 -267
  71. package/dist/utils/deepMerge.js +0 -24
  72. package/dist/utils/file.js +0 -185
  73. package/emptyModule.js +0 -0
  74. package/eslint.config.js +0 -7
  75. /package/{dist → lib}/Button.stories.d.ts +0 -0
  76. /package/{dist → lib}/commands/ai/ai.d.ts +0 -0
  77. /package/{dist → lib}/commands/ai/index.d.ts +0 -0
  78. /package/{dist → lib}/commands/ai/index.js +0 -0
  79. /package/{dist → lib}/commands/clean/clean.d.ts +0 -0
  80. /package/{dist → lib}/commands/compile/compile.d.ts +0 -0
  81. /package/{dist → lib}/commands/config/config.d.ts +0 -0
  82. /package/{dist → lib}/commands/config/config.js +0 -0
  83. /package/{dist → lib}/commands/copy/copy.d.ts +0 -0
  84. /package/{dist → lib}/commands/create/create.d.ts +0 -0
  85. /package/{dist → lib}/commands/init/init.d.ts +0 -0
  86. /package/{dist → lib}/commands/link/link.d.ts +0 -0
  87. /package/{dist → lib}/commands/link/link.js +0 -0
  88. /package/{dist → lib}/commands/lint/autofix.d.ts +0 -0
  89. /package/{dist → lib}/commands/migrate/migrate.d.ts +0 -0
  90. /package/{dist → lib}/commands/publish/publish.d.ts +0 -0
  91. /package/{dist → lib}/commands/storybook/storybook.d.ts +0 -0
  92. /package/{dist → lib}/commands/test/test.d.ts +0 -0
  93. /package/{dist → lib}/commands/update/update.d.ts +0 -0
  94. /package/{dist → lib}/commands/upgrade/upgrade.d.ts +0 -0
  95. /package/{dist → lib}/commands/upgrade/upgrade.js +0 -0
  96. /package/{dist → lib}/commands/versions/versions.d.ts +0 -0
  97. /package/{dist → lib}/create/changelog.d.ts +0 -0
  98. /package/{dist → lib}/lex.d.ts +0 -0
  99. /package/{dist/types.js → lib/storybook/index.js} +0 -0
  100. /package/{dist → lib}/test-react/index.d.ts +0 -0
  101. /package/{dist → lib}/test-react/index.js +0 -0
  102. /package/{dist → lib}/types.d.ts +0 -0
  103. /package/{dist → lib}/utils/deepMerge.d.ts +0 -0
  104. /package/{dist → lib}/utils/log.d.ts +0 -0
  105. /package/{dist → lib}/utils/log.js +0 -0
  106. /package/{dist → lib}/utils/reactShim.d.ts +0 -0
  107. /package/{dist → lib}/utils/reactShim.js +0 -0
@@ -0,0 +1,299 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "fs";
2
+ import { resolve as pathResolve } from "path";
3
+ import readline from "readline";
4
+ import { LexConfig } from "../LexConfig.js";
5
+ import { createSpinner } from "./app.js";
6
+ import { log } from "./log.js";
7
+ const callCursorAI = async (prompt, _options) => {
8
+ try {
9
+ log("Using Cursor IDE for AI fixes...", "info");
10
+ log("AI fix requested via Cursor IDE", "info");
11
+ const taskMatch = prompt.match(/^(Generate code according to the following request|Explain the following code|Generate comprehensive unit tests|Analyze the following code|Provide guidance on the following development question):/);
12
+ const task = taskMatch ? taskMatch[1] : "";
13
+ const isGenerateTask = task.startsWith("Generate code");
14
+ const questionMatch = prompt.match(/(?:Generate code according to the following request|Explain the following code|Generate comprehensive unit tests|Analyze the following code|Provide guidance on the following development question):\s*([\s\S]+?)(?:===CONTEXT===|$)/);
15
+ const question = questionMatch ? questionMatch[1].trim() : prompt;
16
+ if (question.toLowerCase().includes("how many files") && prompt.includes("Project structure:")) {
17
+ const projectStructure = prompt.split("Project structure:")[1] || "";
18
+ const files = projectStructure.trim().split("\n");
19
+ return `Based on the project structure provided, there are ${files.length} files in the project.`;
20
+ }
21
+ if (isGenerateTask) {
22
+ return `
23
+ # Code Generation Request: "${question}"
24
+
25
+ To generate code using Cursor's AI capabilities:
26
+
27
+ 1. **Open your project in Cursor IDE** (https://cursor.sh)
28
+ 2. Press **Cmd+L** (or Ctrl+L on Windows/Linux) to open the AI chat
29
+ 3. Type your request: "${question}"
30
+ 4. Cursor will generate the code directly in your editor
31
+
32
+ The current CLI integration doesn't have direct access to Cursor's code generation capabilities.
33
+
34
+ **Alternative options:**
35
+
36
+ 1. **Use OpenAI or Anthropic directly:**
37
+ Configure in your lex.config file:
38
+ \`\`\`js
39
+ export default {
40
+ ai: {
41
+ provider: 'openai',
42
+ apiKey: process.env.OPENAI_API_KEY,
43
+ model: 'gpt-4o'
44
+ }
45
+ }
46
+ \`\`\`
47
+
48
+ 2. **Use Cursor's command line tool:**
49
+ Install: \`npm install -g @cursor/cli\`
50
+ Run: \`cursor ai "${question}"\`
51
+ `;
52
+ }
53
+ return `
54
+ To use Cursor's AI capabilities for "${question}", you need to:
55
+
56
+ 1. Open your project in Cursor IDE (https://cursor.sh)
57
+ 2. Use Cursor's built-in AI features by pressing Cmd+K or Cmd+L
58
+ 3. Or run the 'cursor' command directly from your terminal
59
+
60
+ The current integration is limited and doesn't directly access Cursor's AI capabilities.
61
+
62
+ For the best experience with AI code generation:
63
+ - Use Cursor IDE directly
64
+ - Or configure OpenAI or Anthropic as your provider in your lex.config file:
65
+
66
+ \`\`\`js
67
+ // lex.config.js (or lex.config.mjs, lex.config.cjs, etc.)
68
+ export default {
69
+ ai: {
70
+ provider: 'openai', // or 'anthropic'
71
+ apiKey: process.env.OPENAI_API_KEY, // or ANTHROPIC_API_KEY
72
+ model: 'gpt-4o' // or 'claude-3-opus'
73
+ }
74
+ }
75
+ \`\`\`
76
+
77
+ Then set your API key as an environment variable:
78
+ \`\`\`
79
+ export OPENAI_API_KEY=your_key_here
80
+ \`\`\`
81
+ `;
82
+ } catch (error) {
83
+ throw new Error(`Cursor AI error: ${error.message}`);
84
+ }
85
+ };
86
+ const callOpenAIAI = async (prompt, options) => {
87
+ try {
88
+ const apiKey = options.apiKey || process.env.OPENAI_API_KEY;
89
+ if (!apiKey) {
90
+ throw new Error("OpenAI API key is required. Set it in your lex.config file or as OPENAI_API_KEY environment variable.");
91
+ }
92
+ const response = await fetch("https://api.openai.com/v1/chat/completions", {
93
+ body: JSON.stringify({
94
+ max_tokens: options.maxTokens || 4e3,
95
+ messages: [
96
+ { content: "You are a helpful assistant that fixes ESLint errors in code.", role: "system" },
97
+ { content: prompt, role: "user" }
98
+ ],
99
+ model: options.model || "gpt-4o",
100
+ temperature: options.temperature || 0.1
101
+ }),
102
+ headers: {
103
+ Authorization: `Bearer ${apiKey}`,
104
+ "Content-Type": "application/json"
105
+ },
106
+ method: "POST"
107
+ });
108
+ if (!response.ok) {
109
+ const error = await response.json();
110
+ throw new Error(`OpenAI API error: ${error.error?.message || response.statusText}`);
111
+ }
112
+ const data = await response.json();
113
+ return data.choices[0].message.content;
114
+ } catch (error) {
115
+ throw new Error(`OpenAI AI error: ${error.message}`);
116
+ }
117
+ };
118
+ const callAnthropicAI = async (prompt, options) => {
119
+ try {
120
+ const apiKey = options.apiKey || process.env.ANTHROPIC_API_KEY;
121
+ if (!apiKey) {
122
+ throw new Error("Anthropic API key is required. Set it in your lex.config file or as ANTHROPIC_API_KEY environment variable.");
123
+ }
124
+ const response = await fetch("https://api.anthropic.com/v1/messages", {
125
+ body: JSON.stringify({
126
+ max_tokens: options.maxTokens || 4e3,
127
+ messages: [
128
+ { content: prompt, role: "user" }
129
+ ],
130
+ model: options.model || "claude-3-sonnet-20240229",
131
+ temperature: options.temperature || 0.1
132
+ }),
133
+ headers: {
134
+ "Content-Type": "application/json",
135
+ "anthropic-version": "2023-06-01",
136
+ "x-api-key": apiKey
137
+ },
138
+ method: "POST"
139
+ });
140
+ if (!response.ok) {
141
+ const error = await response.json();
142
+ throw new Error(`Anthropic API error: ${error.error?.message || response.statusText}`);
143
+ }
144
+ const data = await response.json();
145
+ return data.content[0].text;
146
+ } catch (error) {
147
+ throw new Error(`Anthropic AI error: ${error.message}`);
148
+ }
149
+ };
150
+ const callCopilotAI = async (prompt, _options) => {
151
+ try {
152
+ log("GitHub Copilot AI fixes not directly supported. Using manual fix mode.", "info");
153
+ return prompt;
154
+ } catch (error) {
155
+ throw new Error(`GitHub Copilot AI error: ${error.message}`);
156
+ }
157
+ };
158
+ const promptForAIProvider = async (_quiet = false) => {
159
+ const rl = readline.createInterface({
160
+ input: process.stdin,
161
+ output: process.stdout
162
+ });
163
+ return new Promise((resolve) => {
164
+ log("\nNo AI provider configured. Please choose an AI provider:", "info");
165
+ log("1. Cursor IDE", "info");
166
+ log("2. OpenAI", "info");
167
+ log("3. Anthropic", "info");
168
+ log("4. GitHub Copilot", "info");
169
+ log("5. None (Skip AI features)", "info");
170
+ rl.question("Enter your choice (1-5): ", (answer) => {
171
+ rl.close();
172
+ switch (answer) {
173
+ case "1":
174
+ resolve("cursor");
175
+ break;
176
+ case "2":
177
+ resolve("openai");
178
+ break;
179
+ case "3":
180
+ resolve("anthropic");
181
+ break;
182
+ case "4":
183
+ resolve("copilot");
184
+ break;
185
+ default:
186
+ resolve("none");
187
+ }
188
+ });
189
+ });
190
+ };
191
+ const promptForAPIKey = async (provider, _quiet = false) => {
192
+ const rl = readline.createInterface({
193
+ input: process.stdin,
194
+ output: process.stdout
195
+ });
196
+ return new Promise((resolve) => {
197
+ rl.question(`Please enter your ${provider} API key: `, (answer) => {
198
+ rl.close();
199
+ resolve(answer);
200
+ });
201
+ });
202
+ };
203
+ const getAIService = (provider, _options) => {
204
+ switch (provider) {
205
+ case "cursor":
206
+ return callCursorAI;
207
+ case "openai":
208
+ return callOpenAIAI;
209
+ case "anthropic":
210
+ return callAnthropicAI;
211
+ case "copilot":
212
+ return callCopilotAI;
213
+ default:
214
+ return async () => "No AI provider configured";
215
+ }
216
+ };
217
+ const callAIService = async (prompt, quiet = false) => {
218
+ const spinner = createSpinner(quiet);
219
+ spinner.start("Calling AI service to fix code issues...");
220
+ try {
221
+ const aiConfig = LexConfig.config.ai || { provider: "none" };
222
+ const isInCursorIDE = process.env.CURSOR_IDE === "true";
223
+ if (isInCursorIDE && (aiConfig.provider === "none" || !aiConfig.provider)) {
224
+ log("Detected Cursor IDE environment, using Cursor as AI provider", "info", quiet);
225
+ aiConfig.provider = "cursor";
226
+ }
227
+ if (aiConfig.provider === "none") {
228
+ const provider = await promptForAIProvider(quiet);
229
+ if (provider === "none") {
230
+ spinner.fail("AI features skipped");
231
+ return "";
232
+ }
233
+ aiConfig.provider = provider;
234
+ if (provider !== "cursor" && provider !== "copilot" && !process.env[`${provider.toUpperCase()}_API_KEY`]) {
235
+ aiConfig.apiKey = await promptForAPIKey(provider, quiet);
236
+ }
237
+ LexConfig.config.ai = aiConfig;
238
+ const configFormats = ["js", "mjs", "cjs", "ts", "json"];
239
+ const configBaseName = "lex.config";
240
+ let configPath = "";
241
+ for (const format of configFormats) {
242
+ const potentialPath = pathResolve(process.cwd(), `./${configBaseName}.${format}`);
243
+ if (existsSync(potentialPath)) {
244
+ configPath = potentialPath;
245
+ break;
246
+ }
247
+ }
248
+ if (configPath) {
249
+ try {
250
+ const configContent = readFileSync(configPath, "utf8");
251
+ const updatedConfig = configContent.replace(
252
+ /ai:.*?[,}]/s,
253
+ `ai: { provider: '${aiConfig.provider}' },`
254
+ );
255
+ writeFileSync(configPath, updatedConfig);
256
+ } catch (_error) {
257
+ }
258
+ }
259
+ }
260
+ let result = "";
261
+ switch (aiConfig.provider) {
262
+ case "cursor":
263
+ result = await callCursorAI(prompt, aiConfig);
264
+ log("Cursor IDE AI integration active", "info", quiet);
265
+ break;
266
+ case "openai":
267
+ result = await callOpenAIAI(prompt, aiConfig);
268
+ break;
269
+ case "anthropic":
270
+ result = await callAnthropicAI(prompt, aiConfig);
271
+ break;
272
+ case "copilot":
273
+ result = await callCopilotAI(prompt, aiConfig);
274
+ break;
275
+ default:
276
+ spinner.fail("No AI provider configured");
277
+ return "";
278
+ }
279
+ spinner.succeed("AI code fixes generated successfully");
280
+ return result;
281
+ } catch (error) {
282
+ spinner.fail(`AI service error: ${error.message}`);
283
+ if (!quiet) {
284
+ log(error, "error");
285
+ }
286
+ return "";
287
+ }
288
+ };
289
+ export {
290
+ callAIService,
291
+ callAnthropicAI,
292
+ callCopilotAI,
293
+ callCursorAI,
294
+ callOpenAIAI,
295
+ getAIService,
296
+ promptForAIProvider,
297
+ promptForAPIKey
298
+ };
299
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL3V0aWxzL2FpU2VydmljZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjItUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7ZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jLCB3cml0ZUZpbGVTeW5jfSBmcm9tICdmcyc7XG5pbXBvcnQge3Jlc29sdmUgYXMgcGF0aFJlc29sdmV9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHJlYWRsaW5lIGZyb20gJ3JlYWRsaW5lJztcblxuaW1wb3J0IHtBSUNvbmZpZywgTGV4Q29uZmlnfSBmcm9tICcuLi9MZXhDb25maWcuanMnO1xuaW1wb3J0IHtjcmVhdGVTcGlubmVyfSBmcm9tICcuL2FwcC5qcyc7XG5pbXBvcnQge2xvZ30gZnJvbSAnLi9sb2cuanMnO1xuXG4vLyBDdXJzb3IgSURFIGludGVncmF0aW9uXG5leHBvcnQgY29uc3QgY2FsbEN1cnNvckFJID0gYXN5bmMgKHByb21wdDogc3RyaW5nLCBfb3B0aW9uczogQUlDb25maWcpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICB0cnkge1xuICAgIC8vIFdoZW4gcnVubmluZyB3aXRoaW4gQ3Vyc29yIElERSwgd2UgY2FuIHdyaXRlIHRoZSBwcm9tcHQgdG8gYSB0ZW1wb3JhcnkgZmlsZVxuICAgIC8vIHRoYXQgQ3Vyc29yIGNhbiB1c2UgdG8gcHJvdmlkZSBBSSBhc3Npc3RhbmNlXG4gICAgbG9nKCdVc2luZyBDdXJzb3IgSURFIGZvciBBSSBmaXhlcy4uLicsICdpbmZvJyk7XG5cbiAgICAvLyBGb3Igbm93LCBqdXN0IGxvZyB0aGUgcHJvbXB0IGFuZCByZXR1cm4gYSBwbGFjZWhvbGRlclxuICAgIC8vIEluIGEgcmVhbCBpbXBsZW1lbnRhdGlvbiwgQ3Vyc29yIHdvdWxkIGhhbmRsZSB0aGlzIGF1dG9tYXRpY2FsbHlcbiAgICBsb2coJ0FJIGZpeCByZXF1ZXN0ZWQgdmlhIEN1cnNvciBJREUnLCAnaW5mbycpO1xuXG4gICAgY29uc3QgdGFza01hdGNoID0gcHJvbXB0Lm1hdGNoKC9eKEdlbmVyYXRlIGNvZGUgYWNjb3JkaW5nIHRvIHRoZSBmb2xsb3dpbmcgcmVxdWVzdHxFeHBsYWluIHRoZSBmb2xsb3dpbmcgY29kZXxHZW5lcmF0ZSBjb21wcmVoZW5zaXZlIHVuaXQgdGVzdHN8QW5hbHl6ZSB0aGUgZm9sbG93aW5nIGNvZGV8UHJvdmlkZSBndWlkYW5jZSBvbiB0aGUgZm9sbG93aW5nIGRldmVsb3BtZW50IHF1ZXN0aW9uKTovKTtcbiAgICBjb25zdCB0YXNrID0gdGFza01hdGNoID8gdGFza01hdGNoWzFdIDogJyc7XG4gICAgY29uc3QgaXNHZW5lcmF0ZVRhc2sgPSB0YXNrLnN0YXJ0c1dpdGgoJ0dlbmVyYXRlIGNvZGUnKTtcblxuICAgIGNvbnN0IHF1ZXN0aW9uTWF0Y2ggPSBwcm9tcHQubWF0Y2goLyg/OkdlbmVyYXRlIGNvZGUgYWNjb3JkaW5nIHRvIHRoZSBmb2xsb3dpbmcgcmVxdWVzdHxFeHBsYWluIHRoZSBmb2xsb3dpbmcgY29kZXxHZW5lcmF0ZSBjb21wcmVoZW5zaXZlIHVuaXQgdGVzdHN8QW5hbHl6ZSB0aGUgZm9sbG93aW5nIGNvZGV8UHJvdmlkZSBndWlkYW5jZSBvbiB0aGUgZm9sbG93aW5nIGRldmVsb3BtZW50IHF1ZXN0aW9uKTpcXHMqKFtcXHNcXFNdKz8pKD86PT09Q09OVEVYVD09PXwkKS8pO1xuICAgIGNvbnN0IHF1ZXN0aW9uID0gcXVlc3Rpb25NYXRjaCA/IHF1ZXN0aW9uTWF0Y2hbMV0udHJpbSgpIDogcHJvbXB0O1xuXG4gICAgaWYocXVlc3Rpb24udG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnaG93IG1hbnkgZmlsZXMnKSAmJiBwcm9tcHQuaW5jbHVkZXMoJ1Byb2plY3Qgc3RydWN0dXJlOicpKSB7XG4gICAgICBjb25zdCBwcm9qZWN0U3RydWN0dXJlID0gcHJvbXB0LnNwbGl0KCdQcm9qZWN0IHN0cnVjdHVyZTonKVsxXSB8fCAnJztcbiAgICAgIGNvbnN0IGZpbGVzID0gcHJvamVjdFN0cnVjdHVyZS50cmltKCkuc3BsaXQoJ1xcbicpO1xuICAgICAgcmV0dXJuIGBCYXNlZCBvbiB0aGUgcHJvamVjdCBzdHJ1Y3R1cmUgcHJvdmlkZWQsIHRoZXJlIGFyZSAke2ZpbGVzLmxlbmd0aH0gZmlsZXMgaW4gdGhlIHByb2plY3QuYDtcbiAgICB9XG5cbiAgICBpZihpc0dlbmVyYXRlVGFzaykge1xuICAgICAgcmV0dXJuIGBcbiMgQ29kZSBHZW5lcmF0aW9uIFJlcXVlc3Q6IFwiJHtxdWVzdGlvbn1cIlxuXG5UbyBnZW5lcmF0ZSBjb2RlIHVzaW5nIEN1cnNvcidzIEFJIGNhcGFiaWxpdGllczpcblxuMS4gKipPcGVuIHlvdXIgcHJvamVjdCBpbiBDdXJzb3IgSURFKiogKGh0dHBzOi8vY3Vyc29yLnNoKVxuMi4gUHJlc3MgKipDbWQrTCoqIChvciBDdHJsK0wgb24gV2luZG93cy9MaW51eCkgdG8gb3BlbiB0aGUgQUkgY2hhdFxuMy4gVHlwZSB5b3VyIHJlcXVlc3Q6IFwiJHtxdWVzdGlvbn1cIlxuNC4gQ3Vyc29yIHdpbGwgZ2VuZXJhdGUgdGhlIGNvZGUgZGlyZWN0bHkgaW4geW91ciBlZGl0b3JcblxuVGhlIGN1cnJlbnQgQ0xJIGludGVncmF0aW9uIGRvZXNuJ3QgaGF2ZSBkaXJlY3QgYWNjZXNzIHRvIEN1cnNvcidzIGNvZGUgZ2VuZXJhdGlvbiBjYXBhYmlsaXRpZXMuXG5cbioqQWx0ZXJuYXRpdmUgb3B0aW9uczoqKlxuXG4xLiAqKlVzZSBPcGVuQUkgb3IgQW50aHJvcGljIGRpcmVjdGx5OioqXG4gICBDb25maWd1cmUgaW4geW91ciBsZXguY29uZmlnIGZpbGU6XG4gICBcXGBcXGBcXGBqc1xuICAgZXhwb3J0IGRlZmF1bHQge1xuICAgICBhaToge1xuICAgICAgIHByb3ZpZGVyOiAnb3BlbmFpJyxcbiAgICAgICBhcGlLZXk6IHByb2Nlc3MuZW52Lk9QRU5BSV9BUElfS0VZLFxuICAgICAgIG1vZGVsOiAnZ3B0LTRvJ1xuICAgICB9XG4gICB9XG4gICBcXGBcXGBcXGBcblxuMi4gKipVc2UgQ3Vyc29yJ3MgY29tbWFuZCBsaW5lIHRvb2w6KipcbiAgIEluc3RhbGw6IFxcYG5wbSBpbnN0YWxsIC1nIEBjdXJzb3IvY2xpXFxgXG4gICBSdW46IFxcYGN1cnNvciBhaSBcIiR7cXVlc3Rpb259XCJcXGBcbmA7XG4gICAgfVxuXG4gICAgcmV0dXJuIGBcblRvIHVzZSBDdXJzb3IncyBBSSBjYXBhYmlsaXRpZXMgZm9yIFwiJHtxdWVzdGlvbn1cIiwgeW91IG5lZWQgdG86XG5cbjEuIE9wZW4geW91ciBwcm9qZWN0IGluIEN1cnNvciBJREUgKGh0dHBzOi8vY3Vyc29yLnNoKVxuMi4gVXNlIEN1cnNvcidzIGJ1aWx0LWluIEFJIGZlYXR1cmVzIGJ5IHByZXNzaW5nIENtZCtLIG9yIENtZCtMXG4zLiBPciBydW4gdGhlICdjdXJzb3InIGNvbW1hbmQgZGlyZWN0bHkgZnJvbSB5b3VyIHRlcm1pbmFsXG5cblRoZSBjdXJyZW50IGludGVncmF0aW9uIGlzIGxpbWl0ZWQgYW5kIGRvZXNuJ3QgZGlyZWN0bHkgYWNjZXNzIEN1cnNvcidzIEFJIGNhcGFiaWxpdGllcy5cblxuRm9yIHRoZSBiZXN0IGV4cGVyaWVuY2Ugd2l0aCBBSSBjb2RlIGdlbmVyYXRpb246XG4tIFVzZSBDdXJzb3IgSURFIGRpcmVjdGx5XG4tIE9yIGNvbmZpZ3VyZSBPcGVuQUkgb3IgQW50aHJvcGljIGFzIHlvdXIgcHJvdmlkZXIgaW4geW91ciBsZXguY29uZmlnIGZpbGU6XG5cblxcYFxcYFxcYGpzXG4vLyBsZXguY29uZmlnLmpzIChvciBsZXguY29uZmlnLm1qcywgbGV4LmNvbmZpZy5janMsIGV0Yy4pXG5leHBvcnQgZGVmYXVsdCB7XG4gIGFpOiB7XG4gICAgcHJvdmlkZXI6ICdvcGVuYWknLCAvLyBvciAnYW50aHJvcGljJ1xuICAgIGFwaUtleTogcHJvY2Vzcy5lbnYuT1BFTkFJX0FQSV9LRVksIC8vIG9yIEFOVEhST1BJQ19BUElfS0VZXG4gICAgbW9kZWw6ICdncHQtNG8nIC8vIG9yICdjbGF1ZGUtMy1vcHVzJ1xuICB9XG59XG5cXGBcXGBcXGBcblxuVGhlbiBzZXQgeW91ciBBUEkga2V5IGFzIGFuIGVudmlyb25tZW50IHZhcmlhYmxlOlxuXFxgXFxgXFxgXG5leHBvcnQgT1BFTkFJX0FQSV9LRVk9eW91cl9rZXlfaGVyZVxuXFxgXFxgXFxgXG5gO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ3Vyc29yIEFJIGVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBjYWxsT3BlbkFJQUkgPSBhc3luYyAocHJvbXB0OiBzdHJpbmcsIG9wdGlvbnM6IEFJQ29uZmlnKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBhcGlLZXkgPSBvcHRpb25zLmFwaUtleSB8fCBwcm9jZXNzLmVudi5PUEVOQUlfQVBJX0tFWTtcbiAgICBpZighYXBpS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ09wZW5BSSBBUEkga2V5IGlzIHJlcXVpcmVkLiBTZXQgaXQgaW4geW91ciBsZXguY29uZmlnIGZpbGUgb3IgYXMgT1BFTkFJX0FQSV9LRVkgZW52aXJvbm1lbnQgdmFyaWFibGUuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnaHR0cHM6Ly9hcGkub3BlbmFpLmNvbS92MS9jaGF0L2NvbXBsZXRpb25zJywge1xuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBtYXhfdG9rZW5zOiBvcHRpb25zLm1heFRva2VucyB8fCA0MDAwLFxuICAgICAgICBtZXNzYWdlczogW1xuICAgICAgICAgIHtjb250ZW50OiAnWW91IGFyZSBhIGhlbHBmdWwgYXNzaXN0YW50IHRoYXQgZml4ZXMgRVNMaW50IGVycm9ycyBpbiBjb2RlLicsIHJvbGU6ICdzeXN0ZW0nfSxcbiAgICAgICAgICB7Y29udGVudDogcHJvbXB0LCByb2xlOiAndXNlcid9XG4gICAgICAgIF0sXG4gICAgICAgIG1vZGVsOiBvcHRpb25zLm1vZGVsIHx8ICdncHQtNG8nLFxuICAgICAgICB0ZW1wZXJhdHVyZTogb3B0aW9ucy50ZW1wZXJhdHVyZSB8fCAwLjFcbiAgICAgIH0pLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YXBpS2V5fWAsXG4gICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbidcbiAgICAgIH0sXG4gICAgICBtZXRob2Q6ICdQT1NUJ1xuICAgIH0pO1xuXG4gICAgaWYoIXJlc3BvbnNlLm9rKSB7XG4gICAgICBjb25zdCBlcnJvciA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgT3BlbkFJIEFQSSBlcnJvcjogJHtlcnJvci5lcnJvcj8ubWVzc2FnZSB8fCByZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgcmV0dXJuIGRhdGEuY2hvaWNlc1swXS5tZXNzYWdlLmNvbnRlbnQ7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBPcGVuQUkgQUkgZXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGNhbGxBbnRocm9waWNBSSA9IGFzeW5jIChwcm9tcHQ6IHN0cmluZywgb3B0aW9uczogQUlDb25maWcpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICB0cnkge1xuICAgIGNvbnN0IGFwaUtleSA9IG9wdGlvbnMuYXBpS2V5IHx8IHByb2Nlc3MuZW52LkFOVEhST1BJQ19BUElfS0VZO1xuICAgIGlmKCFhcGlLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQW50aHJvcGljIEFQSSBrZXkgaXMgcmVxdWlyZWQuIFNldCBpdCBpbiB5b3VyIGxleC5jb25maWcgZmlsZSBvciBhcyBBTlRIUk9QSUNfQVBJX0tFWSBlbnZpcm9ubWVudCB2YXJpYWJsZS4nKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCdodHRwczovL2FwaS5hbnRocm9waWMuY29tL3YxL21lc3NhZ2VzJywge1xuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBtYXhfdG9rZW5zOiBvcHRpb25zLm1heFRva2VucyB8fCA0MDAwLFxuICAgICAgICBtZXNzYWdlczogW1xuICAgICAgICAgIHtjb250ZW50OiBwcm9tcHQsIHJvbGU6ICd1c2VyJ31cbiAgICAgICAgXSxcbiAgICAgICAgbW9kZWw6IG9wdGlvbnMubW9kZWwgfHwgJ2NsYXVkZS0zLXNvbm5ldC0yMDI0MDIyOScsXG4gICAgICAgIHRlbXBlcmF0dXJlOiBvcHRpb25zLnRlbXBlcmF0dXJlIHx8IDAuMVxuICAgICAgfSksXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICdhbnRocm9waWMtdmVyc2lvbic6ICcyMDIzLTA2LTAxJyxcbiAgICAgICAgJ3gtYXBpLWtleSc6IGFwaUtleVxuICAgICAgfSxcbiAgICAgIG1ldGhvZDogJ1BPU1QnXG4gICAgfSk7XG5cbiAgICBpZighcmVzcG9uc2Uub2spIHtcbiAgICAgIGNvbnN0IGVycm9yID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBBbnRocm9waWMgQVBJIGVycm9yOiAke2Vycm9yLmVycm9yPy5tZXNzYWdlIHx8IHJlc3BvbnNlLnN0YXR1c1RleHR9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICByZXR1cm4gZGF0YS5jb250ZW50WzBdLnRleHQ7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBBbnRocm9waWMgQUkgZXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGNhbGxDb3BpbG90QUkgPSBhc3luYyAocHJvbXB0OiBzdHJpbmcsIF9vcHRpb25zOiBBSUNvbmZpZyk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gIHRyeSB7XG4gICAgbG9nKCdHaXRIdWIgQ29waWxvdCBBSSBmaXhlcyBub3QgZGlyZWN0bHkgc3VwcG9ydGVkLiBVc2luZyBtYW51YWwgZml4IG1vZGUuJywgJ2luZm8nKTtcbiAgICByZXR1cm4gcHJvbXB0O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IG5ldyBFcnJvcihgR2l0SHViIENvcGlsb3QgQUkgZXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHByb21wdEZvckFJUHJvdmlkZXIgPSBhc3luYyAoX3F1aWV0ID0gZmFsc2UpOiBQcm9taXNlPCdjdXJzb3InIHwgJ2NvcGlsb3QnIHwgJ29wZW5haScgfCAnYW50aHJvcGljJyB8ICdub25lJz4gPT4ge1xuICBjb25zdCBybCA9IHJlYWRsaW5lLmNyZWF0ZUludGVyZmFjZSh7XG4gICAgaW5wdXQ6IHByb2Nlc3Muc3RkaW4sXG4gICAgb3V0cHV0OiBwcm9jZXNzLnN0ZG91dFxuICB9KTtcblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBsb2coJ1xcbk5vIEFJIHByb3ZpZGVyIGNvbmZpZ3VyZWQuIFBsZWFzZSBjaG9vc2UgYW4gQUkgcHJvdmlkZXI6JywgJ2luZm8nKTtcbiAgICBsb2coJzEuIEN1cnNvciBJREUnLCAnaW5mbycpO1xuICAgIGxvZygnMi4gT3BlbkFJJywgJ2luZm8nKTtcbiAgICBsb2coJzMuIEFudGhyb3BpYycsICdpbmZvJyk7XG4gICAgbG9nKCc0LiBHaXRIdWIgQ29waWxvdCcsICdpbmZvJyk7XG4gICAgbG9nKCc1LiBOb25lIChTa2lwIEFJIGZlYXR1cmVzKScsICdpbmZvJyk7XG5cbiAgICBybC5xdWVzdGlvbignRW50ZXIgeW91ciBjaG9pY2UgKDEtNSk6ICcsIChhbnN3ZXIpID0+IHtcbiAgICAgIHJsLmNsb3NlKCk7XG5cbiAgICAgIHN3aXRjaChhbnN3ZXIpIHtcbiAgICAgICAgY2FzZSAnMSc6XG4gICAgICAgICAgcmVzb2x2ZSgnY3Vyc29yJyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJzInOlxuICAgICAgICAgIHJlc29sdmUoJ29wZW5haScpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICczJzpcbiAgICAgICAgICByZXNvbHZlKCdhbnRocm9waWMnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnNCc6XG4gICAgICAgICAgcmVzb2x2ZSgnY29waWxvdCcpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJlc29sdmUoJ25vbmUnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgcHJvbXB0Rm9yQVBJS2V5ID0gYXN5bmMgKHByb3ZpZGVyOiBzdHJpbmcsIF9xdWlldCA9IGZhbHNlKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgY29uc3QgcmwgPSByZWFkbGluZS5jcmVhdGVJbnRlcmZhY2Uoe1xuICAgIGlucHV0OiBwcm9jZXNzLnN0ZGluLFxuICAgIG91dHB1dDogcHJvY2Vzcy5zdGRvdXRcbiAgfSk7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgcmwucXVlc3Rpb24oYFBsZWFzZSBlbnRlciB5b3VyICR7cHJvdmlkZXJ9IEFQSSBrZXk6IGAsIChhbnN3ZXIpID0+IHtcbiAgICAgIHJsLmNsb3NlKCk7XG4gICAgICByZXNvbHZlKGFuc3dlcik7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEFJU2VydmljZSA9IChcbiAgcHJvdmlkZXI6IHN0cmluZyxcbiAgX29wdGlvbnM6IEFJQ29uZmlnXG4pOiAocHJvbXB0OiBzdHJpbmcsIG9wdGlvbnM6IEFJQ29uZmlnKSA9PiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICBzd2l0Y2gocHJvdmlkZXIpIHtcbiAgICBjYXNlICdjdXJzb3InOlxuICAgICAgcmV0dXJuIGNhbGxDdXJzb3JBSTtcbiAgICBjYXNlICdvcGVuYWknOlxuICAgICAgcmV0dXJuIGNhbGxPcGVuQUlBSTtcbiAgICBjYXNlICdhbnRocm9waWMnOlxuICAgICAgcmV0dXJuIGNhbGxBbnRocm9waWNBSTtcbiAgICBjYXNlICdjb3BpbG90JzpcbiAgICAgIHJldHVybiBjYWxsQ29waWxvdEFJO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gYXN5bmMgKCkgPT4gJ05vIEFJIHByb3ZpZGVyIGNvbmZpZ3VyZWQnO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgY2FsbEFJU2VydmljZSA9IGFzeW5jIChwcm9tcHQ6IHN0cmluZywgcXVpZXQgPSBmYWxzZSk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gIGNvbnN0IHNwaW5uZXIgPSBjcmVhdGVTcGlubmVyKHF1aWV0KTtcbiAgc3Bpbm5lci5zdGFydCgnQ2FsbGluZyBBSSBzZXJ2aWNlIHRvIGZpeCBjb2RlIGlzc3Vlcy4uLicpO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgYWlDb25maWcgPSBMZXhDb25maWcuY29uZmlnLmFpIHx8IHtwcm92aWRlcjogJ25vbmUnfTtcblxuICAgIGNvbnN0IGlzSW5DdXJzb3JJREUgPSBwcm9jZXNzLmVudi5DVVJTT1JfSURFID09PSAndHJ1ZSc7XG4gICAgaWYoaXNJbkN1cnNvcklERSAmJiAoYWlDb25maWcucHJvdmlkZXIgPT09ICdub25lJyB8fCAhYWlDb25maWcucHJvdmlkZXIpKSB7XG4gICAgICBsb2coJ0RldGVjdGVkIEN1cnNvciBJREUgZW52aXJvbm1lbnQsIHVzaW5nIEN1cnNvciBhcyBBSSBwcm92aWRlcicsICdpbmZvJywgcXVpZXQpO1xuICAgICAgYWlDb25maWcucHJvdmlkZXIgPSAnY3Vyc29yJztcbiAgICB9XG5cbiAgICBpZihhaUNvbmZpZy5wcm92aWRlciA9PT0gJ25vbmUnKSB7XG4gICAgICBjb25zdCBwcm92aWRlciA9IGF3YWl0IHByb21wdEZvckFJUHJvdmlkZXIocXVpZXQpO1xuXG4gICAgICBpZihwcm92aWRlciA9PT0gJ25vbmUnKSB7XG4gICAgICAgIHNwaW5uZXIuZmFpbCgnQUkgZmVhdHVyZXMgc2tpcHBlZCcpO1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG5cbiAgICAgIGFpQ29uZmlnLnByb3ZpZGVyID0gcHJvdmlkZXI7XG5cbiAgICAgIGlmKHByb3ZpZGVyICE9PSAnY3Vyc29yJyAmJiBwcm92aWRlciAhPT0gJ2NvcGlsb3QnICYmXG4gICAgICAgICFwcm9jZXNzLmVudltgJHtwcm92aWRlci50b1VwcGVyQ2FzZSgpfV9BUElfS0VZYF0pIHtcbiAgICAgICAgYWlDb25maWcuYXBpS2V5ID0gYXdhaXQgcHJvbXB0Rm9yQVBJS2V5KHByb3ZpZGVyLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIExleENvbmZpZy5jb25maWcuYWkgPSBhaUNvbmZpZztcblxuICAgICAgLy8gU2VhcmNoIGZvciBjb25maWcgZmlsZXMgaW4gbXVsdGlwbGUgZm9ybWF0cyBsaWtlIExleENvbmZpZy5wYXJzZUNvbmZpZyBkb2VzXG4gICAgICBjb25zdCBjb25maWdGb3JtYXRzID0gWydqcycsICdtanMnLCAnY2pzJywgJ3RzJywgJ2pzb24nXTtcbiAgICAgIGNvbnN0IGNvbmZpZ0Jhc2VOYW1lID0gJ2xleC5jb25maWcnO1xuICAgICAgbGV0IGNvbmZpZ1BhdGggPSAnJztcblxuICAgICAgZm9yKGNvbnN0IGZvcm1hdCBvZiBjb25maWdGb3JtYXRzKSB7XG4gICAgICAgIGNvbnN0IHBvdGVudGlhbFBhdGggPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBgLi8ke2NvbmZpZ0Jhc2VOYW1lfS4ke2Zvcm1hdH1gKTtcbiAgICAgICAgaWYoZXhpc3RzU3luYyhwb3RlbnRpYWxQYXRoKSkge1xuICAgICAgICAgIGNvbmZpZ1BhdGggPSBwb3RlbnRpYWxQYXRoO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmKGNvbmZpZ1BhdGgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBjb25maWdDb250ZW50ID0gcmVhZEZpbGVTeW5jKGNvbmZpZ1BhdGgsICd1dGY4Jyk7XG4gICAgICAgICAgY29uc3QgdXBkYXRlZENvbmZpZyA9IGNvbmZpZ0NvbnRlbnQucmVwbGFjZShcbiAgICAgICAgICAgIC9haTouKj9bLH1dL3MsXG4gICAgICAgICAgICBgYWk6IHsgcHJvdmlkZXI6ICcke2FpQ29uZmlnLnByb3ZpZGVyfScgfSxgXG4gICAgICAgICAgKTtcbiAgICAgICAgICB3cml0ZUZpbGVTeW5jKGNvbmZpZ1BhdGgsIHVwZGF0ZWRDb25maWcpO1xuICAgICAgICB9IGNhdGNoIChfZXJyb3IpIHtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGxldCByZXN1bHQgPSAnJztcblxuICAgIHN3aXRjaChhaUNvbmZpZy5wcm92aWRlcikge1xuICAgICAgY2FzZSAnY3Vyc29yJzpcbiAgICAgICAgcmVzdWx0ID0gYXdhaXQgY2FsbEN1cnNvckFJKHByb21wdCwgYWlDb25maWcpO1xuICAgICAgICBsb2coJ0N1cnNvciBJREUgQUkgaW50ZWdyYXRpb24gYWN0aXZlJywgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnb3BlbmFpJzpcbiAgICAgICAgcmVzdWx0ID0gYXdhaXQgY2FsbE9wZW5BSUFJKHByb21wdCwgYWlDb25maWcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2FudGhyb3BpYyc6XG4gICAgICAgIHJlc3VsdCA9IGF3YWl0IGNhbGxBbnRocm9waWNBSShwcm9tcHQsIGFpQ29uZmlnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdjb3BpbG90JzpcbiAgICAgICAgcmVzdWx0ID0gYXdhaXQgY2FsbENvcGlsb3RBSShwcm9tcHQsIGFpQ29uZmlnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBzcGlubmVyLmZhaWwoJ05vIEFJIHByb3ZpZGVyIGNvbmZpZ3VyZWQnKTtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHNwaW5uZXIuc3VjY2VlZCgnQUkgY29kZSBmaXhlcyBnZW5lcmF0ZWQgc3VjY2Vzc2Z1bGx5Jyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBzcGlubmVyLmZhaWwoYEFJIHNlcnZpY2UgZXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICBpZighcXVpZXQpIHtcbiAgICAgIGxvZyhlcnJvciwgJ2Vycm9yJyk7XG4gICAgfVxuICAgIHJldHVybiAnJztcbiAgfVxufTsiXSwKICAibWFwcGluZ3MiOiAiQUFJQSxTQUFRLFlBQVksY0FBYyxxQkFBb0I7QUFDdEQsU0FBUSxXQUFXLG1CQUFrQjtBQUNyQyxPQUFPLGNBQWM7QUFFckIsU0FBa0IsaUJBQWdCO0FBQ2xDLFNBQVEscUJBQW9CO0FBQzVCLFNBQVEsV0FBVTtBQUdYLE1BQU0sZUFBZSxPQUFPLFFBQWdCLGFBQXdDO0FBQ3pGLE1BQUk7QUFHRixRQUFJLG9DQUFvQyxNQUFNO0FBSTlDLFFBQUksbUNBQW1DLE1BQU07QUFFN0MsVUFBTSxZQUFZLE9BQU8sTUFBTSxxTUFBcU07QUFDcE8sVUFBTSxPQUFPLFlBQVksVUFBVSxDQUFDLElBQUk7QUFDeEMsVUFBTSxpQkFBaUIsS0FBSyxXQUFXLGVBQWU7QUFFdEQsVUFBTSxnQkFBZ0IsT0FBTyxNQUFNLHNPQUFzTztBQUN6USxVQUFNLFdBQVcsZ0JBQWdCLGNBQWMsQ0FBQyxFQUFFLEtBQUssSUFB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
@@ -23,8 +23,11 @@ export interface Spinner {
23
23
  fail: (text?: string) => void;
24
24
  start: (text?: string) => void;
25
25
  succeed: (text?: string) => void;
26
+ text?: string;
26
27
  }
27
28
  export declare const createSpinner: (quiet?: boolean) => Spinner;
29
+ export declare const createProgressBar: (percentage: number) => string;
30
+ export declare const handleWebpackProgress: (output: string, spinner: Spinner, quiet: boolean, emoji: string, action: string) => void;
28
31
  export declare const copyFiles: (files: string[], typeName: string, spinner: any, config: LexConfigType) => Promise<void>;
29
32
  export declare const copyConfiguredFiles: (spinner: any, config: LexConfigType, quiet: boolean) => Promise<void>;
30
33
  export declare const copyFileSync: (source: string, target: string) => void;