create-pylon 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,17 +3,123 @@
3
3
 
4
4
  // src/index.ts
5
5
  import { Option, program } from "commander";
6
- import consola from "consola";
6
+ import consola2 from "consola";
7
7
  import { input, select, confirm } from "@inquirer/prompts";
8
- import path from "path";
8
+ import path2 from "path";
9
9
  import chalk from "chalk";
10
- import * as fs from "fs";
10
+ import * as fs2 from "fs";
11
11
  import * as telemetry from "@getcronit/pylon-telemetry";
12
12
  import { fileURLToPath } from "url";
13
13
  import { dirname } from "path";
14
+ import { spawnSync } from "child_process";
15
+
16
+ // src/detect-pm.ts
17
+ import * as fs from "fs";
18
+ import * as path from "path";
19
+ import process2 from "process";
20
+ import { execSync } from "child_process";
21
+ import consola from "consola";
22
+ function isCommandAvailable(command) {
23
+ try {
24
+ execSync(`${command} --version`, { stdio: "ignore" });
25
+ return true;
26
+ } catch (e) {
27
+ console.error(e);
28
+ return false;
29
+ }
30
+ }
31
+ function isBun() {
32
+ return typeof Bun !== "undefined" && isCommandAvailable("bun");
33
+ }
34
+ function isNpm() {
35
+ return process2.env.npm_execpath?.includes("npm") ?? false;
36
+ }
37
+ function isYarn() {
38
+ return process2.env.npm_execpath?.includes("yarn") ?? false;
39
+ }
40
+ function isDeno() {
41
+ return typeof Deno !== "undefined" && isCommandAvailable("deno");
42
+ }
43
+ function isPnpm() {
44
+ return process2.env.npm_execpath?.includes("pnpm") ?? false;
45
+ }
46
+ function detectByLockFiles(cwd) {
47
+ if (fs.existsSync(path.join(cwd, "bun.lockb"))) {
48
+ return "bun";
49
+ }
50
+ if (fs.existsSync(path.join(cwd, "package-lock.json"))) {
51
+ return "npm";
52
+ }
53
+ if (fs.existsSync(path.join(cwd, "yarn.lock"))) {
54
+ return "yarn";
55
+ }
56
+ if (fs.existsSync(path.join(cwd, "deno.json")) || fs.existsSync(path.join(cwd, "deno.lock"))) {
57
+ return "deno";
58
+ }
59
+ if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) {
60
+ return "pnpm";
61
+ }
62
+ return null;
63
+ }
64
+ function detectPackageManager({
65
+ preferredPm,
66
+ cwd = process2.cwd()
67
+ }) {
68
+ if (preferredPm && isCommandAvailable(preferredPm)) {
69
+ return preferredPm;
70
+ }
71
+ if (isBun()) {
72
+ return "bun";
73
+ }
74
+ if (isNpm()) {
75
+ return "npm";
76
+ }
77
+ if (isPnpm()) {
78
+ return "pnpm";
79
+ }
80
+ if (isDeno()) {
81
+ return "deno";
82
+ }
83
+ if (isYarn()) {
84
+ return "yarn";
85
+ }
86
+ const lockFileDetection = detectByLockFiles(cwd);
87
+ if (lockFileDetection) {
88
+ consola.info(`Detected package manager by lock file: ${lockFileDetection}`);
89
+ if (isCommandAvailable(lockFileDetection)) {
90
+ return lockFileDetection;
91
+ } else {
92
+ consola.warn(`Lock file detected, but ${lockFileDetection} is not installed.`);
93
+ }
94
+ }
95
+ return "unknown";
96
+ }
97
+ function getRunScript(pm) {
98
+ switch (pm) {
99
+ case "bun":
100
+ return "bun";
101
+ case "npm":
102
+ return "npm run";
103
+ case "yarn":
104
+ return "yarn";
105
+ case "pnpm":
106
+ return "pnpm run";
107
+ case "deno":
108
+ return "deno task";
109
+ default:
110
+ throw new Error("Unknown package manager");
111
+ }
112
+ }
113
+
114
+ // src/index.ts
115
+ var __filename2 = fileURLToPath(import.meta.url);
116
+ var __dirname2 = dirname(__filename2);
117
+ var version = (() => {
118
+ return JSON.parse(fs2.readFileSync(path2.join(__dirname2, "..", "package.json"), "utf-8")).version;
119
+ })();
14
120
  function mkdirp(dir) {
15
121
  try {
16
- fs.mkdirSync(dir, { recursive: true });
122
+ fs2.mkdirSync(dir, { recursive: true });
17
123
  } catch (e) {
18
124
  if (e instanceof Error) {
19
125
  if ("code" in e && e.code === "EEXIST")
@@ -22,11 +128,171 @@ function mkdirp(dir) {
22
128
  throw e;
23
129
  }
24
130
  }
25
- import { detect } from "detect-package-manager";
26
- import { spawnSync } from "child_process";
131
+ var runtimes = [
132
+ {
133
+ key: "bun",
134
+ name: "Bun.js",
135
+ website: "https://bunjs.dev",
136
+ templates: ["default"]
137
+ },
138
+ {
139
+ key: "node",
140
+ name: "Node.js",
141
+ website: "https://nodejs.org",
142
+ templates: ["default"]
143
+ },
144
+ {
145
+ key: "cf-workers",
146
+ name: "Cloudflare Workers",
147
+ website: "https://workers.cloudflare.com",
148
+ templates: ["default"]
149
+ },
150
+ {
151
+ key: "deno",
152
+ name: "Deno",
153
+ website: "https://deno.land",
154
+ templates: ["default"]
155
+ }
156
+ ];
157
+ var templates = [
158
+ {
159
+ key: "default",
160
+ name: "Default",
161
+ description: "Default template"
162
+ },
163
+ {
164
+ key: "database",
165
+ name: "Database (Prisma)",
166
+ description: "Template with Prisma ORM"
167
+ }
168
+ ];
169
+ var injectVariablesInContent = (content, variables) => {
170
+ let result = content;
171
+ Object.entries(variables).forEach(([key, value]) => {
172
+ result = result.replaceAll(key, value);
173
+ });
174
+ return result;
175
+ };
176
+ var readdirFilesSyncRecursive = (dir) => {
177
+ const run = (dir2) => {
178
+ const result = [];
179
+ const files = fs2.readdirSync(dir2);
180
+ files.forEach((file) => {
181
+ const filePath = path2.join(dir2, file);
182
+ if (fs2.statSync(filePath).isDirectory()) {
183
+ result.push(...run(filePath));
184
+ }
185
+ if (fs2.statSync(filePath).isFile()) {
186
+ result.push(filePath);
187
+ }
188
+ });
189
+ return result;
190
+ };
191
+ return run(dir).map((file) => {
192
+ return file.replace(dir, ".");
193
+ });
194
+ };
195
+ var createTemplate = async (options) => {
196
+ const { runtime, template, target } = options;
197
+ const runtimeName = runtimes.find(({ key }) => key === runtime)?.name;
198
+ const templateName = templates.find(({ key }) => key === template)?.name;
199
+ if (!runtimeName) {
200
+ throw new Error(`Invalid runtime: ${runtime}`);
201
+ }
202
+ if (!templateName) {
203
+ throw new Error(`Invalid template: ${template}`);
204
+ }
205
+ const sharedTemplateDir = path2.join(__dirname2, "..", "templates", "shared");
206
+ if (!fs2.existsSync(sharedTemplateDir)) {
207
+ throw new Error(`Shared templates not found: ${sharedTemplateDir}`);
208
+ }
209
+ const templateDir = path2.join(__dirname2, "..", "templates", runtime, template);
210
+ if (!fs2.existsSync(templateDir)) {
211
+ throw new Error(`Template not found: ${templateDir}`);
212
+ }
213
+ const targetDirectoryPath = path2.join(process.cwd(), target);
214
+ consola2.start(`Creating pylon in ${targetDirectoryPath}`);
215
+ const inject = (content) => {
216
+ return injectVariablesInContent(content, {
217
+ __PYLON_NAME__: options.name
218
+ });
219
+ };
220
+ readdirFilesSyncRecursive(sharedTemplateDir).forEach((file) => {
221
+ const source = path2.join(sharedTemplateDir, file);
222
+ let target2 = path2.join(targetDirectoryPath, file);
223
+ const targetDir = path2.dirname(target2);
224
+ if (runtime === "cf-workers" && source.includes(".github/workflows/publish.yaml")) {
225
+ return;
226
+ }
227
+ if (!fs2.existsSync(targetDir)) {
228
+ fs2.mkdirSync(targetDir, { recursive: true });
229
+ }
230
+ if (target2.endsWith(".example")) {
231
+ target2 = target2.replace(".example", "");
232
+ }
233
+ const injectedContent = inject(fs2.readFileSync(source, "utf-8"));
234
+ fs2.writeFileSync(target2, injectedContent);
235
+ });
236
+ readdirFilesSyncRecursive(templateDir).forEach((file) => {
237
+ const source = path2.join(templateDir, file);
238
+ let target2 = path2.join(targetDirectoryPath, file);
239
+ const targetDir = path2.dirname(target2);
240
+ if (!fs2.existsSync(targetDir)) {
241
+ fs2.mkdirSync(targetDir, { recursive: true });
242
+ }
243
+ if (target2.endsWith(".example")) {
244
+ target2 = target2.replace(".example", "");
245
+ }
246
+ const injectedContent = inject(fs2.readFileSync(source, "utf-8"));
247
+ fs2.writeFileSync(target2, injectedContent);
248
+ });
249
+ consola2.success(`Pylon created`);
250
+ };
251
+ var installDependencies = async (args) => {
252
+ const target = path2.resolve(args.target);
253
+ const packageManager = args.packageManager;
254
+ let command = "";
255
+ switch (packageManager) {
256
+ case "yarn":
257
+ command = "yarn";
258
+ break;
259
+ case "npm":
260
+ command = "npm install";
261
+ break;
262
+ case "pnpm":
263
+ command = "pnpm install";
264
+ break;
265
+ case "bun":
266
+ command = "bun install";
267
+ break;
268
+ case "deno":
269
+ command = "deno install";
270
+ break;
271
+ default:
272
+ throw new Error(`Invalid package manager: ${packageManager}`);
273
+ }
274
+ consola2.start(`Installing dependencies using ${packageManager}`);
275
+ const proc = spawnSync(command, {
276
+ cwd: target,
277
+ shell: true,
278
+ stdio: "inherit"
279
+ });
280
+ if (proc.status !== 0) {
281
+ throw new Error(`Failed to install dependencies`);
282
+ }
283
+ consola2.success(`Dependencies installed`);
284
+ };
285
+ program.name("create-pylon").version(version).arguments("[target]").addOption(new Option("-i, --install", "Install dependencies")).addOption(new Option("-r, --runtime <runtime>", "Runtime").choices(runtimes.map(({ key }) => key))).addOption(new Option("-t, --template <template>", "Template")).addOption(new Option("-pm, --package-manager <packageManager>", "Package manager")).addOption(new Option("--client", "Enable client generation (https://pylon.cronit.io/docs/integrations/gqty)")).addOption(new Option("--client-path <clientPath>", "Client path")).addOption(new Option("--client-port <clientPort>", "Client port")).action(main);
286
+ var getPreferredPmByRuntime = (runtime) => {
287
+ if (runtime === "bun") {
288
+ return "bun";
289
+ } else if (runtime === "deno") {
290
+ return "deno";
291
+ }
292
+ };
27
293
  async function main(targetDir, options, command) {
28
294
  try {
29
- consola.log(`${command.name()} version ${command.version()}`);
295
+ consola2.log(`${command.name()} version ${command.version()}`);
30
296
  const {
31
297
  install: installArg,
32
298
  runtime: runtimeArg,
@@ -39,7 +305,7 @@ async function main(targetDir, options, command) {
39
305
  let target = "";
40
306
  if (targetDir) {
41
307
  target = targetDir;
42
- consola.success(`Using target directory \u2026 ${target}`);
308
+ consola2.success(`Using target directory \u2026 ${target}`);
43
309
  } else {
44
310
  const answer = await input({
45
311
  message: "Target directory",
@@ -49,9 +315,9 @@ async function main(targetDir, options, command) {
49
315
  }
50
316
  let projectName = "";
51
317
  if (target === ".") {
52
- projectName = path.basename(process.cwd());
318
+ projectName = path2.basename(process.cwd());
53
319
  } else {
54
- projectName = path.basename(target);
320
+ projectName = path2.basename(target);
55
321
  }
56
322
  const runtimeName = runtimeArg || await select({
57
323
  message: "Which runtime would you like to use?",
@@ -79,8 +345,8 @@ async function main(targetDir, options, command) {
79
345
  if (!templateName) {
80
346
  throw new Error("No template selected");
81
347
  }
82
- if (fs.existsSync(target)) {
83
- if (fs.readdirSync(target).length > 0) {
348
+ if (fs2.existsSync(target)) {
349
+ if (fs2.readdirSync(target).length > 0) {
84
350
  const response = await confirm({
85
351
  message: "Directory not empty. Continue?",
86
352
  default: false
@@ -99,10 +365,10 @@ async function main(targetDir, options, command) {
99
365
  template: templateName,
100
366
  target
101
367
  });
102
- let packageManager = packageManagerArg;
103
- if (runtimeName === "bun" && !packageManager) {
104
- packageManager = "bun";
105
- }
368
+ const packageManager = detectPackageManager({
369
+ preferredPm: getPreferredPmByRuntime(runtime.key),
370
+ cwd: target
371
+ });
106
372
  if (install) {
107
373
  await installDependencies({ target, packageManager });
108
374
  }
@@ -121,7 +387,7 @@ async function main(targetDir, options, command) {
121
387
  });
122
388
  clientPath = await input({
123
389
  message: "Path to generate the client to",
124
- default: path.join(clientRoot, "gqty/index.ts"),
390
+ default: path2.join(clientRoot, "gqty/index.ts"),
125
391
  validate: (value) => {
126
392
  if (!value.startsWith(clientRoot === "." ? "" : clientRoot)) {
127
393
  return "Path must start with the client root";
@@ -134,23 +400,32 @@ async function main(targetDir, options, command) {
134
400
  message: "Port of the pylon server to generate the client from",
135
401
  default: "3000"
136
402
  });
137
- consola.start(`Updating pylon dev script to generate client`);
138
- const devScriptPath = path.join(target, "package.json");
139
- const devScript = JSON.parse(fs.readFileSync(devScriptPath, "utf-8"));
140
- devScript.scripts = {
141
- ...devScript.scripts,
142
- dev: devScript.scripts.dev + ` --client --client-port ${clientPort} --client-path ${clientPath}`
403
+ consola2.start(`Updating pylon dev script to generate client`);
404
+ let packagePath;
405
+ let scriptKey;
406
+ if (runtime.key === "deno") {
407
+ packagePath = path2.join(target, "deno.json");
408
+ scriptKey = "tasks";
409
+ } else {
410
+ packagePath = path2.join(target, "package.json");
411
+ scriptKey = "scripts";
412
+ }
413
+ const devScript = JSON.parse(fs2.readFileSync(packagePath, "utf-8"));
414
+ devScript[scriptKey] = {
415
+ ...devScript[scriptKey],
416
+ dev: devScript[scriptKey].dev + ` --client --client-port ${clientPort} --client-path ${clientPath}`
143
417
  };
144
- fs.writeFileSync(devScriptPath, JSON.stringify(devScript, null, 2));
145
- consola.success(`Pylon dev script updated`);
418
+ fs2.writeFileSync(packagePath, JSON.stringify(devScript, null, 2));
419
+ consola2.success(`Pylon dev script updated`);
146
420
  }
421
+ const runScript = getRunScript(packageManager);
147
422
  const message = `
148
423
  \uD83C\uDF89 ${chalk.green.bold("Pylon created successfully.")}
149
424
 
150
425
  \uD83D\uDCBB ${chalk.cyan.bold("Continue Developing")}
151
426
  ${chalk.yellow("Change directories:")} cd ${chalk.blue(target)}
152
- ${chalk.yellow("Start dev server:")} npm run start
153
- ${chalk.yellow("Deploy:")} npm run deploy
427
+ ${chalk.yellow("Start dev server:")} ${runScript} dev
428
+ ${chalk.yellow("Deploy:")} ${runScript} deploy
154
429
 
155
430
  \uD83D\uDCD6 ${chalk.cyan.bold("Explore Documentation")}
156
431
  ${chalk.underline.blue("https://pylon.cronit.io/docs")}
@@ -166,173 +441,12 @@ async function main(targetDir, options, command) {
166
441
  clientPath: clientPath || undefined,
167
442
  clientPort: parseInt(clientPort) || undefined
168
443
  });
169
- consola.box(message);
444
+ consola2.box(message);
170
445
  } catch (e) {
171
- consola.error(e);
446
+ consola2.error(e);
172
447
  }
173
448
  }
174
- var __filename2 = fileURLToPath(import.meta.url);
175
- var __dirname2 = dirname(__filename2);
176
- var version = (() => {
177
- return JSON.parse(fs.readFileSync(path.join(__dirname2, "..", "package.json"), "utf-8")).version;
178
- })();
179
- var runtimes = [
180
- {
181
- key: "bun",
182
- name: "Bun.js",
183
- website: "https://bunjs.dev",
184
- templates: ["default"]
185
- },
186
- {
187
- key: "node",
188
- name: "Node.js",
189
- website: "https://nodejs.org",
190
- templates: ["default"]
191
- },
192
- {
193
- key: "cf-workers",
194
- name: "Cloudflare Workers",
195
- website: "https://workers.cloudflare.com",
196
- templates: ["default"]
197
- }
198
- ];
199
- var templates = [
200
- {
201
- key: "default",
202
- name: "Default",
203
- description: "Default template"
204
- },
205
- {
206
- key: "database",
207
- name: "Database (Prisma)",
208
- description: "Template with Prisma ORM"
209
- }
210
- ];
211
- var injectVariablesInContent = (content, variables) => {
212
- let result = content;
213
- Object.entries(variables).forEach(([key, value]) => {
214
- result = result.replaceAll(key, value);
215
- });
216
- return result;
217
- };
218
- var readdirFilesSyncRecursive = (dir) => {
219
- const run = (dir2) => {
220
- const result = [];
221
- const files = fs.readdirSync(dir2);
222
- files.forEach((file) => {
223
- const filePath = path.join(dir2, file);
224
- if (fs.statSync(filePath).isDirectory()) {
225
- result.push(...run(filePath));
226
- }
227
- if (fs.statSync(filePath).isFile()) {
228
- result.push(filePath);
229
- }
230
- });
231
- return result;
232
- };
233
- return run(dir).map((file) => {
234
- return file.replace(dir, ".");
235
- });
236
- };
237
- var createTemplate = async (options) => {
238
- const { runtime, template, target } = options;
239
- const runtimeName = runtimes.find(({ key }) => key === runtime)?.name;
240
- const templateName = templates.find(({ key }) => key === template)?.name;
241
- if (!runtimeName) {
242
- throw new Error(`Invalid runtime: ${runtime}`);
243
- }
244
- if (!templateName) {
245
- throw new Error(`Invalid template: ${template}`);
246
- }
247
- const sharedTemplateDir = path.join(__dirname2, "..", "templates", "shared");
248
- if (!fs.existsSync(sharedTemplateDir)) {
249
- throw new Error(`Shared templates not found: ${sharedTemplateDir}`);
250
- }
251
- const templateDir = path.join(__dirname2, "..", "templates", runtime, template);
252
- if (!fs.existsSync(templateDir)) {
253
- throw new Error(`Template not found: ${templateDir}`);
254
- }
255
- const targetDirectoryPath = path.join(process.cwd(), target);
256
- consola.start(`Creating pylon in ${targetDirectoryPath}`);
257
- const inject = (content) => {
258
- return injectVariablesInContent(content, {
259
- __PYLON_NAME__: options.name
260
- });
261
- };
262
- readdirFilesSyncRecursive(sharedTemplateDir).forEach((file) => {
263
- const source = path.join(sharedTemplateDir, file);
264
- let target2 = path.join(targetDirectoryPath, file);
265
- const targetDir = path.dirname(target2);
266
- if (runtime === "cf-workers" && source.includes(".github/workflows/publish.yaml")) {
267
- return;
268
- }
269
- if (!fs.existsSync(targetDir)) {
270
- fs.mkdirSync(targetDir, { recursive: true });
271
- }
272
- if (target2.endsWith(".example")) {
273
- target2 = target2.replace(".example", "");
274
- }
275
- const injectedContent = inject(fs.readFileSync(source, "utf-8"));
276
- fs.writeFileSync(target2, injectedContent);
277
- });
278
- readdirFilesSyncRecursive(templateDir).forEach((file) => {
279
- const source = path.join(templateDir, file);
280
- let target2 = path.join(targetDirectoryPath, file);
281
- const targetDir = path.dirname(target2);
282
- if (!fs.existsSync(targetDir)) {
283
- fs.mkdirSync(targetDir, { recursive: true });
284
- }
285
- if (target2.endsWith(".example")) {
286
- target2 = target2.replace(".example", "");
287
- }
288
- const injectedContent = inject(fs.readFileSync(source, "utf-8"));
289
- fs.writeFileSync(target2, injectedContent);
290
- });
291
- consola.success(`Pylon created`);
292
- };
293
- var installDependencies = async (args) => {
294
- const target = path.resolve(args.target);
295
- console.log("target", target);
296
- if (!args.packageManager) {
297
- args.packageManager = await detect({
298
- cwd: target,
299
- includeGlobalBun: true
300
- });
301
- }
302
- if (!args.packageManager) {
303
- throw new Error("No package manager found");
304
- }
305
- const { packageManager } = args;
306
- let command = "";
307
- switch (packageManager) {
308
- case "yarn":
309
- command = "yarn";
310
- break;
311
- case "npm":
312
- command = "npm install";
313
- break;
314
- case "pnpm":
315
- command = "pnpm install";
316
- break;
317
- case "bun":
318
- command = "bun install";
319
- break;
320
- default:
321
- throw new Error(`Invalid package manager: ${packageManager}`);
322
- }
323
- consola.start(`Installing dependencies using ${packageManager}`);
324
- const proc = spawnSync(command, {
325
- cwd: target,
326
- shell: true,
327
- stdio: "inherit"
328
- });
329
- if (proc.status !== 0) {
330
- throw new Error(`Failed to install dependencies`);
331
- }
332
- consola.success(`Dependencies installed`);
333
- };
334
- program.name("create-pylon").version(version).arguments("[target]").addOption(new Option("-i, --install", "Install dependencies")).addOption(new Option("-r, --runtime <runtime>", "Runtime").choices(runtimes.map(({ key }) => key))).addOption(new Option("-t, --template <template>", "Template")).addOption(new Option("-pm, --package-manager <packageManager>", "Package manager")).addOption(new Option("--client", "Enable client generation (https://pylon.cronit.io/docs/integrations/gqty)")).addOption(new Option("--client-path <clientPath>", "Client path")).addOption(new Option("--client-port <clientPort>", "Client port")).action(main);
335
449
  program.parse();
336
450
 
337
- //# debugId=55AF547960838BB164756E2164756E21
338
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgIiMhL3Vzci9iaW4vZW52IG5vZGVcblxuaW1wb3J0IHtPcHRpb24sIHByb2dyYW0sIHR5cGUgQ29tbWFuZH0gZnJvbSAnY29tbWFuZGVyJ1xuaW1wb3J0IGNvbnNvbGEgZnJvbSAnY29uc29sYSdcbmltcG9ydCB7aW5wdXQsIHNlbGVjdCwgY29uZmlybX0gZnJvbSAnQGlucXVpcmVyL3Byb21wdHMnXG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJ1xuaW1wb3J0IGNoYWxrIGZyb20gJ2NoYWxrJ1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnXG5cbmltcG9ydCAqIGFzIHRlbGVtZXRyeSBmcm9tICdAZ2V0Y3Jvbml0L3B5bG9uLXRlbGVtZXRyeSdcblxuaW1wb3J0IHtmaWxlVVJMVG9QYXRofSBmcm9tICd1cmwnXG5pbXBvcnQge2Rpcm5hbWV9IGZyb20gJ3BhdGgnXG5cbmNvbnN0IF9fZmlsZW5hbWUgPSBmaWxlVVJMVG9QYXRoKGltcG9ydC5tZXRhLnVybClcbmNvbnN0IF9fZGlybmFtZSA9IGRpcm5hbWUoX19maWxlbmFtZSlcblxuY29uc3QgdmVyc2lvbiA9ICgoKSA9PiB7XG4gIHJldHVybiBKU09OLnBhcnNlKFxuICAgIGZzLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4nLCAncGFja2FnZS5qc29uJyksICd1dGYtOCcpXG4gICkudmVyc2lvbiBhcyBzdHJpbmdcbn0pKClcblxuZnVuY3Rpb24gbWtkaXJwKGRpcjogc3RyaW5nKSB7XG4gIHRyeSB7XG4gICAgZnMubWtkaXJTeW5jKGRpciwge3JlY3Vyc2l2ZTogdHJ1ZX0pXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBpZiAoJ2NvZGUnIGluIGUgJiYgZS5jb2RlID09PSAnRUVYSVNUJykgcmV0dXJuXG4gICAgfVxuICAgIHRocm93IGVcbiAgfVxufVxuXG5jb25zdCBydW50aW1lczoge1xuICBrZXk6IHN0cmluZ1xuICBuYW1lOiBzdHJpbmdcbiAgd2Vic2l0ZTogc3RyaW5nXG4gIHRlbXBsYXRlcz86IHN0cmluZ1tdXG59W10gPSBbXG4gIHtcbiAgICBrZXk6ICdidW4nLFxuICAgIG5hbWU6ICdCdW4uanMnLFxuICAgIHdlYnNpdGU6ICdodHRwczovL2J1bmpzLmRldicsXG4gICAgdGVtcGxhdGVzOiBbJ2RlZmF1bHQnXVxuICB9LFxuICB7XG4gICAga2V5OiAnbm9kZScsXG4gICAgbmFtZTogJ05vZGUuanMnLFxuICAgIHdlYnNpdGU6ICdodHRwczovL25vZGVqcy5vcmcnLFxuICAgIHRlbXBsYXRlczogWydkZWZhdWx0J11cbiAgfSxcbiAge1xuICAgIGtleTogJ2NmLXdvcmtlcnMnLFxuICAgIG5hbWU6ICdDbG91ZGZsYXJlIFdvcmtlcnMnLFxuICAgIHdlYnNpdGU6ICdodHRwczovL3dvcmtlcnMuY2xvdWRmbGFyZS5jb20nLFxuICAgIHRlbXBsYXRlczogWydkZWZhdWx0J11cbiAgfVxuXVxuXG5jb25zdCB0ZW1wbGF0ZXM6IHtcbiAga2V5OiBzdHJpbmdcbiAgbmFtZTogc3RyaW5nXG4gIGRlc2NyaXB0aW9uOiBzdHJpbmdcbn1bXSA9IFtcbiAge1xuICAgIGtleTogJ2RlZmF1bHQnLFxuICAgIG5hbWU6ICdEZWZhdWx0JyxcbiAgICBkZXNjcmlwdGlvbjogJ0RlZmF1bHQgdGVtcGxhdGUnXG4gIH0sXG4gIHtcbiAgICBrZXk6ICdkYXRhYmFzZScsXG4gICAgbmFtZTogJ0RhdGFiYXNlIChQcmlzbWEpJyxcbiAgICBkZXNjcmlwdGlvbjogJ1RlbXBsYXRlIHdpdGggUHJpc21hIE9STSdcbiAgfVxuXVxuXG5jb25zdCBpbmplY3RWYXJpYWJsZXNJbkNvbnRlbnQgPSAoXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgdmFyaWFibGVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+XG4pID0+IHtcbiAgbGV0IHJlc3VsdCA9IGNvbnRlbnRcblxuICBPYmplY3QuZW50cmllcyh2YXJpYWJsZXMpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgIHJlc3VsdCA9IHJlc3VsdC5yZXBsYWNlQWxsKGtleSwgdmFsdWUpXG4gIH0pXG5cbiAgcmV0dXJuIHJlc3VsdFxufVxuY29uc3QgcmVhZGRpckZpbGVzU3luY1JlY3Vyc2l2ZSA9IChkaXI6IHN0cmluZyk6IHN0cmluZ1tdID0+IHtcbiAgY29uc3QgcnVuID0gKGRpcjogc3RyaW5nKTogc3RyaW5nW10gPT4ge1xuICAgIGNvbnN0IHJlc3VsdDogc3RyaW5nW10gPSBbXVxuXG4gICAgY29uc3QgZmlsZXMgPSBmcy5yZWFkZGlyU3luYyhkaXIpXG5cbiAgICBmaWxlcy5mb3JFYWNoKGZpbGUgPT4ge1xuICAgICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oZGlyLCBmaWxlKVxuXG4gICAgICBpZiAoZnMuc3RhdFN5bmMoZmlsZVBhdGgpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgcmVzdWx0LnB1c2goLi4ucnVuKGZpbGVQYXRoKSlcbiAgICAgIH1cblxuICAgICAgLy8gT25seSBhZGQgZmlsZXNcbiAgICAgIGlmIChmcy5zdGF0U3luYyhmaWxlUGF0aCkuaXNGaWxlKCkpIHtcbiAgICAgICAgcmVzdWx0LnB1c2goZmlsZVBhdGgpXG4gICAgICB9XG4gICAgfSlcblxuICAgIHJldHVybiByZXN1bHRcbiAgfVxuXG4gIHJldHVybiBydW4oZGlyKS5tYXAoZmlsZSA9PiB7XG4gICAgcmV0dXJuIGZpbGUucmVwbGFjZShkaXIsICcuJylcbiAgfSlcbn1cblxuY29uc3QgY3JlYXRlVGVtcGxhdGUgPSBhc3luYyAob3B0aW9uczoge1xuICBuYW1lOiBzdHJpbmdcbiAgcnVudGltZTogc3RyaW5nXG4gIHRlbXBsYXRlOiBzdHJpbmdcbiAgdGFyZ2V0OiBzdHJpbmdcbn0pID0+IHtcbiAgY29uc3Qge3J1bnRpbWUsIHRlbXBsYXRlLCB0YXJnZXR9ID0gb3B0aW9uc1xuXG4gIGNvbnN0IHJ1bnRpbWVOYW1lID0gcnVudGltZXMuZmluZCgoe2tleX0pID0+IGtleSA9PT0gcnVudGltZSk/Lm5hbWVcbiAgY29uc3QgdGVtcGxhdGVOYW1lID0gdGVtcGxhdGVzLmZpbmQoKHtrZXl9KSA9PiBrZXkgPT09IHRlbXBsYXRlKT8ubmFtZVxuXG4gIGlmICghcnVudGltZU5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcnVudGltZTogJHtydW50aW1lfWApXG4gIH1cblxuICBpZiAoIXRlbXBsYXRlTmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0ZW1wbGF0ZTogJHt0ZW1wbGF0ZX1gKVxuICB9XG5cbiAgLy8gVGhlIHRlbXBsYXRlcyBhcmUgc3RvcmVkIGluIHRoZSBgdGVtcGxhdGVzYCBkaXJlY3RvcnlcbiAgY29uc3Qgc2hhcmVkVGVtcGxhdGVEaXIgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4nLCAndGVtcGxhdGVzJywgJ3NoYXJlZCcpXG5cbiAgaWYgKCFmcy5leGlzdHNTeW5jKHNoYXJlZFRlbXBsYXRlRGlyKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgU2hhcmVkIHRlbXBsYXRlcyBub3QgZm91bmQ6ICR7c2hhcmVkVGVtcGxhdGVEaXJ9YClcbiAgfVxuXG4gIGNvbnN0IHRlbXBsYXRlRGlyID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uJywgJ3RlbXBsYXRlcycsIHJ1bnRpbWUsIHRlbXBsYXRlKVxuXG4gIGlmICghZnMuZXhpc3RzU3luYyh0ZW1wbGF0ZURpcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFRlbXBsYXRlIG5vdCBmb3VuZDogJHt0ZW1wbGF0ZURpcn1gKVxuICB9XG5cbiAgLy8gVGhlIHRhcmdldCBkaXJlY3RvcnkgaXMgYWxyZWFkeSBjcmVhdGVkXG4gIGNvbnN0IHRhcmdldERpcmVjdG9yeVBhdGggPSBwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgdGFyZ2V0KVxuXG4gIGNvbnNvbGEuc3RhcnQoYENyZWF0aW5nIHB5bG9uIGluICR7dGFyZ2V0RGlyZWN0b3J5UGF0aH1gKVxuXG4gIGNvbnN0IGluamVjdCA9IChjb250ZW50OiBzdHJpbmcpID0+IHtcbiAgICByZXR1cm4gaW5qZWN0VmFyaWFibGVzSW5Db250ZW50KGNvbnRlbnQsIHtcbiAgICAgIF9fUFlMT05fTkFNRV9fOiBvcHRpb25zLm5hbWVcbiAgICB9KVxuICB9XG5cbiAgLy8gQ29weSB0aGUgc2hhcmVkIHRlbXBsYXRlIGZpbGVzXG4gIHJlYWRkaXJGaWxlc1N5bmNSZWN1cnNpdmUoc2hhcmVkVGVtcGxhdGVEaXIpLmZvckVhY2goZmlsZSA9PiB7XG4gICAgY29uc3Qgc291cmNlID0gcGF0aC5qb2luKHNoYXJlZFRlbXBsYXRlRGlyLCBmaWxlKVxuICAgIGxldCB0YXJnZXQgPSBwYXRoLmpvaW4odGFyZ2V0RGlyZWN0b3J5UGF0aCwgZmlsZSlcblxuICAgIC8vIENyZWF0ZSBmb2xkZXIgcmVjdXJzaXZlbHkgYW5kIGNvcHkgZmlsZVxuXG4gICAgY29uc3QgdGFyZ2V0RGlyID0gcGF0aC5kaXJuYW1lKHRhcmdldClcblxuICAgIC8vIFNraXAgdGhlIC5naXRodWIvd29ya2Zsb3dzIGRpcmVjdG9yeSBmb3IgY2Ytd29ya2VycyBydW50aW1lXG4gICAgaWYgKFxuICAgICAgcnVudGltZSA9PT0gJ2NmLXdvcmtlcnMnICYmXG4gICAgICBzb3VyY2UuaW5jbHVkZXMoJy5naXRodWIvd29ya2Zsb3dzL3B1Ymxpc2gueWFtbCcpXG4gICAgKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoIWZzLmV4aXN0c1N5bmModGFyZ2V0RGlyKSkge1xuICAgICAgZnMubWtkaXJTeW5jKHRhcmdldERpciwge3JlY3Vyc2l2ZTogdHJ1ZX0pXG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIHRhcmdldCBlbmRzIHdpdGggYC5leGFtcGxlYCwgcmVtb3ZlIHRoZSBzdWZmaXguXG4gICAgLy8gVGhpcyBpcyB1c2VmdWwgZm9yIGAuZ2l0aWdub3JlLmV4YW1wbGVgIGZpbGVzIGJlY2F1c2UgdGhleSBhcmUgbm90IHB1Ymxpc2hlZCBpblxuICAgIC8vIHRoZSBgY3JlYXRlLXB5bG9uYCBwYWNrYWdlIHdoZW4gbmFtZWQgYC5naXRpZ25vcmVgLlxuICAgIGlmICh0YXJnZXQuZW5kc1dpdGgoJy5leGFtcGxlJykpIHtcbiAgICAgIHRhcmdldCA9IHRhcmdldC5yZXBsYWNlKCcuZXhhbXBsZScsICcnKVxuICAgIH1cblxuICAgIGNvbnN0IGluamVjdGVkQ29udGVudCA9IGluamVjdChmcy5yZWFkRmlsZVN5bmMoc291cmNlLCAndXRmLTgnKSlcblxuICAgIGZzLndyaXRlRmlsZVN5bmModGFyZ2V0LCBpbmplY3RlZENvbnRlbnQpXG4gIH0pXG5cbiAgLy8gQ29weSB0aGUgcnVudGltZSBzcGVjaWZpYyB0ZW1wbGF0ZSBmaWxlc1xuICByZWFkZGlyRmlsZXNTeW5jUmVjdXJzaXZlKHRlbXBsYXRlRGlyKS5mb3JFYWNoKGZpbGUgPT4ge1xuICAgIGNvbnN0IHNvdXJjZSA9IHBhdGguam9pbih0ZW1wbGF0ZURpciwgZmlsZSlcbiAgICBsZXQgdGFyZ2V0ID0gcGF0aC5qb2luKHRhcmdldERpcmVjdG9yeVBhdGgsIGZpbGUpXG5cbiAgICAvLyBDcmVhdGUgZm9sZGVyIHJlY3Vyc2l2ZWx5IGFuZCBjb3B5IGZpbGVcbiAgICBjb25zdCB0YXJnZXREaXIgPSBwYXRoLmRpcm5hbWUodGFyZ2V0KVxuXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHRhcmdldERpcikpIHtcbiAgICAgIGZzLm1rZGlyU3luYyh0YXJnZXREaXIsIHtyZWN1cnNpdmU6IHRydWV9KVxuICAgIH1cblxuICAgIC8vIElmIHRoZSB0YXJnZXQgZW5kcyB3aXRoIGAuZXhhbXBsZWAsIHJlbW92ZSB0aGUgc3VmZml4LlxuICAgIC8vIFRoaXMgaXMgdXNlZnVsIGZvciBgLmdpdGlnbm9yZS5leGFtcGxlYCBmaWxlcyBiZWNhdXNlIHRoZXkgYXJlIG5vdCBwdWJsaXNoZWQgaW5cbiAgICAvLyB0aGUgYGNyZWF0ZS1weWxvbmAgcGFja2FnZSB3aGVuIG5hbWVkIGAuZ2l0aWdub3JlYC5cbiAgICBpZiAodGFyZ2V0LmVuZHNXaXRoKCcuZXhhbXBsZScpKSB7XG4gICAgICB0YXJnZXQgPSB0YXJnZXQucmVwbGFjZSgnLmV4YW1wbGUnLCAnJylcbiAgICB9XG5cbiAgICBjb25zdCBpbmplY3RlZENvbnRlbnQgPSBpbmplY3QoZnMucmVhZEZpbGVTeW5jKHNvdXJjZSwgJ3V0Zi04JykpXG5cbiAgICBmcy53cml0ZUZpbGVTeW5jKHRhcmdldCwgaW5qZWN0ZWRDb250ZW50KVxuICB9KVxuXG4gIGNvbnNvbGEuc3VjY2VzcyhgUHlsb24gY3JlYXRlZGApXG59XG5cbmltcG9ydCB7ZGV0ZWN0fSBmcm9tICdkZXRlY3QtcGFja2FnZS1tYW5hZ2VyJ1xuaW1wb3J0IHtzcGF3blN5bmN9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnXG5cbmNvbnN0IGluc3RhbGxEZXBlbmRlbmNpZXMgPSBhc3luYyAoYXJnczoge1xuICB0YXJnZXQ6IHN0cmluZ1xuICBwYWNrYWdlTWFuYWdlcj86IHN0cmluZ1xufSkgPT4ge1xuICBjb25zdCB0YXJnZXQgPSBwYXRoLnJlc29sdmUoYXJncy50YXJnZXQpXG5cbiAgY29uc29sZS5sb2coJ3RhcmdldCcsIHRhcmdldClcblxuICBpZiAoIWFyZ3MucGFja2FnZU1hbmFnZXIpIHtcbiAgICBhcmdzLnBhY2thZ2VNYW5hZ2VyID0gYXdhaXQgZGV0ZWN0KHtcbiAgICAgIGN3ZDogdGFyZ2V0LFxuICAgICAgaW5jbHVkZUdsb2JhbEJ1bjogdHJ1ZVxuICAgIH0pXG4gIH1cblxuICBpZiAoIWFyZ3MucGFja2FnZU1hbmFnZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHBhY2thZ2UgbWFuYWdlciBmb3VuZCcpXG4gIH1cblxuICAvLyB5YXJuJywgJ25wbScsIG9yICdwbnBtJywgJ2J1bidcbiAgY29uc3Qge3BhY2thZ2VNYW5hZ2VyfSA9IGFyZ3NcblxuICBsZXQgY29tbWFuZCA9ICcnXG5cbiAgc3dpdGNoIChwYWNrYWdlTWFuYWdlcikge1xuICAgIGNhc2UgJ3lhcm4nOlxuICAgICAgY29tbWFuZCA9ICd5YXJuJ1xuICAgICAgYnJlYWtcbiAgICBjYXNlICducG0nOlxuICAgICAgY29tbWFuZCA9ICducG0gaW5zdGFsbCdcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAncG5wbSc6XG4gICAgICBjb21tYW5kID0gJ3BucG0gaW5zdGFsbCdcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYnVuJzpcbiAgICAgIGNvbW1hbmQgPSAnYnVuIGluc3RhbGwnXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcGFja2FnZSBtYW5hZ2VyOiAke3BhY2thZ2VNYW5hZ2VyfWApXG4gIH1cblxuICBjb25zb2xhLnN0YXJ0KGBJbnN0YWxsaW5nIGRlcGVuZGVuY2llcyB1c2luZyAke3BhY2thZ2VNYW5hZ2VyfWApXG5cbiAgY29uc3QgcHJvYyA9IHNwYXduU3luYyhjb21tYW5kLCB7XG4gICAgY3dkOiB0YXJnZXQsXG4gICAgc2hlbGw6IHRydWUsXG4gICAgc3RkaW86ICdpbmhlcml0J1xuICB9KVxuXG4gIGlmIChwcm9jLnN0YXR1cyAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGluc3RhbGwgZGVwZW5kZW5jaWVzYClcbiAgfVxuXG4gIGNvbnNvbGEuc3VjY2VzcyhgRGVwZW5kZW5jaWVzIGluc3RhbGxlZGApXG59XG5cbnByb2dyYW1cbiAgLm5hbWUoJ2NyZWF0ZS1weWxvbicpXG4gIC52ZXJzaW9uKHZlcnNpb24pXG4gIC5hcmd1bWVudHMoJ1t0YXJnZXRdJylcbiAgLmFkZE9wdGlvbihuZXcgT3B0aW9uKCctaSwgLS1pbnN0YWxsJywgJ0luc3RhbGwgZGVwZW5kZW5jaWVzJykpXG4gIC5hZGRPcHRpb24oXG4gICAgbmV3IE9wdGlvbignLXIsIC0tcnVudGltZSA8cnVudGltZT4nLCAnUnVudGltZScpLmNob2ljZXMoXG4gICAgICBydW50aW1lcy5tYXAoKHtrZXl9KSA9PiBrZXkpXG4gICAgKVxuICApXG4gIC5hZGRPcHRpb24obmV3IE9wdGlvbignLXQsIC0tdGVtcGxhdGUgPHRlbXBsYXRlPicsICdUZW1wbGF0ZScpKVxuICAuYWRkT3B0aW9uKFxuICAgIG5ldyBPcHRpb24oJy1wbSwgLS1wYWNrYWdlLW1hbmFnZXIgPHBhY2thZ2VNYW5hZ2VyPicsICdQYWNrYWdlIG1hbmFnZXInKVxuICApXG4gIC5hZGRPcHRpb24oXG4gICAgbmV3IE9wdGlvbihcbiAgICAgICctLWNsaWVudCcsXG4gICAgICAnRW5hYmxlIGNsaWVudCBnZW5lcmF0aW9uIChodHRwczovL3B5bG9uLmNyb25pdC5pby9kb2NzL2ludGVncmF0aW9ucy9ncXR5KSdcbiAgICApXG4gIClcbiAgLmFkZE9wdGlvbihuZXcgT3B0aW9uKCctLWNsaWVudC1wYXRoIDxjbGllbnRQYXRoPicsICdDbGllbnQgcGF0aCcpKVxuICAuYWRkT3B0aW9uKG5ldyBPcHRpb24oJy0tY2xpZW50LXBvcnQgPGNsaWVudFBvcnQ+JywgJ0NsaWVudCBwb3J0JykpXG4gIC5hY3Rpb24obWFpbilcblxudHlwZSBBcmdPcHRpb25zID0ge1xuICBpbnN0YWxsOiBib29sZWFuXG4gIHJ1bnRpbWU6IHN0cmluZ1xuICB0ZW1wbGF0ZTogc3RyaW5nXG4gIHBhY2thZ2VNYW5hZ2VyPzogc3RyaW5nXG4gIGNsaWVudD86IGJvb2xlYW5cbiAgY2xpZW50UGF0aD86IHN0cmluZ1xuICBjbGllbnRQb3J0Pzogc3RyaW5nXG59XG5cbmFzeW5jIGZ1bmN0aW9uIG1haW4oXG4gIHRhcmdldERpcjogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICBvcHRpb25zOiBBcmdPcHRpb25zLFxuICBjb21tYW5kOiBDb21tYW5kXG4pIHtcbiAgdHJ5IHtcbiAgICBjb25zb2xhLmxvZyhgJHtjb21tYW5kLm5hbWUoKX0gdmVyc2lvbiAke2NvbW1hbmQudmVyc2lvbigpfWApXG5cbiAgICBjb25zdCB7XG4gICAgICBpbnN0YWxsOiBpbnN0YWxsQXJnLFxuICAgICAgcnVudGltZTogcnVudGltZUFyZyxcbiAgICAgIHRlbXBsYXRlOiB0ZW1wbGF0ZUFyZyxcbiAgICAgIHBhY2thZ2VNYW5hZ2VyOiBwYWNrYWdlTWFuYWdlckFyZyxcbiAgICAgIGNsaWVudDogY2xpZW50QXJnLFxuICAgICAgY2xpZW50UGF0aDogY2xpZW50UGF0aEFyZyxcbiAgICAgIGNsaWVudFBvcnQ6IGNsaWVudFBvcnRBcmdcbiAgICB9ID0gb3B0aW9uc1xuXG4gICAgbGV0IHRhcmdldCA9ICcnXG5cbiAgICBpZiAodGFyZ2V0RGlyKSB7XG4gICAgICB0YXJnZXQgPSB0YXJnZXREaXJcblxuICAgICAgY29uc29sYS5zdWNjZXNzKGBVc2luZyB0YXJnZXQgZGlyZWN0b3J5IOKApiAke3RhcmdldH1gKVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBhbnN3ZXIgPSBhd2FpdCBpbnB1dCh7XG4gICAgICAgIG1lc3NhZ2U6ICdUYXJnZXQgZGlyZWN0b3J5JyxcbiAgICAgICAgZGVmYXVsdDogJ215LXB5bG9uJ1xuICAgICAgfSlcbiAgICAgIHRhcmdldCA9IGFuc3dlclxuICAgIH1cblxuICAgIGxldCBwcm9qZWN0TmFtZSA9ICcnXG5cbiAgICBpZiAodGFyZ2V0ID09PSAnLicpIHtcbiAgICAgIHByb2plY3ROYW1lID0gcGF0aC5iYXNlbmFtZShwcm9jZXNzLmN3ZCgpKVxuICAgIH0gZWxzZSB7XG4gICAgICBwcm9qZWN0TmFtZSA9IHBhdGguYmFzZW5hbWUodGFyZ2V0KVxuICAgIH1cblxuICAgIGNvbnN0IHJ1bnRpbWVOYW1lID1cbiAgICAgIHJ1bnRpbWVBcmcgfHxcbiAgICAgIChhd2FpdCBzZWxlY3Qoe1xuICAgICAgICBtZXNzYWdlOiAnV2hpY2ggcnVudGltZSB3b3VsZCB5b3UgbGlrZSB0byB1c2U/JyxcbiAgICAgICAgY2hvaWNlczogcnVudGltZXMubWFwKHJ1bnRpbWUgPT4gKHtcbiAgICAgICAgICBuYW1lOiBgJHtydW50aW1lLm5hbWV9ICgke3J1bnRpbWUud2Vic2l0ZX0pYCxcbiAgICAgICAgICB2YWx1ZTogcnVudGltZS5rZXlcbiAgICAgICAgfSkpLFxuICAgICAgICBkZWZhdWx0OiAwXG4gICAgICB9KSlcblxuICAgIGlmICghcnVudGltZU5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gcnVudGltZSBzZWxlY3RlZCcpXG4gICAgfVxuXG4gICAgY29uc3QgcnVudGltZSA9IHJ1bnRpbWVzLmZpbmQoKHtrZXl9KSA9PiBrZXkgPT09IHJ1bnRpbWVOYW1lKVxuXG4gICAgaWYgKCFydW50aW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcnVudGltZSBzZWxlY3RlZDogJHtydW50aW1lTmFtZX1gKVxuICAgIH1cblxuICAgIGNvbnN0IHRlbXBsYXRlTmFtZSA9XG4gICAgICB0ZW1wbGF0ZUFyZyB8fFxuICAgICAgKGF3YWl0IHNlbGVjdCh7XG4gICAgICAgIG1lc3NhZ2U6ICdXaGljaCB0ZW1wbGF0ZSB3b3VsZCB5b3UgbGlrZSB0byB1c2U/JyxcbiAgICAgICAgY2hvaWNlczogdGVtcGxhdGVzXG4gICAgICAgICAgLmZpbHRlcih0ZW1wbGF0ZSA9PiBydW50aW1lLnRlbXBsYXRlcz8uaW5jbHVkZXModGVtcGxhdGUua2V5KSlcbiAgICAgICAgICAubWFwKHRlbXBsYXRlID0+ICh7XG4gICAgICAgICAgICBuYW1lOiB0ZW1wbGF0ZS5uYW1lLFxuICAgICAgICAgICAgdmFsdWU6IHRlbXBsYXRlLmtleVxuICAgICAgICAgIH0pKSxcbiAgICAgICAgZGVmYXVsdDogMFxuICAgICAgfSkpXG5cbiAgICBpZiAoIXRlbXBsYXRlTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyB0ZW1wbGF0ZSBzZWxlY3RlZCcpXG4gICAgfVxuXG4gICAgaWYgKGZzLmV4aXN0c1N5bmModGFyZ2V0KSkge1xuICAgICAgaWYgKGZzLnJlYWRkaXJTeW5jKHRhcmdldCkubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNvbmZpcm0oe1xuICAgICAgICAgIG1lc3NhZ2U6ICdEaXJlY3Rvcnkgbm90IGVtcHR5LiBDb250aW51ZT8nLFxuICAgICAgICAgIGRlZmF1bHQ6IGZhbHNlXG4gICAgICAgIH0pXG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBta2RpcnAodGFyZ2V0KVxuICAgIH1cblxuICAgIGNvbnN0IGluc3RhbGwgPVxuICAgICAgaW5zdGFsbEFyZyB8fFxuICAgICAgKGF3YWl0IGNvbmZpcm0oe21lc3NhZ2U6ICdXb3VsZCB5b3UgbGlrZSB0byBpbnN0YWxsIGRlcGVuZGVuY2llcz8nfSkpXG5cbiAgICBhd2FpdCBjcmVhdGVUZW1wbGF0ZSh7XG4gICAgICBuYW1lOiBwcm9qZWN0TmFtZSxcbiAgICAgIHJ1bnRpbWU6IHJ1bnRpbWVOYW1lLFxuICAgICAgdGVtcGxhdGU6IHRlbXBsYXRlTmFtZSxcbiAgICAgIHRhcmdldFxuICAgIH0pXG5cbiAgICBsZXQgcGFja2FnZU1hbmFnZXIgPSBwYWNrYWdlTWFuYWdlckFyZ1xuXG4gICAgaWYgKHJ1bnRpbWVOYW1lID09PSAnYnVuJyAmJiAhcGFja2FnZU1hbmFnZXIpIHtcbiAgICAgIHBhY2thZ2VNYW5hZ2VyID0gJ2J1bidcbiAgICB9XG5cbiAgICBpZiAoaW5zdGFsbCkge1xuICAgICAgYXdhaXQgaW5zdGFsbERlcGVuZGVuY2llcyh7dGFyZ2V0LCBwYWNrYWdlTWFuYWdlcn0pXG4gICAgfVxuXG4gICAgY29uc3QgY2xpZW50ID1cbiAgICAgIGNsaWVudEFyZyB8fFxuICAgICAgKGF3YWl0IGNvbmZpcm0oe1xuICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgICdXb3VsZCB5b3UgbGlrZSB0byBlbmFibGUgY2xpZW50IGdlbmVyYXRpb24/IChodHRwczovL3B5bG9uLmNyb25pdC5pby9kb2NzL2ludGVncmF0aW9ucy9ncXR5KScsXG4gICAgICAgIGRlZmF1bHQ6IGZhbHNlXG4gICAgICB9KSlcblxuICAgIGxldCBjbGllbnRSb290OiBzdHJpbmcgPSAnJ1xuICAgIGxldCBjbGllbnRQYXRoOiBzdHJpbmcgPSAnJ1xuICAgIGxldCBjbGllbnRQb3J0OiBzdHJpbmcgPSAnJ1xuXG4gICAgaWYgKGNsaWVudCkge1xuICAgICAgaWYgKCFjbGllbnRQYXRoQXJnKSB7XG4gICAgICAgIGNsaWVudFJvb3QgPSBhd2FpdCBpbnB1dCh7XG4gICAgICAgICAgbWVzc2FnZTogJ1BhdGggdG8gdGhlIHJvb3Qgd2hlcmUgdGhlIGNsaWVudCBzaG91bGQgYmUgZ2VuZXJhdGVkJyxcbiAgICAgICAgICBkZWZhdWx0OiAnLidcbiAgICAgICAgfSlcblxuICAgICAgICBjbGllbnRQYXRoID0gYXdhaXQgaW5wdXQoe1xuICAgICAgICAgIG1lc3NhZ2U6ICdQYXRoIHRvIGdlbmVyYXRlIHRoZSBjbGllbnQgdG8nLFxuICAgICAgICAgIGRlZmF1bHQ6IHBhdGguam9pbihjbGllbnRSb290LCAnZ3F0eS9pbmRleC50cycpLFxuICAgICAgICAgIHZhbGlkYXRlOiB2YWx1ZSA9PiB7XG4gICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgcGF0aCBzdGFydHMgd2l0aCB0aGUgY2xpZW50IHJvb3QgKHRha2UgY2FyZSBvZiAuKVxuICAgICAgICAgICAgaWYgKCF2YWx1ZS5zdGFydHNXaXRoKGNsaWVudFJvb3QgPT09ICcuJyA/ICcnIDogY2xpZW50Um9vdCkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuICdQYXRoIG11c3Qgc3RhcnQgd2l0aCB0aGUgY2xpZW50IHJvb3QnXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBjbGllbnRQb3J0ID1cbiAgICAgICAgY2xpZW50UG9ydEFyZyB8fFxuICAgICAgICAoYXdhaXQgaW5wdXQoe1xuICAgICAgICAgIG1lc3NhZ2U6ICdQb3J0IG9mIHRoZSBweWxvbiBzZXJ2ZXIgdG8gZ2VuZXJhdGUgdGhlIGNsaWVudCBmcm9tJyxcbiAgICAgICAgICBkZWZhdWx0OiAnMzAwMCdcbiAgICAgICAgfSkpXG5cbiAgICAgIGNvbnNvbGEuc3RhcnQoYFVwZGF0aW5nIHB5bG9uIGRldiBzY3JpcHQgdG8gZ2VuZXJhdGUgY2xpZW50YClcblxuICAgICAgY29uc3QgZGV2U2NyaXB0UGF0aCA9IHBhdGguam9pbih0YXJnZXQsICdwYWNrYWdlLmpzb24nKVxuXG4gICAgICBjb25zdCBkZXZTY3JpcHQgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhkZXZTY3JpcHRQYXRoLCAndXRmLTgnKSlcblxuICAgICAgZGV2U2NyaXB0LnNjcmlwdHMgPSB7XG4gICAgICAgIC4uLmRldlNjcmlwdC5zY3JpcHRzLFxuICAgICAgICBkZXY6XG4gICAgICAgICAgZGV2U2NyaXB0LnNjcmlwdHMuZGV2ICtcbiAgICAgICAgICBgIC0tY2xpZW50IC0tY2xpZW50LXBvcnQgJHtjbGllbnRQb3J0fSAtLWNsaWVudC1wYXRoICR7Y2xpZW50UGF0aH1gXG4gICAgICB9XG5cbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoZGV2U2NyaXB0UGF0aCwgSlNPTi5zdHJpbmdpZnkoZGV2U2NyaXB0LCBudWxsLCAyKSlcblxuICAgICAgY29uc29sYS5zdWNjZXNzKGBQeWxvbiBkZXYgc2NyaXB0IHVwZGF0ZWRgKVxuICAgIH1cblxuICAgIGNvbnN0IG1lc3NhZ2UgPSBgXG7wn46JICR7Y2hhbGsuZ3JlZW4uYm9sZCgnUHlsb24gY3JlYXRlZCBzdWNjZXNzZnVsbHkuJyl9XG5cbvCfkrsgJHtjaGFsay5jeWFuLmJvbGQoJ0NvbnRpbnVlIERldmVsb3BpbmcnKX1cbiAgICAke2NoYWxrLnllbGxvdygnQ2hhbmdlIGRpcmVjdG9yaWVzOicpfSBjZCAke2NoYWxrLmJsdWUodGFyZ2V0KX1cbiAgICAke2NoYWxrLnllbGxvdygnU3RhcnQgZGV2IHNlcnZlcjonKX0gbnBtIHJ1biBzdGFydFxuICAgICR7Y2hhbGsueWVsbG93KCdEZXBsb3k6Jyl9IG5wbSBydW4gZGVwbG95XG5cbvCfk5YgJHtjaGFsay5jeWFuLmJvbGQoJ0V4cGxvcmUgRG9jdW1lbnRhdGlvbicpfVxuICAgICR7Y2hhbGsudW5kZXJsaW5lLmJsdWUoJ2h0dHBzOi8vcHlsb24uY3Jvbml0LmlvL2RvY3MnKX1cblxu8J+SrCAke2NoYWxrLmN5YW4uYm9sZCgnSm9pbiBvdXIgQ29tbXVuaXR5Jyl9XG4gICAgJHtjaGFsay51bmRlcmxpbmUuYmx1ZSgnaHR0cHM6Ly9kaXNjb3JkLmdnL2NiSmprVnJuSGUnKX1cbmBcblxuICAgIGF3YWl0IHRlbGVtZXRyeS5zZW5kQ3JlYXRlRXZlbnQoe1xuICAgICAgbmFtZTogcHJvamVjdE5hbWUsXG4gICAgICBweWxvbkNyZWF0ZVZlcnNpb246IHZlcnNpb24sXG4gICAgICBydW50aW1lOiBydW50aW1lTmFtZSxcbiAgICAgIHRlbXBsYXRlOiB0ZW1wbGF0ZU5hbWUsXG4gICAgICBjbGllbnRQYXRoOiBjbGllbnRQYXRoIHx8IHVuZGVmaW5lZCxcbiAgICAgIGNsaWVudFBvcnQ6IHBhcnNlSW50KGNsaWVudFBvcnQpIHx8IHVuZGVmaW5lZFxuICAgIH0pXG5cbiAgICBjb25zb2xhLmJveChtZXNzYWdlKVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sYS5lcnJvcihlKVxuICB9XG59XG5cbnByb2dyYW0ucGFyc2UoKVxuIgogIF0sCiAgIm1hcHBpbmdzIjogIjs7OztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQVdBLFNBQVMsTUFBTSxDQUFDLEtBQWE7QUFDM0IsTUFBSTtBQUNGLElBQUcsYUFBVSxLQUFLLEVBQUMsV0FBVyxLQUFJLENBQUM7QUFBQSxXQUM1QixHQUFQO0FBQ0EsUUFBSSxhQUFhLE9BQU87QUFDdEIsVUFBSSxVQUFVLEtBQUssRUFBRSxTQUFTO0FBQVU7QUFBQSxJQUMxQztBQUNBLFVBQU07QUFBQTtBQUFBO0FB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S0FBSyxjQUFjLEVBQ25CLFFBQVEsT0FBTyxFQUNmLFVBQVUsVUFBVSxFQUNwQixVQUFVLElBQUksT0FBTyxpQkFBaUIsc0JBQXNCLENBQUMsRUFDN0QsVUFDQyxJQUFJLE9BQU8sMkJBQTJCLFNBQVMsRUFBRSxRQUMvQyxTQUFTLElBQUksR0FBRSxVQUFTLEdBQUcsQ0FDN0IsQ0FDRixFQUNDLFVBQVUsSUFBSSxPQUFPLDZCQUE2QixVQUFVLENBQUMsRUFDN0QsVUFDQyxJQUFJLE9BQU8sMkNBQTJDLGlCQUFpQixDQUN6RSxFQUNDLFVBQ0MsSUFBSSxPQUNGLFlBQ0EsMkVBQ0YsQ0FDRixFQUNDLFVBQVUsSUFBSSxPQUFPLDhCQUE4QixhQUFhLENBQUMsRUFDakUsVUFBVSxJQUFJLE9BQU8sOEJBQThCLGFBQWEsQ0FBQyxFQUNqRSxPQUFPLElBQUk7QUFxTmQsUUFBUSxNQUFNOyIsCiAgImRlYnVnSWQiOiAiNTVBRjU0Nzk2MDgzOEJCMTY0NzU2RTIxNjQ3NTZFMjEiLAogICJuYW1lcyI6IFtdCn0=
451
+ //# debugId=49FD4AB53F50782964756E2164756E21
452
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIiwgIi4uL3NyYy9kZXRlY3QtcG0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuXG5pbXBvcnQge09wdGlvbiwgcHJvZ3JhbSwgdHlwZSBDb21tYW5kfSBmcm9tICdjb21tYW5kZXInXG5pbXBvcnQgY29uc29sYSBmcm9tICdjb25zb2xhJ1xuaW1wb3J0IHtpbnB1dCwgc2VsZWN0LCBjb25maXJtfSBmcm9tICdAaW5xdWlyZXIvcHJvbXB0cydcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXG5pbXBvcnQgY2hhbGsgZnJvbSAnY2hhbGsnXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcydcblxuaW1wb3J0ICogYXMgdGVsZW1ldHJ5IGZyb20gJ0BnZXRjcm9uaXQvcHlsb24tdGVsZW1ldHJ5J1xuXG5pbXBvcnQge2ZpbGVVUkxUb1BhdGh9IGZyb20gJ3VybCdcbmltcG9ydCB7ZGlybmFtZX0gZnJvbSAncGF0aCdcblxuY29uc3QgX19maWxlbmFtZSA9IGZpbGVVUkxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKVxuY29uc3QgX19kaXJuYW1lID0gZGlybmFtZShfX2ZpbGVuYW1lKVxuXG5jb25zdCB2ZXJzaW9uID0gKCgpID0+IHtcbiAgcmV0dXJuIEpTT04ucGFyc2UoXG4gICAgZnMucmVhZEZpbGVTeW5jKHBhdGguam9pbihfX2Rpcm5hbWUsICcuLicsICdwYWNrYWdlLmpzb24nKSwgJ3V0Zi04JylcbiAgKS52ZXJzaW9uIGFzIHN0cmluZ1xufSkoKVxuXG5mdW5jdGlvbiBta2RpcnAoZGlyOiBzdHJpbmcpIHtcbiAgdHJ5IHtcbiAgICBmcy5ta2RpclN5bmMoZGlyLCB7cmVjdXJzaXZlOiB0cnVlfSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGlmICgnY29kZScgaW4gZSAmJiBlLmNvZGUgPT09ICdFRVhJU1QnKSByZXR1cm5cbiAgICB9XG4gICAgdGhyb3cgZVxuICB9XG59XG5cbmNvbnN0IHJ1bnRpbWVzOiB7XG4gIGtleTogc3RyaW5nXG4gIG5hbWU6IHN0cmluZ1xuICB3ZWJzaXRlOiBzdHJpbmdcbiAgdGVtcGxhdGVzPzogc3RyaW5nW11cbn1bXSA9IFtcbiAge1xuICAgIGtleTogJ2J1bicsXG4gICAgbmFtZTogJ0J1bi5qcycsXG4gICAgd2Vic2l0ZTogJ2h0dHBzOi8vYnVuanMuZGV2JyxcbiAgICB0ZW1wbGF0ZXM6IFsnZGVmYXVsdCddXG4gIH0sXG4gIHtcbiAgICBrZXk6ICdub2RlJyxcbiAgICBuYW1lOiAnTm9kZS5qcycsXG4gICAgd2Vic2l0ZTogJ2h0dHBzOi8vbm9kZWpzLm9yZycsXG4gICAgdGVtcGxhdGVzOiBbJ2RlZmF1bHQnXVxuICB9LFxuICB7XG4gICAga2V5OiAnY2Ytd29ya2VycycsXG4gICAgbmFtZTogJ0Nsb3VkZmxhcmUgV29ya2VycycsXG4gICAgd2Vic2l0ZTogJ2h0dHBzOi8vd29ya2Vycy5jbG91ZGZsYXJlLmNvbScsXG4gICAgdGVtcGxhdGVzOiBbJ2RlZmF1bHQnXVxuICB9LFxuICB7XG4gICAga2V5OiAnZGVubycsXG4gICAgbmFtZTogJ0Rlbm8nLFxuICAgIHdlYnNpdGU6ICdodHRwczovL2Rlbm8ubGFuZCcsXG4gICAgdGVtcGxhdGVzOiBbJ2RlZmF1bHQnXVxuICB9XG5dXG5cbmNvbnN0IHRlbXBsYXRlczoge1xuICBrZXk6IHN0cmluZ1xuICBuYW1lOiBzdHJpbmdcbiAgZGVzY3JpcHRpb246IHN0cmluZ1xufVtdID0gW1xuICB7XG4gICAga2V5OiAnZGVmYXVsdCcsXG4gICAgbmFtZTogJ0RlZmF1bHQnLFxuICAgIGRlc2NyaXB0aW9uOiAnRGVmYXVsdCB0ZW1wbGF0ZSdcbiAgfSxcbiAge1xuICAgIGtleTogJ2RhdGFiYXNlJyxcbiAgICBuYW1lOiAnRGF0YWJhc2UgKFByaXNtYSknLFxuICAgIGRlc2NyaXB0aW9uOiAnVGVtcGxhdGUgd2l0aCBQcmlzbWEgT1JNJ1xuICB9XG5dXG5cbmNvbnN0IGluamVjdFZhcmlhYmxlc0luQ29udGVudCA9IChcbiAgY29udGVudDogc3RyaW5nLFxuICB2YXJpYWJsZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz5cbikgPT4ge1xuICBsZXQgcmVzdWx0ID0gY29udGVudFxuXG4gIE9iamVjdC5lbnRyaWVzKHZhcmlhYmxlcykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgcmVzdWx0ID0gcmVzdWx0LnJlcGxhY2VBbGwoa2V5LCB2YWx1ZSlcbiAgfSlcblxuICByZXR1cm4gcmVzdWx0XG59XG5jb25zdCByZWFkZGlyRmlsZXNTeW5jUmVjdXJzaXZlID0gKGRpcjogc3RyaW5nKTogc3RyaW5nW10gPT4ge1xuICBjb25zdCBydW4gPSAoZGlyOiBzdHJpbmcpOiBzdHJpbmdbXSA9PiB7XG4gICAgY29uc3QgcmVzdWx0OiBzdHJpbmdbXSA9IFtdXG5cbiAgICBjb25zdCBmaWxlcyA9IGZzLnJlYWRkaXJTeW5jKGRpcilcblxuICAgIGZpbGVzLmZvckVhY2goZmlsZSA9PiB7XG4gICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbihkaXIsIGZpbGUpXG5cbiAgICAgIGlmIChmcy5zdGF0U3luYyhmaWxlUGF0aCkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICByZXN1bHQucHVzaCguLi5ydW4oZmlsZVBhdGgpKVxuICAgICAgfVxuXG4gICAgICAvLyBPbmx5IGFkZCBmaWxlc1xuICAgICAgaWYgKGZzLnN0YXRTeW5jKGZpbGVQYXRoKS5pc0ZpbGUoKSkge1xuICAgICAgICByZXN1bHQucHVzaChmaWxlUGF0aClcbiAgICAgIH1cbiAgICB9KVxuXG4gICAgcmV0dXJuIHJlc3VsdFxuICB9XG5cbiAgcmV0dXJuIHJ1bihkaXIpLm1hcChmaWxlID0+IHtcbiAgICByZXR1cm4gZmlsZS5yZXBsYWNlKGRpciwgJy4nKVxuICB9KVxufVxuXG5jb25zdCBjcmVhdGVUZW1wbGF0ZSA9IGFzeW5jIChvcHRpb25zOiB7XG4gIG5hbWU6IHN0cmluZ1xuICBydW50aW1lOiBzdHJpbmdcbiAgdGVtcGxhdGU6IHN0cmluZ1xuICB0YXJnZXQ6IHN0cmluZ1xufSkgPT4ge1xuICBjb25zdCB7cnVudGltZSwgdGVtcGxhdGUsIHRhcmdldH0gPSBvcHRpb25zXG5cbiAgY29uc3QgcnVudGltZU5hbWUgPSBydW50aW1lcy5maW5kKCh7a2V5fSkgPT4ga2V5ID09PSBydW50aW1lKT8ubmFtZVxuICBjb25zdCB0ZW1wbGF0ZU5hbWUgPSB0ZW1wbGF0ZXMuZmluZCgoe2tleX0pID0+IGtleSA9PT0gdGVtcGxhdGUpPy5uYW1lXG5cbiAgaWYgKCFydW50aW1lTmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBydW50aW1lOiAke3J1bnRpbWV9YClcbiAgfVxuXG4gIGlmICghdGVtcGxhdGVOYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHRlbXBsYXRlOiAke3RlbXBsYXRlfWApXG4gIH1cblxuICAvLyBUaGUgdGVtcGxhdGVzIGFyZSBzdG9yZWQgaW4gdGhlIGB0ZW1wbGF0ZXNgIGRpcmVjdG9yeVxuICBjb25zdCBzaGFyZWRUZW1wbGF0ZURpciA9IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLicsICd0ZW1wbGF0ZXMnLCAnc2hhcmVkJylcblxuICBpZiAoIWZzLmV4aXN0c1N5bmMoc2hhcmVkVGVtcGxhdGVEaXIpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBTaGFyZWQgdGVtcGxhdGVzIG5vdCBmb3VuZDogJHtzaGFyZWRUZW1wbGF0ZURpcn1gKVxuICB9XG5cbiAgY29uc3QgdGVtcGxhdGVEaXIgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4nLCAndGVtcGxhdGVzJywgcnVudGltZSwgdGVtcGxhdGUpXG5cbiAgaWYgKCFmcy5leGlzdHNTeW5jKHRlbXBsYXRlRGlyKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGVtcGxhdGUgbm90IGZvdW5kOiAke3RlbXBsYXRlRGlyfWApXG4gIH1cblxuICAvLyBUaGUgdGFyZ2V0IGRpcmVjdG9yeSBpcyBhbHJlYWR5IGNyZWF0ZWRcbiAgY29uc3QgdGFyZ2V0RGlyZWN0b3J5UGF0aCA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCB0YXJnZXQpXG5cbiAgY29uc29sYS5zdGFydChgQ3JlYXRpbmcgcHlsb24gaW4gJHt0YXJnZXREaXJlY3RvcnlQYXRofWApXG5cbiAgY29uc3QgaW5qZWN0ID0gKGNvbnRlbnQ6IHN0cmluZykgPT4ge1xuICAgIHJldHVybiBpbmplY3RWYXJpYWJsZXNJbkNvbnRlbnQoY29udGVudCwge1xuICAgICAgX19QWUxPTl9OQU1FX186IG9wdGlvbnMubmFtZVxuICAgIH0pXG4gIH1cblxuICAvLyBDb3B5IHRoZSBzaGFyZWQgdGVtcGxhdGUgZmlsZXNcbiAgcmVhZGRpckZpbGVzU3luY1JlY3Vyc2l2ZShzaGFyZWRUZW1wbGF0ZURpcikuZm9yRWFjaChmaWxlID0+IHtcbiAgICBjb25zdCBzb3VyY2UgPSBwYXRoLmpvaW4oc2hhcmVkVGVtcGxhdGVEaXIsIGZpbGUpXG4gICAgbGV0IHRhcmdldCA9IHBhdGguam9pbih0YXJnZXREaXJlY3RvcnlQYXRoLCBmaWxlKVxuXG4gICAgLy8gQ3JlYXRlIGZvbGRlciByZWN1cnNpdmVseSBhbmQgY29weSBmaWxlXG5cbiAgICBjb25zdCB0YXJnZXREaXIgPSBwYXRoLmRpcm5hbWUodGFyZ2V0KVxuXG4gICAgLy8gU2tpcCB0aGUgLmdpdGh1Yi93b3JrZmxvd3MgZGlyZWN0b3J5IGZvciBjZi13b3JrZXJzIHJ1bnRpbWVcbiAgICBpZiAoXG4gICAgICBydW50aW1lID09PSAnY2Ytd29ya2VycycgJiZcbiAgICAgIHNvdXJjZS5pbmNsdWRlcygnLmdpdGh1Yi93b3JrZmxvd3MvcHVibGlzaC55YW1sJylcbiAgICApIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICghZnMuZXhpc3RzU3luYyh0YXJnZXREaXIpKSB7XG4gICAgICBmcy5ta2RpclN5bmModGFyZ2V0RGlyLCB7cmVjdXJzaXZlOiB0cnVlfSlcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgdGFyZ2V0IGVuZHMgd2l0aCBgLmV4YW1wbGVgLCByZW1vdmUgdGhlIHN1ZmZpeC5cbiAgICAvLyBUaGlzIGlzIHVzZWZ1bCBmb3IgYC5naXRpZ25vcmUuZXhhbXBsZWAgZmlsZXMgYmVjYXVzZSB0aGV5IGFyZSBub3QgcHVibGlzaGVkIGluXG4gICAgLy8gdGhlIGBjcmVhdGUtcHlsb25gIHBhY2thZ2Ugd2hlbiBuYW1lZCBgLmdpdGlnbm9yZWAuXG4gICAgaWYgKHRhcmdldC5lbmRzV2l0aCgnLmV4YW1wbGUnKSkge1xuICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnJlcGxhY2UoJy5leGFtcGxlJywgJycpXG4gICAgfVxuXG4gICAgY29uc3QgaW5qZWN0ZWRDb250ZW50ID0gaW5qZWN0KGZzLnJlYWRGaWxlU3luYyhzb3VyY2UsICd1dGYtOCcpKVxuXG4gICAgZnMud3JpdGVGaWxlU3luYyh0YXJnZXQsIGluamVjdGVkQ29udGVudClcbiAgfSlcblxuICAvLyBDb3B5IHRoZSBydW50aW1lIHNwZWNpZmljIHRlbXBsYXRlIGZpbGVzXG4gIHJlYWRkaXJGaWxlc1N5bmNSZWN1cnNpdmUodGVtcGxhdGVEaXIpLmZvckVhY2goZmlsZSA9PiB7XG4gICAgY29uc3Qgc291cmNlID0gcGF0aC5qb2luKHRlbXBsYXRlRGlyLCBmaWxlKVxuICAgIGxldCB0YXJnZXQgPSBwYXRoLmpvaW4odGFyZ2V0RGlyZWN0b3J5UGF0aCwgZmlsZSlcblxuICAgIC8vIENyZWF0ZSBmb2xkZXIgcmVjdXJzaXZlbHkgYW5kIGNvcHkgZmlsZVxuICAgIGNvbnN0IHRhcmdldERpciA9IHBhdGguZGlybmFtZSh0YXJnZXQpXG5cbiAgICBpZiAoIWZzLmV4aXN0c1N5bmModGFyZ2V0RGlyKSkge1xuICAgICAgZnMubWtkaXJTeW5jKHRhcmdldERpciwge3JlY3Vyc2l2ZTogdHJ1ZX0pXG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIHRhcmdldCBlbmRzIHdpdGggYC5leGFtcGxlYCwgcmVtb3ZlIHRoZSBzdWZmaXguXG4gICAgLy8gVGhpcyBpcyB1c2VmdWwgZm9yIGAuZ2l0aWdub3JlLmV4YW1wbGVgIGZpbGVzIGJlY2F1c2UgdGhleSBhcmUgbm90IHB1Ymxpc2hlZCBpblxuICAgIC8vIHRoZSBgY3JlYXRlLXB5bG9uYCBwYWNrYWdlIHdoZW4gbmFtZWQgYC5naXRpZ25vcmVgLlxuICAgIGlmICh0YXJnZXQuZW5kc1dpdGgoJy5leGFtcGxlJykpIHtcbiAgICAgIHRhcmdldCA9IHRhcmdldC5yZXBsYWNlKCcuZXhhbXBsZScsICcnKVxuICAgIH1cblxuICAgIGNvbnN0IGluamVjdGVkQ29udGVudCA9IGluamVjdChmcy5yZWFkRmlsZVN5bmMoc291cmNlLCAndXRmLTgnKSlcblxuICAgIGZzLndyaXRlRmlsZVN5bmModGFyZ2V0LCBpbmplY3RlZENvbnRlbnQpXG4gIH0pXG5cbiAgY29uc29sYS5zdWNjZXNzKGBQeWxvbiBjcmVhdGVkYClcbn1cblxuaW1wb3J0IHtzcGF3blN5bmN9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnXG5pbXBvcnQge2RldGVjdFBhY2thZ2VNYW5hZ2VyLCBnZXRSdW5TY3JpcHQsIFBhY2thZ2VNYW5hZ2VyfSBmcm9tICcuL2RldGVjdC1wbSdcblxuY29uc3QgaW5zdGFsbERlcGVuZGVuY2llcyA9IGFzeW5jIChhcmdzOiB7XG4gIHRhcmdldDogc3RyaW5nXG4gIHBhY2thZ2VNYW5hZ2VyOiBQYWNrYWdlTWFuYWdlclxufSkgPT4ge1xuICBjb25zdCB0YXJnZXQgPSBwYXRoLnJlc29sdmUoYXJncy50YXJnZXQpXG4gIGNvbnN0IHBhY2thZ2VNYW5hZ2VyID0gYXJncy5wYWNrYWdlTWFuYWdlclxuXG4gIGxldCBjb21tYW5kID0gJydcblxuICBzd2l0Y2ggKHBhY2thZ2VNYW5hZ2VyKSB7XG4gICAgY2FzZSAneWFybic6XG4gICAgICBjb21tYW5kID0gJ3lhcm4nXG4gICAgICBicmVha1xuICAgIGNhc2UgJ25wbSc6XG4gICAgICBjb21tYW5kID0gJ25wbSBpbnN0YWxsJ1xuICAgICAgYnJlYWtcbiAgICBjYXNlICdwbnBtJzpcbiAgICAgIGNvbW1hbmQgPSAncG5wbSBpbnN0YWxsJ1xuICAgICAgYnJlYWtcbiAgICBjYXNlICdidW4nOlxuICAgICAgY29tbWFuZCA9ICdidW4gaW5zdGFsbCdcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnZGVubyc6XG4gICAgICBjb21tYW5kID0gJ2Rlbm8gaW5zdGFsbCdcbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBwYWNrYWdlIG1hbmFnZXI6ICR7cGFja2FnZU1hbmFnZXJ9YClcbiAgfVxuXG4gIGNvbnNvbGEuc3RhcnQoYEluc3RhbGxpbmcgZGVwZW5kZW5jaWVzIHVzaW5nICR7cGFja2FnZU1hbmFnZXJ9YClcblxuICBjb25zdCBwcm9jID0gc3Bhd25TeW5jKGNvbW1hbmQsIHtcbiAgICBjd2Q6IHRhcmdldCxcbiAgICBzaGVsbDogdHJ1ZSxcbiAgICBzdGRpbzogJ2luaGVyaXQnXG4gIH0pXG5cbiAgaWYgKHByb2Muc3RhdHVzICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gaW5zdGFsbCBkZXBlbmRlbmNpZXNgKVxuICB9XG5cbiAgY29uc29sYS5zdWNjZXNzKGBEZXBlbmRlbmNpZXMgaW5zdGFsbGVkYClcbn1cblxucHJvZ3JhbVxuICAubmFtZSgnY3JlYXRlLXB5bG9uJylcbiAgLnZlcnNpb24odmVyc2lvbilcbiAgLmFyZ3VtZW50cygnW3RhcmdldF0nKVxuICAuYWRkT3B0aW9uKG5ldyBPcHRpb24oJy1pLCAtLWluc3RhbGwnLCAnSW5zdGFsbCBkZXBlbmRlbmNpZXMnKSlcbiAgLmFkZE9wdGlvbihcbiAgICBuZXcgT3B0aW9uKCctciwgLS1ydW50aW1lIDxydW50aW1lPicsICdSdW50aW1lJykuY2hvaWNlcyhcbiAgICAgIHJ1bnRpbWVzLm1hcCgoe2tleX0pID0+IGtleSlcbiAgICApXG4gIClcbiAgLmFkZE9wdGlvbihuZXcgT3B0aW9uKCctdCwgLS10ZW1wbGF0ZSA8dGVtcGxhdGU+JywgJ1RlbXBsYXRlJykpXG4gIC5hZGRPcHRpb24oXG4gICAgbmV3IE9wdGlvbignLXBtLCAtLXBhY2thZ2UtbWFuYWdlciA8cGFja2FnZU1hbmFnZXI+JywgJ1BhY2thZ2UgbWFuYWdlcicpXG4gIClcbiAgLmFkZE9wdGlvbihcbiAgICBuZXcgT3B0aW9uKFxuICAgICAgJy0tY2xpZW50JyxcbiAgICAgICdFbmFibGUgY2xpZW50IGdlbmVyYXRpb24gKGh0dHBzOi8vcHlsb24uY3Jvbml0LmlvL2RvY3MvaW50ZWdyYXRpb25zL2dxdHkpJ1xuICAgIClcbiAgKVxuICAuYWRkT3B0aW9uKG5ldyBPcHRpb24oJy0tY2xpZW50LXBhdGggPGNsaWVudFBhdGg+JywgJ0NsaWVudCBwYXRoJykpXG4gIC5hZGRPcHRpb24obmV3IE9wdGlvbignLS1jbGllbnQtcG9ydCA8Y2xpZW50UG9ydD4nLCAnQ2xpZW50IHBvcnQnKSlcbiAgLmFjdGlvbihtYWluKVxuXG50eXBlIEFyZ09wdGlvbnMgPSB7XG4gIGluc3RhbGw6IGJvb2xlYW5cbiAgcnVudGltZTogc3RyaW5nXG4gIHRlbXBsYXRlOiBzdHJpbmdcbiAgcGFja2FnZU1hbmFnZXI/OiBQYWNrYWdlTWFuYWdlclxuICBjbGllbnQ/OiBib29sZWFuXG4gIGNsaWVudFBhdGg/OiBzdHJpbmdcbiAgY2xpZW50UG9ydD86IHN0cmluZ1xufVxuXG5jb25zdCBnZXRQcmVmZXJyZWRQbUJ5UnVudGltZSA9IChcbiAgcnVudGltZTogc3RyaW5nXG4pOiBQYWNrYWdlTWFuYWdlciB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChydW50aW1lID09PSAnYnVuJykge1xuICAgIHJldHVybiAnYnVuJ1xuICB9IGVsc2UgaWYgKHJ1bnRpbWUgPT09ICdkZW5vJykge1xuICAgIHJldHVybiAnZGVubydcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBtYWluKFxuICB0YXJnZXREaXI6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgb3B0aW9uczogQXJnT3B0aW9ucyxcbiAgY29tbWFuZDogQ29tbWFuZFxuKSB7XG4gIHRyeSB7XG4gICAgY29uc29sYS5sb2coYCR7Y29tbWFuZC5uYW1lKCl9IHZlcnNpb24gJHtjb21tYW5kLnZlcnNpb24oKX1gKVxuXG4gICAgY29uc3Qge1xuICAgICAgaW5zdGFsbDogaW5zdGFsbEFyZyxcbiAgICAgIHJ1bnRpbWU6IHJ1bnRpbWVBcmcsXG4gICAgICB0ZW1wbGF0ZTogdGVtcGxhdGVBcmcsXG4gICAgICBwYWNrYWdlTWFuYWdlcjogcGFja2FnZU1hbmFnZXJBcmcsXG4gICAgICBjbGllbnQ6IGNsaWVudEFyZyxcbiAgICAgIGNsaWVudFBhdGg6IGNsaWVudFBhdGhBcmcsXG4gICAgICBjbGllbnRQb3J0OiBjbGllbnRQb3J0QXJnXG4gICAgfSA9IG9wdGlvbnNcblxuICAgIGxldCB0YXJnZXQgPSAnJ1xuXG4gICAgaWYgKHRhcmdldERpcikge1xuICAgICAgdGFyZ2V0ID0gdGFyZ2V0RGlyXG5cbiAgICAgIGNvbnNvbGEuc3VjY2VzcyhgVXNpbmcgdGFyZ2V0IGRpcmVjdG9yeSDigKYgJHt0YXJnZXR9YClcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgYW5zd2VyID0gYXdhaXQgaW5wdXQoe1xuICAgICAgICBtZXNzYWdlOiAnVGFyZ2V0IGRpcmVjdG9yeScsXG4gICAgICAgIGRlZmF1bHQ6ICdteS1weWxvbidcbiAgICAgIH0pXG4gICAgICB0YXJnZXQgPSBhbnN3ZXJcbiAgICB9XG5cbiAgICBsZXQgcHJvamVjdE5hbWUgPSAnJ1xuXG4gICAgaWYgKHRhcmdldCA9PT0gJy4nKSB7XG4gICAgICBwcm9qZWN0TmFtZSA9IHBhdGguYmFzZW5hbWUocHJvY2Vzcy5jd2QoKSlcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvamVjdE5hbWUgPSBwYXRoLmJhc2VuYW1lKHRhcmdldClcbiAgICB9XG5cbiAgICBjb25zdCBydW50aW1lTmFtZSA9XG4gICAgICBydW50aW1lQXJnIHx8XG4gICAgICAoYXdhaXQgc2VsZWN0KHtcbiAgICAgICAgbWVzc2FnZTogJ1doaWNoIHJ1bnRpbWUgd291bGQgeW91IGxpa2UgdG8gdXNlPycsXG4gICAgICAgIGNob2ljZXM6IHJ1bnRpbWVzLm1hcChydW50aW1lID0+ICh7XG4gICAgICAgICAgbmFtZTogYCR7cnVudGltZS5uYW1lfSAoJHtydW50aW1lLndlYnNpdGV9KWAsXG4gICAgICAgICAgdmFsdWU6IHJ1bnRpbWUua2V5XG4gICAgICAgIH0pKSxcbiAgICAgICAgZGVmYXVsdDogMFxuICAgICAgfSkpXG5cbiAgICBpZiAoIXJ1bnRpbWVOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHJ1bnRpbWUgc2VsZWN0ZWQnKVxuICAgIH1cblxuICAgIGNvbnN0IHJ1bnRpbWUgPSBydW50aW1lcy5maW5kKCh7a2V5fSkgPT4ga2V5ID09PSBydW50aW1lTmFtZSlcblxuICAgIGlmICghcnVudGltZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHJ1bnRpbWUgc2VsZWN0ZWQ6ICR7cnVudGltZU5hbWV9YClcbiAgICB9XG5cbiAgICBjb25zdCB0ZW1wbGF0ZU5hbWUgPVxuICAgICAgdGVtcGxhdGVBcmcgfHxcbiAgICAgIChhd2FpdCBzZWxlY3Qoe1xuICAgICAgICBtZXNzYWdlOiAnV2hpY2ggdGVtcGxhdGUgd291bGQgeW91IGxpa2UgdG8gdXNlPycsXG4gICAgICAgIGNob2ljZXM6IHRlbXBsYXRlc1xuICAgICAgICAgIC5maWx0ZXIodGVtcGxhdGUgPT4gcnVudGltZS50ZW1wbGF0ZXM/LmluY2x1ZGVzKHRlbXBsYXRlLmtleSkpXG4gICAgICAgICAgLm1hcCh0ZW1wbGF0ZSA9PiAoe1xuICAgICAgICAgICAgbmFtZTogdGVtcGxhdGUubmFtZSxcbiAgICAgICAgICAgIHZhbHVlOiB0ZW1wbGF0ZS5rZXlcbiAgICAgICAgICB9KSksXG4gICAgICAgIGRlZmF1bHQ6IDBcbiAgICAgIH0pKVxuXG4gICAgaWYgKCF0ZW1wbGF0ZU5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gdGVtcGxhdGUgc2VsZWN0ZWQnKVxuICAgIH1cblxuICAgIGlmIChmcy5leGlzdHNTeW5jKHRhcmdldCkpIHtcbiAgICAgIGlmIChmcy5yZWFkZGlyU3luYyh0YXJnZXQpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjb25maXJtKHtcbiAgICAgICAgICBtZXNzYWdlOiAnRGlyZWN0b3J5IG5vdCBlbXB0eS4gQ29udGludWU/JyxcbiAgICAgICAgICBkZWZhdWx0OiBmYWxzZVxuICAgICAgICB9KVxuICAgICAgICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KDEpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbWtkaXJwKHRhcmdldClcbiAgICB9XG5cbiAgICBjb25zdCBpbnN0YWxsID1cbiAgICAgIGluc3RhbGxBcmcgfHxcbiAgICAgIChhd2FpdCBjb25maXJtKHttZXNzYWdlOiAnV291bGQgeW91IGxpa2UgdG8gaW5zdGFsbCBkZXBlbmRlbmNpZXM/J30pKVxuXG4gICAgYXdhaXQgY3JlYXRlVGVtcGxhdGUoe1xuICAgICAgbmFtZTogcHJvamVjdE5hbWUsXG4gICAgICBydW50aW1lOiBydW50aW1lTmFtZSxcbiAgICAgIHRlbXBsYXRlOiB0ZW1wbGF0ZU5hbWUsXG4gICAgICB0YXJnZXRcbiAgICB9KVxuXG4gICAgY29uc3QgcGFja2FnZU1hbmFnZXIgPSBkZXRlY3RQYWNrYWdlTWFuYWdlcih7XG4gICAgICBwcmVmZXJyZWRQbTogZ2V0UHJlZmVycmVkUG1CeVJ1bnRpbWUocnVudGltZS5rZXkpLFxuICAgICAgY3dkOiB0YXJnZXRcbiAgICB9KVxuXG4gICAgaWYgKGluc3RhbGwpIHtcbiAgICAgIGF3YWl0IGluc3RhbGxEZXBlbmRlbmNpZXMoe3RhcmdldCwgcGFja2FnZU1hbmFnZXJ9KVxuICAgIH1cblxuICAgIGNvbnN0IGNsaWVudCA9XG4gICAgICBjbGllbnRBcmcgfHxcbiAgICAgIChhd2FpdCBjb25maXJtKHtcbiAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAnV291bGQgeW91IGxpa2UgdG8gZW5hYmxlIGNsaWVudCBnZW5lcmF0aW9uPyAoaHR0cHM6Ly9weWxvbi5jcm9uaXQuaW8vZG9jcy9pbnRlZ3JhdGlvbnMvZ3F0eSknLFxuICAgICAgICBkZWZhdWx0OiBmYWxzZVxuICAgICAgfSkpXG5cbiAgICBsZXQgY2xpZW50Um9vdDogc3RyaW5nID0gJydcbiAgICBsZXQgY2xpZW50UGF0aDogc3RyaW5nID0gJydcbiAgICBsZXQgY2xpZW50UG9ydDogc3RyaW5nID0gJydcblxuICAgIGlmIChjbGllbnQpIHtcbiAgICAgIGlmICghY2xpZW50UGF0aEFyZykge1xuICAgICAgICBjbGllbnRSb290ID0gYXdhaXQgaW5wdXQoe1xuICAgICAgICAgIG1lc3NhZ2U6ICdQYXRoIHRvIHRoZSByb290IHdoZXJlIHRoZSBjbGllbnQgc2hvdWxkIGJlIGdlbmVyYXRlZCcsXG4gICAgICAgICAgZGVmYXVsdDogJy4nXG4gICAgICAgIH0pXG5cbiAgICAgICAgY2xpZW50UGF0aCA9IGF3YWl0IGlucHV0KHtcbiAgICAgICAgICBtZXNzYWdlOiAnUGF0aCB0byBnZW5lcmF0ZSB0aGUgY2xpZW50IHRvJyxcbiAgICAgICAgICBkZWZhdWx0OiBwYXRoLmpvaW4oY2xpZW50Um9vdCwgJ2dxdHkvaW5kZXgudHMnKSxcbiAgICAgICAgICB2YWxpZGF0ZTogdmFsdWUgPT4ge1xuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHBhdGggc3RhcnRzIHdpdGggdGhlIGNsaWVudCByb290ICh0YWtlIGNhcmUgb2YgLilcbiAgICAgICAgICAgIGlmICghdmFsdWUuc3RhcnRzV2l0aChjbGllbnRSb290ID09PSAnLicgPyAnJyA6IGNsaWVudFJvb3QpKSB7XG4gICAgICAgICAgICAgIHJldHVybiAnUGF0aCBtdXN0IHN0YXJ0IHdpdGggdGhlIGNsaWVudCByb290J1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgY2xpZW50UG9ydCA9XG4gICAgICAgIGNsaWVudFBvcnRBcmcgfHxcbiAgICAgICAgKGF3YWl0IGlucHV0KHtcbiAgICAgICAgICBtZXNzYWdlOiAnUG9ydCBvZiB0aGUgcHlsb24gc2VydmVyIHRvIGdlbmVyYXRlIHRoZSBjbGllbnQgZnJvbScsXG4gICAgICAgICAgZGVmYXVsdDogJzMwMDAnXG4gICAgICAgIH0pKVxuXG4gICAgICBjb25zb2xhLnN0YXJ0KGBVcGRhdGluZyBweWxvbiBkZXYgc2NyaXB0IHRvIGdlbmVyYXRlIGNsaWVudGApXG5cbiAgICAgIGxldCBwYWNrYWdlUGF0aDogc3RyaW5nXG4gICAgICBsZXQgc2NyaXB0S2V5OiBzdHJpbmdcbiAgICAgIGlmIChydW50aW1lLmtleSA9PT0gJ2Rlbm8nKSB7XG4gICAgICAgIHBhY2thZ2VQYXRoID0gcGF0aC5qb2luKHRhcmdldCwgJ2Rlbm8uanNvbicpXG4gICAgICAgIHNjcmlwdEtleSA9ICd0YXNrcydcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhY2thZ2VQYXRoID0gcGF0aC5qb2luKHRhcmdldCwgJ3BhY2thZ2UuanNvbicpXG4gICAgICAgIHNjcmlwdEtleSA9ICdzY3JpcHRzJ1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkZXZTY3JpcHQgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhwYWNrYWdlUGF0aCwgJ3V0Zi04JykpXG5cbiAgICAgIGRldlNjcmlwdFtzY3JpcHRLZXldID0ge1xuICAgICAgICAuLi5kZXZTY3JpcHRbc2NyaXB0S2V5XSxcbiAgICAgICAgZGV2OlxuICAgICAgICAgIGRldlNjcmlwdFtzY3JpcHRLZXldLmRldiArXG4gICAgICAgICAgYCAtLWNsaWVudCAtLWNsaWVudC1wb3J0ICR7Y2xpZW50UG9ydH0gLS1jbGllbnQtcGF0aCAke2NsaWVudFBhdGh9YFxuICAgICAgfVxuXG4gICAgICBmcy53cml0ZUZpbGVTeW5jKHBhY2thZ2VQYXRoLCBKU09OLnN0cmluZ2lmeShkZXZTY3JpcHQsIG51bGwsIDIpKVxuXG4gICAgICBjb25zb2xhLnN1Y2Nlc3MoYFB5bG9uIGRldiBzY3JpcHQgdXBkYXRlZGApXG4gICAgfVxuXG4gICAgY29uc3QgcnVuU2NyaXB0ID0gZ2V0UnVuU2NyaXB0KHBhY2thZ2VNYW5hZ2VyKVxuXG4gICAgY29uc3QgbWVzc2FnZSA9IGBcbvCfjokgJHtjaGFsay5ncmVlbi5ib2xkKCdQeWxvbiBjcmVhdGVkIHN1Y2Nlc3NmdWxseS4nKX1cblxu8J+SuyAke2NoYWxrLmN5YW4uYm9sZCgnQ29udGludWUgRGV2ZWxvcGluZycpfVxuICAgICR7Y2hhbGsueWVsbG93KCdDaGFuZ2UgZGlyZWN0b3JpZXM6Jyl9IGNkICR7Y2hhbGsuYmx1ZSh0YXJnZXQpfVxuICAgICR7Y2hhbGsueWVsbG93KCdTdGFydCBkZXYgc2VydmVyOicpfSAke3J1blNjcmlwdH0gZGV2XG4gICAgJHtjaGFsay55ZWxsb3coJ0RlcGxveTonKX0gJHtydW5TY3JpcHR9IGRlcGxveVxuXG7wn5OWICR7Y2hhbGsuY3lhbi5ib2xkKCdFeHBsb3JlIERvY3VtZW50YXRpb24nKX1cbiAgICAke2NoYWxrLnVuZGVybGluZS5ibHVlKCdodHRwczovL3B5bG9uLmNyb25pdC5pby9kb2NzJyl9XG5cbvCfkqwgJHtjaGFsay5jeWFuLmJvbGQoJ0pvaW4gb3VyIENvbW11bml0eScpfVxuICAgICR7Y2hhbGsudW5kZXJsaW5lLmJsdWUoJ2h0dHBzOi8vZGlzY29yZC5nZy9jYkpqa1ZybkhlJyl9XG5gXG5cbiAgICBhd2FpdCB0ZWxlbWV0cnkuc2VuZENyZWF0ZUV2ZW50KHtcbiAgICAgIG5hbWU6IHByb2plY3ROYW1lLFxuICAgICAgcHlsb25DcmVhdGVWZXJzaW9uOiB2ZXJzaW9uLFxuICAgICAgcnVudGltZTogcnVudGltZU5hbWUsXG4gICAgICB0ZW1wbGF0ZTogdGVtcGxhdGVOYW1lLFxuICAgICAgY2xpZW50UGF0aDogY2xpZW50UGF0aCB8fCB1bmRlZmluZWQsXG4gICAgICBjbGllbnRQb3J0OiBwYXJzZUludChjbGllbnRQb3J0KSB8fCB1bmRlZmluZWRcbiAgICB9KVxuXG4gICAgY29uc29sYS5ib3gobWVzc2FnZSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGEuZXJyb3IoZSlcbiAgfVxufVxuXG5wcm9ncmFtLnBhcnNlKClcbiIsCiAgICAiaW1wb3J0ICogYXMgZnMgZnJvbSAnbm9kZTpmcydcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAnbm9kZTpwYXRoJ1xuaW1wb3J0IHByb2Nlc3MgZnJvbSAnbm9kZTpwcm9jZXNzJ1xuaW1wb3J0IHtleGVjU3luY30gZnJvbSAnbm9kZTpjaGlsZF9wcm9jZXNzJ1xuaW1wb3J0IGNvbnNvbGEgZnJvbSAnY29uc29sYSdcblxuLy8gSGVscGVyIGZ1bmN0aW9uIHRvIGNoZWNrIGlmIGEgY29tbWFuZCBleGlzdHNcbmZ1bmN0aW9uIGlzQ29tbWFuZEF2YWlsYWJsZShjb21tYW5kOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICBleGVjU3luYyhgJHtjb21tYW5kfSAtLXZlcnNpb25gLCB7c3RkaW86ICdpZ25vcmUnfSlcbiAgICByZXR1cm4gdHJ1ZVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5lcnJvcihlKVxuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbi8vIERldGVjdCBCdW5cbmZ1bmN0aW9uIGlzQnVuKCk6IGJvb2xlYW4ge1xuICAvLyBAdHMtaWdub3JlOiBCdW4gbWF5IG5vdCBiZSBkZWZpbmVkXG4gIHJldHVybiB0eXBlb2YgQnVuICE9PSAndW5kZWZpbmVkJyAmJiBpc0NvbW1hbmRBdmFpbGFibGUoJ2J1bicpXG59XG5cbi8vIERldGVjdCBucG1cbmZ1bmN0aW9uIGlzTnBtKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gcHJvY2Vzcy5lbnYubnBtX2V4ZWNwYXRoPy5pbmNsdWRlcygnbnBtJykgPz8gZmFsc2Vcbn1cblxuLy8gRGV0ZWN0IFlhcm5cbmZ1bmN0aW9uIGlzWWFybigpOiBib29sZWFuIHtcbiAgcmV0dXJuIHByb2Nlc3MuZW52Lm5wbV9leGVjcGF0aD8uaW5jbHVkZXMoJ3lhcm4nKSA/PyBmYWxzZVxufVxuXG4vLyBEZXRlY3QgRGVub1xuZnVuY3Rpb24gaXNEZW5vKCk6IGJvb2xlYW4ge1xuICAvLyBAdHMtaWdub3JlOiBEZW5vIG1heSBub3QgYmUgZGVmaW5lZFxuICByZXR1cm4gdHlwZW9mIERlbm8gIT09ICd1bmRlZmluZWQnICYmIGlzQ29tbWFuZEF2YWlsYWJsZSgnZGVubycpXG59XG5cbi8vIERldGVjdCBwbnBtXG5mdW5jdGlvbiBpc1BucG0oKTogYm9vbGVhbiB7XG4gIHJldHVybiBwcm9jZXNzLmVudi5ucG1fZXhlY3BhdGg/LmluY2x1ZGVzKCdwbnBtJykgPz8gZmFsc2Vcbn1cblxuLy8gRGV0ZWN0IGJhc2VkIG9uIGxvY2sgZmlsZXNcbmZ1bmN0aW9uIGRldGVjdEJ5TG9ja0ZpbGVzKGN3ZDogc3RyaW5nKTogUGFja2FnZU1hbmFnZXIgfCBudWxsIHtcbiAgaWYgKGZzLmV4aXN0c1N5bmMocGF0aC5qb2luKGN3ZCwgJ2J1bi5sb2NrYicpKSkge1xuICAgIHJldHVybiAnYnVuJ1xuICB9XG4gIGlmIChmcy5leGlzdHNTeW5jKHBhdGguam9pbihjd2QsICdwYWNrYWdlLWxvY2suanNvbicpKSkge1xuICAgIHJldHVybiAnbnBtJ1xuICB9XG4gIGlmIChmcy5leGlzdHNTeW5jKHBhdGguam9pbihjd2QsICd5YXJuLmxvY2snKSkpIHtcbiAgICByZXR1cm4gJ3lhcm4nXG4gIH1cbiAgaWYgKFxuICAgIGZzLmV4aXN0c1N5bmMocGF0aC5qb2luKGN3ZCwgJ2Rlbm8uanNvbicpKSB8fFxuICAgIGZzLmV4aXN0c1N5bmMocGF0aC5qb2luKGN3ZCwgJ2Rlbm8ubG9jaycpKVxuICApIHtcbiAgICByZXR1cm4gJ2Rlbm8nXG4gIH1cbiAgaWYgKGZzLmV4aXN0c1N5bmMocGF0aC5qb2luKGN3ZCwgJ3BucG0tbG9jay55YW1sJykpKSB7XG4gICAgcmV0dXJuICdwbnBtJ1xuICB9XG4gIHJldHVybiBudWxsXG59XG5cbmV4cG9ydCB0eXBlIFBhY2thZ2VNYW5hZ2VyID1cbiAgfCAnYnVuJ1xuICB8ICducG0nXG4gIHwgJ3lhcm4nXG4gIHwgJ3BucG0nXG4gIHwgJ2Rlbm8nXG4gIHwgJ3Vua25vd24nXG5cbi8vIE1haW4gZGV0ZWN0aW9uIGZ1bmN0aW9uXG5leHBvcnQgZnVuY3Rpb24gZGV0ZWN0UGFja2FnZU1hbmFnZXIoe1xuICBwcmVmZXJyZWRQbSxcbiAgY3dkID0gcHJvY2Vzcy5jd2QoKVxufToge1xuICBwcmVmZXJyZWRQbT86IFBhY2thZ2VNYW5hZ2VyXG4gIGN3ZD86IHN0cmluZ1xufSk6IFBhY2thZ2VNYW5hZ2VyIHtcbiAgLy8gQ2hlY2sgdGhlIHByZWZlcnJlZCBwYWNrYWdlIG1hbmFnZXIgZmlyc3RcbiAgaWYgKHByZWZlcnJlZFBtICYmIGlzQ29tbWFuZEF2YWlsYWJsZShwcmVmZXJyZWRQbSkpIHtcbiAgICByZXR1cm4gcHJlZmVycmVkUG1cbiAgfVxuXG4gIC8vIFByb2NlZWQgd2l0aCBkZXRlY3Rpb24gbG9naWNcbiAgaWYgKGlzQnVuKCkpIHtcbiAgICByZXR1cm4gJ2J1bidcbiAgfVxuICBpZiAoaXNOcG0oKSkge1xuICAgIHJldHVybiAnbnBtJ1xuICB9XG4gIGlmIChpc1BucG0oKSkge1xuICAgIHJldHVybiAncG5wbSdcbiAgfVxuICBpZiAoaXNEZW5vKCkpIHtcbiAgICByZXR1cm4gJ2Rlbm8nXG4gIH1cbiAgaWYgKGlzWWFybigpKSB7XG4gICAgcmV0dXJuICd5YXJuJ1xuICB9XG5cbiAgLy8gRmFsbGJhY2sgdG8gbG9jayBmaWxlIGRldGVjdGlvblxuICBjb25zdCBsb2NrRmlsZURldGVjdGlvbiA9IGRldGVjdEJ5TG9ja0ZpbGVzKGN3ZClcbiAgaWYgKGxvY2tGaWxlRGV0ZWN0aW9uKSB7XG4gICAgY29uc29sYS5pbmZvKGBEZXRlY3RlZCBwYWNrYWdlIG1hbmFnZXIgYnkgbG9jayBmaWxlOiAke2xvY2tGaWxlRGV0ZWN0aW9ufWApXG4gICAgaWYgKGlzQ29tbWFuZEF2YWlsYWJsZShsb2NrRmlsZURldGVjdGlvbikpIHtcbiAgICAgIHJldHVybiBsb2NrRmlsZURldGVjdGlvblxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xhLndhcm4oXG4gICAgICAgIGBMb2NrIGZpbGUgZGV0ZWN0ZWQsIGJ1dCAke2xvY2tGaWxlRGV0ZWN0aW9ufSBpcyBub3QgaW5zdGFsbGVkLmBcbiAgICAgIClcbiAgICB9XG4gIH1cblxuICByZXR1cm4gJ3Vua25vd24nXG59XG5cbnR5cGUgUGFja2FnZU1hbmFnZXJTY3JpcHQgPVxuICB8ICdidW4nXG4gIHwgJ25wbSBydW4nXG4gIHwgJ3lhcm4nXG4gIHwgJ3BucG0gcnVuJ1xuICB8ICdkZW5vIHRhc2snXG5cbi8vIFJ1biBzY3JpcHQgZGV0ZWN0aW9uXG5leHBvcnQgZnVuY3Rpb24gZ2V0UnVuU2NyaXB0KHBtOiBQYWNrYWdlTWFuYWdlcik6IFBhY2thZ2VNYW5hZ2VyU2NyaXB0IHtcbiAgc3dpdGNoIChwbSkge1xuICAgIGNhc2UgJ2J1bic6XG4gICAgICByZXR1cm4gJ2J1bidcbiAgICBjYXNlICducG0nOlxuICAgICAgcmV0dXJuICducG0gcnVuJ1xuICAgIGNhc2UgJ3lhcm4nOlxuICAgICAgcmV0dXJuICd5YXJuJ1xuICAgIGNhc2UgJ3BucG0nOlxuICAgICAgcmV0dXJuICdwbnBtIHJ1bidcbiAgICBjYXNlICdkZW5vJzpcbiAgICAgIHJldHVybiAnZGVubyB0YXNrJ1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gcGFja2FnZSBtYW5hZ2VyJylcbiAgfVxufVxuIgogIF0sCiAgIm1hcHBpbmdzIjogIjs7OztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQXFOQTs7O0FDak9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQSxTQUFTLGtCQUFr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QjtBQUFBLE1BQ25DLE1BQU0sT0FBTyxxQkFBcUIsUUFBUSxNQUFNLEtBQUssTUFBTTtBQUFBLE1BQzNELE1BQU0sT0FBTyxtQkFBbUIsS0FBSztBQUFBLE1BQ3JDLE1BQU0sT0FBTyxTQUFTLEtBQUs7QUFBQTtBQUFBLGVBRTdCLE1BQU0sS0FBSyxLQUFLLHVCQUF1QjtBQUFBLE1BQ3JDLE1BQU0sVUFBVSxLQUFLLDhCQUE4QjtBQUFBO0FBQUEsZUFFckQsTUFBTSxLQUFLLEtBQUssb0JBQW9CO0FBQUEsTUFDbEMsTUFBTSxVQUFVLEtBQUssK0JBQStCO0FBQUE7QUFHdEQsVUFBZ0IsMEJBQWdCO0FBQUEsTUFDOUIsTUFBTTtBQUFBLE1BQ04sb0JBQW9CO0FBQUEsTUFDcEIsU0FBUztBQUFBLE1BQ1QsVUFBVTtBQUFBLE1BQ1YsWUFBWSxjQUFjO0FBQUEsTUFDMUIsWUFBWSxTQUFTLFVBQVUsS0FBSztBQUFBLElBQ3RDLENBQUM7QUFFRCxhQUFRLElBQUksT0FBTztBQUFBLFdBQ1osR0FBUDtBQUNBLGFBQVEsTUFBTSxDQUFDO0FBQUE7QUFBQTtBQUluQixRQUFRLE1BQU07IiwKICAiZGVidWdJZCI6ICI0OUZENEFCNTNGNTA3ODI5NjQ3NTZFMjE2NDc1NkUyMSIsCiAgIm5hbWVzIjogW10KfQ==
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-pylon",
3
3
  "type": "module",
4
- "version": "1.0.3",
4
+ "version": "1.1.0",
5
5
  "description": "CLI for creating a Pylon",
6
6
  "scripts": {
7
7
  "build": "bun build ./src/index.ts --target=bun --outdir=./dist --sourcemap=inline --packages external"
@@ -24,7 +24,6 @@
24
24
  "chalk": "^5.3.0",
25
25
  "commander": "^12.1.0",
26
26
  "consola": "^3.2.3",
27
- "detect-package-manager": "^3.0.2",
28
27
  "@getcronit/pylon-telemetry": "^1.0.0"
29
28
  },
30
29
  "engines": {
@@ -5,7 +5,7 @@
5
5
  "type": "module",
6
6
  "description": "Generated with `npm create pylon`",
7
7
  "scripts": {
8
- "dev": "pylon dev -c 'bun run .pylon/index.js'",
8
+ "dev": "pylon dev -c \"bun run .pylon/index.js\"",
9
9
  "build": "pylon build"
10
10
  },
11
11
  "dependencies": {
@@ -4,7 +4,7 @@
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "deploy": "pylon build && wrangler deploy",
7
- "dev": "pylon dev -c 'wrangler dev'",
7
+ "dev": "pylon dev -c \"wrangler dev\"",
8
8
  "cf-typegen": "wrangler types"
9
9
  },
10
10
  "dependencies": {
@@ -0,0 +1,5 @@
1
+ {
2
+ "recommendations": [
3
+ "denoland.vscode-deno"
4
+ ]
5
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "deno.enablePaths": [
3
+ "./"
4
+ ],
5
+ "editor.inlayHints.enabled": "off"
6
+ }
@@ -0,0 +1,12 @@
1
+ FROM denoland/deno
2
+
3
+ EXPOSE 3000
4
+
5
+ WORKDIR /app
6
+
7
+ ADD . /app
8
+
9
+ RUN deno install
10
+ RUN deno task build
11
+
12
+ CMD ["run", "-A", ".pylon/index.js"]
@@ -0,0 +1,15 @@
1
+ {
2
+ "imports": {
3
+ "@getcronit/pylon-dev": "npm:@getcronit/pylon-dev@^1.0.1",
4
+ "@getcronit/pylon": "npm:@getcronit/pylon@^2.2.1"
5
+ },
6
+ "tasks": {
7
+ "dev": "pylon dev -c 'deno run -A .pylon/index.js --config tsconfig.json'",
8
+ "build": "pylon build"
9
+ },
10
+ "compilerOptions": {
11
+ "jsx": "precompile",
12
+ "jsxImportSource": "hono/jsx"
13
+ },
14
+ "nodeModulesDir": "auto"
15
+ }
@@ -0,0 +1,17 @@
1
+ import {app} from '@getcronit/pylon'
2
+
3
+ export const graphql = {
4
+ Query: {
5
+ hello: () => {
6
+ return 'Hello, world!'
7
+ }
8
+ },
9
+ Mutation: {}
10
+ }
11
+
12
+ Deno.serve(
13
+ {
14
+ port: 3000
15
+ },
16
+ app.fetch
17
+ )
@@ -5,7 +5,7 @@
5
5
  "type": "module",
6
6
  "description": "Generated with `npm create pylon`",
7
7
  "scripts": {
8
- "dev": "pylon dev -c 'node --enable-source-maps .pylon/index.js'",
8
+ "dev": "pylon dev -c \"node --enable-source-maps .pylon/index.js\"",
9
9
  "build": "pylon build"
10
10
  },
11
11
  "dependencies": {