gitlab-ci-local 4.65.1 → 4.66.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/package.json CHANGED
@@ -2,26 +2,26 @@
2
2
  "type": "module",
3
3
  "name": "gitlab-ci-local",
4
4
  "description": "Tired of pushing to test your .gitlab-ci.yml?",
5
- "main": "src/index.js",
6
- "bin": "src/index.js",
7
- "version": "4.65.1",
5
+ "main": "dist/index.js",
6
+ "bin": "dist/index.js",
7
+ "version": "4.66.0",
8
8
  "scripts": {
9
- "esbuild": "esbuild src/index.ts --outfile=bin/index.cjs --bundle --platform=node --format=cjs --minify --external:yargs --sourcemap=inline",
10
- "pkg-linux": "pkg bin/index.cjs --public --options=enable-source-maps --no-bytecode -t linux-x64 -o bin/linux/gitlab-ci-local && chmod +x bin/linux/gitlab-ci-local && gzip -c bin/linux/gitlab-ci-local > bin/linux.gz",
11
- "pkg-macos": "pkg bin/index.cjs --public --options=enable-source-maps --no-bytecode -t macos-x64 -o bin/macos/gitlab-ci-local && gzip -c bin/macos/gitlab-ci-local > bin/macos.gz",
12
- "pkg-win": "pkg bin/index.cjs --public --options=enable-source-maps --no-bytecode -t win-x64 -o bin/win/gitlab-ci-local && gzip -c bin/win/gitlab-ci-local.exe > bin/win.gz",
13
- "pkg-all": "npm run pkg-linux && npm run pkg-macos && npm run pkg-win && npm ci",
14
- "cleanup": "git clean -fX tests/ && git clean -fX src/",
15
- "build": " npm run cleanup && tsc",
16
- "check-all": "npm run build && npm run lint && npm run coverage && npm run audit",
17
- "audit": "npm audit --parseable",
18
- "lint": "npx eslint .",
19
- "test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --testTimeout 60000",
20
- "test-except-dind": "npm run test -- --testPathIgnorePatterns=\"/dind.*/|/node_modules/|/.gitlab-ci-local/\"",
21
- "coverage": "npm run build && FORCE_COLOR=1 npm run test -- --coverage --verbose",
22
- "start": "tsx src/index.ts --cwd examples/docker-compose-nodejs",
23
- "dev": "touch .gitlab-ci.yml && nodemon -e ts --watch src --watch .gitlab-ci.yml --exec \"tsc --noEmit && tsx src/index.ts\"",
24
- "fetch-and-patch-schema": "curl https://gitlab.com/gitlab-org/gitlab/-/raw/master/app/assets/javascripts/editor/schema/ci.json -sf | jq 'del(.. | .pattern?)' > src/schema/schema.json"
9
+ "build": "bun build --compile --minify --sourcemap src/index.ts --outfile bin/gitlab-ci-local",
10
+ "build:linux-amd64": "bun build --compile --minify --sourcemap --target=bun-linux-x64 src/index.ts --outfile bin/linux-amd64/gitlab-ci-local",
11
+ "build:linux-arm64": "bun build --compile --minify --sourcemap --target=bun-linux-arm64 src/index.ts --outfile bin/linux-arm64/gitlab-ci-local",
12
+ "build:macos-x64": "bun build --compile --minify --sourcemap --target=bun-darwin-x64 src/index.ts --outfile bin/macos-x64/gitlab-ci-local",
13
+ "build:macos-arm64": "bun build --compile --minify --sourcemap --target=bun-darwin-arm64 src/index.ts --outfile bin/macos-arm64/gitlab-ci-local",
14
+ "build:win": "bun build --compile --minify --sourcemap --target=bun-windows-x64 src/index.ts --outfile bin/win/gitlab-ci-local.exe",
15
+ "build:node": "bun build --minify --sourcemap=linked src/index.ts --outdir dist --target=node",
16
+ "build-all": "bun run build:linux-amd64 && bun run build:linux-arm64 && bun run build:win && bun run build:macos-x64 && bun run build:macos-arm64",
17
+ "check-all": "bun run lint && bun run coverage",
18
+ "lint": "eslint .",
19
+ "test": "FORCE_COLOR=1 bun test --timeout 60000",
20
+ "test-except-dind": "bun test --timeout 60000 --filter '(?!.*dind)'",
21
+ "coverage": "FORCE_COLOR=1 bun test --timeout 60000 --coverage --coverage-reporter=text --coverage-reporter=lcov --verbose",
22
+ "start": "bun src/index.ts --cwd examples/docker-compose-nodejs",
23
+ "typecheck": "tsc --noEmit",
24
+ "fetch-schema": "curl https://gitlab.com/gitlab-org/gitlab/-/raw/master/app/assets/javascripts/editor/schema/ci.json -sf > src/schema.json"
25
25
  },
26
26
  "dependencies": {
27
27
  "ajv": "8.x.x",
@@ -46,82 +46,28 @@
46
46
  "semver": "7.x.x",
47
47
  "split2": "4.x.x",
48
48
  "terminal-link": "5.x.x",
49
- "yargs": "17.x.x"
49
+ "yargs": "18.x"
50
50
  },
