sonamu 0.9.19 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +36 -0
  2. package/dist/ai/agents/agent.js +5 -7
  3. package/dist/ai/agents/index.js +1 -2
  4. package/dist/ai/agents/types.js +1 -1
  5. package/dist/ai/index.js +1 -2
  6. package/dist/ai/providers/rtzr/api.js +2 -3
  7. package/dist/ai/providers/rtzr/error.js +14 -29
  8. package/dist/ai/providers/rtzr/index.js +1 -2
  9. package/dist/ai/providers/rtzr/model.js +13 -20
  10. package/dist/ai/providers/rtzr/options.js +2 -3
  11. package/dist/ai/providers/rtzr/provider.js +2 -3
  12. package/dist/ai/providers/rtzr/utils.js +12 -21
  13. package/dist/api/base-frame.js +4 -4
  14. package/dist/api/caster.js +21 -38
  15. package/dist/api/code-converters.js +41 -98
  16. package/dist/api/config.d.ts +1 -10
  17. package/dist/api/config.d.ts.map +1 -1
  18. package/dist/api/config.js +9 -8
  19. package/dist/api/context.js +2 -3
  20. package/dist/api/decorators.js +80 -116
  21. package/dist/api/index.js +2 -3
  22. package/dist/api/secret.js +6 -10
  23. package/dist/api/sonamu.d.ts.map +1 -1
  24. package/dist/api/sonamu.js +200 -387
  25. package/dist/api/validator.js +5 -8
  26. package/dist/api/websocket-helpers.js +21 -32
  27. package/dist/auth/audit-log/builders.js +2 -3
  28. package/dist/auth/audit-log/events.js +2 -2
  29. package/dist/auth/audit-log/plugin.js +30 -61
  30. package/dist/auth/audit-log-ingestor.js +19 -41
  31. package/dist/auth/auth-generator.js +16 -41
  32. package/dist/auth/better-auth-entities.js +3 -4
  33. package/dist/auth/index.js +2 -3
  34. package/dist/auth/knex-adapter.js +18 -45
  35. package/dist/auth/plugins/entity-definitions/admin.js +2 -2
  36. package/dist/auth/plugins/entity-definitions/anonymous.js +2 -2
  37. package/dist/auth/plugins/entity-definitions/api-key.js +2 -2
  38. package/dist/auth/plugins/entity-definitions/audit-log.js +2 -2
  39. package/dist/auth/plugins/entity-definitions/index.js +2 -3
  40. package/dist/auth/plugins/entity-definitions/jwt.js +2 -2
  41. package/dist/auth/plugins/entity-definitions/organization.js +2 -2
  42. package/dist/auth/plugins/entity-definitions/passkey.js +2 -2
  43. package/dist/auth/plugins/entity-definitions/phone-number.js +2 -2
  44. package/dist/auth/plugins/entity-definitions/sso.js +2 -2
  45. package/dist/auth/plugins/entity-definitions/two-factor.js +2 -2
  46. package/dist/auth/plugins/entity-definitions/types.js +1 -1
  47. package/dist/auth/plugins/entity-definitions/username.js +2 -2
  48. package/dist/auth/plugins/index.js +1 -2
  49. package/dist/auth/plugins/wrappers/admin.js +2 -3
  50. package/dist/auth/plugins/wrappers/anonymous.js +2 -3
  51. package/dist/auth/plugins/wrappers/api-key.js +2 -3
  52. package/dist/auth/plugins/wrappers/index.js +1 -2
  53. package/dist/auth/plugins/wrappers/jwt.js +2 -3
  54. package/dist/auth/plugins/wrappers/organization.js +2 -3
  55. package/dist/auth/plugins/wrappers/passkey.js +2 -3
  56. package/dist/auth/plugins/wrappers/phone-number.js +2 -3
  57. package/dist/auth/plugins/wrappers/sso.js +2 -3
  58. package/dist/auth/plugins/wrappers/two-factor.js +2 -3
  59. package/dist/auth/plugins/wrappers/username.js +2 -3
  60. package/dist/bin/build-config.js +2 -2
  61. package/dist/bin/cli.js +151 -258
  62. package/dist/bin/fixture.d.ts.map +1 -1
  63. package/dist/bin/fixture.js +55 -97
  64. package/dist/bin/hmr-hook-register.js +3 -3
  65. package/dist/bin/migrate-targets.d.ts +3 -0
  66. package/dist/bin/migrate-targets.d.ts.map +1 -0
  67. package/dist/bin/migrate-targets.js +11 -0
  68. package/dist/bin/test-command.js +25 -55
  69. package/dist/bin/ts-loader-register.js +5 -6
  70. package/dist/bin/ts-loader-registration.js +6 -13
  71. package/dist/cache/cache-manager.js +3 -4
  72. package/dist/cache/decorator.js +11 -21
  73. package/dist/cache/drivers.js +2 -3
  74. package/dist/cache/index.js +2 -3
  75. package/dist/cache/types.js +1 -1
  76. package/dist/cache-control/cache-control.js +21 -34
  77. package/dist/cache-control/types.js +1 -1
  78. package/dist/compress/compress.js +10 -10
  79. package/dist/compress/index.js +1 -2
  80. package/dist/compress/types.js +1 -1
  81. package/dist/cone/cone-generator.js +25 -63
  82. package/dist/database/_batch_update.js +26 -46
  83. package/dist/database/base-model.js +44 -97
  84. package/dist/database/base-model.types.js +1 -1
  85. package/dist/database/db.d.ts +8 -14
  86. package/dist/database/db.d.ts.map +1 -1
  87. package/dist/database/db.js +127 -72
  88. package/dist/database/knex.js +5 -8
  89. package/dist/database/puri-subset.types.js +1 -1
  90. package/dist/database/puri-wrapper.js +11 -15
  91. package/dist/database/puri.js +117 -234
  92. package/dist/database/puri.types.js +3 -4
  93. package/dist/database/transaction-context.js +4 -5
  94. package/dist/database/upsert-builder.js +109 -176
  95. package/dist/dict/en.d.ts +1 -0
  96. package/dist/dict/en.d.ts.map +1 -1
  97. package/dist/dict/en.js +4 -4
  98. package/dist/dict/index.js +2 -3
  99. package/dist/dict/ko.d.ts +1 -0
  100. package/dist/dict/ko.d.ts.map +1 -1
  101. package/dist/dict/ko.js +4 -4
  102. package/dist/dict/rc-keys.js +3 -4
  103. package/dist/dict/sd.js +8 -19
  104. package/dist/dict/sonamu-dictionary.js +141 -284
  105. package/dist/dict/types.js +1 -1
  106. package/dist/dict/utils.js +4 -5
  107. package/dist/entity/entity-manager.d.ts +2 -2
  108. package/dist/entity/entity-manager.js +34 -82
  109. package/dist/entity/entity-template-cone.js +33 -66
  110. package/dist/entity/entity.js +156 -310
  111. package/dist/env.d.ts +14 -0
  112. package/dist/env.d.ts.map +1 -0
  113. package/dist/env.js +75 -0
  114. package/dist/exceptions/error-handler.js +2 -3
  115. package/dist/exceptions/so-exceptions.js +7 -5
  116. package/dist/filter/index.js +1 -2
  117. package/dist/filter/types.js +3 -4
  118. package/dist/filter/utils.js +21 -54
  119. package/dist/index.js +8 -7
  120. package/dist/logger/category.js +6 -12
  121. package/dist/logger/configure.js +23 -34
  122. package/dist/migration/code-generation.js +146 -314
  123. package/dist/migration/index-where-predicate.js +52 -144
  124. package/dist/migration/migration-set.js +19 -33
  125. package/dist/migration/migrator.d.ts +2 -0
  126. package/dist/migration/migrator.d.ts.map +1 -1
  127. package/dist/migration/migrator.js +69 -53
  128. package/dist/migration/postgresql-schema-reader.js +126 -225
  129. package/dist/migration/slack-confirm.d.ts +1 -0
  130. package/dist/migration/slack-confirm.d.ts.map +1 -1
  131. package/dist/migration/slack-confirm.js +28 -38
  132. package/dist/migration/types.js +1 -1
  133. package/dist/naite/messaging-types.js +1 -1
  134. package/dist/naite/naite-reporter.js +15 -32
  135. package/dist/naite/naite.js +43 -76
  136. package/dist/ssr/index.js +6 -9
  137. package/dist/ssr/registry.js +10 -18
  138. package/dist/ssr/renderer.js +10 -21
  139. package/dist/ssr/types.js +1 -1
  140. package/dist/storage/base-file.js +5 -10
  141. package/dist/storage/buffered-file.js +3 -4
  142. package/dist/storage/drivers.js +2 -3
  143. package/dist/storage/index.js +2 -3
  144. package/dist/storage/s3-driver.js +5 -9
  145. package/dist/storage/storage-manager.js +5 -5
  146. package/dist/storage/types.js +1 -1
  147. package/dist/storage/uploaded-file.js +4 -6
  148. package/dist/stream/index.js +1 -2
  149. package/dist/stream/sse.js +8 -13
  150. package/dist/stream/ws-audience-resolver.js +5 -5
  151. package/dist/stream/ws-audience.js +3 -4
  152. package/dist/stream/ws-cluster-bus.js +3 -4
  153. package/dist/stream/ws-core.js +1 -1
  154. package/dist/stream/ws-delivery.js +11 -25
  155. package/dist/stream/ws-local-connection-store.js +9 -18
  156. package/dist/stream/ws-presence-store.js +43 -97
  157. package/dist/stream/ws-registry.js +17 -22
  158. package/dist/stream/ws-telemetry-memory.js +38 -45
  159. package/dist/stream/ws-telemetry-trace.js +4 -6
  160. package/dist/stream/ws-telemetry.js +82 -135
  161. package/dist/stream/ws.js +47 -91
  162. package/dist/syncer/api-parser.js +81 -147
  163. package/dist/syncer/checksum.js +9 -20
  164. package/dist/syncer/code-generator.js +29 -47
  165. package/dist/syncer/entity-operations.js +17 -27
  166. package/dist/syncer/event-batcher.js +8 -15
  167. package/dist/syncer/file-patterns.js +3 -4
  168. package/dist/syncer/file-tracking.js +6 -10
  169. package/dist/syncer/index.js +1 -2
  170. package/dist/syncer/module-loader.js +10 -26
  171. package/dist/syncer/syncer-actions.js +19 -37
  172. package/dist/syncer/syncer.js +46 -98
  173. package/dist/syncer/watcher.js +12 -26
  174. package/dist/tasks/decorator.js +7 -11
  175. package/dist/tasks/step-wrapper.js +7 -8
  176. package/dist/tasks/workflow-manager.js +18 -25
  177. package/dist/template/entity-converter.js +40 -64
  178. package/dist/template/helpers.js +32 -63
  179. package/dist/template/implementations/entity.template.js +7 -11
  180. package/dist/template/implementations/entry-server.template.js +2 -3
  181. package/dist/template/implementations/generated.template.js +25 -51
  182. package/dist/template/implementations/generated_http.template.js +31 -58
  183. package/dist/template/implementations/generated_sso.template.js +45 -85
  184. package/dist/template/implementations/init_types.template.js +4 -7
  185. package/dist/template/implementations/model.template.js +5 -10
  186. package/dist/template/implementations/model_test.template.js +2 -3
  187. package/dist/template/implementations/queries.template.js +4 -7
  188. package/dist/template/implementations/sd.template.js +17 -35
  189. package/dist/template/implementations/services.template.js +18 -30
  190. package/dist/template/implementations/view_form.template.js +72 -125
  191. package/dist/template/implementations/view_id_all_select.template.js +2 -3
  192. package/dist/template/implementations/view_list.template.js +86 -143
  193. package/dist/template/implementations/view_search_input.template.js +2 -3
  194. package/dist/template/index.js +5 -8
  195. package/dist/template/template-manager.js +13 -26
  196. package/dist/template/template-types.js +2 -3
  197. package/dist/template/template.js +7 -11
  198. package/dist/template/zod-converter.js +173 -348
  199. package/dist/testing/_relation-graph.js +18 -37
  200. package/dist/testing/bootstrap.js +5 -8
  201. package/dist/testing/data-explorer.js +34 -78
  202. package/dist/testing/dev-test-routes.js +54 -60
  203. package/dist/testing/dev-vitest-manager.js +33 -84
  204. package/dist/testing/faker-mappings.js +3 -4
  205. package/dist/testing/fixture-generator.d.ts +2 -1
  206. package/dist/testing/fixture-generator.d.ts.map +1 -1
  207. package/dist/testing/fixture-generator.js +159 -321
  208. package/dist/testing/fixture-loader.js +2 -2
  209. package/dist/testing/fixture-manager.d.ts.map +1 -1
  210. package/dist/testing/fixture-manager.js +124 -227
  211. package/dist/testing/global-setup.d.ts.map +1 -1
  212. package/dist/testing/global-setup.js +29 -17
  213. package/dist/testing/index.js +1 -2
  214. package/dist/testing/naite-vitest-reporter.js +2 -3
  215. package/dist/testing/parallel-db-manager.js +5 -3
  216. package/dist/testing/vitest-helpers.d.ts.map +1 -1
  217. package/dist/testing/vitest-helpers.js +15 -12
  218. package/dist/types/types.d.ts +14 -14
  219. package/dist/types/types.js +27 -50
  220. package/dist/ui/ai-api.js +6 -11
  221. package/dist/ui/ai-client.js +86 -134
  222. package/dist/ui/api.js +99 -195
  223. package/dist/ui/cdd-service.js +78 -130
  224. package/dist/ui/cdd-types.js +1 -1
  225. package/dist/ui-web/assets/{index-Df8q-fhb.js → index-DFStGyd0.js} +49 -49
  226. package/dist/ui-web/assets/index-Dx4ap5i4.css +1 -0
  227. package/dist/ui-web/index.html +2 -2
  228. package/dist/utils/async-utils.js +13 -25
  229. package/dist/utils/class-name.js +3 -4
  230. package/dist/utils/console-util.js +11 -26
  231. package/dist/utils/controller.d.ts.map +1 -1
  232. package/dist/utils/controller.js +14 -12
  233. package/dist/utils/esm-utils.js +5 -8
  234. package/dist/utils/formatter.js +10 -22
  235. package/dist/utils/fs-utils.js +14 -25
  236. package/dist/utils/lodash-able.js +3 -4
  237. package/dist/utils/model.js +7 -14
  238. package/dist/utils/object-utils.js +41 -73
  239. package/dist/utils/path-utils.js +5 -9
  240. package/dist/utils/process-utils.js +4 -7
  241. package/dist/utils/sql-parser.js +6 -13
  242. package/dist/utils/type-utils.js +16 -26
  243. package/dist/utils/utils.js +18 -40
  244. package/dist/utils/zod-error.js +9 -16
  245. package/dist/vector/chunking.js +24 -37
  246. package/dist/vector/config.js +2 -2
  247. package/dist/vector/embedding.js +8 -19
  248. package/dist/vector/index.js +1 -2
  249. package/dist/vector/types.js +1 -1
  250. package/package.json +7 -7
  251. package/src/__tests__/env.test.ts +127 -0
  252. package/src/api/__tests__/config.test.ts +10 -1
  253. package/src/api/config.ts +4 -12
  254. package/src/api/sonamu.ts +14 -4
  255. package/src/bin/__tests__/migrate-targets.test.ts +28 -0
  256. package/src/bin/__tests__/test-command.test.ts +82 -1
  257. package/src/bin/cli.ts +9 -18
  258. package/src/bin/fixture.ts +5 -4
  259. package/src/bin/migrate-targets.ts +7 -0
  260. package/src/bin/test-command.ts +2 -2
  261. package/src/database/__tests__/db.test.ts +175 -0
  262. package/src/database/db.ts +193 -71
  263. package/src/dict/en.ts +2 -0
  264. package/src/dict/ko.ts +2 -0
  265. package/src/env.ts +123 -0
  266. package/src/migration/__tests__/migrator.test.ts +149 -0
  267. package/src/migration/migrator.ts +74 -17
  268. package/src/migration/slack-confirm.ts +21 -0
  269. package/src/skills/sonamu/database.md +1 -1
  270. package/src/skills/sonamu/entity-basic.md +31 -0
  271. package/src/skills/sonamu/puri.md +22 -0
  272. package/src/skills/sonamu/testing-devrunner.md +1 -1
  273. package/src/skills/sonamu/upsert.md +53 -6
  274. package/src/stream/ws-telemetry-memory.ts +2 -2
  275. package/src/testing/fixture-generator.ts +2 -1
  276. package/src/testing/fixture-manager.ts +3 -4
  277. package/src/testing/global-setup.ts +42 -18
  278. package/src/testing/vitest-helpers.ts +14 -0
  279. package/src/utils/controller.ts +14 -7
  280. package/tsdown.api.config.ts +6 -0
  281. package/dist/_virtual/rolldown_runtime.js +0 -39
  282. package/dist/ui-web/assets/index-D4rYm-Xz.css +0 -1
package/dist/bin/cli.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { getSonamuEnvironment, init_env } from "../env.js";
1
2
  import { execWithLinePrefix, init_console_util, printBuildSummary, printTaskFailed, printTaskHeader, printTaskStart, printTaskSuccess } from "../utils/console-util.js";
2
3
  import { exists, init_fs_utils } from "../utils/fs-utils.js";
3
4
  import { findApiRootPath, findAppRootPath, init_utils } from "../utils/utils.js";
@@ -9,34 +10,33 @@ import { API_ARTIFACTS, WEB_ARTIFACTS } from "./build-config.js";
9
10
  import { Migrator, init_migrator } from "../migration/migrator.js";
10
11
  import { FixtureManager, init_fixture_manager } from "../testing/fixture-manager.js";
11
12
  import { fixtureExploreCommand, fixtureFetchCommand, fixtureGenCommand } from "./fixture.js";
13
+ import { getMigrateRunTargets } from "./migrate-targets.js";
12
14
  import { testCommand } from "./test-command.js";
13
15
  import assert from "assert";
16
+ import path from "path";
14
17
  import knex from "knex";
15
18
  import { cp, mkdir, readFile, readdir, rm, symlink, writeFile } from "fs/promises";
16
- import path from "path";
17
19
  import chalk from "chalk";
18
20
  import os from "os";
19
21
  import { execSync, spawn } from "child_process";
20
22
  import { createRequire } from "module";
21
- import dotenv from "dotenv";
22
23
  import process from "process";
23
24
  import { tsicli } from "tsicli";
24
-
25
25
  //#region src/bin/cli.ts
26
26
  init_sonamu();
27
27
  init_entity_manager();
28
+ init_env();
28
29
  init_migrator();
29
30
  init_fixture_manager();
30
31
  init_console_util();
31
32
  init_fs_utils();
32
33
  init_utils();
33
- dotenv.config();
34
34
  let migrator;
35
35
  /**
36
36
  * CLI 옵션을 파싱하는 헬퍼 함수
37
37
  */
