@decaf-ts/utils 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/LICENSE.md +157 -0
  2. package/README.md +95 -0
  3. package/dist/esm/utils.js +1 -0
  4. package/dist/types/bin/tag-release.d.ts +1 -0
  5. package/dist/types/bin/update-scripts.d.ts +1 -0
  6. package/dist/types/cli/command.d.ts +110 -0
  7. package/dist/types/cli/commands/index.d.ts +2 -0
  8. package/dist/types/cli/commands/tag-release.d.ts +105 -0
  9. package/dist/types/cli/commands/update-scripts.d.ts +211 -0
  10. package/dist/types/cli/constants.d.ts +73 -0
  11. package/dist/types/cli/index.d.ts +4 -0
  12. package/dist/types/cli/types.d.ts +28 -0
  13. package/dist/types/index.d.ts +39 -0
  14. package/dist/types/input/index.d.ts +2 -0
  15. package/dist/types/input/input.d.ts +472 -0
  16. package/dist/types/input/types.d.ts +76 -0
  17. package/dist/types/output/common.d.ts +51 -0
  18. package/dist/types/output/index.d.ts +3 -0
  19. package/dist/types/output/logging.d.ts +177 -0
  20. package/dist/types/output/types.d.ts +203 -0
  21. package/dist/types/utils/accumulator.d.ts +105 -0
  22. package/dist/types/utils/constants.d.ts +136 -0
  23. package/dist/types/utils/environment.d.ts +57 -0
  24. package/dist/types/utils/fs.d.ts +133 -0
  25. package/dist/types/utils/http.d.ts +41 -0
  26. package/dist/types/utils/index.d.ts +7 -0
  27. package/dist/types/utils/md.d.ts +156 -0
  28. package/dist/types/utils/tests.d.ts +170 -0
  29. package/dist/types/utils/text.d.ts +106 -0
  30. package/dist/types/utils/timeout.d.ts +1 -0
  31. package/dist/types/utils/types.d.ts +81 -0
  32. package/dist/types/utils/utils.d.ts +91 -0
  33. package/dist/types/utils/web.d.ts +7 -0
  34. package/dist/types/writers/OutputWriter.d.ts +49 -0
  35. package/dist/types/writers/RegexpOutputWriter.d.ts +69 -0
  36. package/dist/types/writers/StandardOutputWriter.d.ts +91 -0
  37. package/dist/types/writers/index.d.ts +4 -0
  38. package/dist/types/writers/types.d.ts +29 -0
  39. package/dist/utils.js +1 -0
  40. package/lib/assets/slogans.json +802 -0
  41. package/lib/bin/tag-release.cjs +12 -0
  42. package/lib/bin/update-scripts.cjs +12 -0
  43. package/lib/cli/command.cjs +153 -0
  44. package/lib/cli/commands/index.cjs +20 -0
  45. package/lib/cli/commands/tag-release.cjs +168 -0
  46. package/lib/cli/commands/update-scripts.cjs +511 -0
  47. package/lib/cli/constants.cjs +80 -0
  48. package/lib/cli/index.cjs +22 -0
  49. package/lib/cli/types.cjs +4 -0
  50. package/lib/esm/assets/slogans.json +802 -0
  51. package/lib/esm/bin/tag-release.js +10 -0
  52. package/lib/esm/bin/update-scripts.js +10 -0
  53. package/lib/esm/cli/command.js +149 -0
  54. package/lib/esm/cli/commands/index.js +4 -0
  55. package/lib/esm/cli/commands/tag-release.js +164 -0
  56. package/lib/esm/cli/commands/update-scripts.js +504 -0
  57. package/lib/esm/cli/constants.js +77 -0
  58. package/lib/esm/cli/index.js +6 -0
  59. package/lib/esm/cli/types.js +3 -0
  60. package/lib/esm/index.js +41 -0
  61. package/lib/esm/input/index.js +4 -0
  62. package/lib/esm/input/input.js +570 -0
  63. package/lib/esm/input/types.js +3 -0
  64. package/lib/esm/output/common.js +93 -0
  65. package/lib/esm/output/index.js +5 -0
  66. package/lib/esm/output/logging.js +350 -0
  67. package/lib/esm/output/types.js +3 -0
  68. package/lib/esm/utils/accumulator.js +145 -0
  69. package/lib/esm/utils/constants.js +176 -0
  70. package/lib/esm/utils/environment.js +91 -0
  71. package/lib/esm/utils/fs.js +271 -0
  72. package/lib/esm/utils/http.js +70 -0
  73. package/lib/esm/utils/index.js +9 -0
  74. package/lib/esm/utils/md.js +3 -0
  75. package/lib/esm/utils/tests.js +223 -0
  76. package/lib/esm/utils/text.js +142 -0
  77. package/lib/esm/utils/timeout.js +5 -0
  78. package/lib/esm/utils/types.js +3 -0
  79. package/lib/esm/utils/utils.js +220 -0
  80. package/lib/esm/utils/web.js +12 -0
  81. package/lib/esm/writers/OutputWriter.js +3 -0
  82. package/lib/esm/writers/RegexpOutputWriter.js +98 -0
  83. package/lib/esm/writers/StandardOutputWriter.js +127 -0
  84. package/lib/esm/writers/index.js +6 -0
  85. package/lib/esm/writers/types.js +3 -0
  86. package/lib/index.cjs +58 -0
  87. package/lib/input/index.cjs +20 -0
  88. package/lib/input/input.cjs +577 -0
  89. package/lib/input/types.cjs +4 -0
  90. package/lib/output/common.cjs +100 -0
  91. package/lib/output/index.cjs +21 -0
  92. package/lib/output/logging.cjs +355 -0
  93. package/lib/output/types.cjs +4 -0
  94. package/lib/utils/accumulator.cjs +149 -0
  95. package/lib/utils/constants.cjs +179 -0
  96. package/lib/utils/environment.cjs +95 -0
  97. package/lib/utils/fs.cjs +288 -0
  98. package/lib/utils/http.cjs +77 -0
  99. package/lib/utils/index.cjs +25 -0
  100. package/lib/utils/md.cjs +4 -0
  101. package/lib/utils/tests.cjs +263 -0
  102. package/lib/utils/text.cjs +153 -0
  103. package/lib/utils/timeout.cjs +8 -0
  104. package/lib/utils/types.cjs +4 -0
  105. package/lib/utils/utils.cjs +226 -0
  106. package/lib/utils/web.cjs +15 -0
  107. package/lib/writers/OutputWriter.cjs +4 -0
  108. package/lib/writers/RegexpOutputWriter.cjs +102 -0
  109. package/lib/writers/StandardOutputWriter.cjs +131 -0
  110. package/lib/writers/index.cjs +22 -0
  111. package/lib/writers/types.cjs +4 -0
  112. package/package.json +121 -0