51
51
  "devDependencies": {
52
- "@eslint/js": "9.x.x",
53
- "@stylistic/eslint-plugin-js": "4.x.x",
54
- "@stylistic/eslint-plugin-ts": "4.x.x",
52
+ "@eslint/js": "10.x",
53
+ "@stylistic/eslint-plugin": "5.x",
55
54
  "@types/base64url": "2.x.x",
55
+ "@types/bun": "1.x.x",
56
56
  "@types/checksum": "0.1.x",
57
57
  "@types/deep-extend": "0.6.x",
58
58
  "@types/fs-extra": "11.x.x",
59
- "@types/jest-when": "3.x.x",
60
59
  "@types/js-yaml": "4.x.x",
61
60
  "@types/micromatch": "4.x.x",
62
- "@types/node": "24.x.x",
63
61
  "@types/pretty-hrtime": "1.x.x",
64
62
  "@types/semver": "7.x.x",
65
63
  "@types/split2": "4.x.x",
66
64
  "@types/yargs": "17.x.x",
67
- "@yao-pkg/pkg": "6.x.x",
68
65
  "axios-mock-adapter": "2.x",
69
66
  "depcheck": "1.x.x",
70
- "esbuild": "0.27.x",
71
- "eslint": "9.x.x",
72
- "jest": "30.x.x",
73
- "jest-when": "3.x.x",
74
- "nodemon": "3.x.x",
75
- "ts-jest": "29.x.x",
76
- "tsx": "4.x.x",
67
+ "eslint": "10.x",
77
68
  "typescript": "5.x.x",
78
69
  "typescript-eslint": "8.x.x"
79
70
  },
80
- "engines": {
81
- "node": ">=18"
82
- },
83
- "pkg": {
84
- "assets": [
85
- "package.json",
86
- "**/src/schema/schema.json"
87
- ],
88
- "scripts": [
89
- "src/**/*.js"
90
- ]
91
- },
92
- "jest": {
93
- "extensionsToTreatAsEsm": [
94
- ".ts"
95
- ],
96
- "transform": {
97
- "^.+\\.tsx?$": [
98
- "ts-jest",
99
- {
100
- "useESM": true
101
- }
102
- ],
103
- "^.+\\.jsx?$": "babel-jest"
104
- },
105
- "preset": "ts-jest",
106
- "testMatch": [
107
- "**/*.test.ts"
108
- ],
109
- "coveragePathIgnorePatterns": [
110
- "<rootDir>/scripts"
111
- ],
112
- "testPathIgnorePatterns": [
113
- "/node_modules/",
114
- "/.gitlab-ci-local/"
115
- ],
116
- "moduleNameMapper": {
117
- "(.+)\\.js": "$1"
118
- },
119
- "coverageReporters": [
120
- "lcov",
121
- "json-summary",
122
- "text-summary"
123
- ]
124
- },
125
71
  "repository": {
126
72
  "type": "git",
127
73
  "url": "https://github.com/firecow/gitlab-ci-local.git"
@@ -145,7 +91,7 @@
145
91
  "gitlab-ci"
146
92
  ],
147
93
  "files": [
148
- "src/**/*.js",
149
- "src/**/*.json"
94
+ "dist/index.js",
95
+ "dist/index.js.map"
150
96
  ]
151
97
  }