38
38
  function parseCliOptions(argv = process.argv) {
39
- const flags = new Set();
39
+ const flags = /* @__PURE__ */ new Set();
40
40
  const options = {};
41
41
  for (let i = 0; i < argv.length; i++) {
42
42
  const arg = argv[i];
@@ -50,9 +50,7 @@ function parseCliOptions(argv = process.argv) {
50
50
  if (nextArg && !nextArg.startsWith("--") && !nextArg.startsWith("-")) {
51
51
  options[arg.slice(2)] = nextArg;
52
52
  i++;
53
- } else {
54
- flags.add(arg.slice(2));
55
- }
53
+ } else flags.add(arg.slice(2));
56
54
  }
57
55
  return {
58
56
  flags,
@@ -60,16 +58,13 @@ function parseCliOptions(argv = process.argv) {
60
58
  };
61
59
  }
62
60
  async function bootstrap() {
63
- const notToInit = [
61
+ if (![
64
62
  "dev",
65
63
  "build",
66
64
  "start",
67
65
  "skills",
68
66
  "test"
69
- ].includes(process.argv[2] ?? "");
70
- if (!notToInit) {
71
- await Sonamu.init(false, false);
72
- }
67
+ ].includes(process.argv[2] ?? "")) await Sonamu.init(false, false);
73
68
  try {
74
69
  const filteredArgv = [];
75
70
  let skipNext = false;
@@ -86,24 +81,16 @@ async function bootstrap() {
86
81
  continue;
87
82
  }
88
83
  if (arg.startsWith("--")) {
89
- if (arg.includes("=")) {
90
- continue;
91
- }
84
+ if (arg.includes("=")) continue;
92
85
  const nextArg = process.argv[i + 1];
93
- if (nextArg && !nextArg.startsWith("--") && !nextArg.startsWith("-")) {
94
- skipNext = true;
95
- }
86
+ if (nextArg && !nextArg.startsWith("--") && !nextArg.startsWith("-")) skipNext = true;
96
87
  continue;
97
88
  }
98
89
  filteredArgv.push(arg);
99
90
  }
100
91
  const cmd = filteredArgv[2];
101
- if ((cmd === "build" || cmd === "dev") && filteredArgv.length === 3) {
102
- filteredArgv.push("all");
103
- }
104
- if (cmd === "test") {
105
- return testCommand();
106
- }
92
+ if ((cmd === "build" || cmd === "dev") && filteredArgv.length === 3) filteredArgv.push("all");
93
+ if (cmd === "test") return testCommand();
107
94
  await tsicli(filteredArgv, {
108
95
  types: {
109
96
  "#entityId": {
@@ -124,11 +111,15 @@ async function bootstrap() {
124
111
  choices: [
125
112
  {
126
113
  title: "Development",
127
- value: "development_master"
114
+ value: "development"
115
+ },
116
+ {
117
+ title: "Staging",
118
+ value: "staging"
128
119
  },
129
120
  {
130
121
  title: "Production",
131
- value: "production_master"
122
+ value: "production"
132
123
  },
133
124
  {
134
125
  title: "Fixture",
@@ -261,11 +252,8 @@ bootstrap().finally(async () => {
261
252
  */
262
253
  async function sync() {
263
254
  const { flags } = parseCliOptions();
264
- if (flags.has("force")) {
265
- await Sonamu.syncer.forceSync();
266
- } else {
267
- await Sonamu.syncer.sync();
268
- }
255
+ if (flags.has("force")) await Sonamu.syncer.forceSync();
256
+ else await Sonamu.syncer.sync();
269
257
  }
270
258
  /**
271
259
  * API 개발 서버를 실행하는 공통 로직입니다.
@@ -300,7 +288,7 @@ function spawnApiDevServer(options) {
300
288
  stdio: "inherit",
301
289
  env: {
302
290
  ...process.env,
303
- NODE_ENV: "development",
291
+ NODE_ENV: process.env.NODE_ENV ?? "development",
304
292
  HOT: "yes",
305
293
  API_ROOT_PATH: apiRoot,
306
294
  ...options?.extraEnv
@@ -327,8 +315,7 @@ function spawnApiDevServer(options) {
327
315
  * Sonamu.init 없이 호출될 것을 상정하여 구현되었습니다.
328
316
  */
329
317
  function dev_all() {
330
- const require = createRequire(import.meta.url);
331
- const { version } = require("../../package.json");
318
+ const { version } = createRequire(import.meta.url)("../../package.json");
332
319
  console.log(`🌲 Sonamu v${version}\n`);
333
320
  spawnApiDevServer();
334
321
  }
@@ -358,11 +345,10 @@ async function dev_web() {
358
345
  process.exit(1);
359
346
  }
360
347
  const doubleDashIndex = process.argv.indexOf("--");
361
- const passthroughArgs = doubleDashIndex !== -1 ? process.argv.slice(doubleDashIndex + 1) : [];
362
348
  const viteArgs = [
363
349
  "exec",
364
350
  "vite",
365
- ...passthroughArgs
351
+ ...doubleDashIndex !== -1 ? process.argv.slice(doubleDashIndex + 1) : []
366
352
  ];
367
353
  console.log(chalk.yellow.bold("Starting Vite dev server...\n"));
368
354
  const viteProcess = spawn("pnpm", viteArgs, {
@@ -372,11 +358,9 @@ async function dev_web() {
372
358
  viteProcess.on("exit", (code) => {
373
359
  process.exit(code ?? 0);
374
360
  });
375
- for (const signal of ["SIGINT", "SIGTERM"]) {
376
- process.on(signal, () => {
377
- viteProcess.kill(signal);
378
- });
379
- }
361
+ for (const signal of ["SIGINT", "SIGTERM"]) process.on(signal, () => {
362
+ viteProcess.kill(signal);
363
+ });
380
364
  }
381
365
  /**
382
366
  * API 빌드 설정 파일 경로를 결정합니다.
@@ -506,8 +490,7 @@ async function runBuildSteps(artifact, options) {
506
490
  * Sonamu.init 없이 호출될 것을 상정하여 구현되었습니다.
507
491
  */
508
492
  async function start() {
509
- const require = createRequire(import.meta.url);
510
- const { version } = require("../../package.json");
493
+ const { version } = createRequire(import.meta.url)("../../package.json");
511
494
  console.log(`🌲 Sonamu v${version}\n`);
512
495
  const apiRoot = findApiRootPath();
513
496
  const entryPoint = "dist/index.js";
@@ -516,8 +499,8 @@ async function start() {
516
499
  console.log(chalk.blue("Run: pnpm sonamu build"));
517
500
  return;
518
501
  }
519
- const { spawn: spawn$1 } = await import("child_process");
520
- const serverProcess = spawn$1(process.execPath, [
502
+ const { spawn } = await import("child_process");
503
+ const serverProcess = spawn(process.execPath, [
521
504
  "--enable-source-maps",
522
505
  "-r",
523
506
  "dotenv/config",
@@ -543,36 +526,18 @@ async function migrate_apply(targets) {
543
526
  }
544
527
  async function migrate_run() {
545
528
  await setupMigrator();
546
- const localHosts = [
547
- "localhost",
548
- "127.0.0.1",
549
- "0.0.0.0",
550
- "::1"
551
- ];
552
- const targets = Object.keys(Sonamu.dbConfig).filter((target) => {
553
- const targetConfig = Sonamu.dbConfig[target];
554
- const host = (targetConfig?.connection)?.host ?? "localhost";
555
- return localHosts.includes(host.toLowerCase());
556
- });
557
- await migrator.runAction("apply", targets);
529
+ await migrator.runAction("apply", getMigrateRunTargets());
558
530
  }
559
531
  async function migrate_generate() {
560
532
  await setupMigrator();
561
533
  const { conns } = await migrator.getStatus();
562
- const hasStatus0 = conns.some((conn) => conn.status === 0);
563
- if (!hasStatus0) {
534
+ if (!conns.some((conn) => conn.status === 0)) {
564
535
  console.log(chalk.red("마이그레이션 파일을 생성하려면 기존 마이그레이션이 최소 하나의 DB에 모두 적용되어 있어야 합니다."));
565
- for (const conn of conns) {
566
- if (conn.pending.length > 0) {
567
- console.log(chalk.yellow(` ${conn.name}: pending ${conn.pending.length}개`));
568
- }
569
- }
536
+ for (const conn of conns) if (conn.pending.length > 0) console.log(chalk.yellow(` ${conn.name}: pending ${conn.pending.length}개`));
570
537
  process.exit(1);
571
538
  }
572
539
  const count = await migrator.generatePreparedCodes();
573
- if (count > 0) {
574
- console.log(chalk.green(`${count}개의 마이그레이션 파일이 생성되었습니다.`));
575
- }
540
+ if (count > 0) console.log(chalk.green(`${count}개의 마이그레이션 파일이 생성되었습니다.`));
576
541
  }
577
542
  async function migrate_status() {
578
543
  await setupMigrator();
@@ -580,7 +545,7 @@ async function migrate_status() {
580
545
  console.log(status);
581
546
  }
582
547
  async function fixture_init() {
583
- const srcConfig = Sonamu.dbConfig.development_master;
548
+ const srcConfig = Sonamu.dbConfig[getSonamuEnvironment()];
584
549
  const targets = [{
585
550
  label: "(REMOTE) Fixture DB",
586
551
  config: Sonamu.dbConfig.fixture
@@ -600,9 +565,7 @@ async function fixture_init() {
600
565
  execSync(`mysqldump -h${srcConn.host} -u${srcConn.user} -p${srcConn.password} --single-transaction -d --no-create-db --triggers ${srcConn.database} > ${dumpFilename}`);
601
566
  const _db = knex(srcConfig);
602
567
  const [[migrations]] = await _db.raw("SELECT COUNT(*) as count FROM information_schema.tables WHERE table_schema = ? AND table_name = 'knex_migrations'", [srcConn.database]);
603
- if (migrations.count > 0) {
604
- execSync(`mysqldump -h${srcConn.host} -u${srcConn.user} -p${srcConn.password} --single-transaction --no-create-db --triggers ${srcConn.database} knex_migrations knex_migrations_lock > ${migrationsDump}`);
605
- }
568
+ if (migrations.count > 0) execSync(`mysqldump -h${srcConn.host} -u${srcConn.user} -p${srcConn.password} --single-transaction --no-create-db --triggers ${srcConn.database} knex_migrations knex_migrations_lock > ${migrationsDump}`);
606
569
  for (const { label, config, toSkip } of targets) {
607
570
  const conn = config.connection;
608
571
  if (toSkip === true) {
@@ -613,7 +576,7 @@ async function fixture_init() {
613
576
  ...config,
614
577
  connection: {
615
578
  ...config.connection ?? {},
616
- database: undefined
579
+ database: void 0
617
580
  }
618
581
  });
619
582
  const [[row]] = await db.raw(`SHOW DATABASES LIKE "${conn.database}"`);
@@ -627,9 +590,7 @@ async function fixture_init() {
627
590
  execSync(`${mysqlCmd} -e 'DROP DATABASE IF EXISTS \`${conn.database}\`'`);
628
591
  execSync(`${mysqlCmd} -e 'CREATE DATABASE \`${conn.database}\`'`);
629
592
  execSync(`${mysqlCmd} ${conn.database} < ${dumpFilename}`);
630
- if (await exists(migrationsDump)) {
631
- execSync(`${mysqlCmd} ${conn.database} < ${migrationsDump}`);
632
- }
593
+ if (await exists(migrationsDump)) execSync(`${mysqlCmd} ${conn.database} < ${migrationsDump}`);
633
594
  await db.destroy();
634
595
  }
635
596
  await _db.destroy();
@@ -648,24 +609,21 @@ async function fixture_sync() {
648
609
  * 옵션을 process.argv에서 파싱
649
610
  */
650
611
  async function fixture_gen() {
651
- const options = parseOptions(process.argv);
652
- await fixtureGenCommand(options);
612
+ await fixtureGenCommand(parseOptions(process.argv));
653
613
  }
654
614
  /**
655
615
  * fixture fetch 명령어
656
616
  * 옵션을 process.argv에서 파싱
657
617
  */
658
618
  async function fixture_fetch() {
659
- const options = parseOptions(process.argv);
660
- await fixtureFetchCommand(options);
619
+ await fixtureFetchCommand(parseOptions(process.argv));
661
620
  }
662
621
  /**
663
622
  * fixture explore 명령어
664
623
  * 옵션을 process.argv에서 파싱
665
624
  */
666
625
  async function fixture_explore() {
667
- const options = parseOptions(process.argv);
668
- await fixtureExploreCommand(options);
626
+ await fixtureExploreCommand(parseOptions(process.argv));
669
627
  }
670
628
  /**
671
629
  * 간단한 옵션 파서
@@ -684,9 +642,7 @@ function parseOptions(argv) {
684
642
  if (next && !next.startsWith("--")) {
685
643
  options[key] = next;
686
644
  i++;
687
- } else {
688
- options[key] = true;
689
- }
645
+ } else options[key] = true;
690
646
  }
691
647
  } else if (arg.startsWith("-")) {
692
648
  const key = arg.slice(1);
@@ -694,35 +650,25 @@ function parseOptions(argv) {
694
650
  if (next && !next.startsWith("-")) {
695
651
  options[key] = next;
696
652
  i++;
697
- } else {
698
- options[key] = true;
699
- }
700
- } else {
701
- options._.push(arg);
702
- }
653
+ } else options[key] = true;
654
+ } else options._.push(arg);
703
655
  }
704
656
  return options;
705
657
  }
706
658
  async function stub_practice(name) {
707
659
  const practiceDir = path.join(Sonamu.apiRootPath, "src", "practices");
708
660
  const fileNames = await readdir(practiceDir);
709
- const maxSeqNo = await (async () => {
710
- if (!await exists(practiceDir)) {
711
- await mkdir(practiceDir, { recursive: true });
712
- }
713
- const filteredSeqs = fileNames.filter((fileName$1) => fileName$1.startsWith("p") && fileName$1.endsWith(".ts")).map((fileName$1) => {
714
- const [, seqNo] = fileName$1.match(/^p([0-9]+)-/) ?? ["0", "0"];
661
+ const fileName = `p${await (async () => {
662
+ if (!await exists(practiceDir)) await mkdir(practiceDir, { recursive: true });
663
+ const filteredSeqs = fileNames.filter((fileName) => fileName.startsWith("p") && fileName.endsWith(".ts")).map((fileName) => {
664
+ const [, seqNo] = fileName.match(/^p([0-9]+)-/) ?? ["0", "0"];
715
665
  return parseInt(seqNo);
716
666
  }).toSorted((a, b) => b - a);
717
- if (filteredSeqs.length > 0) {
718
- return filteredSeqs[0];
719
- }
667
+ if (filteredSeqs.length > 0) return filteredSeqs[0];
720
668
  return 0;
721
- })();
722
- const currentSeqNo = maxSeqNo + 1;
723
- const fileName = `p${currentSeqNo}-${name}.ts`;
669
+ })() + 1}-${name}.ts`;
724
670
  const dstPath = path.join(practiceDir, fileName);
725
- const code = [
671
+ await writeFile(dstPath, [
726
672
  `import { Sonamu } from "sonamu";`,
727
673
  "",
728
674
  `console.clear();`,
@@ -732,8 +678,7 @@ async function stub_practice(name) {
732
678
  ` // TODO`,
733
679
  `});`,
734
680
  ""
735
- ].join("\n");
736
- await writeFile(dstPath, code);
681
+ ].join("\n"));
737
682
  execSync(`code ${dstPath}`);
738
683
  const runCode = `yarn node -r dotenv/config --enable-source-maps dist/practices/${fileName.replace(".ts", ".js")}`;
739
684
  console.log(`${chalk.blue(runCode)} copied to clipboard.`);
@@ -746,13 +691,12 @@ async function stub_entity(entityId) {
746
691
  });
747
692
  const { flags } = parseCliOptions();
748
693
  const useAI = flags.has("ai");
749
- const noCones = flags.has("no-cones");
750
- if (noCones) {
694
+ if (flags.has("no-cones")) {
751
695
  console.log(`✓ Entity '${entityId}' created without cones`);
752
696
  return;
753
697
  }
754
- const { EntityManager: EntityManager$1 } = await import("../entity/entity-manager.js");
755
- const entity = EntityManager$1.get(entityId);
698
+ const { EntityManager } = await import("../entity/entity-manager.js");
699
+ const entity = EntityManager.get(entityId);
756
700
  if (!entity) {
757
701
  console.error(`Entity not found: ${entityId}`);
758
702
  return;
@@ -773,9 +717,7 @@ async function stub_entity(entityId) {
773
717
  if (error instanceof Error && error.message.includes("ANTHROPIC_API_KEY")) {
774
718
  console.error(`\n❌ ${error.message}`);
775
719
  console.error(`\n💡 Remove --ai flag to use template cones instead`);
776
- } else {
777
- throw error;
778
- }
720
+ } else throw error;
779
721
  }
780
722
  return;
781
723
  }
@@ -795,43 +737,39 @@ async function stub_entity(entityId) {
795
737
  * ANTHROPIC_API_KEY 필요 (sonamu.secret.ts 또는 환경변수)
796
738
  */
797
739
  async function cone_gen(entityId) {
798
- const { EntityManager: EntityManager$1 } = await import("../entity/entity-manager.js");
740
+ const { EntityManager } = await import("../entity/entity-manager.js");
799
741
  const { flags, options } = parseCliOptions();
800
742
  if (flags.has("all") || entityId === "all") {
801
- const allEntities = EntityManager$1.getAllEntities();
743
+ const allEntities = EntityManager.getAllEntities();
802
744
  console.log(`🌟 Generating AI-powered cones for ${allEntities.length} entities...\n`);
803
745
  let totalTokens = 0;
804
746
  const errors = [];
805
- for (const entity$1 of allEntities) {
806
- try {
807
- console.log(`Processing ${entity$1.id}...`);
808
- const configLocale = options.locale || Sonamu.config.i18n?.defaultLocale;
809
- const locale = configLocale === "ko" || configLocale === "en" || configLocale === "ja" ? configLocale : "ko";
810
- const result = await entity$1.generateCones({
811
- preserveExisting: !flags.has("regenerate"),
812
- onlyEmpty: !flags.has("regenerate"),
813
- locale
814
- });
815
- totalTokens += result.tokensUsed;
816
- console.log(` ✓ ${entity$1.id} (${result.tokensUsed} tokens)\n`);
817
- } catch (error) {
818
- const message = error instanceof Error ? error.message : "Unknown error";
819
- errors.push(`${entity$1.id}: ${message}`);
820
- console.error(` ✗ ${entity$1.id}: ${message}\n`);
821
- }
747
+ for (const entity of allEntities) try {
748
+ console.log(`Processing ${entity.id}...`);
749
+ const configLocale = options.locale || Sonamu.config.i18n?.defaultLocale;
750
+ const locale = configLocale === "ko" || configLocale === "en" || configLocale === "ja" ? configLocale : "ko";
751
+ const result = await entity.generateCones({
752
+ preserveExisting: !flags.has("regenerate"),
753
+ onlyEmpty: !flags.has("regenerate"),
754
+ locale
755
+ });
756
+ totalTokens += result.tokensUsed;
757
+ console.log(` ✓ ${entity.id} (${result.tokensUsed} tokens)\n`);
758
+ } catch (error) {
759
+ const message = error instanceof Error ? error.message : "Unknown error";
760
+ errors.push(`${entity.id}: ${message}`);
761
+ console.error(` ✗ ${entity.id}: ${message}\n`);
822
762
  }
823
763
  console.log(`\n✅ Done! Total: ${totalTokens} tokens used`);
824
764
  const estimatedCost = totalTokens * 9 / 1e6;
825
765
  console.log(`💰 Estimated cost: ~$${estimatedCost.toFixed(4)}`);
826
766
  if (errors.length > 0) {
827
767
  console.error(`\n❌ Failed entities (${errors.length}):`);
828
- for (const err of errors) {
829
- console.error(` - ${err}`);
830
- }
768
+ for (const err of errors) console.error(` - ${err}`);
831
769
  }
832
770
  return;
833
771
  }
834
- const entity = EntityManager$1.get(entityId);
772
+ const entity = EntityManager.get(entityId);
835
773
  if (!entity) {
836
774
  console.error(`Entity not found: ${entityId}`);
837
775
  return;
@@ -850,21 +788,16 @@ async function cone_gen(entityId) {
850
788
  const estimatedCost = result.tokensUsed * 9 / 1e6;
851
789
  console.log(`💰 Estimated cost: ~$${estimatedCost.toFixed(4)}`);
852
790
  } catch (error) {
853
- if (error instanceof Error) {
854
- if (error.message.includes("ANTHROPIC_API_KEY")) {
855
- console.error(`\n ${error.message}`);
856
- console.error(`\n💡 To use AI-powered cone generation:`);
857
- console.error(` 1. Get an API key from https://console.anthropic.com/`);
858
- console.error(` 2. Add it to sonamu.secret.ts or set ANTHROPIC_API_KEY environment variable`);
859
- } else if (error.message.includes("Rate limit")) {
860
- console.error(`\n ${error.message}`);
861
- console.error(`\n💡 Please wait a moment and try again.`);
862
- } else {
863
- console.error(`\n❌ Failed to generate cones: ${error.message}`);
864
- }
865
- } else {
866
- console.error(`\n❌ Failed to generate cones: Unknown error`);
867
- }
791
+ if (error instanceof Error) if (error.message.includes("ANTHROPIC_API_KEY")) {
792
+ console.error(`\n❌ ${error.message}`);
793
+ console.error(`\n💡 To use AI-powered cone generation:`);
794
+ console.error(` 1. Get an API key from https://console.anthropic.com/`);
795
+ console.error(` 2. Add it to sonamu.secret.ts or set ANTHROPIC_API_KEY environment variable`);
796
+ } else if (error.message.includes("Rate limit")) {
797
+ console.error(`\n❌ ${error.message}`);
798
+ console.error(`\n💡 Please wait a moment and try again.`);
799
+ } else console.error(`\n Failed to generate cones: ${error.message}`);
800
+ else console.error(`\n❌ Failed to generate cones: Unknown error`);
868
801
  }
869
802
  }
870
803
  async function scaffold_model(entityId) {
@@ -909,8 +842,7 @@ async function skills_sync() {
909
842
  console.log(chalk.dim(` Once a project is created, run 'pnpm sonamu skills sync' for project-local sync.`));
910
843
  } else {
911
844
  const workspaceRoot = await findWorkspaceRoot();
912
- const claudeDir = path.join(workspaceRoot, ".claude");
913
- await skills_sync_to(claudeDir, sourceSkillsDir, sourceClaudeMd, {
845
+ await skills_sync_to(path.join(workspaceRoot, ".claude"), sourceSkillsDir, sourceClaudeMd, {
914
846
  useSymlink: true,
915
847
  copyProjectTemplates: true,
916
848
  sourceBase
@@ -929,88 +861,67 @@ async function skills_sync_to(claudeDir, sourceSkillsDir, sourceClaudeMd, option
929
861
  });
930
862
  } catch {}
931
863
  await mkdir(path.dirname(targetSkillsDir), { recursive: true });
932
- if (options.useSymlink) {
933
- try {
934
- await symlink(sourceSkillsDir, targetSkillsDir, "dir");
935
- console.log(chalk.green(`✓ Skills linked (symlink)`));
936
- } catch (error) {
937
- console.log(chalk.yellow(`⚠ Symlink failed: ${error instanceof Error ? error.message : String(error)}`));
938
- console.log(chalk.yellow(` Falling back to copy...`));
939
- await skillsCopy(sourceSkillsDir, targetSkillsDir);
940
- }
941
- } else {
864
+ if (options.useSymlink) try {
865
+ await symlink(sourceSkillsDir, targetSkillsDir, "dir");
866
+ console.log(chalk.green(`✓ Skills linked (symlink)`));
867
+ } catch (error) {
868
+ console.log(chalk.yellow(`⚠ Symlink failed: ${error instanceof Error ? error.message : String(error)}`));
869
+ console.log(chalk.yellow(` Falling back to copy...`));
942
870
  await skillsCopy(sourceSkillsDir, targetSkillsDir);
943
871
  }
872
+ else await skillsCopy(sourceSkillsDir, targetSkillsDir);
944
873
  if (options.copyProjectTemplates && options.sourceBase) {
945
874
  const sourceProjectDir = path.join(options.sourceBase, "project");
946
875
  const targetProjectDir = path.join(claudeDir, "skills", "project");
947
- if (await exists(sourceProjectDir)) {
948
- if (!await exists(targetProjectDir)) {
949
- try {
950
- await cp(sourceProjectDir, targetProjectDir, { recursive: true });
951
- console.log(chalk.green(`✓ Project templates initialized`));
952
- } catch (error) {
953
- console.error(chalk.red(`✗ Failed to initialize project templates: ${error instanceof Error ? error.message : String(error)}`));
954
- }
955
- } else {
956
- console.log(chalk.dim(`⏭ Project templates already exist (preserved)`));
957
- }
876
+ if (await exists(sourceProjectDir)) if (!await exists(targetProjectDir)) try {
877
+ await cp(sourceProjectDir, targetProjectDir, { recursive: true });
878
+ console.log(chalk.green(`✓ Project templates initialized`));
879
+ } catch (error) {
880
+ console.error(chalk.red(`✗ Failed to initialize project templates: ${error instanceof Error ? error.message : String(error)}`));
958
881
  }
882
+ else console.log(chalk.dim(`⏭ Project templates already exist (preserved)`));
959
883
  }
960
884
  if (options.copyProjectTemplates) {
961
885
  const settingsLocalPath = path.join(claudeDir, "settings.local.json");
962
- if (!await exists(settingsLocalPath)) {
963
- try {
964
- const settingsContent = { hooks: { PostToolUse: [{
965
- matcher: "Edit|Write|MultiEdit",
966
- hooks: [{
967
- type: "command",
968
- command: "pnpm check 2>&1 | head -60"
969
- }]
970
- }] } };
971
- await writeFile(settingsLocalPath, `${JSON.stringify(settingsContent, null, 2)}\n`);
972
- console.log(chalk.green(`✓ .claude/settings.local.json created`));
973
- } catch (error) {
974
- console.error(chalk.red(`✗ Failed to create settings.local.json: ${error instanceof Error ? error.message : String(error)}`));
975
- }
976
- } else {
977
- console.log(chalk.dim(`⏭ .claude/settings.local.json already exists (preserved)`));
886
+ if (!await exists(settingsLocalPath)) try {
887
+ await writeFile(settingsLocalPath, `${JSON.stringify({ hooks: { PostToolUse: [{
888
+ matcher: "Edit|Write|MultiEdit",
889
+ hooks: [{
890
+ type: "command",
891
+ command: "pnpm check 2>&1 | head -60"
892
+ }]
893
+ }] } }, null, 2)}\n`);
894
+ console.log(chalk.green(`✓ .claude/settings.local.json created`));
895
+ } catch (error) {
896
+ console.error(chalk.red(`✗ Failed to create settings.local.json: ${error instanceof Error ? error.message : String(error)}`));
978
897
  }
898
+ else console.log(chalk.dim(`⏭ .claude/settings.local.json already exists (preserved)`));
979
899
  }
980
- if (await exists(sourceClaudeMd)) {
981
- try {
982
- const targetClaudeMd = path.join(claudeDir, "CLAUDE.md");
983
- const rawContent = await readFile(sourceClaudeMd, "utf-8");
984
- const sourceContent = options.isGlobal ? rawContent.replaceAll(".claude/skills/sonamu/", "~/.claude/skills/sonamu/") : rawContent;
985
- if (await exists(targetClaudeMd)) {
986
- const targetContent = await readFile(targetClaudeMd, "utf-8");
987
- const startMarker = "<!-- SONAMU:START -->";
988
- const endMarker = "<!-- SONAMU:END -->";
989
- if (targetContent.includes(startMarker) && targetContent.includes(endMarker)) {
990
- const startIdx = targetContent.indexOf(startMarker);
991
- const endIdx = targetContent.indexOf(endMarker);
992
- if (startIdx !== -1 && endIdx !== -1 && startIdx < endIdx) {
993
- const before = targetContent.substring(0, startIdx);
994
- const after = targetContent.substring(endIdx + endMarker.length);
995
- const newContent = `${before}${startMarker}\n${sourceContent}\n${endMarker}${after}`;
996
- await writeFile(targetClaudeMd, newContent);
997
- console.log(chalk.green(`✓ CLAUDE.md updated (marker region)`));
998
- } else {
999
- console.log(chalk.yellow(`⏭ CLAUDE.md marker positions invalid, skipped`));
1000
- }
1001
- } else {
1002
- const appended = `${targetContent.trimEnd()}\n\n<!-- SONAMU:START -->\n${sourceContent}\n<!-- SONAMU:END -->\n`;
1003
- await writeFile(targetClaudeMd, appended);
1004
- console.log(chalk.green(`✓ CLAUDE.md updated (appended Sonamu section)`));
1005
- }
900
+ if (await exists(sourceClaudeMd)) try {
901
+ const targetClaudeMd = path.join(claudeDir, "CLAUDE.md");
902
+ const rawContent = await readFile(sourceClaudeMd, "utf-8");
903
+ const sourceContent = options.isGlobal ? rawContent.replaceAll(".claude/skills/sonamu/", "~/.claude/skills/sonamu/") : rawContent;
904
+ if (await exists(targetClaudeMd)) {
905
+ const targetContent = await readFile(targetClaudeMd, "utf-8");
906
+ const startMarker = "<!-- SONAMU:START -->";
907
+ const endMarker = "<!-- SONAMU:END -->";
908
+ if (targetContent.includes(startMarker) && targetContent.includes(endMarker)) {
909
+ const startIdx = targetContent.indexOf(startMarker);
910
+ const endIdx = targetContent.indexOf(endMarker);
911
+ if (startIdx !== -1 && endIdx !== -1 && startIdx < endIdx) {
912
+ await writeFile(targetClaudeMd, `${targetContent.substring(0, startIdx)}${startMarker}\n${sourceContent}\n${endMarker}${targetContent.substring(endIdx + 19)}`);
913
+ console.log(chalk.green(`✓ CLAUDE.md updated (marker region)`));
914
+ } else console.log(chalk.yellow(`⏭ CLAUDE.md marker positions invalid, skipped`));
1006
915
  } else {
1007
- const withMarkers = `<!-- SONAMU:START -->\n${sourceContent}\n<!-- SONAMU:END -->\n`;
1008
- await writeFile(targetClaudeMd, withMarkers);
1009
- console.log(chalk.green(`✓ CLAUDE.md created`));
916
+ await writeFile(targetClaudeMd, `${targetContent.trimEnd()}\n\n<!-- SONAMU:START -->\n${sourceContent}\n<!-- SONAMU:END -->\n`);
917
+ console.log(chalk.green(`✓ CLAUDE.md updated (appended Sonamu section)`));
1010
918
  }
1011
- } catch (error) {
1012
- console.error(chalk.red(`✗ Failed to update CLAUDE.md: ${error instanceof Error ? error.message : String(error)}`));
919
+ } else {
920
+ await writeFile(targetClaudeMd, `<!-- SONAMU:START -->\n${sourceContent}\n<!-- SONAMU:END -->\n`);
921
+ console.log(chalk.green(`✓ CLAUDE.md created`));
1013
922
  }
923
+ } catch (error) {
924
+ console.error(chalk.red(`✗ Failed to update CLAUDE.md: ${error instanceof Error ? error.message : String(error)}`));
1014
925
  }
1015
926
  }
1016
927
  async function skillsCopy(src, dest) {
@@ -1039,7 +950,7 @@ async function skills_create(name) {
1039
950
  sanitized = sanitized.substring(0, MAX_LENGTH);
1040
951
  console.log(chalk.yellow(`⚠ Name truncated to ${MAX_LENGTH} characters`));
1041
952
  }
1042
- const RESERVED_NAMES = [
953
+ if ([
1043
954
  "CON",
1044
955
  "PRN",
1045
956
  "AUX",
@@ -1062,8 +973,7 @@ async function skills_create(name) {
1062
973
  "LPT7",
1063
974
  "LPT8",
1064
975
  "LPT9"
1065
- ];
1066
- if (RESERVED_NAMES.includes(sanitized.toUpperCase())) {
976
+ ].includes(sanitized.toUpperCase())) {
1067
977
  sanitized = `skill-${sanitized}`;
1068
978
  console.log(chalk.yellow(`⚠ Reserved name detected, prefixed with "skill-"`));
1069
979
  }
@@ -1072,19 +982,17 @@ async function skills_create(name) {
1072
982
  console.log(chalk.dim(` Original: "${name}"`));
1073
983
  return;
1074
984
  }
1075
- if (sanitized !== name) {
1076
- console.log(chalk.yellow(`⚠ Name sanitized: "${name}" → "${sanitized}"`));
1077
- }
985
+ if (sanitized !== name) console.log(chalk.yellow(`⚠ Name sanitized: "${name}" → "${sanitized}"`));
1078
986
  const filePath = path.join(localDir, `${sanitized}.md`);
1079
987
  if (await exists(filePath)) {
1080
988
  console.log(chalk.yellow(`Skill "${sanitized}" already exists.`));
1081
989
  return;
1082
990
  }
1083
991
  await mkdir(localDir, { recursive: true });
1084
- const template = `---
992
+ await writeFile(filePath, `---
1085
993
  name: ${sanitized}
1086
994
  category: other
1087
- created_at: ${new Date().toISOString().split("T")[0]}
995
+ created_at: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
1088
996
  status: draft
1089
997
  ---
1090
998
 
@@ -1103,8 +1011,7 @@ status: draft
1103
1011
  \`\`\`typescript
1104
1012
  // 예시 코드
1105
1013
  \`\`\`
1106
- `;
1107
- await writeFile(filePath, template);
1014
+ `);
1108
1015
  console.log(chalk.green(`✓ Created .claude/skills/local/${sanitized}.md`));
1109
1016
  }
1110
1017
  /**
@@ -1121,20 +1028,15 @@ async function auth_generate() {
1121
1028
  const pluginValue = pluginsArg.includes("=") ? pluginsArg.split("=")[1] : process.argv[process.argv.indexOf(pluginsArg) + 1];
1122
1029
  if (pluginValue) {
1123
1030
  const pluginIds = pluginValue.split(",").map((p) => p.trim());
1124
- for (const id of pluginIds) {
1125
- if (isValidPluginId(id)) {
1126
- plugins.push(id);
1127
- } else {
1128
- console.log(chalk.yellow(`⚠ Unknown plugin: ${id}`));
1129
- console.log(chalk.dim(` Supported plugins: ${SUPPORTED_PLUGIN_IDS.join(", ")}`));
1130
- }
1031
+ for (const id of pluginIds) if (isValidPluginId(id)) plugins.push(id);
1032
+ else {
1033
+ console.log(chalk.yellow(`⚠ Unknown plugin: ${id}`));
1034
+ console.log(chalk.dim(` Supported plugins: ${SUPPORTED_PLUGIN_IDS.join(", ")}`));
1131
1035
  }
1132
1036
  }
1133
1037
  }
1134
1038
  console.log(chalk.yellow.bold("🔐 Generating better-auth entities...\n"));
1135
- if (plugins.length > 0) {
1136
- console.log(chalk.dim(` Plugins: ${plugins.join(", ")}`));
1137
- }
1039
+ if (plugins.length > 0) console.log(chalk.dim(` Plugins: ${plugins.join(", ")}`));
1138
1040
  await generateBetterAuthEntities({ plugins });
1139
1041
  }
1140
1042
  /**
@@ -1158,26 +1060,17 @@ async function auth_add_companions() {
1158
1060
  async function findWorkspaceRoot() {
1159
1061
  let dir = process.cwd();
1160
1062
  while (dir !== path.dirname(dir)) {
1161
- if (await exists(path.join(dir, "pnpm-workspace.yaml"))) {
1162
- return dir;
1163
- }
1063
+ if (await exists(path.join(dir, "pnpm-workspace.yaml"))) return dir;
1164
1064
  const packagePath = path.join(dir, "package.json");
1165
- if (await exists(packagePath)) {
1166
- try {
1167
- const packageJson = JSON.parse(await readFile(packagePath, "utf-8"));
1168
- if (packageJson.workspaces) {
1169
- return dir;
1170
- }
1171
- } catch {}
1172
- }
1173
- if (await exists(path.join(dir, ".agents"))) {
1174
- return dir;
1175
- }
1065
+ if (await exists(packagePath)) try {
1066
+ if (JSON.parse(await readFile(packagePath, "utf-8")).workspaces) return dir;
1067
+ } catch {}
1068
+ if (await exists(path.join(dir, ".agents"))) return dir;
1176
1069
  dir = path.dirname(dir);
1177
1070
  }
1178
1071
  return findAppRootPath();
1179
1072
  }
1180
-
1181
1073
  //#endregion
1182
- export { };
1183
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwibmFtZXMiOlsibWlncmF0b3I6IE1pZ3JhdG9yIiwib3B0aW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiIsImZpbHRlcmVkQXJndjogc3RyaW5nW10iLCJzcGF3biIsIm9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IGJvb2xlYW4gfCBzdHJpbmdbXT4gJiB7IF86IHN0cmluZ1tdIH0iLCJmaWxlTmFtZSIsIkVudGl0eU1hbmFnZXIiLCJlcnJvcnM6IHN0cmluZ1tdIiwiZW50aXR5IiwicGx1Z2luczogQmV0dGVyQXV0aFBsdWdpbklkW10iXSwic291cmNlcyI6WyIuLi8uLi9zcmMvYmluL2NsaS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQgZG90ZW52IGZyb20gXCJkb3RlbnZcIjtcblxuZG90ZW52LmNvbmZpZygpO1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gXCJhc3NlcnRcIjtcbmltcG9ydCB7IGV4ZWNTeW5jLCBzcGF3biB9IGZyb20gXCJjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBjcCwgbWtkaXIsIHJlYWRkaXIsIHJlYWRGaWxlLCBybSwgc3ltbGluaywgd3JpdGVGaWxlIH0gZnJvbSBcImZzL3Byb21pc2VzXCI7XG5pbXBvcnQgeyBjcmVhdGVSZXF1aXJlIH0gZnJvbSBcIm1vZHVsZVwiO1xuaW1wb3J0IG9zIGZyb20gXCJvc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCBwcm9jZXNzIGZyb20gXCJwcm9jZXNzXCI7XG5cbmltcG9ydCBrbmV4IGZyb20gXCJrbmV4XCI7XG5pbXBvcnQgeyB0eXBlIEtuZXggfSBmcm9tIFwia25leFwiO1xuaW1wb3J0IHsgdHNpY2xpIH0gZnJvbSBcInRzaWNsaVwiO1xuXG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHsgYWRkQ29tcGFuaW9uc1RvRW50aXRpZXMsIGdlbmVyYXRlQmV0dGVyQXV0aEVudGl0aWVzIH0gZnJvbSBcIi4uL2F1dGgvYXV0aC1nZW5lcmF0b3JcIjtcbmltcG9ydCB7IGlzVmFsaWRQbHVnaW5JZCwgU1VQUE9SVEVEX1BMVUdJTl9JRFMgfSBmcm9tIFwiLi4vYXV0aC9wbHVnaW5zL2VudGl0eS1kZWZpbml0aW9uc1wiO1xuaW1wb3J0IHsgdHlwZSBCZXR0ZXJBdXRoUGx1Z2luSWQgfSBmcm9tIFwiLi4vYXV0aC9wbHVnaW5zL2VudGl0eS1kZWZpbml0aW9uc1wiO1xuaW1wb3J0IHsgdHlwZSBTb25hbXVEQkNvbmZpZyB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgRW50aXR5TWFuYWdlciB9IGZyb20gXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIjtcbmltcG9ydCB7IE1pZ3JhdG9yIH0gZnJvbSBcIi4uL21pZ3JhdGlvbi9taWdyYXRvclwiO1xuaW1wb3J0IHsgRml4dHVyZU1hbmFnZXIgfSBmcm9tIFwiLi4vdGVzdGluZy9maXh0dXJlLW1hbmFnZXJcIjtcbmltcG9ydCB7XG4gIGV4ZWNXaXRoTGluZVByZWZpeCxcbiAgcHJpbnRCdWlsZFN1bW1hcnksXG4gIHByaW50VGFza0ZhaWxlZCxcbiAgcHJpbnRUYXNrSGVhZGVyLFxuICBwcmludFRhc2tTdGFydCxcbiAgcHJpbnRUYXNrU3VjY2Vzcyxcbn0gZnJvbSBcIi4uL3V0aWxzL2NvbnNvbGUtdXRpbFwiO1xuaW1wb3J0IHsgZXhpc3RzIH0gZnJvbSBcIi4uL3V0aWxzL2ZzLXV0aWxzXCI7XG5pbXBvcnQgeyBmaW5kQXBpUm9vdFBhdGgsIGZpbmRBcHBSb290UGF0aCB9IGZyb20gXCIuLi91dGlscy91dGlsc1wiO1xuaW1wb3J0IHsgQVBJX0FSVElGQUNUUywgV0VCX0FSVElGQUNUUyB9IGZyb20gXCIuL2J1aWxkLWNvbmZpZ1wiO1xuaW1wb3J0IHsgdHlwZSBCdWlsZEFydGlmYWN0IH0gZnJvbSBcIi4vYnVpbGQtY29uZmlnXCI7XG5pbXBvcnQgeyBmaXh0dXJlRXhwbG9yZUNvbW1hbmQsIGZpeHR1cmVGZXRjaENvbW1hbmQsIGZpeHR1cmVHZW5Db21tYW5kIH0gZnJvbSBcIi4vZml4dHVyZVwiO1xuaW1wb3J0IHsgdGVzdENvbW1hbmQgfSBmcm9tIFwiLi90ZXN0LWNvbW1hbmRcIjtcblxubGV0IG1pZ3JhdG9yOiBNaWdyYXRvcjtcblxuLyoqXG4gKiBDTEkg7Ji17IWY7J2EIO2MjOyLse2VmOuKlCDtl6ztjbwg7ZWo7IiYXG4gKi9cbmZ1bmN0aW9uIHBhcnNlQ2xpT3B0aW9ucyhhcmd2OiBzdHJpbmdbXSA9IHByb2Nlc3MuYXJndik6IHtcbiAgZmxhZ3M6IFNldDxzdHJpbmc+OyAvLyAtLXJlZ2VuZXJhdGUsIC0tYWksIC0tbm8tY29uZXMg65OxXG4gIG9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47IC8vIC0tbG9jYWxlIGtvIOuTsVxufSB7XG4gIGNvbnN0IGZsYWdzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGNvbnN0IG9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGFyZ3YubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBhcmcgPSBhcmd2W2ldO1xuICAgIGlmICghYXJnLnN0YXJ0c1dpdGgoXCItLVwiKSkgY29udGludWU7XG5cbiAgICAvLyAtLW9wdGlvbj12YWx1ZSDtmJXsi51cbiAgICBpZiAoYXJnLmluY2x1ZGVzKFwiPVwiKSkge1xuICAgICAgY29uc3QgW2tleSwgdmFsdWVdID0gYXJnLnNsaWNlKDIpLnNwbGl0KFwiPVwiKTtcbiAgICAgIG9wdGlvbnNba2V5XSA9IHZhbHVlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gLS1vcHRpb24gdmFsdWUg7ZiV7Iud7J247KeAIO2ZleyduFxuICAgIGNvbnN0IG5leHRBcmcgPSBhcmd2W2kgKyAxXTtcbiAgICBpZiAobmV4dEFyZyAmJiAhbmV4dEFyZy5zdGFydHNXaXRoKFwiLS1cIikgJiYgIW5leHRBcmcuc3RhcnRzV2l0aChcIi1cIikpIHtcbiAgICAgIG9wdGlvbnNbYXJnLnNsaWNlKDIpXSA9IG5leHRBcmc7XG4gICAgICBpKys7IC8vIOuLpOydjCBhcmfripQg6rCS7J2066+A66GcIOyKpO2CtVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyAtLWZsYWcg7ZiV7IudXG4gICAgICBmbGFncy5hZGQoYXJnLnNsaWNlKDIpKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBmbGFncywgb3B0aW9ucyB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBib290c3RyYXAoKSB7XG4gIGNvbnN0IG5vdFRvSW5pdCA9IFtcImRldlwiLCBcImJ1aWxkXCIsIFwic3RhcnRcIiwgXCJza2lsbHNcIiwgXCJ0ZXN0XCJdLmluY2x1ZGVzKHByb2Nlc3MuYXJndlsyXSA/PyBcIlwiKTtcbiAgaWYgKCFub3RUb0luaXQpIHtcbiAgICBhd2FpdCBTb25hbXUuaW5pdChmYWxzZSwgZmFsc2UpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyB0c2ljbGnripQg7KCV7ZmV7ZWcIOuqheugueyWtCDrp6Tsua3rp4wg7KeA7JuQ7ZWY66+A66GcLCAtLeuhnCDsi5zsnpHtlZjripQg7Ji17IWY6rO8IOq3uCDqsJLsnYQg7ZWE7YSw66eB7ZWp64uI64ukLlxuICAgIC8vIOyYteyFmCDtjIzsi7HsnYAg6rCBIHJ1bm5lciDtlajsiJjsl5DshJwg7JuQ67O4IHByb2Nlc3MuYXJnduulvCDsgqzsmqntlZjsl6wg7IiY7ZaJ7ZWp64uI64ukLlxuICAgIC8vIFwiLS1cIihiYXJlIGRvdWJsZSBkYXNoKeuKlCBwYXNzdGhyb3VnaCDqtazrtoTsnpDsnbTrr4DroZwsIOq3uCDrkqTsnZgg66qo65OgIOyduOyekOuPhCDsoJzsmbjtlanri4jri6QuXG4gICAgY29uc3QgZmlsdGVyZWRBcmd2OiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBza2lwTmV4dCA9IGZhbHNlO1xuICAgIGxldCBhZnRlckRvdWJsZURhc2ggPSBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb2Nlc3MuYXJndi5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgYXJnID0gcHJvY2Vzcy5hcmd2W2ldO1xuICAgICAgaWYgKGFyZyA9PT0gXCItLVwiKSB7XG4gICAgICAgIGFmdGVyRG91YmxlRGFzaCA9IHRydWU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGFmdGVyRG91YmxlRGFzaCkgY29udGludWU7XG4gICAgICBpZiAoc2tpcE5leHQpIHtcbiAgICAgICAgc2tpcE5leHQgPSBmYWxzZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoYXJnLnN0YXJ0c1dpdGgoXCItLVwiKSkge1xuICAgICAgICAvLyAtLW9wdGlvbj12YWx1ZSDtmJXsi53snYAg7J20IGFyZ+unjCDsiqTtgrVcbiAgICAgICAgaWYgKGFyZy5pbmNsdWRlcyhcIj1cIikpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyAtLW9wdGlvbiB2YWx1ZSDtmJXsi53snbjsp4Ag7ZmV7J24OiDri6TsnYwgYXJn6rCAIC0t66GcIOyLnOyeke2VmOyngCDslYrsnLzrqbQg6rCS7J20IOyeiOuKlCDqsoNcbiAgICAgICAgY29uc3QgbmV4dEFyZyA9IHByb2Nlc3MuYXJndltpICsgMV07XG4gICAgICAgIGlmIChuZXh0QXJnICYmICFuZXh0QXJnLnN0YXJ0c1dpdGgoXCItLVwiKSAmJiAhbmV4dEFyZy5zdGFydHNXaXRoKFwiLVwiKSkge1xuICAgICAgICAgIHNraXBOZXh0ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGZpbHRlcmVkQXJndi5wdXNoKGFyZyk7XG4gICAgfVxuXG4gICAgLy8gYnVpbGQvZGV2IOuqheugueyWtOqwgCDshJzruIzsu6Trp6jrk5wg7JeG7J20IO2YuOy2nOuQoCDrlYwgXCJhbGxcIuydhCDquLDrs7jqsJLsnLzroZwg7LaU6rCA7ZWp64uI64ukLlxuICAgIC8vIOyYiDogYHNvbmFtdSBidWlsZGAg4oaSIGBzb25hbXUgYnVpbGQgYWxsYCwgYHNvbmFtdSBkZXZgIOKGkiBgc29uYW11IGRldiBhbGxgXG4gICAgY29uc3QgY21kID0gZmlsdGVyZWRBcmd2WzJdO1xuICAgIGlmICgoY21kID09PSBcImJ1aWxkXCIgfHwgY21kID09PSBcImRldlwiKSAmJiBmaWx0ZXJlZEFyZ3YubGVuZ3RoID09PSAzKSB7XG4gICAgICBmaWx0ZXJlZEFyZ3YucHVzaChcImFsbFwiKTtcbiAgICB9XG5cbiAgICAvLyB0ZXN0IOy7pOunqOuTnOuKlCDqsIDrs4Ag7J247J6QKO2MjOydvOuqhSwgLS1wYXR0ZXJuIOuTsSnrpbwg67Cb7Jy866+A66GcIHRzaWNsaeulvCDsmrDtmoztlanri4jri6QuXG4gICAgaWYgKGNtZCA9PT0gXCJ0ZXN0XCIpIHtcbiAgICAgIHJldHVybiB0ZXN0Q29tbWFuZCgpO1xuICAgIH1cblxuICAgIGF3YWl0IHRzaWNsaShmaWx0ZXJlZEFyZ3YsIHtcbiAgICAgIHR5cGVzOiB7XG4gICAgICAgIFwiI2VudGl0eUlkXCI6IHtcbiAgICAgICAgICB0eXBlOiBcImF1dG9jb21wbGV0ZVwiLFxuICAgICAgICAgIG5hbWU6IFwiI2VudGl0eUlkXCIsXG4gICAgICAgICAgbWVzc2FnZTogXCJQbGVhc2UgaW5wdXQgI2VudGl0eUlkXCIsXG4gICAgICAgICAgY2hvaWNlczogRW50aXR5TWFuYWdlci5nZXRBbGxQYXJlbnRJZHMoKS5tYXAoKGVudGl0eUlkKSA9PiAoe1xuICAgICAgICAgICAgdGl0bGU6IGVudGl0eUlkLFxuICAgICAgICAgICAgdmFsdWU6IGVudGl0eUlkLFxuICAgICAgICAgIH0pKSxcbiAgICAgICAgfSxcbiAgICAgICAgXCIjcmVjb3JkSWRzXCI6IFwibnVtYmVyW11cIixcbiAgICAgICAgXCIjbmFtZVwiOiBcInN0cmluZ1wiLFxuICAgICAgICBcIiN0YXJnZXRzXCI6IHtcbiAgICAgICAgICB0eXBlOiBcIm11bHRpc2VsZWN0XCIsXG4gICAgICAgICAgbmFtZTogXCIjdGFyZ2V0c1wiLFxuICAgICAgICAgIG1lc3NhZ2U6IFwiUGxlYXNlIGlucHV0ICN0YXJnZXRzXCIsXG4gICAgICAgICAgY2hvaWNlczogW1xuICAgICAgICAgICAgeyB0aXRsZTogXCJEZXZlbG9wbWVudFwiLCB2YWx1ZTogXCJkZXZlbG9wbWVudF9tYXN0ZXJcIiB9LFxuICAgICAgICAgICAgeyB0aXRsZTogXCJQcm9kdWN0aW9uXCIsIHZhbHVlOiBcInByb2R1Y3Rpb25fbWFzdGVyXCIgfSxcbiAgICAgICAgICAgIHsgdGl0bGU6IFwiRml4dHVyZVwiLCB2YWx1ZTogXCJmaXh0dXJlXCIgfSxcbiAgICAgICAgICAgIHsgdGl0bGU6IFwiVGVzdFwiLCB2YWx1ZTogXCJ0ZXN0XCIgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFyZ3M6IFtcbiAgICAgICAgW1wiZml4dHVyZVwiLCBcImluaXRcIl0sXG4gICAgICAgIFtcImZpeHR1cmVcIiwgXCJpbXBvcnRcIiwgXCIjZW50aXR5SWRcIiwgXCIjcmVjb3JkSWRzXCJdLFxuICAgICAgICBbXCJmaXh0dXJlXCIsIFwic3luY1wiXSxcbiAgICAgICAgW1wiZml4dHVyZVwiLCBcImdlblwiXSxcbiAgICAgICAgW1wiZml4dHVyZVwiLCBcImZldGNoXCJdLFxuICAgICAgICBbXCJmaXh0dXJlXCIsIFwiZXhwbG9yZVwiXSxcbiAgICAgICAgW1wibWlncmF0ZVwiLCBcInJ1blwiXSxcbiAgICAgICAgW1wibWlncmF0ZVwiLCBcImFwcGx5XCIsIFwiI3RhcmdldHNcIl0sXG4gICAgICAgIFtcIm1pZ3JhdGVcIiwgXCJnZW5lcmF0ZVwiXSxcbiAgICAgICAgW1wibWlncmF0ZVwiLCBcInN0YXR1c1wiXSxcbiAgICAgICAgW1wic3R1YlwiLCBcInByYWN0aWNlXCIsIFwiI25hbWVcIl0sXG4gICAgICAgIFtcInN0dWJcIiwgXCJlbnRpdHlcIiwgXCIjbmFtZVwiXSxcbiAgICAgICAgW1wic2NhZmZvbGRcIiwgXCJtb2RlbFwiLCBcIiNlbnRpdHlJZFwiXSxcbiAgICAgICAgW1wic2NhZmZvbGRcIiwgXCJtb2RlbF90ZXN0XCIsIFwiI2VudGl0eUlkXCJdLFxuICAgICAgICBbXCJzY2FmZm9sZFwiLCBcInZpZXdfbGlzdFwiLCBcIiNlbnRpdHlJZFwiXSxcbiAgICAgICAgW1wic2NhZmZvbGRcIiwgXCJ2aWV3X2Zvcm1cIiwgXCIjZW50aXR5SWRcIl0sXG4gICAgICAgIFtcImNvbmVcIiwgXCJnZW5cIiwgXCIjZW50aXR5SWRcIl0sXG4gICAgICAgIFtcInN5bmNcIl0sXG4gICAgICAgIFtcImJ1aWxkXCIsIFwiYWxsXCJdLFxuICAgICAgICBbXCJidWlsZFwiLCBcImFwaVwiXSxcbiAgICAgICAgW1wiYnVpbGRcIiwgXCJ3ZWJcIl0sXG4gICAgICAgIFtcImRldlwiLCBcImFsbFwiXSxcbiAgICAgICAgW1wiZGV2XCIsIFwiYXBpXCJdLFxuICAgICAgICBbXCJkZXZcIiwgXCJ3ZWJcIl0sXG4gICAgICAgIFtcInN0YXJ0XCJdLFxuICAgICAgICBbXCJza2lsbHNcIiwgXCJzeW5jXCJdLFxuICAgICAgICBbXCJza2lsbHNcIiwgXCJjcmVhdGVcIiwgXCIjbmFtZVwiXSxcbiAgICAgICAgW1widGVzdFwiXSxcbiAgICAgICAgW1wiYXV0aFwiLCBcImdlbmVyYXRlXCJdLFxuICAgICAgICBbXCJhdXRoXCIsIFwiYWRkLWNvbXBhbmlvbnNcIl0sXG4gICAgICBdLFxuICAgICAgcnVubmVyczoge1xuICAgICAgICBtaWdyYXRlX3N0YXR1cyxcbiAgICAgICAgbWlncmF0ZV9ydW4sXG4gICAgICAgIG1pZ3JhdGVfYXBwbHksXG4gICAgICAgIG1pZ3JhdGVfZ2VuZXJhdGUsXG4gICAgICAgIGZpeHR1cmVfaW5pdCxcbiAgICAgICAgZml4dHVyZV9pbXBvcnQsXG4gICAgICAgIGZpeHR1cmVfc3luYyxcbiAgICAgICAgZml4dHVyZV9nZW4sXG4gICAgICAgIGZpeHR1cmVfZmV0Y2gsXG4gICAgICAgIGZpeHR1cmVfZXhwbG9yZSxcbiAgICAgICAgc3R1Yl9wcmFjdGljZSxcbiAgICAgICAgc3R1Yl9lbnRpdHksXG4gICAgICAgIHNjYWZmb2xkX21vZGVsLFxuICAgICAgICBzY2FmZm9sZF9tb2RlbF90ZXN0LFxuICAgICAgICAvLyBzY2FmZm9sZF92aWV3X2xpc3QsXG4gICAgICAgIC8vIHNjYWZmb2xkX3ZpZXdfZm9ybSxcbiAgICAgICAgY29uZV9nZW4sXG4gICAgICAgIHN5bmMsXG4gICAgICAgIGJ1aWxkX2FsbCxcbiAgICAgICAgYnVpbGRfYXBpLFxuICAgICAgICBidWlsZF93ZWIsXG4gICAgICAgIGRldl9hbGwsXG4gICAgICAgIGRldl9hcGksXG4gICAgICAgIGRldl93ZWIsXG4gICAgICAgIHN0YXJ0LFxuICAgICAgICBza2lsbHNfc3luYyxcbiAgICAgICAgc2tpbGxzX2NyZWF0ZSxcbiAgICAgICAgdGVzdDogdGVzdENvbW1hbmQsXG4gICAgICAgIGF1dGhfZ2VuZXJhdGUsXG4gICAgICAgIFwiYXV0aF9hZGQtY29tcGFuaW9uc1wiOiBhdXRoX2FkZF9jb21wYW5pb25zLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfSBmaW5hbGx5IHtcbiAgICBhd2FpdCBTb25hbXUuZGVzdHJveSgpO1xuICB9XG59XG5cbmJvb3RzdHJhcCgpLmZpbmFsbHkoYXN5bmMgKCkgPT4ge1xuICBhd2FpdCBGaXh0dXJlTWFuYWdlci5kZXN0cm95KCk7XG59KTtcblxuLyoqXG4gKiBwbnBtIHN5bmMg7ZWY66m0IOyLpO2WieuQmOuKlCDtlajsiJjsnoXri4jri6QuXG4gKiDtlITroZzsoJ3tirjrpbwg7Iux7YGs7ZWp64uI64ukLlxuICpcbiAqIGAtLWZvcmNlYCDsmLXshZjsnbQg7KO87Ja07KeA66m0IGxvY2vsnYQg66y07Iuc7ZWY6rOgIO2SgC3si7Htgazrpbwg7IiY7ZaJ7ZWp64uI64ukLlxuICogZ2l0IHBvc3QtbWVyZ2UgaG9va+ydtOuCmCBDSeyXkOyEnCDrp6QgcHVsbCDtm4Qg7J6Q64+ZIOyLpO2Wie2VoCDsiJgg7J6I64+E66GdIOuFuOy2nC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc3luYygpIHtcbiAgY29uc3QgeyBmbGFncyB9ID0gcGFyc2VDbGlPcHRpb25zKCk7XG4gIGlmIChmbGFncy5oYXMoXCJmb3JjZVwiKSkge1xuICAgIGF3YWl0IFNvbmFtdS5zeW5jZXIuZm9yY2VTeW5jKCk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgU29uYW11LnN5bmNlci5zeW5jKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBUEkg6rCc67CcIOyEnOuyhOulvCDsi6TtlontlZjripQg6rO17Ya1IOuhnOyngeyeheuLiOuLpC5cbiAqIGRldl9hbGzqs7wgZGV2X2FwaeyXkOyEnCDqs7XsnKDtlanri4jri6QuXG4gKlxuICogVHlwZVNjcmlwdOulvCDrsJTroZwg7Iuk7ZaJ7ZWgIOyImCDsnojrj4TroZ0gQHNvbmFtdS1raXQvdHMtbG9hZGVy66W8LFxuICogSE1S7J2EIOyngOybkO2VmOq4sCDsnITtlbQgQHNvbmFtdS1raXQvaG1yLWhvb2vsnYQgaW1wb3J07ZWY66mwLFxuICog7IaM7Iqk66e1IOyngOybkOydhCDsnITtlbQgLS1lbmFibGUtc291cmNlLW1hcHMg7ZSM656Y6re466W8IO2PrO2VqO2VmOyXrCDsi6Ttlontlanri4jri6QuXG4gKlxuICog7J2065WMIEBzb25hbXUta2l0L3RzLWxvYWRlcuyZgCBAc29uYW11LWtpdC9obXItaG9va+uKlCBzb25hbXXqsIAg7J6Q7LK07KCB7Jy866GcIOqwgOyngOqzoCDsnojripQgZGVwZW5kZW5jeeyeheuLiOuLpC5cbiAqIOuYkO2VnCDsi6Ttlonsl5Ag7IKs7Jqp7ZWY64qUIEBzb25hbXUta2l0L2htci1ydW5uZXLrj4Qg66eI7LCs6rCA7KeA66GcIHNvbmFtdeqwgCDsnpDssrTsoIHsnLzroZwg6rCA7KeA6rOgIOyeiOuKlCBkZXBlbmRlbmN57J6F64uI64ukLlxuICog65Sw65287IScIOyCrOyaqeyekCDtlITroZzsoJ3tirjsl5DshJzripQg7J20IOyEuCDtjKjtgqTsp4Drpbwg7KeB7KCRIOyEpOy5mO2VoCDtlYTsmpTqsIAg7JeG7Iq164uI64ukLlxuICovXG5mdW5jdGlvbiBzcGF3bkFwaURldlNlcnZlcihvcHRpb25zPzogeyBleHRyYUVudj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfSkge1xuICBjb25zdCBhcGlSb290ID0gZmluZEFwaVJvb3RQYXRoKCk7XG4gIGNvbnN0IGVudHJ5UG9pbnQgPSBcInNyYy9pbmRleC50c1wiO1xuXG4gIC8vIOydtCBzb25hbXUg7Yyo7YKk7KeA6rCAIGRlcGVuZGVuY2llc+uhnCDqsIDsp4Dqs6Ag7J6I64qUIEBzb25hbXUta2l0L2htci1ydW5uZXLsnZggYmluL3J1bi5qc+ulvCDsgqzsmqntlanri4jri6QuXG4gIC8vIOydtCDqsr3roZwoL2Jpbi9ydW4uanMp64qUIEBzb25hbXUta2l0L2htci1ydW5uZXLsnZggcGFja2FnZS5qc29u7J2YIGJpbiDtlYTrk5zsl5Ag66qF7Iuc65CY7Ja0IOyeiOuKlCDqt7jqsoPqs7wg6rCZ7Iq164uI64ukLlxuICBjb25zdCBob3RSdW5uZXJCaW5QYXRoID0gY3JlYXRlUmVxdWlyZShpbXBvcnQubWV0YS51cmwpLnJlc29sdmUoXG4gICAgXCJAc29uYW11LWtpdC9obXItcnVubmVyL2Jpbi9ydW4uanNcIixcbiAgKTtcblxuICBjb25zdCBzZXJ2ZXJQcm9jZXNzID0gc3Bhd24oXG4gICAgcHJvY2Vzcy5leGVjUGF0aCwgLy8gbm9kZVxuICAgIFtcbiAgICAgIGhvdFJ1bm5lckJpblBhdGgsIC8vIOydtOugh+qyjCDtlbTshJwgaG90LXJ1bm5lcuulvCDsi6TtlontlZjqtazsmpRcbiAgICAgIFwiLS1jbGVhci1zY3JlZW49ZmFsc2VcIiwgLy8g7J207ZWYIGhvdC1ydW5uZXLsl5Dqsowg64SY6rKo7KSEIOyduOyekOuTpOyeheuLiOuLpC5cbiAgICAgIFwiLS1ub2RlLWFyZ3M9LS1pbXBvcnQ9c29uYW11L3RzLWxvYWRlci1yZWdpc3RlclwiLCAvLyBUeXBlU2NyaXB0IOyEnO2PrO2KuOulvCDsnITtlZwg66Gc642ULFxuICAgICAgXCItLW5vZGUtYXJncz0tLWltcG9ydD1zb25hbXUvaG1yLWhvb2stcmVnaXN0ZXJcIiwgLy8gSE1S7J2EIOyngOybkO2VmOq4sCDsnITtlZwgaG9vayxcbiAgICAgIFwiLS1ub2RlLWFyZ3M9LS1lbmFibGUtc291cmNlLW1hcHNcIiwgLy8g6re466as6rOgIOyGjOyKpOuntSDsp4Dsm5DsnYQg7JyE7ZWcIO2UjOuemOq3uOyeheuLiOuLpC5cbiAgICAgIFwiLS1vbi1rZXk9cjpyZXN0YXJ0OlJlc3RhcnQgc2VydmVyXCIsIC8vIHIg64iE66W066m0IOyEnOuyhCDsnqzsi5zsnpHtlZjqsowg7ZW07KSY7JqULlxuICAgICAgXCItLW9uLWtleT1jOmNsZWFyOkNsZWFyIHNjcmVlblwiLCAvLyBjIOuIhOultOuptCDthLDrr7jrhJAg7ZmU66m07J2EIOyngOybjOykmOyalC5cbiAgICAgIGAtLW9uLWtleT1mOnNoZWxsKHJtICR7cGF0aC5qb2luKGFwaVJvb3QsIFwic29uYW11LmxvY2tcIil9KTpyZXN0YXJ0OkZvcmNlIHJlc3RhcnRgLCAvLyBmIOuIhOultOuptCBsb2NrIOygnOqxsCDtm4Qg7J6s7Iuc7J6RIOKGkiDsg4gg7ZSE66Gc7IS47Iqk6rCAIOu2gO2KuOyKpO2KuOueqeyXkOyEnCDtkoAt7Iux7YGsLiBmb3JjZSBzeW5jIENMSeulvCBzaGVsbOuhnCDrtoDrpbTrqbQg7IK07JWE7J6I64qUIOyEnOuyhOydmCB3YXRjaGVyIO2Pre2SjeydtCA6cmVzdGFydOyZgCDstqnrj4ztlbQg7IOB7YOcIOydtOyDgS5cblxuICAgICAgXCItLW9uLWtleT1lbnRlcjpzaGVsbChlY2hvIGhpKTpLZXkgYmluZGluZyB0ZXN0XCIsIC8vIGVudGVy66W8IGtleeuhnCDsk7gg7IiYIOyeiOydjOydhCDrs7TsnbTquLAg7JyE7ZWcIO2FjOyKpO2KuOyeheuLiOuLpC5cbiAgICAgIFwiLS1vbi1rZXk9Y3RybCtmIGN0cmwrZjpzaGVsbChnaXQgcHVsbCAmJiBwbnBtIGluc3RhbGwgJiYgcG5wbSAtLWZpbHRlciBzb25hbXUgYnVpbGQgJiYgZWNobyAnU29uYW11IGlzIG5vdyB1cC10by1kYXRlIScpOnJlc3RhcnQ6UHVsbCAmIGluc3RhbGwgJiBidWlsZCAmIHJlc3RhcnRcIiwgLy8gbW9kaWZpZXLsmYDsnZgg7KGw7ZWpLCDqt7jrpqzqs6Ag65GQIOqwnOydmCBjaG9yZOulvCDsgqzsmqntlaAg7IiYIOyeiOydjOydhCDrs7TsnbTquLAg7JyE7ZWcIO2FjOyKpO2KuOyeheuLiOuLpC5cbiAgICAgIGVudHJ5UG9pbnQsIC8vIOuniOyngOunieycvOuhnCDsi6TsoJwg7Iuk7ZaJ7ZWgIOyKpO2BrOumve2KuOydmCDqsr3roZzrpbwg64SY6rKo7KSN64uI64ukLlxuICAgIF0sXG4gICAge1xuICAgICAgY3dkOiBhcGlSb290LFxuICAgICAgc3RkaW86IFwiaW5oZXJpdFwiLFxuICAgICAgZW52OiB7XG4gICAgICAgIC4uLnByb2Nlc3MuZW52LFxuICAgICAgICBOT0RFX0VOVjogXCJkZXZlbG9wbWVudFwiLFxuICAgICAgICBIT1Q6IFwieWVzXCIsIC8vIOyWmOqwgCDsnojslrTslbwgSE1S7J20IO2ZnOyEse2ZlOuQqeuLiOuLpC5cbiAgICAgICAgQVBJX1JPT1RfUEFUSDogYXBpUm9vdCwgLy8g7J20IOqyveuhnOqwgCBobXItaG9va+ydmCDro6jtirgg65SU66CJ7Yag66as6rCAIOuQqeuLiOuLpC5cbiAgICAgICAgLi4ub3B0aW9ucz8uZXh0cmFFbnYsXG4gICAgICB9LFxuICAgIH0sXG4gICk7XG5cbiAgLy8g7KKF66OMIOyymOumrFxuICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdyhcIlxcblxcbvCfkYsgU2h1dHRpbmcgZG93bi4uLlwiKSk7XG4gICAgc2VydmVyUHJvY2Vzcy5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICBwcm9jZXNzLmV4aXQoMCk7XG4gIH07XG5cbiAgcHJvY2Vzcy5vbihcIlNJR0lOVFwiLCBjbGVhbnVwKTtcbiAgcHJvY2Vzcy5vbihcIlNJR1RFUk1cIiwgY2xlYW51cCk7XG5cbiAgc2VydmVyUHJvY2Vzcy5vbihcImV4aXRcIiwgKGNvZGUpID0+IHtcbiAgICBpZiAoY29kZSAhPT0gMCkge1xuICAgICAgY29uc29sZS5lcnJvcihjaGFsay5yZWQoYFNlcnZlciBleGl0ZWQgd2l0aCBjb2RlICR7Y29kZX1gKSk7XG4gICAgICBwcm9jZXNzLmV4aXQoY29kZSB8fCAxKTtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIHBucG0gZGV2IC8gcG5wbSBkZXYgYWxsIO2VmOuptCDsi6TtlonrkJjripQg7ZWo7IiY7J6F64uI64ukLlxuICog7ZSE66Gc7KCd7Yq47JeQIOuMgO2VtCBITVIg7KeA7JuQ7ZWY64qUIOqwnOuwnCDshJzrsoTrpbwg652E7JuM7KSN64uI64ukLlxuICpcbiAqIFNvbmFtdS5pbml0IOyXhuydtCDtmLjstpzrkKAg6rKD7J2EIOyDgeygle2VmOyXrCDqtaztmITrkJjsl4jsirXri4jri6QuXG4gKi9cbmZ1bmN0aW9uIGRldl9hbGwoKSB7XG4gIGNvbnN0IHJlcXVpcmUgPSBjcmVhdGVSZXF1aXJlKGltcG9ydC5tZXRhLnVybCk7XG4gIGNvbnN0IHsgdmVyc2lvbiB9ID0gcmVxdWlyZShcIi4uLy4uL3BhY2thZ2UuanNvblwiKTtcbiAgY29uc29sZS5sb2coYPCfjLIgU29uYW11IHYke3ZlcnNpb259XFxuYCk7XG4gIHNwYXduQXBpRGV2U2VydmVyKCk7XG59XG5cbi8qKlxuICogcG5wbSBkZXYgYXBpIO2VmOuptCDsi6TtlonrkJjripQg7ZWo7IiY7J6F64uI64ukLlxuICogQVBJIOyghOyaqSDqsJzrsJwg7ISc67KE66W8IOudhOybgeuLiOuLpC5cbiAqIGRldl9hbGzqs7wg6rGw7J2YIOuPmeydvO2VmOuQmCwg7Ya17ZWpIOybuSDshJzrsoTrpbwg67mE7Zmc7ISx7ZmU7ZWp64uI64ukLlxuICpcbiAqIFNvbmFtdS5pbml0IOyXhuydtCDtmLjstpzrkKAg6rKD7J2EIOyDgeygle2VmOyXrCDqtaztmITrkJjsl4jsirXri4jri6QuXG4gKi9cbmZ1bmN0aW9uIGRldl9hcGkoKSB7XG4gIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdy5ib2xkKFwiU3RhcnRpbmcgU29uYW11IEFQSS1vbmx5IGRldiBzZXJ2ZXIuLi5cXG5cIikpO1xuICBzcGF3bkFwaURldlNlcnZlcih7XG4gICAgZXh0cmFFbnY6IHsgU09OQU1VX0RJU0FCTEVfSU5URUdSQVRFRF9XRUI6IFwieWVzXCIgfSxcbiAgfSk7XG59XG5cbi8qKlxuICogcG5wbSBkZXYgd2ViIO2VmOuptCDsi6TtlonrkJjripQg7ZWo7IiY7J6F64uI64ukLlxuICogVml0ZSDqsJzrsJwg7ISc67KE66W8IOuLqOuPheycvOuhnCDsi6Ttlontlanri4jri6QuXG4gKiAtLSDrkqTsnZgg7J247J6Q64qUIFZpdGXsl5Ag6re464yA66GcIOyghOuLrOuQqeuLiOuLpC5cbiAqXG4gKiBTb25hbXUuaW5pdCDsl4bsnbQg7Zi47Lac65CgIOqyg+ydhCDsg4HsoJXtlZjsl6wg6rWs7ZiE65CY7JeI7Iq164uI64ukLlxuICovXG5hc3luYyBmdW5jdGlvbiBkZXZfd2ViKCkge1xuICBjb25zdCBhcHBSb290ID0gZmluZEFwcFJvb3RQYXRoKCk7XG4gIGNvbnN0IHdlYlBhdGggPSBwYXRoLmpvaW4oYXBwUm9vdCwgXCJ3ZWJcIik7XG5cbiAgaWYgKCEoYXdhaXQgZXhpc3RzKHdlYlBhdGgpKSkge1xuICAgIGNvbnNvbGUuZXJyb3IoYHdlYiDrlJTroInthqDrpqzrpbwg7LC+7J2EIOyImCDsl4bsirXri4jri6Q6ICR7d2ViUGF0aH1gKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cblxuICAvLyAtLSDrkqTsnZgg7J247J6QIOy2lOy2nFxuICBjb25zdCBkb3VibGVEYXNoSW5kZXggPSBwcm9jZXNzLmFyZ3YuaW5kZXhPZihcIi0tXCIpO1xuICBjb25zdCBwYXNzdGhyb3VnaEFyZ3MgPSBkb3VibGVEYXNoSW5kZXggIT09IC0xID8gcHJvY2Vzcy5hcmd2LnNsaWNlKGRvdWJsZURhc2hJbmRleCArIDEpIDogW107XG5cbiAgY29uc3Qgdml0ZUFyZ3MgPSBbXCJleGVjXCIsIFwidml0ZVwiLCAuLi5wYXNzdGhyb3VnaEFyZ3NdO1xuXG4gIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdy5ib2xkKFwiU3RhcnRpbmcgVml0ZSBkZXYgc2VydmVyLi4uXFxuXCIpKTtcblxuICBjb25zdCB2aXRlUHJvY2VzcyA9IHNwYXduKFwicG5wbVwiLCB2aXRlQXJncywge1xuICAgIGN3ZDogd2ViUGF0aCxcbiAgICBzdGRpbzogXCJpbmhlcml0XCIsXG4gIH0pO1xuXG4gIHZpdGVQcm9jZXNzLm9uKFwiZXhpdFwiLCAoY29kZSkgPT4ge1xuICAgIHByb2Nlc3MuZXhpdChjb2RlID8/IDApO1xuICB9KTtcblxuICAvLyBTSUdJTlQvU0lHVEVSTSDsi5wgVml0ZSDtlITroZzshLjsiqTrpbwgZ3JhY2VmdWxseSDsooXro4ztlanri4jri6QuXG4gIGZvciAoY29uc3Qgc2lnbmFsIG9mIFtcIlNJR0lOVFwiLCBcIlNJR1RFUk1cIl0gYXMgY29uc3QpIHtcbiAgICBwcm9jZXNzLm9uKHNpZ25hbCwgKCkgPT4ge1xuICAgICAgdml0ZVByb2Nlc3Mua2lsbChzaWduYWwpO1xuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogQVBJIOu5jOuTnCDshKTsoJUg7YyM7J28IOqyveuhnOulvCDqsrDsoJXtlanri4jri6QuXG4gKiDtlITroZzsoJ3tirgg66Oo7Yq47JeQIGB0c2Rvd24uY29uZmlnLnRzYOqwgCDsnojsnLzrqbQg6re46rKD7J2ELCDsl4bsnLzrqbQgc29uYW11IOq4sOuzuCDshKTsoJXsnYQg7IKs7Jqp7ZWp64uI64ukLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlQXBpQnVpbGRDb25maWdQYXRoKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGxvY2FsQ29uZmlnUGF0aCA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCBcInRzZG93bi5jb25maWcudHNcIik7XG5cbiAgdHJ5IHtcbiAgICBpZiAoYXdhaXQgZXhpc3RzKGxvY2FsQ29uZmlnUGF0aCkpIHtcbiAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShcIlVzaW5nIHRzZG93bi5jb25maWcudHMgZnJvbSBwcm9qZWN0IHJvb3QuLi5cIikpO1xuICAgICAgcmV0dXJuIGxvY2FsQ29uZmlnUGF0aDtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhjaGFsay5kaW0oXCJVc2luZyBkZWZhdWx0IHRzZG93biBBUEkgY29uZmlnIGZyb20gc29uYW11IHBhY2thZ2UuLi5cIikpO1xuICAgIHJldHVybiBwYXRoLmpvaW4oaW1wb3J0Lm1ldGEuZGlybmFtZSwgXCIuLlwiLCBcIi4uXCIsIFwidHNkb3duLmFwaS5jb25maWcudHNcIik7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc29sZS5lcnJvcihjaGFsay5yZWQoXCJTZXR0aW5nIHVwIEFQSSBidWlsZCBjb25maWcgZmFpbGVkLlwiKSwgZXJyb3IpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxufVxuXG4vKipcbiAqIHNvbmFtdSBidWlsZCAvIHNvbmFtdSBidWlsZCBhbGwg7ZWY66m0IOyLpO2WieuQmOuKlCDtlajsiJjsnoXri4jri6QuXG4gKiBidWlsZF9hcGkgKyBidWlsZF93ZWLsnZgg7ZWp7ISx7J6F64uI64ukLiBXZWIg65SU66CJ7Yag66as6rCAIOyXhuycvOuptCBXZWIg67mM65Oc66W8IOyKpO2Cte2VqeuLiOuLpC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gYnVpbGRfYWxsKCkge1xuICBhd2FpdCBidWlsZF9hcGkoKTtcbiAgYXdhaXQgYnVpbGRfd2ViKHsgc2tpcElmTWlzc2luZzogdHJ1ZSB9KTtcbn1cblxuLyoqXG4gKiBwbnBtIGJ1aWxkIGFwaSDtlZjrqbQg7Iuk7ZaJ65CY64qUIO2VqOyImOyeheuLiOuLpC5cbiAqIEFQSSDtlITroZzsoJ3tirjrp4wg67mM65Oc7ZWp64uI64ukLlxuICpcbiAqIFNvbmFtdS5pbml0IOyXhuydtCDtmLjstpzrkKAg6rKD7J2EIOyDgeygle2VmOyXrCDqtaztmITrkJjsl4jsirXri4jri6QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGJ1aWxkX2FwaSgpIHtcbiAgY29uc3QgYXBwUm9vdCA9IGZpbmRBcHBSb290UGF0aCgpO1xuICBjb25zdCBjb25maWdGaWxlUGF0aCA9IGF3YWl0IHJlc29sdmVBcGlCdWlsZENvbmZpZ1BhdGgoKTtcblxuICBjb25zdCBhcGlTdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICB0cnkge1xuICAgIGZvciAoY29uc3QgYXJ0aWZhY3Qgb2YgQVBJX0FSVElGQUNUUykge1xuICAgICAgY29uc3QgY3dkID0gcGF0aC5qb2luKGFwcFJvb3QsIGFydGlmYWN0LnByb2plY3RQYXRoKTtcbiAgICAgIHByaW50VGFza0hlYWRlcihhcnRpZmFjdC5uYW1lLCBhcnRpZmFjdC5kZXNjcmlwdGlvbiwgY3dkKTtcblxuICAgICAgYXdhaXQgcnVuQnVpbGRTdGVwcyhhcnRpZmFjdCwgeyBjd2QsIGJ1aWxkQ29tbWFuZEFyZ3M6IHsgY29uZmlnRmlsZVBhdGggfSB9KTtcbiAgICB9XG4gICAgcHJpbnRCdWlsZFN1bW1hcnkoXCJBUElcIiwgdHJ1ZSwgRGF0ZS5ub3coKSAtIGFwaVN0YXJ0ZWRBdCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBwcmludEJ1aWxkU3VtbWFyeShcIkFQSVwiLCBmYWxzZSwgRGF0ZS5ub3coKSAtIGFwaVN0YXJ0ZWRBdCk7XG4gICAgY29uc29sZS5lcnJvcihlKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cbn1cblxuLyoqXG4gKiBwbnBtIGJ1aWxkIHdlYiDtlZjrqbQg7Iuk7ZaJ65CY64qUIO2VqOyImOyeheuLiOuLpC5cbiAqIFdlYiDtlITroZzsoJ3tirjrp4wg67mM65Oc7ZWp64uI64ukLlxuICpcbiAqIFNvbmFtdS5pbml0IOyXhuydtCDtmLjstpzrkKAg6rKD7J2EIOyDgeygle2VmOyXrCDqtaztmITrkJjsl4jsirXri4jri6QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGJ1aWxkX3dlYih7IHNraXBJZk1pc3NpbmcgPSBmYWxzZSB9ID0ge30pIHtcbiAgY29uc3QgYXBwUm9vdCA9IGZpbmRBcHBSb290UGF0aCgpO1xuICBjb25zdCB3ZWJQYXRoID0gcGF0aC5qb2luKGFwcFJvb3QsIFwid2ViXCIpO1xuXG4gIGlmICghKGF3YWl0IGV4aXN0cyh3ZWJQYXRoKSkpIHtcbiAgICBpZiAoc2tpcElmTWlzc2luZykge1xuICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JheShcIldlYiDrlJTroInthqDrpqzqsIAg7JeG7Jy866+A66GcIFdlYiDruYzrk5zrpbwg6rG064SI65yB64uI64ukLlwiKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnNvbGUuZXJyb3IoYHdlYiDrlJTroInthqDrpqzrpbwg7LC+7J2EIOyImCDsl4bsirXri4jri6Q6ICR7d2ViUGF0aH1gKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cblxuICBjb25zdCB3ZWJTdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICB0cnkge1xuICAgIGZvciAoY29uc3QgYXJ0aWZhY3Qgb2YgV0VCX0FSVElGQUNUUykge1xuICAgICAgY29uc3QgY3dkID0gcGF0aC5qb2luKGFwcFJvb3QsIGFydGlmYWN0LnByb2plY3RQYXRoKTtcbiAgICAgIHByaW50VGFza0hlYWRlcihhcnRpZmFjdC5uYW1lLCBhcnRpZmFjdC5kZXNjcmlwdGlvbiwgY3dkKTtcblxuICAgICAgYXdhaXQgcnVuQnVpbGRTdGVwcyhhcnRpZmFjdCwgeyBjd2QsIGJ1aWxkQ29tbWFuZEFyZ3M6IHt9IH0pO1xuICAgIH1cbiAgICBwcmludEJ1aWxkU3VtbWFyeShcIldlYlwiLCB0cnVlLCBEYXRlLm5vdygpIC0gd2ViU3RhcnRlZEF0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHByaW50QnVpbGRTdW1tYXJ5KFwiV2ViXCIsIGZhbHNlLCBEYXRlLm5vdygpIC0gd2ViU3RhcnRlZEF0KTtcbiAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxufVxuXG4vKipcbiAqIHByZS1idWlsZCwgYnVpbGQsIHBvc3QtYnVpbGQg64uo6rOE66W8IOyInOywqOyggeycvOuhnCDsi6Ttlontlanri4jri6QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJ1bkJ1aWxkU3RlcHM8VD4oXG4gIGFydGlmYWN0OiBCdWlsZEFydGlmYWN0PFQ+LFxuICBvcHRpb25zOiB7IGN3ZDogc3RyaW5nOyBidWlsZENvbW1hbmRBcmdzOiBUIH0sXG4pIHtcbiAgY29uc3Qgc3RlcHMgPSBbXG4gICAgeyBuYW1lOiBcInByZS1idWlsZFwiLCBjbWQ6IGFydGlmYWN0LnByZUJ1aWxkQ29tbWFuZD8uKCkgfSxcbiAgICB7IG5hbWU6IFwiYnVpbGRcIiwgY21kOiBhcnRpZmFjdC5idWlsZENvbW1hbmQob3B0aW9ucy5idWlsZENvbW1hbmRBcmdzKSB9LFxuICAgIHsgbmFtZTogXCJwb3N0LWJ1aWxkXCIsIGNtZDogYXJ0aWZhY3QucG9zdEJ1aWxkQ29tbWFuZD8uKCkgfSxcbiAgXS5maWx0ZXIoKHN0ZXApID0+IHN0ZXAuY21kKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHN0ZXBzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgc3RlcCA9IHN0ZXBzW2ldO1xuICAgIGNvbnN0IGlzTGFzdCA9IGkgPT09IHN0ZXBzLmxlbmd0aCAtIDE7XG5cbiAgICB0cnkge1xuICAgICAgYXNzZXJ0KHN0ZXAuY21kKTtcbiAgICAgIHByaW50VGFza1N0YXJ0KHN0ZXAubmFtZSwgc3RlcC5jbWQsIGlzTGFzdCk7XG4gICAgICBhd2FpdCBleGVjV2l0aExpbmVQcmVmaXgoc3RlcC5jbWQsIHsgY3dkOiBvcHRpb25zLmN3ZCB9KTtcbiAgICAgIHByaW50VGFza1N1Y2Nlc3Moc3RlcC5uYW1lLCBpc0xhc3QpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHByaW50VGFza0ZhaWxlZChzdGVwLm5hbWUsIGlzTGFzdCk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c3RlcC5uYW1lfSBmYWlsZWRgLCB7IGNhdXNlOiBlIH0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIHBucG0gc3RhcnQg7ZWY66m0IOyLpO2WieuQmOuKlCDtlajsiJjsnoXri4jri6QuXG4gKiDruYzrk5zrkJwg7ZSE66Gc7KCd7Yq466W8IOyLpO2Wie2VqeuLiOuLpC5cbiAqXG4gKiDruYzrk5zrkJwg6rKw6rO866y8KGRpc3Qg65SU66CJ7Yag66as7J2YIGluZGV4LmpzIOyXlO2KuOumrO2PrOyduO2KuCnsnbQg7JeG64uk66m0IOyLpO2WieydhCDspJHri6jtlanri4jri6QuXG4gKiDshozsiqTrp7Ug7KeA7JuQ6rO8IGRvdGVudiDsp4Dsm5DsnYQg7Y+s7ZWo7ZWY7JesIOyLpO2Wie2VqeuLiOuLpC5cbiAqXG4gKiBTb25hbXUuaW5pdCDsl4bsnbQg7Zi47Lac65CgIOqyg+ydhCDsg4HsoJXtlZjsl6wg6rWs7ZiE65CY7JeI7Iq164uI64ukLlxuICovXG5hc3luYyBmdW5jdGlvbiBzdGFydCgpIHtcbiAgY29uc3QgcmVxdWlyZSA9IGNyZWF0ZVJlcXVpcmUoaW1wb3J0Lm1ldGEudXJsKTtcbiAgY29uc3QgeyB2ZXJzaW9uIH0gPSByZXF1aXJlKFwiLi4vLi4vcGFja2FnZS5qc29uXCIpO1xuICBjb25zb2xlLmxvZyhg8J+MsiBTb25hbXUgdiR7dmVyc2lvbn1cXG5gKTtcblxuICBjb25zdCBhcGlSb290ID0gZmluZEFwaVJvb3RQYXRoKCk7XG4gIGNvbnN0IGVudHJ5UG9pbnQgPSBcImRpc3QvaW5kZXguanNcIjtcblxuICBpZiAoIShhd2FpdCBleGlzdHMoZW50cnlQb2ludCkpKSB7XG4gICAgY29uc29sZS5sb2coY2hhbGsucmVkKGAke2VudHJ5UG9pbnR9IG5vdCBmb3VuZC4gUGxlYXNlIGJ1aWxkIHlvdXIgcHJvamVjdCBmaXJzdC5gKSk7XG4gICAgY29uc29sZS5sb2coY2hhbGsuYmx1ZShcIlJ1bjogcG5wbSBzb25hbXUgYnVpbGRcIikpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHsgc3Bhd24gfSA9IGF3YWl0IGltcG9ydChcImNoaWxkX3Byb2Nlc3NcIik7XG4gIGNvbnN0IHNlcnZlclByb2Nlc3MgPSBzcGF3bihcbiAgICBwcm9jZXNzLmV4ZWNQYXRoLFxuICAgIFtcIi0tZW5hYmxlLXNvdXJjZS1tYXBzXCIsIFwiLXJcIiwgXCJkb3RlbnYvY29uZmlnXCIsIGVudHJ5UG9pbnRdLFxuICAgIHtcbiAgICAgIGN3ZDogYXBpUm9vdCxcbiAgICAgIHN0ZGlvOiBcImluaGVyaXRcIixcbiAgICB9LFxuICApO1xuXG4gIHByb2Nlc3Mub24oXCJTSUdJTlRcIiwgKCkgPT4ge1xuICAgIHNlcnZlclByb2Nlc3Mua2lsbChcIlNJR1RFUk1cIik7XG4gICAgcHJvY2Vzcy5leGl0KDApO1xuICB9KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc2V0dXBNaWdyYXRvcigpIHtcbiAgLy8gbWlncmF0b3JcbiAgbWlncmF0b3IgPSBuZXcgTWlncmF0b3IoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc2V0dXBGaXh0dXJlTWFuYWdlcigpIHtcbiAgRml4dHVyZU1hbmFnZXIuaW5pdCgpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBtaWdyYXRlX2FwcGx5KHRhcmdldHM6IChrZXlvZiBTb25hbXVEQkNvbmZpZylbXSkge1xuICBhd2FpdCBzZXR1cE1pZ3JhdG9yKCk7XG4gIGF3YWl0IG1pZ3JhdG9yLnJ1bkFjdGlvbihcImFwcGx5XCIsIHRhcmdldHMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBtaWdyYXRlX3J1bigpIHtcbiAgYXdhaXQgc2V0dXBNaWdyYXRvcigpO1xuICBjb25zdCBsb2NhbEhvc3RzID0gW1wibG9jYWxob3N0XCIsIFwiMTI3LjAuMC4xXCIsIFwiMC4wLjAuMFwiLCBcIjo6MVwiXTtcbiAgY29uc3QgdGFyZ2V0cyA9IE9iamVjdC5rZXlzKFNvbmFtdS5kYkNvbmZpZykuZmlsdGVyKCh0YXJnZXQpID0+IHtcbiAgICBjb25zdCB0YXJnZXRDb25maWcgPSBTb25hbXUuZGJDb25maWdbdGFyZ2V0IGFzIGtleW9mIFNvbmFtdURCQ29uZmlnXTtcbiAgICBjb25zdCBob3N0ID0gKHRhcmdldENvbmZpZz8uY29ubmVjdGlvbiBhcyB7IGhvc3Q/OiBzdHJpbmcgfSk/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcbiAgICByZXR1cm4gbG9jYWxIb3N0cy5pbmNsdWRlcyhob3N0LnRvTG93ZXJDYXNlKCkpO1xuICB9KTtcblxuICAvLyDroZzsu6wg642w7J207YSw67Kg7J207Iqk7JeQIOuMgO2VtOyEnOunjCDsoITssrQg66eI7J206re466CI7J207IWY7JeQ7IScIOuPmeyekVxuICBhd2FpdCBtaWdyYXRvci5ydW5BY3Rpb24oXCJhcHBseVwiLCB0YXJnZXRzIGFzIChrZXlvZiBTb25hbXVEQkNvbmZpZylbXSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG1pZ3JhdGVfZ2VuZXJhdGUoKSB7XG4gIGF3YWl0IHNldHVwTWlncmF0b3IoKTtcblxuICBjb25zdCB7IGNvbm5zIH0gPSBhd2FpdCBtaWdyYXRvci5nZXRTdGF0dXMoKTtcbiAgY29uc3QgaGFzU3RhdHVzMCA9IGNvbm5zLnNvbWUoKGNvbm4pID0+IGNvbm4uc3RhdHVzID09PSAwKTtcbiAgaWYgKCFoYXNTdGF0dXMwKSB7XG4gICAgY29uc29sZS5sb2coXG4gICAgICBjaGFsay5yZWQoXG4gICAgICAgIFwi66eI7J206re466CI7J207IWYIO2MjOydvOydhCDsg53shLHtlZjroKTrqbQg6riw7KG0IOuniOydtOq3uOugiOydtOyFmOydtCDstZzshowg7ZWY64KY7J2YIERC7JeQIOuqqOuRkCDsoIHsmqnrkJjslrQg7J6I7Ja07JW8IO2VqeuLiOuLpC5cIixcbiAgICAgICksXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGNvbm4gb2YgY29ubnMpIHtcbiAgICAgIGlmIChjb25uLnBlbmRpbmcubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zb2xlLmxvZyhjaGFsay55ZWxsb3coYCAgJHtjb25uLm5hbWV9OiBwZW5kaW5nICR7Y29ubi5wZW5kaW5nLmxlbmd0aH3qsJxgKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuXG4gIGNvbnN0IGNvdW50ID0gYXdhaXQgbWlncmF0b3IuZ2VuZXJhdGVQcmVwYXJlZENvZGVzKCk7XG4gIGlmIChjb3VudCA+IDApIHtcbiAgICBjb25zb2xlLmxvZyhjaGFsay5ncmVlbihgJHtjb3VudH3qsJzsnZgg66eI7J206re466CI7J207IWYIO2MjOydvOydtCDsg53shLHrkJjsl4jsirXri4jri6QuYCkpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG1pZ3JhdGVfc3RhdHVzKCkge1xuICBhd2FpdCBzZXR1cE1pZ3JhdG9yKCk7XG5cbiAgY29uc3Qgc3RhdHVzID0gYXdhaXQgbWlncmF0b3IuZ2V0U3RhdHVzKCk7XG4gIC8vIHN0YXR1cztcbiAgY29uc29sZS5sb2coc3RhdHVzKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZml4dHVyZV9pbml0KCkge1xuICBjb25zdCBzcmNDb25maWcgPSBTb25hbXUuZGJDb25maWcuZGV2ZWxvcG1lbnRfbWFzdGVyO1xuICBjb25zdCB0YXJnZXRzID0gW1xuICAgIHtcbiAgICAgIGxhYmVsOiBcIihSRU1PVEUpIEZpeHR1cmUgREJcIixcbiAgICAgIGNvbmZpZzogU29uYW11LmRiQ29uZmlnLmZpeHR1cmUsXG4gICAgfSxcbiAgICB7XG4gICAgICBsYWJlbDogXCIoTE9DQUwpIFRlc3RpbmcgREJcIixcbiAgICAgIGNvbmZpZzogU29uYW11LmRiQ29uZmlnLnRlc3QsXG4gICAgICB0b1NraXA6ICgoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbW90ZUNvbm4gPSBTb25hbXUuZGJDb25maWcuZml4dHVyZS5jb25uZWN0aW9uIGFzIEtuZXguQ29ubmVjdGlvbkNvbmZpZztcbiAgICAgICAgY29uc3QgbG9jYWxDb25uID0gU29uYW11LmRiQ29uZmlnLnRlc3QuY29ubmVjdGlvbiBhcyBLbmV4LkNvbm5lY3Rpb25Db25maWc7XG4gICAgICAgIHJldHVybiByZW1vdGVDb25uLmhvc3QgPT09IGxvY2FsQ29ubi5ob3N0ICYmIHJlbW90ZUNvbm4uZGF0YWJhc2UgPT09IGxvY2FsQ29ubi5kYXRhYmFzZTtcbiAgICAgIH0pKCksXG4gICAgfSxcbiAgXSBhcyB7XG4gICAgbGFiZWw6IHN0cmluZztcbiAgICBjb25maWc6IEtuZXguQ29uZmlnO1xuICAgIHRvU2tpcD86IGJvb2xlYW47XG4gIH1bXTtcblxuICAvLyAxLiDquLDspIBEQiDsiqTtgqTrp4jrpbwg642k7ZSEXG4gIGNvbnNvbGUubG9nKFwiRFVNUC4uLlwiKTtcbiAgY29uc3QgZHVtcEZpbGVuYW1lID0gYC90bXAvc29uYW11LWZpeHR1cmUtaW5pdC0ke0RhdGUubm93KCl9LnNxbGA7XG4gIGNvbnN0IHNyY0Nvbm4gPSBzcmNDb25maWcuY29ubmVjdGlvbiBhcyBLbmV4LkNvbm5lY3Rpb25Db25maWc7XG4gIGNvbnN0IG1pZ3JhdGlvbnNEdW1wID0gYC90bXAvc29uYW11LWZpeHR1cmUtaW5pdC1taWdyYXRpb25zLSR7RGF0ZS5ub3coKX0uc3FsYDtcbiAgZXhlY1N5bmMoXG4gICAgYG15c3FsZHVtcCAtaCR7c3JjQ29ubi5ob3N0fSAtdSR7c3JjQ29ubi51c2VyfSAtcCR7c3JjQ29ubi5wYXNzd29yZH0gLS1zaW5nbGUtdHJhbnNhY3Rpb24gLWQgLS1uby1jcmVhdGUtZGIgLS10cmlnZ2VycyAke3NyY0Nvbm4uZGF0YWJhc2V9ID4gJHtkdW1wRmlsZW5hbWV9YCxcbiAgKTtcbiAgY29uc3QgX2RiID0ga25leChzcmNDb25maWcpO1xuICBjb25zdCBbW21pZ3JhdGlvbnNdXSA9IGF3YWl0IF9kYi5yYXcoXG4gICAgXCJTRUxFQ1QgQ09VTlQoKikgYXMgY291bnQgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVzIFdIRVJFIHRhYmxlX3NjaGVtYSA9ID8gQU5EIHRhYmxlX25hbWUgPSAna25leF9taWdyYXRpb25zJ1wiLFxuICAgIFtzcmNDb25uLmRhdGFiYXNlXSxcbiAgKTtcbiAgaWYgKG1pZ3JhdGlvbnMuY291bnQgPiAwKSB7XG4gICAgZXhlY1N5bmMoXG4gICAgICBgbXlzcWxkdW1wIC1oJHtzcmNDb25uLmhvc3R9IC11JHtzcmNDb25uLnVzZXJ9IC1wJHtzcmNDb25uLnBhc3N3b3JkfSAtLXNpbmdsZS10cmFuc2FjdGlvbiAtLW5vLWNyZWF0ZS1kYiAtLXRyaWdnZXJzICR7c3JjQ29ubi5kYXRhYmFzZX0ga25leF9taWdyYXRpb25zIGtuZXhfbWlncmF0aW9uc19sb2NrID4gJHttaWdyYXRpb25zRHVtcH1gLFxuICAgICk7XG4gIH1cblxuICAvLyAyLiDrjIDsg4FEQiDqsIHqsIHsl5Ag64yA7ZWY7JesIOyhtOyerOyXrOu2gCDtmZXsnbgg7ZuEIOu2k+q4sFxuICBmb3IgKGNvbnN0IHsgbGFiZWwsIGNvbmZpZywgdG9Ta2lwIH0gb2YgdGFyZ2V0cykge1xuICAgIGNvbnN0IGNvbm4gPSBjb25maWcuY29ubmVjdGlvbiBhcyBLbmV4LkNvbm5lY3Rpb25Db25maWc7XG5cbiAgICBpZiAodG9Ta2lwID09PSB0cnVlKSB7XG4gICAgICBjb25zb2xlLmxvZyhjaGFsay5yZWQoYCR7bGFiZWx9OiBTa2lwcGVkIWApKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGRiID0ga25leCh7XG4gICAgICAuLi5jb25maWcsXG4gICAgICBjb25uZWN0aW9uOiB7XG4gICAgICAgIC4uLigoY29uZmlnLmNvbm5lY3Rpb24gPz8ge30pIGFzIEtuZXguQ29ubmVjdGlvbkNvbmZpZyksXG4gICAgICAgIGRhdGFiYXNlOiB1bmRlZmluZWQsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGNvbnN0IFtbcm93XV0gPSBhd2FpdCBkYi5yYXcoYFNIT1cgREFUQUJBU0VTIExJS0UgXCIke2Nvbm4uZGF0YWJhc2V9XCJgKTtcbiAgICBpZiAocm93KSB7XG4gICAgICBjb25zb2xlLmxvZyhjaGFsay55ZWxsb3coYCR7bGFiZWx9OiBEYXRhYmFzZSBcIiR7Y29ubi5kYXRhYmFzZX1cIiBBbHJlYWR5IGV4aXN0c2ApKTtcbiAgICAgIGF3YWl0IGRiLmRlc3Ryb3koKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKGBTWU5DIHRvICR7bGFiZWx9Li4uYCk7XG4gICAgY29uc3QgbXlzcWxDbWQgPSBgbXlzcWwgLWgke2Nvbm4uaG9zdH0gLXUke2Nvbm4udXNlcn0gLXAke2Nvbm4ucGFzc3dvcmR9YDtcbiAgICBleGVjU3luYyhgJHtteXNxbENtZH0gLWUgJ0RST1AgREFUQUJBU0UgSUYgRVhJU1RTIFxcYCR7Y29ubi5kYXRhYmFzZX1cXGAnYCk7XG4gICAgZXhlY1N5bmMoYCR7bXlzcWxDbWR9IC1lICdDUkVBVEUgREFUQUJBU0UgXFxgJHtjb25uLmRhdGFiYXNlfVxcYCdgKTtcbiAgICBleGVjU3luYyhgJHtteXNxbENtZH0gJHtjb25uLmRhdGFiYXNlfSA8ICR7ZHVtcEZpbGVuYW1lfWApO1xuICAgIGlmIChhd2FpdCBleGlzdHMobWlncmF0aW9uc0R1bXApKSB7XG4gICAgICBleGVjU3luYyhgJHtteXNxbENtZH0gJHtjb25uLmRhdGFiYXNlfSA8ICR7bWlncmF0aW9uc0R1bXB9YCk7XG4gICAgfVxuXG4gICAgYXdhaXQgZGIuZGVzdHJveSgpO1xuICB9XG5cbiAgYXdhaXQgX2RiLmRlc3Ryb3koKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZml4dHVyZV9pbXBvcnQoZW50aXR5SWQ6IHN0cmluZywgcmVjb3JkSWRzOiBudW1iZXJbXSkge1xuICBhd2FpdCBzZXR1cEZpeHR1cmVNYW5hZ2VyKCk7XG5cbiAgYXdhaXQgRml4dHVyZU1hbmFnZXIuaW1wb3J0Rml4dHVyZShlbnRpdHlJZCwgcmVjb3JkSWRzKTtcbiAgYXdhaXQgRml4dHVyZU1hbmFnZXIuc3luYygpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmaXh0dXJlX3N5bmMoKSB7XG4gIGF3YWl0IHNldHVwRml4dHVyZU1hbmFnZXIoKTtcblxuICBhd2FpdCBGaXh0dXJlTWFuYWdlci5zeW5jKCk7XG59XG5cbi8qKlxuICogZml4dHVyZSBnZW4g66qF66C57Ja0XG4gKiDsmLXshZjsnYQgcHJvY2Vzcy5hcmd27JeQ7IScIO2MjOyLsVxuICovXG5hc3luYyBmdW5jdGlvbiBmaXh0dXJlX2dlbigpIHtcbiAgY29uc3Qgb3B0aW9ucyA9IHBhcnNlT3B0aW9ucyhwcm9jZXNzLmFyZ3YpO1xuICBhd2FpdCBmaXh0dXJlR2VuQ29tbWFuZChvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBmaXh0dXJlIGZldGNoIOuqheugueyWtFxuICog7Ji17IWY7J2EIHByb2Nlc3MuYXJnduyXkOyEnCDtjIzsi7FcbiAqL1xuYXN5bmMgZnVuY3Rpb24gZml4dHVyZV9mZXRjaCgpIHtcbiAgY29uc3Qgb3B0aW9ucyA9IHBhcnNlT3B0aW9ucyhwcm9jZXNzLmFyZ3YpO1xuICBhd2FpdCBmaXh0dXJlRmV0Y2hDb21tYW5kKG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIGZpeHR1cmUgZXhwbG9yZSDrqoXroLnslrRcbiAqIOyYteyFmOydhCBwcm9jZXNzLmFyZ3bsl5DshJwg7YyM7IuxXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZpeHR1cmVfZXhwbG9yZSgpIHtcbiAgY29uc3Qgb3B0aW9ucyA9IHBhcnNlT3B0aW9ucyhwcm9jZXNzLmFyZ3YpO1xuICBhd2FpdCBmaXh0dXJlRXhwbG9yZUNvbW1hbmQob3B0aW9ucyk7XG59XG5cbi8qKlxuICog6rCE64uo7ZWcIOyYteyFmCDtjIzshJxcbiAqL1xuZnVuY3Rpb24gcGFyc2VPcHRpb25zKFxuICBhcmd2OiBzdHJpbmdbXSxcbik6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IGJvb2xlYW4gfCBzdHJpbmdbXT4gJiB7IF86IHN0cmluZ1tdIH0ge1xuICBjb25zdCBvcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBib29sZWFuIHwgc3RyaW5nW10+ICYgeyBfOiBzdHJpbmdbXSB9ID0geyBfOiBbXSB9O1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJndi5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGFyZyA9IGFyZ3ZbaV07XG5cbiAgICBpZiAoYXJnLnN0YXJ0c1dpdGgoXCItLVwiKSkge1xuICAgICAgY29uc3Qga2V5ID0gYXJnLnNsaWNlKDIpO1xuXG4gICAgICBpZiAoa2V5LmluY2x1ZGVzKFwiPVwiKSkge1xuICAgICAgICBjb25zdCBbaywgdl0gPSBrZXkuc3BsaXQoXCI9XCIpO1xuICAgICAgICBvcHRpb25zW2tdID0gdjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IG5leHQgPSBhcmd2W2kgKyAxXTtcbiAgICAgICAgaWYgKG5leHQgJiYgIW5leHQuc3RhcnRzV2l0aChcIi0tXCIpKSB7XG4gICAgICAgICAgb3B0aW9uc1trZXldID0gbmV4dDtcbiAgICAgICAgICBpKys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3B0aW9uc1trZXldID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYXJnLnN0YXJ0c1dpdGgoXCItXCIpKSB7XG4gICAgICBjb25zdCBrZXkgPSBhcmcuc2xpY2UoMSk7XG4gICAgICBjb25zdCBuZXh0ID0gYXJndltpICsgMV07XG5cbiAgICAgIGlmIChuZXh0ICYmICFuZXh0LnN0YXJ0c1dpdGgoXCItXCIpKSB7XG4gICAgICAgIG9wdGlvbnNba2V5XSA9IG5leHQ7XG4gICAgICAgIGkrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9wdGlvbnNba2V5XSA9IHRydWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMuXy5wdXNoKGFyZyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9wdGlvbnM7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHN0dWJfcHJhY3RpY2UobmFtZTogc3RyaW5nKSB7XG4gIGNvbnN0IHByYWN0aWNlRGlyID0gcGF0aC5qb2luKFNvbmFtdS5hcGlSb290UGF0aCwgXCJzcmNcIiwgXCJwcmFjdGljZXNcIik7XG4gIGNvbnN0IGZpbGVOYW1lcyA9IGF3YWl0IHJlYWRkaXIocHJhY3RpY2VEaXIpO1xuXG4gIGNvbnN0IG1heFNlcU5vID0gYXdhaXQgKGFzeW5jICgpID0+IHtcbiAgICBpZiAoIShhd2FpdCBleGlzdHMocHJhY3RpY2VEaXIpKSkge1xuICAgICAgYXdhaXQgbWtkaXIocHJhY3RpY2VEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbHRlcmVkU2VxcyA9IGZpbGVOYW1lc1xuICAgICAgLmZpbHRlcigoZmlsZU5hbWUpID0+IGZpbGVOYW1lLnN0YXJ0c1dpdGgoXCJwXCIpICYmIGZpbGVOYW1lLmVuZHNXaXRoKFwiLnRzXCIpKVxuICAgICAgLm1hcCgoZmlsZU5hbWUpID0+IHtcbiAgICAgICAgY29uc3QgWywgc2VxTm9dID0gZmlsZU5hbWUubWF0Y2goL15wKFswLTldKyktLykgPz8gW1wiMFwiLCBcIjBcIl07XG4gICAgICAgIHJldHVybiBwYXJzZUludChzZXFObyk7XG4gICAgICB9KVxuICAgICAgLnRvU29ydGVkKChhLCBiKSA9PiBiIC0gYSk7XG5cbiAgICBpZiAoZmlsdGVyZWRTZXFzLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiBmaWx0ZXJlZFNlcXNbMF07XG4gICAgfVxuXG4gICAgcmV0dXJuIDA7XG4gIH0pKCk7XG5cbiAgY29uc3QgY3VycmVudFNlcU5vID0gbWF4U2VxTm8gKyAxO1xuICBjb25zdCBmaWxlTmFtZSA9IGBwJHtjdXJyZW50U2VxTm99LSR7bmFtZX0udHNgO1xuICBjb25zdCBkc3RQYXRoID0gcGF0aC5qb2luKHByYWN0aWNlRGlyLCBmaWxlTmFtZSk7XG5cbiAgY29uc3QgY29kZSA9IFtcbiAgICBgaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcInNvbmFtdVwiO2AsXG4gICAgXCJcIixcbiAgICBgY29uc29sZS5jbGVhcigpO2AsXG4gICAgYGNvbnNvbGUubG9nKFwiJHtmaWxlTmFtZX1cIik7YCxcbiAgICBcIlwiLFxuICAgIGBTb25hbXUucnVuU2NyaXB0KGFzeW5jICgpID0+IHtgLFxuICAgIGAgLy8gVE9ET2AsXG4gICAgYH0pO2AsXG4gICAgXCJcIixcbiAgXS5qb2luKFwiXFxuXCIpO1xuICBhd2FpdCB3cml0ZUZpbGUoZHN0UGF0aCwgY29kZSk7XG5cbiAgZXhlY1N5bmMoYGNvZGUgJHtkc3RQYXRofWApO1xuXG4gIGNvbnN0IHJ1bkNvZGUgPSBgeWFybiBub2RlIC1yIGRvdGVudi9jb25maWcgLS1lbmFibGUtc291cmNlLW1hcHMgZGlzdC9wcmFjdGljZXMvJHtmaWxlTmFtZS5yZXBsYWNlKFxuICAgIFwiLnRzXCIsXG4gICAgXCIuanNcIixcbiAgKX1gO1xuICBjb25zb2xlLmxvZyhgJHtjaGFsay5ibHVlKHJ1bkNvZGUpfSBjb3BpZWQgdG8gY2xpcGJvYXJkLmApO1xuICBleGVjU3luYyhgZWNobyBcIiR7cnVuQ29kZX1cIiB8IHBiY29weWApO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzdHViX2VudGl0eShlbnRpdHlJZDogc3RyaW5nKSB7XG4gIGF3YWl0IFNvbmFtdS5zeW5jZXIuY3JlYXRlRW50aXR5KHsgZW50aXR5SWQsIHRpdGxlOiBlbnRpdHlJZCB9KTtcblxuICBjb25zdCB7IGZsYWdzIH0gPSBwYXJzZUNsaU9wdGlvbnMoKTtcbiAgY29uc3QgdXNlQUkgPSBmbGFncy5oYXMoXCJhaVwiKTtcbiAgY29uc3Qgbm9Db25lcyA9IGZsYWdzLmhhcyhcIm5vLWNvbmVzXCIpO1xuXG4gIC8vIC0tbm8tY29uZXM6IGNvbmUg7IOd7ISxIOyKpO2CtVxuICBpZiAobm9Db25lcykge1xuICAgIGNvbnNvbGUubG9nKGDinJMgRW50aXR5ICcke2VudGl0eUlkfScgY3JlYXRlZCB3aXRob3V0IGNvbmVzYCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgeyBFbnRpdHlNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIik7XG4gIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgaWYgKCFlbnRpdHkpIHtcbiAgICBjb25zb2xlLmVycm9yKGBFbnRpdHkgbm90IGZvdW5kOiAke2VudGl0eUlkfWApO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIC0tYWk6IExMTeycvOuhnCBjb25lIOyDneyEsVxuICBpZiAodXNlQUkpIHtcbiAgICBjb25zb2xlLmxvZyhg4pyTIEVudGl0eSAnJHtlbnRpdHlJZH0nIGNyZWF0ZWRgKTtcbiAgICBjb25zb2xlLmxvZyhg8J+MnyBHZW5lcmF0aW5nIEFJLXBvd2VyZWQgY29uZXMuLi5gKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY29uZmlnTG9jYWxlID0gU29uYW11LmNvbmZpZy5pMThuPy5kZWZhdWx0TG9jYWxlO1xuICAgICAgY29uc3QgbG9jYWxlID1cbiAgICAgICAgY29uZmlnTG9jYWxlID09PSBcImtvXCIgfHwgY29uZmlnTG9jYWxlID09PSBcImVuXCIgfHwgY29uZmlnTG9jYWxlID09PSBcImphXCJcbiAgICAgICAgICA/IGNvbmZpZ0xvY2FsZVxuICAgICAgICAgIDogXCJrb1wiO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlbnRpdHkuZ2VuZXJhdGVDb25lcyh7XG4gICAgICAgIHByZXNlcnZlRXhpc3Rpbmc6IGZhbHNlLFxuICAgICAgICBvbmx5RW1wdHk6IGZhbHNlLFxuICAgICAgICBsb2NhbGUsXG4gICAgICB9KTtcblxuICAgICAgY29uc29sZS5sb2coYOKchSBEb25lICgke3Jlc3VsdC50b2tlbnNVc2VkfSB0b2tlbnMpYCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoXCJBTlRIUk9QSUNfQVBJX0tFWVwiKSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBcXG7inYwgJHtlcnJvci5tZXNzYWdlfWApO1xuICAgICAgICBjb25zb2xlLmVycm9yKGBcXG7wn5KhIFJlbW92ZSAtLWFpIGZsYWcgdG8gdXNlIHRlbXBsYXRlIGNvbmVzIGluc3RlYWRgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICAvLyDquLDrs7g6IO2FnO2UjOumvyBjb25lIOyekOuPmSDsg53shLFcbiAgLy8gTExNIOyXhuydtCBmYWtlci1tYXBwaW5ncy50c+ulvCDtmZzsmqntlZjsl6wg6riw67O4IGNvbmUg66mU7YOA642w7J207YSw66W8IOyDneyEse2VqeuLiOuLpC5cbiAgLy8g7J2066W8IO2Gte2VtCBBTlRIUk9QSUNfQVBJX0tFWeqwgCDsl4bslrTrj4QgU29uYW1166W8IOyCrOyaqe2VoCDsiJgg7J6I7Jy866mwLFxuICAvLyDsg53shLHrkJwg7YWc7ZSM66a/IGNvbmXsnYAg64KY7KSR7JeQICdjb25lIGdlbicg66qF66C57Ja066GcIEFJ66W8IO2Gte2VtCDsl4Xqt7jroIjsnbTrk5ztlaAg7IiYIOyeiOyKteuLiOuLpC5cbiAgY29uc29sZS5sb2coYPCfjJ8gR2VuZXJhdGluZyB0ZW1wbGF0ZSBjb25lcy4uLmApO1xuICBhd2FpdCBlbnRpdHkuZ2VuZXJhdGVUZW1wbGF0ZUNvbmVzKCk7XG4gIGNvbnNvbGUubG9nKGDinJMgRW50aXR5ICcke2VudGl0eUlkfScgY3JlYXRlZCB3aXRoIHRlbXBsYXRlIGNvbmVzYCk7XG4gIGNvbnNvbGUubG9nKGDwn5KhIFRpcDogUnVuICdwbnBtIHNvbmFtdSBjb25lIGdlbiAke2VudGl0eUlkfScgdG8gaW1wcm92ZSB3aXRoIEFJYCk7XG59XG5cbi8qKlxuICogQUnrpbwg7IKs7Jqp7ZWY7JesIGVudGl0eeydmCBjb25lIOuplO2DgOuNsOydtO2EsOulvCDsg53shLHtlZjqsbDrgpgg7JeF6re466CI7J2065Oc7ZWp64uI64ukLlxuICpcbiAqIOyYteyFmDpcbiAqIC0gLS1yZWdlbmVyYXRlOiDsoITssrQg7J6s7IOd7ISxICjquLDsobQgY29uZSDrja7slrTsk7DquLApXG4gKiAtIC0tbG9jYWxlIDxrb3xlbnxqYT46IOyDneyEsSDslrjslrQg7KeA7KCVXG4gKiAtIOq4sOuzuDogb25seUVtcHR5IOuqqOuTnCAo6riw7KG0IGZpeHR1cmVIaW50IOuztOyhtClcbiAqXG4gKiBBTlRIUk9QSUNfQVBJX0tFWSDtlYTsmpQgKHNvbmFtdS5zZWNyZXQudHMg65iQ64qUIO2ZmOqyveuzgOyImClcbiAqL1xuYXN5bmMgZnVuY3Rpb24gY29uZV9nZW4oZW50aXR5SWQ6IHN0cmluZykge1xuICBjb25zdCB7IEVudGl0eU1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2VudGl0eS9lbnRpdHktbWFuYWdlclwiKTtcbiAgY29uc3QgeyBmbGFncywgb3B0aW9ucyB9ID0gcGFyc2VDbGlPcHRpb25zKCk7XG5cbiAgLy8gLS1hbGwg7Ji17IWYOiDrqqjrk6AgZW50aXR5IGNvbmUg7IOd7ISxXG4gIGlmIChmbGFncy5oYXMoXCJhbGxcIikgfHwgZW50aXR5SWQgPT09IFwiYWxsXCIpIHtcbiAgICBjb25zdCBhbGxFbnRpdGllcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsRW50aXRpZXMoKTtcbiAgICBjb25zb2xlLmxvZyhg8J+MnyBHZW5lcmF0aW5nIEFJLXBvd2VyZWQgY29uZXMgZm9yICR7YWxsRW50aXRpZXMubGVuZ3RofSBlbnRpdGllcy4uLlxcbmApO1xuXG4gICAgbGV0IHRvdGFsVG9rZW5zID0gMDtcbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBhbGxFbnRpdGllcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc29sZS5sb2coYFByb2Nlc3NpbmcgJHtlbnRpdHkuaWR9Li4uYCk7XG4gICAgICAgIGNvbnN0IGNvbmZpZ0xvY2FsZSA9IG9wdGlvbnMubG9jYWxlIHx8IFNvbmFtdS5jb25maWcuaTE4bj8uZGVmYXVsdExvY2FsZTtcbiAgICAgICAgY29uc3QgbG9jYWxlID1cbiAgICAgICAgICBjb25maWdMb2NhbGUgPT09IFwia29cIiB8fCBjb25maWdMb2NhbGUgPT09IFwiZW5cIiB8fCBjb25maWdMb2NhbGUgPT09IFwiamFcIlxuICAgICAgICAgICAgPyBjb25maWdMb2NhbGVcbiAgICAgICAgICAgIDogXCJrb1wiO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVudGl0eS5nZW5lcmF0ZUNvbmVzKHtcbiAgICAgICAgICBwcmVzZXJ2ZUV4aXN0aW5nOiAhZmxhZ3MuaGFzKFwicmVnZW5lcmF0ZVwiKSxcbiAgICAgICAgICBvbmx5RW1wdHk6ICFmbGFncy5oYXMoXCJyZWdlbmVyYXRlXCIpLFxuICAgICAgICAgIGxvY2FsZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdG90YWxUb2tlbnMgKz0gcmVzdWx0LnRva2Vuc1VzZWQ7XG4gICAgICAgIGNvbnNvbGUubG9nKGAgIOKckyAke2VudGl0eS5pZH0gKCR7cmVzdWx0LnRva2Vuc1VzZWR9IHRva2VucylcXG5gKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFwiVW5rbm93biBlcnJvclwiO1xuICAgICAgICBlcnJvcnMucHVzaChgJHtlbnRpdHkuaWR9OiAke21lc3NhZ2V9YCk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYCAg4pyXICR7ZW50aXR5LmlkfTogJHttZXNzYWdlfVxcbmApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKGBcXG7inIUgRG9uZSEgVG90YWw6ICR7dG90YWxUb2tlbnN9IHRva2VucyB1c2VkYCk7XG4gICAgY29uc3QgZXN0aW1hdGVkQ29zdCA9ICh0b3RhbFRva2VucyAqIDkpIC8gMV8wMDBfMDAwO1xuICAgIGNvbnNvbGUubG9nKGDwn5KwIEVzdGltYXRlZCBjb3N0OiB+JCR7ZXN0aW1hdGVkQ29zdC50b0ZpeGVkKDQpfWApO1xuXG4gICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGBcXG7inYwgRmFpbGVkIGVudGl0aWVzICgke2Vycm9ycy5sZW5ndGh9KTpgKTtcbiAgICAgIGZvciAoY29uc3QgZXJyIG9mIGVycm9ycykge1xuICAgICAgICBjb25zb2xlLmVycm9yKGAgIC0gJHtlcnJ9YCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIOuLqOydvCBlbnRpdHkgY29uZSDsg53shLFcbiAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICBpZiAoIWVudGl0eSkge1xuICAgIGNvbnNvbGUuZXJyb3IoYEVudGl0eSBub3QgZm91bmQ6ICR7ZW50aXR5SWR9YCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgbW9kZSA9IGZsYWdzLmhhcyhcInJlZ2VuZXJhdGVcIikgPyBcInJlZ2VuZXJhdGluZ1wiIDogXCJnZW5lcmF0aW5nXCI7XG4gIGNvbnNvbGUubG9nKFxuICAgIGDwn4yfICR7bW9kZSA9PT0gXCJyZWdlbmVyYXRpbmdcIiA/IFwiUmVnZW5lcmF0aW5nXCIgOiBcIkdlbmVyYXRpbmdcIn0gQUktcG93ZXJlZCBjb25lcyBmb3IgJHtlbnRpdHlJZH0uLi5gLFxuICApO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgY29uZmlnTG9jYWxlID0gb3B0aW9ucy5sb2NhbGUgfHwgU29uYW11LmNvbmZpZy5pMThuPy5kZWZhdWx0TG9jYWxlO1xuICAgIGNvbnN0IGxvY2FsZSA9XG4gICAgICBjb25maWdMb2NhbGUgPT09IFwia29cIiB8fCBjb25maWdMb2NhbGUgPT09IFwiZW5cIiB8fCBjb25maWdMb2NhbGUgPT09IFwiamFcIiA/IGNvbmZpZ0xvY2FsZSA6IFwia29cIjtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVudGl0eS5nZW5lcmF0ZUNvbmVzKHtcbiAgICAgIHByZXNlcnZlRXhpc3Rpbmc6ICFmbGFncy5oYXMoXCJyZWdlbmVyYXRlXCIpLFxuICAgICAgb25seUVtcHR5OiAhZmxhZ3MuaGFzKFwicmVnZW5lcmF0ZVwiKSxcbiAgICAgIGxvY2FsZSxcbiAgICB9KTtcblxuICAgIGNvbnNvbGUubG9nKGDinIUgRG9uZSEgKCR7cmVzdWx0LnRva2Vuc1VzZWR9IHRva2VucyB1c2VkKWApO1xuXG4gICAgLy8g7Yag7YGwIOu5hOyaqSDqs4TsgrAgKOuMgOueteyggeyduCDstpTsoJUpXG4gICAgLy8gQ2xhdWRlIFNvbm5ldCA0LjU6IGlucHV0ICQzL00gdG9rZW5zLCBvdXRwdXQgJDE1L00gdG9rZW5zXG4gICAgLy8g6rCE64uo7ZWY6rKMIO2Pieq3oCAkOS9NIHRva2Vuc+uhnCDqs4TsgrBcbiAgICBjb25zdCBlc3RpbWF0ZWRDb3N0ID0gKHJlc3VsdC50b2tlbnNVc2VkICogOSkgLyAxXzAwMF8wMDA7XG4gICAgY29uc29sZS5sb2coYPCfkrAgRXN0aW1hdGVkIGNvc3Q6IH4kJHtlc3RpbWF0ZWRDb3N0LnRvRml4ZWQoNCl9YCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGlmIChlcnJvci5tZXNzYWdlLmluY2x1ZGVzKFwiQU5USFJPUElDX0FQSV9LRVlcIikpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgXFxu4p2MICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICAgICAgY29uc29sZS5lcnJvcihgXFxu8J+SoSBUbyB1c2UgQUktcG93ZXJlZCBjb25lIGdlbmVyYXRpb246YCk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYCAgIDEuIEdldCBhbiBBUEkga2V5IGZyb20gaHR0cHM6Ly9jb25zb2xlLmFudGhyb3BpYy5jb20vYCk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgYCAgIDIuIEFkZCBpdCB0byBzb25hbXUuc2VjcmV0LnRzIG9yIHNldCBBTlRIUk9QSUNfQVBJX0tFWSBlbnZpcm9ubWVudCB2YXJpYWJsZWAsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoXCJSYXRlIGxpbWl0XCIpKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFxcbuKdjCAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFxcbvCfkqEgUGxlYXNlIHdhaXQgYSBtb21lbnQgYW5kIHRyeSBhZ2Fpbi5gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFxcbuKdjCBGYWlsZWQgdG8gZ2VuZXJhdGUgY29uZXM6ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcihgXFxu4p2MIEZhaWxlZCB0byBnZW5lcmF0ZSBjb25lczogVW5rbm93biBlcnJvcmApO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBzY2FmZm9sZF9tb2RlbChlbnRpdHlJZDogc3RyaW5nKSB7XG4gIGF3YWl0IFNvbmFtdS5zeW5jZXIuZ2VuZXJhdGVUZW1wbGF0ZShcIm1vZGVsXCIsIHtcbiAgICBlbnRpdHlJZCxcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNjYWZmb2xkX21vZGVsX3Rlc3QoZW50aXR5SWQ6IHN0cmluZykge1xuICBhd2FpdCBTb25hbXUuc3luY2VyLmdlbmVyYXRlVGVtcGxhdGUoXCJtb2RlbF90ZXN0XCIsIHtcbiAgICBlbnRpdHlJZCxcbiAgfSk7XG59XG5cbi8qKlxuICogcG5wbSBzb25hbXUgc2tpbGxzIHN5bmMg7ZWY66m0IOyLpO2WieuQmOuKlCDtlajsiJjsnoXri4jri6QuXG4gKiDqs7Xsi50gU2tpbGxz66W8IOuhnOy7rCDtlITroZzsoJ3tirgg65iQ64qUIOq4gOuhnOuyjCB+Ly5jbGF1ZGUv66GcIOuPmeq4sO2ZlO2VqeuLiOuLpC5cbiAqXG4gKiAtLWdsb2JhbCDtlIzrnpjqt7g6IH4vLmNsYXVkZS/sl5Ag64+Z6riw7ZmUICjtlITroZzsoJ3tirgg7IOd7ISxIOyghCDsgqzsmqkg6rCA64qlKVxuICovXG5hc3luYyBmdW5jdGlvbiBza2lsbHNfc3luYygpIHtcbiAgY29uc3QgeyBmbGFncyB9ID0gcGFyc2VDbGlPcHRpb25zKCk7XG4gIGNvbnN0IGlzR2xvYmFsID0gZmxhZ3MuaGFzKFwiZ2xvYmFsXCIpO1xuXG4gIC8vIOqwnOuwnCDtmZjqsr0gLSBjbGkudHM6IHNvbmFtdS9tb2R1bGVzL3NvbmFtdS9zcmMvYmluL2NsaS50c1xuICAvLyDruYzrk5wg7ZuEIC0gY2xpLmpzOiBub2RlX21vZHVsZXMvc29uYW11L2Rpc3QvYmluL2NsaS5qcyAo7Iuk7KCcIOyLpO2WiSlcbiAgLy8gc2tpbGxzIOychOy5mDogbm9kZV9tb2R1bGVzL3NvbmFtdS9zcmMvc2tpbGxzIChucG0g67Cw7Y+sIOyLnClcbiAgY29uc3Qgc291cmNlQmFzZSA9IHBhdGgucmVzb2x2ZShpbXBvcnQubWV0YS5kaXJuYW1lLCBcIi4uXCIsIFwiLi5cIiwgXCJzcmNcIiwgXCJza2lsbHNcIik7XG4gIGNvbnN0IHNvdXJjZVNraWxsc0RpciA9IHBhdGguam9pbihzb3VyY2VCYXNlLCBcInNvbmFtdVwiKTtcbiAgY29uc3Qgc291cmNlQ2xhdWRlTWQgPSBwYXRoLmpvaW4oc291cmNlQmFzZSwgXCJDTEFVREUubWRcIik7XG5cbiAgaWYgKCEoYXdhaXQgZXhpc3RzKHNvdXJjZVNraWxsc0RpcikpKSB7XG4gICAgY29uc29sZS5sb2coY2hhbGsueWVsbG93KFwiU2tpbGxzIHNvdXJjZSBub3QgZm91bmQgaW4gc29uYW11IHBhY2thZ2UuXCIpKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoaXNHbG9iYWwpIHtcbiAgICBjb25zdCBob21lQ2xhdWRlRGlyID0gcGF0aC5qb2luKG9zLmhvbWVkaXIoKSwgXCIuY2xhdWRlXCIpO1xuICAgIGF3YWl0IHNraWxsc19zeW5jX3RvKGhvbWVDbGF1ZGVEaXIsIHNvdXJjZVNraWxsc0Rpciwgc291cmNlQ2xhdWRlTWQsIHtcbiAgICAgIHVzZVN5bWxpbms6IGZhbHNlLFxuICAgICAgY29weVByb2plY3RUZW1wbGF0ZXM6IGZhbHNlLFxuICAgICAgaXNHbG9iYWw6IHRydWUsXG4gICAgfSk7XG5cbiAgICAvLyB+Ly5jbGF1ZGUvY29tbWFuZHMvc29uYW11LXNraWxscy5tZCDshKTsuZhcbiAgICBjb25zdCBzb3VyY2VDb21tYW5kc0RpciA9IHBhdGguam9pbihzb3VyY2VCYXNlLCBcImNvbW1hbmRzXCIpO1xuICAgIGNvbnN0IHNvdXJjZUNvbW1hbmQgPSBwYXRoLmpvaW4oc291cmNlQ29tbWFuZHNEaXIsIFwic29uYW11LXNraWxscy5tZFwiKTtcbiAgICBpZiAoYXdhaXQgZXhpc3RzKHNvdXJjZUNvbW1hbmQpKSB7XG4gICAgICBjb25zdCB0YXJnZXRDb21tYW5kc0RpciA9IHBhdGguam9pbihob21lQ2xhdWRlRGlyLCBcImNvbW1hbmRzXCIpO1xuICAgICAgYXdhaXQgbWtkaXIodGFyZ2V0Q29tbWFuZHNEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgYXdhaXQgY3Aoc291cmNlQ29tbWFuZCwgcGF0aC5qb2luKHRhcmdldENvbW1hbmRzRGlyLCBcInNvbmFtdS1za2lsbHMubWRcIikpO1xuICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYOKckyAvc29uYW11LXNraWxscyBjb21tYW5kIGluc3RhbGxlZCDihpIgfi8uY2xhdWRlL2NvbW1hbmRzL2ApKTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhjaGFsay5jeWFuKGBcXG4gIEdsb2JhbCBzeW5jIGNvbXBsZXRlIOKGkiB+Ly5jbGF1ZGUvc2tpbGxzL3NvbmFtdS9gKSk7XG4gICAgY29uc29sZS5sb2coY2hhbGsuZGltKGAgIFRoZXNlIHNraWxscyBhcmUgYXZhaWxhYmxlIGluIGFsbCBDbGF1ZGUgQ29kZSBzZXNzaW9ucy5gKSk7XG4gICAgY29uc29sZS5sb2coXG4gICAgICBjaGFsay5kaW0oXG4gICAgICAgIGAgIE9uY2UgYSBwcm9qZWN0IGlzIGNyZWF0ZWQsIHJ1biAncG5wbSBzb25hbXUgc2tpbGxzIHN5bmMnIGZvciBwcm9qZWN0LWxvY2FsIHN5bmMuYCxcbiAgICAgICksXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCB3b3Jrc3BhY2VSb290ID0gYXdhaXQgZmluZFdvcmtzcGFjZVJvb3QoKTtcbiAgICBjb25zdCBjbGF1ZGVEaXIgPSBwYXRoLmpvaW4od29ya3NwYWNlUm9vdCwgXCIuY2xhdWRlXCIpO1xuICAgIGF3YWl0IHNraWxsc19zeW5jX3RvKGNsYXVkZURpciwgc291cmNlU2tpbGxzRGlyLCBzb3VyY2VDbGF1ZGVNZCwge1xuICAgICAgdXNlU3ltbGluazogdHJ1ZSxcbiAgICAgIGNvcHlQcm9qZWN0VGVtcGxhdGVzOiB0cnVlLFxuICAgICAgc291cmNlQmFzZSxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIGNsYXVkZURpcuuhnCBza2lsbHPrpbwg64+Z6riw7ZmU7ZWY64qUIOqzte2GtSDroZzsp4HsnoXri4jri6QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHNraWxsc19zeW5jX3RvKFxuICBjbGF1ZGVEaXI6IHN0cmluZyxcbiAgc291cmNlU2tpbGxzRGlyOiBzdHJpbmcsXG4gIHNvdXJjZUNsYXVkZU1kOiBzdHJpbmcsXG4gIG9wdGlvbnM6IHtcbiAgICB1c2VTeW1saW5rOiBib29sZWFuO1xuICAgIGNvcHlQcm9qZWN0VGVtcGxhdGVzOiBib29sZWFuO1xuICAgIHNvdXJjZUJhc2U/OiBzdHJpbmc7XG4gICAgaXNHbG9iYWw/OiBib29sZWFuO1xuICB9LFxuKSB7XG4gIGNvbnN0IHRhcmdldFNraWxsc0RpciA9IHBhdGguam9pbihjbGF1ZGVEaXIsIFwic2tpbGxzXCIsIFwic29uYW11XCIpO1xuXG4gIC8vIOq4sOyhtCDrlJTroInthqDrpqwvc3ltbGluayDsgq3soJwg7ZuEIOyerOyDneyEsVxuICAvLyBleGlzdHMoKeuKlCBicm9rZW4gc3ltbGlua+ulvCDqsJDsp4DtlZjsp4Ag66q77ZWY66+A66GcIHJt7J2EIOustOyhsOqxtCDsi5zrj4Ttlanri4jri6RcbiAgdHJ5IHtcbiAgICBhd2FpdCBybSh0YXJnZXRTa2lsbHNEaXIsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgfSBjYXRjaCB7XG4gICAgLy8g7YyM7J287J20IOyXhuycvOuptCDrrLTsi5xcbiAgfVxuXG4gIGF3YWl0IG1rZGlyKHBhdGguZGlybmFtZSh0YXJnZXRTa2lsbHNEaXIpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICBpZiAob3B0aW9ucy51c2VTeW1saW5rKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHN5bWxpbmsoc291cmNlU2tpbGxzRGlyLCB0YXJnZXRTa2lsbHNEaXIsIFwiZGlyXCIpO1xuICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYOKckyBTa2lsbHMgbGlua2VkIChzeW1saW5rKWApKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIGNoYWxrLnllbGxvdyhg4pqgIFN5bWxpbmsgZmFpbGVkOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gKSxcbiAgICAgICk7XG4gICAgICBjb25zb2xlLmxvZyhjaGFsay55ZWxsb3coYCAgRmFsbGluZyBiYWNrIHRvIGNvcHkuLi5gKSk7XG4gICAgICBhd2FpdCBza2lsbHNDb3B5KHNvdXJjZVNraWxsc0RpciwgdGFyZ2V0U2tpbGxzRGlyKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgc2tpbGxzQ29weShzb3VyY2VTa2lsbHNEaXIsIHRhcmdldFNraWxsc0Rpcik7XG4gIH1cblxuICAvLyBwcm9qZWN0IOuUlOugie2GoOumrCDstIjquLDtmZQgKOyXhuycvOuptCDsg53shLEsIOyeiOycvOuptCDsnKDsp4ApXG4gIGlmIChvcHRpb25zLmNvcHlQcm9qZWN0VGVtcGxhdGVzICYmIG9wdGlvbnMuc291cmNlQmFzZSkge1xuICAgIGNvbnN0IHNvdXJjZVByb2plY3REaXIgPSBwYXRoLmpvaW4ob3B0aW9ucy5zb3VyY2VCYXNlLCBcInByb2plY3RcIik7XG4gICAgY29uc3QgdGFyZ2V0UHJvamVjdERpciA9IHBhdGguam9pbihjbGF1ZGVEaXIsIFwic2tpbGxzXCIsIFwicHJvamVjdFwiKTtcblxuICAgIGlmIChhd2FpdCBleGlzdHMoc291cmNlUHJvamVjdERpcikpIHtcbiAgICAgIGlmICghKGF3YWl0IGV4aXN0cyh0YXJnZXRQcm9qZWN0RGlyKSkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBjcChzb3VyY2VQcm9qZWN0RGlyLCB0YXJnZXRQcm9qZWN0RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhjaGFsay5ncmVlbihg4pyTIFByb2plY3QgdGVtcGxhdGVzIGluaXRpYWxpemVkYCkpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICBjaGFsay5yZWQoXG4gICAgICAgICAgICAgIGDinJcgRmFpbGVkIHRvIGluaXRpYWxpemUgcHJvamVjdCB0ZW1wbGF0ZXM6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWAsXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShg4o+tIFByb2plY3QgdGVtcGxhdGVzIGFscmVhZHkgZXhpc3QgKHByZXNlcnZlZClgKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gc2V0dGluZ3MubG9jYWwuanNvbiDigJQgcHJvamVjdC1sb2NhbCDrqqjrk5zsl5DshJzrp4wsIOyXhuydhCDrlYzrp4wg7IOd7ISxXG4gIGlmIChvcHRpb25zLmNvcHlQcm9qZWN0VGVtcGxhdGVzKSB7XG4gICAgY29uc3Qgc2V0dGluZ3NMb2NhbFBhdGggPSBwYXRoLmpvaW4oY2xhdWRlRGlyLCBcInNldHRpbmdzLmxvY2FsLmpzb25cIik7XG4gICAgaWYgKCEoYXdhaXQgZXhpc3RzKHNldHRpbmdzTG9jYWxQYXRoKSkpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHNldHRpbmdzQ29udGVudCA9IHtcbiAgICAgICAgICBob29rczoge1xuICAgICAgICAgICAgUG9zdFRvb2xVc2U6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG1hdGNoZXI6IFwiRWRpdHxXcml0ZXxNdWx0aUVkaXRcIixcbiAgICAgICAgICAgICAgICBob29rczogW1xuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImNvbW1hbmRcIixcbiAgICAgICAgICAgICAgICAgICAgY29tbWFuZDogXCJwbnBtIGNoZWNrIDI+JjEgfCBoZWFkIC02MFwiLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBhd2FpdCB3cml0ZUZpbGUoc2V0dGluZ3NMb2NhbFBhdGgsIGAke0pTT04uc3RyaW5naWZ5KHNldHRpbmdzQ29udGVudCwgbnVsbCwgMil9XFxuYCk7XG4gICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmdyZWVuKGDinJMgLmNsYXVkZS9zZXR0aW5ncy5sb2NhbC5qc29uIGNyZWF0ZWRgKSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgIGNoYWxrLnJlZChcbiAgICAgICAgICAgIGDinJcgRmFpbGVkIHRvIGNyZWF0ZSBzZXR0aW5ncy5sb2NhbC5qc29uOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShg4o+tIC5jbGF1ZGUvc2V0dGluZ3MubG9jYWwuanNvbiBhbHJlYWR5IGV4aXN0cyAocHJlc2VydmVkKWApKTtcbiAgICB9XG4gIH1cblxuICAvLyBDTEFVREUubWQg67O17IKsL+yXheuNsOydtO2KuFxuICBpZiAoYXdhaXQgZXhpc3RzKHNvdXJjZUNsYXVkZU1kKSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB0YXJnZXRDbGF1ZGVNZCA9IHBhdGguam9pbihjbGF1ZGVEaXIsIFwiQ0xBVURFLm1kXCIpO1xuICAgICAgY29uc3QgcmF3Q29udGVudCA9IGF3YWl0IHJlYWRGaWxlKHNvdXJjZUNsYXVkZU1kLCBcInV0Zi04XCIpO1xuICAgICAgLy8g6riA66Gc67KMIOuqqOuTnOyXkOyEnOuKlCDsg4HrjIAg6rK966Gc66W8IOygiOuMgCDqsr3roZzroZwg67OA7ZmY7ZWp64uI64ukXG4gICAgICBjb25zdCBzb3VyY2VDb250ZW50ID0gb3B0aW9ucy5pc0dsb2JhbFxuICAgICAgICA/IHJhd0NvbnRlbnQucmVwbGFjZUFsbChcIi5jbGF1ZGUvc2tpbGxzL3NvbmFtdS9cIiwgXCJ+Ly5jbGF1ZGUvc2tpbGxzL3NvbmFtdS9cIilcbiAgICAgICAgOiByYXdDb250ZW50O1xuXG4gICAgICBpZiAoYXdhaXQgZXhpc3RzKHRhcmdldENsYXVkZU1kKSkge1xuICAgICAgICBjb25zdCB0YXJnZXRDb250ZW50ID0gYXdhaXQgcmVhZEZpbGUodGFyZ2V0Q2xhdWRlTWQsIFwidXRmLThcIik7XG4gICAgICAgIGNvbnN0IHN0YXJ0TWFya2VyID0gXCI8IS0tIFNPTkFNVTpTVEFSVCAtLT5cIjtcbiAgICAgICAgY29uc3QgZW5kTWFya2VyID0gXCI8IS0tIFNPTkFNVTpFTkQgLS0+XCI7XG4gICAgICAgIGlmICh0YXJnZXRDb250ZW50LmluY2x1ZGVzKHN0YXJ0TWFya2VyKSAmJiB0YXJnZXRDb250ZW50LmluY2x1ZGVzKGVuZE1hcmtlcikpIHtcbiAgICAgICAgICBjb25zdCBzdGFydElkeCA9IHRhcmdldENvbnRlbnQuaW5kZXhPZihzdGFydE1hcmtlcik7XG4gICAgICAgICAgY29uc3QgZW5kSWR4ID0gdGFyZ2V0Q29udGVudC5pbmRleE9mKGVuZE1hcmtlcik7XG5cbiAgICAgICAgICBpZiAoc3RhcnRJZHggIT09IC0xICYmIGVuZElkeCAhPT0gLTEgJiYgc3RhcnRJZHggPCBlbmRJZHgpIHtcbiAgICAgICAgICAgIGNvbnN0IGJlZm9yZSA9IHRhcmdldENvbnRlbnQuc3Vic3RyaW5nKDAsIHN0YXJ0SWR4KTtcbiAgICAgICAgICAgIGNvbnN0IGFmdGVyID0gdGFyZ2V0Q29udGVudC5zdWJzdHJpbmcoZW5kSWR4ICsgZW5kTWFya2VyLmxlbmd0aCk7XG4gICAgICAgICAgICBjb25zdCBuZXdDb250ZW50ID0gYCR7YmVmb3JlfSR7c3RhcnRNYXJrZXJ9XFxuJHtzb3VyY2VDb250ZW50fVxcbiR7ZW5kTWFya2VyfSR7YWZ0ZXJ9YDtcbiAgICAgICAgICAgIGF3YWl0IHdyaXRlRmlsZSh0YXJnZXRDbGF1ZGVNZCwgbmV3Q29udGVudCk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhjaGFsay5ncmVlbihg4pyTIENMQVVERS5tZCB1cGRhdGVkIChtYXJrZXIgcmVnaW9uKWApKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5sb2coY2hhbGsueWVsbG93KGDij60gQ0xBVURFLm1kIG1hcmtlciBwb3NpdGlvbnMgaW52YWxpZCwgc2tpcHBlZGApKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8g66eI7Luk6rCAIOyXhuuKlCDquLDsobQgQ0xBVURFLm1k7JeQIFNvbmFtdSDshLnshZjsnYQg7LaU6rCA7ZWp64uI64ukXG4gICAgICAgICAgY29uc3QgYXBwZW5kZWQgPSBgJHt0YXJnZXRDb250ZW50LnRyaW1FbmQoKX1cXG5cXG48IS0tIFNPTkFNVTpTVEFSVCAtLT5cXG4ke3NvdXJjZUNvbnRlbnR9XFxuPCEtLSBTT05BTVU6RU5EIC0tPlxcbmA7XG4gICAgICAgICAgYXdhaXQgd3JpdGVGaWxlKHRhcmdldENsYXVkZU1kLCBhcHBlbmRlZCk7XG4gICAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYOKckyBDTEFVREUubWQgdXBkYXRlZCAoYXBwZW5kZWQgU29uYW11IHNlY3Rpb24pYCkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCB3aXRoTWFya2VycyA9IGA8IS0tIFNPTkFNVTpTVEFSVCAtLT5cXG4ke3NvdXJjZUNvbnRlbnR9XFxuPCEtLSBTT05BTVU6RU5EIC0tPlxcbmA7XG4gICAgICAgIGF3YWl0IHdyaXRlRmlsZSh0YXJnZXRDbGF1ZGVNZCwgd2l0aE1hcmtlcnMpO1xuICAgICAgICBjb25zb2xlLmxvZyhjaGFsay5ncmVlbihg4pyTIENMQVVERS5tZCBjcmVhdGVkYCkpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICBjaGFsay5yZWQoXG4gICAgICAgICAgYOKclyBGYWlsZWQgdG8gdXBkYXRlIENMQVVERS5tZDogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNraWxsc0NvcHkoc3JjOiBzdHJpbmcsIGRlc3Q6IHN0cmluZykge1xuICB0cnkge1xuICAgIGF3YWl0IGNwKHNyYywgZGVzdCwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYOKckyBTa2lsbHMgY29waWVkYCkpO1xuICB9IGNhdGNoIChjb3B5RXJyb3IpIHtcbiAgICBjb25zb2xlLmVycm9yKFxuICAgICAgY2hhbGsucmVkKFxuICAgICAgICBg4pyXIEZhaWxlZCB0byBjb3B5IHNraWxsczogJHtjb3B5RXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGNvcHlFcnJvci5tZXNzYWdlIDogU3RyaW5nKGNvcHlFcnJvcil9YCxcbiAgICAgICksXG4gICAgKTtcbiAgICB0aHJvdyBjb3B5RXJyb3I7XG4gIH1cbn1cblxuLyoqXG4gKiBwbnBtIHNvbmFtdSBza2lsbHMgY3JlYXRlIDxuYW1lPiDtlZjrqbQg7Iuk7ZaJ65CY64qUIO2VqOyImOyeheuLiOuLpC5cbiAqIOuhnOy7rCBza2lsbCDstIjslYjsnYQg7IOd7ISx7ZWp64uI64ukLlxuICovXG5hc3luYyBmdW5jdGlvbiBza2lsbHNfY3JlYXRlKG5hbWU6IHN0cmluZykge1xuICBjb25zdCB3b3Jrc3BhY2VSb290ID0gYXdhaXQgZmluZFdvcmtzcGFjZVJvb3QoKTtcbiAgY29uc3QgbG9jYWxEaXIgPSBwYXRoLmpvaW4od29ya3NwYWNlUm9vdCwgXCIuY2xhdWRlXCIsIFwic2tpbGxzXCIsIFwibG9jYWxcIik7XG5cbiAgLy8gPT09IO2MjOydvOuqhSDqsoDspp0g67CPIFNhbml0aXplID09PVxuICBpZiAoIW5hbWUgfHwgbmFtZS50cmltKCkgPT09IFwiXCIpIHtcbiAgICBjb25zb2xlLmVycm9yKGNoYWxrLnJlZChcIuKclyBTa2lsbCBuYW1lIGlzIHJlcXVpcmVkXCIpKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBsZXQgc2FuaXRpemVkID0gbmFtZVxuICAgIC8vIOqzteuwseydhCDtlZjsnbTtlIjsnLzroZxcbiAgICAucmVwbGFjZSgvXFxzKy9nLCBcIi1cIilcbiAgICAvLyDqsr3roZwg6rWs67aE7J6QIOygnOqxsFxuICAgIC5yZXBsYWNlKC9bL1xcXFxdL2csIFwiLVwiKVxuICAgIC8vIFBhdGggdHJhdmVyc2FsIOuwqeyngFxuICAgIC5yZXBsYWNlKC9cXC5cXC4vZywgXCJcIilcbiAgICAvLyBXaW5kb3dzIOq4iOyngCDrrLjsnpAg7KCc6rGwXG4gICAgLnJlcGxhY2UoL1s8PjpcInw/Kl0vZywgXCJcIilcbiAgICAvLyDsi5zsnpEv64GdIOygkCwg7ZWY7J207ZSILCDslrjrjZTsiqTsvZTslrQg7KCc6rGwXG4gICAgLnJlcGxhY2UoL15bLlxcLV9dK3xbLlxcLV9dKyQvZywgXCJcIilcbiAgICAvLyDsl7Dsho3rkJwg7ZWY7J207ZSI7J2EIO2VmOuCmOuhnFxuICAgIC5yZXBsYWNlKC8tKy9nLCBcIi1cIilcbiAgICAvLyDslYztjIzrsrMsIOyIq+yekCwg7ZWY7J207ZSILCDslrjrjZTsiqTsvZTslrQsIO2VnOq4gOunjCDtl4jsmqlcbiAgICAucmVwbGFjZSgvW15hLXpBLVowLTktX+qwgC3tnqNdL2csIFwiXCIpO1xuXG4gIC8vIOq4uOydtCDsoJztlZxcbiAgY29uc3QgTUFYX0xFTkdUSCA9IDEwMDtcbiAgaWYgKHNhbml0aXplZC5sZW5ndGggPiBNQVhfTEVOR1RIKSB7XG4gICAgc2FuaXRpemVkID0gc2FuaXRpemVkLnN1YnN0cmluZygwLCBNQVhfTEVOR1RIKTtcbiAgICBjb25zb2xlLmxvZyhjaGFsay55ZWxsb3coYOKaoCBOYW1lIHRydW5jYXRlZCB0byAke01BWF9MRU5HVEh9IGNoYXJhY3RlcnNgKSk7XG4gIH1cblxuICAvLyBXaW5kb3dzIOyYiOyVveyWtCDtmZXsnbhcbiAgY29uc3QgUkVTRVJWRURfTkFNRVMgPSBbXG4gICAgXCJDT05cIixcbiAgICBcIlBSTlwiLFxuICAgIFwiQVVYXCIsXG4gICAgXCJOVUxcIixcbiAgICBcIkNPTTFcIixcbiAgICBcIkNPTTJcIixcbiAgICBcIkNPTTNcIixcbiAgICBcIkNPTTRcIixcbiAgICBcIkNPTTVcIixcbiAgICBcIkNPTTZcIixcbiAgICBcIkNPTTdcIixcbiAgICBcIkNPTThcIixcbiAgICBcIkNPTTlcIixcbiAgICBcIkxQVDFcIixcbiAgICBcIkxQVDJcIixcbiAgICBcIkxQVDNcIixcbiAgICBcIkxQVDRcIixcbiAgICBcIkxQVDVcIixcbiAgICBcIkxQVDZcIixcbiAgICBcIkxQVDdcIixcbiAgICBcIkxQVDhcIixcbiAgICBcIkxQVDlcIixcbiAgXTtcbiAgaWYgKFJFU0VSVkVEX05BTUVTLmluY2x1ZGVzKHNhbml0aXplZC50b1VwcGVyQ2FzZSgpKSkge1xuICAgIHNhbml0aXplZCA9IGBza2lsbC0ke3Nhbml0aXplZH1gO1xuICAgIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdyhg4pqgIFJlc2VydmVkIG5hbWUgZGV0ZWN0ZWQsIHByZWZpeGVkIHdpdGggXCJza2lsbC1cImApKTtcbiAgfVxuXG4gIC8vIOu5iCDrrLjsnpDsl7Qg7LK07YGsXG4gIGlmIChzYW5pdGl6ZWQgPT09IFwiXCIpIHtcbiAgICBjb25zb2xlLmVycm9yKGNoYWxrLnJlZChcIuKclyBJbnZhbGlkIHNraWxsIG5hbWUgYWZ0ZXIgc2FuaXRpemF0aW9uXCIpKTtcbiAgICBjb25zb2xlLmxvZyhjaGFsay5kaW0oYCAgT3JpZ2luYWw6IFwiJHtuYW1lfVwiYCkpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIOuzgOqyvSDslYzrprxcbiAgaWYgKHNhbml0aXplZCAhPT0gbmFtZSkge1xuICAgIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdyhg4pqgIE5hbWUgc2FuaXRpemVkOiBcIiR7bmFtZX1cIiDihpIgXCIke3Nhbml0aXplZH1cImApKTtcbiAgfVxuXG4gIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKGxvY2FsRGlyLCBgJHtzYW5pdGl6ZWR9Lm1kYCk7XG5cbiAgaWYgKGF3YWl0IGV4aXN0cyhmaWxlUGF0aCkpIHtcbiAgICBjb25zb2xlLmxvZyhjaGFsay55ZWxsb3coYFNraWxsIFwiJHtzYW5pdGl6ZWR9XCIgYWxyZWFkeSBleGlzdHMuYCkpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGF3YWl0IG1rZGlyKGxvY2FsRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICBjb25zdCB0ZW1wbGF0ZSA9IGAtLS1cbm5hbWU6ICR7c2FuaXRpemVkfVxuY2F0ZWdvcnk6IG90aGVyXG5jcmVhdGVkX2F0OiAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKS5zcGxpdChcIlRcIilbMF19XG5zdGF0dXM6IGRyYWZ0XG4tLS1cblxuIyAke3Nhbml0aXplZH1cblxuIyMg7IOB7ZmpXG5cblvslrTrlqQg66y47KCc7JiA64qU7KeAXVxuXG4jIyDtlbTqsrAg67Cp67KVXG5cblvslrTrlrvqsowg7ZW06rKw7ZaI64qU7KeAXVxuXG4jIyDsvZTrk5wg7JiI7IucXG5cblxcYFxcYFxcYHR5cGVzY3JpcHRcbi8vIOyYiOyLnCDsvZTrk5xcblxcYFxcYFxcYFxuYDtcblxuICBhd2FpdCB3cml0ZUZpbGUoZmlsZVBhdGgsIHRlbXBsYXRlKTtcbiAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYOKckyBDcmVhdGVkIC5jbGF1ZGUvc2tpbGxzL2xvY2FsLyR7c2FuaXRpemVkfS5tZGApKTtcbn1cblxuLyoqXG4gKiBwbnBtIHNvbmFtdSBhdXRoIGdlbmVyYXRlIO2VmOuptCDsi6TtlonrkJjripQg7ZWo7IiY7J6F64uI64ukLlxuICogYmV0dGVyLWF1dGgg7JeU7Yuw7Yuw65OkKFVzZXIsIFNlc3Npb24sIEFjY291bnQsIFZlcmlmaWNhdGlvbinsnYQg7IOd7ISx7ZWp64uI64ukLlxuICpcbiAqIOyYteyFmDpcbiAqIC0tcGx1Z2lucyBwaG9uZS1udW1iZXIsMmZhICDtlIzrn6zqt7jsnbgg7JeU7Yuw7Yuw64+EIO2VqOq7mCDsg53shLFcbiAqL1xuYXN5bmMgZnVuY3Rpb24gYXV0aF9nZW5lcmF0ZSgpIHtcbiAgLy8gLS1wbHVnaW5zIOyYteyFmCDtjIzsi7FcbiAgY29uc3QgcGx1Z2luc0FyZyA9IHByb2Nlc3MuYXJndi5maW5kKChhcmcpID0+IGFyZy5zdGFydHNXaXRoKFwiLS1wbHVnaW5zXCIpKTtcbiAgY29uc3QgcGx1Z2luczogQmV0dGVyQXV0aFBsdWdpbklkW10gPSBbXTtcblxuICBpZiAocGx1Z2luc0FyZykge1xuICAgIGNvbnN0IHBsdWdpblZhbHVlID0gcGx1Z2luc0FyZy5pbmNsdWRlcyhcIj1cIilcbiAgICAgID8gcGx1Z2luc0FyZy5zcGxpdChcIj1cIilbMV1cbiAgICAgIDogcHJvY2Vzcy5hcmd2W3Byb2Nlc3MuYXJndi5pbmRleE9mKHBsdWdpbnNBcmcpICsgMV07XG5cbiAgICBpZiAocGx1Z2luVmFsdWUpIHtcbiAgICAgIGNvbnN0IHBsdWdpbklkcyA9IHBsdWdpblZhbHVlLnNwbGl0KFwiLFwiKS5tYXAoKHApID0+IHAudHJpbSgpKTtcblxuICAgICAgZm9yIChjb25zdCBpZCBvZiBwbHVnaW5JZHMpIHtcbiAgICAgICAgaWYgKGlzVmFsaWRQbHVnaW5JZChpZCkpIHtcbiAgICAgICAgICBwbHVnaW5zLnB1c2goaWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdyhg4pqgIFVua25vd24gcGx1Z2luOiAke2lkfWApKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhjaGFsay5kaW0oYCAgU3VwcG9ydGVkIHBsdWdpbnM6ICR7U1VQUE9SVEVEX1BMVUdJTl9JRFMuam9pbihcIiwgXCIpfWApKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdy5ib2xkKFwi8J+UkCBHZW5lcmF0aW5nIGJldHRlci1hdXRoIGVudGl0aWVzLi4uXFxuXCIpKTtcblxuICBpZiAocGx1Z2lucy5sZW5ndGggPiAwKSB7XG4gICAgY29uc29sZS5sb2coY2hhbGsuZGltKGAgIFBsdWdpbnM6ICR7cGx1Z2lucy5qb2luKFwiLCBcIil9YCkpO1xuICB9XG5cbiAgYXdhaXQgZ2VuZXJhdGVCZXR0ZXJBdXRoRW50aXRpZXMoeyBwbHVnaW5zIH0pO1xufVxuXG4vKipcbiAqIHBucG0gc29uYW11IGF1dGggYWRkLWNvbXBhbmlvbnMg7ZWY66m0IOyLpO2WieuQmOuKlCDtlajsiJjsnoXri4jri6QuXG4gKiDquLDsobQg7ZSE66Gc7KCd7Yq47J2YIGVudGl0eS5qc29u7JeQIGZpeHR1cmVDb21wYW5pb25z66W8IOyGjOq4iSDstpTqsIDtlanri4jri6QuXG4gKlxuICog7J2066+4IGZpeHR1cmVDb21wYW5pb25z6rCAIOyeiOuKlCBlbnRpdHnripQg7Iqk7YK17ZWp64uI64ukICjrja7slrTsk7DquLAg7JeG7J2MKS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gYXV0aF9hZGRfY29tcGFuaW9ucygpIHtcbiAgY29uc29sZS5sb2coY2hhbGsueWVsbG93LmJvbGQoXCLwn5SQIEFkZGluZyBmaXh0dXJlQ29tcGFuaW9ucyB0byBiZXR0ZXItYXV0aCBlbnRpdGllcy4uLlxcblwiKSk7XG4gIGF3YWl0IGFkZENvbXBhbmlvbnNUb0VudGl0aWVzKCk7XG4gIGNvbnNvbGUubG9nKGNoYWxrLmJvbGQoXCJcXG7inIUgRG9uZSFcIikpO1xufVxuXG4vKipcbiAqIOybjO2BrOyKpO2OmOydtOyKpCDro6jtirjrpbwg7LC+7Iq164uI64ukLlxuICog7Jqw7ISg7Iic7JyEOiBwbnBtLXdvcmtzcGFjZS55YW1sID4gcGFja2FnZS5qc29uKHdvcmtzcGFjZXMpID4gLmFnZW50cy9cbiAqXG4gKiBDTEFVREUubWTripQg7ISc67iM7Yyo7YKk7KeA7JeQ64+EIOyhtOyerO2VoCDsiJgg7J6I7Jy866+A66GcIOyCrOyaqe2VmOyngCDslYrsirXri4jri6QuXG4gKiAuYWdlbnRzL+uKlCBhZ2VudHMgaW5pdOydtCDsg53shLHtlZjripQg65SU66CJ7Yag66as66GcLCDsm4ztgazsiqTtjpjsnbTsiqQg66Oo7Yq47JeQ66eMIOyhtOyerO2VqeuLiOuLpC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZmluZFdvcmtzcGFjZVJvb3QoKSB7XG4gIGxldCBkaXIgPSBwcm9jZXNzLmN3ZCgpO1xuXG4gIHdoaWxlIChkaXIgIT09IHBhdGguZGlybmFtZShkaXIpKSB7XG4gICAgLy8gMS4gcG5wbS13b3Jrc3BhY2UueWFtbDog7ZmV7Iuk7ZWcIG1vbm9yZXBvIOujqO2KuC5cbiAgICBpZiAoYXdhaXQgZXhpc3RzKHBhdGguam9pbihkaXIsIFwicG5wbS13b3Jrc3BhY2UueWFtbFwiKSkpIHtcbiAgICAgIHJldHVybiBkaXI7XG4gICAgfVxuXG4gICAgLy8gMi4gcGFja2FnZS5qc29u7JeQIHdvcmtzcGFjZXMg7ZWE65Oc6rCAIOyeiOycvOuptCBtb25vcmVwbyDro6jtirguXG4gICAgY29uc3QgcGFja2FnZVBhdGggPSBwYXRoLmpvaW4oZGlyLCBcInBhY2thZ2UuanNvblwiKTtcbiAgICBpZiAoYXdhaXQgZXhpc3RzKHBhY2thZ2VQYXRoKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGFja2FnZUpzb24gPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRGaWxlKHBhY2thZ2VQYXRoLCBcInV0Zi04XCIpKTtcbiAgICAgICAgaWYgKHBhY2thZ2VKc29uLndvcmtzcGFjZXMpIHtcbiAgICAgICAgICByZXR1cm4gZGlyO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8g7YyM7IuxIOyLpO2MqOyLnCDrrLTsi5xcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAzLiAuYWdlbnRzLzogYWdlbnRzIGluaXTsnbQg7IOd7ISx7ZWcIOuUlOugie2GoOumrC4g7ISc67iM7Yyo7YKk7KeA7JeQ64qUIOyhtOyerO2VmOyngCDslYrsnYwuXG4gICAgaWYgKGF3YWl0IGV4aXN0cyhwYXRoLmpvaW4oZGlyLCBcIi5hZ2VudHNcIikpKSB7XG4gICAgICByZXR1cm4gZGlyO1xuICAgIH1cblxuICAgIGRpciA9IHBhdGguZGlybmFtZShkaXIpO1xuICB9XG5cbiAgLy8g7LC+7KeAIOuqu+2VmOuptCBhcGkg7Y+0642U7J2YIOu2gOuqqCDsgqzsmqlcbiAgcmV0dXJuIGZpbmRBcHBSb290UGF0aCgpO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O2FBaUJ1QztxQkFLa0I7ZUFDUjtzQkFDVzttQkFRN0I7ZUFDWTtZQUN1QjtBQS9CbEUsT0FBTyxRQUFRO0FBcUNmLElBQUlBOzs7O0FBS0osU0FBUyxnQkFBZ0IsT0FBaUIsUUFBUSxNQUdoRDtDQUNBLE1BQU0sUUFBUSxJQUFJLEtBQWE7Q0FDL0IsTUFB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
1074
+ export {};
1075
+
1076
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9iaW4vY2xpLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IHsgZXhlY1N5bmMsIHNwYXduIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IGNwLCBta2RpciwgcmVhZGRpciwgcmVhZEZpbGUsIHJtLCBzeW1saW5rLCB3cml0ZUZpbGUgfSBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibW9kdWxlXCI7XG5pbXBvcnQgb3MgZnJvbSBcIm9zXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHByb2Nlc3MgZnJvbSBcInByb2Nlc3NcIjtcblxuaW1wb3J0IGNoYWxrIGZyb20gXCJjaGFsa1wiO1xuaW1wb3J0IGtuZXggZnJvbSBcImtuZXhcIjtcbmltcG9ydCB7IHR5cGUgS25leCB9IGZyb20gXCJrbmV4XCI7XG5pbXBvcnQgeyB0c2ljbGkgfSBmcm9tIFwidHNpY2xpXCI7XG5cbmltcG9ydCB7IFNvbmFtdSB9IGZyb20gXCIuLi9hcGkvc29uYW11XCI7XG5pbXBvcnQgeyBhZGRDb21wYW5pb25zVG9FbnRpdGllcywgZ2VuZXJhdGVCZXR0ZXJBdXRoRW50aXRpZXMgfSBmcm9tIFwiLi4vYXV0aC9hdXRoLWdlbmVyYXRvclwiO1xuaW1wb3J0IHsgaXNWYWxpZFBsdWdpbklkLCBTVVBQT1JURURfUExVR0lOX0lEUyB9IGZyb20gXCIuLi9hdXRoL3BsdWdpbnMvZW50aXR5LWRlZmluaXRpb25zXCI7XG5pbXBvcnQgeyB0eXBlIEJldHRlckF1dGhQbHVnaW5JZCB9IGZyb20gXCIuLi9hdXRoL3BsdWdpbnMvZW50aXR5LWRlZmluaXRpb25zXCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdURCQ29uZmlnIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2RiXCI7XG5pbXBvcnQgeyBFbnRpdHlNYW5hZ2VyIH0gZnJvbSBcIi4uL2VudGl0eS9lbnRpdHktbWFuYWdlclwiO1xuaW1wb3J0IHsgZ2V0U29uYW11RW52aXJvbm1lbnQgfSBmcm9tIFwiLi4vZW52XCI7XG5pbXBvcnQgeyBNaWdyYXRvciB9IGZyb20gXCIuLi9taWdyYXRpb24vbWlncmF0b3JcIjtcbmltcG9ydCB7IEZpeHR1cmVNYW5hZ2VyIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZml4dHVyZS1tYW5hZ2VyXCI7XG5pbXBvcnQge1xuICBleGVjV2l0aExpbmVQcmVmaXgsXG4gIHByaW50QnVpbGRTdW1tYXJ5LFxuICBwcmludFRhc2tGYWlsZWQsXG4gIHByaW50VGFza0hlYWRlcixcbiAgcHJpbnRUYXNrU3RhcnQsXG4gIHByaW50VGFza1N1Y2Nlc3MsXG59IGZyb20gXCIuLi91dGlscy9jb25zb2xlLXV0aWxcIjtcbmltcG9ydCB7IGV4aXN0cyB9IGZyb20gXCIuLi91dGlscy9mcy11dGlsc1wiO1xuaW1wb3J0IHsgZmluZEFwaVJvb3RQYXRoLCBmaW5kQXBwUm9vdFBhdGggfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcbmltcG9ydCB7IEFQSV9BUlRJRkFDVFMsIFdFQl9BUlRJRkFDVFMgfSBmcm9tIFwiLi9idWlsZC1jb25maWdcIjtcbmltcG9ydCB7IHR5cGUgQnVpbGRBcnRpZmFjdCB9IGZyb20gXCIuL2J1aWxkLWNvbmZpZ1wiO1xuaW1wb3J0IHsgZml4dHVyZUV4cGxvcmVDb21tYW5kLCBmaXh0dXJlRmV0Y2hDb21tYW5kLCBmaXh0dXJlR2VuQ29tbWFuZCB9IGZyb20gXCIuL2ZpeHR1cmVcIjtcbmltcG9ydCB7IGdldE1pZ3JhdGVSdW5UYXJnZXRzIH0gZnJvbSBcIi4vbWlncmF0ZS10YXJnZXRzXCI7XG5pbXBvcnQgeyB0ZXN0Q29tbWFuZCB9IGZyb20gXCIuL3Rlc3QtY29tbWFuZFwiO1xuXG5sZXQgbWlncmF0b3I6IE1pZ3JhdG9yO1xuXG4vKipcbiAqIENMSSDsmLXshZjsnYQg7YyM7Iux7ZWY64qUIO2XrO2NvCDtlajsiJhcbiAqL1xuZnVuY3Rpb24gcGFyc2VDbGlPcHRpb25zKGFyZ3Y6IHN0cmluZ1tdID0gcHJvY2Vzcy5hcmd2KToge1xuICBmbGFnczogU2V0PHN0cmluZz47IC8vIC0tcmVnZW5lcmF0ZSwgLS1haSwgLS1uby1jb25lcyDrk7FcbiAgb3B0aW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjsgLy8gLS1sb2NhbGUga28g65OxXG59IHtcbiAgY29uc3QgZmxhZ3MgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3Qgb3B0aW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJndi5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGFyZyA9IGFyZ3ZbaV07XG4gICAgaWYgKCFhcmcuc3RhcnRzV2l0aChcIi0tXCIpKSBjb250aW51ZTtcblxuICAgIC8vIC0tb3B0aW9uPXZhbHVlIO2YleyLnVxuICAgIGlmIChhcmcuaW5jbHVkZXMoXCI9XCIpKSB7XG4gICAgICBjb25zdCBba2V5LCB2YWx1ZV0gPSBhcmcuc2xpY2UoMikuc3BsaXQoXCI9XCIpO1xuICAgICAgb3B0aW9uc1trZXldID0gdmFsdWU7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyAtLW9wdGlvbiB2YWx1ZSDtmJXsi53snbjsp4Ag7ZmV7J24XG4gICAgY29uc3QgbmV4dEFyZyA9IGFyZ3ZbaSArIDFdO1xuICAgIGlmIChuZXh0QXJnICYmICFuZXh0QXJnLnN0YXJ0c1dpdGgoXCItLVwiKSAmJiAhbmV4dEFyZy5zdGFydHNXaXRoKFwiLVwiKSkge1xuICAgICAgb3B0aW9uc1thcmcuc2xpY2UoMildID0gbmV4dEFyZztcbiAgICAgIGkrKzsgLy8g64uk7J2MIGFyZ+uKlCDqsJLsnbTrr4DroZwg7Iqk7YK1XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIC0tZmxhZyDtmJXsi51cbiAgICAgIGZsYWdzLmFkZChhcmcuc2xpY2UoMikpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGZsYWdzLCBvcHRpb25zIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGJvb3RzdHJhcCgpIHtcbiAgY29uc3Qgbm90VG9Jbml0ID0gW1wiZGV2XCIsIFwiYnVpbGRcIiwgXCJzdGFydFwiLCBcInNraWxsc1wiLCBcInRlc3RcIl0uaW5jbHVkZXMocHJvY2Vzcy5hcmd2WzJdID8/IFwiXCIpO1xuICBpZiAoIW5vdFRvSW5pdCkge1xuICAgIGF3YWl0IFNvbmFtdS5pbml0KGZhbHNlLCBmYWxzZSk7XG4gIH1cblxuICB0cnkge1xuICAgIC8vIHRzaWNsaeuKlCDsoJXtmZXtlZwg66qF66C57Ja0IOunpOy5reunjCDsp4Dsm5DtlZjrr4DroZwsIC0t66GcIOyLnOyeke2VmOuKlCDsmLXshZjqs7wg6re4IOqwkuydhCDtlYTthLDrp4Htlanri4jri6QuXG4gICAgLy8g7Ji17IWYIO2MjOyLseydgCDqsIEgcnVubmVyIO2VqOyImOyXkOyEnCDsm5Drs7ggcHJvY2Vzcy5hcmd266W8IOyCrOyaqe2VmOyXrCDsiJjtlontlanri4jri6QuXG4gICAgLy8gXCItLVwiKGJhcmUgZG91YmxlIGRhc2gp64qUIHBhc3N0aHJvdWdoIOq1rOu2hOyekOydtOuvgOuhnCwg6re4IOuSpOydmCDrqqjrk6Ag7J247J6Q64+EIOygnOyZuO2VqeuLiOuLpC5cbiAgICBjb25zdCBmaWx0ZXJlZEFyZ3Y6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IHNraXBOZXh0ID0gZmFsc2U7XG4gICAgbGV0IGFmdGVyRG91YmxlRGFzaCA9IGZhbHNlO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvY2Vzcy5hcmd2Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBhcmcgPSBwcm9jZXNzLmFyZ3ZbaV07XG4gICAgICBpZiAoYXJnID09PSBcIi0tXCIpIHtcbiAgICAgICAgYWZ0ZXJEb3VibGVEYXNoID0gdHJ1ZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoYWZ0ZXJEb3VibGVEYXNoKSBjb250aW51ZTtcbiAgICAgIGlmIChza2lwTmV4dCkge1xuICAgICAgICBza2lwTmV4dCA9IGZhbHNlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChhcmcuc3RhcnRzV2l0aChcIi0tXCIpKSB7XG4gICAgICAgIC8vIC0tb3B0aW9uPXZhbHVlIO2YleyLneydgCDsnbQgYXJn66eMIOyKpO2CtVxuICAgICAgICBpZiAoYXJnLmluY2x1ZGVzKFwiPVwiKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIC0tb3B0aW9uIHZhbHVlIO2YleyLneyduOyngCDtmZXsnbg6IOuLpOydjCBhcmfqsIAgLS3roZwg7Iuc7J6R7ZWY7KeAIOyViuycvOuptCDqsJLsnbQg7J6I64qUIOqyg1xuICAgICAgICBjb25zdCBuZXh0QXJnID0gcHJvY2Vzcy5hcmd2W2kgKyAxXTtcbiAgICAgICAgaWYgKG5leHRBcmcgJiYgIW5leHRBcmcuc3RhcnRzV2l0aChcIi0tXCIpICYmICFuZXh0QXJnLnN0YXJ0c1dpdGgoXCItXCIpKSB7XG4gICAgICAgICAgc2tpcE5leHQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgZmlsdGVyZWRBcmd2LnB1c2goYXJnKTtcbiAgICB9XG5cbiAgICAvLyBidWlsZC9kZXYg66qF66C57Ja06rCAIOyEnOu4jOy7pOunqOuTnCDsl4bsnbQg7Zi47Lac65CgIOuVjCBcImFsbFwi7J2EIOq4sOuzuOqwkuycvOuhnCDstpTqsIDtlanri4jri6QuXG4gICAgLy8g7JiIOiBgc29uYW11IGJ1aWxkYCDihpIgYHNvbmFtdSBidWlsZCBhbGxgLCBgc29uYW11IGRldmAg4oaSIGBzb25hbXUgZGV2IGFsbGBcbiAgICBjb25zdCBjbWQgPSBmaWx0ZXJlZEFyZ3ZbMl07XG4gICAgaWYgKChjbWQgPT09IFwiYnVpbGRcIiB8fCBjbWQgPT09IFwiZGV2XCIpICYmIGZpbHRlcmVkQXJndi5sZW5ndGggPT09IDMpIHtcbiAgICAgIGZpbHRlcmVkQXJndi5wdXNoKFwiYWxsXCIpO1xuICAgIH1cblxuICAgIC8vIHRlc3Qg7Luk66eo65Oc64qUIOqwgOuzgCDsnbjsnpAo7YyM7J2866qFLCAtLXBhdHRlcm4g65OxKeulvCDrsJvsnLzrr4DroZwgdHNpY2xp66W8IOyasO2ajO2VqeuLiOuLpC5cbiAgICBpZiAoY21kID09PSBcInRlc3RcIikge1xuICAgICAgcmV0dXJuIHRlc3RDb21tYW5kKCk7XG4gICAgfVxuXG4gICAgYXdhaXQgdHNpY2xpKGZpbHRlcmVkQXJndiwge1xuICAgICAgdHlwZXM6IHtcbiAgICAgICAgXCIjZW50aXR5SWRcIjoge1xuICAgICAgICAgIHR5cGU6IFwiYXV0b2NvbXBsZXRlXCIsXG4gICAgICAgICAgbmFtZTogXCIjZW50aXR5SWRcIixcbiAgICAgICAgICBtZXNzYWdlOiBcIlBsZWFzZSBpbnB1dCAjZW50aXR5SWRcIixcbiAgICAgICAgICBjaG9pY2VzOiBFbnRpdHlNYW5hZ2VyLmdldEFsbFBhcmVudElkcygpLm1hcCgoZW50aXR5SWQpID0+ICh7XG4gICAgICAgICAgICB0aXRsZTogZW50aXR5SWQsXG4gICAgICAgICAgICB2YWx1ZTogZW50aXR5SWQsXG4gICAgICAgICAgfSkpLFxuICAgICAgICB9LFxuICAgICAgICBcIiNyZWNvcmRJZHNcIjogXCJudW1iZXJbXVwiLFxuICAgICAgICBcIiNuYW1lXCI6IFwic3RyaW5nXCIsXG4gICAgICAgIFwiI3RhcmdldHNcIjoge1xuICAgICAgICAgIHR5cGU6IFwibXVsdGlzZWxlY3RcIixcbiAgICAgICAgICBuYW1lOiBcIiN0YXJnZXRzXCIsXG4gICAgICAgICAgbWVzc2FnZTogXCJQbGVhc2UgaW5wdXQgI3RhcmdldHNcIixcbiAgICAgICAgICBjaG9pY2VzOiBbXG4gICAgICAgICAgICB7IHRpdGxlOiBcIkRldmVsb3BtZW50XCIsIHZhbHVlOiBcImRldmVsb3BtZW50XCIgfSxcbiAgICAgICAgICAgIHsgdGl0bGU6IFwiU3RhZ2luZ1wiLCB2YWx1ZTogXCJzdGFnaW5nXCIgfSxcbiAgICAgICAgICAgIHsgdGl0bGU6IFwiUHJvZHVjdGlvblwiLCB2YWx1ZTogXCJwcm9kdWN0aW9uXCIgfSxcbiAgICAgICAgICAgIHsgdGl0bGU6IFwiRml4dHVyZVwiLCB2YWx1ZTogXCJmaXh0dXJlXCIgfSxcbiAgICAgICAgICAgIHsgdGl0bGU6IFwiVGVzdFwiLCB2YWx1ZTogXCJ0ZXN0XCIgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFyZ3M6IFtcbiAgICAgICAgW1wiZml4dHVyZVwiLCBcImluaXRcIl0sXG4gICAgICAgIFtcImZpeHR1cmVcIiwgXCJpbXBvcnRcIiwgXCIjZW50aXR5SWRcIiwgXCIjcmVjb3JkSWRzXCJdLFxuICAgICAgICBbXCJmaXh0dXJlXCIsIFwic3luY1wiXSxcbiAgICAgICAgW1wiZml4dHVyZVwiLCBcImdlblwiXSxcbiAgICAgICAgW1wiZml4dHVyZVwiLCBcImZldGNoXCJdLFxuICAgICAgICBbXCJmaXh0dXJlXCIsIFwiZXhwbG9yZVwiXSxcbiAgICAgICAgW1wibWlncmF0ZVwiLCBcInJ1blwiXSxcbiAgICAgICAgW1wibWlncmF0ZVwiLCBcImFwcGx5XCIsIFwiI3RhcmdldHNcIl0sXG4gICAgICAgIFtcIm1pZ3JhdGVcIiwgXCJnZW5lcmF0ZVwiXSxcbiAgICAgICAgW1wibWlncmF0ZVwiLCBcInN0YXR1c1wiXSxcbiAgICAgICAgW1wic3R1YlwiLCBcInByYWN0aWNlXCIsIFwiI25hbWVcIl0sXG4gICAgICAgIFtcInN0dWJcIiwgXCJlbnRpdHlcIiwgXCIjbmFtZVwiXSxcbiAgICAgICAgW1wic2NhZmZvbGRcIiwgXCJtb2RlbFwiLCBcIiNlbnRpdHlJZFwiXSxcbiAgICAgICAgW1wic2NhZmZvbGRcIiwgXCJtb2RlbF90ZXN0XCIsIFwiI2VudGl0eUlkXCJdLFxuICAgICAgICBbXCJzY2FmZm9sZFwiLCBcInZpZXdfbGlzdFwiLCBcIiNlbnRpdHlJZFwiXSxcbiAgICAgICAgW1wic2NhZmZvbGRcIiwgXCJ2aWV3X2Zvcm1cIiwgXCIjZW50aXR5SWRcIl0sXG4gICAgICAgIFtcImNvbmVcIiwgXCJnZW5cIiwgXCIjZW50aXR5SWRcIl0sXG4gICAgICAgIFtcInN5bmNcIl0sXG4gICAgICAgIFtcImJ1aWxkXCIsIFwiYWxsXCJdLFxuICAgICAgICBbXCJidWlsZFwiLCBcImFwaVwiXSxcbiAgICAgICAgW1wiYnVpbGRcIiwgXCJ3ZWJcIl0sXG4gICAgICAgIFtcImRldlwiLCBcImFsbFwiXSxcbiAgICAgICAgW1wiZGV2XCIsIFwiYXBpXCJdLFxuICAgICAgICBbXCJkZXZcIiwgXCJ3ZWJcIl0sXG4gICAgICAgIFtcInN0YXJ0XCJdLFxuICAgICAgICBbXCJza2lsbHNcIiwgXCJzeW5jXCJdLFxuICAgICAgICBbXCJza2lsbHNcIiwgXCJjcmVhdGVcIiwgXCIjbmFtZVwiXSxcbiAgICAgICAgW1widGVzdFwiXSxcbiAgICAgICAgW1wiYXV0aFwiLCBcImdlbmVyYXRlXCJdLFxuICAgICAgICBbXCJhdXRoXCIsIFwiYWRkLWNvbXBhbmlvbnNcIl0sXG4gICAgICBdLFxuICAgICAgcnVubmVyczoge1xuICAgICAgICBtaWdyYXRlX3N0YXR1cyxcbiAgICAgICAgbWlncmF0ZV9ydW4sXG4gICAgICAgIG1pZ3JhdGVfYXBwbHksXG4gICAgICAgIG1pZ3JhdGVfZ2VuZXJhdGUsXG4gICAgICAgIGZpeHR1cmVfaW5pdCxcbiAgICAgICAgZml4dHVyZV9pbXBvcnQsXG4gICAgICAgIGZpeHR1cmVfc3luYyxcbiAgICAgICAgZml4dHVyZV9nZW4sXG4gICAgICAgIGZpeHR1cmVfZmV0Y2gsXG4gICAgICAgIGZpeHR1cmVfZXhwbG9yZSxcbiAgICAgICAgc3R1Yl9wcmFjdGljZSxcbiAgICAgICAgc3R1Yl9lbnRpdHksXG4gICAgICAgIHNjYWZmb2xkX21vZGVsLFxuICAgICAgICBzY2FmZm9sZF9tb2RlbF90ZXN0LFxuICAgICAgICAvLyBzY2FmZm9sZF92aWV3X2xpc3QsXG4gICAgICAgIC8vIHNjYWZmb2xkX3ZpZXdfZm9ybSxcbiAgICAgICAgY29uZV9nZW4sXG4gICAgICAgIHN5bmMsXG4gICAgICAgIGJ1aWxkX2FsbCxcbiAgICAgICAgYnVpbGRfYXBpLFxuICAgICAgICBidWlsZF93ZWIsXG4gICAgICAgIGRldl9hbGwsXG4gICAgICAgIGRldl9hcGksXG4gICAgICAgIGRldl93ZWIsXG4gICAgICAgIHN0YXJ0LFxuICAgICAgICBza2lsbHNfc3luYyxcbiAgICAgICAgc2tpbGxzX2NyZWF0ZSxcbiAgICAgICAgdGVzdDogdGVzdENvbW1hbmQsXG4gICAgICAgIGF1dGhfZ2VuZXJhdGUsXG4gICAgICAgIFwiYXV0aF9hZGQtY29tcGFuaW9uc1wiOiBhdXRoX2FkZF9jb21wYW5pb25zLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfSBmaW5hbGx5IHtcbiAgICBhd2FpdCBTb25hbXUuZGVzdHJveSgpO1xuICB9XG59XG5cbmJvb3RzdHJhcCgpLmZpbmFsbHkoYXN5bmMgKCkgPT4ge1xuICBhd2FpdCBGaXh0dXJlTWFuYWdlci5kZXN0cm95KCk7XG59KTtcblxuLyoqXG4gKiBwbnBtIHN5bmMg7ZWY66m0IOyLpO2WieuQmOuKlCDtlajsiJjsnoXri4jri6QuXG4gKiDtlITroZzsoJ3tirjrpbwg7Iux7YGs7ZWp64uI64ukLlxuICpcbiAqIGAtLWZvcmNlYCDsmLXshZjsnbQg7KO87Ja07KeA66m0IGxvY2vsnYQg66y07Iuc7ZWY6rOgIO2SgC3si7Htgazrpbwg7IiY7ZaJ7ZWp64uI64ukLlxuICogZ2l0IHBvc3QtbWVyZ2UgaG9va+ydtOuCmCBDSeyXkOyEnCDrp6QgcHVsbCDtm4Qg7J6Q64+ZIOyLpO2Wie2VoCDsiJgg7J6I64+E66GdIOuFuOy2nC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc3luYygpIHtcbiAgY29uc3QgeyBmbGFncyB9ID0gcGFyc2VDbGlPcHRpb25zKCk7XG4gIGlmIChmbGFncy5oYXMoXCJmb3JjZVwiKSkge1xuICAgIGF3YWl0IFNvbmFtdS5zeW5jZXIuZm9yY2VTeW5jKCk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgU29uYW11LnN5bmNlci5zeW5jKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBUEkg6rCc67CcIOyEnOuyhOulvCDsi6TtlontlZjripQg6rO17Ya1IOuhnOyngeyeheuLiOuLpC5cbiAqIGRldl9hbGzqs7wgZGV2X2FwaeyXkOyEnCDqs7XsnKDtlanri4jri6QuXG4gKlxuICogVHlwZVNjcmlwdOulvCDrsJTroZwg7Iuk7ZaJ7ZWgIOyImCDsnojrj4TroZ0gQHNvbmFtdS1raXQvdHMtbG9hZGVy66W8LFxuICogSE1S7J2EIOyngOybkO2VmOq4sCDsnITtlbQgQHNvbmFtdS1raXQvaG1yLWhvb2vsnYQgaW1wb3J07ZWY66mwLFxuICog7IaM7Iqk66e1IOyngOybkOydhCDsnITtlbQgLS1lbmFibGUtc291cmNlLW1hcHMg7ZSM656Y6re466W8IO2PrO2VqO2VmOyXrCDsi6Ttlontlanri4jri6QuXG4gKlxuICog7J2065WMIEBzb25hbXUta2l0L3RzLWxvYWRlcuyZgCBAc29uYW11LWtpdC9obXItaG9va+uKlCBzb25hbXXqsIAg7J6Q7LK07KCB7Jy866GcIOqwgOyngOqzoCDsnojripQgZGVwZW5kZW5jeeyeheuLiOuLpC5cbiAqIOuYkO2VnCDsi6Ttlonsl5Ag7IKs7Jqp7ZWY64qUIEBzb25hbXUta2l0L2htci1ydW5uZXLrj4Qg66eI7LCs6rCA7KeA66GcIHNvbmFtdeqwgCDsnpDssrTsoIHsnLzroZwg6rCA7KeA6rOgIOyeiOuKlCBkZXBlbmRlbmN57J6F64uI64ukLlxuICog65Sw65287IScIOyCrOyaqeyekCDtlITroZzsoJ3tirjsl5DshJzripQg7J20IOyEuCDtjKjtgqTsp4Drpbwg7KeB7KCRIOyEpOy5mO2VoCDtlYTsmpTqsIAg7JeG7Iq164uI64ukLlxuICovXG5mdW5jdGlvbiBzcGF3bkFwaURldlNlcnZlcihvcHRpb25zPzogeyBleHRyYUVudj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfSkge1xuICBjb25zdCBhcGlSb290ID0gZmluZEFwaVJvb3RQYXRoKCk7XG4gIGNvbnN0IGVudHJ5UG9pbnQgPSBcInNyYy9pbmRleC50c1wiO1xuXG4gIC8vIOydtCBzb25hbXUg7Yyo7YKk7KeA6rCAIGRlcGVuZGVuY2llc+uhnCDqsIDsp4Dqs6Ag7J6I64qUIEBzb25hbXUta2l0L2htci1ydW5uZXLsnZggYmluL3J1bi5qc+ulvCDsgqzsmqntlanri4jri6QuXG4gIC8vIOydtCDqsr3roZwoL2Jpbi9ydW4uanMp64qUIEBzb25hbXUta2l0L2htci1ydW5uZXLsnZggcGFja2FnZS5qc29u7J2YIGJpbiDtlYTrk5zsl5Ag66qF7Iuc65CY7Ja0IOyeiOuKlCDqt7jqsoPqs7wg6rCZ7Iq164uI64ukLlxuICBjb25zdCBob3RSdW5uZXJCaW5QYXRoID0gY3JlYXRlUmVxdWlyZShpbXBvcnQubWV0YS51cmwpLnJlc29sdmUoXG4gICAgXCJAc29uYW11LWtpdC9obXItcnVubmVyL2Jpbi9ydW4uanNcIixcbiAgKTtcblxuICBjb25zdCBzZXJ2ZXJQcm9jZXNzID0gc3Bhd24oXG4gICAgcHJvY2Vzcy5leGVjUGF0aCwgLy8gbm9kZVxuICAgIFtcbiAgICAgIGhvdFJ1bm5lckJpblBhdGgsIC8vIOydtOugh+qyjCDtlbTshJwgaG90LXJ1bm5lcuulvCDsi6TtlontlZjqtazsmpRcbiAgICAgIFwiLS1jbGVhci1zY3JlZW49ZmFsc2VcIiwgLy8g7J207ZWYIGhvdC1ydW5uZXLsl5Dqsowg64SY6rKo7KSEIOyduOyekOuTpOyeheuLiOuLpC5cbiAgICAgIFwiLS1ub2RlLWFyZ3M9LS1pbXBvcnQ9c29uYW11L3RzLWxvYWRlci1yZWdpc3RlclwiLCAvLyBUeXBlU2NyaXB0IOyEnO2PrO2KuOulvCDsnITtlZwg66Gc642ULFxuICAgICAgXCItLW5vZGUtYXJncz0tLWltcG9ydD1zb25hbXUvaG1yLWhvb2stcmVnaXN0ZXJcIiwgLy8gSE1S7J2EIOyngOybkO2VmOq4sCDsnITtlZwgaG9vayxcbiAgICAgIFwiLS1ub2RlLWFyZ3M9LS1lbmFibGUtc291cmNlLW1hcHNcIiwgLy8g6re466as6rOgIOyGjOyKpOuntSDsp4Dsm5DsnYQg7JyE7ZWcIO2UjOuemOq3uOyeheuLiOuLpC5cbiAgICAgIFwiLS1vbi1rZXk9cjpyZXN0YXJ0OlJlc3RhcnQgc2VydmVyXCIsIC8vIHIg64iE66W066m0IOyEnOuyhCDsnqzsi5zsnpHtlZjqsowg7ZW07KSY7JqULlxuICAgICAgXCItLW9uLWtleT1jOmNsZWFyOkNsZWFyIHNjcmVlblwiLCAvLyBjIOuIhOultOuptCDthLDrr7jrhJAg7ZmU66m07J2EIOyngOybjOykmOyalC5cbiAgICAgIGAtLW9uLWtleT1mOnNoZWxsKHJtICR7cGF0aC5qb2luKGFwaVJvb3QsIFwic29uYW11LmxvY2tcIil9KTpyZXN0YXJ0OkZvcmNlIHJlc3RhcnRgLCAvLyBmIOuIhOultOuptCBsb2NrIOygnOqxsCDtm4Qg7J6s7Iuc7J6RIOKGkiDsg4gg7ZSE66Gc7IS47Iqk6rCAIOu2gO2KuOyKpO2KuOueqeyXkOyEnCDtkoAt7Iux7YGsLiBmb3JjZSBzeW5jIENMSeulvCBzaGVsbOuhnCDrtoDrpbTrqbQg7IK07JWE7J6I64qUIOyEnOuyhOydmCB3YXRjaGVyIO2Pre2SjeydtCA6cmVzdGFydOyZgCDstqnrj4ztlbQg7IOB7YOcIOydtOyDgS5cblxuICAgICAgXCItLW9uLWtleT1lbnRlcjpzaGVsbChlY2hvIGhpKTpLZXkgYmluZGluZyB0ZXN0XCIsIC8vIGVudGVy66W8IGtleeuhnCDsk7gg7IiYIOyeiOydjOydhCDrs7TsnbTquLAg7JyE7ZWcIO2FjOyKpO2KuOyeheuLiOuLpC5cbiAgICAgIFwiLS1vbi1rZXk9Y3RybCtmIGN0cmwrZjpzaGVsbChnaXQgcHVsbCAmJiBwbnBtIGluc3RhbGwgJiYgcG5wbSAtLWZpbHRlciBzb25hbXUgYnVpbGQgJiYgZWNobyAnU29uYW11IGlzIG5vdyB1cC10by1kYXRlIScpOnJlc3RhcnQ6UHVsbCAmIGluc3RhbGwgJiBidWlsZCAmIHJlc3RhcnRcIiwgLy8gbW9kaWZpZXLsmYDsnZgg7KGw7ZWpLCDqt7jrpqzqs6Ag65GQIOqwnOydmCBjaG9yZOulvCDsgqzsmqntlaAg7IiYIOyeiOydjOydhCDrs7TsnbTquLAg7JyE7ZWcIO2FjOyKpO2KuOyeheuLiOuLpC5cbiAgICAgIGVudHJ5UG9pbnQsIC8vIOuniOyngOunieycvOuhnCDsi6TsoJwg7Iuk7ZaJ7ZWgIOyKpO2BrOumve2KuOydmCDqsr3roZzrpbwg64SY6rKo7KSN64uI64ukLlxuICAgIF0sXG4gICAge1xuICAgICAgY3dkOiBhcGlSb290LFxuICAgICAgc3RkaW86IFwiaW5oZXJpdFwiLFxuICAgICAgZW52OiB7XG4gICAgICAgIC4uLnByb2Nlc3MuZW52LFxuICAgICAgICBOT0RFX0VOVjogcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPz8gXCJkZXZlbG9wbWVudFwiLFxuICAgICAgICBIT1Q6IFwieWVzXCIsIC8vIOyWmOqwgCDsnojslrTslbwgSE1S7J20IO2ZnOyEse2ZlOuQqeuLiOuLpC5cbiAgICAgICAgQVBJX1JPT1RfUEFUSDogYXBpUm9vdCwgLy8g7J20IOqyveuhnOqwgCBobXItaG9va+ydmCDro6jtirgg65SU66CJ7Yag66as6rCAIOuQqeuLiOuLpC5cbiAgICAgICAgLi4ub3B0aW9ucz8uZXh0cmFFbnYsXG4gICAgICB9LFxuICAgIH0sXG4gICk7XG5cbiAgLy8g7KKF66OMIOyymOumrFxuICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdyhcIlxcblxcbvCfkYsgU2h1dHRpbmcgZG93bi4uLlwiKSk7XG4gICAgc2VydmVyUHJvY2Vzcy5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICBwcm9jZXNzLmV4aXQoMCk7XG4gIH07XG5cbiAgcHJvY2Vzcy5vbihcIlNJR0lOVFwiLCBjbGVhbnVwKTtcbiAgcHJvY2Vzcy5vbihcIlNJR1RFUk1cIiwgY2xlYW51cCk7XG5cbiAgc2VydmVyUHJvY2Vzcy5vbihcImV4aXRcIiwgKGNvZGUpID0+IHtcbiAgICBpZiAoY29kZSAhPT0gMCkge1xuICAgICAgY29uc29sZS5lcnJvcihjaGFsay5yZWQoYFNlcnZlciBleGl0ZWQgd2l0aCBjb2RlICR7Y29kZX1gKSk7XG4gICAgICBwcm9jZXNzLmV4aXQoY29kZSB8fCAxKTtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIHBucG0gZGV2IC8gcG5wbSBkZXYgYWxsIO2VmOuptCDsi6TtlonrkJjripQg7ZWo7IiY7J6F64uI64ukLlxuICog7ZSE66Gc7KCd7Yq47JeQIOuMgO2VtCBITVIg7KeA7JuQ7ZWY64qUIOqwnOuwnCDshJzrsoTrpbwg652E7JuM7KSN64uI64ukLlxuICpcbiAqIFNvbmFtdS5pbml0IOyXhuydtCDtmLjstpzrkKAg6rKD7J2EIOyDgeygle2VmOyXrCDqtaztmITrkJjsl4jsirXri4jri6QuXG4gKi9cbmZ1bmN0aW9uIGRldl9hbGwoKSB7XG4gIGNvbnN0IHJlcXVpcmUgPSBjcmVhdGVSZXF1aXJlKGltcG9ydC5tZXRhLnVybCk7XG4gIGNvbnN0IHsgdmVyc2lvbiB9ID0gcmVxdWlyZShcIi4uLy4uL3BhY2thZ2UuanNvblwiKTtcbiAgY29uc29sZS5sb2coYPCfjLIgU29uYW11IHYke3ZlcnNpb259XFxuYCk7XG4gIHNwYXduQXBpRGV2U2VydmVyKCk7XG59XG5cbi8qKlxuICogcG5wbSBkZXYgYXBpIO2VmOuptCDsi6TtlonrkJjripQg7ZWo7IiY7J6F64uI64ukLlxuICogQVBJIOyghOyaqSDqsJzrsJwg7ISc67KE66W8IOudhOybgeuLiOuLpC5cbiAqIGRldl9hbGzqs7wg6rGw7J2YIOuPmeydvO2VmOuQmCwg7Ya17ZWpIOybuSDshJzrsoTrpbwg67mE7Zmc7ISx7ZmU7ZWp64uI64ukLlxuICpcbiAqIFNvbmFtdS5pbml0IOyXhuydtCDtmLjstpzrkKAg6rKD7J2EIOyDgeygle2VmOyXrCDqtaztmITrkJjsl4jsirXri4jri6QuXG4gKi9cbmZ1bmN0aW9uIGRldl9hcGkoKSB7XG4gIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdy5ib2xkKFwiU3RhcnRpbmcgU29uYW11IEFQSS1vbmx5IGRldiBzZXJ2ZXIuLi5cXG5cIikpO1xuICBzcGF3bkFwaURldlNlcnZlcih7XG4gICAgZXh0cmFFbnY6IHsgU09OQU1VX0RJU0FCTEVfSU5URUdSQVRFRF9XRUI6IFwieWVzXCIgfSxcbiAgfSk7XG59XG5cbi8qKlxuICogcG5wbSBkZXYgd2ViIO2VmOuptCDsi6TtlonrkJjripQg7ZWo7IiY7J6F64uI64ukLlxuICogVml0ZSDqsJzrsJwg7ISc67KE66W8IOuLqOuPheycvOuhnCDsi6Ttlontlanri4jri6QuXG4gKiAtLSDrkqTsnZgg7J247J6Q64qUIFZpdGXsl5Ag6re464yA66GcIOyghOuLrOuQqeuLiOuLpC5cbiAqXG4gKiBTb25hbXUuaW5pdCDsl4bsnbQg7Zi47Lac65CgIOqyg+ydhCDsg4HsoJXtlZjsl6wg6rWs7ZiE65CY7JeI7Iq164uI64ukLlxuICovXG5hc3luYyBmdW5jdGlvbiBkZXZfd2ViKCkge1xuICBjb25zdCBhcHBSb290ID0gZmluZEFwcFJvb3RQYXRoKCk7XG4gIGNvbnN0IHdlYlBhdGggPSBwYXRoLmpvaW4oYXBwUm9vdCwgXCJ3ZWJcIik7XG5cbiAgaWYgKCEoYXdhaXQgZXhpc3RzKHdlYlBhdGgpKSkge1xuICAgIGNvbnNvbGUuZXJyb3IoYHdlYiDrlJTroInthqDrpqzrpbwg7LC+7J2EIOyImCDsl4bsirXri4jri6Q6ICR7d2ViUGF0aH1gKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cblxuICAvLyAtLSDrkqTsnZgg7J247J6QIOy2lOy2nFxuICBjb25zdCBkb3VibGVEYXNoSW5kZXggPSBwcm9jZXNzLmFyZ3YuaW5kZXhPZihcIi0tXCIpO1xuICBjb25zdCBwYXNzdGhyb3VnaEFyZ3MgPSBkb3VibGVEYXNoSW5kZXggIT09IC0xID8gcHJvY2Vzcy5hcmd2LnNsaWNlKGRvdWJsZURhc2hJbmRleCArIDEpIDogW107XG5cbiAgY29uc3Qgdml0ZUFyZ3MgPSBbXCJleGVjXCIsIFwidml0ZVwiLCAuLi5wYXNzdGhyb3VnaEFyZ3NdO1xuXG4gIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdy5ib2xkKFwiU3RhcnRpbmcgVml0ZSBkZXYgc2VydmVyLi4uXFxuXCIpKTtcblxuICBjb25zdCB2aXRlUHJvY2VzcyA9IHNwYXduKFwicG5wbVwiLCB2aXRlQXJncywge1xuICAgIGN3ZDogd2ViUGF0aCxcbiAgICBzdGRpbzogXCJpbmhlcml0XCIsXG4gIH0pO1xuXG4gIHZpdGVQcm9jZXNzLm9uKFwiZXhpdFwiLCAoY29kZSkgPT4ge1xuICAgIHByb2Nlc3MuZXhpdChjb2RlID8/IDApO1xuICB9KTtcblxuICAvLyBTSUdJTlQvU0lHVEVSTSDsi5wgVml0ZSDtlITroZzshLjsiqTrpbwgZ3JhY2VmdWxseSDsooXro4ztlanri4jri6QuXG4gIGZvciAoY29uc3Qgc2lnbmFsIG9mIFtcIlNJR0lOVFwiLCBcIlNJR1RFUk1cIl0gYXMgY29uc3QpIHtcbiAgICBwcm9jZXNzLm9uKHNpZ25hbCwgKCkgPT4ge1xuICAgICAgdml0ZVByb2Nlc3Mua2lsbChzaWduYWwpO1xuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogQVBJIOu5jOuTnCDshKTsoJUg7YyM7J28IOqyveuhnOulvCDqsrDsoJXtlanri4jri6QuXG4gKiDtlITroZzsoJ3tirgg66Oo7Yq47JeQIGB0c2Rvd24uY29uZmlnLnRzYOqwgCDsnojsnLzrqbQg6re46rKD7J2ELCDsl4bsnLzrqbQgc29uYW11IOq4sOuzuCDshKTsoJXsnYQg7IKs7Jqp7ZWp64uI64ukLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlQXBpQnVpbGRDb25maWdQYXRoKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGxvY2FsQ29uZmlnUGF0aCA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCBcInRzZG93bi5jb25maWcudHNcIik7XG5cbiAgdHJ5IHtcbiAgICBpZiAoYXdhaXQgZXhpc3RzKGxvY2FsQ29uZmlnUGF0aCkpIHtcbiAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShcIlVzaW5nIHRzZG93bi5jb25maWcudHMgZnJvbSBwcm9qZWN0IHJvb3QuLi5cIikpO1xuICAgICAgcmV0dXJuIGxvY2FsQ29uZmlnUGF0aDtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhjaGFsay5kaW0oXCJVc2luZyBkZWZhdWx0IHRzZG93biBBUEkgY29uZmlnIGZyb20gc29uYW11IHBhY2thZ2UuLi5cIikpO1xuICAgIHJldHVybiBwYXRoLmpvaW4oaW1wb3J0Lm1ldGEuZGlybmFtZSwgXCIuLlwiLCBcIi4uXCIsIFwidHNkb3duLmFwaS5jb25maWcudHNcIik7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc29sZS5lcnJvcihjaGFsay5yZWQoXCJTZXR0aW5nIHVwIEFQSSBidWlsZCBjb25maWcgZmFpbGVkLlwiKSwgZXJyb3IpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxufVxuXG4vKipcbiAqIHNvbmFtdSBidWlsZCAvIHNvbmFtdSBidWlsZCBhbGwg7ZWY66m0IOyLpO2WieuQmOuKlCDtlajsiJjsnoXri4jri6QuXG4gKiBidWlsZF9hcGkgKyBidWlsZF93ZWLsnZgg7ZWp7ISx7J6F64uI64ukLiBXZWIg65SU66CJ7Yag66as6rCAIOyXhuycvOuptCBXZWIg67mM65Oc66W8IOyKpO2Cte2VqeuLiOuLpC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gYnVpbGRfYWxsKCkge1xuICBhd2FpdCBidWlsZF9hcGkoKTtcbiAgYXdhaXQgYnVpbGRfd2ViKHsgc2tpcElmTWlzc2luZzogdHJ1ZSB9KTtcbn1cblxuLyoqXG4gKiBwbnBtIGJ1aWxkIGFwaSDtlZjrqbQg7Iuk7ZaJ65CY64qUIO2VqOyImOyeheuLiOuLpC5cbiAqIEFQSSDtlITroZzsoJ3tirjrp4wg67mM65Oc7ZWp64uI64ukLlxuICpcbiAqIFNvbmFtdS5pbml0IOyXhuydtCDtmLjstpzrkKAg6rKD7J2EIOyDgeygle2VmOyXrCDqtaztmITrkJjsl4jsirXri4jri6QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGJ1aWxkX2FwaSgpIHtcbiAgY29uc3QgYXBwUm9vdCA9IGZpbmRBcHBSb290UGF0aCgpO1xuICBjb25zdCBjb25maWdGaWxlUGF0aCA9IGF3YWl0IHJlc29sdmVBcGlCdWlsZENvbmZpZ1BhdGgoKTtcblxuICBjb25zdCBhcGlTdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICB0cnkge1xuICAgIGZvciAoY29uc3QgYXJ0aWZhY3Qgb2YgQVBJX0FSVElGQUNUUykge1xuICAgICAgY29uc3QgY3dkID0gcGF0aC5qb2luKGFwcFJvb3QsIGFydGlmYWN0LnByb2plY3RQYXRoKTtcbiAgICAgIHByaW50VGFza0hlYWRlcihhcnRpZmFjdC5uYW1lLCBhcnRpZmFjdC5kZXNjcmlwdGlvbiwgY3dkKTtcblxuICAgICAgYXdhaXQgcnVuQnVpbGRTdGVwcyhhcnRpZmFjdCwgeyBjd2QsIGJ1aWxkQ29tbWFuZEFyZ3M6IHsgY29uZmlnRmlsZVBhdGggfSB9KTtcbiAgICB9XG4gICAgcHJpbnRCdWlsZFN1bW1hcnkoXCJBUElcIiwgdHJ1ZSwgRGF0ZS5ub3coKSAtIGFwaVN0YXJ0ZWRBdCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBwcmludEJ1aWxkU3VtbWFyeShcIkFQSVwiLCBmYWxzZSwgRGF0ZS5ub3coKSAtIGFwaVN0YXJ0ZWRBdCk7XG4gICAgY29uc29sZS5lcnJvcihlKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cbn1cblxuLyoqXG4gKiBwbnBtIGJ1aWxkIHdlYiDtlZjrqbQg7Iuk7ZaJ65CY64qUIO2VqOyImOyeheuLiOuLpC5cbiAqIFdlYiDtlITroZzsoJ3tirjrp4wg67mM65Oc7ZWp64uI64ukLlxuICpcbiAqIFNvbmFtdS5pbml0IOyXhuydtCDtmLjstpzrkKAg6rKD7J2EIOyDgeygle2VmOyXrCDqtaztmITrkJjsl4jsirXri4jri6QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGJ1aWxkX3dlYih7IHNraXBJZk1pc3NpbmcgPSBmYWxzZSB9ID0ge30pIHtcbiAgY29uc3QgYXBwUm9vdCA9IGZpbmRBcHBSb290UGF0aCgpO1xuICBjb25zdCB3ZWJQYXRoID0gcGF0aC5qb2luKGFwcFJvb3QsIFwid2ViXCIpO1xuXG4gIGlmICghKGF3YWl0IGV4aXN0cyh3ZWJQYXRoKSkpIHtcbiAgICBpZiAoc2tpcElmTWlzc2luZykge1xuICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JheShcIldlYiDrlJTroInthqDrpqzqsIAg7JeG7Jy866+A66GcIFdlYiDruYzrk5zrpbwg6rG064SI65yB64uI64ukLlwiKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnNvbGUuZXJyb3IoYHdlYiDrlJTroInthqDrpqzrpbwg7LC+7J2EIOyImCDsl4bsirXri4jri6Q6ICR7d2ViUGF0aH1gKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cblxuICBjb25zdCB3ZWJTdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICB0cnkge1xuICAgIGZvciAoY29uc3QgYXJ0aWZhY3Qgb2YgV0VCX0FSVElGQUNUUykge1xuICAgICAgY29uc3QgY3dkID0gcGF0aC5qb2luKGFwcFJvb3QsIGFydGlmYWN0LnByb2plY3RQYXRoKTtcbiAgICAgIHByaW50VGFza0hlYWRlcihhcnRpZmFjdC5uYW1lLCBhcnRpZmFjdC5kZXNjcmlwdGlvbiwgY3dkKTtcblxuICAgICAgYXdhaXQgcnVuQnVpbGRTdGVwcyhhcnRpZmFjdCwgeyBjd2QsIGJ1aWxkQ29tbWFuZEFyZ3M6IHt9IH0pO1xuICAgIH1cbiAgICBwcmludEJ1aWxkU3VtbWFyeShcIldlYlwiLCB0cnVlLCBEYXRlLm5vdygpIC0gd2ViU3RhcnRlZEF0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHByaW50QnVpbGRTdW1tYXJ5KFwiV2ViXCIsIGZhbHNlLCBEYXRlLm5vdygpIC0gd2ViU3RhcnRlZEF0KTtcbiAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxufVxuXG4vKipcbiAqIHByZS1idWlsZCwgYnVpbGQsIHBvc3QtYnVpbGQg64uo6rOE66W8IOyInOywqOyggeycvOuhnCDsi6Ttlontlanri4jri6QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJ1bkJ1aWxkU3RlcHM8VD4oXG4gIGFydGlmYWN0OiBCdWlsZEFydGlmYWN0PFQ+LFxuICBvcHRpb25zOiB7IGN3ZDogc3RyaW5nOyBidWlsZENvbW1hbmRBcmdzOiBUIH0sXG4pIHtcbiAgY29uc3Qgc3RlcHMgPSBbXG4gICAgeyBuYW1lOiBcInByZS1idWlsZFwiLCBjbWQ6IGFydGlmYWN0LnByZUJ1aWxkQ29tbWFuZD8uKCkgfSxcbiAgICB7IG5hbWU6IFwiYnVpbGRcIiwgY21kOiBhcnRpZmFjdC5idWlsZENvbW1hbmQob3B0aW9ucy5idWlsZENvbW1hbmRBcmdzKSB9LFxuICAgIHsgbmFtZTogXCJwb3N0LWJ1aWxkXCIsIGNtZDogYXJ0aWZhY3QucG9zdEJ1aWxkQ29tbWFuZD8uKCkgfSxcbiAgXS5maWx0ZXIoKHN0ZXApID0+IHN0ZXAuY21kKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHN0ZXBzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgc3RlcCA9IHN0ZXBzW2ldO1xuICAgIGNvbnN0IGlzTGFzdCA9IGkgPT09IHN0ZXBzLmxlbmd0aCAtIDE7XG5cbiAgICB0cnkge1xuICAgICAgYXNzZXJ0KHN0ZXAuY21kKTtcbiAgICAgIHByaW50VGFza1N0YXJ0KHN0ZXAubmFtZSwgc3RlcC5jbWQsIGlzTGFzdCk7XG4gICAgICBhd2FpdCBleGVjV2l0aExpbmVQcmVmaXgoc3RlcC5jbWQsIHsgY3dkOiBvcHRpb25zLmN3ZCB9KTtcbiAgICAgIHByaW50VGFza1N1Y2Nlc3Moc3RlcC5uYW1lLCBpc0xhc3QpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHByaW50VGFza0ZhaWxlZChzdGVwLm5hbWUsIGlzTGFzdCk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c3RlcC5uYW1lfSBmYWlsZWRgLCB7IGNhdXNlOiBlIH0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIHBucG0gc3RhcnQg7ZWY66m0IOyLpO2WieuQmOuKlCDtlajsiJjsnoXri4jri6QuXG4gKiDruYzrk5zrkJwg7ZSE66Gc7KCd7Yq466W8IOyLpO2Wie2VqeuLiOuLpC5cbiAqXG4gKiDruYzrk5zrkJwg6rKw6rO866y8KGRpc3Qg65SU66CJ7Yag66as7J2YIGluZGV4LmpzIOyXlO2KuOumrO2PrOyduO2KuCnsnbQg7JeG64uk66m0IOyLpO2WieydhCDspJHri6jtlanri4jri6QuXG4gKiDshozsiqTrp7Ug7KeA7JuQ6rO8IGRvdGVudiDsp4Dsm5DsnYQg7Y+s7ZWo7ZWY7JesIOyLpO2Wie2VqeuLiOuLpC5cbiAqXG4gKiBTb25hbXUuaW5pdCDsl4bsnbQg7Zi47Lac65CgIOqyg+ydhCDsg4HsoJXtlZjsl6wg6rWs7ZiE65CY7JeI7Iq164uI64ukLlxuICovXG5hc3luYyBmdW5jdGlvbiBzdGFydCgpIHtcbiAgY29uc3QgcmVxdWlyZSA9IGNyZWF0ZVJlcXVpcmUoaW1wb3J0Lm1ldGEudXJsKTtcbiAgY29uc3QgeyB2ZXJzaW9uIH0gPSByZXF1aXJlKFwiLi4vLi4vcGFja2FnZS5qc29uXCIpO1xuICBjb25zb2xlLmxvZyhg8J+MsiBTb25hbXUgdiR7dmVyc2lvbn1cXG5gKTtcblxuICBjb25zdCBhcGlSb290ID0gZmluZEFwaVJvb3RQYXRoKCk7XG4gIGNvbnN0IGVudHJ5UG9pbnQgPSBcImRpc3QvaW5kZXguanNcIjtcblxuICBpZiAoIShhd2FpdCBleGlzdHMoZW50cnlQb2ludCkpKSB7XG4gICAgY29uc29sZS5sb2coY2hhbGsucmVkKGAke2VudHJ5UG9pbnR9IG5vdCBmb3VuZC4gUGxlYXNlIGJ1aWxkIHlvdXIgcHJvamVjdCBmaXJzdC5gKSk7XG4gICAgY29uc29sZS5sb2coY2hhbGsuYmx1ZShcIlJ1bjogcG5wbSBzb25hbXUgYnVpbGRcIikpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHsgc3Bhd24gfSA9IGF3YWl0IGltcG9ydChcImNoaWxkX3Byb2Nlc3NcIik7XG4gIGNvbnN0IHNlcnZlclByb2Nlc3MgPSBzcGF3bihcbiAgICBwcm9jZXNzLmV4ZWNQYXRoLFxuICAgIFtcIi0tZW5hYmxlLXNvdXJjZS1tYXBzXCIsIFwiLXJcIiwgXCJkb3RlbnYvY29uZmlnXCIsIGVudHJ5UG9pbnRdLFxuICAgIHtcbiAgICAgIGN3ZDogYXBpUm9vdCxcbiAgICAgIHN0ZGlvOiBcImluaGVyaXRcIixcbiAgICB9LFxuICApO1xuXG4gIHByb2Nlc3Mub24oXCJTSUdJTlRcIiwgKCkgPT4ge1xuICAgIHNlcnZlclByb2Nlc3Mua2lsbChcIlNJR1RFUk1cIik7XG4gICAgcHJvY2Vzcy5leGl0KDApO1xuICB9KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc2V0dXBNaWdyYXRvcigpIHtcbiAgLy8gbWlncmF0b3JcbiAgbWlncmF0b3IgPSBuZXcgTWlncmF0b3IoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc2V0dXBGaXh0dXJlTWFuYWdlcigpIHtcbiAgRml4dHVyZU1hbmFnZXIuaW5pdCgpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBtaWdyYXRlX2FwcGx5KHRhcmdldHM6IChrZXlvZiBTb25hbXVEQkNvbmZpZylbXSkge1xuICBhd2FpdCBzZXR1cE1pZ3JhdG9yKCk7XG4gIGF3YWl0IG1pZ3JhdG9yLnJ1bkFjdGlvbihcImFwcGx5XCIsIHRhcmdldHMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBtaWdyYXRlX3J1bigpIHtcbiAgYXdhaXQgc2V0dXBNaWdyYXRvcigpO1xuICBhd2FpdCBtaWdyYXRvci5ydW5BY3Rpb24oXCJhcHBseVwiLCBnZXRNaWdyYXRlUnVuVGFyZ2V0cygpKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gbWlncmF0ZV9nZW5lcmF0ZSgpIHtcbiAgYXdhaXQgc2V0dXBNaWdyYXRvcigpO1xuXG4gIGNvbnN0IHsgY29ubnMgfSA9IGF3YWl0IG1pZ3JhdG9yLmdldFN0YXR1cygpO1xuICBjb25zdCBoYXNTdGF0dXMwID0gY29ubnMuc29tZSgoY29ubikgPT4gY29ubi5zdGF0dXMgPT09IDApO1xuICBpZiAoIWhhc1N0YXR1czApIHtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGNoYWxrLnJlZChcbiAgICAgICAgXCLrp4jsnbTqt7jroIjsnbTshZgg7YyM7J287J2EIOyDneyEse2VmOugpOuptCDquLDsobQg66eI7J206re466CI7J207IWY7J20IOy1nOyGjCDtlZjrgpjsnZggRELsl5Ag66qo65GQIOyggeyaqeuQmOyWtCDsnojslrTslbwg7ZWp64uI64ukLlwiLFxuICAgICAgKSxcbiAgICApO1xuICAgIGZvciAoY29uc3QgY29ubiBvZiBjb25ucykge1xuICAgICAgaWYgKGNvbm4ucGVuZGluZy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdyhgICAke2Nvbm4ubmFtZX06IHBlbmRpbmcgJHtjb25uLnBlbmRpbmcubGVuZ3RofeqwnGApKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcHJvY2Vzcy5leGl0KDEpO1xuICB9XG5cbiAgY29uc3QgY291bnQgPSBhd2FpdCBtaWdyYXRvci5nZW5lcmF0ZVByZXBhcmVkQ29kZXMoKTtcbiAgaWYgKGNvdW50ID4gMCkge1xuICAgIGNvbnNvbGUubG9nKGNoYWxrLmdyZWVuKGAke2NvdW50feqwnOydmCDrp4jsnbTqt7jroIjsnbTshZgg7YyM7J287J20IOyDneyEseuQmOyXiOyKteuLiOuLpC5gKSk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gbWlncmF0ZV9zdGF0dXMoKSB7XG4gIGF3YWl0IHNldHVwTWlncmF0b3IoKTtcblxuICBjb25zdCBzdGF0dXMgPSBhd2FpdCBtaWdyYXRvci5nZXRTdGF0dXMoKTtcbiAgLy8gc3RhdHVzO1xuICBjb25zb2xlLmxvZyhzdGF0dXMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmaXh0dXJlX2luaXQoKSB7XG4gIGNvbnN0IHNyY0NvbmZpZyA9IFNvbmFtdS5kYkNvbmZpZ1tnZXRTb25hbXVFbnZpcm9ubWVudCgpXTtcbiAgY29uc3QgdGFyZ2V0cyA9IFtcbiAgICB7XG4gICAgICBsYWJlbDogXCIoUkVNT1RFKSBGaXh0dXJlIERCXCIsXG4gICAgICBjb25maWc6IFNvbmFtdS5kYkNvbmZpZy5maXh0dXJlLFxuICAgIH0sXG4gICAge1xuICAgICAgbGFiZWw6IFwiKExPQ0FMKSBUZXN0aW5nIERCXCIsXG4gICAgICBjb25maWc6IFNvbmFtdS5kYkNvbmZpZy50ZXN0LFxuICAgICAgdG9Ta2lwOiAoKCkgPT4ge1xuICAgICAgICBjb25zdCByZW1vdGVDb25uID0gU29uYW11LmRiQ29uZmlnLmZpeHR1cmUuY29ubmVjdGlvbiBhcyBLbmV4LkNvbm5lY3Rpb25Db25maWc7XG4gICAgICAgIGNvbnN0IGxvY2FsQ29ubiA9IFNvbmFtdS5kYkNvbmZpZy50ZXN0LmNvbm5lY3Rpb24gYXMgS25leC5Db25uZWN0aW9uQ29uZmlnO1xuICAgICAgICByZXR1cm4gcmVtb3RlQ29ubi5ob3N0ID09PSBsb2NhbENvbm4uaG9zdCAmJiByZW1vdGVDb25uLmRhdGFiYXNlID09PSBsb2NhbENvbm4uZGF0YWJhc2U7XG4gICAgICB9KSgpLFxuICAgIH0sXG4gIF0gYXMge1xuICAgIGxhYmVsOiBzdHJpbmc7XG4gICAgY29uZmlnOiBLbmV4LkNvbmZpZztcbiAgICB0b1NraXA/OiBib29sZWFuO1xuICB9W107XG5cbiAgLy8gMS4g6riw7KSAREIg7Iqk7YKk66eI66W8IOuNpO2UhFxuICBjb25zb2xlLmxvZyhcIkRVTVAuLi5cIik7XG4gIGNvbnN0IGR1bXBGaWxlbmFtZSA9IGAvdG1wL3NvbmFtdS1maXh0dXJlLWluaXQtJHtEYXRlLm5vdygpfS5zcWxgO1xuICBjb25zdCBzcmNDb25uID0gc3JjQ29uZmlnLmNvbm5lY3Rpb24gYXMgS25leC5Db25uZWN0aW9uQ29uZmlnO1xuICBjb25zdCBtaWdyYXRpb25zRHVtcCA9IGAvdG1wL3NvbmFtdS1maXh0dXJlLWluaXQtbWlncmF0aW9ucy0ke0RhdGUubm93KCl9LnNxbGA7XG4gIGV4ZWNTeW5jKFxuICAgIGBteXNxbGR1bXAgLWgke3NyY0Nvbm4uaG9zdH0gLXUke3NyY0Nvbm4udXNlcn0gLXAke3NyY0Nvbm4ucGFzc3dvcmR9IC0tc2luZ2xlLXRyYW5zYWN0aW9uIC1kIC0tbm8tY3JlYXRlLWRiIC0tdHJpZ2dlcnMgJHtzcmNDb25uLmRhdGFiYXNlfSA+ICR7ZHVtcEZpbGVuYW1lfWAsXG4gICk7XG4gIGNvbnN0IF9kYiA9IGtuZXgoc3JjQ29uZmlnKTtcbiAgY29uc3QgW1ttaWdyYXRpb25zXV0gPSBhd2FpdCBfZGIucmF3KFxuICAgIFwiU0VMRUNUIENPVU5UKCopIGFzIGNvdW50IEZST00gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyBXSEVSRSB0YWJsZV9zY2hlbWEgPSA/IEFORCB0YWJsZV9uYW1lID0gJ2tuZXhfbWlncmF0aW9ucydcIixcbiAgICBbc3JjQ29ubi5kYXRhYmFzZV0sXG4gICk7XG4gIGlmIChtaWdyYXRpb25zLmNvdW50ID4gMCkge1xuICAgIGV4ZWNTeW5jKFxuICAgICAgYG15c3FsZHVtcCAtaCR7c3JjQ29ubi5ob3N0fSAtdSR7c3JjQ29ubi51c2VyfSAtcCR7c3JjQ29ubi5wYXNzd29yZH0gLS1zaW5nbGUtdHJhbnNhY3Rpb24gLS1uby1jcmVhdGUtZGIgLS10cmlnZ2VycyAke3NyY0Nvbm4uZGF0YWJhc2V9IGtuZXhfbWlncmF0aW9ucyBrbmV4X21pZ3JhdGlvbnNfbG9jayA+ICR7bWlncmF0aW9uc0R1bXB9YCxcbiAgICApO1xuICB9XG5cbiAgLy8gMi4g64yA7IOBREIg6rCB6rCB7JeQIOuMgO2VmOyXrCDsobTsnqzsl6zrtoAg7ZmV7J24IO2bhCDrtpPquLBcbiAgZm9yIChjb25zdCB7IGxhYmVsLCBjb25maWcsIHRvU2tpcCB9IG9mIHRhcmdldHMpIHtcbiAgICBjb25zdCBjb25uID0gY29uZmlnLmNvbm5lY3Rpb24gYXMgS25leC5Db25uZWN0aW9uQ29uZmlnO1xuXG4gICAgaWYgKHRvU2tpcCA9PT0gdHJ1ZSkge1xuICAgICAgY29uc29sZS5sb2coY2hhbGsucmVkKGAke2xhYmVsfTogU2tpcHBlZCFgKSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBkYiA9IGtuZXgoe1xuICAgICAgLi4uY29uZmlnLFxuICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICAuLi4oKGNvbmZpZy5jb25uZWN0aW9uID8/IHt9KSBhcyBLbmV4LkNvbm5lY3Rpb25Db25maWcpLFxuICAgICAgICBkYXRhYmFzZTogdW5kZWZpbmVkLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBjb25zdCBbW3Jvd11dID0gYXdhaXQgZGIucmF3KGBTSE9XIERBVEFCQVNFUyBMSUtFIFwiJHtjb25uLmRhdGFiYXNlfVwiYCk7XG4gICAgaWYgKHJvdykge1xuICAgICAgY29uc29sZS5sb2coY2hhbGsueWVsbG93KGAke2xhYmVsfTogRGF0YWJhc2UgXCIke2Nvbm4uZGF0YWJhc2V9XCIgQWxyZWFkeSBleGlzdHNgKSk7XG4gICAgICBhd2FpdCBkYi5kZXN0cm95KCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhgU1lOQyB0byAke2xhYmVsfS4uLmApO1xuICAgIGNvbnN0IG15c3FsQ21kID0gYG15c3FsIC1oJHtjb25uLmhvc3R9IC11JHtjb25uLnVzZXJ9IC1wJHtjb25uLnBhc3N3b3JkfWA7XG4gICAgZXhlY1N5bmMoYCR7bXlzcWxDbWR9IC1lICdEUk9QIERBVEFCQVNFIElGIEVYSVNUUyBcXGAke2Nvbm4uZGF0YWJhc2V9XFxgJ2ApO1xuICAgIGV4ZWNTeW5jKGAke215c3FsQ21kfSAtZSAnQ1JFQVRFIERBVEFCQVNFIFxcYCR7Y29ubi5kYXRhYmFzZX1cXGAnYCk7XG4gICAgZXhlY1N5bmMoYCR7bXlzcWxDbWR9ICR7Y29ubi5kYXRhYmFzZX0gPCAke2R1bXBGaWxlbmFtZX1gKTtcbiAgICBpZiAoYXdhaXQgZXhpc3RzKG1pZ3JhdGlvbnNEdW1wKSkge1xuICAgICAgZXhlY1N5bmMoYCR7bXlzcWxDbWR9ICR7Y29ubi5kYXRhYmFzZX0gPCAke21pZ3JhdGlvbnNEdW1wfWApO1xuICAgIH1cblxuICAgIGF3YWl0IGRiLmRlc3Ryb3koKTtcbiAgfVxuXG4gIGF3YWl0IF9kYi5kZXN0cm95KCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZpeHR1cmVfaW1wb3J0KGVudGl0eUlkOiBzdHJpbmcsIHJlY29yZElkczogbnVtYmVyW10pIHtcbiAgYXdhaXQgc2V0dXBGaXh0dXJlTWFuYWdlcigpO1xuXG4gIGF3YWl0IEZpeHR1cmVNYW5hZ2VyLmltcG9ydEZpeHR1cmUoZW50aXR5SWQsIHJlY29yZElkcyk7XG4gIGF3YWl0IEZpeHR1cmVNYW5hZ2VyLnN5bmMoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZml4dHVyZV9zeW5jKCkge1xuICBhd2FpdCBzZXR1cEZpeHR1cmVNYW5hZ2VyKCk7XG5cbiAgYXdhaXQgRml4dHVyZU1hbmFnZXIuc3luYygpO1xufVxuXG4vKipcbiAqIGZpeHR1cmUgZ2VuIOuqheugueyWtFxuICog7Ji17IWY7J2EIHByb2Nlc3MuYXJnduyXkOyEnCDtjIzsi7FcbiAqL1xuYXN5bmMgZnVuY3Rpb24gZml4dHVyZV9nZW4oKSB7XG4gIGNvbnN0IG9wdGlvbnMgPSBwYXJzZU9wdGlvbnMocHJvY2Vzcy5hcmd2KTtcbiAgYXdhaXQgZml4dHVyZUdlbkNvbW1hbmQob3B0aW9ucyk7XG59XG5cbi8qKlxuICogZml4dHVyZSBmZXRjaCDrqoXroLnslrRcbiAqIOyYteyFmOydhCBwcm9jZXNzLmFyZ3bsl5DshJwg7YyM7IuxXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZpeHR1cmVfZmV0Y2goKSB7XG4gIGNvbnN0IG9wdGlvbnMgPSBwYXJzZU9wdGlvbnMocHJvY2Vzcy5hcmd2KTtcbiAgYXdhaXQgZml4dHVyZUZldGNoQ29tbWFuZChvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBmaXh0dXJlIGV4cGxvcmUg66qF66C57Ja0XG4gKiDsmLXshZjsnYQgcHJvY2Vzcy5hcmd27JeQ7IScIO2MjOyLsVxuICovXG5hc3luYyBmdW5jdGlvbiBmaXh0dXJlX2V4cGxvcmUoKSB7XG4gIGNvbnN0IG9wdGlvbnMgPSBwYXJzZU9wdGlvbnMocHJvY2Vzcy5hcmd2KTtcbiAgYXdhaXQgZml4dHVyZUV4cGxvcmVDb21tYW5kKG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIOqwhOuLqO2VnCDsmLXshZgg7YyM7IScXG4gKi9cbmZ1bmN0aW9uIHBhcnNlT3B0aW9ucyhcbiAgYXJndjogc3RyaW5nW10sXG4pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBib29sZWFuIHwgc3RyaW5nW10+ICYgeyBfOiBzdHJpbmdbXSB9IHtcbiAgY29uc3Qgb3B0aW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgYm9vbGVhbiB8IHN0cmluZ1tdPiAmIHsgXzogc3RyaW5nW10gfSA9IHsgXzogW10gfTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGFyZ3YubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBhcmcgPSBhcmd2W2ldO1xuXG4gICAgaWYgKGFyZy5zdGFydHNXaXRoKFwiLS1cIikpIHtcbiAgICAgIGNvbnN0IGtleSA9IGFyZy5zbGljZSgyKTtcblxuICAgICAgaWYgKGtleS5pbmNsdWRlcyhcIj1cIikpIHtcbiAgICAgICAgY29uc3QgW2ssIHZdID0ga2V5LnNwbGl0KFwiPVwiKTtcbiAgICAgICAgb3B0aW9uc1trXSA9IHY7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBuZXh0ID0gYXJndltpICsgMV07XG4gICAgICAgIGlmIChuZXh0ICYmICFuZXh0LnN0YXJ0c1dpdGgoXCItLVwiKSkge1xuICAgICAgICAgIG9wdGlvbnNba2V5XSA9IG5leHQ7XG4gICAgICAgICAgaSsrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9wdGlvbnNba2V5XSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGFyZy5zdGFydHNXaXRoKFwiLVwiKSkge1xuICAgICAgY29uc3Qga2V5ID0gYXJnLnNsaWNlKDEpO1xuICAgICAgY29uc3QgbmV4dCA9IGFyZ3ZbaSArIDFdO1xuXG4gICAgICBpZiAobmV4dCAmJiAhbmV4dC5zdGFydHNXaXRoKFwiLVwiKSkge1xuICAgICAgICBvcHRpb25zW2tleV0gPSBuZXh0O1xuICAgICAgICBpKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcHRpb25zW2tleV0gPSB0cnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvcHRpb25zLl8ucHVzaChhcmcpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvcHRpb25zO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzdHViX3ByYWN0aWNlKG5hbWU6IHN0cmluZykge1xuICBjb25zdCBwcmFjdGljZURpciA9IHBhdGguam9pbihTb25hbXUuYXBpUm9vdFBhdGgsIFwic3JjXCIsIFwicHJhY3RpY2VzXCIpO1xuICBjb25zdCBmaWxlTmFtZXMgPSBhd2FpdCByZWFkZGlyKHByYWN0aWNlRGlyKTtcblxuICBjb25zdCBtYXhTZXFObyA9IGF3YWl0IChhc3luYyAoKSA9PiB7XG4gICAgaWYgKCEoYXdhaXQgZXhpc3RzKHByYWN0aWNlRGlyKSkpIHtcbiAgICAgIGF3YWl0IG1rZGlyKHByYWN0aWNlRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBmaWx0ZXJlZFNlcXMgPSBmaWxlTmFtZXNcbiAgICAgIC5maWx0ZXIoKGZpbGVOYW1lKSA9PiBmaWxlTmFtZS5zdGFydHNXaXRoKFwicFwiKSAmJiBmaWxlTmFtZS5lbmRzV2l0aChcIi50c1wiKSlcbiAgICAgIC5tYXAoKGZpbGVOYW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IFssIHNlcU5vXSA9IGZpbGVOYW1lLm1hdGNoKC9ecChbMC05XSspLS8pID8/IFtcIjBcIiwgXCIwXCJdO1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQoc2VxTm8pO1xuICAgICAgfSlcbiAgICAgIC50b1NvcnRlZCgoYSwgYikgPT4gYiAtIGEpO1xuXG4gICAgaWYgKGZpbHRlcmVkU2Vxcy5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gZmlsdGVyZWRTZXFzWzBdO1xuICAgIH1cblxuICAgIHJldHVybiAwO1xuICB9KSgpO1xuXG4gIGNvbnN0IGN1cnJlbnRTZXFObyA9IG1heFNlcU5vICsgMTtcbiAgY29uc3QgZmlsZU5hbWUgPSBgcCR7Y3VycmVudFNlcU5vfS0ke25hbWV9LnRzYDtcbiAgY29uc3QgZHN0UGF0aCA9IHBhdGguam9pbihwcmFjdGljZURpciwgZmlsZU5hbWUpO1xuXG4gIGNvbnN0IGNvZGUgPSBbXG4gICAgYGltcG9ydCB7IFNvbmFtdSB9IGZyb20gXCJzb25hbXVcIjtgLFxuICAgIFwiXCIsXG4gICAgYGNvbnNvbGUuY2xlYXIoKTtgLFxuICAgIGBjb25zb2xlLmxvZyhcIiR7ZmlsZU5hbWV9XCIpO2AsXG4gICAgXCJcIixcbiAgICBgU29uYW11LnJ1blNjcmlwdChhc3luYyAoKSA9PiB7YCxcbiAgICBgIC8vIFRPRE9gLFxuICAgIGB9KTtgLFxuICAgIFwiXCIsXG4gIF0uam9pbihcIlxcblwiKTtcbiAgYXdhaXQgd3JpdGVGaWxlKGRzdFBhdGgsIGNvZGUpO1xuXG4gIGV4ZWNTeW5jKGBjb2RlICR7ZHN0UGF0aH1gKTtcblxuICBjb25zdCBydW5Db2RlID0gYHlhcm4gbm9kZSAtciBkb3RlbnYvY29uZmlnIC0tZW5hYmxlLXNvdXJjZS1tYXBzIGRpc3QvcHJhY3RpY2VzLyR7ZmlsZU5hbWUucmVwbGFjZShcbiAgICBcIi50c1wiLFxuICAgIFwiLmpzXCIsXG4gICl9YDtcbiAgY29uc29sZS5sb2coYCR7Y2hhbGsuYmx1ZShydW5Db2RlKX0gY29waWVkIHRvIGNsaXBib2FyZC5gKTtcbiAgZXhlY1N5bmMoYGVjaG8gXCIke3J1bkNvZGV9XCIgfCBwYmNvcHlgKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc3R1Yl9lbnRpdHkoZW50aXR5SWQ6IHN0cmluZykge1xuICBhd2FpdCBTb25hbXUuc3luY2VyLmNyZWF0ZUVudGl0eSh7IGVudGl0eUlkLCB0aXRsZTogZW50aXR5SWQgfSk7XG5cbiAgY29uc3QgeyBmbGFncyB9ID0gcGFyc2VDbGlPcHRpb25zKCk7XG4gIGNvbnN0IHVzZUFJID0gZmxhZ3MuaGFzKFwiYWlcIik7XG4gIGNvbnN0IG5vQ29uZXMgPSBmbGFncy5oYXMoXCJuby1jb25lc1wiKTtcblxuICAvLyAtLW5vLWNvbmVzOiBjb25lIOyDneyEsSDsiqTtgrVcbiAgaWYgKG5vQ29uZXMpIHtcbiAgICBjb25zb2xlLmxvZyhg4pyTIEVudGl0eSAnJHtlbnRpdHlJZH0nIGNyZWF0ZWQgd2l0aG91dCBjb25lc2ApO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHsgRW50aXR5TWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCIpO1xuICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gIGlmICghZW50aXR5KSB7XG4gICAgY29uc29sZS5lcnJvcihgRW50aXR5IG5vdCBmb3VuZDogJHtlbnRpdHlJZH1gKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyAtLWFpOiBMTE3snLzroZwgY29uZSDsg53shLFcbiAgaWYgKHVzZUFJKSB7XG4gICAgY29uc29sZS5sb2coYOKckyBFbnRpdHkgJyR7ZW50aXR5SWR9JyBjcmVhdGVkYCk7XG4gICAgY29uc29sZS5sb2coYPCfjJ8gR2VuZXJhdGluZyBBSS1wb3dlcmVkIGNvbmVzLi4uYCk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbmZpZ0xvY2FsZSA9IFNvbmFtdS5jb25maWcuaTE4bj8uZGVmYXVsdExvY2FsZTtcbiAgICAgIGNvbnN0IGxvY2FsZSA9XG4gICAgICAgIGNvbmZpZ0xvY2FsZSA9PT0gXCJrb1wiIHx8IGNvbmZpZ0xvY2FsZSA9PT0gXCJlblwiIHx8IGNvbmZpZ0xvY2FsZSA9PT0gXCJqYVwiXG4gICAgICAgICAgPyBjb25maWdMb2NhbGVcbiAgICAgICAgICA6IFwia29cIjtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZW50aXR5LmdlbmVyYXRlQ29uZXMoe1xuICAgICAgICBwcmVzZXJ2ZUV4aXN0aW5nOiBmYWxzZSxcbiAgICAgICAgb25seUVtcHR5OiBmYWxzZSxcbiAgICAgICAgbG9jYWxlLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnNvbGUubG9nKGDinIUgRG9uZSAoJHtyZXN1bHQudG9rZW5zVXNlZH0gdG9rZW5zKWApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKFwiQU5USFJPUElDX0FQSV9LRVlcIikpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgXFxu4p2MICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICAgICAgY29uc29sZS5lcnJvcihgXFxu8J+SoSBSZW1vdmUgLS1haSBmbGFnIHRvIHVzZSB0ZW1wbGF0ZSBjb25lcyBpbnN0ZWFkYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8g6riw67O4OiDthZztlIzrpr8gY29uZSDsnpDrj5kg7IOd7ISxXG4gIC8vIExMTSDsl4bsnbQgZmFrZXItbWFwcGluZ3MudHPrpbwg7Zmc7Jqp7ZWY7JesIOq4sOuzuCBjb25lIOuplO2DgOuNsOydtO2EsOulvCDsg53shLHtlanri4jri6QuXG4gIC8vIOydtOulvCDthrXtlbQgQU5USFJPUElDX0FQSV9LRVnqsIAg7JeG7Ja064+EIFNvbmFtdeulvCDsgqzsmqntlaAg7IiYIOyeiOycvOupsCxcbiAgLy8g7IOd7ISx65CcIO2FnO2UjOumvyBjb25l7J2AIOuCmOykkeyXkCAnY29uZSBnZW4nIOuqheugueyWtOuhnCBBSeulvCDthrXtlbQg7JeF6re466CI7J2065Oc7ZWgIOyImCDsnojsirXri4jri6QuXG4gIGNvbnNvbGUubG9nKGDwn4yfIEdlbmVyYXRpbmcgdGVtcGxhdGUgY29uZXMuLi5gKTtcbiAgYXdhaXQgZW50aXR5LmdlbmVyYXRlVGVtcGxhdGVDb25lcygpO1xuICBjb25zb2xlLmxvZyhg4pyTIEVudGl0eSAnJHtlbnRpdHlJZH0nIGNyZWF0ZWQgd2l0aCB0ZW1wbGF0ZSBjb25lc2ApO1xuICBjb25zb2xlLmxvZyhg8J+SoSBUaXA6IFJ1biAncG5wbSBzb25hbXUgY29uZSBnZW4gJHtlbnRpdHlJZH0nIHRvIGltcHJvdmUgd2l0aCBBSWApO1xufVxuXG4vKipcbiAqIEFJ66W8IOyCrOyaqe2VmOyXrCBlbnRpdHnsnZggY29uZSDrqZTtg4DrjbDsnbTthLDrpbwg7IOd7ISx7ZWY6rGw64KYIOyXheq3uOugiOydtOuTnO2VqeuLiOuLpC5cbiAqXG4gKiDsmLXshZg6XG4gKiAtIC0tcmVnZW5lcmF0ZTog7KCE7LK0IOyerOyDneyEsSAo6riw7KG0IGNvbmUg642u7Ja07JOw6riwKVxuICogLSAtLWxvY2FsZSA8a298ZW58amE+OiDsg53shLEg7Ja47Ja0IOyngOyglVxuICogLSDquLDrs7g6IG9ubHlFbXB0eSDrqqjrk5wgKOq4sOyhtCBmaXh0dXJlSGludCDrs7TsobQpXG4gKlxuICogQU5USFJPUElDX0FQSV9LRVkg7ZWE7JqUIChzb25hbXUuc2VjcmV0LnRzIOuYkOuKlCDtmZjqsr3rs4DsiJgpXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNvbmVfZ2VuKGVudGl0eUlkOiBzdHJpbmcpIHtcbiAgY29uc3QgeyBFbnRpdHlNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIik7XG4gIGNvbnN0IHsgZmxhZ3MsIG9wdGlvbnMgfSA9IHBhcnNlQ2xpT3B0aW9ucygpO1xuXG4gIC8vIC0tYWxsIOyYteyFmDog66qo65OgIGVudGl0eSBjb25lIOyDneyEsVxuICBpZiAoZmxhZ3MuaGFzKFwiYWxsXCIpIHx8IGVudGl0eUlkID09PSBcImFsbFwiKSB7XG4gICAgY29uc3QgYWxsRW50aXRpZXMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbEVudGl0aWVzKCk7XG4gICAgY29uc29sZS5sb2coYPCfjJ8gR2VuZXJhdGluZyBBSS1wb3dlcmVkIGNvbmVzIGZvciAke2FsbEVudGl0aWVzLmxlbmd0aH0gZW50aXRpZXMuLi5cXG5gKTtcblxuICAgIGxldCB0b3RhbFRva2VucyA9IDA7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBlbnRpdHkgb2YgYWxsRW50aXRpZXMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBQcm9jZXNzaW5nICR7ZW50aXR5LmlkfS4uLmApO1xuICAgICAgICBjb25zdCBjb25maWdMb2NhbGUgPSBvcHRpb25zLmxvY2FsZSB8fCBTb25hbXUuY29uZmlnLmkxOG4/LmRlZmF1bHRMb2NhbGU7XG4gICAgICAgIGNvbnN0IGxvY2FsZSA9XG4gICAgICAgICAgY29uZmlnTG9jYWxlID09PSBcImtvXCIgfHwgY29uZmlnTG9jYWxlID09PSBcImVuXCIgfHwgY29uZmlnTG9jYWxlID09PSBcImphXCJcbiAgICAgICAgICAgID8gY29uZmlnTG9jYWxlXG4gICAgICAgICAgICA6IFwia29cIjtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlbnRpdHkuZ2VuZXJhdGVDb25lcyh7XG4gICAgICAgICAgcHJlc2VydmVFeGlzdGluZzogIWZsYWdzLmhhcyhcInJlZ2VuZXJhdGVcIiksXG4gICAgICAgICAgb25seUVtcHR5OiAhZmxhZ3MuaGFzKFwicmVnZW5lcmF0ZVwiKSxcbiAgICAgICAgICBsb2NhbGUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRvdGFsVG9rZW5zICs9IHJlc3VsdC50b2tlbnNVc2VkO1xuICAgICAgICBjb25zb2xlLmxvZyhgICDinJMgJHtlbnRpdHkuaWR9ICgke3Jlc3VsdC50b2tlbnNVc2VkfSB0b2tlbnMpXFxuYCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBcIlVua25vd24gZXJyb3JcIjtcbiAgICAgICAgZXJyb3JzLnB1c2goYCR7ZW50aXR5LmlkfTogJHttZXNzYWdlfWApO1xuICAgICAgICBjb25zb2xlLmVycm9yKGAgIOKclyAke2VudGl0eS5pZH06ICR7bWVzc2FnZX1cXG5gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhgXFxu4pyFIERvbmUhIFRvdGFsOiAke3RvdGFsVG9rZW5zfSB0b2tlbnMgdXNlZGApO1xuICAgIGNvbnN0IGVzdGltYXRlZENvc3QgPSAodG90YWxUb2tlbnMgKiA5KSAvIDFfMDAwXzAwMDtcbiAgICBjb25zb2xlLmxvZyhg8J+SsCBFc3RpbWF0ZWQgY29zdDogfiQke2VzdGltYXRlZENvc3QudG9GaXhlZCg0KX1gKTtcblxuICAgIGlmIChlcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc29sZS5lcnJvcihgXFxu4p2MIEZhaWxlZCBlbnRpdGllcyAoJHtlcnJvcnMubGVuZ3RofSk6YCk7XG4gICAgICBmb3IgKGNvbnN0IGVyciBvZiBlcnJvcnMpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgICAtICR7ZXJyfWApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICAvLyDri6jsnbwgZW50aXR5IGNvbmUg7IOd7ISxXG4gIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgaWYgKCFlbnRpdHkpIHtcbiAgICBjb25zb2xlLmVycm9yKGBFbnRpdHkgbm90IGZvdW5kOiAke2VudGl0eUlkfWApO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IG1vZGUgPSBmbGFncy5oYXMoXCJyZWdlbmVyYXRlXCIpID8gXCJyZWdlbmVyYXRpbmdcIiA6IFwiZ2VuZXJhdGluZ1wiO1xuICBjb25zb2xlLmxvZyhcbiAgICBg8J+MnyAke21vZGUgPT09IFwicmVnZW5lcmF0aW5nXCIgPyBcIlJlZ2VuZXJhdGluZ1wiIDogXCJHZW5lcmF0aW5nXCJ9IEFJLXBvd2VyZWQgY29uZXMgZm9yICR7ZW50aXR5SWR9Li4uYCxcbiAgKTtcblxuICB0cnkge1xuICAgIGNvbnN0IGNvbmZpZ0xvY2FsZSA9IG9wdGlvbnMubG9jYWxlIHx8IFNvbmFtdS5jb25maWcuaTE4bj8uZGVmYXVsdExvY2FsZTtcbiAgICBjb25zdCBsb2NhbGUgPVxuICAgICAgY29uZmlnTG9jYWxlID09PSBcImtvXCIgfHwgY29uZmlnTG9jYWxlID09PSBcImVuXCIgfHwgY29uZmlnTG9jYWxlID09PSBcImphXCIgPyBjb25maWdMb2NhbGUgOiBcImtvXCI7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlbnRpdHkuZ2VuZXJhdGVDb25lcyh7XG4gICAgICBwcmVzZXJ2ZUV4aXN0aW5nOiAhZmxhZ3MuaGFzKFwicmVnZW5lcmF0ZVwiKSxcbiAgICAgIG9ubHlFbXB0eTogIWZsYWdzLmhhcyhcInJlZ2VuZXJhdGVcIiksXG4gICAgICBsb2NhbGUsXG4gICAgfSk7XG5cbiAgICBjb25zb2xlLmxvZyhg4pyFIERvbmUhICgke3Jlc3VsdC50b2tlbnNVc2VkfSB0b2tlbnMgdXNlZClgKTtcblxuICAgIC8vIO2GoO2BsCDruYTsmqkg6rOE7IKwICjrjIDrnrXsoIHsnbgg7LaU7KCVKVxuICAgIC8vIENsYXVkZSBTb25uZXQgNC41OiBpbnB1dCAkMy9NIHRva2Vucywgb3V0cHV0ICQxNS9NIHRva2Vuc1xuICAgIC8vIOqwhOuLqO2VmOqyjCDtj4nqt6AgJDkvTSB0b2tlbnProZwg6rOE7IKwXG4gICAgY29uc3QgZXN0aW1hdGVkQ29zdCA9IChyZXN1bHQudG9rZW5zVXNlZCAqIDkpIC8gMV8wMDBfMDAwO1xuICAgIGNvbnNvbGUubG9nKGDwn5KwIEVzdGltYXRlZCBjb3N0OiB+JCR7ZXN0aW1hdGVkQ29zdC50b0ZpeGVkKDQpfWApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IubWVzc2FnZS5pbmNsdWRlcyhcIkFOVEhST1BJQ19BUElfS0VZXCIpKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFxcbuKdjCAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFxcbvCfkqEgVG8gdXNlIEFJLXBvd2VyZWQgY29uZSBnZW5lcmF0aW9uOmApO1xuICAgICAgICBjb25zb2xlLmVycm9yKGAgICAxLiBHZXQgYW4gQVBJIGtleSBmcm9tIGh0dHBzOi8vY29uc29sZS5hbnRocm9waWMuY29tL2ApO1xuICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgIGAgICAyLiBBZGQgaXQgdG8gc29uYW11LnNlY3JldC50cyBvciBzZXQgQU5USFJPUElDX0FQSV9LRVkgZW52aXJvbm1lbnQgdmFyaWFibGVgLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChlcnJvci5tZXNzYWdlLmluY2x1ZGVzKFwiUmF0ZSBsaW1pdFwiKSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBcXG7inYwgJHtlcnJvci5tZXNzYWdlfWApO1xuICAgICAgICBjb25zb2xlLmVycm9yKGBcXG7wn5KhIFBsZWFzZSB3YWl0IGEgbW9tZW50IGFuZCB0cnkgYWdhaW4uYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBcXG7inYwgRmFpbGVkIHRvIGdlbmVyYXRlIGNvbmVzOiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFxcbuKdjCBGYWlsZWQgdG8gZ2VuZXJhdGUgY29uZXM6IFVua25vd24gZXJyb3JgKTtcbiAgICB9XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gc2NhZmZvbGRfbW9kZWwoZW50aXR5SWQ6IHN0cmluZykge1xuICBhd2FpdCBTb25hbXUuc3luY2VyLmdlbmVyYXRlVGVtcGxhdGUoXCJtb2RlbFwiLCB7XG4gICAgZW50aXR5SWQsXG4gIH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzY2FmZm9sZF9tb2RlbF90ZXN0KGVudGl0eUlkOiBzdHJpbmcpIHtcbiAgYXdhaXQgU29uYW11LnN5bmNlci5nZW5lcmF0ZVRlbXBsYXRlKFwibW9kZWxfdGVzdFwiLCB7XG4gICAgZW50aXR5SWQsXG4gIH0pO1xufVxuXG4vKipcbiAqIHBucG0gc29uYW11IHNraWxscyBzeW5jIO2VmOuptCDsi6TtlonrkJjripQg7ZWo7IiY7J6F64uI64ukLlxuICog6rO17IudIFNraWxsc+ulvCDroZzsu6wg7ZSE66Gc7KCd7Yq4IOuYkOuKlCDquIDroZzrsowgfi8uY2xhdWRlL+uhnCDrj5nquLDtmZTtlanri4jri6QuXG4gKlxuICogLS1nbG9iYWwg7ZSM656Y6re4OiB+Ly5jbGF1ZGUv7JeQIOuPmeq4sO2ZlCAo7ZSE66Gc7KCd7Yq4IOyDneyEsSDsoIQg7IKs7JqpIOqwgOuKpSlcbiAqL1xuYXN5bmMgZnVuY3Rpb24gc2tpbGxzX3N5bmMoKSB7XG4gIGNvbnN0IHsgZmxhZ3MgfSA9IHBhcnNlQ2xpT3B0aW9ucygpO1xuICBjb25zdCBpc0dsb2JhbCA9IGZsYWdzLmhhcyhcImdsb2JhbFwiKTtcblxuICAvLyDqsJzrsJwg7ZmY6rK9IC0gY2xpLnRzOiBzb25hbXUvbW9kdWxlcy9zb25hbXUvc3JjL2Jpbi9jbGkudHNcbiAgLy8g67mM65OcIO2bhCAtIGNsaS5qczogbm9kZV9tb2R1bGVzL3NvbmFtdS9kaXN0L2Jpbi9jbGkuanMgKOyLpOygnCDsi6TtlokpXG4gIC8vIHNraWxscyDsnITsuZg6IG5vZGVfbW9kdWxlcy9zb25hbXUvc3JjL3NraWxscyAobnBtIOuwsO2PrCDsi5wpXG4gIGNvbnN0IHNvdXJjZUJhc2UgPSBwYXRoLnJlc29sdmUoaW1wb3J0Lm1ldGEuZGlybmFtZSwgXCIuLlwiLCBcIi4uXCIsIFwic3JjXCIsIFwic2tpbGxzXCIpO1xuICBjb25zdCBzb3VyY2VTa2lsbHNEaXIgPSBwYXRoLmpvaW4oc291cmNlQmFzZSwgXCJzb25hbXVcIik7XG4gIGNvbnN0IHNvdXJjZUNsYXVkZU1kID0gcGF0aC5qb2luKHNvdXJjZUJhc2UsIFwiQ0xBVURFLm1kXCIpO1xuXG4gIGlmICghKGF3YWl0IGV4aXN0cyhzb3VyY2VTa2lsbHNEaXIpKSkge1xuICAgIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdyhcIlNraWxscyBzb3VyY2Ugbm90IGZvdW5kIGluIHNvbmFtdSBwYWNrYWdlLlwiKSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGlzR2xvYmFsKSB7XG4gICAgY29uc3QgaG9tZUNsYXVkZURpciA9IHBhdGguam9pbihvcy5ob21lZGlyKCksIFwiLmNsYXVkZVwiKTtcbiAgICBhd2FpdCBza2lsbHNfc3luY190byhob21lQ2xhdWRlRGlyLCBzb3VyY2VTa2lsbHNEaXIsIHNvdXJjZUNsYXVkZU1kLCB7XG4gICAgICB1c2VTeW1saW5rOiBmYWxzZSxcbiAgICAgIGNvcHlQcm9qZWN0VGVtcGxhdGVzOiBmYWxzZSxcbiAgICAgIGlzR2xvYmFsOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgLy8gfi8uY2xhdWRlL2NvbW1hbmRzL3NvbmFtdS1za2lsbHMubWQg7ISk7LmYXG4gICAgY29uc3Qgc291cmNlQ29tbWFuZHNEaXIgPSBwYXRoLmpvaW4oc291cmNlQmFzZSwgXCJjb21tYW5kc1wiKTtcbiAgICBjb25zdCBzb3VyY2VDb21tYW5kID0gcGF0aC5qb2luKHNvdXJjZUNvbW1hbmRzRGlyLCBcInNvbmFtdS1za2lsbHMubWRcIik7XG4gICAgaWYgKGF3YWl0IGV4aXN0cyhzb3VyY2VDb21tYW5kKSkge1xuICAgICAgY29uc3QgdGFyZ2V0Q29tbWFuZHNEaXIgPSBwYXRoLmpvaW4oaG9tZUNsYXVkZURpciwgXCJjb21tYW5kc1wiKTtcbiAgICAgIGF3YWl0IG1rZGlyKHRhcmdldENvbW1hbmRzRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIGF3YWl0IGNwKHNvdXJjZUNvbW1hbmQsIHBhdGguam9pbih0YXJnZXRDb21tYW5kc0RpciwgXCJzb25hbXUtc2tpbGxzLm1kXCIpKTtcbiAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmdyZWVuKGDinJMgL3NvbmFtdS1za2lsbHMgY29tbWFuZCBpbnN0YWxsZWQg4oaSIH4vLmNsYXVkZS9jb21tYW5kcy9gKSk7XG4gICAgfVxuXG4gICAgY29uc29sZS5sb2coY2hhbGsuY3lhbihgXFxuICBHbG9iYWwgc3luYyBjb21wbGV0ZSDihpIgfi8uY2xhdWRlL3NraWxscy9zb25hbXUvYCkpO1xuICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShgICBUaGVzZSBza2lsbHMgYXJlIGF2YWlsYWJsZSBpbiBhbGwgQ2xhdWRlIENvZGUgc2Vzc2lvbnMuYCkpO1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgY2hhbGsuZGltKFxuICAgICAgICBgICBPbmNlIGEgcHJvamVjdCBpcyBjcmVhdGVkLCBydW4gJ3BucG0gc29uYW11IHNraWxscyBzeW5jJyBmb3IgcHJvamVjdC1sb2NhbCBzeW5jLmAsXG4gICAgICApLFxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgd29ya3NwYWNlUm9vdCA9IGF3YWl0IGZpbmRXb3Jrc3BhY2VSb290KCk7XG4gICAgY29uc3QgY2xhdWRlRGlyID0gcGF0aC5qb2luKHdvcmtzcGFjZVJvb3QsIFwiLmNsYXVkZVwiKTtcbiAgICBhd2FpdCBza2lsbHNfc3luY190byhjbGF1ZGVEaXIsIHNvdXJjZVNraWxsc0Rpciwgc291cmNlQ2xhdWRlTWQsIHtcbiAgICAgIHVzZVN5bWxpbms6IHRydWUsXG4gICAgICBjb3B5UHJvamVjdFRlbXBsYXRlczogdHJ1ZSxcbiAgICAgIHNvdXJjZUJhc2UsXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBjbGF1ZGVEaXLroZwgc2tpbGxz66W8IOuPmeq4sO2ZlO2VmOuKlCDqs7XthrUg66Gc7KeB7J6F64uI64ukLlxuICovXG5hc3luYyBmdW5jdGlvbiBza2lsbHNfc3luY190byhcbiAgY2xhdWRlRGlyOiBzdHJpbmcsXG4gIHNvdXJjZVNraWxsc0Rpcjogc3RyaW5nLFxuICBzb3VyY2VDbGF1ZGVNZDogc3RyaW5nLFxuICBvcHRpb25zOiB7XG4gICAgdXNlU3ltbGluazogYm9vbGVhbjtcbiAgICBjb3B5UHJvamVjdFRlbXBsYXRlczogYm9vbGVhbjtcbiAgICBzb3VyY2VCYXNlPzogc3RyaW5nO1xuICAgIGlzR2xvYmFsPzogYm9vbGVhbjtcbiAgfSxcbikge1xuICBjb25zdCB0YXJnZXRTa2lsbHNEaXIgPSBwYXRoLmpvaW4oY2xhdWRlRGlyLCBcInNraWxsc1wiLCBcInNvbmFtdVwiKTtcblxuICAvLyDquLDsobQg65SU66CJ7Yag66asL3N5bWxpbmsg7IKt7KCcIO2bhCDsnqzsg53shLFcbiAgLy8gZXhpc3RzKCnripQgYnJva2VuIHN5bWxpbmvrpbwg6rCQ7KeA7ZWY7KeAIOuqu+2VmOuvgOuhnCBybeydhCDrrLTsobDqsbQg7Iuc64+E7ZWp64uI64ukXG4gIHRyeSB7XG4gICAgYXdhaXQgcm0odGFyZ2V0U2tpbGxzRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSk7XG4gIH0gY2F0Y2gge1xuICAgIC8vIO2MjOydvOydtCDsl4bsnLzrqbQg66y07IucXG4gIH1cblxuICBhd2FpdCBta2RpcihwYXRoLmRpcm5hbWUodGFyZ2V0U2tpbGxzRGlyKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgaWYgKG9wdGlvbnMudXNlU3ltbGluaykge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBzeW1saW5rKHNvdXJjZVNraWxsc0RpciwgdGFyZ2V0U2tpbGxzRGlyLCBcImRpclwiKTtcbiAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmdyZWVuKGDinJMgU2tpbGxzIGxpbmtlZCAoc3ltbGluaylgKSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBjaGFsay55ZWxsb3coYOKaoCBTeW1saW5rIGZhaWxlZDogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCksXG4gICAgICApO1xuICAgICAgY29uc29sZS5sb2coY2hhbGsueWVsbG93KGAgIEZhbGxpbmcgYmFjayB0byBjb3B5Li4uYCkpO1xuICAgICAgYXdhaXQgc2tpbGxzQ29weShzb3VyY2VTa2lsbHNEaXIsIHRhcmdldFNraWxsc0Rpcik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGF3YWl0IHNraWxsc0NvcHkoc291cmNlU2tpbGxzRGlyLCB0YXJnZXRTa2lsbHNEaXIpO1xuICB9XG5cbiAgLy8gcHJvamVjdCDrlJTroInthqDrpqwg7LSI6riw7ZmUICjsl4bsnLzrqbQg7IOd7ISxLCDsnojsnLzrqbQg7Jyg7KeAKVxuICBpZiAob3B0aW9ucy5jb3B5UHJvamVjdFRlbXBsYXRlcyAmJiBvcHRpb25zLnNvdXJjZUJhc2UpIHtcbiAgICBjb25zdCBzb3VyY2VQcm9qZWN0RGlyID0gcGF0aC5qb2luKG9wdGlvbnMuc291cmNlQmFzZSwgXCJwcm9qZWN0XCIpO1xuICAgIGNvbnN0IHRhcmdldFByb2plY3REaXIgPSBwYXRoLmpvaW4oY2xhdWRlRGlyLCBcInNraWxsc1wiLCBcInByb2plY3RcIik7XG5cbiAgICBpZiAoYXdhaXQgZXhpc3RzKHNvdXJjZVByb2plY3REaXIpKSB7XG4gICAgICBpZiAoIShhd2FpdCBleGlzdHModGFyZ2V0UHJvamVjdERpcikpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgY3Aoc291cmNlUHJvamVjdERpciwgdGFyZ2V0UHJvamVjdERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYOKckyBQcm9qZWN0IHRlbXBsYXRlcyBpbml0aWFsaXplZGApKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgY2hhbGsucmVkKFxuICAgICAgICAgICAgICBg4pyXIEZhaWxlZCB0byBpbml0aWFsaXplIHByb2plY3QgdGVtcGxhdGVzOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmxvZyhjaGFsay5kaW0oYOKPrSBQcm9qZWN0IHRlbXBsYXRlcyBhbHJlYWR5IGV4aXN0IChwcmVzZXJ2ZWQpYCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIHNldHRpbmdzLmxvY2FsLmpzb24g4oCUIHByb2plY3QtbG9jYWwg66qo65Oc7JeQ7ISc66eMLCDsl4bsnYQg65WM66eMIOyDneyEsVxuICBpZiAob3B0aW9ucy5jb3B5UHJvamVjdFRlbXBsYXRlcykge1xuICAgIGNvbnN0IHNldHRpbmdzTG9jYWxQYXRoID0gcGF0aC5qb2luKGNsYXVkZURpciwgXCJzZXR0aW5ncy5sb2NhbC5qc29uXCIpO1xuICAgIGlmICghKGF3YWl0IGV4aXN0cyhzZXR0aW5nc0xvY2FsUGF0aCkpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBzZXR0aW5nc0NvbnRlbnQgPSB7XG4gICAgICAgICAgaG9va3M6IHtcbiAgICAgICAgICAgIFBvc3RUb29sVXNlOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBtYXRjaGVyOiBcIkVkaXR8V3JpdGV8TXVsdGlFZGl0XCIsXG4gICAgICAgICAgICAgICAgaG9va3M6IFtcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJjb21tYW5kXCIsXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hbmQ6IFwicG5wbSBjaGVjayAyPiYxIHwgaGVhZCAtNjBcIixcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgd3JpdGVGaWxlKHNldHRpbmdzTG9jYWxQYXRoLCBgJHtKU09OLnN0cmluZ2lmeShzZXR0aW5nc0NvbnRlbnQsIG51bGwsIDIpfVxcbmApO1xuICAgICAgICBjb25zb2xlLmxvZyhjaGFsay5ncmVlbihg4pyTIC5jbGF1ZGUvc2V0dGluZ3MubG9jYWwuanNvbiBjcmVhdGVkYCkpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICBjaGFsay5yZWQoXG4gICAgICAgICAgICBg4pyXIEZhaWxlZCB0byBjcmVhdGUgc2V0dGluZ3MubG9jYWwuanNvbjogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmxvZyhjaGFsay5kaW0oYOKPrSAuY2xhdWRlL3NldHRpbmdzLmxvY2FsLmpzb24gYWxyZWFkeSBleGlzdHMgKHByZXNlcnZlZClgKSk7XG4gICAgfVxuICB9XG5cbiAgLy8gQ0xBVURFLm1kIOuzteyCrC/sl4XrjbDsnbTtirhcbiAgaWYgKGF3YWl0IGV4aXN0cyhzb3VyY2VDbGF1ZGVNZCkpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdGFyZ2V0Q2xhdWRlTWQgPSBwYXRoLmpvaW4oY2xhdWRlRGlyLCBcIkNMQVVERS5tZFwiKTtcbiAgICAgIGNvbnN0IHJhd0NvbnRlbnQgPSBhd2FpdCByZWFkRmlsZShzb3VyY2VDbGF1ZGVNZCwgXCJ1dGYtOFwiKTtcbiAgICAgIC8vIOq4gOuhnOuyjCDrqqjrk5zsl5DshJzripQg7IOB64yAIOqyveuhnOulvCDsoIjrjIAg6rK966Gc66GcIOuzgO2ZmO2VqeuLiOuLpFxuICAgICAgY29uc3Qgc291cmNlQ29udGVudCA9IG9wdGlvbnMuaXNHbG9iYWxcbiAgICAgICAgPyByYXdDb250ZW50LnJlcGxhY2VBbGwoXCIuY2xhdWRlL3NraWxscy9zb25hbXUvXCIsIFwifi8uY2xhdWRlL3NraWxscy9zb25hbXUvXCIpXG4gICAgICAgIDogcmF3Q29udGVudDtcblxuICAgICAgaWYgKGF3YWl0IGV4aXN0cyh0YXJnZXRDbGF1ZGVNZCkpIHtcbiAgICAgICAgY29uc3QgdGFyZ2V0Q29udGVudCA9IGF3YWl0IHJlYWRGaWxlKHRhcmdldENsYXVkZU1kLCBcInV0Zi04XCIpO1xuICAgICAgICBjb25zdCBzdGFydE1hcmtlciA9IFwiPCEtLSBTT05BTVU6U1RBUlQgLS0+XCI7XG4gICAgICAgIGNvbnN0IGVuZE1hcmtlciA9IFwiPCEtLSBTT05BTVU6RU5EIC0tPlwiO1xuICAgICAgICBpZiAodGFyZ2V0Q29udGVudC5pbmNsdWRlcyhzdGFydE1hcmtlcikgJiYgdGFyZ2V0Q29udGVudC5pbmNsdWRlcyhlbmRNYXJrZXIpKSB7XG4gICAgICAgICAgY29uc3Qgc3RhcnRJZHggPSB0YXJnZXRDb250ZW50LmluZGV4T2Yoc3RhcnRNYXJrZXIpO1xuICAgICAgICAgIGNvbnN0IGVuZElkeCA9IHRhcmdldENvbnRlbnQuaW5kZXhPZihlbmRNYXJrZXIpO1xuXG4gICAgICAgICAgaWYgKHN0YXJ0SWR4ICE9PSAtMSAmJiBlbmRJZHggIT09IC0xICYmIHN0YXJ0SWR4IDwgZW5kSWR4KSB7XG4gICAgICAgICAgICBjb25zdCBiZWZvcmUgPSB0YXJnZXRDb250ZW50LnN1YnN0cmluZygwLCBzdGFydElkeCk7XG4gICAgICAgICAgICBjb25zdCBhZnRlciA9IHRhcmdldENvbnRlbnQuc3Vic3RyaW5nKGVuZElkeCArIGVuZE1hcmtlci5sZW5ndGgpO1xuICAgICAgICAgICAgY29uc3QgbmV3Q29udGVudCA9IGAke2JlZm9yZX0ke3N0YXJ0TWFya2VyfVxcbiR7c291cmNlQ29udGVudH1cXG4ke2VuZE1hcmtlcn0ke2FmdGVyfWA7XG4gICAgICAgICAgICBhd2FpdCB3cml0ZUZpbGUodGFyZ2V0Q2xhdWRlTWQsIG5ld0NvbnRlbnQpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYOKckyBDTEFVREUubWQgdXBkYXRlZCAobWFya2VyIHJlZ2lvbilgKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdyhg4o+tIENMQVVERS5tZCBtYXJrZXIgcG9zaXRpb25zIGludmFsaWQsIHNraXBwZWRgKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIOuniOy7pOqwgCDsl4bripQg6riw7KG0IENMQVVERS5tZOyXkCBTb25hbXUg7IS57IWY7J2EIOy2lOqwgO2VqeuLiOuLpFxuICAgICAgICAgIGNvbnN0IGFwcGVuZGVkID0gYCR7dGFyZ2V0Q29udGVudC50cmltRW5kKCl9XFxuXFxuPCEtLSBTT05BTVU6U1RBUlQgLS0+XFxuJHtzb3VyY2VDb250ZW50fVxcbjwhLS0gU09OQU1VOkVORCAtLT5cXG5gO1xuICAgICAgICAgIGF3YWl0IHdyaXRlRmlsZSh0YXJnZXRDbGF1ZGVNZCwgYXBwZW5kZWQpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmdyZWVuKGDinJMgQ0xBVURFLm1kIHVwZGF0ZWQgKGFwcGVuZGVkIFNvbmFtdSBzZWN0aW9uKWApKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgd2l0aE1hcmtlcnMgPSBgPCEtLSBTT05BTVU6U1RBUlQgLS0+XFxuJHtzb3VyY2VDb250ZW50fVxcbjwhLS0gU09OQU1VOkVORCAtLT5cXG5gO1xuICAgICAgICBhd2FpdCB3cml0ZUZpbGUodGFyZ2V0Q2xhdWRlTWQsIHdpdGhNYXJrZXJzKTtcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYOKckyBDTEFVREUubWQgY3JlYXRlZGApKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgY2hhbGsucmVkKFxuICAgICAgICAgIGDinJcgRmFpbGVkIHRvIHVwZGF0ZSBDTEFVREUubWQ6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWAsXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBza2lsbHNDb3B5KHNyYzogc3RyaW5nLCBkZXN0OiBzdHJpbmcpIHtcbiAgdHJ5IHtcbiAgICBhd2FpdCBjcChzcmMsIGRlc3QsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIGNvbnNvbGUubG9nKGNoYWxrLmdyZWVuKGDinJMgU2tpbGxzIGNvcGllZGApKTtcbiAgfSBjYXRjaCAoY29weUVycm9yKSB7XG4gICAgY29uc29sZS5lcnJvcihcbiAgICAgIGNoYWxrLnJlZChcbiAgICAgICAgYOKclyBGYWlsZWQgdG8gY29weSBza2lsbHM6ICR7Y29weUVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBjb3B5RXJyb3IubWVzc2FnZSA6IFN0cmluZyhjb3B5RXJyb3IpfWAsXG4gICAgICApLFxuICAgICk7XG4gICAgdGhyb3cgY29weUVycm9yO1xuICB9XG59XG5cbi8qKlxuICogcG5wbSBzb25hbXUgc2tpbGxzIGNyZWF0ZSA8bmFtZT4g7ZWY66m0IOyLpO2WieuQmOuKlCDtlajsiJjsnoXri4jri6QuXG4gKiDroZzsu6wgc2tpbGwg7LSI7JWI7J2EIOyDneyEse2VqeuLiOuLpC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc2tpbGxzX2NyZWF0ZShuYW1lOiBzdHJpbmcpIHtcbiAgY29uc3Qgd29ya3NwYWNlUm9vdCA9IGF3YWl0IGZpbmRXb3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IGxvY2FsRGlyID0gcGF0aC5qb2luKHdvcmtzcGFjZVJvb3QsIFwiLmNsYXVkZVwiLCBcInNraWxsc1wiLCBcImxvY2FsXCIpO1xuXG4gIC8vID09PSDtjIzsnbzrqoUg6rKA7KadIOuwjyBTYW5pdGl6ZSA9PT1cbiAgaWYgKCFuYW1lIHx8IG5hbWUudHJpbSgpID09PSBcIlwiKSB7XG4gICAgY29uc29sZS5lcnJvcihjaGFsay5yZWQoXCLinJcgU2tpbGwgbmFtZSBpcyByZXF1aXJlZFwiKSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbGV0IHNhbml0aXplZCA9IG5hbWVcbiAgICAvLyDqs7XrsLHsnYQg7ZWY7J207ZSI7Jy866GcXG4gICAgLnJlcGxhY2UoL1xccysvZywgXCItXCIpXG4gICAgLy8g6rK966GcIOq1rOu2hOyekCDsoJzqsbBcbiAgICAucmVwbGFjZSgvWy9cXFxcXS9nLCBcIi1cIilcbiAgICAvLyBQYXRoIHRyYXZlcnNhbCDrsKnsp4BcbiAgICAucmVwbGFjZSgvXFwuXFwuL2csIFwiXCIpXG4gICAgLy8gV2luZG93cyDquIjsp4Ag66y47J6QIOygnOqxsFxuICAgIC5yZXBsYWNlKC9bPD46XCJ8PypdL2csIFwiXCIpXG4gICAgLy8g7Iuc7J6RL+uBnSDsoJAsIO2VmOydtO2UiCwg7Ja4642U7Iqk7L2U7Ja0IOygnOqxsFxuICAgIC5yZXBsYWNlKC9eWy5cXC1fXSt8Wy5cXC1fXSskL2csIFwiXCIpXG4gICAgLy8g7Jew7IaN65CcIO2VmOydtO2UiOydhCDtlZjrgpjroZxcbiAgICAucmVwbGFjZSgvLSsvZywgXCItXCIpXG4gICAgLy8g7JWM7YyM67KzLCDsiKvsnpAsIO2VmOydtO2UiCwg7Ja4642U7Iqk7L2U7Ja0LCDtlZzquIDrp4wg7ZeI7JqpXG4gICAgLnJlcGxhY2UoL1teYS16QS1aMC05LV/qsIAt7Z6jXS9nLCBcIlwiKTtcblxuICAvLyDquLjsnbQg7KCc7ZWcXG4gIGNvbnN0IE1BWF9MRU5HVEggPSAxMDA7XG4gIGlmIChzYW5pdGl6ZWQubGVuZ3RoID4gTUFYX0xFTkdUSCkge1xuICAgIHNhbml0aXplZCA9IHNhbml0aXplZC5zdWJzdHJpbmcoMCwgTUFYX0xFTkdUSCk7XG4gICAgY29uc29sZS5sb2coY2hhbGsueWVsbG93KGDimqAgTmFtZSB0cnVuY2F0ZWQgdG8gJHtNQVhfTEVOR1RIfSBjaGFyYWN0ZXJzYCkpO1xuICB9XG5cbiAgLy8gV2luZG93cyDsmIjslb3slrQg7ZmV7J24XG4gIGNvbnN0IFJFU0VSVkVEX05BTUVTID0gW1xuICAgIFwiQ09OXCIsXG4gICAgXCJQUk5cIixcbiAgICBcIkFVWFwiLFxuICAgIFwiTlVMXCIsXG4gICAgXCJDT00xXCIsXG4gICAgXCJDT00yXCIsXG4gICAgXCJDT00zXCIsXG4gICAgXCJDT000XCIsXG4gICAgXCJDT001XCIsXG4gICAgXCJDT002XCIsXG4gICAgXCJDT003XCIsXG4gICAgXCJDT004XCIsXG4gICAgXCJDT005XCIsXG4gICAgXCJMUFQxXCIsXG4gICAgXCJMUFQyXCIsXG4gICAgXCJMUFQzXCIsXG4gICAgXCJMUFQ0XCIsXG4gICAgXCJMUFQ1XCIsXG4gICAgXCJMUFQ2XCIsXG4gICAgXCJMUFQ3XCIsXG4gICAgXCJMUFQ4XCIsXG4gICAgXCJMUFQ5XCIsXG4gIF07XG4gIGlmIChSRVNFUlZFRF9OQU1FUy5pbmNsdWRlcyhzYW5pdGl6ZWQudG9VcHBlckNhc2UoKSkpIHtcbiAgICBzYW5pdGl6ZWQgPSBgc2tpbGwtJHtzYW5pdGl6ZWR9YDtcbiAgICBjb25zb2xlLmxvZyhjaGFsay55ZWxsb3coYOKaoCBSZXNlcnZlZCBuYW1lIGRldGVjdGVkLCBwcmVmaXhlZCB3aXRoIFwic2tpbGwtXCJgKSk7XG4gIH1cblxuICAvLyDruYgg66y47J6Q7Je0IOyytO2BrFxuICBpZiAoc2FuaXRpemVkID09PSBcIlwiKSB7XG4gICAgY29uc29sZS5lcnJvcihjaGFsay5yZWQoXCLinJcgSW52YWxpZCBza2lsbCBuYW1lIGFmdGVyIHNhbml0aXphdGlvblwiKSk7XG4gICAgY29uc29sZS5sb2coY2hhbGsuZGltKGAgIE9yaWdpbmFsOiBcIiR7bmFtZX1cImApKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyDrs4Dqsr0g7JWM66a8XG4gIGlmIChzYW5pdGl6ZWQgIT09IG5hbWUpIHtcbiAgICBjb25zb2xlLmxvZyhjaGFsay55ZWxsb3coYOKaoCBOYW1lIHNhbml0aXplZDogXCIke25hbWV9XCIg4oaSIFwiJHtzYW5pdGl6ZWR9XCJgKSk7XG4gIH1cblxuICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbihsb2NhbERpciwgYCR7c2FuaXRpemVkfS5tZGApO1xuXG4gIGlmIChhd2FpdCBleGlzdHMoZmlsZVBhdGgpKSB7XG4gICAgY29uc29sZS5sb2coY2hhbGsueWVsbG93KGBTa2lsbCBcIiR7c2FuaXRpemVkfVwiIGFscmVhZHkgZXhpc3RzLmApKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBhd2FpdCBta2Rpcihsb2NhbERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgY29uc3QgdGVtcGxhdGUgPSBgLS0tXG5uYW1lOiAke3Nhbml0aXplZH1cbmNhdGVnb3J5OiBvdGhlclxuY3JlYXRlZF9hdDogJHtuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkuc3BsaXQoXCJUXCIpWzBdfVxuc3RhdHVzOiBkcmFmdFxuLS0tXG5cbiMgJHtzYW5pdGl6ZWR9XG5cbiMjIOyDge2ZqVxuXG5b7Ja065akIOusuOygnOyYgOuKlOyngF1cblxuIyMg7ZW06rKwIOuwqeuylVxuXG5b7Ja065a76rKMIO2VtOqysO2WiOuKlOyngF1cblxuIyMg7L2U65OcIOyYiOyLnFxuXG5cXGBcXGBcXGB0eXBlc2NyaXB0XG4vLyDsmIjsi5wg7L2U65OcXG5cXGBcXGBcXGBcbmA7XG5cbiAgYXdhaXQgd3JpdGVGaWxlKGZpbGVQYXRoLCB0ZW1wbGF0ZSk7XG4gIGNvbnNvbGUubG9nKGNoYWxrLmdyZWVuKGDinJMgQ3JlYXRlZCAuY2xhdWRlL3NraWxscy9sb2NhbC8ke3Nhbml0aXplZH0ubWRgKSk7XG59XG5cbi8qKlxuICogcG5wbSBzb25hbXUgYXV0aCBnZW5lcmF0ZSDtlZjrqbQg7Iuk7ZaJ65CY64qUIO2VqOyImOyeheuLiOuLpC5cbiAqIGJldHRlci1hdXRoIOyXlO2LsO2LsOuTpChVc2VyLCBTZXNzaW9uLCBBY2NvdW50LCBWZXJpZmljYXRpb24p7J2EIOyDneyEse2VqeuLiOuLpC5cbiAqXG4gKiDsmLXshZg6XG4gKiAtLXBsdWdpbnMgcGhvbmUtbnVtYmVyLDJmYSAg7ZSM65+s6re47J24IOyXlO2LsO2LsOuPhCDtlajqu5gg7IOd7ISxXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGF1dGhfZ2VuZXJhdGUoKSB7XG4gIC8vIC0tcGx1Z2lucyDsmLXshZgg7YyM7IuxXG4gIGNvbnN0IHBsdWdpbnNBcmcgPSBwcm9jZXNzLmFyZ3YuZmluZCgoYXJnKSA9PiBhcmcuc3RhcnRzV2l0aChcIi0tcGx1Z2luc1wiKSk7XG4gIGNvbnN0IHBsdWdpbnM6IEJldHRlckF1dGhQbHVnaW5JZFtdID0gW107XG5cbiAgaWYgKHBsdWdpbnNBcmcpIHtcbiAgICBjb25zdCBwbHVnaW5WYWx1ZSA9IHBsdWdpbnNBcmcuaW5jbHVkZXMoXCI9XCIpXG4gICAgICA/IHBsdWdpbnNBcmcuc3BsaXQoXCI9XCIpWzFdXG4gICAgICA6IHByb2Nlc3MuYXJndltwcm9jZXNzLmFyZ3YuaW5kZXhPZihwbHVnaW5zQXJnKSArIDFdO1xuXG4gICAgaWYgKHBsdWdpblZhbHVlKSB7XG4gICAgICBjb25zdCBwbHVnaW5JZHMgPSBwbHVnaW5WYWx1ZS5zcGxpdChcIixcIikubWFwKChwKSA9PiBwLnRyaW0oKSk7XG5cbiAgICAgIGZvciAoY29uc3QgaWQgb2YgcGx1Z2luSWRzKSB7XG4gICAgICAgIGlmIChpc1ZhbGlkUGx1Z2luSWQoaWQpKSB7XG4gICAgICAgICAgcGx1Z2lucy5wdXNoKGlkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhjaGFsay55ZWxsb3coYOKaoCBVbmtub3duIHBsdWdpbjogJHtpZH1gKSk7XG4gICAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZGltKGAgIFN1cHBvcnRlZCBwbHVnaW5zOiAke1NVUFBPUlRFRF9QTFVHSU5fSURTLmpvaW4oXCIsIFwiKX1gKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zb2xlLmxvZyhjaGFsay55ZWxsb3cuYm9sZChcIvCflJAgR2VuZXJhdGluZyBiZXR0ZXItYXV0aCBlbnRpdGllcy4uLlxcblwiKSk7XG5cbiAgaWYgKHBsdWdpbnMubGVuZ3RoID4gMCkge1xuICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShgICBQbHVnaW5zOiAke3BsdWdpbnMuam9pbihcIiwgXCIpfWApKTtcbiAgfVxuXG4gIGF3YWl0IGdlbmVyYXRlQmV0dGVyQXV0aEVudGl0aWVzKHsgcGx1Z2lucyB9KTtcbn1cblxuLyoqXG4gKiBwbnBtIHNvbmFtdSBhdXRoIGFkZC1jb21wYW5pb25zIO2VmOuptCDsi6TtlonrkJjripQg7ZWo7IiY7J6F64uI64ukLlxuICog6riw7KG0IO2UhOuhnOygne2KuOydmCBlbnRpdHkuanNvbuyXkCBmaXh0dXJlQ29tcGFuaW9uc+ulvCDshozquIkg7LaU6rCA7ZWp64uI64ukLlxuICpcbiAqIOydtOuvuCBmaXh0dXJlQ29tcGFuaW9uc+qwgCDsnojripQgZW50aXR564qUIOyKpO2Cte2VqeuLiOuLpCAo642u7Ja07JOw6riwIOyXhuydjCkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGF1dGhfYWRkX2NvbXBhbmlvbnMoKSB7XG4gIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdy5ib2xkKFwi8J+UkCBBZGRpbmcgZml4dHVyZUNvbXBhbmlvbnMgdG8gYmV0dGVyLWF1dGggZW50aXRpZXMuLi5cXG5cIikpO1xuICBhd2FpdCBhZGRDb21wYW5pb25zVG9FbnRpdGllcygpO1xuICBjb25zb2xlLmxvZyhjaGFsay5ib2xkKFwiXFxu4pyFIERvbmUhXCIpKTtcbn1cblxuLyoqXG4gKiDsm4ztgazsiqTtjpjsnbTsiqQg66Oo7Yq466W8IOywvuyKteuLiOuLpC5cbiAqIOyasOyEoOyInOychDogcG5wbS13b3Jrc3BhY2UueWFtbCA+IHBhY2thZ2UuanNvbih3b3Jrc3BhY2VzKSA+IC5hZ2VudHMvXG4gKlxuICogQ0xBVURFLm1k64qUIOyEnOu4jO2MqO2CpOyngOyXkOuPhCDsobTsnqztlaAg7IiYIOyeiOycvOuvgOuhnCDsgqzsmqntlZjsp4Ag7JWK7Iq164uI64ukLlxuICogLmFnZW50cy/ripQgYWdlbnRzIGluaXTsnbQg7IOd7ISx7ZWY64qUIOuUlOugie2GoOumrOuhnCwg7JuM7YGs7Iqk7Y6Y7J207IqkIOujqO2KuOyXkOunjCDsobTsnqztlanri4jri6QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZpbmRXb3Jrc3BhY2VSb290KCkge1xuICBsZXQgZGlyID0gcHJvY2Vzcy5jd2QoKTtcblxuICB3aGlsZSAoZGlyICE9PSBwYXRoLmRpcm5hbWUoZGlyKSkge1xuICAgIC8vIDEuIHBucG0td29ya3NwYWNlLnlhbWw6IO2ZleyLpO2VnCBtb25vcmVwbyDro6jtirguXG4gICAgaWYgKGF3YWl0IGV4aXN0cyhwYXRoLmpvaW4oZGlyLCBcInBucG0td29ya3NwYWNlLnlhbWxcIikpKSB7XG4gICAgICByZXR1cm4gZGlyO1xuICAgIH1cblxuICAgIC8vIDIuIHBhY2thZ2UuanNvbuyXkCB3b3Jrc3BhY2VzIO2VhOuTnOqwgCDsnojsnLzrqbQgbW9ub3JlcG8g66Oo7Yq4LlxuICAgIGNvbnN0IHBhY2thZ2VQYXRoID0gcGF0aC5qb2luKGRpciwgXCJwYWNrYWdlLmpzb25cIik7XG4gICAgaWYgKGF3YWl0IGV4aXN0cyhwYWNrYWdlUGF0aCkpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHBhY2thZ2VKc29uID0gSlNPTi5wYXJzZShhd2FpdCByZWFkRmlsZShwYWNrYWdlUGF0aCwgXCJ1dGYtOFwiKSk7XG4gICAgICAgIGlmIChwYWNrYWdlSnNvbi53b3Jrc3BhY2VzKSB7XG4gICAgICAgICAgcmV0dXJuIGRpcjtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIO2MjOyLsSDsi6TtjKjsi5wg66y07IucXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gMy4gLmFnZW50cy86IGFnZW50cyBpbml07J20IOyDneyEse2VnCDrlJTroInthqDrpqwuIOyEnOu4jO2MqO2CpOyngOyXkOuKlCDsobTsnqztlZjsp4Ag7JWK7J2MLlxuICAgIGlmIChhd2FpdCBleGlzdHMocGF0aC5qb2luKGRpciwgXCIuYWdlbnRzXCIpKSkge1xuICAgICAgcmV0dXJuIGRpcjtcbiAgICB9XG5cbiAgICBkaXIgPSBwYXRoLmRpcm5hbWUoZGlyKTtcbiAgfVxuXG4gIC8vIOywvuyngCDrqrvtlZjrqbQgYXBpIO2PtOuNlOydmCDrtoDrqqgg7IKs7JqpXG4gIHJldHVybiBmaW5kQXBwUm9vdFBhdGgoKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztZQWFzQztvQkFLa0I7U0FDWDtjQUNHO3FCQUNXO2tCQVE3QjtjQUNZO1dBQ3VCO0FBT2pFLElBQUk7Ozs7QUFLSixTQUFTLGdCQUFnQixPQUFpQixRQUFRLE1BR2hEO0NBQ0EsTUFBTSx3QkFBUSxJQUFJLElBQVk7Q0FDOUIsTUFBTSxVQUFrQyxDQUFDO0NBRXpDLEtBQUssSUFBSSxJQUFJLEdBQUcsSUFBSSxLQUFLLFFBQVEsS0FBSztFQUNwQyxNQUFNLE1BQU0sS0FBSztFQUNqQixJQUFJLENBQUMsSUFBSSxXQUFXLElBQUksR0FBRztFQUczQixJQUFJLElBQUksU0FBUyxHQUFHLEdBQUc7R0FDckIsTUFBTSxDQUFDLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHO0dBQzNDLFFBQVEsT0FBTztHQUNmO0VBQ0Y7RUFHQSxNQUFNLFVBQVUsS0FBSyxJQUFJO0VBQ3pCLElBQUksV0FBVyxDQUFDLFFBQVEsV0FBVyxJQUFJLEtBQUssQ0FBQyxRQUFRLFdBQVcsR0FBRyxHQUFHO0dBQ3BFLFFBQVEsSUFBSSxNQUFNLENBQUMsS0FBSztHQUN4QjtFQUNGLE9BRUUsTUFBTSxJQUFJLElBQUksTUFBTSxDQUFDLENBQUM7Q0FFMUI7Q0FFQSxPQUFPO0VBQUU7RUFBTztDQUFRO0FBQzFCO0FBRUEsZUFBZSxZQUFZO0NBRXpCLElBQUksQ0FEYztFQUFDO0VBQU87RUFBUztFQUFTO0VBQVU7Q0FBTSxDQUFDLENBQUMsU0FBUyxRQUFRLEtBQUssTUFBTSxFQUNyRixHQUNILE1BQU0sT0FBTyxLQUFLLE9BQU8sS0FBSztDQUdoQyxJQUFJO0VBSUYsTUFBTSxlQUF5QixDQUFDO0VBQ2hD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