@@ -0,0 +1,271 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { Logging } from "../output/logging";
4
+ import { patchString } from "./text";
5
+ import { runCommand } from "./utils";
6
+ const logger = Logging.for("fs");
7
+ /**
8
+ * @description Patches a file with given values.
9
+ * @summary Reads a file, applies patches using TextUtils, and writes the result back to the file.
10
+ *
11
+ * @param {string} path - The path to the file to be patched.
12
+ * @param {Record<string, number | string>} values - The values to patch into the file.
13
+ * @return {void}
14
+ *
15
+ * @function patchFile
16
+ *
17
+ * @mermaid
18
+ * sequenceDiagram
19
+ * participant Caller
20
+ * participant patchFile
21
+ * participant fs
22
+ * participant readFile
23
+ * participant TextUtils
24
+ * participant writeFile
25
+ * Caller->>patchFile: Call with path and values
26
+ * patchFile->>fs: Check if file exists
27
+ * patchFile->>readFile: Read file content
28
+ * readFile->>fs: Read file
29
+ * fs-->>readFile: Return file content
30
+ * readFile-->>patchFile: Return file content
31
+ * patchFile->>TextUtils: Patch string
32
+ * TextUtils-->>patchFile: Return patched content
33
+ * patchFile->>writeFile: Write patched content
34
+ * writeFile->>fs: Write to file
35
+ * fs-->>writeFile: File written
36
+ * writeFile-->>patchFile: File written
37
+ * patchFile-->>Caller: Patching complete
38
+ *
39
+ * @memberOf module:fs-utils
40
+ */
41
+ export function patchFile(path, values) {
42
+ const log = logger.for(patchFile);
43
+ if (!fs.existsSync(path))
44
+ throw new Error(`File not found at path "${path}".`);
45
+ let content = readFile(path);
46
+ try {
47
+ log.verbose(`Patching file "${path}"...`);
48
+ log.debug(`with value: ${JSON.stringify(values)}`);
49
+ content = patchString(content, values);
50
+ }
51
+ catch (error) {
52
+ throw new Error(`Error patching file: ${error}`);
53
+ }
54
+ writeFile(path, content);
55
+ }
56
+ /**
57
+ * @description Reads a file and returns its content.
58
+ * @summary Reads the content of a file at the specified path and returns it as a string.
59
+ *
60
+ * @param {string} path - The path to the file to be read.
61
+ * @return {string} The content of the file.
62
+ *
63
+ * @function readFile
64
+ *
65
+ * @memberOf module:utils
66
+ */
67
+ export function readFile(path) {
68
+ const log = logger.for(readFile);
69
+ try {
70
+ log.verbose(`Reading file "${path}"...`);
71
+ return fs.readFileSync(path, "utf8");
72
+ }
73
+ catch (error) {
74
+ log.verbose(`Error reading file "${path}": ${error}`);
75
+ throw new Error(`Error reading file "${path}": ${error}`);
76
+ }
77
+ }
78
+ /**
79
+ * @description Writes data to a file.
80
+ * @summary Writes the provided data to a file at the specified path.
81
+ *
82
+ * @param {string} path - The path to the file to be written.
83
+ * @param {string | Buffer} data - The data to be written to the file.
84
+ * @return {void}
85
+ *
86
+ * @function writeFile
87
+ *
88
+ * @memberOf module:utils
89
+ */
90
+ export function writeFile(path, data) {
91
+ const log = logger.for(writeFile);
92
+ try {
93
+ log.verbose(`Writing file "${path} with ${data.length} bytes...`);
94
+ fs.writeFileSync(path, data, "utf8");
95
+ }
96
+ catch (error) {
97
+ log.verbose(`Error writing file "${path}": ${error}`);
98
+ throw new Error(`Error writing file "${path}": ${error}`);
99
+ }
100
+ }
101
+ /**
102
+ * @description Retrieves package information from package.json.
103
+ * @summary Loads and parses the package.json file from a specified directory or the current working directory. Can return the entire package object or a specific property.
104
+ * @param {string} [p=process.cwd()] - The directory path where the package.json file is located.
105
+ * @param {string} [property] - Optional. The specific property to retrieve from package.json.
106
+ * @return {object | string} The parsed contents of package.json or the value of the specified property.
107
+ * @function getPackage
108
+ * @mermaid
109
+ * sequenceDiagram
110
+ * participant Caller
111
+ * participant getPackage
112
+ * participant readFile
113
+ * participant JSON
114
+ * Caller->>getPackage: Call with path and optional property
115
+ * getPackage->>readFile: Read package.json
116
+ * readFile-->>getPackage: Return file content
117
+ * getPackage->>JSON: Parse file content
118
+ * JSON-->>getPackage: Return parsed object
119
+ * alt property specified
120
+ * getPackage->>getPackage: Check if property exists
121
+ * alt property exists
122
+ * getPackage-->>Caller: Return property value
123
+ * else property doesn't exist
124
+ * getPackage-->>Caller: Throw Error
125
+ * end
126
+ * else no property specified
127
+ * getPackage-->>Caller: Return entire package object
128
+ * end
129
+ * @memberOf module:utils
130
+ */
131
+ export function getPackage(p = process.cwd(), property) {
132
+ let pkg;
133
+ try {
134
+ pkg = JSON.parse(readFile(path.join(p, `package.json`)));
135
+ }
136
+ catch (error) {
137
+ throw new Error(`Failed to retrieve package information" ${error}`);
138
+ }
139
+ if (property) {
140
+ if (!(property in pkg))
141
+ throw new Error(`Property "${property}" not found in package.json`);
142
+ return pkg[property];
143
+ }
144
+ return pkg;
145
+ }
146
+ export function setPackageAttribute(attr, value, p = process.cwd()) {
147
+ const pkg = getPackage(p);
148
+ pkg[attr] = value;
149
+ writeFile(path.join(p, `package.json`), JSON.stringify(pkg, null, 2));
150
+ }
151
+ /**
152
+ * @description Retrieves the version from package.json.
153
+ * @summary A convenience function that calls getPackage to retrieve the "version" property from package.json.
154
+ * @param {string} [p=process.cwd()] - The directory path where the package.json file is located.
155
+ * @return {string} The version string from package.json.
156
+ * @function getPackageVersion
157
+ * @memberOf module:fs-utils
158
+ */
159
+ export function getPackageVersion(p = process.cwd()) {
160
+ return getPackage(p, "version");
161
+ }
162
+ /**
163
+ * @description Retrieves all dependencies from the project.
164
+ * @summary Executes 'npm ls --json' command to get a detailed list of all dependencies (production, development, and peer) and their versions.
165
+ * @param {string} [path=process.cwd()] - The directory path of the project.
166
+ * @return {Promise<{prod: Array<{name: string, version: string}>, dev: Array<{name: string, version: string}>, peer: Array<{name: string, version: string}>}>} An object containing arrays of production, development, and peer dependencies.
167
+ * @function getDependencies
168
+ * @mermaid
169
+ * sequenceDiagram
170
+ * participant Caller
171
+ * participant getDependencies
172
+ * participant runCommand
173
+ * participant JSON
174
+ * Caller->>getDependencies: Call with optional path
175
+ * getDependencies->>runCommand: Execute 'npm ls --json'
176
+ * runCommand-->>getDependencies: Return command output
177
+ * getDependencies->>JSON: Parse command output
178
+ * JSON-->>getDependencies: Return parsed object
179
+ * getDependencies->>getDependencies: Process dependencies
180
+ * getDependencies-->>Caller: Return processed dependencies
181
+ * @memberOf module:fs-utils
182
+ */
183
+ export async function getDependencies(path = process.cwd()) {
184
+ let pkg;
185
+ try {
186
+ pkg = JSON.parse(await runCommand(`npm ls --json`, { cwd: path }).promise);
187
+ }
188
+ catch (e) {
189
+ throw new Error(`Failed to retrieve dependencies: ${e}`);
190
+ }
191
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
192
+ const mapper = (entry, index) => ({
193
+ name: entry[0],
194
+ version: entry[1].version,
195
+ });
196
+ return {
197
+ prod: Object.entries(pkg.dependencies || {}).map(mapper),
198
+ dev: Object.entries(pkg.devDependencies || {}).map(mapper),
199
+ peer: Object.entries(pkg.peerDependencies || {}).map(mapper),
200
+ };
201
+ }
202
+ export async function updateDependencies() {
203
+ const log = logger.for(updateDependencies);
204
+ log.info("checking for updates...");
205
+ await runCommand("npx npm-check-updates -u").promise;
206
+ log.info("updating...");
207
+ await runCommand("npx npm run do-install").promise;
208
+ }
209
+ export async function installIfNotAvailable(deps, dependencies) {
210
+ if (!dependencies) {
211
+ const d = await getDependencies();
212
+ dependencies = {
213
+ prod: d.prod?.map((p) => p.name) || [],
214
+ dev: d.dev?.map((d) => d.name) || [],
215
+ peer: d.peer?.map((p) => p.name) || [],
216
+ };
217
+ }
218
+ const { prod, dev, peer } = dependencies;
219
+ const installed = Array.from(new Set([...(prod || []), ...(dev || []), ...(peer || [])]));
220
+ deps = typeof deps === "string" ? [deps] : deps;
221
+ const toInstall = deps.filter((d) => !installed.includes(d));
222
+ if (toInstall.length)
223
+ await installDependencies({ dev: toInstall });
224
+ dependencies.dev = dependencies.dev || [];
225
+ dependencies.dev.push(...toInstall);
226
+ return dependencies;
227
+ }
228
+ export async function pushToGit() {
229
+ const log = logger.for(pushToGit);
230
+ const gitUser = await runCommand("git config user.name").promise;
231
+ const gitEmail = await runCommand("git config user.email").promise;
232
+ log.verbose(`cached git id: ${gitUser}/${gitEmail}. changing to automation`);
233
+ await runCommand('git config user.email "automation@decaf.ts"').promise;
234
+ await runCommand('git config user.name "decaf"').promise;
235
+ log.info("Pushing changes to git...");
236
+ await runCommand("git add .").promise;
237
+ await runCommand(`git commit -m "refs #1 - after repo setup"`).promise;
238
+ await runCommand("git push").promise;
239
+ await runCommand(`git config user.email "${gitEmail}"`).promise;
240
+ await runCommand(`git config user.name "${gitUser}"`).promise;
241
+ log.verbose(`reverted to git id: ${gitUser}/${gitEmail}`);
242
+ }
243
+ export async function installDependencies(dependencies) {
244
+ const log = logger.for(installDependencies);
245
+ const prod = dependencies.prod || [];
246
+ const dev = dependencies.dev || [];
247
+ const peer = dependencies.peer || [];
248
+ if (prod.length) {
249
+ log.info(`Installing dependencies ${prod.join(", ")}...`);
250
+ await runCommand(`npm install ${prod.join(" ")}`, { cwd: process.cwd() })
251
+ .promise;
252
+ }
253
+ if (dev.length) {
254
+ log.info(`Installing devDependencies ${dev.join(", ")}...`);
255
+ await runCommand(`npm install --save-dev ${dev.join(" ")}`, {
256
+ cwd: process.cwd(),
257
+ }).promise;
258
+ }
259
+ if (peer.length) {
260
+ log.info(`Installing peerDependencies ${peer.join(", ")}...`);
261
+ await runCommand(`npm install --save-peer ${peer.join(" ")}`, {
262
+ cwd: process.cwd(),
263
+ }).promise;
264
+ }
265
+ }
266
+ export async function normalizeImport(importPromise) {
267
+ // CommonJS's `module.exports` is wrapped as `default` in ESModule.
268
+ return importPromise.then((m) => (m.default || m));
269
+ }
270
+
271
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,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LDhCQUE4QixHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1RCxNQUFNLFVBQVUsQ0FBQywwQkFBMEIsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFO1lBQzFELEdBQUcsRUFBRSxPQUFPLENBQUMsR0FBRyxFQUFFO1NBQ25CLENBQUMsQ0FBQyxPQUFPLENBQUM7SUFDYixDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEIsR0FBRyxDQUFDLElBQUksQ0FBQywrQkFBK0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUQsTUFBTSxVQUFVLENBQUMsMkJBQTJCLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRTtZQUM1RCxHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUcsRUFBRTtTQUNuQixDQUFDLENBQUMsT0FBTyxDQUFDO0lBQ2IsQ0FBQztBQUNILENBQUM7QUFFRCxNQUFNLENBQUMsS0FBSyxVQUFVLGVBQWUsQ0FDbkMsYUFBeUI7SUFFekIsbUVBQW1FO0lBQ25FLE9BQU8sYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBTSxDQUFDLENBQUM7QUFDL0QsQ0FBQyIsImZpbGUiOiJ1dGlscy9mcy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIi4uL291dHB1dC9sb2dnaW5nXCI7XG5pbXBvcnQgeyBwYXRjaFN0cmluZyB9IGZyb20gXCIuL3RleHRcIjtcbmltcG9ydCB7IHJ1bkNvbW1hbmQgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgRGVwZW5kZW5jeU1hcCwgU2ltcGxlRGVwZW5kZW5jeU1hcCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IExvZ2dpbmcuZm9yKFwiZnNcIik7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFBhdGNoZXMgYSBmaWxlIHdpdGggZ2l2ZW4gdmFsdWVzLlxuICogQHN1bW1hcnkgUmVhZHMgYSBmaWxlLCBhcHBsaWVzIHBhdGNoZXMgdXNpbmcgVGV4dFV0aWxzLCBhbmQgd3JpdGVzIHRoZSByZXN1bHQgYmFjayB0byB0aGUgZmlsZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIFRoZSBwYXRoIHRvIHRoZSBmaWxlIHRvIGJlIHBhdGNoZWQuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz59IHZhbHVlcyAtIFRoZSB2YWx1ZXMgdG8gcGF0Y2ggaW50byB0aGUgZmlsZS5cbiAqIEByZXR1cm4ge3ZvaWR9XG4gKlxuICogQGZ1bmN0aW9uIHBhdGNoRmlsZVxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IHBhdGNoRmlsZVxuICogICBwYXJ0aWNpcGFudCBmc1xuICogICBwYXJ0aWNpcGFudCByZWFkRmlsZVxuICogICBwYXJ0aWNpcGFudCBUZXh0VXRpbHNcbiAqICAgcGFydGljaXBhbnQgd3JpdGVGaWxlXG4gKiAgIENhbGxlci0+PnBhdGNoRmlsZTogQ2FsbCB3aXRoIHBhdGggYW5kIHZhbHVlc1xuICogICBwYXRjaEZpbGUtPj5mczogQ2hlY2sgaWYgZmlsZSBleGlzdHNcbiAqICAgcGF0Y2hGaWxlLT4+cmVhZEZpbGU6IFJlYWQgZmlsZSBjb250ZW50XG4gKiAgIHJlYWRGaWxlLT4+ZnM6IFJlYWQgZmlsZVxuICogICBmcy0tPj5yZWFkRmlsZTogUmV0dXJuIGZpbGUgY29udGVudFxuICogICByZWFkRmlsZS0tPj5wYXRjaEZpbGU6IFJldHVybiBmaWxlIGNvbnRlbnRcbiAqICAgcGF0Y2hGaWxlLT4+VGV4dFV0aWxzOiBQYXRjaCBzdHJpbmdcbiAqICAgVGV4dFV0aWxzLS0+PnBhdGNoRmlsZTogUmV0dXJuIHBhdGNoZWQgY29udGVudFxuICogICBwYXRjaEZpbGUtPj53cml0ZUZpbGU6IFdyaXRlIHBhdGNoZWQgY29udGVudFxuICogICB3cml0ZUZpbGUtPj5mczogV3JpdGUgdG8gZmlsZVxuICogICBmcy0tPj53cml0ZUZpbGU6IEZpbGUgd3JpdHRlblxuICogICB3cml0ZUZpbGUtLT4+cGF0Y2hGaWxlOiBGaWxlIHdyaXR0ZW5cbiAqICAgcGF0Y2hGaWxlLS0+PkNhbGxlcjogUGF0Y2hpbmcgY29tcGxldGVcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmZzLXV0aWxzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXRjaEZpbGUoXG4gIHBhdGg6IHN0cmluZyxcbiAgdmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+XG4pIHtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcihwYXRjaEZpbGUpO1xuICBpZiAoIWZzLmV4aXN0c1N5bmMocGF0aCkpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBGaWxlIG5vdCBmb3VuZCBhdCBwYXRoIFwiJHtwYXRofVwiLmApO1xuICBsZXQgY29udGVudCA9IHJlYWRGaWxlKHBhdGgpO1xuXG4gIHRyeSB7XG4gICAgbG9nLnZlcmJvc2UoYFBhdGNoaW5nIGZpbGUgXCIke3BhdGh9XCIuLi5gKTtcbiAgICBsb2cuZGVidWcoYHdpdGggdmFsdWU6ICR7SlNPTi5zdHJpbmdpZnkodmFsdWVzKX1gKTtcbiAgICBjb250ZW50ID0gcGF0Y2hTdHJpbmcoY29udGVudCwgdmFsdWVzKTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIHBhdGNoaW5nIGZpbGU6ICR7ZXJyb3J9YCk7XG4gIH1cbiAgd3JpdGVGaWxlKHBhdGgsIGNvbnRlbnQpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZWFkcyBhIGZpbGUgYW5kIHJldHVybnMgaXRzIGNvbnRlbnQuXG4gKiBAc3VtbWFyeSBSZWFkcyB0aGUgY29udGVudCBvZiBhIGZpbGUgYXQgdGhlIHNwZWNpZmllZCBwYXRoIGFuZCByZXR1cm5zIGl0IGFzIGEgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIHBhdGggdG8gdGhlIGZpbGUgdG8gYmUgcmVhZC5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGNvbnRlbnQgb2YgdGhlIGZpbGUuXG4gKlxuICogQGZ1bmN0aW9uIHJlYWRGaWxlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEZpbGUocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcihyZWFkRmlsZSk7XG4gIHRyeSB7XG4gICAgbG9nLnZlcmJvc2UoYFJlYWRpbmcgZmlsZSBcIiR7cGF0aH1cIi4uLmApO1xuICAgIHJldHVybiBmcy5yZWFkRmlsZVN5bmMocGF0aCwgXCJ1dGY4XCIpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZy52ZXJib3NlKGBFcnJvciByZWFkaW5nIGZpbGUgXCIke3BhdGh9XCI6ICR7ZXJyb3J9YCk7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBFcnJvciByZWFkaW5nIGZpbGUgXCIke3BhdGh9XCI6ICR7ZXJyb3J9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gV3JpdGVzIGRhdGEgdG8gYSBmaWxlLlxuICogQHN1bW1hcnkgV3JpdGVzIHRoZSBwcm92aWRlZCBkYXRhIHRvIGEgZmlsZSBhdCB0aGUgc3BlY2lmaWVkIHBhdGguXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBUaGUgcGF0aCB0byB0aGUgZmlsZSB0byBiZSB3cml0dGVuLlxuICogQHBhcmFtIHtzdHJpbmcgfCBCdWZmZXJ9IGRhdGEgLSBUaGUgZGF0YSB0byBiZSB3cml0dGVuIHRvIHRoZSBmaWxlLlxuICogQHJldHVybiB7dm9pZH1cbiAqXG4gKiBAZnVuY3Rpb24gd3JpdGVGaWxlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gd3JpdGVGaWxlKHBhdGg6IHN0cmluZywgZGF0YTogc3RyaW5nIHwgQnVmZmVyKTogdm9pZCB7XG4gIGNvbnN0IGxvZyA9IGxvZ2dlci5mb3Iod3JpdGVGaWxlKTtcbiAgdHJ5IHtcbiAgICBsb2cudmVyYm9zZShgV3JpdGluZyBmaWxlIFwiJHtwYXRofSB3aXRoICR7ZGF0YS5sZW5ndGh9IGJ5dGVzLi4uYCk7XG4gICAgZnMud3JpdGVGaWxlU3luYyhwYXRoLCBkYXRhLCBcInV0ZjhcIik7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgbG9nLnZlcmJvc2UoYEVycm9yIHdyaXRpbmcgZmlsZSBcIiR7cGF0aH1cIjogJHtlcnJvcn1gKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIHdyaXRpbmcgZmlsZSBcIiR7cGF0aH1cIjogJHtlcnJvcn1gKTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgcGFja2FnZSBpbmZvcm1hdGlvbiBmcm9tIHBhY2thZ2UuanNvbi5cbiAqIEBzdW1tYXJ5IExvYWRzIGFuZCBwYXJzZXMgdGhlIHBhY2thZ2UuanNvbiBmaWxlIGZyb20gYSBzcGVjaWZpZWQgZGlyZWN0b3J5IG9yIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LiBDYW4gcmV0dXJuIHRoZSBlbnRpcmUgcGFja2FnZSBvYmplY3Qgb3IgYSBzcGVjaWZpYyBwcm9wZXJ0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbcD1wcm9jZXNzLmN3ZCgpXSAtIFRoZSBkaXJlY3RvcnkgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbcHJvcGVydHldIC0gT3B0aW9uYWwuIFRoZSBzcGVjaWZpYyBwcm9wZXJ0eSB0byByZXRyaWV2ZSBmcm9tIHBhY2thZ2UuanNvbi5cbiAqIEByZXR1cm4ge29iamVjdCB8IHN0cmluZ30gVGhlIHBhcnNlZCBjb250ZW50cyBvZiBwYWNrYWdlLmpzb24gb3IgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkuXG4gKiBAZnVuY3Rpb24gZ2V0UGFja2FnZVxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgZ2V0UGFja2FnZVxuICogICBwYXJ0aWNpcGFudCByZWFkRmlsZVxuICogICBwYXJ0aWNpcGFudCBKU09OXG4gKiAgIENhbGxlci0+PmdldFBhY2thZ2U6IENhbGwgd2l0aCBwYXRoIGFuZCBvcHRpb25hbCBwcm9wZXJ0eVxuICogICBnZXRQYWNrYWdlLT4+cmVhZEZpbGU6IFJlYWQgcGFja2FnZS5qc29uXG4gKiAgIHJlYWRGaWxlLS0+PmdldFBhY2thZ2U6IFJldHVybiBmaWxlIGNvbnRlbnRcbiAqICAgZ2V0UGFja2FnZS0+PkpTT046IFBhcnNlIGZpbGUgY29udGVudFxuICogICBKU09OLS0+PmdldFBhY2thZ2U6IFJldHVybiBwYXJzZWQgb2JqZWN0XG4gKiAgIGFsdCBwcm9wZXJ0eSBzcGVjaWZpZWRcbiAqICAgICBnZXRQYWNrYWdlLT4+Z2V0UGFja2FnZTogQ2hlY2sgaWYgcHJvcGVydHkgZXhpc3RzXG4gKiAgICAgYWx0IHByb3BlcnR5IGV4aXN0c1xuICogICAgICAgZ2V0UGFja2FnZS0tPj5DYWxsZXI6IFJldHVybiBwcm9wZXJ0eSB2YWx1ZVxuICogICAgIGVsc2UgcHJvcGVydHkgZG9lc24ndCBleGlzdFxuICogICAgICAgZ2V0UGFja2FnZS0tPj5DYWxsZXI6IFRocm93IEVycm9yXG4gKiAgICAgZW5kXG4gKiAgIGVsc2Ugbm8gcHJvcGVydHkgc3BlY2lmaWVkXG4gKiAgICAgZ2V0UGFja2FnZS0tPj5DYWxsZXI6IFJldHVybiBlbnRpcmUgcGFja2FnZSBvYmplY3RcbiAqICAgZW5kXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnV0aWxzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYWNrYWdlKFxuICBwOiBzdHJpbmcgPSBwcm9jZXNzLmN3ZCgpLFxuICBwcm9wZXJ0eT86IHN0cmluZ1xuKTogb2JqZWN0IHwgc3RyaW5nIHtcbiAgbGV0IHBrZzogYW55O1xuICB0cnkge1xuICAgIHBrZyA9IEpTT04ucGFyc2UocmVhZEZpbGUocGF0aC5qb2luKHAsIGBwYWNrYWdlLmpzb25gKSkpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHJldHJpZXZlIHBhY2thZ2UgaW5mb3JtYXRpb25cIiAke2Vycm9yfWApO1xuICB9XG5cbiAgaWYgKHByb3BlcnR5KSB7XG4gICAgaWYgKCEocHJvcGVydHkgaW4gcGtnKSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUHJvcGVydHkgXCIke3Byb3BlcnR5fVwiIG5vdCBmb3VuZCBpbiBwYWNrYWdlLmpzb25gKTtcbiAgICByZXR1cm4gcGtnW3Byb3BlcnR5XSBhcyBzdHJpbmc7XG4gIH1cbiAgcmV0dXJuIHBrZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFBhY2thZ2VBdHRyaWJ1dGUoXG4gIGF0dHI6IHN0cmluZyxcbiAgdmFsdWU6IHN0cmluZyxcbiAgcDogc3RyaW5nID0gcHJvY2Vzcy5jd2QoKVxuKTogdm9pZCB7XG4gIGNvbnN0IHBrZyA9IGdldFBhY2thZ2UocCkgYXMgUmVjb3JkPHN0cmluZywgYW55PjtcbiAgcGtnW2F0dHJdID0gdmFsdWU7XG4gIHdyaXRlRmlsZShwYXRoLmpvaW4ocCwgYHBhY2thZ2UuanNvbmApLCBKU09OLnN0cmluZ2lmeShwa2csIG51bGwsIDIpKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSB2ZXJzaW9uIGZyb20gcGFja2FnZS5qc29uLlxuICogQHN1bW1hcnkgQSBjb252ZW5pZW5jZSBmdW5jdGlvbiB0aGF0IGNhbGxzIGdldFBhY2thZ2UgdG8gcmV0cmlldmUgdGhlIFwidmVyc2lvblwiIHByb3BlcnR5IGZyb20gcGFja2FnZS5qc29uLlxuICogQHBhcmFtIHtzdHJpbmd9IFtwPXByb2Nlc3MuY3dkKCldIC0gVGhlIGRpcmVjdG9yeSBwYXRoIHdoZXJlIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBpcyBsb2NhdGVkLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgdmVyc2lvbiBzdHJpbmcgZnJvbSBwYWNrYWdlLmpzb24uXG4gKiBAZnVuY3Rpb24gZ2V0UGFja2FnZVZlcnNpb25cbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZnMtdXRpbHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFBhY2thZ2VWZXJzaW9uKHAgPSBwcm9jZXNzLmN3ZCgpKTogc3RyaW5nIHtcbiAgcmV0dXJuIGdldFBhY2thZ2UocCwgXCJ2ZXJzaW9uXCIpIGFzIHN0cmluZztcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGFsbCBkZXBlbmRlbmNpZXMgZnJvbSB0aGUgcHJvamVjdC5cbiAqIEBzdW1tYXJ5IEV4ZWN1dGVzICducG0gbHMgLS1qc29uJyBjb21tYW5kIHRvIGdldCBhIGRldGFpbGVkIGxpc3Qgb2YgYWxsIGRlcGVuZGVuY2llcyAocHJvZHVjdGlvbiwgZGV2ZWxvcG1lbnQsIGFuZCBwZWVyKSBhbmQgdGhlaXIgdmVyc2lvbnMuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3BhdGg9cHJvY2Vzcy5jd2QoKV0gLSBUaGUgZGlyZWN0b3J5IHBhdGggb2YgdGhlIHByb2plY3QuXG4gKiBAcmV0dXJuIHtQcm9taXNlPHtwcm9kOiBBcnJheTx7bmFtZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmd9PiwgZGV2OiBBcnJheTx7bmFtZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmd9PiwgcGVlcjogQXJyYXk8e25hbWU6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nfT59Pn0gQW4gb2JqZWN0IGNvbnRhaW5pbmcgYXJyYXlzIG9mIHByb2R1Y3Rpb24sIGRldmVsb3BtZW50LCBhbmQgcGVlciBkZXBlbmRlbmNpZXMuXG4gKiBAZnVuY3Rpb24gZ2V0RGVwZW5kZW5jaWVzXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCBnZXREZXBlbmRlbmNpZXNcbiAqICAgcGFydGljaXBhbnQgcnVuQ29tbWFuZFxuICogICBwYXJ0aWNpcGFudCBKU09OXG4gKiAgIENhbGxlci0+PmdldERlcGVuZGVuY2llczogQ2FsbCB3aXRoIG9wdGlvbmFsIHBhdGhcbiAqICAgZ2V0RGVwZW5kZW5jaWVzLT4+cnVuQ29tbWFuZDogRXhlY3V0ZSAnbnBtIGxzIC0tanNvbidcbiAqICAgcnVuQ29tbWFuZC0tPj5nZXREZXBlbmRlbmNpZXM6IFJldHVybiBjb21tYW5kIG91dHB1dFxuICogICBnZXREZXBlbmRlbmNpZXMtPj5KU09OOiBQYXJzZSBjb21tYW5kIG91dHB1dFxuICogICBKU09OLS0+PmdldERlcGVuZGVuY2llczogUmV0dXJuIHBhcnNlZCBvYmplY3RcbiAqICAgZ2V0RGVwZW5kZW5jaWVzLT4+Z2V0RGVwZW5kZW5jaWVzOiBQcm9jZXNzIGRlcGVuZGVuY2llc1xuICogICBnZXREZXBlbmRlbmNpZXMtLT4+Q2FsbGVyOiBSZXR1cm4gcHJvY2Vzc2VkIGRlcGVuZGVuY2llc1xuICogQG1lbWJlck9mIG1vZHVsZTpmcy11dGlsc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RGVwZW5kZW5jaWVzKFxuICBwYXRoOiBzdHJpbmcgPSBwcm9jZXNzLmN3ZCgpXG4pOiBQcm9taXNlPERlcGVuZGVuY3lNYXA+IHtcbiAgbGV0IHBrZzogYW55O1xuXG4gIHRyeSB7XG4gICAgcGtnID0gSlNPTi5wYXJzZShhd2FpdCBydW5Db21tYW5kKGBucG0gbHMgLS1qc29uYCwgeyBjd2Q6IHBhdGggfSkucHJvbWlzZSk7XG4gIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byByZXRyaWV2ZSBkZXBlbmRlbmNpZXM6ICR7ZX1gKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgY29uc3QgbWFwcGVyID0gKGVudHJ5OiBbc3RyaW5nLCB1bmtub3duXSwgaW5kZXg6IG51bWJlcikgPT4gKHtcbiAgICBuYW1lOiBlbnRyeVswXSxcbiAgICB2ZXJzaW9uOiAoZW50cnlbMV0gYXMgYW55KS52ZXJzaW9uLFxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIHByb2Q6IE9iamVjdC5lbnRyaWVzKHBrZy5kZXBlbmRlbmNpZXMgfHwge30pLm1hcChtYXBwZXIpLFxuICAgIGRldjogT2JqZWN0LmVudHJpZXMocGtnLmRldkRlcGVuZGVuY2llcyB8fCB7fSkubWFwKG1hcHBlciksXG4gICAgcGVlcjogT2JqZWN0LmVudHJpZXMocGtnLnBlZXJEZXBlbmRlbmNpZXMgfHwge30pLm1hcChtYXBwZXIpLFxuICB9O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdXBkYXRlRGVwZW5kZW5jaWVzKCkge1xuICBjb25zdCBsb2cgPSBsb2dnZXIuZm9yKHVwZGF0ZURlcGVuZGVuY2llcyk7XG4gIGxvZy5pbmZvKFwiY2hlY2tpbmcgZm9yIHVwZGF0ZXMuLi5cIik7XG4gIGF3YWl0IHJ1bkNvbW1hbmQoXCJucHggbnBtLWNoZWNrLXVwZGF0ZXMgLXVcIikucHJvbWlzZTtcbiAgbG9nLmluZm8oXCJ1cGRhdGluZy4uLlwiKTtcbiAgYXdhaXQgcnVuQ29tbWFuZChcIm5weCBucG0gcnVuIGRvLWluc3RhbGxcIikucHJvbWlzZTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluc3RhbGxJZk5vdEF2YWlsYWJsZShcbiAgZGVwczogc3RyaW5nW10gfCBzdHJpbmcsXG4gIGRlcGVuZGVuY2llcz86IFNpbXBsZURlcGVuZGVuY3lNYXBcbikge1xuICBpZiAoIWRlcGVuZGVuY2llcykge1xuICAgIGNvbnN0IGQ6IERlcGVuZGVuY3lNYXAgPSBhd2FpdCBnZXREZXBlbmRlbmNpZXMoKTtcbiAgICBkZXBlbmRlbmNpZXMgPSB7XG4gICAgICBwcm9kOiBkLnByb2Q/Lm1hcCgocCkgPT4gcC5uYW1lKSB8fCBbXSxcbiAgICAgIGRldjogZC5kZXY/Lm1hcCgoZCkgPT4gZC5uYW1lKSB8fCBbXSxcbiAgICAgIHBlZXI6IGQucGVlcj8ubWFwKChwKSA9PiBwLm5hbWUpIHx8IFtdLFxuICAgIH07XG4gIH1cbiAgY29uc3QgeyBwcm9kLCBkZXYsIHBlZXIgfSA9IGRlcGVuZGVuY2llcztcbiAgY29uc3QgaW5zdGFsbGVkID0gQXJyYXkuZnJvbShcbiAgICBuZXcgU2V0KFsuLi4ocHJvZCB8fCBbXSksIC4uLihkZXYgfHwgW10pLCAuLi4ocGVlciB8fCBbXSldKVxuICApO1xuICBkZXBzID0gdHlwZW9mIGRlcHMgPT09IFwic3RyaW5nXCIgPyBbZGVwc10gOiBkZXBzO1xuICBjb25zdCB0b0luc3RhbGwgPSBkZXBzLmZpbHRlcigoZCkgPT4gIWluc3RhbGxlZC5pbmNsdWRlcyhkKSk7XG5cbiAgaWYgKHRvSW5zdGFsbC5sZW5ndGgpIGF3YWl0IGluc3RhbGxEZXBlbmRlbmNpZXMoeyBkZXY6IHRvSW5zdGFsbCB9KTtcbiAgZGVwZW5kZW5jaWVzLmRldiA9IGRlcGVuZGVuY2llcy5kZXYgfHwgW107XG4gIGRlcGVuZGVuY2llcy5kZXYucHVzaCguLi50b0luc3RhbGwpO1xuICByZXR1cm4gZGVwZW5kZW5jaWVzO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHVzaFRvR2l0KCkge1xuICBjb25zdCBsb2cgPSBsb2dnZXIuZm9yKHB1c2hUb0dpdCk7XG4gIGNvbnN0IGdpdFVzZXIgPSBhd2FpdCBydW5Db21tYW5kKFwiZ2l0IGNvbmZpZyB1c2VyLm5hbWVcIikucHJvbWlzZTtcbiAgY29uc3QgZ2l0RW1haWwgPSBhd2FpdCBydW5Db21tYW5kKFwiZ2l0IGNvbmZpZyB1c2VyLmVtYWlsXCIpLnByb21pc2U7XG4gIGxvZy52ZXJib3NlKGBjYWNoZWQgZ2l0IGlkOiAke2dpdFVzZXJ9LyR7Z2l0RW1haWx9LiBjaGFuZ2luZyB0byBhdXRvbWF0aW9uYCk7XG4gIGF3YWl0IHJ1bkNvbW1hbmQoJ2dpdCBjb25maWcgdXNlci5lbWFpbCBcImF1dG9tYXRpb25AZGVjYWYudHNcIicpLnByb21pc2U7XG4gIGF3YWl0IHJ1bkNvbW1hbmQoJ2dpdCBjb25maWcgdXNlci5uYW1lIFwiZGVjYWZcIicpLnByb21pc2U7XG4gIGxvZy5pbmZvKFwiUHVzaGluZyBjaGFuZ2VzIHRvIGdpdC4uLlwiKTtcbiAgYXdhaXQgcnVuQ29tbWFuZChcImdpdCBhZGQgLlwiKS5wcm9taXNlO1xuICBhd2FpdCBydW5Db21tYW5kKGBnaXQgY29tbWl0IC1tIFwicmVmcyAjMSAtIGFmdGVyIHJlcG8gc2V0dXBcImApLnByb21pc2U7XG4gIGF3YWl0IHJ1bkNvbW1hbmQoXCJnaXQgcHVzaFwiKS5wcm9taXNlO1xuICBhd2FpdCBydW5Db21tYW5kKGBnaXQgY29uZmlnIHVzZXIuZW1haWwgXCIke2dpdEVtYWlsfVwiYCkucHJvbWlzZTtcbiAgYXdhaXQgcnVuQ29tbWFuZChgZ2l0IGNvbmZpZyB1c2VyLm5hbWUgXCIke2dpdFVzZXJ9XCJgKS5wcm9taXNlO1xuICBsb2cudmVyYm9zZShgcmV2ZXJ0ZWQgdG8gZ2l0IGlkOiAke2dpdFVzZXJ9LyR7Z2l0RW1haWx9YCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbnN0YWxsRGVwZW5kZW5jaWVzKGRlcGVuZGVuY2llczoge1xuICBwcm9kPzogc3RyaW5nW107XG4gIGRldj86IHN0cmluZ1tdO1xuICBwZWVyPzogc3RyaW5nW107XG59KSB7XG4gIGNvbnN0IGxvZyA9IGxvZ2dlci5mb3IoaW5zdGFsbERlcGVuZGVuY2llcyk7XG4gIGNvbnN0IHByb2QgPSBkZXBlbmRlbmNpZXMucHJvZCB8fCBbXTtcbiAgY29uc3QgZGV2ID0gZGVwZW5kZW5jaWVzLmRldiB8fCBbXTtcbiAgY29uc3QgcGVlciA9IGRlcGVuZGVuY2llcy5wZWVyIHx8IFtdO1xuICBpZiAocHJvZC5sZW5ndGgpIHtcbiAgICBsb2cuaW5mbyhgSW5zdGFsbGluZyBkZXBlbmRlbmNpZXMgJHtwcm9kLmpvaW4oXCIsIFwiKX0uLi5gKTtcbiAgICBhd2FpdCBydW5Db21tYW5kKGBucG0gaW5zdGFsbCAke3Byb2Quam9pbihcIiBcIil9YCwgeyBjd2Q6IHByb2Nlc3MuY3dkKCkgfSlcbiAgICAgIC5wcm9taXNlO1xuICB9XG4gIGlmIChkZXYubGVuZ3RoKSB7XG4gICAgbG9nLmluZm8oYEluc3RhbGxpbmcgZGV2RGVwZW5kZW5jaWVzICR7ZGV2LmpvaW4oXCIsIFwiKX0uLi5gKTtcbiAgICBhd2FpdCBydW5Db21tYW5kKGBucG0gaW5zdGFsbCAtLXNhdmUtZGV2ICR7ZGV2LmpvaW4oXCIgXCIpfWAsIHtcbiAgICAgIGN3ZDogcHJvY2Vzcy5jd2QoKSxcbiAgICB9KS5wcm9taXNlO1xuICB9XG4gIGlmIChwZWVyLmxlbmd0aCkge1xuICAgIGxvZy5pbmZvKGBJbnN0YWxsaW5nIHBlZXJEZXBlbmRlbmNpZXMgJHtwZWVyLmpvaW4oXCIsIFwiKX0uLi5gKTtcbiAgICBhd2FpdCBydW5Db21tYW5kKGBucG0gaW5zdGFsbCAtLXNhdmUtcGVlciAke3BlZXIuam9pbihcIiBcIil9YCwge1xuICAgICAgY3dkOiBwcm9jZXNzLmN3ZCgpLFxuICAgIH0pLnByb21pc2U7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG5vcm1hbGl6ZUltcG9ydDxUPihcbiAgaW1wb3J0UHJvbWlzZTogUHJvbWlzZTxUPlxuKTogUHJvbWlzZTxUPiB7XG4gIC8vIENvbW1vbkpTJ3MgYG1vZHVsZS5leHBvcnRzYCBpcyB3cmFwcGVkIGFzIGBkZWZhdWx0YCBpbiBFU01vZHVsZS5cbiAgcmV0dXJuIGltcG9ydFByb21pc2UudGhlbigobTogYW55KSA9PiAobS5kZWZhdWx0IHx8IG0pIGFzIFQpO1xufVxuIl19
@@ -0,0 +1,70 @@
1
+ import https from "https";
2
+ import { Logging } from "../output/logging";
3
+ /**
4
+ * @description A simple HTTP client for downloading files.
5
+ * @summary This class provides functionality to download files from HTTPS URLs.
6
+ * It uses Node.js built-in https module to make requests.
7
+ *
8
+ * @class
9
+ */
10
+ export class HttpClient {
11
+ static { this.log = Logging.for(HttpClient); }
12
+ /**
13
+ * @description Downloads a file from a given URL.
14
+ * @summary This method sends a GET request to the specified URL and returns the response body as a string.
15
+ * It handles different scenarios such as non-200 status codes and network errors.
16
+ *
17
+ * @param url - The URL of the file to download.
18
+ * @return A promise that resolves with the file content as a string.
19
+ *
20
+ * @mermaid
21
+ * sequenceDiagram
22
+ * participant Client
23
+ * participant HttpClient
24
+ * participant HTTPS
25
+ * participant Server
26
+ * Client->>HttpClient: downloadFile(url)
27
+ * HttpClient->>HTTPS: get(url)
28
+ * HTTPS->>Server: GET request
29
+ * Server-->>HTTPS: Response
30
+ * HTTPS-->>HttpClient: Response object
31
+ * alt Status code is 200
32
+ * loop For each data chunk
33
+ * HTTPS->>HttpClient: 'data' event
34
+ * HttpClient->>HttpClient: Accumulate data
35
+ * end
36
+ * HTTPS->>HttpClient: 'end' event
37
+ * HttpClient-->>Client: Resolve with data
38
+ * else Status code is not 200
39
+ * HttpClient-->>Client: Reject with error
40
+ * end
41
+ */
42
+ static async downloadFile(url) {
43
+ return new Promise((resolve, reject) => {
44
+ function request(url) {
45
+ url = encodeURI(url);
46
+ https.get(url, (res) => {
47
+ if (res.statusCode === 301 || res.statusCode === 307)
48
+ return request(res.headers.location);
49
+ if (res.statusCode !== 200) {
50
+ HttpClient.log.error(`Failed to fetch ${url} (status: ${res.statusCode})`);
51
+ return reject(new Error(`Failed to fetch ${url}`));
52
+ }
53
+ let data = "";
54
+ res.on("data", (chunk) => {
55
+ data += chunk;
56
+ });
57
+ res.on("error", (error) => {
58
+ reject(error);
59
+ });
60
+ res.on("end", () => {
61
+ resolve(data);
62
+ });
63
+ });
64
+ }
65
+ request(url);
66
+ });
67
+ }
68
+ }
69
+
70
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy91dGlscy9odHRwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMxQixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFNUM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxPQUFPLFVBQVU7YUFDSixRQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMvQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0E2Qkc7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUFXO1FBQ25DLE9BQU8sSUFBSSxPQUFPLENBQVMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDN0MsU0FBUyxPQUFPLENBQUMsR0FBVztnQkFDMUIsR0FBRyxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDckIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtvQkFDckIsSUFBSSxHQUFHLENBQUMsVUFBVSxLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsVUFBVSxLQUFLLEdBQUc7d0JBQ2xELE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsUUFBa0IsQ0FBQyxDQUFDO29CQUVqRCxJQUFJLEdBQUcsQ0FBQyxVQUFVLEtBQUssR0FBRyxFQUFFLENBQUM7d0JBQzNCLFVBQVUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNsQixtQkFBbUIsR0FBRyxhQUFhLEdBQUcsQ0FBQyxVQUFVLEdBQUcsQ0FDckQsQ0FBQzt3QkFDRixPQUFPLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUNyRCxDQUFDO29CQUNELElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztvQkFDZCxHQUFHLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFO3dCQUN2QixJQUFJLElBQUksS0FBSyxDQUFDO29CQUNoQixDQUFDLENBQUMsQ0FBQztvQkFDSCxHQUFHLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFO3dCQUN4QixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ2hCLENBQUMsQ0FBQyxDQUFDO29CQUVILEdBQUcsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRTt3QkFDakIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUNoQixDQUFDLENBQUMsQ0FBQztnQkFDTCxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7WUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDZixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMiLCJmaWxlIjoidXRpbHMvaHR0cC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBodHRwcyBmcm9tIFwiaHR0cHNcIjtcbmltcG9ydCB7IExvZ2dpbmcgfSBmcm9tIFwiLi4vb3V0cHV0L2xvZ2dpbmdcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQSBzaW1wbGUgSFRUUCBjbGllbnQgZm9yIGRvd25sb2FkaW5nIGZpbGVzLlxuICogQHN1bW1hcnkgVGhpcyBjbGFzcyBwcm92aWRlcyBmdW5jdGlvbmFsaXR5IHRvIGRvd25sb2FkIGZpbGVzIGZyb20gSFRUUFMgVVJMcy5cbiAqIEl0IHVzZXMgTm9kZS5qcyBidWlsdC1pbiBodHRwcyBtb2R1bGUgdG8gbWFrZSByZXF1ZXN0cy5cbiAqXG4gKiBAY2xhc3NcbiAqL1xuZXhwb3J0IGNsYXNzIEh0dHBDbGllbnQge1xuICBwcm90ZWN0ZWQgc3RhdGljIGxvZyA9IExvZ2dpbmcuZm9yKEh0dHBDbGllbnQpO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERvd25sb2FkcyBhIGZpbGUgZnJvbSBhIGdpdmVuIFVSTC5cbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2Qgc2VuZHMgYSBHRVQgcmVxdWVzdCB0byB0aGUgc3BlY2lmaWVkIFVSTCBhbmQgcmV0dXJucyB0aGUgcmVzcG9uc2UgYm9keSBhcyBhIHN0cmluZy5cbiAgICogSXQgaGFuZGxlcyBkaWZmZXJlbnQgc2NlbmFyaW9zIHN1Y2ggYXMgbm9uLTIwMCBzdGF0dXMgY29kZXMgYW5kIG5ldHdvcmsgZXJyb3JzLlxuICAgKlxuICAgKiBAcGFyYW0gdXJsIC0gVGhlIFVSTCBvZiB0aGUgZmlsZSB0byBkb3dubG9hZC5cbiAgICogQHJldHVybiBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBmaWxlIGNvbnRlbnQgYXMgYSBzdHJpbmcuXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IEh0dHBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBIVFRQU1xuICAgKiAgIHBhcnRpY2lwYW50IFNlcnZlclxuICAgKiAgIENsaWVudC0+Pkh0dHBDbGllbnQ6IGRvd25sb2FkRmlsZSh1cmwpXG4gICAqICAgSHR0cENsaWVudC0+PkhUVFBTOiBnZXQodXJsKVxuICAgKiAgIEhUVFBTLT4+U2VydmVyOiBHRVQgcmVxdWVzdFxuICAgKiAgIFNlcnZlci0tPj5IVFRQUzogUmVzcG9uc2VcbiAgICogICBIVFRQUy0tPj5IdHRwQ2xpZW50OiBSZXNwb25zZSBvYmplY3RcbiAgICogICBhbHQgU3RhdHVzIGNvZGUgaXMgMjAwXG4gICAqICAgICBsb29wIEZvciBlYWNoIGRhdGEgY2h1bmtcbiAgICogICAgICAgSFRUUFMtPj5IdHRwQ2xpZW50OiAnZGF0YScgZXZlbnRcbiAgICogICAgICAgSHR0cENsaWVudC0+Pkh0dHBDbGllbnQ6IEFjY3VtdWxhdGUgZGF0YVxuICAgKiAgICAgZW5kXG4gICAqICAgICBIVFRQUy0+Pkh0dHBDbGllbnQ6ICdlbmQnIGV2ZW50XG4gICAqICAgICBIdHRwQ2xpZW50LS0+PkNsaWVudDogUmVzb2x2ZSB3aXRoIGRhdGFcbiAgICogICBlbHNlIFN0YXR1cyBjb2RlIGlzIG5vdCAyMDBcbiAgICogICAgIEh0dHBDbGllbnQtLT4+Q2xpZW50OiBSZWplY3Qgd2l0aCBlcnJvclxuICAgKiAgIGVuZFxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGRvd25sb2FkRmlsZSh1cmw6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHN0cmluZz4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZnVuY3Rpb24gcmVxdWVzdCh1cmw6IHN0cmluZykge1xuICAgICAgICB1cmwgPSBlbmNvZGVVUkkodXJsKTtcbiAgICAgICAgaHR0cHMuZ2V0KHVybCwgKHJlcykgPT4ge1xuICAgICAgICAgIGlmIChyZXMuc3RhdHVzQ29kZSA9PT0gMzAxIHx8IHJlcy5zdGF0dXNDb2RlID09PSAzMDcpXG4gICAgICAgICAgICByZXR1cm4gcmVxdWVzdChyZXMuaGVhZGVycy5sb2NhdGlvbiBhcyBzdHJpbmcpO1xuXG4gICAgICAgICAgaWYgKHJlcy5zdGF0dXNDb2RlICE9PSAyMDApIHtcbiAgICAgICAgICAgIEh0dHBDbGllbnQubG9nLmVycm9yKFxuICAgICAgICAgICAgICBgRmFpbGVkIHRvIGZldGNoICR7dXJsfSAoc3RhdHVzOiAke3Jlcy5zdGF0dXNDb2RlfSlgXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBmZXRjaCAke3VybH1gKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxldCBkYXRhID0gXCJcIjtcbiAgICAgICAgICByZXMub24oXCJkYXRhXCIsIChjaHVuaykgPT4ge1xuICAgICAgICAgICAgZGF0YSArPSBjaHVuaztcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXMub24oXCJlcnJvclwiLCAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICByZXMub24oXCJlbmRcIiwgKCkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXF1ZXN0KHVybCk7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,9 @@
1
+ export * from "./constants";
2
+ export * from "./environment";
3
+ export * from "./fs";
4
+ export * from "./http";
5
+ export * from "./text";
6
+ export * from "./types";
7
+ export * from "./utils";
8
+
9
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy91dGlscy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLGVBQWUsQ0FBQztBQUM5QixjQUFjLE1BQU0sQ0FBQztBQUNyQixjQUFjLFFBQVEsQ0FBQztBQUN2QixjQUFjLFFBQVEsQ0FBQztBQUN2QixjQUFjLFNBQVMsQ0FBQztBQUN4QixjQUFjLFNBQVMsQ0FBQyIsImZpbGUiOiJ1dGlscy9pbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gXCIuL2NvbnN0YW50c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZW52aXJvbm1lbnRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9odHRwXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90ZXh0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbHNcIjtcbiJdfQ==
@@ -0,0 +1,3 @@
1
+ export {};
2
+
3
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy91dGlscy9tZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwiZmlsZSI6InV0aWxzL21kLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZGVzY3JpcHRpb24gU2luZ2xlIGxpbmUgbWFya2Rvd24gZWxlbWVudCB0eXBlXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIHRoZSBwb3NzaWJsZSBoZWFkZXIgbGV2ZWxzIGluIG1hcmtkb3duXG4gKiBAdHlwZWRlZiB7XCJoMVwifFwiaDJcInxcImgzXCJ8XCJoNFwifFwiaDVcInxcImg2XCJ9IE1kU2luZ2xlTGluZUVsZW1lbnRcbiAqIEBtZW1iZXJPZiBAZGVjYWYtdHMvdXRpbHNcbiAqL1xuZXhwb3J0IHR5cGUgTWRTaW5nbGVMaW5lRWxlbWVudCA9IFwiaDFcIiB8IFwiaDJcIiB8IFwiaDNcIiB8IFwiaDRcIiB8IFwiaDVcIiB8IFwiaDZcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTXVsdGktbGluZSBlbGVtZW50IHR5cGVzIGluIG1hcmtkb3duXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBhdmFpbGFibGUgbXVsdGktbGluZSBlbGVtZW50IHR5cGVzXG4gKiBAdHlwZWRlZiB7XCJwXCJ8XCJibG9ja3F1b3RlXCJ9IE1kTXVsdGlMaW5lRWxlbWVudFxuICogQG1lbWJlck9mIEBkZWNhZi10cy91dGlsc1xuICovXG5leHBvcnQgdHlwZSBNZE11bHRpTGluZUVsZW1lbnQgPSBcInBcIiB8IFwiYmxvY2txdW90ZVwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBMaXN0IGVsZW1lbnQgdHlwZXMgaW4gbWFya2Rvd25cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGF2YWlsYWJsZSBsaXN0IHR5cGVzXG4gKiBAdHlwZWRlZiB7XCJ1bFwifFwib2xcIn0gTWRMaXN0RWxlbWVudFxuICogQG1lbWJlck9mIEBkZWNhZi10cy91dGlsc1xuICovXG5leHBvcnQgdHlwZSBNZExpc3RFbGVtZW50ID0gXCJ1bFwiIHwgXCJvbFwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBMaXN0IGVsZW1lbnQgdHlwZXMgaW4gbWFya2Rvd25cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGF2YWlsYWJsZSBsaXN0IHR5cGVzXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBNZFNpbmdsZUxpbmVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdWxdIC0gdW5vcmRlcmVkIGxpc3RcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbb2xdIC0gb3JkZXJlZCBsaXN0XG4gKiBAbWVtYmVyT2YgQGRlY2FmLXRzL3V0aWxzXG4gKi9cbmV4cG9ydCB0eXBlIE1kU2luZ2xlTGluZSA9IHtcbiAgW2sgaW4gTWRTaW5nbGVMaW5lRWxlbWVudF0/OiBzdHJpbmc7XG59O1xuLyoqXG4gKiBAZGVzY3JpcHRpb24gTXVsdGktbGluZSBtYXJrZG93biBlbGVtZW50IHR5cGVcbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgbWFya2Rvd24gZWxlbWVudHMgdGhhdCBjYW4gY29udGFpbiBtdWx0aXBsZSBsaW5lcyBvZiB0ZXh0XG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBNZE11bHRpTGluZVxuICogQHByb3BlcnR5IHtzdHJpbmd8c3RyaW5nW119IFtwXSAtIFBhcmFncmFwaCBjb250ZW50XG4gKiBAcHJvcGVydHkge3N0cmluZ3xzdHJpbmdbXX0gW2Jsb2NrcXVvdGVdIC0gQmxvY2txdW90ZSBjb250ZW50XG4gKiBAbWVtYmVyT2YgQGRlY2FmLXRzL3V0aWxzXG4gKi9cbmV4cG9ydCB0eXBlIE1kTXVsdGlMaW5lID0geyBbayBpbiBNZE11bHRpTGluZUVsZW1lbnRdPzogc3RyaW5nIHwgc3RyaW5nW10gfTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gSW1hZ2UgZGVmaW5pdGlvbiB0eXBlIGluIG1hcmtkb3duXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBzdHJ1Y3R1cmUgZm9yIGltYWdlIGVsZW1lbnRzXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBNZEltYWdlRGVmaW5pdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IFt0aXRsZV0gLSBPcHRpb25hbCBpbWFnZSB0aXRsZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IHNvdXJjZSAtIEltYWdlIHNvdXJjZSBVUkxcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbYWx0XSAtIE9wdGlvbmFsIGFsdGVybmF0aXZlIHRleHRcbiAqIEBtZW1iZXJPZiBAZGVjYWYtdHMvdXRpbHNcbiAqL1xuZXhwb3J0IHR5cGUgTWRJbWFnZURlZmluaXRpb24gPSB7XG4gIHRpdGxlPzogc3RyaW5nO1xuICBzb3VyY2U6IHN0cmluZztcbiAgYWx0Pzogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gSW1hZ2UgZWxlbWVudCB0eXBlIGluIG1hcmtkb3duXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIGFuIGltYWdlIGVsZW1lbnQgd2l0aCBpdHMgcHJvcGVydGllc1xuICogQHR5cGVkZWYge09iamVjdH0gTWRJbWFnZVxuICogQHByb3BlcnR5IHtNZEltYWdlRGVmaW5pdGlvbn0gaW1nIC0gVGhlIGltYWdlIGRlZmluaXRpb24gb2JqZWN0XG4gKiBAbWVtYmVyT2YgQGRlY2FmLXRzL3V0aWxzXG4gKi9cbmV4cG9ydCB0eXBlIE1kSW1hZ2UgPSB7IGltZzogTWRJbWFnZURlZmluaXRpb24gfTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTGlzdCBpdGVtIGVsZW1lbnQgdHlwZSBpbiBtYXJrZG93blxuICogQHN1bW1hcnkgUmVwcmVzZW50cyBvcmRlcmVkIGFuZCB1bm9yZGVyZWQgbGlzdHMgaW4gbWFya2Rvd25cbiAqIEB0eXBlZGVmIHtPYmplY3R9IE1kTGlzdEl0ZW1cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IHVsIC0gVW5vcmRlcmVkIGxpc3QgaXRlbXNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IG9sIC0gT3JkZXJlZCBsaXN0IGl0ZW1zXG4gKiBAbWVtYmVyT2YgQGRlY2FmLXRzL3V0aWxzXG4gKi9cbmV4cG9ydCB0eXBlIE1kTGlzdEl0ZW0gPSB7IFtrIGluIE1kTGlzdEVsZW1lbnRdOiBzdHJpbmdbXSB9O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBUYWJsZSBkZWZpbml0aW9uIHR5cGUgaW4gbWFya2Rvd25cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIHN0cnVjdHVyZSBmb3IgdGFibGUgZWxlbWVudHNcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE1kVGFibGVEZWZpbml0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBoZWFkZXJzIC0gQXJyYXkgb2YgdGFibGUgaGVhZGVyIG5hbWVzXG4gKiBAcHJvcGVydHkge09iamVjdFtdfSByb3dzIC0gQXJyYXkgb2Ygcm93IG9iamVjdHMgY29udGFpbmluZyBjb2x1bW4gdmFsdWVzXG4gKiBAbWVtYmVyT2YgQGRlY2FmLXRzL3V0aWxzXG4gKi9cbmV4cG9ydCB0eXBlIE1kVGFibGVEZWZpbml0aW9uID0ge1xuICBoZWFkZXJzOiBzdHJpbmdbXTtcbiAgcm93czogeyBbY29sdW1uOiBzdHJpbmddOiBzdHJpbmcgfCBzdHJpbmdbXSB9W107XG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBUYWJsZSBlbGVtZW50IHR5cGUgaW4gbWFya2Rvd25cbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSB0YWJsZSBzdHJ1Y3R1cmUgd2l0aCBoZWFkZXJzIGFuZCByb3dzXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBNZFRhYmxlXG4gKiBAcHJvcGVydHkge01kVGFibGVEZWZpbml0aW9ufSB0YWJsZSAtIFRoZSB0YWJsZSBkZWZpbml0aW9uIG9iamVjdFxuICogQG1lbWJlck9mIEBkZWNhZi10cy91dGlsc1xuICovXG5leHBvcnQgdHlwZSBNZFRhYmxlID0geyB0YWJsZTogTWRUYWJsZURlZmluaXRpb24gfTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29kZSBibG9jayBkZWZpbml0aW9uIHR5cGUgaW4gbWFya2Rvd25cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIHN0cnVjdHVyZSBmb3IgY29kZSBibG9ja3NcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE1kQ29kZURlZmluaXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbbGFuZ3VhZ2VdIC0gT3B0aW9uYWwgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2Ugc3BlY2lmaWNhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd8c3RyaW5nW119IGNvbnRlbnQgLSBUaGUgY29kZSBjb250ZW50IGFzIHN0cmluZyBvciBhcnJheSBvZiBzdHJpbmdzXG4gKiBAbWVtYmVyT2YgQGRlY2FmLXRzL3V0aWxzXG4gKi9cbmV4cG9ydCB0eXBlIE1kQ29kZURlZmluaXRpb24gPSB7XG4gIGxhbmd1YWdlPzogc3RyaW5nO1xuICBjb250ZW50OiBzdHJpbmcgfCBzdHJpbmdbXTtcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvZGUgYmxvY2sgZWxlbWVudCB0eXBlIGluIG1hcmtkb3duXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIGEgY29kZSBibG9jayB3aXRoIG9wdGlvbmFsIGxhbmd1YWdlIHNwZWNpZmljYXRpb25cbiAqIEB0eXBlZGVmIHtPYmplY3R9IE1kQ29kZVxuICogQHByb3BlcnR5IHtNZENvZGVEZWZpbml0aW9ufSBjb2RlIC0gVGhlIGNvZGUgYmxvY2sgZGVmaW5pdGlvbiBvYmplY3RcbiAqIEBtZW1iZXJPZiBAZGVjYWYtdHMvdXRpbHNcbiAqL1xuZXhwb3J0IHR5cGUgTWRDb2RlID0geyBjb2RlOiBNZENvZGVEZWZpbml0aW9uIH07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEhvcml6b250YWwgcnVsZSBlbGVtZW50IHR5cGUgaW4gbWFya2Rvd25cbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBob3Jpem9udGFsIHJ1bGUgc2VwYXJhdG9yXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBNZFNlcGFyYXRvclxuICogQHByb3BlcnR5IHtzdHJpbmd9IGhyIC0gVGhlIGhvcml6b250YWwgcnVsZSByZXByZXNlbnRhdGlvblxuICogQG1lbWJlck9mIEBkZWNhZi10cy91dGlsc1xuICovXG5leHBvcnQgdHlwZSBNZFNlcGFyYXRvciA9IHsgaHI6IHN0cmluZyB9O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBMaW5rIGVsZW1lbnQgdHlwZSBpbiBtYXJrZG93blxuICogQHN1bW1hcnkgUmVwcmVzZW50cyBhIGh5cGVybGluayB3aXRoIHRpdGxlIGFuZCBzb3VyY2VcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE1kTGlua1xuICogQHByb3BlcnR5IHt7dGl0bGU6IHN0cmluZywgc291cmNlOiBzdHJpbmd9fSBsaW5rIC0gVGhlIGxpbmsgZGVmaW5pdGlvbiBvYmplY3RcbiAqIEBtZW1iZXJPZiBAZGVjYWYtdHMvdXRpbHNcbiAqL1xuZXhwb3J0IHR5cGUgTWRMaW5rID0ge1xuICBsaW5rOiB7XG4gICAgdGl0bGU6IHN0cmluZztcbiAgICBzb3VyY2U6IHN0cmluZztcbiAgfTtcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1hcmtkb3duIGVsZW1lbnQgdHlwZSBkZWZpbml0aW9uXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIGFsbCBwb3NzaWJsZSBtYXJrZG93biBlbGVtZW50cyB0aGF0IGNhbiBiZSB1c2VkIGluIGRvY3VtZW50IGdlbmVyYXRpb24uXG4gKiBUaGlzIHR5cGUgY29tYmluZXMgdmFyaW91cyBtYXJrZG93biBlbGVtZW50cyBpbmNsdWRpbmcgaGVhZGVycywgcGFyYWdyYXBocywgaW1hZ2VzLCBsaXN0cyxcbiAqIHRhYmxlcywgY29kZSBibG9ja3MsIHNlcGFyYXRvcnMsIGFuZCBsaW5rcyBpbnRvIGEgdW5pb24gdHlwZSBmb3IgZmxleGlibGUgbWFya2Rvd24gY29udGVudCBjcmVhdGlvbi5cbiAqIEB0eXBlZGVmIHsoTWRTaW5nbGVMaW5lIHwgTWRNdWx0aUxpbmUgfCBNZEltYWdlIHwgTWRMaXN0SXRlbSB8IE1kVGFibGUgfCBNZENvZGUgfCBNZFNlcGFyYXRvciB8IE1kTGluayl9IE1kRWxlbWVudHNcbiAqIEBtZW1iZXJPZiBAZGVjYWYtdHMvdXRpbHNcbiAqL1xuZXhwb3J0IHR5cGUgTWRFbGVtZW50cyA9XG4gIHwgTWRTaW5nbGVMaW5lXG4gIHwgTWRNdWx0aUxpbmVcbiAgfCBNZEltYWdlXG4gIHwgTWRMaXN0SXRlbVxuICB8IE1kVGFibGVcbiAgfCBNZENvZGVcbiAgfCBNZFNlcGFyYXRvclxuICB8IE1kTGluaztcbiJdfQ==