package/src/argv.js DELETED
@@ -1,307 +0,0 @@
1
- import assert from "assert";
2
- import fs from "fs-extra";
3
- import * as dotenv from "dotenv";
4
- import * as path from "path";
5
- import camelCase from "camelcase";
6
- import { Utils } from "./utils.js";
7
- import chalkBase from "chalk";
8
- import chalk from "chalk-template";
9
- async function isInGitRepository() {
10
- try {
11
- await Utils.spawn(["git", "rev-parse", "--is-inside-work-tree"]);
12
- return true;
13
- }
14
- catch {
15
- return false;
16
- }
17
- }
18
- async function gitRootPath() {
19
- const { stdout } = await Utils.spawn(["git", "rev-parse", "--show-toplevel"]);
20
- return stdout;
21
- }
22
- export class Argv {
23
- static default = {
24
- "variablesFile": ".gitlab-ci-local-variables.yml",
25
- "evaluateRuleChanges": true,
26
- "ignoreSchemaPaths": [],
27
- "ignorePredefinedVars": "",
28
- };
29
- map = new Map();
30
- writeStreams;
31
- async fallbackCwd(args) {
32
- if (args.cwd !== undefined || args.file !== undefined)
33
- return;
34
- if (fs.existsSync(`${process.cwd()}/.gitlab-ci.yml`))
35
- return;
36
- if (!(await isInGitRepository()))
37
- return;
38
- this.writeStreams?.stderr(chalk `{yellow .gitlab-ci.yml not found in cwd, falling back to git root directory}\n`);
39
- this.map.set("cwd", path.relative(process.cwd(), await gitRootPath()));
40
- }
41
- static async build(args, writeStreams) {
42
- const argv = new Argv(args, writeStreams);
43
- await argv.fallbackCwd(args);
44
- argv.injectDotenv(`${argv.home}/.gitlab-ci-local/.env`, args);
45
- argv.injectDotenv(`${argv.cwd}/.gitlab-ci-local-env`, args);
46
- if (!argv.shellExecutorNoImage && argv.shellIsolation) {
47
- writeStreams?.stderr(chalk `{black.bgYellowBright WARN } --shell-isolation does not work with --no-shell-executor-no-image\n`);
48
- }
49
- if (argv.defaultImageExplicitlySet && argv.shellIsolation) {
50
- writeStreams?.stderr(chalk `{black.bgYellowBright WARN } --default-image does not work with --shell-isolation=true\n`);
51
- }
52
- if (argv.defaultImageExplicitlySet && argv.shellExecutorNoImage) {
53
- writeStreams?.stderr(chalk `{black.bgYellowBright WARN } --default-image does not work with --shell-executor-no-image=true\n`);
54
- }
55
- if (argv.defaultImageExplicitlySet && argv.forceShellExecutor) {
56
- writeStreams?.stderr(chalk `{black.bgYellowBright WARN } --default-image does not work with --force-shell-executor=true\n`);
57
- }
58
- return argv;
59
- }
60
- constructor(argv, writeStreams) {
61
- if (argv.noColor) {
62
- chalkBase.level = 0;
63
- }
64
- this.writeStreams = writeStreams;
65
- for (const [key, value] of Object.entries(argv)) {
66
- this.map.set(key, value);
67
- }
68
- }
69
- injectDotenv(potentialDotenvFilepath, argv) {
70
- if (fs.existsSync(potentialDotenvFilepath)) {
71
- const config = dotenv.parse(fs.readFileSync(potentialDotenvFilepath));
72
- for (const [key, value] of Object.entries(config)) {
73
- const argKey = camelCase(key);
74
- // Special handle KEY=VALUE variable keys
75
- if (argKey === "variable") {
76
- let currentVal = argv[argKey];
77
- if (currentVal == null) {
78
- currentVal = [];
79
- this.map.set(argKey, currentVal);
80
- }
81
- if (!Array.isArray(currentVal)) {
82
- continue;
83
- }
84
- for (const pair of value.split(" ")) {
85
- currentVal.unshift(pair);
86
- }
87
- }
88
- else if (argv[argKey] == null) {
89
- // Work around `dotenv.parse` limitation https://github.com/motdotla/dotenv/issues/51#issuecomment-552559070
90
- if (value === "true")
91
- this.map.set(argKey, true);
92
- else if (value === "false")
93
- this.map.set(argKey, false);
94
- else if (value === "null")
95
- this.map.set(argKey, null);
96
- else if (!isNaN(Number(value)))
97
- this.map.set(argKey, Number(value));
98
- else
99
- this.map.set(argKey, value);
100
- }
101
- }
102
- }
103
- }
104
- get cwd() {
105
- let cwd = this.map.get("cwd") ?? ".";
106
- assert(typeof cwd != "object", "--cwd option cannot be an array");
107
- assert(!path.isAbsolute(cwd), "Please use relative path for the --cwd option");
108
- cwd = path.normalize(`${process.cwd()}/${cwd}`);
109
- cwd = cwd.replace(/\/$/, "");
110
- assert(fs.pathExistsSync(cwd), `${cwd} is not a directory`);
111
- return cwd;
112
- }
113
- get variablesFile() {
114
- return this.map.get("variablesFile") ?? Argv.default.variablesFile;
115
- }
116
- get evaluateRuleChanges() {
117
- return this.map.get("evaluateRuleChanges") ?? Argv.default.evaluateRuleChanges;
118
- }
119
- get file() {
120
- return this.map.get("file") ?? ".gitlab-ci.yml";
121
- }
122
- get stateDir() {
123
- return (this.map.get("stateDir") ?? ".gitlab-ci-local").replace(/\/$/, "");
124
- }
125
- get home() {
126
- return (this.map.get("home") ?? process.env.HOME ?? "").replace(/\/$/, "");
127
- }
128
- get volume() {
129
- const val = this.map.get("volume") ?? [];
130
- return typeof val == "string" ? val.split(" ") : val;
131
- }
132
- get network() {
133
- const val = this.map.get("network") ?? [];
134
- return typeof val == "string" ? val.split(" ") : val;
135
- }
136
- get extraHost() {
137
- const val = this.map.get("extraHost") ?? [];
138
- return typeof val == "string" ? val.split(" ") : val;
139
- }
140
- get caFile() {
141
- return this.map.get("caFile") ?? null;
142
- }
143
- get ignoreSchemaPaths() {
144
- return this.map.get("ignoreSchemaPaths") ?? Argv.default.ignoreSchemaPaths;
145
- }
146
- get ignorePredefinedVars() {
147
- return this.map.get("ignorePredefinedVars") ?? Argv.default.ignorePredefinedVars;
148
- }
149
- get pullPolicy() {
150
- return this.map.get("pullPolicy") ?? "if-not-present";
151
- }
152
- get remoteVariables() {
153
- const val = this.map.get("remoteVariables") ?? [];
154
- return typeof val == "string" ? val.split(" ") : val;
155
- }
156
- get variable() {
157
- const val = this.map.get("variable");
158
- const variables = {};
159
- const pairs = typeof val == "string" ? val.split(" ") : val;
160
- (pairs ?? []).forEach((variablePair) => {
161
- const exec = /(?<key>\w*?)(=)(?<value>(.|\n|\r)*)/.exec(variablePair);
162
- if (exec?.groups?.key) {
163
- variables[exec.groups.key] = exec?.groups?.value;
164
- }
165
- });
166
- return variables;
167
- }
168
- get unsetVariables() {
169
- return this.map.get("unsetVariable") ?? [];
170
- }
171
- get manual() {
172
- const val = this.map.get("manual") ?? [];
173
- return typeof val == "string" ? val.split(" ") : val;
174
- }
175
- get job() {
176
- return this.map.get("job") ?? [];
177
- }
178
- get autoCompleting() {
179
- return this.map.get("autoCompleting") ?? false;
180
- }
181
- get cleanup() {
182
- return this.map.get("cleanup") ?? true;
183
- }
184
- get quiet() {
185
- return this.map.get("quiet") ?? false;
186
- }
187
- get umask() {
188
- // TODO: default to false in 5.x.x
189
- return this.map.get("umask") ?? true;
190
- }
191
- get userns() {
192
- return this.map.get("userns");
193
- }
194
- get privileged() {
195
- return this.map.get("privileged") ?? false;
196
- }
197
- get device() {
198
- const val = this.map.get("device") ?? [];
199
- return typeof val == "string" ? val.split(" ") : val;
200
- }
201
- get ulimit() {
202
- const ulimit = this.map.get("ulimit");
203
- if (!ulimit)
204
- return null;
205
- return ulimit;
206
- }
207
- get needs() {
208
- return this.map.get("needs") ?? false;
209
- }
210
- get onlyNeeds() {
211
- return this.map.get("onlyNeeds") ?? false;
212
- }
213
- get stage() {
214
- return this.map.get("stage") ?? null;
215
- }
216
- get completion() {
217
- return this.map.get("completion") ?? false;
218
- }
219
- get list() {
220
- return this.map.get("list") ?? false;
221
- }
222
- get listAll() {
223
- return this.map.get("listAll") ?? false;
224
- }
225
- get listJson() {
226
- return this.map.get("listJson") ?? false;
227
- }
228
- get listCsv() {
229
- return this.map.get("listCsv") ?? false;
230
- }
231
- get listCsvAll() {
232
- return this.map.get("listCsvAll") ?? false;
233
- }
234
- get preview() {
235
- return this.map.get("preview") ?? false;
236
- }
237
- get validateDependencyChain() {
238
- return this.map.get("validateDependencyChain") ?? false;
239
- }
240
- get shellIsolation() {
241
- // TODO: default to true in 5.x.x
242
- return this.map.get("shellIsolation") ?? false;
243
- }
244
- get fetchIncludes() {
245
- return this.map.get("fetchIncludes") ?? false;
246
- }
247
- get mountCache() {
248
- return this.map.get("mountCache") ?? false;
249
- }
250
- get artifactsToSource() {
251
- // TODO: default to false in 5.x.x
252
- return this.map.get("artifactsToSource") ?? true;
253
- }
254
- get showTimestamps() {
255
- return this.map.get("timestamps") ?? false;
256
- }
257
- get maxJobNamePadding() {
258
- return this.map.get("maxJobNamePadding") ?? null;
259
- }
260
- get containerMacAddress() {
261
- return this.map.get("containerMacAddress") ?? null;
262
- }
263
- get containerEmulate() {
264
- return this.map.get("containerEmulate") ?? null;
265
- }
266
- get concurrency() {
267
- const concurrency = this.map.get("concurrency");
268
- if (!concurrency)
269
- return null;
270
- return Number(concurrency);
271
- }
272
- get containerExecutable() {
273
- return this.map.get("containerExecutable") ?? "docker";
274
- }
275
- get jsonSchemaValidation() {
276
- return this.map.get("jsonSchemaValidation") ?? true;
277
- }
278
- get shellExecutorNoImage() {
279
- // TODO: default to false in 5.x.x
280
- return this.map.get("shellExecutorNoImage") ?? true;
281
- }
282
- get forceShellExecutor() {
283
- return this.map.get("forceShellExecutor") ?? false;
284
- }
285
- get defaultImage() {
286
- return this.map.get("defaultImage") ?? "docker.io/ruby:3.1";
287
- }
288
- get waitImage() {
289
- return this.map.get("waitImage") ?? "docker.io/sumina46/wait-for-it:latest";
290
- }
291
- get helperImage() {
292
- return this.map.get("helperImage") ?? "docker.io/firecow/gitlab-ci-local-util:latest";
293
- }
294
- get defaultImageExplicitlySet() {
295
- return this.map.get("defaultImage") ?? false;
296
- }
297
- get maximumIncludes() {
298
- return this.map.get("maximumIncludes") ?? 150; // https://docs.gitlab.com/ee/administration/settings/continuous_integration.html#maximum-includes
299
- }
300
- get childPipelineDepth() {
301
- return this.map.get("childPipelineDepth");
302
- }
303
- get registry() {
304
- return this.map.get("registry") ?? false;
305
- }
306
- }
307
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJndi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImFyZ3YudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMxQixPQUFPLEtBQUssTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUNqQyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLFNBQVMsTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxFQUFDLEtBQUssRUFBQyxNQUFNLFlBQVksQ0FBQztBQUVqQyxPQUFPLFNBQVMsTUFBTSxPQUFPLENBQUM7QUFDOUIsT0FBTyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFFbkMsS0FBSyxVQUFVLGlCQUFpQjtJQUM1QixJQUFJLENBQUM7UUFDRCxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLHVCQUF1QixDQUFDLENBQUMsQ0FBQztRQUNqRSxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ0wsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztBQUNMLENBQUM7QUFFRCxLQUFLLFVBQVUsV0FBVztJQUN0QixNQUFNLEVBQUMsTUFBTSxFQUFDLEdBQUcsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7SUFDNUUsT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQztBQUVELE1BQU0sT0FBTyxJQUFJO0lBQ2IsTUFBTSxDQUFVLE9BQU8sR0FBRztRQUN0QixlQUFlLEVBQUUsZ0NBQWdDO1FBQ2pELHFCQUFxQixFQUFFLElBQUk7UUFDM0IsbUJBQW1CLEVBQUUsRUFBRTtRQUN2QixzQkFBc0IsRUFBRSxFQUFFO0tBQzdCLENBQUM7SUFFRixHQUFHLEdBQXFCLElBQUksR0FBRyxFQUFlLENB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QkFBa0I7UUFDbEIsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDUixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssQ0FBQztJQUM3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzLWV4dHJhXCI7XG5pbXBvcnQgKiBhcyBkb3RlbnYgZnJvbSBcImRvdGVudlwiO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IGNhbWVsQ2FzZSBmcm9tIFwiY2FtZWxjYXNlXCI7XG5pbXBvcnQge1V0aWxzfSBmcm9tIFwiLi91dGlscy5qc1wiO1xuaW1wb3J0IHtXcml0ZVN0cmVhbXN9IGZyb20gXCIuL3dyaXRlLXN0cmVhbXMuanNcIjtcbmltcG9ydCBjaGFsa0Jhc2UgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrLXRlbXBsYXRlXCI7XG5cbmFzeW5jIGZ1bmN0aW9uIGlzSW5HaXRSZXBvc2l0b3J5ICgpIHtcbiAgICB0cnkge1xuICAgICAgICBhd2FpdCBVdGlscy5zcGF3bihbXCJnaXRcIiwgXCJyZXYtcGFyc2VcIiwgXCItLWlzLWluc2lkZS13b3JrLXRyZWVcIl0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2l0Um9vdFBhdGggKCkge1xuICAgIGNvbnN0IHtzdGRvdXR9ID0gYXdhaXQgVXRpbHMuc3Bhd24oW1wiZ2l0XCIsIFwicmV2LXBhcnNlXCIsIFwiLS1zaG93LXRvcGxldmVsXCJdKTtcbiAgICByZXR1cm4gc3Rkb3V0O1xufVxuXG5leHBvcnQgY2xhc3MgQXJndiB7XG4gICAgc3RhdGljIHJlYWRvbmx5IGRlZmF1bHQgPSB7XG4gICAgICAgIFwidmFyaWFibGVzRmlsZVwiOiBcIi5naXRsYWItY2ktbG9jYWwtdmFyaWFibGVzLnltbFwiLFxuICAgICAgICBcImV2YWx1YXRlUnVsZUNoYW5nZXNcIjogdHJ1ZSxcbiAgICAgICAgXCJpZ25vcmVTY2hlbWFQYXRoc1wiOiBbXSxcbiAgICAgICAgXCJpZ25vcmVQcmVkZWZpbmVkVmFyc1wiOiBcIlwiLFxuICAgIH07XG5cbiAgICBtYXA6IE1hcDxzdHJpbmcsIGFueT4gPSBuZXcgTWFwPHN0cmluZywgYW55PigpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgd3JpdGVTdHJlYW1zOiBXcml0ZVN0cmVhbXMgfCB1bmRlZmluZWQ7XG5cbiAgICBwcml2YXRlIGFzeW5jIGZhbGxiYWNrQ3dkIChhcmdzOiBhbnkpIHtcbiAgICAgICAgaWYgKGFyZ3MuY3dkICE9PSB1bmRlZmluZWQgfHwgYXJncy5maWxlICE9PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoYCR7cHJvY2Vzcy5jd2QoKX0vLmdpdGxhYi1jaS55bWxgKSkgcmV0dXJuO1xuICAgICAgICBpZiAoIShhd2FpdCBpc0luR2l0UmVwb3NpdG9yeSgpKSkgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMud3JpdGVTdHJlYW1zPy5zdGRlcnIoY2hhbGtge3llbGxvdyAuZ2l0bGFiLWNpLnltbCBub3QgZm91bmQgaW4gY3dkLCBmYWxsaW5nIGJhY2sgdG8gZ2l0IHJvb3QgZGlyZWN0b3J5fVxcbmApO1xuICAgICAgICB0aGlzLm1hcC5zZXQoXCJjd2RcIiwgcGF0aC5yZWxhdGl2ZShwcm9jZXNzLmN3ZCgpLCBhd2FpdCBnaXRSb290UGF0aCgpKSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGFzeW5jIGJ1aWxkIChhcmdzOiBhbnksIHdyaXRlU3RyZWFtcz86IFdyaXRlU3RyZWFtcykge1xuICAgICAgICBjb25zdCBhcmd2ID0gbmV3IEFyZ3YoYXJncywgd3JpdGVTdHJlYW1zKTtcbiAgICAgICAgYXdhaXQgYXJndi5mYWxsYmFja0N3ZChhcmdzKTtcblxuICAgICAgICBhcmd2LmluamVjdERvdGVudihgJHthcmd2LmhvbWV9Ly5naXRsYWItY2ktbG9jYWwvLmVudmAsIGFyZ3MpO1xuICAgICAgICBhcmd2LmluamVjdERvdGVudihgJHthcmd2LmN3ZH0vLmdpdGxhYi1jaS1sb2NhbC1lbnZgLCBhcmdzKTtcblxuICAgICAgICBpZiAoIWFyZ3Yuc2hlbGxFeGVjdXRvck5vSW1hZ2UgJiYgYXJndi5zaGVsbElzb2xhdGlvbikge1xuICAgICAgICAgICAgd3JpdGVTdHJlYW1zPy5zdGRlcnIoY2hhbGtge2JsYWNrLmJnWWVsbG93QnJpZ2h0ICBXQVJOIH0gLS1zaGVsbC1pc29sYXRpb24gZG9lcyBub3Qgd29yayB3aXRoIC0tbm8tc2hlbGwtZXhlY3V0b3Itbm8taW1hZ2VcXG5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhcmd2LmRlZmF1bHRJbWFnZUV4cGxpY2l0bHlTZXQgJiYgYXJndi5zaGVsbElzb2xhdGlvbikge1xuICAgICAgICAgICAgd3JpdGVTdHJlYW1zPy5zdGRlcnIoY2hhbGtge2JsYWNrLmJnWWVsbG93QnJpZ2h0ICBXQVJOIH0gLS1kZWZhdWx0LWltYWdlIGRvZXMgbm90IHdvcmsgd2l0aCAtLXNoZWxsLWlzb2xhdGlvbj10cnVlXFxuYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYXJndi5kZWZhdWx0SW1hZ2VFeHBsaWNpdGx5U2V0ICYmIGFyZ3Yuc2hlbGxFeGVjdXRvck5vSW1hZ2UpIHtcbiAgICAgICAgICAgIHdyaXRlU3RyZWFtcz8uc3RkZXJyKGNoYWxrYHtibGFjay5iZ1llbGxvd0JyaWdodCAgV0FSTiB9IC0tZGVmYXVsdC1pbWFnZSBkb2VzIG5vdCB3b3JrIHdpdGggLS1zaGVsbC1leGVjdXRvci1uby1pbWFnZT10cnVlXFxuYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYXJndi5kZWZhdWx0SW1hZ2VFeHBsaWNpdGx5U2V0ICYmIGFyZ3YuZm9yY2VTaGVsbEV4ZWN1dG9yKSB7XG4gICAgICAgICAgICB3cml0ZVN0cmVhbXM/LnN0ZGVycihjaGFsa2B7YmxhY2suYmdZZWxsb3dCcmlnaHQgIFdBUk4gfSAtLWRlZmF1bHQtaW1hZ2UgZG9lcyBub3Qgd29yayB3aXRoIC0tZm9yY2Utc2hlbGwtZXhlY3V0b3I9dHJ1ZVxcbmApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFyZ3Y7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvciAoYXJndjogYW55LCB3cml0ZVN0cmVhbXM/OiBXcml0ZVN0cmVhbXMpIHtcbiAgICAgICAgaWYgKGFyZ3Yubm9Db2xvcikge1xuICAgICAgICAgICAgY2hhbGtCYXNlLmxldmVsID0gMDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLndyaXRlU3RyZWFtcyA9IHdyaXRlU3RyZWFtcztcbiAgICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoYXJndikpIHtcbiAgICAgICAgICAgIHRoaXMubWFwLnNldChrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5qZWN0RG90ZW52IChwb3RlbnRpYWxEb3RlbnZGaWxlcGF0aDogc3RyaW5nLCBhcmd2OiBhbnkpIHtcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMocG90ZW50aWFsRG90ZW52RmlsZXBhdGgpKSB7XG4gICAgICAgICAgICBjb25zdCBjb25maWcgPSBkb3RlbnYucGFyc2UoZnMucmVhZEZpbGVTeW5jKHBvdGVudGlhbERvdGVudkZpbGVwYXRoKSk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhjb25maWcpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYXJnS2V5ID0gY2FtZWxDYXNlKGtleSk7XG5cbiAgICAgICAgICAgICAgICAvLyBTcGVjaWFsIGhhbmRsZSBLRVk9VkFMVUUgdmFyaWFibGUga2V5c1xuICAgICAgICAgICAgICAgIGlmIChhcmdLZXkgPT09IFwidmFyaWFibGVcIikge1xuICAgICAgICAgICAgICAgICAgICBsZXQgY3VycmVudFZhbCA9IGFyZ3ZbYXJnS2V5XTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRWYWwgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudFZhbCA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXAuc2V0KGFyZ0tleSwgY3VycmVudFZhbCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGN1cnJlbnRWYWwpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgdmFsdWUuc3BsaXQoXCIgXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50VmFsLnVuc2hpZnQocGFpcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFyZ3ZbYXJnS2V5XSA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdvcmsgYXJvdW5kIGBkb3RlbnYucGFyc2VgIGxpbWl0YXRpb24gaHR0cHM6Ly9naXRodWIuY29tL21vdGRvdGxhL2RvdGVudi9pc3N1ZXMvNTEjaXNzdWVjb21tZW50LTU1MjU1OTA3MFxuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IFwidHJ1ZVwiKSB0aGlzLm1hcC5zZXQoYXJnS2V5LCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT09IFwiZmFsc2VcIikgdGhpcy5tYXAuc2V0KGFyZ0tleSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PT0gXCJudWxsXCIpIHRoaXMubWFwLnNldChhcmdLZXksIG51bGwpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghaXNOYU4oTnVtYmVyKHZhbHVlKSkpIHRoaXMubWFwLnNldChhcmdLZXksIE51bWJlcih2YWx1ZSkpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIHRoaXMubWFwLnNldChhcmdLZXksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgY3dkICgpOiBzdHJpbmcge1xuICAgICAgICBsZXQgY3dkID0gdGhpcy5tYXAuZ2V0KFwiY3dkXCIpID8/IFwiLlwiO1xuICAgICAgICBhc3NlcnQodHlwZW9mIGN3ZCAhPSBcIm9iamVjdFwiLCBcIi0tY3dkIG9wdGlvbiBjYW5ub3QgYmUgYW4gYXJyYXlcIik7XG4gICAgICAgIGFzc2VydCghcGF0aC5pc0Fic29sdXRlKGN3ZCksIFwiUGxlYXNlIHVzZSByZWxhdGl2ZSBwYXRoIGZvciB0aGUgLS1jd2Qgb3B0aW9uXCIpO1xuICAgICAgICBjd2QgPSBwYXRoLm5vcm1hbGl6ZShgJHtwcm9jZXNzLmN3ZCgpfS8ke2N3ZH1gKTtcbiAgICAgICAgY3dkID0gY3dkLnJlcGxhY2UoL1xcLyQvLCBcIlwiKTtcbiAgICAgICAgYXNzZXJ0KGZzLnBhdGhFeGlzdHNTeW5jKGN3ZCksIGAke2N3ZH0gaXMgbm90IGEgZGlyZWN0b3J5YCk7XG4gICAgICAgIHJldHVybiBjd2Q7XG4gICAgfVxuXG4gICAgZ2V0IHZhcmlhYmxlc0ZpbGUgKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJ2YXJpYWJsZXNGaWxlXCIpID8/IEFyZ3YuZGVmYXVsdC52YXJpYWJsZXNGaWxlO1xuICAgIH1cblxuICAgIGdldCBldmFsdWF0ZVJ1bGVDaGFuZ2VzICgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImV2YWx1YXRlUnVsZUNoYW5nZXNcIikgPz8gQXJndi5kZWZhdWx0LmV2YWx1YXRlUnVsZUNoYW5nZXM7XG4gICAgfVxuXG4gICAgZ2V0IGZpbGUgKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJmaWxlXCIpID8/IFwiLmdpdGxhYi1jaS55bWxcIjtcbiAgICB9XG5cbiAgICBnZXQgc3RhdGVEaXIgKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiAodGhpcy5tYXAuZ2V0KFwic3RhdGVEaXJcIikgPz8gXCIuZ2l0bGFiLWNpLWxvY2FsXCIpLnJlcGxhY2UoL1xcLyQvLCBcIlwiKTtcbiAgICB9XG5cbiAgICBnZXQgaG9tZSAoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLm1hcC5nZXQoXCJob21lXCIpID8/IHByb2Nlc3MuZW52LkhPTUUgPz8gXCJcIikucmVwbGFjZSgvXFwvJC8sIFwiXCIpO1xuICAgIH1cblxuICAgIGdldCB2b2x1bWUgKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgdmFsID0gdGhpcy5tYXAuZ2V0KFwidm9sdW1lXCIpID8/IFtdO1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbCA9PSBcInN0cmluZ1wiID8gdmFsLnNwbGl0KFwiIFwiKSA6IHZhbDtcbiAgICB9XG5cbiAgICBnZXQgbmV0d29yayAoKTogc3RyaW5nW10ge1xuICAgICAgICBjb25zdCB2YWwgPSB0aGlzLm1hcC5nZXQoXCJuZXR3b3JrXCIpID8/IFtdO1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbCA9PSBcInN0cmluZ1wiID8gdmFsLnNwbGl0KFwiIFwiKSA6IHZhbDtcbiAgICB9XG5cbiAgICBnZXQgZXh0cmFIb3N0ICgpOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHRoaXMubWFwLmdldChcImV4dHJhSG9zdFwiKSA/PyBbXTtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWwgPT0gXCJzdHJpbmdcIiA/IHZhbC5zcGxpdChcIiBcIikgOiB2YWw7XG4gICAgfVxuXG4gICAgZ2V0IGNhRmlsZSAoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJjYUZpbGVcIikgPz8gbnVsbDtcbiAgICB9XG5cbiAgICBnZXQgaWdub3JlU2NoZW1hUGF0aHMgKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImlnbm9yZVNjaGVtYVBhdGhzXCIpID8/IEFyZ3YuZGVmYXVsdC5pZ25vcmVTY2hlbWFQYXRocztcbiAgICB9XG5cbiAgICBnZXQgaWdub3JlUHJlZGVmaW5lZFZhcnMgKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImlnbm9yZVByZWRlZmluZWRWYXJzXCIpID8/IEFyZ3YuZGVmYXVsdC5pZ25vcmVQcmVkZWZpbmVkVmFycztcbiAgICB9XG5cbiAgICBnZXQgcHVsbFBvbGljeSAoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcInB1bGxQb2xpY3lcIikgPz8gXCJpZi1ub3QtcHJlc2VudFwiO1xuICAgIH1cblxuICAgIGdldCByZW1vdGVWYXJpYWJsZXMgKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgdmFsID0gdGhpcy5tYXAuZ2V0KFwicmVtb3RlVmFyaWFibGVzXCIpID8/IFtdO1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbCA9PSBcInN0cmluZ1wiID8gdmFsLnNwbGl0KFwiIFwiKSA6IHZhbDtcbiAgICB9XG5cbiAgICBnZXQgdmFyaWFibGUgKCk6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9IHtcbiAgICAgICAgY29uc3QgdmFsID0gdGhpcy5tYXAuZ2V0KFwidmFyaWFibGVcIik7XG4gICAgICAgIGNvbnN0IHZhcmlhYmxlczoge1trZXk6IHN0cmluZ106IHN0cmluZ30gPSB7fTtcbiAgICAgICAgY29uc3QgcGFpcnMgPSB0eXBlb2YgdmFsID09IFwic3RyaW5nXCIgPyB2YWwuc3BsaXQoXCIgXCIpIDogdmFsO1xuICAgICAgICAocGFpcnMgPz8gW10pLmZvckVhY2goKHZhcmlhYmxlUGFpcjogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBleGVjID0gLyg/PGtleT5cXHcqPykoPSkoPzx2YWx1ZT4oLnxcXG58XFxyKSopLy5leGVjKHZhcmlhYmxlUGFpcik7XG4gICAgICAgICAgICBpZiAoZXhlYz8uZ3JvdXBzPy5rZXkpIHtcbiAgICAgICAgICAgICAgICB2YXJpYWJsZXNbZXhlYy5ncm91cHMua2V5XSA9IGV4ZWM/Lmdyb3Vwcz8udmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdmFyaWFibGVzO1xuICAgIH1cblxuICAgIGdldCB1bnNldFZhcmlhYmxlcyAoKTogc3RyaW5nW10ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwidW5zZXRWYXJpYWJsZVwiKSA/PyBbXTtcbiAgICB9XG5cbiAgICBnZXQgbWFudWFsICgpOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHRoaXMubWFwLmdldChcIm1hbnVhbFwiKSA/PyBbXTtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWwgPT0gXCJzdHJpbmdcIiA/IHZhbC5zcGxpdChcIiBcIikgOiB2YWw7XG4gICAgfVxuXG4gICAgZ2V0IGpvYiAoKTogc3RyaW5nW10ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwiam9iXCIpID8/IFtdO1xuICAgIH1cblxuICAgIGdldCBhdXRvQ29tcGxldGluZyAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJhdXRvQ29tcGxldGluZ1wiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgY2xlYW51cCAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJjbGVhbnVwXCIpID8/IHRydWU7XG4gICAgfVxuXG4gICAgZ2V0IHF1aWV0ICgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcInF1aWV0XCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCB1bWFzayAoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIFRPRE86IGRlZmF1bHQgdG8gZmFsc2UgaW4gNS54LnhcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcInVtYXNrXCIpID8/IHRydWU7XG4gICAgfVxuXG4gICAgZ2V0IHVzZXJucyAoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcInVzZXJuc1wiKTtcbiAgICB9XG5cbiAgICBnZXQgcHJpdmlsZWdlZCAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJwcml2aWxlZ2VkXCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBkZXZpY2UgKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgdmFsID0gdGhpcy5tYXAuZ2V0KFwiZGV2aWNlXCIpID8/IFtdO1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbCA9PSBcInN0cmluZ1wiID8gdmFsLnNwbGl0KFwiIFwiKSA6IHZhbDtcbiAgICB9XG5cbiAgICBnZXQgdWxpbWl0ICgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICAgICAgY29uc3QgdWxpbWl0ID0gdGhpcy5tYXAuZ2V0KFwidWxpbWl0XCIpO1xuICAgICAgICBpZiAoIXVsaW1pdCkgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiB1bGltaXQ7XG4gICAgfVxuXG4gICAgZ2V0IG5lZWRzICgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcIm5lZWRzXCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBvbmx5TmVlZHMgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwib25seU5lZWRzXCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBzdGFnZSAoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJzdGFnZVwiKSA/PyBudWxsO1xuICAgIH1cblxuICAgIGdldCBjb21wbGV0aW9uICgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImNvbXBsZXRpb25cIikgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2V0IGxpc3QgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwibGlzdFwiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgbGlzdEFsbCAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJsaXN0QWxsXCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBsaXN0SnNvbiAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJsaXN0SnNvblwiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgbGlzdENzdiAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJsaXN0Q3N2XCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBsaXN0Q3N2QWxsICgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImxpc3RDc3ZBbGxcIikgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2V0IHByZXZpZXcgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwicHJldmlld1wiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgdmFsaWRhdGVEZXBlbmRlbmN5Q2hhaW4gKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwidmFsaWRhdGVEZXBlbmRlbmN5Q2hhaW5cIikgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2V0IHNoZWxsSXNvbGF0aW9uICgpOiBib29sZWFuIHtcbiAgICAgICAgLy8gVE9ETzogZGVmYXVsdCB0byB0cnVlIGluIDUueC54XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJzaGVsbElzb2xhdGlvblwiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgZmV0Y2hJbmNsdWRlcyAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJmZXRjaEluY2x1ZGVzXCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBtb3VudENhY2hlICgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcIm1vdW50Q2FjaGVcIikgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2V0IGFydGlmYWN0c1RvU291cmNlICgpOiBib29sZWFuIHtcbiAgICAgICAgLy8gVE9ETzogZGVmYXVsdCB0byBmYWxzZSBpbiA1LngueFxuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwiYXJ0aWZhY3RzVG9Tb3VyY2VcIikgPz8gdHJ1ZTtcbiAgICB9XG5cbiAgICBnZXQgc2hvd1RpbWVzdGFtcHMgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwidGltZXN0YW1wc1wiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgbWF4Sm9iTmFtZVBhZGRpbmcgKCk6IG51bWJlciB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwibWF4Sm9iTmFtZVBhZGRpbmdcIikgPz8gbnVsbDtcbiAgICB9XG5cbiAgICBnZXQgY29udGFpbmVyTWFjQWRkcmVzcyAoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJjb250YWluZXJNYWNBZGRyZXNzXCIpID8/IG51bGw7XG4gICAgfVxuXG4gICAgZ2V0IGNvbnRhaW5lckVtdWxhdGUgKCk6IHN0cmluZyB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwiY29udGFpbmVyRW11bGF0ZVwiKSA/PyBudWxsO1xuICAgIH1cblxuICAgIGdldCBjb25jdXJyZW5jeSAoKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgICAgIGNvbnN0IGNvbmN1cnJlbmN5ID0gdGhpcy5tYXAuZ2V0KFwiY29uY3VycmVuY3lcIik7XG4gICAgICAgIGlmICghY29uY3VycmVuY3kpIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gTnVtYmVyKGNvbmN1cnJlbmN5KTtcbiAgICB9XG5cbiAgICBnZXQgY29udGFpbmVyRXhlY3V0YWJsZSAoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImNvbnRhaW5lckV4ZWN1dGFibGVcIikgPz8gXCJkb2NrZXJcIjtcbiAgICB9XG5cbiAgICBnZXQganNvblNjaGVtYVZhbGlkYXRpb24gKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwianNvblNjaGVtYVZhbGlkYXRpb25cIikgPz8gdHJ1ZTtcbiAgICB9XG5cbiAgICBnZXQgc2hlbGxFeGVjdXRvck5vSW1hZ2UgKCk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBUT0RPOiBkZWZhdWx0IHRvIGZhbHNlIGluIDUueC54XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJzaGVsbEV4ZWN1dG9yTm9JbWFnZVwiKSA/PyB0cnVlO1xuICAgIH1cblxuICAgIGdldCBmb3JjZVNoZWxsRXhlY3V0b3IgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwiZm9yY2VTaGVsbEV4ZWN1dG9yXCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBkZWZhdWx0SW1hZ2UgKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJkZWZhdWx0SW1hZ2VcIikgPz8gXCJkb2NrZXIuaW8vcnVieTozLjFcIjtcbiAgICB9XG5cbiAgICBnZXQgd2FpdEltYWdlICgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwid2FpdEltYWdlXCIpID8/IFwiZG9ja2VyLmlvL3N1bWluYTQ2L3dhaXQtZm9yLWl0OmxhdGVzdFwiO1xuICAgIH1cblxuICAgIGdldCBoZWxwZXJJbWFnZSAoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImhlbHBlckltYWdlXCIpID8/IFwiZG9ja2VyLmlvL2ZpcmVjb3cvZ2l0bGFiLWNpLWxvY2FsLXV0aWw6bGF0ZXN0XCI7XG4gICAgfVxuXG4gICAgZ2V0IGRlZmF1bHRJbWFnZUV4cGxpY2l0bHlTZXQgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwiZGVmYXVsdEltYWdlXCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBtYXhpbXVtSW5jbHVkZXMgKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJtYXhpbXVtSW5jbHVkZXNcIikgPz8gMTUwOyAvLyBodHRwczovL2RvY3MuZ2l0bGFiLmNvbS9lZS9hZG1pbmlzdHJhdGlvbi9zZXR0aW5ncy9jb250aW51b3VzX2ludGVncmF0aW9uLmh0bWwjbWF4aW11bS1pbmNsdWRlc1xuICAgIH1cblxuICAgIGdldCBjaGlsZFBpcGVsaW5lRGVwdGggKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJjaGlsZFBpcGVsaW5lRGVwdGhcIik7XG4gICAgfVxuXG4gICAgZ2V0IHJlZ2lzdHJ5ICgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcInJlZ2lzdHJ5XCIpID8/IGZhbHNlO1xuICAgIH1cbn1cbiJdfQ==